2
0
forked from Wavyzz/dolibarr

New expense report rules and ik (index kilometers) - MAIN_USE_EXPENSE_IK - MAIN_USE_EXPENSE_RULE

This commit is contained in:
phf
2017-06-15 11:08:53 +02:00
parent 00bf4bba13
commit 1beec51928
27 changed files with 2551 additions and 238 deletions

View File

@@ -87,7 +87,7 @@ $hookmanager->initHooks(array('admin'));
// Put here declaration of dictionaries properties
// Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this.
$taborder=array(9,0,4,3,2,0,1,8,19,16,27,0,5,11,0,33,34,0,6,0,29,0,7,17,24,28,0,10,23,12,13,0,14,0,22,20,18,21,0,15,30,0,26,0);
$taborder=array(9,0,4,3,2,0,1,8,19,16,27,0,5,11,0,33,34,0,6,0,29,0,7,17,35,36,24,28,0,10,23,12,13,0,14,0,22,20,18,21,0,15,30,0,26,0,);
// Name of SQL tables of dictionaries
$tabname=array();
@@ -125,6 +125,8 @@ $tabname[30]= MAIN_DB_PREFIX."c_format_cards";
//$tabname[32]= MAIN_DB_PREFIX."c_accounting_category";
$tabname[33]= MAIN_DB_PREFIX."c_hrm_department";
$tabname[34]= MAIN_DB_PREFIX."c_hrm_function";
$tabname[35]= MAIN_DB_PREFIX."c_exp_tax_cat";
$tabname[36]= MAIN_DB_PREFIX."c_exp_tax_range";
// Dictionary labels
$tablib=array();
@@ -162,6 +164,8 @@ $tablib[30]= "DictionaryFormatCards";
//$tablib[32]= "DictionaryAccountancyCategory";
$tablib[33]= "DictionaryDepartment";
$tablib[34]= "DictionaryFunction";
$tablib[35]= "DictionaryExpenseTaxCat";
$tablib[36]= "DictionaryExpenseTaxRange";
// Requests to extract data
$tabsql=array();
@@ -199,6 +203,8 @@ $tabsql[30]= "SELECT rowid, code, name, paper_size, orientation, metric, leftmar
//$tabsql[32]= "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account, a.sens, a.category_type, a.formula, a.position as position, a.fk_country as country_id, c.code as country_code, c.label as country, a.active FROM ".MAIN_DB_PREFIX."c_accounting_category as a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_country=c.rowid and c.active=1";
$tabsql[33]= "SELECT rowid, pos, code, label, active FROM ".MAIN_DB_PREFIX."c_hrm_department";
$tabsql[34]= "SELECT rowid, pos, code, label, c_level, active FROM ".MAIN_DB_PREFIX."c_hrm_function";
$tabsql[35]= "SELECT c.rowid, c.label, c.active, c.entity FROM ".MAIN_DB_PREFIX."c_exp_tax_cat c";
$tabsql[36]= "SELECT r.rowid, r.fk_cat, r.range, r.active, r.entity FROM ".MAIN_DB_PREFIX."c_exp_tax_range r";
// Criteria to sort dictionaries
$tabsqlsort=array();
@@ -236,6 +242,8 @@ $tabsqlsort[30]="code ASC";
//$tabsqlsort[32]="position ASC";
$tabsqlsort[33]="code ASC";
$tabsqlsort[34]="code ASC";
$tabsqlsort[35]="c.label ASC";
$tabsqlsort[36]="r.fk_cat ASC, r.range ASC";
// Nom des champs en resultat de select pour affichage du dictionnaire
$tabfield=array();
@@ -271,8 +279,8 @@ $tabfield[29]= "code,label,percent,position";
$tabfield[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y";
//$tabfield[31]= "pcg_version,label";
//$tabfield[32]= "code,label,range_account,sens,category_type,formula,position,country_id,country";
$tabfield[33]= "code,label";
$tabfield[34]= "code,label";
$tabfield[35]= "label";
$tabfield[36]= "range,fk_cat";
// Nom des champs d'edition pour modification d'un enregistrement
$tabfieldvalue=array();
@@ -310,6 +318,8 @@ $tabfieldvalue[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargi
//$tabfieldvalue[32]= "code,label,range_account,sens,category_type,formula,position,country";
$tabfieldvalue[33]= "code,label";
$tabfieldvalue[34]= "code,label";
$tabfieldvalue[35]= "label";
$tabfieldvalue[36]= "range,fk_cat";
// Nom des champs dans la table pour insertion d'un enregistrement
$tabfieldinsert=array();
@@ -347,6 +357,8 @@ $tabfieldinsert[30]= "code,name,paper_size,orientation,metric,leftmargin,topmarg
//$tabfieldinsert[32]= "code,label,range_account,sens,category_type,formula,position,fk_country";
$tabfieldinsert[33]= "code,label";
$tabfieldinsert[34]= "code,label";
$tabfieldinsert[35]= "label";
$tabfieldinsert[36]= "`range`,fk_cat";
// Nom du rowid si le champ n'est pas de type autoincrement
// Example: "" if id field is "rowid" and has autoincrement on
@@ -386,6 +398,8 @@ $tabrowid[30]= "";
//$tabrowid[32]= "";
$tabrowid[33]= "rowid";
$tabrowid[34]= "rowid";
$tabrowid[35]= "";
$tabrowid[36]= "";
// Condition to show dictionary in setup page
$tabcond=array();
@@ -423,6 +437,8 @@ $tabcond[30]= ! empty($conf->label->enabled);
//$tabcond[32]= ! empty($conf->accounting->enabled);
$tabcond[33]= ! empty($conf->hrm->enabled);
$tabcond[34]= ! empty($conf->hrm->enabled);
$tabcond[35]= ! empty($conf->expensereport->enabled);
$tabcond[36]= ! empty($conf->expensereport->enabled);
// List of help for fields
$tabhelp=array();
@@ -460,6 +476,8 @@ $tabhelp[30] = array('code'=>$langs->trans("EnterAnyCode"), 'name'=>$langs->tran
//$tabhelp[32] = array('code'=>$langs->trans("EnterAnyCode"));
$tabhelp[33] = array('code'=>$langs->trans("EnterAnyCode"));
$tabhelp[34] = array('code'=>$langs->trans("EnterAnyCode"));
$tabhelp[35]= array();
$tabhelp[36]= array('range'=>$langs->trans('PrevRangeToThisRange'));
// List of check for fields (NOT USED YET)
$tabfieldcheck=array();
@@ -497,6 +515,8 @@ $tabfieldcheck[30] = array();
//$tabfieldcheck[32] = array();
$tabfieldcheck[33] = array();
$tabfieldcheck[34] = array();
$tabfieldcheck[35]= array();
$tabfieldcheck[36]= array();
// Complete all arrays with entries found into modules
complete_dictionary_with_modules($taborder,$tabname,$tablib,$tabsql,$tabsqlsort,$tabfield,$tabfieldvalue,$tabfieldinsert,$tabrowid,$tabcond,$tabhelp,$tabfieldcheck);
@@ -1064,6 +1084,7 @@ if ($id)
if ($fieldlist[$field]=='affect') { $valuetoshow=$langs->trans("WithCounter"); }
if ($fieldlist[$field]=='delay') { $valuetoshow=$langs->trans("NoticePeriod"); }
if ($fieldlist[$field]=='newbymonth') { $valuetoshow=$langs->trans("NewByMonth"); }
if ($fieldlist[$field]=='fk_tva') { $valuetoshow=$langs->trans("VAT"); }
if ($id == 2) // Special cas for state page
{
@@ -1283,6 +1304,7 @@ if ($id)
if ($fieldlist[$field]=='affect') { $valuetoshow=$langs->trans("WithCounter"); }
if ($fieldlist[$field]=='delay') { $valuetoshow=$langs->trans("NoticePeriod"); }
if ($fieldlist[$field]=='newbymonth') { $valuetoshow=$langs->trans("NewByMonth"); }
if ($fieldlist[$field]=='fk_tva') { $valuetoshow=$langs->trans("VAT"); }
// Affiche nom du champ
if ($showfield)
@@ -1500,6 +1522,26 @@ if ($id)
else if ($fieldlist[$field]=='accountancy_code' || $fieldlist[$field]=='accountancy_code_sell' || $fieldlist[$field]=='accountancy_code_buy') {
$valuetoshow = length_accountg($valuetoshow);
}
elseif ($fieldlist[$field] == 'fk_tva')
{
foreach ($form->cache_vatrates as $key => $Tab)
{
if ($form->cache_vatrates[$key]['rowid'] == $valuetoshow)
{
$valuetoshow = $form->cache_vatrates[$key]['libtva'];
break;
}
}
}
elseif (in_array($fieldlist[$field], array('fk_cat', 'fk_exp_tax_cat')))
{
$valuetoshow = getDictvalue(MAIN_DB_PREFIX.'c_exp_tax_cat', 'label', $valuetoshow);
$valuetoshow = $langs->trans($valuetoshow);
}
elseif ($tabname[$id] == MAIN_DB_PREFIX.'c_exp_tax_cat')
{
$valuetoshow = $langs->trans($valuetoshow);
}
$class='tddict';
if ($fieldlist[$field] == 'tracking') $class.=' tdoverflowauto';
@@ -1663,7 +1705,7 @@ $db->close();
*/
function fieldList($fieldlist, $obj='', $tabname='', $context='')
{
global $conf,$langs,$db;
global $conf,$langs,$db,$mysoc;
global $form;
global $region_id;
global $elementList,$sourceList,$localtax_typeList;
@@ -1829,6 +1871,24 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
}
print '</td>';
}
elseif ($fieldlist[$field] == 'fk_tva')
{
print '<td>';
print $form->load_tva('fk_tva', $obj->taux, $mysoc, new Societe($db), 0, 0, '', false, -1);
print '</td>';
}
elseif ($fieldlist[$field] == 'fk_cat')
{
print '<td>';
print $form->selectExpenseCategories($obj->fk_cat);
print '</td>';
}
elseif ($fieldlist[$field] == 'fk_range')
{
print '<td>';
print $form->selectExpenseRanges($obj->fk_range);
print '</td>';
}
else
{
$classtd=''; $class='';

View File

@@ -0,0 +1,188 @@
<?php
/* Copyright (C) 2012 Mikael Carlavan <contact@mika-carl.fr>
* Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
* Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/admin/expensereport_ik.php
* \ingroup expensereport
* \brief Page to display expense tax ik
*/
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/expensereport.lib.php';
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_ik.class.php';
$langs->load('admin');
$langs->load('other');
$langs->load('trips');
$langs->load('errors');
$langs->load('dict');
if (!$user->admin) accessforbidden();
//Init error
$error = false;
$message = false;
$action = GETPOST('action','alpha');
$id = GETPOST('id','int');
$offset = GETPOST('offset','int');
$coef = GETPOST('coef','int');
$fk_cat = GETPOST('fk_cat');
$fk_range = GETPOST('fk_range');
if ($action == 'updateik')
{
$expIk = new ExpenseReportIk($db);
if ($id > 0)
{
$result = $expIk->fetch($id);
if ($result < 0) dol_print_error('', $expIk->error, $expIk->errors);
}
$expIk->setValues($_POST);
$result = $expIk->create($user);
if ($result > 0) setEventMessages('SetupSaved', null, 'mesgs');
header('Location: '.$_SERVER['PHP_SELF']);
exit;
}
elseif ($action == 'delete') // TODO add confirm
{
$expIk = new ExpenseReportIk($db);
if ($id > 0)
{
$result = $expIk->fetch($id);
if ($result < 0) dol_print_error('', $expIk->error, $expIk->errors);
$expIk->delete($user);
}
header('Location: '.$_SERVER['PHP_SELF']);
exit;
}
$rangesbycateg = ExpenseReportIk::getAllRanges();
/*
* View
*/
llxHeader();
$form=new Form($db);
$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans("ExpenseReportsIkSetup"),$linkback,'title_setup');
$head=expensereport_admin_prepare_head();
dol_fiche_head($head, 'expenseik', $langs->trans("ExpenseReportsIk"), -1, 'trip');
echo $langs->trans('ExpenseReportIkDesc');
echo '<form action="'.$_SERVER['PHP_SELF'].'" method="post">';
if ($action == 'edit')
{
echo '<input type="hidden" name="id" value="'.$id.'" />';
echo '<input type="hidden" name="fk_cat" value="'.$fk_cat.'" />';
echo '<input type="hidden" name="fk_range" value="'.$fk_range.'" />';
echo '<input type="hidden" name="action" value="updateik" />';
}
echo '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />';
echo '<table class="noborder" width="100%">';
foreach ($rangesbycateg as $fk_cat => $Tab)
{
$title = ($Tab['active'] == 1) ? $langs->trans($Tab['label']) : $form->textwithpicto($langs->trans($Tab['label']), $langs->trans('expenseReportCatDisabled'), 1, 'help', '', 0, 3);
echo '<tr class="liste_titre">';
echo '<td>'.$title.'</td>';
echo '<td>'.$langs->trans('expenseReportOffset').'</td>';
echo '<td>'.$langs->trans('expenseReportCoef').'</td>';
echo '<td>'.$langs->trans('expenseReportTotalForFive').'</td>';
echo '<td>&nbsp;</td>';
echo '</tr>';
if ($Tab['active'] == 0) continue;
$tranche=1;
$var = true;
foreach ($Tab['ranges'] as $k => $range)
{
if (isset($Tab['ranges'][$k+1])) $label = $langs->trans('expenseReportRangeFromTo', $range->range, ($Tab['ranges'][$k+1]->range-1));
else $label = $langs->trans('expenseReportRangeMoreThan', $range->range);
if ($range->range_active == 0) $label = $form->textwithpicto($label, $langs->trans('expenseReportRangeDisabled'), 1, 'help', '', 0, 3);
echo '<tr '.$bc[$var].'>';
// Label
echo '<td width="20%"><b>['.$langs->trans('RangeNum', $tranche++).']</b> - '.$label.'</td>';
// Offset
echo '<td width="20%">';
if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_cat == $fk_cat) echo '<input type="text" name="offset" value="'.$range->ik->offset.'" />';
else echo $range->ik->offset;
echo '</td>';
// Coef
echo '<td width="20%">';
if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_cat == $fk_cat) echo '<input type="text" name="coef" value="'.$range->ik->coef.'" />';
else echo ($range->ik->id > 0 ? $range->ik->coef : $langs->trans('expenseReportCoefUndefined'));
echo '</td>';
// Total for one
echo '<td width="30%">'.$langs->trans('expenseReportPrintExample', price($range->ik->offset + 5 * $range->ik->coef)).'</td>';
// Action
echo '<td align="right">';
if ($range->range_active == 1)
{
if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_cat == $fk_cat)
{
echo '<input id="" class="button" name="save" value="'.$langs->trans('Save').'" type="submit" />';
echo '<input class="button" value="'.$langs->trans('Cancel').'" onclick="javascript:history.go(-1)" type="button" />';
}
else
{
echo '<a href="'.$_SERVER['PHP_SELF'].'?action=edit&id='.$range->ik->id.'&fk_cat='.$range->fk_cat.'&fk_range='.$range->rowid.'">'.img_edit().'</a>';
if (!empty($range->ik->id)) echo '<a href="'.$_SERVER['PHP_SELF'].'?action=delete&id='.$range->ik->id.'">'.img_delete().'</a>';
// TODO add delete link
}
}
echo '</td>';
echo '</tr>';
$var=!$var;
}
}
echo '</table>';
echo '</form>';
dol_fiche_end();
llxFooter();
$db->close();

