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
23use Luracast\Restler\RestException;
24
25require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
26
27
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
164 public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '', $properties = '', $pagination_data = false)
165 {
166 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
167 throw new RestException(403);
168 }
169
170 $obj_ret = array();
171
172 // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
173 $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids;
174
175 // If the internal user must only see his customers, force searching by him
176 $search_sale = 0;
177 if (!DolibarrApiAccess::$user->hasRight('societe', 'client', 'voir') && !$socids) {
178 $search_sale = DolibarrApiAccess::$user->id;
179 }
180
181 $sql = "SELECT t.rowid";
182 $sql .= " FROM ".MAIN_DB_PREFIX."propal AS t";
183 $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
184 $sql .= ' WHERE t.entity IN ('.getEntity('propal').')';
185 if ($socids) {
186 $sql .= " AND t.fk_soc IN (".$this->db->sanitize($socids).")";
187 }
188 // Search on sale representative
189 if ($search_sale && $search_sale != '-1') {
190 if ($search_sale == -2) {
191 $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc)";
192 } elseif ($search_sale > 0) {
193 $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).")";
194 }
195 }
196 // Add sql filters
197 if ($sqlfilters) {
198 $errormessage = '';
199 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
200 if ($errormessage) {
201 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
202 }
203 }
204
205 //this query will return total proposals with the filters given
206 $sqlTotals = str_replace('SELECT t.rowid', 'SELECT count(t.rowid) as total', $sql);
207
208 $sql .= $this->db->order($sortfield, $sortorder);
209 if ($limit) {
210 if ($page < 0) {
211 $page = 0;
212 }
213 $offset = $limit * $page;
214
215 $sql .= $this->db->plimit($limit + 1, $offset);
216 }
217
218 dol_syslog("API Rest request");
219 $result = $this->db->query($sql);
220
221 if ($result) {
222 $num = $this->db->num_rows($result);
223 $min = min($num, ($limit <= 0 ? $num : $limit));
224 $i = 0;
225 while ($i < $min) {
226 $obj = $this->db->fetch_object($result);
227 $proposal_static = new Propal($this->db);
228 if ($proposal_static->fetch($obj->rowid)) {
229 // Add external contacts ids
230 $tmparray = $proposal_static->liste_contact(-1, 'external', 1);
231 if (is_array($tmparray)) {
232 $proposal_static->contacts_ids = $tmparray;
233 }
234 $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($proposal_static), $properties);
235 }
236 $i++;
237 }
238 } else {
239 throw new RestException(503, 'Error when retrieve propal list : '.$this->db->lasterror());
240 }
241
242 //if $pagination_data is true the response will contain element data with all values and element pagination with pagination data(total,page,limit)
243 if ($pagination_data) {
244 $totalsResult = $this->db->query($sqlTotals);
245 $total = $this->db->fetch_object($totalsResult)->total;
246
247 $tmp = $obj_ret;
248 $obj_ret = [];
249
250 $obj_ret['data'] = $tmp;
251 $obj_ret['pagination'] = [
252 'total' => (int) $total,
253 'page' => $page, //count starts from 0
254 'page_count' => ceil((int) $total / $limit),
255 'limit' => $limit
256 ];
257 }
258
259 return $obj_ret;
260 }
261
268 public function post($request_data = null)
269 {
270 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
271 throw new RestException(403, "Insuffisant rights");
272 }
273 // Check mandatory fields
274 $result = $this->_validate($request_data);
275
276 foreach ($request_data as $field => $value) {
277 if ($field === 'caller') {
278 // 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
279 $this->propal->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
280 continue;
281 }
282
283 $this->propal->$field = $this->_checkValForAPI($field, $value, $this->propal);
284 }
285 /*if (isset($request_data["lines"])) {
286 $lines = array();
287 foreach ($request_data["lines"] as $line) {
288 array_push($lines, (object) $line);
289 }
290 $this->propal->lines = $lines;
291 }*/
292 if ($this->propal->create(DolibarrApiAccess::$user) < 0) {
293 throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors));
294 }
295
296 return ((int) $this->propal->id);
297 }
298
309 public function getLines($id, $sqlfilters = '')
310 {
311 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
312 throw new RestException(403);
313 }
314
315 $result = $this->propal->fetch($id);
316 if (!$result) {
317 throw new RestException(404, 'Commercial Proposal not found');
318 }
319
320 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
321 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
322 }
323
324 $sql = '';
325 if (!empty($sqlfilters)) {
326 $errormessage = '';
327 $sql = forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
328 if ($errormessage) {
329 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
330 }
331 }
332
333 $this->propal->getLinesArray($sql);
334 $result = array();
335 foreach ($this->propal->lines as $line) {
336 array_push($result, $this->_cleanObjectDatas($line));
337 }
338 return $result;
339 }
340
351 public function postLine($id, $request_data = null)
352 {
353 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
354 throw new RestException(403);
355 }
356
357 $result = $this->propal->fetch($id);
358 if (!$result) {
359 throw new RestException(404, 'Commercial Proposal not found');
360 }
361
362 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
363 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
364 }
365
366 $request_data = (object) $request_data;
367
368 $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
369 $request_data->label = sanitizeVal($request_data->label);
370
371 $updateRes = $this->propal->addline(
372 $request_data->desc,
373 $request_data->subprice,
374 $request_data->qty,
375 $request_data->tva_tx,
376 $request_data->localtax1_tx,
377 $request_data->localtax2_tx,
378 $request_data->fk_product,
379 $request_data->remise_percent,
380 $request_data->price_base_type ? $request_data->price_base_type : 'HT',
381 $request_data->subprice,
382 $request_data->info_bits,
383 $request_data->product_type,
384 $request_data->rang,
385 $request_data->special_code,
386 $request_data->fk_parent_line,
387 $request_data->fk_fournprice,
388 $request_data->pa_ht,
389 $request_data->label,
390 $request_data->date_start,
391 $request_data->date_end,
392 $request_data->array_options,
393 $request_data->fk_unit,
394 $request_data->origin,
395 $request_data->origin_id,
396 $request_data->multicurrency_subprice,
397 $request_data->fk_remise_except
398 );
399
400 if ($updateRes > 0) {
401 return $updateRes;
402 } else {
403 throw new RestException(400, $this->propal->error);
404 }
405 }
406
417 public function postLines($id, $request_data = null)
418 {
419 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
420 throw new RestException(403);
421 }
422
423 $result = $this->propal->fetch($id);
424 if (!$result) {
425 throw new RestException(404, 'Commercial Proposal not found');
426 }
427
428 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
429 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
430 }
431
432 $errors = [];
433 $updateRes = 0;
434 $this->db->begin();
435
436 foreach ($request_data as $TData) {
437 if (empty($TData[0])) {
438 $TData = array($TData);
439 }
440
441 foreach ($TData as $lineData) {
442 $line = (object) $lineData;
443
444 $updateRes = $this->propal->addline(
445 $line->desc,
446 $line->subprice,
447 $line->qty,
448 $line->tva_tx,
449 $line->localtax1_tx,
450 $line->localtax2_tx,
451 $line->fk_product,
452 $line->remise_percent,
453 'HT',
454 0,
455 $line->info_bits,
456 $line->product_type,
457 $line->rang,
458 $line->special_code,
459 $line->fk_parent_line,
460 $line->fk_fournprice,
461 $line->pa_ht,
462 $line->label,
463 $line->date_start,
464 $line->date_end,
465 $line->array_options,
466 $line->fk_unit,
467 $line->origin,
468 $line->origin_id,
469 $line->multicurrency_subprice,
470 $line->fk_remise_except
471 );
472
473 if ($updateRes < 0) {
474 $errors['lineLabel'] = $line->label;
475 $errors['msg'] = $this->propal->errors;
476 }
477 }
478 }
479 if (empty($errors)) {
480 $this->db->commit();
481 return $updateRes;
482 } else {
483 $this->db->rollback();
484 throw new RestException(400, implode(", ", $errors));
485 }
486 }
487
498 public function putLine($id, $lineid, $request_data = null)
499 {
500 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
501 throw new RestException(403);
502 }
503
504 $result = $this->propal->fetch($id);
505 if ($result <= 0) {
506 throw new RestException(404, 'Proposal not found');
507 }
508
509 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
510 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
511 }
512
513 $request_data = (object) $request_data;
514
515 if (isset($request_data->desc)) {
516 $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
517 }
518 if (isset($request_data->label)) {
519 $request_data->label = sanitizeVal($request_data->label);
520 }
521
522 $propalline = new PropaleLigne($this->db);
523 $result = $propalline->fetch($lineid);
524 if ($result <= 0) {
525 throw new RestException(404, 'Proposal line not found');
526 }
527
528 $updateRes = $this->propal->updateline(
529 $lineid,
530 isset($request_data->subprice) ? $request_data->subprice : $propalline->subprice,
531 isset($request_data->qty) ? $request_data->qty : $propalline->qty,
532 isset($request_data->remise_percent) ? $request_data->remise_percent : $propalline->remise_percent,
533 isset($request_data->tva_tx) ? $request_data->tva_tx : $propalline->tva_tx,
534 isset($request_data->localtax1_tx) ? $request_data->localtax1_tx : $propalline->localtax1_tx,
535 isset($request_data->localtax2_tx) ? $request_data->localtax2_tx : $propalline->localtax2_tx,
536 isset($request_data->desc) ? $request_data->desc : $propalline->desc,
537 isset($request_data->price_base_type) ? $request_data->price_base_type : 'HT',
538 isset($request_data->info_bits) ? $request_data->info_bits : $propalline->info_bits,
539 isset($request_data->special_code) ? $request_data->special_code : $propalline->special_code,
540 isset($request_data->fk_parent_line) ? $request_data->fk_parent_line : $propalline->fk_parent_line,
541 0,
542 isset($request_data->fk_fournprice) ? $request_data->fk_fournprice : $propalline->fk_fournprice,
543 isset($request_data->pa_ht) ? $request_data->pa_ht : $propalline->pa_ht,
544 isset($request_data->label) ? $request_data->label : $propalline->label,
545 isset($request_data->product_type) ? $request_data->product_type : $propalline->product_type,
546 isset($request_data->date_start) ? $request_data->date_start : $propalline->date_start,
547 isset($request_data->date_end) ? $request_data->date_end : $propalline->date_end,
548 isset($request_data->array_options) ? $request_data->array_options : $propalline->array_options,
549 isset($request_data->fk_unit) ? $request_data->fk_unit : $propalline->fk_unit,
550 isset($request_data->multicurrency_subprice) ? $request_data->multicurrency_subprice : $propalline->subprice,
551 0,
552 isset($request_data->rang) ? $request_data->rang : $propalline->rang
553 );
554
555 if ($updateRes > 0) {
556 $result = $this->get($id);
557 unset($result->line);
558 return $this->_cleanObjectDatas($result);
559 }
560 return false;
561 }
562
576 public function deleteLine($id, $lineid)
577 {
578 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
579 throw new RestException(403);
580 }
581
582 $result = $this->propal->fetch($id);
583 if (!$result) {
584 throw new RestException(404, 'Proposal not found');
585 }
586
587 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
588 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
589 }
590
591 $updateRes = $this->propal->deleteLine($lineid, $id);
592 if ($updateRes > 0) {
593 return $this->get($id);
594 } else {
595 throw new RestException(405, $this->propal->error);
596 }
597 }
598
612 public function postContact($id, $contactid, $type)
613 {
614 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
615 throw new RestException(403);
616 }
617
618 $result = $this->propal->fetch($id);
619
620 if (!$result) {
621 throw new RestException(404, 'Proposal not found');
622 }
623
624 if (!in_array($type, array('BILLING', 'SHIPPING', 'CUSTOMER'), true)) {
625 throw new RestException(500, 'Availables types: BILLING, SHIPPING OR CUSTOMER');
626 }
627
628 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
629 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
630 }
631
632 $result = $this->propal->add_contact($contactid, $type, 'external');
633
634 if (!$result) {
635 throw new RestException(500, 'Error when added the contact');
636 }
637
638 return array(
639 'success' => array(
640 'code' => 200,
641 'message' => 'Contact linked to the proposal'
642 )
643 );
644 }
645
660 public function deleteContact($id, $contactid, $type)
661 {
662 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
663 throw new RestException(403);
664 }
665
666 $result = $this->propal->fetch($id);
667
668 if (!$result) {
669 throw new RestException(404, 'Proposal not found');
670 }
671
672 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
673 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
674 }
675
676 $contacts = $this->propal->liste_contact();
677
678 foreach ($contacts as $contact) {
679 if ($contact['id'] == $contactid && $contact['code'] == $type) {
680 $result = $this->propal->delete_contact($contact['rowid']);
681
682 if (!$result) {
683 throw new RestException(500, 'Error when deleted the contact');
684 }
685 }
686 }
687
688 return $this->_cleanObjectDatas($this->propal);
689 }
690
698 public function put($id, $request_data = null)
699 {
700 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
701 throw new RestException(403);
702 }
703
704 $result = $this->propal->fetch($id);
705 if (!$result) {
706 throw new RestException(404, 'Proposal not found');
707 }
708
709 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
710 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
711 }
712 foreach ($request_data as $field => $value) {
713 if ($field == 'id') {
714 continue;
715 }
716 if ($field === 'caller') {
717 // 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
718 $this->propal->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
719 continue;
720 }
721 if ($field == 'array_options' && is_array($value)) {
722 foreach ($value as $index => $val) {
723 $this->propal->array_options[$index] = $this->_checkValForAPI($field, $val, $this->propal);
724 }
725 continue;
726 }
727
728 $this->propal->$field = $this->_checkValForAPI($field, $value, $this->propal);
729 }
730
731 // update end of validity date
732 if (empty($this->propal->fin_validite) && !empty($this->propal->duree_validite) && !empty($this->propal->date_creation)) {
733 $this->propal->fin_validite = $this->propal->date_creation + ($this->propal->duree_validite * 24 * 3600);
734 }
735 if (!empty($this->propal->fin_validite)) {
736 if ($this->propal->set_echeance(DolibarrApiAccess::$user, $this->propal->fin_validite) < 0) {
737 throw new RestException(500, $this->propal->error);
738 }
739 }
740
741 if ($this->propal->update(DolibarrApiAccess::$user) > 0) {
742 return $this->get($id);
743 } else {
744 throw new RestException(500, $this->propal->error);
745 }
746 }
747
754 public function delete($id)
755 {
756 if (!DolibarrApiAccess::$user->hasRight('propal', 'supprimer')) {
757 throw new RestException(403);
758 }
759 $result = $this->propal->fetch($id);
760 if (!$result) {
761 throw new RestException(404, 'Commercial Proposal not found');
762 }
763
764 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
765 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
766 }
767
768 if (!$this->propal->delete(DolibarrApiAccess::$user)) {
769 throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error);
770 }
771
772 return array(
773 'success' => array(
774 'code' => 200,
775 'message' => 'Commercial Proposal deleted'
776 )
777 );
778 }
779
788 public function settodraft($id)
789 {
790 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
791 throw new RestException(403);
792 }
793 $result = $this->propal->fetch($id);
794 if (!$result) {
795 throw new RestException(404, 'Proposal not found');
796 }
797
798 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
799 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
800 }
801
802 $result = $this->propal->setDraft(DolibarrApiAccess::$user);
803 if ($result == 0) {
804 throw new RestException(304, 'Nothing done. May be object is already draft');
805 }
806 if ($result < 0) {
807 throw new RestException(500, 'Error : '.$this->propal->error);
808 }
809
810 $result = $this->propal->fetch($id);
811 if (!$result) {
812 throw new RestException(404, 'Proposal not found');
813 }
814
815 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
816 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
817 }
818
819 $this->propal->fetchObjectLinked();
820
821 return $this->_cleanObjectDatas($this->propal);
822 }
823
824
844 public function validate($id, $notrigger = 0)
845 {
846 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
847 throw new RestException(403);
848 }
849 $result = $this->propal->fetch($id);
850 if (!$result) {
851 throw new RestException(404, 'Commercial Proposal not found');
852 }
853
854 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
855 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
856 }
857
858 $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger);
859 if ($result == 0) {
860 throw new RestException(304, 'Error nothing done. May be object is already validated');
861 }
862 if ($result < 0) {
863 throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error);
864 }
865
866 $result = $this->propal->fetch($id);
867 if (!$result) {
868 throw new RestException(404, 'Commercial Proposal not found');
869 }
870
871 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
872 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
873 }
874
875 $this->propal->fetchObjectLinked();
876
877 return $this->_cleanObjectDatas($this->propal);
878 }
879
891 public function close($id, $status, $note_private = '', $notrigger = 0)
892 {
893 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
894 throw new RestException(403);
895 }
896 $result = $this->propal->fetch($id);
897 if (!$result) {
898 throw new RestException(404, 'Commercial Proposal not found');
899 }
900
901 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
902 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
903 }
904
905 $result = $this->propal->closeProposal(DolibarrApiAccess::$user, $status, $note_private, $notrigger);
906 if ($result == 0) {
907 throw new RestException(304, 'Error nothing done. May be object is already closed');
908 }
909 if ($result < 0) {
910 throw new RestException(500, 'Error when closing Commercial Proposal: '.$this->propal->error);
911 }
912
913 $result = $this->propal->fetch($id);
914 if (!$result) {
915 throw new RestException(404, 'Proposal not found');
916 }
917
918 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
919 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
920 }
921
922 $this->propal->fetchObjectLinked();
923
924 return $this->_cleanObjectDatas($this->propal);
925 }
926
935 public function setinvoiced($id)
936 {
937 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
938 throw new RestException(403);
939 }
940 $result = $this->propal->fetch($id);
941 if (!$result) {
942 throw new RestException(404, 'Commercial Proposal not found');
943 }
944
945 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
946 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
947 }
948
949 $result = $this->propal->classifyBilled(DolibarrApiAccess::$user);
950 if ($result < 0) {
951 throw new RestException(500, 'Error : '.$this->propal->error);
952 }
953
954 $result = $this->propal->fetch($id);
955 if (!$result) {
956 throw new RestException(404, 'Proposal not found');
957 }
958
959 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
960 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
961 }
962
963 $this->propal->fetchObjectLinked();
964
965 return $this->_cleanObjectDatas($this->propal);
966 }
967
968
977 private function _validate($data)
978 {
979 $propal = array();
980 foreach (Proposals::$FIELDS as $field) {
981 if (!isset($data[$field])) {
982 throw new RestException(400, "$field field missing");
983 }
984 $propal[$field] = $data[$field];
985 }
986 return $propal;
987 }
988
989
990 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
997 protected function _cleanObjectDatas($object)
998 {
999 // phpcs:enable
1000 $object = parent::_cleanObjectDatas($object);
1001
1002 unset($object->note);
1003 unset($object->name);
1004 unset($object->lastname);
1005 unset($object->firstname);
1006 unset($object->civility_id);
1007 unset($object->address);
1008
1009 return $object;
1010 }
1011}
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 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)
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $sqlfilters='', $properties='', $pagination_data=false)
List commercial proposals.
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.
putLine($id, $lineid, $request_data=null)
Update a line of given commercial proposal.
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.