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;
168 public $fields = array(
169 'rowid' =>array(
'type'=>
'integer',
'label'=>
'ID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
170 'ref' =>array(
'type'=>
'varchar(50)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'showoncombobox'=>1,
'position'=>15),
171 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>20),
172 'ref_number_int' =>array(
'type'=>
'integer',
'label'=>
'Ref number int',
'enabled'=>1,
'visible'=>-1,
'position'=>25),
173 'ref_ext' =>array(
'type'=>
'integer',
'label'=>
'Ref ext',
'enabled'=>1,
'visible'=>-1,
'position'=>30),
174 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total ht',
'enabled'=>1,
'visible'=>-1,
'position'=>35),
175 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total tva',
'enabled'=>1,
'visible'=>-1,
'position'=>40),
176 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax1',
'enabled'=>1,
'visible'=>-1,
'position'=>45),
177 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax2',
'enabled'=>1,
'visible'=>-1,
'position'=>50),
178 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'Total ttc',
'enabled'=>1,
'visible'=>-1,
'position'=>55),
179 'date_debut' =>array(
'type'=>
'date',
'label'=>
'Date debut',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>60),
180 'date_fin' =>array(
'type'=>
'date',
'label'=>
'Date fin',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>65),
181 'date_valid' =>array(
'type'=>
'datetime',
'label'=>
'Date valid',
'enabled'=>1,
'visible'=>-1,
'position'=>75),
182 'date_approve' =>array(
'type'=>
'datetime',
'label'=>
'Date approve',
'enabled'=>1,
'visible'=>-1,
'position'=>80),
183 'date_refuse' =>array(
'type'=>
'datetime',
'label'=>
'Date refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>85),
184 'date_cancel' =>array(
'type'=>
'datetime',
'label'=>
'Date cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>90),
185 'fk_user_author' =>array(
'type'=>
'integer',
'label'=>
'Fk user author',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>100),
186 'fk_user_modif' =>array(
'type'=>
'integer',
'label'=>
'Fk user modif',
'enabled'=>1,
'visible'=>-1,
'position'=>105),
187 'fk_user_valid' =>array(
'type'=>
'integer',
'label'=>
'Fk user valid',
'enabled'=>1,
'visible'=>-1,
'position'=>110),
188 'fk_user_validator' =>array(
'type'=>
'integer',
'label'=>
'Fk user validator',
'enabled'=>1,
'visible'=>-1,
'position'=>115),
189 'fk_user_approve' =>array(
'type'=>
'integer',
'label'=>
'Fk user approve',
'enabled'=>1,
'visible'=>-1,
'position'=>120),
190 'fk_user_refuse' =>array(
'type'=>
'integer',
'label'=>
'Fk user refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>125),
191 'fk_user_cancel' =>array(
'type'=>
'integer',
'label'=>
'Fk user cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>130),
192 'fk_c_paiement' =>array(
'type'=>
'integer',
'label'=>
'Fk c paiement',
'enabled'=>1,
'visible'=>-1,
'position'=>140),
193 'paid' =>array(
'type'=>
'integer',
'label'=>
'Paid',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>145),
194 'note_public' =>array(
'type'=>
'text',
'label'=>
'Note public',
'enabled'=>1,
'visible'=>0,
'position'=>150),
195 'note_private' =>array(
'type'=>
'text',
'label'=>
'Note private',
'enabled'=>1,
'visible'=>0,
'position'=>155),
196 'detail_refuse' =>array(
'type'=>
'varchar(255)',
'label'=>
'Detail refuse',
'enabled'=>1,
'visible'=>-1,
'position'=>160),
197 'detail_cancel' =>array(
'type'=>
'varchar(255)',
'label'=>
'Detail cancel',
'enabled'=>1,
'visible'=>-1,
'position'=>165),
198 'integration_compta' =>array(
'type'=>
'integer',
'label'=>
'Integration compta',
'enabled'=>1,
'visible'=>-1,
'position'=>170),
199 'fk_bank_account' =>array(
'type'=>
'integer',
'label'=>
'Fk bank account',
'enabled'=>1,
'visible'=>-1,
'position'=>175),
200 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'Fk multicurrency',
'enabled'=>1,
'visible'=>-1,
'position'=>185),
201 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'Multicurrency code',
'enabled'=>1,
'visible'=>-1,
'position'=>190),
202 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency tx',
'enabled'=>1,
'visible'=>-1,
'position'=>195),
203 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total ht',
'enabled'=>1,
'visible'=>-1,
'position'=>200),
204 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total tva',
'enabled'=>1,
'visible'=>-1,
'position'=>205),
205 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'Multicurrency total ttc',
'enabled'=>1,
'visible'=>-1,
'position'=>210),
206 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>220),
207 'date_create' =>array(
'type'=>
'datetime',
'label'=>
'Date create',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>300),
208 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'Tms',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>305),
209 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-1,
'position'=>1000),
210 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'Model pdf',
'enabled'=>1,
'visible'=>0,
'position'=>1010),
211 'fk_statut' =>array(
'type'=>
'integer',
'label'=>
'Fk statut',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>500),
223 $this->total_ttc = 0;
224 $this->total_tva = 0;
225 $this->total_localtax1 = 0;
226 $this->total_localtax2 = 0;
227 $this->localtax1 = 0;
228 $this->localtax2 = 0;
229 $this->modepaymentid = 0;
232 $this->statuts_short = array(0 =>
'Draft', 2 =>
'Validated', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
233 $this->statuts = array(0 =>
'Draft', 2 =>
'ValidatedWaitingApproval', 4 =>
'Canceled', 5 =>
'Approved', 6 =>
'Paid', 99 =>
'Refused');
234 $this->statuts_logo = array(0 =>
'status0', 2 =>
'status1', 4 =>
'status6', 5 =>
'status4', 6 =>
'status6', 99 =>
'status5');
244 public function create($user, $notrigger = 0)
246 global $conf, $langs;
253 if (empty($this->date_debut) || empty($this->date_fin)) {
254 $this->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
'Date'));
258 $fuserid = $this->fk_user_author;
259 if (empty($fuserid)) {
260 $fuserid = $user->id;
265 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
" (";
268 $sql .=
",total_ttc";
269 $sql .=
",total_tva";
270 $sql .=
",date_debut";
272 $sql .=
",date_create";
273 $sql .=
",fk_user_creat";
274 $sql .=
",fk_user_author";
275 $sql .=
",fk_user_validator";
276 $sql .=
",fk_user_approve";
277 $sql .=
",fk_user_modif";
278 $sql .=
",fk_statut";
279 $sql .=
",fk_c_paiement";
281 $sql .=
",note_public";
282 $sql .=
",note_private";
286 $sql .=
", ".price2num($this->total_ht,
'MT');
287 $sql .=
", ".price2num($this->total_ttc,
'MT');
288 $sql .=
", ".price2num($this->total_tva,
'MT');
289 $sql .=
", '".$this->db->idate($this->date_debut).
"'";
290 $sql .=
", '".$this->db->idate($this->date_fin).
"'";
291 $sql .=
", '".$this->db->idate($now).
"'";
292 $sql .=
", ".((int) $user->id);
293 $sql .=
", ".((int) $fuserid);
294 $sql .=
", ".($this->fk_user_validator > 0 ? ((int) $this->fk_user_validator) :
"null");
295 $sql .=
", ".($this->fk_user_approve > 0 ? ((int) $this->fk_user_approve) :
"null");
296 $sql .=
", ".($this->fk_user_modif > 0 ? ((int) $this->fk_user_modif) :
"null");
297 $sql .=
", ".($this->fk_statut > 1 ? ((int) $this->fk_statut) : 0);
298 $sql .=
", ".($this->modepaymentid ? ((int) $this->modepaymentid) :
"null");
300 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
"null");
301 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
"null");
302 $sql .=
", ".((int) $conf->entity);
305 $result = $this->
db->query($sql);
307 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
308 $this->
ref =
'(PROV'.$this->id.
')';
310 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
" SET ref='".$this->
db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
313 $this->error = $this->
db->lasterror();
318 if (is_array($this->lines) && count($this->lines) > 0) {
319 foreach ($this->lines as $line) {
322 if (!is_object($line)) {
323 $line = (object) $line;
325 $newndfline->fk_expensereport = $line->fk_expensereport;
326 $newndfline->fk_c_type_fees = $line->fk_c_type_fees;
327 $newndfline->fk_project = $line->fk_project;
328 $newndfline->vatrate = $line->vatrate;
329 $newndfline->vat_src_code = $line->vat_src_code;
330 $newndfline->localtax1_tx = $line->localtax1_tx;
331 $newndfline->localtax2_tx = $line->localtax2_tx;
332 $newndfline->localtax1_type = $line->localtax1_type;
333 $newndfline->localtax2_type = $line->localtax2_type;
334 $newndfline->comments = $line->comments;
335 $newndfline->qty = $line->qty;
336 $newndfline->value_unit = $line->value_unit;
337 $newndfline->total_ht = $line->total_ht;
338 $newndfline->total_ttc = $line->total_ttc;
339 $newndfline->total_tva = $line->total_tva;
340 $newndfline->total_localtax1 = $line->total_localtax1;
341 $newndfline->total_localtax2 = $line->total_localtax2;
342 $newndfline->date = $line->date;
343 $newndfline->rule_warning_message = $line->rule_warning_message;
344 $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat;
345 $newndfline->fk_ecm_files = $line->fk_ecm_files;
350 $newndfline->fk_expensereport = $this->id;
351 $result = $newndfline->insert();
353 $this->error = $newndfline->error;
354 $this->errors = $newndfline->errors;
374 $result = $this->
call_trigger(
'EXPENSE_REPORT_CREATE', $user);
386 $this->
db->rollback();
390 $this->
db->rollback();
394 dol_syslog(get_class($this).
"::create error ".$this->error, LOG_ERR);
395 $this->
db->rollback();
399 $this->error = $this->
db->lasterror().
" sql=".$sql;
400 $this->
db->rollback();
418 if (empty($fk_user_author)) {
419 $fk_user_author = $user->id;
429 $objFrom = clone $this;
434 $this->fk_statut = 0;
437 $this->fk_user_creat = $user->id;
438 $this->fk_user_author = $fk_user_author;
439 $this->fk_user_valid =
'';
440 $this->date_create =
'';
441 $this->date_creation =
'';
442 $this->date_validation =
'';
445 if (is_array($this->lines) && count($this->lines) > 0) {
446 foreach ($this->lines as $key => $line) {
447 $this->lines[$key]->fk_ecm_files = 0;
452 $this->context[
'createfromclone'] =
'createfromclone';
453 $result = $this->
create($user);
460 if (is_object($hookmanager)) {
461 $parameters = array(
'objFrom'=>$objFrom);
463 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
470 unset($this->context[
'createfromclone']);
477 $this->
db->rollback();
491 public function update($user, $notrigger = 0, $userofexpensereport =
null)
498 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
499 $sql .=
" total_ht = ".$this->total_ht;
500 $sql .=
" , total_ttc = ".$this->total_ttc;
501 $sql .=
" , total_tva = ".$this->total_tva;
502 $sql .=
" , date_debut = '".$this->db->idate($this->date_debut).
"'";
503 $sql .=
" , date_fin = '".$this->db->idate($this->date_fin).
"'";
504 if ($userofexpensereport && is_object($userofexpensereport)) {
505 $sql .=
" , fk_user_author = ".($userofexpensereport->id > 0 ? $userofexpensereport->id :
"null");
507 $sql .=
" , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator :
"null");
508 $sql .=
" , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid :
"null");
509 $sql .=
" , fk_user_approve = ".($this->fk_user_approve > 0 ? $this->fk_user_approve :
"null");
510 $sql .=
" , fk_user_modif = ".$user->id;
511 $sql .=
" , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut :
'0');
512 $sql .=
" , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement :
"null");
513 $sql .=
" , note_public = ".(!empty($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"''");
514 $sql .=
" , note_private = ".(!empty($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"''");
515 $sql .=
" , detail_refuse = ".(!empty($this->detail_refuse) ?
"'".$this->db->escape($this->detail_refuse).
"'" :
"''");
516 $sql .=
" WHERE rowid = ".((int) $this->
id);
518 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
519 $result = $this->
db->query($sql);
523 $result = $this->
call_trigger(
'EXPENSE_REPORT_MODIFY', $user);
535 $this->
db->rollback();
536 $this->error = $this->
db->error();
540 $this->
db->rollback();
541 $this->error = $this->
db->error();
553 public function fetch($id, $ref =
'')
557 $sql =
"SELECT d.rowid, d.entity, d.ref, d.note_public, d.note_private,";
558 $sql .=
" d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,";
559 $sql .=
" d.date_refuse, d.date_cancel,";
560 $sql .=
" d.total_ht, d.total_ttc, d.total_tva,";
561 $sql .=
" d.localtax1 as total_localtax1, d.localtax2 as total_localtax2,";
562 $sql .=
" d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,";
563 $sql .=
" d.fk_user_creat, d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
564 $sql .=
" d.fk_user_valid, d.fk_user_approve,";
565 $sql .=
" d.fk_statut as status, d.fk_c_paiement, d.paid";
566 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as d";
568 $sql .=
" WHERE d.ref = '".$this->db->escape($ref).
"'";
570 $sql .=
" WHERE d.rowid = ".((int) $id);
574 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
577 $obj = $this->
db->fetch_object(
$resql);
579 $this->
id = $obj->rowid;
580 $this->
ref = $obj->ref;
582 $this->entity = $obj->entity;
584 $this->total_ht = $obj->total_ht;
585 $this->total_tva = $obj->total_tva;
586 $this->total_ttc = $obj->total_ttc;
587 $this->localtax1 = $obj->total_localtax1;
588 $this->localtax2 = $obj->total_localtax2;
589 $this->total_localtax1 = $obj->total_localtax1;
590 $this->total_localtax2 = $obj->total_localtax2;
592 $this->note_public = $obj->note_public;
593 $this->note_private = $obj->note_private;
594 $this->detail_refuse = $obj->detail_refuse;
595 $this->detail_cancel = $obj->detail_cancel;
597 $this->date_debut = $this->
db->jdate($obj->date_debut);
598 $this->date_fin = $this->
db->jdate($obj->date_fin);
599 $this->date_valid = $this->
db->jdate($obj->date_valid);
600 $this->date_approve = $this->
db->jdate($obj->date_approve);
601 $this->date_create = $this->
db->jdate($obj->date_create);
602 $this->date_modif = $this->
db->jdate($obj->date_modif);
603 $this->date_refuse = $this->
db->jdate($obj->date_refuse);
604 $this->date_cancel = $this->
db->jdate($obj->date_cancel);
606 $this->fk_user_creat = $obj->fk_user_creat;
607 $this->fk_user_author = $obj->fk_user_author;
608 $this->fk_user_modif = $obj->fk_user_modif;
609 $this->fk_user_validator = $obj->fk_user_validator;
610 $this->fk_user_valid = $obj->fk_user_valid;
611 $this->fk_user_refuse = $obj->fk_user_refuse;
612 $this->fk_user_cancel = $obj->fk_user_cancel;
613 $this->fk_user_approve = $obj->fk_user_approve;
615 $user_author =
new User($this->
db);
616 if ($this->fk_user_author > 0) {
617 $user_author->fetch($this->fk_user_author);
620 $this->user_author_infos =
dolGetFirstLastname($user_author->firstname, $user_author->lastname);
622 $user_approver =
new User($this->
db);
623 if ($this->fk_user_approve > 0) {
624 $user_approver->fetch($this->fk_user_approve);
625 } elseif ($this->fk_user_validator > 0) {
626 $user_approver->fetch($this->fk_user_validator);
628 $this->user_validator_infos =
dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
630 $this->fk_statut = $obj->status;
631 $this->status = $obj->status;
632 $this->fk_c_paiement = $obj->fk_c_paiement;
633 $this->paid = $obj->paid;
635 if ($this->status == self::STATUS_APPROVED || $this->status == self::STATUS_CLOSED) {
636 $user_valid =
new User($this->
db);
637 if ($this->fk_user_valid > 0) {
638 $user_valid->fetch($this->fk_user_valid);
640 $this->user_valid_infos =
dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
652 $this->error = $this->
db->lasterror();
668 public function set_paid($id, $fuser, $notrigger = 0)
671 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
672 return $this->
setPaid($id, $fuser, $notrigger);
683 public function setPaid($id, $fuser, $notrigger = 0)
688 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport";
689 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", paid=1";
692 dol_syslog(get_class($this).
"::set_paid", LOG_DEBUG);
695 if ($this->
db->affected_rows(
$resql)) {
698 $result = $this->
call_trigger(
'EXPENSE_REPORT_PAID', $fuser);
710 $this->
db->rollback();
711 $this->error = $this->
db->error();
719 $this->
db->rollback();
733 return $this->
LibStatut($this->status, $mode);
749 $labelStatus = $langs->transnoentitiesnoconv($this->statuts[$status]);
750 $labelStatusShort = $langs->transnoentitiesnoconv($this->statuts_short[$status]);
752 $statusType = $this->statuts_logo[$status];
754 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
768 $sql =
"SELECT f.rowid,";
769 $sql .=
" f.date_create as datec,";
770 $sql .=
" f.tms as date_modification,";
771 $sql .=
" f.date_valid as datev,";
772 $sql .=
" f.date_approve as datea,";
773 $sql .=
" f.fk_user_creat as fk_user_creation,";
774 $sql .=
" f.fk_user_author as fk_user_author,";
775 $sql .=
" f.fk_user_modif as fk_user_modification,";
776 $sql .=
" f.fk_user_valid,";
777 $sql .=
" f.fk_user_approve";
778 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
779 $sql .=
" WHERE f.rowid = ".((int) $id);
780 $sql .=
" AND f.entity = ".$conf->entity;
785 $obj = $this->
db->fetch_object(
$resql);
787 $this->
id = $obj->rowid;
789 $this->date_creation = $this->
db->jdate($obj->datec);
790 $this->date_modification = $this->
db->jdate($obj->date_modification);
791 $this->date_validation = $this->
db->jdate($obj->datev);
792 $this->date_approbation = $this->
db->jdate($obj->datea);
794 $cuser =
new User($this->
db);
795 $cuser->fetch($obj->fk_user_author);
796 $this->user_creation = $cuser;
798 if ($obj->fk_user_creation) {
799 $cuser =
new User($this->
db);
800 $cuser->fetch($obj->fk_user_creation);
801 $this->user_creation = $cuser;
803 if ($obj->fk_user_valid) {
804 $vuser =
new User($this->
db);
805 $vuser->fetch($obj->fk_user_valid);
806 $this->user_validation = $vuser;
808 if ($obj->fk_user_modification) {
809 $muser =
new User($this->
db);
810 $muser->fetch($obj->fk_user_modification);
811 $this->user_modification = $muser;
813 if ($obj->fk_user_approve) {
814 $auser =
new User($this->
db);
815 $auser->fetch($obj->fk_user_approve);
816 $this->user_approve = $auser;
836 global $user, $langs, $conf;
842 $this->
ref =
'SPECIMEN';
845 $this->date_create = $now;
846 $this->date_debut = $now;
847 $this->date_fin = $now;
848 $this->date_valid = $now;
849 $this->date_approve = $now;
854 $this->fk_statut = 5;
856 $this->fk_user_author = $user->id;
857 $this->fk_user_validator = $user->id;
858 $this->fk_user_valid = $user->id;
859 $this->fk_user_approve = $user->id;
861 $this->note_private =
'Private note';
862 $this->note_public =
'SPECIMEN';
865 while ($xnbp < $nbp) {
867 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
868 $line->date = ($now - 3600 * (1 + $xnbp));
869 $line->total_ht = 100;
870 $line->total_tva = 20;
871 $line->total_ttc = 120;
874 $line->value_unit = 120;
875 $line->fk_expensereport = 0;
876 $line->type_fees_code =
'TRA';
877 $line->fk_c_type_fees = $type_fees_id;
879 $line->projet_ref =
'ABC';
881 $this->lines[$xnbp] = $line;
884 $this->total_ht += $line->total_ht;
885 $this->total_tva += $line->total_tva;
886 $this->total_ttc += $line->total_ttc;
901 global $conf, $db, $langs;
903 $langs->load(
'trips');
905 if ($user->rights->expensereport->lire) {
906 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
907 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
908 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
910 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
911 $result = $this->
db->query($sql);
913 $num = $this->
db->num_rows($result);
919 $objp = $this->
db->fetch_object($result);
921 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
922 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
923 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
925 $result2 = $this->
db->query($sql2);
926 $obj = $this->
db->fetch_object($result2);
928 $objp->fk_user_author = $obj->fk_user_author;
929 $objp->ref = $obj->ref;
930 $objp->fk_c_expensereport_status = $obj->status;
931 $objp->rowid = $obj->rowid;
933 $total_HT = $total_HT + $objp->total_ht;
934 $total_TTC = $total_TTC + $objp->total_ttc;
935 $author =
new User($this->
db);
936 $author->fetch($objp->fk_user_author);
939 print
'<td><a href="'.DOL_URL_ROOT.
'/expensereport/card.php?id='.$objp->rowid.
'">'.$objp->ref_num.
'</a></td>';
940 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
941 print
'<td>'.$author->getNomUrl(1).
'</td>';
942 print
'<td>'.$objp->comments.
'</td>';
943 print
'<td class="right">'.price($objp->total_ht).
'</td>';
944 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
945 print
'<td class="right">';
947 switch ($objp->fk_c_expensereport_status) {
949 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
952 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
955 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
958 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
961 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
978 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
979 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
980 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
981 print
'<td> </td>';
984 $this->error = $this->
db->lasterror();
1001 $this->lines = array();
1003 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1004 $sql .=
" de.".$this->fk_element.
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1005 $sql .=
' de.tva_tx, de.vat_src_code,';
1006 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1007 $sql .=
' de.fk_ecm_files,';
1008 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1009 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1010 $sql .=
' ctf.code as code_type_fees, ctf.label as libelle_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1011 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1012 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as de';
1013 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1014 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1015 $sql .=
" WHERE de.".$this->fk_element.
" = ".((int) $this->
id);
1016 if (!empty($conf->global->EXPENSEREPORT_LINES_SORTED_BY_ROWID)) {
1017 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1019 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1024 $num = $this->
db->num_rows(
$resql);
1027 $objp = $this->
db->fetch_object(
$resql);
1031 $deplig->rowid = $objp->rowid;
1032 $deplig->id = $objp->rowid;
1033 $deplig->comments = $objp->comments;
1034 $deplig->qty = $objp->qty;
1035 $deplig->value_unit = $objp->value_unit;
1036 $deplig->date = $objp->date;
1037 $deplig->dates = $this->
db->jdate($objp->date);
1039 $deplig->fk_expensereport = $objp->fk_expensereport;
1040 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1041 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1042 $deplig->fk_projet = $objp->fk_project;
1043 $deplig->fk_project = $objp->fk_project;
1044 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1046 $deplig->total_ht = $objp->total_ht;
1047 $deplig->total_tva = $objp->total_tva;
1048 $deplig->total_ttc = $objp->total_ttc;
1049 $deplig->total_localtax1 = $objp->total_localtax1;
1050 $deplig->total_localtax2 = $objp->total_localtax2;
1052 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1053 $deplig->type_fees_libelle = $objp->libelle_type_fees;
1054 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1056 $deplig->tva_tx = $objp->tva_tx;
1057 $deplig->vatrate = $objp->tva_tx;
1058 $deplig->vat_src_code = $objp->vat_src_code;
1059 $deplig->localtax1_tx = $objp->localtax1_tx;
1060 $deplig->localtax2_tx = $objp->localtax2_tx;
1061 $deplig->localtax1_type = $objp->localtax1_type;
1062 $deplig->localtax2_type = $objp->localtax2_type;
1064 $deplig->projet_ref = $objp->ref_projet;
1065 $deplig->projet_title = $objp->title_projet;
1067 $deplig->rule_warning_message = $objp->rule_warning_message;
1069 $deplig->rang = $objp->rang;
1071 $this->lines[$i] = $deplig;
1078 $this->error = $this->
db->lasterror();
1079 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1092 public function delete(
User $user =
null, $notrigger =
false)
1095 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1103 $result = $this->
call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1111 if (!$error && !empty($this->table_element_line)) {
1112 $tabletodelete = $this->table_element_line;
1114 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1115 if (!$this->
db->query($sql)) {
1117 $this->error = $this->
db->lasterror();
1118 $this->errors[] = $this->error;
1119 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1144 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1150 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1151 $res = $this->
db->query($sql);
1154 $this->error = $this->
db->lasterror();
1155 $this->errors[] = $this->error;
1156 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1171 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1172 $dir = $conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1173 $file = $dir.
"/".$ref.
".pdf";
1174 if (file_exists($file)) {
1178 $this->error =
'ErrorFailToDeleteFile';
1179 $this->errors[] = $this->error;
1180 $this->
db->rollback();
1184 if (file_exists($dir)) {
1187 $this->error =
'ErrorFailToDeleteDir';
1188 $this->errors[] = $this->error;
1189 $this->
db->rollback();
1197 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1198 $this->
db->commit();
1201 $this->
db->rollback();
1215 global $conf, $langs, $user;
1221 if ($this->status == self::STATUS_VALIDATED) {
1222 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1226 $this->date_valid = $now;
1229 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
1234 if (empty($num) || $num < 0) {
1243 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1244 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1245 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1246 $sql .=
" date_valid='".$this->db->idate($this->date_valid).
"',";
1247 $sql .=
" fk_user_valid = ".$user->id;
1248 $sql .=
" WHERE rowid = ".((int) $this->
id);
1252 if (!$error && !$notrigger) {
1254 $result = $this->
call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1262 $this->oldref = $this->ref;
1265 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1266 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1269 $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).
"'";
1270 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->
db->escape($this->
ref).
"' and entity = ".$conf->entity;
1273 $error++; $this->error = $this->
db->lasterror();
1279 $dirsource = $conf->expensereport->dir_output.
'/'.$oldref;
1280 $dirdest = $conf->expensereport->dir_output.
'/'.$newref;
1281 if (!$error && file_exists($dirsource)) {
1282 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1284 if (@rename($dirsource, $dirdest)) {
1287 $listoffiles =
dol_dir_list($conf->expensereport->dir_output.
'/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1288 foreach ($listoffiles as $fileentry) {
1289 $dirsource = $fileentry[
'name'];
1290 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1291 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1292 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1293 @rename($dirsource, $dirdest);
1306 if (empty($error)) {
1307 $this->
db->commit();
1310 $this->
db->rollback();
1311 $this->error = $this->
db->error();
1315 $this->
db->rollback();
1316 $this->error = $this->
db->lasterror();
1331 global $conf, $langs;
1334 $sql =
'SELECT date_debut';
1335 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1336 $sql .=
" WHERE rowid = ".((int) $this->
id);
1338 $result = $this->
db->query($sql);
1340 $objp = $this->
db->fetch_object($result);
1342 $this->date_debut = $this->
db->jdate($objp->date_debut);
1344 if ($this->status != self::STATUS_VALIDATED) {
1345 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1346 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1347 $sql .=
" WHERE rowid = ".((int) $this->
id);
1349 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1351 if ($this->
db->query($sql)) {
1354 $this->error = $this->
db->lasterror();
1358 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1375 $this->date_approve = $now;
1376 if ($this->status != self::STATUS_APPROVED) {
1379 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1380 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1381 $sql .=
" date_approve='".$this->db->idate($this->date_approve).
"'";
1382 $sql .=
" WHERE rowid = ".((int) $this->
id);
1383 if ($this->
db->query($sql)) {
1386 $result = $this->
call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1394 if (empty($error)) {
1395 $this->
db->commit();
1398 $this->
db->rollback();
1399 $this->error = $this->
db->error();
1403 $this->
db->rollback();
1404 $this->error = $this->
db->lasterror();
1408 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1422 public function setDeny($fuser, $details, $notrigger = 0)
1428 if ($this->status != self::STATUS_REFUSED) {
1429 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1430 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1431 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1432 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1433 $sql .=
" fk_user_approve = NULL";
1434 $sql .=
" WHERE rowid = ".((int) $this->
id);
1435 if ($this->
db->query($sql)) {
1436 $this->fk_statut = 99;
1438 $this->fk_user_refuse = $fuser->id;
1439 $this->detail_refuse = $details;
1440 $this->date_refuse = $now;
1444 $result = $this->
call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1452 if (empty($error)) {
1453 $this->
db->commit();
1456 $this->
db->rollback();
1457 $this->error = $this->
db->error();
1461 $this->
db->rollback();
1462 $this->error = $this->
db->lasterror();
1466 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1483 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1484 return $this->
setUnpaid($fuser, $notrigger);
1501 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1502 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1503 $sql .=
" WHERE rowid = ".((int) $this->
id);
1505 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1507 if ($this->
db->query($sql)) {
1510 $result = $this->
call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1518 if (empty($error)) {
1519 $this->
db->commit();
1522 $this->
db->rollback();
1523 $this->error = $this->
db->error();
1527 $this->
db->rollback();
1528 $this->error = $this->
db->error();
1532 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1549 $this->date_cancel = $this->
db->idate(
dol_now());
1550 if ($this->status != self::STATUS_CANCELED) {
1553 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1554 $sql .=
" SET fk_statut = ".self::STATUS_CANCELED.
", fk_user_cancel = ".((int) $fuser->id);
1555 $sql .=
", date_cancel='".$this->db->idate($this->date_cancel).
"'";
1556 $sql .=
", detail_cancel='".$this->db->escape($detail).
"'";
1557 $sql .=
" WHERE rowid = ".((int) $this->
id);
1559 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1561 if ($this->
db->query($sql)) {
1564 $result = $this->
call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1572 if (empty($error)) {
1573 $this->
db->commit();
1576 $this->
db->rollback();
1577 $this->error = $this->
db->error();
1581 $this->
db->rollback();
1582 $this->error = $this->
db->error();
1586 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1598 global $langs, $conf;
1599 $langs->load(
"trips");
1601 if (!empty($conf->global->EXPENSEREPORT_ADDON)) {
1604 $file = $conf->global->EXPENSEREPORT_ADDON.
".php";
1605 $classname = $conf->global->EXPENSEREPORT_ADDON;
1608 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1609 foreach ($dirmodels as $reldir) {
1610 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1613 $mybool |= @include_once $dir.$file;
1616 if ($mybool ===
false) {
1621 $obj =
new $classname();
1622 $numref = $obj->getNextValue($this);
1624 if ($numref !=
"") {
1627 $this->error = $obj->error;
1628 $this->errors = $obj->errors;
1633 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1650 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1652 global $langs, $conf, $hookmanager;
1656 $url = DOL_URL_ROOT.
'/expensereport/card.php?id='.$this->id;
1662 $label =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1663 if (isset($this->status)) {
1664 $label .=
' '.$this->getLibStatut(5);
1666 if (!empty($this->
ref)) {
1667 $label .=
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1669 if (!empty($this->total_ht)) {
1670 $label .=
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1672 if (!empty($this->total_tva)) {
1673 $label .=
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1675 if (!empty($this->total_ttc)) {
1676 $label .=
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
1679 $label .=
' - '.$moretitle;
1682 if ($option !=
'nolink') {
1684 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1685 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1686 $add_save_lastsearch_values = 1;
1688 if ($add_save_lastsearch_values) {
1689 $url .=
'&save_lastsearch_values=1';
1699 if (empty($notooltip)) {
1700 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1701 $label = $langs->trans(
"ShowExpenseReport");
1702 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1704 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
1705 $linkclose .=
' class="classfortooltip"';
1708 $linkstart =
'<a href="'.$url.
'"';
1709 $linkstart .= $linkclose.
'>';
1712 $result .= $linkstart;
1714 $result .=
img_object(($notooltip ?
'' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
1716 if ($withpicto != 2) {
1717 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1719 $result .= $linkend;
1722 $hookmanager->initHooks(array($this->element .
'dao'));
1723 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
1724 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1726 $result = $hookmanager->resPrint;
1728 $result .= $hookmanager->resPrint;
1744 $this->total_ht = $this->total_ht + $ligne_total_ht;
1745 $this->total_tva = $this->total_tva + $ligne_total_tva;
1746 $this->total_ttc = $this->total_ht + $this->total_tva;
1748 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1749 $sql .=
" total_ht = ".$this->total_ht;
1750 $sql .=
" , total_ttc = ".$this->total_ttc;
1751 $sql .=
" , total_tva = ".$this->total_tva;
1752 $sql .=
" WHERE rowid = ".((int) $this->
id);
1754 $result = $this->
db->query($sql);
1758 $this->error = $this->
db->error();
1778 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)
1780 global $conf, $langs, $mysoc;
1782 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);
1784 if ($this->status == self::STATUS_DRAFT) {
1788 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1789 $fk_c_type_fees = 0;
1791 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1792 $fk_c_exp_tax_cat = 0;
1794 if (empty($vatrate) || $vatrate < 0) {
1800 if (empty($fk_project)) {
1805 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1816 $seller->tva_assuj = 1;
1823 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
1824 $vat_src_code = $reg[1];
1825 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
1827 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
1829 $tmp =
calcul_price_total($qty, $up, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
1831 $this->line->value_unit = $up;
1833 $this->line->vat_src_code = $vat_src_code;
1834 $this->line->vatrate =
price2num($vatrate);
1835 $this->line->localtax1_tx = $localtaxes_type[1];
1836 $this->line->localtax2_tx = $localtaxes_type[3];
1837 $this->line->localtax1_type = $localtaxes_type[0];
1838 $this->line->localtax2_type = $localtaxes_type[2];
1840 $this->line->total_ttc = $tmp[2];
1841 $this->line->total_ht = $tmp[0];
1842 $this->line->total_tva = $tmp[1];
1843 $this->line->total_localtax1 = $tmp[9];
1844 $this->line->total_localtax2 = $tmp[10];
1846 $this->line->fk_expensereport = $this->id;
1847 $this->line->qty = $qty;
1848 $this->line->date = $date;
1849 $this->line->fk_c_type_fees = $fk_c_type_fees;
1850 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
1851 $this->line->comments = $comments;
1852 $this->line->fk_projet = $fk_project;
1853 $this->line->fk_project = $fk_project;
1855 $this->line->fk_ecm_files = $fk_ecm_files;
1860 $result = $this->line->insert(0,
true);
1864 $this->
db->commit();
1865 return $this->line->id;
1867 $this->
db->rollback();
1871 $this->error = $this->line->error;
1872 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
1873 $this->
db->rollback();
1877 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
1878 $this->error =
'ErrorExpenseNotDraft';
1892 global $user, $conf, $db, $langs, $mysoc;
1894 $langs->load(
'trips');
1897 if (!is_object($seller)) {
1899 $seller->tva_assuj = 1;
1903 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
1906 $rule_warning_message_tab = array();
1908 $current_total_ttc = $this->line->total_ttc;
1909 $new_current_total_ttc = $this->line->total_ttc;
1912 foreach ($rulestocheck as $rule) {
1913 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
1914 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
1916 $amount_to_test = $current_total_ttc;
1919 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
1921 if ($amount_to_test > $rule->amount) {
1924 if ($rule->restrictive) {
1925 $this->error =
'ExpenseReportConstraintViolationError';
1926 $this->errors[] = $this->error;
1928 $new_current_total_ttc -= $amount_to_test - $rule->amount;
1929 $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));
1931 $this->error =
'ExpenseReportConstraintViolationWarning';
1932 $this->errors[] = $this->error;
1934 $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));
1941 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
1943 if ($violation > 0) {
1944 $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);
1946 $this->line->value_unit = $tmp[5];
1947 $this->line->total_ttc = $tmp[2];
1948 $this->line->total_ht = $tmp[0];
1949 $this->line->total_tva = $tmp[1];
1950 $this->line->total_localtax1 = $tmp[9];
1951 $this->line->total_localtax2 = $tmp[10];
1968 global $conf, $mysoc;
1970 if (empty($conf->global->MAIN_USE_EXPENSE_IK)) {
1974 $userauthor =
new User($this->
db);
1975 if ($userauthor->fetch($this->fk_user_author) <= 0) {
1976 $this->error =
'ErrorCantFetchUser';
1977 $this->errors[] =
'ErrorCantFetchUser';
1982 if (!is_object($seller)) {
1984 $seller->tva_assuj = 1;
1988 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
1990 if (empty($range)) {
1991 $this->error =
'ErrorNoRangeAvailable';
1992 $this->errors[] =
'ErrorNoRangeAvailable';
1996 if (!empty($conf->global->MAIN_EXPENSE_APPLY_ENTIRE_OFFSET)) {
1997 $ikoffset = $range->ikoffset;
1999 $ikoffset = $range->ikoffset / 12;
2004 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2005 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2007 $this->line->value_unit = $tmp[5];
2008 $this->line->total_ttc = $tmp[2];
2009 $this->line->total_ht = $tmp[0];
2010 $this->line->total_tva = $tmp[1];
2011 $this->line->total_localtax1 = $tmp[9];
2012 $this->line->total_localtax2 = $tmp[10];
2027 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2028 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2029 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2030 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2031 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2032 if (!empty($this->line->id)) {
2033 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2036 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2039 $num = $this->
db->num_rows(
$resql);
2067 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)
2069 global $user, $mysoc;
2071 if ($this->status == self::STATUS_DRAFT || $this->status == self::STATUS_REFUSED) {
2079 $seller->tva_assuj = 1;
2080 $seller->localtax1_assuj = $mysoc->localtax1_assuj;
2081 $seller->localtax2_assuj = $mysoc->localtax1_assuj;
2089 if (preg_match(
'/\((.*)\)/', $vatrate, $reg)) {
2090 $vat_src_code = $reg[1];
2091 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2093 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2095 $tmp =
calcul_price_total($qty, $value_unit, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2100 $tx_tva = $vatrate / 100;
2101 $tx_tva = $tx_tva + 1;
2104 $this->line->comments = $comments;
2105 $this->line->qty = $qty;
2106 $this->line->value_unit = $value_unit;
2107 $this->line->date = $date;
2109 $this->line->fk_expensereport = $expensereport_id;
2110 $this->line->fk_c_type_fees = $type_fees_id;
2111 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2112 $this->line->fk_projet = $projet_id;
2113 $this->line->fk_project = $projet_id;
2115 $this->line->vat_src_code = $vat_src_code;
2116 $this->line->vatrate =
price2num($vatrate);
2117 $this->line->localtax1_tx = $localtaxes_type[1];
2118 $this->line->localtax2_tx = $localtaxes_type[3];
2119 $this->line->localtax1_type = $localtaxes_type[0];
2120 $this->line->localtax2_type = $localtaxes_type[2];
2122 $this->line->total_ttc = $tmp[2];
2123 $this->line->total_ht = $tmp[0];
2124 $this->line->total_tva = $tmp[1];
2125 $this->line->total_localtax1 = $tmp[9];
2126 $this->line->total_localtax2 = $tmp[10];
2128 $this->line->fk_ecm_files = $fk_ecm_files;
2130 $this->line->id = ((int) $rowid);
2133 $sql =
"SELECT c.code as code_type_fees, c.label as libelle_type_fees";
2134 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2135 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2138 $objp_fees = $this->
db->fetch_object(
$resql);
2139 $this->line->type_fees_code = $objp_fees->code_type_fees;
2140 $this->line->type_fees_libelle = $objp_fees->libelle_type_fees;
2145 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2146 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2147 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2150 $objp_projet = $this->
db->fetch_object(
$resql);
2151 $this->line->projet_ref = $objp_projet->ref_projet;
2152 $this->line->projet_title = $objp_projet->title_projet;
2159 $result = $this->line->update($user);
2164 if (!$error && !$notrigger) {
2166 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_MODIFY', $user);
2174 $this->
db->commit();
2177 $this->error = $this->line->error;
2178 $this->errors = $this->line->errors;
2179 $this->
db->rollback();
2203 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2210 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2211 $sql .=
' WHERE rowid = '.((int) $rowid);
2213 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2214 $result = $this->
db->query($sql);
2216 if (!$result || $error > 0 ) {
2217 $this->error = $this->
db->error();
2218 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2219 $this->
db->rollback();
2225 $this->
db->commit();
2242 $sql =
"SELECT rowid, date_debut, date_fin";
2243 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2244 $sql .=
" WHERE fk_user_author = '{$fuser->id}'";
2246 dol_syslog(get_class($this).
"::periode_existe sql=".$sql);
2247 $result = $this->
db->query($sql);
2249 $num_rows = $this->
db->num_rows($result); $i = 0;
2251 if ($num_rows > 0) {
2252 $date_d_form = $date_debut;
2253 $date_f_form = $date_fin;
2255 while ($i < $num_rows) {
2256 $objp = $this->
db->fetch_object($result);
2258 $date_d_req = $this->
db->jdate($objp->date_debut);
2259 $date_f_req = $this->
db->jdate($objp->date_fin);
2261 if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) {
2262 return $objp->rowid;
2273 $this->error = $this->
db->lasterror();
2274 dol_syslog(get_class($this).
"::periode_existe Error ".$this->error, LOG_ERR);
2290 $users_validator = array();
2292 $sql =
"SELECT DISTINCT ur.fk_user";
2293 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2294 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2296 $sql .=
" SELECT DISTINCT ugu.fk_user";
2297 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2298 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2301 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2302 $result = $this->
db->query($sql);
2304 $num_rows = $this->
db->num_rows($result); $i = 0;
2305 while ($i < $num_rows) {
2306 $objp = $this->
db->fetch_object($result);
2307 array_push($users_validator, $objp->fk_user);
2310 return $users_validator;
2312 $this->error = $this->
db->lasterror();
2313 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2329 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2333 $outputlangs->load(
"trips");
2336 if (!empty($this->model_pdf)) {
2337 $modele = $this->model_pdf;
2338 } elseif (!empty($this->modelpdf)) {
2339 $modele = $this->modelpdf;
2340 } elseif (!empty($conf->global->EXPENSEREPORT_ADDON_PDF)) {
2341 $modele = $conf->global->EXPENSEREPORT_ADDON_PDF;
2345 if (!empty($modele)) {
2346 $modelpath =
"core/modules/expensereport/doc/";
2348 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2364 $sql =
"SELECT id, code, label";
2365 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2366 $sql .=
" WHERE active = ".((int) $active);
2367 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2368 $result = $this->
db->query($sql);
2370 $num = $this->
db->num_rows($result);
2373 $obj = $this->
db->fetch_object($result);
2374 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2392 global $conf, $user;
2394 $this->nb = array();
2396 $sql =
"SELECT count(ex.rowid) as nb";
2397 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2398 $sql .=
" WHERE ex.fk_statut > 0";
2399 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2400 if (empty($user->rights->expensereport->readall)) {
2401 $userchildids = $user->getAllChildIds(1);
2402 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2403 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2408 while ($obj = $this->
db->fetch_object(
$resql)) {
2409 $this->nb[
"expensereports"] = $obj->nb;
2415 $this->error = $this->
db->error();
2431 global $conf, $langs;
2439 $sql =
"SELECT ex.rowid, ex.date_valid";
2440 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2441 if ($option ==
'toapprove') {
2442 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2444 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2446 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2447 if (empty($user->rights->expensereport->readall)) {
2448 $userchildids = $user->getAllChildIds(1);
2449 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2450 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2455 $langs->load(
"trips");
2458 if ($option ==
'toapprove') {
2459 $response->warning_delay = $conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2460 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2461 $response->labelShort = $langs->trans(
"ToApprove");
2464 $response->warning_delay = $conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2465 $response->label = $langs->trans(
"ExpenseReportsToPay");
2466 $response->labelShort = $langs->trans(
"StatusToPay");
2467 $response->url = DOL_URL_ROOT.
'/expensereport/list.php?mainmenu=hrm&statut='.
self::STATUS_APPROVED;
2471 while ($obj = $this->
db->fetch_object(
$resql)) {
2472 $response->nbtodo++;
2474 if ($option ==
'toapprove') {
2475 if ($this->
db->jdate($obj->date_valid) < ($now - $conf->expensereport->approve->warning_delay)) {
2476 $response->nbtodolate++;
2479 if ($this->
db->jdate($obj->date_valid) < ($now - $conf->expensereport->payment->warning_delay)) {
2480 $response->nbtodolate++;
2488 $this->error = $this->
db->error();
2504 if ($option ==
'toapprove' && $this->status != 2) {
2507 if ($option ==
'topay' && $this->status != 5) {
2512 if ($option ==
'toapprove') {
2513 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->approve->warning_delay);
2515 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->payment->warning_delay);
2526 $alreadydispatched = 0;
2528 $type =
'expense_report';
2530 $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);
2533 $obj = $this->
db->fetch_object(
$resql);
2535 $alreadydispatched = $obj->nb;
2538 $this->error = $this->
db->lasterror();
2542 if ($alreadydispatched) {
2555 $table =
'payment_expensereport';
2556 $field =
'fk_expensereport';
2558 $sql =
'SELECT sum(amount) as amount';
2559 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2560 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
2562 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2565 $obj = $this->
db->fetch_object(
$resql);
2567 return (empty($obj->amount) ? 0 : $obj->amount);
2569 $this->error = $this->
db->lasterror();
2584 global $langs, $db, $conf;
2592 $this->error = $langs->trans(
'ErrorBadParameterCat');
2597 $this->error = $langs->trans(
'ErrorBadParameterQty');
2601 $currentUser =
new User($db);
2602 $currentUser->fetch($this->fk_user);
2603 $currentUser->getrights(
'expensereport');
2607 $sql =
" SELECT r.range_ik, t.ikoffset as offset, t.coef";
2608 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2609 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2610 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2611 $sql .=
" ORDER BY r.range_ik ASC";
2613 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2615 $result = $this->
db->query($sql);
2618 if ($conf->global->EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR) {
2620 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2621 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2622 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2623 $sql.=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2624 $sql.=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2625 $sql.=
" AND tf.code = 'EX_KME' ";
2631 $obj = $this->
db->fetch_object(
$resql);
2632 $cumulYearQty = $obj->cumul;
2634 $qty = $cumulYearQty + $qty;
2637 $num = $this->
db->num_rows($result);
2640 for ($i = 0; $i < $num; $i++) {
2641 $obj = $this->
db->fetch_object($result);
2647 for ($i = 0; $i < $num; $i++) {
2648 if ($i < ($num - 1)) {
2649 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i+1]->range_ik) {
2650 $coef = $ranges[$i]->coef;
2651 $offset = $ranges[$i]->offset;
2654 if ($qty > $ranges[$i]->range_ik) {
2655 $coef = $ranges[$i]->coef;
2656 $offset = $ranges[$i]->offset;
2663 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2667 $this->error = $this->
db->error().
" sql=".$sql;
2703 public $fk_c_type_fees;
2708 public $fk_c_exp_tax_cat;
2718 public $fk_expensereport;
2720 public $type_fees_code;
2721 public $type_fees_libelle;
2722 public $type_fees_accountancy_code;
2725 public $projet_title;
2729 public $vat_src_code;
2731 public $localtax1_tx;
2732 public $localtax2_tx;
2733 public $localtax1_type;
2734 public $localtax2_type;
2739 public $total_localtax1;
2740 public $total_localtax2;
2745 public $fk_ecm_files;
2747 public $rule_warning_message;
2768 $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,';
2769 $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,';
2770 $sql .=
' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,';
2771 $sql .=
' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
2772 $sql .=
' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
2773 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det as fde';
2774 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
2775 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as pjt ON fde.fk_projet=pjt.rowid';
2776 $sql .=
' WHERE fde.rowid = '.((int) $rowid);
2778 $result = $this->
db->query($sql);
2781 $objp = $this->
db->fetch_object($result);
2783 $this->
rowid = $objp->rowid;
2784 $this->
id = $objp->rowid;
2785 $this->
ref = $objp->ref;
2786 $this->fk_expensereport = $objp->fk_expensereport;
2787 $this->comments = $objp->comments;
2788 $this->qty = $objp->qty;
2789 $this->date = $objp->date;
2790 $this->dates = $this->
db->jdate($objp->date);
2791 $this->value_unit = $objp->value_unit;
2792 $this->fk_c_type_fees = $objp->fk_c_type_fees;
2793 $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
2794 $this->fk_projet = $objp->fk_project;
2795 $this->fk_project = $objp->fk_project;
2796 $this->type_fees_code = $objp->type_fees_code;
2797 $this->type_fees_libelle = $objp->type_fees_libelle;
2798 $this->projet_ref = $objp->projet_ref;
2799 $this->projet_title = $objp->projet_title;
2801 $this->
vatrate = $objp->vatrate;
2802 $this->vat_src_code = $objp->vat_src_code;
2803 $this->localtax1_tx = $objp->localtax1_tx;
2804 $this->localtax2_tx = $objp->localtax2_tx;
2805 $this->localtax1_type = $objp->localtax1_type;
2806 $this->localtax2_type = $objp->localtax2_type;
2808 $this->total_ht = $objp->total_ht;
2809 $this->total_tva = $objp->total_tva;
2810 $this->total_ttc = $objp->total_ttc;
2811 $this->total_localtax1 = $objp->total_localtax1;
2812 $this->total_localtax2 = $objp->total_localtax2;
2814 $this->fk_ecm_files = $objp->fk_ecm_files;
2816 $this->rule_warning_message = $objp->rule_warning_message;
2818 $this->
db->free($result);
2834 public function insert($notrigger = 0, $fromaddline =
false)
2836 global $user, $conf;
2840 dol_syslog(
"ExpenseReportLine::Insert", LOG_DEBUG);
2843 $this->comments = trim($this->comments);
2844 if (empty($this->value_unit)) {
2845 $this->value_unit = 0;
2849 if (empty($this->fk_c_exp_tax_cat)) {
2850 $this->fk_c_exp_tax_cat = 0;
2855 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'expensereport_det';
2856 $sql .=
' (fk_expensereport, fk_c_type_fees, fk_projet,';
2857 $sql .=
' tva_tx, vat_src_code,';
2858 $sql .=
' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
2859 $sql .=
' comments, qty, value_unit,';
2860 $sql .=
' total_ht, total_tva, total_ttc,';
2861 $sql .=
' total_localtax1, total_localtax2,';
2862 $sql .=
' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)';
2863 $sql .=
" VALUES (".$this->db->escape($this->fk_expensereport).
",";
2864 $sql .=
" ".((int) $this->fk_c_type_fees).
",";
2865 $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')).
",";
2866 $sql .=
" ".((float) $this->
vatrate).
",";
2867 $sql .=
" '".$this->db->escape(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"',";
2868 $sql .=
" ".((float)
price2num($this->localtax1_tx)).
",";
2869 $sql .=
" ".((float)
price2num($this->localtax2_tx)).
",";
2870 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
2871 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
2872 $sql .=
" '".$this->db->escape($this->comments).
"',";
2873 $sql .=
" ".((float) $this->qty).
",";
2874 $sql .=
" ".((float) $this->value_unit).
",";
2875 $sql .=
" ".((float)
price2num($this->total_ht)).
",";
2876 $sql .=
" ".((float)
price2num($this->total_tva)).
",";
2877 $sql .=
" ".((float)
price2num($this->total_ttc)).
",";
2878 $sql .=
" ".((float)
price2num($this->total_localtax1)).
",";
2879 $sql .=
" ".((float)
price2num($this->total_localtax2)).
",";
2880 $sql .=
" '".$this->db->idate($this->date).
"',";
2881 $sql .=
" ".(empty($this->rule_warning_message) ?
'null' :
"'".$this->db->escape($this->rule_warning_message).
"'").
",";
2882 $sql .=
" ".((int) $this->fk_c_exp_tax_cat).
",";
2883 $sql .=
" ".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
2888 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
'expensereport_det');
2891 if (!$error && !$notrigger) {
2893 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_CREATE', $user);
2901 if (!$fromaddline) {
2903 $tmpparent->fetch($this->fk_expensereport);
2904 $result = $tmpparent->update_price(1);
2907 $this->error = $tmpparent->error;
2908 $this->errors = $tmpparent->errors;
2916 $this->
db->commit();
2919 $this->error = $this->
db->lasterror();
2920 dol_syslog(
"ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
2921 $this->
db->rollback();
2938 $sql =
'SELECT SUM(d.total_ttc) as total_amount';
2939 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det d';
2940 $sql .=
' INNER JOIN '.MAIN_DB_PREFIX.
'expensereport e ON (d.fk_expensereport = e.rowid)';
2941 $sql .=
' WHERE e.fk_user_author = '.((int) $fk_user);
2942 if (!empty($this->
id)) {
2943 $sql .=
' AND d.rowid <> '.((int) $this->
id);
2945 $sql .=
' AND d.fk_c_type_fees = '.((int) $rule->fk_c_type_fees);
2946 if ($mode ==
'day' || $mode ==
'EX_DAY') {
2947 $sql .=
" AND d.date = '".dol_print_date($this->date,
'%Y-%m-%d').
"'";
2948 } elseif ($mode ==
'mon' || $mode ==
'EX_MON') {
2949 $sql .=
" AND DATE_FORMAT(d.date, '%Y-%m') = '".dol_print_date($this->date,
'%Y-%m').
"'";
2950 } elseif ($mode ==
'year' || $mode ==
'EX_YEA') {
2951 $sql .=
" AND DATE_FORMAT(d.date, '%Y') = '".dol_print_date($this->date,
'%Y').
"'";
2954 dol_syslog(
'ExpenseReportLine::getExpAmount');
2958 $num = $this->
db->num_rows(
$resql);
2960 $obj = $this->
db->fetch_object(
$resql);
2961 $amount = (double) $obj->total_amount;
2967 return $amount + $this->total_ttc;
2978 global $langs, $conf;
2983 $this->comments = trim($this->comments);
2985 $this->value_unit =
price2num($this->value_unit);
2986 if (empty($this->fk_c_exp_tax_cat)) {
2987 $this->fk_c_exp_tax_cat = 0;
2993 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport_det SET";
2994 $sql .=
" comments='".$this->db->escape($this->comments).
"'";
2995 $sql .=
", value_unit = ".((float) $this->value_unit);
2996 $sql .=
", qty=".((float) $this->qty);
2997 $sql .=
", date='".$this->db->idate($this->date).
"'";
2998 $sql .=
", total_ht=".((float)
price2num($this->total_ht,
'MT'));
2999 $sql .=
", total_tva=".((float)
price2num($this->total_tva,
'MT'));
3000 $sql .=
", total_ttc=".((float)
price2num($this->total_ttc,
'MT'));
3001 $sql .=
", total_localtax1=".((float)
price2num($this->total_localtax1,
'MT'));
3002 $sql .=
", total_localtax2=".((float)
price2num($this->total_localtax2,
'MT'));
3003 $sql .=
", tva_tx=".((float) $this->
vatrate);
3004 $sql .=
", vat_src_code='".$this->db->escape($this->vat_src_code).
"'";
3005 $sql .=
", localtax1_tx=".((float) $this->localtax1_tx);
3006 $sql .=
", localtax2_tx=".((float) $this->localtax2_tx);
3007 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
3008 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
3009 $sql .=
", rule_warning_message='".$this->db->escape($this->rule_warning_message).
"'";
3010 $sql .=
", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat);
3011 $sql .=
", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3012 if ($this->fk_c_type_fees) {
3013 $sql .=
", fk_c_type_fees = ".((int) $this->fk_c_type_fees);
3015 $sql .=
", fk_c_type_fees=null";
3017 if ($this->fk_project > 0) {
3018 $sql .=
", fk_projet=".((int) $this->fk_project);
3020 $sql .=
", fk_projet=null";
3022 $sql .=
" WHERE rowid = ".((int) ($this->
rowid ? $this->
rowid : $this->
id));
3029 $result = $tmpparent->fetch($this->fk_expensereport);
3031 $result = $tmpparent->update_price(1);
3034 $this->error = $tmpparent->error;
3035 $this->errors = $tmpparent->errors;
3039 $this->error = $tmpparent->error;
3040 $this->errors = $tmpparent->errors;
3048 $this->
db->commit();
3051 $this->error = $this->
db->lasterror();
3052 dol_syslog(
"ExpenseReportLine::update Error ".$this->error, LOG_ERR);
3053 $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.
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.