30require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
31require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
32require_once DOL_DOCUMENT_ROOT.
'/expensereport/class/expensereport_ik.class.php';
33require_once DOL_DOCUMENT_ROOT.
'/expensereport/class/expensereport_rule.class.php';
44 public $element =
'expensereport';
49 public $table_element =
'expensereport';
54 public $table_element_line =
'expensereport_det';
59 public $fk_element =
'fk_expensereport';
64 public $picto =
'trip';
69 public $lines = array();
89 public $date_approbation;
99 public $user_approve_id;
119 public $fk_c_paiement;
124 public $modepaymentid;
132 public $user_paid_infos;
137 public $user_author_infos;
142 public $user_validator_infos;
144 public $rule_warning_message;
157 public $fk_user_creat;
162 public $fk_user_author;
173 public $fk_user_modif;
184 public $detail_refuse;
189 public $fk_user_refuse;
200 public $detail_cancel;
205 public $fk_user_cancel;
210 public $fk_user_validator;
229 public $fk_user_valid;
234 public $user_valid_infos;
240 public $date_approve;
245 public $fk_user_approve;
280 public $fields = array(
281 'rowid' => array(
'type' =>
'integer',
'label' =>
'ID',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 10),
282 'ref' => array(
'type' =>
'varchar(50)',
'label' =>
'Ref',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'showoncombobox' => 1,
'position' => 15),
283 'entity' => array(
'type' =>
'integer',
'label' =>
'Entity',
'default' =>
'1',
'enabled' => 1,
'visible' => -2,
'notnull' => 1,
'position' => 20),
284 'ref_number_int' => array(
'type' =>
'integer',
'label' =>
'Ref number int',
'enabled' => 1,
'visible' => -1,
'position' => 25),
285 'ref_ext' => array(
'type' =>
'integer',
'label' =>
'Ref ext',
'enabled' => 1,
'visible' => -1,
'position' => 30),
286 'total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'Total ht',
'enabled' => 1,
'visible' => -1,
'position' => 35),
287 'total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'Total tva',
'enabled' => 1,
'visible' => -1,
'position' => 40),
288 'localtax1' => array(
'type' =>
'double(24,8)',
'label' =>
'Localtax1',
'enabled' => 1,
'visible' => -1,
'position' => 45),
289 'localtax2' => array(
'type' =>
'double(24,8)',
'label' =>
'Localtax2',
'enabled' => 1,
'visible' => -1,
'position' => 50),
290 'total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'Total ttc',
'enabled' => 1,
'visible' => -1,
'position' => 55),
291 'date_debut' => array(
'type' =>
'date',
'label' =>
'Date debut',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 60),
292 'date_fin' => array(
'type' =>
'date',
'label' =>
'Date fin',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 65),
293 'date_valid' => array(
'type' =>
'datetime',
'label' =>
'Date valid',
'enabled' => 1,
'visible' => -1,
'position' => 75),
294 'date_approve' => array(
'type' =>
'datetime',
'label' =>
'Date approve',
'enabled' => 1,
'visible' => -1,
'position' => 80),
295 'date_refuse' => array(
'type' =>
'datetime',
'label' =>
'Date refuse',
'enabled' => 1,
'visible' => -1,
'position' => 85),
296 'date_cancel' => array(
'type' =>
'datetime',
'label' =>
'Date cancel',
'enabled' => 1,
'visible' => -1,
'position' => 90),
297 'fk_user_author' => array(
'type' =>
'integer',
'label' =>
'Fk user author',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 100),
298 'fk_user_modif' => array(
'type' =>
'integer',
'label' =>
'Fk user modif',
'enabled' => 1,
'visible' => -1,
'position' => 105),
299 'fk_user_valid' => array(
'type' =>
'integer',
'label' =>
'Fk user valid',
'enabled' => 1,
'visible' => -1,
'position' => 110),
300 'fk_user_validator' => array(
'type' =>
'integer',
'label' =>
'Fk user validator',
'enabled' => 1,
'visible' => -1,
'position' => 115),
301 'fk_user_approve' => array(
'type' =>
'integer',
'label' =>
'Fk user approve',
'enabled' => 1,
'visible' => -1,
'position' => 120),
302 'fk_user_refuse' => array(
'type' =>
'integer',
'label' =>
'Fk user refuse',
'enabled' => 1,
'visible' => -1,
'position' => 125),
303 'fk_user_cancel' => array(
'type' =>
'integer',
'label' =>
'Fk user cancel',
'enabled' => 1,
'visible' => -1,
'position' => 130),
304 'fk_c_paiement' => array(
'type' =>
'integer',
'label' =>
'Fk c paiement',
'enabled' => 1,
'visible' => -1,
'position' => 140),
305 'paid' => array(
'type' =>
'integer',
'label' =>
'Paid',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 145),
306 'note_public' => array(
'type' =>
'html',
'label' =>
'Note public',
'enabled' => 1,
'visible' => 0,
'position' => 150),
307 'note_private' => array(
'type' =>
'html',
'label' =>
'Note private',
'enabled' => 1,
'visible' => 0,
'position' => 155),
308 'detail_refuse' => array(
'type' =>
'varchar(255)',
'label' =>
'Detail refuse',
'enabled' => 1,
'visible' => -1,
'position' => 160),
309 'detail_cancel' => array(
'type' =>
'varchar(255)',
'label' =>
'Detail cancel',
'enabled' => 1,
'visible' => -1,
'position' => 165),
310 'integration_compta' => array(
'type' =>
'integer',
'label' =>
'Integration compta',
'enabled' => 1,
'visible' => -1,
'position' => 170),
311 'fk_bank_account' => array(
'type' =>
'integer',
'label' =>
'Fk bank account',
'enabled' => 1,
'visible' => -1,
'position' => 175),
312 'fk_multicurrency' => array(
'type' =>
'integer',
'label' =>
'Fk multicurrency',
'enabled' => 1,
'visible' => -1,
'position' => 185),
313 'multicurrency_code' => array(
'type' =>
'varchar(255)',
'label' =>
'Multicurrency code',
'enabled' => 1,
'visible' => -1,
'position' => 190),
314 'multicurrency_tx' => array(
'type' =>
'double(24,8)',
'label' =>
'Multicurrency tx',
'enabled' => 1,
'visible' => -1,
'position' => 195),
315 'multicurrency_total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'Multicurrency total ht',
'enabled' => 1,
'visible' => -1,
'position' => 200),
316 'multicurrency_total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'Multicurrency total tva',
'enabled' => 1,
'visible' => -1,
'position' => 205),
317 'multicurrency_total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'Multicurrency total ttc',
'enabled' => 1,
'visible' => -1,
'position' => 210),
318 'extraparams' => array(
'type' =>
'varchar(255)',
'label' =>
'Extraparams',
'enabled' => 1,
'visible' => -1,
'position' => 220),
319 'date_create' => array(
'type' =>
'datetime',
'label' =>
'Date create',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 300),
320 'tms' => array(
'type' =>
'timestamp',
'label' =>
'Tms',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 305),
321 'import_key' => array(
'type' =>
'varchar(14)',
'label' =>
'ImportId',
'enabled' => 1,
'visible' => -1,
'position' => 1000),
322 'model_pdf' => array(
'type' =>
'varchar(255)',
'label' =>
'Model pdf',
'enabled' => 1,
'visible' => 0,
'position' => 1010),
323 'fk_statut' => array(
'type' =>
'integer',
'label' =>
'Fk statut',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 500),
335 $this->total_ttc = 0;
336 $this->total_tva = 0;
337 $this->total_localtax1 = 0;
338 $this->total_localtax2 = 0;
339 $this->localtax1 = 0;
340 $this->localtax2 = 0;
341 $this->modepaymentid = 0;
344 $this->labelStatusShort = array(0 =>
'Draft', 2 =>
'Validated', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
345 $this->labelStatus = array(0 =>
'Draft', 2 =>
'ValidatedWaitingApproval', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
355 public function create($user, $notrigger = 0)
357 global $conf, $langs;
364 if (empty($this->date_debut) || empty($this->date_fin)) {
365 $this->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
'Date'));
369 $fuserid = $this->fk_user_author;
370 if (empty($fuserid)) {
371 $fuserid = $user->id;
376 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
" (";
379 $sql .=
",total_ttc";
380 $sql .=
",total_tva";
381 $sql .=
",date_debut";
383 $sql .=
",date_create";
384 $sql .=
",fk_user_creat";
385 $sql .=
",fk_user_author";
386 $sql .=
",fk_user_validator";
387 $sql .=
",fk_user_approve";
388 $sql .=
",fk_user_modif";
389 $sql .=
",fk_statut";
390 $sql .=
",fk_c_paiement";
392 $sql .=
",note_public";
393 $sql .=
",note_private";
397 $sql .=
", ".price2num($this->total_ht,
'MT');
398 $sql .=
", ".price2num($this->total_ttc,
'MT');
399 $sql .=
", ".price2num($this->total_tva,
'MT');
400 $sql .=
", '".$this->db->idate($this->date_debut).
"'";
401 $sql .=
", '".$this->db->idate($this->date_fin).
"'";
402 $sql .=
", '".$this->db->idate($now).
"'";
403 $sql .=
", ".((int) $user->id);
404 $sql .=
", ".((int) $fuserid);
405 $sql .=
", ".($this->fk_user_validator > 0 ? ((int) $this->fk_user_validator) :
"null");
406 $sql .=
", ".($this->fk_user_approve > 0 ? ((int) $this->fk_user_approve) :
"null");
407 $sql .=
", ".($this->fk_user_modif > 0 ? ((int) $this->fk_user_modif) :
"null");
408 $sql .=
", ".($this->fk_statut > 1 ? ((int) $this->fk_statut) : 0);
409 $sql .=
", ".($this->modepaymentid ? ((int) $this->modepaymentid) :
"null");
411 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
"null");
412 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
"null");
413 $sql .=
", ".((int) $conf->entity);
416 $result = $this->db->query($sql);
418 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
419 $this->
ref =
'(PROV'.$this->id.
')';
421 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
" SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
422 $resql = $this->db->query($sql);
424 $this->error = $this->db->lasterror();
429 if (is_array($this->lines) && count($this->lines) > 0) {
430 foreach ($this->lines as $line) {
433 if (!is_object($line)) {
434 $line = (object) $line;
436 $newndfline->fk_expensereport = $line->fk_expensereport;
437 $newndfline->fk_c_type_fees = $line->fk_c_type_fees;
438 $newndfline->fk_project = $line->fk_project;
439 $newndfline->vatrate = $line->vatrate;
440 $newndfline->vat_src_code = $line->vat_src_code;
441 $newndfline->localtax1_tx = $line->localtax1_tx;
442 $newndfline->localtax2_tx = $line->localtax2_tx;
443 $newndfline->localtax1_type = $line->localtax1_type;
444 $newndfline->localtax2_type = $line->localtax2_type;
445 $newndfline->comments = $line->comments;
446 $newndfline->qty = $line->qty;
447 $newndfline->value_unit = $line->value_unit;
448 $newndfline->total_ht = $line->total_ht;
449 $newndfline->total_ttc = $line->total_ttc;
450 $newndfline->total_tva = $line->total_tva;
451 $newndfline->total_localtax1 = $line->total_localtax1;
452 $newndfline->total_localtax2 = $line->total_localtax2;
453 $newndfline->date = $line->date;
454 $newndfline->rule_warning_message = $line->rule_warning_message;
455 $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat;
456 $newndfline->fk_ecm_files = $line->fk_ecm_files;
461 $newndfline->fk_expensereport = $this->id;
462 $result = $newndfline->insert();
464 $this->error = $newndfline->error;
465 $this->errors = $newndfline->errors;
485 $result = $this->
call_trigger(
'EXPENSE_REPORT_CREATE', $user);
497 $this->db->rollback();
501 $this->db->rollback();
505 dol_syslog(get_class($this).
"::create error ".$this->error, LOG_ERR);
506 $this->db->rollback();
510 $this->error = $this->db->lasterror().
" sql=".$sql;
511 $this->db->rollback();
529 if (empty($fk_user_author)) {
530 $fk_user_author = $user->id;
540 $objFrom = clone $this;
545 $this->fk_statut = 0;
548 $this->fk_user_creat = $user->id;
549 $this->fk_user_author = $fk_user_author;
550 $this->fk_user_valid = 0;
551 $this->date_create =
'';
552 $this->date_creation =
'';
553 $this->date_validation =
'';
556 if (is_array($this->lines) && count($this->lines) > 0) {
557 foreach ($this->lines as $key => $line) {
558 $this->lines[$key]->fk_ecm_files = 0;
563 $this->context[
'createfromclone'] =
'createfromclone';
564 $result = $this->
create($user);
571 if (is_object($hookmanager)) {
572 $parameters = array(
'objFrom' => $objFrom);
574 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
582 unset($this->context[
'createfromclone']);
589 $this->db->rollback();
603 public function update($user, $notrigger = 0, $userofexpensereport =
null)
610 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
611 $sql .=
" total_ht = ".$this->total_ht;
612 $sql .=
" , total_ttc = ".$this->total_ttc;
613 $sql .=
" , total_tva = ".$this->total_tva;
614 $sql .=
" , date_debut = '".$this->db->idate($this->date_debut).
"'";
615 $sql .=
" , date_fin = '".$this->db->idate($this->date_fin).
"'";
616 if ($userofexpensereport && is_object($userofexpensereport)) {
617 $sql .=
" , fk_user_author = ".($userofexpensereport->id > 0 ? $userofexpensereport->id :
"null");
619 $sql .=
" , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator :
"null");
620 $sql .=
" , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid :
"null");
621 $sql .=
" , fk_user_approve = ".($this->fk_user_approve > 0 ? $this->fk_user_approve :
"null");
622 $sql .=
" , fk_user_modif = ".$user->id;
623 $sql .=
" , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut :
'0');
624 $sql .=
" , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement :
"null");
625 $sql .=
" , note_public = ".(!empty($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"''");
626 $sql .=
" , note_private = ".(!empty($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"''");
627 $sql .=
" , detail_refuse = ".(!empty($this->detail_refuse) ?
"'".$this->db->escape($this->detail_refuse).
"'" :
"''");
628 $sql .=
" WHERE rowid = ".((int) $this->
id);
630 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
631 $result = $this->db->query($sql);
635 $result = $this->
call_trigger(
'EXPENSE_REPORT_MODIFY', $user);
647 $this->db->rollback();
648 $this->error = $this->db->error();
652 $this->db->rollback();
653 $this->error = $this->db->error();
665 public function fetch($id, $ref =
'')
667 $sql =
"SELECT d.rowid, d.entity, d.ref, d.note_public, d.note_private,";
668 $sql .=
" d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,";
669 $sql .=
" d.date_refuse, d.date_cancel,";
670 $sql .=
" d.total_ht, d.total_ttc, d.total_tva,";
671 $sql .=
" d.localtax1 as total_localtax1, d.localtax2 as total_localtax2,";
672 $sql .=
" d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,";
673 $sql .=
" d.fk_user_creat, d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
674 $sql .=
" d.fk_user_valid, d.fk_user_approve,";
675 $sql .=
" d.fk_statut as status, d.fk_c_paiement, d.paid";
676 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as d";
678 $sql .=
" WHERE d.ref = '".$this->db->escape($ref).
"'";
680 $sql .=
" WHERE d.rowid = ".((int) $id);
684 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
685 $resql = $this->db->query($sql);
687 $obj = $this->db->fetch_object($resql);
689 $this->
id = $obj->rowid;
690 $this->
ref = $obj->ref;
692 $this->entity = $obj->entity;
694 $this->total_ht = $obj->total_ht;
695 $this->total_tva = $obj->total_tva;
696 $this->total_ttc = $obj->total_ttc;
697 $this->localtax1 = $obj->total_localtax1;
698 $this->localtax2 = $obj->total_localtax2;
699 $this->total_localtax1 = $obj->total_localtax1;
700 $this->total_localtax2 = $obj->total_localtax2;
702 $this->note_public = $obj->note_public;
703 $this->note_private = $obj->note_private;
704 $this->detail_refuse = $obj->detail_refuse;
705 $this->detail_cancel = $obj->detail_cancel;
707 $this->date_debut = $this->db->jdate($obj->date_debut);
708 $this->date_fin = $this->db->jdate($obj->date_fin);
709 $this->date_valid = $this->db->jdate($obj->date_valid);
710 $this->date_approve = $this->db->jdate($obj->date_approve);
711 $this->date_create = $this->db->jdate($obj->date_create);
712 $this->date_modif = $this->db->jdate($obj->date_modif);
713 $this->date_refuse = $this->db->jdate($obj->date_refuse);
714 $this->date_cancel = $this->db->jdate($obj->date_cancel);
716 $this->fk_user_creat = $obj->fk_user_creat;
717 $this->fk_user_author = $obj->fk_user_author;
718 $this->fk_user_modif = $obj->fk_user_modif;
719 $this->fk_user_validator = $obj->fk_user_validator;
720 $this->fk_user_valid = $obj->fk_user_valid;
721 $this->fk_user_refuse = $obj->fk_user_refuse;
722 $this->fk_user_cancel = $obj->fk_user_cancel;
723 $this->fk_user_approve = $obj->fk_user_approve;
725 $user_author =
new User($this->db);
726 if ($this->fk_user_author > 0) {
727 $user_author->fetch($this->fk_user_author);
730 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
732 $user_approver =
new User($this->db);
733 if ($this->fk_user_approve > 0) {
734 $user_approver->fetch($this->fk_user_approve);
735 } elseif ($this->fk_user_validator > 0) {
736 $user_approver->fetch($this->fk_user_validator);
738 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
740 $this->fk_statut = $obj->status;
741 $this->
status = $obj->status;
742 $this->fk_c_paiement = $obj->fk_c_paiement;
743 $this->paid = $obj->paid;
745 if ($this->
status == self::STATUS_APPROVED || $this->
status == self::STATUS_CLOSED) {
746 $user_valid =
new User($this->db);
747 if ($this->fk_user_valid > 0) {
748 $user_valid->fetch($this->fk_user_valid);
750 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
762 $this->error = $this->db->lasterror();
778 public function set_paid($id, $fuser, $notrigger = 0)
781 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
782 return $this->
setPaid($id, $fuser, $notrigger);
793 public function setPaid($id, $fuser, $notrigger = 0)
798 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
799 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid=1";
802 dol_syslog(get_class($this).
"::setPaid", LOG_DEBUG);
803 $resql = $this->db->query($sql);
805 if ($this->db->affected_rows($resql)) {
808 $result = $this->
call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
820 $this->db->rollback();
821 $this->error = $this->db->error();
829 $this->db->rollback();
859 $labelStatus = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
860 $labelStatusShort = $langs->transnoentitiesnoconv($this->labelStatusShort[$status]);
862 $statuslogo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
864 $statusType = $statuslogo[$status];
866 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
880 $sql =
"SELECT f.rowid,";
881 $sql .=
" f.date_create as datec,";
882 $sql .=
" f.tms as date_modification,";
883 $sql .=
" f.date_valid as datev,";
884 $sql .=
" f.date_approve as datea,";
885 $sql .=
" f.fk_user_creat as fk_user_creation,";
886 $sql .=
" f.fk_user_author as fk_user_author,";
887 $sql .=
" f.fk_user_modif as fk_user_modification,";
888 $sql .=
" f.fk_user_valid,";
889 $sql .=
" f.fk_user_approve";
890 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
891 $sql .=
" WHERE f.rowid = ".((int) $id);
892 $sql .=
" AND f.entity = ".$conf->entity;
896 $resql = $this->db->query($sql);
898 if ($this->db->num_rows($resql)) {
899 $obj = $this->db->fetch_object($resql);
901 $this->
id = $obj->rowid;
903 $this->date_creation = $this->db->jdate($obj->datec);
904 $this->date_modification = $this->db->jdate($obj->date_modification);
905 $this->date_validation = $this->db->jdate($obj->datev);
906 $this->date_approbation = $this->db->jdate($obj->datea);
908 $this->user_creation_id = $obj->fk_user_author;
909 $this->user_creation_id = $obj->fk_user_creation;
910 $this->user_validation_id = $obj->fk_user_valid;
911 $this->user_modification_id = $obj->fk_user_modification;
912 $this->user_approve_id = $obj->fk_user_approve;
914 $this->db->free($resql);
931 global $user, $langs;
937 $this->
ref =
'SPECIMEN';
940 $this->date_create = $now;
941 $this->date_debut = $now;
942 $this->date_fin = $now;
943 $this->date_valid = $now;
944 $this->date_approve = $now;
950 $this->fk_user_author = $user->id;
951 $this->fk_user_validator = $user->id;
952 $this->fk_user_valid = $user->id;
953 $this->fk_user_approve = $user->id;
955 $this->note_private =
'Private note';
956 $this->note_public =
'SPECIMEN';
959 while ($xnbp < $nbp) {
961 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
962 $line->date = ($now - 3600 * (1 + $xnbp));
963 $line->total_ht = 100;
964 $line->total_tva = 20;
965 $line->total_ttc = 120;
968 $line->value_unit = 120;
969 $line->fk_expensereport = 0;
970 $line->type_fees_code =
'TRA';
971 $line->fk_c_type_fees = $type_fees_id;
973 $line->projet_ref =
'ABC';
975 $this->lines[$xnbp] = $line;
978 $this->total_ht += $line->total_ht;
979 $this->total_tva += $line->total_tva;
980 $this->total_ttc += $line->total_ttc;
999 $langs->load(
'trips');
1001 if ($user->hasRight(
'expensereport',
'lire')) {
1002 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
1003 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
1004 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
1006 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1007 $result = $this->db->query($sql);
1009 $num = $this->db->num_rows($result);
1015 $objp = $this->db->fetch_object($result);
1017 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
1018 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
1019 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
1021 $result2 = $this->db->query($sql2);
1022 $obj = $this->db->fetch_object($result2);
1024 $objp->fk_user_author = $obj->fk_user_author;
1025 $objp->ref = $obj->ref;
1026 $objp->fk_c_expensereport_status = $obj->status;
1027 $objp->rowid = $obj->rowid;
1029 $total_HT += $objp->total_ht;
1030 $total_TTC += $objp->total_ttc;
1031 $author =
new User($this->db);
1032 $author->fetch($objp->fk_user_author);
1035 print
'<td><a href="'.DOL_URL_ROOT.
'/expensereport/card.php?id='.$objp->rowid.
'">'.$objp->ref_num.
'</a></td>';
1036 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
1037 print
'<td>'.$author->getNomUrl(1).
'</td>';
1038 print
'<td>'.$objp->comments.
'</td>';
1039 print
'<td class="right">'.price($objp->total_ht).
'</td>';
1040 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
1041 print
'<td class="right">';
1043 switch ($objp->fk_c_expensereport_status) {
1045 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
1048 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
1051 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
1054 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
1057 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
1074 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
1075 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
1076 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
1077 print
'<td> </td>';
1080 $this->error = $this->db->lasterror();
1097 $this->lines = array();
1099 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1100 $sql .=
" de.".$this->fk_element.
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1101 $sql .=
' de.tva_tx, de.vat_src_code,';
1102 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1103 $sql .=
' de.fk_ecm_files,';
1104 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1105 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1106 $sql .=
' ctf.code as code_type_fees, ctf.label as label_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1107 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1108 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as de';
1109 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1110 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1111 $sql .=
" WHERE de.".$this->fk_element.
" = ".((int) $this->
id);
1113 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1115 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1118 $resql = $this->db->query($sql);
1120 $num = $this->db->num_rows($resql);
1123 $objp = $this->db->fetch_object($resql);
1127 $deplig->rowid = $objp->rowid;
1128 $deplig->id = $objp->rowid;
1129 $deplig->comments = $objp->comments;
1130 $deplig->qty = $objp->qty;
1131 $deplig->value_unit = $objp->value_unit;
1132 $deplig->date = $objp->date;
1133 $deplig->dates = $this->db->jdate($objp->date);
1135 $deplig->fk_expensereport = $objp->fk_expensereport;
1136 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1137 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1138 $deplig->fk_projet = $objp->fk_project;
1139 $deplig->fk_project = $objp->fk_project;
1140 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1142 $deplig->total_ht = $objp->total_ht;
1143 $deplig->total_tva = $objp->total_tva;
1144 $deplig->total_ttc = $objp->total_ttc;
1145 $deplig->total_localtax1 = $objp->total_localtax1;
1146 $deplig->total_localtax2 = $objp->total_localtax2;
1148 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1149 $deplig->type_fees_libelle = $objp->label_type_fees;
1150 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1152 $deplig->tva_tx = $objp->tva_tx;
1153 $deplig->vatrate = $objp->tva_tx;
1154 $deplig->vat_src_code = $objp->vat_src_code;
1155 $deplig->localtax1_tx = $objp->localtax1_tx;
1156 $deplig->localtax2_tx = $objp->localtax2_tx;
1157 $deplig->localtax1_type = $objp->localtax1_type;
1158 $deplig->localtax2_type = $objp->localtax2_type;
1160 $deplig->projet_ref = $objp->ref_projet;
1161 $deplig->projet_title = $objp->title_projet;
1163 $deplig->rule_warning_message = $objp->rule_warning_message;
1165 $deplig->rang = $objp->rang;
1167 $this->lines[$i] = $deplig;
1171 $this->db->free($resql);
1174 $this->error = $this->db->lasterror();
1175 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1188 public function delete(
User $user =
null, $notrigger = 0)
1191 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1199 $result = $this->
call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1207 if (!$error && !empty($this->table_element_line)) {
1208 $tabletodelete = $this->table_element_line;
1210 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1211 if (!$this->db->query($sql)) {
1213 $this->error = $this->db->lasterror();
1214 $this->errors[] = $this->error;
1215 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1240 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1246 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1247 $res = $this->db->query($sql);
1250 $this->error = $this->db->lasterror();
1251 $this->errors[] = $this->error;
1252 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1268 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1269 $dir = $conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1270 $file = $dir.
"/".$ref.
".pdf";
1271 if (file_exists($file)) {
1275 $this->error =
'ErrorFailToDeleteFile';
1276 $this->errors[] = $this->error;
1277 $this->db->rollback();
1281 if (file_exists($dir)) {
1284 $this->error =
'ErrorFailToDeleteDir';
1285 $this->errors[] = $this->error;
1286 $this->db->rollback();
1294 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1295 $this->db->commit();
1298 $this->db->rollback();
1312 global $conf, $langs, $user;
1318 if ($this->
status == self::STATUS_VALIDATED) {
1319 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
1323 $this->date_valid = $now;
1326 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
1331 if (empty($num) || $num < 0) {
1340 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1341 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1342 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1343 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1344 $sql .=
" fk_user_valid = ".((int) $user->id);
1345 $sql .=
" WHERE rowid = ".((int) $this->
id);
1347 $resql = $this->db->query($sql);
1349 if (!$error && !$notrigger) {
1351 $result = $this->
call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1359 $this->oldref = $this->ref;
1362 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1363 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1366 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filename = CONCAT('".$this->db->escape($this->newref).
"', SUBSTR(filename, ".(strlen($this->
ref) + 1).
")), filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1367 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1368 $resql = $this->db->query($sql);
1371 $this->error = $this->db->lasterror();
1373 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1374 $sql .=
" WHERE filepath = 'expensereport/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
1375 $resql = $this->db->query($sql);
1378 $this->error = $this->db->lasterror();
1384 $dirsource = $conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1385 $dirdest = $conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1386 if (!$error && file_exists($dirsource)) {
1387 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1389 if (@rename($dirsource, $dirdest)) {
1392 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1393 foreach ($listoffiles as $fileentry) {
1394 $dirsource = $fileentry[
'name'];
1395 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1396 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1397 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1398 @rename($dirsource, $dirdest);
1411 if (empty($error)) {
1412 $this->db->commit();
1415 $this->db->rollback();
1416 $this->error = $this->db->error();
1420 $this->db->rollback();
1421 $this->error = $this->db->lasterror();
1437 $sql =
'SELECT date_debut';
1438 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1439 $sql .=
" WHERE rowid = ".((int) $this->
id);
1441 $result = $this->db->query($sql);
1443 $objp = $this->db->fetch_object($result);
1445 $this->date_debut = $this->db->jdate($objp->date_debut);
1447 if ($this->
status != self::STATUS_VALIDATED) {
1448 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1449 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1450 $sql .=
" WHERE rowid = ".((int) $this->
id);
1452 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1454 if ($this->db->query($sql)) {
1457 $this->error = $this->db->lasterror();
1461 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1480 $this->date_approve = $now;
1481 if ($this->
status != self::STATUS_APPROVED) {
1484 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1485 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1486 $sql .=
" date_approve='".$this->db->idate($this->date_approve).
"'";
1487 $sql .=
" WHERE rowid = ".((int) $this->
id);
1488 if ($this->db->query($sql)) {
1491 $result = $this->
call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1499 if (empty($error)) {
1500 $this->db->commit();
1503 $this->db->rollback();
1504 $this->error = $this->db->error();
1508 $this->db->rollback();
1509 $this->error = $this->db->lasterror();
1513 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1527 public function setDeny($fuser, $details, $notrigger = 0)
1533 if ($this->
status != self::STATUS_REFUSED) {
1534 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1535 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1536 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1537 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1538 $sql .=
" fk_user_approve = NULL";
1539 $sql .=
" WHERE rowid = ".((int) $this->
id);
1540 if ($this->db->query($sql)) {
1541 $this->fk_statut = 99;
1543 $this->fk_user_refuse = $fuser->id;
1544 $this->detail_refuse = $details;
1545 $this->date_refuse = $now;
1549 $result = $this->
call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1557 if (empty($error)) {
1558 $this->db->commit();
1561 $this->db->rollback();
1562 $this->error = $this->db->error();
1566 $this->db->rollback();
1567 $this->error = $this->db->lasterror();
1571 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1590 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1591 return $this->
setUnpaid($fuser, $notrigger);
1608 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1609 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1610 $sql .=
" WHERE rowid = ".((int) $this->
id);
1612 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1614 if ($this->db->query($sql)) {
1617 $result = $this->
call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1625 if (empty($error)) {
1626 $this->db->commit();
1629 $this->db->rollback();
1630 $this->error = $this->db->error();
1634 $this->db->rollback();
1635 $this->error = $this->db->error();
1639 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1658 $this->date_cancel = $this->db->idate(
dol_now());
1659 if ($this->
status != self::STATUS_CANCELED) {
1662 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1663 $sql .=
" SET fk_statut = ".self::STATUS_CANCELED.
", fk_user_cancel = ".((int) $fuser->id);
1664 $sql .=
", date_cancel='".$this->db->idate($this->date_cancel).
"'";
1665 $sql .=
", detail_cancel='".$this->db->escape($detail).
"'";
1666 $sql .=
" WHERE rowid = ".((int) $this->
id);
1668 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1670 if ($this->db->query($sql)) {
1673 $result = $this->
call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1681 if (empty($error)) {
1682 $this->db->commit();
1685 $this->db->rollback();
1686 $this->error = $this->db->error();
1690 $this->db->rollback();
1691 $this->error = $this->db->error();
1695 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1707 global $langs, $conf;
1708 $langs->load(
"trips");
1717 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1718 foreach ($dirmodels as $reldir) {
1719 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1722 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1730 $obj =
new $classname();
1731 $numref = $obj->getNextValue($this);
1733 if ($numref !=
"") {
1736 $this->error = $obj->error;
1737 $this->errors = $obj->errors;
1742 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1756 global $conf, $langs;
1758 $langs->load(
'trips');
1760 $nofetch = !empty($params[
'nofetch']);
1761 $moretitle = $params[
'moretitle'] ??
'';
1764 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1765 if (isset($this->
status)) {
1766 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1769 $datas[
'picto'] .=
' - '.$moretitle;
1771 if (!empty($this->
ref)) {
1772 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1774 if (!empty($this->total_ht)) {
1775 $datas[
'total_ht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1777 if (!empty($this->total_tva)) {
1778 $datas[
'total_tva'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1780 if (!empty($this->total_ttc)) {
1781 $datas[
'total_ttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
1799 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1801 global $langs, $hookmanager;
1805 $url = DOL_URL_ROOT.
'/expensereport/card.php?id='.$this->id;
1813 'objecttype' => $this->element,
1814 'option' => $option,
1815 'moretitle' => $moretitle,
1818 $classfortooltip =
'classfortooltip';
1821 $classfortooltip =
'classforajaxtooltip';
1822 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1828 if ($option !=
'nolink') {
1830 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1831 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1832 $add_save_lastsearch_values = 1;
1834 if ($add_save_lastsearch_values) {
1835 $url .=
'&save_lastsearch_values=1';
1845 if (empty($notooltip)) {
1847 $label = $langs->trans(
"ShowExpenseReport");
1848 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1850 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
1851 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
1854 $linkstart =
'<a href="'.$url.
'"';
1855 $linkstart .= $linkclose.
'>';
1858 $result .= $linkstart;
1860 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
1862 if ($withpicto != 2) {
1863 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1865 $result .= $linkend;
1868 $hookmanager->initHooks(array($this->element .
'dao'));
1869 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
1870 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1872 $result = $hookmanager->resPrint;
1874 $result .= $hookmanager->resPrint;
1890 $this->total_ht += (float) $ligne_total_ht;
1891 $this->total_tva += (float) $ligne_total_tva;
1892 $this->total_ttc += $this->total_tva;
1894 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1895 $sql .=
" total_ht = ".$this->total_ht;
1896 $sql .=
" , total_ttc = ".$this->total_ttc;
1897 $sql .=
" , total_tva = ".$this->total_tva;
1898 $sql .=
" WHERE rowid = ".((int) $this->
id);
1900 $result = $this->db->query($sql);
1904 $this->error = $this->db->error();
1924 public 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, $fk_ecm_files = 0)
1926 global $langs, $mysoc;
1928 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);
1930 if ($this->
status == self::STATUS_DRAFT) {
1934 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1935 $fk_c_type_fees = 0;
1937 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1938 $fk_c_exp_tax_cat = 0;
1940 if (empty($vatrate) || $vatrate < 0) {
1946 if (empty($fk_project)) {
1951 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1962 $seller->tva_assuj = 1;
1963 $buyer =
new Societe($this->db);
1969 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
1970 $vat_src_code = $reg[1];
1971 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
1973 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
1975 $tmp =
calcul_price_total($qty, $up, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
1977 $this->line->value_unit = $up;
1979 $this->line->vat_src_code = $vat_src_code;
1980 $this->line->vatrate =
price2num($vatrate);
1981 $this->line->localtax1_tx = $localtaxes_type[1];
1982 $this->line->localtax2_tx = $localtaxes_type[3];
1983 $this->line->localtax1_type = $localtaxes_type[0];
1984 $this->line->localtax2_type = $localtaxes_type[2];
1986 $this->line->total_ttc = $tmp[2];
1987 $this->line->total_ht = $tmp[0];
1988 $this->line->total_tva = $tmp[1];
1989 $this->line->total_localtax1 = $tmp[9];
1990 $this->line->total_localtax2 = $tmp[10];
1992 $this->line->fk_expensereport = $this->id;
1993 $this->line->qty = $qty;
1994 $this->line->date = $date;
1995 $this->line->fk_c_type_fees = $fk_c_type_fees;
1996 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
1997 $this->line->comments = $comments;
1998 $this->line->fk_projet = $fk_project;
1999 $this->line->fk_project = $fk_project;
2001 $this->line->fk_ecm_files = $fk_ecm_files;
2006 $result = $this->line->insert(0,
true);
2010 $this->db->commit();
2011 return $this->line->id;
2013 $this->db->rollback();
2017 $this->error = $this->line->error;
2018 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
2019 $this->db->rollback();
2023 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
2024 $this->error =
'ErrorExpenseNotDraft';
2038 global $conf, $db, $langs, $mysoc;
2040 $langs->load(
'trips');
2043 if (!is_object($seller)) {
2045 $seller->tva_assuj = 1;
2049 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
2052 $rule_warning_message_tab = array();
2054 $current_total_ttc = $this->line->total_ttc;
2055 $new_current_total_ttc = $this->line->total_ttc;
2058 foreach ($rulestocheck as $rule) {
2059 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
2060 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
2062 $amount_to_test = $current_total_ttc;
2065 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
2067 if ($amount_to_test > $rule->amount) {
2070 if ($rule->restrictive) {
2071 $this->error =
'ExpenseReportConstraintViolationError';
2072 $this->errors[] = $this->error;
2074 $new_current_total_ttc -= $amount_to_test - $rule->amount;
2075 $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));
2077 $this->error =
'ExpenseReportConstraintViolationWarning';
2078 $this->errors[] = $this->error;
2080 $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));
2087 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
2089 if ($violation > 0) {
2090 $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);
2092 $this->line->value_unit = $tmp[5];
2093 $this->line->total_ttc = $tmp[2];
2094 $this->line->total_ht = $tmp[0];
2095 $this->line->total_tva = $tmp[1];
2096 $this->line->total_localtax1 = $tmp[9];
2097 $this->line->total_localtax2 = $tmp[10];
2120 $userauthor =
new User($this->db);
2121 if ($userauthor->fetch($this->fk_user_author) <= 0) {
2122 $this->error =
'ErrorCantFetchUser';
2123 $this->errors[] =
'ErrorCantFetchUser';
2128 if (!is_object($seller)) {
2130 $seller->tva_assuj = 1;
2134 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2136 if (empty($range)) {
2137 $this->error =
'ErrorNoRangeAvailable';
2138 $this->errors[] =
'ErrorNoRangeAvailable';
2143 $ikoffset = $range->ikoffset;
2145 $ikoffset = $range->ikoffset / 12;
2150 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2151 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2153 $this->line->value_unit = $tmp[5];
2154 $this->line->total_ttc = $tmp[2];
2155 $this->line->total_ht = $tmp[0];
2156 $this->line->total_tva = $tmp[1];
2157 $this->line->total_localtax1 = $tmp[9];
2158 $this->line->total_localtax2 = $tmp[10];
2173 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2174 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2175 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2176 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2177 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2178 if (!empty($this->line->id)) {
2179 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2182 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2183 $resql = $this->db->query($sql);
2185 $num = $this->db->num_rows($resql);
2213 public function updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id, $fk_c_exp_tax_cat = 0, $fk_ecm_files = 0, $notrigger = 0)
2215 global $user, $mysoc;
2217 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
2225 $seller->tva_assuj = 1;
2226 $seller->localtax1_assuj = $mysoc->localtax1_assuj;
2227 $seller->localtax2_assuj = $mysoc->localtax1_assuj;
2228 $buyer =
new Societe($this->db);
2235 if (preg_match(
'/\((.*)\)/', (
string) $vatrate, $reg)) {
2236 $vat_src_code = $reg[1];
2237 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', (
string) $vatrate);
2239 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2241 $tmp =
calcul_price_total($qty, $value_unit, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2246 $tx_tva = 1 + (float) $vatrate / 100;
2249 $this->line->comments = $comments;
2250 $this->line->qty = $qty;
2251 $this->line->value_unit = $value_unit;
2252 $this->line->date = $date;
2254 $this->line->fk_expensereport = $expensereport_id;
2255 $this->line->fk_c_type_fees = $type_fees_id;
2256 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2257 $this->line->fk_projet = $projet_id;
2258 $this->line->fk_project = $projet_id;
2260 $this->line->vat_src_code = $vat_src_code;
2261 $this->line->vatrate =
price2num($vatrate);
2262 $this->line->localtax1_tx = $localtaxes_type[1];
2263 $this->line->localtax2_tx = $localtaxes_type[3];
2264 $this->line->localtax1_type = $localtaxes_type[0];
2265 $this->line->localtax2_type = $localtaxes_type[2];
2267 $this->line->total_ttc = $tmp[2];
2268 $this->line->total_ht = $tmp[0];
2269 $this->line->total_tva = $tmp[1];
2270 $this->line->total_localtax1 = $tmp[9];
2271 $this->line->total_localtax2 = $tmp[10];
2273 $this->line->fk_ecm_files = $fk_ecm_files;
2275 $this->line->id = ((int) $rowid);
2278 $sql =
"SELECT c.code as code_type_fees, c.label as label_type_fees";
2279 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2280 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2281 $resql = $this->db->query($sql);
2283 $objp_fees = $this->db->fetch_object($resql);
2284 $this->line->type_fees_code = $objp_fees->code_type_fees;
2285 $this->line->type_fees_libelle = $objp_fees->label_type_fees;
2286 $this->db->free($resql);
2290 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2291 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2292 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2293 $resql = $this->db->query($sql);
2295 $objp_projet = $this->db->fetch_object($resql);
2296 $this->line->projet_ref = $objp_projet->ref_projet;
2297 $this->line->projet_title = $objp_projet->title_projet;
2298 $this->db->free($resql);
2304 $result = $this->line->update($user);
2309 if (!$error && !$notrigger) {
2311 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_MODIFY', $user);
2319 $this->db->commit();
2322 $this->error = $this->line->error;
2323 $this->errors = $this->line->errors;
2324 $this->db->rollback();
2348 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2355 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2356 $sql .=
' WHERE rowid = '.((int) $rowid);
2358 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2359 $result = $this->db->query($sql);
2361 if (!$result || $error > 0) {
2362 $this->error = $this->db->error();
2363 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2364 $this->db->rollback();
2370 $this->db->commit();
2389 $sql =
"SELECT rowid, date_debut, date_fin";
2390 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2391 $sql .=
" WHERE entity = ".((int) $conf->entity);
2392 $sql .=
" AND fk_user_author = ".((int) $fuser->id);
2394 dol_syslog(get_class($this).
"::periode_existe sql=".$sql);
2395 $result = $this->db->query($sql);
2397 $num_rows = $this->db->num_rows($result);
2400 if ($num_rows > 0) {
2401 $date_d_form = $date_debut;
2402 $date_f_form = $date_fin;
2404 while ($i < $num_rows) {
2405 $objp = $this->db->fetch_object($result);
2407 $date_d_req = $this->db->jdate($objp->date_debut);
2408 $date_f_req = $this->db->jdate($objp->date_fin);
2410 if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) {
2411 return $objp->rowid;
2422 $this->error = $this->db->lasterror();
2423 dol_syslog(get_class($this).
"::periode_existe Error ".$this->error, LOG_ERR);
2439 $users_validator = array();
2441 $sql =
"SELECT DISTINCT ur.fk_user";
2442 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2443 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2445 $sql .=
" SELECT DISTINCT ugu.fk_user";
2446 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2447 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2450 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2451 $result = $this->db->query($sql);
2453 $num_rows = $this->db->num_rows($result);
2455 while ($i < $num_rows) {
2456 $objp = $this->db->fetch_object($result);
2457 array_push($users_validator, $objp->fk_user);
2460 return $users_validator;
2462 $this->error = $this->db->lasterror();
2463 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2479 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2481 $outputlangs->load(
"trips");
2484 if (!empty($this->model_pdf)) {
2485 $modele = $this->model_pdf;
2491 if (!empty($modele)) {
2492 $modelpath =
"core/modules/expensereport/doc/";
2494 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2510 $sql =
"SELECT id, code, label";
2511 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2512 $sql .=
" WHERE active = ".((int) $active);
2513 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2514 $result = $this->db->query($sql);
2516 $num = $this->db->num_rows($result);
2519 $obj = $this->db->fetch_object($result);
2520 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2538 $this->nb = array();
2540 $sql =
"SELECT count(ex.rowid) as nb";
2541 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2542 $sql .=
" WHERE ex.fk_statut > 0";
2543 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2544 if (!$user->hasRight(
'expensereport',
'readall')) {
2545 $userchildids = $user->getAllChildIds(1);
2546 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2547 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2550 $resql = $this->db->query($sql);
2552 while ($obj = $this->db->fetch_object($resql)) {
2553 $this->nb[
"expensereports"] = $obj->nb;
2555 $this->db->free($resql);
2559 $this->error = $this->db->error();
2575 global $conf, $langs;
2583 $sql =
"SELECT ex.rowid, ex.date_valid";
2584 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2585 if ($option ==
'toapprove') {
2586 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2588 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2590 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2591 if (!$user->hasRight(
'expensereport',
'readall')) {
2592 $userchildids = $user->getAllChildIds(1);
2593 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2594 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2597 $resql = $this->db->query($sql);
2599 $langs->load(
"trips");
2602 if ($option ==
'toapprove') {
2603 $response->warning_delay = $conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2604 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2605 $response->labelShort = $langs->trans(
"ToApprove");
2608 $response->warning_delay = $conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2609 $response->label = $langs->trans(
"ExpenseReportsToPay");
2610 $response->labelShort = $langs->trans(
"StatusToPay");
2611 $response->url = DOL_URL_ROOT.
'/expensereport/list.php?mainmenu=hrm&statut='.
self::STATUS_APPROVED;
2615 while ($obj = $this->db->fetch_object($resql)) {
2616 $response->nbtodo++;
2618 if ($option ==
'toapprove') {
2619 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->approve->warning_delay)) {
2620 $response->nbtodolate++;
2623 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->payment->warning_delay)) {
2624 $response->nbtodolate++;
2632 $this->error = $this->db->error();
2648 if ($option ==
'toapprove' && $this->
status != 2) {
2651 if ($option ==
'topay' && $this->
status != 5) {
2656 if ($option ==
'toapprove') {
2657 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->approve->warning_delay);
2659 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->payment->warning_delay);
2670 $alreadydispatched = 0;
2672 $type =
'expense_report';
2674 $sql =
" SELECT COUNT(ab.rowid) as nb FROM ".MAIN_DB_PREFIX.
"accounting_bookkeeping as ab WHERE ab.doc_type='".$this->db->escape($type).
"' AND ab.fk_doc = ".((int) $this->
id);
2675 $resql = $this->db->query($sql);
2677 $obj = $this->db->fetch_object($resql);
2679 $alreadydispatched = $obj->nb;
2682 $this->error = $this->db->lasterror();
2686 if ($alreadydispatched) {
2699 $table =
'payment_expensereport';
2700 $field =
'fk_expensereport';
2702 $sql =
'SELECT sum(amount) as amount';
2703 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2704 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
2706 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2707 $resql = $this->db->query($sql);
2709 $obj = $this->db->fetch_object($resql);
2710 $this->db->free($resql);
2711 return (empty($obj->amount) ? 0 : $obj->amount);
2713 $this->error = $this->db->lasterror();
2728 global $langs, $db, $conf;
2736 $this->error = $langs->trans(
'ErrorBadParameterCat');
2741 $this->error = $langs->trans(
'ErrorBadParameterQty');
2745 $currentUser =
new User($db);
2746 $currentUser->fetch($this->fk_user);
2747 $currentUser->getrights(
'expensereport');
2751 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2752 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2753 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2754 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2755 $sql .=
" ORDER BY r.range_ik ASC";
2757 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2759 $result = $this->db->query($sql);
2762 if ($conf->global->EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR) {
2764 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2765 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2766 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2767 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2768 $sql .=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2769 $sql .=
" AND tf.code = 'EX_KME' ";
2772 $resql = $this->db->query($sql);
2775 $obj = $this->db->fetch_object($resql);
2776 $cumulYearQty = $obj->cumul;
2779 $qty += (float) $cumulYearQty;
2782 $num = $this->db->num_rows($result);
2785 for ($i = 0; $i < $num; $i++) {
2786 $obj = $this->db->fetch_object($result);
2792 for ($i = 0; $i < $num; $i++) {
2793 if ($i < ($num - 1)) {
2794 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i + 1]->range_ik) {
2795 $coef = $ranges[$i]->coef;
2796 $offset = $ranges[$i]->ikoffset;
2799 if ($qty > $ranges[$i]->range_ik) {
2800 $coef = $ranges[$i]->coef;
2801 $offset = $ranges[$i]->ikoffset;
2808 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2812 $this->error = $this->db->error().
" sql=".$sql;
2829 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2831 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2832 $return .=
'<div class="info-box info-box-sm">';
2833 $return .=
'<span class="info-box-icon bg-infobox-action">';
2835 $return .=
'</span>';
2836 $return .=
'<div class="info-box-content">';
2837 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
2838 if ($selected >= 0) {
2839 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2841 if (array_key_exists(
'userauthor', $arraydata)) {
2842 $return .=
'<br><span class="info-box-label">'.$arraydata[
'userauthor']->getNomUrl(-1).
'</span>';
2844 if (property_exists($this,
'date_debut') && property_exists($this,
'date_fin')) {
2845 $return .=
'<br><span class="info-box-label">'.dol_print_date($this->date_debut,
'day').
'</span>';
2846 $return .=
' <span class="opacitymedium">'.$langs->trans(
"To").
'</span> ';
2847 $return .=
'<span class="info-box-label">'.dol_print_date($this->date_fin,
'day').
'</span>';
2849 if (method_exists($this,
'getLibStatut')) {
2850 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
2852 $return .=
'</div>';
2853 $return .=
'</div>';
2854 $return .=
'</div>';
2873 public $table_element =
'expensereport_det';
2902 public $fk_c_type_fees;
2907 public $fk_c_exp_tax_cat;
2917 public $fk_expensereport;
2919 public $type_fees_code;
2920 public $type_fees_libelle;
2921 public $type_fees_accountancy_code;
2924 public $projet_title;
2928 public $vat_src_code;
2930 public $localtax1_tx;
2931 public $localtax2_tx;
2932 public $localtax1_type;
2933 public $localtax2_type;
2938 public $total_localtax1;
2939 public $total_localtax2;
2945 public $fk_multicurrency;
2950 public $multicurrency_code;
2951 public $multicurrency_tx;
2952 public $multicurrency_total_ht;
2953 public $multicurrency_total_tva;
2954 public $multicurrency_total_ttc;
2959 public $fk_ecm_files;
2961 public $rule_warning_message;
2982 $sql =
'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_c_exp_tax_cat, fde.fk_projet as fk_project, fde.date,';
2983 $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, fde.fk_ecm_files,';
2984 $sql .=
' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,';
2985 $sql .=
' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
2986 $sql .=
' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
2987 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det as fde';
2988 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
2989 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as pjt ON fde.fk_projet=pjt.rowid';
2990 $sql .=
' WHERE fde.rowid = '.((int) $rowid);
2992 $result = $this->db->query($sql);
2995 $objp = $this->db->fetch_object($result);
2997 $this->
rowid = $objp->rowid;
2998 $this->
id = $objp->rowid;
2999 $this->
ref = $objp->ref;
3000 $this->fk_expensereport = $objp->fk_expensereport;
3001 $this->comments = $objp->comments;
3002 $this->qty = $objp->qty;
3003 $this->date = $objp->date;
3004 $this->dates = $this->db->jdate($objp->date);
3005 $this->value_unit = $objp->value_unit;
3006 $this->fk_c_type_fees = $objp->fk_c_type_fees;
3007 $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
3008 $this->fk_projet = $objp->fk_project;
3009 $this->fk_project = $objp->fk_project;
3010 $this->type_fees_code = $objp->type_fees_code;
3011 $this->type_fees_libelle = $objp->type_fees_libelle;
3012 $this->projet_ref = $objp->projet_ref;
3013 $this->projet_title = $objp->projet_title;
3015 $this->
vatrate = $objp->vatrate;
3016 $this->vat_src_code = $objp->vat_src_code;
3017 $this->localtax1_tx = $objp->localtax1_tx;
3018 $this->localtax2_tx = $objp->localtax2_tx;
3019 $this->localtax1_type = $objp->localtax1_type;
3020 $this->localtax2_type = $objp->localtax2_type;
3022 $this->total_ht = $objp->total_ht;
3023 $this->total_tva = $objp->total_tva;
3024 $this->total_ttc = $objp->total_ttc;
3025 $this->total_localtax1 = $objp->total_localtax1;
3026 $this->total_localtax2 = $objp->total_localtax2;
3028 $this->fk_ecm_files = $objp->fk_ecm_files;
3030 $this->rule_warning_message = $objp->rule_warning_message;
3032 $this->db->free($result);
3048 public function insert($notrigger = 0, $fromaddline =
false)
3054 dol_syslog(
"ExpenseReportLine::Insert", LOG_DEBUG);
3057 $this->comments = trim($this->comments);
3058 if (empty($this->value_unit)) {
3059 $this->value_unit = 0;
3061 $this->qty = (float)
price2num($this->qty);
3063 if (empty($this->fk_c_exp_tax_cat)) {
3064 $this->fk_c_exp_tax_cat = 0;
3069 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'expensereport_det';
3070 $sql .=
' (fk_expensereport, fk_c_type_fees, fk_projet,';
3071 $sql .=
' tva_tx, vat_src_code,';
3072 $sql .=
' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
3073 $sql .=
' comments, qty, value_unit,';
3074 $sql .=
' total_ht, total_tva, total_ttc,';
3075 $sql .=
' total_localtax1, total_localtax2,';
3076 $sql .=
' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)';
3077 $sql .=
" VALUES (".$this->db->escape($this->fk_expensereport).
",";
3078 $sql .=
" ".((int) $this->fk_c_type_fees).
",";
3079 $sql .=
" ".((int) (!empty($this->fk_project) && $this->fk_project > 0) ? $this->fk_project : ((!empty($this->fk_projet) && $this->fk_projet > 0) ? $this->fk_projet :
'null')).
",";
3080 $sql .=
" ".((float) $this->
vatrate).
",";
3081 $sql .=
" '".$this->db->escape(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"',";
3082 $sql .=
" ".((float)
price2num($this->localtax1_tx)).
",";
3083 $sql .=
" ".((float)
price2num($this->localtax2_tx)).
",";
3084 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
3085 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
3086 $sql .=
" '".$this->db->escape($this->comments).
"',";
3087 $sql .=
" ".((float) $this->qty).
",";
3088 $sql .=
" ".((float) $this->value_unit).
",";
3089 $sql .=
" ".((float)
price2num($this->total_ht)).
",";
3090 $sql .=
" ".((float)
price2num($this->total_tva)).
",";
3091 $sql .=
" ".((float)
price2num($this->total_ttc)).
",";
3092 $sql .=
" ".((float)
price2num($this->total_localtax1)).
",";
3093 $sql .=
" ".((float)
price2num($this->total_localtax2)).
",";
3094 $sql .=
" '".$this->db->idate($this->date).
"',";
3095 $sql .=
" ".(empty($this->rule_warning_message) ?
'null' :
"'".$this->db->escape($this->rule_warning_message).
"'").
",";
3096 $sql .=
" ".((int) $this->fk_c_exp_tax_cat).
",";
3097 $sql .=
" ".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3100 $resql = $this->db->query($sql);
3102 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'expensereport_det');
3105 if (!$error && !$notrigger) {
3107 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_CREATE', $user);
3115 if (!$fromaddline) {
3117 $tmpparent->fetch($this->fk_expensereport);
3118 $result = $tmpparent->update_price(1);
3121 $this->error = $tmpparent->error;
3122 $this->errors = $tmpparent->errors;
3130 $this->db->commit();
3133 $this->error = $this->db->lasterror();
3134 dol_syslog(
"ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
3135 $this->db->rollback();
3152 $sql =
'SELECT SUM(d.total_ttc) as total_amount';
3153 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det d';
3154 $sql .=
' INNER JOIN '.MAIN_DB_PREFIX.
'expensereport e ON (d.fk_expensereport = e.rowid)';
3155 $sql .=
' WHERE e.fk_user_author = '.((int) $fk_user);
3156 if (!empty($this->
id)) {
3157 $sql .=
' AND d.rowid <> '.((int) $this->
id);
3159 $sql .=
' AND d.fk_c_type_fees = '.((int) $rule->fk_c_type_fees);
3160 if ($mode ==
'day' || $mode ==
'EX_DAY') {
3161 $sql .=
" AND d.date = '".dol_print_date($this->date,
'%Y-%m-%d').
"'";
3162 } elseif ($mode ==
'mon' || $mode ==
'EX_MON') {
3163 $sql .=
" AND DATE_FORMAT(d.date, '%Y-%m') = '".dol_print_date($this->date,
'%Y-%m').
"'";
3164 } elseif ($mode ==
'year' || $mode ==
'EX_YEA') {
3165 $sql .=
" AND DATE_FORMAT(d.date, '%Y') = '".dol_print_date($this->date,
'%Y').
"'";
3168 dol_syslog(
'ExpenseReportLine::getExpAmount');
3170 $resql = $this->db->query($sql);
3172 $num = $this->db->num_rows($resql);
3174 $obj = $this->db->fetch_object($resql);
3175 $amount = (float) $obj->total_amount;
3181 return $amount + $this->total_ttc;
3197 $this->comments = trim($this->comments);
3199 $this->value_unit =
price2num($this->value_unit);
3200 if (empty($this->fk_c_exp_tax_cat)) {
3201 $this->fk_c_exp_tax_cat = 0;
3207 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport_det SET";
3208 $sql .=
" comments='".$this->db->escape($this->comments).
"'";
3209 $sql .=
", value_unit = ".((float) $this->value_unit);
3210 $sql .=
", qty=".((float) $this->qty);
3211 $sql .=
", date='".$this->db->idate($this->date).
"'";
3212 $sql .=
", total_ht=".((float)
price2num($this->total_ht,
'MT'));
3213 $sql .=
", total_tva=".((float)
price2num($this->total_tva,
'MT'));
3214 $sql .=
", total_ttc=".((float)
price2num($this->total_ttc,
'MT'));
3215 $sql .=
", total_localtax1=".((float)
price2num($this->total_localtax1,
'MT'));
3216 $sql .=
", total_localtax2=".((float)
price2num($this->total_localtax2,
'MT'));
3217 $sql .=
", tva_tx=".((float) $this->
vatrate);
3218 $sql .=
", vat_src_code='".$this->db->escape($this->vat_src_code).
"'";
3219 $sql .=
", localtax1_tx=".((float) $this->localtax1_tx);
3220 $sql .=
", localtax2_tx=".((float) $this->localtax2_tx);
3221 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
3222 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
3223 $sql .=
", rule_warning_message='".$this->db->escape($this->rule_warning_message).
"'";
3224 $sql .=
", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat);
3225 $sql .=
", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3226 if ($this->fk_c_type_fees) {
3227 $sql .=
", fk_c_type_fees = ".((int) $this->fk_c_type_fees);
3229 $sql .=
", fk_c_type_fees=null";
3231 if ($this->fk_project > 0) {
3232 $sql .=
", fk_projet=".((int) $this->fk_project);
3234 $sql .=
", fk_projet=null";
3236 $sql .=
" WHERE rowid = ".((int) ($this->
rowid ? $this->
rowid : $this->id));
3240 $resql = $this->db->query($sql);
3243 $result = $tmpparent->fetch($this->fk_expensereport);
3245 $result = $tmpparent->update_price(1);
3248 $this->error = $tmpparent->error;
3249 $this->errors = $tmpparent->errors;
3253 $this->error = $tmpparent->error;
3254 $this->errors = $tmpparent->errors;
3262 $this->db->commit();
3265 $this->error = $this->db->lasterror();
3266 dol_syslog(
"ExpenseReportLine::update Error ".$this->error, LOG_ERR);
3267 $this->db->rollback();
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteEcmFiles($mode=0)
Delete related files of object in database.
update_price($exclspec=0, $roundingadjust='auto', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
setErrorsFromObject($object)
setErrorsFromObject
deleteExtraFields()
Delete all extra fields values for the current object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Trips and Expenses.
setPaid($id, $fuser, $notrigger=0)
Classify the expense report as paid.
loadStateBoard()
Load the indicators this->nb for the state board.
__construct($db)
Constructor.
checkRules($type=0, $seller='')
Check constraint of rules and update price if needed.
updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id, $fk_c_exp_tax_cat=0, $fk_ecm_files=0, $notrigger=0)
Update an expense report line.
getNextNumRef()
Return next reference of expense report not already used.
createFromClone(User $user, $fk_user_author)
Load an object from its id and create a new one in database.
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, $fk_ecm_files=0)
Add expense report line.
const STATUS_DRAFT
Draft status.
computeTotalKm($fk_cat, $qty, $tva)
Compute the cost of the kilometers expense based on the number of kilometers and the vehicle category...
offsetAlreadyGiven()
If the sql find any rows then the ikoffset is already given (ikoffset is applied at the first expense...
listOfTypes($active=1)
List of types.
const STATUS_APPROVED
Classified approved.
set_save_from_refuse($fuser)
set_save_from_refuse
periode_existe($fuser, $date_debut, $date_fin)
periode_existe
setValidate($fuser, $notrigger=0)
Set to status validate.
getSumPayments()
Return amount of payments already done.
getLibStatut($mode=0)
Returns the label status.
set_cancel($fuser, $detail, $notrigger=0)
set_cancel
getNomUrl($withpicto=0, $option='', $max=0, $short=0, $moretitle='', $notooltip=0, $save_lastsearch_value=-1)
Return clicable name (with picto eventually)
set_unpaid($fuser, $notrigger=0)
set_unpaid
info($id)
Load information on object.
getTooltipContentArray($params)
getTooltipContentArray
hasDelay($option)
Return if an expense report is late or not.
applyOffset($type=0, $seller='')
Method to apply the offset if needed.
const STATUS_CANCELED
Classified canceled.
const STATUS_CLOSED
Classified paid.
const STATUS_REFUSED
Classified refused.
deleteLine($rowid, $fuser='', $notrigger=0)
deleteline
setDeny($fuser, $details, $notrigger=0)
setDeny
getVentilExportCompta()
Return if object was dispatched into bookkeeping.
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with optional picto)
update($user, $notrigger=0, $userofexpensereport=null)
update
const STATUS_VALIDATED
Validated (need to be paid)
create($user, $notrigger=0)
Create object in database.
load_board($user, $option='topay')
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
set_paid($id, $fuser, $notrigger=0)
Classify the expense report as paid.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
initAsSpecimen()
Initialise an instance with random values.
fetch_users_approver_expensereport()
Return list of people with permission to validate expense reports.
setApproved($fuser, $notrigger=0)
Set status to approved.
LibStatut($status, $mode=0)
Returns the label of a status.
setUnpaid($fuser, $notrigger=0)
set_unpaid
fetch_line_by_project($projectid, $user)
fetch_line_by_project
update_totaux_add($ligne_total_ht, $ligne_total_tva)
Update total of an expense report when you add a line.
Class to manage inventories.
Class of expense report details lines.
fetch($rowid)
Fetch record for expense report detailed line.
update(User $user)
Update line.
getExpAmount(ExpenseReportRule $rule, $fk_user, $mode='day')
Function to get total amount in expense reports for a same rule.
insert($notrigger=0, $fromaddline=false)
Insert a line of expense report.
__construct($db)
Constructor.
Class to manage inventories.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_delete_preview($object)
Delete all preview files linked to object instance.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller='', $localtaxes_array=[], $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall TAKEPOS_SHOW_SUBPRICE right right right takeposterminal SELECT e rowid