View File

@@ -0,0 +1,366 @@
<?php
/* Copyright (C) 2012 Mikael Carlavan <contact@mika-carl.fr>
* Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
* Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/admin/expensereport_ik.php
* \ingroup expensereport
* \brief Page to display expense tax ik
*/
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/expensereport.lib.php';
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_rule.class.php';
$langs->load('admin');
$langs->load('other');
$langs->load('trips');
$langs->load('errors');
$langs->load('dict');
if (!$user->admin) accessforbidden();
//Init error
$error = false;
$message = false;
$action = GETPOST('action','alpha');
$id = GETPOST('id','int');
$apply_to = GETPOST('apply_to');
$fk_user = GETPOST('fk_user');
$fk_usergroup = GETPOST('fk_usergroup');
$fk_c_type_fees = GETPOST('fk_c_type_fees');
$code_expense_rules_type = GETPOST('code_expense_rules_type');
$dates = dol_mktime(12, 0, 0, GETPOST('startmonth'), GETPOST('startday'), GETPOST('startyear'));
$datee = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
$amount = GETPOST('amount');
$restrictive = GETPOST('restrictive');
$object = new ExpenseReportRule($db);
if (!empty($id))
{
$result = $object->fetch($id);
if ($result < 0) dol_print_error('', $object->error, $object->errors);
}
// TODO do action
if ($action == 'save')
{
$error = 0;
// check parameters
if (empty($apply_to)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportApplyTo")), null, 'errors');
}
if (empty($fk_c_type_fees)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDomain")), null, 'errors');
}
if (empty($code_expense_rules_type)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitOn")), null, 'errors');
}
if (empty($dates)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateStart")), null, 'errors');
}
if (empty($datee)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateEnd")), null, 'errors');
}
if (empty($amount)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitAmount")), null, 'errors');
}
if (empty($error))
{
$object->setValues($_POST);
if($apply_to=='U'){
$object->fk_user=$fk_user;
$object->fk_usergroup=0;
$object->is_for_all=0;
}elseif($apply_to=='G'){
$object->fk_usergroup=$fk_usergroup;
$object->fk_user=0;
$object->is_for_all=0;
}elseif($apply_to=='A'){
$object->is_for_all=1;
$object->fk_user=0;
$object->fk_usergroup=0;
}
$object->dates = $dates;
$object->datee = $datee;
$object->entity = $conf->entity;
$res = $object->create($user);
if ($res > 0) setEventMessages($langs->trans('ExpenseReportRuleSave'), null);
else dol_print_error($object->db);
header('Location: '.$_SERVER['PHP_SELF']);
exit;
}
}
elseif ($action == 'delete')
{
// TODO add confirm
$res = $object->delete($user);
if ($res < 0) dol_print_error($object->db);
header('Location: '.$_SERVER['PHP_SELF']);
exit;
}
$rules = ExpenseReportRule::getAllRule();
$tab_apply = array('A' => $langs->trans('All'), 'G' => $langs->trans('Group'), 'U' => $langs->trans('User'));
$tab_rules_type = array('EX_DAY' => $langs->trans('Day'), 'EX_MON' => $langs->trans('Month'), 'EX_YEA' => $langs->trans('Year'), 'EX_EXP' => $langs->trans('OnExpense'));
/*
* View
*/
llxHeader();
$form=new Form($db);
$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans("ExpenseReportsRulesSetup"),$linkback,'title_setup');
$head=expensereport_admin_prepare_head();
dol_fiche_head($head, 'expenserules', $langs->trans("ExpenseReportsRules"), -1, 'trip');
echo $langs->trans('ExpenseReportRulesDesc');
if ($action != 'edit')
{
echo '<form action="'.$_SERVER['PHP_SELF'].'" method="post">';
echo '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />';
echo '<input type="hidden" name="action" value="save" />';
echo '<table class="noborder" width="100%">';
echo '<tr class="liste_titre">';
echo '<th>'.$langs->trans('ExpenseReportApplyTo').'</th>';
echo '<th>'.$langs->trans('ExpenseReportDomain').'</th>';
echo '<th>'.$langs->trans('ExpenseReportLimitOn').'</th>';
echo '<th>'.$langs->trans('ExpenseReportDateStart').'</th>';
echo '<th>'.$langs->trans('ExpenseReportDateEnd').'</th>';
echo '<th>'.$langs->trans('ExpenseReportLimitAmount').'</th>';
echo '<th>'.$langs->trans('ExpenseReportRestrictive').'</th>';
echo '<th>&nbsp;</th>';
echo '</tr>';
$var=true;
echo '<tr '.$bc[$var].'>';
echo '<td>';
echo '<div class="float">'.$form->selectarray('apply_to', $tab_apply, '', 0).'</div>';
echo '<div id="user" class="float">'.$form->select_dolusers('', 'fk_user').'</div>';
echo '<div id="group" class="float">'.$form->select_dolgroups('', 'fk_usergroup').'</div>';
echo '</td>';
echo '<td>'.$form->selectExpense('', 'fk_c_type_fees', 0, 1, 1).'</td>';
echo '<td>'.$form->selectarray('code_expense_rules_type', $tab_rules_type, '', 0).'</td>';
echo '<td>'.$form->select_date(strtotime(date('Y-m-01', dol_now())), 'start', '', '', 0, '', 1, 0, 1).'</td>';
echo '<td>'.$form->select_date(strtotime(date('Y-m-t', dol_now())), 'end', '', '', 0, '', 1, 0, 1).'</td>';
echo '<td><input type="text" value="" name="amount" class="amount" />'.$conf->currency.'</td>';
echo '<td>'.$form->selectyesno('restrictive', 0, 1).'</td>';
echo '<td align="right"><input type="submit" class="button" value="'.$langs->trans('Add').'" /></td>';
echo '</tr>';
echo '</table>';
echo '</form>';
}
echo '<form action="'.$_SERVER['PHP_SELF'].'" method="post">';
echo '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />';
if ($action == 'edit')
{
echo '<input type="hidden" name="id" value="'.$object->id.'" />';
echo '<input type="hidden" name="action" value="save" />';
}
echo '<table class="noborder" width="100%">';
echo '<tr class="liste_titre">';
echo '<th>'.$langs->trans('ExpenseReportApplyTo').'</th>';
echo '<th>'.$langs->trans('ExpenseReportDomain').'</th>';
echo '<th>'.$langs->trans('ExpenseReportLimitOn').'</th>';
echo '<th>'.$langs->trans('ExpenseReportDateStart').'</th>';
echo '<th>'.$langs->trans('ExpenseReportDateEnd').'</th>';
echo '<th>'.$langs->trans('ExpenseReportLimitAmount').'</th>';
echo '<th>'.$langs->trans('ExpenseReportRestrictive').'</th>';
echo '<th>&nbsp;</th>';
echo '</tr>';
$var=true;
foreach ($rules as $rule)
{
echo '<tr '.$bc[$var].'>';
echo '<td>';
if ($action == 'edit' && $object->id == $rule->id)
{
$selected = ($object->is_for_all > 0) ? 'A' : ($object->fk_usergroup > 0 ? 'G' : 'U');
echo '<div class="float">'.$form->selectarray('apply_to', $tab_apply, $selected, 0).'</div>';
echo '<div id="user" class="float">'.$form->select_dolusers($object->fk_user, 'fk_user').'</div>';
echo '<div id="group" class="float">'.$form->select_dolgroups($object->fk_usergroup, 'fk_usergroup').'</div>';
}
else
{
if ($rule->is_for_all > 0) echo $tab_apply['A'];
elseif ($rule->fk_usergroup > 0) echo $tab_apply['G'].' ('.$rule->getGroupLabel().')';
elseif ($rule->fk_user > 0) echo $tab_apply['U'].' ('.$rule->getUserName().')';
}
echo '</td>';
echo '<td>';
if ($action == 'edit' && $object->id == $rule->id)
{
echo $form->selectExpense($object->fk_c_type_fees, 'fk_c_type_fees', 0, 1, 1);
}
else
{
if ($rule->fk_c_type_fees == -1) echo $langs->trans('AllExpenseReport');
else
{
$key = getDictvalue(MAIN_DB_PREFIX.'c_type_fees', 'code', $rule->fk_c_type_fees, false, 'id');
if ($key != $langs->trans($key)) echo $langs->trans($key);
else echo $langs->trans(getDictvalue(MAIN_DB_PREFIX.'c_type_fees', 'label', $rule->fk_c_type_fees, false, 'id')); // TODO check to return trans of 'code'
}
}
echo '</td>';
echo '<td>';
if ($action == 'edit' && $object->id == $rule->id)
{
echo $form->selectarray('code_expense_rules_type', $tab_rules_type, $object->code_expense_rules_type, 0);
}
else
{
echo $tab_rules_type[$rule->code_expense_rules_type];
}
echo '</td>';
echo '<td>';
if ($action == 'edit' && $object->id == $rule->id)
{
echo $form->select_date(strtotime(date('Y-m-d', $object->dates)), 'start', '', '', 0, '', 1, 0, 1);
}
else
{
echo dol_print_date($rule->dates, 'day');
}
echo '</td>';
echo '<td>';
if ($action == 'edit' && $object->id == $rule->id)
{
echo $form->select_date(strtotime(date('Y-m-d', $object->datee)), 'end', '', '', 0, '', 1, 0, 1);
}
else
{
echo dol_print_date($rule->datee, 'day');
}
echo '</td>';
echo '<td>';
if ($action == 'edit' && $object->id == $rule->id)
{
echo '<input type="text" value="'.price2num($object->amount).'" name="amount" class="amount" />'.$conf->currency;
}
else
{
echo price($rule->amount, 0, $langs, 1, -1, -1, $conf->currency);
}
echo '</td>';
echo '<td>';
if ($action == 'edit' && $object->id == $rule->id)
{
echo $form->selectyesno('restrictive', $object->restrictive, 1);
}
else
{
echo yn($rule->restrictive, 1, 1);
}
echo '</td>';
echo '<td>';
if ($object->id != $rule->id)
{
echo '<a href="'.$_SERVER['PHP_SELF'].'?action=edit&id='.$rule->id.'">'.img_edit().'</a>&nbsp;';
echo '<a href="'.$_SERVER['PHP_SELF'].'?action=delete&id='.$rule->id.'">'.img_delete().'</a>';
}
else
{
echo '<input type="submit" class="button" value="'.$langs->trans('Update').'" />&nbsp;';
echo '<a href="'.$_SERVER['PHP_SELF'].'" class="button">'.$langs->trans('Cancel').'</a>';
}
echo '</td>';
echo '</tr>';
$var=!$var;
}
echo '</table>';
echo '</form>';
echo '<script type="text/javascript"> $(function() {
$("#apply_to").change(function() {
var value = $(this).val();
if (value == "A") {
$("#group").hide(); $("#user").hide();
} else if (value == "U") {
$("#user").show();
$("#group").hide();
} else if (value == "G") {
$("#group").show();
$("#user").hide();
}
});
$("#apply_to").change();
}); </script>';
dol_fiche_end();
llxFooter();
$db->close();

View File

