28require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
29require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
30require_once DOL_DOCUMENT_ROOT.
'/expensereport/class/expensereport_ik.class.php';
31require_once DOL_DOCUMENT_ROOT.
'/expensereport/class/expensereport_rule.class.php';
41 public $element =
'expensereport';
46 public $table_element =
'expensereport';
51 public $table_element_line =
'expensereport_det';
56 public $fk_element =
'fk_expensereport';
61 public $picto =
'trip';
66 public $lines = array();
92 public $fk_c_paiement;
93 public $modepaymentid;
97 public $user_author_infos;
98 public $user_validator_infos;
100 public $rule_warning_message;
110 public $fk_user_creat;
115 public $fk_user_author;
119 public $fk_user_modif;
123 public $detail_refuse;
124 public $fk_user_refuse;
128 public $detail_cancel;
133 public $fk_user_cancel;
138 public $fk_user_validator;
157 public $fk_user_valid;
158 public $user_valid_infos;
161 public $date_approve;
162 public $fk_user_approve;
165 public $user_paid_infos;
170 public $statuts = array();
171 public $statuts_short = array();
172 public $statuts_logo;
178 public $fk_multicurrency;
183 public $multicurrency_code;
184 public $multicurrency_tx;
185 public $multicurrency_total_ht;
186 public $multicurrency_total_tva;
187 public $multicurrency_total_ttc;
220 public $fields = array(
221 'rowid' =>array(
'type'=>
'integer',
'label'=>
'ID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
222 'ref' =>array(
'type'=>
'varchar(50)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'showoncombobox'=>1,
'position'=>15),
223 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>20),
224 'ref_number_int' =>array(
'type'=>
'integer',
'label'=>
'Ref number int',
'enabled'=>1,
'visible'=>-1,
'position'=>25),
225 'ref_ext' =>array(
'type'=>
'integer',
'label'=>
'Ref ext',
'enabled'=>1,
'visible'=>-1,
'position'=>30),
226 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total ht',
'enabled'=>1,
'visible'=>-1,
'position'=>35),
227 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total tva',
'enabled'=>1,
'visible'=>-1,
'position'=>40),
228 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax1',
'enabled'=>1,
'visible'=>-1,
'position'=>45),
229 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax2',
'enabled'=>1,
'visible'=>-1,
'position'=>50),
230 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total ttc',
'enabled'=>1,
'visible'=>-1,
'position'=>55),
231 'date_debut' =>array(
'type'=>
'date',
'label'=>
'Date debut',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>60),
232 'date_fin' =>array(
'type'=>
'date',
'label'=>
'Date fin',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>65),
233 'date_valid' =>array(
'type'=>
'datetime',
'label'=>
'Date valid',
'enabled'=>1,
'visible'=>-1,
'position'=>75),
234 'date_approve' =>array(
'type'=>
'datetime',
'label'=>
'Date approve',
'enabled'=>1,
'visible'=>-1,
'position'=>80),
235 'date_refuse' =>array(
'type'=>
'datetime',
'label'=>
'Date refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>85),
236 'date_cancel' =>array(
'type'=>
'datetime',
'label'=>
'Date cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>90),
237 'fk_user_author' =>array(
'type'=>
'integer',
'label'=>
'Fk user author',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>100),
238 'fk_user_modif' =>array(
'type'=>
'integer',
'label'=>
'Fk user modif',
'enabled'=>1,
'visible'=>-1,
'position'=>105),
239 'fk_user_valid' =>array(
'type'=>
'integer',
'label'=>
'Fk user valid',
'enabled'=>1,
'visible'=>-1,
'position'=>110),
240 'fk_user_validator' =>array(
'type'=>
'integer',
'label'=>
'Fk user validator',
'enabled'=>1,
'visible'=>-1,
'position'=>115),
241 'fk_user_approve' =>array(
'type'=>
'integer',
'label'=>
'Fk user approve',
'enabled'=>1,
'visible'=>-1,
'position'=>120),
242 'fk_user_refuse' =>array(
'type'=>
'integer',
'label'=>
'Fk user refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>125),
243 'fk_user_cancel' =>array(
'type'=>
'integer',
'label'=>
'Fk user cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>130),
244 'fk_c_paiement' =>array(
'type'=>
'integer',
'label'=>
'Fk c paiement',
'enabled'=>1,
'visible'=>-1,
'position'=>140),
245 'paid' =>array(
'type'=>
'integer',
'label'=>
'Paid',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>145),
246 'note_public' =>array(
'type'=>
'html',
'label'=>
'Note public',
'enabled'=>1,
'visible'=>0,
'position'=>150),
247 'note_private' =>array(
'type'=>
'html',
'label'=>
'Note private',
'enabled'=>1,
'visible'=>0,
'position'=>155),
248 'detail_refuse' =>array(
'type'=>
'varchar(255)',
'label'=>
'Detail refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>160),
249 'detail_cancel' =>array(
'type'=>
'varchar(255)',
'label'=>
'Detail cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>165),
250 'integration_compta' =>array(
'type'=>
'integer',
'label'=>
'Integration compta',
'enabled'=>1,
'visible'=>-1,
'position'=>170),
251 'fk_bank_account' =>array(
'type'=>
'integer',
'label'=>
'Fk bank account',
'enabled'=>1,
'visible'=>-1,
'position'=>175),
252 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'Fk multicurrency',
'enabled'=>1,
'visible'=>-1,
'position'=>185),
253 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'Multicurrency code',
'enabled'=>1,
'visible'=>-1,
'position'=>190),
254 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency tx',
'enabled'=>1,
'visible'=>-1,
'position'=>195),
255 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total ht',
'enabled'=>1,
'visible'=>-1,
'position'=>200),
256 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total tva',
'enabled'=>1,
'visible'=>-1,
'position'=>205),
257 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total ttc',
'enabled'=>1,
'visible'=>-1,
'position'=>210),
258 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>220),
259 'date_create' =>array(
'type'=>
'datetime',
'label'=>
'Date create',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>300),
260 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'Tms',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>305),
261 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-1,
'position'=>1000),
262 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'Model pdf',
'enabled'=>1,
'visible'=>0,
'position'=>1010),
263 'fk_statut' =>array(
'type'=>
'integer',
'label'=>
'Fk statut',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>500),
275 $this->total_ttc = 0;
276 $this->total_tva = 0;
277 $this->total_localtax1 = 0;
278 $this->total_localtax2 = 0;
279 $this->localtax1 = 0;
280 $this->localtax2 = 0;
281 $this->modepaymentid = 0;
284 $this->statuts_short = array(0 =>
'Draft', 2 =>
'Validated', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
285 $this->statuts = array(0 =>
'Draft', 2 =>
'ValidatedWaitingApproval', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
286 $this->statuts_logo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
296 public function create($user, $notrigger = 0)
298 global $conf, $langs;
305 if (empty($this->date_debut) || empty($this->date_fin)) {
306 $this->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
'Date'));
310 $fuserid = $this->fk_user_author;
311 if (empty($fuserid)) {
312 $fuserid = $user->id;
317 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
" (";
320 $sql .=
",total_ttc";
321 $sql .=
",total_tva";
322 $sql .=
",date_debut";
324 $sql .=
",date_create";
325 $sql .=
",fk_user_creat";
326 $sql .=
",fk_user_author";
327 $sql .=
",fk_user_validator";
328 $sql .=
",fk_user_approve";
329 $sql .=
",fk_user_modif";
330 $sql .=
",fk_statut";
331 $sql .=
",fk_c_paiement";
333 $sql .=
",note_public";
334 $sql .=
",note_private";
338 $sql .=
", ".price2num($this->total_ht,
'MT');
339 $sql .=
", ".price2num($this->total_ttc,
'MT');
340 $sql .=
", ".price2num($this->total_tva,
'MT');
341 $sql .=
", '".$this->db->idate($this->date_debut).
"'";
342 $sql .=
", '".$this->db->idate($this->date_fin).
"'";
343 $sql .=
", '".$this->db->idate($now).
"'";
344 $sql .=
", ".((int) $user->id);
345 $sql .=
", ".((int) $fuserid);
346 $sql .=
", ".($this->fk_user_validator > 0 ? ((int) $this->fk_user_validator) :
"null");
347 $sql .=
", ".($this->fk_user_approve > 0 ? ((int) $this->fk_user_approve) :
"null");
348 $sql .=
", ".($this->fk_user_modif > 0 ? ((int) $this->fk_user_modif) :
"null");
349 $sql .=
", ".($this->fk_statut > 1 ? ((int) $this->fk_statut) : 0);
350 $sql .=
", ".($this->modepaymentid ? ((int) $this->modepaymentid) :
"null");
352 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
"null");
353 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
"null");
354 $sql .=
", ".((int) $conf->entity);
357 $result = $this->db->query($sql);
359 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
360 $this->
ref =
'(PROV'.$this->id.
')';
362 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
" SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
363 $resql = $this->db->query($sql);
365 $this->error = $this->db->lasterror();
370 if (is_array($this->lines) && count($this->lines) > 0) {
371 foreach ($this->lines as $line) {
374 if (!is_object($line)) {
375 $line = (object) $line;
377 $newndfline->fk_expensereport = $line->fk_expensereport;
378 $newndfline->fk_c_type_fees = $line->fk_c_type_fees;
379 $newndfline->fk_project = $line->fk_project;
380 $newndfline->vatrate = $line->vatrate;
381 $newndfline->vat_src_code = $line->vat_src_code;
382 $newndfline->localtax1_tx = $line->localtax1_tx;
383 $newndfline->localtax2_tx = $line->localtax2_tx;
384 $newndfline->localtax1_type = $line->localtax1_type;
385 $newndfline->localtax2_type = $line->localtax2_type;
386 $newndfline->comments = $line->comments;
387 $newndfline->qty = $line->qty;
388 $newndfline->value_unit = $line->value_unit;
389 $newndfline->total_ht = $line->total_ht;
390 $newndfline->total_ttc = $line->total_ttc;
391 $newndfline->total_tva = $line->total_tva;
392 $newndfline->total_localtax1 = $line->total_localtax1;
393 $newndfline->total_localtax2 = $line->total_localtax2;
394 $newndfline->date = $line->date;
395 $newndfline->rule_warning_message = $line->rule_warning_message;
396 $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat;
397 $newndfline->fk_ecm_files = $line->fk_ecm_files;
402 $newndfline->fk_expensereport = $this->id;
403 $result = $newndfline->insert();
405 $this->error = $newndfline->error;
406 $this->errors = $newndfline->errors;
426 $result = $this->
call_trigger(
'EXPENSE_REPORT_CREATE', $user);
438 $this->db->rollback();
442 $this->db->rollback();
446 dol_syslog(get_class($this).
"::create error ".$this->error, LOG_ERR);
447 $this->db->rollback();
451 $this->error = $this->db->lasterror().
" sql=".$sql;
452 $this->db->rollback();
470 if (empty($fk_user_author)) {
471 $fk_user_author = $user->id;
481 $objFrom = clone $this;
486 $this->fk_statut = 0;
489 $this->fk_user_creat = $user->id;
490 $this->fk_user_author = $fk_user_author;
491 $this->fk_user_valid =
'';
492 $this->date_create =
'';
493 $this->date_creation =
'';
494 $this->date_validation =
'';
497 if (is_array($this->lines) && count($this->lines) > 0) {
498 foreach ($this->lines as $key => $line) {
499 $this->lines[$key]->fk_ecm_files = 0;
504 $this->context[
'createfromclone'] =
'createfromclone';
505 $result = $this->
create($user);
512 if (is_object($hookmanager)) {
513 $parameters = array(
'objFrom'=>$objFrom);
515 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
523 unset($this->context[
'createfromclone']);
530 $this->db->rollback();
544 public function update($user, $notrigger = 0, $userofexpensereport =
null)
551 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
552 $sql .=
" total_ht = ".$this->total_ht;
553 $sql .=
" , total_ttc = ".$this->total_ttc;
554 $sql .=
" , total_tva = ".$this->total_tva;
555 $sql .=
" , date_debut = '".$this->db->idate($this->date_debut).
"'";
556 $sql .=
" , date_fin = '".$this->db->idate($this->date_fin).
"'";
557 if ($userofexpensereport && is_object($userofexpensereport)) {
558 $sql .=
" , fk_user_author = ".($userofexpensereport->id > 0 ? $userofexpensereport->id :
"null");
560 $sql .=
" , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator :
"null");
561 $sql .=
" , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid :
"null");
562 $sql .=
" , fk_user_approve = ".($this->fk_user_approve > 0 ? $this->fk_user_approve :
"null");
563 $sql .=
" , fk_user_modif = ".$user->id;
564 $sql .=
" , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut :
'0');
565 $sql .=
" , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement :
"null");
566 $sql .=
" , note_public = ".(!empty($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"''");
567 $sql .=
" , note_private = ".(!empty($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"''");
568 $sql .=
" , detail_refuse = ".(!empty($this->detail_refuse) ?
"'".$this->db->escape($this->detail_refuse).
"'" :
"''");
569 $sql .=
" WHERE rowid = ".((int) $this->
id);
571 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
572 $result = $this->db->query($sql);
576 $result = $this->
call_trigger(
'EXPENSE_REPORT_MODIFY', $user);
588 $this->db->rollback();
589 $this->error = $this->db->error();
593 $this->db->rollback();
594 $this->error = $this->db->error();
606 public function fetch($id, $ref =
'')
610 $sql =
"SELECT d.rowid, d.entity, d.ref, d.note_public, d.note_private,";
611 $sql .=
" d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,";
612 $sql .=
" d.date_refuse, d.date_cancel,";
613 $sql .=
" d.total_ht, d.total_ttc, d.total_tva,";
614 $sql .=
" d.localtax1 as total_localtax1, d.localtax2 as total_localtax2,";
615 $sql .=
" d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,";
616 $sql .=
" d.fk_user_creat, d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
617 $sql .=
" d.fk_user_valid, d.fk_user_approve,";
618 $sql .=
" d.fk_statut as status, d.fk_c_paiement, d.paid";
619 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as d";
621 $sql .=
" WHERE d.ref = '".$this->db->escape($ref).
"'";
622 $sql .=
" AND d.entity IN (".getEntity(
'expensereport').
")";
624 $sql .=
" WHERE d.rowid = ".((int) $id);
628 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
629 $resql = $this->db->query($sql);
631 $obj = $this->db->fetch_object($resql);
633 $this->
id = $obj->rowid;
634 $this->
ref = $obj->ref;
636 $this->entity = $obj->entity;
638 $this->total_ht = $obj->total_ht;
639 $this->total_tva = $obj->total_tva;
640 $this->total_ttc = $obj->total_ttc;
641 $this->localtax1 = $obj->total_localtax1;
642 $this->localtax2 = $obj->total_localtax2;
643 $this->total_localtax1 = $obj->total_localtax1;
644 $this->total_localtax2 = $obj->total_localtax2;
646 $this->note_public = $obj->note_public;
647 $this->note_private = $obj->note_private;
648 $this->detail_refuse = $obj->detail_refuse;
649 $this->detail_cancel = $obj->detail_cancel;
651 $this->date_debut = $this->db->jdate($obj->date_debut);
652 $this->date_fin = $this->db->jdate($obj->date_fin);
653 $this->date_valid = $this->db->jdate($obj->date_valid);
654 $this->date_approve = $this->db->jdate($obj->date_approve);
655 $this->date_create = $this->db->jdate($obj->date_create);
656 $this->date_modif = $this->db->jdate($obj->date_modif);
657 $this->date_refuse = $this->db->jdate($obj->date_refuse);
658 $this->date_cancel = $this->db->jdate($obj->date_cancel);
660 $this->fk_user_creat = $obj->fk_user_creat;
661 $this->fk_user_author = $obj->fk_user_author;
662 $this->fk_user_modif = $obj->fk_user_modif;
663 $this->fk_user_validator = $obj->fk_user_validator;
664 $this->fk_user_valid = $obj->fk_user_valid;
665 $this->fk_user_refuse = $obj->fk_user_refuse;
666 $this->fk_user_cancel = $obj->fk_user_cancel;
667 $this->fk_user_approve = $obj->fk_user_approve;
669 $user_author =
new User($this->db);
670 if ($this->fk_user_author > 0) {
671 $user_author->fetch($this->fk_user_author);
674 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
676 $user_approver =
new User($this->db);
677 if ($this->fk_user_approve > 0) {
678 $user_approver->fetch($this->fk_user_approve);
679 } elseif ($this->fk_user_validator > 0) {
680 $user_approver->fetch($this->fk_user_validator);
682 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
684 $this->fk_statut = $obj->status;
685 $this->status = $obj->status;
686 $this->fk_c_paiement = $obj->fk_c_paiement;
687 $this->paid = $obj->paid;
689 if ($this->status == self::STATUS_APPROVED || $this->status == self::STATUS_CLOSED) {
690 $user_valid =
new User($this->db);
691 if ($this->fk_user_valid > 0) {
692 $user_valid->fetch($this->fk_user_valid);
694 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
706 $this->error = $this->db->lasterror();
722 public function set_paid($id, $fuser, $notrigger = 0)
725 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
726 return $this->
setPaid($id, $fuser, $notrigger);
737 public function setPaid($id, $fuser, $notrigger = 0)
742 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
743 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid=1";
746 dol_syslog(get_class($this).
"::set_paid", LOG_DEBUG);
747 $resql = $this->db->query($sql);
749 if ($this->db->affected_rows($resql)) {
752 $result = $this->
call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
764 $this->db->rollback();
765 $this->error = $this->db->error();
773 $this->db->rollback();
787 return $this->
LibStatut($this->status, $mode);
803 $labelStatus = $langs->transnoentitiesnoconv($this->statuts[$status]);
804 $labelStatusShort = $langs->transnoentitiesnoconv($this->statuts_short[$status]);
806 $statusType = $this->statuts_logo[$status];
808 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
822 $sql =
"SELECT f.rowid,";
823 $sql .=
" f.date_create as datec,";
824 $sql .=
" f.tms as date_modification,";
825 $sql .=
" f.date_valid as datev,";
826 $sql .=
" f.date_approve as datea,";
827 $sql .=
" f.fk_user_creat as fk_user_creation,";
828 $sql .=
" f.fk_user_author as fk_user_author,";
829 $sql .=
" f.fk_user_modif as fk_user_modification,";
830 $sql .=
" f.fk_user_valid,";
831 $sql .=
" f.fk_user_approve";
832 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
833 $sql .=
" WHERE f.rowid = ".((int) $id);
834 $sql .=
" AND f.entity = ".$conf->entity;
836 $resql = $this->db->query($sql);
838 if ($this->db->num_rows($resql)) {
839 $obj = $this->db->fetch_object($resql);
841 $this->
id = $obj->rowid;
843 $this->date_creation = $this->db->jdate($obj->datec);
844 $this->date_modification = $this->db->jdate($obj->date_modification);
845 $this->date_validation = $this->db->jdate($obj->datev);
846 $this->date_approbation = $this->db->jdate($obj->datea);
848 $cuser =
new User($this->db);
849 $cuser->fetch($obj->fk_user_author);
850 $this->user_creation = $cuser;
852 if ($obj->fk_user_creation) {
853 $cuser =
new User($this->db);
854 $cuser->fetch($obj->fk_user_creation);
855 $this->user_creation = $cuser;
857 if ($obj->fk_user_valid) {
858 $vuser =
new User($this->db);
859 $vuser->fetch($obj->fk_user_valid);
860 $this->user_validation = $vuser;
862 if ($obj->fk_user_modification) {
863 $muser =
new User($this->db);
864 $muser->fetch($obj->fk_user_modification);
865 $this->user_modification = $muser;
867 if ($obj->fk_user_approve) {
868 $auser =
new User($this->db);
869 $auser->fetch($obj->fk_user_approve);
870 $this->user_approve = $auser;
873 $this->db->free($resql);
890 global $user, $langs, $conf;
896 $this->
ref =
'SPECIMEN';
899 $this->date_create = $now;
900 $this->date_debut = $now;
901 $this->date_fin = $now;
902 $this->date_valid = $now;
903 $this->date_approve = $now;
908 $this->fk_statut = 5;
910 $this->fk_user_author = $user->id;
911 $this->fk_user_validator = $user->id;
912 $this->fk_user_valid = $user->id;
913 $this->fk_user_approve = $user->id;
915 $this->note_private =
'Private note';
916 $this->note_public =
'SPECIMEN';
919 while ($xnbp < $nbp) {
921 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
922 $line->date = ($now - 3600 * (1 + $xnbp));
923 $line->total_ht = 100;
924 $line->total_tva = 20;
925 $line->total_ttc = 120;
928 $line->value_unit = 120;
929 $line->fk_expensereport = 0;
930 $line->type_fees_code =
'TRA';
931 $line->fk_c_type_fees = $type_fees_id;
933 $line->projet_ref =
'ABC';
935 $this->lines[$xnbp] = $line;
938 $this->total_ht += $line->total_ht;
939 $this->total_tva += $line->total_tva;
940 $this->total_ttc += $line->total_ttc;
955 global $conf, $db, $langs;
957 $langs->load(
'trips');
959 if ($user->rights->expensereport->lire) {
960 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
961 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
962 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
964 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
965 $result = $this->db->query($sql);
967 $num = $this->db->num_rows($result);
973 $objp = $this->db->fetch_object($result);
975 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
976 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
977 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
979 $result2 = $this->db->query($sql2);
980 $obj = $this->db->fetch_object($result2);
982 $objp->fk_user_author = $obj->fk_user_author;
983 $objp->ref = $obj->ref;
984 $objp->fk_c_expensereport_status = $obj->status;
985 $objp->rowid = $obj->rowid;
987 $total_HT = $total_HT + $objp->total_ht;
988 $total_TTC = $total_TTC + $objp->total_ttc;
989 $author =
new User($this->db);
990 $author->fetch($objp->fk_user_author);
993 print
'<td><a href="'.DOL_URL_ROOT.
'/expensereport/card.php?id='.$objp->rowid.
'">'.$objp->ref_num.
'</a></td>';
994 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
995 print
'<td>'.$author->getNomUrl(1).
'</td>';
996 print
'<td>'.$objp->comments.
'</td>';
997 print
'<td class="right">'.price($objp->total_ht).
'</td>';
998 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
999 print
'<td class="right">';
1001 switch ($objp->fk_c_expensereport_status) {
1003 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
1006 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
1009 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
1012 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
1015 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
1032 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
1033 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
1034 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
1035 print
'<td> </td>';
1038 $this->error = $this->db->lasterror();
1057 $this->lines = array();
1059 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1060 $sql .=
" de.".$this->fk_element.
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1061 $sql .=
' de.tva_tx, de.vat_src_code,';
1062 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1063 $sql .=
' de.fk_ecm_files,';
1064 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1065 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1066 $sql .=
' ctf.code as code_type_fees, ctf.label as libelle_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1067 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1068 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as de';
1069 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1070 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1071 $sql .=
" WHERE de.".$this->fk_element.
" = ".((int) $this->
id);
1072 if (!empty($conf->global->EXPENSEREPORT_LINES_SORTED_BY_ROWID)) {
1073 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1075 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1078 $resql = $this->db->query($sql);
1080 $num = $this->db->num_rows($resql);
1083 $objp = $this->db->fetch_object($resql);
1087 $deplig->rowid = $objp->rowid;
1088 $deplig->id = $objp->rowid;
1089 $deplig->comments = $objp->comments;
1090 $deplig->qty = $objp->qty;
1091 $deplig->value_unit = $objp->value_unit;
1092 $deplig->date = $objp->date;
1093 $deplig->dates = $this->db->jdate($objp->date);
1095 $deplig->fk_expensereport = $objp->fk_expensereport;
1096 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1097 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1098 $deplig->fk_projet = $objp->fk_project;
1099 $deplig->fk_project = $objp->fk_project;
1100 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1102 $deplig->total_ht = $objp->total_ht;
1103 $deplig->total_tva = $objp->total_tva;
1104 $deplig->total_ttc = $objp->total_ttc;
1105 $deplig->total_localtax1 = $objp->total_localtax1;
1106 $deplig->total_localtax2 = $objp->total_localtax2;
1108 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1109 $deplig->type_fees_libelle = $objp->libelle_type_fees;
1110 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1112 $deplig->tva_tx = $objp->tva_tx;
1113 $deplig->vatrate = $objp->tva_tx;
1114 $deplig->vat_src_code = $objp->vat_src_code;
1115 $deplig->localtax1_tx = $objp->localtax1_tx;
1116 $deplig->localtax2_tx = $objp->localtax2_tx;
1117 $deplig->localtax1_type = $objp->localtax1_type;
1118 $deplig->localtax2_type = $objp->localtax2_type;
1120 $deplig->projet_ref = $objp->ref_projet;
1121 $deplig->projet_title = $objp->title_projet;
1123 $deplig->rule_warning_message = $objp->rule_warning_message;
1125 $deplig->rang = $objp->rang;
1127 $this->lines[$i] = $deplig;
1131 $this->db->free($resql);
1134 $this->error = $this->db->lasterror();
1135 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1148 public function delete(
User $user =
null, $notrigger =
false)
1151 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1159 $result = $this->
call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1167 if (!$error && !empty($this->table_element_line)) {
1168 $tabletodelete = $this->table_element_line;
1170 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1171 if (!$this->db->query($sql)) {
1173 $this->error = $this->db->lasterror();
1174 $this->errors[] = $this->error;
1175 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1200 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1206 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1207 $res = $this->db->query($sql);
1210 $this->error = $this->db->lasterror();
1211 $this->errors[] = $this->error;
1212 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1227 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1228 $dir = $conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1229 $file = $dir.
"/".$ref.
".pdf";
1230 if (file_exists($file)) {
1234 $this->error =
'ErrorFailToDeleteFile';
1235 $this->errors[] = $this->error;
1236 $this->db->rollback();
1240 if (file_exists($dir)) {
1243 $this->error =
'ErrorFailToDeleteDir';
1244 $this->errors[] = $this->error;
1245 $this->db->rollback();
1253 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1254 $this->db->commit();
1257 $this->db->rollback();
1271 global $conf, $langs, $user;
1277 if ($this->status == self::STATUS_VALIDATED) {
1278 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1282 $this->date_valid = $now;
1285 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
1290 if (empty($num) || $num < 0) {
1299 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1300 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1301 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1302 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1303 $sql .=
" fk_user_valid = ".((int) $user->id);
1304 $sql .=
" WHERE rowid = ".((int) $this->
id);
1306 $resql = $this->db->query($sql);
1308 if (!$error && !$notrigger) {
1310 $result = $this->
call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1318 $this->oldref = $this->ref;
1321 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1322 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1325 $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).
"'";
1326 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1327 $resql = $this->db->query($sql);
1329 $error++; $this->error = $this->db->lasterror();
1331 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1332 $sql .=
" WHERE filepath = 'expensereport/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
1333 $resql = $this->db->query($sql);
1335 $error++; $this->error = $this->db->lasterror();
1341 $dirsource = $conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1342 $dirdest = $conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1343 if (!$error && file_exists($dirsource)) {
1344 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1346 if (@rename($dirsource, $dirdest)) {
1349 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1350 foreach ($listoffiles as $fileentry) {
1351 $dirsource = $fileentry[
'name'];
1352 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1353 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1354 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1355 @rename($dirsource, $dirdest);
1368 if (empty($error)) {
1369 $this->db->commit();
1372 $this->db->rollback();
1373 $this->error = $this->db->error();
1377 $this->db->rollback();
1378 $this->error = $this->db->lasterror();
1394 $sql =
'SELECT date_debut';
1395 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1396 $sql .=
" WHERE rowid = ".((int) $this->
id);
1398 $result = $this->db->query($sql);
1400 $objp = $this->db->fetch_object($result);
1402 $this->date_debut = $this->db->jdate($objp->date_debut);
1404 if ($this->status != self::STATUS_VALIDATED) {
1405 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1406 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1407 $sql .=
" WHERE rowid = ".((int) $this->
id);
1409 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1411 if ($this->db->query($sql)) {
1414 $this->error = $this->db->lasterror();
1418 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1437 $this->date_approve = $now;
1438 if ($this->status != self::STATUS_APPROVED) {
1441 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1442 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1443 $sql .=
" date_approve='".$this->db->idate($this->date_approve).
"'";
1444 $sql .=
" WHERE rowid = ".((int) $this->
id);
1445 if ($this->db->query($sql)) {
1448 $result = $this->
call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
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();
1470 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1484 public function setDeny($fuser, $details, $notrigger = 0)
1490 if ($this->status != self::STATUS_REFUSED) {
1491 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1492 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1493 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1494 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1495 $sql .=
" fk_user_approve = NULL";
1496 $sql .=
" WHERE rowid = ".((int) $this->
id);
1497 if ($this->db->query($sql)) {
1498 $this->fk_statut = 99;
1500 $this->fk_user_refuse = $fuser->id;
1501 $this->detail_refuse = $details;
1502 $this->date_refuse = $now;
1506 $result = $this->
call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1514 if (empty($error)) {
1515 $this->db->commit();
1518 $this->db->rollback();
1519 $this->error = $this->db->error();
1523 $this->db->rollback();
1524 $this->error = $this->db->lasterror();
1528 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1547 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1548 return $this->
setUnpaid($fuser, $notrigger);
1565 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1566 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1567 $sql .=
" WHERE rowid = ".((int) $this->
id);
1569 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1571 if ($this->db->query($sql)) {
1574 $result = $this->
call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1582 if (empty($error)) {
1583 $this->db->commit();
1586 $this->db->rollback();
1587 $this->error = $this->db->error();
1591 $this->db->rollback();
1592 $this->error = $this->db->error();
1596 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1615 $this->date_cancel = $this->db->idate(
dol_now());
1616 if ($this->status != self::STATUS_CANCELED) {
1619 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1620 $sql .=
" SET fk_statut = ".self::STATUS_CANCELED.
", fk_user_cancel = ".((int) $fuser->id);
1621 $sql .=
", date_cancel='".$this->db->idate($this->date_cancel).
"'";
1622 $sql .=
", detail_cancel='".$this->db->escape($detail).
"'";
1623 $sql .=
" WHERE rowid = ".((int) $this->
id);
1625 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1627 if ($this->db->query($sql)) {
1630 $result = $this->
call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1638 if (empty($error)) {
1639 $this->db->commit();
1642 $this->db->rollback();
1643 $this->error = $this->db->error();
1647 $this->db->rollback();
1648 $this->error = $this->db->error();
1652 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1664 global $langs, $conf;
1665 $langs->load(
"trips");
1667 if (!empty($conf->global->EXPENSEREPORT_ADDON)) {
1670 $file = $conf->global->EXPENSEREPORT_ADDON.
".php";
1671 $classname = $conf->global->EXPENSEREPORT_ADDON;
1674 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1675 foreach ($dirmodels as $reldir) {
1676 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1679 $mybool |= @include_once $dir.$file;
1682 if ($mybool ===
false) {
1687 $obj =
new $classname();
1688 $numref = $obj->getNextValue($this);
1690 if ($numref !=
"") {
1693 $this->error = $obj->error;
1694 $this->errors = $obj->errors;
1699 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1713 global $conf, $langs;
1715 $langs->load(
'expensereport');
1717 $nofetch = !empty($params[
'nofetch']);
1718 $moretitle = $params[
'moretitle'] ??
'';
1721 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1722 if (isset($this->status)) {
1723 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1726 $datas[
'picto'] .=
' - '.$moretitle;
1728 if (!empty($this->
ref)) {
1729 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1731 if (!empty($this->total_ht)) {
1732 $datas[
'total_ht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1734 if (!empty($this->total_tva)) {
1735 $datas[
'total_tva'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1737 if (!empty($this->total_ttc)) {
1738 $datas[
'total_ttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
1756 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1758 global $langs, $conf, $hookmanager;
1762 $url = DOL_URL_ROOT.
'/expensereport/card.php?id='.$this->id;
1770 'objecttype' => $this->element,
1771 'option' => $option,
1772 'moretitle' => $moretitle,
1775 $classfortooltip =
'classfortooltip';
1778 $classfortooltip =
'classforajaxtooltip';
1779 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1785 if ($option !=
'nolink') {
1787 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1788 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1789 $add_save_lastsearch_values = 1;
1791 if ($add_save_lastsearch_values) {
1792 $url .=
'&save_lastsearch_values=1';
1802 if (empty($notooltip)) {
1803 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1804 $label = $langs->trans(
"ShowExpenseReport");
1805 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1807 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
1808 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
1811 $linkstart =
'<a href="'.$url.
'"';
1812 $linkstart .= $linkclose.
'>';
1815 $result .= $linkstart;
1817 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
1819 if ($withpicto != 2) {
1820 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1822 $result .= $linkend;
1825 $hookmanager->initHooks(array($this->element .
'dao'));
1826 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
1827 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1829 $result = $hookmanager->resPrint;
1831 $result .= $hookmanager->resPrint;
1847 $this->total_ht = $this->total_ht + $ligne_total_ht;
1848 $this->total_tva = $this->total_tva + $ligne_total_tva;
1849 $this->total_ttc = $this->total_ht + $this->total_tva;
1851 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1852 $sql .=
" total_ht = ".$this->total_ht;
1853 $sql .=
" , total_ttc = ".$this->total_ttc;
1854 $sql .=
" , total_tva = ".$this->total_tva;
1855 $sql .=
" WHERE rowid = ".((int) $this->
id);
1857 $result = $this->db->query($sql);
1861 $this->error = $this->db->error();
1881 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)
1883 global $conf, $langs, $mysoc;
1885 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);
1887 if ($this->status == self::STATUS_DRAFT) {
1891 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1892 $fk_c_type_fees = 0;
1894 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1895 $fk_c_exp_tax_cat = 0;
1897 if (empty($vatrate) || $vatrate < 0) {
1903 if (empty($fk_project)) {
1908 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1919 $seller->tva_assuj = 1;
1920 $buyer =
new Societe($this->db);
1926 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
1927 $vat_src_code = $reg[1];
1928 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
1930 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
1932 $tmp =
calcul_price_total($qty, $up, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
1934 $this->line->value_unit = $up;
1936 $this->line->vat_src_code = $vat_src_code;
1937 $this->line->vatrate =
price2num($vatrate);
1938 $this->line->localtax1_tx = $localtaxes_type[1];
1939 $this->line->localtax2_tx = $localtaxes_type[3];
1940 $this->line->localtax1_type = $localtaxes_type[0];
1941 $this->line->localtax2_type = $localtaxes_type[2];
1943 $this->line->total_ttc = $tmp[2];
1944 $this->line->total_ht = $tmp[0];
1945 $this->line->total_tva = $tmp[1];
1946 $this->line->total_localtax1 = $tmp[9];
1947 $this->line->total_localtax2 = $tmp[10];
1949 $this->line->fk_expensereport = $this->id;
1950 $this->line->qty = $qty;
1951 $this->line->date = $date;
1952 $this->line->fk_c_type_fees = $fk_c_type_fees;
1953 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
1954 $this->line->comments = $comments;
1955 $this->line->fk_projet = $fk_project;
1956 $this->line->fk_project = $fk_project;
1958 $this->line->fk_ecm_files = $fk_ecm_files;
1963 $result = $this->line->insert(0,
true);
1967 $this->db->commit();
1968 return $this->line->id;
1970 $this->db->rollback();
1974 $this->error = $this->line->error;
1975 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
1976 $this->db->rollback();
1980 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
1981 $this->error =
'ErrorExpenseNotDraft';
1995 global $user, $conf, $db, $langs, $mysoc;
1997 $langs->load(
'trips');
2000 if (!is_object($seller)) {
2002 $seller->tva_assuj = 1;
2006 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
2009 $rule_warning_message_tab = array();
2011 $current_total_ttc = $this->line->total_ttc;
2012 $new_current_total_ttc = $this->line->total_ttc;
2015 foreach ($rulestocheck as $rule) {
2016 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
2017 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
2019 $amount_to_test = $current_total_ttc;
2022 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
2024 if ($amount_to_test > $rule->amount) {
2027 if ($rule->restrictive) {
2028 $this->error =
'ExpenseReportConstraintViolationError';
2029 $this->errors[] = $this->error;
2031 $new_current_total_ttc -= $amount_to_test - $rule->amount;
2032 $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));
2034 $this->error =
'ExpenseReportConstraintViolationWarning';
2035 $this->errors[] = $this->error;
2037 $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));
2044 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
2046 if ($violation > 0) {
2047 $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);
2049 $this->line->value_unit = $tmp[5];
2050 $this->line->total_ttc = $tmp[2];
2051 $this->line->total_ht = $tmp[0];
2052 $this->line->total_tva = $tmp[1];
2053 $this->line->total_localtax1 = $tmp[9];
2054 $this->line->total_localtax2 = $tmp[10];
2071 global $conf, $mysoc;
2073 if (empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2077 $userauthor =
new User($this->db);
2078 if ($userauthor->fetch($this->fk_user_author) <= 0) {
2079 $this->error =
'ErrorCantFetchUser';
2080 $this->errors[] =
'ErrorCantFetchUser';
2085 if (!is_object($seller)) {
2087 $seller->tva_assuj = 1;
2091 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2093 if (empty($range)) {
2094 $this->error =
'ErrorNoRangeAvailable';
2095 $this->errors[] =
'ErrorNoRangeAvailable';
2099 if (!empty($conf->global->MAIN_EXPENSE_APPLY_ENTIRE_OFFSET)) {
2100 $ikoffset = $range->ikoffset;
2102 $ikoffset = $range->ikoffset / 12;
2107 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2108 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2110 $this->line->value_unit = $tmp[5];
2111 $this->line->total_ttc = $tmp[2];
2112 $this->line->total_ht = $tmp[0];
2113 $this->line->total_tva = $tmp[1];
2114 $this->line->total_localtax1 = $tmp[9];
2115 $this->line->total_localtax2 = $tmp[10];
2130 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2131 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2132 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2133 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2134 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2135 if (!empty($this->line->id)) {
2136 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2139 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2140 $resql = $this->db->query($sql);
2142 $num = $this->db->num_rows($resql);
2170 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)
2172 global $user, $mysoc;
2174 if ($this->status == self::STATUS_DRAFT || $this->status == self::STATUS_REFUSED) {
2182 $seller->tva_assuj = 1;
2183 $seller->localtax1_assuj = $mysoc->localtax1_assuj;
2184 $seller->localtax2_assuj = $mysoc->localtax1_assuj;
2185 $buyer =
new Societe($this->db);
2192 if (preg_match(
'/\((.*)\)/', $vatrate, $reg)) {
2193 $vat_src_code = $reg[1];
2194 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2196 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2198 $tmp =
calcul_price_total($qty, $value_unit, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2203 $tx_tva = $vatrate / 100;
2204 $tx_tva = $tx_tva + 1;
2207 $this->line->comments = $comments;
2208 $this->line->qty = $qty;
2209 $this->line->value_unit = $value_unit;
2210 $this->line->date = $date;
2212 $this->line->fk_expensereport = $expensereport_id;
2213 $this->line->fk_c_type_fees = $type_fees_id;
2214 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2215 $this->line->fk_projet = $projet_id;
2216 $this->line->fk_project = $projet_id;
2218 $this->line->vat_src_code = $vat_src_code;
2219 $this->line->vatrate =
price2num($vatrate);
2220 $this->line->localtax1_tx = $localtaxes_type[1];
2221 $this->line->localtax2_tx = $localtaxes_type[3];
2222 $this->line->localtax1_type = $localtaxes_type[0];
2223 $this->line->localtax2_type = $localtaxes_type[2];
2225 $this->line->total_ttc = $tmp[2];
2226 $this->line->total_ht = $tmp[0];
2227 $this->line->total_tva = $tmp[1];
2228 $this->line->total_localtax1 = $tmp[9];
2229 $this->line->total_localtax2 = $tmp[10];
2231 $this->line->fk_ecm_files = $fk_ecm_files;
2233 $this->line->id = ((int) $rowid);
2236 $sql =
"SELECT c.code as code_type_fees, c.label as libelle_type_fees";
2237 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2238 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2239 $resql = $this->db->query($sql);
2241 $objp_fees = $this->db->fetch_object($resql);
2242 $this->line->type_fees_code = $objp_fees->code_type_fees;
2243 $this->line->type_fees_libelle = $objp_fees->libelle_type_fees;
2244 $this->db->free($resql);
2248 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2249 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2250 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2251 $resql = $this->db->query($sql);
2253 $objp_projet = $this->db->fetch_object($resql);
2254 $this->line->projet_ref = $objp_projet->ref_projet;
2255 $this->line->projet_title = $objp_projet->title_projet;
2256 $this->db->free($resql);
2262 $result = $this->line->update($user);
2267 if (!$error && !$notrigger) {
2269 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_MODIFY', $user);
2277 $this->db->commit();
2280 $this->error = $this->line->error;
2281 $this->errors = $this->line->errors;
2282 $this->db->rollback();
2306 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2313 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2314 $sql .=
' WHERE rowid = '.((int) $rowid);
2316 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2317 $result = $this->db->query($sql);
2319 if (!$result || $error > 0 ) {
2320 $this->error = $this->db->error();
2321 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2322 $this->db->rollback();
2328 $this->db->commit();
2347 $sql =
"SELECT rowid, date_debut, date_fin";
2348 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2349 $sql .=
" WHERE entity = ".((int) $conf->entity);
2350 $sql .=
" AND fk_user_author = ".((int) $fuser->id);
2352 dol_syslog(get_class($this).
"::periode_existe sql=".$sql);
2353 $result = $this->db->query($sql);
2355 $num_rows = $this->db->num_rows($result); $i = 0;
2357 if ($num_rows > 0) {
2358 $date_d_form = $date_debut;
2359 $date_f_form = $date_fin;
2361 while ($i < $num_rows) {
2362 $objp = $this->db->fetch_object($result);
2364 $date_d_req = $this->db->jdate($objp->date_debut);
2365 $date_f_req = $this->db->jdate($objp->date_fin);
2367 if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) {
2368 return $objp->rowid;
2379 $this->error = $this->db->lasterror();
2380 dol_syslog(get_class($this).
"::periode_existe Error ".$this->error, LOG_ERR);
2396 $users_validator = array();
2398 $sql =
"SELECT DISTINCT ur.fk_user";
2399 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2400 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2402 $sql .=
" SELECT DISTINCT ugu.fk_user";
2403 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2404 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2407 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2408 $result = $this->db->query($sql);
2410 $num_rows = $this->db->num_rows($result); $i = 0;
2411 while ($i < $num_rows) {
2412 $objp = $this->db->fetch_object($result);
2413 array_push($users_validator, $objp->fk_user);
2416 return $users_validator;
2418 $this->error = $this->db->lasterror();
2419 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2435 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2439 $outputlangs->load(
"trips");
2442 if (!empty($this->model_pdf)) {
2443 $modele = $this->model_pdf;
2444 } elseif (!empty($this->modelpdf)) {
2445 $modele = $this->modelpdf;
2446 } elseif (!empty($conf->global->EXPENSEREPORT_ADDON_PDF)) {
2447 $modele = $conf->global->EXPENSEREPORT_ADDON_PDF;
2451 if (!empty($modele)) {
2452 $modelpath =
"core/modules/expensereport/doc/";
2454 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2470 $sql =
"SELECT id, code, label";
2471 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2472 $sql .=
" WHERE active = ".((int) $active);
2473 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2474 $result = $this->db->query($sql);
2476 $num = $this->db->num_rows($result);
2479 $obj = $this->db->fetch_object($result);
2480 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2498 global $conf, $user;
2500 $this->nb = array();
2502 $sql =
"SELECT count(ex.rowid) as nb";
2503 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2504 $sql .=
" WHERE ex.fk_statut > 0";
2505 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2506 if (empty($user->rights->expensereport->readall)) {
2507 $userchildids = $user->getAllChildIds(1);
2508 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2509 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2512 $resql = $this->db->query($sql);
2514 while ($obj = $this->db->fetch_object($resql)) {
2515 $this->nb[
"expensereports"] = $obj->nb;
2517 $this->db->free($resql);
2521 $this->error = $this->db->error();
2537 global $conf, $langs;
2545 $sql =
"SELECT ex.rowid, ex.date_valid";
2546 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2547 if ($option ==
'toapprove') {
2548 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2550 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2552 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2553 if (empty($user->rights->expensereport->readall)) {
2554 $userchildids = $user->getAllChildIds(1);
2555 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2556 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2559 $resql = $this->db->query($sql);
2561 $langs->load(
"trips");
2564 if ($option ==
'toapprove') {
2565 $response->warning_delay = $conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2566 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2567 $response->labelShort = $langs->trans(
"ToApprove");
2570 $response->warning_delay = $conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2571 $response->label = $langs->trans(
"ExpenseReportsToPay");
2572 $response->labelShort = $langs->trans(
"StatusToPay");
2573 $response->url = DOL_URL_ROOT.
'/expensereport/list.php?mainmenu=hrm&statut='.
self::STATUS_APPROVED;
2577 while ($obj = $this->db->fetch_object($resql)) {
2578 $response->nbtodo++;
2580 if ($option ==
'toapprove') {
2581 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->approve->warning_delay)) {
2582 $response->nbtodolate++;
2585 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->payment->warning_delay)) {
2586 $response->nbtodolate++;
2594 $this->error = $this->db->error();
2610 if ($option ==
'toapprove' && $this->status != 2) {
2613 if ($option ==
'topay' && $this->status != 5) {
2618 if ($option ==
'toapprove') {
2619 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->approve->warning_delay);
2621 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->payment->warning_delay);
2632 $alreadydispatched = 0;
2634 $type =
'expense_report';
2636 $sql =
" SELECT COUNT(ab.rowid) as nb FROM ".MAIN_DB_PREFIX.
"accounting_bookkeeping as ab WHERE ab.doc_type='".$this->db->escape($type).
"' AND ab.fk_doc = ".((int) $this->
id);
2637 $resql = $this->db->query($sql);
2639 $obj = $this->db->fetch_object($resql);
2641 $alreadydispatched = $obj->nb;
2644 $this->error = $this->db->lasterror();
2648 if ($alreadydispatched) {
2661 $table =
'payment_expensereport';
2662 $field =
'fk_expensereport';
2664 $sql =
'SELECT sum(amount) as amount';
2665 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2666 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
2668 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2669 $resql = $this->db->query($sql);
2671 $obj = $this->db->fetch_object($resql);
2672 $this->db->free($resql);
2673 return (empty($obj->amount) ? 0 : $obj->amount);
2675 $this->error = $this->db->lasterror();
2690 global $langs, $db, $conf;
2698 $this->error = $langs->trans(
'ErrorBadParameterCat');
2703 $this->error = $langs->trans(
'ErrorBadParameterQty');
2707 $currentUser =
new User($db);
2708 $currentUser->fetch($this->fk_user);
2709 $currentUser->getrights(
'expensereport');
2713 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2714 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2715 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2716 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2717 $sql .=
" ORDER BY r.range_ik ASC";
2719 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2721 $result = $this->db->query($sql);
2724 if ($conf->global->EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR) {
2726 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2727 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2728 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2729 $sql.=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2730 $sql.=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2731 $sql.=
" AND tf.code = 'EX_KME' ";
2734 $resql = $this->db->query($sql);
2737 $obj = $this->db->fetch_object($resql);
2738 $cumulYearQty = $obj->cumul;
2741 $qty = $cumulYearQty + $qty;
2744 $num = $this->db->num_rows($result);
2747 for ($i = 0; $i < $num; $i++) {
2748 $obj = $this->db->fetch_object($result);
2754 for ($i = 0; $i < $num; $i++) {
2755 if ($i < ($num - 1)) {
2756 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i+1]->range_ik) {
2757 $coef = $ranges[$i]->coef;
2758 $offset = $ranges[$i]->ikoffset;
2761 if ($qty > $ranges[$i]->range_ik) {
2762 $coef = $ranges[$i]->coef;
2763 $offset = $ranges[$i]->ikoffset;
2770 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2774 $this->error = $this->db->error().
" sql=".$sql;
2791 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2793 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2794 $return .=
'<div class="info-box info-box-sm">';
2795 $return .=
'<span class="info-box-icon bg-infobox-action">';
2797 $return .=
'</span>';
2798 $return .=
'<div class="info-box-content">';
2799 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
2800 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2801 if (property_exists($this,
'fk_user_author') && !empty($this->
id)) {
2802 $return .=
'<br><span class="info-box-label">'.$this->fk_user_author.
'</span>';
2804 if (property_exists($this,
'date_debut') && property_exists($this,
'date_fin')) {
2805 $return .=
'<br><span class="info-box-label">'.dol_print_date($this->date_debut,
'day').
'</span>';
2806 $return .=
' <span class="opacitymedium">'.$langs->trans(
"To").
'</span> ';
2807 $return .=
'<span class="info-box-label">'.dol_print_date($this->date_fin,
'day').
'</span>';
2809 if (method_exists($this,
'getLibStatut')) {
2810 $return .=
'<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).
'</div>';
2812 $return .=
'</div>';
2813 $return .=
'</div>';
2814 $return .=
'</div>';
2833 public $table_element =
'expensereport_det';
2853 public $fk_c_type_fees;
2858 public $fk_c_exp_tax_cat;
2868 public $fk_expensereport;
2870 public $type_fees_code;
2871 public $type_fees_libelle;
2872 public $type_fees_accountancy_code;
2875 public $projet_title;
2879 public $vat_src_code;
2881 public $localtax1_tx;
2882 public $localtax2_tx;
2883 public $localtax1_type;
2884 public $localtax2_type;
2889 public $total_localtax1;
2890 public $total_localtax2;
2896 public $fk_multicurrency;
2901 public $multicurrency_code;
2902 public $multicurrency_tx;
2903 public $multicurrency_total_ht;
2904 public $multicurrency_total_tva;
2905 public $multicurrency_total_ttc;
2910 public $fk_ecm_files;
2912 public $rule_warning_message;
2933 $sql =
'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_c_exp_tax_cat, fde.fk_projet as fk_project, fde.date,';
2934 $sql .=
' fde.tva_tx as vatrate, fde.vat_src_code, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc, fde.fk_ecm_files,';
2935 $sql .=
' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,';
2936 $sql .=
' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
2937 $sql .=
' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
2938 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det as fde';
2939 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
2940 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as pjt ON fde.fk_projet=pjt.rowid';
2941 $sql .=
' WHERE fde.rowid = '.((int) $rowid);
2943 $result = $this->db->query($sql);
2946 $objp = $this->db->fetch_object($result);
2948 $this->
rowid = $objp->rowid;
2949 $this->
id = $objp->rowid;
2950 $this->
ref = $objp->ref;
2951 $this->fk_expensereport = $objp->fk_expensereport;
2952 $this->comments = $objp->comments;
2953 $this->qty = $objp->qty;
2954 $this->date = $objp->date;
2955 $this->dates = $this->db->jdate($objp->date);
2956 $this->value_unit = $objp->value_unit;
2957 $this->fk_c_type_fees = $objp->fk_c_type_fees;
2958 $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
2959 $this->fk_projet = $objp->fk_project;
2960 $this->fk_project = $objp->fk_project;
2961 $this->type_fees_code = $objp->type_fees_code;
2962 $this->type_fees_libelle = $objp->type_fees_libelle;
2963 $this->projet_ref = $objp->projet_ref;
2964 $this->projet_title = $objp->projet_title;
2966 $this->
vatrate = $objp->vatrate;
2967 $this->vat_src_code = $objp->vat_src_code;
2968 $this->localtax1_tx = $objp->localtax1_tx;
2969 $this->localtax2_tx = $objp->localtax2_tx;
2970 $this->localtax1_type = $objp->localtax1_type;
2971 $this->localtax2_type = $objp->localtax2_type;
2973 $this->total_ht = $objp->total_ht;
2974 $this->total_tva = $objp->total_tva;
2975 $this->total_ttc = $objp->total_ttc;
2976 $this->total_localtax1 = $objp->total_localtax1;
2977 $this->total_localtax2 = $objp->total_localtax2;
2979 $this->fk_ecm_files = $objp->fk_ecm_files;
2981 $this->rule_warning_message = $objp->rule_warning_message;
2983 $this->db->free($result);
2999 public function insert($notrigger = 0, $fromaddline =
false)
3001 global $user, $conf;
3005 dol_syslog(
"ExpenseReportLine::Insert", LOG_DEBUG);
3008 $this->comments = trim($this->comments);
3009 if (empty($this->value_unit)) {
3010 $this->value_unit = 0;
3014 if (empty($this->fk_c_exp_tax_cat)) {
3015 $this->fk_c_exp_tax_cat = 0;
3020 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'expensereport_det';
3021 $sql .=
' (fk_expensereport, fk_c_type_fees, fk_projet,';
3022 $sql .=
' tva_tx, vat_src_code,';
3023 $sql .=
' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
3024 $sql .=
' comments, qty, value_unit,';
3025 $sql .=
' total_ht, total_tva, total_ttc,';
3026 $sql .=
' total_localtax1, total_localtax2,';
3027 $sql .=
' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)';
3028 $sql .=
" VALUES (".$this->db->escape($this->fk_expensereport).
",";
3029 $sql .=
" ".((int) $this->fk_c_type_fees).
",";
3030 $sql .=
" ".((int) (!empty($this->fk_project) && $this->fk_project > 0) ? $this->fk_project : ((!empty($this->fk_projet) && $this->fk_projet > 0) ? $this->fk_projet :
'null')).
",";
3031 $sql .=
" ".((float) $this->
vatrate).
",";
3032 $sql .=
" '".$this->db->escape(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"',";
3033 $sql .=
" ".((float)
price2num($this->localtax1_tx)).
",";
3034 $sql .=
" ".((float)
price2num($this->localtax2_tx)).
",";
3035 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
3036 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
3037 $sql .=
" '".$this->db->escape($this->comments).
"',";
3038 $sql .=
" ".((float) $this->qty).
",";
3039 $sql .=
" ".((float) $this->value_unit).
",";
3040 $sql .=
" ".((float)
price2num($this->total_ht)).
",";
3041 $sql .=
" ".((float)
price2num($this->total_tva)).
",";
3042 $sql .=
" ".((float)
price2num($this->total_ttc)).
",";
3043 $sql .=
" ".((float)
price2num($this->total_localtax1)).
",";
3044 $sql .=
" ".((float)
price2num($this->total_localtax2)).
",";
3045 $sql .=
" '".$this->db->idate($this->date).
"',";
3046 $sql .=
" ".(empty($this->rule_warning_message) ?
'null' :
"'".$this->db->escape($this->rule_warning_message).
"'").
",";
3047 $sql .=
" ".((int) $this->fk_c_exp_tax_cat).
",";
3048 $sql .=
" ".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3051 $resql = $this->db->query($sql);
3053 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'expensereport_det');
3056 if (!$error && !$notrigger) {
3058 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_CREATE', $user);
3066 if (!$fromaddline) {
3068 $tmpparent->fetch($this->fk_expensereport);
3069 $result = $tmpparent->update_price(1);
3072 $this->error = $tmpparent->error;
3073 $this->errors = $tmpparent->errors;
3081 $this->db->commit();
3084 $this->error = $this->db->lasterror();
3085 dol_syslog(
"ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
3086 $this->db->rollback();
3103 $sql =
'SELECT SUM(d.total_ttc) as total_amount';
3104 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det d';
3105 $sql .=
' INNER JOIN '.MAIN_DB_PREFIX.
'expensereport e ON (d.fk_expensereport = e.rowid)';
3106 $sql .=
' WHERE e.fk_user_author = '.((int) $fk_user);
3107 if (!empty($this->
id)) {
3108 $sql .=
' AND d.rowid <> '.((int) $this->
id);
3110 $sql .=
' AND d.fk_c_type_fees = '.((int) $rule->fk_c_type_fees);
3111 if ($mode ==
'day' || $mode ==
'EX_DAY') {
3112 $sql .=
" AND d.date = '".dol_print_date($this->date,
'%Y-%m-%d').
"'";
3113 } elseif ($mode ==
'mon' || $mode ==
'EX_MON') {
3114 $sql .=
" AND DATE_FORMAT(d.date, '%Y-%m') = '".dol_print_date($this->date,
'%Y-%m').
"'";
3115 } elseif ($mode ==
'year' || $mode ==
'EX_YEA') {
3116 $sql .=
" AND DATE_FORMAT(d.date, '%Y') = '".dol_print_date($this->date,
'%Y').
"'";
3119 dol_syslog(
'ExpenseReportLine::getExpAmount');
3121 $resql = $this->db->query($sql);
3123 $num = $this->db->num_rows($resql);
3125 $obj = $this->db->fetch_object($resql);
3126 $amount = (double) $obj->total_amount;
3132 return $amount + $this->total_ttc;
3143 global $langs, $conf;
3148 $this->comments = trim($this->comments);
3150 $this->value_unit =
price2num($this->value_unit);
3151 if (empty($this->fk_c_exp_tax_cat)) {
3152 $this->fk_c_exp_tax_cat = 0;
3158 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport_det SET";
3159 $sql .=
" comments='".$this->db->escape($this->comments).
"'";
3160 $sql .=
", value_unit = ".((float) $this->value_unit);
3161 $sql .=
", qty=".((float) $this->qty);
3162 $sql .=
", date='".$this->db->idate($this->date).
"'";
3163 $sql .=
", total_ht=".((float)
price2num($this->total_ht,
'MT'));
3164 $sql .=
", total_tva=".((float)
price2num($this->total_tva,
'MT'));
3165 $sql .=
", total_ttc=".((float)
price2num($this->total_ttc,
'MT'));
3166 $sql .=
", total_localtax1=".((float)
price2num($this->total_localtax1,
'MT'));
3167 $sql .=
", total_localtax2=".((float)
price2num($this->total_localtax2,
'MT'));
3168 $sql .=
", tva_tx=".((float) $this->
vatrate);
3169 $sql .=
", vat_src_code='".$this->db->escape($this->vat_src_code).
"'";
3170 $sql .=
", localtax1_tx=".((float) $this->localtax1_tx);
3171 $sql .=
", localtax2_tx=".((float) $this->localtax2_tx);
3172 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
3173 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
3174 $sql .=
", rule_warning_message='".$this->db->escape($this->rule_warning_message).
"'";
3175 $sql .=
", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat);
3176 $sql .=
", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3177 if ($this->fk_c_type_fees) {
3178 $sql .=
", fk_c_type_fees = ".((int) $this->fk_c_type_fees);
3180 $sql .=
", fk_c_type_fees=null";
3182 if ($this->fk_project > 0) {
3183 $sql .=
", fk_projet=".((int) $this->fk_project);
3185 $sql .=
", fk_projet=null";
3187 $sql .=
" WHERE rowid = ".((int) ($this->
rowid ? $this->
rowid : $this->id));
3191 $resql = $this->db->query($sql);
3194 $result = $tmpparent->fetch($this->fk_expensereport);
3196 $result = $tmpparent->update_price(1);
3199 $this->error = $tmpparent->error;
3200 $this->errors = $tmpparent->errors;
3204 $this->error = $tmpparent->error;
3205 $this->errors = $tmpparent->errors;
3213 $this->db->commit();
3216 $this->error = $this->db->lasterror();
3217 dol_syslog(
"ExpenseReportLine::update Error ".$this->error, LOG_ERR);
3218 $this->db->rollback();
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.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='', $f_user=null, $notrigger=0)
Delete all links between an object $this.
update_price($exclspec=0, $roundingadjust='none', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
deleteExtraFields()
Delete all extra fields values for the current object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Trips and Expenses.
setPaid($id, $fuser, $notrigger=0)
Classify the expense report as paid.
__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 vehicule categor...
load_state_board()
Charge indicateurs this->nb pour le tableau de bord.
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.
deleteline($rowid, $fuser='', $notrigger=0)
deleteline
const STATUS_APPROVED
Classified approved.
set_save_from_refuse($fuser)
set_save_from_refuse
periode_existe($fuser, $date_debut, $date_fin)
periode_existe
setValidate($fuser, $notrigger=0)
Set to status validate.
getSumPayments()
Return amount of payments already done.
getLibStatut($mode=0)
Returns the label status.
set_cancel($fuser, $detail, $notrigger=0)
set_cancel
getNomUrl($withpicto=0, $option='', $max=0, $short=0, $moretitle='', $notooltip=0, $save_lastsearch_value=-1)
Return clicable name (with picto eventually)
set_unpaid($fuser, $notrigger=0)
set_unpaid
info($id)
Load information on object.
getTooltipContentArray($params)
getTooltipContentArray
hasDelay($option)
Return if an expense report is late or not.
applyOffset($type=0, $seller='')
Method to apply the offset if needed.
const STATUS_CANCELED
Classified canceled.
const STATUS_CLOSED
Classified paid.
const STATUS_REFUSED
Classified refused.
setDeny($fuser, $details, $notrigger=0)
setDeny
getVentilExportCompta()
Return if object was dispatched into bookkeeping.
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually 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 accordign 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.
fetch_line_by_project($projectid, $user='')
fetch_line_by_project
setUnpaid($fuser, $notrigger=0)
set_unpaid
update_totaux_add($ligne_total_ht, $ligne_total_tva)
Update total of an expense report when you add a line.
Class to manage inventories.
Class of expense report details lines.
fetch($rowid)
Fetch record for expense report detailed line.
update(User $user)
Update line.
getExpAmount(ExpenseReportRule $rule, $fk_user, $mode='day')
Function to get total amount in expense reports for a same rule.
insert($notrigger=0, $fromaddline=false)
Insert a line of expense report.
__construct($db)
Constructor.
Class to manage inventories.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_dir_list($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.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
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.
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.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller='', $localtaxes_array='', $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.