dolibarr 21.0.0-beta
expensereportline.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2011 Dimitri Mouillard <dmouillard@teclib.com>
3 * Copyright (C) 2015 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
5 * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
6 * Copyright (c) 2018-2024 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2016-2020 Ferran Marcet <fmarcet@2byte.es>
8 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
10 * Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
31require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
32require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_rule.class.php';
33
38{
42 public $db;
43
47 public $table_element = 'expensereport_det';
48
52 public $error = '';
53
57 public $rowid;
58
62 public $comments;
63
67 public $qty;
68
72 public $value_unit;
73
77 public $date;
78
82 public $dates;
83
87 public $fk_c_type_fees;
88
92 public $fk_c_exp_tax_cat;
93
97 public $fk_projet;
98
102 public $fk_expensereport;
103
107 public $type_fees_code;
108
112 public $type_fees_libelle;
113
117 public $type_fees_accountancy_code;
118
122 public $projet_ref;
123
127 public $projet_title;
128
132 public $rang;
133
137 public $vatrate;
138
142 public $vat_src_code;
143
147 public $tva_tx;
148
152 public $localtax1_tx;
153
157 public $localtax2_tx;
158
162 public $localtax1_type;
163
167 public $localtax2_type;
168
172 public $total_ht;
173
177 public $total_tva;
178
182 public $total_ttc;
183
187 public $total_localtax1;
188
192 public $total_localtax2;
193
194 // Multicurrency
198 public $fk_multicurrency;
199
203 public $multicurrency_code;
204
208 public $multicurrency_tx;
209
213 public $multicurrency_total_ht;
214
218 public $multicurrency_total_tva;
219
223 public $multicurrency_total_ttc;
224
228 public $fk_ecm_files;
229
233 public $rule_warning_message;
234
235
241 public function __construct($db)
242 {
243 $this->db = $db;
244 }
245
252 public function fetch($rowid)
253 {
254 $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,';
255 $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,';
256 $sql .= ' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,';
257 $sql .= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
258 $sql .= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
259 $sql .= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde';
260 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id'; // Sometimes type of expense report has been removed, so we use a left join here.
261 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid';
262 $sql .= ' WHERE fde.rowid = '.((int) $rowid);
263
264 $result = $this->db->query($sql);
265
266 if ($result) {
267 $objp = $this->db->fetch_object($result);
268
269 $this->rowid = $objp->rowid;
270 $this->id = $objp->rowid;
271 //$this->ref = $objp->ref; Undefined property
272 $this->fk_expensereport = $objp->fk_expensereport;
273 $this->comments = $objp->comments;
274 $this->qty = $objp->qty;
275 $this->date = $objp->date;
276 $this->dates = $this->db->jdate($objp->date);
277 $this->value_unit = $objp->value_unit;
278 $this->fk_c_type_fees = $objp->fk_c_type_fees;
279 $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat;
280 $this->fk_projet = $objp->fk_project; // deprecated
281 $this->fk_project = $objp->fk_project;
282 $this->type_fees_code = $objp->type_fees_code;
283 $this->type_fees_libelle = $objp->type_fees_libelle;
284 $this->projet_ref = $objp->projet_ref;
285 $this->projet_title = $objp->projet_title;
286
287 $this->vatrate = $objp->vatrate;
288 $this->vat_src_code = $objp->vat_src_code;
289 $this->localtax1_tx = $objp->localtax1_tx;
290 $this->localtax2_tx = $objp->localtax2_tx;
291 $this->localtax1_type = $objp->localtax1_type;
292 $this->localtax2_type = $objp->localtax2_type;
293
294 $this->total_ht = $objp->total_ht;
295 $this->total_tva = $objp->total_tva;
296 $this->total_ttc = $objp->total_ttc;
297 $this->total_localtax1 = $objp->total_localtax1;
298 $this->total_localtax2 = $objp->total_localtax2;
299
300 $this->fk_ecm_files = $objp->fk_ecm_files;
301
302 $this->rule_warning_message = $objp->rule_warning_message;
303
304 $this->db->free($result);
305
306 return $this->id;
307 } else {
308 dol_print_error($this->db);
309 return -1;
310 }
311 }
312
320 public function insert($notrigger = 0, $fromaddline = false)
321 {
322 global $user;
323
324 $error = 0;
325
326 dol_syslog("ExpenseReportLine::Insert", LOG_DEBUG);
327
328 // Clean parameters
329 $this->comments = trim($this->comments);
330 if (empty($this->value_unit)) {
331 $this->value_unit = 0;
332 }
333 $this->qty = (float) price2num($this->qty);
334 $this->vatrate = price2num($this->vatrate);
335 if (empty($this->fk_c_exp_tax_cat)) {
336 $this->fk_c_exp_tax_cat = 0;
337 }
338
339 $this->db->begin();
340
341 $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'expensereport_det';
342 $sql .= ' (fk_expensereport, fk_c_type_fees, fk_projet,';
343 $sql .= ' tva_tx, vat_src_code,';
344 $sql .= ' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
345 $sql .= ' comments, qty, value_unit,';
346 $sql .= ' total_ht, total_tva, total_ttc,';
347 $sql .= ' total_localtax1, total_localtax2,';
348 $sql .= ' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)';
349 $sql .= " VALUES (".$this->db->escape($this->fk_expensereport).",";
350 $sql .= " ".((int) $this->fk_c_type_fees).",";
351 $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')).",";
352 $sql .= " ".((float) $this->vatrate).",";
353 $sql .= " '".$this->db->escape(empty($this->vat_src_code) ? '' : $this->vat_src_code)."',";
354 $sql .= " ".((float) price2num($this->localtax1_tx)).",";
355 $sql .= " ".((float) price2num($this->localtax2_tx)).",";
356 $sql .= " '".$this->db->escape($this->localtax1_type)."',";
357 $sql .= " '".$this->db->escape($this->localtax2_type)."',";
358 $sql .= " '".$this->db->escape($this->comments)."',";
359 $sql .= " ".((float) $this->qty).",";
360 $sql .= " ".((float) $this->value_unit).",";
361 $sql .= " ".((float) price2num($this->total_ht)).",";
362 $sql .= " ".((float) price2num($this->total_tva)).",";
363 $sql .= " ".((float) price2num($this->total_ttc)).",";
364 $sql .= " ".((float) price2num($this->total_localtax1)).",";
365 $sql .= " ".((float) price2num($this->total_localtax2)).",";
366 $sql .= " '".$this->db->idate($this->date)."',";
367 $sql .= " ".(empty($this->rule_warning_message) ? 'null' : "'".$this->db->escape($this->rule_warning_message)."'").",";
368 $sql .= " ".((int) $this->fk_c_exp_tax_cat).",";
369 $sql .= " ".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) : 'null');
370 $sql .= ")";
371
372 $resql = $this->db->query($sql);
373 if ($resql) {
374 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'expensereport_det');
375
376 if (!$error && !$notrigger) {
377 // Call triggers
378 $result = $this->call_trigger('EXPENSE_REPORT_DET_CREATE', $user);
379 if ($result < 0) {
380 $error++;
381 }
382 // End call triggers
383 }
384
385 if (!$fromaddline) {
386 $tmpparent = new ExpenseReport($this->db);
387 $tmpparent->fetch($this->fk_expensereport);
388 $result = $tmpparent->update_price(1);
389 if ($result < 0) {
390 $error++;
391 $this->error = $tmpparent->error;
392 $this->errors = $tmpparent->errors;
393 }
394 }
395 } else {
396 $error++;
397 }
398
399 if (!$error) {
400 $this->db->commit();
401 return $this->id;
402 } else {
403 $this->error = $this->db->lasterror();
404 dol_syslog("ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
405 $this->db->rollback();
406 return -2;
407 }
408 }
409
418 public function getExpAmount(ExpenseReportRule $rule, $fk_user, $mode = 'day')
419 {
420 $amount = 0;
421
422 $sql = 'SELECT SUM(d.total_ttc) as total_amount';
423 $sql .= ' FROM '.MAIN_DB_PREFIX.'expensereport_det d';
424 $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'expensereport e ON (d.fk_expensereport = e.rowid)';
425 $sql .= ' WHERE e.fk_user_author = '.((int) $fk_user);
426 if (!empty($this->id)) {
427 $sql .= ' AND d.rowid <> '.((int) $this->id);
428 }
429 $sql .= ' AND d.fk_c_type_fees = '.((int) $rule->fk_c_type_fees);
430 if ($mode == 'day' || $mode == 'EX_DAY') {
431 $sql .= " AND d.date = '".dol_print_date($this->date, '%Y-%m-%d')."'";
432 } elseif ($mode == 'mon' || $mode == 'EX_MON') {
433 $sql .= " AND DATE_FORMAT(d.date, '%Y-%m') = '".dol_print_date($this->date, '%Y-%m')."'"; // @todo DATE_FORMAT is forbidden
434 } elseif ($mode == 'year' || $mode == 'EX_YEA') {
435 $sql .= " AND DATE_FORMAT(d.date, '%Y') = '".dol_print_date($this->date, '%Y')."'"; // @todo DATE_FORMAT is forbidden
436 }
437
438 dol_syslog('ExpenseReportLine::getExpAmount');
439
440 $resql = $this->db->query($sql);
441 if ($resql) {
442 $num = $this->db->num_rows($resql);
443 if ($num > 0) {
444 $obj = $this->db->fetch_object($resql);
445 $amount = (float) $obj->total_amount;
446 }
447 } else {
448 dol_print_error($this->db);
449 }
450
451 return $amount + $this->total_ttc;
452 }
453
461 public function update(User $user, $notrigger = 0)
462 {
463 global $langs;
464
465 $error = 0;
466
467 // Clean parameters
468 $this->comments = trim($this->comments);
469 $this->vatrate = price2num($this->vatrate);
470 $this->value_unit = price2num($this->value_unit);
471 if (empty($this->fk_c_exp_tax_cat)) {
472 $this->fk_c_exp_tax_cat = 0;
473 }
474
475 $this->db->begin();
476
477 // Update line in database
478 $sql = "UPDATE ".MAIN_DB_PREFIX."expensereport_det SET";
479 $sql .= " comments='".$this->db->escape($this->comments)."'";
480 $sql .= ", value_unit = ".((float) $this->value_unit);
481 $sql .= ", qty=".((float) $this->qty);
482 $sql .= ", date='".$this->db->idate($this->date)."'";
483 $sql .= ", total_ht=".((float) price2num($this->total_ht, 'MT'));
484 $sql .= ", total_tva=".((float) price2num($this->total_tva, 'MT'));
485 $sql .= ", total_ttc=".((float) price2num($this->total_ttc, 'MT'));
486 $sql .= ", total_localtax1=".((float) price2num($this->total_localtax1, 'MT'));
487 $sql .= ", total_localtax2=".((float) price2num($this->total_localtax2, 'MT'));
488 $sql .= ", tva_tx=".((float) $this->vatrate);
489 $sql .= ", vat_src_code='".$this->db->escape($this->vat_src_code)."'";
490 $sql .= ", localtax1_tx=".((float) $this->localtax1_tx);
491 $sql .= ", localtax2_tx=".((float) $this->localtax2_tx);
492 $sql .= ", localtax1_type='".$this->db->escape($this->localtax1_type)."'";
493 $sql .= ", localtax2_type='".$this->db->escape($this->localtax2_type)."'";
494 $sql .= ", rule_warning_message='".$this->db->escape($this->rule_warning_message)."'";
495 $sql .= ", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat);
496 $sql .= ", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) : 'null');
497 if ($this->fk_c_type_fees) {
498 $sql .= ", fk_c_type_fees = ".((int) $this->fk_c_type_fees);
499 } else {
500 $sql .= ", fk_c_type_fees=null";
501 }
502 if ($this->fk_project > 0) {
503 $sql .= ", fk_projet=".((int) $this->fk_project);
504 } else {
505 $sql .= ", fk_projet=null";
506 }
507 $sql .= " WHERE rowid = ".((int) ($this->rowid ? $this->rowid : $this->id));
508
509 dol_syslog("ExpenseReportLine::update");
510
511 $resql = $this->db->query($sql);
512 if ($resql) {
513 $tmpparent = new ExpenseReport($this->db);
514 $result = $tmpparent->fetch($this->fk_expensereport);
515 if ($result > 0) {
516 $result = $tmpparent->update_price(1);
517 if ($result < 0) {
518 $error++;
519 $this->error = $tmpparent->error;
520 $this->errors = $tmpparent->errors;
521 }
522 } else {
523 $error++;
524 $this->error = $tmpparent->error;
525 $this->errors = $tmpparent->errors;
526 }
527 } else {
528 $error++;
529 dol_print_error($this->db);
530 }
531
532 if (!$error && !$notrigger) {
533 // Call triggers
534 $result = $this->call_trigger('EXPENSE_REPORT_DET_MODIFY', $user);
535 if ($result < 0) {
536 $error++;
537 }
538 // End call triggers
539 }
540
541 if (!$error) {
542 $this->db->commit();
543 return 1;
544 } else {
545 $this->error = $this->db->lasterror();
546 dol_syslog("ExpenseReportLine::update Error ".$this->error, LOG_ERR);
547 $this->db->rollback();
548 return -2;
549 }
550 }
551}
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.
Class of expense report details lines.
fetch($rowid)
Fetch record for expense report detailed line.
update(User $user, $notrigger=0)
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.
Class to manage inventories.
Class to manage Dolibarr users.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted 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=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.