@@ -6294,5 +6294,175 @@ class Form
}
return $out;
}
/**
* Return HTML to show the select categories of expense category
*
* @param string $selected preselected category
* @param string $htmlname name of HTML select list
* @param integer $useempty 1=Add empty line
* @param array $excludeid id to exclude
* @param string $target htmlname of target select to bind event
* @param int $default_selected default category to select if fk_c_type_fees change = EX_KME
* @param array $params param to give
* @return string
*/
function selectExpenseCategories($selected='', $htmlname='fk_cat', $useempty=0, $excludeid=array(), $target='', $default_selected=0, $params=array())
{
global $db,$conf,$langs;
$sql = 'SELECT rowid, label FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat WHERE active = 1';
$sql.= ' AND entity IN (0,'.getEntity('').')';
if (!empty($excludeid)) $sql.= ' AND rowid NOT IN ('.implode(',', $excludeid).')';
$sql.= ' ORDER BY label';
$resql = $db->query($sql);
if ($resql)
{
$out = '<select name="'.$htmlname.'" class="'.$htmlname.' flat minwidth75imp">';
if ($useempty) $out.= '<option value="0"></option>';
while ($obj = $db->fetch_object($resql))
{
$out.= '<option '.($selected == $obj->rowid ? 'selected="selected"' : '').' value="'.$obj->rowid.'">'.$langs->trans($obj->label).'</option>';
}
$out.= '</select>';
if (!empty($target))
{
$sql = "SELECT c.id FROM ".MAIN_DB_PREFIX."c_type_fees as c WHERE c.code = 'EX_KME' AND c.active = 1";
$resql = $db->query($sql);
if ($resql)
{
if ($db->num_rows($resql) > 0)
{ dol_buildpath($path);
$obj = $db->fetch_object($resql);
$out.= '<script type="text/javascript">
$(function() {
$("select[name='.$target.']").on("change", function() {
var current_val = $(this).val();
if (current_val == '.$obj->id.') {';
if (!empty($default_selected) || !empty($selected)) $out.= '$("select[name='.$htmlname.']").val("'.($default_selected > 0 ? $default_selected : $selected).'");';
$out.= '
$("select[name='.$htmlname.']").change();
}
});
$("select[name='.$htmlname.']").change(function() {
if ($("select[name='.$target.']").val() == '.$obj->id.') {
// get price of kilometer to fill the unit price
var data = '.json_encode($params).';
data.fk_c_exp_tax_cat = $(this).val();
$.ajax({
method: "POST",
dataType: "json",
data: data,
url: "'.(DOL_URL_ROOT.'/expensereport/ajax/ajaxik.php').'",
}).done(function( data, textStatus, jqXHR ) {
console.log(data);
if (typeof data.up != "undefined") {
$("input[name=value_unit]").val(data.up);
$("select[name='.$htmlname.']").attr("title", data.title);
} else {
$("input[name=value_unit]").val("");
$("select[name='.$htmlname.']").attr("title", "");
}
});
}
});
});
</script>';
}
}
}
}
else
{
dol_print_error($db);
}
return $out;
}
/**
* Return HTML to show the select ranges of expense range
*
* @param string $selected preselected category
* @param string $htmlname name of HTML select list
* @param integer $useempty 1=Add empty line
* @return string
*/
function selectExpenseRanges($selected='', $htmlname='fk_range', $useempty=0)
{
global $db,$conf,$langs;
$sql = 'SELECT rowid, `range` FROM '.MAIN_DB_PREFIX.'c_exp_tax_range';
$sql.= ' WHERE entity = '.$conf->entity.' AND active = 1';
$resql = $db->query($sql);
if ($resql)
{
$out = '<select name="'.$htmlname.'" class="'.$htmlname.' flat minwidth75imp">';
if ($useempty) $out.= '<option value="0"></option>';
while ($obj = $db->fetch_object($resql))
{
$out.= '<option '.($selected == $obj->rowid ? 'selected="selected"' : '').' value="'.$obj->rowid.'">'.price($obj->range, 0, $langs, 1, 0).'</option>';
}
$out.= '</select>';
}
else
{
dol_print_error($db);
}
return $out;
}
/**
* Return HTML to show a select of expense
*
* @param string $selected preselected category
* @param string $htmlname name of HTML select list
* @param integer $useempty 1=Add empty choice
* @param integer $allchoice 1=Add all choice
* @param integer $useid 0=use 'code' as key, 1=use 'id' as key
* @return string
*/
function selectExpense($selected='', $htmlname='fk_c_type_fees', $useempty=0, $allchoice=1, $useid=0)
{
global $db,$langs;
$sql = 'SELECT id, code, label FROM '.MAIN_DB_PREFIX.'c_type_fees';
$sql.= ' WHERE active = 1';
$resql = $db->query($sql);
if ($resql)
{
$out = '<select name="'.$htmlname.'" class="'.$htmlname.' flat minwidth75imp">';
if ($useempty) $out.= '<option value="0"></option>';
if ($allchoice) $out.= '<option value="-1">'.$langs->trans('AllExpenseReport').'</option>';
$field = 'code';
if ($useid) $field = 'id';
while ($obj = $db->fetch_object($resql))
{
$key = $langs->trans($obj->code);
$out.= '<option '.($selected == $obj->{$field} ? 'selected="selected"' : '').' value="'.$obj->{$field}.'">'.($key != $obj->code ? $key : $obj->label).'</option>';
}
$out.= '</select>';
}
else
{
dol_print_error($db);
}
return $out;
}
}

View File

@@ -132,6 +132,22 @@ function expensereport_admin_prepare_head()
$head[$h][2] = 'expensereport';
$h++;
if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
{
$head[$h][0] = DOL_URL_ROOT."/admin/expensereport_ik.php";
$head[$h][1] = $langs->trans("ExpenseReportsIk");
$head[$h][2] = 'expenseik';
$h++;
}
if (!empty($conf->global->MAIN_USE_EXPENSE_RULE))
{
$head[$h][0] = DOL_URL_ROOT."/admin/expensereport_rules.php";
$head[$h][1] = $langs->trans("ExpenseReportsRules");
$head[$h][2] = 'expenserules';
$h++;
}
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab

View File

@@ -6383,3 +6383,43 @@ function dol_mimetype($file,$default='application/octet-stream',$mode=0)
return $mime;
}
/**
* Return value from dictionary
*
* @param string $tablename name of dictionary
* @param string $field the value to return
* @param int $id id of line
* @param bool $checkentity add filter on entity
* @param string $rowidfield name of the column rowid
*/
function getDictvalue($tablename, $field, $id, $checkentity=false, $rowidfield='rowid')
{
global $dictvalues,$db,$langs;
if (!isset($dictvalues[$tablename]))
{
$dictvalues[$tablename] = array();
$sql = 'SELECT * FROM '.$tablename.' WHERE 1';
if ($checkentity) $sql.= ' entity IN (0,'.getEntity('').')';
$resql = $db->query($sql);
if ($resql)
{
while ($obj = $db->fetch_object($resql))
{
$dictvalues[$tablename][$obj->{$rowidfield}] = $obj;
}
}
else
{
dol_print_error($db);
}
}
if (!empty($dictvalues[$tablename][$id])) return $dictvalues[$tablename][$id]->{$field}; // Found
else // Not found
{
if ($id > 0) return $id;
return '';
}
}

View File

