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';
42 public $element =
'expensereport';
47 public $table_element =
'expensereport';
52 public $table_element_line =
'expensereport_det';
57 public $fk_element =
'fk_expensereport';
62 public $picto =
'trip';
67 public $lines = array();
81 public $date_approbation;
88 public $user_approve_id;
105 public $fk_c_paiement;
106 public $modepaymentid;
110 public $user_author_infos;
111 public $user_validator_infos;
113 public $rule_warning_message;
123 public $fk_user_creat;
128 public $fk_user_author;
132 public $fk_user_modif;
136 public $detail_refuse;
137 public $fk_user_refuse;
141 public $detail_cancel;
146 public $fk_user_cancel;
151 public $fk_user_validator;
170 public $fk_user_valid;
171 public $user_valid_infos;
174 public $date_approve;
175 public $fk_user_approve;
178 public $user_paid_infos;
183 public $labelStatus = array();
184 public $labelStatusShort = array();
190 public $fk_multicurrency;
195 public $multicurrency_code;
196 public $multicurrency_tx;
197 public $multicurrency_total_ht;
198 public $multicurrency_total_tva;
199 public $multicurrency_total_ttc;
232 public $fields = array(
233 'rowid' =>array(
'type'=>
'integer',
'label'=>
'ID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
234 'ref' =>array(
'type'=>
'varchar(50)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'showoncombobox'=>1,
'position'=>15),
235 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>20),
236 'ref_number_int' =>array(
'type'=>
'integer',
'label'=>
'Ref number int',
'enabled'=>1,
'visible'=>-1,
'position'=>25),
237 'ref_ext' =>array(
'type'=>
'integer',
'label'=>
'Ref ext',
'enabled'=>1,
'visible'=>-1,
'position'=>30),
238 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total ht',
'enabled'=>1,
'visible'=>-1,
'position'=>35),
239 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total tva',
'enabled'=>1,
'visible'=>-1,
'position'=>40),
240 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax1',
'enabled'=>1,
'visible'=>-1,
'position'=>45),
241 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax2',
'enabled'=>1,
'visible'=>-1,
'position'=>50),
242 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total ttc',
'enabled'=>1,
'visible'=>-1,
'position'=>55),
243 'date_debut' =>array(
'type'=>
'date',
'label'=>
'Date debut',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>60),
244 'date_fin' =>array(
'type'=>
'date',
'label'=>
'Date fin',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>65),
245 'date_valid' =>array(
'type'=>
'datetime',
'label'=>
'Date valid',
'enabled'=>1,
'visible'=>-1,
'position'=>75),
246 'date_approve' =>array(
'type'=>
'datetime',
'label'=>
'Date approve',
'enabled'=>1,
'visible'=>-1,
'position'=>80),
247 'date_refuse' =>array(
'type'=>
'datetime',
'label'=>
'Date refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>85),
248 'date_cancel' =>array(
'type'=>
'datetime',
'label'=>
'Date cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>90),
249 'fk_user_author' =>array(
'type'=>
'integer',
'label'=>
'Fk user author',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>100),
250 'fk_user_modif' =>array(
'type'=>
'integer',
'label'=>
'Fk user modif',
'enabled'=>1,
'visible'=>-1,
'position'=>105),
251 'fk_user_valid' =>array(
'type'=>
'integer',
'label'=>
'Fk user valid',
'enabled'=>1,
'visible'=>-1,
'position'=>110),
252 'fk_user_validator' =>array(
'type'=>
'integer',
'label'=>
'Fk user validator',
'enabled'=>1,
'visible'=>-1,
'position'=>115),
253 'fk_user_approve' =>array(
'type'=>
'integer',
'label'=>
'Fk user approve',
'enabled'=>1,
'visible'=>-1,
'position'=>120),
254 'fk_user_refuse' =>array(
'type'=>
'integer',
'label'=>
'Fk user refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>125),
255 'fk_user_cancel' =>array(
'type'=>
'integer',
'label'=>
'Fk user cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>130),
256 'fk_c_paiement' =>array(
'type'=>
'integer',
'label'=>
'Fk c paiement',
'enabled'=>1,
'visible'=>-1,
'position'=>140),
257 'paid' =>array(
'type'=>
'integer',
'label'=>
'Paid',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>145),
258 'note_public' =>array(
'type'=>
'html',
'label'=>
'Note public',
'enabled'=>1,
'visible'=>0,
'position'=>150),
259 'note_private' =>array(
'type'=>
'html',
'label'=>
'Note private',
'enabled'=>1,
'visible'=>0,
'position'=>155),
260 'detail_refuse' =>array(
'type'=>
'varchar(255)',
'label'=>
'Detail refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>160),
261 'detail_cancel' =>array(
'type'=>
'varchar(255)',
'label'=>
'Detail cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>165),
262 'integration_compta' =>array(
'type'=>
'integer',
'label'=>
'Integration compta',
'enabled'=>1,
'visible'=>-1,
'position'=>170),
263 'fk_bank_account' =>array(
'type'=>
'integer',
'label'=>
'Fk bank account',
'enabled'=>1,
'visible'=>-1,
'position'=>175),
264 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'Fk multicurrency',
'enabled'=>1,
'visible'=>-1,
'position'=>185),
265 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'Multicurrency code',
'enabled'=>1,
'visible'=>-1,
'position'=>190),
266 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency tx',
'enabled'=>1,
'visible'=>-1,
'position'=>195),
267 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total ht',
'enabled'=>1,
'visible'=>-1,
'position'=>200),
268 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total tva',
'enabled'=>1,
'visible'=>-1,
'position'=>205),
269 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total ttc',
'enabled'=>1,
'visible'=>-1,
'position'=>210),
270 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>220),
271 'date_create' =>array(
'type'=>
'datetime',
'label'=>
'Date create',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>300),
272 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'Tms',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>305),
273 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-1,
'position'=>1000),
274 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'Model pdf',
'enabled'=>1,
'visible'=>0,
'position'=>1010),
275 'fk_statut' =>array(
'type'=>
'integer',
'label'=>
'Fk statut',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>500),
287 $this->total_ttc = 0;
288 $this->total_tva = 0;
289 $this->total_localtax1 = 0;
290 $this->total_localtax2 = 0;
291 $this->localtax1 = 0;
292 $this->localtax2 = 0;
293 $this->modepaymentid = 0;
296 $this->labelStatusShort = array(0 =>
'Draft', 2 =>
'Validated', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
297 $this->labelStatus = array(0 =>
'Draft', 2 =>
'ValidatedWaitingApproval', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
307 public function create($user, $notrigger = 0)
309 global $conf, $langs;
316 if (empty($this->date_debut) || empty($this->date_fin)) {
317 $this->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
'Date'));
321 $fuserid = $this->fk_user_author;
322 if (empty($fuserid)) {
323 $fuserid = $user->id;
328 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
" (";
331 $sql .=
",total_ttc";
332 $sql .=
",total_tva";
333 $sql .=
",date_debut";
335 $sql .=
",date_create";
336 $sql .=
",fk_user_creat";
337 $sql .=
",fk_user_author";
338 $sql .=
",fk_user_validator";
339 $sql .=
",fk_user_approve";
340 $sql .=
",fk_user_modif";
341 $sql .=
",fk_statut";
342 $sql .=
",fk_c_paiement";
344 $sql .=
",note_public";
345 $sql .=
",note_private";
349 $sql .=
", ".price2num($this->total_ht,
'MT');
350 $sql .=
", ".price2num($this->total_ttc,
'MT');
351 $sql .=
", ".price2num($this->total_tva,
'MT');
352 $sql .=
", '".$this->db->idate($this->date_debut).
"'";
353 $sql .=
", '".$this->db->idate($this->date_fin).
"'";
354 $sql .=
", '".$this->db->idate($now).
"'";
355 $sql .=
", ".((int) $user->id);
356 $sql .=
", ".((int) $fuserid);
357 $sql .=
", ".($this->fk_user_validator > 0 ? ((int) $this->fk_user_validator) :
"null");
358 $sql .=
", ".($this->fk_user_approve > 0 ? ((int) $this->fk_user_approve) :
"null");
359 $sql .=
", ".($this->fk_user_modif > 0 ? ((int) $this->fk_user_modif) :
"null");
360 $sql .=
", ".($this->fk_statut > 1 ? ((int) $this->fk_statut) : 0);
361 $sql .=
", ".($this->modepaymentid ? ((int) $this->modepaymentid) :
"null");
363 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
"null");
364 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
"null");
365 $sql .=
", ".((int) $conf->entity);
368 $result = $this->db->query($sql);
370 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
371 $this->
ref =
'(PROV'.$this->id.
')';
373 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
" SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
374 $resql = $this->db->query($sql);
376 $this->error = $this->db->lasterror();
381 if (is_array($this->lines) && count($this->lines) > 0) {
382 foreach ($this->lines as $line) {
385 if (!is_object($line)) {
386 $line = (object) $line;
388 $newndfline->fk_expensereport = $line->fk_expensereport;
389 $newndfline->fk_c_type_fees = $line->fk_c_type_fees;
390 $newndfline->fk_project = $line->fk_project;
391 $newndfline->vatrate = $line->vatrate;
392 $newndfline->vat_src_code = $line->vat_src_code;
393 $newndfline->localtax1_tx = $line->localtax1_tx;
394 $newndfline->localtax2_tx = $line->localtax2_tx;
395 $newndfline->localtax1_type = $line->localtax1_type;
396 $newndfline->localtax2_type = $line->localtax2_type;
397 $newndfline->comments = $line->comments;
398 $newndfline->qty = $line->qty;
399 $newndfline->value_unit = $line->value_unit;
400 $newndfline->total_ht = $line->total_ht;
401 $newndfline->total_ttc = $line->total_ttc;
402 $newndfline->total_tva = $line->total_tva;
403 $newndfline->total_localtax1 = $line->total_localtax1;
404 $newndfline->total_localtax2 = $line->total_localtax2;
405 $newndfline->date = $line->date;
406 $newndfline->rule_warning_message = $line->rule_warning_message;
407 $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat;
408 $newndfline->fk_ecm_files = $line->fk_ecm_files;
413 $newndfline->fk_expensereport = $this->id;
414 $result = $newndfline->insert();
416 $this->error = $newndfline->error;
417 $this->errors = $newndfline->errors;
437 $result = $this->
call_trigger(
'EXPENSE_REPORT_CREATE', $user);
449 $this->db->rollback();
453 $this->db->rollback();
457 dol_syslog(get_class($this).
"::create error ".$this->error, LOG_ERR);
458 $this->db->rollback();
462 $this->error = $this->db->lasterror().
" sql=".$sql;
463 $this->db->rollback();
481 if (empty($fk_user_author)) {
482 $fk_user_author = $user->id;
492 $objFrom = clone $this;
497 $this->fk_statut = 0;
500 $this->fk_user_creat = $user->id;
501 $this->fk_user_author = $fk_user_author;
502 $this->fk_user_valid =
'';
503 $this->date_create =
'';
504 $this->date_creation =
'';
505 $this->date_validation =
'';
508 if (is_array($this->lines) && count($this->lines) > 0) {
509 foreach ($this->lines as $key => $line) {
510 $this->lines[$key]->fk_ecm_files = 0;
515 $this->context[
'createfromclone'] =
'createfromclone';
516 $result = $this->
create($user);
523 if (is_object($hookmanager)) {
524 $parameters = array(
'objFrom'=>$objFrom);
526 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
534 unset($this->context[
'createfromclone']);
541 $this->db->rollback();
555 public function update($user, $notrigger = 0, $userofexpensereport =
null)
562 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
563 $sql .=
" total_ht = ".$this->total_ht;
564 $sql .=
" , total_ttc = ".$this->total_ttc;
565 $sql .=
" , total_tva = ".$this->total_tva;
566 $sql .=
" , date_debut = '".$this->db->idate($this->date_debut).
"'";
567 $sql .=
" , date_fin = '".$this->db->idate($this->date_fin).
"'";
568 if ($userofexpensereport && is_object($userofexpensereport)) {
569 $sql .=
" , fk_user_author = ".($userofexpensereport->id > 0 ? $userofexpensereport->id :
"null");
571 $sql .=
" , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator :
"null");
572 $sql .=
" , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid :
"null");
573 $sql .=
" , fk_user_approve = ".($this->fk_user_approve > 0 ? $this->fk_user_approve :
"null");
574 $sql .=
" , fk_user_modif = ".$user->id;
575 $sql .=
" , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut :
'0');
576 $sql .=
" , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement :
"null");
577 $sql .=
" , note_public = ".(!empty($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"''");
578 $sql .=
" , note_private = ".(!empty($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"''");
579 $sql .=
" , detail_refuse = ".(!empty($this->detail_refuse) ?
"'".$this->db->escape($this->detail_refuse).
"'" :
"''");
580 $sql .=
" WHERE rowid = ".((int) $this->
id);
582 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
583 $result = $this->db->query($sql);
587 $result = $this->
call_trigger(
'EXPENSE_REPORT_MODIFY', $user);
599 $this->db->rollback();
600 $this->error = $this->db->error();
604 $this->db->rollback();
605 $this->error = $this->db->error();
617 public function fetch($id, $ref =
'')
621 $sql =
"SELECT d.rowid, d.entity, d.ref, d.note_public, d.note_private,";
622 $sql .=
" d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,";
623 $sql .=
" d.date_refuse, d.date_cancel,";
624 $sql .=
" d.total_ht, d.total_ttc, d.total_tva,";
625 $sql .=
" d.localtax1 as total_localtax1, d.localtax2 as total_localtax2,";
626 $sql .=
" d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,";
627 $sql .=
" d.fk_user_creat, d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
628 $sql .=
" d.fk_user_valid, d.fk_user_approve,";
629 $sql .=
" d.fk_statut as status, d.fk_c_paiement, d.paid";
630 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as d";
632 $sql .=
" WHERE d.ref = '".$this->db->escape($ref).
"'";
633 $sql .=
" AND d.entity IN (".getEntity(
'expensereport').
")";
635 $sql .=
" WHERE d.rowid = ".((int) $id);
639 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
640 $resql = $this->db->query($sql);
642 $obj = $this->db->fetch_object($resql);
644 $this->
id = $obj->rowid;
645 $this->
ref = $obj->ref;
647 $this->entity = $obj->entity;
649 $this->total_ht = $obj->total_ht;
650 $this->total_tva = $obj->total_tva;
651 $this->total_ttc = $obj->total_ttc;
652 $this->localtax1 = $obj->total_localtax1;
653 $this->localtax2 = $obj->total_localtax2;
654 $this->total_localtax1 = $obj->total_localtax1;
655 $this->total_localtax2 = $obj->total_localtax2;
657 $this->note_public = $obj->note_public;
658 $this->note_private = $obj->note_private;
659 $this->detail_refuse = $obj->detail_refuse;
660 $this->detail_cancel = $obj->detail_cancel;
662 $this->date_debut = $this->db->jdate($obj->date_debut);
663 $this->date_fin = $this->db->jdate($obj->date_fin);
664 $this->date_valid = $this->db->jdate($obj->date_valid);
665 $this->date_approve = $this->db->jdate($obj->date_approve);
666 $this->date_create = $this->db->jdate($obj->date_create);
667 $this->date_modif = $this->db->jdate($obj->date_modif);
668 $this->date_refuse = $this->db->jdate($obj->date_refuse);
669 $this->date_cancel = $this->db->jdate($obj->date_cancel);
671 $this->fk_user_creat = $obj->fk_user_creat;
672 $this->fk_user_author = $obj->fk_user_author;
673 $this->fk_user_modif = $obj->fk_user_modif;
674 $this->fk_user_validator = $obj->fk_user_validator;
675 $this->fk_user_valid = $obj->fk_user_valid;
676 $this->fk_user_refuse = $obj->fk_user_refuse;
677 $this->fk_user_cancel = $obj->fk_user_cancel;
678 $this->fk_user_approve = $obj->fk_user_approve;
680 $user_author =
new User($this->db);
681 if ($this->fk_user_author > 0) {
682 $user_author->fetch($this->fk_user_author);
685 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
687 $user_approver =
new User($this->db);
688 if ($this->fk_user_approve > 0) {
689 $user_approver->fetch($this->fk_user_approve);
690 } elseif ($this->fk_user_validator > 0) {
691 $user_approver->fetch($this->fk_user_validator);
693 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
695 $this->fk_statut = $obj->status;
696 $this->
status = $obj->status;
697 $this->fk_c_paiement = $obj->fk_c_paiement;
698 $this->paid = $obj->paid;
700 if ($this->
status == self::STATUS_APPROVED || $this->
status == self::STATUS_CLOSED) {
701 $user_valid =
new User($this->db);
702 if ($this->fk_user_valid > 0) {
703 $user_valid->fetch($this->fk_user_valid);
705 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
717 $this->error = $this->db->lasterror();
733 public function set_paid($id, $fuser, $notrigger = 0)
736 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
737 return $this->
setPaid($id, $fuser, $notrigger);
748 public function setPaid($id, $fuser, $notrigger = 0)
753 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
754 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid=1";
757 dol_syslog(get_class($this).
"::setPaid", LOG_DEBUG);
758 $resql = $this->db->query($sql);
760 if ($this->db->affected_rows($resql)) {
763 $result = $this->
call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
775 $this->db->rollback();
776 $this->error = $this->db->error();
784 $this->db->rollback();
814 $labelStatus = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
815 $labelStatusShort = $langs->transnoentitiesnoconv($this->labelStatusShort[$status]);
817 $statuslogo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
819 $statusType = $statuslogo[$status];
821 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
835 $sql =
"SELECT f.rowid,";
836 $sql .=
" f.date_create as datec,";
837 $sql .=
" f.tms as date_modification,";
838 $sql .=
" f.date_valid as datev,";
839 $sql .=
" f.date_approve as datea,";
840 $sql .=
" f.fk_user_creat as fk_user_creation,";
841 $sql .=
" f.fk_user_author as fk_user_author,";
842 $sql .=
" f.fk_user_modif as fk_user_modification,";
843 $sql .=
" f.fk_user_valid,";
844 $sql .=
" f.fk_user_approve";
845 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
846 $sql .=
" WHERE f.rowid = ".((int) $id);
847 $sql .=
" AND f.entity = ".$conf->entity;
849 $resql = $this->db->query($sql);
851 if ($this->db->num_rows($resql)) {
852 $obj = $this->db->fetch_object($resql);
854 $this->
id = $obj->rowid;
856 $this->date_creation = $this->db->jdate($obj->datec);
857 $this->date_modification = $this->db->jdate($obj->date_modification);
858 $this->date_validation = $this->db->jdate($obj->datev);
859 $this->date_approbation = $this->db->jdate($obj->datea);
861 $this->user_creation_id = $obj->fk_user_author;
862 $this->user_creation_id = $obj->fk_user_creation;
863 $this->user_validation_id = $obj->fk_user_valid;
864 $this->user_modification_id = $obj->fk_user_modification;
865 $this->user_approve_id = $obj->fk_user_approve;
867 $this->db->free($resql);
884 global $user, $langs, $conf;
890 $this->
ref =
'SPECIMEN';
893 $this->date_create = $now;
894 $this->date_debut = $now;
895 $this->date_fin = $now;
896 $this->date_valid = $now;
897 $this->date_approve = $now;
902 $this->fk_statut = 5;
904 $this->fk_user_author = $user->id;
905 $this->fk_user_validator = $user->id;
906 $this->fk_user_valid = $user->id;
907 $this->fk_user_approve = $user->id;
909 $this->note_private =
'Private note';
910 $this->note_public =
'SPECIMEN';
913 while ($xnbp < $nbp) {
915 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
916 $line->date = ($now - 3600 * (1 + $xnbp));
917 $line->total_ht = 100;
918 $line->total_tva = 20;
919 $line->total_ttc = 120;
922 $line->value_unit = 120;
923 $line->fk_expensereport = 0;
924 $line->type_fees_code =
'TRA';
925 $line->fk_c_type_fees = $type_fees_id;
927 $line->projet_ref =
'ABC';
929 $this->lines[$xnbp] = $line;
932 $this->total_ht += $line->total_ht;
933 $this->total_tva += $line->total_tva;
934 $this->total_ttc += $line->total_ttc;
949 global $conf, $db, $langs;
951 $langs->load(
'trips');
953 if ($user->hasRight(
'expensereport',
'lire')) {
954 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
955 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
956 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
958 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
959 $result = $this->db->query($sql);
961 $num = $this->db->num_rows($result);
967 $objp = $this->db->fetch_object($result);
969 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
970 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
971 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
973 $result2 = $this->db->query($sql2);
974 $obj = $this->db->fetch_object($result2);
976 $objp->fk_user_author = $obj->fk_user_author;
977 $objp->ref = $obj->ref;
978 $objp->fk_c_expensereport_status = $obj->status;
979 $objp->rowid = $obj->rowid;
981 $total_HT = $total_HT + $objp->total_ht;
982 $total_TTC = $total_TTC + $objp->total_ttc;
983 $author =
new User($this->db);
984 $author->fetch($objp->fk_user_author);
987 print
'<td><a href="'.DOL_URL_ROOT.
'/expensereport/card.php?id='.$objp->rowid.
'">'.$objp->ref_num.
'</a></td>';
988 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
989 print
'<td>'.$author->getNomUrl(1).
'</td>';
990 print
'<td>'.$objp->comments.
'</td>';
991 print
'<td class="right">'.price($objp->total_ht).
'</td>';
992 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
993 print
'<td class="right">';
995 switch ($objp->fk_c_expensereport_status) {
997 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
1000 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
1003 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
1006 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
1009 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
1026 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
1027 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
1028 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
1029 print
'<td> </td>';
1032 $this->error = $this->db->lasterror();
1051 $this->lines = array();
1053 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1054 $sql .=
" de.".$this->fk_element.
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1055 $sql .=
' de.tva_tx, de.vat_src_code,';
1056 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1057 $sql .=
' de.fk_ecm_files,';
1058 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1059 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1060 $sql .=
' ctf.code as code_type_fees, ctf.label as label_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1061 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1062 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as de';
1063 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1064 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1065 $sql .=
" WHERE de.".$this->fk_element.
" = ".((int) $this->
id);
1067 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1069 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1072 $resql = $this->db->query($sql);
1074 $num = $this->db->num_rows($resql);
1077 $objp = $this->db->fetch_object($resql);
1081 $deplig->rowid = $objp->rowid;
1082 $deplig->id = $objp->rowid;
1083 $deplig->comments = $objp->comments;
1084 $deplig->qty = $objp->qty;
1085 $deplig->value_unit = $objp->value_unit;
1086 $deplig->date = $objp->date;
1087 $deplig->dates = $this->db->jdate($objp->date);
1089 $deplig->fk_expensereport = $objp->fk_expensereport;
1090 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1091 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1092 $deplig->fk_projet = $objp->fk_project;
1093 $deplig->fk_project = $objp->fk_project;
1094 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1096 $deplig->total_ht = $objp->total_ht;
1097 $deplig->total_tva = $objp->total_tva;
1098 $deplig->total_ttc = $objp->total_ttc;
1099 $deplig->total_localtax1 = $objp->total_localtax1;
1100 $deplig->total_localtax2 = $objp->total_localtax2;
1102 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1103 $deplig->type_fees_libelle = $objp->label_type_fees;
1104 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1106 $deplig->tva_tx = $objp->tva_tx;
1107 $deplig->vatrate = $objp->tva_tx;
1108 $deplig->vat_src_code = $objp->vat_src_code;
1109 $deplig->localtax1_tx = $objp->localtax1_tx;
1110 $deplig->localtax2_tx = $objp->localtax2_tx;
1111 $deplig->localtax1_type = $objp->localtax1_type;
1112 $deplig->localtax2_type = $objp->localtax2_type;
1114 $deplig->projet_ref = $objp->ref_projet;
1115 $deplig->projet_title = $objp->title_projet;
1117 $deplig->rule_warning_message = $objp->rule_warning_message;
1119 $deplig->rang = $objp->rang;
1121 $this->lines[$i] = $deplig;
1125 $this->db->free($resql);
1128 $this->error = $this->db->lasterror();
1129 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1142 public function delete(
User $user =
null, $notrigger =
false)
1145 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1153 $result = $this->
call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1161 if (!$error && !empty($this->table_element_line)) {
1162 $tabletodelete = $this->table_element_line;
1164 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1165 if (!$this->db->query($sql)) {
1167 $this->error = $this->db->lasterror();
1168 $this->errors[] = $this->error;
1169 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1194 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1200 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1201 $res = $this->db->query($sql);
1204 $this->error = $this->db->lasterror();
1205 $this->errors[] = $this->error;
1206 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1222 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1223 $dir = $conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1224 $file = $dir.
"/".$ref.
".pdf";
1225 if (file_exists($file)) {
1229 $this->error =
'ErrorFailToDeleteFile';
1230 $this->errors[] = $this->error;
1231 $this->db->rollback();
1235 if (file_exists($dir)) {
1238 $this->error =
'ErrorFailToDeleteDir';
1239 $this->errors[] = $this->error;
1240 $this->db->rollback();
1248 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1249 $this->db->commit();
1252 $this->db->rollback();
1266 global $conf, $langs, $user;
1272 if ($this->
status == self::STATUS_VALIDATED) {
1273 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1277 $this->date_valid = $now;
1280 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
1285 if (empty($num) || $num < 0) {
1294 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1295 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1296 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1297 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1298 $sql .=
" fk_user_valid = ".((int) $user->id);
1299 $sql .=
" WHERE rowid = ".((int) $this->
id);
1301 $resql = $this->db->query($sql);
1303 if (!$error && !$notrigger) {
1305 $result = $this->
call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1313 $this->oldref = $this->ref;
1316 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1317 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1320 $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).
"'";
1321 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1322 $resql = $this->db->query($sql);
1325 $this->error = $this->db->lasterror();
1327 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1328 $sql .=
" WHERE filepath = 'expensereport/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
1329 $resql = $this->db->query($sql);
1332 $this->error = $this->db->lasterror();
1338 $dirsource = $conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1339 $dirdest = $conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1340 if (!$error && file_exists($dirsource)) {
1341 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1343 if (@rename($dirsource, $dirdest)) {
1346 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1347 foreach ($listoffiles as $fileentry) {
1348 $dirsource = $fileentry[
'name'];
1349 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1350 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1351 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1352 @rename($dirsource, $dirdest);
1365 if (empty($error)) {
1366 $this->db->commit();
1369 $this->db->rollback();
1370 $this->error = $this->db->error();
1374 $this->db->rollback();
1375 $this->error = $this->db->lasterror();
1391 $sql =
'SELECT date_debut';
1392 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1393 $sql .=
" WHERE rowid = ".((int) $this->
id);
1395 $result = $this->db->query($sql);
1397 $objp = $this->db->fetch_object($result);
1399 $this->date_debut = $this->db->jdate($objp->date_debut);
1401 if ($this->
status != self::STATUS_VALIDATED) {
1402 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1403 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1404 $sql .=
" WHERE rowid = ".((int) $this->
id);
1406 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1408 if ($this->db->query($sql)) {
1411 $this->error = $this->db->lasterror();
1415 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1434 $this->date_approve = $now;
1435 if ($this->
status != self::STATUS_APPROVED) {
1438 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1439 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1440 $sql .=
" date_approve='".$this->db->idate($this->date_approve).
"'";
1441 $sql .=
" WHERE rowid = ".((int) $this->
id);
1442 if ($this->db->query($sql)) {
1445 $result = $this->
call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1453 if (empty($error)) {
1454 $this->db->commit();
1457 $this->db->rollback();
1458 $this->error = $this->db->error();
1462 $this->db->rollback();
1463 $this->error = $this->db->lasterror();
1467 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1481 public function setDeny($fuser, $details, $notrigger = 0)
1487 if ($this->
status != self::STATUS_REFUSED) {
1488 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1489 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1490 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1491 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1492 $sql .=
" fk_user_approve = NULL";
1493 $sql .=
" WHERE rowid = ".((int) $this->
id);
1494 if ($this->db->query($sql)) {
1495 $this->fk_statut = 99;
1497 $this->fk_user_refuse = $fuser->id;
1498 $this->detail_refuse = $details;
1499 $this->date_refuse = $now;
1503 $result = $this->
call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1511 if (empty($error)) {
1512 $this->db->commit();
1515 $this->db->rollback();
1516 $this->error = $this->db->error();
1520 $this->db->rollback();
1521 $this->error = $this->db->lasterror();
1525 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1544 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1545 return $this->
setUnpaid($fuser, $notrigger);
1562 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1563 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1564 $sql .=
" WHERE rowid = ".((int) $this->
id);
1566 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1568 if ($this->db->query($sql)) {
1571 $result = $this->
call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1579 if (empty($error)) {
1580 $this->db->commit();
1583 $this->db->rollback();
1584 $this->error = $this->db->error();
1588 $this->db->rollback();
1589 $this->error = $this->db->error();
1593 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1612 $this->date_cancel = $this->db->idate(
dol_now());
1613 if ($this->
status != self::STATUS_CANCELED) {
1616 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1617 $sql .=
" SET fk_statut = ".self::STATUS_CANCELED.
", fk_user_cancel = ".((int) $fuser->id);
1618 $sql .=
", date_cancel='".$this->db->idate($this->date_cancel).
"'";
1619 $sql .=
", detail_cancel='".$this->db->escape($detail).
"'";
1620 $sql .=
" WHERE rowid = ".((int) $this->
id);
1622 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1624 if ($this->db->query($sql)) {
1627 $result = $this->
call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1635 if (empty($error)) {
1636 $this->db->commit();
1639 $this->db->rollback();
1640 $this->error = $this->db->error();
1644 $this->db->rollback();
1645 $this->error = $this->db->error();
1649 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1661 global $langs, $conf;
1662 $langs->load(
"trips");
1668 $classname = $conf->global->EXPENSEREPORT_ADDON;
1671 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1672 foreach ($dirmodels as $reldir) {
1673 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1676 $mybool |= @include_once $dir.$file;
1679 if ($mybool ===
false) {
1684 $obj =
new $classname();
1685 $numref = $obj->getNextValue($this);
1687 if ($numref !=
"") {
1690 $this->error = $obj->error;
1691 $this->errors = $obj->errors;
1696 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1710 global $conf, $langs;
1712 $langs->load(
'expensereport');
1714 $nofetch = !empty($params[
'nofetch']);
1715 $moretitle = $params[
'moretitle'] ??
'';
1718 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1719 if (isset($this->
status)) {
1720 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1723 $datas[
'picto'] .=
' - '.$moretitle;
1725 if (!empty($this->
ref)) {
1726 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1728 if (!empty($this->total_ht)) {
1729 $datas[
'total_ht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1731 if (!empty($this->total_tva)) {
1732 $datas[
'total_tva'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1734 if (!empty($this->total_ttc)) {
1735 $datas[
'total_ttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
1753 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1755 global $langs, $conf, $hookmanager;
1759 $url = DOL_URL_ROOT.
'/expensereport/card.php?id='.$this->id;
1767 'objecttype' => $this->element,
1768 'option' => $option,
1769 'moretitle' => $moretitle,
1772 $classfortooltip =
'classfortooltip';
1775 $classfortooltip =
'classforajaxtooltip';
1776 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1782 if ($option !=
'nolink') {
1784 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1785 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1786 $add_save_lastsearch_values = 1;
1788 if ($add_save_lastsearch_values) {
1789 $url .=
'&save_lastsearch_values=1';
1799 if (empty($notooltip)) {
1801 $label = $langs->trans(
"ShowExpenseReport");
1802 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1804 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
1805 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
1808 $linkstart =
'<a href="'.$url.
'"';
1809 $linkstart .= $linkclose.
'>';
1812 $result .= $linkstart;
1814 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
1816 if ($withpicto != 2) {
1817 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1819 $result .= $linkend;
1822 $hookmanager->initHooks(array($this->element .
'dao'));
1823 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
1824 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1826 $result = $hookmanager->resPrint;
1828 $result .= $hookmanager->resPrint;
1844 $this->total_ht = $this->total_ht + $ligne_total_ht;
1845 $this->total_tva = $this->total_tva + $ligne_total_tva;
1846 $this->total_ttc = $this->total_ht + $this->total_tva;
1848 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1849 $sql .=
" total_ht = ".$this->total_ht;
1850 $sql .=
" , total_ttc = ".$this->total_ttc;
1851 $sql .=
" , total_tva = ".$this->total_tva;
1852 $sql .=
" WHERE rowid = ".((int) $this->
id);
1854 $result = $this->db->query($sql);
1858 $this->error = $this->db->error();
1878 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)
1880 global $conf, $langs, $mysoc;
1882 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);
1884 if ($this->
status == self::STATUS_DRAFT) {
1888 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1889 $fk_c_type_fees = 0;
1891 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1892 $fk_c_exp_tax_cat = 0;
1894 if (empty($vatrate) || $vatrate < 0) {
1900 if (empty($fk_project)) {
1905 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1916 $seller->tva_assuj = 1;
1917 $buyer =
new Societe($this->db);
1923 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
1924 $vat_src_code = $reg[1];
1925 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
1927 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
1929 $tmp =
calcul_price_total($qty, $up, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
1931 $this->line->value_unit = $up;
1933 $this->line->vat_src_code = $vat_src_code;
1934 $this->line->vatrate =
price2num($vatrate);
1935 $this->line->localtax1_tx = $localtaxes_type[1];
1936 $this->line->localtax2_tx = $localtaxes_type[3];
1937 $this->line->localtax1_type = $localtaxes_type[0];
1938 $this->line->localtax2_type = $localtaxes_type[2];
1940 $this->line->total_ttc = $tmp[2];
1941 $this->line->total_ht = $tmp[0];
1942 $this->line->total_tva = $tmp[1];
1943 $this->line->total_localtax1 = $tmp[9];
1944 $this->line->total_localtax2 = $tmp[10];
1946 $this->line->fk_expensereport = $this->id;
1947 $this->line->qty = $qty;
1948 $this->line->date = $date;
1949 $this->line->fk_c_type_fees = $fk_c_type_fees;
1950 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
1951 $this->line->comments = $comments;
1952 $this->line->fk_projet = $fk_project;
1953 $this->line->fk_project = $fk_project;
1955 $this->line->fk_ecm_files = $fk_ecm_files;
1960 $result = $this->line->insert(0,
true);
1964 $this->db->commit();
1965 return $this->line->id;
1967 $this->db->rollback();
1971 $this->error = $this->line->error;
1972 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
1973 $this->db->rollback();
1977 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
1978 $this->error =
'ErrorExpenseNotDraft';
1992 global $user, $conf, $db, $langs, $mysoc;
1994 $langs->load(
'trips');
1997 if (!is_object($seller)) {
1999 $seller->tva_assuj = 1;
2003 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
2006 $rule_warning_message_tab = array();
2008 $current_total_ttc = $this->line->total_ttc;
2009 $new_current_total_ttc = $this->line->total_ttc;
2012 foreach ($rulestocheck as $rule) {
2013 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
2014 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
2016 $amount_to_test = $current_total_ttc;
2019 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
2021 if ($amount_to_test > $rule->amount) {
2024 if ($rule->restrictive) {
2025 $this->error =
'ExpenseReportConstraintViolationError';
2026 $this->errors[] = $this->error;
2028 $new_current_total_ttc -= $amount_to_test - $rule->amount;
2029 $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));
2031 $this->error =
'ExpenseReportConstraintViolationWarning';
2032 $this->errors[] = $this->error;
2034 $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));
2041 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
2043 if ($violation > 0) {
2044 $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);
2046 $this->line->value_unit = $tmp[5];
2047 $this->line->total_ttc = $tmp[2];
2048 $this->line->total_ht = $tmp[0];
2049 $this->line->total_tva = $tmp[1];
2050 $this->line->total_localtax1 = $tmp[9];
2051 $this->line->total_localtax2 = $tmp[10];
2068 global $conf, $mysoc;
2074 $userauthor =
new User($this->db);
2075 if ($userauthor->fetch($this->fk_user_author) <= 0) {
2076 $this->error =
'ErrorCantFetchUser';
2077 $this->errors[] =
'ErrorCantFetchUser';
2082 if (!is_object($seller)) {
2084 $seller->tva_assuj = 1;
2088 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2090 if (empty($range)) {
2091 $this->error =
'ErrorNoRangeAvailable';
2092 $this->errors[] =
'ErrorNoRangeAvailable';
2097 $ikoffset = $range->ikoffset;
2099 $ikoffset = $range->ikoffset / 12;
2104 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2105 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2107 $this->line->value_unit = $tmp[5];
2108 $this->line->total_ttc = $tmp[2];
2109 $this->line->total_ht = $tmp[0];
2110 $this->line->total_tva = $tmp[1];
2111 $this->line->total_localtax1 = $tmp[9];
2112 $this->line->total_localtax2 = $tmp[10];
2127 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2128 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2129 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2130 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2131 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2132 if (!empty($this->line->id)) {
2133 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2136 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2137 $resql = $this->db->query($sql);
2139 $num = $this->db->num_rows($resql);
2167 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)
2169 global $user, $mysoc;
2171 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
2179 $seller->tva_assuj = 1;
2180 $seller->localtax1_assuj = $mysoc->localtax1_assuj;
2181 $seller->localtax2_assuj = $mysoc->localtax1_assuj;
2182 $buyer =
new Societe($this->db);
2189 if (preg_match(
'/\((.*)\)/', $vatrate, $reg)) {
2190 $vat_src_code = $reg[1];
2191 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2193 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2195 $tmp =
calcul_price_total($qty, $value_unit, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2200 $tx_tva = $vatrate / 100;
2201 $tx_tva = $tx_tva + 1;
2204 $this->line->comments = $comments;
2205 $this->line->qty = $qty;
2206 $this->line->value_unit = $value_unit;
2207 $this->line->date = $date;
2209 $this->line->fk_expensereport = $expensereport_id;
2210 $this->line->fk_c_type_fees = $type_fees_id;
2211 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2212 $this->line->fk_projet = $projet_id;
2213 $this->line->fk_project = $projet_id;
2215 $this->line->vat_src_code = $vat_src_code;
2216 $this->line->vatrate =
price2num($vatrate);
2217 $this->line->localtax1_tx = $localtaxes_type[1];
2218 $this->line->localtax2_tx = $localtaxes_type[3];
2219 $this->line->localtax1_type = $localtaxes_type[0];
2220 $this->line->localtax2_type = $localtaxes_type[2];
2222 $this->line->total_ttc = $tmp[2];
2223 $this->line->total_ht = $tmp[0];
2224 $this->line->total_tva = $tmp[1];
2225 $this->line->total_localtax1 = $tmp[9];
2226 $this->line->total_localtax2 = $tmp[10];
2228 $this->line->fk_ecm_files = $fk_ecm_files;
2230 $this->line->id = ((int) $rowid);
2233 $sql =
"SELECT c.code as code_type_fees, c.label as label_type_fees";
2234 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2235 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2236 $resql = $this->db->query($sql);
2238 $objp_fees = $this->db->fetch_object($resql);
2239 $this->line->type_fees_code = $objp_fees->code_type_fees;
2240 $this->line->type_fees_libelle = $objp_fees->label_type_fees;
2241 $this->db->free($resql);
2245 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2246 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2247 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2248 $resql = $this->db->query($sql);
2250 $objp_projet = $this->db->fetch_object($resql);
2251 $this->line->projet_ref = $objp_projet->ref_projet;
2252 $this->line->projet_title = $objp_projet->title_projet;
2253 $this->db->free($resql);
2259 $result = $this->line->update($user);
2264 if (!$error && !$notrigger) {
2266 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_MODIFY', $user);
2274 $this->db->commit();
2277 $this->error = $this->line->error;
2278 $this->errors = $this->line->errors;
2279 $this->db->rollback();
2303 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2310 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2311 $sql .=
' WHERE rowid = '.((int) $rowid);
2313 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2314 $result = $this->db->query($sql);
2316 if (!$result || $error > 0) {
2317 $this->error = $this->db->error();
2318 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2319 $this->db->rollback();
2325 $this->db->commit();
2344 $sql =
"SELECT rowid, date_debut, date_fin";
2345 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2346 $sql .=
" WHERE entity = ".((int) $conf->entity);
2347 $sql .=
" AND fk_user_author = ".((int) $fuser->id);
2349 dol_syslog(get_class($this).
"::periode_existe sql=".$sql);
2350 $result = $this->db->query($sql);
2352 $num_rows = $this->db->num_rows($result);
2355 if ($num_rows > 0) {
2356 $date_d_form = $date_debut;
2357 $date_f_form = $date_fin;
2359 while ($i < $num_rows) {
2360 $objp = $this->db->fetch_object($result);
2362 $date_d_req = $this->db->jdate($objp->date_debut);
2363 $date_f_req = $this->db->jdate($objp->date_fin);
2365 if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) {
2366 return $objp->rowid;
2377 $this->error = $this->db->lasterror();
2378 dol_syslog(get_class($this).
"::periode_existe Error ".$this->error, LOG_ERR);
2394 $users_validator = array();
2396 $sql =
"SELECT DISTINCT ur.fk_user";
2397 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2398 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2400 $sql .=
" SELECT DISTINCT ugu.fk_user";
2401 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2402 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2405 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2406 $result = $this->db->query($sql);
2408 $num_rows = $this->db->num_rows($result);
2410 while ($i < $num_rows) {
2411 $objp = $this->db->fetch_object($result);
2412 array_push($users_validator, $objp->fk_user);
2415 return $users_validator;
2417 $this->error = $this->db->lasterror();
2418 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2434 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2438 $outputlangs->load(
"trips");
2441 if (!empty($this->model_pdf)) {
2442 $modele = $this->model_pdf;
2444 $modele = $conf->global->EXPENSEREPORT_ADDON_PDF;
2448 if (!empty($modele)) {
2449 $modelpath =
"core/modules/expensereport/doc/";
2451 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2467 $sql =
"SELECT id, code, label";
2468 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2469 $sql .=
" WHERE active = ".((int) $active);
2470 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2471 $result = $this->db->query($sql);
2473 $num = $this->db->num_rows($result);
2476 $obj = $this->db->fetch_object($result);
2477 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2495 global $conf, $user;
2497 $this->nb = array();
2499 $sql =
"SELECT count(ex.rowid) as nb";
2500 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2501 $sql .=
" WHERE ex.fk_statut > 0";
2502 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2503 if (!$user->hasRight(
'expensereport',
'readall')) {
2504 $userchildids = $user->getAllChildIds(1);
2505 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2506 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2509 $resql = $this->db->query($sql);
2511 while ($obj = $this->db->fetch_object($resql)) {
2512 $this->nb[
"expensereports"] = $obj->nb;
2514 $this->db->free($resql);
2518 $this->error = $this->db->error();
2534 global $conf, $langs;
2542 $sql =
"SELECT ex.rowid, ex.date_valid";
2543 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2544 if ($option ==
'toapprove') {
2545 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2547 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2549 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2550 if (!$user->hasRight(
'expensereport',
'readall')) {
2551 $userchildids = $user->getAllChildIds(1);
2552 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2553 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2556 $resql = $this->db->query($sql);
2558 $langs->load(
"trips");
2561 if ($option ==
'toapprove') {
2562 $response->warning_delay = $conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2563 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2564 $response->labelShort = $langs->trans(
"ToApprove");
2567 $response->warning_delay = $conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2568 $response->label = $langs->trans(
"ExpenseReportsToPay");
2569 $response->labelShort = $langs->trans(
"StatusToPay");
2570 $response->url = DOL_URL_ROOT.
'/expensereport/list.php?mainmenu=hrm&statut='.
self::STATUS_APPROVED;
2574 while ($obj = $this->db->fetch_object($resql)) {
2575 $response->nbtodo++;
2577 if ($option ==
'toapprove') {
2578 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->approve->warning_delay)) {
2579 $response->nbtodolate++;
2582 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->payment->warning_delay)) {
2583 $response->nbtodolate++;
2591 $this->error = $this->db->error();
2607 if ($option ==
'toapprove' && $this->
status != 2) {
2610 if ($option ==
'topay' && $this->
status != 5) {
2615 if ($option ==
'toapprove') {
2616 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->approve->warning_delay);
2618 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->payment->warning_delay);
2629 $alreadydispatched = 0;
2631 $type =
'expense_report';
2633 $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);
2634 $resql = $this->db->query($sql);
2636 $obj = $this->db->fetch_object($resql);
2638 $alreadydispatched = $obj->nb;
2641 $this->error = $this->db->lasterror();
2645 if ($alreadydispatched) {
2658 $table =
'payment_expensereport';
2659 $field =
'fk_expensereport';
2661 $sql =
'SELECT sum(amount) as amount';
2662 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2663 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
2665 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2666 $resql = $this->db->query($sql);
2668 $obj = $this->db->fetch_object($resql);
2669 $this->db->free($resql);
2670 return (empty($obj->amount) ? 0 : $obj->amount);
2672 $this->error = $this->db->lasterror();
2687 global $langs, $db, $conf;
2695 $this->error = $langs->trans(
'ErrorBadParameterCat');
2700 $this->error = $langs->trans(
'ErrorBadParameterQty');
2704 $currentUser =
new User($db);
2705 $currentUser->fetch($this->fk_user);
2706 $currentUser->getrights(
'expensereport');
2710 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2711 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2712 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2713 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2714 $sql .=
" ORDER BY r.range_ik ASC";
2716 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2718 $result = $this->db->query($sql);
2721 if ($conf->global->EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR) {
2723 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2724 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2725 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2726 $sql.=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2727 $sql.=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2728 $sql.=
" AND tf.code = 'EX_KME' ";
2731 $resql = $this->db->query($sql);
2734 $obj = $this->db->fetch_object($resql);
2735 $cumulYearQty = $obj->cumul;
2738 $qty = $cumulYearQty + $qty;
2741 $num = $this->db->num_rows($result);
2744 for ($i = 0; $i < $num; $i++) {
2745 $obj = $this->db->fetch_object($result);
2751 for ($i = 0; $i < $num; $i++) {
2752 if ($i < ($num - 1)) {
2753 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i+1]->range_ik) {
2754 $coef = $ranges[$i]->coef;
2755 $offset = $ranges[$i]->ikoffset;
2758 if ($qty > $ranges[$i]->range_ik) {
2759 $coef = $ranges[$i]->coef;
2760 $offset = $ranges[$i]->ikoffset;
2767 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2771 $this->error = $this->db->error().
" sql=".$sql;
2788 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2790 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2791 $return .=
'<div class="info-box info-box-sm">';
2792 $return .=
'<span class="info-box-icon bg-infobox-action">';
2794 $return .=
'</span>';
2795 $return .=
'<div class="info-box-content">';
2796 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
2797 if ($selected >= 0) {
2798 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2800 if (array_key_exists(
'userauthor', $arraydata)) {
2801 $return .=
'<br><span class="info-box-label">'.$arraydata[
'userauthor']->getNomUrl(-1).
'</span>';
2803 if (property_exists($this,
'date_debut') && property_exists($this,
'date_fin')) {
2804 $return .=
'<br><span class="info-box-label">'.dol_print_date($this->date_debut,
'day').
'</span>';
2805 $return .=
' <span class="opacitymedium">'.$langs->trans(
"To").
'</span> ';
2806 $return .=
'<span class="info-box-label">'.dol_print_date($this->date_fin,
'day').
'</span>';
2808 if (method_exists($this,
'getLibStatut')) {
2809 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
2811 $return .=
'</div>';
2812 $return .=
'</div>';
2813 $return .=
'</div>';
2832 public $table_element =
'expensereport_det';
2857 public $fk_c_type_fees;
2862 public $fk_c_exp_tax_cat;
2872 public $fk_expensereport;
2874 public $type_fees_code;
2875 public $type_fees_libelle;
2876 public $type_fees_accountancy_code;
2879 public $projet_title;
2883 public $vat_src_code;
2885 public $localtax1_tx;
2886 public $localtax2_tx;
2887 public $localtax1_type;
2888 public $localtax2_type;
2893 public $total_localtax1;
2894 public $total_localtax2;
2900 public $fk_multicurrency;
2905 public $multicurrency_code;
2906 public $multicurrency_tx;
2907 public $multicurrency_total_ht;
2908 public $multicurrency_total_tva;
2909 public $multicurrency_total_ttc;
2914 public $fk_ecm_files;
2916 public $rule_warning_message;
2937 $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,';
2938 $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,';
2939 $sql .=
' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,';
2940 $sql .=
' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
2941 $sql .=
' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
2942 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det as fde';
2943 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
2944 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as pjt ON fde.fk_projet=pjt.rowid';
2945 $sql .=
' WHERE fde.rowid = '.((int) $rowid);
2947 $result = $this->db->query($sql);
2950 $objp = $this->db->fetch_object($result);
2952 $this->
rowid = $objp->rowid;
2953 $this->
id = $objp->rowid;
2954 $this->
ref = $objp->ref;
2955 $this->fk_expensereport = $objp->fk_expensereport;
2956 $this->comments = $objp->comments;
2957 $this->qty = $objp->qty;
2958 $this->date = $objp->date;
2959 $this->dates = $this->db->jdate($objp->date);
2960 $this->value_unit = $objp->value_unit;
2961 $this->fk_c_type_fees = $objp->fk_c_type_fees;
2962 $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
2963 $this->fk_projet = $objp->fk_project;
2964 $this->fk_project = $objp->fk_project;
2965 $this->type_fees_code = $objp->type_fees_code;
2966 $this->type_fees_libelle = $objp->type_fees_libelle;
2967 $this->projet_ref = $objp->projet_ref;
2968 $this->projet_title = $objp->projet_title;
2970 $this->
vatrate = $objp->vatrate;
2971 $this->vat_src_code = $objp->vat_src_code;
2972 $this->localtax1_tx = $objp->localtax1_tx;
2973 $this->localtax2_tx = $objp->localtax2_tx;
2974 $this->localtax1_type = $objp->localtax1_type;
2975 $this->localtax2_type = $objp->localtax2_type;
2977 $this->total_ht = $objp->total_ht;
2978 $this->total_tva = $objp->total_tva;
2979 $this->total_ttc = $objp->total_ttc;
2980 $this->total_localtax1 = $objp->total_localtax1;
2981 $this->total_localtax2 = $objp->total_localtax2;
2983 $this->fk_ecm_files = $objp->fk_ecm_files;
2985 $this->rule_warning_message = $objp->rule_warning_message;
2987 $this->db->free($result);
3003 public function insert($notrigger = 0, $fromaddline =
false)
3005 global $user, $conf;
3009 dol_syslog(
"ExpenseReportLine::Insert", LOG_DEBUG);
3012 $this->comments = trim($this->comments);
3013 if (empty($this->value_unit)) {
3014 $this->value_unit = 0;
3018 if (empty($this->fk_c_exp_tax_cat)) {
3019 $this->fk_c_exp_tax_cat = 0;
3024 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'expensereport_det';
3025 $sql .=
' (fk_expensereport, fk_c_type_fees, fk_projet,';
3026 $sql .=
' tva_tx, vat_src_code,';
3027 $sql .=
' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
3028 $sql .=
' comments, qty, value_unit,';
3029 $sql .=
' total_ht, total_tva, total_ttc,';
3030 $sql .=
' total_localtax1, total_localtax2,';
3031 $sql .=
' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)';
3032 $sql .=
" VALUES (".$this->db->escape($this->fk_expensereport).
",";
3033 $sql .=
" ".((int) $this->fk_c_type_fees).
",";
3034 $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')).
",";
3035 $sql .=
" ".((float) $this->
vatrate).
",";
3036 $sql .=
" '".$this->db->escape(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"',";
3037 $sql .=
" ".((float)
price2num($this->localtax1_tx)).
",";
3038 $sql .=
" ".((float)
price2num($this->localtax2_tx)).
",";
3039 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
3040 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
3041 $sql .=
" '".$this->db->escape($this->comments).
"',";
3042 $sql .=
" ".((float) $this->qty).
",";
3043 $sql .=
" ".((float) $this->value_unit).
",";
3044 $sql .=
" ".((float)
price2num($this->total_ht)).
",";
3045 $sql .=
" ".((float)
price2num($this->total_tva)).
",";
3046 $sql .=
" ".((float)
price2num($this->total_ttc)).
",";
3047 $sql .=
" ".((float)
price2num($this->total_localtax1)).
",";
3048 $sql .=
" ".((float)
price2num($this->total_localtax2)).
",";
3049 $sql .=
" '".$this->db->idate($this->date).
"',";
3050 $sql .=
" ".(empty($this->rule_warning_message) ?
'null' :
"'".$this->db->escape($this->rule_warning_message).
"'").
",";
3051 $sql .=
" ".((int) $this->fk_c_exp_tax_cat).
",";
3052 $sql .=
" ".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3055 $resql = $this->db->query($sql);
3057 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'expensereport_det');
3060 if (!$error && !$notrigger) {
3062 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_CREATE', $user);
3070 if (!$fromaddline) {
3072 $tmpparent->fetch($this->fk_expensereport);
3073 $result = $tmpparent->update_price(1);
3076 $this->error = $tmpparent->error;
3077 $this->errors = $tmpparent->errors;
3085 $this->db->commit();
3088 $this->error = $this->db->lasterror();
3089 dol_syslog(
"ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
3090 $this->db->rollback();
3107 $sql =
'SELECT SUM(d.total_ttc) as total_amount';
3108 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det d';
3109 $sql .=
' INNER JOIN '.MAIN_DB_PREFIX.
'expensereport e ON (d.fk_expensereport = e.rowid)';
3110 $sql .=
' WHERE e.fk_user_author = '.((int) $fk_user);
3111 if (!empty($this->
id)) {
3112 $sql .=
' AND d.rowid <> '.((int) $this->
id);
3114 $sql .=
' AND d.fk_c_type_fees = '.((int) $rule->fk_c_type_fees);
3115 if ($mode ==
'day' || $mode ==
'EX_DAY') {
3116 $sql .=
" AND d.date = '".dol_print_date($this->date,
'%Y-%m-%d').
"'";
3117 } elseif ($mode ==
'mon' || $mode ==
'EX_MON') {
3118 $sql .=
" AND DATE_FORMAT(d.date, '%Y-%m') = '".dol_print_date($this->date,
'%Y-%m').
"'";
3119 } elseif ($mode ==
'year' || $mode ==
'EX_YEA') {
3120 $sql .=
" AND DATE_FORMAT(d.date, '%Y') = '".dol_print_date($this->date,
'%Y').
"'";
3123 dol_syslog(
'ExpenseReportLine::getExpAmount');
3125 $resql = $this->db->query($sql);
3127 $num = $this->db->num_rows($resql);
3129 $obj = $this->db->fetch_object($resql);
3130 $amount = (float) $obj->total_amount;
3136 return $amount + $this->total_ttc;
3147 global $langs, $conf;
3152 $this->comments = trim($this->comments);
3154 $this->value_unit =
price2num($this->value_unit);
3155 if (empty($this->fk_c_exp_tax_cat)) {
3156 $this->fk_c_exp_tax_cat = 0;
3162 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport_det SET";
3163 $sql .=
" comments='".$this->db->escape($this->comments).
"'";
3164 $sql .=
", value_unit = ".((float) $this->value_unit);
3165 $sql .=
", qty=".((float) $this->qty);
3166 $sql .=
", date='".$this->db->idate($this->date).
"'";
3167 $sql .=
", total_ht=".((float)
price2num($this->total_ht,
'MT'));
3168 $sql .=
", total_tva=".((float)
price2num($this->total_tva,
'MT'));
3169 $sql .=
", total_ttc=".((float)
price2num($this->total_ttc,
'MT'));
3170 $sql .=
", total_localtax1=".((float)
price2num($this->total_localtax1,
'MT'));
3171 $sql .=
", total_localtax2=".((float)
price2num($this->total_localtax2,
'MT'));
3172 $sql .=
", tva_tx=".((float) $this->
vatrate);
3173 $sql .=
", vat_src_code='".$this->db->escape($this->vat_src_code).
"'";
3174 $sql .=
", localtax1_tx=".((float) $this->localtax1_tx);
3175 $sql .=
", localtax2_tx=".((float) $this->localtax2_tx);
3176 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
3177 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
3178 $sql .=
", rule_warning_message='".$this->db->escape($this->rule_warning_message).
"'";
3179 $sql .=
", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat);
3180 $sql .=
", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3181 if ($this->fk_c_type_fees) {
3182 $sql .=
", fk_c_type_fees = ".((int) $this->fk_c_type_fees);
3184 $sql .=
", fk_c_type_fees=null";
3186 if ($this->fk_project > 0) {
3187 $sql .=
", fk_projet=".((int) $this->fk_project);
3189 $sql .=
", fk_projet=null";
3191 $sql .=
" WHERE rowid = ".((int) ($this->
rowid ? $this->
rowid : $this->id));
3195 $resql = $this->db->query($sql);
3198 $result = $tmpparent->fetch($this->fk_expensereport);
3200 $result = $tmpparent->update_price(1);
3203 $this->error = $tmpparent->error;
3204 $this->errors = $tmpparent->errors;
3208 $this->error = $tmpparent->error;
3209 $this->errors = $tmpparent->errors;
3217 $this->db->commit();
3220 $this->error = $this->db->lasterror();
3221 dol_syslog(
"ExpenseReportLine::update Error ".$this->error, LOG_ERR);
3222 $this->db->rollback();
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
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.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
setErrorsFromObject($object)
setErrorsFromObject
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 a 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.
getDolGlobalString($key, $default='')
Return 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.
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.