31require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
32require_once DOL_DOCUMENT_ROOT.
'/expensereport/class/expensereportline.class.php';
33require_once DOL_DOCUMENT_ROOT.
'/expensereport/class/expensereport_ik.class.php';
34require_once DOL_DOCUMENT_ROOT.
'/expensereport/class/expensereport_rule.class.php';
45 public $element =
'expensereport';
50 public $table_element =
'expensereport';
55 public $table_element_line =
'expensereport_det';
60 public $class_element_line =
'ExpenseReportLine';
65 public $fk_element =
'fk_expensereport';
70 public $picto =
'trip';
75 public $lines = array();
95 public $date_approbation;
105 public $user_approve_id;
125 public $fk_c_paiement;
130 public $modepaymentid;
141 public $user_paid_infos;
146 public $user_author_infos;
151 public $user_validator_infos;
156 public $rule_warning_message;
169 public $fk_user_creat;
174 public $fk_user_author;
185 public $fk_user_modif;
196 public $detail_refuse;
201 public $fk_user_refuse;
212 public $detail_cancel;
217 public $fk_user_cancel;
222 public $fk_user_validator;
241 public $fk_user_valid;
246 public $user_valid_infos;
252 public $date_approve;
257 public $fk_user_approve;
300 public $fields = array(
301 'rowid' => array(
'type' =>
'integer',
'label' =>
'ID',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 10),
302 'ref' => array(
'type' =>
'varchar(50)',
'label' =>
'Ref',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'showoncombobox' => 1,
'position' => 15),
303 'entity' => array(
'type' =>
'integer',
'label' =>
'Entity',
'default' =>
'1',
'enabled' => 1,
'visible' => -2,
'notnull' => 1,
'position' => 20),
304 'ref_number_int' => array(
'type' =>
'integer',
'label' =>
'Ref number int',
'enabled' => 1,
'visible' => -1,
'position' => 25),
305 'ref_ext' => array(
'type' =>
'integer',
'label' =>
'RefExt',
'enabled' => 1,
'visible' => 0,
'position' => 30),
306 'total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'Total ht',
'enabled' => 1,
'visible' => -1,
'position' => 35),
307 'total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'Total tva',
'enabled' => 1,
'visible' => -1,
'position' => 40),
308 'localtax1' => array(
'type' =>
'double(24,8)',
'label' =>
'Localtax1',
'enabled' => 1,
'visible' => -1,
'position' => 45),
309 'localtax2' => array(
'type' =>
'double(24,8)',
'label' =>
'Localtax2',
'enabled' => 1,
'visible' => -1,
'position' => 50),
310 'total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'Total ttc',
'enabled' => 1,
'visible' => -1,
'position' => 55),
311 'date_debut' => array(
'type' =>
'date',
'label' =>
'Date debut',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 60),
312 'date_fin' => array(
'type' =>
'date',
'label' =>
'Date fin',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 65),
313 'date_valid' => array(
'type' =>
'datetime',
'label' =>
'Date valid',
'enabled' => 1,
'visible' => -1,
'position' => 75),
314 'date_approve' => array(
'type' =>
'datetime',
'label' =>
'Date approve',
'enabled' => 1,
'visible' => -1,
'position' => 80),
315 'date_refuse' => array(
'type' =>
'datetime',
'label' =>
'Date refuse',
'enabled' => 1,
'visible' => -1,
'position' => 85),
316 'date_cancel' => array(
'type' =>
'datetime',
'label' =>
'Date cancel',
'enabled' => 1,
'visible' => -1,
'position' => 90),
317 'fk_user_author' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserAuthor',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 100),
318 'fk_user_modif' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserModif',
'enabled' => 1,
'visible' => -1,
'position' => 105),
319 'fk_user_valid' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserValidation',
'enabled' => 1,
'visible' => -1,
'position' => 110),
320 'fk_user_validator' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user validator',
'enabled' => 1,
'visible' => -1,
'position' => 115),
321 'fk_user_approve' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user approve',
'enabled' => 1,
'visible' => -1,
'position' => 120),
322 'fk_user_refuse' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user refuse',
'enabled' => 1,
'visible' => -1,
'position' => 125),
323 'fk_user_cancel' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user cancel',
'enabled' => 1,
'visible' => -1,
'position' => 130),
324 'fk_c_paiement' => array(
'type' =>
'integer',
'label' =>
'Fk c paiement',
'enabled' => 1,
'visible' => -1,
'position' => 140),
325 'paid' => array(
'type' =>
'integer',
'label' =>
'Paid',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 145),
326 'note_public' => array(
'type' =>
'html',
'label' =>
'Note public',
'enabled' => 1,
'visible' => 0,
'position' => 150),
327 'note_private' => array(
'type' =>
'html',
'label' =>
'Note private',
'enabled' => 1,
'visible' => 0,
'position' => 155),
328 'detail_refuse' => array(
'type' =>
'varchar(255)',
'label' =>
'Detail refuse',
'enabled' => 1,
'visible' => -1,
'position' => 160),
329 'detail_cancel' => array(
'type' =>
'varchar(255)',
'label' =>
'Detail cancel',
'enabled' => 1,
'visible' => -1,
'position' => 165),
330 'integration_compta' => array(
'type' =>
'integer',
'label' =>
'Integration compta',
'enabled' => 1,
'visible' => -1,
'position' => 170),
331 'fk_bank_account' => array(
'type' =>
'integer',
'label' =>
'Fk bank account',
'enabled' => 1,
'visible' => -1,
'position' => 175),
332 'fk_multicurrency' => array(
'type' =>
'integer',
'label' =>
'Fk multicurrency',
'enabled' => 1,
'visible' => -1,
'position' => 185),
333 'multicurrency_code' => array(
'type' =>
'varchar(255)',
'label' =>
'Multicurrency code',
'enabled' => 1,
'visible' => -1,
'position' => 190),
334 'multicurrency_tx' => array(
'type' =>
'double(24,8)',
'label' =>
'Multicurrency tx',
'enabled' => 1,
'visible' => -1,
'position' => 195),
335 'multicurrency_total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'Multicurrency total ht',
'enabled' => 1,
'visible' => -1,
'position' => 200),
336 'multicurrency_total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'Multicurrency total tva',
'enabled' => 1,
'visible' => -1,
'position' => 205),
337 'multicurrency_total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'Multicurrency total ttc',
'enabled' => 1,
'visible' => -1,
'position' => 210),
338 'extraparams' => array(
'type' =>
'varchar(255)',
'label' =>
'Extraparams',
'enabled' => 1,
'visible' => -1,
'position' => 220),
339 'date_create' => array(
'type' =>
'datetime',
'label' =>
'Date create',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 300),
340 'tms' => array(
'type' =>
'timestamp',
'label' =>
'Tms',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 305),
341 'import_key' => array(
'type' =>
'varchar(14)',
'label' =>
'ImportId',
'enabled' => 1,
'visible' => -1,
'position' => 1000),
342 'model_pdf' => array(
'type' =>
'varchar(255)',
'label' =>
'Model pdf',
'enabled' => 1,
'visible' => 0,
'position' => 1010),
343 'fk_statut' => array(
'type' =>
'integer',
'label' =>
'Status',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 500),
355 $this->total_ttc = 0;
356 $this->total_tva = 0;
357 $this->total_localtax1 = 0;
358 $this->total_localtax2 = 0;
359 $this->localtax1 = 0;
360 $this->localtax2 = 0;
361 $this->modepaymentid = 0;
364 $this->labelStatusShort = array(0 =>
'Draft', 2 =>
'Validated', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
365 $this->labelStatus = array(0 =>
'Draft', 2 =>
'ValidatedWaitingApproval', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
367 $this->fields[
'ref_ext'][
'visible'] =
getDolGlobalInt(
'MAIN_LIST_SHOW_REF_EXT');
377 public function create($user, $notrigger = 0)
379 global $conf, $langs;
386 if (empty($this->date_debut) || empty($this->date_fin)) {
387 $this->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
'Date'));
391 $fuserid = $this->fk_user_author;
392 if (empty($fuserid)) {
393 $fuserid = $user->id;
398 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
" (";
401 $sql .=
",total_ttc";
402 $sql .=
",total_tva";
403 $sql .=
",date_debut";
405 $sql .=
",date_create";
406 $sql .=
",fk_user_creat";
407 $sql .=
",fk_user_author";
408 $sql .=
",fk_user_validator";
409 $sql .=
",fk_user_approve";
410 $sql .=
",fk_user_modif";
411 $sql .=
",fk_statut";
412 $sql .=
",fk_c_paiement";
414 $sql .=
",note_public";
415 $sql .=
",note_private";
419 $sql .=
", ".price2num($this->total_ht,
'MT');
420 $sql .=
", ".price2num($this->total_ttc,
'MT');
421 $sql .=
", ".price2num($this->total_tva,
'MT');
422 $sql .=
", '".$this->db->idate($this->date_debut).
"'";
423 $sql .=
", '".$this->db->idate($this->date_fin).
"'";
424 $sql .=
", '".$this->db->idate($now).
"'";
425 $sql .=
", ".((int) $user->id);
426 $sql .=
", ".((int) $fuserid);
427 $sql .=
", ".($this->fk_user_validator > 0 ? ((int) $this->fk_user_validator) :
"null");
428 $sql .=
", ".($this->fk_user_approve > 0 ? ((int) $this->fk_user_approve) :
"null");
429 $sql .=
", ".($this->fk_user_modif > 0 ? ((int) $this->fk_user_modif) :
"null");
430 $sql .=
", ".($this->fk_statut > 1 ? ((int) $this->fk_statut) : 0);
431 $sql .=
", ".($this->modepaymentid ? ((int) $this->modepaymentid) :
"null");
433 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
"null");
434 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
"null");
435 $sql .=
", ".((int) $conf->entity);
438 $result = $this->db->query($sql);
440 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
441 $this->
ref =
'(PROV'.$this->id.
')';
443 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
" SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
444 $resql = $this->db->query($sql);
446 $this->error = $this->db->lasterror();
451 if (is_array($this->lines) && count($this->lines) > 0) {
452 foreach ($this->lines as $line) {
455 if (!is_object($line)) {
456 $line = (object) $line;
458 $newndfline->fk_expensereport = $line->fk_expensereport;
459 $newndfline->fk_c_type_fees = $line->fk_c_type_fees;
460 $newndfline->fk_project = $line->fk_project;
461 $newndfline->vatrate = $line->vatrate;
462 $newndfline->vat_src_code = $line->vat_src_code;
463 $newndfline->localtax1_tx = $line->localtax1_tx;
464 $newndfline->localtax2_tx = $line->localtax2_tx;
465 $newndfline->localtax1_type = $line->localtax1_type;
466 $newndfline->localtax2_type = $line->localtax2_type;
467 $newndfline->comments = $line->comments;
468 $newndfline->qty = $line->qty;
469 $newndfline->value_unit = $line->value_unit;
470 $newndfline->total_ht = $line->total_ht;
471 $newndfline->total_ttc = $line->total_ttc;
472 $newndfline->total_tva = $line->total_tva;
473 $newndfline->total_localtax1 = $line->total_localtax1;
474 $newndfline->total_localtax2 = $line->total_localtax2;
475 $newndfline->date = $line->date;
476 $newndfline->rule_warning_message = $line->rule_warning_message;
477 $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat;
478 $newndfline->fk_ecm_files = $line->fk_ecm_files;
483 $newndfline->fk_expensereport = $this->id;
484 $result = $newndfline->insert();
486 $this->error = $newndfline->error;
487 $this->errors = $newndfline->errors;
507 $result = $this->call_trigger(
'EXPENSE_REPORT_CREATE', $user);
519 $this->db->rollback();
523 $this->db->rollback();
527 dol_syslog(get_class($this).
"::create error ".$this->error, LOG_ERR);
528 $this->db->rollback();
532 $this->error = $this->db->lasterror().
" sql=".$sql;
533 $this->db->rollback();
551 if (empty($fk_user_author)) {
552 $fk_user_author = $user->id;
562 $objFrom = clone $this;
567 $this->fk_statut = 0;
570 $this->fk_user_creat = $user->id;
571 $this->fk_user_author = $fk_user_author;
572 $this->fk_user_valid = 0;
573 $this->date_create =
'';
574 $this->date_creation =
'';
575 $this->date_validation =
'';
578 if (is_array($this->lines) && count($this->lines) > 0) {
579 foreach ($this->lines as $key => $line) {
580 $this->lines[$key]->fk_ecm_files = 0;
585 $this->context[
'createfromclone'] =
'createfromclone';
586 $result = $this->
create($user);
593 if (is_object($hookmanager)) {
594 $parameters = array(
'objFrom' => $objFrom);
596 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
604 unset($this->context[
'createfromclone']);
611 $this->db->rollback();
625 public function update($user, $notrigger = 0, $userofexpensereport =
null)
630 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
631 $sql .=
" total_ht = ".((float) $this->total_ht);
632 $sql .=
" , total_ttc = ".((float) $this->total_ttc);
633 $sql .=
" , total_tva = ".((float) $this->total_tva);
634 $sql .=
" , date_debut = '".$this->db->idate($this->date_debut).
"'";
635 $sql .=
" , date_fin = '".$this->db->idate($this->date_fin).
"'";
636 if ($userofexpensereport && is_object($userofexpensereport)) {
637 $sql .=
" , fk_user_author = ".($userofexpensereport->id > 0 ? $userofexpensereport->id :
"null");
639 $sql .=
" , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator :
"null");
640 $sql .=
" , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid :
"null");
641 $sql .=
" , fk_user_approve = ".($this->fk_user_approve > 0 ? $this->fk_user_approve :
"null");
642 $sql .=
" , fk_user_modif = ".((int) $user->id);
643 $sql .=
" , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut :
'0');
644 $sql .=
" , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement :
"null");
645 $sql .=
" , note_public = ".(!empty($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"''");
646 $sql .=
" , note_private = ".(!empty($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"''");
647 $sql .=
" , detail_refuse = ".(!empty($this->detail_refuse) ?
"'".$this->db->escape($this->detail_refuse).
"'" :
"''");
648 $sql .=
" WHERE rowid = ".((int) $this->
id);
650 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
651 $result = $this->db->query($sql);
658 if (!$error && !$notrigger) {
660 $result = $this->call_trigger(
'EXPENSE_REPORT_MODIFY', $user);
671 $this->db->rollback();
672 $this->error = $this->db->error();
676 $this->db->rollback();
677 $this->error = $this->db->error();
689 public function fetch($id, $ref =
'')
691 $sql =
"SELECT d.rowid, d.entity, d.ref, d.note_public, d.note_private,";
692 $sql .=
" d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,";
693 $sql .=
" d.date_refuse, d.date_cancel,";
694 $sql .=
" d.total_ht, d.total_ttc, d.total_tva,";
695 $sql .=
" d.localtax1 as total_localtax1, d.localtax2 as total_localtax2,";
696 $sql .=
" d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,";
697 $sql .=
" d.fk_user_creat, d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
698 $sql .=
" d.fk_user_valid, d.fk_user_approve,";
699 $sql .=
" d.fk_statut as status, d.fk_c_paiement, d.paid";
700 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as d";
702 $sql .=
" WHERE d.ref = '".$this->db->escape($ref).
"'";
703 $sql .=
" AND d.entity IN (".getEntity(
'expensereport').
")";
705 $sql .=
" WHERE d.rowid = ".((int) $id);
709 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
710 $resql = $this->db->query($sql);
712 $obj = $this->db->fetch_object($resql);
714 $this->
id = $obj->rowid;
715 $this->
ref = $obj->ref;
717 $this->entity = $obj->entity;
719 $this->total_ht = $obj->total_ht;
720 $this->total_tva = $obj->total_tva;
721 $this->total_ttc = $obj->total_ttc;
722 $this->localtax1 = $obj->total_localtax1;
723 $this->localtax2 = $obj->total_localtax2;
724 $this->total_localtax1 = $obj->total_localtax1;
725 $this->total_localtax2 = $obj->total_localtax2;
727 $this->note_public = $obj->note_public;
728 $this->note_private = $obj->note_private;
729 $this->detail_refuse = $obj->detail_refuse;
730 $this->detail_cancel = $obj->detail_cancel;
732 $this->date_debut = $this->db->jdate($obj->date_debut);
733 $this->date_fin = $this->db->jdate($obj->date_fin);
734 $this->date_valid = $this->db->jdate($obj->date_valid);
735 $this->date_approve = $this->db->jdate($obj->date_approve);
736 $this->date_create = $this->db->jdate($obj->date_create);
737 $this->date_modif = $this->db->jdate($obj->date_modif);
738 $this->date_refuse = $this->db->jdate($obj->date_refuse);
739 $this->date_cancel = $this->db->jdate($obj->date_cancel);
741 $this->fk_user_creat = $obj->fk_user_creat;
742 $this->fk_user_author = $obj->fk_user_author;
743 $this->fk_user_modif = $obj->fk_user_modif;
744 $this->fk_user_validator = $obj->fk_user_validator;
745 $this->fk_user_valid = $obj->fk_user_valid;
746 $this->fk_user_refuse = $obj->fk_user_refuse;
747 $this->fk_user_cancel = $obj->fk_user_cancel;
748 $this->fk_user_approve = $obj->fk_user_approve;
750 $user_author =
new User($this->db);
751 if ($this->fk_user_author > 0) {
752 $user_author->fetch($this->fk_user_author);
755 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
757 $user_approver =
new User($this->db);
758 if ($this->fk_user_approve > 0) {
759 $user_approver->fetch($this->fk_user_approve);
760 } elseif ($this->fk_user_validator > 0) {
761 $user_approver->fetch($this->fk_user_validator);
763 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
765 $this->fk_statut = (int) $obj->status;
766 $this->
status = (int) $obj->status;
767 $this->fk_c_paiement = $obj->fk_c_paiement;
768 $this->paid = $obj->paid;
770 if ($this->
status == self::STATUS_APPROVED || $this->
status == self::STATUS_CLOSED) {
771 $user_valid =
new User($this->db);
772 if ($this->fk_user_valid > 0) {
773 $user_valid->fetch($this->fk_user_valid);
775 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
787 $this->error = $this->db->lasterror();
803 public function set_paid($id, $fuser, $notrigger = 0)
806 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
807 return $this->
setPaid($id, $fuser, $notrigger);
818 public function setPaid($id, $fuser, $notrigger = 0)
823 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
824 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid = 1";
827 dol_syslog(get_class($this).
"::setPaid", LOG_DEBUG);
828 $resql = $this->db->query($sql);
830 if ($this->db->affected_rows($resql)) {
833 $result = $this->call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
849 $this->db->rollback();
850 $this->error = $this->db->error();
858 $this->db->rollback();
888 $labelStatus = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
889 $labelStatusShort = $langs->transnoentitiesnoconv($this->labelStatusShort[$status]);
891 $statuslogo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
893 $statusType = $statuslogo[$status];
895 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
909 $sql =
"SELECT f.rowid,";
910 $sql .=
" f.date_create as datec,";
911 $sql .=
" f.tms as date_modification,";
912 $sql .=
" f.date_valid as datev,";
913 $sql .=
" f.date_approve as datea,";
914 $sql .=
" f.fk_user_creat as fk_user_creation,";
915 $sql .=
" f.fk_user_author as fk_user_author,";
916 $sql .=
" f.fk_user_modif as fk_user_modification,";
917 $sql .=
" f.fk_user_valid,";
918 $sql .=
" f.fk_user_approve";
919 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
920 $sql .=
" WHERE f.rowid = ".((int) $id);
921 $sql .=
" AND f.entity = ".$conf->entity;
925 $resql = $this->db->query($sql);
927 if ($this->db->num_rows($resql)) {
928 $obj = $this->db->fetch_object($resql);
930 $this->
id = $obj->rowid;
932 $this->date_creation = $this->db->jdate($obj->datec);
933 $this->date_modification = $this->db->jdate($obj->date_modification);
934 $this->date_validation = $this->db->jdate($obj->datev);
935 $this->date_approbation = $this->db->jdate($obj->datea);
937 $this->user_creation_id = $obj->fk_user_author;
938 $this->user_creation_id = $obj->fk_user_creation;
939 $this->user_validation_id = $obj->fk_user_valid;
940 $this->user_modification_id = $obj->fk_user_modification;
941 $this->user_approve_id = $obj->fk_user_approve;
943 $this->db->free($resql);
960 global $user, $langs;
966 $this->
ref =
'SPECIMEN';
969 $this->date_create = $now;
970 $this->date_debut = $now;
971 $this->date_fin = $now;
972 $this->date_valid = $now;
973 $this->date_approve = $now;
979 $this->fk_user_author = $user->id;
980 $this->fk_user_validator = $user->id;
981 $this->fk_user_valid = $user->id;
982 $this->fk_user_approve = $user->id;
984 $this->note_private =
'Private note';
985 $this->note_public =
'SPECIMEN';
988 while ($xnbp < $nbp) {
990 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
991 $line->date = ($now - 3600 * (1 + $xnbp));
992 $line->total_ht = 100;
993 $line->total_tva = 20;
994 $line->total_ttc = 120;
997 $line->value_unit = 120;
998 $line->fk_expensereport = 0;
999 $line->type_fees_code =
'TRA';
1000 $line->fk_c_type_fees = $type_fees_id;
1002 $line->projet_ref =
'ABC';
1004 $this->lines[$xnbp] = $line;
1007 $this->total_ht += $line->total_ht;
1008 $this->total_tva += $line->total_tva;
1009 $this->total_ttc += $line->total_ttc;
1028 $langs->load(
'trips');
1030 if ($user->hasRight(
'expensereport',
'lire')) {
1031 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
1032 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
1033 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
1035 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1036 $result = $this->db->query($sql);
1038 $num = $this->db->num_rows($result);
1044 $objp = $this->db->fetch_object($result);
1046 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
1047 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
1048 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
1050 $result2 = $this->db->query($sql2);
1051 $obj = $this->db->fetch_object($result2);
1053 $objp->fk_user_author = $obj->fk_user_author;
1054 $objp->ref = $obj->ref;
1055 $objp->fk_c_expensereport_status = $obj->status;
1056 $objp->rowid = $obj->rowid;
1058 $total_HT += $objp->total_ht;
1059 $total_TTC += $objp->total_ttc;
1060 $author =
new User($this->db);
1061 $author->fetch($objp->fk_user_author);
1065 print
'<a href="'.dolBuildUrl(DOL_URL_ROOT.
'/expensereport/card.php', [
'id' => $objp->rowid]).
'">'.$objp->ref_num.
'</a>';
1067 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
1068 print
'<td>'.$author->getNomUrl(1).
'</td>';
1069 print
'<td>'.$objp->comments.
'</td>';
1070 print
'<td class="right">'.price($objp->total_ht).
'</td>';
1071 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
1072 print
'<td class="right">';
1074 switch ($objp->fk_c_expensereport_status) {
1076 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
1079 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
1082 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
1085 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
1088 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
1105 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
1106 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
1107 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
1108 print
'<td> </td>';
1111 $this->error = $this->db->lasterror();
1128 $this->lines = array();
1130 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1131 $sql .=
" de.".$this->fk_element.
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1132 $sql .=
' de.tva_tx, de.vat_src_code,';
1133 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1134 $sql .=
' de.fk_ecm_files,';
1135 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1136 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1137 $sql .=
' ctf.code as code_type_fees, ctf.label as label_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1138 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1139 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as de';
1140 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1141 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1142 $sql .=
" WHERE de.".$this->fk_element.
" = ".((int) $this->
id);
1144 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1146 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1149 $resql = $this->db->query($sql);
1151 $num = $this->db->num_rows($resql);
1154 $objp = $this->db->fetch_object($resql);
1158 $deplig->rowid = $objp->rowid;
1159 $deplig->id = $objp->rowid;
1160 $deplig->comments = $objp->comments;
1161 $deplig->qty = $objp->qty;
1162 $deplig->value_unit = $objp->value_unit;
1163 $deplig->date = $objp->date;
1164 $deplig->dates = $this->db->jdate($objp->date);
1166 $deplig->fk_expensereport = $objp->fk_expensereport;
1167 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1168 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1169 $deplig->fk_projet = $objp->fk_project;
1170 $deplig->fk_project = $objp->fk_project;
1171 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1173 $deplig->total_ht = $objp->total_ht;
1174 $deplig->total_tva = $objp->total_tva;
1175 $deplig->total_ttc = $objp->total_ttc;
1176 $deplig->total_localtax1 = $objp->total_localtax1;
1177 $deplig->total_localtax2 = $objp->total_localtax2;
1179 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1180 $deplig->type_fees_libelle = $objp->label_type_fees;
1181 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1183 $deplig->tva_tx = $objp->tva_tx;
1184 $deplig->vatrate = $objp->tva_tx;
1185 $deplig->vat_src_code = $objp->vat_src_code;
1186 $deplig->localtax1_tx = $objp->localtax1_tx;
1187 $deplig->localtax2_tx = $objp->localtax2_tx;
1188 $deplig->localtax1_type = $objp->localtax1_type;
1189 $deplig->localtax2_type = $objp->localtax2_type;
1191 $deplig->projet_ref = $objp->ref_projet;
1192 $deplig->projet_title = $objp->title_projet;
1194 $deplig->rule_warning_message = $objp->rule_warning_message;
1196 $deplig->rang = $objp->rang;
1198 $this->lines[$i] = $deplig;
1202 $this->db->free($resql);
1205 $this->error = $this->db->lasterror();
1206 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1219 public function delete($user =
null, $notrigger = 0)
1222 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1230 $result = $this->call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1238 if (!$error && !empty($this->table_element_line)) {
1239 $tabletodelete = $this->table_element_line;
1241 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1242 if (!$this->db->query($sql)) {
1244 $this->error = $this->db->lasterror();
1245 $this->errors[] = $this->error;
1246 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1271 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1277 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1278 $res = $this->db->query($sql);
1281 $this->error = $this->db->lasterror();
1282 $this->errors[] = $this->error;
1283 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1299 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1300 $dir = $conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1301 $file = $dir.
"/".$ref.
".pdf";
1302 if (file_exists($file)) {
1306 $this->error =
'ErrorFailToDeleteFile';
1307 $this->errors[] = $this->error;
1308 $this->db->rollback();
1312 if (file_exists($dir)) {
1315 $this->error =
'ErrorFailToDeleteDir';
1316 $this->errors[] = $this->error;
1317 $this->db->rollback();
1325 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1326 $this->db->commit();
1329 $this->db->rollback();
1343 global $conf, $langs, $user;
1349 if ($this->
status == self::STATUS_VALIDATED) {
1350 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
1354 $this->date_valid = $now;
1357 if (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) {
1360 $num = (string) $this->
ref;
1362 if (empty($num) || $num < 0) {
1371 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1372 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1373 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1374 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1375 $sql .=
" fk_user_valid = ".((int) $user->id);
1376 $sql .=
" WHERE rowid = ".((int) $this->
id);
1378 $resql = $this->db->query($sql);
1382 $result = $this->call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1390 $this->oldref = $this->ref;
1393 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1394 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1397 $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).
"'";
1398 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1399 $resql = $this->db->query($sql);
1402 $this->error = $this->db->lasterror();
1404 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1405 $sql .=
" WHERE filepath = 'expensereport/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
1406 $resql = $this->db->query($sql);
1409 $this->error = $this->db->lasterror();
1415 $dirsource = $conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1416 $dirdest = $conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1417 if (!$error && file_exists($dirsource)) {
1418 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1420 if (@rename($dirsource, $dirdest)) {
1423 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1424 foreach ($listoffiles as $fileentry) {
1425 $dirsource = $fileentry[
'name'];
1426 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1427 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1428 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1429 @rename($dirsource, $dirdest);
1442 if (empty($error)) {
1443 $this->db->commit();
1446 $this->db->rollback();
1447 $this->error = $this->db->error();
1451 $this->db->rollback();
1452 $this->error = $this->db->lasterror();
1468 $sql =
'SELECT date_debut';
1469 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1470 $sql .=
" WHERE rowid = ".((int) $this->
id);
1472 $result = $this->db->query($sql);
1474 $objp = $this->db->fetch_object($result);
1476 $this->date_debut = $this->db->jdate($objp->date_debut);
1478 if ($this->
status != self::STATUS_VALIDATED) {
1479 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1480 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1481 $sql .=
" WHERE rowid = ".((int) $this->
id);
1483 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1485 if ($this->db->query($sql)) {
1488 $this->error = $this->db->lasterror();
1492 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1510 if ($this->
status != self::STATUS_APPROVED) {
1512 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1513 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1514 $sql .=
" date_approve='".$this->db->idate($now).
"'";
1515 $sql .=
" WHERE rowid = ".((int) $this->
id);
1516 if ($this->db->query($sql)) {
1518 $this->date_approve = $now;
1519 $this->fk_user_approve = $fuser->id;
1522 $result = $this->call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1530 if (empty($error)) {
1531 $this->db->commit();
1534 $this->db->rollback();
1535 $this->error = $this->db->error();
1539 $this->db->rollback();
1540 $this->error = $this->db->lasterror();
1544 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1558 public function setDeny($fuser, $details, $notrigger = 0)
1564 if ($this->
status != self::STATUS_REFUSED) {
1565 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1566 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1567 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1568 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1569 $sql .=
" fk_user_approve = NULL";
1570 $sql .=
" WHERE rowid = ".((int) $this->
id);
1571 if ($this->db->query($sql)) {
1572 $this->fk_statut = 99;
1574 $this->fk_user_refuse = $fuser->id;
1575 $this->detail_refuse = $details;
1576 $this->date_refuse = $now;
1580 $result = $this->call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1588 if (empty($error)) {
1589 $this->db->commit();
1592 $this->db->rollback();
1593 $this->error = $this->db->error();
1597 $this->db->rollback();
1598 $this->error = $this->db->lasterror();
1602 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1621 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1622 return $this->
setUnpaid($fuser, $notrigger);
1639 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1640 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1641 $sql .=
" WHERE rowid = ".((int) $this->
id);
1643 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1645 if ($this->db->query($sql)) {
1648 $result = $this->call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1656 if (empty($error)) {
1657 $this->db->commit();
1660 $this->db->rollback();
1661 $this->error = $this->db->error();
1665 $this->db->rollback();
1666 $this->error = $this->db->error();
1670 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1689 $this->date_cancel = $this->db->idate(
dol_now());
1690 if ($this->
status != self::STATUS_CANCELED) {
1693 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1694 $sql .=
" SET fk_statut = ".((int) self::STATUS_CANCELED).
", fk_user_cancel = ".((int) $fuser->id);
1695 $sql .=
", date_cancel = '".$this->db->idate($this->date_cancel).
"'";
1696 $sql .=
", detail_cancel = '".$this->db->escape($detail).
"'";
1697 $sql .=
" WHERE rowid = ".((int) $this->
id);
1699 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1701 if ($this->db->query($sql)) {
1704 $result = $this->call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1712 if (empty($error)) {
1713 $this->db->commit();
1716 $this->db->rollback();
1717 $this->error = $this->db->error();
1721 $this->db->rollback();
1722 $this->error = $this->db->error();
1726 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1738 global $langs, $conf;
1739 $langs->load(
"trips");
1748 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1749 foreach ($dirmodels as $reldir) {
1750 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1753 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1761 $obj =
new $classname();
1762 '@phan-var-force ModeleNumRefExpenseReport $obj';
1763 $numref = $obj->getNextValue($this);
1765 if ($numref !=
"") {
1768 $this->error = $obj->error;
1769 $this->errors = $obj->errors;
1774 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1787 global $conf, $langs;
1789 $langs->load(
'trips');
1791 $nofetch = !empty($params[
'nofetch']);
1792 $moretitle = $params[
'moretitle'] ??
'';
1795 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1796 if (isset($this->
status)) {
1797 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1800 $datas[
'picto'] .=
' - '.$moretitle;
1802 if (!empty($this->
ref)) {
1803 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1805 if (!empty($this->total_ht)) {
1806 $datas[
'total_ht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1808 if (!empty($this->total_tva)) {
1809 $datas[
'total_tva'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1811 if (!empty($this->total_ttc)) {
1812 $datas[
'total_ttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
1830 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1832 global $langs, $hookmanager;
1836 $baseurl = DOL_URL_ROOT.
'/expensereport/card.php';
1837 $query = [
'id' => $this->id];
1845 'objecttype' => $this->element,
1846 'option' => $option,
1847 'moretitle' => $moretitle,
1850 $classfortooltip =
'classfortooltip';
1853 $classfortooltip =
'classforajaxtooltip';
1854 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1860 if ($option !=
'nolink') {
1862 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1863 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1864 $add_save_lastsearch_values = 1;
1866 if ($add_save_lastsearch_values) {
1867 $query += [
'save_lastsearch_values' => 1];
1878 if (empty($notooltip)) {
1880 $label = $langs->trans(
"ShowExpenseReport");
1881 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
1883 $linkclose .= ($label ?
' title="'.dolPrintHTMLForAttribute($label).
'"' :
' title="tocomplete"');
1884 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
1887 $linkstart =
'<a href="'.$url.
'"';
1888 $linkstart .= $linkclose.
'>';
1891 $result .= $linkstart;
1893 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
1895 if ($withpicto != 2) {
1896 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1898 $result .= $linkend;
1901 $hookmanager->initHooks(array($this->element .
'dao'));
1902 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
1903 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1905 $result = $hookmanager->resPrint;
1907 $result .= $hookmanager->resPrint;
1923 $this->total_ht += (float) $ligne_total_ht;
1924 $this->total_tva += (float) $ligne_total_tva;
1925 $this->total_ttc += $this->total_tva;
1927 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1928 $sql .=
" total_ht = ".((float) $this->total_ht);
1929 $sql .=
" , total_ttc = ".((float) $this->total_ttc);
1930 $sql .=
" , total_tva = ".((float) $this->total_tva);
1931 $sql .=
" WHERE rowid = ".((int) $this->
id);
1933 $result = $this->db->query($sql);
1937 $this->error = $this->db->error();
1957 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)
1961 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);
1963 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
1967 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1968 $fk_c_type_fees = 0;
1970 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1971 $fk_c_exp_tax_cat = 0;
1973 if (empty($vatrate) || $vatrate < 0) {
1979 if (empty($fk_project)) {
1984 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1995 $seller->tva_assuj = 1;
1996 $buyer =
new Societe($this->db);
2002 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
2003 $vat_src_code = $reg[1];
2004 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2006 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2008 $tmp =
calcul_price_total($qty, (
float) $up, 0, (
float)
price2num($vatrate), -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2010 $this->line->value_unit = $up;
2012 $this->line->vat_src_code = $vat_src_code;
2013 $this->line->vatrate =
price2num($vatrate);
2014 $this->line->localtax1_tx = $localtaxes_type[1];
2015 $this->line->localtax2_tx = $localtaxes_type[3];
2016 $this->line->localtax1_type = $localtaxes_type[0];
2017 $this->line->localtax2_type = $localtaxes_type[2];
2019 $this->line->total_ttc = (float) $tmp[2];
2020 $this->line->total_ht = (float) $tmp[0];
2021 $this->line->total_tva = (float) $tmp[1];
2022 $this->line->total_localtax1 = (float) $tmp[9];
2023 $this->line->total_localtax2 = (float) $tmp[10];
2025 $this->line->fk_expensereport = $this->id;
2026 $this->line->qty = $qty;
2027 $this->line->date = $date;
2028 $this->line->fk_c_type_fees = $fk_c_type_fees;
2029 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2030 $this->line->comments = $comments;
2031 $this->line->fk_projet = $fk_project;
2032 $this->line->fk_project = $fk_project;
2034 $this->line->fk_ecm_files = $fk_ecm_files;
2039 $result = $this->line->insert(0,
true);
2043 $this->db->commit();
2044 return $this->line->id;
2046 $this->db->rollback();
2050 $this->error = $this->line->error;
2051 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
2052 $this->db->rollback();
2056 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
2057 $this->error =
'ErrorExpenseNotDraftAndNotRefused';
2071 global $conf, $langs,
$mysoc;
2073 $langs->load(
'trips');
2076 if (!is_object($seller)) {
2078 $seller->tva_assuj = 1;
2082 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
2085 $rule_warning_message_tab = array();
2087 $current_total_ttc = $this->line->total_ttc;
2088 $new_current_total_ttc = $this->line->total_ttc;
2091 foreach ($rulestocheck as $rule) {
2092 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
2093 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
2095 $amount_to_test = $current_total_ttc;
2098 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
2100 if ($amount_to_test > $rule->amount) {
2103 if ($rule->restrictive) {
2104 $this->error =
'ExpenseReportConstraintViolationError';
2105 $this->errors[] = $this->error;
2107 $new_current_total_ttc -= $amount_to_test - $rule->amount;
2108 $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));
2110 $this->error =
'ExpenseReportConstraintViolationWarning';
2111 $this->errors[] = $this->error;
2113 $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));
2120 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
2122 if ($violation > 0) {
2123 $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);
2125 $this->line->value_unit = $tmp[5];
2126 $this->line->total_ttc = (float) $tmp[2];
2127 $this->line->total_ht = (float) $tmp[0];
2128 $this->line->total_tva = (float) $tmp[1];
2129 $this->line->total_localtax1 = (float) $tmp[9];
2130 $this->line->total_localtax2 = (float) $tmp[10];
2153 $userauthor =
new User($this->db);
2154 if ($userauthor->fetch($this->fk_user_author) <= 0) {
2155 $this->error =
'ErrorCantFetchUser';
2156 $this->errors[] =
'ErrorCantFetchUser';
2161 if (!is_object($seller)) {
2163 $seller->tva_assuj = 1;
2167 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2169 if (empty($range)) {
2170 $this->error =
'ErrorNoRangeAvailable';
2171 $this->errors[] =
'ErrorNoRangeAvailable';
2176 $ikoffset = $range->ikoffset;
2178 $ikoffset = $range->ikoffset / 12;
2183 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2184 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2186 $this->line->value_unit = $tmp[5];
2187 $this->line->total_ttc = (float) $tmp[2];
2188 $this->line->total_ht = (float) $tmp[0];
2189 $this->line->total_tva = (float) $tmp[1];
2190 $this->line->total_localtax1 = (float) $tmp[9];
2191 $this->line->total_localtax2 = (float) $tmp[10];
2206 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2207 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2208 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2209 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2210 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2211 if (!empty($this->line->id)) {
2212 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2215 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2216 $resql = $this->db->query($sql);
2218 $num = $this->db->num_rows($resql);
2246 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)
2250 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
2258 $seller->tva_assuj = 1;
2259 $seller->localtax1_assuj =
$mysoc->localtax1_assuj;
2260 $seller->localtax2_assuj =
$mysoc->localtax1_assuj;
2261 $buyer =
new Societe($this->db);
2268 if (preg_match(
'/\((.*)\)/', (
string) $vatrate, $reg)) {
2269 $vat_src_code = $reg[1];
2270 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', (
string) $vatrate);
2272 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2274 $tmp =
calcul_price_total($qty, $value_unit, 0, (
float)
price2num($vatrate), -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2278 $tx_tva = 1 + (float) $vatrate / 100;
2281 $this->line->comments = $comments;
2282 $this->line->qty = $qty;
2283 $this->line->value_unit = $value_unit;
2284 $this->line->date = $date;
2286 $this->line->fk_expensereport = $expensereport_id;
2287 $this->line->fk_c_type_fees = $type_fees_id;
2288 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2289 $this->line->fk_projet = $projet_id;
2290 $this->line->fk_project = $projet_id;
2292 $this->line->vat_src_code = $vat_src_code;
2293 $this->line->vatrate =
price2num($vatrate);
2294 $this->line->localtax1_tx = $localtaxes_type[1];
2295 $this->line->localtax2_tx = $localtaxes_type[3];
2296 $this->line->localtax1_type = $localtaxes_type[0];
2297 $this->line->localtax2_type = $localtaxes_type[2];
2299 $this->line->total_ttc = (float) $tmp[2];
2300 $this->line->total_ht = (float) $tmp[0];
2301 $this->line->total_tva = (float) $tmp[1];
2302 $this->line->total_localtax1 = (float) $tmp[9];
2303 $this->line->total_localtax2 = (float) $tmp[10];
2305 $this->line->fk_ecm_files = $fk_ecm_files;
2307 $this->line->id = ((int) $rowid);
2310 $sql =
"SELECT c.code as code_type_fees, c.label as label_type_fees";
2311 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2312 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2313 $resql = $this->db->query($sql);
2315 $objp_fees = $this->db->fetch_object($resql);
2316 $this->line->type_fees_code = $objp_fees->code_type_fees;
2317 $this->line->type_fees_libelle = $objp_fees->label_type_fees;
2318 $this->db->free($resql);
2322 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2323 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2324 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2325 $resql = $this->db->query($sql);
2327 $objp_projet = $this->db->fetch_object($resql);
2328 $this->line->projet_ref = $objp_projet->ref_projet;
2329 $this->line->projet_title = $objp_projet->title_projet;
2330 $this->db->free($resql);
2336 $result = $this->line->update($user, $notrigger);
2342 $this->db->commit();
2345 $this->error = $this->line->error;
2346 $this->errors = $this->line->errors;
2347 $this->db->rollback();
2363 public function deleteLine($rowid, $fuser =
null, $notrigger = 0)
2371 $result = $this->call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2378 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2379 $sql .=
' WHERE rowid = '.((int) $rowid);
2381 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2382 $result = $this->db->query($sql);
2384 if (!$result || $error > 0) {
2385 $this->error = $this->db->error();
2386 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2387 $this->db->rollback();
2393 $this->db->commit();
2410 $sql =
"SELECT rowid, date_debut, date_fin";
2411 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2412 $sql .=
" WHERE entity = ".((int) $conf->entity);
2413 $sql .=
" AND fk_user_author = ".((int) $fuser->id);
2414 $sql .=
" AND (date_fin >= '".$this->db->idate($startDate).
"' AND date_debut <= '".$this->db->idate($endDate).
"')";
2416 $row = $this->db->getRow($sql);
2418 if ($row ===
false) {
2419 $this->error = $this->db->lasterror();
2420 dol_syslog(__CLASS__.
"::". __METHOD__.
" Error ".$this->error, LOG_ERR);
2424 return $row->rowid ?? 0;
2438 $users_validator = array();
2440 $sql =
"SELECT DISTINCT ur.fk_user";
2441 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2442 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2444 $sql .=
" SELECT DISTINCT ugu.fk_user";
2445 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2446 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2449 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2450 $result = $this->db->query($sql);
2452 $num_rows = $this->db->num_rows($result);
2454 while ($i < $num_rows) {
2455 $objp = $this->db->fetch_object($result);
2456 array_push($users_validator, $objp->fk_user);
2459 return $users_validator;
2461 $this->error = $this->db->lasterror();
2462 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2478 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2480 $outputlangs->load(
"trips");
2483 if (!empty($this->model_pdf)) {
2484 $modele = $this->model_pdf;
2490 if (!empty($modele)) {
2491 $modelpath =
"core/modules/expensereport/doc/";
2493 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2509 $sql =
"SELECT id, code, label";
2510 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2511 $sql .=
" WHERE active = ".((int) $active);
2512 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2513 $result = $this->db->query($sql);
2515 $num = $this->db->num_rows($result);
2518 $obj = $this->db->fetch_object($result);
2519 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2537 $this->nb = array();
2539 $sql =
"SELECT count(ex.rowid) as nb";
2540 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2541 $sql .=
" WHERE ex.fk_statut > 0";
2542 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2543 if (!$user->hasRight(
'expensereport',
'readall')) {
2544 $userchildids = $user->getAllChildIds(1);
2545 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2546 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2549 $resql = $this->db->query($sql);
2551 while ($obj = $this->db->fetch_object($resql)) {
2552 $this->nb[
"expensereports"] = $obj->nb;
2554 $this->db->free($resql);
2558 $this->error = $this->db->error();
2574 global $conf, $langs;
2582 $sql =
"SELECT ex.rowid, ex.date_valid";
2583 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2584 if ($option ==
'toapprove') {
2585 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2587 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2589 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2590 if (!$user->hasRight(
'expensereport',
'readall')) {
2591 $userchildids = $user->getAllChildIds(1);
2592 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2593 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2596 $resql = $this->db->query($sql);
2598 $langs->load(
"trips");
2601 if ($option ==
'toapprove') {
2602 $response->warning_delay = $conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2603 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2604 $response->labelShort = $langs->trans(
"ToApprove");
2605 $response->url =
dolBuildUrl(DOL_URL_ROOT.
'/expensereport/list.php', [
'mainmenu' =>
'hrm',
'statut' => self::STATUS_VALIDATED]);
2607 $response->warning_delay = $conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2608 $response->label = $langs->trans(
"ExpenseReportsToPay");
2609 $response->labelShort = $langs->trans(
"StatusToPay");
2610 $response->url =
dolBuildUrl(DOL_URL_ROOT.
'/expensereport/list.php', [
'mainmenu' =>
'hrm',
'statut' => self::STATUS_APPROVED]);
2614 while ($obj = $this->db->fetch_object($resql)) {
2615 $response->nbtodo++;
2617 if ($option ==
'toapprove') {
2618 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->approve->warning_delay)) {
2619 $response->nbtodolate++;
2622 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->payment->warning_delay)) {
2623 $response->nbtodolate++;
2631 $this->error = $this->db->error();
2647 if ($option ==
'toapprove' && $this->
status != 2) {
2650 if ($option ==
'topay' && $this->
status != 5) {
2655 $warning_delay = (int) ($option ==
'toapprove' ? $conf->expensereport->approve->warning_delay : $conf->expensereport->payment->warning_delay);
2656 if ($warning_delay <= 0) {
2660 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $warning_delay);
2671 $alreadydispatched = 0;
2673 $type =
'expense_report';
2675 $sql =
" SELECT ".($mode ?
'DISTINCT piece_num' :
'COUNT(ab.rowid)').
" as nb";
2676 $sql .=
" FROM ".MAIN_DB_PREFIX.
"accounting_bookkeeping as ab WHERE ab.doc_type = '".$this->db->escape($type).
"' AND ab.fk_doc = ".((int) $this->
id);
2677 $resql = $this->db->query($sql);
2679 $obj = $this->db->fetch_object($resql);
2681 $alreadydispatched = $obj->nb;
2684 $this->error = $this->db->lasterror();
2688 if ($alreadydispatched) {
2689 return $alreadydispatched;
2701 $table =
'payment_expensereport';
2702 $field =
'fk_expensereport';
2704 $sql =
'SELECT sum(amount) as amount';
2705 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2706 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
2708 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2709 $resql = $this->db->query($sql);
2711 $obj = $this->db->fetch_object($resql);
2712 $this->db->free($resql);
2713 return (empty($obj->amount) ? 0 : $obj->amount);
2715 $this->error = $this->db->lasterror();
2730 global $langs, $conf;
2738 $this->error = $langs->trans(
'ErrorBadParameterCat');
2743 $this->error = $langs->trans(
'ErrorBadParameterQty');
2747 $currentUser =
new User($this->db);
2748 $currentUser->fetch($this->fk_user);
2749 $currentUser->loadRights(
'expensereport');
2753 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2754 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2755 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2756 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2757 $sql .=
" ORDER BY r.range_ik ASC";
2759 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2761 $result = $this->db->query($sql);
2764 if (
getDolGlobalInt(
'EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR')) {
2766 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2767 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2768 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2769 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2770 $sql .=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2771 $sql .=
" AND tf.code = 'EX_KME' ";
2774 $resql = $this->db->query($sql);
2777 $obj = $this->db->fetch_object($resql);
2778 $cumulYearQty = $obj->cumul;
2781 $qty += (float) $cumulYearQty;
2784 $num = $this->db->num_rows($result);
2787 for ($i = 0; $i < $num; $i++) {
2788 $obj = $this->db->fetch_object($result);
2792 '@phan-var-force Object[] $ranges';
2794 for ($i = 0; $i < $num; $i++) {
2795 if ($i < ($num - 1)) {
2797 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i + 1]->range_ik) {
2798 $coef = $ranges[$i]->coef;
2799 $offset = $ranges[$i]->ikoffset;
2802 if ($qty > $ranges[$i]->range_ik) {
2803 $coef = $ranges[$i]->coef;
2804 $offset = $ranges[$i]->ikoffset;
2811 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2815 $this->error = $this->db->error().
" sql=".$sql;
2832 if ($arraydata ===
null) {
2833 $arraydata = array();
2836 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2838 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2839 $return .=
'<div class="info-box info-box-sm">';
2840 $return .=
'<span class="info-box-icon bg-infobox-action">';
2842 $return .=
'</span>';
2843 $return .=
'<div class="info-box-content">';
2844 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->
getNomUrl(1) .
'</span>';
2845 if ($selected >= 0) {
2846 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2848 if (array_key_exists(
'userauthor', $arraydata) && $arraydata[
'userauthor'] instanceof
User) {
2849 $return .=
'<br><span class="info-box-label">'.$arraydata[
'userauthor']->getNomUrl(-1).
'</span>';
2852 $return .=
'<br><span class="info-box-label">'.dol_print_date($this->date_debut,
'day').
'</span>';
2853 $return .=
' <span class="opacitymedium">'.$langs->trans(
"To").
'</span> ';
2854 $return .=
'<span class="info-box-label">'.dol_print_date($this->date_fin,
'day').
'</span>';
2856 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
2857 $return .=
'</div>';
2858 $return .=
'</div>';
2859 $return .=
'</div>';
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.
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
setValidate($fuser, $notrigger=0)
Set to status validate.
getSumPayments()
Return amount of payments already done.
getLibStatut($mode=0)
Returns the label status.
deleteLine($rowid, $fuser=null, $notrigger=0)
deleteline
set_cancel($fuser, $detail, $notrigger=0)
set_cancel
getNomUrl($withpicto=0, $option='', $max=0, $short=0, $moretitle='', $notooltip=0, $save_lastsearch_value=-1)
Return clickable name (with picto eventually)
set_unpaid($fuser, $notrigger=0)
set_unpaid
getVentilExportCompta($mode=0)
Return if object was dispatched into bookkeeping.
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.
periodExists(User $fuser, $startDate, $endDate)
periodExists
setDeny($fuser, $details, $notrigger=0)
setDeny
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.
Class to manage inventories.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
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_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
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.
dol_now($mode='gmt')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dolBuildUrl($url, $params=[], $addtoken=false)
Return path of url.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
isDolTms($timestamp)
isDolTms check if a timestamp is valid.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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.
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.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
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 a 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=null, $localtaxes_array=[], $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.