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 if (!empty($this->date_create)) {
635 $sql .=
" , date_create = '".$this->db->idate($this->date_create).
"'";
637 $sql .=
" , date_debut = '".$this->db->idate($this->date_debut).
"'";
638 $sql .=
" , date_fin = '".$this->db->idate($this->date_fin).
"'";
639 if ($userofexpensereport && is_object($userofexpensereport)) {
640 $sql .=
" , fk_user_author = ".($userofexpensereport->id > 0 ? (int) $userofexpensereport->id :
"null");
642 $sql .=
" , fk_user_validator = ".($this->fk_user_validator > 0 ? (int) $this->fk_user_validator :
"null");
643 $sql .=
" , fk_user_valid = ".($this->fk_user_valid > 0 ? (int) $this->fk_user_valid :
"null");
644 $sql .=
" , fk_user_approve = ".($this->fk_user_approve > 0 ? (int) $this->fk_user_approve :
"null");
645 $sql .=
" , fk_user_modif = ".((int) $user->id);
646 $sql .=
" , fk_statut = ".($this->fk_statut >= 0 ? (int) $this->fk_statut : 0);
647 $sql .=
" , fk_c_paiement = ".($this->fk_c_paiement > 0 ? (int) $this->fk_c_paiement :
"null");
648 $sql .=
" , note_public = ".(!empty($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"''");
649 $sql .=
" , note_private = ".(!empty($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"''");
650 $sql .=
" , detail_refuse = ".(!empty($this->detail_refuse) ?
"'".$this->db->escape($this->detail_refuse).
"'" :
"''");
651 $sql .=
" WHERE rowid = ".((int) $this->
id);
653 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
654 $result = $this->db->query($sql);
661 if (!$error && !$notrigger) {
663 $result = $this->call_trigger(
'EXPENSE_REPORT_MODIFY', $user);
674 $this->db->rollback();
675 $this->error = $this->db->error();
679 $this->db->rollback();
680 $this->error = $this->db->error();
692 public function fetch($id, $ref =
'')
694 $sql =
"SELECT d.rowid, d.entity, d.ref, d.note_public, d.note_private,";
695 $sql .=
" d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,";
696 $sql .=
" d.date_refuse, d.date_cancel,";
697 $sql .=
" d.total_ht, d.total_ttc, d.total_tva,";
698 $sql .=
" d.localtax1 as total_localtax1, d.localtax2 as total_localtax2,";
699 $sql .=
" d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,";
700 $sql .=
" d.fk_user_creat, d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
701 $sql .=
" d.fk_user_valid, d.fk_user_approve,";
702 $sql .=
" d.fk_statut as status, d.fk_c_paiement, d.paid";
703 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as d";
705 $sql .=
" WHERE d.ref = '".$this->db->escape($ref).
"'";
706 $sql .=
" AND d.entity IN (".getEntity(
'expensereport').
")";
708 $sql .=
" WHERE d.rowid = ".((int) $id);
712 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
713 $resql = $this->db->query($sql);
715 $obj = $this->db->fetch_object($resql);
717 $this->
id = $obj->rowid;
718 $this->
ref = $obj->ref;
720 $this->entity = $obj->entity;
722 $this->total_ht = $obj->total_ht;
723 $this->total_tva = $obj->total_tva;
724 $this->total_ttc = $obj->total_ttc;
725 $this->localtax1 = $obj->total_localtax1;
726 $this->localtax2 = $obj->total_localtax2;
727 $this->total_localtax1 = $obj->total_localtax1;
728 $this->total_localtax2 = $obj->total_localtax2;
730 $this->note_public = $obj->note_public;
731 $this->note_private = $obj->note_private;
732 $this->detail_refuse = $obj->detail_refuse;
733 $this->detail_cancel = $obj->detail_cancel;
735 $this->date_debut = $this->db->jdate($obj->date_debut);
736 $this->date_fin = $this->db->jdate($obj->date_fin);
737 $this->date_valid = $this->db->jdate($obj->date_valid);
738 $this->date_approve = $this->db->jdate($obj->date_approve);
739 $this->date_create = $this->db->jdate($obj->date_create);
740 $this->date_modif = $this->db->jdate($obj->date_modif);
741 $this->date_refuse = $this->db->jdate($obj->date_refuse);
742 $this->date_cancel = $this->db->jdate($obj->date_cancel);
744 $this->fk_user_creat = $obj->fk_user_creat;
745 $this->fk_user_author = $obj->fk_user_author;
746 $this->fk_user_modif = $obj->fk_user_modif;
747 $this->fk_user_validator = $obj->fk_user_validator;
748 $this->fk_user_valid = $obj->fk_user_valid;
749 $this->fk_user_refuse = $obj->fk_user_refuse;
750 $this->fk_user_cancel = $obj->fk_user_cancel;
751 $this->fk_user_approve = $obj->fk_user_approve;
753 $user_author =
new User($this->db);
754 if ($this->fk_user_author > 0) {
755 $user_author->fetch($this->fk_user_author);
758 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
760 $user_approver =
new User($this->db);
761 if ($this->fk_user_approve > 0) {
762 $user_approver->fetch($this->fk_user_approve);
763 } elseif ($this->fk_user_validator > 0) {
764 $user_approver->fetch($this->fk_user_validator);
766 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
768 $this->fk_statut = (int) $obj->status;
769 $this->
status = (int) $obj->status;
770 $this->fk_c_paiement = $obj->fk_c_paiement;
771 $this->paid = $obj->paid;
773 if ($this->
status == self::STATUS_APPROVED || $this->
status == self::STATUS_CLOSED) {
774 $user_valid =
new User($this->db);
775 if ($this->fk_user_valid > 0) {
776 $user_valid->fetch($this->fk_user_valid);
778 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
790 $this->error = $this->db->lasterror();
806 public function set_paid($id, $fuser, $notrigger = 0)
809 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
810 return $this->
setPaid($id, $fuser, $notrigger);
821 public function setPaid($id, $fuser, $notrigger = 0)
826 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
827 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid = 1";
830 dol_syslog(get_class($this).
"::setPaid", LOG_DEBUG);
831 $resql = $this->db->query($sql);
833 if ($this->db->affected_rows($resql)) {
836 $result = $this->call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
852 $this->db->rollback();
853 $this->error = $this->db->error();
861 $this->db->rollback();
891 $labelStatus = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
892 $labelStatusShort = $langs->transnoentitiesnoconv($this->labelStatusShort[$status]);
894 $statuslogo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
896 $statusType = $statuslogo[$status];
898 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
912 $sql =
"SELECT f.rowid,";
913 $sql .=
" f.date_create as datec,";
914 $sql .=
" f.tms as date_modification,";
915 $sql .=
" f.date_valid as datev,";
916 $sql .=
" f.date_approve as datea,";
917 $sql .=
" f.fk_user_creat as fk_user_creation,";
918 $sql .=
" f.fk_user_author as fk_user_author,";
919 $sql .=
" f.fk_user_modif as fk_user_modification,";
920 $sql .=
" f.fk_user_valid,";
921 $sql .=
" f.fk_user_approve";
922 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
923 $sql .=
" WHERE f.rowid = ".((int) $id);
924 $sql .=
" AND f.entity = ".$conf->entity;
928 $resql = $this->db->query($sql);
930 if ($this->db->num_rows($resql)) {
931 $obj = $this->db->fetch_object($resql);
933 $this->
id = $obj->rowid;
935 $this->date_creation = $this->db->jdate($obj->datec);
936 $this->date_modification = $this->db->jdate($obj->date_modification);
937 $this->date_validation = $this->db->jdate($obj->datev);
938 $this->date_approbation = $this->db->jdate($obj->datea);
940 $this->user_creation_id = $obj->fk_user_author;
941 $this->user_creation_id = $obj->fk_user_creation;
942 $this->user_validation_id = $obj->fk_user_valid;
943 $this->user_modification_id = $obj->fk_user_modification;
944 $this->user_approve_id = $obj->fk_user_approve;
946 $this->db->free($resql);
963 global $user, $langs;
969 $this->
ref =
'SPECIMEN';
972 $this->date_create = $now;
973 $this->date_debut = $now;
974 $this->date_fin = $now;
975 $this->date_valid = $now;
976 $this->date_approve = $now;
982 $this->fk_user_author = $user->id;
983 $this->fk_user_validator = $user->id;
984 $this->fk_user_valid = $user->id;
985 $this->fk_user_approve = $user->id;
987 $this->note_private =
'Private note';
988 $this->note_public =
'SPECIMEN';
991 while ($xnbp < $nbp) {
993 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
994 $line->date = ($now - 3600 * (1 + $xnbp));
995 $line->total_ht = 100;
996 $line->total_tva = 20;
997 $line->total_ttc = 120;
1000 $line->value_unit = 120;
1001 $line->fk_expensereport = 0;
1002 $line->type_fees_code =
'TRA';
1003 $line->fk_c_type_fees = $type_fees_id;
1005 $line->projet_ref =
'ABC';
1007 $this->lines[$xnbp] = $line;
1010 $this->total_ht += $line->total_ht;
1011 $this->total_tva += $line->total_tva;
1012 $this->total_ttc += $line->total_ttc;
1031 $langs->load(
'trips');
1033 if ($user->hasRight(
'expensereport',
'lire')) {
1034 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
1035 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
1036 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
1038 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1039 $result = $this->db->query($sql);
1041 $num = $this->db->num_rows($result);
1047 $objp = $this->db->fetch_object($result);
1049 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
1050 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
1051 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
1053 $result2 = $this->db->query($sql2);
1054 $obj = $this->db->fetch_object($result2);
1056 $objp->fk_user_author = $obj->fk_user_author;
1057 $objp->ref = $obj->ref;
1058 $objp->fk_c_expensereport_status = $obj->status;
1059 $objp->rowid = $obj->rowid;
1061 $total_HT += $objp->total_ht;
1062 $total_TTC += $objp->total_ttc;
1063 $author =
new User($this->db);
1064 $author->fetch($objp->fk_user_author);
1068 print
'<a href="'.dolBuildUrl(DOL_URL_ROOT.
'/expensereport/card.php', [
'id' => $objp->rowid]).
'">'.$objp->ref_num.
'</a>';
1070 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
1071 print
'<td>'.$author->getNomUrl(1).
'</td>';
1072 print
'<td>'.$objp->comments.
'</td>';
1073 print
'<td class="right">'.price($objp->total_ht).
'</td>';
1074 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
1075 print
'<td class="right">';
1077 switch ($objp->fk_c_expensereport_status) {
1079 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
1082 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
1085 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
1088 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
1091 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
1108 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
1109 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
1110 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
1111 print
'<td> </td>';
1114 $this->error = $this->db->lasterror();
1131 $this->lines = array();
1133 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1134 $sql .=
" de.".$this->db->sanitize($this->fk_element).
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1135 $sql .=
' de.tva_tx, de.vat_src_code,';
1136 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1137 $sql .=
' de.fk_ecm_files,';
1138 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1139 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1140 $sql .=
' ctf.code as code_type_fees, ctf.label as label_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1141 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1142 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->db->sanitize($this->table_element_line).
' as de';
1143 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1144 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1145 $sql .=
" WHERE de.".$this->db->sanitize($this->fk_element).
" = ".((int) $this->
id);
1147 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1149 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1152 $resql = $this->db->query($sql);
1154 $num = $this->db->num_rows($resql);
1157 $objp = $this->db->fetch_object($resql);
1161 $deplig->rowid = $objp->rowid;
1162 $deplig->id = $objp->rowid;
1163 $deplig->comments = $objp->comments;
1164 $deplig->qty = $objp->qty;
1165 $deplig->value_unit = $objp->value_unit;
1166 $deplig->date = $objp->date;
1167 $deplig->dates = $this->db->jdate($objp->date);
1169 $deplig->fk_expensereport = $objp->fk_expensereport;
1170 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1171 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1172 $deplig->fk_projet = $objp->fk_project;
1173 $deplig->fk_project = $objp->fk_project;
1174 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1176 $deplig->total_ht = $objp->total_ht;
1177 $deplig->total_tva = $objp->total_tva;
1178 $deplig->total_ttc = $objp->total_ttc;
1179 $deplig->total_localtax1 = $objp->total_localtax1;
1180 $deplig->total_localtax2 = $objp->total_localtax2;
1182 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1183 $deplig->type_fees_libelle = $objp->label_type_fees;
1184 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1186 $deplig->tva_tx = $objp->tva_tx;
1187 $deplig->vatrate = $objp->tva_tx;
1188 $deplig->vat_src_code = $objp->vat_src_code;
1189 $deplig->localtax1_tx = $objp->localtax1_tx;
1190 $deplig->localtax2_tx = $objp->localtax2_tx;
1191 $deplig->localtax1_type = $objp->localtax1_type;
1192 $deplig->localtax2_type = $objp->localtax2_type;
1194 $deplig->projet_ref = $objp->ref_projet;
1195 $deplig->projet_title = $objp->title_projet;
1197 $deplig->rule_warning_message = $objp->rule_warning_message;
1199 $deplig->rang = $objp->rang;
1201 $this->lines[$i] = $deplig;
1205 $this->db->free($resql);
1208 $this->error = $this->db->lasterror();
1209 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1222 public function delete($user =
null, $notrigger = 0)
1225 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1233 $result = $this->call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1241 if (!$error && !empty($this->table_element_line)) {
1242 $tabletodelete = $this->table_element_line;
1244 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1245 if (!$this->db->query($sql)) {
1247 $this->error = $this->db->lasterror();
1248 $this->errors[] = $this->error;
1249 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1274 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1280 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1281 $res = $this->db->query($sql);
1284 $this->error = $this->db->lasterror();
1285 $this->errors[] = $this->error;
1286 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1302 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1303 $dir =
$conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1304 $file = $dir.
"/".$ref.
".pdf";
1305 if (file_exists($file)) {
1309 $this->error =
'ErrorFailToDeleteFile';
1310 $this->errors[] = $this->error;
1311 $this->db->rollback();
1315 if (file_exists($dir)) {
1318 $this->error =
'ErrorFailToDeleteDir';
1319 $this->errors[] = $this->error;
1320 $this->db->rollback();
1328 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1329 $this->db->commit();
1332 $this->db->rollback();
1346 global
$conf, $langs, $user;
1352 if ($this->
status == self::STATUS_VALIDATED) {
1353 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
1357 $this->date_valid = $now;
1360 if (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) {
1365 if (empty($num) || $num < 0) {
1374 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1375 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1376 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1377 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1378 $sql .=
" fk_user_valid = ".((int) $user->id);
1379 $sql .=
" WHERE rowid = ".((int) $this->
id);
1381 $resql = $this->db->query($sql);
1385 $result = $this->call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1393 $this->oldref = $this->ref;
1396 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1397 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1400 $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).
"'";
1401 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1402 $resql = $this->db->query($sql);
1405 $this->error = $this->db->lasterror();
1407 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1408 $sql .=
" WHERE filepath = 'expensereport/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
1409 $resql = $this->db->query($sql);
1412 $this->error = $this->db->lasterror();
1418 $dirsource =
$conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1419 $dirdest =
$conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1420 if (!$error && file_exists($dirsource)) {
1421 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1423 if (@rename($dirsource, $dirdest)) {
1426 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1427 foreach ($listoffiles as $fileentry) {
1428 $dirsource = $fileentry[
'name'];
1429 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1430 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1431 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1432 @rename($dirsource, $dirdest);
1445 if (empty($error)) {
1446 $this->db->commit();
1449 $this->db->rollback();
1450 $this->error = $this->db->error();
1454 $this->db->rollback();
1455 $this->error = $this->db->lasterror();
1471 $sql =
'SELECT date_debut';
1472 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1473 $sql .=
" WHERE rowid = ".((int) $this->
id);
1475 $result = $this->db->query($sql);
1477 $objp = $this->db->fetch_object($result);
1479 $this->date_debut = $this->db->jdate($objp->date_debut);
1481 if ($this->
status != self::STATUS_VALIDATED) {
1482 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1483 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1484 $sql .=
" WHERE rowid = ".((int) $this->
id);
1486 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1488 if ($this->db->query($sql)) {
1491 $this->error = $this->db->lasterror();
1495 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1513 if ($this->
status != self::STATUS_APPROVED) {
1515 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1516 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1517 $sql .=
" date_approve='".$this->db->idate($now).
"'";
1518 $sql .=
" WHERE rowid = ".((int) $this->
id);
1519 if ($this->db->query($sql)) {
1521 $this->date_approve = $now;
1522 $this->fk_user_approve = $fuser->id;
1525 $result = $this->call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1533 if (empty($error)) {
1534 $this->db->commit();
1537 $this->db->rollback();
1538 $this->error = $this->db->error();
1542 $this->db->rollback();
1543 $this->error = $this->db->lasterror();
1547 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1561 public function setDeny($fuser, $details, $notrigger = 0)
1567 if ($this->
status != self::STATUS_REFUSED) {
1568 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1569 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1570 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1571 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1572 $sql .=
" fk_user_approve = NULL";
1573 $sql .=
" WHERE rowid = ".((int) $this->
id);
1574 if ($this->db->query($sql)) {
1575 $this->fk_statut = 99;
1577 $this->fk_user_refuse = $fuser->id;
1578 $this->detail_refuse = $details;
1579 $this->date_refuse = $now;
1583 $result = $this->call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1591 if (empty($error)) {
1592 $this->db->commit();
1595 $this->db->rollback();
1596 $this->error = $this->db->error();
1600 $this->db->rollback();
1601 $this->error = $this->db->lasterror();
1605 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1624 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1625 return $this->
setUnpaid($fuser, $notrigger);
1642 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1643 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1644 $sql .=
" WHERE rowid = ".((int) $this->
id);
1646 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1648 if ($this->db->query($sql)) {
1651 $result = $this->call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1659 if (empty($error)) {
1660 $this->db->commit();
1663 $this->db->rollback();
1664 $this->error = $this->db->error();
1668 $this->db->rollback();
1669 $this->error = $this->db->error();
1673 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1692 $this->date_cancel =
dol_now();
1693 if ($this->
status != self::STATUS_CANCELED) {
1696 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1697 $sql .=
" SET fk_statut = ".((int) self::STATUS_CANCELED).
", fk_user_cancel = ".((int) $fuser->id);
1698 $sql .=
", date_cancel = '".$this->db->idate($this->date_cancel).
"'";
1699 $sql .=
", detail_cancel = '".$this->db->escape($detail).
"'";
1700 $sql .=
" WHERE rowid = ".((int) $this->
id);
1702 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1704 if ($this->db->query($sql)) {
1707 $result = $this->call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1715 if (empty($error)) {
1716 $this->db->commit();
1719 $this->db->rollback();
1720 $this->error = $this->db->error();
1724 $this->db->rollback();
1725 $this->error = $this->db->error();
1729 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1741 global $langs,
$conf;
1742 $langs->load(
"trips");
1751 $dirmodels = array_merge(array(
'/'), (array)
$conf->modules_parts[
'models']);
1752 foreach ($dirmodels as $reldir) {
1753 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1756 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1764 $obj =
new $classname();
1765 '@phan-var-force ModeleNumRefExpenseReport $obj';
1766 $numref = $obj->getNextValue($this);
1768 if ($numref !=
"") {
1771 $this->error = $obj->error;
1772 $this->errors = $obj->errors;
1777 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1790 global
$conf, $langs;
1792 $langs->load(
'trips');
1794 $nofetch = !empty($params[
'nofetch']);
1795 $moretitle = $params[
'moretitle'] ??
'';
1798 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1799 if (isset($this->
status)) {
1800 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1803 $datas[
'picto'] .=
' - '.$moretitle;
1805 if (!empty($this->
ref)) {
1806 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1808 if (!empty($this->total_ht)) {
1809 $datas[
'total_ht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1,
$conf->currency);
1811 if (!empty($this->total_tva)) {
1812 $datas[
'total_tva'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1,
$conf->currency);
1814 if (!empty($this->total_ttc)) {
1815 $datas[
'total_ttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1,
$conf->currency);
1833 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1835 global $langs, $hookmanager;
1839 $baseurl = DOL_URL_ROOT.
'/expensereport/card.php';
1840 $query = [
'id' => $this->id];
1848 'objecttype' => $this->element,
1849 'option' => $option,
1850 'moretitle' => $moretitle,
1853 $classfortooltip =
'classfortooltip';
1856 $classfortooltip =
'classforajaxtooltip';
1857 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1863 if ($option !=
'nolink') {
1865 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1866 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1867 $add_save_lastsearch_values = 1;
1869 if ($add_save_lastsearch_values) {
1870 $query += [
'save_lastsearch_values' => 1];
1881 if (empty($notooltip)) {
1883 $label = $langs->trans(
"ShowExpenseReport");
1884 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
1886 $linkclose .= ($label ?
' title="'.dolPrintHTMLForAttribute($label).
'"' :
' title="tocomplete"');
1887 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
1890 $linkstart =
'<a href="'.$url.
'"';
1891 $linkstart .= $linkclose.
'>';
1894 $result .= $linkstart;
1896 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
1898 if ($withpicto != 2) {
1899 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1901 $result .= $linkend;
1904 $hookmanager->initHooks(array($this->element .
'dao'));
1905 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
1906 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1908 $result = $hookmanager->resPrint;
1910 $result .= $hookmanager->resPrint;
1926 $this->total_ht += (float) $ligne_total_ht;
1927 $this->total_tva += (float) $ligne_total_tva;
1928 $this->total_ttc += $this->total_tva;
1930 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1931 $sql .=
" total_ht = ".((float) $this->total_ht);
1932 $sql .=
" , total_ttc = ".((float) $this->total_ttc);
1933 $sql .=
" , total_tva = ".((float) $this->total_tva);
1934 $sql .=
" WHERE rowid = ".((int) $this->
id);
1936 $result = $this->db->query($sql);
1940 $this->error = $this->db->error();
1960 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)
1964 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);
1966 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
1970 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1971 $fk_c_type_fees = 0;
1973 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1974 $fk_c_exp_tax_cat = 0;
1976 if (empty($vatrate) || $vatrate < 0) {
1982 if (empty($fk_project)) {
1987 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1998 $seller->tva_assuj = 1;
1999 $buyer =
new Societe($this->db);
2005 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
2006 $vat_src_code = $reg[1];
2007 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2009 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2011 $tmp =
calcul_price_total($qty, (
float) $up, 0, (
float)
price2num($vatrate), -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2013 $this->line->value_unit = $up;
2015 $this->line->vat_src_code = $vat_src_code;
2016 $this->line->vatrate =
price2num($vatrate);
2017 $this->line->localtax1_tx = $localtaxes_type[1];
2018 $this->line->localtax2_tx = $localtaxes_type[3];
2019 $this->line->localtax1_type = $localtaxes_type[0];
2020 $this->line->localtax2_type = $localtaxes_type[2];
2022 $this->line->total_ttc = (float) $tmp[2];
2023 $this->line->total_ht = (float) $tmp[0];
2024 $this->line->total_tva = (float) $tmp[1];
2025 $this->line->total_localtax1 = (float) $tmp[9];
2026 $this->line->total_localtax2 = (float) $tmp[10];
2028 $this->line->fk_expensereport = $this->id;
2029 $this->line->qty = $qty;
2030 $this->line->date = $date;
2031 $this->line->fk_c_type_fees = $fk_c_type_fees;
2032 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2033 $this->line->comments = $comments;
2034 $this->line->fk_projet = $fk_project;
2035 $this->line->fk_project = $fk_project;
2037 $this->line->fk_ecm_files = $fk_ecm_files;
2042 $result = $this->line->insert(0,
true);
2046 $this->db->commit();
2047 return $this->line->id;
2049 $this->db->rollback();
2053 $this->error = $this->line->error;
2054 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
2055 $this->db->rollback();
2059 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
2060 $this->error =
'ErrorExpenseNotDraftAndNotRefused';
2076 $langs->load(
'trips');
2079 if (!is_object($seller)) {
2081 $seller->tva_assuj = 1;
2085 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
2088 $rule_warning_message_tab = array();
2090 $current_total_ttc = $this->line->total_ttc;
2091 $new_current_total_ttc = $this->line->total_ttc;
2094 foreach ($rulestocheck as $rule) {
2095 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
2096 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
2098 $amount_to_test = $current_total_ttc;
2101 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
2103 if ($amount_to_test > $rule->amount) {
2106 if ($rule->restrictive) {
2107 $this->error =
'ExpenseReportConstraintViolationError';
2108 $this->errors[] = $this->error;
2110 $new_current_total_ttc -= $amount_to_test - $rule->amount;
2111 $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));
2113 $this->error =
'ExpenseReportConstraintViolationWarning';
2114 $this->errors[] = $this->error;
2116 $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));
2123 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
2125 if ($violation > 0) {
2126 $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);
2128 $this->line->value_unit = $tmp[5];
2129 $this->line->total_ttc = (float) $tmp[2];
2130 $this->line->total_ht = (float) $tmp[0];
2131 $this->line->total_tva = (float) $tmp[1];
2132 $this->line->total_localtax1 = (float) $tmp[9];
2133 $this->line->total_localtax2 = (float) $tmp[10];
2156 $userauthor =
new User($this->db);
2157 if ($userauthor->fetch($this->fk_user_author) <= 0) {
2158 $this->error =
'ErrorCantFetchUser';
2159 $this->errors[] =
'ErrorCantFetchUser';
2164 if (!is_object($seller)) {
2166 $seller->tva_assuj = 1;
2170 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2172 if (empty($range)) {
2173 $this->error =
'ErrorNoRangeAvailable';
2174 $this->errors[] =
'ErrorNoRangeAvailable';
2179 $ikoffset = $range->ikoffset;
2181 $ikoffset = $range->ikoffset / 12;
2186 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2187 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2189 $this->line->value_unit = $tmp[5];
2190 $this->line->total_ttc = (float) $tmp[2];
2191 $this->line->total_ht = (float) $tmp[0];
2192 $this->line->total_tva = (float) $tmp[1];
2193 $this->line->total_localtax1 = (float) $tmp[9];
2194 $this->line->total_localtax2 = (float) $tmp[10];
2209 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2210 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2211 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2212 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2213 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2214 if (!empty($this->line->id)) {
2215 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2218 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2219 $resql = $this->db->query($sql);
2221 $num = $this->db->num_rows($resql);
2249 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)
2253 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
2261 $seller->tva_assuj = 1;
2262 $seller->localtax1_assuj =
$mysoc->localtax1_assuj;
2263 $seller->localtax2_assuj =
$mysoc->localtax1_assuj;
2264 $buyer =
new Societe($this->db);
2271 if (preg_match(
'/\((.*)\)/', (
string) $vatrate, $reg)) {
2272 $vat_src_code = $reg[1];
2273 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', (
string) $vatrate);
2275 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2277 $tmp =
calcul_price_total($qty, $value_unit, 0, (
float)
price2num($vatrate), -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2281 $tx_tva = 1 + (float) $vatrate / 100;
2284 $this->line->comments = $comments;
2285 $this->line->qty = $qty;
2286 $this->line->value_unit = $value_unit;
2287 $this->line->date = $date;
2289 $this->line->fk_expensereport = $expensereport_id;
2290 $this->line->fk_c_type_fees = $type_fees_id;
2291 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2292 $this->line->fk_projet = $projet_id;
2293 $this->line->fk_project = $projet_id;
2295 $this->line->vat_src_code = $vat_src_code;
2296 $this->line->vatrate =
price2num($vatrate);
2297 $this->line->localtax1_tx = $localtaxes_type[1];
2298 $this->line->localtax2_tx = $localtaxes_type[3];
2299 $this->line->localtax1_type = $localtaxes_type[0];
2300 $this->line->localtax2_type = $localtaxes_type[2];
2302 $this->line->total_ttc = (float) $tmp[2];
2303 $this->line->total_ht = (float) $tmp[0];
2304 $this->line->total_tva = (float) $tmp[1];
2305 $this->line->total_localtax1 = (float) $tmp[9];
2306 $this->line->total_localtax2 = (float) $tmp[10];
2308 $this->line->fk_ecm_files = $fk_ecm_files;
2310 $this->line->id = ((int) $rowid);
2313 $sql =
"SELECT c.code as code_type_fees, c.label as label_type_fees";
2314 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2315 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2316 $resql = $this->db->query($sql);
2318 $objp_fees = $this->db->fetch_object($resql);
2319 $this->line->type_fees_code = $objp_fees->code_type_fees;
2320 $this->line->type_fees_libelle = $objp_fees->label_type_fees;
2321 $this->db->free($resql);
2324 if ($projet_id > 0) {
2326 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2327 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2328 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2329 $resql = $this->db->query($sql);
2331 if ($this->db->num_rows($resql) > 0) {
2332 $objp_projet = $this->db->fetch_object($resql);
2333 $this->line->projet_ref = $objp_projet->ref_projet;
2334 $this->line->projet_title = $objp_projet->title_projet;
2336 $this->db->free($resql);
2342 $result = $this->line->update($user, $notrigger);
2348 $this->db->commit();
2351 $this->error = $this->line->error;
2352 $this->errors = $this->line->errors;
2353 $this->db->rollback();
2369 public function deleteLine($rowid, $fuser =
null, $notrigger = 0)
2377 $result = $this->call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2384 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2385 $sql .=
' WHERE rowid = '.((int) $rowid);
2387 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2388 $result = $this->db->query($sql);
2390 if (!$result || $error > 0) {
2391 $this->error = $this->db->error();
2392 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2393 $this->db->rollback();
2399 $this->db->commit();
2416 $sql =
"SELECT rowid, date_debut, date_fin";
2417 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2418 $sql .=
" WHERE entity = ".((int)
$conf->entity);
2419 $sql .=
" AND fk_user_author = ".((int) $fuser->id);
2420 $sql .=
" AND (date_fin >= '".$this->db->idate($startDate).
"' AND date_debut <= '".$this->db->idate($endDate).
"')";
2422 $row = $this->db->getRow($sql);
2424 if ($row ===
false) {
2425 $this->error = $this->db->lasterror();
2426 dol_syslog(__CLASS__.
"::". __METHOD__.
" Error ".$this->error, LOG_ERR);
2430 return $row->rowid ?? 0;
2444 $users_validator = array();
2446 $sql =
"SELECT DISTINCT ur.fk_user";
2447 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2448 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2450 $sql .=
" SELECT DISTINCT ugu.fk_user";
2451 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2452 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2455 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2456 $result = $this->db->query($sql);
2458 $num_rows = $this->db->num_rows($result);
2460 while ($i < $num_rows) {
2461 $objp = $this->db->fetch_object($result);
2462 array_push($users_validator, $objp->fk_user);
2465 return $users_validator;
2467 $this->error = $this->db->lasterror();
2468 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2484 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2486 $outputlangs->load(
"trips");
2489 if (!empty($this->model_pdf)) {
2490 $modele = $this->model_pdf;
2496 if (!empty($modele)) {
2497 $modelpath =
"core/modules/expensereport/doc/";
2499 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2515 $sql =
"SELECT id, code, label";
2516 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2517 $sql .=
" WHERE active = ".((int) $active);
2518 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2519 $result = $this->db->query($sql);
2521 $num = $this->db->num_rows($result);
2524 $obj = $this->db->fetch_object($result);
2525 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2543 $this->nb = array();
2545 $sql =
"SELECT count(ex.rowid) as nb";
2546 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2547 $sql .=
" WHERE ex.fk_statut > 0";
2548 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2549 if (!$user->hasRight(
'expensereport',
'readall')) {
2550 $userchildids = $user->getAllChildIds(1);
2551 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2552 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2555 $resql = $this->db->query($sql);
2557 while ($obj = $this->db->fetch_object($resql)) {
2558 $this->nb[
"expensereports"] = $obj->nb;
2560 $this->db->free($resql);
2564 $this->error = $this->db->error();
2580 global
$conf, $langs;
2588 $sql =
"SELECT ex.rowid, ex.date_valid";
2589 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2590 if ($option ==
'toapprove') {
2591 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2593 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2595 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2596 if (!$user->hasRight(
'expensereport',
'readall')) {
2597 $userchildids = $user->getAllChildIds(1);
2598 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2599 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2602 $resql = $this->db->query($sql);
2604 $langs->load(
"trips");
2607 if ($option ==
'toapprove') {
2608 $response->warning_delay =
$conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2609 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2610 $response->labelShort = $langs->trans(
"ToApprove");
2611 $response->url =
dolBuildUrl(DOL_URL_ROOT.
'/expensereport/list.php', [
'mainmenu' =>
'hrm',
'statut' => self::STATUS_VALIDATED]);
2613 $response->warning_delay =
$conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2614 $response->label = $langs->trans(
"ExpenseReportsToPay");
2615 $response->labelShort = $langs->trans(
"StatusToPay");
2616 $response->url =
dolBuildUrl(DOL_URL_ROOT.
'/expensereport/list.php', [
'mainmenu' =>
'hrm',
'statut' => self::STATUS_APPROVED]);
2620 while ($obj = $this->db->fetch_object($resql)) {
2621 $response->nbtodo++;
2623 if ($option ==
'toapprove') {
2624 if ($this->db->jdate($obj->date_valid) < ($now -
$conf->expensereport->approve->warning_delay)) {
2625 $response->nbtodolate++;
2628 if ($this->db->jdate($obj->date_valid) < ($now -
$conf->expensereport->payment->warning_delay)) {
2629 $response->nbtodolate++;
2637 $this->error = $this->db->error();
2653 if ($option ==
'toapprove' && $this->
status != 2) {
2656 if ($option ==
'topay' && $this->
status != 5) {
2661 $warning_delay = (int) ($option ==
'toapprove' ?
$conf->expensereport->approve->warning_delay :
$conf->expensereport->payment->warning_delay);
2662 if ($warning_delay <= 0) {
2666 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $warning_delay);
2677 $alreadydispatched = 0;
2679 $type =
'expense_report';
2681 $sql =
" SELECT ".($mode ?
'DISTINCT piece_num' :
'COUNT(ab.rowid)').
" as nb";
2682 $sql .=
" FROM ".MAIN_DB_PREFIX.
"accounting_bookkeeping as ab WHERE ab.doc_type = '".$this->db->escape($type).
"' AND ab.fk_doc = ".((int) $this->
id);
2683 $resql = $this->db->query($sql);
2685 $obj = $this->db->fetch_object($resql);
2687 $alreadydispatched = $obj->nb;
2690 $this->error = $this->db->lasterror();
2694 if ($alreadydispatched) {
2695 return $alreadydispatched;
2707 $table =
'payment_expensereport';
2708 $field =
'fk_expensereport';
2710 $sql =
'SELECT sum(amount) as amount';
2711 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2712 $sql .=
" WHERE ".$this->db->sanitize($field).
" = ".((int) $this->
id);
2714 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2715 $resql = $this->db->query($sql);
2717 $obj = $this->db->fetch_object($resql);
2718 $this->db->free($resql);
2719 return (empty($obj->amount) ? 0 : $obj->amount);
2721 $this->error = $this->db->lasterror();
2736 global $langs,
$conf;
2744 $this->error = $langs->trans(
'ErrorBadParameterCat');
2749 $this->error = $langs->trans(
'ErrorBadParameterQty');
2753 $currentUser =
new User($this->db);
2754 $currentUser->fetch($this->fk_user);
2755 $currentUser->loadRights(
'expensereport');
2759 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2760 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2761 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2762 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2763 $sql .=
" ORDER BY r.range_ik ASC";
2765 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2767 $result = $this->db->query($sql);
2770 if (
getDolGlobalInt(
'EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR')) {
2772 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2773 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2774 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2775 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2776 $sql .=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2777 $sql .=
" AND tf.code = 'EX_KME' ";
2780 $resql = $this->db->query($sql);
2783 $obj = $this->db->fetch_object($resql);
2784 $cumulYearQty = $obj->cumul;
2787 $qty += (float) $cumulYearQty;
2790 $num = $this->db->num_rows($result);
2793 for ($i = 0; $i < $num; $i++) {
2794 $obj = $this->db->fetch_object($result);
2798 '@phan-var-force Object[] $ranges';
2800 for ($i = 0; $i < $num; $i++) {
2801 if ($i < ($num - 1)) {
2803 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i + 1]->range_ik) {
2804 $coef = $ranges[$i]->coef;
2805 $offset = $ranges[$i]->ikoffset;
2808 if ($qty > $ranges[$i]->range_ik) {
2809 $coef = $ranges[$i]->coef;
2810 $offset = $ranges[$i]->ikoffset;
2817 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2821 $this->error = $this->db->error().
" sql=".$sql;
2838 if ($arraydata ===
null) {
2839 $arraydata = array();
2842 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2844 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2845 $return .=
'<div class="info-box info-box-sm">';
2846 $return .=
'<span class="info-box-icon bg-infobox-action">';
2848 $return .=
'</span>';
2849 $return .=
'<div class="info-box-content">';
2850 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->
getNomUrl(1) .
'</span>';
2851 if ($selected >= 0) {
2852 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2854 if (array_key_exists(
'userauthor', $arraydata) && $arraydata[
'userauthor'] instanceof
User) {
2855 $return .=
'<br><span class="info-box-label">'.$arraydata[
'userauthor']->getNomUrl(-1).
'</span>';
2858 $return .=
'<br><span class="info-box-label">'.dol_print_date($this->date_debut,
'day').
'</span>';
2859 $return .=
' <span class="opacitymedium">'.$langs->trans(
"To").
'</span> ';
2860 $return .=
'<span class="info-box-label">'.dol_print_date($this->date_fin,
'day').
'</span>';
2862 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
2863 $return .=
'</div>';
2864 $return .=
'</div>';
2865 $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.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
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.
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.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
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.