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";
690 $sql .=
" WHERE rowid = ".((int) $id).
" AND fk_statut = ".self::STATUS_APPROVED;
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_modif as fk_user_modification,";
775 $sql .=
" f.fk_user_valid,";
776 $sql .=
" f.fk_user_approve";
777 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as f";
778 $sql .=
" WHERE f.rowid = ".((int) $id);
779 $sql .=
" AND f.entity = ".$conf->entity;
784 $obj = $this->
db->fetch_object(
$resql);
786 $this->
id = $obj->rowid;
788 $this->date_creation = $this->
db->jdate($obj->datec);
789 $this->date_modification = $this->
db->jdate($obj->date_modification);
790 $this->date_validation = $this->
db->jdate($obj->datev);
791 $this->date_approbation = $this->
db->jdate($obj->datea);
793 $cuser =
new User($this->
db);
794 $cuser->fetch($obj->fk_user_author);
795 $this->user_creation = $cuser;
797 if ($obj->fk_user_creation) {
798 $cuser =
new User($this->
db);
799 $cuser->fetch($obj->fk_user_creation);
800 $this->user_creation = $cuser;
802 if ($obj->fk_user_valid) {
803 $vuser =
new User($this->
db);
804 $vuser->fetch($obj->fk_user_valid);
805 $this->user_validation = $vuser;
807 if ($obj->fk_user_modification) {
808 $muser =
new User($this->
db);
809 $muser->fetch($obj->fk_user_modification);
810 $this->user_modification = $muser;
812 if ($obj->fk_user_approve) {
813 $auser =
new User($this->
db);
814 $auser->fetch($obj->fk_user_approve);
815 $this->user_approve = $auser;
835 global $user, $langs, $conf;
841 $this->
ref =
'SPECIMEN';
844 $this->date_create = $now;
845 $this->date_debut = $now;
846 $this->date_fin = $now;
847 $this->date_valid = $now;
848 $this->date_approve = $now;
853 $this->fk_statut = 5;
855 $this->fk_user_author = $user->id;
856 $this->fk_user_validator = $user->id;
857 $this->fk_user_valid = $user->id;
858 $this->fk_user_approve = $user->id;
860 $this->note_private =
'Private note';
861 $this->note_public =
'SPECIMEN';
864 while ($xnbp < $nbp) {
866 $line->comments = $langs->trans(
"Comment").
" ".$xnbp;
867 $line->date = ($now - 3600 * (1 + $xnbp));
868 $line->total_ht = 100;
869 $line->total_tva = 20;
870 $line->total_ttc = 120;
873 $line->value_unit = 120;
874 $line->fk_expensereport = 0;
875 $line->type_fees_code =
'TRA';
876 $line->fk_c_type_fees = $type_fees_id;
878 $line->projet_ref =
'ABC';
880 $this->lines[$xnbp] = $line;
883 $this->total_ht += $line->total_ht;
884 $this->total_tva += $line->total_tva;
885 $this->total_ttc += $line->total_ttc;
900 global $conf, $db, $langs;
902 $langs->load(
'trips');
904 if ($user->rights->expensereport->lire) {
905 $sql =
"SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
906 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_det as de";
907 $sql .=
" WHERE de.fk_projet = ".((int) $projectid);
909 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
910 $result = $this->
db->query($sql);
912 $num = $this->
db->num_rows($result);
918 $objp = $this->
db->fetch_object($result);
920 $sql2 =
"SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut as status";
921 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as d";
922 $sql2 .=
" WHERE d.rowid = ".((int) $objp->fk_expensereport);
924 $result2 = $this->
db->query($sql2);
925 $obj = $this->
db->fetch_object($result2);
927 $objp->fk_user_author = $obj->fk_user_author;
928 $objp->ref = $obj->ref;
929 $objp->fk_c_expensereport_status = $obj->status;
930 $objp->rowid = $obj->rowid;
932 $total_HT = $total_HT + $objp->total_ht;
933 $total_TTC = $total_TTC + $objp->total_ttc;
934 $author =
new User($this->
db);
935 $author->fetch($objp->fk_user_author);
938 print
'<td><a href="'.DOL_URL_ROOT.
'/expensereport/card.php?id='.$objp->rowid.
'">'.$objp->ref_num.
'</a></td>';
939 print
'<td class="center">'.dol_print_date($objp->date,
'day').
'</td>';
940 print
'<td>'.$author->getNomUrl(1).
'</td>';
941 print
'<td>'.$objp->comments.
'</td>';
942 print
'<td class="right">'.price($objp->total_ht).
'</td>';
943 print
'<td class="right">'.price($objp->total_ttc).
'</td>';
944 print
'<td class="right">';
946 switch ($objp->fk_c_expensereport_status) {
948 print
img_picto($langs->trans(
'StatusOrderCanceled'),
'statut5');
951 print $langs->trans(
'Draft').
' '.
img_picto($langs->trans(
'Draft'),
'statut0');
954 print $langs->trans(
'TripForValid').
' '.
img_picto($langs->trans(
'TripForValid'),
'statut3');
957 print $langs->trans(
'TripForPaid').
' '.
img_picto($langs->trans(
'TripForPaid'),
'statut3');
960 print $langs->trans(
'TripPaid').
' '.
img_picto($langs->trans(
'TripPaid'),
'statut4');
977 print
'<tr class="liste_total"><td colspan="4">'.$langs->trans(
"Number").
': '.$i.
'</td>';
978 print
'<td class="right" width="100">'.$langs->trans(
"TotalHT").
' : '.
price($total_HT).
'</td>';
979 print
'<td class="right" width="100">'.$langs->trans(
"TotalTTC").
' : '.
price($total_TTC).
'</td>';
980 print
'<td> </td>';
983 $this->error = $this->
db->lasterror();
1000 $this->lines = array();
1002 $sql =
' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
1003 $sql .=
" de.".$this->fk_element.
", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,";
1004 $sql .=
' de.tva_tx, de.vat_src_code,';
1005 $sql .=
' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,';
1006 $sql .=
' de.fk_ecm_files,';
1007 $sql .=
' de.total_ht, de.total_tva, de.total_ttc,';
1008 $sql .=
' de.total_localtax1, de.total_localtax2, de.rule_warning_message,';
1009 $sql .=
' ctf.code as code_type_fees, ctf.label as libelle_type_fees, ctf.accountancy_code as accountancy_code_type_fees,';
1010 $sql .=
' p.ref as ref_projet, p.title as title_projet';
1011 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as de';
1012 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
1013 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as p ON de.fk_projet = p.rowid';
1014 $sql .=
" WHERE de.".$this->fk_element.
" = ".((int) $this->
id);
1015 if (!empty($conf->global->EXPENSEREPORT_LINES_SORTED_BY_ROWID)) {
1016 $sql .=
' ORDER BY de.rang ASC, de.rowid ASC';
1018 $sql .=
' ORDER BY de.rang ASC, de.date ASC';
1023 $num = $this->
db->num_rows(
$resql);
1026 $objp = $this->
db->fetch_object(
$resql);
1030 $deplig->rowid = $objp->rowid;
1031 $deplig->id = $objp->rowid;
1032 $deplig->comments = $objp->comments;
1033 $deplig->qty = $objp->qty;
1034 $deplig->value_unit = $objp->value_unit;
1035 $deplig->date = $objp->date;
1036 $deplig->dates = $this->
db->jdate($objp->date);
1038 $deplig->fk_expensereport = $objp->fk_expensereport;
1039 $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
1040 $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
1041 $deplig->fk_projet = $objp->fk_project;
1042 $deplig->fk_project = $objp->fk_project;
1043 $deplig->fk_ecm_files = $objp->fk_ecm_files;
1045 $deplig->total_ht = $objp->total_ht;
1046 $deplig->total_tva = $objp->total_tva;
1047 $deplig->total_ttc = $objp->total_ttc;
1048 $deplig->total_localtax1 = $objp->total_localtax1;
1049 $deplig->total_localtax2 = $objp->total_localtax2;
1051 $deplig->type_fees_code = empty($objp->code_type_fees) ?
'TF_OTHER' : $objp->code_type_fees;
1052 $deplig->type_fees_libelle = $objp->libelle_type_fees;
1053 $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees;
1055 $deplig->tva_tx = $objp->tva_tx;
1056 $deplig->vatrate = $objp->tva_tx;
1057 $deplig->vat_src_code = $objp->vat_src_code;
1058 $deplig->localtax1_tx = $objp->localtax1_tx;
1059 $deplig->localtax2_tx = $objp->localtax2_tx;
1060 $deplig->localtax1_type = $objp->localtax1_type;
1061 $deplig->localtax2_type = $objp->localtax2_type;
1063 $deplig->projet_ref = $objp->ref_projet;
1064 $deplig->projet_title = $objp->title_projet;
1066 $deplig->rule_warning_message = $objp->rule_warning_message;
1068 $deplig->rang = $objp->rang;
1070 $this->lines[$i] = $deplig;
1077 $this->error = $this->
db->lasterror();
1078 dol_syslog(get_class($this).
"::fetch_lines: Error ".$this->error, LOG_ERR);
1091 public function delete(
User $user = null, $notrigger =
false)
1094 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1102 $result = $this->
call_trigger(
'EXPENSE_REPORT_DELETE', $user);
1110 if (!$error && !empty($this->table_element_line)) {
1111 $tabletodelete = $this->table_element_line;
1113 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
1114 if (!$this->
db->query($sql)) {
1116 $this->error = $this->
db->lasterror();
1117 $this->errors[] = $this->error;
1118 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1143 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1149 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
1150 $res = $this->
db->query($sql);
1153 $this->error = $this->
db->lasterror();
1154 $this->errors[] = $this->error;
1155 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
1170 if ($conf->expensereport->multidir_output[$this->entity] && !empty($this->
ref)) {
1171 $dir = $conf->expensereport->multidir_output[$this->entity].
"/".$ref;
1172 $file = $dir.
"/".$ref.
".pdf";
1173 if (file_exists($file)) {
1177 $this->error =
'ErrorFailToDeleteFile';
1178 $this->errors[] = $this->error;
1179 $this->
db->rollback();
1183 if (file_exists($dir)) {
1186 $this->error =
'ErrorFailToDeleteDir';
1187 $this->errors[] = $this->error;
1188 $this->
db->rollback();
1196 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
1197 $this->
db->commit();
1200 $this->
db->rollback();
1214 global $conf, $langs, $user;
1220 if ($this->status == self::STATUS_VALIDATED) {
1221 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1225 $this->date_valid = $now;
1228 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
1233 if (empty($num) || $num < 0) {
1242 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1243 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
1244 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
1245 $sql .=
" date_valid='".$this->db->idate($this->date_valid).
"',";
1246 $sql .=
" fk_user_valid = ".$user->id;
1247 $sql .=
" WHERE rowid = ".((int) $this->
id);
1251 if (!$error && !$notrigger) {
1253 $result = $this->
call_trigger(
'EXPENSE_REPORT_VALIDATE', $fuser);
1261 $this->oldref = $this->ref;
1264 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
1265 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1268 $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).
"'";
1269 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'expensereport/".$this->
db->escape($this->
ref).
"' and entity = ".$conf->entity;
1272 $error++; $this->error = $this->
db->lasterror();
1278 $dirsource = $conf->expensereport->dir_output.
'/'.$oldref;
1279 $dirdest = $conf->expensereport->dir_output.
'/'.$newref;
1280 if (!$error && file_exists($dirsource)) {
1281 dol_syslog(get_class($this).
"::setValidate() rename dir ".$dirsource.
" into ".$dirdest);
1283 if (@rename($dirsource, $dirdest)) {
1286 $listoffiles =
dol_dir_list($conf->expensereport->dir_output.
'/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
1287 foreach ($listoffiles as $fileentry) {
1288 $dirsource = $fileentry[
'name'];
1289 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
1290 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
1291 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
1292 @rename($dirsource, $dirdest);
1302 $this->status = self::STATUS_VALIDATED;
1305 if (empty($error)) {
1306 $this->
db->commit();
1309 $this->
db->rollback();
1310 $this->error = $this->
db->error();
1314 $this->
db->rollback();
1315 $this->error = $this->
db->lasterror();
1330 global $conf, $langs;
1333 $sql =
'SELECT date_debut';
1334 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
1335 $sql .=
" WHERE rowid = ".((int) $this->
id);
1337 $result = $this->
db->query($sql);
1339 $objp = $this->
db->fetch_object($result);
1341 $this->date_debut = $this->
db->jdate($objp->date_debut);
1343 if ($this->status != self::STATUS_VALIDATED) {
1344 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1345 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1346 $sql .=
" WHERE rowid = ".((int) $this->
id);
1348 dol_syslog(get_class($this).
"::set_save_from_refuse", LOG_DEBUG);
1350 if ($this->
db->query($sql)) {
1353 $this->error = $this->
db->lasterror();
1357 dol_syslog(get_class($this).
"::set_save_from_refuse expensereport already with save status", LOG_WARNING);
1374 $this->date_approve = $now;
1375 if ($this->status != self::STATUS_APPROVED) {
1378 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1379 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_APPROVED.
", fk_user_approve = ".((int) $fuser->id).
",";
1380 $sql .=
" date_approve='".$this->db->idate($this->date_approve).
"'";
1381 $sql .=
" WHERE rowid = ".((int) $this->
id);
1382 if ($this->
db->query($sql)) {
1385 $result = $this->
call_trigger(
'EXPENSE_REPORT_APPROVE', $fuser);
1393 if (empty($error)) {
1394 $this->
db->commit();
1397 $this->
db->rollback();
1398 $this->error = $this->
db->error();
1402 $this->
db->rollback();
1403 $this->error = $this->
db->lasterror();
1407 dol_syslog(get_class($this).
"::setApproved expensereport already with approve status", LOG_WARNING);
1421 public function setDeny($fuser, $details, $notrigger = 0)
1427 if ($this->status != self::STATUS_REFUSED) {
1428 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1429 $sql .=
" SET ref = '".$this->db->escape($this->
ref).
"', fk_statut = ".self::STATUS_REFUSED.
", fk_user_refuse = ".((int) $fuser->id).
",";
1430 $sql .=
" date_refuse='".$this->db->idate($now).
"',";
1431 $sql .=
" detail_refuse='".$this->db->escape($details).
"',";
1432 $sql .=
" fk_user_approve = NULL";
1433 $sql .=
" WHERE rowid = ".((int) $this->
id);
1434 if ($this->
db->query($sql)) {
1435 $this->fk_statut = 99;
1437 $this->fk_user_refuse = $fuser->id;
1438 $this->detail_refuse = $details;
1439 $this->date_refuse = $now;
1443 $result = $this->
call_trigger(
'EXPENSE_REPORT_DENY', $fuser);
1451 if (empty($error)) {
1452 $this->
db->commit();
1455 $this->
db->rollback();
1456 $this->error = $this->
db->error();
1460 $this->
db->rollback();
1461 $this->error = $this->
db->lasterror();
1465 dol_syslog(get_class($this).
"::setDeny expensereport already with refuse status", LOG_WARNING);
1482 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
1483 return $this->
setUnpaid($fuser, $notrigger);
1500 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1501 $sql .=
" SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
1502 $sql .=
" WHERE rowid = ".((int) $this->
id);
1504 dol_syslog(get_class($this).
"::set_unpaid", LOG_DEBUG);
1506 if ($this->
db->query($sql)) {
1509 $result = $this->
call_trigger(
'EXPENSE_REPORT_UNPAID', $fuser);
1517 if (empty($error)) {
1518 $this->
db->commit();
1521 $this->
db->rollback();
1522 $this->error = $this->
db->error();
1526 $this->
db->rollback();
1527 $this->error = $this->
db->error();
1531 dol_syslog(get_class($this).
"::set_unpaid expensereport already with unpaid status", LOG_WARNING);
1548 $this->date_cancel = $this->
db->idate(
dol_now());
1549 if ($this->status != self::STATUS_CANCELED) {
1552 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
1553 $sql .=
" SET fk_statut = ".self::STATUS_CANCELED.
", fk_user_cancel = ".((int) $fuser->id);
1554 $sql .=
", date_cancel='".$this->db->idate($this->date_cancel).
"'";
1555 $sql .=
" ,detail_cancel='".$this->db->escape($detail).
"'";
1556 $sql .=
" WHERE rowid = ".((int) $this->
id);
1558 dol_syslog(get_class($this).
"::set_cancel", LOG_DEBUG);
1560 if ($this->
db->query($sql)) {
1563 $result = $this->
call_trigger(
'EXPENSE_REPORT_CANCEL', $fuser);
1571 if (empty($error)) {
1572 $this->
db->commit();
1575 $this->
db->rollback();
1576 $this->error = $this->
db->error();
1580 $this->
db->rollback();
1581 $this->error = $this->
db->error();
1585 dol_syslog(get_class($this).
"::set_cancel expensereport already with cancel status", LOG_WARNING);
1596 global $langs, $conf;
1597 $langs->load(
"trips");
1599 if (!empty($conf->global->EXPENSEREPORT_ADDON)) {
1602 $file = $conf->global->EXPENSEREPORT_ADDON.
".php";
1603 $classname = $conf->global->EXPENSEREPORT_ADDON;
1606 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1607 foreach ($dirmodels as $reldir) {
1608 $dir =
dol_buildpath($reldir.
"core/modules/expensereport/");
1611 $mybool |= @include_once $dir.$file;
1614 if ($mybool ===
false) {
1619 $obj =
new $classname();
1620 $numref = $obj->getNextValue($this);
1622 if ($numref !=
"") {
1625 $this->error = $obj->error;
1626 $this->errors = $obj->errors;
1631 $this->error =
"Error_EXPENSEREPORT_ADDON_NotDefined";
1648 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $save_lastsearch_value = -1)
1650 global $langs, $conf, $hookmanager;
1654 $url = DOL_URL_ROOT.
'/expensereport/card.php?id='.$this->id;
1660 $label =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"ExpenseReport").
'</u>';
1661 if (isset($this->status)) {
1662 $label .=
' '.$this->getLibStatut(5);
1664 if (!empty($this->
ref)) {
1665 $label .=
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1667 if (!empty($this->total_ht)) {
1668 $label .=
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1670 if (!empty($this->total_tva)) {
1671 $label .=
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1673 if (!empty($this->total_ttc)) {
1674 $label .=
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
1677 $label .=
' - '.$moretitle;
1680 if ($option !=
'nolink') {
1682 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1683 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1684 $add_save_lastsearch_values = 1;
1686 if ($add_save_lastsearch_values) {
1687 $url .=
'&save_lastsearch_values=1';
1697 if (empty($notooltip)) {
1698 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1699 $label = $langs->trans(
"ShowExpenseReport");
1700 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1702 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
1703 $linkclose .=
' class="classfortooltip"';
1706 $linkstart =
'<a href="'.$url.
'"';
1707 $linkstart .= $linkclose.
'>';
1710 $result .= $linkstart;
1712 $result .=
img_object(($notooltip ?
'' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
1714 if ($withpicto != 2) {
1715 $result .= ($max ?
dol_trunc($ref, $max) : $ref);
1717 $result .= $linkend;
1720 $hookmanager->initHooks(array($this->element .
'dao'));
1721 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
1722 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1724 $result = $hookmanager->resPrint;
1726 $result .= $hookmanager->resPrint;
1742 $this->total_ht = $this->total_ht + $ligne_total_ht;
1743 $this->total_tva = $this->total_tva + $ligne_total_tva;
1744 $this->total_ttc = $this->total_ht + $this->total_tva;
1746 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1747 $sql .=
" total_ht = ".$this->total_ht;
1748 $sql .=
" , total_ttc = ".$this->total_ttc;
1749 $sql .=
" , total_tva = ".$this->total_tva;
1750 $sql .=
" WHERE rowid = ".((int) $this->
id);
1752 $result = $this->
db->query($sql);
1756 $this->error = $this->
db->error();
1776 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)
1778 global $conf, $langs, $mysoc;
1780 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);
1782 if ($this->status == self::STATUS_DRAFT) {
1786 if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) {
1787 $fk_c_type_fees = 0;
1789 if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) {
1790 $fk_c_exp_tax_cat = 0;
1792 if (empty($vatrate) || $vatrate < 0) {
1798 if (empty($fk_project)) {
1803 if (!preg_match(
'/\s*\((.*)\)/', $vatrate)) {
1814 $seller->tva_assuj = 1;
1821 if (preg_match(
'/\s*\((.*)\)/', $vatrate, $reg)) {
1822 $vat_src_code = $reg[1];
1823 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
1825 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
1827 $tmp =
calcul_price_total($qty, $up, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
1829 $this->line->value_unit = $up;
1831 $this->line->vat_src_code = $vat_src_code;
1832 $this->line->vatrate =
price2num($vatrate);
1833 $this->line->localtax1_tx = $localtaxes_type[1];
1834 $this->line->localtax2_tx = $localtaxes_type[3];
1835 $this->line->localtax1_type = $localtaxes_type[0];
1836 $this->line->localtax2_type = $localtaxes_type[2];
1838 $this->line->total_ttc = $tmp[2];
1839 $this->line->total_ht = $tmp[0];
1840 $this->line->total_tva = $tmp[1];
1841 $this->line->total_localtax1 = $tmp[9];
1842 $this->line->total_localtax2 = $tmp[10];
1844 $this->line->fk_expensereport = $this->id;
1845 $this->line->qty = $qty;
1846 $this->line->date = $date;
1847 $this->line->fk_c_type_fees = $fk_c_type_fees;
1848 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
1849 $this->line->comments = $comments;
1850 $this->line->fk_projet = $fk_project;
1851 $this->line->fk_project = $fk_project;
1853 $this->line->fk_ecm_files = $fk_ecm_files;
1858 $result = $this->line->insert(0,
true);
1862 $this->
db->commit();
1863 return $this->line->id;
1865 $this->
db->rollback();
1869 $this->error = $this->line->error;
1870 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
1871 $this->
db->rollback();
1875 dol_syslog(get_class($this).
"::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
1876 $this->error =
'ErrorExpenseNotDraft';
1890 global $user, $conf, $db, $langs, $mysoc;
1892 $langs->load(
'trips');
1895 if (!is_object($seller)) {
1897 $seller->tva_assuj = 1;
1901 $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author);
1904 $rule_warning_message_tab = array();
1906 $current_total_ttc = $this->line->total_ttc;
1907 $new_current_total_ttc = $this->line->total_ttc;
1910 foreach ($rulestocheck as $rule) {
1911 if (in_array($rule->code_expense_rules_type, array(
'EX_DAY',
'EX_MON',
'EX_YEA'))) {
1912 $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type);
1914 $amount_to_test = $current_total_ttc;
1917 $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc;
1919 if ($amount_to_test > $rule->amount) {
1922 if ($rule->restrictive) {
1923 $this->error =
'ExpenseReportConstraintViolationError';
1924 $this->errors[] = $this->error;
1926 $new_current_total_ttc -= $amount_to_test - $rule->amount;
1927 $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));
1929 $this->error =
'ExpenseReportConstraintViolationWarning';
1930 $this->errors[] = $this->error;
1932 $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));
1939 $this->line->rule_warning_message = implode(
'\n', $rule_warning_message_tab);
1941 if ($violation > 0) {
1942 $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);
1944 $this->line->value_unit = $tmp[5];
1945 $this->line->total_ttc = $tmp[2];
1946 $this->line->total_ht = $tmp[0];
1947 $this->line->total_tva = $tmp[1];
1948 $this->line->total_localtax1 = $tmp[9];
1949 $this->line->total_localtax2 = $tmp[10];
1966 global $conf, $mysoc;
1968 if (empty($conf->global->MAIN_USE_EXPENSE_IK)) {
1972 $userauthor =
new User($this->
db);
1973 if ($userauthor->fetch($this->fk_user_author) <= 0) {
1974 $this->error =
'ErrorCantFetchUser';
1975 $this->errors[] =
'ErrorCantFetchUser';
1980 if (!is_object($seller)) {
1982 $seller->tva_assuj = 1;
1986 $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat);
1988 if (empty($range)) {
1989 $this->error =
'ErrorNoRangeAvailable';
1990 $this->errors[] =
'ErrorNoRangeAvailable';
1994 if (!empty($conf->global->MAIN_EXPENSE_APPLY_ENTIRE_OFFSET)) {
1995 $ikoffset = $range->ikoffset;
1997 $ikoffset = $range->ikoffset / 12;
2002 $new_up = $range->coef + ($ikoffset / $this->line->qty);
2003 $tmp =
calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0,
'TTC', 0, $type, $seller);
2005 $this->line->value_unit = $tmp[5];
2006 $this->line->total_ttc = $tmp[2];
2007 $this->line->total_ht = $tmp[0];
2008 $this->line->total_tva = $tmp[1];
2009 $this->line->total_localtax1 = $tmp[9];
2010 $this->line->total_localtax2 = $tmp[10];
2025 $sql =
'SELECT e.rowid FROM '.MAIN_DB_PREFIX.
'expensereport e';
2026 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"expensereport_det d ON (e.rowid = d.fk_expensereport)";
2027 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = 'EX_KME')";
2028 $sql .=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2029 $sql .=
" AND YEAR(d.date) = '".dol_print_date($this->line->date,
'%Y').
"' AND MONTH(d.date) = '".
dol_print_date($this->line->date,
'%m').
"'";
2030 if (!empty($this->line->id)) {
2031 $sql .=
' AND d.rowid <> '.((int) $this->line->id);
2034 dol_syslog(get_class($this).
"::offsetAlreadyGiven");
2037 $num = $this->
db->num_rows(
$resql);
2065 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)
2067 global $user, $mysoc;
2069 if ($this->status == self::STATUS_DRAFT || $this->status == self::STATUS_REFUSED) {
2077 $seller->tva_assuj = 1;
2078 $seller->localtax1_assuj = $mysoc->localtax1_assuj;
2079 $seller->localtax2_assuj = $mysoc->localtax1_assuj;
2087 if (preg_match(
'/\((.*)\)/', $vatrate, $reg)) {
2088 $vat_src_code = $reg[1];
2089 $vatrate = preg_replace(
'/\s*\(.*\)/',
'', $vatrate);
2091 $vatrate = preg_replace(
'/\*/',
'', $vatrate);
2093 $tmp =
calcul_price_total($qty, $value_unit, 0, $vatrate, -1, -1, 0,
'TTC', 0, $type, $seller, $localtaxes_type);
2098 $tx_tva = $vatrate / 100;
2099 $tx_tva = $tx_tva + 1;
2102 $this->line->comments = $comments;
2103 $this->line->qty = $qty;
2104 $this->line->value_unit = $value_unit;
2105 $this->line->date = $date;
2107 $this->line->fk_expensereport = $expensereport_id;
2108 $this->line->fk_c_type_fees = $type_fees_id;
2109 $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat;
2110 $this->line->fk_projet = $projet_id;
2111 $this->line->fk_project = $projet_id;
2113 $this->line->vat_src_code = $vat_src_code;
2114 $this->line->vatrate =
price2num($vatrate);
2115 $this->line->localtax1_tx = $localtaxes_type[1];
2116 $this->line->localtax2_tx = $localtaxes_type[3];
2117 $this->line->localtax1_type = $localtaxes_type[0];
2118 $this->line->localtax2_type = $localtaxes_type[2];
2120 $this->line->total_ttc = $tmp[2];
2121 $this->line->total_ht = $tmp[0];
2122 $this->line->total_tva = $tmp[1];
2123 $this->line->total_localtax1 = $tmp[9];
2124 $this->line->total_localtax2 = $tmp[10];
2126 $this->line->fk_ecm_files = $fk_ecm_files;
2128 $this->line->id = ((int) $rowid);
2131 $sql =
"SELECT c.code as code_type_fees, c.label as libelle_type_fees";
2132 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees as c";
2133 $sql .=
" WHERE c.id = ".((int) $type_fees_id);
2136 $objp_fees = $this->
db->fetch_object(
$resql);
2137 $this->line->type_fees_code = $objp_fees->code_type_fees;
2138 $this->line->type_fees_libelle = $objp_fees->libelle_type_fees;
2143 $sql =
"SELECT p.ref as ref_projet, p.title as title_projet";
2144 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2145 $sql .=
" WHERE p.rowid = ".((int) $projet_id);
2148 $objp_projet = $this->
db->fetch_object(
$resql);
2149 $this->line->projet_ref = $objp_projet->ref_projet;
2150 $this->line->projet_title = $objp_projet->title_projet;
2157 $result = $this->line->update($user);
2162 if (!$error && !$notrigger) {
2164 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_MODIFY', $user);
2172 $this->
db->commit();
2175 $this->error = $this->line->error;
2176 $this->errors = $this->line->errors;
2177 $this->
db->rollback();
2199 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_DELETE', $fuser);
2206 $sql =
' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2207 $sql .=
' WHERE rowid = '.((int) $rowid);
2209 dol_syslog(get_class($this).
"::deleteline sql=".$sql);
2210 $result = $this->
db->query($sql);
2212 if (!$result || $error > 0 ) {
2213 $this->error = $this->
db->error();
2214 dol_syslog(get_class($this).
"::deleteline Error ".$this->error, LOG_ERR);
2215 $this->
db->rollback();
2221 $this->
db->commit();
2238 $sql =
"SELECT rowid, date_debut, date_fin";
2239 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element;
2240 $sql .=
" WHERE fk_user_author = '{$fuser->id}'";
2242 dol_syslog(get_class($this).
"::periode_existe sql=".$sql);
2243 $result = $this->
db->query($sql);
2245 $num_rows = $this->
db->num_rows($result); $i = 0;
2247 if ($num_rows > 0) {
2248 $date_d_form = $date_debut;
2249 $date_f_form = $date_fin;
2251 while ($i < $num_rows) {
2252 $objp = $this->
db->fetch_object($result);
2254 $date_d_req = $this->
db->jdate($objp->date_debut);
2255 $date_f_req = $this->
db->jdate($objp->date_fin);
2257 if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) {
2258 return $objp->rowid;
2269 $this->error = $this->
db->lasterror();
2270 dol_syslog(get_class($this).
"::periode_existe Error ".$this->error, LOG_ERR);
2286 $users_validator = array();
2288 $sql =
"SELECT DISTINCT ur.fk_user";
2289 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2290 $sql .=
" WHERE ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2292 $sql .=
" SELECT DISTINCT ugu.fk_user";
2293 $sql .=
" FROM ".MAIN_DB_PREFIX.
"usergroup_user as ugu, ".MAIN_DB_PREFIX.
"usergroup_rights as ur, ".MAIN_DB_PREFIX.
"rights_def as rd";
2294 $sql .=
" WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'expensereport' AND rd.perms = 'approve'";
2297 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport sql=".$sql);
2298 $result = $this->
db->query($sql);
2300 $num_rows = $this->
db->num_rows($result); $i = 0;
2301 while ($i < $num_rows) {
2302 $objp = $this->
db->fetch_object($result);
2303 array_push($users_validator, $objp->fk_user);
2306 return $users_validator;
2308 $this->error = $this->
db->lasterror();
2309 dol_syslog(get_class($this).
"::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
2325 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2329 $outputlangs->load(
"trips");
2332 if (!empty($this->model_pdf)) {
2333 $modele = $this->model_pdf;
2334 } elseif (!empty($this->modelpdf)) {
2335 $modele = $this->modelpdf;
2336 } elseif (!empty($conf->global->EXPENSEREPORT_ADDON_PDF)) {
2337 $modele = $conf->global->EXPENSEREPORT_ADDON_PDF;
2341 if (!empty($modele)) {
2342 $modelpath =
"core/modules/expensereport/doc/";
2344 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2360 $sql =
"SELECT id, code, label";
2361 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_fees";
2362 $sql .=
" WHERE active = ".((int) $active);
2363 dol_syslog(get_class($this).
"::listOfTypes", LOG_DEBUG);
2364 $result = $this->
db->query($sql);
2366 $num = $this->
db->num_rows($result);
2369 $obj = $this->
db->fetch_object($result);
2370 $ret[$obj->code] = (($langs->transnoentitiesnoconv($obj->code) != $obj->code) ? $langs->transnoentitiesnoconv($obj->code) : $obj->label);
2388 global $conf, $user;
2390 $this->nb = array();
2392 $sql =
"SELECT count(ex.rowid) as nb";
2393 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2394 $sql .=
" WHERE ex.fk_statut > 0";
2395 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2396 if (empty($user->rights->expensereport->readall)) {
2397 $userchildids = $user->getAllChildIds(1);
2398 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2399 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2404 while ($obj = $this->
db->fetch_object(
$resql)) {
2405 $this->nb[
"expensereports"] = $obj->nb;
2411 $this->error = $this->
db->error();
2427 global $conf, $langs;
2435 $sql =
"SELECT ex.rowid, ex.date_valid";
2436 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport as ex";
2437 if ($option ==
'toapprove') {
2438 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_VALIDATED;
2440 $sql .=
" WHERE ex.fk_statut = ".self::STATUS_APPROVED;
2442 $sql .=
" AND ex.entity IN (".getEntity(
'expensereport').
")";
2443 if (empty($user->rights->expensereport->readall)) {
2444 $userchildids = $user->getAllChildIds(1);
2445 $sql .=
" AND (ex.fk_user_author IN (".$this->db->sanitize(join(
',', $userchildids)).
")";
2446 $sql .=
" OR ex.fk_user_validator IN (".$this->db->sanitize(join(
',', $userchildids)).
"))";
2451 $langs->load(
"trips");
2454 if ($option ==
'toapprove') {
2455 $response->warning_delay = $conf->expensereport->approve->warning_delay / 60 / 60 / 24;
2456 $response->label = $langs->trans(
"ExpenseReportsToApprove");
2457 $response->labelShort = $langs->trans(
"ToApprove");
2458 $response->url = DOL_URL_ROOT.
'/expensereport/list.php?mainmenu=hrm&statut='.self::STATUS_VALIDATED;
2460 $response->warning_delay = $conf->expensereport->payment->warning_delay / 60 / 60 / 24;
2461 $response->label = $langs->trans(
"ExpenseReportsToPay");
2462 $response->labelShort = $langs->trans(
"StatusToPay");
2463 $response->url = DOL_URL_ROOT.
'/expensereport/list.php?mainmenu=hrm&statut='.self::STATUS_APPROVED;
2467 while ($obj = $this->
db->fetch_object(
$resql)) {
2468 $response->nbtodo++;
2470 if ($option ==
'toapprove') {
2471 if ($this->
db->jdate($obj->date_valid) < ($now - $conf->expensereport->approve->warning_delay)) {
2472 $response->nbtodolate++;
2475 if ($this->
db->jdate($obj->date_valid) < ($now - $conf->expensereport->payment->warning_delay)) {
2476 $response->nbtodolate++;
2484 $this->error = $this->
db->error();
2500 if ($option ==
'toapprove' && $this->status != 2) {
2503 if ($option ==
'topay' && $this->status != 5) {
2508 if ($option ==
'toapprove') {
2509 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->approve->warning_delay);
2511 return (!empty($this->datevalid) ? $this->datevalid : $this->date_valid) < ($now - $conf->expensereport->payment->warning_delay);
2522 $alreadydispatched = 0;
2524 $type =
'expense_report';
2526 $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);
2529 $obj = $this->
db->fetch_object(
$resql);
2531 $alreadydispatched = $obj->nb;
2534 $this->error = $this->
db->lasterror();
2538 if ($alreadydispatched) {
2551 $table =
'payment_expensereport';
2552 $field =
'fk_expensereport';
2554 $sql =
'SELECT sum(amount) as amount';
2555 $sql .=
' FROM '.MAIN_DB_PREFIX.$table;
2556 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
2558 dol_syslog(get_class($this).
"::getSumPayments", LOG_DEBUG);
2561 $obj = $this->
db->fetch_object(
$resql);
2563 return (empty($obj->amount) ? 0 : $obj->amount);
2565 $this->error = $this->
db->lasterror();
2580 global $langs,$user,$db,$conf;
2589 $this->error = $langs->trans(
'ErrorBadParameterCat');
2594 $this->error = $langs->trans(
'ErrorBadParameterQty');
2598 $currentUser =
new User($db);
2599 $currentUser->fetch($this->fk_user);
2600 $currentUser->getrights(
'expensereport');
2604 $sql =
" SELECT r.range_ik, t.ikoffset as offset, t.coef";
2605 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expensereport_ik t";
2606 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_exp_tax_range r ON r.rowid = t.fk_range";
2607 $sql .=
" WHERE t.fk_c_exp_tax_cat = ".(int) $fk_cat;
2608 $sql .=
" ORDER BY r.range_ik ASC";
2610 dol_syslog(
"expenseReport::computeTotalkm sql=".$sql, LOG_DEBUG);
2612 $result = $this->
db->query($sql);
2615 if ($conf->global->EXPENSEREPORT_CALCULATE_MILEAGE_EXPENSE_COEFFICIENT_ON_CURRENT_YEAR) {
2617 $sql =
" SELECT count(n.qty) as cumul FROM ".MAIN_DB_PREFIX.
"expensereport_det n";
2618 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expensereport e ON e.rowid = n.fk_expensereport";
2619 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_type_fees tf ON tf.id = n.fk_c_type_fees";
2620 $sql.=
" WHERE e.fk_user_author = ".(int) $this->fk_user_author;
2621 $sql.=
" AND YEAR(n.date) = ".(int) $arrayDate[
'year'];
2622 $sql.=
" AND tf.code = 'EX_KME' ";
2628 $obj = $this->
db->fetch_object(
$resql);
2629 $cumulYearQty = $obj->cumul;
2631 $qty = $cumulYearQty + $qty;
2634 $num = $this->
db->num_rows($result);
2637 for ($i = 0; $i < $num; $i++) {
2638 $obj = $this->
db->fetch_object($result);
2644 for ($i = 0; $i < $num; $i++) {
2645 if ($i < ($num - 1)) {
2646 if ($qty > $ranges[$i]->range_ik && $qty < $ranges[$i+1]->range_ik) {
2647 $coef = $ranges[$i]->coef;
2648 $offset = $ranges[$i]->offset;
2651 if ($qty > $ranges[$i]->range_ik) {
2652 $coef = $ranges[$i]->coef;
2653 $offset = $ranges[$i]->offset;
2660 $this->error = $langs->trans(
'TaxUndefinedForThisCategory');
2664 $this->error = $this->
db->error().
" sql=".$sql;
2700 public $fk_c_type_fees;
2705 public $fk_c_exp_tax_cat;
2715 public $fk_expensereport;
2717 public $type_fees_code;
2718 public $type_fees_libelle;
2719 public $type_fees_accountancy_code;
2722 public $projet_title;
2726 public $vat_src_code;
2728 public $localtax1_tx;
2729 public $localtax2_tx;
2730 public $localtax1_type;
2731 public $localtax2_type;
2736 public $total_localtax1;
2737 public $total_localtax2;
2742 public $fk_ecm_files;
2744 public $rule_warning_message;
2765 $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,';
2766 $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,';
2767 $sql .=
' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,';
2768 $sql .=
' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
2769 $sql .=
' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
2770 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det as fde';
2771 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
2772 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'projet as pjt ON fde.fk_projet=pjt.rowid';
2773 $sql .=
' WHERE fde.rowid = '.((int) $rowid);
2775 $result = $this->
db->query($sql);
2778 $objp = $this->
db->fetch_object($result);
2780 $this->
rowid = $objp->rowid;
2781 $this->
id = $objp->rowid;
2782 $this->
ref = $objp->ref;
2783 $this->fk_expensereport = $objp->fk_expensereport;
2784 $this->comments = $objp->comments;
2785 $this->qty = $objp->qty;
2786 $this->date = $objp->date;
2787 $this->dates = $this->
db->jdate($objp->date);
2788 $this->value_unit = $objp->value_unit;
2789 $this->fk_c_type_fees = $objp->fk_c_type_fees;
2790 $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
2791 $this->fk_projet = $objp->fk_project;
2792 $this->fk_project = $objp->fk_project;
2793 $this->type_fees_code = $objp->type_fees_code;
2794 $this->type_fees_libelle = $objp->type_fees_libelle;
2795 $this->projet_ref = $objp->projet_ref;
2796 $this->projet_title = $objp->projet_title;
2798 $this->
vatrate = $objp->vatrate;
2799 $this->vat_src_code = $objp->vat_src_code;
2800 $this->localtax1_tx = $objp->localtax1_tx;
2801 $this->localtax2_tx = $objp->localtax2_tx;
2802 $this->localtax1_type = $objp->localtax1_type;
2803 $this->localtax2_type = $objp->localtax2_type;
2805 $this->total_ht = $objp->total_ht;
2806 $this->total_tva = $objp->total_tva;
2807 $this->total_ttc = $objp->total_ttc;
2808 $this->total_localtax1 = $objp->total_localtax1;
2809 $this->total_localtax2 = $objp->total_localtax2;
2811 $this->fk_ecm_files = $objp->fk_ecm_files;
2813 $this->rule_warning_message = $objp->rule_warning_message;
2815 $this->
db->free($result);
2828 public function insert($notrigger = 0, $fromaddline =
false)
2830 global $langs, $user, $conf;
2834 dol_syslog(
"ExpenseReportLine::Insert", LOG_DEBUG);
2837 $this->comments = trim($this->comments);
2838 if (empty($this->value_unit)) {
2839 $this->value_unit = 0;
2843 if (empty($this->fk_c_exp_tax_cat)) {
2844 $this->fk_c_exp_tax_cat = 0;
2849 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'expensereport_det';
2850 $sql .=
' (fk_expensereport, fk_c_type_fees, fk_projet,';
2851 $sql .=
' tva_tx, vat_src_code,';
2852 $sql .=
' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
2853 $sql .=
' comments, qty, value_unit,';
2854 $sql .=
' total_ht, total_tva, total_ttc,';
2855 $sql .=
' total_localtax1, total_localtax2,';
2856 $sql .=
' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)';
2857 $sql .=
" VALUES (".$this->db->escape($this->fk_expensereport).
",";
2858 $sql .=
" ".((int) $this->fk_c_type_fees).
",";
2859 $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')).
",";
2860 $sql .=
" ".((float) $this->
vatrate).
",";
2861 $sql .=
" '".$this->db->escape(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"',";
2862 $sql .=
" ".((float)
price2num($this->localtax1_tx)).
",";
2863 $sql .=
" ".((float)
price2num($this->localtax2_tx)).
",";
2864 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
2865 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
2866 $sql .=
" '".$this->db->escape($this->comments).
"',";
2867 $sql .=
" ".((float) $this->qty).
",";
2868 $sql .=
" ".((float) $this->value_unit).
",";
2869 $sql .=
" ".((float)
price2num($this->total_ht)).
",";
2870 $sql .=
" ".((float)
price2num($this->total_tva)).
",";
2871 $sql .=
" ".((float)
price2num($this->total_ttc)).
",";
2872 $sql .=
" ".((float)
price2num($this->total_localtax1)).
",";
2873 $sql .=
" ".((float)
price2num($this->total_localtax2)).
",";
2874 $sql .=
" '".$this->db->idate($this->date).
"',";
2875 $sql .=
" ".(empty($this->rule_warning_message) ?
'null' :
"'".$this->db->escape($this->rule_warning_message).
"'").
",";
2876 $sql .=
" ".((int) $this->fk_c_exp_tax_cat).
",";
2877 $sql .=
" ".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
2882 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
'expensereport_det');
2885 if (!$error && !$notrigger) {
2887 $result = $this->
call_trigger(
'EXPENSE_REPORT_DET_CREATE', $user);
2895 if (!$fromaddline) {
2897 $tmpparent->fetch($this->fk_expensereport);
2898 $result = $tmpparent->update_price();
2901 $this->error = $tmpparent->error;
2902 $this->errors = $tmpparent->errors;
2910 $this->
db->commit();
2913 $this->error = $this->
db->lasterror();
2914 dol_syslog(
"ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
2915 $this->
db->rollback();
2932 $sql =
'SELECT SUM(d.total_ttc) as total_amount';
2933 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expensereport_det d';
2934 $sql .=
' INNER JOIN '.MAIN_DB_PREFIX.
'expensereport e ON (d.fk_expensereport = e.rowid)';
2935 $sql .=
' WHERE e.fk_user_author = '.((int) $fk_user);
2936 if (!empty($this->
id)) {
2937 $sql .=
' AND d.rowid <> '.((int) $this->
id);
2939 $sql .=
' AND d.fk_c_type_fees = '.((int) $rule->fk_c_type_fees);
2940 if ($mode ==
'day' || $mode ==
'EX_DAY') {
2941 $sql .=
" AND d.date = '".dol_print_date($this->date,
'%Y-%m-%d').
"'";
2942 } elseif ($mode ==
'mon' || $mode ==
'EX_MON') {
2943 $sql .=
" AND DATE_FORMAT(d.date, '%Y-%m') = '".dol_print_date($this->date,
'%Y-%m').
"'";
2944 } elseif ($mode ==
'year' || $mode ==
'EX_YEA') {
2945 $sql .=
" AND DATE_FORMAT(d.date, '%Y') = '".dol_print_date($this->date,
'%Y').
"'";
2948 dol_syslog(
'ExpenseReportLine::getExpAmount');
2952 $num = $this->
db->num_rows(
$resql);
2954 $obj = $this->
db->fetch_object(
$resql);
2955 $amount = (double) $obj->total_amount;
2961 return $amount + $this->total_ttc;
2972 global $langs, $conf;
2977 $this->comments = trim($this->comments);
2979 $this->value_unit =
price2num($this->value_unit);
2980 if (empty($this->fk_c_exp_tax_cat)) {
2981 $this->fk_c_exp_tax_cat = 0;
2987 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"expensereport_det SET";
2988 $sql .=
" comments='".$this->db->escape($this->comments).
"'";
2989 $sql .=
", value_unit = ".((float) $this->value_unit);
2990 $sql .=
", qty=".((float) $this->qty);
2991 $sql .=
", date='".$this->db->idate($this->date).
"'";
2992 $sql .=
", total_ht=".((float)
price2num($this->total_ht,
'MT'));
2993 $sql .=
", total_tva=".((float)
price2num($this->total_tva,
'MT'));
2994 $sql .=
", total_ttc=".((float)
price2num($this->total_ttc,
'MT'));
2995 $sql .=
", total_localtax1=".((float)
price2num($this->total_localtax1,
'MT'));
2996 $sql .=
", total_localtax2=".((float)
price2num($this->total_localtax2,
'MT'));
2997 $sql .=
", tva_tx=".((float) $this->
vatrate);
2998 $sql .=
", vat_src_code='".$this->db->escape($this->vat_src_code).
"'";
2999 $sql .=
", localtax1_tx=".((float) $this->localtax1_tx);
3000 $sql .=
", localtax2_tx=".((float) $this->localtax2_tx);
3001 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
3002 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
3003 $sql .=
", rule_warning_message='".$this->db->escape($this->rule_warning_message).
"'";
3004 $sql .=
", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat);
3005 $sql .=
", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) :
'null');
3006 if ($this->fk_c_type_fees) {
3007 $sql .=
", fk_c_type_fees = ".((int) $this->fk_c_type_fees);
3009 $sql .=
", fk_c_type_fees=null";
3011 if ($this->fk_project > 0) {
3012 $sql .=
", fk_projet=".((int) $this->fk_project);
3014 $sql .=
", fk_projet=null";
3016 $sql .=
" WHERE rowid = ".((int) ($this->
rowid ? $this->
rowid : $this->
id));
3023 $result = $tmpparent->fetch($this->fk_expensereport);
3025 $result = $tmpparent->update_price();
3028 $this->error = $tmpparent->error;
3029 $this->errors = $tmpparent->errors;
3033 $this->error = $tmpparent->error;
3034 $this->errors = $tmpparent->errors;
3042 $this->
db->commit();
3045 $this->error = $this->
db->lasterror();
3046 dol_syslog(
"ExpenseReportLine::update Error ".$this->error, LOG_ERR);
3047 $this->
db->rollback();
createFromClone(User $user, $fk_user_author)
Load an object from its id and create a new one in database.
getNextNumRef()
Return next reference of expense report not already used.
const STATUS_APPROVED
Classified approved.
const STATUS_VALIDATED
Validated (need to be paid)
LibStatut($status, $mode=0)
Returns the label of a status.
info($id)
Load information on object.
Class of expense report details lines.
__construct($db)
Constructor.
$conf db
API class for accounts.
getNomUrl($withpicto=0, $option= '', $max=0, $short=0, $moretitle= '', $notooltip=0, $save_lastsearch_value=-1)
Return clicable name (with picto eventually)
Class to manage inventories.
setUnpaid($fuser, $notrigger=0)
set_unpaid
dol_now($mode= 'auto')
Return date for now.
getVentilExportCompta()
Return if object was dispatched into bookkeeping.
deleteObjectLinked($sourceid=null, $sourcetype= '', $targetid=null, $targettype= '', $rowid= '', $f_user=null, $notrigger=0)
Delete all links between an object $this.
dol_delete_preview($object)
Delete all preview files linked to object instance.
Class to manage inventories.
delete_linked_contact($source= '', $code= '')
Delete all links between an object $this and all its contacts.
setPaid($id, $fuser, $notrigger=0)
Classify the expense report as paid.
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.
Class to manage Dolibarr users.
const STATUS_CLOSED
Classified paid.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setDeny($fuser, $details, $notrigger=0)
setDeny
const STATUS_CANCELED
Classified canceled.
fetch($rowid)
Fetch record for expense report detailed line.
periode_existe($fuser, $date_debut, $date_fin)
periode_existe
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
deleteline($rowid, $fuser= '', $notrigger=0)
deleteline
const STATUS_REFUSED
Classified refused.
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...
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
set_unpaid($fuser, $notrigger=0)
set_unpaid
insertExtraFields($trigger= '', $userused=null)
Add/Update all extra fields values for the current object.
fetch_line_by_project($projectid, $user= '')
fetch_line_by_project
setValidate($fuser, $notrigger=0)
Set to status validate.
Class to manage third parties objects (customers, suppliers, prospects...)
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.
computeTotalKm($fk_cat, $qty, $tva)
Compute the cost of the kilometers expense based on the number of kilometers and the vehicule categor...
checkRules($type=0, $seller= '')
Check constraint of rules and update price if needed.
update(User $user)
Update line.
dol_strlen($string, $stringencoding= 'UTF-8')
Make a strlen call.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is '...
update_totaux_add($ligne_total_ht, $ligne_total_tva)
Update total of an expense report when you add a line.
load_board($user, $option= 'topay')
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
fetch_users_approver_expensereport()
Return list of people with permission to validate expense reports.
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) ...
getSumPayments()
Return amount of payments already done.
deleteEcmFiles($mode=0)
Delete related files of object in database.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
initAsSpecimen()
Initialise an instance with random values.
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.
set_paid($id, $fuser, $notrigger=0)
Classify the expense report as paid.
getExpAmount(ExpenseReportRule $rule, $fk_user, $mode= 'day')
Function to get total amount in expense reports for a same rule.
img_object($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
deleteExtraFields()
Delete all extra fields values for the current object.
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
Class to manage Trips and Expenses.
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...
listOfTypes($active=1)
List of types.
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.
if(isModEnabled('facture')&&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur')&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)&&$user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice')&&$user->rights->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->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
setApproved($fuser, $notrigger=0)
Set status to approved.
hasDelay($option)
Return if an expense report is late or not.
load_state_board()
Charge indicateurs this->nb pour le tableau de bord.
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
call_trigger($triggerName, $user)
Call trigger based on this instance.
set_cancel($fuser, $detail, $notrigger=0)
set_cancel
create($user, $notrigger=0)
Create object in database.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk accordign to template module.
insert($notrigger=0, $fromaddline=false)
Insert a line of expense report.
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
update($user, $notrigger=0, $userofexpensereport=null)
update
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. ...
dolGetStatus($statusLabel= '', $statusLabelShort= '', $html= '', $statusType= 'status0', $displayMode=0, $url= '', $params=array())
Output the badge of a status.
offsetAlreadyGiven()
If the sql find any rows then the ikoffset is already given (ikoffset is applied at the first expense...
__construct($db)
Constructor.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
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)...
getLibStatut($mode=0)
Returns the label status.
const STATUS_DRAFT
Draft status.
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.
Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
set_save_from_refuse($fuser)
set_save_from_refuse
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
applyOffset($type=0, $seller= '')
Method to apply the offset if needed.
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...
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid