dolibarr  21.0.0-alpha
api_proposals.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 Thibault FOUCART <support@ptibogxiv.net>
5  * Copyright (C) 2022 ATM Consulting <contact@atm-consulting.fr>
6  * Copyright (C) 2022 OpenDSI <support@open-dsi.fr>
7  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  */
22 
23 use Luracast\Restler\RestException;
24 
25 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
26 
27 
34 class Proposals extends DolibarrApi
35 {
39  public static $FIELDS = array(
40  'socid'
41  );
42 
46  public $propal;
47 
51  public function __construct()
52  {
53  global $db;
54  $this->db = $db;
55  $this->propal = new Propal($this->db);
56  }
57 
69  public function get($id, $contact_list = 1)
70  {
71  return $this->_fetch($id, '', '', $contact_list);
72  }
73 
87  public function getByRef($ref, $contact_list = 1)
88  {
89  return $this->_fetch('', $ref, '', $contact_list);
90  }
91 
105  public function getByRefExt($ref_ext, $contact_list = 1)
106  {
107  return $this->_fetch('', '', $ref_ext, $contact_list);
108  }
109 
123  private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1)
124  {
125  if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
126  throw new RestException(403);
127  }
128 
129  $result = $this->propal->fetch($id, $ref, $ref_ext);
130  if (!$result) {
131  throw new RestException(404, 'Commercial Proposal not found');
132  }
133 
134  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
135  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
136  }
137 
138  // Add external contacts ids.
139  $tmparray = $this->propal->liste_contact(-1, 'external', $contact_list);
140  if (is_array($tmparray)) {
141  $this->propal->contacts_ids = $tmparray;
142  }
143 
144  $this->propal->fetchObjectLinked();
145 
146  return $this->_cleanObjectDatas($this->propal);
147  }
148 
163  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '', $properties = '')
164  {
165  if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
166  throw new RestException(403);
167  }
168 
169  $obj_ret = array();
170 
171  // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
172  $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids;
173 
174  // If the internal user must only see his customers, force searching by him
175  $search_sale = 0;
176  if (!DolibarrApiAccess::$user->hasRight('societe', 'client', 'voir') && !$socids) {
177  $search_sale = DolibarrApiAccess::$user->id;
178  }
179 
180  $sql = "SELECT t.rowid";
181  $sql .= " FROM ".MAIN_DB_PREFIX."propal AS t";
182  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."propal_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
183  $sql .= ' WHERE t.entity IN ('.getEntity('propal').')';
184  if ($socids) {
185  $sql .= " AND t.fk_soc IN (".$this->db->sanitize($socids).")";
186  }
187  // Search on sale representative
188  if ($search_sale && $search_sale != '-1') {
189  if ($search_sale == -2) {
190  $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc)";
191  } elseif ($search_sale > 0) {
192  $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc AND sc.fk_user = ".((int) $search_sale).")";
193  }
194  }
195  // Add sql filters
196  if ($sqlfilters) {
197  $errormessage = '';
198  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
199  if ($errormessage) {
200  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
201  }
202  }
203 
204  $sql .= $this->db->order($sortfield, $sortorder);
205  if ($limit) {
206  if ($page < 0) {
207  $page = 0;
208  }
209  $offset = $limit * $page;
210 
211  $sql .= $this->db->plimit($limit + 1, $offset);
212  }
213 
214  dol_syslog("API Rest request");
215  $result = $this->db->query($sql);
216 
217  if ($result) {
218  $num = $this->db->num_rows($result);
219  $min = min($num, ($limit <= 0 ? $num : $limit));
220  $i = 0;
221  while ($i < $min) {
222  $obj = $this->db->fetch_object($result);
223  $proposal_static = new Propal($this->db);
224  if ($proposal_static->fetch($obj->rowid)) {
225  // Add external contacts ids
226  $tmparray = $proposal_static->liste_contact(-1, 'external', 1);
227  if (is_array($tmparray)) {
228  $proposal_static->contacts_ids = $tmparray;
229  }
230  $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($proposal_static), $properties);
231  }
232  $i++;
233  }
234  } else {
235  throw new RestException(503, 'Error when retrieve propal list : '.$this->db->lasterror());
236  }
237 
238  return $obj_ret;
239  }
240 
247  public function post($request_data = null)
248  {
249  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
250  throw new RestException(403, "Insuffisant rights");
251  }
252  // Check mandatory fields
253  $result = $this->_validate($request_data);
254 
255  foreach ($request_data as $field => $value) {
256  if ($field === 'caller') {
257  // 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
258  $this->propal->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
259  continue;
260  }
261 
262  $this->propal->$field = $this->_checkValForAPI($field, $value, $this->propal);
263  }
264  /*if (isset($request_data["lines"])) {
265  $lines = array();
266  foreach ($request_data["lines"] as $line) {
267  array_push($lines, (object) $line);
268  }
269  $this->propal->lines = $lines;
270  }*/
271  if ($this->propal->create(DolibarrApiAccess::$user) < 0) {
272  throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors));
273  }
274 
275  return ((int) $this->propal->id);
276  }
277 
288  public function getLines($id, $sqlfilters = '')
289  {
290  if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
291  throw new RestException(403);
292  }
293 
294  $result = $this->propal->fetch($id);
295  if (!$result) {
296  throw new RestException(404, 'Commercial Proposal not found');
297  }
298 
299  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
300  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
301  }
302 
303  $sql = '';
304  if (!empty($sqlfilters)) {
305  $errormessage = '';
306  $sql = forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
307  if ($errormessage) {
308  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
309  }
310  }
311 
312  $this->propal->getLinesArray($sql);
313  $result = array();
314  foreach ($this->propal->lines as $line) {
315  array_push($result, $this->_cleanObjectDatas($line));
316  }
317  return $result;
318  }
319 
330  public function postLine($id, $request_data = null)
331  {
332  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
333  throw new RestException(403);
334  }
335 
336  $result = $this->propal->fetch($id);
337  if (!$result) {
338  throw new RestException(404, 'Commercial Proposal not found');
339  }
340 
341  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
342  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
343  }
344 
345  $request_data = (object) $request_data;
346 
347  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
348  $request_data->label = sanitizeVal($request_data->label);
349 
350  $updateRes = $this->propal->addline(
351  $request_data->desc,
352  $request_data->subprice,
353  $request_data->qty,
354  $request_data->tva_tx,
355  $request_data->localtax1_tx,
356  $request_data->localtax2_tx,
357  $request_data->fk_product,
358  $request_data->remise_percent,
359  $request_data->price_base_type ? $request_data->price_base_type : 'HT',
360  $request_data->subprice,
361  $request_data->info_bits,
362  $request_data->product_type,
363  $request_data->rang,
364  $request_data->special_code,
365  $request_data->fk_parent_line,
366  $request_data->fk_fournprice,
367  $request_data->pa_ht,
368  $request_data->label,
369  $request_data->date_start,
370  $request_data->date_end,
371  $request_data->array_options,
372  $request_data->fk_unit,
373  $request_data->origin,
374  $request_data->origin_id,
375  $request_data->multicurrency_subprice,
376  $request_data->fk_remise_except
377  );
378 
379  if ($updateRes > 0) {
380  return $updateRes;
381  } else {
382  throw new RestException(400, $this->propal->error);
383  }
384  }
385 
396  public function postLines($id, $request_data = null)
397  {
398  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
399  throw new RestException(403);
400  }
401 
402  $result = $this->propal->fetch($id);
403  if (!$result) {
404  throw new RestException(404, 'Commercial Proposal not found');
405  }
406 
407  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
408  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
409  }
410 
411  $errors = [];
412  $updateRes = 0;
413  $this->db->begin();
414 
415  foreach ($request_data as $TData) {
416  if (empty($TData[0])) {
417  $TData = array($TData);
418  }
419 
420  foreach ($TData as $lineData) {
421  $line = (object) $lineData;
422 
423  $updateRes = $this->propal->addline(
424  $line->desc,
425  $line->subprice,
426  $line->qty,
427  $line->tva_tx,
428  $line->localtax1_tx,
429  $line->localtax2_tx,
430  $line->fk_product,
431  $line->remise_percent,
432  'HT',
433  0,
434  $line->info_bits,
435  $line->product_type,
436  $line->rang,
437  $line->special_code,
438  $line->fk_parent_line,
439  $line->fk_fournprice,
440  $line->pa_ht,
441  $line->label,
442  $line->date_start,
443  $line->date_end,
444  $line->array_options,
445  $line->fk_unit,
446  $line->origin,
447  $line->origin_id,
448  $line->multicurrency_subprice,
449  $line->fk_remise_except
450  );
451 
452  if ($updateRes < 0) {
453  $errors['lineLabel'] = $line->label;
454  $errors['msg'] = $this->propal->errors;
455  }
456  }
457  }
458  if (empty($errors)) {
459  $this->db->commit();
460  return $updateRes;
461  } else {
462  $this->db->rollback();
463  throw new RestException(400, implode(", ", $errors));
464  }
465  }
466 
477  public function putLine($id, $lineid, $request_data = null)
478  {
479  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
480  throw new RestException(403);
481  }
482 
483  $result = $this->propal->fetch($id);
484  if ($result <= 0) {
485  throw new RestException(404, 'Proposal not found');
486  }
487 
488  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
489  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
490  }
491 
492  $request_data = (object) $request_data;
493 
494  if (isset($request_data->desc)) {
495  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
496  }
497  if (isset($request_data->label)) {
498  $request_data->label = sanitizeVal($request_data->label);
499  }
500 
501  $propalline = new PropaleLigne($this->db);
502  $result = $propalline->fetch($lineid);
503  if ($result <= 0) {
504  throw new RestException(404, 'Proposal line not found');
505  }
506 
507  $updateRes = $this->propal->updateline(
508  $lineid,
509  isset($request_data->subprice) ? $request_data->subprice : $propalline->subprice,
510  isset($request_data->qty) ? $request_data->qty : $propalline->qty,
511  isset($request_data->remise_percent) ? $request_data->remise_percent : $propalline->remise_percent,
512  isset($request_data->tva_tx) ? $request_data->tva_tx : $propalline->tva_tx,
513  isset($request_data->localtax1_tx) ? $request_data->localtax1_tx : $propalline->localtax1_tx,
514  isset($request_data->localtax2_tx) ? $request_data->localtax2_tx : $propalline->localtax2_tx,
515  isset($request_data->desc) ? $request_data->desc : $propalline->desc,
516  isset($request_data->price_base_type) ? $request_data->price_base_type : 'HT',
517  isset($request_data->info_bits) ? $request_data->info_bits : $propalline->info_bits,
518  isset($request_data->special_code) ? $request_data->special_code : $propalline->special_code,
519  isset($request_data->fk_parent_line) ? $request_data->fk_parent_line : $propalline->fk_parent_line,
520  0,
521  isset($request_data->fk_fournprice) ? $request_data->fk_fournprice : $propalline->fk_fournprice,
522  isset($request_data->pa_ht) ? $request_data->pa_ht : $propalline->pa_ht,
523  isset($request_data->label) ? $request_data->label : $propalline->label,
524  isset($request_data->product_type) ? $request_data->product_type : $propalline->product_type,
525  isset($request_data->date_start) ? $request_data->date_start : $propalline->date_start,
526  isset($request_data->date_end) ? $request_data->date_end : $propalline->date_end,
527  isset($request_data->array_options) ? $request_data->array_options : $propalline->array_options,
528  isset($request_data->fk_unit) ? $request_data->fk_unit : $propalline->fk_unit,
529  isset($request_data->multicurrency_subprice) ? $request_data->multicurrency_subprice : $propalline->subprice,
530  0,
531  isset($request_data->rang) ? $request_data->rang : $propalline->rang
532  );
533 
534  if ($updateRes > 0) {
535  $result = $this->get($id);
536  unset($result->line);
537  return $this->_cleanObjectDatas($result);
538  }
539  return false;
540  }
541 
555  public function deleteLine($id, $lineid)
556  {
557  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
558  throw new RestException(403);
559  }
560 
561  $result = $this->propal->fetch($id);
562  if (!$result) {
563  throw new RestException(404, 'Proposal not found');
564  }
565 
566  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
567  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
568  }
569 
570  $updateRes = $this->propal->deleteLine($lineid, $id);
571  if ($updateRes > 0) {
572  return $this->get($id);
573  } else {
574  throw new RestException(405, $this->propal->error);
575  }
576  }
577 
591  public function postContact($id, $contactid, $type)
592  {
593  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
594  throw new RestException(403);
595  }
596 
597  $result = $this->propal->fetch($id);
598 
599  if (!$result) {
600  throw new RestException(404, 'Proposal not found');
601  }
602 
603  if (!in_array($type, array('BILLING', 'SHIPPING', 'CUSTOMER'), true)) {
604  throw new RestException(500, 'Availables types: BILLING, SHIPPING OR CUSTOMER');
605  }
606 
607  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
608  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
609  }
610 
611  $result = $this->propal->add_contact($contactid, $type, 'external');
612 
613  if (!$result) {
614  throw new RestException(500, 'Error when added the contact');
615  }
616 
617  return array(
618  'success' => array(
619  'code' => 200,
620  'message' => 'Contact linked to the proposal'
621  )
622  );
623  }
624 
639  public function deleteContact($id, $contactid, $type)
640  {
641  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
642  throw new RestException(403);
643  }
644 
645  $result = $this->propal->fetch($id);
646 
647  if (!$result) {
648  throw new RestException(404, 'Proposal not found');
649  }
650 
651  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
652  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
653  }
654 
655  $contacts = $this->propal->liste_contact();
656 
657  foreach ($contacts as $contact) {
658  if ($contact['id'] == $contactid && $contact['code'] == $type) {
659  $result = $this->propal->delete_contact($contact['rowid']);
660 
661  if (!$result) {
662  throw new RestException(500, 'Error when deleted the contact');
663  }
664  }
665  }
666 
667  return $this->_cleanObjectDatas($this->propal);
668  }
669 
677  public function put($id, $request_data = null)
678  {
679  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
680  throw new RestException(403);
681  }
682 
683  $result = $this->propal->fetch($id);
684  if (!$result) {
685  throw new RestException(404, 'Proposal not found');
686  }
687 
688  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
689  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
690  }
691  foreach ($request_data as $field => $value) {
692  if ($field == 'id') {
693  continue;
694  }
695  if ($field === 'caller') {
696  // 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
697  $this->propal->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
698  continue;
699  }
700  if ($field == 'array_options' && is_array($value)) {
701  foreach ($value as $index => $val) {
702  $this->propal->array_options[$index] = $this->_checkValForAPI($field, $val, $this->propal);
703  }
704  continue;
705  }
706 
707  $this->propal->$field = $this->_checkValForAPI($field, $value, $this->propal);
708  }
709 
710  // update end of validity date
711  if (empty($this->propal->fin_validite) && !empty($this->propal->duree_validite) && !empty($this->propal->date_creation)) {
712  $this->propal->fin_validite = $this->propal->date_creation + ($this->propal->duree_validite * 24 * 3600);
713  }
714  if (!empty($this->propal->fin_validite)) {
715  if ($this->propal->set_echeance(DolibarrApiAccess::$user, $this->propal->fin_validite) < 0) {
716  throw new RestException(500, $this->propal->error);
717  }
718  }
719 
720  if ($this->propal->update(DolibarrApiAccess::$user) > 0) {
721  return $this->get($id);
722  } else {
723  throw new RestException(500, $this->propal->error);
724  }
725  }
726 
733  public function delete($id)
734  {
735  if (!DolibarrApiAccess::$user->hasRight('propal', 'supprimer')) {
736  throw new RestException(403);
737  }
738  $result = $this->propal->fetch($id);
739  if (!$result) {
740  throw new RestException(404, 'Commercial Proposal not found');
741  }
742 
743  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
744  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
745  }
746 
747  if (!$this->propal->delete(DolibarrApiAccess::$user)) {
748  throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error);
749  }
750 
751  return array(
752  'success' => array(
753  'code' => 200,
754  'message' => 'Commercial Proposal deleted'
755  )
756  );
757  }
758 
767  public function settodraft($id)
768  {
769  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
770  throw new RestException(403);
771  }
772  $result = $this->propal->fetch($id);
773  if (!$result) {
774  throw new RestException(404, 'Proposal not found');
775  }
776 
777  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
778  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
779  }
780 
781  $result = $this->propal->setDraft(DolibarrApiAccess::$user);
782  if ($result == 0) {
783  throw new RestException(304, 'Nothing done. May be object is already draft');
784  }
785  if ($result < 0) {
786  throw new RestException(500, 'Error : '.$this->propal->error);
787  }
788 
789  $result = $this->propal->fetch($id);
790  if (!$result) {
791  throw new RestException(404, 'Proposal not found');
792  }
793 
794  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
795  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
796  }
797 
798  $this->propal->fetchObjectLinked();
799 
800  return $this->_cleanObjectDatas($this->propal);
801  }
802 
803 
823  public function validate($id, $notrigger = 0)
824  {
825  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
826  throw new RestException(403);
827  }
828  $result = $this->propal->fetch($id);
829  if (!$result) {
830  throw new RestException(404, 'Commercial Proposal not found');
831  }
832 
833  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
834  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
835  }
836 
837  $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger);
838  if ($result == 0) {
839  throw new RestException(304, 'Error nothing done. May be object is already validated');
840  }
841  if ($result < 0) {
842  throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error);
843  }
844 
845  $result = $this->propal->fetch($id);
846  if (!$result) {
847  throw new RestException(404, 'Commercial Proposal not found');
848  }
849 
850  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
851  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
852  }
853 
854  $this->propal->fetchObjectLinked();
855 
856  return $this->_cleanObjectDatas($this->propal);
857  }
858 
870  public function close($id, $status, $note_private = '', $notrigger = 0)
871  {
872  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
873  throw new RestException(403);
874  }
875  $result = $this->propal->fetch($id);
876  if (!$result) {
877  throw new RestException(404, 'Commercial Proposal not found');
878  }
879 
880  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
881  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
882  }
883 
884  $result = $this->propal->closeProposal(DolibarrApiAccess::$user, $status, $note_private, $notrigger);
885  if ($result == 0) {
886  throw new RestException(304, 'Error nothing done. May be object is already closed');
887  }
888  if ($result < 0) {
889  throw new RestException(500, 'Error when closing Commercial Proposal: '.$this->propal->error);
890  }
891 
892  $result = $this->propal->fetch($id);
893  if (!$result) {
894  throw new RestException(404, 'Proposal not found');
895  }
896 
897  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
898  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
899  }
900 
901  $this->propal->fetchObjectLinked();
902 
903  return $this->_cleanObjectDatas($this->propal);
904  }
905 
914  public function setinvoiced($id)
915  {
916  if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
917  throw new RestException(403);
918  }
919  $result = $this->propal->fetch($id);
920  if (!$result) {
921  throw new RestException(404, 'Commercial Proposal not found');
922  }
923 
924  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
925  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
926  }
927 
928  $result = $this->propal->classifyBilled(DolibarrApiAccess::$user);
929  if ($result < 0) {
930  throw new RestException(500, 'Error : '.$this->propal->error);
931  }
932 
933  $result = $this->propal->fetch($id);
934  if (!$result) {
935  throw new RestException(404, 'Proposal not found');
936  }
937 
938  if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
939  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
940  }
941 
942  $this->propal->fetchObjectLinked();
943 
944  return $this->_cleanObjectDatas($this->propal);
945  }
946 
947 
956  private function _validate($data)
957  {
958  $propal = array();
959  foreach (Proposals::$FIELDS as $field) {
960  if (!isset($data[$field])) {
961  throw new RestException(400, "$field field missing");
962  }
963  $propal[$field] = $data[$field];
964  }
965  return $propal;
966  }
967 
968 
969  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
976  protected function _cleanObjectDatas($object)
977  {
978  // phpcs:enable
979  $object = parent::_cleanObjectDatas($object);
980 
981  unset($object->note);
982  unset($object->name);
983  unset($object->lastname);
984  unset($object->firstname);
985  unset($object->civility_id);
986  unset($object->address);
987 
988  return $object;
989  }
990 }
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 proposals.
Class to manage commercial proposal lines.
_fetch($id, $ref='', $ref_ext='', $contact_list=1)
Get properties of an proposal object.
getLines($id, $sqlfilters='')
Get lines of a commercial proposal.
settodraft($id)
Set a proposal to draft.
put($id, $request_data=null)
Update commercial proposal general fields (won't touch lines of commercial proposal)
close($id, $status, $note_private='', $notrigger=0)
Close (Accept or refuse) a quote / commercial proposal.
setinvoiced($id)
Set a commercial proposal billed.
post($request_data=null)
Create commercial proposal object.
postContact($id, $contactid, $type)
Add a contact type of given commercial proposal.
getByRefExt($ref_ext, $contact_list=1)
Get properties of an proposal object by ref_ext.
postLine($id, $request_data=null)
Add a line to given commercial proposal.
_cleanObjectDatas($object)
Clean sensible object datas.
postLines($id, $request_data=null)
Add lines to given commercial proposal.
_validate($data)
Validate fields before create or update object.
deleteLine($id, $lineid)
Delete a line of given commercial proposal.
deleteContact($id, $contactid, $type)
Delete a contact type of given commercial proposal.
validate($id, $notrigger=0)
Validate a commercial proposal.
__construct()
Constructor.
getByRef($ref, $contact_list=1)
Get properties of an proposal object by ref.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $sqlfilters='', $properties='')
List commercial proposals.
putLine($id, $lineid, $request_data=null)
Update a line of given commercial proposal.
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.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.