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 
20 use Luracast\Restler\RestException;
21 
22 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
23 require_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 
110  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = '', $sqlfilters = '', $properties = '')
111  {
112  if (!DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
113  throw new RestException(403);
114  }
115 
116  $obj_ret = array();
117 
118  // case of external user, $societe param is ignored and replaced by user's socid
119  //$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $societe;
120 
121  $sql = "SELECT t.rowid";
122  $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
123  $sql .= ' WHERE t.entity IN ('.getEntity('expensereport').')';
124  if ($user_ids) {
125  $sql .= " AND t.fk_user_author IN (".$this->db->sanitize($user_ids).")";
126  }
127 
128  // Add sql filters
129  if ($sqlfilters) {
130  $errormessage = '';
131  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
132  if ($errormessage) {
133  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
134  }
135  }
136 
137  $sql .= $this->db->order($sortfield, $sortorder);
138  if ($limit) {
139  if ($page < 0) {
140  $page = 0;
141  }
142  $offset = $limit * $page;
143 
144  $sql .= $this->db->plimit($limit + 1, $offset);
145  }
146 
147  $result = $this->db->query($sql);
148 
149  if ($result) {
150  $num = $this->db->num_rows($result);
151  $min = min($num, ($limit <= 0 ? $num : $limit));
152  $i = 0;
153  while ($i < $min) {
154  $obj = $this->db->fetch_object($result);
155  $expensereport_static = new ExpenseReport($this->db);
156  if ($expensereport_static->fetch($obj->rowid)) {
157  $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($expensereport_static), $properties);
158  }
159  $i++;
160  }
161  } else {
162  throw new RestException(503, 'Error when retrieve Expense Report list : '.$this->db->lasterror());
163  }
164 
165  return $obj_ret;
166  }
167 
174  public function post($request_data = null)
175  {
176  if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
177  throw new RestException(403, "Insuffisant rights");
178  }
179 
180  // Check mandatory fields
181  $result = $this->_validate($request_data);
182 
183  foreach ($request_data as $field => $value) {
184  if ($field === 'caller') {
185  // 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
186  $this->expensereport->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
187  continue;
188  }
189 
190  $this->expensereport->$field = $this->_checkValForAPI($field, $value, $this->expensereport);
191  }
192  /*if (isset($request_data["lines"])) {
193  $lines = array();
194  foreach ($request_data["lines"] as $line) {
195  array_push($lines, (object) $line);
196  }
197  $this->expensereport->lines = $lines;
198  }*/
199  if ($this->expensereport->create(DolibarrApiAccess::$user) < 0) {
200  throw new RestException(500, "Error creating expensereport", array_merge(array($this->expensereport->error), $this->expensereport->errors));
201  }
202 
203  return $this->expensereport->id;
204  }
205 
215  /*
216  public function getLines($id)
217  {
218  if(! DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
219  throw new RestException(403);
220  }
221 
222  $result = $this->expensereport->fetch($id);
223  if( ! $result ) {
224  throw new RestException(404, 'expensereport not found');
225  }
226 
227  if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
228  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
229  }
230  $this->expensereport->getLinesArray();
231  $result = array();
232  foreach ($this->expensereport->lines as $line) {
233  array_push($result,$this->_cleanObjectDatas($line));
234  }
235  return $result;
236  }
237  */
238 
249  /*
250  public function postLine($id, $request_data = null)
251  {
252  if(! DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
253  throw new RestException(403);
254  }
255 
256  $result = $this->expensereport->fetch($id);
257  if( ! $result ) {
258  throw new RestException(404, 'expensereport not found');
259  }
260 
261  if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
262  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
263  }
264 
265  $request_data = (object) $request_data;
266 
267  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
268  $request_data->label = sanitizeVal($request_data->label);
269 
270  $updateRes = $this->expensereport->addline(
271  $request_data->desc,
272  $request_data->subprice,
273  $request_data->qty,
274  $request_data->tva_tx,
275  $request_data->localtax1_tx,
276  $request_data->localtax2_tx,
277  $request_data->fk_product,
278  $request_data->remise_percent,
279  $request_data->info_bits,
280  $request_data->fk_remise_except,
281  'HT',
282  0,
283  $request_data->date_start,
284  $request_data->date_end,
285  $request_data->product_type,
286  $request_data->rang,
287  $request_data->special_code,
288  $fk_parent_line,
289  $request_data->fk_fournprice,
290  $request_data->pa_ht,
291  $request_data->label,
292  $request_data->array_options,
293  $request_data->fk_unit,
294  $this->element,
295  $request_data->id
296  );
297 
298  if ($updateRes > 0) {
299  return $updateRes;
300 
301  }
302  return false;
303  }
304  */
305 
317  /*
318  public function putLine($id, $lineid, $request_data = null)
319  {
320  if(! DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
321  throw new RestException(403);
322  }
323 
324  $result = $this->expensereport->fetch($id);
325  if( ! $result ) {
326  throw new RestException(404, 'expensereport not found');
327  }
328 
329  if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
330  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
331  }
332 
333  $request_data = (object) $request_data;
334 
335  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
336  $request_data->label = sanitizeVal($request_data->label);
337 
338  $updateRes = $this->expensereport->updateline(
339  $lineid,
340  $request_data->desc,
341  $request_data->subprice,
342  $request_data->qty,
343  $request_data->remise_percent,
344  $request_data->tva_tx,
345  $request_data->localtax1_tx,
346  $request_data->localtax2_tx,
347  'HT',
348  $request_data->info_bits,
349  $request_data->date_start,
350  $request_data->date_end,
351  $request_data->product_type,
352  $request_data->fk_parent_line,
353  0,
354  $request_data->fk_fournprice,
355  $request_data->pa_ht,
356  $request_data->label,
357  $request_data->special_code,
358  $request_data->array_options,
359  $request_data->fk_unit
360  );
361 
362  if ($updateRes > 0) {
363  $result = $this->get($id);
364  unset($result->line);
365  return $this->_cleanObjectDatas($result);
366  }
367  return false;
368  }
369  */
370 
381  /*
382  public function deleteLine($id, $lineid)
383  {
384  if(! DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
385  throw new RestException(403);
386  }
387 
388  $result = $this->expensereport->fetch($id);
389  if( ! $result ) {
390  throw new RestException(404, 'expensereport not found');
391  }
392 
393  if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
394  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
395  }
396 
397  // TODO Check the lineid $lineid is a line of object
398 
399  $updateRes = $this->expensereport->deleteLine($lineid);
400  if ($updateRes == 1) {
401  return $this->get($id);
402  }
403  return false;
404  }
405  */
406 
418  public function put($id, $request_data = null)
419  {
420  if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
421  throw new RestException(403);
422  }
423 
424  $result = $this->expensereport->fetch($id);
425  if (!$result) {
426  throw new RestException(404, 'expensereport not found');
427  }
428 
429  if (!DolibarrApi::_checkAccessToResource('expensereport', $this->expensereport->id)) {
430  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
431  }
432  foreach ($request_data as $field => $value) {
433  if ($field == 'id') {
434  continue;
435  }
436  if ($field === 'caller') {
437  // 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
438  $this->expensereport->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
439  continue;
440  }
441 
442  $this->expensereport->$field = $this->_checkValForAPI($field, $value, $this->expensereport);
443  }
444 
445  if ($this->expensereport->update(DolibarrApiAccess::$user) > 0) {
446  return $this->get($id);
447  } else {
448  throw new RestException(500, $this->expensereport->error);
449  }
450  }
451 
459  public function delete($id)
460  {
461  if (!DolibarrApiAccess::$user->hasRight('expensereport', 'supprimer')) {
462  throw new RestException(403);
463  }
464 
465  $result = $this->expensereport->fetch($id);
466  if (!$result) {
467  throw new RestException(404, 'Expense Report not found');
468  }
469 
470  if (!DolibarrApi::_checkAccessToResource('expensereport', $this->expensereport->id)) {
471  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
472  }
473 
474  if (!$this->expensereport->delete(DolibarrApiAccess::$user)) {
475  throw new RestException(500, 'Error when delete Expense Report : '.$this->expensereport->error);
476  }
477 
478  return array(
479  'success' => array(
480  'code' => 200,
481  'message' => 'Expense Report deleted'
482  )
483  );
484  }
485 
501  /*
502  public function validate($id, $idwarehouse=0)
503  {
504  if(! DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
505  throw new RestException(403);
506  }
507 
508  $result = $this->expensereport->fetch($id);
509  if( ! $result ) {
510  throw new RestException(404, 'expensereport not found');
511  }
512 
513  if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
514  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
515  }
516 
517  if( ! $this->expensereport->valid(DolibarrApiAccess::$user, $idwarehouse)) {
518  throw new RestException(500, 'Error when validate expensereport');
519  }
520 
521  return array(
522  'success' => array(
523  'code' => 200,
524  'message' => 'expensereport validated'
525  )
526  );
527  }*/
528 
529 
530 
544  public function getAllPayments($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0)
545  {
546  $list = array();
547 
548  if (!DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
549  throw new RestException(403);
550  }
551 
552  $sql = "SELECT t.rowid FROM " . MAIN_DB_PREFIX . "payment_expensereport as t, ".MAIN_DB_PREFIX."expensereport as e";
553  $sql .= " WHERE e.rowid = t.fk_expensereport";
554  $sql .= ' AND e.entity IN ('.getEntity('expensereport').')';
555 
556  $sql .= $this->db->order($sortfield, $sortorder);
557  if ($limit) {
558  if ($page < 0) {
559  $page = 0;
560  }
561  $offset = $limit * $page;
562 
563  $sql .= $this->db->plimit($limit + 1, $offset);
564  }
565 
566  dol_syslog("API Rest request");
567  $result = $this->db->query($sql);
568 
569  if ($result) {
570  $num = $this->db->num_rows($result);
571  $min = min($num, ($limit <= 0 ? $num : $limit));
572  for ($i = 0; $i < $min; $i++) {
573  $obj = $this->db->fetch_object($result);
574  $paymentExpenseReport = new PaymentExpenseReport($this->db);
575  if ($paymentExpenseReport->fetch($obj->rowid) > 0) {
576  $list[] = $this->_cleanObjectDatas($paymentExpenseReport);
577  }
578  }
579  } else {
580  throw new RestException(503, 'Error when retrieving list of paymentexpensereport: ' . $this->db->lasterror());
581  }
582 
583  return $list;
584  }
585 
596  public function getPayments($pid)
597  {
598  if (!DolibarrApiAccess::$user->hasRight('expensereport', 'lire')) {
599  throw new RestException(403);
600  }
601 
602  $paymentExpenseReport = new PaymentExpenseReport($this->db);
603  $result = $paymentExpenseReport->fetch($pid);
604  if (!$result) {
605  throw new RestException(404, 'paymentExpenseReport not found');
606  }
607 
608  return $this->_cleanObjectDatas($paymentExpenseReport);
609  }
610 
620  public function addPayment($id, $request_data = null)
621  {
622  if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
623  throw new RestException(403);
624  }
625  // Check mandatory fields
626  $result = $this->_validatepayment($request_data);
627 
628  $paymentExpenseReport = new PaymentExpenseReport($this->db);
629  $paymentExpenseReport->fk_expensereport = $id;
630  foreach ($request_data as $field => $value) {
631  $paymentExpenseReport->$field = $this->_checkValForAPI($field, $value, $paymentExpenseReport);
632  }
633 
634  if ($paymentExpenseReport->create(DolibarrApiAccess::$user) < 0) {
635  throw new RestException(500, 'Error creating paymentExpenseReport', array_merge(array($paymentExpenseReport->error), $paymentExpenseReport->errors));
636  }
637  if (isModEnabled("bank")) {
638  $paymentExpenseReport->addPaymentToBank(
639  DolibarrApiAccess::$user,
640  'payment_expensereport',
641  '(ExpenseReportPayment)',
642  (int) $request_data['accountid'],
643  '',
644  ''
645  );
646  }
647 
648  return $paymentExpenseReport->id;
649  }
650 
660  public function updatePayment($id, $request_data = null)
661  {
662  if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer')) {
663  throw new RestException(403);
664  }
665 
666  $paymentExpenseReport = new PaymentExpenseReport($this->db);
667  $result = $paymentExpenseReport->fetch($id);
668  if (!$result) {
669  throw new RestException(404, 'payment of expense report not found');
670  }
671 
672  foreach ($request_data as $field => $value) {
673  if ($field == 'id') {
674  continue;
675  }
676  $paymentExpenseReport->$field = $this->_checkValForAPI($field, $value, $paymentExpenseReport);
677  }
678 
679  if ($paymentExpenseReport->update(DolibarrApiAccess::$user) > 0) {
680  return $this->get($id);
681  } else {
682  throw new RestException(500, $paymentExpenseReport->error);
683  }
684  }
685 
694  /*public function delete($id)
695  {
696  if (!DolibarrApiAccess::$user->hasRight('expensereport', 'creer') {
697  throw new RestException(403);
698  }
699  $paymentExpenseReport = new PaymentExpenseReport($this->db);
700  $result = $paymentExpenseReport->fetch($id);
701  if (!$result) {
702  throw new RestException(404, 'paymentExpenseReport not found');
703  }
704 
705  if ($paymentExpenseReport->delete(DolibarrApiAccess::$user) < 0) {
706  throw new RestException(403, 'error when deleting paymentExpenseReport');
707  }
708 
709  return array(
710  'success' => array(
711  'code' => 200,
712  'message' => 'paymentExpenseReport deleted'
713  )
714  );
715  }*/
716 
717 
718 
719  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
726  protected function _cleanObjectDatas($object)
727  {
728  // phpcs:enable
729  $object = parent::_cleanObjectDatas($object);
730 
731  unset($object->fk_statut);
732  unset($object->statut);
733  unset($object->user);
734  unset($object->thirdparty);
735 
736  unset($object->cond_reglement);
737  unset($object->shipping_method_id);
738 
739  unset($object->barcode_type);
740  unset($object->barcode_type_code);
741  unset($object->barcode_type_label);
742  unset($object->barcode_type_coder);
743 
744  unset($object->code_paiement);
745  unset($object->code_statut);
746  unset($object->fk_c_paiement);
747  unset($object->fk_incoterms);
748  unset($object->label_incoterms);
749  unset($object->location_incoterms);
750  unset($object->mode_reglement_id);
751  unset($object->cond_reglement_id);
752 
753  unset($object->name);
754  unset($object->lastname);
755  unset($object->firstname);
756  unset($object->civility_id);
757  unset($object->cond_reglement_id);
758  unset($object->contact);
759  unset($object->contact_id);
760 
761  unset($object->state);
762  unset($object->state_id);
763  unset($object->state_code);
764  unset($object->country);
765  unset($object->country_id);
766  unset($object->country_code);
767 
768  unset($object->note); // We already use note_public and note_pricate
769 
770  return $object;
771  }
772 
780  private function _validate($data)
781  {
782  $expensereport = array();
783  foreach (ExpenseReports::$FIELDS as $field) {
784  if (!isset($data[$field])) {
785  throw new RestException(400, "$field field missing");
786  }
787  $expensereport[$field] = $data[$field];
788  }
789  return $expensereport;
790  }
791 
799  private function _validatepayment($data)
800  {
801  $expensereport = array();
802  foreach (ExpenseReports::$FIELDSPAYMENT as $field) {
803  if (!isset($data[$field])) {
804  throw new RestException(400, "$field field missing");
805  }
806  $expensereport[$field] = $data[$field];
807  }
808  return $expensereport;
809  }
810 }
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.
Definition: api.class.php:136
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
Check access by user to a given resource.
Definition: api.class.php:369
_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.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $user_ids='', $sqlfilters='', $properties='')
List Expense Reports.
_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.
Class to manage payments of expense report.
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:751
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.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.