diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
index ae26dce060d..b77128b6597 100644
--- a/htdocs/admin/dict.php
+++ b/htdocs/admin/dict.php
@@ -88,7 +88,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();
@@ -126,6 +126,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();
@@ -163,6 +165,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();
@@ -200,6 +204,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_c_exp_tax_cat, r.range_ik, r.active, r.entity FROM ".MAIN_DB_PREFIX."c_exp_tax_range r";
// Criteria to sort dictionaries
$tabsqlsort=array();
@@ -237,6 +243,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_c_exp_tax_cat ASC, r.range_ik ASC";
// Nom des champs en resultat de select pour affichage du dictionnaire
$tabfield=array();
@@ -272,8 +280,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_ik,fk_c_exp_tax_cat";
// Nom des champs d'edition pour modification d'un enregistrement
$tabfieldvalue=array();
@@ -311,6 +319,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_ik,fk_c_exp_tax_cat";
// Nom des champs dans la table pour insertion d'un enregistrement
$tabfieldinsert=array();
@@ -348,6 +358,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_ik,fk_c_exp_tax_cat";
// Nom du rowid si le champ n'est pas de type autoincrement
// Example: "" if id field is "rowid" and has autoincrement on
@@ -387,6 +399,8 @@ $tabrowid[30]= "";
//$tabrowid[32]= "";
$tabrowid[33]= "rowid";
$tabrowid[34]= "rowid";
+$tabrowid[35]= "";
+$tabrowid[36]= "";
// Condition to show dictionary in setup page
$tabcond=array();
@@ -424,6 +438,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();
@@ -461,6 +477,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_ik'=>$langs->trans('PrevRangeToThisRange'));
// List of check for fields (NOT USED YET)
$tabfieldcheck=array();
@@ -498,6 +516,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);
@@ -1065,6 +1085,9 @@ 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 ($fieldlist[$field]=='range_ik') { $valuetoshow=$langs->trans("RangeIk"); }
+ if ($fieldlist[$field]=='fk_c_exp_tax_cat'){ $valuetoshow=$langs->trans("CarCategory"); }
if ($id == 2) // Special cas for state page
{
@@ -1284,6 +1307,9 @@ 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 ($fieldlist[$field]=='range_ik') { $valuetoshow=$langs->trans("RangeIk"); }
+ if ($fieldlist[$field]=='fk_c_exp_tax_cat'){ $valuetoshow=$langs->trans("CarCategory"); }
// Affiche nom du champ
if ($showfield)
@@ -1501,6 +1527,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 ($fieldlist[$field] == 'fk_c_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] == 'note' && $id == 10) $class.=' tdoverflowmax200';
@@ -1667,7 +1713,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;
@@ -1834,6 +1880,24 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
}
print '';
}
+ elseif ($fieldlist[$field] == 'fk_tva')
+ {
+ print '
';
+ print $form->load_tva('fk_tva', $obj->taux, $mysoc, new Societe($db), 0, 0, '', false, -1);
+ print ' ';
+ }
+ elseif ($fieldlist[$field] == 'fk_c_exp_tax_cat')
+ {
+ print '';
+ print $form->selectExpenseCategories($obj->fk_c_exp_tax_cat);
+ print ' ';
+ }
+ elseif ($fieldlist[$field] == 'fk_range')
+ {
+ print '';
+ print $form->selectExpenseRanges($obj->fk_range);
+ print ' ';
+ }
else
{
$classtd=''; $class='';
diff --git a/htdocs/admin/expensereport_ik.php b/htdocs/admin/expensereport_ik.php
new file mode 100644
index 00000000000..9e653dce906
--- /dev/null
+++ b/htdocs/admin/expensereport_ik.php
@@ -0,0 +1,188 @@
+
+ * Copyright (C) 2017 ATM Consulting
+ * Copyright (C) 2017 Pierre-Henry Favre
+ *
+ * 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 .
+ */
+
+
+/**
+ * \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_c_exp_tax_cat = GETPOST('fk_c_exp_tax_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=''.$langs->trans("BackToModuleList").' ';
+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 '';
+
+dol_fiche_end();
+llxFooter();
+
+$db->close();
\ No newline at end of file
diff --git a/htdocs/admin/expensereport_rules.php b/htdocs/admin/expensereport_rules.php
new file mode 100644
index 00000000000..695bdf09a12
--- /dev/null
+++ b/htdocs/admin/expensereport_rules.php
@@ -0,0 +1,366 @@
+
+ * Copyright (C) 2017 ATM Consulting
+ * Copyright (C) 2017 Pierre-Henry Favre
+ *
+ * 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 .
+ */
+
+
+/**
+ * \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=''.$langs->trans("BackToModuleList").' ';
+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 '';
+}
+
+
+echo '';
+
+echo '';
+
+dol_fiche_end();
+llxFooter();
+
+$db->close();
\ No newline at end of file
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 880f32cc580..cda39e3ca9d 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -6325,5 +6325,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_c_exp_tax_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 = '';
+ if ($useempty) $out.= ' ';
+
+ while ($obj = $db->fetch_object($resql))
+ {
+ $out.= 'rowid ? 'selected="selected"' : '').' value="'.$obj->rowid.'">'.$langs->trans($obj->label).' ';
+ }
+ $out.= ' ';
+
+ 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)
+ {
+ $obj = $db->fetch_object($resql);
+ $out.= '';
+ }
+ }
+ }
+ }
+ 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_ik FROM '.MAIN_DB_PREFIX.'c_exp_tax_range';
+ $sql.= ' WHERE entity = '.$conf->entity.' AND active = 1';
+
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $out = '';
+ if ($useempty) $out.= ' ';
+
+ while ($obj = $db->fetch_object($resql))
+ {
+ $out.= 'rowid ? 'selected="selected"' : '').' value="'.$obj->rowid.'">'.price($obj->range_ik, 0, $langs, 1, 0).' ';
+ }
+ $out.= ' ';
+ }
+ 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 = '';
+ if ($useempty) $out.= ' ';
+ if ($allchoice) $out.= ''.$langs->trans('AllExpenseReport').' ';
+
+ $field = 'code';
+ if ($useid) $field = 'id';
+
+ while ($obj = $db->fetch_object($resql))
+ {
+ $key = $langs->trans($obj->code);
+ $out.= '{$field} ? 'selected="selected"' : '').' value="'.$obj->{$field}.'">'.($key != $obj->code ? $key : $obj->label).' ';
+ }
+ $out.= ' ';
+ }
+ else
+ {
+ dol_print_error($db);
+ }
+
+ return $out;
+ }
+
}
diff --git a/htdocs/core/lib/expensereport.lib.php b/htdocs/core/lib/expensereport.lib.php
index a5f19174a84..1efdc73f247 100644
--- a/htdocs/core/lib/expensereport.lib.php
+++ b/htdocs/core/lib/expensereport.lib.php
@@ -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
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 950e421e729..c28ae952afa 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -6452,3 +6452,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 '';
+ }
+}
\ No newline at end of file
diff --git a/htdocs/expensereport/ajax/ajaxik.php b/htdocs/expensereport/ajax/ajaxik.php
new file mode 100644
index 00000000000..e1856f438b0
--- /dev/null
+++ b/htdocs/expensereport/ajax/ajaxik.php
@@ -0,0 +1,76 @@
+
+ * Copyright (C) 2017 Pierre-Henry Favre
+ *
+ * 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 .
+ */
+
+/**
+ * \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'));
+ }
+ }
+ }
+}
diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php
index 504ad47fa77..25a725a5062 100644
--- a/htdocs/expensereport/card.php
+++ b/htdocs/expensereport/card.php
@@ -1059,31 +1059,18 @@ if (empty($reshook))
if ($action == "addline" && $user->rights->expensereport->creer)
{
$error = 0;
-
- $db->begin();
-
- $object_ligne = new ExpenseReportLine($db);
-
- $vatrate = GETPOST('vatrate','alpha'); // May be 8.5* (8.5NPROM)
-
- $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->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');
@@ -1108,13 +1095,13 @@ 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');
@@ -1123,50 +1110,39 @@ if (empty($reshook))
// S'il y'a eu au moins une erreur
if (! $error)
{
- $object_ligne->fk_expensereport = $_POST['fk_expensereport'];
-
$type = 0; // TODO What if service ?
- // We don't know seller and buyer for expense reports
- $seller = $mysoc;
- $buyer = new Societe($db);
+ // 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
- $localtaxes_type=getLocalTaxesFromRate($vatrate,0,$buyer,$seller);
+ 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);
+ }
- // Clean vat code
- $vat_src_code='';
+ $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+ }
- if (preg_match('/\((.*)\)/', $vatrate, $reg))
- {
- $vat_src_code = $reg[1];
- $vatrate = preg_replace('/\s*\(.*\)/', '', $vatrate); // Remove code into vatrate.
- }
- $vatrate = preg_replace('/\*/','',$vatrate);
+ unset($qty);
+ unset($value_unit);
+ unset($vatrate);
+ unset($comments);
+ unset($fk_c_type_fees);
+ unset($fk_projet);
- $tmp = calcul_price_total($qty, $up, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller, $localtaxes_type);
-
- $object_ligne->vat_src_code = $vat_src_code;
- $object_ligne->vatrate = price2num($vatrate);
- $object_ligne->total_ttc = $tmp[2];
- $object_ligne->total_ht = $tmp[0];
- $object_ligne->total_tva = $tmp[1];
- $object_ligne->localtax1_tx = $localtaxes_type[1];
- $object_ligne->localtax2_tx = $localtaxes_type[3];
- $object_ligne->localtax1_type = $localtaxes_type[0];
- $object_ligne->localtax2_type = $localtaxes_type[2];
-
- $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();
- }
+ unset($date);
+
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
}
$action='';
@@ -1222,6 +1198,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');
@@ -1248,7 +1225,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)
@@ -1946,17 +1923,6 @@ else
print '
';
- // 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.vat_src_code, 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 '
';
$actiontouse='updateligne';
@@ -1971,235 +1937,244 @@ else
print '';
print '
';
- $resql = $db->query($sql);
- if ($resql)
+ if (!empty($object->lines))
{
- $num_lignes = $db->num_rows($resql);
$i = 0;$total = 0;
- if ($num_lignes)
+ print '';
+ print ''.$langs->trans('Piece').' ';
+ print ''.$langs->trans('Date').' ';
+ if (! empty($conf->projet->enabled)) print ''.$langs->trans('Project').' ';
+ if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) print ''.$langs->trans('CarCategory').' ';
+ print ''.$langs->trans('Type').' ';
+ print ''.$langs->trans('Description').' ';
+ print ''.$langs->trans('VAT').' ';
+ print ''.$langs->trans('PriceUTTC').' ';
+ print ''.$langs->trans('Qty').' ';
+ if ($action != 'editline')
{
- print ' ';
- print ''.$langs->trans('Piece').' ';
- print ''.$langs->trans('Date').' ';
- if (! empty($conf->projet->enabled)) print ''.$langs->trans('Project').' ';
- print ''.$langs->trans('Type').' ';
- print ''.$langs->trans('Description').' ';
- print ''.$langs->trans('VAT').' ';
- print ''.$langs->trans('PriceUTTC').' ';
- print ''.$langs->trans('Qty').' ';
- if ($action != 'editline')
- {
- print ''.$langs->trans('AmountHT').' ';
- print ''.$langs->trans('AmountTTC').' ';
- }
- // Ajout des boutons de modification/suppression
- if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer)
- {
- print ' ';
- }
- print ' ';
+ print ''.$langs->trans('AmountHT').' ';
+ print ''.$langs->trans('AmountTTC').' ';
+ }
+ // Ajout des boutons de modification/suppression
+ if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer)
+ {
+ print ' ';
+ }
+ print '';
- 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 '';
+
+ print '';
+ print img_picto($langs->trans("Document"), "object_generic");
+ print ' '.$piece_comptable.' ';
+ print ''.dol_print_date($db->jdate($line->date), 'day').' ';
+ if (! empty($conf->projet->enabled))
{
+ print '';
+ if ($line->fk_projet > 0)
+ {
+ $projecttmp->id=$line->fk_projet;
+ $projecttmp->ref=$line->projet_ref;
+ print $projecttmp->getNomUrl(1);
+ }
+ print ' ';
+ }
+ if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
+ {
+ print '';
+ print dol_getIdFromCode($db, $line->fk_c_exp_tax_cat, 'c_exp_tax_cat', 'rowid', 'label');
+ print ' ';
+ }
+ // print ''.$langs->trans("TF_".strtoupper(empty($objp->type_fees_libelle)?'OTHER':$objp->type_fees_libelle)).' ';
+ print ''.($langs->trans(($line->type_fees_code)) == $line->type_fees_code ? $line->type_fees_libelle : $langs->trans(($line->type_fees_code))).' ';
+ print ''.$line->comments.' ';
+ print ''.vatrate($line->vatrate,true).' ';
+ print ''.price($line->value_unit).' ';
+ print ''.$line->qty.' ';
+
+ if ($action != 'editline')
+ {
+ print ''.price($line->total_ht).' ';
+ print ''.price($line->total_ttc).' ';
+ }
+
+ // Ajout des boutons de modification/suppression
+ if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer)
+ {
+ print '';
+
+ print 'id.'&action=editline&rowid='.$line->rowid.'#'.$line->rowid.'">';
+ print img_edit();
+ print ' ';
+ print 'id.'&action=delete_line&rowid='.$line->rowid.'">';
+ print img_delete();
+ print ' ';
+
+ print ' ';
+ }
+
+ print ' ';
+ }
+
+ if ($action == 'editline' && $line->rowid == GETPOST('rowid'))
+ {
print '';
- print '';
- print img_picto($langs->trans("Document"), "object_generic");
- print ' '.$piece_comptable.' ';
- print ''.dol_print_date($db->jdate($objp->date), 'day').' ';
+ print ' ';
+
+ // Select date
+ print '';
+ $form->select_date($line->date,'date');
+ print ' ';
+
+ // Select project
if (! empty($conf->projet->enabled))
{
- print '';
- if ($objp->projet_id > 0)
- {
- $projecttmp->id=$objp->projet_id;
- $projecttmp->ref=$objp->projet_ref;
- print $projecttmp->getNomUrl(1);
- }
- print ' ';
+ print '';
+ $formproject->select_projects(-1, $line->fk_projet,'fk_projet', 0, 0, 1, 1);
+ print ' ';
}
- // print ''.$langs->trans("TF_".strtoupper(empty($objp->type_fees_libelle)?'OTHER':$objp->type_fees_libelle)).' ';
- print ''.($langs->trans(($objp->type_fees_code)) == $objp->type_fees_code ? $objp->type_fees_libelle : $langs->trans(($objp->type_fees_code))).' ';
- print ''.$objp->comments.' ';
- print ''.vatrate($objp->vatrate.($objp->vat_src_code?' ('.$objp->vat_src_code.')':''),true).' ';
- print ''.price($objp->value_unit).' ';
- print ''.$objp->qty.' ';
+
+ if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
+ {
+ print '';
+ $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 ' ';
+ }
+
+ // Select type
+ print '';
+ select_type_fees_id($line->fk_c_type_fees,'fk_c_type_fees');
+ print ' ';
+
+ // Add comments
+ print '';
+ print '';
+ print ' ';
+
+ // VAT
+ print '';
+ print $form->load_tva('vatrate', (isset($_POST["vatrate"])?$_POST["vatrate"]:$line->vatrate), $mysoc, '');
+ print ' ';
+
+ // Unit price
+ print '';
+ print ' ';
+ print ' ';
+
+ // Quantity
+ print '';
+ print ' ';
+ print ' ';
if ($action != 'editline')
{
- print ''.price($objp->total_ht).' ';
- print ''.price($objp->total_ttc).' ';
+ print ''.$langs->trans('AmountHT').' ';
+ print ''.$langs->trans('AmountTTC').' ';
}
- // Ajout des boutons de modification/suppression
- if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer)
- {
- print '';
-
- print 'id.'&action=editline&rowid='.$objp->rowid.'#'.$objp->rowid.'">';
- print img_edit();
- print ' ';
- print 'id.'&action=delete_line&rowid='.$objp->rowid.'">';
- print img_delete();
- print ' ';
-
- print ' ';
- }
-
- print ' ';
- }
-
- if ($action == 'editline' && $objp->rowid == GETPOST('rowid'))
- {
- print '';
-
- print ' ';
-
- // Select date
- print '';
- $form->select_date($objp->date,'date');
- print ' ';
-
- // Select project
- if (! empty($conf->projet->enabled))
- {
- print '';
- $formproject->select_projects(-1, $objp->fk_projet,'fk_projet', 0, 0, 1, 1);
- print ' ';
- }
-
- // Select type
- print '';
- select_type_fees_id($objp->type_fees_code,'fk_c_type_fees');
- print ' ';
-
- // Add comments
- print '';
- print '';
- print ' ';
-
- // VAT
- print '';
- $seller=$mysoc;
- $buyer=new Societe($db);
- $selectedvat=(GETPOST("vatrate",'alpha')?GETPOST("vatrate",'alpha'):$objp->vatrate.($objp->vat_src_code?' ('.$objp->vat_src_code.')':''));
- print $form->load_tva('vatrate', $selectedvat, $seller, $buyer, 0, 0, '', false, 1);
- print ' ';
-
- // Unit price
- print '';
- print ' ';
- print ' ';
-
- // Quantity
- print '';
- print ' '; // We must be able to enter decimal qty
- print ' ';
-
- if ($action != 'editline')
- {
- print ''.$langs->trans('AmountHT').' ';
- print ''.$langs->trans('AmountTTC').' ';
- }
-
- print '';
- print ' ';
- print ' ';
- print ' ';
- print ' ';
- }
-
- $i++;
+ print '';
+ print ' ';
+ print ' ';
+ print ' ';
+ print ' ';
}
- $db->free($resql);
+ $i++;
+ }
+ }
+
+ // Add a line
+ if (($object->fk_statut==0 || $object->fk_statut==99) && $action != 'editline' && $user->rights->expensereport->creer)
+ {
+ print ' ';
+ print ' ';
+ print ''.$langs->trans('Date').' ';
+ if (! empty($conf->projet->enabled)) print ''.$langs->trans('Project').' ';
+ if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) print ''.$langs->trans('CarCategory').' ';
+ print ''.$langs->trans('Type').' ';
+ print ''.$langs->trans('Description').' ';
+ print ''.$langs->trans('VAT').' ';
+ print ''.$langs->trans('PriceUTTC').' ';
+ print ''.$langs->trans('Qty').' ';
+ print ' ';
+ print ' ';
+
+ print '';
+
+ print ' ';
+
+ // Select date
+ print '';
+ $form->select_date($date?$date:-1,'date');
+ print ' ';
+
+ // Select project
+ if (! empty($conf->projet->enabled))
+ {
+ print '';
+ $formproject->select_projects(-1, $fk_projet, 'fk_projet', 0, 0, 1, 1);
+ print ' ';
+ }
+
+ if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
+ {
+ print '';
+ $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 ' ';
}
- // Add a line
- if (($object->fk_statut==0 || $object->fk_statut==99) && $action != 'editline' && $user->rights->expensereport->creer)
+ // Select type
+ print '';
+ select_type_fees_id($fk_c_type_fees,'fk_c_type_fees',1);
+ print ' ';
+
+ // Add comments
+ print '';
+ print '';
+ print ' ';
+
+ // Select VAT
+ print '';
+ $defaultvat=-1;
+ if (! empty($conf->global->EXPENSEREPORT_NO_DEFAULT_VAT)) $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none';
+ print $form->load_tva('vatrate', ($vatrate!=''?$vatrate:$defaultvat), $mysoc, '', 0, 0, '', false, 1);
+ print ' ';
+
+ // Unit price
+ print '';
+ print ' ';
+ print ' ';
+
+ // Quantity
+ print '';
+ print ' '; // We must be able to enter decimal qty
+ print ' ';
+
+ if ($action != 'editline')
{
- print ' ';
- print ' ';
- print ''.$langs->trans('Date').' ';
- if (! empty($conf->projet->enabled)) print ''.$langs->trans('Project').' ';
- print ''.$langs->trans('Type').' ';
- print ''.$langs->trans('Description').' ';
- print ''.$langs->trans('VAT').' ';
- print ''.$langs->trans('PriceUTTC').' ';
- print ''.$langs->trans('Qty').' ';
- print ' ';
- print ' ';
+ print ' ';
+ print ' ';
+ }
- print '';
+ print ' ';
- print ' ';
+ print ' ';
+ } // Fin si c'est payé/validé
- // Select date
- print '';
- $form->select_date($date?$date:-1,'date');
- print ' ';
+ print '
';
+ print '
';
- // Select project
- if (! empty($conf->projet->enabled))
- {
- print '';
- $formproject->select_projects(-1, $fk_projet, 'fk_projet', 0, 0, 1, 1);
- print ' ';
- }
-
- // Select type
- print '';
- select_type_fees_id($fk_c_type_fees,'fk_c_type_fees',1);
- print ' ';
-
- // Add comments
- print '';
- print '';
- print ' ';
-
- // Select VAT
- print '';
- $defaultvat=-1;
- if (! empty($conf->global->EXPENSEREPORT_NO_DEFAULT_VAT)) $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none';
- print $form->load_tva('vatrate', ($vatrate!=''?$vatrate:$defaultvat), $mysoc, '', 0, 0, '', false, 1);
- print ' ';
-
- // Unit price
- print '';
- print ' ';
- print ' ';
-
- // Quantity
- print '';
- print ' '; // We must be able to enter decimal qty
- print ' ';
-
- if ($action != 'editline')
- {
- print ' ';
- print ' ';
- }
-
- print ' ';
-
- print '';
- } // Fin si c'est payé/validé
-
- print '';
- print '';
-
- print '';
- }
- else
- {
- dol_print_error($db);
- }
+ print '';
dol_fiche_end();
@@ -2369,6 +2344,8 @@ if ($action != 'create' && $action != 'edit')
print '';
}
+ $parameters = array();
+ $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
}
print '';
diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php
index f999a93c57f..e4ee53e174a 100644
--- a/htdocs/expensereport/class/expensereport.class.php
+++ b/htdocs/expensereport/class/expensereport.class.php
@@ -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
@@ -37,9 +39,9 @@ class ExpenseReport extends CommonObject
var $picto = 'trip';
var $lignes=array();
-
+
public $date_debut;
-
+
public $date_fin;
var $fk_user_validator;
@@ -65,7 +67,7 @@ class ExpenseReport extends CommonObject
// Update
var $date_modif;
var $fk_user_modif;
-
+
// Refus
var $date_refuse;
var $detail_refuse;
@@ -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
@@ -268,6 +296,7 @@ class ExpenseReport extends CommonObject
if (empty($fk_user_author)) $fk_user_author = $user->id;
$this->context['createfromclone'] = 'createfromclone';
+
$this->db->begin();
// get extrafields so they will be clone
@@ -306,7 +335,6 @@ class ExpenseReport extends CommonObject
// Call trigger
$result=$this->call_trigger('EXPENSEREPORT_CLONE',$user);
-
if ($result < 0) $error++;
// End call triggers
}
@@ -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, $mysoc;
@@ -1623,34 +1892,29 @@ class ExpenseReport extends CommonObject
$total_tva = price2num($total_ttc - $total_ht, 'MT');
// fin calculs
- $ligne = new ExpenseReportLine($this->db);
+ $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->rowid = $rowid;
+ $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->comments = $comments;
- $ligne->qty = $qty;
- $ligne->value_unit = $value_unit;
- $ligne->date = $date;
-
- $ligne->fk_expensereport= $expensereport_id;
- $ligne->fk_c_type_fees = $type_fees_id;
- $ligne->fk_projet = $projet_id;
-
- //$ligne->total_ht = $total_ht;
- //$ligne->total_tva = $total_tva;
- //$ligne->total_ttc = $total_ttc;
- //$ligne->vatrate = price2num($vatrate);
-
- $ligne->vat_src_code = $vat_src_code;
- $ligne->vatrate = price2num($vatrate);
- $ligne->total_ttc = $tmp[2];
- $ligne->total_ht = $tmp[0];
- $ligne->total_tva = $tmp[1];
- $ligne->localtax1_tx = $localtaxes_type[1];
- $ligne->localtax2_tx = $localtaxes_type[3];
- $ligne->localtax1_type = $localtaxes_type[0];
- $ligne->localtax2_type = $localtaxes_type[2];
+ $this->line->vat_src_code = $vat_src_code;
+ $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->localtax1_tx = $localtaxes_type[1];
+ $this->line->localtax2_tx = $localtaxes_type[3];
+ $this->line->localtax1_type = $localtaxes_type[0];
+ $this->line->localtax2_type = $localtaxes_type[2];
+ $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";
@@ -1658,8 +1922,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";
@@ -1669,10 +1933,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();
@@ -1680,8 +1947,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;
}
@@ -2025,6 +2292,7 @@ class ExpenseReportLine
var $date;
var $fk_c_type_fees;
+ var $fk_c_exp_tax_cat;
var $fk_projet;
var $fk_expensereport;
@@ -2057,7 +2325,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.vat_src_code, 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';
@@ -2079,8 +2347,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;
@@ -2102,9 +2372,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;
@@ -2117,12 +2388,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, vat_src_code, comments, qty, value_unit, total_ht, total_tva, total_ttc, date)';
+ $sql.= ' tva_tx, vat_src_code, 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').",";
@@ -2134,7 +2406,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);
@@ -2144,16 +2418,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)
{
@@ -2168,7 +2449,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
*
@@ -2185,6 +2509,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();
@@ -2198,7 +2523,9 @@ class ExpenseReportLine
$sql.= ",total_tva=".$this->total_tva."";
$sql.= ",total_ttc=".$this->total_ttc."";
$sql.= ",tva_tx=".$this->vatrate;
- $sql.= ",vat_src_code='".$this->db->escape($this->vat_src_code)."'";
+ $sql.= ",vat_src_code='".$this->db->escape($this->vat_src_code)."'";
+ $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;
diff --git a/htdocs/expensereport/class/expensereport_ik.class.php b/htdocs/expensereport/class/expensereport_ik.class.php
new file mode 100644
index 00000000000..41170ce2fd4
--- /dev/null
+++ b/htdocs/expensereport/class/expensereport_ik.class.php
@@ -0,0 +1,248 @@
+
+ * Copyright (C) 2017 Pierre-Henry Favre
+ *
+ * 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 .
+ */
+
+/**
+ * \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_c_exp_tax_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(
+ 'rowid'=>array('type'=>'integer','index'=>true)
+ ,'fk_c_exp_tax_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_c_exp_tax_cat = c.rowid)';
+ $sql.= ' WHERE r.fk_c_exp_tax_cat = '.$fk_c_exp_tax_cat;
+ if ($active) $sql.= ' AND r.active = 1 AND c.active = 1';
+ $sql.= ' ORDER BY r.range_ik';
+
+ 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_c_exp_tax_cat, r.range_ik, 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_c_exp_tax_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_c_exp_tax_cat, r.range_ik';
+
+ 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_c_exp_tax_cat])) $ranges[$obj->fk_c_exp_tax_cat] = array('label' => $obj->label, 'active' => $obj->cat_active, 'ranges' => array());
+ $ranges[$obj->fk_c_exp_tax_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_c_exp_tax_cat = '.$default_c_exp_tax_cat;
+ $sql.= ' GROUP BY r.fk_c_exp_tax_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;
+ }
+}
diff --git a/htdocs/expensereport/class/expensereport_rule.class.php b/htdocs/expensereport/class/expensereport_rule.class.php
new file mode 100644
index 00000000000..f1c5dc7136d
--- /dev/null
+++ b/htdocs/expensereport/class/expensereport_rule.class.php
@@ -0,0 +1,237 @@
+
+ * Copyright (C) 2017 Pierre-Henry Favre
+ *
+ * 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 .
+ */
+
+/**
+ * \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(
+ 'rowid'=>array('type'=>'integer','index'=>true)
+ ,'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 '';
+ }
+}
diff --git a/htdocs/install/mysql/data/llx_c_exp_tax_cat.sql b/htdocs/install/mysql/data/llx_c_exp_tax_cat.sql
new file mode 100644
index 00000000000..ba6516d81ad
--- /dev/null
+++ b/htdocs/install/mysql/data/llx_c_exp_tax_cat.sql
@@ -0,0 +1,56 @@
+-- Copyright (C) 2017 ATM Consulting
+-- Copyright (C) 2017 Pierre-Henry Favre
+--
+-- 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 .
+--
+--
+
+--
+-- 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, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (2,'ExpCycloCat', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (3,'ExpMotoCat', 1, 0);
+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, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (11,'ExpAuto10CV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (12,'ExpAuto11CV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (13,'ExpAuto12CV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (14,'ExpAuto3PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (15,'ExpAuto4PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (16,'ExpAuto5PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (17,'ExpAuto6PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (18,'ExpAuto7PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (19,'ExpAuto8PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (20,'ExpAuto9PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (21,'ExpAuto10PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (22,'ExpAuto11PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (23,'ExpAuto12PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (24,'ExpAuto13PCV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (25,'ExpCyclo', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (26,'ExpMoto12CV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (27,'ExpMoto345CV', 1, 0);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (28,'ExpMoto5PCV', 1, 0);
diff --git a/htdocs/install/mysql/data/llx_c_exp_tax_range.sql b/htdocs/install/mysql/data/llx_c_exp_tax_range.sql
new file mode 100644
index 00000000000..ad15c320153
--- /dev/null
+++ b/htdocs/install/mysql/data/llx_c_exp_tax_range.sql
@@ -0,0 +1,47 @@
+-- Copyright (C) 2017 ATM Consulting
+-- Copyright (C) 2017 Pierre-Henry Favre
+--
+-- 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 .
+--
+--
+
+--
+-- 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_c_exp_tax_cat,range_ik, entity, active) values (1,4, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (2,4, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (3,4, 20000, 1, 1);
+
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (4,5, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (5,5, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (6,5, 20000, 1, 1);
+
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (7,6, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (8,6, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (9,6, 20000, 1, 1);
+
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (10,7, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (11,7, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (12,7, 20000, 1, 1);
+
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (13,8, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (14,8, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (15,8, 20000, 1, 1);
\ No newline at end of file
diff --git a/htdocs/install/mysql/data/llx_c_type_fees.sql b/htdocs/install/mysql/data/llx_c_type_fees.sql
index 19ee7865e9f..868a210d891 100644
--- a/htdocs/install/mysql/data/llx_c_type_fees.sql
+++ b/htdocs/install/mysql/data/llx_c_type_fees.sql
@@ -5,6 +5,8 @@
-- Copyright (C) 2004 Guillaume Delecourt
-- Copyright (C) 2005-2009 Regis Houssin
-- Copyright (C) 2007 Patrick Raguin
+-- Copyright (C) 2017 ATM Consulting
+-- Copyright (C) 2017 Pierre-Henry Favre
--
-- 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', 1, '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');
\ No newline at end of file
diff --git a/htdocs/install/mysql/data/llx_expensereport_ik.sql b/htdocs/install/mysql/data/llx_expensereport_ik.sql
new file mode 100644
index 00000000000..c39700d9994
--- /dev/null
+++ b/htdocs/install/mysql/data/llx_expensereport_ik.sql
@@ -0,0 +1,47 @@
+-- Copyright (C) 2017 ATM Consulting
+-- Copyright (C) 2017 Pierre-Henry Favre
+--
+-- 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 .
+--
+--
+
+--
+-- 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_c_exp_tax_cat, fk_range, coef, offset) values (1,4, 1, 0.41, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (2,4, 2, 0.244, 824);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (3,4, 3, 0.286, 0);
+
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (4,5, 4, 0.493, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (5,5, 5, 0.277, 1082);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (6,5, 6, 0.332, 0);
+
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (7,6, 7, 0.543, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (8,6, 8, 0.305, 1180);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (9,6, 9, 0.364, 0);
+
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (10,7, 10, 0.568, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (11,7, 11, 0.32, 1244);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (12,7, 12, 0.382, 0);
+
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (13,8, 13, 0.595, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (14,8, 14, 0.337, 1288);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (15,8, 15, 0.401, 0);
\ No newline at end of file
diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
index be8bd9c2701..ebf3920916c 100644
--- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
+++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
@@ -49,3 +49,136 @@ ALTER TABLE llx_accounting_bookkeeping ADD COLUMN extraparams varchar(255);
ALTER TABLE llx_accounting_bookkeeping ADD COLUMN date_lim_reglement datetime;
+CREATE TABLE IF NOT EXISTS llx_expensereport_ik (
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ datec datetime DEFAULT NULL,
+ tms timestamp,
+ fk_c_exp_tax_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_c_exp_tax_cat integer DEFAULT 1 NOT NULL,
+ range_ik 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', 1, '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', 'ExpLabelIndemnityTranspSub', 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_c_exp_tax_cat, fk_range, coef, offset) values (1,4, 1, 0.41, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (2,4, 2, 0.244, 824);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (3,4, 3, 0.286, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (4,5, 4, 0.493, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (5,5, 5, 0.277, 1082);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (6,5, 6, 0.332, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (7,6, 7, 0.543, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (8,6, 8, 0.305, 1180);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (9,6, 9, 0.364, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (10,7, 10, 0.568, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (11,7, 11, 0.32, 1244);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (12,7, 12, 0.382, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (13,8, 13, 0.595, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_cat, fk_range, coef, offset) values (14,8, 14, 0.337, 1288);
+INSERT INTO llx_expensereport_ik (rowid,fk_c_exp_tax_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_c_exp_tax_cat,range_ik, entity, active) values (1,4, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (2,4, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (3,4, 20000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (4,5, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (5,5, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (6,5, 20000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (7,6, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (8,6, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (9,6, 20000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (10,7, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (11,7, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (12,7, 20000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (13,8, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, entity, active) values (14,8, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_c_exp_tax_cat,range_ik, 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 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 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;
diff --git a/htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql b/htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql
new file mode 100644
index 00000000000..9caea48ca21
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql
@@ -0,0 +1,26 @@
+-- ============================================================================
+-- Copyright (C) 2012 Mikael Carlavan
+-- Copyright (C) 2017 ATM Consulting
+-- Copyright (C) 2017 Pierre-Henry Favre
+--
+-- 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 .
+--
+-- ============================================================================
+
+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;
\ No newline at end of file
diff --git a/htdocs/install/mysql/tables/llx_c_exp_tax_range.sql b/htdocs/install/mysql/tables/llx_c_exp_tax_range.sql
new file mode 100644
index 00000000000..4b60557851a
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_c_exp_tax_range.sql
@@ -0,0 +1,27 @@
+-- ============================================================================
+-- Copyright (C) 2012 Mikael Carlavan
+-- Copyright (C) 2017 ATM Consulting
+-- Copyright (C) 2017 Pierre-Henry Favre
+--
+-- 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 .
+--
+-- ============================================================================
+
+CREATE TABLE IF NOT EXISTS llx_c_exp_tax_range (
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ fk_c_exp_tax_cat integer DEFAULT 1 NOT NULL,
+ range_ik double DEFAULT 0 NOT NULL,
+ entity integer DEFAULT 1 NOT NULL,
+ active integer DEFAULT 1 NOT NULL
+)ENGINE=innodb DEFAULT CHARSET=utf8;
diff --git a/htdocs/install/mysql/tables/llx_expensereport_det.sql b/htdocs/install/mysql/tables/llx_expensereport_det.sql
index 8d01f29de68..5cc7b1b86f5 100644
--- a/htdocs/install/mysql/tables/llx_expensereport_det.sql
+++ b/htdocs/install/mysql/tables/llx_expensereport_det.sql
@@ -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,
@@ -50,5 +51,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;
\ No newline at end of file
diff --git a/htdocs/install/mysql/tables/llx_expensereport_ik.sql b/htdocs/install/mysql/tables/llx_expensereport_ik.sql
new file mode 100644
index 00000000000..13f1a8067d6
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_expensereport_ik.sql
@@ -0,0 +1,29 @@
+-- ============================================================================
+-- Copyright (C) 2012 Mikael Carlavan
+-- Copyright (C) 2017 ATM Consulting
+-- Copyright (C) 2017 Pierre-Henry Favre
+--
+-- 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 .
+--
+-- ============================================================================
+
+CREATE TABLE IF NOT EXISTS llx_expensereport_ik (
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ datec datetime DEFAULT NULL,
+ tms timestamp,
+ fk_c_exp_tax_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;
\ No newline at end of file
diff --git a/htdocs/install/mysql/tables/llx_expensereport_rules.sql b/htdocs/install/mysql/tables/llx_expensereport_rules.sql
new file mode 100644
index 00000000000..0a3b6dc0c49
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_expensereport_rules.sql
@@ -0,0 +1,34 @@
+-- ============================================================================
+-- Copyright (C) 2017 ATM Consulting
+-- Copyright (C) 2017 Pierre-Henry Favre
+--
+-- 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 .
+--
+-- ============================================================================
+
+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 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 DEFAULT '0',
+ entity integer DEFAULT 1
+) ENGINE=InnoDB
\ No newline at end of file
diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql
index 9df2f57a22b..ed837b49b51 100644
--- a/htdocs/install/mysql/tables/llx_user.sql
+++ b/htdocs/install/mysql/tables/llx_user.sql
@@ -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;
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index 9d897396036..2f5222720cb 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -875,6 +875,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
@@ -1141,6 +1143,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 #####
@@ -1609,6 +1613,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*
diff --git a/htdocs/langs/en_US/dict.lang b/htdocs/langs/en_US/dict.lang
index 8971d8e82d4..f0fa27bcbf8 100644
--- a/htdocs/langs/en_US/dict.lang
+++ b/htdocs/langs/en_US/dict.lang
@@ -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
\ No newline at end of file
diff --git a/htdocs/langs/en_US/trips.lang b/htdocs/langs/en_US/trips.lang
index a51a392499b..501ccb6ff10 100644
--- a/htdocs/langs/en_US/trips.lang
+++ b/htdocs/langs/en_US/trips.lang
@@ -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,44 @@ 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 ?
\ No newline at end of file
+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. d 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 d = 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=Constraint 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=Constraint 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
+RangeIk=Mileage range
\ No newline at end of file
diff --git a/htdocs/user/card.php b/htdocs/user/card.php
index a2938a89712..7209b900378 100644
--- a/htdocs/user/card.php
+++ b/htdocs/user/card.php
@@ -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 "";
}
+
+ if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
+ {
+ print ''.$langs->trans("DefaultCategoryCar").' ';
+ print '';
+ print $form->selectExpenseCategories($object->default_c_exp_tax_cat, 'default_c_exp_tax_cat', 1);
+ print ' ';
+ print ''.$langs->trans("DefaultRangeNumber").' ';
+ print '';
+ $maxRangeNum = ExpenseReportIk::getMaxRangeNumber($object->default_c_exp_tax_cat);
+ print $form->selectarray('default_range', range(0, $maxRangeNum), $object->default_range);
+ print ' ';
+ }
+
// 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 "\n";
-
+
// Signature
print ''.$langs->trans("Signature").' ';
print '';
@@ -1498,6 +1515,19 @@ else
print ' '.dol_print_date($object->datepreviouslogin,"dayhour").' ';
print " \n";
+ if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
+ {
+ print ''.$langs->trans("DefaultCategoryCar").' ';
+ print '';
+ print dol_getIdFromCode($db, $object->default_c_exp_tax_cat, 'c_exp_tax_cat', 'rowid', 'label');
+ print ' ';
+
+ print ''.$langs->trans("DefaultRangeNumber").' ';
+ print '';
+ print $object->default_range;
+ print ' ';
+ }
+
// Other attributes
include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
@@ -2392,6 +2422,20 @@ else
print "\n";
}
+ if (!empty($conf->global->MAIN_USE_EXPENSE_IK))
+ {
+ print ''.$langs->trans("DefaultCategoryCar").' ';
+ print '';
+ print $form->selectExpenseCategories($object->default_c_exp_tax_cat, 'default_c_exp_tax_cat', 1);
+ print ' ';
+
+ print ''.$langs->trans("DefaultRangeNumber").' ';
+ print '';
+ $maxRangeNum = ExpenseReportIk::getMaxRangeNumber($object->default_c_exp_tax_cat);
+ print $form->selectarray('default_range', range(0, $maxRangeNum), $object->default_range);
+ print ' ';
+ }
+
// 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
diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php
index 577a6389b6f..2ff98899462 100644
--- a/htdocs/user/class/user.class.php
+++ b/htdocs/user/class/user.class.php
@@ -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";
@@ -310,6 +312,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 then, the module was disabled,
// in such case, this admin user must be admin for ALL entities.
@@ -1320,7 +1325,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))
{
@@ -1371,6 +1376,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);