dolibarr 21.0.0-alpha
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 $this->expensereport->$field = $this->_checkValForAPI($field, $value, $this->expensereport);
464 }
465
466 if ($this->expensereport->update(DolibarrApiAccess::$user) > 0) {
467 return $this->get($id);
468 } else {
469 throw new RestException(500, $this->expensereport->error);
470 }
471 }
472
480 public function delete($id)
481 {
482 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'supprimer')) {
483 throw new RestException(403);
484 }
485
486 $result = $this->expensereport->fetch($id);
487 if (!$result) {
488 throw new RestException(404, 'Expense Report not found');
489 }
490
491 if (!DolibarrApi::_checkAccessToResource('expensereport', $this->expensereport->id)) {
492 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
493 }
494
495 if (!$this->expensereport->delete(DolibarrApiAccess::$user)) {
496 throw new RestException(500, 'Error when delete Expense Report : '.$this->expensereport->error);
497 }
498
499 return array(
500 'success' => array(
501 'code' => 200,
502 'message' => 'Expense Report deleted'
503 )
504 );
505 }
506
522 /*
523 public function validate($id, $idwarehouse=0)
524 {
525 if(! DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
526 throw new RestException(403);
527 }
528
529 $result = $this->expensereport->fetch($id);
530 if( ! $result ) {
531 throw new RestException(404, 'expensereport not found');
532 }
533
534 if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
535 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
536 }
537
538 if( ! $this->expensereport->valid(DolibarrApiAccess::$user, $idwarehouse)) {
539 throw new RestException(500, 'Error when validate expensereport');
540 }
541
542 return array(
543 'success' => array(
544 'code' => 200,
545 'message' => 'expensereport validated'
546 )
547 );
548 }*/
549
550
551
565 public function getAllPayments($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0)
566 {
567 $list = array();
568
569 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
570 throw new RestException(403);
571 }
572
573 $sql = "SELECT t.rowid FROM " . MAIN_DB_PREFIX . "payment_expensereport as t, ".MAIN_DB_PREFIX."expensereport as e";
574 $sql .= " WHERE e.rowid = t.fk_expensereport";
575 $sql .= ' AND e.entity IN ('.getEntity('expensereport').')';
576
577 $sql .= $this->db->order($sortfield, $sortorder);
578 if ($limit) {
579 if ($page < 0) {
580 $page = 0;
581 }
582 $offset = $limit * $page;
583
584 $sql .= $this->db->plimit($limit + 1, $offset);
585 }
586
587 dol_syslog("API Rest request");
588 $result = $this->db->query($sql);
589
590 if ($result) {
591 $num = $this->db->num_rows($result);
592 $min = min($num, ($limit <= 0 ? $num : $limit));
593 for ($i = 0; $i < $min; $i++) {
594 $obj = $this->db->fetch_object($result);
595 $paymentExpenseReport = new PaymentExpenseReport($this->db);
596 if ($paymentExpenseReport->fetch($obj->rowid) > 0) {
597 $list[] = $this->_cleanObjectDatas($paymentExpenseReport);
598 }
599 }
600 } else {
601 throw new RestException(503, 'Error when retrieving list of paymentexpensereport: ' . $this->db->lasterror());
602 }
603
604 return $list;
605 }
606
617 public function getPayments($pid)
618 {
619 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
620 throw new RestException(403);
621 }
622
623 $paymentExpenseReport = new PaymentExpenseReport($this->db);
624 $result = $paymentExpenseReport->fetch($pid);
625 if (!$result) {
626 throw new RestException(404, 'paymentExpenseReport not found');
627 }
628
629 return $this->_cleanObjectDatas($paymentExpenseReport);
630 }
631
641 public function addPayment($id, $request_data = null)
642 {
643 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
644 throw new RestException(403);
645 }
646 // Check mandatory fields
647 $result = $this->_validatepayment($request_data);
648
649 $paymentExpenseReport = new PaymentExpenseReport($this->db);
650 $paymentExpenseReport->fk_expensereport = $id;
651 foreach ($request_data as $field => $value) {
652 $paymentExpenseReport->$field = $this->_checkValForAPI($field, $value, $paymentExpenseReport);
653 }
654
655 if ($paymentExpenseReport->create(DolibarrApiAccess::$user) < 0) {
656 throw new RestException(500, 'Error creating paymentExpenseReport', array_merge(array($paymentExpenseReport->error), $paymentExpenseReport->errors));
657 }
658 if (isModEnabled("bank")) {
659 $paymentExpenseReport->addPaymentToBank(
660 DolibarrApiAccess::$user,
661 'payment_expensereport',
662 '(ExpenseReportPayment)',
663 (int) $request_data['accountid'],
664 '',
665 ''
666 );
667 }
668
669 return $paymentExpenseReport->id;
670 }
671
681 public function updatePayment($id, $request_data = null)
682 {
683 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
684 throw new RestException(403);
685 }
686
687 $paymentExpenseReport = new PaymentExpenseReport($this->db);
688 $result = $paymentExpenseReport->fetch($id);
689 if (!$result) {
690 throw new RestException(404, 'payment of expense report not found');
691 }
692
693 foreach ($request_data as $field => $value) {
694 if ($field == 'id') {
695 continue;
696 }
697 $paymentExpenseReport->$field = $this->_checkValForAPI($field, $value, $paymentExpenseReport);
698 }
699
700 if ($paymentExpenseReport->update(DolibarrApiAccess::$user) > 0) {
701 return $this->get($id);
702 } else {
703 throw new RestException(500, $paymentExpenseReport->error);
704 }
705 }
706
715 /*public function delete($id)
716 {
717 if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer') {
718 throw new RestException(403);
719 }
720 $paymentExpenseReport = new PaymentExpenseReport($this->db);
721 $result = $paymentExpenseReport->fetch($id);
722 if (!$result) {
723 throw new RestException(404, 'paymentExpenseReport not found');
724 }
725
726 if ($paymentExpenseReport->delete(DolibarrApiAccess::$user) < 0) {
727 throw new RestException(403, 'error when deleting paymentExpenseReport');
728 }
729
730 return array(
731 'success' => array(
732 'code' => 200,
733 'message' => 'paymentExpenseReport deleted'
734 )
735 );
736 }*/
737
738
739
740 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
747 protected function _cleanObjectDatas($object)
748 {
749 // phpcs:enable
750 $object = parent::_cleanObjectDatas($object);
751
752 unset($object->fk_statut);
753 unset($object->statut);
754 unset($object->user);
755 unset($object->thirdparty);
756
757 unset($object->cond_reglement);
758 unset($object->shipping_method_id);
759
760 unset($object->barcode_type);
761 unset($object->barcode_type_code);
762 unset($object->barcode_type_label);
763 unset($object->barcode_type_coder);
764
765 unset($object->code_paiement);
766 unset($object->code_statut);
767 unset($object->fk_c_paiement);
768 unset($object->fk_incoterms);
769 unset($object->label_incoterms);
770 unset($object->location_incoterms);
771 unset($object->mode_reglement_id);
772 unset($object->cond_reglement_id);
773
774 unset($object->name);
775 unset($object->lastname);
776 unset($object->firstname);
777 unset($object->civility_id);
778 unset($object->cond_reglement_id);
779 unset($object->contact);
780 unset($object->contact_id);
781
782 unset($object->state);
783 unset($object->state_id);
784 unset($object->state_code);
785 unset($object->country);
786 unset($object->country_id);
787 unset($object->country_code);
788
789 unset($object->note); // We already use note_public and note_pricate
790
791 return $object;
792 }
793
801 private function _validate($data)
802 {
803 $expensereport = array();
804 foreach (ExpenseReports::$FIELDS as $field) {
805 if (!isset($data[$field])) {
806 throw new RestException(400, "$field field missing");
807 }
808 $expensereport[$field] = $data[$field];
809 }
810 return $expensereport;
811 }
812
820 private function _validatepayment($data)
821 {
822 $expensereport = array();
823 foreach (ExpenseReports::$FIELDSPAYMENT as $field) {
824 if (!isset($data[$field])) {
825 throw new RestException(400, "$field field missing");
826 }
827 $expensereport[$field] = $data[$field];
828 }
829 return $expensereport;
830 }
831}
$id
Definition account.php:39
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
Class for API REST v1.
Definition api.class.php:30
_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:82
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.