@@ -0,0 +1,76 @@
<?php
/* Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
* Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/expensereport/ajax/ajaxprojet.php
* \ingroup expensereport
* \brief File to return Ajax response on third parties request
*/
if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal
if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1');
if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1');
if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1');
$res=0;
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_ik.class.php';
$langs->load('errors');
$langs->load('trips');
/*
* View
*/
top_httphead();
dol_syslog(join(',',$_POST));
$fk_expense = GETPOST('fk_expense');
$fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat');
if (empty($fk_expense) || $fk_expense < 0) echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorBadValueForParameter', $fk_expense, 'fk_expense')));
elseif (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorBadValueForParameter', $fk_c_exp_tax_cat, 'fk_c_exp_tax_cat')));
else
{
// @see ndfp.class.php:3576 (method: compute_total_km)
$expense = new ExpenseReport($db);
if ($expense->fetch($fk_expense) <= 0) echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorRecordNotFound'), 'fk_expense' => $fk_expense));
else
{
$userauthor = new User($db);
if ($userauthor->fetch($expense->fk_user_author) <= 0) echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorRecordNotFound'), 'fk_user_author' => $expense->fk_user_author));
else
{
$range = ExpenseReportIk::getRangeByUser($userauthor, $fk_c_exp_tax_cat);
if (empty($range)) echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorRecordNotFound'), 'range' => $range));
else
{
$offset = price($range->offset, 0, $langs, 1, -1, -1, $conf->currency);
echo json_encode(array('up' => $range->coef, 'offset' => $range->offset, 'title' => $langs->transnoentitiesnoconv('ExpenseRangeOffset', $offset), 'comment' => 'offset should be apply on addline or updateline'));
}
}
}
}

View File

@@ -1058,31 +1058,18 @@ if (empty($reshook))
if ($action == "addline" && $user->rights->expensereport->creer)
{
$error = 0;
$db->begin();
$object_ligne = new ExpenseReportLine($db);
$vatrate = GETPOST('vatrate');
$object_ligne->comments = GETPOST('comments');
// if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary.
if (empty($vatrate)) $vatrate = "0.000";
$vatrate = price2num($vatrate);
$value_unit=price2num(GETPOST('value_unit'),'MU');
$fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat');
$qty = GETPOST('qty','int');
if (empty($qty)) $qty=1;
$object_ligne->qty = $qty;
$up=price2num(GETPOST('value_unit'),'MU');
$object_ligne->value_unit = $up;
$object_ligne->date = $date;
$object_ligne->fk_c_type_fees = GETPOST('fk_c_type_fees');
// if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary.
if (empty($vatrate)) $vatrate = "0.000";
$object_ligne->vatrate = price2num($vatrate);
$object_ligne->fk_projet = $fk_projet;
if (! GETPOST('fk_c_type_fees') > 0)
if (! $fk_c_type_fees > 0)
{
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
@@ -1107,44 +1094,54 @@ if (empty($reshook))
}*/
// Si aucune date n'est rentrée
if (empty($object_ligne->date) || $object_ligne->date=="--")
if (empty($date) || $date=="--")
{
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
}
// Si aucun prix n'est rentré
if($object_ligne->value_unit==0)
if($value_unit==0)
{
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PriceUTTC")), null, 'errors');
}
// S'il y'a eu au moins une erreur
if (! $error)
{
$object_ligne->fk_expensereport = $_POST['fk_expensereport'];
$type = 0; // TODO What if service ?
$seller = ''; // seller is unknown
$tmp = calcul_price_total($qty, $up, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller);
$object_ligne->vatrate = price2num($vatrate);
$object_ligne->total_ttc = $tmp[2];
$object_ligne->total_ht = $tmp[0];
$object_ligne->total_tva = $tmp[1];
// Insert line
$result = $object->addline($qty,$value_unit,$fk_c_type_fees,$vatrate,$date,$comments,$fk_projet,$fk_c_exp_tax_cat,$type);
if ($result > 0) {
$ret = $object->fetch($object->id); // Reload to get new records
$result = $object_ligne->insert();
if ($result > 0)
{
$db->commit();
header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
exit;
}
else
{
dol_print_error($db,$object->error);
$db->rollback();
}
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
// Define output language
$outputlangs = $langs;
$newlang = GETPOST('lang_id', 'alpha');
if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang))
$newlang = $object->thirdparty->default_lang;
if (! empty($newlang)) {
$outputlangs = new Translate("", $conf);
$outputlangs->setDefaultLang($newlang);
}
$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
}
unset($qty);
unset($value_unit);
unset($vatrate);
unset($comments);
unset($fk_c_type_fees);
unset($fk_projet);
unset($date);
} else {
setEventMessages($object->error, $object->errors, 'errors');
}
}
$action='';
@@ -1200,6 +1197,7 @@ if (empty($reshook))
$rowid = $_POST['rowid'];
$type_fees_id = GETPOST('fk_c_type_fees');
$fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat');
$projet_id = $fk_projet;
$comments = GETPOST('comments');
$qty = GETPOST('qty');
@@ -1226,7 +1224,7 @@ if (empty($reshook))
if (! $error)
{
// TODO Use update method of ExpenseReportLine
$result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $id);
$result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $id, $fk_c_exp_tax_cat);
if ($result >= 0)
{
if ($result > 0)
@@ -1922,17 +1920,6 @@ else
print '<div class="clearboth"></div><br>';
// Fetch Lines of current expense report
$sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_projet, fde.date,';
$sql.= ' fde.tva_tx as vatrate, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,';
$sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
$sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
$sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid';
$sql.= ' WHERE fde.fk_expensereport = '.$object->id;
$sql.= ' ORDER BY fde.date ASC';
print '<div style="clear: both;"></div>';
$actiontouse='updateligne';
@@ -1947,158 +1934,160 @@ else
print '<div class="div-table-responsive">';
print '<table id="tablelines" class="noborder" width="100%">';
$resql = $db->query($sql);
if ($resql)
if (!empty($object->lines))
{
$num_lignes = $db->num_rows($resql);
$i = 0;$total = 0;
if ($num_lignes)
print '<tr class="liste_titre">';
print '<td style="text-align:center;">'.$langs->trans('Piece').'</td>';
print '<td style="text-align:center;">'.$langs->trans('Date').'</td>';
if (! empty($conf->projet->enabled)) print '<td class="minwidth100imp">'.$langs->trans('Project').'</td>';
if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) print '<td>'.$langs->trans('CarCategory').'</td>';
print '<td style="text-align:center;">'.$langs->trans('Type').'</td>';
print '<td style="text-align:left;">'.$langs->trans('Description').'</td>';
print '<td style="text-align:right;">'.$langs->trans('VAT').'</td>';
print '<td style="text-align:right;">'.$langs->trans('PriceUTTC').'</td>';
print '<td style="text-align:right;">'.$langs->trans('Qty').'</td>';
if ($action != 'editline')
{
print '<tr class="liste_titre">';
print '<td style="text-align:center;">'.$langs->trans('Piece').'</td>';
print '<td style="text-align:center;">'.$langs->trans('Date').'</td>';
if (! empty($conf->projet->enabled)) print '<td class="minwidth100imp">'.$langs->trans('Project').'</td>';
print '<td style="text-align:center;">'.$langs->trans('Type').'</td>';
print '<td style="text-align:left;">'.$langs->trans('Description').'</td>';
print '<td style="text-align:right;">'.$langs->trans('VAT').'</td>';
print '<td style="text-align:right;">'.$langs->trans('PriceUTTC').'</td>';
print '<td style="text-align:right;">'.$langs->trans('Qty').'</td>';
if ($action != 'editline')
{
print '<td style="text-align:right;">'.$langs->trans('AmountHT').'</td>';
print '<td style="text-align:right;">'.$langs->trans('AmountTTC').'</td>';
}
// Ajout des boutons de modification/suppression
if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer)
{
print '<td style="text-align:right;"></td>';
}
print '</tr>';
print '<td style="text-align:right;">'.$langs->trans('AmountHT').'</td>';
print '<td style="text-align:right;">'.$langs->trans('AmountTTC').'</td>';
}
// Ajout des boutons de modification/suppression
if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer)
{
print '<td style="text-align:right;"></td>';
}
print '</tr>';
while ($i < $num_lignes)
{
$piece_comptable = $i + 1;
$objp = $db->fetch_object($resql);
foreach ($object->lines as &$line)
{
$piece_comptable = $i + 1;
if ($action != 'editline' || $objp->rowid != GETPOST('rowid'))
if ($action != 'editline' || $line->rowid != GETPOST('rowid'))
{
print '<tr class="oddeven">';
print '<td style="text-align:center;">';
print img_picto($langs->trans("Document"), "object_generic");
print ' <span>'.$piece_comptable.'</span></td>';
print '<td style="text-align:center;">'.dol_print_date($db->jdate($line->date), 'day').'</td>';
if (! empty($conf->projet->enabled))
{
print '<td>';
if ($line->fk_projet > 0)
{
$projecttmp->id=$line->fk_projet;
$projecttmp->ref=$line->projet_ref;
print $projecttmp->getNomUrl(1);
}
print '</td>';
}
if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
{
print '<td class="fk_c_exp_tax_cat">';
print dol_getIdFromCode($db, $line->fk_c_exp_tax_cat, 'c_exp_tax_cat', 'rowid', 'label');
print '</td>';
}
// print '<td style="text-align:center;">'.$langs->trans("TF_".strtoupper(empty($objp->type_fees_libelle)?'OTHER':$objp->type_fees_libelle)).'</td>';
print '<td style="text-align:center;">'.($langs->trans(($line->type_fees_code)) == $line->type_fees_code ? $line->type_fees_libelle : $langs->trans(($line->type_fees_code))).'</td>';
print '<td style="text-align:left;">'.$line->comments.'</td>';
print '<td style="text-align:right;">'.vatrate($line->vatrate,true).'</td>';
print '<td style="text-align:right;">'.price($line->value_unit).'</td>';
print '<td style="text-align:right;">'.$line->qty.'</td>';
if ($action != 'editline')
{
print '<td style="text-align:right;">'.price($line->total_ht).'</td>';
print '<td style="text-align:right;">'.price($line->total_ttc).'</td>';
}
// Ajout des boutons de modification/suppression
if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer)
{
print '<td style="text-align:right;" class="nowrap">';
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=editline&amp;rowid='.$line->rowid.'#'.$line->rowid.'">';
print img_edit();
print '</a> &nbsp; ';
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete_line&amp;rowid='.$line->rowid.'">';
print img_delete();
print '</a>';
print '</td>';
}
print '</tr>';
}
if ($action == 'editline' && $line->rowid == GETPOST('rowid'))
{
print '<tr class="oddeven">';
print '<td style="text-align:center;">';
print img_picto($langs->trans("Document"), "object_generic");
print ' <span>'.$piece_comptable.'</span></td>';
print '<td style="text-align:center;">'.dol_print_date($db->jdate($objp->date), 'day').'</td>';
print '<td></td>';
// Select date
print '<td class="center">';
$form->select_date($line->date,'date');
print '</td>';
// Select project
if (! empty($conf->projet->enabled))
{
print '<td>';
if ($objp->projet_id > 0)
{
$projecttmp->id=$objp->projet_id;
$projecttmp->ref=$objp->projet_ref;
print $projecttmp->getNomUrl(1);
}
print '</td>';
print '<td>';
$formproject->select_projects(-1, $line->fk_projet,'fk_projet', 0, 0, 1, 1);
print '</td>';
}
// print '<td style="text-align:center;">'.$langs->trans("TF_".strtoupper(empty($objp->type_fees_libelle)?'OTHER':$objp->type_fees_libelle)).'</td>';
print '<td style="text-align:center;">'.($langs->trans(($objp->type_fees_code)) == $objp->type_fees_code ? $objp->type_fees_libelle : $langs->trans(($objp->type_fees_code))).'</td>';
print '<td style="text-align:left;">'.$objp->comments.'</td>';
print '<td style="text-align:right;">'.vatrate($objp->vatrate,true).'</td>';
print '<td style="text-align:right;">'.price($objp->value_unit).'</td>';
print '<td style="text-align:right;">'.$objp->qty.'</td>';
if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
{
print '<td class="fk_c_exp_tax_cat">';
$params = array('fk_expense' => $object->id, 'fk_expense_det' => $line->rowid, 'date' => $line->dates);
print $form->selectExpenseCategories($line->fk_c_exp_tax_cat, 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params);
print '</td>';
}
// Select type
print '<td class="center">';
select_type_fees_id($line->fk_c_type_fees,'fk_c_type_fees');
print '</td>';
// Add comments
print '<td>';
print '<textarea name="comments" class="flat_ndf centpercent">'.$line->comments.'</textarea>';
print '</td>';
// VAT
print '<td style="text-align:right;">';
print $form->load_tva('vatrate', (isset($_POST["vatrate"])?$_POST["vatrate"]:$line->vatrate), $mysoc, '');
print '</td>';
// Unit price
print '<td style="text-align:right;">';
print '<input type="text" min="0" class="maxwidth100" name="value_unit" value="'.$line->value_unit.'" />';
print '</td>';
// Quantity
print '<td style="text-align:right;">';
print '<input type="number" min="0" class="maxwidth100" name="qty" value="'.$line->qty.'" />';
print '</td>';
if ($action != 'editline')
{
print '<td style="text-align:right;">'.price($objp->total_ht).'</td>';
print '<td style="text-align:right;">'.price($objp->total_ttc).'</td>';
print '<td style="text-align:right;">'.$langs->trans('AmountHT').'</td>';
print '<td style="text-align:right;">'.$langs->trans('AmountTTC').'</td>';
}
// Ajout des boutons de modification/suppression
if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer)
{
print '<td style="text-align:right;" class="nowrap">';
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=editline&amp;rowid='.$objp->rowid.'#'.$objp->rowid.'">';
print img_edit();
print '</a> &nbsp; ';
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete_line&amp;rowid='.$objp->rowid.'">';
print img_delete();
print '</a>';
print '</td>';
}
print '</tr>';
}
if ($action == 'editline' && $objp->rowid == GETPOST('rowid'))
{
print '<tr class="oddeven">';
print '<td></td>';
// Select date
print '<td class="center">';
$form->select_date($objp->date,'date');
print '</td>';
// Select project
if (! empty($conf->projet->enabled))
{
print '<td>';
$formproject->select_projects(-1, $objp->fk_projet,'fk_projet', 0, 0, 1, 1);
print '</td>';
}
// Select type
print '<td class="center">';
select_type_fees_id($objp->type_fees_code,'fk_c_type_fees');
print '</td>';
// Add comments
print '<td>';
print '<textarea name="comments" class="flat_ndf centpercent">'.$objp->comments.'</textarea>';
print '</td>';
// VAT
print '<td style="text-align:right;">';
print $form->load_tva('vatrate', (isset($_POST["vatrate"])?$_POST["vatrate"]:$objp->vatrate), $mysoc, '');
print '</td>';
// Unit price
print '<td style="text-align:right;">';
print '<input type="text" min="0" class="maxwidth100" name="value_unit" value="'.$objp->value_unit.'" />';
print '</td>';
// Quantity
print '<td style="text-align:right;">';
print '<input type="number" min="0" class="maxwidth100" name="qty" value="'.$objp->qty.'" />';
print '</td>';
if ($action != 'editline')
{
print '<td style="text-align:right;">'.$langs->trans('AmountHT').'</td>';
print '<td style="text-align:right;">'.$langs->trans('AmountTTC').'</td>';
}
print '<td style="text-align:center;">';
print '<input type="hidden" name="rowid" value="'.$objp->rowid.'">';
print '<input type="submit" class="button" name="save" value="'.$langs->trans('Save').'">';
print '<br /><input type="submit" class="button" name="cancel" value="'.$langs->trans('Cancel').'">';
print '</td>';
}
$i++;
print '<td style="text-align:center;">';
print '<input type="hidden" name="rowid" value="'.$line->rowid.'">';
print '<input type="submit" class="button" name="save" value="'.$langs->trans('Save').'">';
print '<br /><input type="submit" class="button" name="cancel" value="'.$langs->trans('Cancel').'">';
print '</td>';
}
$db->free($resql);
}
else
{
/* print '<table width="100%">';
print '<tr><td><div class="error" style="display:block;">'.$langs->trans("AucuneLigne").'</div></td></tr>';
print '</table>';*/
$i++;
}
//print '</div>';
// Add a line
@@ -2108,6 +2097,7 @@ else
print '<td></td>';
print '<td align="center">'.$langs->trans('Date').'</td>';
if (! empty($conf->projet->enabled)) print '<td class="minwidth100imp">'.$langs->trans('Project').'</td>';
if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) print '<td>'.$langs->trans('CarCategory').'</td>';
print '<td align="center">'.$langs->trans('Type').'</td>';
print '<td>'.$langs->trans('Description').'</td>';
print '<td align="right">'.$langs->trans('VAT').'</td>';
@@ -2133,6 +2123,14 @@ else
$formproject->select_projects(-1, $fk_projet, 'fk_projet', 0, 0, 1, 1);
print '</td>';
}
if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
{
print '<td class="fk_c_exp_tax_cat">';
$params = array('fk_expense' => $object->id);
print $form->selectExpenseCategories('', 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params);
print '</td>';
}
// Select type
print '<td align="center">';
@@ -2350,6 +2348,8 @@ if ($action != 'create' && $action != 'edit')
print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&id='.$object->id.'">'.$langs->trans('Delete').'</a></div>';
}
$parameters = array();
$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
}
print '</div>';

View File

