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).
"'";
634 $sql .=
" WHERE d.rowid = ".((int) $id);
638 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
639 $resql = $this->db->query($sql);
641 $obj = $this->db->fetch_object($resql);
643 $this->
id = $obj->rowid;
644 $this->
ref = $obj->ref;
646 $this->entity = $obj->entity;
648 $this->total_ht = $obj->total_ht;
649 $this->total_tva = $obj->total_tva;
650 $this->total_ttc = $obj->total_ttc;
651 $this->localtax1 = $obj->total_localtax1;
652 $this->localtax2 = $obj->total_localtax2;
653 $this->total_localtax1 = $obj->total_localtax1;
654 $this->total_localtax2 = $obj->total_localtax2;
656 $this->note_public = $obj->note_public;
657 $this->note_private = $obj->note_private;
658 $this->detail_refuse = $obj->detail_refuse;
659 $this->detail_cancel = $obj->detail_cancel;
661 $this->date_debut = $this->db->jdate($obj->date_debut);
662 $this->date_fin = $this->db->jdate($obj->date_fin);
663 $this->date_valid = $this->db->jdate($obj->date_valid);
664 $this->date_approve = $this->db->jdate($obj->date_approve);
665 $this->date_create = $this->db->jdate($obj->date_create);
666 $this->date_modif = $this->db->jdate($obj->date_modif);
667 $this->date_refuse = $this->db->jdate($obj->date_refuse);
668 $this->date_cancel = $this->db->jdate($obj->date_cancel);
670 $this->fk_user_creat = $obj->fk_user_creat;
671 $this->fk_user_author = $obj->fk_user_author;
672 $this->fk_user_modif = $obj->fk_user_modif;
673 $this->fk_user_validator = $obj->fk_user_validator;
674 $this->fk_user_valid = $obj->fk_user_valid;
675 $this->fk_user_refuse = $obj->fk_user_refuse;
676 $this->fk_user_cancel = $obj->fk_user_cancel;
677 $this->fk_user_approve = $obj->fk_user_approve;
679 $user_author =
new User($this->db);
680 if ($this->fk_user_author > 0) {
681 $user_author->fetch($this->fk_user_author);
684 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
686 $user_approver =
new User($this->db);
687 if ($this->fk_user_approve > 0) {
688 $user_approver->fetch($this->fk_user_approve);
689 } elseif ($this->fk_user_validator > 0) {
690 $user_approver->fetch($this->fk_user_validator);
692 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
694 $this->fk_statut = $obj->status;
695 $this->
status = $obj->status;
696 $this->fk_c_paiement = $obj->fk_c_paiement;
697 $this->paid = $obj->paid;
699 if ($this->
status == self::STATUS_APPROVED || $this->
status == self::STATUS_CLOSED) {
700 $user_valid =
new User($this->db);
701 if ($this->fk_user_valid > 0) {
702 $user_valid->fetch($this->fk_user_valid);
704 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
716 $this->error = $this->db->lasterror();
732 public function set_paid($id, $fuser, $notrigger = 0)
735 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
736 return $this->
setPaid($id, $fuser, $notrigger);
747 public function setPaid($id, $fuser, $notrigger = 0)
752 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
753 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid=1";
756 dol_syslog(get_class($this).
"::setPaid", LOG_DEBUG);
757 $resql = $this->db->query($sql);
759 if ($this->db->affected_rows($resql)) {
762 $result = $this->
call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
774 $this->db->rollback();
775 $this->error = $this->db->error();
783 $this->db->rollback();
813 $labelStatus = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
814 $labelStatusShort = $langs->transnoentitiesnoconv($this->labelStatusShort[$status]);
816 $statuslogo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
818 $statusType = $statuslogo[$status];
820 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
834 $sql =
"SELECT f.rowid,";
835 $sql .=
" f.date_create as datec,";
836 $sql .=
" f.tms as date_modification,";
837 $sql .=
" f.date_valid as datev,";
838 $sql .=
" f.date_approve as datea,";
839 $sql .=
" f.fk_user_creat as fk_user_creation,";
840 $sql .=
" f.fk_user_author as fk_user_author,";
841 $sql .=
" f.fk_user_modif as fk_user_modification,";
842 $sql .=
" f.fk_user_valid,";
843 $sql .=
" f.fk_user_approve";
844 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
845 $sql .=
" WHERE f.rowid = ".((int) $id);
846 $sql .=
" AND f.entity = ".$conf->entity;
848 $resql = $this->db->query($sql);
850 if ($this->db->num_rows($resql)) {
851 $obj = $this->db->fetch_object($resql);
853 $this->
id = $obj->rowid;
855 $this->date_creation = $this->db->jdate($obj->datec);
856 $this->date_modification = $this->db->jdate($obj->date_modification);
857 $this->date_validation = $this->db->jdate($obj->datev);
858 $this->date_approbation = $this->db->jdate($obj->datea);
860 $this->user_creation_id = $obj->fk_user_author;
861 $this->user_creation_id = $obj->fk_user_creation;
862 $this->user_validation_id = $obj->fk_user_valid;
863 $this->user_modification_id = $obj->fk_user_modification;
864 $this->user_approve_id = $obj->fk_user_approve;
866 $this->db->free($resql);
883 global $user, $langs, $conf;
889 $this->
ref =
'SPECIMEN';
892 $this->date_create = $now;
893 $this->date_debut = $now;
894 $this->date_fin = $now;
895 $this->date_valid = $now;
896 $this->date_approve = $now;
901 $this->fk_statut = 5;
903 $this->fk_user_author = $user->id;
904 $this->fk_user_validator = $user->id;
905 $this->fk_user_valid = $user->id;
906 $this->fk_user_approve = $user->id;
908 $this->note_private =
'Private note';
909 $this->note_public =
'SPECIMEN';
912 while ($xnbp < $nbp) {
914 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
915 $line->date = ($now - 3600 * (1 + $xnbp));
916 $line->total_ht = 100;
917 $line->total_tva = 20;
918 $line->total_ttc = 120;
921 $line->value_unit = 120;
922 $line->fk_expensereport = 0;
923 $line->type_fees_code =
'TRA';
924 $line->fk_c_type_fees = $type_fees_id;
926 $line->projet_ref =
'ABC';
928 $this->lines[$xnbp] = $line;
931 $this->total_ht += $line->total_ht;
932 $this->total_tva += $line->total_tva;
933 $this->total_ttc += $line->total_ttc;
948 global $conf, $db, $langs;
950 $langs->load(
'trips');
952 if ($user->hasRight(
'expensereport',
'lire')) {
953 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
954 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
955 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
957 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
958 $result = $this->db->query($sql);
960 $num = $this->db->num_rows($result);
966 $objp = $this->db->fetch_object($result);
968 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
969 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
970 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
972 $result2 = $this->db->query($sql2);
973 $obj = $this->db->fetch_object($result2);
975 $objp->fk_user_author = $obj->fk_user_author;
976 $objp->ref = $obj->ref;
977 $objp->fk_c_expensereport_status = $obj->status;
978 $objp->rowid = $obj->rowid;
980 $total_HT = $total_HT + $objp->total_ht;
981 $total_TTC = $total_TTC + $objp->total_ttc;
982 $author =
new User($this->db);
983 $author->fetch($objp->fk_user_author);
986 print
'<td><a href="'.DOL_URL_ROOT.
'/expensereport/card.php?id='.$objp->rowid.
'">'.$objp->ref_num.
'</a></td>';
987 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
988 print
'<td>'.$author->getNomUrl(1).
'</td>';
989 print
'<td>'.$objp->comments.
'</td>';
990 print
'<td class="right">'.price($objp->total_ht).
'</td>';
991 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
992 print
'<td class="right">';
994 switch ($objp->fk_c_expensereport_status) {
996 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
999 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
1002 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
1005 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
1008 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
1025 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
1026 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
1027 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
1028 print
'<td> </td>';
1031 $this->error = $this->db->lasterror();
1050 $this->lines = array();
1052 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1053 $sql .=
" de.".$this->fk_element.
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1054 $sql .=
' de.tva_tx, de.vat_src_code,';
1055 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1056 $sql .=
' de.fk_ecm_files,';
1057 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1058 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1059 $sql .=
' ctf.code as code_type_fees, ctf.label as label_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1060 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1061 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as de';
1062 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1063 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1064 $sql .=
" WHERE de.".$this->fk_element.
" = ".((int) $this->
id);
1066 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1068 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1071 $resql = $this->db->query($sql);
1073 $num = $this->db->num_rows($resql);
1076 $objp = $this->db->fetch_object($resql);
1080 $deplig->rowid = $objp->rowid;
1081 $deplig->id = $objp->rowid;
1082 $deplig->comments = $objp->comments;
1083 $deplig->qty = $objp->qty;
1084 $deplig->value_unit = $objp->value_unit;
1085 $deplig->date = $objp->date;
1086 $deplig->dates = $this->db->jdate($objp->date);
1088 $deplig->fk_expensereport = $objp->fk_expensereport;
1089 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1090 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1091 $deplig->fk_projet = $objp->fk_project;
1092 $deplig->fk_project = $objp->fk_project;
1093 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1095 $deplig->total_ht = $objp->total_ht;
1096 $deplig->total_tva = $objp->total_tva;
1097 $deplig->total_ttc = $objp->total_ttc;
1098 $deplig->total_localtax1 = $objp->total_localtax1;
1099 $deplig->total_localtax2 = $objp->total_localtax2;
1101 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1102 $deplig->type_fees_libelle = $objp->label_type_fees;
1103 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1105 $deplig->tva_tx = $objp->tva_tx;
1106 $deplig->vatrate = $objp->tva_tx;
1107 $deplig->vat_src_code = $objp->vat_src_code;
1108 $deplig->localtax1_tx = $objp->localtax1_tx;
1109 $deplig->localtax2_tx = $objp->localtax2_tx;
1110 $deplig->localtax1_type = $objp->localtax1_type;
1111 $deplig->localtax2_type = $objp->localtax2_type;
1113 $deplig->projet_ref = $objp->ref_projet;
1114 $deplig->projet_title = $objp->title_projet;
1116 $deplig->rule_warning_message = $objp->rule_warning_message;
1118 $deplig->rang = $objp->rang;
1120 $this->lines[$i] = $deplig;
1124 $this->db->free($resql);
1127 $this->error = $this->db->lasterror();
1128 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1141 public function delete(
User $user =
null, $notrigger =
false)
1144 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1152 $result = $this->
call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1160 if (!$error && !empty($this->table_element_line)) {
1161 $tabletodelete = $this->table_element_line;
1163 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1164 if (!$this->db->query($sql)) {
1166 $this->error = $this->db->lasterror();
1167 $this->errors[] = $this->error;
1168 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1193 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1199 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1200 $res = $this->db->query($sql);
1203 $this->error = $this->db->lasterror();
1204 $this->errors[] = $this->error;
1205 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1221 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1222 $dir = $conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1223 $file = $dir.
"/".$ref.
".pdf";
1224 if (file_exists($file)) {
1228 $this->error =
'ErrorFailToDeleteFile';
1229 $this->errors[] = $this->error;
1230 $this->db->rollback();
1234 if (file_exists($dir)) {
1237 $this->error =
'ErrorFailToDeleteDir';
1238 $this->errors[] = $this->error;
1239 $this->db->rollback();
1247 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1248 $this->db->commit();
1251 $this->db->rollback();
1265 global $conf, $langs, $user;
1271 if ($this->
status == self::STATUS_VALIDATED) {
1272 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1276 $this->date_valid = $now;
1279 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
1284 if (empty($num) || $num < 0) {
1293 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1294 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1295 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1296 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1297 $sql .=
" fk_user_valid = ".((int) $user->id);
1298 $sql .=
" WHERE rowid = ".((int) $this->
id);
1300 $resql = $this->db->query($sql);
1302 if (!$error && !$notrigger) {
1304 $result = $this->
call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1312 $this->oldref = $this->ref;
1315 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1316 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1319 $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).
"'";
1320 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1321 $resql = $this->db->query($sql);
1324 $this->error = $this->db->lasterror();
1326 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1327 $sql .=
" WHERE filepath = 'expensereport/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
1328 $resql = $this->db->query($sql);
1331 $this->error = $this->db->lasterror();
1337 $dirsource = $conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1338 $dirdest = $conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1339 if (!$error && file_exists($dirsource)) {
1340 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1342 if (@rename($dirsource, $dirdest)) {
1345 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1346 foreach ($listoffiles as $fileentry) {
1347 $dirsource = $fileentry[
'name'];
1348 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1349 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1350 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1351 @rename($dirsource, $dirdest);
1364 if (empty($error)) {
1365 $this->db->commit();
1368 $this->db->rollback();
1369 $this->error = $this->db->error();
1373 $this->db->rollback();
1374 $this->error = $this->db->lasterror();
1390 $sql =
'SELECT date_debut';
1391 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1392 $sql .=
" WHERE rowid = ".((int) $this->
id);
1394 $result = $this->db->query($sql);
1396 $objp = $this->db->fetch_object($result);
1398 $this->date_debut = $this->db->jdate($objp->date_debut);
1400 if ($this->
status != self::STATUS_VALIDATED) {
1401 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1402 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1403 $sql .=
" WHERE rowid = ".((int) $this->
id);
1405 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1407 if ($this->db->query($sql)) {
1410 $this->error = $this->db->lasterror();
1414 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1433 $this->date_approve = $now;
1434 if ($this->
status != self::STATUS_APPROVED) {
1437 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1438 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1439 $sql .=
" date_approve='".$this->db->idate($this->date_approve).
"'";
1440 $sql .=
" WHERE rowid = ".((int) $this->
id);
1441 if ($this->db->query($sql)) {
1444 $result = $this->
call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1452 if (empty($error)) {
1453 $this->db->commit();
1456 $this->db->rollback();
1457 $this->error = $this->db->error();
1461 $this->db->rollback();
1462 $this->error = $this->db->lasterror();
1466 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1480 public function setDeny($fuser, $details, $notrigger = 0)
1486 if ($this->
status != self::STATUS_REFUSED) {
1487 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1488 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1489 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1490 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1491 $sql .=
" fk_user_approve = NULL";
1492 $sql .=
" WHERE rowid = ".((int) $this->
id);
1493 if ($this->db->query($sql)) {
1494 $this->fk_statut = 99;
1496 $this->fk_user_refuse = $fuser->id;
1497 $this->detail_refuse = $details;
1498 $this->date_refuse = $now;
1502 $result = $this->
call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1510 if (empty($error)) {
1511 $this->db->commit();
1514 $this->db->rollback();
1515 $this->error = $this->db->error();
1519 $this->db->rollback();
1520 $this->error = $this->db->lasterror();
1524 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1543 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1544 return $this->
setUnpaid($fuser, $notrigger);
1561 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1562 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1563 $sql .=
" WHERE rowid = ".((int) $this->
id);
1565 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1567 if ($this->db->query($sql)) {
1570 $result = $this->
call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1578 if (empty($error)) {
1579 $this->db->commit();
1582 $this->db->rollback();
1583 $this->error = $this->db->error();
1587 $this->db->rollback();
1588 $this->error = $this->db->error();
1592 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1611 $this->date_cancel = $this->db->idate(
dol_now());
1612 if ($this->
status != self::STATUS_CANCELED) {
1615 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1616 $sql .=
" SET fk_statut = ".self::STATUS_CANCELED.
", fk_user_cancel = ".((int) $fuser->id);
1617 $sql .=
", date_cancel='".$this->db->idate($this->date_cancel).
"'";
1618 $sql .=
", detail_cancel='".$this->db->escape($detail).
"'";
1619 $sql .=
" WHERE rowid = ".((int) $this->
id);
1621 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1623 if ($this->db->query($sql)) {
1626 $result = $this->
call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1634 if (empty($error)) {
1635 $this->db->commit();
1638 $this->db->rollback();
1639 $this->error = $this->db->error();
1643 $this->db->rollback();
1644 $this->error = $this->db->error();
1648 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1660 global $langs, $conf;
1661 $langs->load(
"trips");
1667 $classname = $conf->global->EXPENSEREPORT_ADDON;
1670 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1671 foreach ($dirmodels as $reldir) {
1672 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1675 $mybool |= @include_once $dir.$file;
1678 if ($mybool ===
false) {
1683 $obj =
new $classname();
1684 $numref = $obj->getNextValue($this);
1686 if ($numref !=
"") {
1689 $this->error = $obj->error;
1690 $this->errors = $obj->errors;
1695 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1709 global $conf, $langs;
1711 $langs->load(
'expensereport');
1713 $nofetch = !empty($params[
'nofetch']);
1714 $moretitle = $params[
'moretitle'] ??
'';
1717 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1718 if (isset($this->
status)) {
1719 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1722 $datas[
'picto'] .=
' - '.$moretitle;
1724 if (!empty($this->
ref)) {
1725 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1727 if (!empty($this->total_ht)) {
1728 $datas[
'total_ht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1730 if (!empty($this->total_tva)) {
1731 $datas[
'total_tva'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1733 if (!empty($this->total_ttc)) {
1734 $datas[
'total_ttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
1752 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1754 global $langs, $conf, $hookmanager;
1758 $url = DOL_URL_ROOT.
'/expensereport/card.php?id='.$this->id;
1766 'objecttype' => $this->element,
1767 'option' => $option,
1768 'moretitle' => $moretitle,
1771 $classfortooltip =
'classfortooltip';
1774 $classfortooltip =
'classforajaxtooltip';
1775 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1781 if ($option !=
'nolink') {
1783 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1784 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1785 $add_save_lastsearch_values = 1;
1787 if ($add_save_lastsearch_values) {
1788 $url .=
'&save_lastsearch_values=1';
1798 if (empty($notooltip)) {
1800 $label = $langs->trans(
"ShowExpenseReport");
1801 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1803 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
1804 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
1807 $linkstart =
'<a href="'.$url.
'"';
1808 $linkstart .= $linkclose.
'>';
1811 $result .= $linkstart;
1813 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
1815 if ($withpicto != 2) {
1816 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1818 $result .= $linkend;
1821 $hookmanager->initHooks(array($this->element .
'dao'));
1822 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
1823 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1825 $result = $hookmanager->resPrint;
1827 $result .= $hookmanager->resPrint;
1843 $this->total_ht = $this->total_ht + $ligne_total_ht;
1844 $this->total_tva = $this->total_tva + $ligne_total_tva;
1845 $this->total_ttc = $this->total_ht + $this->total_tva;
1847 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1848 $sql .=
" total_ht = ".$this->total_ht;
1849 $sql .=
" , total_ttc = ".$this->total_ttc;
1850 $sql .=
" , total_tva = ".$this->total_tva;
1851 $sql .=
" WHERE rowid = ".((int) $this->
id);
1853 $result = $this->db->query($sql);
1857 $this->error = $this->db->error();
1877 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)
1879 global $conf, $langs, $mysoc;
1881 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);
1883 if ($this->
status == self::STATUS_DRAFT) {
1887 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1888 $fk_c_type_fees = 0;
1890 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1891 $fk_c_exp_tax_cat = 0;
1893 if (empty($vatrate) || $vatrate < 0) {
1899 if (empty($fk_project)) {
1904 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1915 $seller->tva_assuj = 1;
1916 $buyer =
new Societe($this->db);
1922 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
1923 $vat_src_code = $reg[1];
1924 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
1926 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
1928 $tmp =
calcul_price_total($qty, $up, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
1930 $this->line->value_unit = $up;
1932 $this->line->vat_src_code = $vat_src_code;
1933 $this->line->vatrate =
price2num($vatrate);
1934 $this->line->localtax1_tx = $localtaxes_type[1];
1935 $this->line->localtax2_tx = $localtaxes_type[3];
1936 $this->line->localtax1_type = $localtaxes_type[0];
1937 $this->line->localtax2_type = $localtaxes_type[2];
1939 $this->line->total_ttc = $tmp[2];
1940 $this->line->total_ht = $tmp[0];
1941 $this->line->total_tva = $tmp[1];
1942 $this->line->total_localtax1 = $tmp[9];
1943 $this->line->total_localtax2 = $tmp[10];
1945 $this->line->fk_expensereport = $this->id;
1946 $this->line->qty = $qty;
1947 $this->line->date = $date;
1948 $this->line->fk_c_type_fees = $fk_c_type_fees;
1949 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
1950 $this->line->comments = $comments;
1951 $this->line->fk_projet = $fk_project;
1952 $this->line->fk_project = $fk_project;
1954 $this->line->fk_ecm_files = $fk_ecm_files;
1959 $result = $this->line->insert(0,
true);
1963 $this->db->commit();
1964 return $this->line->id;
1966 $this->db->rollback();
1970 $this->error = $this->line->error;
1971 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
1972 $this->db->rollback();
1976 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
1977 $this->error =
'ErrorExpenseNotDraft';
1991 global $user, $conf, $db, $langs, $mysoc;
1993 $langs->load(
'trips');
1996 if (!is_object($seller)) {
1998 $seller->tva_assuj = 1;
2002 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
2005 $rule_warning_message_tab = array();
2007 $current_total_ttc = $this->line->total_ttc;
2008 $new_current_total_ttc = $this->line->total_ttc;
2011 foreach ($rulestocheck as $rule) {
2012 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
2013 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
2015 $amount_to_test = $current_total_ttc;
2018 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
2020 if ($amount_to_test > $rule->amount) {
2023 if ($rule->restrictive) {
2024 $this->error =
'ExpenseReportConstraintViolationError';
2025 $this->errors[] = $this->error;
2027 $new_current_total_ttc -= $amount_to_test - $rule->amount;
2028 $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));
2030 $this->error =
'ExpenseReportConstraintViolationWarning';
2031 $this->errors[] = $this->error;
2033 $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));
2040 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
2042 if ($violation > 0) {
2043 $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);
2045 $this->line->value_unit = $tmp[5];
2046 $this->line->total_ttc = $tmp[2];
2047 $this->line->total_ht = $tmp[0];
2048 $this->line->total_tva = $tmp[1];
2049 $this->line->total_localtax1 = $tmp[9];
2050 $this->line->total_localtax2 = $tmp[10];
2067 global $conf, $mysoc;
2073 $userauthor =
new User($this->db);
2074 if ($userauthor->fetch($this->fk_user_author) <= 0) {
2075 $this->error =
'ErrorCantFetchUser';
2076 $this->errors[] =
'ErrorCantFetchUser';
2081 if (!is_object($seller)) {
2083 $seller->tva_assuj = 1;
2087 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2089 if (empty($range)) {
2090 $this->error =
'ErrorNoRangeAvailable';
2091 $this->errors[] =
'ErrorNoRangeAvailable';
2096 $ikoffset = $range->ikoffset;
2098 $ikoffset = $range->ikoffset / 12;
2103 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2104 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2106 $this->line->value_unit = $tmp[5];
2107 $this->line->total_ttc = $tmp[2];
2108 $this->line->total_ht = $tmp[0];
2109 $this->line->total_tva = $tmp[1];
2110 $this->line->total_localtax1 = $tmp[9];
2111 $this->line->total_localtax2 = $tmp[10];
2126 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2127 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2128 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2129 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2130 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2131 if (!empty($this->line->id)) {
2132 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2135 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2136 $resql = $this->db->query($sql);
2138 $num = $this->db->num_rows($resql);
2166 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)
2168 global $user, $mysoc;
2170 if ($this->
status == self::STATUS_DRAFT || $this->
status == self::STATUS_REFUSED) {
2178 $seller->tva_assuj = 1;
2179 $seller->localtax1_assuj = $mysoc->localtax1_assuj;
2180 $seller->localtax2_assuj = $mysoc->localtax1_assuj;
2181 $buyer =
new Societe($this->db);
2188 if (preg_match(
'/\((.*)\)/', $vatrate, $reg)) {
2189 $vat_src_code = $reg[1];
2190 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2192 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2194 $tmp =
calcul_price_total($qty, $value_unit, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2199 $tx_tva = $vatrate / 100;
2200 $tx_tva = $tx_tva + 1;
2203 $this->line->comments = $comments;
2204 $this->line->qty = $qty;
2205 $this->line->value_unit = $value_unit;
2206 $this->line->date = $date;
2208 $this->line->fk_expensereport = $expensereport_id;
2209 $this->line->fk_c_type_fees = $type_fees_id;
2210 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2211 $this->line->fk_projet = $projet_id;
2212 $this->line->fk_project = $projet_id;
2214 $this->line->vat_src_code = $vat_src_code;
2215 $this->line->vatrate =
price2num($vatrate);
2216 $this->line->localtax1_tx = $localtaxes_type[1];
2217 $this->line->localtax2_tx = $localtaxes_type[3];
2218 $this->line->localtax1_type = $localtaxes_type[0];
2219 $this->line->localtax2_type = $localtaxes_type[2];
2221 $this->line->total_ttc = $tmp[2];
2222 $this->line->total_ht = $tmp[0];
2223 $this->line->total_tva = $tmp[1];
2224 $this->line->total_localtax1 = $tmp[9];
2225 $this->line->total_localtax2 = $tmp[10];
2227 $this->line->fk_ecm_files = $fk_ecm_files;
2229 $this->line->id = ((int) $rowid);
2232 $sql =
"SELECT c.code as code_type_fees, c.label as label_type_fees";
2233 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2234 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2235 $resql = $this->db->query($sql);
2237 $objp_fees = $this->db->fetch_object($resql);
2238 $this->line->type_fees_code = $objp_fees->code_type_fees;
2239 $this->line->type_fees_libelle = $objp_fees->label_type_fees;
2240 $this->db->free($resql);
2244 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2245 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2246 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2247 $resql = $this->db->query($sql);
2249 $objp_projet = $this->db->fetch_object($resql);
2250 $this->line->projet_ref = $objp_projet->ref_projet;
2251 $this->line->projet_title = $objp_projet->title_projet;
2252 $this->db->free($resql);
2258 $result = $this->line->update($user);
2263 if (!$error && !$notrigger) {
2265 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_MODIFY', $user);
2273 $this->db->commit();
2276 $this->error = $this->line->error;
2277 $this->errors = $this->line->errors;
2278 $this->db->rollback();
2302 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2309 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2310 $sql .=
' WHERE rowid = '.((int) $rowid);
2312 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2313 $result = $this->db->query($sql);
2315 if (!$result || $error > 0) {
2316 $this->error = $this->db->error();
2317 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2318 $this->db->rollback();
2324 $this->db->commit();
2343 $sql =
"SELECT rowid, date_debut, date_fin";
2344 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2345 $sql .=
" WHERE entity = ".((int) $conf->entity);
2346 $sql .=
" AND fk_user_author = ".((int) $fuser->id);
2348 dol_syslog(get_class($this).
"::periode_existe sql=".$sql);
2349 $result = $this->db->query($sql);
2351 $num_rows = $this->db->num_rows($result);
2354 if ($num_rows > 0) {
2355 $date_d_form = $date_debut;
2356 $date_f_form = $date_fin;
2358 while ($i < $num_rows) {
2359 $objp = $this->db->fetch_object($result);
2361 $date_d_req = $this->db->jdate($objp->date_debut);
2362 $date_f_req = $this->db->jdate($objp->date_fin);
2364 if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) {
2365 return $objp->rowid;
2376 $this->error = $this->db->lasterror();
2377 dol_syslog(get_class($this).
"::periode_existe Error ".$this->error, LOG_ERR);
2393 $users_validator = array();
2395 $sql =
"SELECT DISTINCT ur.fk_user";
2396 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2397 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2399 $sql .=
" SELECT DISTINCT ugu.fk_user";
2400 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2401 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2404 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2405 $result = $this->db->query($sql);
2407 $num_rows = $this->db->num_rows($result);
2409 while ($i < $num_rows) {
2410 $objp = $this->db->fetch_object($result);
2411 array_push($users_validator, $objp->fk_user);
2414 return $users_validator;
2416 $this->error = $this->db->lasterror();
2417 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2433 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2437 $outputlangs->load(
"trips");
2440 if (!empty($this->model_pdf)) {
2441 $modele = $this->model_pdf;
2443 $modele = $conf->global->EXPENSEREPORT_ADDON_PDF;
2447 if (!empty($modele)) {
2448 $modelpath =
"core/modules/expensereport/doc/";
2450 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2466 $sql =
"SELECT id, code, label";
2467 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2468 $sql .=
" WHERE active = ".((int) $active);
2469 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2470 $result = $this->db->query($sql);
2472 $num = $this->db->num_rows($result);
2475 $obj = $this->db->fetch_object($result);
2476 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2494 global $conf, $user;
2496 $this->nb = array();
2498 $sql =
"SELECT count(ex.rowid) as nb";
2499 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2500 $sql .=
" WHERE ex.fk_statut > 0";
2501 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2502 if (!$user->hasRight(
'expensereport',
'readall')) {
2503 $userchildids = $user->getAllChildIds(1);
2504 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2505 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2508 $resql = $this->db->query($sql);
2510 while ($obj = $this->db->fetch_object($resql)) {
2511 $this->nb[
"expensereports"] = $obj->nb;
2513 $this->db->free($resql);
2517 $this->error = $this->db->error();
2533 global $conf, $langs;
2541 $sql =
"SELECT ex.rowid, ex.date_valid";
2542 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2543 if ($option ==
'toapprove') {
2544 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2546 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2548 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2549 if (!$user->hasRight(
'expensereport',
'readall')) {
2550 $userchildids = $user->getAllChildIds(1);
2551 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2552 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2555 $resql = $this->db->query($sql);
2557 $langs->load(
"trips");
2560 if ($option ==
'toapprove') {
2561 $response->warning_delay = $conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2562 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2563 $response->labelShort = $langs->trans(
"ToApprove");
2566 $response->warning_delay = $conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2567 $response->label = $langs->trans(
"ExpenseReportsToPay");
2568 $response->labelShort = $langs->trans(
"StatusToPay");
2569 $response->url = DOL_URL_ROOT.
'/expensereport/list.php?mainmenu=hrm&statut='.
self::STATUS_APPROVED;
2573 while ($obj = $this->db->fetch_object($resql)) {
2574 $response->nbtodo++;
2576 if ($option ==
'toapprove') {
2577 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->approve->warning_delay)) {
2578 $response->nbtodolate++;
2581 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->payment->warning_delay)) {
2582 $response->nbtodolate++;
2590 $this->error = $this->db->error();
2606 if ($option ==
'toapprove' && $this->
status != 2) {
2609 if ($option ==
'topay' && $this->
status != 5) {
2614 if ($option ==
'toapprove') {
2615 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->approve->warning_delay);
2617 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->payment->warning_delay);
2628 $alreadydispatched = 0;
2630 $type =
'expense_report';
2632 $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);
2633 $resql = $this->db->query($sql);
2635 $obj = $this->db->fetch_object($resql);
2637 $alreadydispatched = $obj->nb;
2640 $this->error = $this->db->lasterror();
2644 if ($alreadydispatched) {
2657 $table =
'payment_expensereport';
2658 $field =
'fk_expensereport';
2660 $sql =
'SELECT sum(amount) as amount';
2661 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2662 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
2664 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2665 $resql = $this->db->query($sql);
2667 $obj = $this->db->fetch_object($resql);
2668 $this->db->free($resql);
2669 return (empty($obj->amount) ? 0 : $obj->amount);
2671 $this->error = $this->db->lasterror();
2686 global $langs, $db, $conf;
2694 $this->error = $langs->trans(
'ErrorBadParameterCat');
2699 $this->error = $langs->trans(
'ErrorBadParameterQty');
2703 $currentUser =
new User($db);
2704 $currentUser->fetch($this->fk_user);
2705 $currentUser->getrights(
'expensereport');
2709 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2710 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2711 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2712 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2713 $sql .=
" ORDER BY r.range_ik ASC";
2715 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2717 $result = $this->db->query($sql);
2720 if ($conf->global->EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR) {
2722 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2723 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2724 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2725 $sql.=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2726 $sql.=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2727 $sql.=
" AND tf.code = 'EX_KME' ";
2730 $resql = $this->db->query($sql);
2733 $obj = $this->db->fetch_object($resql);
2734 $cumulYearQty = $obj->cumul;
2737 $qty = $cumulYearQty + $qty;
2740 $num = $this->db->num_rows($result);
2743 for ($i = 0; $i < $num; $i++) {
2744 $obj = $this->db->fetch_object($result);
2750 for ($i = 0; $i < $num; $i++) {
2751 if ($i < ($num - 1)) {
2752 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i+1]->range_ik) {
2753 $coef = $ranges[$i]->coef;
2754 $offset = $ranges[$i]->ikoffset;
2757 if ($qty > $ranges[$i]->range_ik) {
2758 $coef = $ranges[$i]->coef;
2759 $offset = $ranges[$i]->ikoffset;
2766 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2770 $this->error = $this->db->error().
" sql=".$sql;
2787 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2789 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2790 $return .=
'<div class="info-box info-box-sm">';
2791 $return .=
'<span class="info-box-icon bg-infobox-action">';
2793 $return .=
'</span>';
2794 $return .=
'<div class="info-box-content">';
2795 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
2796 if ($selected >= 0) {
2797 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2799 if (array_key_exists(
'userauthor', $arraydata)) {
2800 $return .=
'<br><span class="info-box-label">'.$arraydata[
'userauthor']->getNomUrl(-1).
'</span>';
2802 if (property_exists($this,
'date_debut') && property_exists($this,
'date_fin')) {
2803 $return .=
'<br><span class="info-box-label">'.dol_print_date($this->date_debut,
'day').
'</span>';
2804 $return .=
' <span class="opacitymedium">'.$langs->trans(
"To").
'</span> ';
2805 $return .=
'<span class="info-box-label">'.dol_print_date($this->date_fin,
'day').
'</span>';
2807 if (method_exists($this,
'getLibStatut')) {
2808 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
2810 $return .=
'</div>';
2811 $return .=
'</div>';
2812 $return .=
'</div>';
2831 public $table_element =
'expensereport_det';
2856 public $fk_c_type_fees;
2861 public $fk_c_exp_tax_cat;
2871 public $fk_expensereport;
2873 public $type_fees_code;
2874 public $type_fees_libelle;
2875 public $type_fees_accountancy_code;
2878 public $projet_title;
2882 public $vat_src_code;
2884 public $localtax1_tx;
2885 public $localtax2_tx;
2886 public $localtax1_type;
2887 public $localtax2_type;
2892 public $total_localtax1;
2893 public $total_localtax2;
2899 public $fk_multicurrency;
2904 public $multicurrency_code;
2905 public $multicurrency_tx;
2906 public $multicurrency_total_ht;
2907 public $multicurrency_total_tva;
2908 public $multicurrency_total_ttc;
2913 public $fk_ecm_files;
2915 public $rule_warning_message;
2936 $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,';
2937 $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,';
2938 $sql .=
' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,';
2939 $sql .=
' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
2940 $sql .=
' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
2941 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det as fde';
2942 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
2943 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as pjt ON fde.fk_projet=pjt.rowid';
2944 $sql .=
' WHERE fde.rowid = '.((int) $rowid);
2946 $result = $this->db->query($sql);
2949 $objp = $this->db->fetch_object($result);
2951 $this->
rowid = $objp->rowid;
2952 $this->
id = $objp->rowid;
2953 $this->
ref = $objp->ref;
2954 $this->fk_expensereport = $objp->fk_expensereport;
2955 $this->comments = $objp->comments;
2956 $this->qty = $objp->qty;
2957 $this->date = $objp->date;
2958 $this->dates = $this->db->jdate($objp->date);
2959 $this->value_unit = $objp->value_unit;
2960 $this->fk_c_type_fees = $objp->fk_c_type_fees;
2961 $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
2962 $this->fk_projet = $objp->fk_project;
2963 $this->fk_project = $objp->fk_project;
2964 $this->type_fees_code = $objp->type_fees_code;
2965 $this->type_fees_libelle = $objp->type_fees_libelle;
2966 $this->projet_ref = $objp->projet_ref;
2967 $this->projet_title = $objp->projet_title;
2969 $this->
vatrate = $objp->vatrate;
2970 $this->vat_src_code = $objp->vat_src_code;
2971 $this->localtax1_tx = $objp->localtax1_tx;
2972 $this->localtax2_tx = $objp->localtax2_tx;
2973 $this->localtax1_type = $objp->localtax1_type;
2974 $this->localtax2_type = $objp->localtax2_type;
2976 $this->total_ht = $objp->total_ht;
2977 $this->total_tva = $objp->total_tva;
2978 $this->total_ttc = $objp->total_ttc;
2979 $this->total_localtax1 = $objp->total_localtax1;
2980 $this->total_localtax2 = $objp->total_localtax2;
2982 $this->fk_ecm_files = $objp->fk_ecm_files;
2984 $this->rule_warning_message = $objp->rule_warning_message;
2986 $this->db->free($result);
3002 public function insert($notrigger = 0, $fromaddline =
false)
3004 global $user, $conf;
3008 dol_syslog(
"ExpenseReportLine::Insert", LOG_DEBUG);
3011 $this->comments = trim($this->comments);
3012 if (empty($this->value_unit)) {
3013 $this->value_unit = 0;
3017 if (empty($this->fk_c_exp_tax_cat)) {
3018 $this->fk_c_exp_tax_cat = 0;
3023 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'expensereport_det';
3024 $sql .=
' (fk_expensereport, fk_c_type_fees, fk_projet,';
3025 $sql .=
' tva_tx, vat_src_code,';
3026 $sql .=
' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
3027 $sql .=
' comments, qty, value_unit,';
3028 $sql .=
' total_ht, total_tva, total_ttc,';
3029 $sql .=
' total_localtax1, total_localtax2,';
3030 $sql .=
' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)';
3031 $sql .=
" VALUES (".$this->db->escape($this->fk_expensereport).
",";
3032 $sql .=
" ".((int) $this->fk_c_type_fees).
",";
3033 $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')).
",";
3034 $sql .=
" ".((float) $this->
vatrate).
",";
3035 $sql .=
" '".$this->db->escape(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"',";
3036 $sql .=
" ".((float)
price2num($this->localtax1_tx)).
",";
3037 $sql .=
" ".((float)
price2num($this->localtax2_tx)).
",";
3038 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
3039 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
3040 $sql .=
" '".$this->db->escape($this->comments).
"',";
3041 $sql .=
" ".((float) $this->qty).
",";
3042 $sql .=
" ".((float) $this->value_unit).
",";
3043 $sql .=
" ".((float)
price2num($this->total_ht)).
",";
3044 $sql .=
" ".((float)
price2num($this->total_tva)).
",";
3045 $sql .=
" ".((float)
price2num($this->total_ttc)).
",";
3046 $sql .=
" ".((float)
price2num($this->total_localtax1)).
",";
3047 $sql .=
" ".((float)
price2num($this->total_localtax2)).
",";
3048 $sql .=
" '".$this->db->idate($this->date).
"',";
3049 $sql .=
" ".(empty($this->rule_warning_message) ?
'null' :
"'".$this->db->escape($this->rule_warning_message).
"'").
",";
3050 $sql .=
" ".((int) $this->fk_c_exp_tax_cat).
",";
3051 $sql .=
" ".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3054 $resql = $this->db->query($sql);
3056 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'expensereport_det');
3059 if (!$error && !$notrigger) {
3061 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_CREATE', $user);
3069 if (!$fromaddline) {
3071 $tmpparent->fetch($this->fk_expensereport);
3072 $result = $tmpparent->update_price(1);
3075 $this->error = $tmpparent->error;
3076 $this->errors = $tmpparent->errors;
3084 $this->db->commit();
3087 $this->error = $this->db->lasterror();
3088 dol_syslog(
"ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
3089 $this->db->rollback();
3106 $sql =
'SELECT SUM(d.total_ttc) as total_amount';
3107 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det d';
3108 $sql .=
' INNER JOIN '.MAIN_DB_PREFIX.
'expensereport e ON (d.fk_expensereport = e.rowid)';
3109 $sql .=
' WHERE e.fk_user_author = '.((int) $fk_user);
3110 if (!empty($this->
id)) {
3111 $sql .=
' AND d.rowid <> '.((int) $this->
id);
3113 $sql .=
' AND d.fk_c_type_fees = '.((int) $rule->fk_c_type_fees);
3114 if ($mode ==
'day' || $mode ==
'EX_DAY') {
3115 $sql .=
" AND d.date = '".dol_print_date($this->date,
'%Y-%m-%d').
"'";
3116 } elseif ($mode ==
'mon' || $mode ==
'EX_MON') {
3117 $sql .=
" AND DATE_FORMAT(d.date, '%Y-%m') = '".dol_print_date($this->date,
'%Y-%m').
"'";
3118 } elseif ($mode ==
'year' || $mode ==
'EX_YEA') {
3119 $sql .=
" AND DATE_FORMAT(d.date, '%Y') = '".dol_print_date($this->date,
'%Y').
"'";
3122 dol_syslog(
'ExpenseReportLine::getExpAmount');
3124 $resql = $this->db->query($sql);
3126 $num = $this->db->num_rows($resql);
3128 $obj = $this->db->fetch_object($resql);
3129 $amount = (float) $obj->total_amount;
3135 return $amount + $this->total_ttc;
3146 global $langs, $conf;
3151 $this->comments = trim($this->comments);
3153 $this->value_unit =
price2num($this->value_unit);
3154 if (empty($this->fk_c_exp_tax_cat)) {
3155 $this->fk_c_exp_tax_cat = 0;
3161 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport_det SET";
3162 $sql .=
" comments='".$this->db->escape($this->comments).
"'";
3163 $sql .=
", value_unit = ".((float) $this->value_unit);
3164 $sql .=
", qty=".((float) $this->qty);
3165 $sql .=
", date='".$this->db->idate($this->date).
"'";
3166 $sql .=
", total_ht=".((float)
price2num($this->total_ht,
'MT'));
3167 $sql .=
", total_tva=".((float)
price2num($this->total_tva,
'MT'));
3168 $sql .=
", total_ttc=".((float)
price2num($this->total_ttc,
'MT'));
3169 $sql .=
", total_localtax1=".((float)
price2num($this->total_localtax1,
'MT'));
3170 $sql .=
", total_localtax2=".((float)
price2num($this->total_localtax2,
'MT'));
3171 $sql .=
", tva_tx=".((float) $this->
vatrate);
3172 $sql .=
", vat_src_code='".$this->db->escape($this->vat_src_code).
"'";
3173 $sql .=
", localtax1_tx=".((float) $this->localtax1_tx);
3174 $sql .=
", localtax2_tx=".((float) $this->localtax2_tx);
3175 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
3176 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
3177 $sql .=
", rule_warning_message='".$this->db->escape($this->rule_warning_message).
"'";
3178 $sql .=
", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat);
3179 $sql .=
", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3180 if ($this->fk_c_type_fees) {
3181 $sql .=
", fk_c_type_fees = ".((int) $this->fk_c_type_fees);
3183 $sql .=
", fk_c_type_fees=null";
3185 if ($this->fk_project > 0) {
3186 $sql .=
", fk_projet=".((int) $this->fk_project);
3188 $sql .=
", fk_projet=null";
3190 $sql .=
" WHERE rowid = ".((int) ($this->
rowid ? $this->
rowid : $this->id));
3194 $resql = $this->db->query($sql);
3197 $result = $tmpparent->fetch($this->fk_expensereport);
3199 $result = $tmpparent->update_price(1);
3202 $this->error = $tmpparent->error;
3203 $this->errors = $tmpparent->errors;
3207 $this->error = $tmpparent->error;
3208 $this->errors = $tmpparent->errors;
3216 $this->db->commit();
3219 $this->error = $this->db->lasterror();
3220 dol_syslog(
"ExpenseReportLine::update Error ".$this->error, LOG_ERR);
3221 $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.