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->fk_user_approve = 0;
574 $this->date_create =
'';
575 $this->date_creation =
'';
576 $this->date_validation =
'';
577 $this->date_approve =
'';
580 if (is_array($this->lines) && count($this->lines) > 0) {
581 foreach ($this->lines as $key => $line) {
582 $this->lines[$key]->fk_ecm_files = 0;
587 $this->context[
'createfromclone'] =
'createfromclone';
588 $result = $this->
create($user);
595 if (is_object($hookmanager)) {
596 $parameters = array(
'objFrom' => $objFrom);
598 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
606 unset($this->context[
'createfromclone']);
613 $this->db->rollback();
627 public function update($user, $notrigger = 0, $userofexpensereport =
null)
632 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
633 $sql .=
" total_ht = ".((float) $this->total_ht);
634 $sql .=
" , total_ttc = ".((float) $this->total_ttc);
635 $sql .=
" , total_tva = ".((float) $this->total_tva);
636 if (!empty($this->date_create)) {
637 $sql .=
" , date_create = '".$this->db->idate($this->date_create).
"'";
639 $sql .=
" , date_debut = '".$this->db->idate($this->date_debut).
"'";
640 $sql .=
" , date_fin = '".$this->db->idate($this->date_fin).
"'";
641 if ($userofexpensereport && is_object($userofexpensereport)) {
642 $sql .=
" , fk_user_author = ".($userofexpensereport->id > 0 ? (int) $userofexpensereport->id :
"null");
644 $sql .=
" , fk_user_validator = ".($this->fk_user_validator > 0 ? (int) $this->fk_user_validator :
"null");
645 $sql .=
" , fk_user_valid = ".($this->fk_user_valid > 0 ? (int) $this->fk_user_valid :
"null");
646 $sql .=
" , fk_user_approve = ".($this->fk_user_approve > 0 ? (int) $this->fk_user_approve :
"null");
647 $sql .=
" , fk_user_modif = ".((int) $user->id);
648 $sql .=
" , fk_statut = ".($this->fk_statut >= 0 ? (int) $this->fk_statut : 0);
649 $sql .=
" , fk_c_paiement = ".($this->fk_c_paiement > 0 ? (int) $this->fk_c_paiement :
"null");
650 $sql .=
" , note_public = ".(!empty($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"''");
651 $sql .=
" , note_private = ".(!empty($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"''");
652 $sql .=
" , detail_refuse = ".(!empty($this->detail_refuse) ?
"'".$this->db->escape($this->detail_refuse).
"'" :
"''");
653 $sql .=
" WHERE rowid = ".((int) $this->
id);
655 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
656 $result = $this->db->query($sql);
663 if (!$error && !$notrigger) {
665 $result = $this->call_trigger(
'EXPENSE_REPORT_MODIFY', $user);
676 $this->db->rollback();
677 $this->error = $this->db->error();
681 $this->db->rollback();
682 $this->error = $this->db->error();
694 public function fetch($id, $ref =
'')
696 $sql =
"SELECT d.rowid, d.entity, d.ref, d.note_public, d.note_private,";
697 $sql .=
" d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,";
698 $sql .=
" d.date_refuse, d.date_cancel,";
699 $sql .=
" d.total_ht, d.total_ttc, d.total_tva,";
700 $sql .=
" d.localtax1 as total_localtax1, d.localtax2 as total_localtax2,";
701 $sql .=
" d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,";
702 $sql .=
" d.fk_user_creat, d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
703 $sql .=
" d.fk_user_valid, d.fk_user_approve,";
704 $sql .=
" d.fk_statut as status, d.fk_c_paiement, d.paid";
705 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as d";
707 $sql .=
" WHERE d.ref = '".$this->db->escape($ref).
"'";
708 $sql .=
" AND d.entity IN (".getEntity(
'expensereport').
")";
710 $sql .=
" WHERE d.rowid = ".((int) $id);
714 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
715 $resql = $this->db->query($sql);
717 $obj = $this->db->fetch_object($resql);
719 $this->
id = $obj->rowid;
720 $this->
ref = $obj->ref;
722 $this->entity = $obj->entity;
724 $this->total_ht = $obj->total_ht;
725 $this->total_tva = $obj->total_tva;
726 $this->total_ttc = $obj->total_ttc;
727 $this->localtax1 = $obj->total_localtax1;
728 $this->localtax2 = $obj->total_localtax2;
729 $this->total_localtax1 = $obj->total_localtax1;
730 $this->total_localtax2 = $obj->total_localtax2;
732 $this->note_public = $obj->note_public;
733 $this->note_private = $obj->note_private;
734 $this->detail_refuse = $obj->detail_refuse;
735 $this->detail_cancel = $obj->detail_cancel;
737 $this->date_debut = $this->db->jdate($obj->date_debut);
738 $this->date_fin = $this->db->jdate($obj->date_fin);
739 $this->date_valid = $this->db->jdate($obj->date_valid);
740 $this->date_approve = $this->db->jdate($obj->date_approve);
741 $this->date_create = $this->db->jdate($obj->date_create);
742 $this->date_modif = $this->db->jdate($obj->date_modif);
743 $this->date_refuse = $this->db->jdate($obj->date_refuse);
744 $this->date_cancel = $this->db->jdate($obj->date_cancel);
746 $this->fk_user_creat = $obj->fk_user_creat;
747 $this->fk_user_author = $obj->fk_user_author;
748 $this->fk_user_modif = $obj->fk_user_modif;
749 $this->fk_user_validator = $obj->fk_user_validator;
750 $this->fk_user_valid = $obj->fk_user_valid;
751 $this->fk_user_refuse = $obj->fk_user_refuse;
752 $this->fk_user_cancel = $obj->fk_user_cancel;
753 $this->fk_user_approve = $obj->fk_user_approve;
755 $user_author =
new User($this->db);
756 if ($this->fk_user_author > 0) {
757 $user_author->fetch($this->fk_user_author);
760 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
762 $user_approver =
new User($this->db);
763 if ($this->fk_user_approve > 0) {
764 $user_approver->fetch($this->fk_user_approve);
765 } elseif ($this->fk_user_validator > 0) {
766 $user_approver->fetch($this->fk_user_validator);
768 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
770 $this->fk_statut = (int) $obj->status;
771 $this->
status = (int) $obj->status;
772 $this->fk_c_paiement = $obj->fk_c_paiement;
773 $this->paid = $obj->paid;
775 if ($this->
status == self::STATUS_APPROVED || $this->
status == self::STATUS_CLOSED) {
776 $user_valid =
new User($this->db);
777 if ($this->fk_user_valid > 0) {
778 $user_valid->fetch($this->fk_user_valid);
780 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
792 $this->error = $this->db->lasterror();
808 public function set_paid($id, $fuser, $notrigger = 0)
811 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
812 return $this->
setPaid($id, $fuser, $notrigger);
823 public function setPaid($id, $fuser, $notrigger = 0)
828 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
829 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid = 1";
832 dol_syslog(get_class($this).
"::setPaid", LOG_DEBUG);
833 $resql = $this->db->query($sql);
835 if ($this->db->affected_rows($resql)) {
838 $result = $this->call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
854 $this->db->rollback();
855 $this->error = $this->db->error();
863 $this->db->rollback();
893 $labelStatus = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
894 $labelStatusShort = $langs->transnoentitiesnoconv($this->labelStatusShort[$status]);
896 $statuslogo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
898 $statusType = $statuslogo[$status];
900 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
914 $sql =
"SELECT f.rowid,";
915 $sql .=
" f.date_create as datec,";
916 $sql .=
" f.tms as date_modification,";
917 $sql .=
" f.date_valid as datev,";
918 $sql .=
" f.date_approve as datea,";
919 $sql .=
" f.fk_user_creat as fk_user_creation,";
920 $sql .=
" f.fk_user_author as fk_user_author,";
921 $sql .=
" f.fk_user_modif as fk_user_modification,";
922 $sql .=
" f.fk_user_valid,";
923 $sql .=
" f.fk_user_approve";
924 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
925 $sql .=
" WHERE f.rowid = ".((int) $id);
926 $sql .=
" AND f.entity = ".((int)
$conf->entity);
930 $resql = $this->db->query($sql);
932 if ($this->db->num_rows($resql)) {
933 $obj = $this->db->fetch_object($resql);
935 $this->
id = $obj->rowid;
937 $this->date_creation = $this->db->jdate($obj->datec);
938 $this->date_modification = $this->db->jdate($obj->date_modification);
939 $this->date_validation = $this->db->jdate($obj->datev);
940 $this->date_approbation = $this->db->jdate($obj->datea);
942 $this->user_creation_id = $obj->fk_user_author;
943 $this->user_creation_id = $obj->fk_user_creation;
944 $this->user_validation_id = $obj->fk_user_valid;
945 $this->user_modification_id = $obj->fk_user_modification;
946 $this->user_approve_id = $obj->fk_user_approve;
948 $this->db->free($resql);
965 global $user, $langs;
971 $this->
ref =
'SPECIMEN';
974 $this->date_create = $now;
975 $this->date_debut = $now;
976 $this->date_fin = $now;
977 $this->date_valid = $now;
978 $this->date_approve = $now;
984 $this->fk_user_author = $user->id;
985 $this->fk_user_validator = $user->id;
986 $this->fk_user_valid = $user->id;
987 $this->fk_user_approve = $user->id;
989 $this->note_private =
'Private note';
990 $this->note_public =
'SPECIMEN';
993 while ($xnbp < $nbp) {
995 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
996 $line->date = ($now - 3600 * (1 + $xnbp));
997 $line->total_ht = 100;
998 $line->total_tva = 20;
999 $line->total_ttc = 120;
1001 $line->vatrate = 20;
1002 $line->value_unit = 120;
1003 $line->fk_expensereport = 0;
1004 $line->type_fees_code =
'TRA';
1005 $line->fk_c_type_fees = $type_fees_id;
1007 $line->projet_ref =
'ABC';
1009 $this->lines[$xnbp] = $line;
1012 $this->total_ht += $line->total_ht;
1013 $this->total_tva += $line->total_tva;
1014 $this->total_ttc += $line->total_ttc;
1033 $langs->load(
'trips');
1035 if ($user->hasRight(
'expensereport',
'lire')) {
1036 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
1037 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
1038 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
1040 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1041 $result = $this->db->query($sql);
1043 $num = $this->db->num_rows($result);
1049 $objp = $this->db->fetch_object($result);
1051 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
1052 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
1053 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
1055 $result2 = $this->db->query($sql2);
1056 $obj = $this->db->fetch_object($result2);
1058 $objp->fk_user_author = $obj->fk_user_author;
1059 $objp->ref = $obj->ref;
1060 $objp->fk_c_expensereport_status = $obj->status;
1061 $objp->rowid = $obj->rowid;
1063 $total_HT += $objp->total_ht;
1064 $total_TTC += $objp->total_ttc;
1065 $author =
new User($this->db);
1066 $author->fetch($objp->fk_user_author);
1070 print
'<a href="'.dolBuildUrl(DOL_URL_ROOT.
'/expensereport/card.php', [
'id' => $objp->rowid]).
'">'.$objp->ref_num.
'</a>';
1072 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
1073 print
'<td>'.$author->getNomUrl(1).
'</td>';
1074 print
'<td>'.$objp->comments.
'</td>';
1075 print
'<td class="right">'.price($objp->total_ht).
'</td>';
1076 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
1077 print
'<td class="right">';
1079 switch ($objp->fk_c_expensereport_status) {
1081 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
1084 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
1087 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
1090 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
1093 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
1110 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
1111 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
1112 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
1113 print
'<td> </td>';
1116 $this->error = $this->db->lasterror();
1133 $this->lines = array();
1135 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1136 $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,";
1137 $sql .=
' de.tva_tx, de.vat_src_code,';
1138 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1139 $sql .=
' de.fk_ecm_files,';
1140 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1141 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1142 $sql .=
' ctf.code as code_type_fees, ctf.label as label_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1143 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1144 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->db->sanitize($this->table_element_line).
' as de';
1145 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1146 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1147 $sql .=
" WHERE de.".$this->db->sanitize($this->fk_element).
" = ".((int) $this->
id);
1149 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1151 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1154 $resql = $this->db->query($sql);
1156 $num = $this->db->num_rows($resql);
1159 $objp = $this->db->fetch_object($resql);
1163 $deplig->rowid = $objp->rowid;
1164 $deplig->id = $objp->rowid;
1165 $deplig->comments = $objp->comments;
1166 $deplig->qty = $objp->qty;
1167 $deplig->value_unit = $objp->value_unit;
1168 $deplig->date = $objp->date;
1169 $deplig->dates = $this->db->jdate($objp->date);
1171 $deplig->fk_expensereport = $objp->fk_expensereport;
1172 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1173 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1174 $deplig->fk_projet = $objp->fk_project;
1175 $deplig->fk_project = $objp->fk_project;
1176 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1178 $deplig->total_ht = $objp->total_ht;
1179 $deplig->total_tva = $objp->total_tva;
1180 $deplig->total_ttc = $objp->total_ttc;
1181 $deplig->total_localtax1 = $objp->total_localtax1;
1182 $deplig->total_localtax2 = $objp->total_localtax2;
1184 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1185 $deplig->type_fees_libelle = $objp->label_type_fees;
1186 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1188 $deplig->tva_tx = $objp->tva_tx;
1189 $deplig->vatrate = $objp->tva_tx;
1190 $deplig->vat_src_code = $objp->vat_src_code;
1191 $deplig->localtax1_tx = $objp->localtax1_tx;
1192 $deplig->localtax2_tx = $objp->localtax2_tx;
1193 $deplig->localtax1_type = $objp->localtax1_type;
1194 $deplig->localtax2_type = $objp->localtax2_type;
1196 $deplig->projet_ref = $objp->ref_projet;
1197 $deplig->projet_title = $objp->title_projet;
1199 $deplig->rule_warning_message = $objp->rule_warning_message;
1201 $deplig->rang = $objp->rang;
1203 $this->lines[$i] = $deplig;
1207 $this->db->free($resql);
1210 $this->error = $this->db->lasterror();
1211 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1224 public function delete($user =
null, $notrigger = 0)
1227 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1232 $sql =
"SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX.
"payment_expensereport WHERE fk_expensereport = ".((int) $this->
id);
1233 $resql = $this->db->query($sql);
1235 $this->error = $this->db->lasterror();
1238 $obj = $this->db->fetch_object($resql);
1239 if ($obj && $obj->nb > 0) {
1240 $this->error =
'ErrorRecordHasChildren';
1248 $result = $this->call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1256 if (!$error && !empty($this->table_element_line)) {
1257 $tabletodelete = $this->table_element_line;
1259 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1260 if (!$this->db->query($sql)) {
1262 $this->error = $this->db->lasterror();
1263 $this->errors[] = $this->error;
1264 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1289 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1295 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1296 $res = $this->db->query($sql);
1299 $this->error = $this->db->lasterror();
1300 $this->errors[] = $this->error;
1301 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1317 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1318 $dir =
$conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1319 $file = $dir.
"/".$ref.
".pdf";
1320 if (file_exists($file)) {
1324 $this->error =
'ErrorFailToDeleteFile';
1325 $this->errors[] = $this->error;
1326 $this->db->rollback();
1330 if (file_exists($dir)) {
1333 $this->error =
'ErrorFailToDeleteDir';
1334 $this->errors[] = $this->error;
1335 $this->db->rollback();
1343 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1344 $this->db->commit();
1347 $this->db->rollback();
1361 global
$conf, $langs, $user;
1367 if ($this->
status == self::STATUS_VALIDATED) {
1368 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
1372 $this->date_valid = $now;
1375 if (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) {
1380 if (empty($num) || $num < 0) {
1389 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1390 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1391 $sql .=
" fk_statut = ".((int) self::STATUS_VALIDATED).
",";
1392 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1393 $sql .=
" fk_user_valid = ".((int) $user->id);
1394 $sql .=
" WHERE rowid = ".((int) $this->
id);
1396 $resql = $this->db->query($sql);
1400 $result = $this->call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1408 $this->oldref = $this->ref;
1411 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1412 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1415 $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).
"'";
1416 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1417 $resql = $this->db->query($sql);
1420 $this->error = $this->db->lasterror();
1422 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1423 $sql .=
" WHERE filepath = 'expensereport/".$this->db->escape($this->
ref).
"' and entity = ".((int)
$conf->entity);
1424 $resql = $this->db->query($sql);
1427 $this->error = $this->db->lasterror();
1433 $dirsource =
$conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1434 $dirdest =
$conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1435 if (!$error && file_exists($dirsource)) {
1436 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1438 if (@rename($dirsource, $dirdest)) {
1441 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1442 foreach ($listoffiles as $fileentry) {
1443 $dirsource = $fileentry[
'name'];
1444 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1445 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1446 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1447 @rename($dirsource, $dirdest);
1460 if (empty($error)) {
1461 $this->db->commit();
1464 $this->db->rollback();
1465 $this->error = $this->db->error();
1469 $this->db->rollback();
1470 $this->error = $this->db->lasterror();
1486 $sql =
'SELECT date_debut';
1487 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1488 $sql .=
" WHERE rowid = ".((int) $this->
id);
1490 $result = $this->db->query($sql);
1492 $objp = $this->db->fetch_object($result);
1494 $this->date_debut = $this->db->jdate($objp->date_debut);
1496 if ($this->
status != self::STATUS_VALIDATED) {
1497 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1498 $sql .=
" SET fk_statut = ".((int) self::STATUS_VALIDATED);
1499 $sql .=
" WHERE rowid = ".((int) $this->
id);
1501 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1503 if ($this->db->query($sql)) {
1506 $this->error = $this->db->lasterror();
1510 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1528 if ($this->
status != self::STATUS_APPROVED) {
1530 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1531 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".((int) self::STATUS_APPROVED).
", fk_user_approve = ".((int) $fuser->id).
",";
1532 $sql .=
" date_approve='".$this->db->idate($now).
"'";
1533 $sql .=
" WHERE rowid = ".((int) $this->
id);
1534 if ($this->db->query($sql)) {
1536 $this->date_approve = $now;
1537 $this->fk_user_approve = $fuser->id;
1540 $result = $this->call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1548 if (empty($error)) {
1549 $this->db->commit();
1552 $this->db->rollback();
1553 $this->error = $this->db->error();
1557 $this->db->rollback();
1558 $this->error = $this->db->lasterror();
1562 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1576 public function setDeny($fuser, $details, $notrigger = 0)
1582 if ($this->
status != self::STATUS_REFUSED) {
1583 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1584 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1585 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1586 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1587 $sql .=
" fk_user_approve = NULL";
1588 $sql .=
" WHERE rowid = ".((int) $this->
id);
1589 if ($this->db->query($sql)) {
1590 $this->fk_statut = 99;
1592 $this->fk_user_refuse = $fuser->id;
1593 $this->detail_refuse = $details;
1594 $this->date_refuse = $now;
1598 $result = $this->call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1606 if (empty($error)) {
1607 $this->db->commit();
1610 $this->db->rollback();
1611 $this->error = $this->db->error();
1615 $this->db->rollback();
1616 $this->error = $this->db->lasterror();
1620 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1639 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1640 return $this->
setUnpaid($fuser, $notrigger);
1657 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1658 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1659 $sql .=
" WHERE rowid = ".((int) $this->
id);
1661 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1663 if ($this->db->query($sql)) {
1666 $result = $this->call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1674 if (empty($error)) {
1675 $this->db->commit();
1678 $this->db->rollback();
1679 $this->error = $this->db->error();
1683 $this->db->rollback();
1684 $this->error = $this->db->error();
1688 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1707 $this->date_cancel =
dol_now();
1708 if ($this->
status != self::STATUS_CANCELED) {
1711 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1712 $sql .=
" SET fk_statut = ".((int) self::STATUS_CANCELED).
", fk_user_cancel = ".((int) $fuser->id);
1713 $sql .=
", date_cancel = '".$this->db->idate($this->date_cancel).
"'";
1714 $sql .=
", detail_cancel = '".$this->db->escape($detail).
"'";
1715 $sql .=
" WHERE rowid = ".((int) $this->
id);
1717 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1719 if ($this->db->query($sql)) {
1722 $result = $this->call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1730 if (empty($error)) {
1731 $this->db->commit();
1734 $this->db->rollback();
1735 $this->error = $this->db->error();
1739 $this->db->rollback();
1740 $this->error = $this->db->error();
1744 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1756 global $langs,
$conf;
1757 $langs->load(
"trips");
1766 $dirmodels = array_merge(array(
'/'), (array)
$conf->modules_parts[
'models']);
1767 foreach ($dirmodels as $reldir) {
1768 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1771 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1779 $obj =
new $classname();
1780 '@phan-var-force ModeleNumRefExpenseReport $obj';
1781 $numref = $obj->getNextValue($this);
1783 if ($numref !=
"") {
1786 $this->error = $obj->error;
1787 $this->errors = $obj->errors;
1792 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1805 global
$conf, $langs;
1807 $langs->load(
'trips');
1809 $nofetch = !empty($params[
'nofetch']);
1810 $moretitle = $params[
'moretitle'] ??
'';
1813 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1814 if (isset($this->
status)) {
1815 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1818 $datas[
'picto'] .=
' - '.$moretitle;
1820 if (!empty($this->
ref)) {
1821 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1823 if (!empty($this->total_ht)) {
1824 $datas[
'total_ht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1,
$conf->currency);
1826 if (!empty($this->total_tva)) {
1827 $datas[
'total_tva'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1,
$conf->currency);
1829 if (!empty($this->total_ttc)) {
1830 $datas[
'total_ttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1,
$conf->currency);
1848 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1850 global $langs, $hookmanager;
1854 $baseurl = DOL_URL_ROOT.
'/expensereport/card.php';
1855 $query = [
'id' => $this->id];
1863 'objecttype' => $this->element,
1864 'option' => $option,
1865 'moretitle' => $moretitle,
1868 $classfortooltip =
'classfortooltip';
1871 $classfortooltip =
'classforajaxtooltip';
1872 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1878 if ($option !=
'nolink') {
1880 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1881 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1882 $add_save_lastsearch_values = 1;
1884 if ($add_save_lastsearch_values) {
1885 $query += [
'save_lastsearch_values' => 1];
1896 if (empty($notooltip)) {
1898 $label = $langs->trans(
"ShowExpenseReport");
1899 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
1901 $linkclose .= ($label ?
' title="'.dolPrintHTMLForAttribute($label).
'"' :
' title="tocomplete"');
1902 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
1905 $linkstart =
'<a href="'.$url.
'"';
1906 $linkstart .= $linkclose.
'>';
1909 $result .= $linkstart;
1911 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
1913 if ($withpicto != 2) {
1914 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1916 $result .= $linkend;
1919 $hookmanager->initHooks(array($this->element .
'dao'));
1920 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
1921 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1923 $result = $hookmanager->resPrint;
1925 $result .= $hookmanager->resPrint;
1941 $this->total_ht += (float) $ligne_total_ht;
1942 $this->total_tva += (float) $ligne_total_tva;
1943 $this->total_ttc += $this->total_tva;
1945 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1946 $sql .=
" total_ht = ".((float) $this->total_ht);
1947 $sql .=
" , total_ttc = ".((float) $this->total_ttc);
1948 $sql .=
" , total_tva = ".((float) $this->total_tva);
1949 $sql .=
" WHERE rowid = ".((int) $this->
id);
1951 $result = $this->db->query($sql);
1955 $this->error = $this->db->error();
1975 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)
1979 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);
1981 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
1985 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1986 $fk_c_type_fees = 0;
1988 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1989 $fk_c_exp_tax_cat = 0;
1991 if (empty($vatrate) || $vatrate < 0) {
1997 if (empty($fk_project)) {
2002 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
2013 $seller->tva_assuj = 1;
2014 $buyer =
new Societe($this->db);
2020 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
2021 $vat_src_code = $reg[1];
2022 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2024 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2026 $tmp =
calcul_price_total($qty, (
float) $up, 0, (
float)
price2num($vatrate), -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2028 $this->line->value_unit = $up;
2030 $this->line->vat_src_code = $vat_src_code;
2031 $this->line->vatrate =
price2num($vatrate);
2032 $this->line->localtax1_tx = $localtaxes_type[1];
2033 $this->line->localtax2_tx = $localtaxes_type[3];
2034 $this->line->localtax1_type = $localtaxes_type[0];
2035 $this->line->localtax2_type = $localtaxes_type[2];
2037 $this->line->total_ttc = (float) $tmp[2];
2038 $this->line->total_ht = (float) $tmp[0];
2039 $this->line->total_tva = (float) $tmp[1];
2040 $this->line->total_localtax1 = (float) $tmp[9];
2041 $this->line->total_localtax2 = (float) $tmp[10];
2043 $this->line->fk_expensereport = $this->id;
2044 $this->line->qty = $qty;
2045 $this->line->date = $date;
2046 $this->line->fk_c_type_fees = $fk_c_type_fees;
2047 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2048 $this->line->comments = $comments;
2049 $this->line->fk_projet = $fk_project;
2050 $this->line->fk_project = $fk_project;
2052 $this->line->fk_ecm_files = $fk_ecm_files;
2057 $result = $this->line->insert(0,
true);
2061 $this->db->commit();
2062 return $this->line->id;
2064 $this->db->rollback();
2068 $this->error = $this->line->error;
2069 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
2070 $this->db->rollback();
2074 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
2075 $this->error =
'ErrorExpenseNotDraftAndNotRefused';
2091 $langs->load(
'trips');
2094 if (!is_object($seller)) {
2096 $seller->tva_assuj = 1;
2100 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
2103 $rule_warning_message_tab = array();
2105 $current_total_ttc = $this->line->total_ttc;
2106 $new_current_total_ttc = $this->line->total_ttc;
2109 foreach ($rulestocheck as $rule) {
2110 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
2111 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
2113 $amount_to_test = $current_total_ttc;
2116 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
2118 if ($amount_to_test > $rule->amount) {
2121 if ($rule->restrictive) {
2122 $this->error =
'ExpenseReportConstraintViolationError';
2123 $this->errors[] = $this->error;
2125 $new_current_total_ttc -= $amount_to_test - $rule->amount;
2126 $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));
2128 $this->error =
'ExpenseReportConstraintViolationWarning';
2129 $this->errors[] = $this->error;
2131 $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));
2138 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
2140 if ($violation > 0) {
2141 $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);
2143 $this->line->value_unit = $tmp[5];
2144 $this->line->total_ttc = (float) $tmp[2];
2145 $this->line->total_ht = (float) $tmp[0];
2146 $this->line->total_tva = (float) $tmp[1];
2147 $this->line->total_localtax1 = (float) $tmp[9];
2148 $this->line->total_localtax2 = (float) $tmp[10];
2171 $userauthor =
new User($this->db);
2172 if ($userauthor->fetch($this->fk_user_author) <= 0) {
2173 $this->error =
'ErrorCantFetchUser';
2174 $this->errors[] =
'ErrorCantFetchUser';
2179 if (!is_object($seller)) {
2181 $seller->tva_assuj = 1;
2185 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2187 if (empty($range)) {
2188 $this->error =
'ErrorNoRangeAvailable';
2189 $this->errors[] =
'ErrorNoRangeAvailable';
2194 $ikoffset = $range->ikoffset;
2196 $ikoffset = $range->ikoffset / 12;
2201 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2202 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2204 $this->line->value_unit = $tmp[5];
2205 $this->line->total_ttc = (float) $tmp[2];
2206 $this->line->total_ht = (float) $tmp[0];
2207 $this->line->total_tva = (float) $tmp[1];
2208 $this->line->total_localtax1 = (float) $tmp[9];
2209 $this->line->total_localtax2 = (float) $tmp[10];
2224 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2225 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2226 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2227 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2228 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2229 if (!empty($this->line->id)) {
2230 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2233 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2234 $resql = $this->db->query($sql);
2236 $num = $this->db->num_rows($resql);
2264 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)
2269 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
2273 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
2281 $seller->tva_assuj = 1;
2282 $seller->localtax1_assuj =
$mysoc->localtax1_assuj;
2283 $seller->localtax2_assuj =
$mysoc->localtax1_assuj;
2284 $buyer =
new Societe($this->db);
2291 if (preg_match(
'/\((.*)\)/', (
string) $vatrate, $reg)) {
2292 $vat_src_code = $reg[1];
2293 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', (
string) $vatrate);
2295 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2297 $tmp =
calcul_price_total($qty, $value_unit, 0, (
float)
price2num($vatrate), -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2301 $tx_tva = 1 + (float) $vatrate / 100;
2304 $this->line->comments = $comments;
2305 $this->line->qty = $qty;
2306 $this->line->value_unit = $value_unit;
2307 $this->line->date = $date;
2309 $this->line->fk_expensereport = $expensereport_id;
2310 $this->line->fk_c_type_fees = $type_fees_id;
2311 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2312 $this->line->fk_projet = $projet_id;
2313 $this->line->fk_project = $projet_id;
2315 $this->line->vat_src_code = $vat_src_code;
2316 $this->line->vatrate =
price2num($vatrate);
2317 $this->line->localtax1_tx = $localtaxes_type[1];
2318 $this->line->localtax2_tx = $localtaxes_type[3];
2319 $this->line->localtax1_type = $localtaxes_type[0];
2320 $this->line->localtax2_type = $localtaxes_type[2];
2322 $this->line->total_ttc = (float) $tmp[2];
2323 $this->line->total_ht = (float) $tmp[0];
2324 $this->line->total_tva = (float) $tmp[1];
2325 $this->line->total_localtax1 = (float) $tmp[9];
2326 $this->line->total_localtax2 = (float) $tmp[10];
2328 $this->line->fk_ecm_files = $fk_ecm_files;
2330 $this->line->id = ((int) $rowid);
2333 $sql =
"SELECT c.code as code_type_fees, c.label as label_type_fees";
2334 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2335 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2336 $resql = $this->db->query($sql);
2338 $objp_fees = $this->db->fetch_object($resql);
2339 $this->line->type_fees_code = $objp_fees->code_type_fees;
2340 $this->line->type_fees_libelle = $objp_fees->label_type_fees;
2341 $this->db->free($resql);
2344 if ($projet_id > 0) {
2346 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2347 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2348 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2349 $resql = $this->db->query($sql);
2351 if ($this->db->num_rows($resql) > 0) {
2352 $objp_projet = $this->db->fetch_object($resql);
2353 $this->line->projet_ref = $objp_projet->ref_projet;
2354 $this->line->projet_title = $objp_projet->title_projet;
2356 $this->db->free($resql);
2362 $result = $this->line->update($user, $notrigger);
2368 $this->db->commit();
2371 $this->error = $this->line->error;
2372 $this->errors = $this->line->errors;
2373 $this->db->rollback();
2389 public function deleteLine($rowid, $fuser =
null, $notrigger = 0)
2393 if ($this->
id > 0) {
2395 $sql =
"SELECT rowid FROM ".$this->db->prefix().$this->table_element_line;
2396 $sql .=
" WHERE rowid = ".((int) $rowid).
" AND fk_expensereport = ".((int) $this->
id);
2397 $resql = $this->db->query($sql);
2398 if (!$resql || !$this->db->num_rows($resql)) {
2399 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
2408 $result = $this->call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2415 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2416 $sql .=
' WHERE rowid = '.((int) $rowid);
2418 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2419 $result = $this->db->query($sql);
2421 if (!$result || $error > 0) {
2422 $this->error = $this->db->error();
2423 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2424 $this->db->rollback();
2430 $this->db->commit();
2447 $sql =
"SELECT rowid, date_debut, date_fin";
2448 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2449 $sql .=
" WHERE entity = ".((int)
$conf->entity);
2450 $sql .=
" AND fk_user_author = ".((int) $fuser->id);
2451 $sql .=
" AND (date_fin >= '".$this->db->idate($startDate).
"' AND date_debut <= '".$this->db->idate($endDate).
"')";
2453 $row = $this->db->getRow($sql);
2455 if ($row ===
false) {
2456 $this->error = $this->db->lasterror();
2457 dol_syslog(__CLASS__.
"::". __METHOD__.
" Error ".$this->error, LOG_ERR);
2461 return $row->rowid ?? 0;
2475 $users_validator = array();
2477 $sql =
"SELECT DISTINCT ur.fk_user";
2478 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2479 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2481 $sql .=
" SELECT DISTINCT ugu.fk_user";
2482 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2483 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2486 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2487 $result = $this->db->query($sql);
2489 $num_rows = $this->db->num_rows($result);
2491 while ($i < $num_rows) {
2492 $objp = $this->db->fetch_object($result);
2493 array_push($users_validator, $objp->fk_user);
2496 return $users_validator;
2498 $this->error = $this->db->lasterror();
2499 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2515 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2517 $outputlangs->load(
"trips");
2520 if (!empty($this->model_pdf)) {
2521 $modele = $this->model_pdf;
2527 if (!empty($modele)) {
2528 $modelpath =
"core/modules/expensereport/doc/";
2530 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2546 $sql =
"SELECT id, code, label";
2547 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2548 $sql .=
" WHERE active = ".((int) $active);
2549 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2550 $result = $this->db->query($sql);
2552 $num = $this->db->num_rows($result);
2555 $obj = $this->db->fetch_object($result);
2556 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2574 $this->nb = array();
2576 $sql =
"SELECT count(ex.rowid) as nb";
2577 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2578 $sql .=
" WHERE ex.fk_statut > 0";
2579 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2580 if (!$user->hasRight(
'expensereport',
'readall')) {
2581 $userchildids = $user->getAllChildIds(1);
2582 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2583 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2586 $resql = $this->db->query($sql);
2588 while ($obj = $this->db->fetch_object($resql)) {
2589 $this->nb[
"expensereports"] = $obj->nb;
2591 $this->db->free($resql);
2595 $this->error = $this->db->error();
2611 global
$conf, $langs;
2619 $sql =
"SELECT ex.rowid, ex.date_valid";
2620 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2621 if ($option ==
'toapprove') {
2622 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2624 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2626 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2627 if (!$user->hasRight(
'expensereport',
'readall')) {
2628 $userchildids = $user->getAllChildIds(1);
2629 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(implode(
',', $userchildids)).
")";
2630 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(implode(
',', $userchildids)).
"))";
2633 $resql = $this->db->query($sql);
2635 $langs->load(
"trips");
2638 if ($option ==
'toapprove') {
2639 $response->warning_delay =
$conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2640 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2641 $response->labelShort = $langs->trans(
"ToApprove");
2642 $response->url =
dolBuildUrl(DOL_URL_ROOT.
'/expensereport/list.php', [
'mainmenu' =>
'hrm',
'statut' => self::STATUS_VALIDATED]);
2644 $response->warning_delay =
$conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2645 $response->label = $langs->trans(
"ExpenseReportsToPay");
2646 $response->labelShort = $langs->trans(
"StatusToPay");
2647 $response->url =
dolBuildUrl(DOL_URL_ROOT.
'/expensereport/list.php', [
'mainmenu' =>
'hrm',
'statut' => self::STATUS_APPROVED]);
2651 while ($obj = $this->db->fetch_object($resql)) {
2652 $response->nbtodo++;
2654 if ($option ==
'toapprove') {
2655 if ($this->db->jdate($obj->date_valid) < ($now -
$conf->expensereport->approve->warning_delay)) {
2656 $response->nbtodolate++;
2659 if ($this->db->jdate($obj->date_valid) < ($now -
$conf->expensereport->payment->warning_delay)) {
2660 $response->nbtodolate++;
2668 $this->error = $this->db->error();
2684 if ($option ==
'toapprove' && $this->
status != 2) {
2687 if ($option ==
'topay' && $this->
status != 5) {
2692 $warning_delay = (int) ($option ==
'toapprove' ?
$conf->expensereport->approve->warning_delay :
$conf->expensereport->payment->warning_delay);
2693 if ($warning_delay <= 0) {
2697 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $warning_delay);
2708 $alreadydispatched = 0;
2710 $type =
'expense_report';
2712 $sql =
" SELECT ".($mode ?
'DISTINCT piece_num' :
'COUNT(ab.rowid)').
" as nb";
2713 $sql .=
" FROM ".MAIN_DB_PREFIX.
"accounting_bookkeeping as ab WHERE ab.doc_type = '".$this->db->escape($type).
"' AND ab.fk_doc = ".((int) $this->
id);
2714 $resql = $this->db->query($sql);
2716 $obj = $this->db->fetch_object($resql);
2718 $alreadydispatched = $obj->nb;
2721 $this->error = $this->db->lasterror();
2725 if ($alreadydispatched) {
2726 return $alreadydispatched;
2738 $table =
'payment_expensereport';
2739 $field =
'fk_expensereport';
2741 $sql =
'SELECT sum(amount) as amount';
2742 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2743 $sql .=
" WHERE ".$this->db->sanitize($field).
" = ".((int) $this->
id);
2745 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2746 $resql = $this->db->query($sql);
2748 $obj = $this->db->fetch_object($resql);
2749 $this->db->free($resql);
2750 return (empty($obj->amount) ? 0 : $obj->amount);
2752 $this->error = $this->db->lasterror();
2767 global $langs,
$conf;
2775 $this->error = $langs->trans(
'ErrorBadParameterCat');
2780 $this->error = $langs->trans(
'ErrorBadParameterQty');
2784 $currentUser =
new User($this->db);
2785 $currentUser->fetch($this->fk_user);
2786 $currentUser->loadRights(
'expensereport');
2790 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2791 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2792 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2793 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2794 $sql .=
" ORDER BY r.range_ik ASC";
2796 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2798 $result = $this->db->query($sql);
2801 if (
getDolGlobalInt(
'EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR')) {
2803 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2804 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2805 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2806 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2807 $sql .=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2808 $sql .=
" AND tf.code = 'EX_KME' ";
2811 $resql = $this->db->query($sql);
2814 $obj = $this->db->fetch_object($resql);
2815 $cumulYearQty = $obj->cumul;
2818 $qty += (float) $cumulYearQty;
2821 $num = $this->db->num_rows($result);
2824 for ($i = 0; $i < $num; $i++) {
2825 $obj = $this->db->fetch_object($result);
2829 '@phan-var-force Object[] $ranges';
2831 for ($i = 0; $i < $num; $i++) {
2832 if ($i < ($num - 1)) {
2834 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i + 1]->range_ik) {
2835 $coef = $ranges[$i]->coef;
2836 $offset = $ranges[$i]->ikoffset;
2839 if ($qty > $ranges[$i]->range_ik) {
2840 $coef = $ranges[$i]->coef;
2841 $offset = $ranges[$i]->ikoffset;
2848 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2852 $this->error = $this->db->error().
" sql=".$sql;
2869 if ($arraydata ===
null) {
2870 $arraydata = array();
2873 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2875 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2876 $return .=
'<div class="info-box info-box-sm">';
2877 $return .=
'<span class="info-box-icon bg-infobox-action">';
2879 $return .=
'</span>';
2880 $return .=
'<div class="info-box-content">';
2881 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->
getNomUrl(1) .
'</span>';
2882 if ($selected >= 0) {
2883 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2885 if (array_key_exists(
'userauthor', $arraydata) && $arraydata[
'userauthor'] instanceof
User) {
2886 $return .=
'<br><span class="info-box-label">'.$arraydata[
'userauthor']->getNomUrl(-1).
'</span>';
2889 $return .=
'<br><span class="info-box-label">'.dol_print_date($this->date_debut,
'day').
'</span>';
2890 $return .=
' <span class="opacitymedium">'.$langs->trans(
"To").
'</span> ';
2891 $return .=
'<span class="info-box-label">'.dol_print_date($this->date_fin,
'day').
'</span>';
2893 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
2894 $return .=
'</div>';
2895 $return .=
'</div>';
2896 $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
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.
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)
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.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
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_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, $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.