@@ -24,6 +24,8 @@
* \brief File to manage Expense Reports
*/
require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
require_once DOL_DOCUMENT_ROOT .'/expensereport/class/expensereport_ik.class.php';
require_once DOL_DOCUMENT_ROOT .'/expensereport/class/expensereport_rule.class.php';
/**
* Class to manage Trips and Expenses
@@ -91,9 +93,35 @@ class ExpenseReport extends CommonObject
/*
END ACTIONS
*/
/**
* Draft
*/
const STATUS_DRAFT = 0;
/**
* Validated (need to be paid)
*/
const STATUS_VALIDATED = 2;
/**
/**
* Classified approved
*/
const STATUS_APPROVED = 5;
/**
* Classified refused
*/
const STATUS_REFUSED = 99;
/**
* Classified paid.
*/
const STATUS_CLOSED = 6;
/**
* Constructor
*
* @param DoliDB $db Handler acces base de donnees
@@ -911,7 +939,7 @@ class ExpenseReport extends CommonObject
$this->lines=array();
$sql = ' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date,';
$sql.= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_projet, de.tva_tx,';
$sql.= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet, de.tva_tx,';
$sql.= ' de.total_ht, de.total_tva, de.total_ttc,';
$sql.= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,';
$sql.= ' p.ref as ref_projet, p.title as title_projet';
@@ -933,13 +961,16 @@ class ExpenseReport extends CommonObject
$deplig = new ExpenseReportLine($this->db);
$deplig->rowid = $objp->rowid;
$deplig->id = $objp->id;
$deplig->comments = $objp->comments;
$deplig->qty = $objp->qty;
$deplig->value_unit = $objp->value_unit;
$deplig->date = $objp->date;
$deplig->dates = $this->db->jdate($objp->date);
$deplig->fk_expensereport = $objp->fk_expensereport;
$deplig->fk_c_type_fees = $objp->fk_c_type_fees;
$deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
$deplig->fk_projet = $objp->fk_projet;
$deplig->total_ht = $objp->total_ht;
@@ -1570,7 +1601,244 @@ class ExpenseReport extends CommonObject
endif;
}
/**
* addline
*
* @param real $qty Qty
* @param double $up Value init
* @param int $fk_c_type_fees Type payment
* @param double $vatrate Vat rate
* @param string $date Date
* @param string $comments Description
* @param int $fk_project Project id
* @param int $fk_c_exp_tax_cat Car category id
* @param int $type Type line
* @return int <0 if KO, >0 if OK
*/
function addline($qty=0, $up=0, $fk_c_type_fees=0, $vatrate=0, $date='', $comments='', $fk_project=0, $fk_c_exp_tax_cat=0, $type=0)
{
global $conf,$langs;
dol_syslog(get_class($this)."::addline qty=$qty, up=$up, fk_c_type_fees=$fk_c_type_fees, vatrate=$vatrate, date=$date, fk_project=$fk_project, type=$type, comments=$comments", LOG_DEBUG);
if (empty($qty)) $qty = 0;
if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) $fk_c_type_fees = 0;
if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) $fk_c_exp_tax_cat = 0;
if (empty($vatrate) || $vatrate < 0) $vatrate = 0;
if (empty($date)) $date = '';
if (empty($fk_project)) $fk_project = 0;
$qty = price2num($qty);
$vatrate = price2num($vatrate);
$up = price2num($up);
if ($this->fk_statut == self::STATUS_DRAFT)
{
$this->db->begin();
$this->line = new ExpenseReportLine($this->db);
$seller = ''; // seller is unknown
$tmp = calcul_price_total($qty, $up, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller);
$this->line->value_unit = $up;
$this->line->vatrate = price2num($vatrate);
$this->line->total_ttc = $tmp[2];
$this->line->total_ht = $tmp[0];
$this->line->total_tva = $tmp[1];
$this->line->fk_expensereport = $this->id;
$this->line->qty = $qty;
$this->line->date = $date;
$this->line->fk_c_type_fees = $fk_c_type_fees;
$this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
$this->line->comments = $comments;
$this->line->fk_projet = $fk_project;
$this->applyOffset();
$this->checkRules($type, $seller);
$result=$this->line->insert(0, true);
if ($result > 0)
{
$result=$this->update_price(); // This method is designed to add line from user input so total calculation must be done using 'auto' mode.
if ($result > 0)
{
$this->db->commit();
return $this->line->rowid;
}
else
{
$this->db->rollback();
return -1;
}
}
else
{
$this->error=$this->line->error;
dol_syslog(get_class($this)."::addline error=".$this->error, LOG_ERR);
$this->db->rollback();
return -2;
}
}
else
{
dol_syslog(get_class($this)."::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
$this->error = 'ErrorExpenseNotDraft';
return -3;
}
}
/**
* Check constraint of rules and update price if needed
*
* @param int $type type of line
* @param string $seller seller, but actually he is unknown
* @return true or false
*/
function checkRules($type=0, $seller='')
{
global $user,$conf,$db,$langs;
$langs->load('trips');
if (empty($conf->global->MAIN_USE_EXPENSE_RULE)) return true; // if don't use rules
$rulestocheck = ExpenseReportRule::getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
$violation = 0;
$rule_warning_message_tab = array();
$current_total_ttc = $this->line->total_ttc;
$new_current_total_ttc = $this->line->total_ttc;
// check if one is violated
foreach ($rulestocheck as $rule)
{
if (in_array($rule->code_expense_rules_type, array('EX_DAY', 'EX_MON', 'EX_YEA'))) $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
else $amount_to_test = $current_total_ttc; // EX_EXP
$amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc; // if amount as been modified by a previous rule
if ($amount_to_test > $rule->amount)
{
$violation++;
if ($rule->restrictive)
{
$this->error = 'ExpenseReportConstraintViolationError';
$this->errors[] = $this->error;
$new_current_total_ttc -= $amount_to_test - $rule->amount; // ex, entered 16€, limit 12€, subtracts 4€;
$rule_warning_message_tab[] = $langs->trans('ExpenseReportConstraintViolationError', $rule->id, price($amount_to_test,0,$langs,1,-1,-1,$conf->currency), price($rule->amount,0,$langs,1,-1,-1,$conf->currency), $langs->trans('by'.$rule->code_expense_rules_type, price($new_current_total_ttc,0,$langs,1,-1,-1,$conf->currency)));
}
else
{
$this->error = 'ExpenseReportConstraintViolationWarning';
$this->errors[] = $this->error;
$rule_warning_message_tab[] = $langs->trans('ExpenseReportConstraintViolationWarning', $rule->id, price($amount_to_test,0,$langs,1,-1,-1,$conf->currency), price($rule->amount,0,$langs,1,-1,-1,$conf->currency), $langs->trans('nolimitby'.$rule->code_expense_rules_type));
}
// No break, we sould test if another rule is violated
}
}
$this->line->rule_warning_message = implode('\n', $rule_warning_message_tab);
if ($violation > 0)
{
$tmp = calcul_price_total($this->line->qty, $new_current_total_ttc/$this->line->qty, 0, $this->line->vatrate, 0, 0, 0, 'TTC', 0, $type, $seller);
$this->line->value_unit = $tmp[5];
$this->line->total_ttc = $tmp[2];
$this->line->total_ht = $tmp[0];
$this->line->total_tva = $tmp[1];
return false;
}
else return true;
}
/**
* Method to apply the offset if needed
*
* @return boolean true=applied, false=not applied
*/
function applyOffset()
{
global $conf;
if (empty($conf->global->MAIN_USE_EXPENSE_IK)) return false;
$userauthor = new User($this->db);
if ($userauthor->fetch($this->fk_user_author) <= 0)
{
$this->error = 'ErrorCantFetchUser';
$this->errors[] = 'ErrorCantFetchUser';
return false;
}
$range = ExpenseReportIk::getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
if (empty($range))
{
$this->error = 'ErrorNoRangeAvailable';
$this->errors[] = 'ErrorNoRangeAvailable';
return false;
}
if (!empty($conf->global->MAIN_EXPENSE_APPLY_ENTIRE_OFFSET)) $offset = $range->offset;
else $offset = $range->offset / 12; // The amount of offset is a global value for the year
// Test if offset has been applied for the current month
if (!$this->offsetAlreadyGiven())
{
$new_up = $range->coef + ($offset / $this->line->qty);
$tmp = calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0, 'TTC', 0, $type, $seller);
$this->line->value_unit = $tmp[5];
$this->line->total_ttc = $tmp[2];
$this->line->total_ht = $tmp[0];
$this->line->total_tva = $tmp[1];
return true;
}
return false;
}
/**
* If the sql find any rows then the offset is already given (offset is applied at the first expense report line)
*
* @return bool
*/
function offsetAlreadyGiven()
{
$sql = 'SELECT e.rowid FROM '.MAIN_DB_PREFIX.'expensereport e';
$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'expensereport_det d ON (e.rowid = d.fk_expensereport)';
$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = "EX_KME")';
$sql.= ' WHERE e.fk_user_author = '.(int) $this->fk_user_author;
$sql.= ' AND YEAR(d.date) = "'.dol_print_date($this->line->date, '%Y').'" AND MONTH(d.date) = "'.dol_print_date($this->line->date, '%m').'"';
if (!empty($this->line->id)) $sql.= ' AND d.rowid <> '.$this->line->id;
dol_syslog(get_class($this)."::offsetAlreadyGiven sql=".$sql);
$resql = $this->db->query($sql);
if ($resql)
{
$num = $this->db->num_rows($resql);
if ($num > 0) return true;
}
else
{
dol_print_error($this->db);
}
return false;
}
/**
* updateline
*
@@ -1583,9 +1851,10 @@ class ExpenseReport extends CommonObject
* @param double $value_unit Value init
* @param int $date Date
* @param int $expensereport_id Expense report id
* @param int $fk_c_exp_tax_cat id of category of car
* @return int <0 if KO, >0 if OK
*/
function updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id)
function updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id, $fk_c_exp_tax_cat=0)
{
global $user;
@@ -1603,21 +1872,23 @@ class ExpenseReport extends CommonObject
$total_tva = price2num($total_ttc - $total_ht, 'MT');
// fin calculs
$ligne = new ExpenseReportLine($this->db);
$ligne->comments = $comments;
$ligne->qty = $qty;
$ligne->value_unit = $value_unit;
$ligne->date = $date;
$this->line = new ExpenseReportLine($this->db);
$this->line->comments = $comments;
$this->line->qty = $qty;
$this->line->value_unit = $value_unit;
$this->line->date = $date;
$ligne->fk_expensereport= $expensereport_id;
$ligne->fk_c_type_fees = $type_fees_id;
$ligne->fk_projet = $projet_id;
$this->line->fk_expensereport= $expensereport_id;
$this->line->fk_c_type_fees = $type_fees_id;
$this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
$this->line->fk_projet = $projet_id;
$ligne->total_ht = $total_ht;
$ligne->total_tva = $total_tva;
$ligne->total_ttc = $total_ttc;
$ligne->vatrate = price2num($vatrate);
$ligne->rowid = $rowid;
$this->line->total_ht = $total_ht;
$this->line->total_tva = $total_tva;
$this->line->total_ttc = $total_ttc;
$this->line->vatrate = price2num($vatrate);
$this->line->rowid = $rowid;
$this->line->id = $rowid;
// Select des infos sur le type fees
$sql = "SELECT c.code as code_type_fees, c.label as libelle_type_fees";
@@ -1625,8 +1896,8 @@ class ExpenseReport extends CommonObject
$sql.= " WHERE c.id = ".$type_fees_id;
$result = $this->db->query($sql);
$objp_fees = $this->db->fetch_object($result);
$ligne->type_fees_code = $objp_fees->code_type_fees;
$ligne->type_fees_libelle = $objp_fees->libelle_type_fees;
$this->line->type_fees_code = $objp_fees->code_type_fees;
$this->line->type_fees_libelle = $objp_fees->libelle_type_fees;
// Select des informations du projet
$sql = "SELECT p.ref as ref_projet, p.title as title_projet";
@@ -1636,10 +1907,13 @@ class ExpenseReport extends CommonObject
if ($result) {
$objp_projet = $this->db->fetch_object($result);
}
$ligne->projet_ref = $objp_projet->ref_projet;
$ligne->projet_title = $objp_projet->title_projet;
$this->line->projet_ref = $objp_projet->ref_projet;
$this->line->projet_title = $objp_projet->title_projet;
$result = $ligne->update($user);
$this->applyOffset();
$this->checkRules();
$result = $this->line->update($user);
if ($result > 0)
{
$this->db->commit();
@@ -1647,8 +1921,8 @@ class ExpenseReport extends CommonObject
}
else
{
$this->error=$ligne->error;
$this->errors=$ligne->errors;
$this->error=$this->line->error;
$this->errors=$this->line->errors;
$this->db->rollback();
return -2;
}
@@ -1992,6 +2266,7 @@ class ExpenseReportLine
var $date;
var $fk_c_type_fees;
var $fk_c_exp_tax_cat;
var $fk_projet;
var $fk_expensereport;
@@ -2024,7 +2299,7 @@ class ExpenseReportLine
*/
function fetch($rowid)
{
$sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_projet, fde.date,';
$sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_c_exp_tax_cat, fde.fk_projet, fde.date,';
$sql.= ' fde.tva_tx as vatrate, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,';
$sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
$sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
@@ -2046,8 +2321,10 @@ class ExpenseReportLine
$this->comments = $objp->comments;
$this->qty = $objp->qty;
$this->date = $objp->date;
$this->dates = $this->db->jdate($objp->date);
$this->value_unit = $objp->value_unit;
$this->fk_c_type_fees = $objp->fk_c_type_fees;
$this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
$this->fk_projet = $objp->fk_projet;
$this->type_fees_code = $objp->type_fees_code;
$this->type_fees_libelle = $objp->type_fees_libelle;
@@ -2068,9 +2345,10 @@ class ExpenseReportLine
* insert
*
* @param int $notrigger 1=No trigger
* @param bool $fromaddline false=keep default behavior, true=exclude the update_price() of parent object
* @return int <0 if KO, >0 if OK
*/
function insert($notrigger=0)
function insert($notrigger=0,$fromaddline=false)
{
global $langs,$user,$conf;
@@ -2083,12 +2361,13 @@ class ExpenseReportLine
if (!$this->value_unit_HT) $this->value_unit_HT=0;
$this->qty = price2num($this->qty);
$this->vatrate = price2num($this->vatrate);
if (empty($this->fk_c_exp_tax_cat)) $this->fk_c_exp_tax_cat = 0;
$this->db->begin();
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'expensereport_det';
$sql.= ' (fk_expensereport, fk_c_type_fees, fk_projet,';
$sql.= ' tva_tx, comments, qty, value_unit, total_ht, total_tva, total_ttc, date)';
$sql.= ' tva_tx, comments, qty, value_unit, total_ht, total_tva, total_ttc, date, rule_warning_message, fk_c_exp_tax_cat)';
$sql.= " VALUES (".$this->fk_expensereport.",";
$sql.= " ".$this->fk_c_type_fees.",";
$sql.= " ".($this->fk_projet>0?$this->fk_projet:'null').",";
@@ -2099,7 +2378,9 @@ class ExpenseReportLine
$sql.= " ".$this->total_ht.",";
$sql.= " ".$this->total_tva.",";
$sql.= " ".$this->total_ttc.",";
$sql.= "'".$this->db->idate($this->date)."'";
$sql.= "'".$this->db->idate($this->date)."',";
$sql.= " '".$this->db->escape($this->rule_warning_message)."',";
$sql.= " ".$this->fk_c_exp_tax_cat;
$sql.= ")";
dol_syslog("ExpenseReportLine::insert sql=".$sql);
@@ -2109,16 +2390,23 @@ class ExpenseReportLine
{
$this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'expensereport_det');
$tmpparent=new ExpenseReport($this->db);
$tmpparent->fetch($this->fk_expensereport);
$result = $tmpparent->update_price();
if ($result < 0)
{
$error++;
$this->error = $tmpparent->error;
$this->errors = $tmpparent->errors;
}
if (! $fromaddline)
{
$tmpparent=new ExpenseReport($this->db);
$tmpparent->fetch($this->fk_expensereport);
$result = $tmpparent->update_price();
if ($result < 0)
{
$error++;
$this->error = $tmpparent->error;
$this->errors = $tmpparent->errors;
}
}
}
else
{
$error++;
}
if (! $error)
{
@@ -2133,7 +2421,50 @@ class ExpenseReportLine
return -2;
}
}
/**
* Function to get total amount in expense reports for a same rule
*
* @param ExpenseReportRule $rule object rule to check
* @param int $fk_user user author id
* @param string $mode day|EX_DAY / month|EX_MON / year|EX_YEA to get amount
* @return amount
*/
public function getExpAmount(ExpenseReportRule $rule, $fk_user, $mode='day')
{
$amount = 0;
$sql = 'SELECT SUM(d.total_ttc) as total_amount';
$sql .= ' FROM '.MAIN_DB_PREFIX.'expensereport_det d';
$sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'expensereport e ON (d.fk_expensereport = e.rowid)';
$sql .= ' WHERE e.fk_user_author = '.$fk_user;
if (!empty($this->id)) $sql.= ' AND d.rowid <> '.$this->id;
$sql .= ' AND d.fk_c_type_fees = '.$rule->fk_c_type_fees;
if ($mode == 'day' || $mode == 'EX_DAY') $sql .= ' AND d.date = \''.dol_print_date($this->date, '%Y-%m-%d').'\'';
elseif ($mode == 'mon' || $mode == 'EX_MON') $sql .= ' AND DATE_FORMAT(d.date, \'%Y-%m\') = \''.dol_print_date($this->date, '%Y-%m').'\'';
elseif ($mode == 'year' || $mode == 'EX_YEA') $sql .= ' AND DATE_FORMAT(d.date, \'%Y\') = \''.dol_print_date($this->date, '%Y').'\'';
dol_syslog('ExpenseReportLine::getExpAmountByDay sql='.$sql);
$resql = $this->db->query($sql);
if ($resql)
{
$num = $this->db->num_rows($resql);
if ($num > 0)
{
$obj = $this->db->fetch_object($resql);
$amount = (double) $obj->total_amount;
}
}
else
{
dol_print_error($this->db);
}
return $amount + $this->total_ttc;
}
/**
* update
*
@@ -2150,6 +2481,7 @@ class ExpenseReportLine
$this->comments=trim($this->comments);
$this->vatrate = price2num($this->vatrate);
$this->value_unit = price2num($this->value_unit);
if (empty($this->fk_c_exp_tax_cat)) $this->fk_c_exp_tax_cat = 0;
$this->db->begin();
@@ -2163,6 +2495,8 @@ class ExpenseReportLine
$sql.= ",total_tva=".$this->total_tva."";
$sql.= ",total_ttc=".$this->total_ttc."";
$sql.= ",tva_tx=".$this->vatrate;
$sql.= ",rule_warning_message='".$this->db->escape($this->rule_warning_message)."'";
$sql.= ",fk_c_exp_tax_cat=".$this->fk_c_exp_tax_cat;
if ($this->fk_c_type_fees) $sql.= ",fk_c_type_fees=".$this->fk_c_type_fees;
else $sql.= ",fk_c_type_fees=null";
if ($this->fk_projet) $sql.= ",fk_projet=".$this->fk_projet;

View File

@@ -0,0 +1,248 @@
<?php
/* Copyright (C) 2017 ATM Consulting <support@atm-consulting.fr>
* Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/expensereport/class/expensereport_ik.class.php
* \ingroup expenseik
* \brief File of class to manage expense ik
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/coreobject.class.php';
/**
* Class to manage inventories
*/
class ExpenseReportIk extends CoreObject
{
public $element='expenseik';
public $table_element='expensereport_ik';
public $fk_element='fk_expense_ik';
/**
* c_exp_tax_cat Id
* @var int
*/
public $fk_cat;
/**
* c_exp_tax_range id
* @var int
*/
public $fk_range;
/**
* Coef
* @var double
*/
public $coef;
/**
* Offset
* @var double
*/
public $offset;
/**
* Attribute object linked with database
* @var array
*/
protected $fields=array(
'fk_cat'=>array('type'=>'integer','index'=>true)
,'fk_range'=>array('type'=>'integer','index'=>true)
,'coef'=>array('type'=>'double')
,'offset'=>array('type'=>'double')
);
/**
* Constructor
*
* @param DoliDB $db Database handler
*/
public function __construct(DoliDB &$db)
{
global $conf;
parent::__construct($db);
parent::init();
$this->errors = array();
}
/**
* Return expense categories in array
*
* @param int $mode 1=only active; 2=only inactive; other value return all
* @return array of category
*/
public static function getTaxCategories($mode=1)
{
global $db;
$categories = array();
$sql = 'SELECT rowid, label, entity, active';
$sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat';
$sql.= ' WHERE entity IN (0,'. getEntity('').')';
if ($mode == 1) $sql.= ' AND active = 1';
elseif ($mode == 2) $sql.= 'AND active = 0';
dol_syslog(get_called_class().'::getTaxCategories sql='.$sql, LOG_DEBUG);
$resql = $db->query($sql);
if ($resql)
{
while ($obj = $db->fetch_object($resql))
{
$categories[$obj->rowid] = $obj;
}
}
else
{
dol_print_error($db);
}
return $categories;
}
public static function getRangeByUser(User $userauthor, $fk_c_exp_tax_cat)
{
$default_range = (int) $userauthor->default_range; // if not defined, then 0
$ranges = self::getRangesByCategory($fk_c_exp_tax_cat);
// substract 1 because array start from 0
if (empty($ranges) || !isset($ranges[$default_range-1])) return false;
else return $ranges[$default_range-1];
}
/**
* Return an array of ranges for a category
*
* @param int $fk_c_exp_tax_cat category id
* @param int $active active
* @return array
*/
public static function getRangesByCategory($fk_c_exp_tax_cat, $active=1)
{
global $db;
$ranges = array();
$sql = 'SELECT r.rowid FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
if ($active) $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_cat = c.rowid)';
$sql.= ' WHERE r.fk_cat = '.$fk_c_exp_tax_cat;
if ($active) $sql.= ' AND r.active = 1 AND c.active = 1';
$sql.= ' ORDER BY r.range';
dol_syslog(get_called_class().'::getRangesByCategory sql='.$sql, LOG_DEBUG);
$resql = $db->query($sql);
if ($resql)
{
$num = $db->num_rows($resql);
if ($num > 0)
{
while ($obj = $db->fetch_object($resql))
{
$object = new ExpenseReportIk($db);
$object->fetch($obj->rowid);
$ranges[] = $object;
}
}
}
else
{
dol_print_error($db);
}
return $ranges;
}
/**
* Return an array of ranges grouped by category
*
* @return array
*/
public static function getAllRanges()
{
global $db;
$ranges = array();
$sql = ' SELECT r.rowid, r.fk_cat, r.range, c.label, i.rowid as fk_expense_ik, r.active as range_active, c.active as cat_active';
$sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_cat = c.rowid)';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport_ik i ON (r.rowid = i.fk_range)';
$sql.= ' WHERE r.entity IN (0, '. getEntity('').')';
$sql.= ' ORDER BY r.fk_cat, r.range';
dol_syslog(get_called_class().'::getAllRanges sql='.$sql, LOG_DEBUG);
$resql = $db->query($sql);
if ($resql)
{
while ($obj = $db->fetch_object($resql))
{
$ik = new ExpenseReportIk($db);
if ($obj->fk_expense_ik > 0) $ik->fetch($obj->fk_expense_ik);
$obj->ik = $ik;
if (!isset($ranges[$obj->fk_cat])) $ranges[$obj->fk_cat] = array('label' => $obj->label, 'active' => $obj->cat_active, 'ranges' => array());
$ranges[$obj->fk_cat]['ranges'][] = $obj;
}
}
else
{
dol_print_error($db);
}
return $ranges;
}
/**
* Return the max number of range by a category
*
* @param int $default_c_exp_tax_cat id
* @return int
*/
public static function getMaxRangeNumber($default_c_exp_tax_cat=0)
{
global $db,$conf;
$sql = 'SELECT MAX(counted) as nbRange FROM (';
$sql.= ' SELECT COUNT(*) as counted';
$sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
$sql.= ' WHERE r.entity IN (0, '.$conf->entity.')';
if ($default_c_exp_tax_cat > 0) $sql .= ' AND r.fk_cat = '.$default_c_exp_tax_cat;
$sql.= ' GROUP BY r.fk_cat';
$sql .= ') as counts';
dol_syslog(get_called_class().'::getMaxRangeNumber sql='.$sql, LOG_DEBUG);
$resql = $db->query($sql);
if ($resql)
{
$obj = $db->fetch_object($resql);
return $obj->nbRange;
}
else
{
dol_print_error($db);
}
return 0;
}
}

