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' =>
'UserValidation',
'enabled' => 1,
'visible' => -1,
'position' => 115),
321 'fk_user_approve' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'ApprovedBy',
'enabled' => 1,
'visible' => -1,
'position' => 120),
322 'fk_user_refuse' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'REFUSEUR',
'enabled' => 1,
'visible' => -1,
'position' => 125),
323 'fk_user_cancel' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'CANCEL_USER',
'enabled' => 1,
'visible' => -1,
'position' => 130),
324 'fk_c_paiement' => array(
'type' =>
'integer',
'label' =>
'PaymentMode',
'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' =>
'BankAccount',
'enabled' => 1,
'visible' => -1,
'position' => 175),
332 'fk_multicurrency' => array(
'type' =>
'integer',
'label' =>
'Currency',
'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();
862 dol_print_error($this->db);
885 $note = preg_replace(
'/(?:<br\s*\/?>|<\/(?:p|div|li)>)/i',
"\n", (
string) $this->note_public);
902 $labelStatus = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
903 $labelStatusShort = $langs->transnoentitiesnoconv($this->labelStatusShort[$status]);
905 $statuslogo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
907 $statusType = $statuslogo[$status];
909 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
923 $sql =
"SELECT f.rowid,";
924 $sql .=
" f.date_create as datec,";
925 $sql .=
" f.tms as date_modification,";
926 $sql .=
" f.date_valid as datev,";
927 $sql .=
" f.date_approve as datea,";
928 $sql .=
" f.fk_user_creat as fk_user_creation,";
929 $sql .=
" f.fk_user_author as fk_user_author,";
930 $sql .=
" f.fk_user_modif as fk_user_modification,";
931 $sql .=
" f.fk_user_valid,";
932 $sql .=
" f.fk_user_approve";
933 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
934 $sql .=
" WHERE f.rowid = ".((int) $id);
935 $sql .=
" AND f.entity = ".((int)
$conf->entity);
939 $resql = $this->db->query($sql);
941 if ($this->db->num_rows($resql)) {
942 $obj = $this->db->fetch_object($resql);
944 $this->
id = $obj->rowid;
946 $this->date_creation = $this->db->jdate($obj->datec);
947 $this->date_modification = $this->db->jdate($obj->date_modification);
948 $this->date_validation = $this->db->jdate($obj->datev);
949 $this->date_approbation = $this->db->jdate($obj->datea);
951 $this->user_creation_id = $obj->fk_user_author;
952 $this->user_creation_id = $obj->fk_user_creation;
953 $this->user_validation_id = $obj->fk_user_valid;
954 $this->user_modification_id = $obj->fk_user_modification;
955 $this->user_approve_id = $obj->fk_user_approve;
957 $this->db->free($resql);
959 dol_print_error($this->db);
974 global $user, $langs;
980 $this->
ref =
'SPECIMEN';
983 $this->date_create = $now;
984 $this->date_debut = $now;
985 $this->date_fin = $now;
986 $this->date_valid = $now;
987 $this->date_approve = $now;
993 $this->fk_user_author = $user->id;
994 $this->fk_user_validator = $user->id;
995 $this->fk_user_valid = $user->id;
996 $this->fk_user_approve = $user->id;
998 $this->note_private =
'Private note';
999 $this->note_public =
'SPECIMEN';
1002 while ($xnbp < $nbp) {
1004 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
1005 $line->date = ($now - 3600 * (1 + $xnbp));
1006 $line->total_ht = 100;
1007 $line->total_tva = 20;
1008 $line->total_ttc = 120;
1010 $line->vatrate = 20;
1011 $line->value_unit = 120;
1012 $line->fk_expensereport = 0;
1013 $line->type_fees_code =
'TRA';
1014 $line->fk_c_type_fees = $type_fees_id;
1016 $line->projet_ref =
'ABC';
1018 $this->lines[$xnbp] = $line;
1021 $this->total_ht += $line->total_ht;
1022 $this->total_tva += $line->total_tva;
1023 $this->total_ttc += $line->total_ttc;
1042 $langs->load(
'trips');
1044 if ($user->hasRight(
'expensereport',
'lire')) {
1045 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
1046 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
1047 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
1049 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1050 $result = $this->db->query($sql);
1052 $num = $this->db->num_rows($result);
1058 $objp = $this->db->fetch_object($result);
1060 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
1061 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
1062 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
1064 $result2 = $this->db->query($sql2);
1065 $obj = $this->db->fetch_object($result2);
1067 $objp->fk_user_author = $obj->fk_user_author;
1068 $objp->ref = $obj->ref;
1069 $objp->fk_c_expensereport_status = $obj->status;
1070 $objp->rowid = $obj->rowid;
1072 $total_HT += $objp->total_ht;
1073 $total_TTC += $objp->total_ttc;
1074 $author =
new User($this->db);
1075 $author->fetch($objp->fk_user_author);
1079 print
'<a href="'.dolBuildUrl(DOL_URL_ROOT.
'/expensereport/card.php', [
'id' => $objp->rowid]).
'">'.$objp->ref_num.
'</a>';
1081 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
1082 print
'<td>'.$author->getNomUrl(1).
'</td>';
1083 print
'<td>'.$objp->comments.
'</td>';
1084 print
'<td class="right">'.price($objp->total_ht).
'</td>';
1085 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
1086 print
'<td class="right">';
1088 switch ($objp->fk_c_expensereport_status) {
1090 print img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
1093 print $langs->trans(
'Draft').
' '.img_picto($langs->trans(
'Draft'),
'statut0');
1096 print $langs->trans(
'TripForValid').
' '.img_picto($langs->trans(
'TripForValid'),
'statut3');
1099 print $langs->trans(
'TripForPaid').
' '.img_picto($langs->trans(
'TripForPaid'),
'statut3');
1102 print $langs->trans(
'TripPaid').
' '.img_picto($langs->trans(
'TripPaid'),
'statut4');
1119 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
1120 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
1121 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
1122 print
'<td> </td>';
1125 $this->error = $this->db->lasterror();
1142 $this->lines = array();
1144 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1145 $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,";
1146 $sql .=
' de.tva_tx, de.vat_src_code,';
1147 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1148 $sql .=
' de.fk_ecm_files,';
1149 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1150 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1151 $sql .=
' ctf.code as code_type_fees, ctf.label as label_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1152 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1153 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->db->sanitize($this->table_element_line).
' as de';
1154 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1155 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1156 $sql .=
" WHERE de.".$this->db->sanitize($this->fk_element).
" = ".((int) $this->
id);
1158 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1160 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1163 $resql = $this->db->query($sql);
1165 $num = $this->db->num_rows($resql);
1168 $objp = $this->db->fetch_object($resql);
1172 $deplig->rowid = $objp->rowid;
1173 $deplig->id = $objp->rowid;
1174 $deplig->comments = $objp->comments;
1175 $deplig->qty = $objp->qty;
1176 $deplig->value_unit = $objp->value_unit;
1177 $deplig->date = $objp->date;
1178 $deplig->dates = $this->db->jdate($objp->date);
1180 $deplig->fk_expensereport = $objp->fk_expensereport;
1181 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1182 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1183 $deplig->fk_projet = $objp->fk_project;
1184 $deplig->fk_project = $objp->fk_project;
1185 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1187 $deplig->total_ht = $objp->total_ht;
1188 $deplig->total_tva = $objp->total_tva;
1189 $deplig->total_ttc = $objp->total_ttc;
1190 $deplig->total_localtax1 = $objp->total_localtax1;
1191 $deplig->total_localtax2 = $objp->total_localtax2;
1193 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1194 $deplig->type_fees_libelle = $objp->label_type_fees;
1195 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1197 $deplig->tva_tx = $objp->tva_tx;
1198 $deplig->vatrate = $objp->tva_tx;
1199 $deplig->vat_src_code = $objp->vat_src_code;
1200 $deplig->localtax1_tx = $objp->localtax1_tx;
1201 $deplig->localtax2_tx = $objp->localtax2_tx;
1202 $deplig->localtax1_type = $objp->localtax1_type;
1203 $deplig->localtax2_type = $objp->localtax2_type;
1205 $deplig->projet_ref = $objp->ref_projet;
1206 $deplig->projet_title = $objp->title_projet;
1208 $deplig->rule_warning_message = $objp->rule_warning_message;
1210 $deplig->rang = $objp->rang;
1212 $this->lines[$i] = $deplig;
1216 $this->db->free($resql);
1219 $this->error = $this->db->lasterror();
1220 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1233 public function delete($user =
null, $notrigger = 0)
1236 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1244 $result = $this->call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1252 if (!$error && !empty($this->table_element_line)) {
1253 $tabletodelete = $this->table_element_line;
1255 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1256 if (!$this->db->query($sql)) {
1258 $this->error = $this->db->lasterror();
1259 $this->errors[] = $this->error;
1260 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1285 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1291 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1292 $res = $this->db->query($sql);
1295 $this->error = $this->db->lasterror();
1296 $this->errors[] = $this->error;
1297 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1313 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1314 $dir =
$conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1315 $file = $dir.
"/".$ref.
".pdf";
1316 if (file_exists($file)) {
1320 $this->error =
'ErrorFailToDeleteFile';
1321 $this->errors[] = $this->error;
1322 $this->db->rollback();
1326 if (file_exists($dir)) {
1329 $this->error =
'ErrorFailToDeleteDir';
1330 $this->errors[] = $this->error;
1331 $this->db->rollback();
1339 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1340 $this->db->commit();
1343 $this->db->rollback();
1357 global
$conf, $langs, $user;
1363 if ($this->
status == self::STATUS_VALIDATED) {
1364 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
1368 $this->date_valid = $now;
1371 if (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) {
1374 $num = (string) $this->
ref;
1376 if (empty($num) || $num < 0) {
1385 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1386 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1387 $sql .=
" fk_statut = ".((int) self::STATUS_VALIDATED).
",";
1388 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1389 $sql .=
" fk_user_valid = ".((int) $user->id);
1390 $sql .=
" WHERE rowid = ".((int) $this->
id);
1392 $resql = $this->db->query($sql);
1396 $result = $this->call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1404 $this->oldref = $this->ref;
1407 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1408 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1411 $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).
"'";
1412 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1413 $resql = $this->db->query($sql);
1416 $this->error = $this->db->lasterror();
1418 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1419 $sql .=
" WHERE filepath = 'expensereport/".$this->db->escape($this->
ref).
"' and entity = ".((int)
$conf->entity);
1420 $resql = $this->db->query($sql);
1423 $this->error = $this->db->lasterror();
1429 $dirsource =
$conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1430 $dirdest =
$conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1431 if (!$error && file_exists($dirsource)) {
1432 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1434 if (@rename($dirsource, $dirdest)) {
1437 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1438 foreach ($listoffiles as $fileentry) {
1439 $dirsource = $fileentry[
'name'];
1440 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1441 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1442 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1443 @rename($dirsource, $dirdest);
1456 if (empty($error)) {
1457 $this->db->commit();
1460 $this->db->rollback();
1461 $this->error = $this->db->error();
1465 $this->db->rollback();
1466 $this->error = $this->db->lasterror();
1482 $sql =
'SELECT date_debut';
1483 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1484 $sql .=
" WHERE rowid = ".((int) $this->
id);
1486 $result = $this->db->query($sql);
1488 $objp = $this->db->fetch_object($result);
1490 $this->date_debut = $this->db->jdate($objp->date_debut);
1492 if ($this->
status != self::STATUS_VALIDATED) {
1493 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1494 $sql .=
" SET fk_statut = ".((int) self::STATUS_VALIDATED);
1495 $sql .=
" WHERE rowid = ".((int) $this->
id);
1497 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1499 if ($this->db->query($sql)) {
1502 $this->error = $this->db->lasterror();
1506 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1524 if ($this->
status != self::STATUS_APPROVED) {
1526 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1527 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".((int) self::STATUS_APPROVED).
", fk_user_approve = ".((int) $fuser->id).
",";
1528 $sql .=
" date_approve='".$this->db->idate($now).
"'";
1529 $sql .=
" WHERE rowid = ".((int) $this->
id);
1530 if ($this->db->query($sql)) {
1532 $this->date_approve = $now;
1533 $this->fk_user_approve = $fuser->id;
1536 $result = $this->call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1544 if (empty($error)) {
1545 $this->db->commit();
1548 $this->db->rollback();
1549 $this->error = $this->db->error();
1553 $this->db->rollback();
1554 $this->error = $this->db->lasterror();
1558 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1572 public function setDeny($fuser, $details, $notrigger = 0)
1578 if ($this->
status != self::STATUS_REFUSED) {
1579 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1580 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1581 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1582 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1583 $sql .=
" fk_user_approve = NULL";
1584 $sql .=
" WHERE rowid = ".((int) $this->
id);
1585 if ($this->db->query($sql)) {
1586 $this->fk_statut = 99;
1588 $this->fk_user_refuse = $fuser->id;
1589 $this->detail_refuse = $details;
1590 $this->date_refuse = $now;
1594 $result = $this->call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1602 if (empty($error)) {
1603 $this->db->commit();
1606 $this->db->rollback();
1607 $this->error = $this->db->error();
1611 $this->db->rollback();
1612 $this->error = $this->db->lasterror();
1616 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1635 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1636 return $this->
setUnpaid($fuser, $notrigger);
1653 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1654 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1655 $sql .=
" WHERE rowid = ".((int) $this->
id);
1657 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1659 if ($this->db->query($sql)) {
1662 $result = $this->call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1670 if (empty($error)) {
1671 $this->db->commit();
1674 $this->db->rollback();
1675 $this->error = $this->db->error();
1679 $this->db->rollback();
1680 $this->error = $this->db->error();
1684 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1703 $this->date_cancel =
dol_now();
1704 if ($this->
status != self::STATUS_CANCELED) {
1707 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1708 $sql .=
" SET fk_statut = ".((int) self::STATUS_CANCELED).
", fk_user_cancel = ".((int) $fuser->id);
1709 $sql .=
", date_cancel = '".$this->db->idate($this->date_cancel).
"'";
1710 $sql .=
", detail_cancel = '".$this->db->escape($detail).
"'";
1711 $sql .=
" WHERE rowid = ".((int) $this->
id);
1713 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1715 if ($this->db->query($sql)) {
1718 $result = $this->call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1726 if (empty($error)) {
1727 $this->db->commit();
1730 $this->db->rollback();
1731 $this->error = $this->db->error();
1735 $this->db->rollback();
1736 $this->error = $this->db->error();
1740 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1752 global $langs,
$conf;
1753 $langs->load(
"trips");
1762 $dirmodels = array_merge(array(
'/'), (array)
$conf->modules_parts[
'models']);
1763 foreach ($dirmodels as $reldir) {
1764 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1767 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1771 dol_print_error(
null,
"Failed to include file ".$file);
1775 $obj =
new $classname();
1776 '@phan-var-force ModeleNumRefExpenseReport $obj';
1777 $numref = $obj->getNextValue($this);
1779 if ($numref !=
"") {
1782 $this->error = $obj->error;
1783 $this->errors = $obj->errors;
1788 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1801 global
$conf, $langs;
1803 $langs->load(
'trips');
1805 $nofetch = !empty($params[
'nofetch']);
1806 $moretitle = $params[
'moretitle'] ??
'';
1809 $datas[
'picto'] = img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1810 if (isset($this->
status)) {
1811 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1814 $datas[
'picto'] .=
' - '.$moretitle;
1816 if (!empty($this->
ref)) {
1817 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1819 if (!empty($this->total_ht)) {
1820 $datas[
'total_ht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1,
$conf->currency);
1822 if (!empty($this->total_tva)) {
1823 $datas[
'total_tva'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1,
$conf->currency);
1825 if (!empty($this->total_ttc)) {
1826 $datas[
'total_ttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1,
$conf->currency);
1844 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1846 global $langs, $hookmanager;
1850 $baseurl = DOL_URL_ROOT.
'/expensereport/card.php';
1851 $query = [
'id' => $this->id];
1859 'objecttype' => $this->element,
1860 'option' => $option,
1861 'moretitle' => $moretitle,
1864 $classfortooltip =
'classfortooltip';
1867 $classfortooltip =
'classforajaxtooltip';
1868 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1874 if ($option !=
'nolink') {
1876 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1877 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1878 $add_save_lastsearch_values = 1;
1880 if ($add_save_lastsearch_values) {
1881 $query += [
'save_lastsearch_values' => 1];
1892 if (empty($notooltip)) {
1894 $label = $langs->trans(
"ShowExpenseReport");
1895 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
1897 $linkclose .= ($label ?
' title="'.dolPrintHTMLForAttribute($label).
'"' :
' title="tocomplete"');
1898 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
1901 $linkstart =
'<a href="'.$url.
'"';
1902 $linkstart .= $linkclose.
'>';
1905 $result .= $linkstart;
1907 $result .= img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
1909 if ($withpicto != 2) {
1910 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1912 $result .= $linkend;
1915 $hookmanager->initHooks(array($this->element .
'dao'));
1916 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
1917 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1919 $result = $hookmanager->resPrint;
1921 $result .= $hookmanager->resPrint;
1937 $this->total_ht += (float) $ligne_total_ht;
1938 $this->total_tva += (float) $ligne_total_tva;
1939 $this->total_ttc += $this->total_tva;
1941 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1942 $sql .=
" total_ht = ".((float) $this->total_ht);
1943 $sql .=
" , total_ttc = ".((float) $this->total_ttc);
1944 $sql .=
" , total_tva = ".((float) $this->total_tva);
1945 $sql .=
" WHERE rowid = ".((int) $this->
id);
1947 $result = $this->db->query($sql);
1951 $this->error = $this->db->error();
1971 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)
1975 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);
1977 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
1981 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1982 $fk_c_type_fees = 0;
1984 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1985 $fk_c_exp_tax_cat = 0;
1987 if (empty($vatrate) || $vatrate < 0) {
1993 if (empty($fk_project)) {
1998 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
2009 $seller->tva_assuj = 1;
2010 $buyer =
new Societe($this->db);
2016 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
2017 $vat_src_code = $reg[1];
2018 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2020 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2022 $tmp =
calcul_price_total($qty, (
float) $up, 0, (
float)
price2num($vatrate), -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2024 $this->line->value_unit = $up;
2026 $this->line->vat_src_code = $vat_src_code;
2027 $this->line->vatrate =
price2num($vatrate);
2028 $this->line->localtax1_tx = $localtaxes_type[1];
2029 $this->line->localtax2_tx = $localtaxes_type[3];
2030 $this->line->localtax1_type = $localtaxes_type[0];
2031 $this->line->localtax2_type = $localtaxes_type[2];
2033 $this->line->total_ttc = (float) $tmp[2];
2034 $this->line->total_ht = (float) $tmp[0];
2035 $this->line->total_tva = (float) $tmp[1];
2036 $this->line->total_localtax1 = (float) $tmp[9];
2037 $this->line->total_localtax2 = (float) $tmp[10];
2039 $this->line->fk_expensereport = $this->id;
2040 $this->line->qty = $qty;
2041 $this->line->date = $date;
2042 $this->line->fk_c_type_fees = $fk_c_type_fees;
2043 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2044 $this->line->comments = $comments;
2045 $this->line->fk_projet = $fk_project;
2046 $this->line->fk_project = $fk_project;
2048 $this->line->fk_ecm_files = $fk_ecm_files;
2053 $result = $this->line->insert(0,
true);
2057 $this->db->commit();
2058 return $this->line->id;
2060 $this->db->rollback();
2064 $this->error = $this->line->error;
2065 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
2066 $this->db->rollback();
2070 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
2071 $this->error =
'ErrorExpenseNotDraftAndNotRefused';
2087 $langs->load(
'trips');
2090 if (!is_object($seller)) {
2092 $seller->tva_assuj = 1;
2096 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
2099 $rule_warning_message_tab = array();
2101 $current_total_ttc = $this->line->total_ttc;
2102 $new_current_total_ttc = $this->line->total_ttc;
2105 foreach ($rulestocheck as $rule) {
2106 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
2107 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
2109 $amount_to_test = $current_total_ttc;
2112 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
2114 if ($amount_to_test > $rule->amount) {
2117 if ($rule->restrictive) {
2118 $this->error =
'ExpenseReportConstraintViolationError';
2119 $this->errors[] = $this->error;
2121 $new_current_total_ttc -= $amount_to_test - $rule->amount;
2122 $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));
2124 $this->error =
'ExpenseReportConstraintViolationWarning';
2125 $this->errors[] = $this->error;
2127 $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));
2134 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
2136 if ($violation > 0) {
2137 $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);
2139 $this->line->value_unit = $tmp[5];
2140 $this->line->total_ttc = (float) $tmp[2];
2141 $this->line->total_ht = (float) $tmp[0];
2142 $this->line->total_tva = (float) $tmp[1];
2143 $this->line->total_localtax1 = (float) $tmp[9];
2144 $this->line->total_localtax2 = (float) $tmp[10];
2167 $userauthor =
new User($this->db);
2168 if ($userauthor->fetch($this->fk_user_author) <= 0) {
2169 $this->error =
'ErrorCantFetchUser';
2170 $this->errors[] =
'ErrorCantFetchUser';
2175 if (!is_object($seller)) {
2177 $seller->tva_assuj = 1;
2181 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2183 if (empty($range)) {
2184 $this->error =
'ErrorNoRangeAvailable';
2185 $this->errors[] =
'ErrorNoRangeAvailable';
2190 $ikoffset = $range->ikoffset;
2192 $ikoffset = $range->ikoffset / 12;
2197 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2198 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2200 $this->line->value_unit = $tmp[5];
2201 $this->line->total_ttc = (float) $tmp[2];
2202 $this->line->total_ht = (float) $tmp[0];
2203 $this->line->total_tva = (float) $tmp[1];
2204 $this->line->total_localtax1 = (float) $tmp[9];
2205 $this->line->total_localtax2 = (float) $tmp[10];
2220 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2221 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2222 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2223 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2224 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2225 if (!empty($this->line->id)) {
2226 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2229 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2230 $resql = $this->db->query($sql);
2232 $num = $this->db->num_rows($resql);
2237 dol_print_error($this->db);
2260 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)
2265 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
2269 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
2277 $seller->tva_assuj = 1;
2278 $seller->localtax1_assuj =
$mysoc->localtax1_assuj;
2279 $seller->localtax2_assuj =
$mysoc->localtax1_assuj;
2280 $buyer =
new Societe($this->db);
2287 if (preg_match(
'/\((.*)\)/', (
string) $vatrate, $reg)) {
2288 $vat_src_code = $reg[1];
2289 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', (
string) $vatrate);
2291 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2293 $tmp =
calcul_price_total($qty, $value_unit, 0, (
float)
price2num($vatrate), -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2297 $tx_tva = 1 + (float) $vatrate / 100;
2300 $this->line->comments = $comments;
2301 $this->line->qty = $qty;
2302 $this->line->value_unit = $value_unit;
2303 $this->line->date = $date;
2305 $this->line->fk_expensereport = $expensereport_id;
2306 $this->line->fk_c_type_fees = $type_fees_id;
2307 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2308 $this->line->fk_projet = $projet_id;
2309 $this->line->fk_project = $projet_id;
2311 $this->line->vat_src_code = $vat_src_code;
2312 $this->line->vatrate =
price2num($vatrate);
2313 $this->line->localtax1_tx = $localtaxes_type[1];
2314 $this->line->localtax2_tx = $localtaxes_type[3];
2315 $this->line->localtax1_type = $localtaxes_type[0];
2316 $this->line->localtax2_type = $localtaxes_type[2];
2318 $this->line->total_ttc = (float) $tmp[2];
2319 $this->line->total_ht = (float) $tmp[0];
2320 $this->line->total_tva = (float) $tmp[1];
2321 $this->line->total_localtax1 = (float) $tmp[9];
2322 $this->line->total_localtax2 = (float) $tmp[10];
2324 $this->line->fk_ecm_files = $fk_ecm_files;
2326 $this->line->id = ((int) $rowid);
2329 $sql =
"SELECT c.code as code_type_fees, c.label as label_type_fees";
2330 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2331 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2332 $resql = $this->db->query($sql);
2334 $objp_fees = $this->db->fetch_object($resql);
2335 $this->line->type_fees_code = $objp_fees->code_type_fees;
2336 $this->line->type_fees_libelle = $objp_fees->label_type_fees;
2337 $this->db->free($resql);
2340 if ($projet_id > 0) {
2342 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2343 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2344 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2345 $resql = $this->db->query($sql);
2347 if ($this->db->num_rows($resql) > 0) {
2348 $objp_projet = $this->db->fetch_object($resql);
2349 $this->line->projet_ref = $objp_projet->ref_projet;
2350 $this->line->projet_title = $objp_projet->title_projet;
2352 $this->db->free($resql);
2358 $result = $this->line->update($user, $notrigger);
2364 $this->db->commit();
2367 $this->error = $this->line->error;
2368 $this->errors = $this->line->errors;
2369 $this->db->rollback();
2385 public function deleteLine($rowid, $fuser =
null, $notrigger = 0)
2389 if ($this->
id > 0) {
2391 $sql =
"SELECT rowid FROM ".$this->db->prefix().$this->table_element_line;
2392 $sql .=
" WHERE rowid = ".((int) $rowid).
" AND fk_expensereport = ".((int) $this->
id);
2393 $resql = $this->db->query($sql);
2394 if (!$resql || !$this->db->num_rows($resql)) {
2395 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
2404 $result = $this->call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2411 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2412 $sql .=
' WHERE rowid = '.((int) $rowid);
2414 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2415 $result = $this->db->query($sql);
2417 if (!$result || $error > 0) {
2418 $this->error = $this->db->error();
2419 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2420 $this->db->rollback();
2426 $this->db->commit();
2443 $sql =
"SELECT rowid, date_debut, date_fin";
2444 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2445 $sql .=
" WHERE entity = ".((int)
$conf->entity);
2446 $sql .=
" AND fk_user_author = ".((int) $fuser->id);
2447 $sql .=
" AND (date_fin >= '".$this->db->idate($startDate).
"' AND date_debut <= '".$this->db->idate($endDate).
"')";
2449 $row = $this->db->getRow($sql);
2451 if ($row ===
false) {
2452 $this->error = $this->db->lasterror();
2453 dol_syslog(__CLASS__.
"::". __METHOD__.
" Error ".$this->error, LOG_ERR);
2457 return $row->rowid ?? 0;
2471 $users_validator = array();
2473 $sql =
"SELECT DISTINCT ur.fk_user";
2474 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2475 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2477 $sql .=
" SELECT DISTINCT ugu.fk_user";
2478 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2479 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2482 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2483 $result = $this->db->query($sql);
2485 $num_rows = $this->db->num_rows($result);
2487 while ($i < $num_rows) {
2488 $objp = $this->db->fetch_object($result);
2489 array_push($users_validator, $objp->fk_user);
2492 return $users_validator;
2494 $this->error = $this->db->lasterror();
2495 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2511 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2513 $outputlangs->load(
"trips");
2516 if (!empty($this->model_pdf)) {
2517 $modele = $this->model_pdf;
2523 if (!empty($modele)) {
2524 $modelpath =
"core/modules/expensereport/doc/";
2526 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2542 $sql =
"SELECT id, code, label";
2543 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2544 $sql .=
" WHERE active = ".((int) $active);
2545 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2546 $result = $this->db->query($sql);
2548 $num = $this->db->num_rows($result);
2551 $obj = $this->db->fetch_object($result);
2552 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2556 dol_print_error($this->db);
2570 $this->nb = array();
2572 $sql =
"SELECT count(ex.rowid) as nb";
2573 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2574 $sql .=
" WHERE ex.fk_statut > 0";
2575 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2576 if (!$user->hasRight(
'expensereport',
'readall')) {
2577 $userchildids = $user->getAllChildIds(1);
2578 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2579 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2582 $resql = $this->db->query($sql);
2584 while ($obj = $this->db->fetch_object($resql)) {
2585 $this->nb[
"expensereports"] = $obj->nb;
2587 $this->db->free($resql);
2590 dol_print_error($this->db);
2591 $this->error = $this->db->error();
2607 global
$conf, $langs;
2614 $warning_delay = ($option ==
'toapprove' ?
$conf->expensereport->approve->warning_delay :
$conf->expensereport->payment->warning_delay);
2619 $sql =
"SELECT COUNT(ex.rowid) as nb,";
2620 $sql .=
" SUM(CASE WHEN ex.date_valid IS NULL OR ex.date_valid < '".$this->db->idate($now - $warning_delay).
"' THEN 1 ELSE 0 END) as nblate";
2621 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2622 if ($option ==
'toapprove') {
2623 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2625 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2627 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2628 if (!$user->hasRight(
'expensereport',
'readall')) {
2629 $userchildids = $user->getAllChildIds(1);
2630 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2631 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2634 $resql = $this->db->query($sql);
2636 $langs->load(
"trips");
2639 if ($option ==
'toapprove') {
2640 $response->warning_delay =
$conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2641 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2642 $response->labelShort = $langs->trans(
"ToApprove");
2643 $response->url =
dolBuildUrl(DOL_URL_ROOT.
'/expensereport/list.php', [
'mainmenu' =>
'hrm',
'statut' => self::STATUS_VALIDATED]);
2645 $response->warning_delay =
$conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2646 $response->label = $langs->trans(
"ExpenseReportsToPay");
2647 $response->labelShort = $langs->trans(
"StatusToPay");
2648 $response->url =
dolBuildUrl(DOL_URL_ROOT.
'/expensereport/list.php', [
'mainmenu' =>
'hrm',
'statut' => self::STATUS_APPROVED]);
2650 $response->img = img_object(
'',
"trip");
2652 $obj = $this->db->fetch_object($resql);
2654 $response->nbtodo = (int) $obj->nb;
2655 $response->nbtodolate = (int) $obj->nblate;
2660 dol_print_error($this->db);
2661 $this->error = $this->db->error();
2677 if ($option ==
'toapprove' && $this->
status != 2) {
2680 if ($option ==
'topay' && $this->
status != 5) {
2685 $warning_delay = (int) ($option ==
'toapprove' ?
$conf->expensereport->approve->warning_delay :
$conf->expensereport->payment->warning_delay);
2686 if ($warning_delay <= 0) {
2690 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $warning_delay);
2701 $alreadydispatched = 0;
2703 $type =
'expense_report';
2705 $sql =
" SELECT ".($mode ?
'DISTINCT piece_num' :
'COUNT(ab.rowid)').
" as nb";
2706 $sql .=
" FROM ".MAIN_DB_PREFIX.
"accounting_bookkeeping as ab WHERE ab.doc_type = '".$this->db->escape($type).
"' AND ab.fk_doc = ".((int) $this->
id);
2707 $resql = $this->db->query($sql);
2709 $obj = $this->db->fetch_object($resql);
2711 $alreadydispatched = $obj->nb;
2714 $this->error = $this->db->lasterror();
2718 if ($alreadydispatched) {
2719 return $alreadydispatched;
2731 $table =
'payment_expensereport';
2732 $field =
'fk_expensereport';
2734 $sql =
'SELECT sum(amount) as amount';
2735 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2736 $sql .=
" WHERE ".$this->db->sanitize($field).
" = ".((int) $this->
id);
2738 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2739 $resql = $this->db->query($sql);
2741 $obj = $this->db->fetch_object($resql);
2742 $this->db->free($resql);
2743 return (empty($obj->amount) ? 0 : $obj->amount);
2745 $this->error = $this->db->lasterror();
2760 global $langs,
$conf;
2768 $this->error = $langs->trans(
'ErrorBadParameterCat');
2773 $this->error = $langs->trans(
'ErrorBadParameterQty');
2777 $currentUser =
new User($this->db);
2778 $currentUser->fetch($this->fk_user);
2779 $currentUser->loadRights(
'expensereport');
2783 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2784 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2785 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2786 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2787 $sql .=
" ORDER BY r.range_ik ASC";
2789 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2791 $result = $this->db->query($sql);
2794 if (
getDolGlobalInt(
'EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR')) {
2796 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2797 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2798 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2799 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2800 $sql .=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2801 $sql .=
" AND tf.code = 'EX_KME' ";
2804 $resql = $this->db->query($sql);
2807 $obj = $this->db->fetch_object($resql);
2808 $cumulYearQty = $obj->cumul;
2811 $qty += (float) $cumulYearQty;
2814 $num = $this->db->num_rows($result);
2817 for ($i = 0; $i < $num; $i++) {
2818 $obj = $this->db->fetch_object($result);
2822 '@phan-var-force Object[] $ranges';
2824 for ($i = 0; $i < $num; $i++) {
2825 if ($i < ($num - 1)) {
2827 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i + 1]->range_ik) {
2828 $coef = $ranges[$i]->coef;
2829 $offset = $ranges[$i]->ikoffset;
2832 if ($qty > $ranges[$i]->range_ik) {
2833 $coef = $ranges[$i]->coef;
2834 $offset = $ranges[$i]->ikoffset;
2841 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2845 $this->error = $this->db->error().
" sql=".$sql;
2862 if ($arraydata ===
null) {
2863 $arraydata = array();
2866 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2868 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2869 $return .=
'<div class="info-box info-box-sm">';
2870 $return .=
'<span class="info-box-icon bg-infobox-action">';
2871 $return .= img_picto(
'', $this->picto);
2872 $return .=
'</span>';
2873 $return .=
'<div class="info-box-content">';
2874 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->
getNomUrl(1) .
'</span>';
2875 if ($selected >= 0) {
2876 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2878 if (array_key_exists(
'userauthor', $arraydata) && $arraydata[
'userauthor'] instanceof
User) {
2879 $return .=
'<br><span class="info-box-label">'.$arraydata[
'userauthor']->getNomUrl(-1).
'</span>';
2882 $return .=
'<br><span class="info-box-label">'.dol_print_date($this->date_debut,
'day').
'</span>';
2883 $return .=
' <span class="opacitymedium">'.$langs->trans(
"To").
'</span> ';
2884 $return .=
'<span class="info-box-label">'.dol_print_date($this->date_fin,
'day').
'</span>';
2886 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
2887 $return .=
'</div>';
2888 $return .=
'</div>';
2889 $return .=
'</div>';
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
isLineOfObject($lineid)
Check that a line belongs to this object, using $this->table_element_line and $this->fk_element.
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.
getSummary()
Return a short summary of the public note.
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.
dolGetFirstLineOfText($text, $nboflines=1, $charset='UTF-8')
Return first line of text.
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.
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.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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_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, $notused, $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.