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 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24use Luracast\Restler\RestException;
25
26require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
27
28
36{
40 public static $FIELDS = array(
41 'socid'
42 );
43
47 public $propal;
48
52 public function __construct()
53 {
54 global $db;
55 $this->db = $db;
56 $this->propal = new Propal($this->db);
57 }
58
70 public function get($id, $contact_list = 1)
71 {
72 return $this->_fetch($id, '', '', $contact_list);
73 }
74
88 public function getByRef($ref, $contact_list = 1)
89 {
90 return $this->_fetch(0, $ref, '', $contact_list);
91 }
92
106 public function getByRefExt($ref_ext, $contact_list = 1)
107 {
108 return $this->_fetch(0, '', $ref_ext, $contact_list);
109 }
110
124 private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1)
125 {
126 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
127 throw new RestException(403);
128 }
129
130 $result = $this->propal->fetch($id, $ref, $ref_ext);
131 if (!$result) {
132 throw new RestException(404, 'Commercial Proposal not found');
133 }
134
135 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
136 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
137 }
138
139 // Add external contacts ids.
140 $tmparray = $this->propal->liste_contact(-1, 'external', $contact_list);
141 if (is_array($tmparray)) {
142 $this->propal->contacts_ids = $tmparray;
143 }
144
145 $this->propal->fetchObjectLinked();
146
147 return $this->_cleanObjectDatas($this->propal);
148 }
149
165 public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '', $properties = '', $pagination_data = false)
166 {
167 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
168 throw new RestException(403);
169 }
170
171 $obj_ret = array();
172
173 // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
174 $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids;
175
176 // If the internal user must only see his customers, force searching by him
177 $search_sale = 0;
178 if (!DolibarrApiAccess::$user->hasRight('societe', 'client', 'voir') && !$socids) {
179 $search_sale = DolibarrApiAccess::$user->id;
180 }
181
182 $sql = "SELECT t.rowid";
183 $sql .= " FROM ".MAIN_DB_PREFIX."propal AS t";
184 $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
185 $sql .= ' WHERE t.entity IN ('.getEntity('propal').')';
186 if ($socids) {
187 $sql .= " AND t.fk_soc IN (".$this->db->sanitize($socids).")";
188 }
189 // Search on sale representative
190 if ($search_sale && $search_sale != '-1') {
191 if ($search_sale == -2) {
192 $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc)";
193 } elseif ($search_sale > 0) {
194 $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).")";
195 }
196 }
197 // Add sql filters
198 if ($sqlfilters) {
199 $errormessage = '';
200 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
201 if ($errormessage) {
202 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
203 }
204 }
205
206 //this query will return total proposals with the filters given
207 $sqlTotals = str_replace('SELECT t.rowid', 'SELECT count(t.rowid) as total', $sql);
208
209 $sql .= $this->db->order($sortfield, $sortorder);
210 if ($limit) {
211 if ($page < 0) {
212 $page = 0;
213 }
214 $offset = $limit * $page;
215
216 $sql .= $this->db->plimit($limit + 1, $offset);
217 }
218
219 dol_syslog("API Rest request");
220 $result = $this->db->query($sql);
221
222 if ($result) {
223 $num = $this->db->num_rows($result);
224 $min = min($num, ($limit <= 0 ? $num : $limit));
225 $i = 0;
226 while ($i < $min) {
227 $obj = $this->db->fetch_object($result);
228 $proposal_static = new Propal($this->db);
229 if ($proposal_static->fetch($obj->rowid)) {
230 // Add external contacts ids
231 $tmparray = $proposal_static->liste_contact(-1, 'external', 1);
232 if (is_array($tmparray)) {
233 $proposal_static->contacts_ids = $tmparray;
234 }
235 $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($proposal_static), $properties);
236 }
237 $i++;
238 }
239 } else {
240 throw new RestException(503, 'Error when retrieve propal list : '.$this->db->lasterror());
241 }
242
243 //if $pagination_data is true the response will contain element data with all values and element pagination with pagination data(total,page,limit)
244 if ($pagination_data) {
245 $totalsResult = $this->db->query($sqlTotals);
246 $total = $this->db->fetch_object($totalsResult)->total;
247
248 $tmp = $obj_ret;
249 $obj_ret = [];
250
251 $obj_ret['data'] = $tmp;
252 $obj_ret['pagination'] = [
253 'total' => (int) $total,
254 'page' => $page, //count starts from 0
255 'page_count' => ceil((int) $total / $limit),
256 'limit' => $limit
257 ];
258 }
259
260 return $obj_ret;
261 }
262
269 public function post($request_data = null)
270 {
271 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
272 throw new RestException(403, "Insuffisant rights");
273 }
274 // Check mandatory fields
275 $result = $this->_validate($request_data);
276
277 foreach ($request_data as $field => $value) {
278 if ($field === 'caller') {
279 // 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
280 $this->propal->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
281 continue;
282 }
283
284 $this->propal->$field = $this->_checkValForAPI($field, $value, $this->propal);
285 }
286 /*if (isset($request_data["lines"])) {
287 $lines = array();
288 foreach ($request_data["lines"] as $line) {
289 array_push($lines, (object) $line);
290 }
291 $this->propal->lines = $lines;
292 }*/
293 if ($this->propal->create(DolibarrApiAccess::$user) < 0) {
294 throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors));
295 }
296
297 return ((int) $this->propal->id);
298 }
299
310 public function getLines($id, $sqlfilters = '')
311 {
312 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) {
313 throw new RestException(403);
314 }
315
316 $result = $this->propal->fetch($id);
317 if (!$result) {
318 throw new RestException(404, 'Commercial Proposal not found');
319 }
320
321 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
322 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
323 }
324
325 $sql = '';
326 if (!empty($sqlfilters)) {
327 $errormessage = '';
328 $sql = forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
329 if ($errormessage) {
330 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
331 }
332 }
333
334 $this->propal->getLinesArray($sql);
335 $result = array();
336 foreach ($this->propal->lines as $line) {
337 array_push($result, $this->_cleanObjectDatas($line));
338 }
339 return $result;
340 }
341
352 public function postLine($id, $request_data = null)
353 {
354 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
355 throw new RestException(403);
356 }
357
358 $result = $this->propal->fetch($id);
359 if (!$result) {
360 throw new RestException(404, 'Commercial Proposal not found');
361 }
362
363 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
364 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
365 }
366
367 $request_data = (object) $request_data;
368
369 $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
370 $request_data->label = sanitizeVal($request_data->label);
371
372 $updateRes = $this->propal->addline(
373 $request_data->desc,
374 $request_data->subprice,
375 $request_data->qty,
376 $request_data->tva_tx,
377 $request_data->localtax1_tx,
378 $request_data->localtax2_tx,
379 $request_data->fk_product,
380 $request_data->remise_percent,
381 $request_data->price_base_type ? $request_data->price_base_type : 'HT',
382 $request_data->subprice,
383 $request_data->info_bits,
384 $request_data->product_type,
385 $request_data->rang,
386 $request_data->special_code,
387 $request_data->fk_parent_line,
388 $request_data->fk_fournprice,
389 $request_data->pa_ht,
390 $request_data->label,
391 $request_data->date_start,
392 $request_data->date_end,
393 $request_data->array_options,
394 $request_data->fk_unit,
395 $request_data->origin,
396 $request_data->origin_id,
397 $request_data->multicurrency_subprice,
398 $request_data->fk_remise_except
399 );
400
401 if ($updateRes > 0) {
402 return $updateRes;
403 } else {
404 throw new RestException(400, $this->propal->error);
405 }
406 }
407
418 public function postLines($id, $request_data = null)
419 {
420 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
421 throw new RestException(403);
422 }
423
424 $result = $this->propal->fetch($id);
425 if (!$result) {
426 throw new RestException(404, 'Commercial Proposal not found');
427 }
428
429 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
430 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
431 }
432
433 $errors = [];
434 $updateRes = 0;
435 $this->db->begin();
436
437 foreach ($request_data as $TData) {
438 if (empty($TData[0])) {
439 $TData = array($TData);
440 }
441
442 foreach ($TData as $lineData) {
443 $line = (object) $lineData;
444
445 $updateRes = $this->propal->addline(
446 $line->desc,
447 $line->subprice,
448 $line->qty,
449 $line->tva_tx,
450 $line->localtax1_tx,
451 $line->localtax2_tx,
452 $line->fk_product,
453 $line->remise_percent,
454 'HT',
455 0,
456 $line->info_bits,
457 $line->product_type,
458 $line->rang,
459 $line->special_code,
460 $line->fk_parent_line,
461 $line->fk_fournprice,
462 $line->pa_ht,
463 $line->label,
464 $line->date_start,
465 $line->date_end,
466 $line->array_options,
467 $line->fk_unit,
468 $line->origin,
469 $line->origin_id,
470 $line->multicurrency_subprice,
471 $line->fk_remise_except
472 );
473
474 if ($updateRes < 0) {
475 $errors['lineLabel'] = $line->label;
476 $errors['msg'] = $this->propal->errors;
477 }
478 }
479 }
480 if (empty($errors)) {
481 $this->db->commit();
482 return $updateRes;
483 } else {
484 $this->db->rollback();
485 throw new RestException(400, implode(", ", $errors));
486 }
487 }
488
499 public function putLine($id, $lineid, $request_data = null)
500 {
501 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
502 throw new RestException(403);
503 }
504
505 $result = $this->propal->fetch($id);
506 if ($result <= 0) {
507 throw new RestException(404, 'Proposal not found');
508 }
509
510 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
511 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
512 }
513
514 $request_data = (object) $request_data;
515
516 if (isset($request_data->desc)) {
517 $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
518 }
519 if (isset($request_data->label)) {
520 $request_data->label = sanitizeVal($request_data->label);
521 }
522
523 $propalline = new PropaleLigne($this->db);
524 $result = $propalline->fetch($lineid);
525 if ($result <= 0) {
526 throw new RestException(404, 'Proposal line not found');
527 }
528
529 $updateRes = $this->propal->updateline(
530 $lineid,
531 isset($request_data->subprice) ? $request_data->subprice : $propalline->subprice,
532 isset($request_data->qty) ? $request_data->qty : $propalline->qty,
533 isset($request_data->remise_percent) ? $request_data->remise_percent : $propalline->remise_percent,
534 isset($request_data->tva_tx) ? $request_data->tva_tx : $propalline->tva_tx,
535 isset($request_data->localtax1_tx) ? $request_data->localtax1_tx : $propalline->localtax1_tx,
536 isset($request_data->localtax2_tx) ? $request_data->localtax2_tx : $propalline->localtax2_tx,
537 isset($request_data->desc) ? $request_data->desc : $propalline->desc,
538 isset($request_data->price_base_type) ? $request_data->price_base_type : 'HT',
539 isset($request_data->info_bits) ? $request_data->info_bits : $propalline->info_bits,
540 isset($request_data->special_code) ? $request_data->special_code : $propalline->special_code,
541 isset($request_data->fk_parent_line) ? $request_data->fk_parent_line : $propalline->fk_parent_line,
542 0,
543 isset($request_data->fk_fournprice) ? $request_data->fk_fournprice : $propalline->fk_fournprice,
544 isset($request_data->pa_ht) ? $request_data->pa_ht : $propalline->pa_ht,
545 isset($request_data->label) ? $request_data->label : $propalline->label,
546 isset($request_data->product_type) ? $request_data->product_type : $propalline->product_type,
547 isset($request_data->date_start) ? $request_data->date_start : $propalline->date_start,
548 isset($request_data->date_end) ? $request_data->date_end : $propalline->date_end,
549 isset($request_data->array_options) ? $request_data->array_options : $propalline->array_options,
550 isset($request_data->fk_unit) ? $request_data->fk_unit : $propalline->fk_unit,
551 isset($request_data->multicurrency_subprice) ? $request_data->multicurrency_subprice : $propalline->subprice,
552 0,
553 isset($request_data->rang) ? $request_data->rang : $propalline->rang
554 );
555
556 if ($updateRes > 0) {
557 $result = $this->get($id);
558 unset($result->line);
559 return $this->_cleanObjectDatas($result);
560 }
561 return false;
562 }
563
577 public function deleteLine($id, $lineid)
578 {
579 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
580 throw new RestException(403);
581 }
582
583 $result = $this->propal->fetch($id);
584 if (!$result) {
585 throw new RestException(404, 'Proposal not found');
586 }
587
588 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
589 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
590 }
591
592 $updateRes = $this->propal->deleteLine($lineid, $id);
593 if ($updateRes > 0) {
594 return $this->get($id);
595 } else {
596 throw new RestException(405, $this->propal->error);
597 }
598 }
599
614 public function postContact($id, $contactid, $type, $source = 'external')
615 {
616 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
617 throw new RestException(403);
618 }
619
620 $result = $this->propal->fetch($id);
621
622 if (!$result) {
623 throw new RestException(404, 'Proposal not found');
624 }
625
626 if (!in_array($source, array('internal', 'external'), true)) {
627 throw new RestException(500, 'Availables sources: internal OR external');
628 }
629
630 if ($source == 'external' && !in_array($type, array('BILLING', 'SHIPPING', 'CUSTOMER'), true)) {
631 throw new RestException(500, 'Availables external types: BILLING, SHIPPING OR CUSTOMER');
632 }
633
634 if ($source == 'internal' && !in_array($type, array('SALESREPFOLL'), true)) {
635 throw new RestException(500, 'Availables internal types: SALESREPFOLL');
636 }
637
638 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
639 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
640 }
641
642 $result = $this->propal->add_contact($contactid, $type, $source);
643
644 if (!$result) {
645 throw new RestException(500, 'Error when added the contact');
646 }
647
648 return array(
649 'success' => array(
650 'code' => 200,
651 'message' => 'Contact linked to the proposal'
652 )
653 );
654 }
655
670 public function deleteContact($id, $contactid, $type)
671 {
672 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
673 throw new RestException(403);
674 }
675
676 $result = $this->propal->fetch($id);
677
678 if (!$result) {
679 throw new RestException(404, 'Proposal not found');
680 }
681
682 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
683 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
684 }
685
686 $contacts = $this->propal->liste_contact();
687
688 foreach ($contacts as $contact) {
689 if ($contact['id'] == $contactid && $contact['code'] == $type) {
690 $result = $this->propal->delete_contact($contact['rowid']);
691
692 if (!$result) {
693 throw new RestException(500, 'Error when deleted the contact');
694 }
695 }
696 }
697
698 return $this->_cleanObjectDatas($this->propal);
699 }
700
708 public function put($id, $request_data = null)
709 {
710 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
711 throw new RestException(403);
712 }
713
714 $result = $this->propal->fetch($id);
715 if (!$result) {
716 throw new RestException(404, 'Proposal not found');
717 }
718
719 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
720 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
721 }
722 foreach ($request_data as $field => $value) {
723 if ($field == 'id') {
724 continue;
725 }
726 if ($field === 'caller') {
727 // 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
728 $this->propal->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
729 continue;
730 }
731 if ($field == 'array_options' && is_array($value)) {
732 foreach ($value as $index => $val) {
733 $this->propal->array_options[$index] = $this->_checkValForAPI($field, $val, $this->propal);
734 }
735 continue;
736 }
737
738 $this->propal->$field = $this->_checkValForAPI($field, $value, $this->propal);
739 }
740
741 // update end of validity date
742 if (empty($this->propal->fin_validite) && !empty($this->propal->duree_validite) && !empty($this->propal->date_creation)) {
743 $this->propal->fin_validite = $this->propal->date_creation + ($this->propal->duree_validite * 24 * 3600);
744 }
745 if (!empty($this->propal->fin_validite)) {
746 if ($this->propal->set_echeance(DolibarrApiAccess::$user, $this->propal->fin_validite) < 0) {
747 throw new RestException(500, $this->propal->error);
748 }
749 }
750
751 if ($this->propal->update(DolibarrApiAccess::$user) > 0) {
752 return $this->get($id);
753 } else {
754 throw new RestException(500, $this->propal->error);
755 }
756 }
757
764 public function delete($id)
765 {
766 if (!DolibarrApiAccess::$user->hasRight('propal', 'supprimer')) {
767 throw new RestException(403);
768 }
769 $result = $this->propal->fetch($id);
770 if (!$result) {
771 throw new RestException(404, 'Commercial Proposal not found');
772 }
773
774 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
775 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
776 }
777
778 if (!$this->propal->delete(DolibarrApiAccess::$user)) {
779 throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error);
780 }
781
782 return array(
783 'success' => array(
784 'code' => 200,
785 'message' => 'Commercial Proposal deleted'
786 )
787 );
788 }
789
798 public function settodraft($id)
799 {
800 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
801 throw new RestException(403);
802 }
803 $result = $this->propal->fetch($id);
804 if (!$result) {
805 throw new RestException(404, 'Proposal not found');
806 }
807
808 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
809 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
810 }
811
812 $result = $this->propal->setDraft(DolibarrApiAccess::$user);
813 if ($result == 0) {
814 throw new RestException(304, 'Nothing done. May be object is already draft');
815 }
816 if ($result < 0) {
817 throw new RestException(500, 'Error : '.$this->propal->error);
818 }
819
820 $result = $this->propal->fetch($id);
821 if (!$result) {
822 throw new RestException(404, 'Proposal not found');
823 }
824
825 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
826 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
827 }
828
829 $this->propal->fetchObjectLinked();
830
831 return $this->_cleanObjectDatas($this->propal);
832 }
833
834
854 public function validate($id, $notrigger = 0)
855 {
856 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
857 throw new RestException(403);
858 }
859 $result = $this->propal->fetch($id);
860 if (!$result) {
861 throw new RestException(404, 'Commercial Proposal not found');
862 }
863
864 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
865 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
866 }
867
868 $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger);
869 if ($result == 0) {
870 throw new RestException(304, 'Error nothing done. May be object is already validated');
871 }
872 if ($result < 0) {
873 throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error);
874 }
875
876 $result = $this->propal->fetch($id);
877 if (!$result) {
878 throw new RestException(404, 'Commercial Proposal not found');
879 }
880
881 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
882 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
883 }
884
885 $this->propal->fetchObjectLinked();
886
887 return $this->_cleanObjectDatas($this->propal);
888 }
889
902 public function close($id, $status, $note_private = '', $notrigger = 0, $note_public = '')
903 {
904 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
905 throw new RestException(403);
906 }
907 $result = $this->propal->fetch($id);
908 if (!$result) {
909 throw new RestException(404, 'Commercial Proposal not found');
910 }
911
912 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
913 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
914 }
915
916 $result = $this->propal->closeProposal(DolibarrApiAccess::$user, $status, $note_private, $notrigger, $note_public);
917 if ($result == 0) {
918 throw new RestException(304, 'Error nothing done. May be object is already closed');
919 }
920 if ($result < 0) {
921 throw new RestException(500, 'Error when closing Commercial Proposal: '.$this->propal->error);
922 }
923
924 $result = $this->propal->fetch($id);
925 if (!$result) {
926 throw new RestException(404, 'Proposal not found');
927 }
928
929 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
930 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
931 }
932
933 $this->propal->fetchObjectLinked();
934
935 return $this->_cleanObjectDatas($this->propal);
936 }
937
946 public function setinvoiced($id)
947 {
948 if (!DolibarrApiAccess::$user->hasRight('propal', 'creer')) {
949 throw new RestException(403);
950 }
951 $result = $this->propal->fetch($id);
952 if (!$result) {
953 throw new RestException(404, 'Commercial Proposal not found');
954 }
955
956 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
957 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
958 }
959
960 $result = $this->propal->classifyBilled(DolibarrApiAccess::$user);
961 if ($result < 0) {
962 throw new RestException(500, 'Error : '.$this->propal->error);
963 }
964
965 $result = $this->propal->fetch($id);
966 if (!$result) {
967 throw new RestException(404, 'Proposal not found');
968 }
969
970 if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
971 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
972 }
973
974 $this->propal->fetchObjectLinked();
975
976 return $this->_cleanObjectDatas($this->propal);
977 }
978
979
988 private function _validate($data)
989 {
990 $propal = array();
991 foreach (Proposals::$FIELDS as $field) {
992 if (!isset($data[$field])) {
993 throw new RestException(400, "$field field missing");
994 }
995 $propal[$field] = $data[$field];
996 }
997 return $propal;
998 }
999
1000
1001 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1008 protected function _cleanObjectDatas($object)
1009 {
1010 // phpcs:enable
1011 $object = parent::_cleanObjectDatas($object);
1012
1013 unset($object->note);
1014 unset($object->name);
1015 unset($object->lastname);
1016 unset($object->firstname);
1017 unset($object->civility_id);
1018 unset($object->address);
1019
1020 return $object;
1021 }
1022}
$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 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.
setinvoiced($id)
Set a commercial proposal billed.
post($request_data=null)
Create commercial proposal object.
postContact($id, $contactid, $type, $source='external')
Add a contact type of given commercial proposal.
close($id, $status, $note_private='', $notrigger=0, $note_public='')
Close (Accept or refuse) a quote / 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.