View File

@@ -0,0 +1,236 @@
<?php
/* Copyright (C) 2017 ATM Consulting <support@atm-consulting.fr>
* Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/expensereport/class/expensereport_ik.class.php
* \ingroup expenseik
* \brief File of class to manage expense ik
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/coreobject.class.php';
/**
* Class to manage inventories
*/
class ExpenseReportRule extends CoreObject
{
public $element='expenserule';
public $table_element='expensereport_rules';
public $fk_element='fk_expense_rule';
/**
* date start
* @var date
*/
public $dates;
/**
* date end
* @var date
*/
public $datee;
/**
* amount
* @var double
*/
public $amount;
/**
* restrective
* @var int
*/
public $restrictive;
/**
* rule for user
* @var int
*/
public $fk_user;
/**
* rule for group
* @var int
*/
public $fk_usergroup;
/**
* c_type_fees id
* @var int
*/
public $fk_c_type_fees;
/**
* code type of expense report
* @var string
*/
public $code_expense_rules_type;
/**
* rule for all
* @var int
*/
public $is_for_all;
/**
* entity
* @var int
*/
public $entity;
/**
* Attribute object linked with database
* @var array
*/
protected $fields=array(
'dates'=>array('type'=>'date')
,'datee'=>array('type'=>'date')
,'amount'=>array('type'=>'double')
,'restrictive'=>array('type'=>'integer')
,'fk_user'=>array('type'=>'integer')
,'fk_usergroup'=>array('type'=>'integer')
,'fk_c_type_fees'=>array('type'=>'integer')
,'code_expense_rules_type'=>array('type'=>'string')
,'is_for_all'=>array('type'=>'integer')
,'entity'=>array('type'=>'integer')
);
/**
* Constructor
*
* @param DoliDB $db Database handler
*/
public function __construct(DoliDB &$db)
{
global $conf;
parent::__construct($db);
parent::init();
$this->errors = array();
}
/**
* Return all rules or filtered by something
*
* @param int $fk_c_type_fees type of expense
* @param date $date date of expense
* @param type $fk_user user of expense
* @return array \ExpenseReportRule
*/
public static function getAllRule($fk_c_type_fees='', $date='', $fk_user='')
{
global $db;
$rules = array();
$sql = 'SELECT er.rowid';
$sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_rules er';
$sql.= ' WHERE er.entity IN (0,'. getEntity('').')';
if (!empty($fk_c_type_fees))
{
$sql.= ' AND er.fk_c_type_fees IN (-1, '.$fk_c_type_fees.')';
}
if (!empty($date))
{
$date = dol_print_date($date, '%Y-%m-%d');
$sql.= ' AND er.dates <= \''.$date.'\'';
$sql.= ' AND er.datee >= \''.$date.'\'';
}
if ($fk_user > 0)
{
$sql.= ' AND (er.is_for_all = 1';
$sql.= ' OR er.fk_user = '.$fk_user;
$sql.= ' OR er.fk_usergroup IN (SELECT ugu.fk_usergroup FROM '.MAIN_DB_PREFIX.'usergroup_user ugu WHERE ugu.fk_user = '.$fk_user.') )';
}
$sql.= ' ORDER BY er.is_for_all, er.fk_usergroup, er.fk_user';
dol_syslog("ExpenseReportRule::getAllRule sql=".$sql);
$resql = $db->query($sql);
if ($resql)
{
while ($obj = $db->fetch_object($resql))
{
$rule = new ExpenseReportRule($db);
if ($rule->fetch($obj->rowid) > 0) $rules[$rule->id] = $rule;
else dol_print_error($db);
}
}
else
{
dol_print_error($db);
}
return $rules;
}
/**
* Return the label of group for the current object
*
* @return string
*/
public function getGroupLabel()
{
include_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
if ($this->fk_usergroup > 0)
{
$group = new UserGroup($this->db);
if ($group->fetch($this->fk_usergroup) > 0)
{
return $group->nom;
}
else
{
$this->error = $group->error;
$this->errors[] = $this->error;
}
}
return '';
}
/**
* Return the name of user for the current object
*
* @return string
*/
public function getUserName()
{
include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
if ($this->fk_user > 0)
{
$u = new User($this->db);
if ($u->fetch($this->fk_user) > 0)
{
return dolGetFirstLastname($u->firstname, $u->lastname);
}
else
{
$this->error = $u->error;
$this->errors[] = $this->error;
}
}
return '';
}
}

View File

