28 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
29 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
30 require_once DOL_DOCUMENT_ROOT.
'/expensereport/class/expensereport_ik.class.php';
31 require_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';
63 public $lines = array();
84 public $fk_c_paiement;
87 public $user_author_infos;
88 public $user_validator_infos;
90 public $rule_warning_message;
96 public $fk_user_author;
100 public $fk_user_modif;
104 public $detail_refuse;
105 public $fk_user_refuse;
109 public $detail_cancel;
110 public $fk_user_cancel;
112 public $fk_user_validator;
119 public $fk_user_valid;
120 public $user_valid_infos;
123 public $date_approve;
124 public $fk_user_approve;
127 public $user_paid_infos;
132 public $statuts = array();
133 public $statuts_short = array();
134 public $statuts_logo;
140 public $fk_multicurrency;
145 public $multicurrency_code;
146 public $multicurrency_tx;
147 public $multicurrency_total_ht;
148 public $multicurrency_total_tva;
149 public $multicurrency_total_ttc;
183 public $fields = array(
184 'rowid' =>array(
'type'=>
'integer',
'label'=>
'ID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
185 'ref' =>array(
'type'=>
'varchar(50)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'showoncombobox'=>1,
'position'=>15),
186 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>20),
187 'ref_number_int' =>array(
'type'=>
'integer',
'label'=>
'Ref number int',
'enabled'=>1,
'visible'=>-1,
'position'=>25),
188 'ref_ext' =>array(
'type'=>
'integer',
'label'=>
'Ref ext',
'enabled'=>1,
'visible'=>-1,
'position'=>30),
189 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total ht',
'enabled'=>1,
'visible'=>-1,
'position'=>35),
190 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total tva',
'enabled'=>1,
'visible'=>-1,
'position'=>40),
191 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax1',
'enabled'=>1,
'visible'=>-1,
'position'=>45),
192 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax2',
'enabled'=>1,
'visible'=>-1,
'position'=>50),
193 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total ttc',
'enabled'=>1,
'visible'=>-1,
'position'=>55),
194 'date_debut' =>array(
'type'=>
'date',
'label'=>
'Date debut',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>60),
195 'date_fin' =>array(
'type'=>
'date',
'label'=>
'Date fin',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>65),
196 'date_valid' =>array(
'type'=>
'datetime',
'label'=>
'Date valid',
'enabled'=>1,
'visible'=>-1,
'position'=>75),
197 'date_approve' =>array(
'type'=>
'datetime',
'label'=>
'Date approve',
'enabled'=>1,
'visible'=>-1,
'position'=>80),
198 'date_refuse' =>array(
'type'=>
'datetime',
'label'=>
'Date refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>85),
199 'date_cancel' =>array(
'type'=>
'datetime',
'label'=>
'Date cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>90),
200 'fk_user_author' =>array(
'type'=>
'integer',
'label'=>
'Fk user author',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>100),
201 'fk_user_modif' =>array(
'type'=>
'integer',
'label'=>
'Fk user modif',
'enabled'=>1,
'visible'=>-1,
'position'=>105),
202 'fk_user_valid' =>array(
'type'=>
'integer',
'label'=>
'Fk user valid',
'enabled'=>1,
'visible'=>-1,
'position'=>110),
203 'fk_user_validator' =>array(
'type'=>
'integer',
'label'=>
'Fk user validator',
'enabled'=>1,
'visible'=>-1,
'position'=>115),
204 'fk_user_approve' =>array(
'type'=>
'integer',
'label'=>
'Fk user approve',
'enabled'=>1,
'visible'=>-1,
'position'=>120),
205 'fk_user_refuse' =>array(
'type'=>
'integer',
'label'=>
'Fk user refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>125),
206 'fk_user_cancel' =>array(
'type'=>
'integer',
'label'=>
'Fk user cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>130),
207 'fk_c_paiement' =>array(
'type'=>
'integer',
'label'=>
'Fk c paiement',
'enabled'=>1,
'visible'=>-1,
'position'=>140),
208 'paid' =>array(
'type'=>
'integer',
'label'=>
'Paid',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>145),
209 'note_public' =>array(
'type'=>
'text',
'label'=>
'Note public',
'enabled'=>1,
'visible'=>0,
'position'=>150),
210 'note_private' =>array(
'type'=>
'text',
'label'=>
'Note private',
'enabled'=>1,
'visible'=>0,
'position'=>155),
211 'detail_refuse' =>array(
'type'=>
'varchar(255)',
'label'=>
'Detail refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>160),
212 'detail_cancel' =>array(
'type'=>
'varchar(255)',
'label'=>
'Detail cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>165),
213 'integration_compta' =>array(
'type'=>
'integer',
'label'=>
'Integration compta',
'enabled'=>1,
'visible'=>-1,
'position'=>170),
214 'fk_bank_account' =>array(
'type'=>
'integer',
'label'=>
'Fk bank account',
'enabled'=>1,
'visible'=>-1,
'position'=>175),
215 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'Fk multicurrency',
'enabled'=>1,
'visible'=>-1,
'position'=>185),
216 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'Multicurrency code',
'enabled'=>1,
'visible'=>-1,
'position'=>190),
217 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency tx',
'enabled'=>1,
'visible'=>-1,
'position'=>195),
218 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total ht',
'enabled'=>1,
'visible'=>-1,
'position'=>200),
219 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total tva',
'enabled'=>1,
'visible'=>-1,
'position'=>205),
220 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total ttc',
'enabled'=>1,
'visible'=>-1,
'position'=>210),
221 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>220),
222 'date_create' =>array(
'type'=>
'datetime',
'label'=>
'Date create',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>300),
223 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'Tms',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>305),
224 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-1,
'position'=>1000),
225 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'Model pdf',
'enabled'=>1,
'visible'=>0,
'position'=>1010),
226 'fk_statut' =>array(
'type'=>
'integer',
'label'=>
'Fk statut',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>500),
238 $this->total_ttc = 0;
239 $this->total_tva = 0;
240 $this->total_localtax1 = 0;
241 $this->total_localtax2 = 0;
242 $this->localtax1 = 0;
243 $this->localtax2 = 0;
244 $this->modepaymentid = 0;
247 $this->statuts_short = array(0 =>
'Draft', 2 =>
'Validated', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
248 $this->statuts = array(0 =>
'Draft', 2 =>
'ValidatedWaitingApproval', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
249 $this->statuts_logo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
259 public function create($user, $notrigger = 0)
261 global $conf, $langs;
268 if (empty($this->date_debut) || empty($this->date_fin)) {
269 $this->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
'Date'));
273 $fuserid = $this->fk_user_author;
274 if (empty($fuserid)) {
275 $fuserid = $user->id;
280 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
" (";
283 $sql .=
",total_ttc";
284 $sql .=
",total_tva";
285 $sql .=
",date_debut";
287 $sql .=
",date_create";
288 $sql .=
",fk_user_creat";
289 $sql .=
",fk_user_author";
290 $sql .=
",fk_user_validator";
291 $sql .=
",fk_user_approve";
292 $sql .=
",fk_user_modif";
293 $sql .=
",fk_statut";
294 $sql .=
",fk_c_paiement";
296 $sql .=
",note_public";
297 $sql .=
",note_private";
301 $sql .=
", ".price2num($this->total_ht,
'MT');
302 $sql .=
", ".price2num($this->total_ttc,
'MT');
303 $sql .=
", ".price2num($this->total_tva,
'MT');
304 $sql .=
", '".$this->db->idate($this->date_debut).
"'";
305 $sql .=
", '".$this->db->idate($this->date_fin).
"'";
306 $sql .=
", '".$this->db->idate($now).
"'";
307 $sql .=
", ".((int) $user->id);
308 $sql .=
", ".((int) $fuserid);
309 $sql .=
", ".($this->fk_user_validator > 0 ? ((int) $this->fk_user_validator) :
"null");
310 $sql .=
", ".($this->fk_user_approve > 0 ? ((int) $this->fk_user_approve) :
"null");
311 $sql .=
", ".($this->fk_user_modif > 0 ? ((int) $this->fk_user_modif) :
"null");
312 $sql .=
", ".($this->fk_statut > 1 ? ((int) $this->fk_statut) : 0);
313 $sql .=
", ".($this->modepaymentid ? ((int) $this->modepaymentid) :
"null");
315 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
"null");
316 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
"null");
317 $sql .=
", ".((int) $conf->entity);
320 $result = $this->
db->query($sql);
322 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
323 $this->
ref =
'(PROV'.$this->id.
')';
325 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
" SET ref='".$this->
db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
328 $this->error = $this->
db->lasterror();
333 if (is_array($this->lines) && count($this->lines) > 0) {
334 foreach ($this->lines as $line) {
337 if (!is_object($line)) {
338 $line = (object) $line;
340 $newndfline->fk_expensereport = $line->fk_expensereport;
341 $newndfline->fk_c_type_fees = $line->fk_c_type_fees;
342 $newndfline->fk_project = $line->fk_project;
343 $newndfline->vatrate = $line->vatrate;
344 $newndfline->vat_src_code = $line->vat_src_code;
345 $newndfline->localtax1_tx = $line->localtax1_tx;
346 $newndfline->localtax2_tx = $line->localtax2_tx;
347 $newndfline->localtax1_type = $line->localtax1_type;
348 $newndfline->localtax2_type = $line->localtax2_type;
349 $newndfline->comments = $line->comments;
350 $newndfline->qty = $line->qty;
351 $newndfline->value_unit = $line->value_unit;
352 $newndfline->total_ht = $line->total_ht;
353 $newndfline->total_ttc = $line->total_ttc;
354 $newndfline->total_tva = $line->total_tva;
355 $newndfline->total_localtax1 = $line->total_localtax1;
356 $newndfline->total_localtax2 = $line->total_localtax2;
357 $newndfline->date = $line->date;
358 $newndfline->rule_warning_message = $line->rule_warning_message;
359 $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat;
360 $newndfline->fk_ecm_files = $line->fk_ecm_files;
365 $newndfline->fk_expensereport = $this->id;
366 $result = $newndfline->insert();
368 $this->error = $newndfline->error;
369 $this->errors = $newndfline->errors;
389 $result = $this->
call_trigger(
'EXPENSE_REPORT_CREATE', $user);
401 $this->
db->rollback();
405 $this->
db->rollback();
409 dol_syslog(get_class($this).
"::create error ".$this->error, LOG_ERR);
410 $this->
db->rollback();
414 $this->error = $this->
db->lasterror().
" sql=".$sql;
415 $this->
db->rollback();
433 if (empty($fk_user_author)) {
434 $fk_user_author = $user->id;
444 $objFrom = clone $this;
449 $this->fk_statut = 0;
452 $this->fk_user_creat = $user->id;
453 $this->fk_user_author = $fk_user_author;
454 $this->fk_user_valid =
'';
455 $this->date_create =
'';
456 $this->date_creation =
'';
457 $this->date_validation =
'';
460 if (is_array($this->lines) && count($this->lines) > 0) {
461 foreach ($this->lines as $key => $line) {
462 $this->lines[$key]->fk_ecm_files = 0;
467 $this->context[
'createfromclone'] =
'createfromclone';
468 $result = $this->
create($user);
475 if (is_object($hookmanager)) {
476 $parameters = array(
'objFrom'=>$objFrom);
478 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
480 $this->errors += $hookmanager->errors;
481 $this->error = $hookmanager->error;
487 unset($this->context[
'createfromclone']);
494 $this->
db->rollback();
508 public function update($user, $notrigger = 0, $userofexpensereport =
null)
515 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
516 $sql .=
" total_ht = ".$this->total_ht;
517 $sql .=
" , total_ttc = ".$this->total_ttc;
518 $sql .=
" , total_tva = ".$this->total_tva;
519 $sql .=
" , date_debut = '".$this->db->idate($this->date_debut).
"'";
520 $sql .=
" , date_fin = '".$this->db->idate($this->date_fin).
"'";
521 if ($userofexpensereport && is_object($userofexpensereport)) {
522 $sql .=
" , fk_user_author = ".($userofexpensereport->id > 0 ? $userofexpensereport->id :
"null");
524 $sql .=
" , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator :
"null");
525 $sql .=
" , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid :
"null");
526 $sql .=
" , fk_user_approve = ".($this->fk_user_approve > 0 ? $this->fk_user_approve :
"null");
527 $sql .=
" , fk_user_modif = ".$user->id;
528 $sql .=
" , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut :
'0');
529 $sql .=
" , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement :
"null");
530 $sql .=
" , note_public = ".(!empty($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"''");
531 $sql .=
" , note_private = ".(!empty($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"''");
532 $sql .=
" , detail_refuse = ".(!empty($this->detail_refuse) ?
"'".$this->db->escape($this->detail_refuse).
"'" :
"''");
533 $sql .=
" WHERE rowid = ".((int) $this->
id);
535 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
536 $result = $this->
db->query($sql);
540 $result = $this->
call_trigger(
'EXPENSE_REPORT_MODIFY', $user);
552 $this->
db->rollback();
553 $this->error = $this->
db->error();
557 $this->
db->rollback();
558 $this->error = $this->
db->error();
570 public function fetch($id, $ref =
'')
574 $sql =
"SELECT d.rowid, d.entity, d.ref, d.note_public, d.note_private,";
575 $sql .=
" d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,";
576 $sql .=
" d.date_refuse, d.date_cancel,";
577 $sql .=
" d.total_ht, d.total_ttc, d.total_tva,";
578 $sql .=
" d.localtax1 as total_localtax1, d.localtax2 as total_localtax2,";
579 $sql .=
" d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,";
580 $sql .=
" d.fk_user_creat, d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
581 $sql .=
" d.fk_user_valid, d.fk_user_approve,";
582 $sql .=
" d.fk_statut as status, d.fk_c_paiement, d.paid";
583 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as d";
585 $sql .=
" WHERE d.ref = '".$this->db->escape($ref).
"'";
587 $sql .=
" WHERE d.rowid = ".((int) $id);
591 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
594 $obj = $this->
db->fetch_object(
$resql);
596 $this->
id = $obj->rowid;
597 $this->
ref = $obj->ref;
599 $this->entity = $obj->entity;
601 $this->total_ht = $obj->total_ht;
602 $this->total_tva = $obj->total_tva;
603 $this->total_ttc = $obj->total_ttc;
604 $this->localtax1 = $obj->total_localtax1;
605 $this->localtax2 = $obj->total_localtax2;
606 $this->total_localtax1 = $obj->total_localtax1;
607 $this->total_localtax2 = $obj->total_localtax2;
609 $this->note_public = $obj->note_public;
610 $this->note_private = $obj->note_private;
611 $this->detail_refuse = $obj->detail_refuse;
612 $this->detail_cancel = $obj->detail_cancel;
614 $this->date_debut = $this->
db->jdate($obj->date_debut);
615 $this->date_fin = $this->
db->jdate($obj->date_fin);
616 $this->date_valid = $this->
db->jdate($obj->date_valid);
617 $this->date_approve = $this->
db->jdate($obj->date_approve);
618 $this->date_create = $this->
db->jdate($obj->date_create);
619 $this->date_modif = $this->
db->jdate($obj->date_modif);
620 $this->date_refuse = $this->
db->jdate($obj->date_refuse);
621 $this->date_cancel = $this->
db->jdate($obj->date_cancel);
623 $this->fk_user_creat = $obj->fk_user_creat;
624 $this->fk_user_author = $obj->fk_user_author;
625 $this->fk_user_modif = $obj->fk_user_modif;
626 $this->fk_user_validator = $obj->fk_user_validator;
627 $this->fk_user_valid = $obj->fk_user_valid;
628 $this->fk_user_refuse = $obj->fk_user_refuse;
629 $this->fk_user_cancel = $obj->fk_user_cancel;
630 $this->fk_user_approve = $obj->fk_user_approve;
632 $user_author =
new User($this->
db);
633 if ($this->fk_user_author > 0) {
634 $user_author->fetch($this->fk_user_author);
637 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
639 $user_approver =
new User($this->
db);
640 if ($this->fk_user_approve > 0) {
641 $user_approver->fetch($this->fk_user_approve);
642 } elseif ($this->fk_user_validator > 0) {
643 $user_approver->fetch($this->fk_user_validator);
645 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
647 $this->fk_statut = $obj->status;
648 $this->status = $obj->status;
649 $this->fk_c_paiement = $obj->fk_c_paiement;
650 $this->paid = $obj->paid;
652 if ($this->status == self::STATUS_APPROVED || $this->status == self::STATUS_CLOSED) {
653 $user_valid =
new User($this->
db);
654 if ($this->fk_user_valid > 0) {
655 $user_valid->fetch($this->fk_user_valid);
657 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
669 $this->error = $this->
db->lasterror();
685 public function set_paid($id, $fuser, $notrigger = 0)
688 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
689 return $this->
setPaid($id, $fuser, $notrigger);
700 public function setPaid($id, $fuser, $notrigger = 0)
705 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
706 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid=1";
709 dol_syslog(get_class($this).
"::set_paid", LOG_DEBUG);
712 if ($this->
db->affected_rows(
$resql)) {
715 $result = $this->
call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
727 $this->
db->rollback();
728 $this->error = $this->
db->error();
736 $this->
db->rollback();
750 return $this->
LibStatut($this->status, $mode);
766 $labelStatus = $langs->transnoentitiesnoconv($this->statuts[$status]);
767 $labelStatusShort = $langs->transnoentitiesnoconv($this->statuts_short[$status]);
769 $statusType = $this->statuts_logo[$status];
771 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
785 $sql =
"SELECT f.rowid,";
786 $sql .=
" f.date_create as datec,";
787 $sql .=
" f.tms as date_modification,";
788 $sql .=
" f.date_valid as datev,";
789 $sql .=
" f.date_approve as datea,";
790 $sql .=
" f.fk_user_creat as fk_user_creation,";
791 $sql .=
" f.fk_user_author as fk_user_author,";
792 $sql .=
" f.fk_user_modif as fk_user_modification,";
793 $sql .=
" f.fk_user_valid,";
794 $sql .=
" f.fk_user_approve";
795 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
796 $sql .=
" WHERE f.rowid = ".((int) $id);
797 $sql .=
" AND f.entity = ".$conf->entity;
802 $obj = $this->
db->fetch_object(
$resql);
804 $this->
id = $obj->rowid;
806 $this->date_creation = $this->
db->jdate($obj->datec);
807 $this->date_modification = $this->
db->jdate($obj->date_modification);
808 $this->date_validation = $this->
db->jdate($obj->datev);
809 $this->date_approbation = $this->
db->jdate($obj->datea);
811 $cuser =
new User($this->
db);
812 $cuser->fetch($obj->fk_user_author);
813 $this->user_creation = $cuser;
815 if ($obj->fk_user_creation) {
816 $cuser =
new User($this->
db);
817 $cuser->fetch($obj->fk_user_creation);
818 $this->user_creation = $cuser;
820 if ($obj->fk_user_valid) {
821 $vuser =
new User($this->
db);
822 $vuser->fetch($obj->fk_user_valid);
823 $this->user_validation = $vuser;
825 if ($obj->fk_user_modification) {
826 $muser =
new User($this->
db);
827 $muser->fetch($obj->fk_user_modification);
828 $this->user_modification = $muser;
830 if ($obj->fk_user_approve) {
831 $auser =
new User($this->
db);
832 $auser->fetch($obj->fk_user_approve);
833 $this->user_approve = $auser;
853 global $user, $langs, $conf;
859 $this->
ref =
'SPECIMEN';
862 $this->date_create = $now;
863 $this->date_debut = $now;
864 $this->date_fin = $now;
865 $this->date_valid = $now;
866 $this->date_approve = $now;
871 $this->fk_statut = 5;
873 $this->fk_user_author = $user->id;
874 $this->fk_user_validator = $user->id;
875 $this->fk_user_valid = $user->id;
876 $this->fk_user_approve = $user->id;
878 $this->note_private =
'Private note';
879 $this->note_public =
'SPECIMEN';
882 while ($xnbp < $nbp) {
884 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
885 $line->date = ($now - 3600 * (1 + $xnbp));
886 $line->total_ht = 100;
887 $line->total_tva = 20;
888 $line->total_ttc = 120;
891 $line->value_unit = 120;
892 $line->fk_expensereport = 0;
893 $line->type_fees_code =
'TRA';
894 $line->fk_c_type_fees = $type_fees_id;
896 $line->projet_ref =
'ABC';
898 $this->lines[$xnbp] = $line;
901 $this->total_ht += $line->total_ht;
902 $this->total_tva += $line->total_tva;
903 $this->total_ttc += $line->total_ttc;
918 global $conf, $db, $langs;
920 $langs->load(
'trips');
922 if ($user->rights->expensereport->lire) {
923 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
924 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
925 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
927 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
928 $result = $this->
db->query($sql);
930 $num = $this->
db->num_rows($result);
936 $objp = $this->
db->fetch_object($result);
938 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
939 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
940 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
942 $result2 = $this->
db->query($sql2);
943 $obj = $this->
db->fetch_object($result2);
945 $objp->fk_user_author = $obj->fk_user_author;
946 $objp->ref = $obj->ref;
947 $objp->fk_c_expensereport_status = $obj->status;
948 $objp->rowid = $obj->rowid;
950 $total_HT = $total_HT + $objp->total_ht;
951 $total_TTC = $total_TTC + $objp->total_ttc;
952 $author =
new User($this->
db);
953 $author->fetch($objp->fk_user_author);
956 print
'<td><a href="'.DOL_URL_ROOT.
'/expensereport/card.php?id='.$objp->rowid.
'">'.$objp->ref_num.
'</a></td>';
957 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
958 print
'<td>'.$author->getNomUrl(1).
'</td>';
959 print
'<td>'.$objp->comments.
'</td>';
960 print
'<td class="right">'.price($objp->total_ht).
'</td>';
961 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
962 print
'<td class="right">';
964 switch ($objp->fk_c_expensereport_status) {
966 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
969 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
972 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
975 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
978 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
995 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
996 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
997 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
998 print
'<td> </td>';
1001 $this->error = $this->
db->lasterror();
1018 $this->lines = array();
1020 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1021 $sql .=
" de.".$this->fk_element.
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1022 $sql .=
' de.tva_tx, de.vat_src_code,';
1023 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1024 $sql .=
' de.fk_ecm_files,';
1025 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1026 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1027 $sql .=
' ctf.code as code_type_fees, ctf.label as libelle_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1028 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1029 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as de';
1030 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1031 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1032 $sql .=
" WHERE de.".$this->fk_element.
" = ".((int) $this->
id);
1033 if (!empty($conf->global->EXPENSEREPORT_LINES_SORTED_BY_ROWID)) {
1034 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1036 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1041 $num = $this->
db->num_rows(
$resql);
1044 $objp = $this->
db->fetch_object(
$resql);
1048 $deplig->rowid = $objp->rowid;
1049 $deplig->id = $objp->rowid;
1050 $deplig->comments = $objp->comments;
1051 $deplig->qty = $objp->qty;
1052 $deplig->value_unit = $objp->value_unit;
1053 $deplig->date = $objp->date;
1054 $deplig->dates = $this->
db->jdate($objp->date);
1056 $deplig->fk_expensereport = $objp->fk_expensereport;
1057 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1058 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1059 $deplig->fk_projet = $objp->fk_project;
1060 $deplig->fk_project = $objp->fk_project;
1061 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1063 $deplig->total_ht = $objp->total_ht;
1064 $deplig->total_tva = $objp->total_tva;
1065 $deplig->total_ttc = $objp->total_ttc;
1066 $deplig->total_localtax1 = $objp->total_localtax1;
1067 $deplig->total_localtax2 = $objp->total_localtax2;
1069 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1070 $deplig->type_fees_libelle = $objp->libelle_type_fees;
1071 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1073 $deplig->tva_tx = $objp->tva_tx;
1074 $deplig->vatrate = $objp->tva_tx;
1075 $deplig->vat_src_code = $objp->vat_src_code;
1076 $deplig->localtax1_tx = $objp->localtax1_tx;
1077 $deplig->localtax2_tx = $objp->localtax2_tx;
1078 $deplig->localtax1_type = $objp->localtax1_type;
1079 $deplig->localtax2_type = $objp->localtax2_type;
1081 $deplig->projet_ref = $objp->ref_projet;
1082 $deplig->projet_title = $objp->title_projet;
1084 $deplig->rule_warning_message = $objp->rule_warning_message;
1086 $deplig->rang = $objp->rang;
1088 $this->lines[$i] = $deplig;
1095 $this->error = $this->
db->lasterror();
1096 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1109 public function delete(
User $user =
null, $notrigger =
false)
1112 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1120 $result = $this->
call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1128 if (!$error && !empty($this->table_element_line)) {
1129 $tabletodelete = $this->table_element_line;
1131 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1132 if (!$this->
db->query($sql)) {
1134 $this->error = $this->
db->lasterror();
1135 $this->errors[] = $this->error;
1136 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1161 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1167 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1168 $res = $this->
db->query($sql);
1171 $this->error = $this->
db->lasterror();
1172 $this->errors[] = $this->error;
1173 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1188 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1189 $dir = $conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1190 $file = $dir.
"/".$ref.
".pdf";
1191 if (file_exists($file)) {
1195 $this->error =
'ErrorFailToDeleteFile';
1196 $this->errors[] = $this->error;
1197 $this->
db->rollback();
1201 if (file_exists($dir)) {
1204 $this->error =
'ErrorFailToDeleteDir';
1205 $this->errors[] = $this->error;
1206 $this->
db->rollback();
1214 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1215 $this->
db->commit();
1218 $this->
db->rollback();
1232 global $conf, $langs, $user;
1238 if ($this->status == self::STATUS_VALIDATED) {
1239 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1243 $this->date_valid = $now;
1246 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
1251 if (empty($num) || $num < 0) {
1260 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1261 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1262 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1263 $sql .=
" date_valid = '".$this->db->idate($this->date_valid).
"',";
1264 $sql .=
" fk_user_valid = ".((int) $user->id);
1265 $sql .=
" WHERE rowid = ".((int) $this->
id);
1269 if (!$error && !$notrigger) {
1271 $result = $this->
call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1279 $this->oldref = $this->ref;
1282 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1283 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1286 $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).
"'";
1287 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->
db->escape($this->
ref).
"' AND entity = ".((int) $this->entity);
1290 $error++; $this->error = $this->
db->lasterror();
1296 $dirsource = $conf->expensereport->multidir_output[$this->entity].
'/'.$oldref;
1297 $dirdest = $conf->expensereport->multidir_output[$this->entity].
'/'.$newref;
1298 if (!$error && file_exists($dirsource)) {
1299 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1301 if (@rename($dirsource, $dirdest)) {
1304 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1305 foreach ($listoffiles as $fileentry) {
1306 $dirsource = $fileentry[
'name'];
1307 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1308 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1309 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1310 @rename($dirsource, $dirdest);
1323 if (empty($error)) {
1324 $this->
db->commit();
1327 $this->
db->rollback();
1328 $this->error = $this->
db->error();
1332 $this->
db->rollback();
1333 $this->error = $this->
db->lasterror();
1348 global $conf, $langs;
1351 $sql =
'SELECT date_debut';
1352 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1353 $sql .=
" WHERE rowid = ".((int) $this->
id);
1355 $result = $this->
db->query($sql);
1357 $objp = $this->
db->fetch_object($result);
1359 $this->date_debut = $this->
db->jdate($objp->date_debut);
1361 if ($this->status != self::STATUS_VALIDATED) {
1362 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1363 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1364 $sql .=
" WHERE rowid = ".((int) $this->
id);
1366 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1368 if ($this->
db->query($sql)) {
1371 $this->error = $this->
db->lasterror();
1375 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1392 $this->date_approve = $now;
1393 if ($this->status != self::STATUS_APPROVED) {
1396 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1397 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1398 $sql .=
" date_approve='".$this->db->idate($this->date_approve).
"'";
1399 $sql .=
" WHERE rowid = ".((int) $this->
id);
1400 if ($this->
db->query($sql)) {
1403 $result = $this->
call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1411 if (empty($error)) {
1412 $this->
db->commit();
1415 $this->
db->rollback();
1416 $this->error = $this->
db->error();
1420 $this->
db->rollback();
1421 $this->error = $this->
db->lasterror();
1425 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1439 public function setDeny($fuser, $details, $notrigger = 0)
1445 if ($this->status != self::STATUS_REFUSED) {
1446 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1447 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1448 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1449 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1450 $sql .=
" fk_user_approve = NULL";
1451 $sql .=
" WHERE rowid = ".((int) $this->
id);
1452 if ($this->
db->query($sql)) {
1453 $this->fk_statut = 99;
1455 $this->fk_user_refuse = $fuser->id;
1456 $this->detail_refuse = $details;
1457 $this->date_refuse = $now;
1461 $result = $this->
call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1469 if (empty($error)) {
1470 $this->
db->commit();
1473 $this->
db->rollback();
1474 $this->error = $this->
db->error();
1478 $this->
db->rollback();
1479 $this->error = $this->
db->lasterror();
1483 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1500 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1501 return $this->
setUnpaid($fuser, $notrigger);
1518 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1519 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1520 $sql .=
" WHERE rowid = ".((int) $this->
id);
1522 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1524 if ($this->
db->query($sql)) {
1527 $result = $this->
call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1535 if (empty($error)) {
1536 $this->
db->commit();
1539 $this->
db->rollback();
1540 $this->error = $this->
db->error();
1544 $this->
db->rollback();
1545 $this->error = $this->
db->error();
1549 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1566 $this->date_cancel = $this->
db->idate(
dol_now());
1567 if ($this->status != self::STATUS_CANCELED) {
1570 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1571 $sql .=
" SET fk_statut = ".self::STATUS_CANCELED.
", fk_user_cancel = ".((int) $fuser->id);
1572 $sql .=
", date_cancel='".$this->db->idate($this->date_cancel).
"'";
1573 $sql .=
" ,detail_cancel='".$this->db->escape($detail).
"'";
1574 $sql .=
" WHERE rowid = ".((int) $this->
id);
1576 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1578 if ($this->
db->query($sql)) {
1581 $result = $this->
call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1589 if (empty($error)) {
1590 $this->
db->commit();
1593 $this->
db->rollback();
1594 $this->error = $this->
db->error();
1598 $this->
db->rollback();
1599 $this->error = $this->
db->error();
1603 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1614 global $langs, $conf;
1615 $langs->load(
"trips");
1617 if (!empty($conf->global->EXPENSEREPORT_ADDON)) {
1620 $file = $conf->global->EXPENSEREPORT_ADDON.
".php";
1621 $classname = $conf->global->EXPENSEREPORT_ADDON;
1624 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1625 foreach ($dirmodels as $reldir) {
1626 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1629 $mybool |= @include_once $dir.$file;
1632 if ($mybool ===
false) {
1637 $obj =
new $classname();
1638 $numref = $obj->getNextValue($this);
1640 if ($numref !=
"") {
1643 $this->error = $obj->error;
1644 $this->errors = $obj->errors;
1649 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1666 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1668 global $langs, $conf, $hookmanager;
1672 $url = DOL_URL_ROOT.
'/expensereport/card.php?id='.$this->id;
1678 $label =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1679 if (isset($this->status)) {
1680 $label .=
' '.$this->getLibStatut(5);
1682 if (!empty($this->
ref)) {
1683 $label .=
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1685 if (!empty($this->total_ht)) {
1686 $label .=
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1688 if (!empty($this->total_tva)) {
1689 $label .=
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1691 if (!empty($this->total_ttc)) {
1692 $label .=
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
1695 $label .=
' - '.$moretitle;
1698 if ($option !=
'nolink') {
1700 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1701 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1702 $add_save_lastsearch_values = 1;
1704 if ($add_save_lastsearch_values) {
1705 $url .=
'&save_lastsearch_values=1';
1715 if (empty($notooltip)) {
1716 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1717 $label = $langs->trans(
"ShowExpenseReport");
1718 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1720 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
1721 $linkclose .=
' class="classfortooltip"';
1724 $linkstart =
'<a href="'.$url.
'"';
1725 $linkstart .= $linkclose.
'>';
1728 $result .= $linkstart;
1730 $result .=
img_object(($notooltip ?
'' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
1732 if ($withpicto != 2) {
1733 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1735 $result .= $linkend;
1738 $hookmanager->initHooks(array($this->element .
'dao'));
1739 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
1740 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1742 $result = $hookmanager->resPrint;
1744 $result .= $hookmanager->resPrint;
1760 $this->total_ht = $this->total_ht + $ligne_total_ht;
1761 $this->total_tva = $this->total_tva + $ligne_total_tva;
1762 $this->total_ttc = $this->total_ht + $this->total_tva;
1764 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1765 $sql .=
" total_ht = ".$this->total_ht;
1766 $sql .=
" , total_ttc = ".$this->total_ttc;
1767 $sql .=
" , total_tva = ".$this->total_tva;
1768 $sql .=
" WHERE rowid = ".((int) $this->
id);
1770 $result = $this->
db->query($sql);
1774 $this->error = $this->
db->error();
1794 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)
1796 global $conf, $langs, $mysoc;
1798 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);
1800 if ($this->status == self::STATUS_DRAFT) {
1804 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1805 $fk_c_type_fees = 0;
1807 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1808 $fk_c_exp_tax_cat = 0;
1810 if (empty($vatrate) || $vatrate < 0) {
1816 if (empty($fk_project)) {
1821 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1832 $seller->tva_assuj = 1;
1839 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
1840 $vat_src_code = $reg[1];
1841 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
1843 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
1845 $tmp =
calcul_price_total($qty, $up, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
1847 $this->line->value_unit = $up;
1849 $this->line->vat_src_code = $vat_src_code;
1850 $this->line->vatrate =
price2num($vatrate);
1851 $this->line->localtax1_tx = $localtaxes_type[1];
1852 $this->line->localtax2_tx = $localtaxes_type[3];
1853 $this->line->localtax1_type = $localtaxes_type[0];
1854 $this->line->localtax2_type = $localtaxes_type[2];
1856 $this->line->total_ttc = $tmp[2];
1857 $this->line->total_ht = $tmp[0];
1858 $this->line->total_tva = $tmp[1];
1859 $this->line->total_localtax1 = $tmp[9];
1860 $this->line->total_localtax2 = $tmp[10];
1862 $this->line->fk_expensereport = $this->id;
1863 $this->line->qty = $qty;
1864 $this->line->date = $date;
1865 $this->line->fk_c_type_fees = $fk_c_type_fees;
1866 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
1867 $this->line->comments = $comments;
1868 $this->line->fk_projet = $fk_project;
1869 $this->line->fk_project = $fk_project;
1871 $this->line->fk_ecm_files = $fk_ecm_files;
1876 $result = $this->line->insert(0,
true);
1880 $this->
db->commit();
1881 return $this->line->id;
1883 $this->
db->rollback();
1887 $this->error = $this->line->error;
1888 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
1889 $this->
db->rollback();
1893 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
1894 $this->error =
'ErrorExpenseNotDraft';
1908 global $user, $conf, $db, $langs, $mysoc;
1910 $langs->load(
'trips');
1913 if (!is_object($seller)) {
1915 $seller->tva_assuj = 1;
1919 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
1922 $rule_warning_message_tab = array();
1924 $current_total_ttc = $this->line->total_ttc;
1925 $new_current_total_ttc = $this->line->total_ttc;
1928 foreach ($rulestocheck as $rule) {
1929 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
1930 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
1932 $amount_to_test = $current_total_ttc;
1935 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
1937 if ($amount_to_test > $rule->amount) {
1940 if ($rule->restrictive) {
1941 $this->error =
'ExpenseReportConstraintViolationError';
1942 $this->errors[] = $this->error;
1944 $new_current_total_ttc -= $amount_to_test - $rule->amount;
1945 $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));
1947 $this->error =
'ExpenseReportConstraintViolationWarning';
1948 $this->errors[] = $this->error;
1950 $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));
1957 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
1959 if ($violation > 0) {
1960 $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);
1962 $this->line->value_unit = $tmp[5];
1963 $this->line->total_ttc = $tmp[2];
1964 $this->line->total_ht = $tmp[0];
1965 $this->line->total_tva = $tmp[1];
1966 $this->line->total_localtax1 = $tmp[9];
1967 $this->line->total_localtax2 = $tmp[10];
1984 global $conf, $mysoc;
1986 if (empty($conf->global->MAIN_USE_EXPENSE_IK)) {
1990 $userauthor =
new User($this->
db);
1991 if ($userauthor->fetch($this->fk_user_author) <= 0) {
1992 $this->error =
'ErrorCantFetchUser';
1993 $this->errors[] =
'ErrorCantFetchUser';
1998 if (!is_object($seller)) {
2000 $seller->tva_assuj = 1;
2004 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
2006 if (empty($range)) {
2007 $this->error =
'ErrorNoRangeAvailable';
2008 $this->errors[] =
'ErrorNoRangeAvailable';
2012 if (!empty($conf->global->MAIN_EXPENSE_APPLY_ENTIRE_OFFSET)) {
2013 $ikoffset = $range->ikoffset;
2015 $ikoffset = $range->ikoffset / 12;
2020 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2021 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2023 $this->line->value_unit = $tmp[5];
2024 $this->line->total_ttc = $tmp[2];
2025 $this->line->total_ht = $tmp[0];
2026 $this->line->total_tva = $tmp[1];
2027 $this->line->total_localtax1 = $tmp[9];
2028 $this->line->total_localtax2 = $tmp[10];
2043 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2044 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2045 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2046 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2047 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2048 if (!empty($this->line->id)) {
2049 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2052 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2055 $num = $this->
db->num_rows(
$resql);
2083 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)
2085 global $user, $mysoc;
2087 if ($this->status == self::STATUS_DRAFT || $this->status == self::STATUS_REFUSED) {
2095 $seller->tva_assuj = 1;
2096 $seller->localtax1_assuj = $mysoc->localtax1_assuj;
2097 $seller->localtax2_assuj = $mysoc->localtax1_assuj;
2105 if (preg_match(
'/\((.*)\)/', $vatrate, $reg)) {
2106 $vat_src_code = $reg[1];
2107 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2109 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2111 $tmp =
calcul_price_total($qty, $value_unit, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2116 $tx_tva = $vatrate / 100;
2117 $tx_tva = $tx_tva + 1;
2120 $this->line->comments = $comments;
2121 $this->line->qty = $qty;
2122 $this->line->value_unit = $value_unit;
2123 $this->line->date = $date;
2125 $this->line->fk_expensereport = $expensereport_id;
2126 $this->line->fk_c_type_fees = $type_fees_id;
2127 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2128 $this->line->fk_projet = $projet_id;
2129 $this->line->fk_project = $projet_id;
2131 $this->line->vat_src_code = $vat_src_code;
2132 $this->line->vatrate =
price2num($vatrate);
2133 $this->line->localtax1_tx = $localtaxes_type[1];
2134 $this->line->localtax2_tx = $localtaxes_type[3];
2135 $this->line->localtax1_type = $localtaxes_type[0];
2136 $this->line->localtax2_type = $localtaxes_type[2];
2138 $this->line->total_ttc = $tmp[2];
2139 $this->line->total_ht = $tmp[0];
2140 $this->line->total_tva = $tmp[1];
2141 $this->line->total_localtax1 = $tmp[9];
2142 $this->line->total_localtax2 = $tmp[10];
2144 $this->line->fk_ecm_files = $fk_ecm_files;
2146 $this->line->id = ((int) $rowid);
2149 $sql =
"SELECT c.code as code_type_fees, c.label as libelle_type_fees";
2150 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2151 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2154 $objp_fees = $this->
db->fetch_object(
$resql);
2155 $this->line->type_fees_code = $objp_fees->code_type_fees;
2156 $this->line->type_fees_libelle = $objp_fees->libelle_type_fees;
2161 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2162 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2163 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2166 $objp_projet = $this->
db->fetch_object(
$resql);
2167 $this->line->projet_ref = $objp_projet->ref_projet;
2168 $this->line->projet_title = $objp_projet->title_projet;
2175 $result = $this->line->update($user);
2180 if (!$error && !$notrigger) {
2182 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_MODIFY', $user);
2190 $this->
db->commit();
2193 $this->error = $this->line->error;
2194 $this->errors = $this->line->errors;
2195 $this->
db->rollback();
2217 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2224 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2225 $sql .=
' WHERE rowid = '.((int) $rowid);
2227 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2228 $result = $this->
db->query($sql);
2230 if (!$result || $error > 0 ) {
2231 $this->error = $this->
db->error();
2232 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2233 $this->
db->rollback();
2239 $this->
db->commit();
2256 $sql =
"SELECT rowid, date_debut, date_fin";
2257 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2258 $sql .=
" WHERE fk_user_author = '{$fuser->id}'";
2260 dol_syslog(get_class($this).
"::periode_existe sql=".$sql);
2261 $result = $this->
db->query($sql);
2263 $num_rows = $this->
db->num_rows($result); $i = 0;
2265 if ($num_rows > 0) {
2266 $date_d_form = $date_debut;
2267 $date_f_form = $date_fin;
2269 while ($i < $num_rows) {
2270 $objp = $this->
db->fetch_object($result);
2272 $date_d_req = $this->
db->jdate($objp->date_debut);
2273 $date_f_req = $this->
db->jdate($objp->date_fin);
2275 if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) {
2276 return $objp->rowid;
2287 $this->error = $this->
db->lasterror();
2288 dol_syslog(get_class($this).
"::periode_existe Error ".$this->error, LOG_ERR);
2304 $users_validator = array();
2306 $sql =
"SELECT DISTINCT ur.fk_user";
2307 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2308 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2310 $sql .=
" SELECT DISTINCT ugu.fk_user";
2311 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2312 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2315 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2316 $result = $this->
db->query($sql);
2318 $num_rows = $this->
db->num_rows($result); $i = 0;
2319 while ($i < $num_rows) {
2320 $objp = $this->
db->fetch_object($result);
2321 array_push($users_validator, $objp->fk_user);
2324 return $users_validator;
2326 $this->error = $this->
db->lasterror();
2327 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2343 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2347 $outputlangs->load(
"trips");
2350 if (!empty($this->model_pdf)) {
2351 $modele = $this->model_pdf;
2352 } elseif (!empty($this->modelpdf)) {
2353 $modele = $this->modelpdf;
2354 } elseif (!empty($conf->global->EXPENSEREPORT_ADDON_PDF)) {
2355 $modele = $conf->global->EXPENSEREPORT_ADDON_PDF;
2359 if (!empty($modele)) {
2360 $modelpath =
"core/modules/expensereport/doc/";
2362 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2378 $sql =
"SELECT id, code, label";
2379 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2380 $sql .=
" WHERE active = ".((int) $active);
2381 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2382 $result = $this->
db->query($sql);
2384 $num = $this->
db->num_rows($result);
2387 $obj = $this->
db->fetch_object($result);
2388 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2406 global $conf, $user;
2408 $this->nb = array();
2410 $sql =
"SELECT count(ex.rowid) as nb";
2411 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2412 $sql .=
" WHERE ex.fk_statut > 0";
2413 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2414 if (empty($user->rights->expensereport->readall)) {
2415 $userchildids = $user->getAllChildIds(1);
2416 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2417 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2422 while ($obj = $this->
db->fetch_object(
$resql)) {
2423 $this->nb[
"expensereports"] = $obj->nb;
2429 $this->error = $this->
db->error();
2445 global $conf, $langs;
2453 $sql =
"SELECT ex.rowid, ex.date_valid";
2454 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2455 if ($option ==
'toapprove') {
2456 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2458 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2460 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2461 if (empty($user->rights->expensereport->readall)) {
2462 $userchildids = $user->getAllChildIds(1);
2463 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2464 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2469 $langs->load(
"trips");
2472 if ($option ==
'toapprove') {
2473 $response->warning_delay = $conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2474 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2475 $response->labelShort = $langs->trans(
"ToApprove");
2478 $response->warning_delay = $conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2479 $response->label = $langs->trans(
"ExpenseReportsToPay");
2480 $response->labelShort = $langs->trans(
"StatusToPay");
2481 $response->url = DOL_URL_ROOT.
'/expensereport/list.php?mainmenu=hrm&statut='.
self::STATUS_APPROVED;
2485 while ($obj = $this->
db->fetch_object(
$resql)) {
2486 $response->nbtodo++;
2488 if ($option ==
'toapprove') {
2489 if ($this->
db->jdate($obj->date_valid) < ($now - $conf->expensereport->approve->warning_delay)) {
2490 $response->nbtodolate++;
2493 if ($this->
db->jdate($obj->date_valid) < ($now - $conf->expensereport->payment->warning_delay)) {
2494 $response->nbtodolate++;
2502 $this->error = $this->
db->error();
2518 if ($option ==
'toapprove' && $this->status != 2) {
2521 if ($option ==
'topay' && $this->status != 5) {
2526 if ($option ==
'toapprove') {
2527 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->approve->warning_delay);
2529 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->payment->warning_delay);
2540 $alreadydispatched = 0;
2542 $type =
'expense_report';
2544 $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);
2547 $obj = $this->
db->fetch_object(
$resql);
2549 $alreadydispatched = $obj->nb;
2552 $this->error = $this->
db->lasterror();
2556 if ($alreadydispatched) {
2569 $table =
'payment_expensereport';
2570 $field =
'fk_expensereport';
2572 $sql =
'SELECT sum(amount) as amount';
2573 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2574 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
2576 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2579 $obj = $this->
db->fetch_object(
$resql);
2581 return (empty($obj->amount) ? 0 : $obj->amount);
2583 $this->error = $this->
db->lasterror();
2598 global $langs,$user,$db,$conf;
2607 $this->error = $langs->trans(
'ErrorBadParameterCat');
2612 $this->error = $langs->trans(
'ErrorBadParameterQty');
2616 $currentUser =
new User($db);
2617 $currentUser->fetch($this->fk_user);
2618 $currentUser->getrights(
'expensereport');
2622 $sql =
" SELECT r.range_ik, t.ikoffset, t.coef";
2623 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2624 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2625 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2626 $sql .=
" ORDER BY r.range_ik ASC";
2628 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2630 $result = $this->
db->query($sql);
2633 if ($conf->global->EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR) {
2635 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2636 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2637 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2638 $sql.=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2639 $sql.=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2640 $sql.=
" AND tf.code = 'EX_KME' ";
2646 $obj = $this->
db->fetch_object(
$resql);
2647 $cumulYearQty = $obj->cumul;
2650 $qty = $cumulYearQty + $qty;
2653 $num = $this->
db->num_rows($result);
2656 for ($i = 0; $i < $num; $i++) {
2657 $obj = $this->
db->fetch_object($result);
2663 for ($i = 0; $i < $num; $i++) {
2664 if ($i < ($num - 1)) {
2665 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i+1]->range_ik) {
2666 $coef = $ranges[$i]->coef;
2667 $offset = $ranges[$i]->ikoffset;
2670 if ($qty > $ranges[$i]->range_ik) {
2671 $coef = $ranges[$i]->coef;
2672 $offset = $ranges[$i]->ikoffset;
2679 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2683 $this->error = $this->
db->error().
" sql=".$sql;
2704 public $table_element =
'expensereport_det';
2724 public $fk_c_type_fees;
2729 public $fk_c_exp_tax_cat;
2739 public $fk_expensereport;
2741 public $type_fees_code;
2742 public $type_fees_libelle;
2743 public $type_fees_accountancy_code;
2746 public $projet_title;
2750 public $vat_src_code;
2752 public $localtax1_tx;
2753 public $localtax2_tx;
2754 public $localtax1_type;
2755 public $localtax2_type;
2760 public $total_localtax1;
2761 public $total_localtax2;
2767 public $fk_multicurrency;
2772 public $multicurrency_code;
2773 public $multicurrency_tx;
2774 public $multicurrency_total_ht;
2775 public $multicurrency_total_tva;
2776 public $multicurrency_total_ttc;
2781 public $fk_ecm_files;
2783 public $rule_warning_message;
2804 $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,';
2805 $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,';
2806 $sql .=
' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,';
2807 $sql .=
' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
2808 $sql .=
' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
2809 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det as fde';
2810 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
2811 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as pjt ON fde.fk_projet=pjt.rowid';
2812 $sql .=
' WHERE fde.rowid = '.((int) $rowid);
2814 $result = $this->
db->query($sql);
2817 $objp = $this->
db->fetch_object($result);
2819 $this->
rowid = $objp->rowid;
2820 $this->
id = $objp->rowid;
2821 $this->
ref = $objp->ref;
2822 $this->fk_expensereport = $objp->fk_expensereport;
2823 $this->comments = $objp->comments;
2824 $this->qty = $objp->qty;
2825 $this->date = $objp->date;
2826 $this->dates = $this->
db->jdate($objp->date);
2827 $this->value_unit = $objp->value_unit;
2828 $this->fk_c_type_fees = $objp->fk_c_type_fees;
2829 $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
2830 $this->fk_projet = $objp->fk_project;
2831 $this->fk_project = $objp->fk_project;
2832 $this->type_fees_code = $objp->type_fees_code;
2833 $this->type_fees_libelle = $objp->type_fees_libelle;
2834 $this->projet_ref = $objp->projet_ref;
2835 $this->projet_title = $objp->projet_title;
2837 $this->
vatrate = $objp->vatrate;
2838 $this->vat_src_code = $objp->vat_src_code;
2839 $this->localtax1_tx = $objp->localtax1_tx;
2840 $this->localtax2_tx = $objp->localtax2_tx;
2841 $this->localtax1_type = $objp->localtax1_type;
2842 $this->localtax2_type = $objp->localtax2_type;
2844 $this->total_ht = $objp->total_ht;
2845 $this->total_tva = $objp->total_tva;
2846 $this->total_ttc = $objp->total_ttc;
2847 $this->total_localtax1 = $objp->total_localtax1;
2848 $this->total_localtax2 = $objp->total_localtax2;
2850 $this->fk_ecm_files = $objp->fk_ecm_files;
2852 $this->rule_warning_message = $objp->rule_warning_message;
2854 $this->
db->free($result);
2867 public function insert($notrigger = 0, $fromaddline =
false)
2869 global $langs, $user, $conf;
2873 dol_syslog(
"ExpenseReportLine::Insert", LOG_DEBUG);
2876 $this->comments = trim($this->comments);
2877 if (empty($this->value_unit)) {
2878 $this->value_unit = 0;
2882 if (empty($this->fk_c_exp_tax_cat)) {
2883 $this->fk_c_exp_tax_cat = 0;
2888 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'expensereport_det';
2889 $sql .=
' (fk_expensereport, fk_c_type_fees, fk_projet,';
2890 $sql .=
' tva_tx, vat_src_code,';
2891 $sql .=
' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
2892 $sql .=
' comments, qty, value_unit,';
2893 $sql .=
' total_ht, total_tva, total_ttc,';
2894 $sql .=
' total_localtax1, total_localtax2,';
2895 $sql .=
' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)';
2896 $sql .=
" VALUES (".$this->db->escape($this->fk_expensereport).
",";
2897 $sql .=
" ".((int) $this->fk_c_type_fees).
",";
2898 $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')).
",";
2899 $sql .=
" ".((float) $this->
vatrate).
",";
2900 $sql .=
" '".$this->db->escape(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"',";
2901 $sql .=
" ".((float)
price2num($this->localtax1_tx)).
",";
2902 $sql .=
" ".((float)
price2num($this->localtax2_tx)).
",";
2903 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
2904 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
2905 $sql .=
" '".$this->db->escape($this->comments).
"',";
2906 $sql .=
" ".((float) $this->qty).
",";
2907 $sql .=
" ".((float) $this->value_unit).
",";
2908 $sql .=
" ".((float)
price2num($this->total_ht)).
",";
2909 $sql .=
" ".((float)
price2num($this->total_tva)).
",";
2910 $sql .=
" ".((float)
price2num($this->total_ttc)).
",";
2911 $sql .=
" ".((float)
price2num($this->total_localtax1)).
",";
2912 $sql .=
" ".((float)
price2num($this->total_localtax2)).
",";
2913 $sql .=
" '".$this->db->idate($this->date).
"',";
2914 $sql .=
" ".(empty($this->rule_warning_message) ?
'null' :
"'".$this->db->escape($this->rule_warning_message).
"'").
",";
2915 $sql .=
" ".((int) $this->fk_c_exp_tax_cat).
",";
2916 $sql .=
" ".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
2921 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
'expensereport_det');
2924 if (!$error && !$notrigger) {
2926 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_CREATE', $user);
2934 if (!$fromaddline) {
2936 $tmpparent->fetch($this->fk_expensereport);
2937 $result = $tmpparent->update_price(1);
2940 $this->error = $tmpparent->error;
2941 $this->errors = $tmpparent->errors;
2949 $this->
db->commit();
2952 $this->error = $this->
db->lasterror();
2953 dol_syslog(
"ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
2954 $this->
db->rollback();
2971 $sql =
'SELECT SUM(d.total_ttc) as total_amount';
2972 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det d';
2973 $sql .=
' INNER JOIN '.MAIN_DB_PREFIX.
'expensereport e ON (d.fk_expensereport = e.rowid)';
2974 $sql .=
' WHERE e.fk_user_author = '.((int) $fk_user);
2975 if (!empty($this->
id)) {
2976 $sql .=
' AND d.rowid <> '.((int) $this->
id);
2978 $sql .=
' AND d.fk_c_type_fees = '.((int) $rule->fk_c_type_fees);
2979 if ($mode ==
'day' || $mode ==
'EX_DAY') {
2980 $sql .=
" AND d.date = '".dol_print_date($this->date,
'%Y-%m-%d').
"'";
2981 } elseif ($mode ==
'mon' || $mode ==
'EX_MON') {
2982 $sql .=
" AND DATE_FORMAT(d.date, '%Y-%m') = '".dol_print_date($this->date,
'%Y-%m').
"'";
2983 } elseif ($mode ==
'year' || $mode ==
'EX_YEA') {
2984 $sql .=
" AND DATE_FORMAT(d.date, '%Y') = '".dol_print_date($this->date,
'%Y').
"'";
2987 dol_syslog(
'ExpenseReportLine::getExpAmount');
2991 $num = $this->
db->num_rows(
$resql);
2993 $obj = $this->
db->fetch_object(
$resql);
2994 $amount = (double) $obj->total_amount;
3000 return $amount + $this->total_ttc;
3011 global $langs, $conf;
3016 $this->comments = trim($this->comments);
3018 $this->value_unit =
price2num($this->value_unit);
3019 if (empty($this->fk_c_exp_tax_cat)) {
3020 $this->fk_c_exp_tax_cat = 0;
3026 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport_det SET";
3027 $sql .=
" comments='".$this->db->escape($this->comments).
"'";
3028 $sql .=
", value_unit = ".((float) $this->value_unit);
3029 $sql .=
", qty=".((float) $this->qty);
3030 $sql .=
", date='".$this->db->idate($this->date).
"'";
3031 $sql .=
", total_ht=".((float)
price2num($this->total_ht,
'MT'));
3032 $sql .=
", total_tva=".((float)
price2num($this->total_tva,
'MT'));
3033 $sql .=
", total_ttc=".((float)
price2num($this->total_ttc,
'MT'));
3034 $sql .=
", total_localtax1=".((float)
price2num($this->total_localtax1,
'MT'));
3035 $sql .=
", total_localtax2=".((float)
price2num($this->total_localtax2,
'MT'));
3036 $sql .=
", tva_tx=".((float) $this->
vatrate);
3037 $sql .=
", vat_src_code='".$this->db->escape($this->vat_src_code).
"'";
3038 $sql .=
", localtax1_tx=".((float) $this->localtax1_tx);
3039 $sql .=
", localtax2_tx=".((float) $this->localtax2_tx);
3040 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
3041 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
3042 $sql .=
", rule_warning_message='".$this->db->escape($this->rule_warning_message).
"'";
3043 $sql .=
", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat);
3044 $sql .=
", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3045 if ($this->fk_c_type_fees) {
3046 $sql .=
", fk_c_type_fees = ".((int) $this->fk_c_type_fees);
3048 $sql .=
", fk_c_type_fees=null";
3050 if ($this->fk_project > 0) {
3051 $sql .=
", fk_projet=".((int) $this->fk_project);
3053 $sql .=
", fk_projet=null";
3055 $sql .=
" WHERE rowid = ".((int) ($this->
rowid ? $this->
rowid : $this->
id));
3062 $result = $tmpparent->fetch($this->fk_expensereport);
3064 $result = $tmpparent->update_price(1);
3067 $this->error = $tmpparent->error;
3068 $this->errors = $tmpparent->errors;
3072 $this->error = $tmpparent->error;
3073 $this->errors = $tmpparent->errors;
3081 $this->
db->commit();
3084 $this->error = $this->
db->lasterror();
3085 dol_syslog(
"ExpenseReportLine::update Error ".$this->error, LOG_ERR);
3086 $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.
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.
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.
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.
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid
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.
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.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
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.
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.
$conf db
API class for accounts.