';
-
- 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 '';
- print $form->load_tva('vatrate', (isset($_POST["vatrate"])?$_POST["vatrate"]:$objp->vatrate), $mysoc, '');
- print ' ';
-
- // Unit price
- print '';
- print ' ';
- print ' ';
-
- // Quantity
- print '';
- print ' ';
- 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);
- }
- else
- {
- /* print '';
- print ''.$langs->trans("AucuneLigne").'
';
- print '
';*/
+ $i++;
}
+
//print '';
// Add a line
@@ -2108,6 +2097,7 @@ else
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').' ';
@@ -2133,6 +2123,14 @@ else
$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 ' ';
+ }
// Select type
print '';
@@ -2350,6 +2348,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 ffef31cad8b..c948c1ebcce 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
@@ -91,9 +93,35 @@ class ExpenseReport extends CommonObject
/*
END ACTIONS
*/
+
+ /**
+ * Draft
+ */
+ const STATUS_DRAFT = 0;
+ /**
+ * Validated (need to be paid)
+ */
+ const STATUS_VALIDATED = 2;
- /**
+ /**
+ * Classified approved
+ */
+ const STATUS_APPROVED = 5;
+
+ /**
+ * Classified refused
+ */
+ const STATUS_REFUSED = 99;
+
+ /**
+ * Classified paid.
+ */
+ const STATUS_CLOSED = 6;
+
+
+
+ /**
* Constructor
*
* @param DoliDB $db Handler acces base de donnees
@@ -911,7 +939,7 @@ class ExpenseReport extends CommonObject
$this->lines=array();
$sql = ' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date,';
- $sql.= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_projet, de.tva_tx,';
+ $sql.= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet, de.tva_tx,';
$sql.= ' de.total_ht, de.total_tva, de.total_ttc,';
$sql.= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,';
$sql.= ' p.ref as ref_projet, p.title as title_projet';
@@ -933,13 +961,16 @@ class ExpenseReport extends CommonObject
$deplig = new ExpenseReportLine($this->db);
$deplig->rowid = $objp->rowid;
+ $deplig->id = $objp->id;
$deplig->comments = $objp->comments;
$deplig->qty = $objp->qty;
$deplig->value_unit = $objp->value_unit;
$deplig->date = $objp->date;
+ $deplig->dates = $this->db->jdate($objp->date);
$deplig->fk_expensereport = $objp->fk_expensereport;
$deplig->fk_c_type_fees = $objp->fk_c_type_fees;
+ $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
$deplig->fk_projet = $objp->fk_projet;
$deplig->total_ht = $objp->total_ht;
@@ -1570,7 +1601,244 @@ class ExpenseReport extends CommonObject
endif;
}
+ /**
+ * addline
+ *
+ * @param real $qty Qty
+ * @param double $up Value init
+ * @param int $fk_c_type_fees Type payment
+ * @param double $vatrate Vat rate
+ * @param string $date Date
+ * @param string $comments Description
+ * @param int $fk_project Project id
+ * @param int $fk_c_exp_tax_cat Car category id
+ * @param int $type Type line
+ * @return int <0 if KO, >0 if OK
+ */
+ function addline($qty=0, $up=0, $fk_c_type_fees=0, $vatrate=0, $date='', $comments='', $fk_project=0, $fk_c_exp_tax_cat=0, $type=0)
+ {
+ global $conf,$langs;
+ dol_syslog(get_class($this)."::addline qty=$qty, up=$up, fk_c_type_fees=$fk_c_type_fees, vatrate=$vatrate, date=$date, fk_project=$fk_project, type=$type, comments=$comments", LOG_DEBUG);
+
+ if (empty($qty)) $qty = 0;
+ if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) $fk_c_type_fees = 0;
+ if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) $fk_c_exp_tax_cat = 0;
+ if (empty($vatrate) || $vatrate < 0) $vatrate = 0;
+ if (empty($date)) $date = '';
+ if (empty($fk_project)) $fk_project = 0;
+
+ $qty = price2num($qty);
+ $vatrate = price2num($vatrate);
+ $up = price2num($up);
+
+ if ($this->fk_statut == self::STATUS_DRAFT)
+ {
+ $this->db->begin();
+
+ $this->line = new ExpenseReportLine($this->db);
+
+ $seller = ''; // seller is unknown
+ $tmp = calcul_price_total($qty, $up, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller);
+
+ $this->line->value_unit = $up;
+ $this->line->vatrate = price2num($vatrate);
+ $this->line->total_ttc = $tmp[2];
+ $this->line->total_ht = $tmp[0];
+ $this->line->total_tva = $tmp[1];
+
+ $this->line->fk_expensereport = $this->id;
+ $this->line->qty = $qty;
+ $this->line->date = $date;
+ $this->line->fk_c_type_fees = $fk_c_type_fees;
+ $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
+ $this->line->comments = $comments;
+ $this->line->fk_projet = $fk_project;
+
+ $this->applyOffset();
+ $this->checkRules($type, $seller);
+
+ $result=$this->line->insert(0, true);
+ if ($result > 0)
+ {
+ $result=$this->update_price(); // This method is designed to add line from user input so total calculation must be done using 'auto' mode.
+ if ($result > 0)
+ {
+ $this->db->commit();
+ return $this->line->rowid;
+ }
+ else
+ {
+ $this->db->rollback();
+ return -1;
+ }
+ }
+ else
+ {
+ $this->error=$this->line->error;
+ dol_syslog(get_class($this)."::addline error=".$this->error, LOG_ERR);
+ $this->db->rollback();
+ return -2;
+ }
+ }
+ else
+ {
+ dol_syslog(get_class($this)."::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
+ $this->error = 'ErrorExpenseNotDraft';
+ return -3;
+ }
+
+
+ }
+
+ /**
+ * Check constraint of rules and update price if needed
+ *
+ * @param int $type type of line
+ * @param string $seller seller, but actually he is unknown
+ * @return true or false
+ */
+ function checkRules($type=0, $seller='')
+ {
+ global $user,$conf,$db,$langs;
+
+ $langs->load('trips');
+
+ if (empty($conf->global->MAIN_USE_EXPENSE_RULE)) return true; // if don't use rules
+
+ $rulestocheck = ExpenseReportRule::getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
+
+ $violation = 0;
+ $rule_warning_message_tab = array();
+
+ $current_total_ttc = $this->line->total_ttc;
+ $new_current_total_ttc = $this->line->total_ttc;
+
+ // check if one is violated
+ foreach ($rulestocheck as $rule)
+ {
+ if (in_array($rule->code_expense_rules_type, array('EX_DAY', 'EX_MON', 'EX_YEA'))) $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
+ else $amount_to_test = $current_total_ttc; // EX_EXP
+
+ $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc; // if amount as been modified by a previous rule
+
+ if ($amount_to_test > $rule->amount)
+ {
+ $violation++;
+
+ if ($rule->restrictive)
+ {
+ $this->error = 'ExpenseReportConstraintViolationError';
+ $this->errors[] = $this->error;
+
+ $new_current_total_ttc -= $amount_to_test - $rule->amount; // ex, entered 16€, limit 12€, subtracts 4€;
+ $rule_warning_message_tab[] = $langs->trans('ExpenseReportConstraintViolationError', $rule->id, price($amount_to_test,0,$langs,1,-1,-1,$conf->currency), price($rule->amount,0,$langs,1,-1,-1,$conf->currency), $langs->trans('by'.$rule->code_expense_rules_type, price($new_current_total_ttc,0,$langs,1,-1,-1,$conf->currency)));
+ }
+ else
+ {
+ $this->error = 'ExpenseReportConstraintViolationWarning';
+ $this->errors[] = $this->error;
+
+ $rule_warning_message_tab[] = $langs->trans('ExpenseReportConstraintViolationWarning', $rule->id, price($amount_to_test,0,$langs,1,-1,-1,$conf->currency), price($rule->amount,0,$langs,1,-1,-1,$conf->currency), $langs->trans('nolimitby'.$rule->code_expense_rules_type));
+ }
+
+ // No break, we sould test if another rule is violated
+ }
+ }
+
+ $this->line->rule_warning_message = implode('\n', $rule_warning_message_tab);
+
+ if ($violation > 0)
+ {
+ $tmp = calcul_price_total($this->line->qty, $new_current_total_ttc/$this->line->qty, 0, $this->line->vatrate, 0, 0, 0, 'TTC', 0, $type, $seller);
+
+ $this->line->value_unit = $tmp[5];
+ $this->line->total_ttc = $tmp[2];
+ $this->line->total_ht = $tmp[0];
+ $this->line->total_tva = $tmp[1];
+
+ return false;
+ }
+ else return true;
+ }
+
+ /**
+ * Method to apply the offset if needed
+ *
+ * @return boolean true=applied, false=not applied
+ */
+ function applyOffset()
+ {
+ global $conf;
+
+ if (empty($conf->global->MAIN_USE_EXPENSE_IK)) return false;
+
+ $userauthor = new User($this->db);
+ if ($userauthor->fetch($this->fk_user_author) <= 0)
+ {
+ $this->error = 'ErrorCantFetchUser';
+ $this->errors[] = 'ErrorCantFetchUser';
+ return false;
+ }
+
+ $range = ExpenseReportIk::getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
+
+ if (empty($range))
+ {
+ $this->error = 'ErrorNoRangeAvailable';
+ $this->errors[] = 'ErrorNoRangeAvailable';
+ return false;
+ }
+
+ if (!empty($conf->global->MAIN_EXPENSE_APPLY_ENTIRE_OFFSET)) $offset = $range->offset;
+ else $offset = $range->offset / 12; // The amount of offset is a global value for the year
+
+ // Test if offset has been applied for the current month
+ if (!$this->offsetAlreadyGiven())
+ {
+ $new_up = $range->coef + ($offset / $this->line->qty);
+ $tmp = calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0, 'TTC', 0, $type, $seller);
+
+ $this->line->value_unit = $tmp[5];
+ $this->line->total_ttc = $tmp[2];
+ $this->line->total_ht = $tmp[0];
+ $this->line->total_tva = $tmp[1];
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * If the sql find any rows then the offset is already given (offset is applied at the first expense report line)
+ *
+ * @return bool
+ */
+ function offsetAlreadyGiven()
+ {
+ $sql = 'SELECT e.rowid FROM '.MAIN_DB_PREFIX.'expensereport e';
+ $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'expensereport_det d ON (e.rowid = d.fk_expensereport)';
+ $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = "EX_KME")';
+ $sql.= ' WHERE e.fk_user_author = '.(int) $this->fk_user_author;
+ $sql.= ' AND YEAR(d.date) = "'.dol_print_date($this->line->date, '%Y').'" AND MONTH(d.date) = "'.dol_print_date($this->line->date, '%m').'"';
+ if (!empty($this->line->id)) $sql.= ' AND d.rowid <> '.$this->line->id;
+
+ dol_syslog(get_class($this)."::offsetAlreadyGiven sql=".$sql);
+ $resql = $this->db->query($sql);
+ if ($resql)
+ {
+ $num = $this->db->num_rows($resql);
+ if ($num > 0) return true;
+ }
+ else
+ {
+ dol_print_error($this->db);
+ }
+
+ return false;
+ }
+
/**
* updateline
*
@@ -1583,9 +1851,10 @@ class ExpenseReport extends CommonObject
* @param double $value_unit Value init
* @param int $date Date
* @param int $expensereport_id Expense report id
+ * @param int $fk_c_exp_tax_cat id of category of car
* @return int <0 if KO, >0 if OK
*/
- function updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id)
+ function updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id, $fk_c_exp_tax_cat=0)
{
global $user;
@@ -1603,21 +1872,23 @@ class ExpenseReport extends CommonObject
$total_tva = price2num($total_ttc - $total_ht, 'MT');
// fin calculs
- $ligne = new ExpenseReportLine($this->db);
- $ligne->comments = $comments;
- $ligne->qty = $qty;
- $ligne->value_unit = $value_unit;
- $ligne->date = $date;
+ $this->line = new ExpenseReportLine($this->db);
+ $this->line->comments = $comments;
+ $this->line->qty = $qty;
+ $this->line->value_unit = $value_unit;
+ $this->line->date = $date;
- $ligne->fk_expensereport= $expensereport_id;
- $ligne->fk_c_type_fees = $type_fees_id;
- $ligne->fk_projet = $projet_id;
+ $this->line->fk_expensereport= $expensereport_id;
+ $this->line->fk_c_type_fees = $type_fees_id;
+ $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
+ $this->line->fk_projet = $projet_id;
- $ligne->total_ht = $total_ht;
- $ligne->total_tva = $total_tva;
- $ligne->total_ttc = $total_ttc;
- $ligne->vatrate = price2num($vatrate);
- $ligne->rowid = $rowid;
+ $this->line->total_ht = $total_ht;
+ $this->line->total_tva = $total_tva;
+ $this->line->total_ttc = $total_ttc;
+ $this->line->vatrate = price2num($vatrate);
+ $this->line->rowid = $rowid;
+ $this->line->id = $rowid;
// Select des infos sur le type fees
$sql = "SELECT c.code as code_type_fees, c.label as libelle_type_fees";
@@ -1625,8 +1896,8 @@ class ExpenseReport extends CommonObject
$sql.= " WHERE c.id = ".$type_fees_id;
$result = $this->db->query($sql);
$objp_fees = $this->db->fetch_object($result);
- $ligne->type_fees_code = $objp_fees->code_type_fees;
- $ligne->type_fees_libelle = $objp_fees->libelle_type_fees;
+ $this->line->type_fees_code = $objp_fees->code_type_fees;
+ $this->line->type_fees_libelle = $objp_fees->libelle_type_fees;
// Select des informations du projet
$sql = "SELECT p.ref as ref_projet, p.title as title_projet";
@@ -1636,10 +1907,13 @@ class ExpenseReport extends CommonObject
if ($result) {
$objp_projet = $this->db->fetch_object($result);
}
- $ligne->projet_ref = $objp_projet->ref_projet;
- $ligne->projet_title = $objp_projet->title_projet;
+ $this->line->projet_ref = $objp_projet->ref_projet;
+ $this->line->projet_title = $objp_projet->title_projet;
- $result = $ligne->update($user);
+ $this->applyOffset();
+ $this->checkRules();
+
+ $result = $this->line->update($user);
if ($result > 0)
{
$this->db->commit();
@@ -1647,8 +1921,8 @@ class ExpenseReport extends CommonObject
}
else
{
- $this->error=$ligne->error;
- $this->errors=$ligne->errors;
+ $this->error=$this->line->error;
+ $this->errors=$this->line->errors;
$this->db->rollback();
return -2;
}
@@ -1992,6 +2266,7 @@ class ExpenseReportLine
var $date;
var $fk_c_type_fees;
+ var $fk_c_exp_tax_cat;
var $fk_projet;
var $fk_expensereport;
@@ -2024,7 +2299,7 @@ class ExpenseReportLine
*/
function fetch($rowid)
{
- $sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_projet, fde.date,';
+ $sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_c_exp_tax_cat, fde.fk_projet, fde.date,';
$sql.= ' fde.tva_tx as vatrate, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,';
$sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
$sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
@@ -2046,8 +2321,10 @@ class ExpenseReportLine
$this->comments = $objp->comments;
$this->qty = $objp->qty;
$this->date = $objp->date;
+ $this->dates = $this->db->jdate($objp->date);
$this->value_unit = $objp->value_unit;
$this->fk_c_type_fees = $objp->fk_c_type_fees;
+ $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
$this->fk_projet = $objp->fk_projet;
$this->type_fees_code = $objp->type_fees_code;
$this->type_fees_libelle = $objp->type_fees_libelle;
@@ -2068,9 +2345,10 @@ class ExpenseReportLine
* insert
*
* @param int $notrigger 1=No trigger
+ * @param bool $fromaddline false=keep default behavior, true=exclude the update_price() of parent object
* @return int <0 if KO, >0 if OK
*/
- function insert($notrigger=0)
+ function insert($notrigger=0,$fromaddline=false)
{
global $langs,$user,$conf;
@@ -2083,12 +2361,13 @@ class ExpenseReportLine
if (!$this->value_unit_HT) $this->value_unit_HT=0;
$this->qty = price2num($this->qty);
$this->vatrate = price2num($this->vatrate);
-
+ if (empty($this->fk_c_exp_tax_cat)) $this->fk_c_exp_tax_cat = 0;
+
$this->db->begin();
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'expensereport_det';
$sql.= ' (fk_expensereport, fk_c_type_fees, fk_projet,';
- $sql.= ' tva_tx, comments, qty, value_unit, total_ht, total_tva, total_ttc, date)';
+ $sql.= ' tva_tx, comments, qty, value_unit, total_ht, total_tva, total_ttc, date, rule_warning_message, fk_c_exp_tax_cat)';
$sql.= " VALUES (".$this->fk_expensereport.",";
$sql.= " ".$this->fk_c_type_fees.",";
$sql.= " ".($this->fk_projet>0?$this->fk_projet:'null').",";
@@ -2099,7 +2378,9 @@ class ExpenseReportLine
$sql.= " ".$this->total_ht.",";
$sql.= " ".$this->total_tva.",";
$sql.= " ".$this->total_ttc.",";
- $sql.= "'".$this->db->idate($this->date)."'";
+ $sql.= "'".$this->db->idate($this->date)."',";
+ $sql.= " '".$this->db->escape($this->rule_warning_message)."',";
+ $sql.= " ".$this->fk_c_exp_tax_cat;
$sql.= ")";
dol_syslog("ExpenseReportLine::insert sql=".$sql);
@@ -2109,16 +2390,23 @@ class ExpenseReportLine
{
$this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'expensereport_det');
- $tmpparent=new ExpenseReport($this->db);
- $tmpparent->fetch($this->fk_expensereport);
- $result = $tmpparent->update_price();
- if ($result < 0)
- {
- $error++;
- $this->error = $tmpparent->error;
- $this->errors = $tmpparent->errors;
- }
+ if (! $fromaddline)
+ {
+ $tmpparent=new ExpenseReport($this->db);
+ $tmpparent->fetch($this->fk_expensereport);
+ $result = $tmpparent->update_price();
+ if ($result < 0)
+ {
+ $error++;
+ $this->error = $tmpparent->error;
+ $this->errors = $tmpparent->errors;
+ }
+ }
}
+ else
+ {
+ $error++;
+ }
if (! $error)
{
@@ -2133,7 +2421,50 @@ class ExpenseReportLine
return -2;
}
}
+
+ /**
+ * Function to get total amount in expense reports for a same rule
+ *
+ * @param ExpenseReportRule $rule object rule to check
+ * @param int $fk_user user author id
+ * @param string $mode day|EX_DAY / month|EX_MON / year|EX_YEA to get amount
+ * @return amount
+ */
+ public function getExpAmount(ExpenseReportRule $rule, $fk_user, $mode='day')
+ {
+ $amount = 0;
+
+ $sql = 'SELECT SUM(d.total_ttc) as total_amount';
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'expensereport_det d';
+ $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'expensereport e ON (d.fk_expensereport = e.rowid)';
+ $sql .= ' WHERE e.fk_user_author = '.$fk_user;
+ if (!empty($this->id)) $sql.= ' AND d.rowid <> '.$this->id;
+ $sql .= ' AND d.fk_c_type_fees = '.$rule->fk_c_type_fees;
+ if ($mode == 'day' || $mode == 'EX_DAY') $sql .= ' AND d.date = \''.dol_print_date($this->date, '%Y-%m-%d').'\'';
+ elseif ($mode == 'mon' || $mode == 'EX_MON') $sql .= ' AND DATE_FORMAT(d.date, \'%Y-%m\') = \''.dol_print_date($this->date, '%Y-%m').'\'';
+ elseif ($mode == 'year' || $mode == 'EX_YEA') $sql .= ' AND DATE_FORMAT(d.date, \'%Y\') = \''.dol_print_date($this->date, '%Y').'\'';
+
+ dol_syslog('ExpenseReportLine::getExpAmountByDay sql='.$sql);
+
+ $resql = $this->db->query($sql);
+ if ($resql)
+ {
+ $num = $this->db->num_rows($resql);
+ if ($num > 0)
+ {
+ $obj = $this->db->fetch_object($resql);
+ $amount = (double) $obj->total_amount;
+ }
+ }
+ else
+ {
+ dol_print_error($this->db);
+ }
+
+ return $amount + $this->total_ttc;
+ }
+
/**
* update
*
@@ -2150,6 +2481,7 @@ class ExpenseReportLine
$this->comments=trim($this->comments);
$this->vatrate = price2num($this->vatrate);
$this->value_unit = price2num($this->value_unit);
+ if (empty($this->fk_c_exp_tax_cat)) $this->fk_c_exp_tax_cat = 0;
$this->db->begin();
@@ -2163,6 +2495,8 @@ class ExpenseReportLine
$sql.= ",total_tva=".$this->total_tva."";
$sql.= ",total_ttc=".$this->total_ttc."";
$sql.= ",tva_tx=".$this->vatrate;
+ $sql.= ",rule_warning_message='".$this->db->escape($this->rule_warning_message)."'";
+ $sql.= ",fk_c_exp_tax_cat=".$this->fk_c_exp_tax_cat;
if ($this->fk_c_type_fees) $sql.= ",fk_c_type_fees=".$this->fk_c_type_fees;
else $sql.= ",fk_c_type_fees=null";
if ($this->fk_projet) $sql.= ",fk_projet=".$this->fk_projet;
diff --git a/htdocs/expensereport/class/expensereport_ik.class.php b/htdocs/expensereport/class/expensereport_ik.class.php
new file mode 100644
index 00000000000..775837692eb
--- /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_cat;
+
+ /**
+ * c_exp_tax_range id
+ * @var int
+ */
+ public $fk_range;
+
+ /**
+ * Coef
+ * @var double
+ */
+ public $coef;
+
+ /**
+ * Offset
+ * @var double
+ */
+ public $offset;
+
+ /**
+ * Attribute object linked with database
+ * @var array
+ */
+ protected $fields=array(
+ 'fk_cat'=>array('type'=>'integer','index'=>true)
+ ,'fk_range'=>array('type'=>'integer','index'=>true)
+ ,'coef'=>array('type'=>'double')
+ ,'offset'=>array('type'=>'double')
+ );
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct(DoliDB &$db)
+ {
+ global $conf;
+
+ parent::__construct($db);
+ parent::init();
+
+ $this->errors = array();
+ }
+
+
+ /**
+ * Return expense categories in array
+ *
+ * @param int $mode 1=only active; 2=only inactive; other value return all
+ * @return array of category
+ */
+ public static function getTaxCategories($mode=1)
+ {
+ global $db;
+
+ $categories = array();
+
+ $sql = 'SELECT rowid, label, entity, active';
+ $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat';
+ $sql.= ' WHERE entity IN (0,'. getEntity('').')';
+ if ($mode == 1) $sql.= ' AND active = 1';
+ elseif ($mode == 2) $sql.= 'AND active = 0';
+
+ dol_syslog(get_called_class().'::getTaxCategories sql='.$sql, LOG_DEBUG);
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ while ($obj = $db->fetch_object($resql))
+ {
+ $categories[$obj->rowid] = $obj;
+ }
+ }
+ else
+ {
+ dol_print_error($db);
+ }
+
+ return $categories;
+ }
+
+ public static function getRangeByUser(User $userauthor, $fk_c_exp_tax_cat)
+ {
+ $default_range = (int) $userauthor->default_range; // if not defined, then 0
+ $ranges = self::getRangesByCategory($fk_c_exp_tax_cat);
+
+ // substract 1 because array start from 0
+ if (empty($ranges) || !isset($ranges[$default_range-1])) return false;
+ else return $ranges[$default_range-1];
+ }
+
+ /**
+ * Return an array of ranges for a category
+ *
+ * @param int $fk_c_exp_tax_cat category id
+ * @param int $active active
+ * @return array
+ */
+ public static function getRangesByCategory($fk_c_exp_tax_cat, $active=1)
+ {
+ global $db;
+
+ $ranges = array();
+
+ $sql = 'SELECT r.rowid FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
+ if ($active) $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_cat = c.rowid)';
+ $sql.= ' WHERE r.fk_cat = '.$fk_c_exp_tax_cat;
+ if ($active) $sql.= ' AND r.active = 1 AND c.active = 1';
+ $sql.= ' ORDER BY r.range';
+
+ dol_syslog(get_called_class().'::getRangesByCategory sql='.$sql, LOG_DEBUG);
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $num = $db->num_rows($resql);
+ if ($num > 0)
+ {
+ while ($obj = $db->fetch_object($resql))
+ {
+ $object = new ExpenseReportIk($db);
+ $object->fetch($obj->rowid);
+
+ $ranges[] = $object;
+ }
+ }
+ }
+ else
+ {
+ dol_print_error($db);
+ }
+
+ return $ranges;
+ }
+
+ /**
+ * Return an array of ranges grouped by category
+ *
+ * @return array
+ */
+ public static function getAllRanges()
+ {
+ global $db;
+
+ $ranges = array();
+
+ $sql = ' SELECT r.rowid, r.fk_cat, r.range, c.label, i.rowid as fk_expense_ik, r.active as range_active, c.active as cat_active';
+ $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
+ $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_cat = c.rowid)';
+ $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport_ik i ON (r.rowid = i.fk_range)';
+ $sql.= ' WHERE r.entity IN (0, '. getEntity('').')';
+ $sql.= ' ORDER BY r.fk_cat, r.range';
+
+ dol_syslog(get_called_class().'::getAllRanges sql='.$sql, LOG_DEBUG);
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ while ($obj = $db->fetch_object($resql))
+ {
+ $ik = new ExpenseReportIk($db);
+ if ($obj->fk_expense_ik > 0) $ik->fetch($obj->fk_expense_ik);
+
+ $obj->ik = $ik;
+
+ if (!isset($ranges[$obj->fk_cat])) $ranges[$obj->fk_cat] = array('label' => $obj->label, 'active' => $obj->cat_active, 'ranges' => array());
+ $ranges[$obj->fk_cat]['ranges'][] = $obj;
+ }
+ }
+ else
+ {
+ dol_print_error($db);
+ }
+
+ return $ranges;
+ }
+
+ /**
+ * Return the max number of range by a category
+ *
+ * @param int $default_c_exp_tax_cat id
+ * @return int
+ */
+ public static function getMaxRangeNumber($default_c_exp_tax_cat=0)
+ {
+ global $db,$conf;
+
+ $sql = 'SELECT MAX(counted) as nbRange FROM (';
+ $sql.= ' SELECT COUNT(*) as counted';
+ $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
+ $sql.= ' WHERE r.entity IN (0, '.$conf->entity.')';
+ if ($default_c_exp_tax_cat > 0) $sql .= ' AND r.fk_cat = '.$default_c_exp_tax_cat;
+ $sql.= ' GROUP BY r.fk_cat';
+ $sql .= ') as counts';
+
+ dol_syslog(get_called_class().'::getMaxRangeNumber sql='.$sql, LOG_DEBUG);
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $obj = $db->fetch_object($resql);
+ return $obj->nbRange;
+ }
+ else
+ {
+ dol_print_error($db);
+ }
+
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/htdocs/expensereport/class/expensereport_rule.class.php b/htdocs/expensereport/class/expensereport_rule.class.php
new file mode 100644
index 00000000000..a8b43bb4479
--- /dev/null
+++ b/htdocs/expensereport/class/expensereport_rule.class.php
@@ -0,0 +1,236 @@
+
+ * 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(
+ '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 '';
+ }
+}
\ No newline at end of file
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..576d90236b5
--- /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, 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);
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..cb568fdc0c1
--- /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_cat,`range`, entity, active) values (1,4, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (2,4, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (3,4, 20000, 1, 1);
+
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (4,5, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (5,5, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (6,5, 20000, 1, 1);
+
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (7,6, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (8,6, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (9,6, 20000, 1, 1);
+
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (10,7, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (11,7, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (12,7, 20000, 1, 1);
+
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (13,8, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (14,8, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (15,8, 20000, 1, 1);
\ 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..3065133fbeb 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', 0, '625100'),
+('EX_FUE', 'ExpLabelFuelCV', 0, '606150'),
+('EX_HOT', 'ExpLabelHotel', 0, '625160'),
+('EX_PAR', 'ExpLabelParkingCV', 0, '625160'),
+('EX_TOL', 'ExpLabelTollCV', 0, '625160'),
+('EX_TAX', 'ExpLabelVariousTaxes', 0, '637800'),
+('EX_IND', 'ExpLabelIndemnityTransportationSubscription', 0, '648100'),
+('EX_SUM', 'ExpLabelMaintenanceSupply', 0, '606300'),
+('EX_SUO', 'ExpLabelOfficeSupplies', 0, '606400'),
+('EX_CAR', 'ExpLabelCarRental', 0, '613000'),
+('EX_DOC', 'ExpLabelDocumentation', 0, '618100'),
+('EX_CUR', 'ExpLabelCustomersReceiving', 0, '625710'),
+('EX_OTR', 'ExpLabelOtherReceiving', 0, '625700'),
+('EX_POS', 'ExpLabelPostage', 0, '626100'),
+('EX_CAM', 'ExpLabelMaintenanceRepairCV', 0, '615300'),
+('EX_EMM', 'ExpLabelEmployeesMeal', 0, '625160'),
+('EX_GUM', 'ExpLabelGuestsMeal', 0, '625160'),
+('EX_BRE', 'ExpLabelBreakfast', 0, '625160'),
+('EX_FUE_VP', 'ExpLabelFuelPV', 0, '606150'),
+('EX_TOL_VP', 'ExpLabelTollPV', 0, '625160'),
+('EX_PAR_VP', 'ExpLabelParkingPV', 0, '625160'),
+('EX_CAM_VP', 'ExpLabelMaintenanceRepairPV', 0, '615300');
\ 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..957e824bdca
--- /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_cat, fk_range, coef, offset) values (1,4, 1, 0.41, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (2,4, 2, 0.244, 824);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (3,4, 3, 0.286, 0);
+
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (4,5, 4, 0.493, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (5,5, 5, 0.277, 1082);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (6,5, 6, 0.332, 0);
+
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (7,6, 7, 0.543, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (8,6, 8, 0.305, 1180);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (9,6, 9, 0.364, 0);
+
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (10,7, 10, 0.568, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (11,7, 11, 0.32, 1244);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (12,7, 12, 0.382, 0);
+
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (13,8, 13, 0.595, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (14,8, 14, 0.337, 1288);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (15,8, 15, 0.401, 0);
\ No newline at end of file
diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql
index bc09bf25ca3..8a332d66f8f 100644
--- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql
+++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql
@@ -431,3 +431,138 @@ CREATE TABLE llx_blockedlog_authority
) ENGINE=innodb;
ALTER TABLE llx_blockedlog_authority ADD INDEX signature (signature);
+
+
+CREATE TABLE IF NOT EXISTS llx_expensereport_ik (
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ datec datetime DEFAULT NULL,
+ tms timestamp,
+ fk_cat integer DEFAULT 0 NOT NULL,
+ fk_range integer DEFAULT 0 NOT NULL,
+ coef double DEFAULT 0 NOT NULL,
+ offset double DEFAULT 0 NOT NULL
+)ENGINE=innodb DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS llx_c_exp_tax_cat (
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ label varchar(48) NOT NULL,
+ entity integer DEFAULT 1 NOT NULL,
+ active integer DEFAULT 1 NOT NULL
+)ENGINE=innodb DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS llx_c_exp_tax_range (
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ fk_cat integer DEFAULT 1 NOT NULL,
+ `range` double DEFAULT 0 NOT NULL,
+ entity integer DEFAULT 1 NOT NULL,
+ active integer DEFAULT 1 NOT NULL
+)ENGINE=innodb DEFAULT CHARSET=utf8;
+
+INSERT INTO llx_c_type_fees (code, label, active, accountancy_code) VALUES
+('EX_KME', 'ExpLabelKm', 0, '625100'),
+('EX_FUE', 'ExpLabelFuelCV', 0, '606150'),
+('EX_HOT', 'ExpLabelHotel', 0, '625160'),
+('EX_PAR', 'ExpLabelParkingCV', 0, '625160'),
+('EX_TOL', 'ExpLabelTollCV', 0, '625160'),
+('EX_TAX', 'ExpLabelVariousTaxes', 0, '637800'),
+('EX_IND', 'ExpLabelIndemnityTransportationSubscription', 0, '648100'),
+('EX_SUM', 'ExpLabelMaintenanceSupply', 0, '606300'),
+('EX_SUO', 'ExpLabelOfficeSupplies', 0, '606400'),
+('EX_CAR', 'ExpLabelCarRental', 0, '613000'),
+('EX_DOC', 'ExpLabelDocumentation', 0, '618100'),
+('EX_CUR', 'ExpLabelCustomersReceiving', 0, '625710'),
+('EX_OTR', 'ExpLabelOtherReceiving', 0, '625700'),
+('EX_POS', 'ExpLabelPostage', 0, '626100'),
+('EX_CAM', 'ExpLabelMaintenanceRepairCV', 0, '615300'),
+('EX_EMM', 'ExpLabelEmployeesMeal', 0, '625160'),
+('EX_GUM', 'ExpLabelGuestsMeal', 0, '625160'),
+('EX_BRE', 'ExpLabelBreakfast', 0, '625160'),
+('EX_FUE_VP', 'ExpLabelFuelPV', 0, '606150'),
+('EX_TOL_VP', 'ExpLabelTollPV', 0, '625160'),
+('EX_PAR_VP', 'ExpLabelParkingPV', 0, '625160'),
+('EX_CAM_VP', 'ExpLabelMaintenanceRepairPV', 0, '615300');
+
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (1,4, 1, 0.41, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (2,4, 2, 0.244, 824);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (3,4, 3, 0.286, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (4,5, 4, 0.493, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (5,5, 5, 0.277, 1082);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (6,5, 6, 0.332, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (7,6, 7, 0.543, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (8,6, 8, 0.305, 1180);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (9,6, 9, 0.364, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (10,7, 10, 0.568, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (11,7, 11, 0.32, 1244);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (12,7, 12, 0.382, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (13,8, 13, 0.595, 0);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (14,8, 14, 0.337, 1288);
+INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (15,8, 15, 0.401, 0);
+
+
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (1,'ExpAutoCat', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (2,'ExpCycloCat', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (3,'ExpMotoCat', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (4,'ExpAuto3CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (5,'ExpAuto4CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (6,'ExpAuto5CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (7,'ExpAuto6CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (8,'ExpAuto7CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (9,'ExpAuto8CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (10,'ExpAuto9CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (11,'ExpAuto10CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (12,'ExpAuto11CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (13,'ExpAuto12CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (14,'ExpAuto3PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (15,'ExpAuto4PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (16,'ExpAuto5PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (17,'ExpAuto6PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (18,'ExpAuto7PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (19,'ExpAuto8PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (20,'ExpAuto9PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (21,'ExpAuto10PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (22,'ExpAuto11PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (23,'ExpAuto12PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (24,'ExpAuto13PCV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (25,'ExpCyclo', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (26,'ExpMoto12CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (27,'ExpMoto345CV', 1, 1);
+INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (28,'ExpMoto5PCV', 1, 1);
+
+
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (1,4, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (2,4, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (3,4, 20000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (4,5, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (5,5, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (6,5, 20000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (7,6, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (8,6, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (9,6, 20000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (10,7, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (11,7, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (12,7, 20000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (13,8, 0, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (14,8, 5000, 1, 1);
+INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (15,8, 20000, 1, 1);
+
+CREATE TABLE `llx_expensereport_rules` (
+ `rowid` integer AUTO_INCREMENT PRIMARY KEY,
+ `datec` datetime DEFAULT NULL,
+ `tms` timestamp,
+ `dates` datetime NOT NULL,
+ `datee` datetime NOT NULL,
+ `amount` numeric(24,8) NOT NULL,
+ `restrictive` tinyint(1) NOT NULL,
+ `fk_user` integer DEFAULT NULL,
+ `fk_usergroup` integer DEFAULT NULL,
+ `fk_c_type_fees` integer NOT NULL,
+ `code_expense_rules_type` varchar(50) NOT NULL,
+ `is_for_all` tinyint(1) DEFAULT '0',
+ `entity` integer DEFAULT 1
+);
+
+ALTER TABLE llx_expensereport_det ADD COLUMN rule_warning_message text;
+ALTER TABLE llx_expensereport_det ADD COLUMN fk_c_exp_tax_cat integer;
+
+ALTER TABLE llx_user ADD COLUMN default_range integer;
+ALTER TABLE llx_user ADD COLUMN default_c_exp_tax_cat integer;
\ No newline at end of file
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..15c9d4ce35b
--- /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_cat integer DEFAULT 1 NOT NULL,
+ `range` double DEFAULT 0 NOT NULL,
+ entity integer DEFAULT 1 NOT NULL,
+ active integer DEFAULT 1 NOT NULL
+)ENGINE=innodb DEFAULT CHARSET=utf8;
diff --git a/htdocs/install/mysql/tables/llx_expensereport_det.sql b/htdocs/install/mysql/tables/llx_expensereport_det.sql
index 069cd534e4f..9b30932ee7a 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,
@@ -49,5 +50,6 @@ CREATE TABLE llx_expensereport_det
fk_facture integer DEFAULT 0, -- ID of customer invoice line if expense is rebilled to a customer
fk_code_ventilation integer DEFAULT 0,
rang integer DEFAULT 0, -- position of line
- import_key varchar(14)
+ import_key varchar(14),
+ rule_warning_message text
) ENGINE=innodb;
\ 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..c2d0999c6d6
--- /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_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..1045a29b70a
--- /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(1) NOT NULL,
+ `fk_user` integer DEFAULT NULL,
+ `fk_usergroup` integer DEFAULT NULL,
+ `fk_c_type_fees` integer NOT NULL,
+ `code_expense_rules_type` varchar(50) NOT NULL,
+ `is_for_all` tinyint(1) DEFAULT '0',
+ `entity` integer DEFAULT 1
+) ENGINE=InnoDB
\ 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 d033ba5eca4..93d39f83b0d 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 695373e22b5..641466b9337 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -873,6 +873,8 @@ DictionaryUnits=Units
DictionaryProspectStatus=Prospection status
DictionaryHolidayTypes=Types of leaves
DictionaryOpportunityStatus=Opportunity status for project/lead
+DictionaryExpenseTaxCat=Expense report categories
+DictionaryExpenseTaxRange=Expense report range by category
SetupSaved=Setup saved
SetupNotSaved=Setup not saved
BackToModuleList=Back to modules list
@@ -1139,6 +1141,8 @@ RuleForGeneratedPasswords=Rule to generate suggested passwords or validate passw
DisableForgetPasswordLinkOnLogonPage=Do not show the link "Forget password" on login page
UsersSetup=Users module setup
UserMailRequired=EMail required to create a new user
+DefaultCategoryCar=Default car category
+DefaultRangeNumber=Default range number
##### HRM setup #####
HRMSetup=HRM module setup
##### Company setup #####
@@ -1607,6 +1611,8 @@ TypePaymentDesc=0:Customer payment type, 1:Supplier payment type, 2:Both custome
IncludePath=Include path (defined into variable %s)
ExpenseReportsSetup=Setup of module Expense Reports
TemplatePDFExpenseReports=Document templates to generate expense report document
+ExpenseReportsIkSetup=Setup of module Expense Reports - Milles index
+ExpenseReportsRulesSetup=Setup of module Expense Reports - Rules
NoModueToManageStockIncrease=No module able to manage automatic stock increase has been activated. Stock increase will be done on manual input only.
YouMayFindNotificationsFeaturesIntoModuleNotification=You may find options for EMail notifications by enabling and configuring the module "Notification".
ListOfNotificationsPerUser=List of notifications per user*
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..75b0d18e56f 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,43 @@ ExpenseReportPayment=Expense report payment
ExpenseReportsToApprove=Expense reports to approve
ExpenseReportsToPay=Expense reports to pay
CloneExpenseReport=Clone expense report
-ConfirmCloneExpenseReport=Are you sure you want to clone this expense report ?
\ 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=Contraint violation id [%s]: %s is superior to %s %s
+byEX_DAY=by day (limitation to %s)
+byEX_MON=by month (limitation to %s)
+byEX_YEA=by year (limitation to %s)
+byEX_EXP=by line (limitation to %s)
+ExpenseReportConstraintViolationWarning=Contraint violation id [%s]: %s is superior to %s %s
+nolimitbyEX_DAY=by day (no limitation)
+nolimitbyEX_MON=by month (no limitation)
+nolimitbyEX_YEA=by year (no limitation)
+nolimitbyEX_EXP=by line (no limitation)
+
+CarCategory=Category of car
+ExpenseRangeOffset=Offset amount: %s
\ No newline at end of file
diff --git a/htdocs/user/card.php b/htdocs/user/card.php
index 089820da442..2ebd93d05da 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 '