@@ -0,0 +1,56 @@
-- Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
-- Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--
--
-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors
-- de l'install et tous les sigles '--' sont supprimés.
--
--
-- Categories expense
--
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (1,'ExpAutoCat', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (2,'ExpCycloCat', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (3,'ExpMotoCat', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (4,'ExpAuto3CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (5,'ExpAuto4CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (6,'ExpAuto5CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (7,'ExpAuto6CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (8,'ExpAuto7CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (9,'ExpAuto8CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (10,'ExpAuto9CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (11,'ExpAuto10CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (12,'ExpAuto11CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (13,'ExpAuto12CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (14,'ExpAuto3PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (15,'ExpAuto4PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (16,'ExpAuto5PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (17,'ExpAuto6PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (18,'ExpAuto7PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (19,'ExpAuto8PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (20,'ExpAuto9PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (21,'ExpAuto10PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (22,'ExpAuto11PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (23,'ExpAuto12PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (24,'ExpAuto13PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (25,'ExpCyclo', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (26,'ExpMoto12CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (27,'ExpMoto345CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (28,'ExpMoto5PCV', 1, 1);

View File

@@ -0,0 +1,47 @@
-- Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
-- Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--
--
-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors
-- de l'install et tous les sigles '--' sont supprimés.
--
--
-- Range expense
--
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (1,4, 0, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (2,4, 5000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (3,4, 20000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (4,5, 0, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (5,5, 5000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (6,5, 20000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (7,6, 0, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (8,6, 5000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (9,6, 20000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (10,7, 0, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (11,7, 5000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (12,7, 20000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (13,8, 0, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (14,8, 5000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (15,8, 20000, 1, 1);

View File

@@ -5,6 +5,8 @@
-- Copyright (C) 2004 Guillaume Delecourt <guillaume.delecourt@opensides.be>
-- Copyright (C) 2005-2009 Regis Houssin <regis.houssin@capnetworks.com>
-- Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com>
-- Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
-- Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
@@ -33,3 +35,27 @@
insert into llx_c_type_fees (code,label,active) values ('TF_OTHER', 'Other', 1);
insert into llx_c_type_fees (code,label,active) values ('TF_TRIP', 'Transportation', 1);
insert into llx_c_type_fees (code,label,active) values ('TF_LUNCH', 'Lunch', 1);
INSERT INTO llx_c_type_fees (code, label, active, accountancy_code) VALUES
('EX_KME', 'ExpLabelKm', 0, '625100'),
('EX_FUE', 'ExpLabelFuelCV', 0, '606150'),
('EX_HOT', 'ExpLabelHotel', 0, '625160'),
('EX_PAR', 'ExpLabelParkingCV', 0, '625160'),
('EX_TOL', 'ExpLabelTollCV', 0, '625160'),
('EX_TAX', 'ExpLabelVariousTaxes', 0, '637800'),
('EX_IND', 'ExpLabelIndemnityTransportationSubscription', 0, '648100'),
('EX_SUM', 'ExpLabelMaintenanceSupply', 0, '606300'),
('EX_SUO', 'ExpLabelOfficeSupplies', 0, '606400'),
('EX_CAR', 'ExpLabelCarRental', 0, '613000'),
('EX_DOC', 'ExpLabelDocumentation', 0, '618100'),
('EX_CUR', 'ExpLabelCustomersReceiving', 0, '625710'),
('EX_OTR', 'ExpLabelOtherReceiving', 0, '625700'),
('EX_POS', 'ExpLabelPostage', 0, '626100'),
('EX_CAM', 'ExpLabelMaintenanceRepairCV', 0, '615300'),
('EX_EMM', 'ExpLabelEmployeesMeal', 0, '625160'),
('EX_GUM', 'ExpLabelGuestsMeal', 0, '625160'),
('EX_BRE', 'ExpLabelBreakfast', 0, '625160'),
('EX_FUE_VP', 'ExpLabelFuelPV', 0, '606150'),
('EX_TOL_VP', 'ExpLabelTollPV', 0, '625160'),
('EX_PAR_VP', 'ExpLabelParkingPV', 0, '625160'),
('EX_CAM_VP', 'ExpLabelMaintenanceRepairPV', 0, '615300');

View File

@@ -0,0 +1,47 @@
-- Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
-- Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--
--
-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors
-- de l'install et tous les sigles '--' sont supprimés.
--
--
-- Coef expense
--
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (1,4, 1, 0.41, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (2,4, 2, 0.244, 824);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (3,4, 3, 0.286, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (4,5, 4, 0.493, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (5,5, 5, 0.277, 1082);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (6,5, 6, 0.332, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (7,6, 7, 0.543, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (8,6, 8, 0.305, 1180);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (9,6, 9, 0.364, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (10,7, 10, 0.568, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (11,7, 11, 0.32, 1244);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (12,7, 12, 0.382, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (13,8, 13, 0.595, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (14,8, 14, 0.337, 1288);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (15,8, 15, 0.401, 0);

View File

@@ -431,3 +431,138 @@ CREATE TABLE llx_blockedlog_authority
) ENGINE=innodb;
ALTER TABLE llx_blockedlog_authority ADD INDEX signature (signature);
CREATE TABLE IF NOT EXISTS llx_expensereport_ik (
rowid integer AUTO_INCREMENT PRIMARY KEY,
datec datetime DEFAULT NULL,
tms timestamp,
fk_cat integer DEFAULT 0 NOT NULL,
fk_range integer DEFAULT 0 NOT NULL,
coef double DEFAULT 0 NOT NULL,
offset double DEFAULT 0 NOT NULL
)ENGINE=innodb DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS llx_c_exp_tax_cat (
rowid integer AUTO_INCREMENT PRIMARY KEY,
label varchar(48) NOT NULL,
entity integer DEFAULT 1 NOT NULL,
active integer DEFAULT 1 NOT NULL
)ENGINE=innodb DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS llx_c_exp_tax_range (
rowid integer AUTO_INCREMENT PRIMARY KEY,
fk_cat integer DEFAULT 1 NOT NULL,
`range` double DEFAULT 0 NOT NULL,
entity integer DEFAULT 1 NOT NULL,
active integer DEFAULT 1 NOT NULL
)ENGINE=innodb DEFAULT CHARSET=utf8;
INSERT INTO llx_c_type_fees (code, label, active, accountancy_code) VALUES
('EX_KME', 'ExpLabelKm', 0, '625100'),
('EX_FUE', 'ExpLabelFuelCV', 0, '606150'),
('EX_HOT', 'ExpLabelHotel', 0, '625160'),
('EX_PAR', 'ExpLabelParkingCV', 0, '625160'),
('EX_TOL', 'ExpLabelTollCV', 0, '625160'),
('EX_TAX', 'ExpLabelVariousTaxes', 0, '637800'),
('EX_IND', 'ExpLabelIndemnityTransportationSubscription', 0, '648100'),
('EX_SUM', 'ExpLabelMaintenanceSupply', 0, '606300'),
('EX_SUO', 'ExpLabelOfficeSupplies', 0, '606400'),
('EX_CAR', 'ExpLabelCarRental', 0, '613000'),
('EX_DOC', 'ExpLabelDocumentation', 0, '618100'),
('EX_CUR', 'ExpLabelCustomersReceiving', 0, '625710'),
('EX_OTR', 'ExpLabelOtherReceiving', 0, '625700'),
('EX_POS', 'ExpLabelPostage', 0, '626100'),
('EX_CAM', 'ExpLabelMaintenanceRepairCV', 0, '615300'),
('EX_EMM', 'ExpLabelEmployeesMeal', 0, '625160'),
('EX_GUM', 'ExpLabelGuestsMeal', 0, '625160'),
('EX_BRE', 'ExpLabelBreakfast', 0, '625160'),
('EX_FUE_VP', 'ExpLabelFuelPV', 0, '606150'),
('EX_TOL_VP', 'ExpLabelTollPV', 0, '625160'),
('EX_PAR_VP', 'ExpLabelParkingPV', 0, '625160'),
('EX_CAM_VP', 'ExpLabelMaintenanceRepairPV', 0, '615300');
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (1,4, 1, 0.41, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (2,4, 2, 0.244, 824);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (3,4, 3, 0.286, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (4,5, 4, 0.493, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (5,5, 5, 0.277, 1082);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (6,5, 6, 0.332, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (7,6, 7, 0.543, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (8,6, 8, 0.305, 1180);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (9,6, 9, 0.364, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (10,7, 10, 0.568, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (11,7, 11, 0.32, 1244);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (12,7, 12, 0.382, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (13,8, 13, 0.595, 0);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (14,8, 14, 0.337, 1288);
INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (15,8, 15, 0.401, 0);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (1,'ExpAutoCat', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (2,'ExpCycloCat', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (3,'ExpMotoCat', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (4,'ExpAuto3CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (5,'ExpAuto4CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (6,'ExpAuto5CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (7,'ExpAuto6CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (8,'ExpAuto7CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (9,'ExpAuto8CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (10,'ExpAuto9CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (11,'ExpAuto10CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (12,'ExpAuto11CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (13,'ExpAuto12CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (14,'ExpAuto3PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (15,'ExpAuto4PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (16,'ExpAuto5PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (17,'ExpAuto6PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (18,'ExpAuto7PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (19,'ExpAuto8PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (20,'ExpAuto9PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (21,'ExpAuto10PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (22,'ExpAuto11PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (23,'ExpAuto12PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (24,'ExpAuto13PCV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (25,'ExpCyclo', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (26,'ExpMoto12CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (27,'ExpMoto345CV', 1, 1);
INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (28,'ExpMoto5PCV', 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (1,4, 0, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (2,4, 5000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (3,4, 20000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (4,5, 0, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (5,5, 5000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (6,5, 20000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (7,6, 0, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (8,6, 5000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (9,6, 20000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (10,7, 0, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (11,7, 5000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (12,7, 20000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (13,8, 0, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (14,8, 5000, 1, 1);
INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (15,8, 20000, 1, 1);
CREATE TABLE `llx_expensereport_rules` (
`rowid` integer AUTO_INCREMENT PRIMARY KEY,
`datec` datetime DEFAULT NULL,
`tms` timestamp,
`dates` datetime NOT NULL,
`datee` datetime NOT NULL,
`amount` numeric(24,8) NOT NULL,
`restrictive` tinyint(1) NOT NULL,
`fk_user` integer DEFAULT NULL,
`fk_usergroup` integer DEFAULT NULL,
`fk_c_type_fees` integer NOT NULL,
`code_expense_rules_type` varchar(50) NOT NULL,
`is_for_all` tinyint(1) DEFAULT '0',
`entity` integer DEFAULT 1
);
ALTER TABLE llx_expensereport_det ADD COLUMN rule_warning_message text;
ALTER TABLE llx_expensereport_det ADD COLUMN fk_c_exp_tax_cat integer;
ALTER TABLE llx_user ADD COLUMN default_range integer;
ALTER TABLE llx_user ADD COLUMN default_c_exp_tax_cat integer;

View File

@@ -0,0 +1,26 @@
-- ============================================================================
-- Copyright (C) 2012 Mikael Carlavan <mcarlavan@qis-network.com>
-- Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
-- Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- ============================================================================
CREATE TABLE IF NOT EXISTS llx_c_exp_tax_cat (
rowid integer AUTO_INCREMENT PRIMARY KEY,
label varchar(48) NOT NULL,
entity integer DEFAULT 1 NOT NULL,
active integer DEFAULT 1 NOT NULL
)ENGINE=innodb DEFAULT CHARSET=utf8;

View File

@@ -0,0 +1,27 @@
-- ============================================================================
-- Copyright (C) 2012 Mikael Carlavan <mcarlavan@qis-network.com>
-- Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
-- Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- ============================================================================
CREATE TABLE IF NOT EXISTS llx_c_exp_tax_range (
rowid integer AUTO_INCREMENT PRIMARY KEY,
fk_cat integer DEFAULT 1 NOT NULL,
`range` double DEFAULT 0 NOT NULL,
entity integer DEFAULT 1 NOT NULL,
active integer DEFAULT 1 NOT NULL
)ENGINE=innodb DEFAULT CHARSET=utf8;

View File

@@ -21,6 +21,7 @@ CREATE TABLE llx_expensereport_det
rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
fk_expensereport integer NOT NULL,
fk_c_type_fees integer NOT NULL,
fk_c_exp_tax_cat integer,
fk_projet integer,
comments text NOT NULL,
product_type integer DEFAULT -1,
@@ -49,5 +50,6 @@ CREATE TABLE llx_expensereport_det
fk_facture integer DEFAULT 0, -- ID of customer invoice line if expense is rebilled to a customer
fk_code_ventilation integer DEFAULT 0,
rang integer DEFAULT 0, -- position of line
import_key varchar(14)
import_key varchar(14),
rule_warning_message text
) ENGINE=innodb;

View File

@@ -0,0 +1,29 @@
-- ============================================================================
-- Copyright (C) 2012 Mikael Carlavan <mcarlavan@qis-network.com>
-- Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
-- Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- ============================================================================
CREATE TABLE IF NOT EXISTS llx_expensereport_ik (
rowid integer AUTO_INCREMENT PRIMARY KEY,
datec datetime DEFAULT NULL,
tms timestamp,
fk_cat integer DEFAULT 0 NOT NULL,
fk_range integer DEFAULT 0 NOT NULL,
coef double DEFAULT 0 NOT NULL,
offset double DEFAULT 0 NOT NULL
)ENGINE=innodb DEFAULT CHARSET=utf8;

View File

@@ -0,0 +1,34 @@
-- ============================================================================
-- Copyright (C) 2017 ATM Consulting <contact@atm-consulting.fr>
-- Copyright (C) 2017 Pierre-Henry Favre <phf@atm-consulting.fr>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- ============================================================================
CREATE TABLE `llx_expensereport_rules` (
`rowid` integer AUTO_INCREMENT PRIMARY KEY,
`datec` datetime DEFAULT NULL,
`tms` timestamp,
`dates` datetime NOT NULL,
`datee` datetime NOT NULL,
`amount` numeric(24,8) NOT NULL,
`restrictive` tinyint(1) NOT NULL,
`fk_user` integer DEFAULT NULL,
`fk_usergroup` integer DEFAULT NULL,
`fk_c_type_fees` integer NOT NULL,
`code_expense_rules_type` varchar(50) NOT NULL,
`is_for_all` tinyint(1) DEFAULT '0',
`entity` integer DEFAULT 1
) ENGINE=InnoDB

View File

@@ -85,5 +85,7 @@ create table llx_user
dateemployment date, -- denormalized value coming from llx_user_employment
weeklyhours double(16,8), -- denormalized value coming from llx_user_employment
import_key varchar(14) -- import key
import_key varchar(14), -- import key
default_range integer,
default_c_exp_tax_cat integer
)ENGINE=innodb;

View File

@@ -873,6 +873,8 @@ DictionaryUnits=Units
DictionaryProspectStatus=Prospection status
DictionaryHolidayTypes=Types of leaves
DictionaryOpportunityStatus=Opportunity status for project/lead
DictionaryExpenseTaxCat=Expense report categories
DictionaryExpenseTaxRange=Expense report range by category
SetupSaved=Setup saved
SetupNotSaved=Setup not saved
BackToModuleList=Back to modules list
@@ -1139,6 +1141,8 @@ RuleForGeneratedPasswords=Rule to generate suggested passwords or validate passw
DisableForgetPasswordLinkOnLogonPage=Do not show the link "Forget password" on login page
UsersSetup=Users module setup
UserMailRequired=EMail required to create a new user
DefaultCategoryCar=Default car category
DefaultRangeNumber=Default range number
##### HRM setup #####
HRMSetup=HRM module setup
##### Company setup #####
@@ -1607,6 +1611,8 @@ TypePaymentDesc=0:Customer payment type, 1:Supplier payment type, 2:Both custome
IncludePath=Include path (defined into variable %s)
ExpenseReportsSetup=Setup of module Expense Reports
TemplatePDFExpenseReports=Document templates to generate expense report document
ExpenseReportsIkSetup=Setup of module Expense Reports - Milles index
ExpenseReportsRulesSetup=Setup of module Expense Reports - Rules
NoModueToManageStockIncrease=No module able to manage automatic stock increase has been activated. Stock increase will be done on manual input only.
YouMayFindNotificationsFeaturesIntoModuleNotification=You may find options for EMail notifications by enabling and configuring the module "Notification".
ListOfNotificationsPerUser=List of notifications per user*

View File

@@ -325,3 +325,32 @@ PaperFormatCAP3=Format P3 Canada
PaperFormatCAP4=Format P4 Canada
PaperFormatCAP5=Format P5 Canada
PaperFormatCAP6=Format P6 Canada
#### Expense report categories ####
ExpAutoCat=Car
ExpCycloCat=Moped
ExpMotoCat=Motorbike
ExpAuto3CV=3 CV
ExpAuto4CV=4 CV
ExpAuto5CV=5 CV
ExpAuto6CV=6 CV
ExpAuto7CV=7 CV
ExpAuto8CV=8 CV
ExpAuto9CV=9 CV
ExpAuto10CV=10 CV
ExpAuto11CV=11 CV
ExpAuto12CV=12 CV
ExpAuto3PCV=3 CV and more
ExpAuto4PCV=4 CV and more
ExpAuto5PCV=5 CV and more
ExpAuto6PCV=6 CV and more
ExpAuto7PCV=7 CV and more
ExpAuto8PCV=8 CV and more
ExpAuto9PCV=9 CV and more
ExpAuto10PCV=10 CV and more
ExpAuto11PCV=11 CV and more
ExpAuto12PCV=12 CV and more
ExpAuto13PCV=13 CV and more
ExpCyclo=Capacity lower to 50cm3
ExpMoto12CV=Motorbike 1 or 2 CV
ExpMoto345CV=Motorbike 3, 4 or 5 CV
ExpMoto5PCV=Motorbike 5 CV and more

View File

@@ -49,6 +49,28 @@ TF_PEAGE=Toll
TF_ESSENCE=Fuel
TF_HOTEL=Hotel
TF_TAXI=Taxi
EX_KME=Mileage costs
EX_FUE=Fuel CV
EX_HOT=Hotel
EX_PAR=Parking CV
EX_TOL=Toll CV
EX_TAX=Various Taxes
EX_IND=Indemnity transportation subscription
EX_SUM=Maintenance supply
EX_SUO=Office supplies
EX_CAR=Car rental
EX_DOC=Documentation
EX_CUR=Customers receiving
EX_OTR=Other receiving
EX_POS=Postage
EX_CAM=CV maintenance and repair
EX_EMM=Employees meal
EX_GUM=Guests meal
EX_BRE=Breakfast
EX_FUE_VP=Fuel PV
EX_TOL_VP=Toll PV
EX_PAR_VP=Parking PV
EX_CAM_VP=PV maintenance and repair
ErrorDoubleDeclaration=You have declared another expense report into a similar date range.
AucuneLigne=There is no expense report declared yet
@@ -89,4 +111,43 @@ ExpenseReportPayment=Expense report payment
ExpenseReportsToApprove=Expense reports to approve
ExpenseReportsToPay=Expense reports to pay
CloneExpenseReport=Clone expense report
ConfirmCloneExpenseReport=Are you sure you want to clone this expense report ?
ConfirmCloneExpenseReport=Are you sure you want to clone this expense report ?
ExpenseReportsIk=Expense report milles index
ExpenseReportsRules=Expense report rules
ExpenseReportIkDesc=You can modify the calculation of kilometers expense by category and range who they are previously defined. <b>d</b> is the distance in kilometers
ExpenseReportRulesDesc=You can create or update any rules of calculation. This part will be used when user will create a new expense report
expenseReportOffset=Offset
expenseReportCoef=Coefficient
expenseReportTotalForFive=Example with <u>d</u> = 5
expenseReportRangeFromTo=from %d to %d
expenseReportRangeMoreThan=more than %d
expenseReportCoefUndefined=(value not defined)
expenseReportCatDisabled=Category disabled - see the c_exp_tax_cat dictionary
expenseReportRangeDisabled=Range disabled - see the c_exp_tax_range dictionay
expenseReportPrintExample=offset + (d x coef) = %s
ExpenseReportApplyTo=Apply to
ExpenseReportDomain=Domain to apply
ExpenseReportLimitOn=Limit on
ExpenseReportDateStart=Date start
ExpenseReportDateEnd=Date end
ExpenseReportLimitAmount=Limite amount
ExpenseReportRestrictive=Restrictive
AllExpenseReport=All type of expense report
OnExpense=Expense line
ExpenseReportRuleSave=Expense report rule saved
ExpenseReportRuleErrorOnSave=Error: %s
RangeNum=Range %d
ExpenseReportConstraintViolationError=Contraint violation id [%s]: %s is superior to %s %s
byEX_DAY=by day (limitation to %s)
byEX_MON=by month (limitation to %s)
byEX_YEA=by year (limitation to %s)
byEX_EXP=by line (limitation to %s)
ExpenseReportConstraintViolationWarning=Contraint violation id [%s]: %s is superior to %s %s
nolimitbyEX_DAY=by day (no limitation)
nolimitbyEX_MON=by month (no limitation)
nolimitbyEX_YEA=by year (no limitation)
nolimitbyEX_EXP=by line (no limitation)
CarCategory=Category of car
ExpenseRangeOffset=Offset amount: %s

View File

@@ -47,7 +47,7 @@ if (! empty($conf->ldap->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class/l
if (! empty($conf->adherent->enabled)) require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
if (! empty($conf->multicompany->enabled)) dol_include_once('/multicompany/class/actions_multicompany.class.php');
if (! empty($conf->categorie->enabled)) require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_ik.class.php';
$id = GETPOST('id','int');
$action = GETPOST('action','alpha');
@@ -367,6 +367,9 @@ if (empty($reshook)) {
$dateemployment = dol_mktime(0, 0, 0, GETPOST('dateemploymentmonth'), GETPOST('dateemploymentday'), GETPOST('dateemploymentyear'));
$object->dateemployment = $dateemployment;
$object->default_range = GETPOST('default_range');
$object->default_c_exp_tax_cat = GETPOST('default_c_exp_tax_cat');
if (! empty($conf->multicompany->enabled))
{
if (! empty($_POST["superadmin"]))
@@ -1108,7 +1111,21 @@ if ($action == 'create' || $action == 'adduserldap')
null, '90%' );
print "</td></tr>";
}
if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
{
print '<tr><td>'.$langs->trans("DefaultCategoryCar").'</td>';
print '<td>';
print $form->selectExpenseCategories($object->default_c_exp_tax_cat, 'default_c_exp_tax_cat', 1);
print '</td></tr>';
print '<tr><td>'.$langs->trans("DefaultRangeNumber").'</td>';
print '<td>';
$maxRangeNum = ExpenseReportIk::getMaxRangeNumber($object->default_c_exp_tax_cat);
print $form->selectarray('default_range', range(0, $maxRangeNum), $object->default_range);
print '</td></tr>';
}
// Other attributes
$parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"');
$reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
@@ -1126,7 +1143,7 @@ if ($action == 'create' || $action == 'adduserldap')
$doleditor=new DolEditor('note','','',120,'dolibarr_notes','',false,true,$conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_3,'90%');
$doleditor->Create();
print "</td></tr>\n";
// Signature
print '<tr><td class="tdtop">'.$langs->trans("Signature").'</td>';
print '<td>';
@@ -1498,6 +1515,19 @@ else
print '<td>'.dol_print_date($object->datepreviouslogin,"dayhour").'</td>';
print "</tr>\n";
if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
{
print '<tr><td>'.$langs->trans("DefaultCategoryCar").'</td>';
print '<td class="fk_c_exp_tax_cat">';
print dol_getIdFromCode($db, $object->default_c_exp_tax_cat, 'c_exp_tax_cat', 'rowid', 'label');
print '</td></tr>';
print '<tr><td>'.$langs->trans("DefaultRangeNumber").'</td>';
print '<td>';
print $object->default_range;
print '</td></tr>';
}
// Other attributes
include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
@@ -2423,6 +2453,20 @@ else
print "</tr>\n";
}
if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
{
print '<tr><td>'.$langs->trans("DefaultCategoryCar").'</td>';
print '<td>';
print $form->selectExpenseCategories($object->default_c_exp_tax_cat, 'default_c_exp_tax_cat', 1);
print '</td></tr>';
print '<tr><td>'.$langs->trans("DefaultRangeNumber").'</td>';
print '<td>';
$maxRangeNum = ExpenseReportIk::getMaxRangeNumber($object->default_c_exp_tax_cat);
print $form->selectarray('default_range', range(0, $maxRangeNum), $object->default_range);
print '</td></tr>';
}
// Other attributes
$parameters=array('colspan' => ' colspan="2"');
$reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook

View File

@@ -130,7 +130,8 @@ class User extends CommonObject
public $dateemployment; // Define date of employment by company
public $default_c_exp_tax_cat;
public $default_range;
/**
* Constructor de la classe
@@ -199,6 +200,7 @@ class User extends CommonObject
$sql.= " u.color,";
$sql.= " u.dateemployment,";
$sql.= " u.ref_int, u.ref_ext,";
$sql.= " u.default_range, u.default_c_exp_tax_cat,";
$sql.= " c.code as country_code, c.label as country,";
$sql.= " d.code_departement as state_code, d.nom as state";
$sql.= " FROM ".MAIN_DB_PREFIX."user as u";
@@ -309,6 +311,9 @@ class User extends CommonObject
$this->contactid = $obj->fk_socpeople;
$this->fk_member = $obj->fk_member;
$this->fk_user = $obj->fk_user;
$this->default_range = $obj->default_range;
$this->default_c_exp_tax_cat = $obj->default_c_exp_tax_cat;
// Protection when module multicompany was set, admin was set to first entity and the module disabled,
// then this admin user must be admin for all entities.
@@ -1319,7 +1324,7 @@ class User extends CommonObject
$this->accountancy_code = trim($this->accountancy_code);
$this->color = empty($this->color)?'':$this->color;
$this->dateemployment = empty($this->dateemployment)?'':$this->dateemployment;
// Check parameters
if (! empty($conf->global->USER_MAIL_REQUIRED) && ! isValidEMail($this->email))
{
@@ -1370,6 +1375,9 @@ class User extends CommonObject
if (isset($this->salaryextra) || $this->salaryextra != '') $sql.= ", salaryextra= ".($this->salaryextra != ''?"'".$this->db->escape($this->salaryextra)."'":"null");
$sql.= ", weeklyhours= ".($this->weeklyhours != ''?"'".$this->db->escape($this->weeklyhours)."'":"null");
$sql.= ", entity = '".$this->db->escape($this->entity)."'";
$sql.= ", default_range = ".($this->default_range > 0 ? $this->default_range : 'null');
$sql.= ", default_c_exp_tax_cat = ".($this->default_c_exp_tax_cat > 0 ? $this->default_c_exp_tax_cat : 'null');
$sql.= " WHERE rowid = ".$this->id;
dol_syslog(get_class($this)."::update", LOG_DEBUG);