dolibarr  7.0.0-beta
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 
19 use Luracast\Restler\RestException;
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  $this->propal->fetchObjectLinked();
81  return $this->_cleanObjectDatas($this->propal);
82  }
83 
97  function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
98  global $db, $conf;
99 
100  $obj_ret = array();
101 
102  // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
103  $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids;
104 
105  // If the internal user must only see his customers, force searching by him
106  $search_sale = 0;
107  if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
108 
109  $sql = "SELECT t.rowid";
110  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)
111  $sql.= " FROM ".MAIN_DB_PREFIX."propal as t";
112 
113  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
114 
115  $sql.= ' WHERE t.entity IN ('.getEntity('propal').')';
116  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc";
117  if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")";
118  if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
119  // Insert sale filter
120  if ($search_sale > 0)
121  {
122  $sql .= " AND sc.fk_user = ".$search_sale;
123  }
124  // Add sql filters
125  if ($sqlfilters)
126  {
127  if (! DolibarrApi::_checkFilters($sqlfilters))
128  {
129  throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
130  }
131  $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
132  $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
133  }
134 
135  $sql.= $db->order($sortfield, $sortorder);
136  if ($limit) {
137  if ($page < 0)
138  {
139  $page = 0;
140  }
141  $offset = $limit * $page;
142 
143  $sql.= $db->plimit($limit + 1, $offset);
144  }
145 
146  dol_syslog("API Rest request");
147  $result = $db->query($sql);
148 
149  if ($result)
150  {
151  $num = $db->num_rows($result);
152  $min = min($num, ($limit <= 0 ? $num : $limit));
153  $i = 0;
154  while ($i < $min)
155  {
156  $obj = $db->fetch_object($result);
157  $proposal_static = new Propal($db);
158  if($proposal_static->fetch($obj->rowid)) {
159  $obj_ret[] = $this->_cleanObjectDatas($proposal_static);
160  }
161  $i++;
162  }
163  }
164  else {
165  throw new RestException(503, 'Error when retrieve propal list : '.$db->lasterror());
166  }
167  if( ! count($obj_ret)) {
168  throw new RestException(404, 'No proposal found');
169  }
170  return $obj_ret;
171  }
172 
179  function post($request_data = NULL)
180  {
181  if(! DolibarrApiAccess::$user->rights->propal->creer) {
182  throw new RestException(401, "Insuffisant rights");
183  }
184  // Check mandatory fields
185  $result = $this->_validate($request_data);
186 
187  foreach($request_data as $field => $value) {
188  $this->propal->$field = $value;
189  }
190  /*if (isset($request_data["lines"])) {
191  $lines = array();
192  foreach ($request_data["lines"] as $line) {
193  array_push($lines, (object) $line);
194  }
195  $this->propal->lines = $lines;
196  }*/
197  if ($this->propal->create(DolibarrApiAccess::$user) < 0) {
198  throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors));
199  }
200 
201  return $this->propal->id;
202  }
203 
213  function getLines($id) {
214  if(! DolibarrApiAccess::$user->rights->propal->lire) {
215  throw new RestException(401);
216  }
217 
218  $result = $this->propal->fetch($id);
219  if( ! $result ) {
220  throw new RestException(404, 'Commercial Proposal not found');
221  }
222 
223  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
224  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
225  }
226  $this->propal->getLinesArray();
227  $result = array();
228  foreach ($this->propal->lines as $line) {
229  array_push($result,$this->_cleanObjectDatas($line));
230  }
231  return $result;
232  }
233 
244  function postLine($id, $request_data = NULL)
245  {
246  if(! DolibarrApiAccess::$user->rights->propal->creer) {
247  throw new RestException(401);
248  }
249 
250  $result = $this->propal->fetch($id);
251  if (! $result) {
252  throw new RestException(404, 'Commercial Proposal not found');
253  }
254 
255  if (! DolibarrApi::_checkAccessToResource('propal',$this->propal->id))
256  {
257  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
258  }
259 
260  $request_data = (object) $request_data;
261 
262  $updateRes = $this->propal->addline(
263  $request_data->desc,
264  $request_data->subprice,
265  $request_data->qty,
266  $request_data->tva_tx,
267  $request_data->localtax1_tx,
268  $request_data->localtax2_tx,
269  $request_data->fk_product,
270  $request_data->remise_percent,
271  'HT',
272  0,
273  $request_data->info_bits,
274  $request_data->product_type,
275  $request_data->rang,
276  $request_data->special_code,
277  $request_data->fk_parent_line,
278  $request_data->fk_fournprice,
279  $request_data->pa_ht,
280  $request_data->label,
281  $request_data->date_start,
282  $request_data->date_end,
283  $request_data->array_options,
284  $request_data->fk_unit,
285  $request_data->origin,
286  $request_data->origin_id,
287  $request_data->multicurrency_subprice,
288  $request_data->fk_remise_except
289  );
290 
291  if ($updateRes > 0) {
292  return $updateRes;
293  }
294  else {
295  throw new RestException(400, $this->propal->error);
296  }
297  }
298 
310  function putLine($id, $lineid, $request_data = NULL)
311  {
312  if(! DolibarrApiAccess::$user->rights->propal->creer) {
313  throw new RestException(401);
314  }
315 
316  $result = $this->propal->fetch($id);
317  if($result <= 0) {
318  throw new RestException(404, 'Proposal not found');
319  }
320 
321  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
322  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
323  }
324 
325  $request_data = (object) $request_data;
326 
327  $propalline = new PropaleLigne($this->db);
328  $result = $propalline->fetch($lineid);
329  if ($result <= 0) {
330  throw new RestException(404, 'Proposal line not found');
331  }
332 
333  $updateRes = $this->propal->updateline(
334  $lineid,
335  isset($request_data->subprice)?$request_data->subprice:$propalline->subprice,
336  isset($request_data->qty)?$request_data->qty:$propalline->qty,
337  isset($request_data->remise_percent)?$request_data->remise_percent:$propalline->remise_percent,
338  isset($request_data->tva_tx)?$request_data->tva_tx:$propalline->tva_tx,
339  isset($request_data->localtax1_tx)?$request_data->localtax1_tx:$propalline->localtax1_tx,
340  isset($request_data->localtax2_tx)?$request_data->localtax2_tx:$propalline->localtax2_tx,
341  isset($request_data->desc)?$request_data->desc:$propalline->desc,
342  'HT',
343  isset($request_data->info_bits)?$request_data->info_bits:$propalline->info_bits,
344  isset($request_data->special_code)?$request_data->special_code:$propalline->special_code,
345  isset($request_data->fk_parent_line)?$request_data->fk_parent_line:$propalline->fk_parent_line,
346  0,
347  isset($request_data->fk_fournprice)?$request_data->fk_fournprice:$propalline->fk_fournprice,
348  isset($request_data->pa_ht)?$request_data->pa_ht:$propalline->pa_ht,
349  isset($request_data->label)?$request_data->label:$propalline->label,
350  isset($request_data->product_type)?$request_data->product_type:$propalline->product_type,
351  isset($request_data->date_start)?$request_data->date_start:$propalline->date_start,
352  isset($request_data->date_end)?$request_data->date_end:$propalline->date_end,
353  isset($request_data->array_options)?$request_data->array_options:$propalline->array_options,
354  isset($request_data->fk_unit)?$request_data->fk_unit:$propalline->fk_unit,
355  isset($request_data->multicurrency_subprice)?$request_data->multicurrency_subprice:$propalline->subprice
356  );
357 
358  if ($updateRes > 0) {
359  $result = $this->get($id);
360  unset($result->line);
361  return $this->_cleanObjectDatas($result);
362  }
363  return false;
364  }
365 
379  function deleteLine($id, $lineid) {
380  if(! DolibarrApiAccess::$user->rights->propal->creer) {
381  throw new RestException(401);
382  }
383 
384  $result = $this->propal->fetch($id);
385  if( ! $result ) {
386  throw new RestException(404, 'Proposal not found');
387  }
388 
389  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
390  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
391  }
392 
393  // TODO Check the lineid $lineid is a line of ojbect
394 
395  $updateRes = $this->propal->deleteline($lineid);
396  if ($updateRes > 0) {
397  return $this->get($id);
398  }
399  else
400  {
401  throw new RestException(405, $this->propal->error);
402  }
403  }
404 
413  function put($id, $request_data = NULL) {
414  if(! DolibarrApiAccess::$user->rights->propal->creer) {
415  throw new RestException(401);
416  }
417 
418  $result = $this->propal->fetch($id);
419  if( ! $result ) {
420  throw new RestException(404, 'Proposal not found');
421  }
422 
423  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
424  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
425  }
426  foreach($request_data as $field => $value) {
427  if ($field == 'id') continue;
428  $this->propal->$field = $value;
429  }
430 
431  // update end of validity date
432  if (empty($this->propal->fin_validite) && !empty($this->propal->duree_validite) && !empty($this->propal->date_creation))
433  {
434  $this->propal->fin_validite = $this->propal->date_creation + ($this->propal->duree_validite * 24 * 3600);
435  }
436  if (!empty($this->propal->fin_validite))
437  {
438  if($this->propal->set_echeance(DolibarrApiAccess::$user, $this->propal->fin_validite)<0)
439  {
440  throw new RestException(500, $this->propal->error);
441  }
442  }
443 
444  if ($this->propal->update(DolibarrApiAccess::$user) > 0)
445  {
446  return $this->get($id);
447  }
448  else
449  {
450  throw new RestException(500, $this->propal->error);
451  }
452  }
453 
461  function delete($id)
462  {
463  if(! DolibarrApiAccess::$user->rights->propal->supprimer) {
464  throw new RestException(401);
465  }
466  $result = $this->propal->fetch($id);
467  if( ! $result ) {
468  throw new RestException(404, 'Commercial Proposal not found');
469  }
470 
471  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
472  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
473  }
474 
475  if( ! $this->propal->delete(DolibarrApiAccess::$user)) {
476  throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error);
477  }
478 
479  return array(
480  'success' => array(
481  'code' => 200,
482  'message' => 'Commercial Proposal deleted'
483  )
484  );
485 
486  }
487 
497  function settodraft($id)
498  {
499  if(! DolibarrApiAccess::$user->rights->propal->creer) {
500  throw new RestException(401);
501  }
502  $result = $this->propal->fetch($id);
503  if( ! $result ) {
504  throw new RestException(404, 'Proposal not found');
505  }
506 
507  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
508  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
509  }
510 
511  $result = $this->propal->set_draft(DolibarrApiAccess::$user);
512  if ($result == 0) {
513  throw new RestException(304, 'Nothing done. May be object is already draft');
514  }
515  if ($result < 0) {
516  throw new RestException(500, 'Error : '.$this->propal->error);
517  }
518 
519  $result = $this->propal->fetch($id);
520  if( ! $result ) {
521  throw new RestException(404, 'Proposal not found');
522  }
523 
524  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
525  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
526  }
527 
528  $this->propal->fetchObjectLinked();
529 
530  return $this->_cleanObjectDatas($this->propal);
531  }
532 
533 
554  function validate($id, $notrigger=0)
555  {
556  if(! DolibarrApiAccess::$user->rights->propal->creer) {
557  throw new RestException(401);
558  }
559  $result = $this->propal->fetch($id);
560  if( ! $result ) {
561  throw new RestException(404, 'Commercial Proposal not found');
562  }
563 
564  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
565  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
566  }
567 
568  $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger);
569  if ($result == 0) {
570  throw new RestException(304, 'Error nothing done. May be object is already validated');
571  }
572  if ($result < 0) {
573  throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error);
574  }
575 
576  $result = $this->propal->fetch($id);
577  if( ! $result ) {
578  throw new RestException(404, 'Commercial Proposal not found');
579  }
580 
581  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
582  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
583  }
584 
585  $this->propal->fetchObjectLinked();
586 
587  return $this->_cleanObjectDatas($this->propal);
588  }
589 
602  function close($id, $status, $note_private='', $notrigger=0)
603  {
604  if(! DolibarrApiAccess::$user->rights->propal->creer) {
605  throw new RestException(401);
606  }
607  $result = $this->propal->fetch($id);
608  if( ! $result ) {
609  throw new RestException(404, 'Commercial Proposal not found');
610  }
611 
612  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
613  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
614  }
615 
616  $result = $this->propal->cloture(DolibarrApiAccess::$user, $status, $note_private, $notrigger);
617  if ($result == 0) {
618  throw new RestException(304, 'Error nothing done. May be object is already closed');
619  }
620  if ($result < 0) {
621  throw new RestException(500, 'Error when closing Commercial Proposal: '.$this->propal->error);
622  }
623 
624  $result = $this->propal->fetch($id);
625  if( ! $result ) {
626  throw new RestException(404, 'Proposal not found');
627  }
628 
629  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
630  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
631  }
632 
633  $this->propal->fetchObjectLinked();
634 
635  return $this->_cleanObjectDatas($this->propal);
636  }
637 
647  function setinvoiced($id)
648  {
649  if(! DolibarrApiAccess::$user->rights->propal->creer) {
650  throw new RestException(401);
651  }
652  $result = $this->propal->fetch($id);
653  if( ! $result ) {
654  throw new RestException(404, 'Commercial Proposal not found');
655  }
656 
657  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
658  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
659  }
660 
661  $result = $this->propal->classifyBilled(DolibarrApiAccess::$user );
662  if ($result < 0) {
663  throw new RestException(500, 'Error : '.$this->propal->error);
664  }
665 
666  $result = $this->propal->fetch($id);
667  if( ! $result ) {
668  throw new RestException(404, 'Proposal not found');
669  }
670 
671  if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
672  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
673  }
674 
675  $this->propal->fetchObjectLinked();
676 
677  return $this->_cleanObjectDatas($this->propal);
678  }
679 
680 
688  function _validate($data)
689  {
690  $propal = array();
691  foreach (Proposals::$FIELDS as $field) {
692  if (!isset($data[$field]))
693  throw new RestException(400, "$field field missing");
694  $propal[$field] = $data[$field];
695 
696  }
697  return $propal;
698  }
699 
700 
707  function _cleanObjectDatas($object) {
708 
709  $object = parent::_cleanObjectDatas($object);
710 
711  unset($object->note);
712  unset($object->name);
713  unset($object->lastname);
714  unset($object->firstname);
715  unset($object->civility_id);
716  unset($object->address);
717 
718  return $object;
719  }
720 }
close($id, $status, $note_private='', $notrigger=0)
Close (Accept or refuse) a quote / commercial proposal.
_validate($data)
Validate fields before create or update object.
putLine($id, $lineid, $request_data=NULL)
Update a line of given commercial proposal.
setinvoiced($id)
Set a commercial proposal billed.
post($request_data=NULL)
Create commercial proposal object.
getLines($id)
Get lines of a commercial proposal.
put($id, $request_data=NULL)
Update commercial proposal general fields (won't touch lines of commercial proposal) ...
_checkFilters($sqlfilters)
Return if a $sqlfilters parameter is valid.
Definition: api.class.php:246
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.
Class to manage commercial proposal lines.
postLine($id, $request_data=NULL)
Add a line to given 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:221
_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.