dolibarr  9.0.0
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  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
20 
21 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
22 
23 
30 class Proposals extends DolibarrApi
31 {
32 
36  static $FIELDS = array(
37  'socid'
38  );
39 
43  public $propal;
44 
48  function __construct()
49  {
50  global $db, $conf;
51  $this->db = $db;
52  $this->propal = new Propal($this->db);
53  }
54 
65  function get($id)
66  {
67  if(! DolibarrApiAccess::$user->rights->propal->lire) {
68  throw new RestException(401);
69  }
70 
71  $result = $this->propal->fetch($id);
72  if( ! $result ) {
73  throw new RestException(404, 'Commercial Proposal not found');
74  }
75 
76  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
77  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
78  }
79 
80  // Add external contacts ids
81  $this->propal->contacts_ids = $this->propal->liste_contact(-1,'external',1);
82 
83  $this->propal->fetchObjectLinked();
84  return $this->_cleanObjectDatas($this->propal);
85  }
86 
100  function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
101  {
102  global $db, $conf;
103 
104  $obj_ret = array();
105 
106  // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
107  $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids;
108 
109  // If the internal user must only see his customers, force searching by him
110  $search_sale = 0;
111  if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
112 
113  $sql = "SELECT t.rowid";
114  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
115  $sql.= " FROM ".MAIN_DB_PREFIX."propal as t";
116 
117  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
118 
119  $sql.= ' WHERE t.entity IN ('.getEntity('propal').')';
120  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc";
121  if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")";
122  if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
123  // Insert sale filter
124  if ($search_sale > 0)
125  {
126  $sql .= " AND sc.fk_user = ".$search_sale;
127  }
128  // Add sql filters
129  if ($sqlfilters)
130  {
131  if (! DolibarrApi::_checkFilters($sqlfilters))
132  {
133  throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
134  }
135  $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
136  $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
137  }
138 
139  $sql.= $db->order($sortfield, $sortorder);
140  if ($limit) {
141  if ($page < 0)
142  {
143  $page = 0;
144  }
145  $offset = $limit * $page;
146 
147  $sql.= $db->plimit($limit + 1, $offset);
148  }
149 
150  dol_syslog("API Rest request");
151  $result = $db->query($sql);
152 
153  if ($result)
154  {
155  $num = $db->num_rows($result);
156  $min = min($num, ($limit <= 0 ? $num : $limit));
157  $i = 0;
158  while ($i < $min)
159  {
160  $obj = $db->fetch_object($result);
161  $proposal_static = new Propal($db);
162  if($proposal_static->fetch($obj->rowid)) {
163  // Add external contacts ids
164  $proposal_static->contacts_ids = $proposal_static->liste_contact(-1,'external',1);
165  $obj_ret[] = $this->_cleanObjectDatas($proposal_static);
166  }
167  $i++;
168  }
169  }
170  else {
171  throw new RestException(503, 'Error when retrieve propal list : '.$db->lasterror());
172  }
173  if( ! count($obj_ret)) {
174  throw new RestException(404, 'No proposal found');
175  }
176  return $obj_ret;
177  }
178 
185  function post($request_data = null)
186  {
187  if(! DolibarrApiAccess::$user->rights->propal->creer) {
188  throw new RestException(401, "Insuffisant rights");
189  }
190  // Check mandatory fields
191  $result = $this->_validate($request_data);
192 
193  foreach($request_data as $field => $value) {
194  $this->propal->$field = $value;
195  }
196  /*if (isset($request_data["lines"])) {
197  $lines = array();
198  foreach ($request_data["lines"] as $line) {
199  array_push($lines, (object) $line);
200  }
201  $this->propal->lines = $lines;
202  }*/
203  if ($this->propal->create(DolibarrApiAccess::$user) < 0) {
204  throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors));
205  }
206 
207  return $this->propal->id;
208  }
209 
219  function getLines($id)
220  {
221  if(! DolibarrApiAccess::$user->rights->propal->lire) {
222  throw new RestException(401);
223  }
224 
225  $result = $this->propal->fetch($id);
226  if( ! $result ) {
227  throw new RestException(404, 'Commercial Proposal not found');
228  }
229 
230  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
231  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
232  }
233  $this->propal->getLinesArray();
234  $result = array();
235  foreach ($this->propal->lines as $line) {
236  array_push($result,$this->_cleanObjectDatas($line));
237  }
238  return $result;
239  }
240 
251  function postLine($id, $request_data = null)
252  {
253  if(! DolibarrApiAccess::$user->rights->propal->creer) {
254  throw new RestException(401);
255  }
256 
257  $result = $this->propal->fetch($id);
258  if (! $result) {
259  throw new RestException(404, 'Commercial Proposal not found');
260  }
261 
262  if (! DolibarrApi::_checkAccessToResource('propal',$this->propal->id))
263  {
264  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
265  }
266 
267  $request_data = (object) $request_data;
268 
269  $updateRes = $this->propal->addline(
270  $request_data->desc,
271  $request_data->subprice,
272  $request_data->qty,
273  $request_data->tva_tx,
274  $request_data->localtax1_tx,
275  $request_data->localtax2_tx,
276  $request_data->fk_product,
277  $request_data->remise_percent,
278  'HT',
279  0,
280  $request_data->info_bits,
281  $request_data->product_type,
282  $request_data->rang,
283  $request_data->special_code,
284  $request_data->fk_parent_line,
285  $request_data->fk_fournprice,
286  $request_data->pa_ht,
287  $request_data->label,
288  $request_data->date_start,
289  $request_data->date_end,
290  $request_data->array_options,
291  $request_data->fk_unit,
292  $request_data->origin,
293  $request_data->origin_id,
294  $request_data->multicurrency_subprice,
295  $request_data->fk_remise_except
296  );
297 
298  if ($updateRes > 0) {
299  return $updateRes;
300  }
301  else {
302  throw new RestException(400, $this->propal->error);
303  }
304  }
305 
317  function putLine($id, $lineid, $request_data = null)
318  {
319  if(! DolibarrApiAccess::$user->rights->propal->creer) {
320  throw new RestException(401);
321  }
322 
323  $result = $this->propal->fetch($id);
324  if($result <= 0) {
325  throw new RestException(404, 'Proposal not found');
326  }
327 
328  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
329  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
330  }
331 
332  $request_data = (object) $request_data;
333 
334  $propalline = new PropaleLigne($this->db);
335  $result = $propalline->fetch($lineid);
336  if ($result <= 0) {
337  throw new RestException(404, 'Proposal line not found');
338  }
339 
340  $updateRes = $this->propal->updateline(
341  $lineid,
342  isset($request_data->subprice)?$request_data->subprice:$propalline->subprice,
343  isset($request_data->qty)?$request_data->qty:$propalline->qty,
344  isset($request_data->remise_percent)?$request_data->remise_percent:$propalline->remise_percent,
345  isset($request_data->tva_tx)?$request_data->tva_tx:$propalline->tva_tx,
346  isset($request_data->localtax1_tx)?$request_data->localtax1_tx:$propalline->localtax1_tx,
347  isset($request_data->localtax2_tx)?$request_data->localtax2_tx:$propalline->localtax2_tx,
348  isset($request_data->desc)?$request_data->desc:$propalline->desc,
349  'HT',
350  isset($request_data->info_bits)?$request_data->info_bits:$propalline->info_bits,
351  isset($request_data->special_code)?$request_data->special_code:$propalline->special_code,
352  isset($request_data->fk_parent_line)?$request_data->fk_parent_line:$propalline->fk_parent_line,
353  0,
354  isset($request_data->fk_fournprice)?$request_data->fk_fournprice:$propalline->fk_fournprice,
355  isset($request_data->pa_ht)?$request_data->pa_ht:$propalline->pa_ht,
356  isset($request_data->label)?$request_data->label:$propalline->label,
357  isset($request_data->product_type)?$request_data->product_type:$propalline->product_type,
358  isset($request_data->date_start)?$request_data->date_start:$propalline->date_start,
359  isset($request_data->date_end)?$request_data->date_end:$propalline->date_end,
360  isset($request_data->array_options)?$request_data->array_options:$propalline->array_options,
361  isset($request_data->fk_unit)?$request_data->fk_unit:$propalline->fk_unit,
362  isset($request_data->multicurrency_subprice)?$request_data->multicurrency_subprice:$propalline->subprice
363  );
364 
365  if ($updateRes > 0) {
366  $result = $this->get($id);
367  unset($result->line);
368  return $this->_cleanObjectDatas($result);
369  }
370  return false;
371  }
372 
386  function deleteLine($id, $lineid)
387  {
388  if(! DolibarrApiAccess::$user->rights->propal->creer) {
389  throw new RestException(401);
390  }
391 
392  $result = $this->propal->fetch($id);
393  if( ! $result ) {
394  throw new RestException(404, 'Proposal not found');
395  }
396 
397  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
398  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
399  }
400 
401  // TODO Check the lineid $lineid is a line of ojbect
402 
403  $updateRes = $this->propal->deleteline($lineid);
404  if ($updateRes > 0) {
405  return $this->get($id);
406  }
407  else
408  {
409  throw new RestException(405, $this->propal->error);
410  }
411  }
412 
421  function put($id, $request_data = null)
422  {
423  if(! DolibarrApiAccess::$user->rights->propal->creer) {
424  throw new RestException(401);
425  }
426 
427  $result = $this->propal->fetch($id);
428  if( ! $result ) {
429  throw new RestException(404, 'Proposal not found');
430  }
431 
432  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
433  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
434  }
435  foreach($request_data as $field => $value) {
436  if ($field == 'id') continue;
437  $this->propal->$field = $value;
438  }
439 
440  // update end of validity date
441  if (empty($this->propal->fin_validite) && !empty($this->propal->duree_validite) && !empty($this->propal->date_creation))
442  {
443  $this->propal->fin_validite = $this->propal->date_creation + ($this->propal->duree_validite * 24 * 3600);
444  }
445  if (!empty($this->propal->fin_validite))
446  {
447  if($this->propal->set_echeance(DolibarrApiAccess::$user, $this->propal->fin_validite)<0)
448  {
449  throw new RestException(500, $this->propal->error);
450  }
451  }
452 
453  if ($this->propal->update(DolibarrApiAccess::$user) > 0)
454  {
455  return $this->get($id);
456  }
457  else
458  {
459  throw new RestException(500, $this->propal->error);
460  }
461  }
462 
470  function delete($id)
471  {
472  if(! DolibarrApiAccess::$user->rights->propal->supprimer) {
473  throw new RestException(401);
474  }
475  $result = $this->propal->fetch($id);
476  if( ! $result ) {
477  throw new RestException(404, 'Commercial Proposal not found');
478  }
479 
480  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
481  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
482  }
483 
484  if( ! $this->propal->delete(DolibarrApiAccess::$user)) {
485  throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error);
486  }
487 
488  return array(
489  'success' => array(
490  'code' => 200,
491  'message' => 'Commercial Proposal deleted'
492  )
493  );
494  }
495 
505  function settodraft($id)
506  {
507  if(! DolibarrApiAccess::$user->rights->propal->creer) {
508  throw new RestException(401);
509  }
510  $result = $this->propal->fetch($id);
511  if( ! $result ) {
512  throw new RestException(404, 'Proposal not found');
513  }
514 
515  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
516  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
517  }
518 
519  $result = $this->propal->set_draft(DolibarrApiAccess::$user);
520  if ($result == 0) {
521  throw new RestException(304, 'Nothing done. May be object is already draft');
522  }
523  if ($result < 0) {
524  throw new RestException(500, 'Error : '.$this->propal->error);
525  }
526 
527  $result = $this->propal->fetch($id);
528  if( ! $result ) {
529  throw new RestException(404, 'Proposal not found');
530  }
531 
532  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
533  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
534  }
535 
536  $this->propal->fetchObjectLinked();
537 
538  return $this->_cleanObjectDatas($this->propal);
539  }
540 
541 
562  function validate($id, $notrigger=0)
563  {
564  if(! DolibarrApiAccess::$user->rights->propal->creer) {
565  throw new RestException(401);
566  }
567  $result = $this->propal->fetch($id);
568  if( ! $result ) {
569  throw new RestException(404, 'Commercial Proposal not found');
570  }
571 
572  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
573  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
574  }
575 
576  $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger);
577  if ($result == 0) {
578  throw new RestException(304, 'Error nothing done. May be object is already validated');
579  }
580  if ($result < 0) {
581  throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error);
582  }
583 
584  $result = $this->propal->fetch($id);
585  if( ! $result ) {
586  throw new RestException(404, 'Commercial Proposal not found');
587  }
588 
589  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
590  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
591  }
592 
593  $this->propal->fetchObjectLinked();
594 
595  return $this->_cleanObjectDatas($this->propal);
596  }
597 
610  function close($id, $status, $note_private='', $notrigger=0)
611  {
612  if(! DolibarrApiAccess::$user->rights->propal->creer) {
613  throw new RestException(401);
614  }
615  $result = $this->propal->fetch($id);
616  if( ! $result ) {
617  throw new RestException(404, 'Commercial Proposal not found');
618  }
619 
620  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
621  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
622  }
623 
624  $result = $this->propal->cloture(DolibarrApiAccess::$user, $status, $note_private, $notrigger);
625  if ($result == 0) {
626  throw new RestException(304, 'Error nothing done. May be object is already closed');
627  }
628  if ($result < 0) {
629  throw new RestException(500, 'Error when closing Commercial Proposal: '.$this->propal->error);
630  }
631 
632  $result = $this->propal->fetch($id);
633  if( ! $result ) {
634  throw new RestException(404, 'Proposal not found');
635  }
636 
637  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
638  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
639  }
640 
641  $this->propal->fetchObjectLinked();
642 
643  return $this->_cleanObjectDatas($this->propal);
644  }
645 
655  function setinvoiced($id)
656  {
657  if(! DolibarrApiAccess::$user->rights->propal->creer) {
658  throw new RestException(401);
659  }
660  $result = $this->propal->fetch($id);
661  if( ! $result ) {
662  throw new RestException(404, 'Commercial Proposal not found');
663  }
664 
665  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
666  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
667  }
668 
669  $result = $this->propal->classifyBilled(DolibarrApiAccess::$user );
670  if ($result < 0) {
671  throw new RestException(500, 'Error : '.$this->propal->error);
672  }
673 
674  $result = $this->propal->fetch($id);
675  if( ! $result ) {
676  throw new RestException(404, 'Proposal not found');
677  }
678 
679  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
680  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
681  }
682 
683  $this->propal->fetchObjectLinked();
684 
685  return $this->_cleanObjectDatas($this->propal);
686  }
687 
688 
696  function _validate($data)
697  {
698  $propal = array();
699  foreach (Proposals::$FIELDS as $field) {
700  if (!isset($data[$field]))
701  throw new RestException(400, "$field field missing");
702  $propal[$field] = $data[$field];
703  }
704  return $propal;
705  }
706 
707 
714  function _cleanObjectDatas($object)
715  {
716 
717  $object = parent::_cleanObjectDatas($object);
718 
719  unset($object->note);
720  unset($object->name);
721  unset($object->lastname);
722  unset($object->firstname);
723  unset($object->civility_id);
724  unset($object->address);
725 
726  return $object;
727  }
728 }
close($id, $status, $note_private='', $notrigger=0)
Close (Accept or refuse) a quote / commercial proposal.
_validate($data)
Validate fields before create or update object.
setinvoiced($id)
Set a commercial proposal billed.
getLines($id)
Get lines of a commercial proposal.
_checkFilters($sqlfilters)
Return if a $sqlfilters parameter is valid.
Definition: api.class.php:251
Class for API REST v1.
Definition: api.class.php:29
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
deleteLine($id, $lineid)
Delete a line of given commercial proposal.
postLine($id, $request_data=null)
Add a line to given commercial proposal.
Class to manage commercial proposal lines.
putLine($id, $lineid, $request_data=null)
Update a line of given commercial proposal.
post($request_data=null)
Create commercial proposal object.
put($id, $request_data=null)
Update commercial proposal general fields (won&#39;t touch lines of commercial proposal) ...
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
Check user access to a resource.
Definition: api.class.php:225
_cleanObjectDatas($object)
Clean sensible object datas.
validate($id, $notrigger=0)
Validate a commercial proposal.
Class to manage proposals.
__construct()
Constructor.
settodraft($id)
Set a proposal to draft.