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).
"'";
679 $sql .=
" AND d.entity IN (".getEntity(
'expensereport').
")";
681 $sql .=
" WHERE d.rowid = ".((int) $id);
685 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
686 $resql = $this->db->query($sql);
688 $obj = $this->db->fetch_object($resql);
690 $this->
id = $obj->rowid;
691 $this->
ref = $obj->ref;
693 $this->entity = $obj->entity;
695 $this->total_ht = $obj->total_ht;
696 $this->total_tva = $obj->total_tva;
697 $this->total_ttc = $obj->total_ttc;
698 $this->localtax1 = $obj->total_localtax1;
699 $this->localtax2 = $obj->total_localtax2;
700 $this->total_localtax1 = $obj->total_localtax1;
701 $this->total_localtax2 = $obj->total_localtax2;
703 $this->note_public = $obj->note_public;
704 $this->note_private = $obj->note_private;
705 $this->detail_refuse = $obj->detail_refuse;
706 $this->detail_cancel = $obj->detail_cancel;
708 $this->date_debut = $this->db->jdate($obj->date_debut);
709 $this->date_fin = $this->db->jdate($obj->date_fin);
710 $this->date_valid = $this->db->jdate($obj->date_valid);
711 $this->date_approve = $this->db->jdate($obj->date_approve);
712 $this->date_create = $this->db->jdate($obj->date_create);
713 $this->date_modif = $this->db->jdate($obj->date_modif);
714 $this->date_refuse = $this->db->jdate($obj->date_refuse);
715 $this->date_cancel = $this->db->jdate($obj->date_cancel);
717 $this->fk_user_creat = $obj->fk_user_creat;
718 $this->fk_user_author = $obj->fk_user_author;
719 $this->fk_user_modif = $obj->fk_user_modif;
720 $this->fk_user_validator = $obj->fk_user_validator;
721 $this->fk_user_valid = $obj->fk_user_valid;
722 $this->fk_user_refuse = $obj->fk_user_refuse;
723 $this->fk_user_cancel = $obj->fk_user_cancel;
724 $this->fk_user_approve = $obj->fk_user_approve;
726 $user_author =
new User($this->db);
727 if ($this->fk_user_author > 0) {
728 $user_author->fetch($this->fk_user_author);
731 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
733 $user_approver =
new User($this->db);
734 if ($this->fk_user_approve > 0) {
735 $user_approver->fetch($this->fk_user_approve);
736 } elseif ($this->fk_user_validator > 0) {
737 $user_approver->fetch($this->fk_user_validator);
739 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
741 $this->fk_statut = $obj->status;
742 $this->
status = $obj->status;
743 $this->fk_c_paiement = $obj->fk_c_paiement;
744 $this->paid = $obj->paid;
746 if ($this->
status == self::STATUS_APPROVED || $this->
status == self::STATUS_CLOSED) {
747 $user_valid =
new User($this->db);
748 if ($this->fk_user_valid > 0) {
749 $user_valid->fetch($this->fk_user_valid);
751 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
763 $this->error = $this->db->lasterror();
779 public function set_paid($id, $fuser, $notrigger = 0)
782 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
783 return $this->
setPaid($id, $fuser, $notrigger);
794 public function setPaid($id, $fuser, $notrigger = 0)
799 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
800 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid=1";
803 dol_syslog(get_class($this).
"::setPaid", LOG_DEBUG);
804 $resql = $this->db->query($sql);
806 if ($this->db->affected_rows($resql)) {
809 $result = $this->
call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
821 $this->db->rollback();
822 $this->error = $this->db->error();
830 $this->db->rollback();
860 $labelStatus = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
861 $labelStatusShort = $langs->transnoentitiesnoconv($this->labelStatusShort[$status]);
863 $statuslogo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
865 $statusType = $statuslogo[$status];
867 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
881 $sql =
"SELECT f.rowid,";
882 $sql .=
" f.date_create as datec,";
883 $sql .=
" f.tms as date_modification,";
884 $sql .=
" f.date_valid as datev,";
885 $sql .=
" f.date_approve as datea,";
886 $sql .=
" f.fk_user_creat as fk_user_creation,";
887 $sql .=
" f.fk_user_author as fk_user_author,";
888 $sql .=
" f.fk_user_modif as fk_user_modification,";
889 $sql .=
" f.fk_user_valid,";
890 $sql .=
" f.fk_user_approve";
891 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
892 $sql .=
" WHERE f.rowid = ".((int) $id);
893 $sql .=
" AND f.entity = ".$conf->entity;
897 $resql = $this->db->query($sql);
899 if ($this->db->num_rows($resql)) {
900 $obj = $this->db->fetch_object($resql);
902 $this->
id = $obj->rowid;
904 $this->date_creation = $this->db->jdate($obj->datec);
905 $this->date_modification = $this->db->jdate($obj->date_modification);
906 $this->date_validation = $this->db->jdate($obj->datev);
907 $this->date_approbation = $this->db->jdate($obj->datea);
909 $this->user_creation_id = $obj->fk_user_author;
910 $this->user_creation_id = $obj->fk_user_creation;
911 $this->user_validation_id = $obj->fk_user_valid;
912 $this->user_modification_id = $obj->fk_user_modification;
913 $this->user_approve_id = $obj->fk_user_approve;
915 $this->db->free($resql);
932 global $user, $langs;
938 $this->
ref =
'SPECIMEN';
941 $this->date_create = $now;
942 $this->date_debut = $now;
943 $this->date_fin = $now;
944 $this->date_valid = $now;
945 $this->date_approve = $now;
951 $this->fk_user_author = $user->id;
952 $this->fk_user_validator = $user->id;
953 $this->fk_user_valid = $user->id;
954 $this->fk_user_approve = $user->id;
956 $this->note_private =
'Private note';
957 $this->note_public =
'SPECIMEN';
960 while ($xnbp < $nbp) {
962 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
963 $line->date = ($now - 3600 * (1 + $xnbp));
964 $line->total_ht = 100;
965 $line->total_tva = 20;
966 $line->total_ttc = 120;
969 $line->value_unit = 120;
970 $line->fk_expensereport = 0;
971 $line->type_fees_code =
'TRA';
972 $line->fk_c_type_fees = $type_fees_id;
974 $line->projet_ref =
'ABC';
976 $this->lines[$xnbp] = $line;
979 $this->total_ht += $line->total_ht;
980 $this->total_tva += $line->total_tva;
981 $this->total_ttc += $line->total_ttc;
1000 $langs->load(
'trips');
1002 if ($user->hasRight(
'expensereport',
'lire')) {
1003 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
1004 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
1005 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
1007 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1008 $result = $this->db->query($sql);
1010 $num = $this->db->num_rows($result);
1016 $objp = $this->db->fetch_object($result);
1018 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
1019 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
1020 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
1022 $result2 = $this->db->query($sql2);
1023 $obj = $this->db->fetch_object($result2);
1025 $objp->fk_user_author = $obj->fk_user_author;
1026 $objp->ref = $obj->ref;
1027 $objp->fk_c_expensereport_status = $obj->status;
1028 $objp->rowid = $obj->rowid;
1030 $total_HT += $objp->total_ht;
1031 $total_TTC += $objp->total_ttc;
1032 $author =
new User($this->db);
1033 $author->fetch($objp->fk_user_author);
1036 print
'<td><a href="'.DOL_URL_ROOT.
'/expensereport/card.php?id='.$objp->rowid.
'">'.$objp->ref_num.
'</a></td>';
1037 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
1038 print
'<td>'.$author->getNomUrl(1).
'</td>';
1039 print
'<td>'.$objp->comments.
'</td>';
1040 print
'<td class="right">'.price($objp->total_ht).
'</td>';
1041 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
1042 print
'<td class="right">';
1044 switch ($objp->fk_c_expensereport_status) {
1046 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
1049 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
1052 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
1055 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
1058 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
1075 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
1076 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
1077 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
1078 print
'<td> </td>';
1081 $this->error = $this->db->lasterror();
1098 $this->lines = array();
1100 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1101 $sql .=
" de.".$this->fk_element.
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1102 $sql .=
' de.tva_tx, de.vat_src_code,';
1103 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1104 $sql .=
' de.fk_ecm_files,';
1105 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1106 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1107 $sql .=
' ctf.code as code_type_fees, ctf.label as label_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1108 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1109 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as de';
1110 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1111 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1112 $sql .=
" WHERE de.".$this->fk_element.
" = ".((int) $this->
id);
1114 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1116 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1119 $resql = $this->db->query($sql);
1121 $num = $this->db->num_rows($resql);
1124 $objp = $this->db->fetch_object($resql);
1128 $deplig->rowid = $objp->rowid;
1129 $deplig->id = $objp->rowid;
1130 $deplig->comments = $objp->comments;
1131 $deplig->qty = $objp->qty;
1132 $deplig->value_unit = $objp->value_unit;
1133 $deplig->date = $objp->date;
1134 $deplig->dates = $this->db->jdate($objp->date);
1136 $deplig->fk_expensereport = $objp->fk_expensereport;
1137 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1138 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1139 $deplig->fk_projet = $objp->fk_project;
1140 $deplig->fk_project = $objp->fk_project;
1141 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1143 $deplig->total_ht = $objp->total_ht;
1144 $deplig->total_tva = $objp->total_tva;
1145 $deplig->total_ttc = $objp->total_ttc;
1146 $deplig->total_localtax1 = $objp->total_localtax1;
1147 $deplig->total_localtax2 = $objp->total_localtax2;
1149 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1150 $deplig->type_fees_libelle = $objp->label_type_fees;
1151 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1153 $deplig->tva_tx = $objp->tva_tx;
1154 $deplig->vatrate = $objp->tva_tx;
1155 $deplig->vat_src_code = $objp->vat_src_code;
1156 $deplig->localtax1_tx = $objp->localtax1_tx;
1157 $deplig->localtax2_tx = $objp->localtax2_tx;
1158 $deplig->localtax1_type = $objp->localtax1_type;
1159 $deplig->localtax2_type = $objp->localtax2_type;
1161 $deplig->projet_ref = $objp->ref_projet;
1162 $deplig->projet_title = $objp->title_projet;
1164 $deplig->rule_warning_message = $objp->rule_warning_message;
1166 $deplig->rang = $objp->rang;
1168 $this->lines[$i] = $deplig;
1172 $this->db->free($resql);
1175 $this->error = $this->db->lasterror();
1176 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1189 public function delete(
User $user =
null, $notrigger = 0)
1192 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1200 $result = $this->
call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1208 if (!$error && !empty($this->table_element_line)) {
1209 $tabletodelete = $this->table_element_line;
1211 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1212 if (!$this->db->query($sql)) {
1214 $this->error = $this->db->lasterror();
1215 $this->errors[] = $this->error;
1216 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1241 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1247 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1248 $res = $this->db->query($sql);
1251 $this->error = $this->db->lasterror();
1252 $this->errors[] = $this->error;
1253 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1269 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1270 $dir = $conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1271 $file = $dir.
"/".$ref.
".pdf";
1272 if (file_exists($file)) {
1276 $this->error =
'ErrorFailToDeleteFile';
1277 $this->errors[] = $this->error;
1278 $this->db->rollback();
1282 if (file_exists($dir)) {
1285 $this->error =
'ErrorFailToDeleteDir';
1286 $this->errors[] = $this->error;
1287 $this->db->rollback();
1295 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1296 $this->db->commit();
1299 $this->db->rollback();
1313 global $conf, $langs, $user;
1319 if ($this->
status == self::STATUS_VALIDATED) {
1320 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
1324 $this->date_valid = $now;
1327 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
1332 if (empty($num) || $num < 0) {
1341 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1342 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1343 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1344 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1345 $sql .=
" fk_user_valid = ".((int) $user->id);
1346 $sql .=
" WHERE rowid = ".((int) $this->
id);
1348 $resql = $this->db->query($sql);
1350 if (!$error && !$notrigger) {
1352 $result = $this->
call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1360 $this->oldref = $this->ref;
1363 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1364 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1367 $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).
"'";
1368 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1369 $resql = $this->db->query($sql);
1372 $this->error = $this->db->lasterror();
1374 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1375 $sql .=
" WHERE filepath = 'expensereport/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
1376 $resql = $this->db->query($sql);
1379 $this->error = $this->db->lasterror();
1385 $dirsource = $conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1386 $dirdest = $conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1387 if (!$error && file_exists($dirsource)) {
1388 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1390 if (@rename($dirsource, $dirdest)) {
1393 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1394 foreach ($listoffiles as $fileentry) {
1395 $dirsource = $fileentry[
'name'];
1396 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1397 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1398 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1399 @rename($dirsource, $dirdest);
1412 if (empty($error)) {
1413 $this->db->commit();
1416 $this->db->rollback();
1417 $this->error = $this->db->error();
1421 $this->db->rollback();
1422 $this->error = $this->db->lasterror();
1438 $sql =
'SELECT date_debut';
1439 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1440 $sql .=
" WHERE rowid = ".((int) $this->
id);
1442 $result = $this->db->query($sql);
1444 $objp = $this->db->fetch_object($result);
1446 $this->date_debut = $this->db->jdate($objp->date_debut);
1448 if ($this->
status != self::STATUS_VALIDATED) {
1449 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1450 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1451 $sql .=
" WHERE rowid = ".((int) $this->
id);
1453 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1455 if ($this->db->query($sql)) {
1458 $this->error = $this->db->lasterror();
1462 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1481 $this->date_approve = $now;
1482 if ($this->
status != self::STATUS_APPROVED) {
1485 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1486 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1487 $sql .=
" date_approve='".$this->db->idate($this->date_approve).
"'";
1488 $sql .=
" WHERE rowid = ".((int) $this->
id);
1489 if ($this->db->query($sql)) {
1492 $result = $this->
call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1500 if (empty($error)) {
1501 $this->db->commit();
1504 $this->db->rollback();
1505 $this->error = $this->db->error();
1509 $this->db->rollback();
1510 $this->error = $this->db->lasterror();
1514 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1528 public function setDeny($fuser, $details, $notrigger = 0)
1534 if ($this->
status != self::STATUS_REFUSED) {
1535 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1536 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1537 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1538 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1539 $sql .=
" fk_user_approve = NULL";
1540 $sql .=
" WHERE rowid = ".((int) $this->
id);
1541 if ($this->db->query($sql)) {
1542 $this->fk_statut = 99;
1544 $this->fk_user_refuse = $fuser->id;
1545 $this->detail_refuse = $details;
1546 $this->date_refuse = $now;
1550 $result = $this->
call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1558 if (empty($error)) {
1559 $this->db->commit();
1562 $this->db->rollback();
1563 $this->error = $this->db->error();
1567 $this->db->rollback();
1568 $this->error = $this->db->lasterror();
1572 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1591 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1592 return $this->
setUnpaid($fuser, $notrigger);
1609 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1610 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1611 $sql .=
" WHERE rowid = ".((int) $this->
id);
1613 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1615 if ($this->db->query($sql)) {
1618 $result = $this->
call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1626 if (empty($error)) {
1627 $this->db->commit();
1630 $this->db->rollback();
1631 $this->error = $this->db->error();
1635 $this->db->rollback();
1636 $this->error = $this->db->error();
1640 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1659 $this->date_cancel = $this->db->idate(
dol_now());
1660 if ($this->
status != self::STATUS_CANCELED) {
1663 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1664 $sql .=
" SET fk_statut = ".self::STATUS_CANCELED.
", fk_user_cancel = ".((int) $fuser->id);
1665 $sql .=
", date_cancel='".$this->db->idate($this->date_cancel).
"'";
1666 $sql .=
", detail_cancel='".$this->db->escape($detail).
"'";
1667 $sql .=
" WHERE rowid = ".((int) $this->
id);
1669 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1671 if ($this->db->query($sql)) {
1674 $result = $this->
call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1682 if (empty($error)) {
1683 $this->db->commit();
1686 $this->db->rollback();
1687 $this->error = $this->db->error();
1691 $this->db->rollback();
1692 $this->error = $this->db->error();
1696 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1708 global $langs, $conf;
1709 $langs->load(
"trips");
1718 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1719 foreach ($dirmodels as $reldir) {
1720 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1723 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1731 $obj =
new $classname();
1732 $numref = $obj->getNextValue($this);
1734 if ($numref !=
"") {
1737 $this->error = $obj->error;
1738 $this->errors = $obj->errors;
1743 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1757 global $conf, $langs;
1759 $langs->load(
'trips');
1761 $nofetch = !empty($params[
'nofetch']);
1762 $moretitle = $params[
'moretitle'] ??
'';
1765 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1766 if (isset($this->
status)) {
1767 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1770 $datas[
'picto'] .=
' - '.$moretitle;
1772 if (!empty($this->
ref)) {
1773 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1775 if (!empty($this->total_ht)) {
1776 $datas[
'total_ht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1778 if (!empty($this->total_tva)) {
1779 $datas[
'total_tva'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1781 if (!empty($this->total_ttc)) {
1782 $datas[
'total_ttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
1800 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1802 global $langs, $hookmanager;
1806 $url = DOL_URL_ROOT.
'/expensereport/card.php?id='.$this->id;
1814 'objecttype' => $this->element,
1815 'option' => $option,
1816 'moretitle' => $moretitle,
1819 $classfortooltip =
'classfortooltip';
1822 $classfortooltip =
'classforajaxtooltip';
1823 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1829 if ($option !=
'nolink') {
1831 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1832 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1833 $add_save_lastsearch_values = 1;
1835 if ($add_save_lastsearch_values) {
1836 $url .=
'&save_lastsearch_values=1';
1846 if (empty($notooltip)) {
1848 $label = $langs->trans(
"ShowExpenseReport");
1849 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1851 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
1852 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
1855 $linkstart =
'<a href="'.$url.
'"';
1856 $linkstart .= $linkclose.
'>';
1859 $result .= $linkstart;
1861 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
1863 if ($withpicto != 2) {
1864 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1866 $result .= $linkend;
1869 $hookmanager->initHooks(array($this->element .
'dao'));
1870 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
1871 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1873 $result = $hookmanager->resPrint;
1875 $result .= $hookmanager->resPrint;
1891 $this->total_ht += (float) $ligne_total_ht;
1892 $this->total_tva += (float) $ligne_total_tva;
1893 $this->total_ttc += $this->total_tva;
1895 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1896 $sql .=
" total_ht = ".$this->total_ht;
1897 $sql .=
" , total_ttc = ".$this->total_ttc;
1898 $sql .=
" , total_tva = ".$this->total_tva;
1899 $sql .=
" WHERE rowid = ".((int) $this->
id);
1901 $result = $this->db->query($sql);
1905 $this->error = $this->db->error();
1925 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)
1927 global $langs, $mysoc;
1929 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);
1931 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
1935 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1936 $fk_c_type_fees = 0;
1938 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1939 $fk_c_exp_tax_cat = 0;
1941 if (empty($vatrate) || $vatrate < 0) {
1947 if (empty($fk_project)) {
1952 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1963 $seller->tva_assuj = 1;
1964 $buyer =
new Societe($this->db);
1970 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
1971 $vat_src_code = $reg[1];
1972 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
1974 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
1976 $tmp =
calcul_price_total($qty, $up, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
1978 $this->line->value_unit = $up;
1980 $this->line->vat_src_code = $vat_src_code;
1981 $this->line->vatrate =
price2num($vatrate);
1982 $this->line->localtax1_tx = $localtaxes_type[1];
1983 $this->line->localtax2_tx = $localtaxes_type[3];
1984 $this->line->localtax1_type = $localtaxes_type[0];
1985 $this->line->localtax2_type = $localtaxes_type[2];
1987 $this->line->total_ttc = $tmp[2];
1988 $this->line->total_ht = $tmp[0];
1989 $this->line->total_tva = $tmp[1];
1990 $this->line->total_localtax1 = $tmp[9];
1991 $this->line->total_localtax2 = $tmp[10];
1993 $this->line->fk_expensereport = $this->id;
1994 $this->line->qty = $qty;
1995 $this->line->date = $date;
1996 $this->line->fk_c_type_fees = $fk_c_type_fees;
1997 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
1998 $this->line->comments = $comments;
1999 $this->line->fk_projet = $fk_project;
2000 $this->line->fk_project = $fk_project;
2002 $this->line->fk_ecm_files = $fk_ecm_files;
2007 $result = $this->line->insert(0,
true);
2011 $this->db->commit();
2012 return $this->line->id;
2014 $this->db->rollback();
2018 $this->error = $this->line->error;
2019 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
2020 $this->db->rollback();
2024 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
2025 $this->error =
'ErrorExpenseNotDraftAndNotRefused';
2039 global $conf, $db, $langs, $mysoc;
2041 $langs->load(
'trips');
2044 if (!is_object($seller)) {
2046 $seller->tva_assuj = 1;
2050 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
2053 $rule_warning_message_tab = array();
2055 $current_total_ttc = $this->line->total_ttc;
2056 $new_current_total_ttc = $this->line->total_ttc;
2059 foreach ($rulestocheck as $rule) {
2060 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
2061 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
2063 $amount_to_test = $current_total_ttc;
2066 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
2068 if ($amount_to_test > $rule->amount) {
2071 if ($rule->restrictive) {
2072 $this->error =
'ExpenseReportConstraintViolationError';
2073 $this->errors[] = $this->error;
2075 $new_current_total_ttc -= $amount_to_test - $rule->amount;
2076 $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));
2078 $this->error =
'ExpenseReportConstraintViolationWarning';
2079 $this->errors[] = $this->error;
2081 $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));
2088 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
2090 if ($violation > 0) {
2091 $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);
2093 $this->line->value_unit = $tmp[5];
2094 $this->line->total_ttc = $tmp[2];
2095 $this->line->total_ht = $tmp[0];
2096 $this->line->total_tva = $tmp[1];
2097 $this->line->total_localtax1 = $tmp[9];
2098 $this->line->total_localtax2 = $tmp[10];
2121 $userauthor =
new User($this->db);
2122 if ($userauthor->fetch($this->fk_user_author) <= 0) {
2123 $this->error =
'ErrorCantFetchUser';
2124 $this->errors[] =
'ErrorCantFetchUser';
2129 if (!is_object($seller)) {
2131 $seller->tva_assuj = 1;
2135 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2137 if (empty($range)) {
2138 $this->error =
'ErrorNoRangeAvailable';
2139 $this->errors[] =
'ErrorNoRangeAvailable';
2144 $ikoffset = $range->ikoffset;
2146 $ikoffset = $range->ikoffset / 12;
2151 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2152 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2154 $this->line->value_unit = $tmp[5];
2155 $this->line->total_ttc = $tmp[2];
2156 $this->line->total_ht = $tmp[0];
2157 $this->line->total_tva = $tmp[1];
2158 $this->line->total_localtax1 = $tmp[9];
2159 $this->line->total_localtax2 = $tmp[10];
2174 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2175 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2176 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2177 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2178 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2179 if (!empty($this->line->id)) {
2180 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2183 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2184 $resql = $this->db->query($sql);
2186 $num = $this->db->num_rows($resql);
2214 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)
2216 global $user, $mysoc;
2218 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
2226 $seller->tva_assuj = 1;
2227 $seller->localtax1_assuj = $mysoc->localtax1_assuj;
2228 $seller->localtax2_assuj = $mysoc->localtax1_assuj;
2229 $buyer =
new Societe($this->db);
2236 if (preg_match(
'/\((.*)\)/', (
string) $vatrate, $reg)) {
2237 $vat_src_code = $reg[1];
2238 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', (
string) $vatrate);
2240 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2242 $tmp =
calcul_price_total($qty, $value_unit, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2247 $tx_tva = 1 + (float) $vatrate / 100;
2250 $this->line->comments = $comments;
2251 $this->line->qty = $qty;
2252 $this->line->value_unit = $value_unit;
2253 $this->line->date = $date;
2255 $this->line->fk_expensereport = $expensereport_id;
2256 $this->line->fk_c_type_fees = $type_fees_id;
2257 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2258 $this->line->fk_projet = $projet_id;
2259 $this->line->fk_project = $projet_id;
2261 $this->line->vat_src_code = $vat_src_code;
2262 $this->line->vatrate =
price2num($vatrate);
2263 $this->line->localtax1_tx = $localtaxes_type[1];
2264 $this->line->localtax2_tx = $localtaxes_type[3];
2265 $this->line->localtax1_type = $localtaxes_type[0];
2266 $this->line->localtax2_type = $localtaxes_type[2];
2268 $this->line->total_ttc = $tmp[2];
2269 $this->line->total_ht = $tmp[0];
2270 $this->line->total_tva = $tmp[1];
2271 $this->line->total_localtax1 = $tmp[9];
2272 $this->line->total_localtax2 = $tmp[10];
2274 $this->line->fk_ecm_files = $fk_ecm_files;
2276 $this->line->id = ((int) $rowid);
2279 $sql =
"SELECT c.code as code_type_fees, c.label as label_type_fees";
2280 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2281 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2282 $resql = $this->db->query($sql);
2284 $objp_fees = $this->db->fetch_object($resql);
2285 $this->line->type_fees_code = $objp_fees->code_type_fees;
2286 $this->line->type_fees_libelle = $objp_fees->label_type_fees;
2287 $this->db->free($resql);
2291 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2292 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2293 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2294 $resql = $this->db->query($sql);
2296 $objp_projet = $this->db->fetch_object($resql);
2297 $this->line->projet_ref = $objp_projet->ref_projet;
2298 $this->line->projet_title = $objp_projet->title_projet;
2299 $this->db->free($resql);
2305 $result = $this->line->update($user);
2310 if (!$error && !$notrigger) {
2312 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_MODIFY', $user);
2320 $this->db->commit();
2323 $this->error = $this->line->error;
2324 $this->errors = $this->line->errors;
2325 $this->db->rollback();
2349 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2356 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2357 $sql .=
' WHERE rowid = '.((int) $rowid);
2359 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2360 $result = $this->db->query($sql);
2362 if (!$result || $error > 0) {
2363 $this->error = $this->db->error();
2364 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2365 $this->db->rollback();
2371 $this->db->commit();
2390 $sql =
"SELECT rowid, date_debut, date_fin";
2391 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2392 $sql .=
" WHERE entity = ".((int) $conf->entity);
2393 $sql .=
" AND fk_user_author = ".((int) $fuser->id);
2395 dol_syslog(get_class($this).
"::periode_existe sql=".$sql);
2396 $result = $this->db->query($sql);
2398 $num_rows = $this->db->num_rows($result);
2401 if ($num_rows > 0) {
2402 $date_d_form = $date_debut;
2403 $date_f_form = $date_fin;
2405 while ($i < $num_rows) {
2406 $objp = $this->db->fetch_object($result);
2408 $date_d_req = $this->db->jdate($objp->date_debut);
2409 $date_f_req = $this->db->jdate($objp->date_fin);
2411 if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) {
2412 return $objp->rowid;
2423 $this->error = $this->db->lasterror();
2424 dol_syslog(get_class($this).
"::periode_existe Error ".$this->error, LOG_ERR);
2440 $users_validator = array();
2442 $sql =
"SELECT DISTINCT ur.fk_user";
2443 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2444 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2446 $sql .=
" SELECT DISTINCT ugu.fk_user";
2447 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2448 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2451 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2452 $result = $this->db->query($sql);
2454 $num_rows = $this->db->num_rows($result);
2456 while ($i < $num_rows) {
2457 $objp = $this->db->fetch_object($result);
2458 array_push($users_validator, $objp->fk_user);
2461 return $users_validator;
2463 $this->error = $this->db->lasterror();
2464 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2480 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2482 $outputlangs->load(
"trips");
2485 if (!empty($this->model_pdf)) {
2486 $modele = $this->model_pdf;
2492 if (!empty($modele)) {
2493 $modelpath =
"core/modules/expensereport/doc/";
2495 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2511 $sql =
"SELECT id, code, label";
2512 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2513 $sql .=
" WHERE active = ".((int) $active);
2514 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2515 $result = $this->db->query($sql);
2517 $num = $this->db->num_rows($result);
2520 $obj = $this->db->fetch_object($result);
2521 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2539 $this->nb = array();
2541 $sql =
"SELECT count(ex.rowid) as nb";
2542 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2543 $sql .=
" WHERE ex.fk_statut > 0";
2544 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2545 if (!$user->hasRight(
'expensereport',
'readall')) {
2546 $userchildids = $user->getAllChildIds(1);
2547 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2548 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2551 $resql = $this->db->query($sql);
2553 while ($obj = $this->db->fetch_object($resql)) {
2554 $this->nb[
"expensereports"] = $obj->nb;
2556 $this->db->free($resql);
2560 $this->error = $this->db->error();
2576 global $conf, $langs;
2584 $sql =
"SELECT ex.rowid, ex.date_valid";
2585 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2586 if ($option ==
'toapprove') {
2587 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2589 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2591 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2592 if (!$user->hasRight(
'expensereport',
'readall')) {
2593 $userchildids = $user->getAllChildIds(1);
2594 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2595 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2598 $resql = $this->db->query($sql);
2600 $langs->load(
"trips");
2603 if ($option ==
'toapprove') {
2604 $response->warning_delay = $conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2605 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2606 $response->labelShort = $langs->trans(
"ToApprove");
2609 $response->warning_delay = $conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2610 $response->label = $langs->trans(
"ExpenseReportsToPay");
2611 $response->labelShort = $langs->trans(
"StatusToPay");
2612 $response->url = DOL_URL_ROOT.
'/expensereport/list.php?mainmenu=hrm&statut='.
self::STATUS_APPROVED;
2616 while ($obj = $this->db->fetch_object($resql)) {
2617 $response->nbtodo++;
2619 if ($option ==
'toapprove') {
2620 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->approve->warning_delay)) {
2621 $response->nbtodolate++;
2624 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->payment->warning_delay)) {
2625 $response->nbtodolate++;
2633 $this->error = $this->db->error();
2649 if ($option ==
'toapprove' && $this->
status != 2) {
2652 if ($option ==
'topay' && $this->
status != 5) {
2657 if ($option ==
'toapprove') {
2658 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->approve->warning_delay);
2660 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->payment->warning_delay);
2671 $alreadydispatched = 0;
2673 $type =
'expense_report';
2675 $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);
2676 $resql = $this->db->query($sql);
2678 $obj = $this->db->fetch_object($resql);
2680 $alreadydispatched = $obj->nb;
2683 $this->error = $this->db->lasterror();
2687 if ($alreadydispatched) {
2700 $table =
'payment_expensereport';
2701 $field =
'fk_expensereport';
2703 $sql =
'SELECT sum(amount) as amount';
2704 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2705 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
2707 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2708 $resql = $this->db->query($sql);
2710 $obj = $this->db->fetch_object($resql);
2711 $this->db->free($resql);
2712 return (empty($obj->amount) ? 0 : $obj->amount);
2714 $this->error = $this->db->lasterror();
2729 global $langs, $db, $conf;
2737 $this->error = $langs->trans(
'ErrorBadParameterCat');
2742 $this->error = $langs->trans(
'ErrorBadParameterQty');
2746 $currentUser =
new User($db);
2747 $currentUser->fetch($this->fk_user);
2748 $currentUser->getrights(
'expensereport');
2752 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2753 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2754 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2755 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2756 $sql .=
" ORDER BY r.range_ik ASC";
2758 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2760 $result = $this->db->query($sql);
2763 if ($conf->global->EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR) {
2765 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2766 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2767 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2768 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2769 $sql .=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2770 $sql .=
" AND tf.code = 'EX_KME' ";
2773 $resql = $this->db->query($sql);
2776 $obj = $this->db->fetch_object($resql);
2777 $cumulYearQty = $obj->cumul;
2780 $qty += (float) $cumulYearQty;
2783 $num = $this->db->num_rows($result);
2786 for ($i = 0; $i < $num; $i++) {
2787 $obj = $this->db->fetch_object($result);
2793 for ($i = 0; $i < $num; $i++) {
2794 if ($i < ($num - 1)) {
2795 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i + 1]->range_ik) {
2796 $coef = $ranges[$i]->coef;
2797 $offset = $ranges[$i]->ikoffset;
2800 if ($qty > $ranges[$i]->range_ik) {
2801 $coef = $ranges[$i]->coef;
2802 $offset = $ranges[$i]->ikoffset;
2809 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2813 $this->error = $this->db->error().
" sql=".$sql;
2830 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2832 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2833 $return .=
'<div class="info-box info-box-sm">';
2834 $return .=
'<span class="info-box-icon bg-infobox-action">';
2836 $return .=
'</span>';
2837 $return .=
'<div class="info-box-content">';
2838 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
2839 if ($selected >= 0) {
2840 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2842 if (array_key_exists(
'userauthor', $arraydata)) {
2843 $return .=
'<br><span class="info-box-label">'.$arraydata[
'userauthor']->getNomUrl(-1).
'</span>';
2845 if (property_exists($this,
'date_debut') && property_exists($this,
'date_fin')) {
2846 $return .=
'<br><span class="info-box-label">'.dol_print_date($this->date_debut,
'day').
'</span>';
2847 $return .=
' <span class="opacitymedium">'.$langs->trans(
"To").
'</span> ';
2848 $return .=
'<span class="info-box-label">'.dol_print_date($this->date_fin,
'day').
'</span>';
2850 if (method_exists($this,
'getLibStatut')) {
2851 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
2853 $return .=
'</div>';
2854 $return .=
'</div>';
2855 $return .=
'</div>';
2874 public $table_element =
'expensereport_det';
2903 public $fk_c_type_fees;
2908 public $fk_c_exp_tax_cat;
2918 public $fk_expensereport;
2920 public $type_fees_code;
2921 public $type_fees_libelle;
2922 public $type_fees_accountancy_code;
2925 public $projet_title;
2929 public $vat_src_code;
2931 public $localtax1_tx;
2932 public $localtax2_tx;
2933 public $localtax1_type;
2934 public $localtax2_type;
2939 public $total_localtax1;
2940 public $total_localtax2;
2946 public $fk_multicurrency;
2951 public $multicurrency_code;
2952 public $multicurrency_tx;
2953 public $multicurrency_total_ht;
2954 public $multicurrency_total_tva;
2955 public $multicurrency_total_ttc;
2960 public $fk_ecm_files;
2962 public $rule_warning_message;
2983 $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,';
2984 $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,';
2985 $sql .=
' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,';
2986 $sql .=
' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
2987 $sql .=
' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
2988 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det as fde';
2989 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
2990 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as pjt ON fde.fk_projet=pjt.rowid';
2991 $sql .=
' WHERE fde.rowid = '.((int) $rowid);
2993 $result = $this->db->query($sql);
2996 $objp = $this->db->fetch_object($result);
2998 $this->
rowid = $objp->rowid;
2999 $this->
id = $objp->rowid;
3000 $this->
ref = $objp->ref;
3001 $this->fk_expensereport = $objp->fk_expensereport;
3002 $this->comments = $objp->comments;
3003 $this->qty = $objp->qty;
3004 $this->date = $objp->date;
3005 $this->dates = $this->db->jdate($objp->date);
3006 $this->value_unit = $objp->value_unit;
3007 $this->fk_c_type_fees = $objp->fk_c_type_fees;
3008 $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
3009 $this->fk_projet = $objp->fk_project;
3010 $this->fk_project = $objp->fk_project;
3011 $this->type_fees_code = $objp->type_fees_code;
3012 $this->type_fees_libelle = $objp->type_fees_libelle;
3013 $this->projet_ref = $objp->projet_ref;
3014 $this->projet_title = $objp->projet_title;
3016 $this->
vatrate = $objp->vatrate;
3017 $this->vat_src_code = $objp->vat_src_code;
3018 $this->localtax1_tx = $objp->localtax1_tx;
3019 $this->localtax2_tx = $objp->localtax2_tx;
3020 $this->localtax1_type = $objp->localtax1_type;
3021 $this->localtax2_type = $objp->localtax2_type;
3023 $this->total_ht = $objp->total_ht;
3024 $this->total_tva = $objp->total_tva;
3025 $this->total_ttc = $objp->total_ttc;
3026 $this->total_localtax1 = $objp->total_localtax1;
3027 $this->total_localtax2 = $objp->total_localtax2;
3029 $this->fk_ecm_files = $objp->fk_ecm_files;
3031 $this->rule_warning_message = $objp->rule_warning_message;
3033 $this->db->free($result);
3049 public function insert($notrigger = 0, $fromaddline =
false)
3055 dol_syslog(
"ExpenseReportLine::Insert", LOG_DEBUG);
3058 $this->comments = trim($this->comments);
3059 if (empty($this->value_unit)) {
3060 $this->value_unit = 0;
3062 $this->qty = (float)
price2num($this->qty);
3064 if (empty($this->fk_c_exp_tax_cat)) {
3065 $this->fk_c_exp_tax_cat = 0;
3070 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'expensereport_det';
3071 $sql .=
' (fk_expensereport, fk_c_type_fees, fk_projet,';
3072 $sql .=
' tva_tx, vat_src_code,';
3073 $sql .=
' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
3074 $sql .=
' comments, qty, value_unit,';
3075 $sql .=
' total_ht, total_tva, total_ttc,';
3076 $sql .=
' total_localtax1, total_localtax2,';
3077 $sql .=
' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)';
3078 $sql .=
" VALUES (".$this->db->escape($this->fk_expensereport).
",";
3079 $sql .=
" ".((int) $this->fk_c_type_fees).
",";
3080 $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')).
",";
3081 $sql .=
" ".((float) $this->
vatrate).
",";
3082 $sql .=
" '".$this->db->escape(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"',";
3083 $sql .=
" ".((float)
price2num($this->localtax1_tx)).
",";
3084 $sql .=
" ".((float)
price2num($this->localtax2_tx)).
",";
3085 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
3086 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
3087 $sql .=
" '".$this->db->escape($this->comments).
"',";
3088 $sql .=
" ".((float) $this->qty).
",";
3089 $sql .=
" ".((float) $this->value_unit).
",";
3090 $sql .=
" ".((float)
price2num($this->total_ht)).
",";
3091 $sql .=
" ".((float)
price2num($this->total_tva)).
",";
3092 $sql .=
" ".((float)
price2num($this->total_ttc)).
",";
3093 $sql .=
" ".((float)
price2num($this->total_localtax1)).
",";
3094 $sql .=
" ".((float)
price2num($this->total_localtax2)).
",";
3095 $sql .=
" '".$this->db->idate($this->date).
"',";
3096 $sql .=
" ".(empty($this->rule_warning_message) ?
'null' :
"'".$this->db->escape($this->rule_warning_message).
"'").
",";
3097 $sql .=
" ".((int) $this->fk_c_exp_tax_cat).
",";
3098 $sql .=
" ".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3101 $resql = $this->db->query($sql);
3103 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'expensereport_det');
3106 if (!$error && !$notrigger) {
3108 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_CREATE', $user);
3116 if (!$fromaddline) {
3118 $tmpparent->fetch($this->fk_expensereport);
3119 $result = $tmpparent->update_price(1);
3122 $this->error = $tmpparent->error;
3123 $this->errors = $tmpparent->errors;
3131 $this->db->commit();
3134 $this->error = $this->db->lasterror();
3135 dol_syslog(
"ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
3136 $this->db->rollback();
3153 $sql =
'SELECT SUM(d.total_ttc) as total_amount';
3154 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det d';
3155 $sql .=
' INNER JOIN '.MAIN_DB_PREFIX.
'expensereport e ON (d.fk_expensereport = e.rowid)';
3156 $sql .=
' WHERE e.fk_user_author = '.((int) $fk_user);
3157 if (!empty($this->
id)) {
3158 $sql .=
' AND d.rowid <> '.((int) $this->
id);
3160 $sql .=
' AND d.fk_c_type_fees = '.((int) $rule->fk_c_type_fees);
3161 if ($mode ==
'day' || $mode ==
'EX_DAY') {
3162 $sql .=
" AND d.date = '".dol_print_date($this->date,
'%Y-%m-%d').
"'";
3163 } elseif ($mode ==
'mon' || $mode ==
'EX_MON') {
3164 $sql .=
" AND DATE_FORMAT(d.date, '%Y-%m') = '".dol_print_date($this->date,
'%Y-%m').
"'";
3165 } elseif ($mode ==
'year' || $mode ==
'EX_YEA') {
3166 $sql .=
" AND DATE_FORMAT(d.date, '%Y') = '".dol_print_date($this->date,
'%Y').
"'";
3169 dol_syslog(
'ExpenseReportLine::getExpAmount');
3171 $resql = $this->db->query($sql);
3173 $num = $this->db->num_rows($resql);
3175 $obj = $this->db->fetch_object($resql);
3176 $amount = (float) $obj->total_amount;
3182 return $amount + $this->total_ttc;
3198 $this->comments = trim($this->comments);
3200 $this->value_unit =
price2num($this->value_unit);
3201 if (empty($this->fk_c_exp_tax_cat)) {
3202 $this->fk_c_exp_tax_cat = 0;
3208 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport_det SET";
3209 $sql .=
" comments='".$this->db->escape($this->comments).
"'";
3210 $sql .=
", value_unit = ".((float) $this->value_unit);
3211 $sql .=
", qty=".((float) $this->qty);
3212 $sql .=
", date='".$this->db->idate($this->date).
"'";
3213 $sql .=
", total_ht=".((float)
price2num($this->total_ht,
'MT'));
3214 $sql .=
", total_tva=".((float)
price2num($this->total_tva,
'MT'));
3215 $sql .=
", total_ttc=".((float)
price2num($this->total_ttc,
'MT'));
3216 $sql .=
", total_localtax1=".((float)
price2num($this->total_localtax1,
'MT'));
3217 $sql .=
", total_localtax2=".((float)
price2num($this->total_localtax2,
'MT'));
3218 $sql .=
", tva_tx=".((float) $this->
vatrate);
3219 $sql .=
", vat_src_code='".$this->db->escape($this->vat_src_code).
"'";
3220 $sql .=
", localtax1_tx=".((float) $this->localtax1_tx);
3221 $sql .=
", localtax2_tx=".((float) $this->localtax2_tx);
3222 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
3223 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
3224 $sql .=
", rule_warning_message='".$this->db->escape($this->rule_warning_message).
"'";
3225 $sql .=
", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat);
3226 $sql .=
", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3227 if ($this->fk_c_type_fees) {
3228 $sql .=
", fk_c_type_fees = ".((int) $this->fk_c_type_fees);
3230 $sql .=
", fk_c_type_fees=null";
3232 if ($this->fk_project > 0) {
3233 $sql .=
", fk_projet=".((int) $this->fk_project);
3235 $sql .=
", fk_projet=null";
3237 $sql .=
" WHERE rowid = ".((int) ($this->
rowid ? $this->
rowid : $this->id));
3241 $resql = $this->db->query($sql);
3244 $result = $tmpparent->fetch($this->fk_expensereport);
3246 $result = $tmpparent->update_price(1);
3249 $this->error = $tmpparent->error;
3250 $this->errors = $tmpparent->errors;
3254 $this->error = $tmpparent->error;
3255 $this->errors = $tmpparent->errors;
3263 $this->db->commit();
3266 $this->error = $this->db->lasterror();
3267 dol_syslog(
"ExpenseReportLine::update Error ".$this->error, LOG_ERR);
3268 $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