dolibarr 21.0.3
api_expensereports.class.php
1<?php
2/* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
3 * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2020-2024 Frédéric France <frederic.france@free.fr>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20use Luracast\Restler\RestException;
21
22require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
23require_once DOL_DOCUMENT_ROOT.'/expensereport/class/paymentexpensereport.class.php';
24
25
33{
37 public static $FIELDS = array(
38 'fk_user_author'
39 );
40
44 public static $FIELDSPAYMENT = array(
45 "fk_typepayment",
46 'datepaid',
47 'amounts',
48 );
49
53 public $expensereport;
54
55
59 public function __construct()
60 {
61 global $db;
62
63 $this->db = $db;
64 $this->expensereport = new ExpenseReport($this->db);
65 }
66
77 public function get($id)
78 {
79 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
80 throw new RestException(403);
81 }
82
83 $result = $this->expensereport->fetch($id);
84 if (!$result) {
85 throw new RestException(404, 'Expense report not found');
86 }
87
88 if (!DolibarrApi::_checkAccessToResource('expensereport', $this->expensereport->id)) {
89 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
90 }
91
92 $this->expensereport->fetchObjectLinked();
93 return $this->_cleanObjectDatas($this->expensereport);
94 }
95
111 public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = '', $sqlfilters = '', $properties = '', $pagination_data = false)
112 {
113 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
114 throw new RestException(403);
115 }
116
117 $obj_ret = array();
118
119 // case of external user, $societe param is ignored and replaced by user's socid
120 //$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $societe;
121
122 $sql = "SELECT t.rowid";
123 $sql .= " FROM ".MAIN_DB_PREFIX."expensereport AS t LEFT JOIN ".MAIN_DB_PREFIX."expensereport_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call, so we will be able to filter on extrafields
124 $sql .= ' WHERE t.entity IN ('.getEntity('expensereport').')';
125 if ($user_ids) {
126 $sql .= " AND t.fk_user_author IN (".$this->db->sanitize($user_ids).")";
127 }
128
129 // Add sql filters
130 if ($sqlfilters) {
131 $errormessage = '';
132 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
133 if ($errormessage) {
134 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
135 }
136 }
137
138 //this query will return total orders with the filters given
139 $sqlTotals = str_replace('SELECT t.rowid', 'SELECT count(t.rowid) as total', $sql);
140
141 $sql .= $this->db->order($sortfield, $sortorder);
142 if ($limit) {
143 if ($page < 0) {
144 $page = 0;
145 }
146 $offset = $limit * $page;
147
148 $sql .= $this->db->plimit($limit + 1, $offset);
149 }
150
151 $result = $this->db->query($sql);
152
153 if ($result) {
154 $num = $this->db->num_rows($result);
155 $min = min($num, ($limit <= 0 ? $num : $limit));
156 $i = 0;
157 while ($i < $min) {
158 $obj = $this->db->fetch_object($result);
159 $expensereport_static = new ExpenseReport($this->db);
160 if ($expensereport_static->fetch($obj->rowid)) {
161 $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($expensereport_static), $properties);
162 }
163 $i++;
164 }
165 } else {
166 throw new RestException(503, 'Error when retrieve Expense Report list : '.$this->db->lasterror());
167 }
168
169 //if $pagination_data is true the response will contain element data with all values and element pagination with pagination data(total,page,limit)
170 if ($pagination_data) {
171 $totalsResult = $this->db->query($sqlTotals);
172 $total = $this->db->fetch_object($totalsResult)->total;
173
174 $tmp = $obj_ret;
175 $obj_ret = [];
176
177 $obj_ret['data'] = $tmp;
178 $obj_ret['pagination'] = [
179 'total' => (int) $total,
180 'page' => $page, //count starts from 0
181 'page_count' => ceil((int) $total / $limit),
182 'limit' => $limit
183 ];
184 }
185
186 return $obj_ret;
187 }
188
195 public function post($request_data = null)
196 {
197 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
198 throw new RestException(403, "Insuffisant rights");
199 }
200
201 // Check mandatory fields
202 $result = $this->_validate($request_data);
203
204 foreach ($request_data as $field => $value) {
205 if ($field === 'caller') {
206 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
207 $this->expensereport->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
208 continue;
209 }
210
211 $this->expensereport->$field = $this->_checkValForAPI($field, $value, $this->expensereport);
212 }
213 /*if (isset($request_data["lines"])) {
214 $lines = array();
215 foreach ($request_data["lines"] as $line) {
216 array_push($lines, (object) $line);
217 }
218 $this->expensereport->lines = $lines;
219 }*/
220 if ($this->expensereport->create(DolibarrApiAccess::$user) < 0) {
221 throw new RestException(500, "Error creating expensereport", array_merge(array($this->expensereport->error), $this->expensereport->errors));
222 }
223
224 return $this->expensereport->id;
225 }
226
236 /*
237 public function getLines($id)
238 {
239 if(! DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
240 throw new RestException(403);
241 }
242
243 $result = $this->expensereport->fetch($id);
244 if( ! $result ) {
245 throw new RestException(404, 'expensereport not found');
246 }
247
248 if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
249 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
250 }
251 $this->expensereport->getLinesArray();
252 $result = array();
253 foreach ($this->expensereport->lines as $line) {
254 array_push($result,$this->_cleanObjectDatas($line));
255 }
256 return $result;
257 }
258 */
259
270 /*
271 public function postLine($id, $request_data = null)
272 {
273 if(! DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
274 throw new RestException(403);
275 }
276
277 $result = $this->expensereport->fetch($id);
278 if( ! $result ) {
279 throw new RestException(404, 'expensereport not found');
280 }
281
282 if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
283 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
284 }
285
286 $request_data = (object) $request_data;
287
288 $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
289 $request_data->label = sanitizeVal($request_data->label);
290
291 $updateRes = $this->expensereport->addline(
292 $request_data->desc,
293 $request_data->subprice,
294 $request_data->qty,
295 $request_data->tva_tx,
296 $request_data->localtax1_tx,
297 $request_data->localtax2_tx,
298 $request_data->fk_product,
299 $request_data->remise_percent,
300 $request_data->info_bits,
301 $request_data->fk_remise_except,
302 'HT',
303 0,
304 $request_data->date_start,
305 $request_data->date_end,
306 $request_data->product_type,
307 $request_data->rang,
308 $request_data->special_code,
309 $fk_parent_line,
310 $request_data->fk_fournprice,
311 $request_data->pa_ht,
312 $request_data->label,
313 $request_data->array_options,
314 $request_data->fk_unit,
315 $this->element,
316 $request_data->id
317 );
318
319 if ($updateRes > 0) {
320 return $updateRes;
321
322 }
323 return false;
324 }
325 */
326
338 /*
339 public function putLine($id, $lineid, $request_data = null)
340 {
341 if(! DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
342 throw new RestException(403);
343 }
344
345 $result = $this->expensereport->fetch($id);
346 if( ! $result ) {
347 throw new RestException(404, 'expensereport not found');
348 }
349
350 if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
351 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
352 }
353
354 $request_data = (object) $request_data;
355
356 $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
357 $request_data->label = sanitizeVal($request_data->label);
358
359 $updateRes = $this->expensereport->updateline(
360 $lineid,
361 $request_data->desc,
362 $request_data->subprice,
363 $request_data->qty,
364 $request_data->remise_percent,
365 $request_data->tva_tx,
366 $request_data->localtax1_tx,
367 $request_data->localtax2_tx,
368 'HT',
369 $request_data->info_bits,
370 $request_data->date_start,
371 $request_data->date_end,
372 $request_data->product_type,
373 $request_data->fk_parent_line,
374 0,
375 $request_data->fk_fournprice,
376 $request_data->pa_ht,
377 $request_data->label,
378 $request_data->special_code,
379 $request_data->array_options,
380 $request_data->fk_unit
381 );
382
383 if ($updateRes > 0) {
384 $result = $this->get($id);
385 unset($result->line);
386 return $this->_cleanObjectDatas($result);
387 }
388 return false;
389 }
390 */
391
402 /*
403 public function deleteLine($id, $lineid)
404 {
405 if(! DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
406 throw new RestException(403);
407 }
408
409 $result = $this->expensereport->fetch($id);
410 if( ! $result ) {
411 throw new RestException(404, 'expensereport not found');
412 }
413
414 if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
415 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
416 }
417
418 // TODO Check the lineid $lineid is a line of object
419
420 $updateRes = $this->expensereport->deleteLine($lineid);
421 if ($updateRes == 1) {
422 return $this->get($id);
423 }
424 return false;
425 }
426 */
427
439 public function put($id, $request_data = null)
440 {
441 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
442 throw new RestException(403);
443 }
444
445 $result = $this->expensereport->fetch($id);
446 if (!$result) {
447 throw new RestException(404, 'expensereport not found');
448 }
449
450 if (!DolibarrApi::_checkAccessToResource('expensereport', $this->expensereport->id)) {
451 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
452 }
453 foreach ($request_data as $field => $value) {
454 if ($field == 'id') {
455 continue;
456 }
457 if ($field === 'caller') {
458 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
459 $this->expensereport->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
460 continue;
461 }
462
463 if ($field == 'array_options' && is_array($value)) {
464 foreach ($value as $index => $val) {
465 $this->expensereport->array_options[$index] = $this->_checkValForAPI($field, $val, $this->expensereport);
466 }
467 continue;
468 }
469
470 $this->expensereport->$field = $this->_checkValForAPI($field, $value, $this->expensereport);
471 }
472
473 if ($this->expensereport->update(DolibarrApiAccess::$user) > 0) {
474 return $this->get($id);
475 } else {
476 throw new RestException(500, $this->expensereport->error);
477 }
478 }
479
487 public function delete($id)
488 {
489 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'supprimer')) {
490 throw new RestException(403);
491 }
492
493 $result = $this->expensereport->fetch($id);
494 if (!$result) {
495 throw new RestException(404, 'Expense Report not found');
496 }
497
498 if (!DolibarrApi::_checkAccessToResource('expensereport', $this->expensereport->id)) {
499 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
500 }
501
502 if (!$this->expensereport->delete(DolibarrApiAccess::$user)) {
503 throw new RestException(500, 'Error when delete Expense Report : '.$this->expensereport->error);
504 }
505
506 return array(
507 'success' => array(
508 'code' => 200,
509 'message' => 'Expense Report deleted'
510 )
511 );
512 }
513
529 /*
530 public function validate($id, $idwarehouse=0)
531 {
532 if(! DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
533 throw new RestException(403);
534 }
535
536 $result = $this->expensereport->fetch($id);
537 if( ! $result ) {
538 throw new RestException(404, 'expensereport not found');
539 }
540
541 if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
542 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
543 }
544
545 if( ! $this->expensereport->valid(DolibarrApiAccess::$user, $idwarehouse)) {
546 throw new RestException(500, 'Error when validate expensereport');
547 }
548
549 return array(
550 'success' => array(
551 'code' => 200,
552 'message' => 'expensereport validated'
553 )
554 );
555 }*/
556
557
558
572 public function getAllPayments($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0)
573 {
574 $list = array();
575
576 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
577 throw new RestException(403);
578 }
579
580 $sql = "SELECT t.rowid FROM " . MAIN_DB_PREFIX . "payment_expensereport as t, ".MAIN_DB_PREFIX."expensereport as e";
581 $sql .= " WHERE e.rowid = t.fk_expensereport";
582 $sql .= ' AND e.entity IN ('.getEntity('expensereport').')';
583
584 $sql .= $this->db->order($sortfield, $sortorder);
585 if ($limit) {
586 if ($page < 0) {
587 $page = 0;
588 }
589 $offset = $limit * $page;
590
591 $sql .= $this->db->plimit($limit + 1, $offset);
592 }
593
594 dol_syslog("API Rest request");
595 $result = $this->db->query($sql);
596
597 if ($result) {
598 $num = $this->db->num_rows($result);
599 $min = min($num, ($limit <= 0 ? $num : $limit));
600 for ($i = 0; $i < $min; $i++) {
601 $obj = $this->db->fetch_object($result);
602 $paymentExpenseReport = new PaymentExpenseReport($this->db);
603 if ($paymentExpenseReport->fetch($obj->rowid) > 0) {
604 $list[] = $this->_cleanObjectDatas($paymentExpenseReport);
605 }
606 }
607 } else {
608 throw new RestException(503, 'Error when retrieving list of paymentexpensereport: ' . $this->db->lasterror());
609 }
610
611 return $list;
612 }
613
624 public function getPayments($pid)
625 {
626 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
627 throw new RestException(403);
628 }
629
630 $paymentExpenseReport = new PaymentExpenseReport($this->db);
631 $result = $paymentExpenseReport->fetch($pid);
632 if (!$result) {
633 throw new RestException(404, 'paymentExpenseReport not found');
634 }
635
636 return $this->_cleanObjectDatas($paymentExpenseReport);
637 }
638
648 public function addPayment($id, $request_data = null)
649 {
650 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
651 throw new RestException(403);
652 }
653 // Check mandatory fields
654 $result = $this->_validatepayment($request_data);
655
656 $paymentExpenseReport = new PaymentExpenseReport($this->db);
657 $paymentExpenseReport->fk_expensereport = $id;
658 foreach ($request_data as $field => $value) {
659 $paymentExpenseReport->$field = $this->_checkValForAPI($field, $value, $paymentExpenseReport);
660 }
661
662 if ($paymentExpenseReport->create(DolibarrApiAccess::$user) < 0) {
663 throw new RestException(500, 'Error creating paymentExpenseReport', array_merge(array($paymentExpenseReport->error), $paymentExpenseReport->errors));
664 }
665 if (isModEnabled("bank")) {
666 $paymentExpenseReport->addPaymentToBank(
667 DolibarrApiAccess::$user,
668 'payment_expensereport',
669 '(ExpenseReportPayment)',
670 (int) $request_data['accountid'],
671 '',
672 ''
673 );
674 }
675
676 return $paymentExpenseReport->id;
677 }
678
688 public function updatePayment($id, $request_data = null)
689 {
690 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
691 throw new RestException(403);
692 }
693
694 $paymentExpenseReport = new PaymentExpenseReport($this->db);
695 $result = $paymentExpenseReport->fetch($id);
696 if (!$result) {
697 throw new RestException(404, 'payment of expense report not found');
698 }
699
700 foreach ($request_data as $field => $value) {
701 if ($field == 'id') {
702 continue;
703 }
704 $paymentExpenseReport->$field = $this->_checkValForAPI($field, $value, $paymentExpenseReport);
705 }
706
707 if ($paymentExpenseReport->update(DolibarrApiAccess::$user) > 0) {
708 return $this->get($id);
709 } else {
710 throw new RestException(500, $paymentExpenseReport->error);
711 }
712 }
713
722 /*public function delete($id)
723 {
724 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer') {
725 throw new RestException(403);
726 }
727 $paymentExpenseReport = new PaymentExpenseReport($this->db);
728 $result = $paymentExpenseReport->fetch($id);
729 if (!$result) {
730 throw new RestException(404, 'paymentExpenseReport not found');
731 }
732
733 if ($paymentExpenseReport->delete(DolibarrApiAccess::$user) < 0) {
734 throw new RestException(403, 'error when deleting paymentExpenseReport');
735 }
736
737 return array(
738 'success' => array(
739 'code' => 200,
740 'message' => 'paymentExpenseReport deleted'
741 )
742 );
743 }*/
744
745
746
747 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
754 protected function _cleanObjectDatas($object)
755 {
756 // phpcs:enable
757 $object = parent::_cleanObjectDatas($object);
758
759 unset($object->fk_statut);
760 unset($object->statut);
761 unset($object->user);
762 unset($object->thirdparty);
763
764 unset($object->cond_reglement);
765 unset($object->shipping_method_id);
766
767 unset($object->barcode_type);
768 unset($object->barcode_type_code);
769 unset($object->barcode_type_label);
770 unset($object->barcode_type_coder);
771
772 unset($object->code_paiement);
773 unset($object->code_statut);
774 unset($object->fk_c_paiement);
775 unset($object->fk_incoterms);
776 unset($object->label_incoterms);
777 unset($object->location_incoterms);
778 unset($object->mode_reglement_id);
779 unset($object->cond_reglement_id);
780
781 unset($object->name);
782 unset($object->lastname);
783 unset($object->firstname);
784 unset($object->civility_id);
785 unset($object->cond_reglement_id);
786 unset($object->contact);
787 unset($object->contact_id);
788
789 unset($object->state);
790 unset($object->state_id);
791 unset($object->state_code);
792 unset($object->country);
793 unset($object->country_id);
794 unset($object->country_code);
795
796 unset($object->note); // We already use note_public and note_pricate
797
798 return $object;
799 }
800
808 private function _validate($data)
809 {
810 $expensereport = array();
811 foreach (ExpenseReports::$FIELDS as $field) {
812 if (!isset($data[$field])) {
813 throw new RestException(400, "$field field missing");
814 }
815 $expensereport[$field] = $data[$field];
816 }
817 return $expensereport;
818 }
819
827 private function _validatepayment($data)
828 {
829 $expensereport = array();
830 foreach (ExpenseReports::$FIELDSPAYMENT as $field) {
831 if (!isset($data[$field])) {
832 throw new RestException(400, "$field field missing");
833 }
834 $expensereport[$field] = $data[$field];
835 }
836 return $expensereport;
837 }
838}
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
Class for API REST v1.
Definition api.class.php:31
_filterObjectProperties($object, $properties)
Filter properties that will be returned on object.
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
Check access by user to a given resource.
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
Definition api.class.php:83
Class to manage Trips and Expenses.
getPayments($pid)
Get a given payment.
_cleanObjectDatas($object)
Delete paymentExpenseReport.
_validate($data)
Validate fields before create or update object.
updatePayment($id, $request_data=null)
Update a payment of ExpenseReport.
put($id, $request_data=null)
Get lines of an Expense Report.
addPayment($id, $request_data=null)
Create payment of ExpenseReport.
getAllPayments($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0)
Validate an Expense Report.
post($request_data=null)
Create Expense Report object.
_validatepayment($data)
Validate fields before create or update object.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $user_ids='', $sqlfilters='', $properties='', $pagination_data=false)
List Expense Reports.
Class to manage payments of expense report.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.