28require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
29require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
30require_once DOL_DOCUMENT_ROOT.
'/expensereport/class/expensereport_ik.class.php';
31require_once DOL_DOCUMENT_ROOT.
'/expensereport/class/expensereport_rule.class.php';
41 public $element =
'expensereport';
46 public $table_element =
'expensereport';
51 public $table_element_line =
'expensereport_det';
56 public $fk_element =
'fk_expensereport';
61 public $picto =
'trip';
66 public $lines = array();
92 public $fk_c_paiement;
93 public $modepaymentid;
97 public $user_author_infos;
98 public $user_validator_infos;
100 public $rule_warning_message;
110 public $fk_user_creat;
115 public $fk_user_author;
119 public $fk_user_modif;
123 public $detail_refuse;
124 public $fk_user_refuse;
128 public $detail_cancel;
133 public $fk_user_cancel;
138 public $fk_user_validator;
157 public $fk_user_valid;
158 public $user_valid_infos;
161 public $date_approve;
162 public $fk_user_approve;
165 public $user_paid_infos;
170 public $statuts = array();
171 public $statuts_short = array();
172 public $statuts_logo;
178 public $fk_multicurrency;
183 public $multicurrency_code;
184 public $multicurrency_tx;
185 public $multicurrency_total_ht;
186 public $multicurrency_total_tva;
187 public $multicurrency_total_ttc;
220 public $fields = array(
221 'rowid' =>array(
'type'=>
'integer',
'label'=>
'ID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
222 'ref' =>array(
'type'=>
'varchar(50)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'showoncombobox'=>1,
'position'=>15),
223 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>20),
224 'ref_number_int' =>array(
'type'=>
'integer',
'label'=>
'Ref number int',
'enabled'=>1,
'visible'=>-1,
'position'=>25),
225 'ref_ext' =>array(
'type'=>
'integer',
'label'=>
'Ref ext',
'enabled'=>1,
'visible'=>-1,
'position'=>30),
226 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total ht',
'enabled'=>1,
'visible'=>-1,
'position'=>35),
227 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total tva',
'enabled'=>1,
'visible'=>-1,
'position'=>40),
228 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax1',
'enabled'=>1,
'visible'=>-1,
'position'=>45),
229 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax2',
'enabled'=>1,
'visible'=>-1,
'position'=>50),
230 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total ttc',
'enabled'=>1,
'visible'=>-1,
'position'=>55),
231 'date_debut' =>array(
'type'=>
'date',
'label'=>
'Date debut',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>60),
232 'date_fin' =>array(
'type'=>
'date',
'label'=>
'Date fin',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>65),
233 'date_valid' =>array(
'type'=>
'datetime',
'label'=>
'Date valid',
'enabled'=>1,
'visible'=>-1,
'position'=>75),
234 'date_approve' =>array(
'type'=>
'datetime',
'label'=>
'Date approve',
'enabled'=>1,
'visible'=>-1,
'position'=>80),
235 'date_refuse' =>array(
'type'=>
'datetime',
'label'=>
'Date refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>85),
236 'date_cancel' =>array(
'type'=>
'datetime',
'label'=>
'Date cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>90),
237 'fk_user_author' =>array(
'type'=>
'integer',
'label'=>
'Fk user author',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>100),
238 'fk_user_modif' =>array(
'type'=>
'integer',
'label'=>
'Fk user modif',
'enabled'=>1,
'visible'=>-1,
'position'=>105),
239 'fk_user_valid' =>array(
'type'=>
'integer',
'label'=>
'Fk user valid',
'enabled'=>1,
'visible'=>-1,
'position'=>110),
240 'fk_user_validator' =>array(
'type'=>
'integer',
'label'=>
'Fk user validator',
'enabled'=>1,
'visible'=>-1,
'position'=>115),
241 'fk_user_approve' =>array(
'type'=>
'integer',
'label'=>
'Fk user approve',
'enabled'=>1,
'visible'=>-1,
'position'=>120),
242 'fk_user_refuse' =>array(
'type'=>
'integer',
'label'=>
'Fk user refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>125),
243 'fk_user_cancel' =>array(
'type'=>
'integer',
'label'=>
'Fk user cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>130),
244 'fk_c_paiement' =>array(
'type'=>
'integer',
'label'=>
'Fk c paiement',
'enabled'=>1,
'visible'=>-1,
'position'=>140),
245 'paid' =>array(
'type'=>
'integer',
'label'=>
'Paid',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>145),
246 'note_public' =>array(
'type'=>
'html',
'label'=>
'Note public',
'enabled'=>1,
'visible'=>0,
'position'=>150),
247 'note_private' =>array(
'type'=>
'html',
'label'=>
'Note private',
'enabled'=>1,
'visible'=>0,
'position'=>155),
248 'detail_refuse' =>array(
'type'=>
'varchar(255)',
'label'=>
'Detail refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>160),
249 'detail_cancel' =>array(
'type'=>
'varchar(255)',
'label'=>
'Detail cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>165),
250 'integration_compta' =>array(
'type'=>
'integer',
'label'=>
'Integration compta',
'enabled'=>1,
'visible'=>-1,
'position'=>170),
251 'fk_bank_account' =>array(
'type'=>
'integer',
'label'=>
'Fk bank account',
'enabled'=>1,
'visible'=>-1,
'position'=>175),
252 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'Fk multicurrency',
'enabled'=>1,
'visible'=>-1,
'position'=>185),
253 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'Multicurrency code',
'enabled'=>1,
'visible'=>-1,
'position'=>190),
254 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency tx',
'enabled'=>1,
'visible'=>-1,
'position'=>195),
255 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total ht',
'enabled'=>1,
'visible'=>-1,
'position'=>200),
256 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total tva',
'enabled'=>1,
'visible'=>-1,
'position'=>205),
257 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total ttc',
'enabled'=>1,
'visible'=>-1,
'position'=>210),
258 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>220),
259 'date_create' =>array(
'type'=>
'datetime',
'label'=>
'Date create',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>300),
260 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'Tms',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>305),
261 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-1,
'position'=>1000),
262 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'Model pdf',
'enabled'=>1,
'visible'=>0,
'position'=>1010),
263 'fk_statut' =>array(
'type'=>
'integer',
'label'=>
'Fk statut',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>500),
275 $this->total_ttc = 0;
276 $this->total_tva = 0;
277 $this->total_localtax1 = 0;
278 $this->total_localtax2 = 0;
279 $this->localtax1 = 0;
280 $this->localtax2 = 0;
281 $this->modepaymentid = 0;
284 $this->statuts_short = array(0 =>
'Draft', 2 =>
'Validated', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
285 $this->statuts = array(0 =>
'Draft', 2 =>
'ValidatedWaitingApproval', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
286 $this->statuts_logo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
296 public function create($user, $notrigger = 0)
298 global $conf, $langs;
305 if (empty($this->date_debut) || empty($this->date_fin)) {
306 $this->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
'Date'));
310 $fuserid = $this->fk_user_author;
311 if (empty($fuserid)) {
312 $fuserid = $user->id;
317 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
" (";
320 $sql .=
",total_ttc";
321 $sql .=
",total_tva";
322 $sql .=
",date_debut";
324 $sql .=
",date_create";
325 $sql .=
",fk_user_creat";
326 $sql .=
",fk_user_author";
327 $sql .=
",fk_user_validator";
328 $sql .=
",fk_user_approve";
329 $sql .=
",fk_user_modif";
330 $sql .=
",fk_statut";
331 $sql .=
",fk_c_paiement";
333 $sql .=
",note_public";
334 $sql .=
",note_private";
338 $sql .=
", ".price2num($this->total_ht,
'MT');
339 $sql .=
", ".price2num($this->total_ttc,
'MT');
340 $sql .=
", ".price2num($this->total_tva,
'MT');
341 $sql .=
", '".$this->db->idate($this->date_debut).
"'";
342 $sql .=
", '".$this->db->idate($this->date_fin).
"'";
343 $sql .=
", '".$this->db->idate($now).
"'";
344 $sql .=
", ".((int) $user->id);
345 $sql .=
", ".((int) $fuserid);
346 $sql .=
", ".($this->fk_user_validator > 0 ? ((int) $this->fk_user_validator) :
"null");
347 $sql .=
", ".($this->fk_user_approve > 0 ? ((int) $this->fk_user_approve) :
"null");
348 $sql .=
", ".($this->fk_user_modif > 0 ? ((int) $this->fk_user_modif) :
"null");
349 $sql .=
", ".($this->fk_statut > 1 ? ((int) $this->fk_statut) : 0);
350 $sql .=
", ".($this->modepaymentid ? ((int) $this->modepaymentid) :
"null");
352 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
"null");
353 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
"null");
354 $sql .=
", ".((int) $conf->entity);
357 $result = $this->db->query($sql);
359 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
360 $this->
ref =
'(PROV'.$this->id.
')';
362 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
" SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
363 $resql = $this->db->query($sql);
365 $this->error = $this->db->lasterror();
370 if (is_array($this->lines) && count($this->lines) > 0) {
371 foreach ($this->lines as $line) {
374 if (!is_object($line)) {
375 $line = (object) $line;
377 $newndfline->fk_expensereport = $line->fk_expensereport;
378 $newndfline->fk_c_type_fees = $line->fk_c_type_fees;
379 $newndfline->fk_project = $line->fk_project;
380 $newndfline->vatrate = $line->vatrate;
381 $newndfline->vat_src_code = $line->vat_src_code;
382 $newndfline->localtax1_tx = $line->localtax1_tx;
383 $newndfline->localtax2_tx = $line->localtax2_tx;
384 $newndfline->localtax1_type = $line->localtax1_type;
385 $newndfline->localtax2_type = $line->localtax2_type;
386 $newndfline->comments = $line->comments;
387 $newndfline->qty = $line->qty;
388 $newndfline->value_unit = $line->value_unit;
389 $newndfline->total_ht = $line->total_ht;
390 $newndfline->total_ttc = $line->total_ttc;
391 $newndfline->total_tva = $line->total_tva;
392 $newndfline->total_localtax1 = $line->total_localtax1;
393 $newndfline->total_localtax2 = $line->total_localtax2;
394 $newndfline->date = $line->date;
395 $newndfline->rule_warning_message = $line->rule_warning_message;
396 $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat;
397 $newndfline->fk_ecm_files = $line->fk_ecm_files;
402 $newndfline->fk_expensereport = $this->id;
403 $result = $newndfline->insert();
405 $this->error = $newndfline->error;
406 $this->errors = $newndfline->errors;
426 $result = $this->
call_trigger(
'EXPENSE_REPORT_CREATE', $user);
438 $this->db->rollback();
442 $this->db->rollback();
446 dol_syslog(get_class($this).
"::create error ".$this->error, LOG_ERR);
447 $this->db->rollback();
451 $this->error = $this->db->lasterror().
" sql=".$sql;
452 $this->db->rollback();
470 if (empty($fk_user_author)) {
471 $fk_user_author = $user->id;
481 $objFrom = clone $this;
486 $this->fk_statut = 0;
489 $this->fk_user_creat = $user->id;
490 $this->fk_user_author = $fk_user_author;
491 $this->fk_user_valid =
'';
492 $this->date_create =
'';
493 $this->date_creation =
'';
494 $this->date_validation =
'';
497 if (is_array($this->lines) && count($this->lines) > 0) {
498 foreach ($this->lines as $key => $line) {
499 $this->lines[$key]->fk_ecm_files = 0;
504 $this->context[
'createfromclone'] =
'createfromclone';
505 $result = $this->
create($user);
512 if (is_object($hookmanager)) {
513 $parameters = array(
'objFrom'=>$objFrom);
515 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
523 unset($this->context[
'createfromclone']);
530 $this->db->rollback();
544 public function update($user, $notrigger = 0, $userofexpensereport =
null)
551 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
552 $sql .=
" total_ht = ".$this->total_ht;
553 $sql .=
" , total_ttc = ".$this->total_ttc;
554 $sql .=
" , total_tva = ".$this->total_tva;
555 $sql .=
" , date_debut = '".$this->db->idate($this->date_debut).
"'";
556 $sql .=
" , date_fin = '".$this->db->idate($this->date_fin).
"'";
557 if ($userofexpensereport && is_object($userofexpensereport)) {
558 $sql .=
" , fk_user_author = ".($userofexpensereport->id > 0 ? $userofexpensereport->id :
"null");
560 $sql .=
" , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator :
"null");
561 $sql .=
" , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid :
"null");
562 $sql .=
" , fk_user_approve = ".($this->fk_user_approve > 0 ? $this->fk_user_approve :
"null");
563 $sql .=
" , fk_user_modif = ".$user->id;
564 $sql .=
" , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut :
'0');
565 $sql .=
" , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement :
"null");
566 $sql .=
" , note_public = ".(!empty($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"''");
567 $sql .=
" , note_private = ".(!empty($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"''");
568 $sql .=
" , detail_refuse = ".(!empty($this->detail_refuse) ?
"'".$this->db->escape($this->detail_refuse).
"'" :
"''");
569 $sql .=
" WHERE rowid = ".((int) $this->
id);
571 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
572 $result = $this->db->query($sql);
576 $result = $this->
call_trigger(
'EXPENSE_REPORT_MODIFY', $user);
588 $this->db->rollback();
589 $this->error = $this->db->error();
593 $this->db->rollback();
594 $this->error = $this->db->error();
606 public function fetch($id, $ref =
'')
610 $sql =
"SELECT d.rowid, d.entity, d.ref, d.note_public, d.note_private,";
611 $sql .=
" d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,";
612 $sql .=
" d.date_refuse, d.date_cancel,";
613 $sql .=
" d.total_ht, d.total_ttc, d.total_tva,";
614 $sql .=
" d.localtax1 as total_localtax1, d.localtax2 as total_localtax2,";
615 $sql .=
" d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,";
616 $sql .=
" d.fk_user_creat, d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
617 $sql .=
" d.fk_user_valid, d.fk_user_approve,";
618 $sql .=
" d.fk_statut as status, d.fk_c_paiement, d.paid";
619 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as d";
621 $sql .=
" WHERE d.ref = '".$this->db->escape($ref).
"'";
623 $sql .=
" WHERE d.rowid = ".((int) $id);
627 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
628 $resql = $this->db->query($sql);
630 $obj = $this->db->fetch_object($resql);
632 $this->
id = $obj->rowid;
633 $this->
ref = $obj->ref;
635 $this->entity = $obj->entity;
637 $this->total_ht = $obj->total_ht;
638 $this->total_tva = $obj->total_tva;
639 $this->total_ttc = $obj->total_ttc;
640 $this->localtax1 = $obj->total_localtax1;
641 $this->localtax2 = $obj->total_localtax2;
642 $this->total_localtax1 = $obj->total_localtax1;
643 $this->total_localtax2 = $obj->total_localtax2;
645 $this->note_public = $obj->note_public;
646 $this->note_private = $obj->note_private;
647 $this->detail_refuse = $obj->detail_refuse;
648 $this->detail_cancel = $obj->detail_cancel;
650 $this->date_debut = $this->db->jdate($obj->date_debut);
651 $this->date_fin = $this->db->jdate($obj->date_fin);
652 $this->date_valid = $this->db->jdate($obj->date_valid);
653 $this->date_approve = $this->db->jdate($obj->date_approve);
654 $this->date_create = $this->db->jdate($obj->date_create);
655 $this->date_modif = $this->db->jdate($obj->date_modif);
656 $this->date_refuse = $this->db->jdate($obj->date_refuse);
657 $this->date_cancel = $this->db->jdate($obj->date_cancel);
659 $this->fk_user_creat = $obj->fk_user_creat;
660 $this->fk_user_author = $obj->fk_user_author;
661 $this->fk_user_modif = $obj->fk_user_modif;
662 $this->fk_user_validator = $obj->fk_user_validator;
663 $this->fk_user_valid = $obj->fk_user_valid;
664 $this->fk_user_refuse = $obj->fk_user_refuse;
665 $this->fk_user_cancel = $obj->fk_user_cancel;
666 $this->fk_user_approve = $obj->fk_user_approve;
668 $user_author =
new User($this->db);
669 if ($this->fk_user_author > 0) {
670 $user_author->fetch($this->fk_user_author);
673 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
675 $user_approver =
new User($this->db);
676 if ($this->fk_user_approve > 0) {
677 $user_approver->fetch($this->fk_user_approve);
678 } elseif ($this->fk_user_validator > 0) {
679 $user_approver->fetch($this->fk_user_validator);
681 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
683 $this->fk_statut = $obj->status;
684 $this->status = $obj->status;
685 $this->fk_c_paiement = $obj->fk_c_paiement;
686 $this->paid = $obj->paid;
688 if ($this->status == self::STATUS_APPROVED || $this->status == self::STATUS_CLOSED) {
689 $user_valid =
new User($this->db);
690 if ($this->fk_user_valid > 0) {
691 $user_valid->fetch($this->fk_user_valid);
693 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
705 $this->error = $this->db->lasterror();
721 public function set_paid($id, $fuser, $notrigger = 0)
724 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
725 return $this->
setPaid($id, $fuser, $notrigger);
736 public function setPaid($id, $fuser, $notrigger = 0)
741 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
742 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid=1";
745 dol_syslog(get_class($this).
"::set_paid", LOG_DEBUG);
746 $resql = $this->db->query($sql);
748 if ($this->db->affected_rows($resql)) {
751 $result = $this->
call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
763 $this->db->rollback();
764 $this->error = $this->db->error();
772 $this->db->rollback();
786 return $this->
LibStatut($this->status, $mode);
802 $labelStatus = $langs->transnoentitiesnoconv($this->statuts[$status]);
803 $labelStatusShort = $langs->transnoentitiesnoconv($this->statuts_short[$status]);
805 $statusType = $this->statuts_logo[$status];
807 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
821 $sql =
"SELECT f.rowid,";
822 $sql .=
" f.date_create as datec,";
823 $sql .=
" f.tms as date_modification,";
824 $sql .=
" f.date_valid as datev,";
825 $sql .=
" f.date_approve as datea,";
826 $sql .=
" f.fk_user_creat as fk_user_creation,";
827 $sql .=
" f.fk_user_author as fk_user_author,";
828 $sql .=
" f.fk_user_modif as fk_user_modification,";
829 $sql .=
" f.fk_user_valid,";
830 $sql .=
" f.fk_user_approve";
831 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
832 $sql .=
" WHERE f.rowid = ".((int) $id);
833 $sql .=
" AND f.entity = ".$conf->entity;
835 $resql = $this->db->query($sql);
837 if ($this->db->num_rows($resql)) {
838 $obj = $this->db->fetch_object($resql);
840 $this->
id = $obj->rowid;
842 $this->date_creation = $this->db->jdate($obj->datec);
843 $this->date_modification = $this->db->jdate($obj->date_modification);
844 $this->date_validation = $this->db->jdate($obj->datev);
845 $this->date_approbation = $this->db->jdate($obj->datea);
847 $cuser =
new User($this->db);
848 $cuser->fetch($obj->fk_user_author);
849 $this->user_creation = $cuser;
851 if ($obj->fk_user_creation) {
852 $cuser =
new User($this->db);
853 $cuser->fetch($obj->fk_user_creation);
854 $this->user_creation = $cuser;
856 if ($obj->fk_user_valid) {
857 $vuser =
new User($this->db);
858 $vuser->fetch($obj->fk_user_valid);
859 $this->user_validation = $vuser;
861 if ($obj->fk_user_modification) {
862 $muser =
new User($this->db);
863 $muser->fetch($obj->fk_user_modification);
864 $this->user_modification = $muser;
866 if ($obj->fk_user_approve) {
867 $auser =
new User($this->db);
868 $auser->fetch($obj->fk_user_approve);
869 $this->user_approve = $auser;
872 $this->db->free($resql);
889 global $user, $langs, $conf;
895 $this->
ref =
'SPECIMEN';
898 $this->date_create = $now;
899 $this->date_debut = $now;
900 $this->date_fin = $now;
901 $this->date_valid = $now;
902 $this->date_approve = $now;
907 $this->fk_statut = 5;
909 $this->fk_user_author = $user->id;
910 $this->fk_user_validator = $user->id;
911 $this->fk_user_valid = $user->id;
912 $this->fk_user_approve = $user->id;
914 $this->note_private =
'Private note';
915 $this->note_public =
'SPECIMEN';
918 while ($xnbp < $nbp) {
920 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
921 $line->date = ($now - 3600 * (1 + $xnbp));
922 $line->total_ht = 100;
923 $line->total_tva = 20;
924 $line->total_ttc = 120;
927 $line->value_unit = 120;
928 $line->fk_expensereport = 0;
929 $line->type_fees_code =
'TRA';
930 $line->fk_c_type_fees = $type_fees_id;
932 $line->projet_ref =
'ABC';
934 $this->lines[$xnbp] = $line;
937 $this->total_ht += $line->total_ht;
938 $this->total_tva += $line->total_tva;
939 $this->total_ttc += $line->total_ttc;
954 global $conf, $db, $langs;
956 $langs->load(
'trips');
958 if ($user->rights->expensereport->lire) {
959 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
960 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
961 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
963 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
964 $result = $this->db->query($sql);
966 $num = $this->db->num_rows($result);
972 $objp = $this->db->fetch_object($result);
974 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
975 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
976 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
978 $result2 = $this->db->query($sql2);
979 $obj = $this->db->fetch_object($result2);
981 $objp->fk_user_author = $obj->fk_user_author;
982 $objp->ref = $obj->ref;
983 $objp->fk_c_expensereport_status = $obj->status;
984 $objp->rowid = $obj->rowid;
986 $total_HT = $total_HT + $objp->total_ht;
987 $total_TTC = $total_TTC + $objp->total_ttc;
988 $author =
new User($this->db);
989 $author->fetch($objp->fk_user_author);
992 print
'<td><a href="'.DOL_URL_ROOT.
'/expensereport/card.php?id='.$objp->rowid.
'">'.$objp->ref_num.
'</a></td>';
993 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
994 print
'<td>'.$author->getNomUrl(1).
'</td>';
995 print
'<td>'.$objp->comments.
'</td>';
996 print
'<td class="right">'.price($objp->total_ht).
'</td>';
997 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
998 print
'<td class="right">';
1000 switch ($objp->fk_c_expensereport_status) {
1002 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
1005 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
1008 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
1011 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
1014 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
1031 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
1032 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
1033 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
1034 print
'<td> </td>';
1037 $this->error = $this->db->lasterror();
1056 $this->lines = array();
1058 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1059 $sql .=
" de.".$this->fk_element.
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1060 $sql .=
' de.tva_tx, de.vat_src_code,';
1061 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1062 $sql .=
' de.fk_ecm_files,';
1063 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1064 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1065 $sql .=
' ctf.code as code_type_fees, ctf.label as libelle_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1066 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1067 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as de';
1068 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1069 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1070 $sql .=
" WHERE de.".$this->fk_element.
" = ".((int) $this->
id);
1071 if (!empty($conf->global->EXPENSEREPORT_LINES_SORTED_BY_ROWID)) {
1072 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1074 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1077 $resql = $this->db->query($sql);
1079 $num = $this->db->num_rows($resql);
1082 $objp = $this->db->fetch_object($resql);
1086 $deplig->rowid = $objp->rowid;
1087 $deplig->id = $objp->rowid;
1088 $deplig->comments = $objp->comments;
1089 $deplig->qty = $objp->qty;
1090 $deplig->value_unit = $objp->value_unit;
1091 $deplig->date = $objp->date;
1092 $deplig->dates = $this->db->jdate($objp->date);
1094 $deplig->fk_expensereport = $objp->fk_expensereport;
1095 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1096 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1097 $deplig->fk_projet = $objp->fk_project;
1098 $deplig->fk_project = $objp->fk_project;
1099 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1101 $deplig->total_ht = $objp->total_ht;
1102 $deplig->total_tva = $objp->total_tva;
1103 $deplig->total_ttc = $objp->total_ttc;
1104 $deplig->total_localtax1 = $objp->total_localtax1;
1105 $deplig->total_localtax2 = $objp->total_localtax2;
1107 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1108 $deplig->type_fees_libelle = $objp->libelle_type_fees;
1109 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1111 $deplig->tva_tx = $objp->tva_tx;
1112 $deplig->vatrate = $objp->tva_tx;
1113 $deplig->vat_src_code = $objp->vat_src_code;
1114 $deplig->localtax1_tx = $objp->localtax1_tx;
1115 $deplig->localtax2_tx = $objp->localtax2_tx;
1116 $deplig->localtax1_type = $objp->localtax1_type;
1117 $deplig->localtax2_type = $objp->localtax2_type;
1119 $deplig->projet_ref = $objp->ref_projet;
1120 $deplig->projet_title = $objp->title_projet;
1122 $deplig->rule_warning_message = $objp->rule_warning_message;
1124 $deplig->rang = $objp->rang;
1126 $this->lines[$i] = $deplig;
1130 $this->db->free($resql);
1133 $this->error = $this->db->lasterror();
1134 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1147 public function delete(
User $user =
null, $notrigger =
false)
1150 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1158 $result = $this->
call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1166 if (!$error && !empty($this->table_element_line)) {
1167 $tabletodelete = $this->table_element_line;
1169 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1170 if (!$this->db->query($sql)) {
1172 $this->error = $this->db->lasterror();
1173 $this->errors[] = $this->error;
1174 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1199 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1205 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1206 $res = $this->db->query($sql);
1209 $this->error = $this->db->lasterror();
1210 $this->errors[] = $this->error;
1211 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1226 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1227 $dir = $conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1228 $file = $dir.
"/".$ref.
".pdf";
1229 if (file_exists($file)) {
1233 $this->error =
'ErrorFailToDeleteFile';
1234 $this->errors[] = $this->error;
1235 $this->db->rollback();
1239 if (file_exists($dir)) {
1242 $this->error =
'ErrorFailToDeleteDir';
1243 $this->errors[] = $this->error;
1244 $this->db->rollback();
1252 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1253 $this->db->commit();
1256 $this->db->rollback();
1270 global $conf, $langs, $user;
1276 if ($this->status == self::STATUS_VALIDATED) {
1277 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1281 $this->date_valid = $now;
1284 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
1289 if (empty($num) || $num < 0) {
1298 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1299 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1300 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1301 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1302 $sql .=
" fk_user_valid = ".((int) $user->id);
1303 $sql .=
" WHERE rowid = ".((int) $this->
id);
1305 $resql = $this->db->query($sql);
1307 if (!$error && !$notrigger) {
1309 $result = $this->
call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1317 $this->oldref = $this->ref;
1320 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1321 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1324 $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).
"'";
1325 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1326 $resql = $this->db->query($sql);
1328 $error++; $this->error = $this->db->lasterror();
1330 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'expensereport/".$this->db->escape($this->newref).
"'";
1331 $sql .=
" WHERE filepath = 'expensereport/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
1332 $resql = $this->db->query($sql);
1334 $error++; $this->error = $this->db->lasterror();
1340 $dirsource = $conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1341 $dirdest = $conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1342 if (!$error && file_exists($dirsource)) {
1343 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1345 if (@rename($dirsource, $dirdest)) {
1348 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1349 foreach ($listoffiles as $fileentry) {
1350 $dirsource = $fileentry[
'name'];
1351 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1352 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1353 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1354 @rename($dirsource, $dirdest);
1367 if (empty($error)) {
1368 $this->db->commit();
1371 $this->db->rollback();
1372 $this->error = $this->db->error();
1376 $this->db->rollback();
1377 $this->error = $this->db->lasterror();
1393 $sql =
'SELECT date_debut';
1394 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1395 $sql .=
" WHERE rowid = ".((int) $this->
id);
1397 $result = $this->db->query($sql);
1399 $objp = $this->db->fetch_object($result);
1401 $this->date_debut = $this->db->jdate($objp->date_debut);
1403 if ($this->status != self::STATUS_VALIDATED) {
1404 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1405 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1406 $sql .=
" WHERE rowid = ".((int) $this->
id);
1408 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1410 if ($this->db->query($sql)) {
1413 $this->error = $this->db->lasterror();
1417 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1436 $this->date_approve = $now;
1437 if ($this->status != self::STATUS_APPROVED) {
1440 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1441 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1442 $sql .=
" date_approve='".$this->db->idate($this->date_approve).
"'";
1443 $sql .=
" WHERE rowid = ".((int) $this->
id);
1444 if ($this->db->query($sql)) {
1447 $result = $this->
call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1455 if (empty($error)) {
1456 $this->db->commit();
1459 $this->db->rollback();
1460 $this->error = $this->db->error();
1464 $this->db->rollback();
1465 $this->error = $this->db->lasterror();
1469 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1483 public function setDeny($fuser, $details, $notrigger = 0)
1489 if ($this->status != self::STATUS_REFUSED) {
1490 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1491 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1492 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1493 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1494 $sql .=
" fk_user_approve = NULL";
1495 $sql .=
" WHERE rowid = ".((int) $this->
id);
1496 if ($this->db->query($sql)) {
1497 $this->fk_statut = 99;
1499 $this->fk_user_refuse = $fuser->id;
1500 $this->detail_refuse = $details;
1501 $this->date_refuse = $now;
1505 $result = $this->
call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1513 if (empty($error)) {
1514 $this->db->commit();
1517 $this->db->rollback();
1518 $this->error = $this->db->error();
1522 $this->db->rollback();
1523 $this->error = $this->db->lasterror();
1527 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1546 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1547 return $this->
setUnpaid($fuser, $notrigger);
1564 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1565 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1566 $sql .=
" WHERE rowid = ".((int) $this->
id);
1568 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1570 if ($this->db->query($sql)) {
1573 $result = $this->
call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1581 if (empty($error)) {
1582 $this->db->commit();
1585 $this->db->rollback();
1586 $this->error = $this->db->error();
1590 $this->db->rollback();
1591 $this->error = $this->db->error();
1595 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1614 $this->date_cancel = $this->db->idate(
dol_now());
1615 if ($this->status != self::STATUS_CANCELED) {
1618 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1619 $sql .=
" SET fk_statut = ".self::STATUS_CANCELED.
", fk_user_cancel = ".((int) $fuser->id);
1620 $sql .=
", date_cancel='".$this->db->idate($this->date_cancel).
"'";
1621 $sql .=
", detail_cancel='".$this->db->escape($detail).
"'";
1622 $sql .=
" WHERE rowid = ".((int) $this->
id);
1624 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1626 if ($this->db->query($sql)) {
1629 $result = $this->
call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1637 if (empty($error)) {
1638 $this->db->commit();
1641 $this->db->rollback();
1642 $this->error = $this->db->error();
1646 $this->db->rollback();
1647 $this->error = $this->db->error();
1651 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1663 global $langs, $conf;
1664 $langs->load(
"trips");
1666 if (!empty($conf->global->EXPENSEREPORT_ADDON)) {
1669 $file = $conf->global->EXPENSEREPORT_ADDON.
".php";
1670 $classname = $conf->global->EXPENSEREPORT_ADDON;
1673 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1674 foreach ($dirmodels as $reldir) {
1675 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1678 $mybool |= @include_once $dir.$file;
1681 if ($mybool ===
false) {
1686 $obj =
new $classname();
1687 $numref = $obj->getNextValue($this);
1689 if ($numref !=
"") {
1692 $this->error = $obj->error;
1693 $this->errors = $obj->errors;
1698 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1712 global $conf, $langs;
1714 $langs->load(
'expensereport');
1716 $nofetch = !empty($params[
'nofetch']);
1717 $moretitle = $params[
'moretitle'] ??
'';
1720 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1721 if (isset($this->status)) {
1722 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1725 $datas[
'picto'] .=
' - '.$moretitle;
1727 if (!empty($this->
ref)) {
1728 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1730 if (!empty($this->total_ht)) {
1731 $datas[
'total_ht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1733 if (!empty($this->total_tva)) {
1734 $datas[
'total_tva'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1736 if (!empty($this->total_ttc)) {
1737 $datas[
'total_ttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
1755 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1757 global $langs, $conf, $hookmanager;
1761 $url = DOL_URL_ROOT.
'/expensereport/card.php?id='.$this->id;
1769 'objecttype' => $this->element,
1770 'option' => $option,
1771 'moretitle' => $moretitle,
1774 $classfortooltip =
'classfortooltip';
1777 $classfortooltip =
'classforajaxtooltip';
1778 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1784 if ($option !=
'nolink') {
1786 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1787 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1788 $add_save_lastsearch_values = 1;
1790 if ($add_save_lastsearch_values) {
1791 $url .=
'&save_lastsearch_values=1';
1801 if (empty($notooltip)) {
1802 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1803 $label = $langs->trans(
"ShowExpenseReport");
1804 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1806 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
1807 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
1810 $linkstart =
'<a href="'.$url.
'"';
1811 $linkstart .= $linkclose.
'>';
1814 $result .= $linkstart;
1816 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
1818 if ($withpicto != 2) {
1819 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1821 $result .= $linkend;
1824 $hookmanager->initHooks(array($this->element .
'dao'));
1825 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
1826 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1828 $result = $hookmanager->resPrint;
1830 $result .= $hookmanager->resPrint;
1846 $this->total_ht = $this->total_ht + $ligne_total_ht;
1847 $this->total_tva = $this->total_tva + $ligne_total_tva;
1848 $this->total_ttc = $this->total_ht + $this->total_tva;
1850 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1851 $sql .=
" total_ht = ".$this->total_ht;
1852 $sql .=
" , total_ttc = ".$this->total_ttc;
1853 $sql .=
" , total_tva = ".$this->total_tva;
1854 $sql .=
" WHERE rowid = ".((int) $this->
id);
1856 $result = $this->db->query($sql);
1860 $this->error = $this->db->error();
1880 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)
1882 global $conf, $langs, $mysoc;
1884 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);
1886 if ($this->status == self::STATUS_DRAFT) {
1890 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1891 $fk_c_type_fees = 0;
1893 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1894 $fk_c_exp_tax_cat = 0;
1896 if (empty($vatrate) || $vatrate < 0) {
1902 if (empty($fk_project)) {
1907 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1918 $seller->tva_assuj = 1;
1919 $buyer =
new Societe($this->db);
1925 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
1926 $vat_src_code = $reg[1];
1927 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
1929 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
1931 $tmp =
calcul_price_total($qty, $up, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
1933 $this->line->value_unit = $up;
1935 $this->line->vat_src_code = $vat_src_code;
1936 $this->line->vatrate =
price2num($vatrate);
1937 $this->line->localtax1_tx = $localtaxes_type[1];
1938 $this->line->localtax2_tx = $localtaxes_type[3];
1939 $this->line->localtax1_type = $localtaxes_type[0];
1940 $this->line->localtax2_type = $localtaxes_type[2];
1942 $this->line->total_ttc = $tmp[2];
1943 $this->line->total_ht = $tmp[0];
1944 $this->line->total_tva = $tmp[1];
1945 $this->line->total_localtax1 = $tmp[9];
1946 $this->line->total_localtax2 = $tmp[10];
1948 $this->line->fk_expensereport = $this->id;
1949 $this->line->qty = $qty;
1950 $this->line->date = $date;
1951 $this->line->fk_c_type_fees = $fk_c_type_fees;
1952 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
1953 $this->line->comments = $comments;
1954 $this->line->fk_projet = $fk_project;
1955 $this->line->fk_project = $fk_project;
1957 $this->line->fk_ecm_files = $fk_ecm_files;
1962 $result = $this->line->insert(0,
true);
1966 $this->db->commit();
1967 return $this->line->id;
1969 $this->db->rollback();
1973 $this->error = $this->line->error;
1974 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
1975 $this->db->rollback();
1979 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
1980 $this->error =
'ErrorExpenseNotDraft';
1994 global $user, $conf, $db, $langs, $mysoc;
1996 $langs->load(
'trips');
1999 if (!is_object($seller)) {
2001 $seller->tva_assuj = 1;
2005 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
2008 $rule_warning_message_tab = array();
2010 $current_total_ttc = $this->line->total_ttc;
2011 $new_current_total_ttc = $this->line->total_ttc;
2014 foreach ($rulestocheck as $rule) {
2015 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
2016 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
2018 $amount_to_test = $current_total_ttc;
2021 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
2023 if ($amount_to_test > $rule->amount) {
2026 if ($rule->restrictive) {
2027 $this->error =
'ExpenseReportConstraintViolationError';
2028 $this->errors[] = $this->error;
2030 $new_current_total_ttc -= $amount_to_test - $rule->amount;
2031 $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));
2033 $this->error =
'ExpenseReportConstraintViolationWarning';
2034 $this->errors[] = $this->error;
2036 $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));
2043 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
2045 if ($violation > 0) {
2046 $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);
2048 $this->line->value_unit = $tmp[5];
2049 $this->line->total_ttc = $tmp[2];
2050 $this->line->total_ht = $tmp[0];
2051 $this->line->total_tva = $tmp[1];
2052 $this->line->total_localtax1 = $tmp[9];
2053 $this->line->total_localtax2 = $tmp[10];
2070 global $conf, $mysoc;
2072 if (empty($conf->global->MAIN_USE_EXPENSE_IK)) {
2076 $userauthor =
new User($this->db);
2077 if ($userauthor->fetch($this->fk_user_author) <= 0) {
2078 $this->error =
'ErrorCantFetchUser';
2079 $this->errors[] =
'ErrorCantFetchUser';
2084 if (!is_object($seller)) {
2086 $seller->tva_assuj = 1;
2090 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2092 if (empty($range)) {
2093 $this->error =
'ErrorNoRangeAvailable';
2094 $this->errors[] =
'ErrorNoRangeAvailable';
2098 if (!empty($conf->global->MAIN_EXPENSE_APPLY_ENTIRE_OFFSET)) {
2099 $ikoffset = $range->ikoffset;
2101 $ikoffset = $range->ikoffset / 12;
2106 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2107 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2109 $this->line->value_unit = $tmp[5];
2110 $this->line->total_ttc = $tmp[2];
2111 $this->line->total_ht = $tmp[0];
2112 $this->line->total_tva = $tmp[1];
2113 $this->line->total_localtax1 = $tmp[9];
2114 $this->line->total_localtax2 = $tmp[10];
2129 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2130 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2131 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2132 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2133 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2134 if (!empty($this->line->id)) {
2135 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2138 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2139 $resql = $this->db->query($sql);
2141 $num = $this->db->num_rows($resql);
2169 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)
2171 global $user, $mysoc;
2173 if ($this->status == self::STATUS_DRAFT || $this->status == self::STATUS_REFUSED) {
2181 $seller->tva_assuj = 1;
2182 $seller->localtax1_assuj = $mysoc->localtax1_assuj;
2183 $seller->localtax2_assuj = $mysoc->localtax1_assuj;
2184 $buyer =
new Societe($this->db);
2191 if (preg_match(
'/\((.*)\)/', $vatrate, $reg)) {
2192 $vat_src_code = $reg[1];
2193 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2195 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2197 $tmp =
calcul_price_total($qty, $value_unit, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2202 $tx_tva = $vatrate / 100;
2203 $tx_tva = $tx_tva + 1;
2206 $this->line->comments = $comments;
2207 $this->line->qty = $qty;
2208 $this->line->value_unit = $value_unit;
2209 $this->line->date = $date;
2211 $this->line->fk_expensereport = $expensereport_id;
2212 $this->line->fk_c_type_fees = $type_fees_id;
2213 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2214 $this->line->fk_projet = $projet_id;
2215 $this->line->fk_project = $projet_id;
2217 $this->line->vat_src_code = $vat_src_code;
2218 $this->line->vatrate =
price2num($vatrate);
2219 $this->line->localtax1_tx = $localtaxes_type[1];
2220 $this->line->localtax2_tx = $localtaxes_type[3];
2221 $this->line->localtax1_type = $localtaxes_type[0];
2222 $this->line->localtax2_type = $localtaxes_type[2];
2224 $this->line->total_ttc = $tmp[2];
2225 $this->line->total_ht = $tmp[0];
2226 $this->line->total_tva = $tmp[1];
2227 $this->line->total_localtax1 = $tmp[9];
2228 $this->line->total_localtax2 = $tmp[10];
2230 $this->line->fk_ecm_files = $fk_ecm_files;
2232 $this->line->id = ((int) $rowid);
2235 $sql =
"SELECT c.code as code_type_fees, c.label as libelle_type_fees";
2236 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2237 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2238 $resql = $this->db->query($sql);
2240 $objp_fees = $this->db->fetch_object($resql);
2241 $this->line->type_fees_code = $objp_fees->code_type_fees;
2242 $this->line->type_fees_libelle = $objp_fees->libelle_type_fees;
2243 $this->db->free($resql);
2247 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2248 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2249 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2250 $resql = $this->db->query($sql);
2252 $objp_projet = $this->db->fetch_object($resql);
2253 $this->line->projet_ref = $objp_projet->ref_projet;
2254 $this->line->projet_title = $objp_projet->title_projet;
2255 $this->db->free($resql);
2261 $result = $this->line->update($user);
2266 if (!$error && !$notrigger) {
2268 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_MODIFY', $user);
2276 $this->db->commit();
2279 $this->error = $this->line->error;
2280 $this->errors = $this->line->errors;
2281 $this->db->rollback();
2305 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2312 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2313 $sql .=
' WHERE rowid = '.((int) $rowid);
2315 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2316 $result = $this->db->query($sql);
2318 if (!$result || $error > 0 ) {
2319 $this->error = $this->db->error();
2320 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2321 $this->db->rollback();
2327 $this->db->commit();
2346 $sql =
"SELECT rowid, date_debut, date_fin";
2347 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2348 $sql .=
" WHERE entity = ".((int) $conf->entity);
2349 $sql .=
" AND fk_user_author = ".((int) $fuser->id);
2351 dol_syslog(get_class($this).
"::periode_existe sql=".$sql);
2352 $result = $this->db->query($sql);
2354 $num_rows = $this->db->num_rows($result); $i = 0;
2356 if ($num_rows > 0) {
2357 $date_d_form = $date_debut;
2358 $date_f_form = $date_fin;
2360 while ($i < $num_rows) {
2361 $objp = $this->db->fetch_object($result);
2363 $date_d_req = $this->db->jdate($objp->date_debut);
2364 $date_f_req = $this->db->jdate($objp->date_fin);
2366 if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) {
2367 return $objp->rowid;
2378 $this->error = $this->db->lasterror();
2379 dol_syslog(get_class($this).
"::periode_existe Error ".$this->error, LOG_ERR);
2395 $users_validator = array();
2397 $sql =
"SELECT DISTINCT ur.fk_user";
2398 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2399 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2401 $sql .=
" SELECT DISTINCT ugu.fk_user";
2402 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2403 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2406 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2407 $result = $this->db->query($sql);
2409 $num_rows = $this->db->num_rows($result); $i = 0;
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;
2443 } elseif (!empty($this->modelpdf)) {
2444 $modele = $this->modelpdf;
2445 } elseif (!empty($conf->global->EXPENSEREPORT_ADDON_PDF)) {
2446 $modele = $conf->global->EXPENSEREPORT_ADDON_PDF;
2450 if (!empty($modele)) {
2451 $modelpath =
"core/modules/expensereport/doc/";
2453 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2469 $sql =
"SELECT id, code, label";
2470 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2471 $sql .=
" WHERE active = ".((int) $active);
2472 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2473 $result = $this->db->query($sql);
2475 $num = $this->db->num_rows($result);
2478 $obj = $this->db->fetch_object($result);
2479 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2497 global $conf, $user;
2499 $this->nb = array();
2501 $sql =
"SELECT count(ex.rowid) as nb";
2502 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2503 $sql .=
" WHERE ex.fk_statut > 0";
2504 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2505 if (empty($user->rights->expensereport->readall)) {
2506 $userchildids = $user->getAllChildIds(1);
2507 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2508 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2511 $resql = $this->db->query($sql);
2513 while ($obj = $this->db->fetch_object($resql)) {
2514 $this->nb[
"expensereports"] = $obj->nb;
2516 $this->db->free($resql);
2520 $this->error = $this->db->error();
2536 global $conf, $langs;
2544 $sql =
"SELECT ex.rowid, ex.date_valid";
2545 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2546 if ($option ==
'toapprove') {
2547 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2549 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2551 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2552 if (empty($user->rights->expensereport->readall)) {
2553 $userchildids = $user->getAllChildIds(1);
2554 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2555 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2558 $resql = $this->db->query($sql);
2560 $langs->load(
"trips");
2563 if ($option ==
'toapprove') {
2564 $response->warning_delay = $conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2565 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2566 $response->labelShort = $langs->trans(
"ToApprove");
2569 $response->warning_delay = $conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2570 $response->label = $langs->trans(
"ExpenseReportsToPay");
2571 $response->labelShort = $langs->trans(
"StatusToPay");
2572 $response->url = DOL_URL_ROOT.
'/expensereport/list.php?mainmenu=hrm&statut='.
self::STATUS_APPROVED;
2576 while ($obj = $this->db->fetch_object($resql)) {
2577 $response->nbtodo++;
2579 if ($option ==
'toapprove') {
2580 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->approve->warning_delay)) {
2581 $response->nbtodolate++;
2584 if ($this->db->jdate($obj->date_valid) < ($now - $conf->expensereport->payment->warning_delay)) {
2585 $response->nbtodolate++;
2593 $this->error = $this->db->error();
2609 if ($option ==
'toapprove' && $this->status != 2) {
2612 if ($option ==
'topay' && $this->status != 5) {
2617 if ($option ==
'toapprove') {
2618 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->approve->warning_delay);
2620 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->payment->warning_delay);
2631 $alreadydispatched = 0;
2633 $type =
'expense_report';
2635 $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);
2636 $resql = $this->db->query($sql);
2638 $obj = $this->db->fetch_object($resql);
2640 $alreadydispatched = $obj->nb;
2643 $this->error = $this->db->lasterror();
2647 if ($alreadydispatched) {
2660 $table =
'payment_expensereport';
2661 $field =
'fk_expensereport';
2663 $sql =
'SELECT sum(amount) as amount';
2664 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2665 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
2667 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2668 $resql = $this->db->query($sql);
2670 $obj = $this->db->fetch_object($resql);
2671 $this->db->free($resql);
2672 return (empty($obj->amount) ? 0 : $obj->amount);
2674 $this->error = $this->db->lasterror();
2689 global $langs, $db, $conf;
2697 $this->error = $langs->trans(
'ErrorBadParameterCat');
2702 $this->error = $langs->trans(
'ErrorBadParameterQty');
2706 $currentUser =
new User($db);
2707 $currentUser->fetch($this->fk_user);
2708 $currentUser->getrights(
'expensereport');
2712 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2713 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2714 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2715 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2716 $sql .=
" ORDER BY r.range_ik ASC";
2718 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2720 $result = $this->db->query($sql);
2723 if ($conf->global->EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR) {
2725 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2726 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2727 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2728 $sql.=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2729 $sql.=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2730 $sql.=
" AND tf.code = 'EX_KME' ";
2733 $resql = $this->db->query($sql);
2736 $obj = $this->db->fetch_object($resql);
2737 $cumulYearQty = $obj->cumul;
2740 $qty = $cumulYearQty + $qty;
2743 $num = $this->db->num_rows($result);
2746 for ($i = 0; $i < $num; $i++) {
2747 $obj = $this->db->fetch_object($result);
2753 for ($i = 0; $i < $num; $i++) {
2754 if ($i < ($num - 1)) {
2755 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i+1]->range_ik) {
2756 $coef = $ranges[$i]->coef;
2757 $offset = $ranges[$i]->ikoffset;
2760 if ($qty > $ranges[$i]->range_ik) {
2761 $coef = $ranges[$i]->coef;
2762 $offset = $ranges[$i]->ikoffset;
2769 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2773 $this->error = $this->db->error().
" sql=".$sql;
2790 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2792 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2793 $return .=
'<div class="info-box info-box-sm">';
2794 $return .=
'<span class="info-box-icon bg-infobox-action">';
2796 $return .=
'</span>';
2797 $return .=
'<div class="info-box-content">';
2798 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
2799 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2800 if (property_exists($this,
'fk_user_author') && !empty($this->
id)) {
2801 $return .=
'<br><span class="info-box-label">'.$this->fk_user_author.
'</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 margintoponly">'.$this->getLibStatut(3).
'</div>';
2811 $return .=
'</div>';
2812 $return .=
'</div>';
2813 $return .=
'</div>';
2832 public $table_element =
'expensereport_det';
2852 public $fk_c_type_fees;
2857 public $fk_c_exp_tax_cat;
2867 public $fk_expensereport;
2869 public $type_fees_code;
2870 public $type_fees_libelle;
2871 public $type_fees_accountancy_code;
2874 public $projet_title;
2878 public $vat_src_code;
2880 public $localtax1_tx;
2881 public $localtax2_tx;
2882 public $localtax1_type;
2883 public $localtax2_type;
2888 public $total_localtax1;
2889 public $total_localtax2;
2895 public $fk_multicurrency;
2900 public $multicurrency_code;
2901 public $multicurrency_tx;
2902 public $multicurrency_total_ht;
2903 public $multicurrency_total_tva;
2904 public $multicurrency_total_ttc;
2909 public $fk_ecm_files;
2911 public $rule_warning_message;
2932 $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,';
2933 $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,';
2934 $sql .=
' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,';
2935 $sql .=
' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
2936 $sql .=
' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
2937 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det as fde';
2938 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
2939 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as pjt ON fde.fk_projet=pjt.rowid';
2940 $sql .=
' WHERE fde.rowid = '.((int) $rowid);
2942 $result = $this->db->query($sql);
2945 $objp = $this->db->fetch_object($result);
2947 $this->
rowid = $objp->rowid;
2948 $this->
id = $objp->rowid;
2949 $this->
ref = $objp->ref;
2950 $this->fk_expensereport = $objp->fk_expensereport;
2951 $this->comments = $objp->comments;
2952 $this->qty = $objp->qty;
2953 $this->date = $objp->date;
2954 $this->dates = $this->db->jdate($objp->date);
2955 $this->value_unit = $objp->value_unit;
2956 $this->fk_c_type_fees = $objp->fk_c_type_fees;
2957 $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
2958 $this->fk_projet = $objp->fk_project;
2959 $this->fk_project = $objp->fk_project;
2960 $this->type_fees_code = $objp->type_fees_code;
2961 $this->type_fees_libelle = $objp->type_fees_libelle;
2962 $this->projet_ref = $objp->projet_ref;
2963 $this->projet_title = $objp->projet_title;
2965 $this->
vatrate = $objp->vatrate;
2966 $this->vat_src_code = $objp->vat_src_code;
2967 $this->localtax1_tx = $objp->localtax1_tx;
2968 $this->localtax2_tx = $objp->localtax2_tx;
2969 $this->localtax1_type = $objp->localtax1_type;
2970 $this->localtax2_type = $objp->localtax2_type;
2972 $this->total_ht = $objp->total_ht;
2973 $this->total_tva = $objp->total_tva;
2974 $this->total_ttc = $objp->total_ttc;
2975 $this->total_localtax1 = $objp->total_localtax1;
2976 $this->total_localtax2 = $objp->total_localtax2;
2978 $this->fk_ecm_files = $objp->fk_ecm_files;
2980 $this->rule_warning_message = $objp->rule_warning_message;
2982 $this->db->free($result);
2998 public function insert($notrigger = 0, $fromaddline =
false)
3000 global $user, $conf;
3004 dol_syslog(
"ExpenseReportLine::Insert", LOG_DEBUG);
3007 $this->comments = trim($this->comments);
3008 if (empty($this->value_unit)) {
3009 $this->value_unit = 0;
3013 if (empty($this->fk_c_exp_tax_cat)) {
3014 $this->fk_c_exp_tax_cat = 0;
3019 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'expensereport_det';
3020 $sql .=
' (fk_expensereport, fk_c_type_fees, fk_projet,';
3021 $sql .=
' tva_tx, vat_src_code,';
3022 $sql .=
' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
3023 $sql .=
' comments, qty, value_unit,';
3024 $sql .=
' total_ht, total_tva, total_ttc,';
3025 $sql .=
' total_localtax1, total_localtax2,';
3026 $sql .=
' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)';
3027 $sql .=
" VALUES (".$this->db->escape($this->fk_expensereport).
",";
3028 $sql .=
" ".((int) $this->fk_c_type_fees).
",";
3029 $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')).
",";
3030 $sql .=
" ".((float) $this->
vatrate).
",";
3031 $sql .=
" '".$this->db->escape(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"',";
3032 $sql .=
" ".((float)
price2num($this->localtax1_tx)).
",";
3033 $sql .=
" ".((float)
price2num($this->localtax2_tx)).
",";
3034 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
3035 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
3036 $sql .=
" '".$this->db->escape($this->comments).
"',";
3037 $sql .=
" ".((float) $this->qty).
",";
3038 $sql .=
" ".((float) $this->value_unit).
",";
3039 $sql .=
" ".((float)
price2num($this->total_ht)).
",";
3040 $sql .=
" ".((float)
price2num($this->total_tva)).
",";
3041 $sql .=
" ".((float)
price2num($this->total_ttc)).
",";
3042 $sql .=
" ".((float)
price2num($this->total_localtax1)).
",";
3043 $sql .=
" ".((float)
price2num($this->total_localtax2)).
",";
3044 $sql .=
" '".$this->db->idate($this->date).
"',";
3045 $sql .=
" ".(empty($this->rule_warning_message) ?
'null' :
"'".$this->db->escape($this->rule_warning_message).
"'").
",";
3046 $sql .=
" ".((int) $this->fk_c_exp_tax_cat).
",";
3047 $sql .=
" ".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3050 $resql = $this->db->query($sql);
3052 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'expensereport_det');
3055 if (!$error && !$notrigger) {
3057 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_CREATE', $user);
3065 if (!$fromaddline) {
3067 $tmpparent->fetch($this->fk_expensereport);
3068 $result = $tmpparent->update_price(1);
3071 $this->error = $tmpparent->error;
3072 $this->errors = $tmpparent->errors;
3080 $this->db->commit();
3083 $this->error = $this->db->lasterror();
3084 dol_syslog(
"ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
3085 $this->db->rollback();
3102 $sql =
'SELECT SUM(d.total_ttc) as total_amount';
3103 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det d';
3104 $sql .=
' INNER JOIN '.MAIN_DB_PREFIX.
'expensereport e ON (d.fk_expensereport = e.rowid)';
3105 $sql .=
' WHERE e.fk_user_author = '.((int) $fk_user);
3106 if (!empty($this->
id)) {
3107 $sql .=
' AND d.rowid <> '.((int) $this->
id);
3109 $sql .=
' AND d.fk_c_type_fees = '.((int) $rule->fk_c_type_fees);
3110 if ($mode ==
'day' || $mode ==
'EX_DAY') {
3111 $sql .=
" AND d.date = '".dol_print_date($this->date,
'%Y-%m-%d').
"'";
3112 } elseif ($mode ==
'mon' || $mode ==
'EX_MON') {
3113 $sql .=
" AND DATE_FORMAT(d.date, '%Y-%m') = '".dol_print_date($this->date,
'%Y-%m').
"'";
3114 } elseif ($mode ==
'year' || $mode ==
'EX_YEA') {
3115 $sql .=
" AND DATE_FORMAT(d.date, '%Y') = '".dol_print_date($this->date,
'%Y').
"'";
3118 dol_syslog(
'ExpenseReportLine::getExpAmount');
3120 $resql = $this->db->query($sql);
3122 $num = $this->db->num_rows($resql);
3124 $obj = $this->db->fetch_object($resql);
3125 $amount = (double) $obj->total_amount;
3131 return $amount + $this->total_ttc;
3142 global $langs, $conf;
3147 $this->comments = trim($this->comments);
3149 $this->value_unit =
price2num($this->value_unit);
3150 if (empty($this->fk_c_exp_tax_cat)) {
3151 $this->fk_c_exp_tax_cat = 0;
3157 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport_det SET";
3158 $sql .=
" comments='".$this->db->escape($this->comments).
"'";
3159 $sql .=
", value_unit = ".((float) $this->value_unit);
3160 $sql .=
", qty=".((float) $this->qty);
3161 $sql .=
", date='".$this->db->idate($this->date).
"'";
3162 $sql .=
", total_ht=".((float)
price2num($this->total_ht,
'MT'));
3163 $sql .=
", total_tva=".((float)
price2num($this->total_tva,
'MT'));
3164 $sql .=
", total_ttc=".((float)
price2num($this->total_ttc,
'MT'));
3165 $sql .=
", total_localtax1=".((float)
price2num($this->total_localtax1,
'MT'));
3166 $sql .=
", total_localtax2=".((float)
price2num($this->total_localtax2,
'MT'));
3167 $sql .=
", tva_tx=".((float) $this->
vatrate);
3168 $sql .=
", vat_src_code='".$this->db->escape($this->vat_src_code).
"'";
3169 $sql .=
", localtax1_tx=".((float) $this->localtax1_tx);
3170 $sql .=
", localtax2_tx=".((float) $this->localtax2_tx);
3171 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
3172 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
3173 $sql .=
", rule_warning_message='".$this->db->escape($this->rule_warning_message).
"'";
3174 $sql .=
", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat);
3175 $sql .=
", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3176 if ($this->fk_c_type_fees) {
3177 $sql .=
", fk_c_type_fees = ".((int) $this->fk_c_type_fees);
3179 $sql .=
", fk_c_type_fees=null";
3181 if ($this->fk_project > 0) {
3182 $sql .=
", fk_projet=".((int) $this->fk_project);
3184 $sql .=
", fk_projet=null";
3186 $sql .=
" WHERE rowid = ".((int) ($this->
rowid ? $this->
rowid : $this->id));
3190 $resql = $this->db->query($sql);
3193 $result = $tmpparent->fetch($this->fk_expensereport);
3195 $result = $tmpparent->update_price(1);
3198 $this->error = $tmpparent->error;
3199 $this->errors = $tmpparent->errors;
3203 $this->error = $tmpparent->error;
3204 $this->errors = $tmpparent->errors;
3212 $this->db->commit();
3215 $this->error = $this->db->lasterror();
3216 dol_syslog(
"ExpenseReportLine::update Error ".$this->error, LOG_ERR);
3217 $this->db->rollback();
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteEcmFiles($mode=0)
Delete related files of object in database.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='', $f_user=null, $notrigger=0)
Delete all links between an object $this.
update_price($exclspec=0, $roundingadjust='none', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
deleteExtraFields()
Delete all extra fields values for the current object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Trips and Expenses.
setPaid($id, $fuser, $notrigger=0)
Classify the expense report as paid.
__construct($db)
Constructor.
checkRules($type=0, $seller='')
Check constraint of rules and update price if needed.
updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id, $fk_c_exp_tax_cat=0, $fk_ecm_files=0, $notrigger=0)
Update an expense report line.
getNextNumRef()
Return next reference of expense report not already used.
createFromClone(User $user, $fk_user_author)
Load an object from its id and create a new one in database.
addline($qty=0, $up=0, $fk_c_type_fees=0, $vatrate=0, $date='', $comments='', $fk_project=0, $fk_c_exp_tax_cat=0, $type=0, $fk_ecm_files=0)
Add expense report line.
const STATUS_DRAFT
Draft status.
computeTotalKm($fk_cat, $qty, $tva)
Compute the cost of the kilometers expense based on the number of kilometers and the vehicule categor...
load_state_board()
Charge indicateurs this->nb pour le tableau de bord.
offsetAlreadyGiven()
If the sql find any rows then the ikoffset is already given (ikoffset is applied at the first expense...
listOfTypes($active=1)
List of types.
deleteline($rowid, $fuser='', $notrigger=0)
deleteline
const STATUS_APPROVED
Classified approved.
set_save_from_refuse($fuser)
set_save_from_refuse
periode_existe($fuser, $date_debut, $date_fin)
periode_existe
setValidate($fuser, $notrigger=0)
Set to status validate.
getSumPayments()
Return amount of payments already done.
getLibStatut($mode=0)
Returns the label status.
set_cancel($fuser, $detail, $notrigger=0)
set_cancel
getNomUrl($withpicto=0, $option='', $max=0, $short=0, $moretitle='', $notooltip=0, $save_lastsearch_value=-1)
Return clicable name (with picto eventually)
set_unpaid($fuser, $notrigger=0)
set_unpaid
info($id)
Load information on object.
getTooltipContentArray($params)
getTooltipContentArray
hasDelay($option)
Return if an expense report is late or not.
applyOffset($type=0, $seller='')
Method to apply the offset if needed.
const STATUS_CANCELED
Classified canceled.
const STATUS_CLOSED
Classified paid.
const STATUS_REFUSED
Classified refused.
setDeny($fuser, $details, $notrigger=0)
setDeny
getVentilExportCompta()
Return if object was dispatched into bookkeeping.
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
update($user, $notrigger=0, $userofexpensereport=null)
update
const STATUS_VALIDATED
Validated (need to be paid)
create($user, $notrigger=0)
Create object in database.
load_board($user, $option='topay')
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
set_paid($id, $fuser, $notrigger=0)
Classify the expense report as paid.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk accordign to template module.
initAsSpecimen()
Initialise an instance with random values.
fetch_users_approver_expensereport()
Return list of people with permission to validate expense reports.
setApproved($fuser, $notrigger=0)
Set status to approved.
LibStatut($status, $mode=0)
Returns the label of a status.
fetch_line_by_project($projectid, $user='')
fetch_line_by_project
setUnpaid($fuser, $notrigger=0)
set_unpaid
update_totaux_add($ligne_total_ht, $ligne_total_tva)
Update total of an expense report when you add a line.
Class to manage inventories.
Class of expense report details lines.
fetch($rowid)
Fetch record for expense report detailed line.
update(User $user)
Update line.
getExpAmount(ExpenseReportRule $rule, $fk_user, $mode='day')
Function to get total amount in expense reports for a same rule.
insert($notrigger=0, $fromaddline=false)
Insert a line of expense report.
__construct($db)
Constructor.
Class to manage inventories.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_delete_preview($object)
Delete all preview files linked to object instance.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller='', $localtaxes_array='', $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.