dolibarr  19.0.0-dev
api_tickets.class.php
1 <?php
2 /* Copyright (C) 2016 Jean-François Ferry <hello@librethic.io>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18  use Luracast\Restler\RestException;
19 
20 require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
21 require_once DOL_DOCUMENT_ROOT.'/core/lib/ticket.lib.php';
22 
23 
30 class Tickets extends DolibarrApi
31 {
35  public static $FIELDS = array(
36  'subject',
37  'message'
38  );
39 
43  public static $FIELDS_MESSAGES = array(
44  'track_id',
45  'message'
46  );
47 
51  public $ticket;
52 
56  public function __construct()
57  {
58  global $db;
59  $this->db = $db;
60  $this->ticket = new Ticket($this->db);
61  }
62 
75  public function get($id)
76  {
77  return $this->getCommon($id, '', '');
78  }
79 
94  public function getByTrackId($track_id)
95  {
96  return $this->getCommon(0, $track_id, '');
97  }
98 
113  public function getByRef($ref)
114  {
115  return $this->getCommon(0, '', $ref);
116  }
117 
127  private function getCommon($id = 0, $track_id = '', $ref = '')
128  {
129  if (!DolibarrApiAccess::$user->rights->ticket->read) {
130  throw new RestException(403);
131  }
132 
133  // Check parameters
134  if (($id < 0) && !$track_id && !$ref) {
135  throw new RestException(401, 'Wrong parameters');
136  }
137  if ($id == 0) {
138  $result = $this->ticket->initAsSpecimen();
139  } else {
140  $result = $this->ticket->fetch($id, $ref, $track_id);
141  }
142  if (!$result) {
143  throw new RestException(404, 'Ticket not found');
144  }
145 
146  // String for user assigned
147  if ($this->ticket->fk_user_assign > 0) {
148  $userStatic = new User($this->db);
149  $userStatic->fetch($this->ticket->fk_user_assign);
150  $this->ticket->fk_user_assign_string = $userStatic->firstname.' '.$userStatic->lastname;
151  }
152 
153  // Messages of ticket
154  $messages = array();
155  $this->ticket->loadCacheMsgsTicket();
156  if (is_array($this->ticket->cache_msgs_ticket) && count($this->ticket->cache_msgs_ticket) > 0) {
157  $num = count($this->ticket->cache_msgs_ticket);
158  $i = 0;
159  while ($i < $num) {
160  if ($this->ticket->cache_msgs_ticket[$i]['fk_user_author'] > 0) {
161  $user_action = new User($this->db);
162  $user_action->fetch($this->ticket->cache_msgs_ticket[$i]['fk_user_author']);
163  }
164 
165  // Now define messages
166  $messages[] = array(
167  'id' => $this->ticket->cache_msgs_ticket[$i]['id'],
168  'fk_user_action' => $this->ticket->cache_msgs_ticket[$i]['fk_user_author'],
169  'fk_user_action_socid' => $user_action->socid,
170  'fk_user_action_string' => dolGetFirstLastname($user_action->firstname, $user_action->lastname),
171  'message' => $this->ticket->cache_msgs_ticket[$i]['message'],
172  'datec' => $this->ticket->cache_msgs_ticket[$i]['datec'],
173  'private' => $this->ticket->cache_msgs_ticket[$i]['private']
174  );
175  $i++;
176  }
177  $this->ticket->messages = $messages;
178  }
179 
180  if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) {
181  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
182  }
183  return $this->_cleanObjectDatas($this->ticket);
184  }
185 
201  public function index($socid = 0, $sortfield = "t.rowid", $sortorder = "ASC", $limit = 100, $page = 0, $sqlfilters = '')
202  {
203  global $db, $conf;
204 
205  if (!DolibarrApiAccess::$user->rights->ticket->read) {
206  throw new RestException(403);
207  }
208 
209  $obj_ret = array();
210 
211  if (!$socid && DolibarrApiAccess::$user->socid) {
212  $socid = DolibarrApiAccess::$user->socid;
213  }
214 
215  $search_sale = null;
216  // If the internal user must only see his customers, force searching by him
217  $search_sale = 0;
218  if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) {
219  $search_sale = DolibarrApiAccess::$user->id;
220  }
221 
222  $sql = "SELECT t.rowid";
223  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
224  $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)
225  }
226  $sql .= " FROM ".MAIN_DB_PREFIX."ticket AS t LEFT JOIN ".MAIN_DB_PREFIX."ticket_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
227 
228  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
229  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
230  }
231 
232  $sql .= ' WHERE t.entity IN ('.getEntity('ticket', 1).')';
233  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
234  $sql .= " AND t.fk_soc = sc.fk_soc";
235  }
236  if ($socid > 0) {
237  $sql .= " AND t.fk_soc = ".((int) $socid);
238  }
239  if ($search_sale > 0) {
240  $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
241  }
242 
243  // Insert sale filter
244  if ($search_sale > 0) {
245  $sql .= " AND sc.fk_user = ".((int) $search_sale);
246  }
247  // Add sql filters
248  if ($sqlfilters) {
249  $errormessage = '';
250  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
251  if ($errormessage) {
252  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
253  }
254  }
255 
256  $sql .= $this->db->order($sortfield, $sortorder);
257 
258  if ($limit) {
259  if ($page < 0) {
260  $page = 0;
261  }
262  $offset = $limit * $page;
263 
264  $sql .= $this->db->plimit($limit, $offset);
265  }
266 
267  $result = $this->db->query($sql);
268  if ($result) {
269  $num = $this->db->num_rows($result);
270  $i = 0;
271  while ($i < $num) {
272  $obj = $this->db->fetch_object($result);
273  $ticket_static = new Ticket($this->db);
274  if ($ticket_static->fetch($obj->rowid)) {
275  if ($ticket_static->fk_user_assign > 0) {
276  $userStatic = new User($this->db);
277  $userStatic->fetch($ticket_static->fk_user_assign);
278  $ticket_static->fk_user_assign_string = $userStatic->firstname.' '.$userStatic->lastname;
279  }
280  $obj_ret[] = $this->_cleanObjectDatas($ticket_static);
281  }
282  $i++;
283  }
284  } else {
285  throw new RestException(503, 'Error when retrieve ticket list');
286  }
287  if (!count($obj_ret)) {
288  throw new RestException(404, 'No ticket found');
289  }
290  return $obj_ret;
291  }
292 
299  public function post($request_data = null)
300  {
301  $ticketstatic = new Ticket($this->db);
302  if (!DolibarrApiAccess::$user->rights->ticket->write) {
303  throw new RestException(401);
304  }
305  // Check mandatory fields
306  $result = $this->_validate($request_data);
307 
308  foreach ($request_data as $field => $value) {
309  $this->ticket->$field = $value;
310  }
311  if (empty($this->ticket->ref)) {
312  $this->ticket->ref = $ticketstatic->getDefaultRef();
313  }
314  if (empty($this->ticket->track_id)) {
315  $this->ticket->track_id = generate_random_id(16);
316  }
317 
318  if ($this->ticket->create(DolibarrApiAccess::$user) < 0) {
319  throw new RestException(500, "Error creating ticket", array_merge(array($this->ticket->error), $this->ticket->errors));
320  }
321 
322  return $this->ticket->id;
323  }
324 
332  public function postNewMessage($request_data = null)
333  {
334  $ticketstatic = new Ticket($this->db);
335  if (!DolibarrApiAccess::$user->rights->ticket->write) {
336  throw new RestException(401);
337  }
338  // Check mandatory fields
339  $result = $this->_validateMessage($request_data);
340 
341  foreach ($request_data as $field => $value) {
342  $this->ticket->$field = $value;
343  }
344  $ticketMessageText = $this->ticket->message;
345  $result = $this->ticket->fetch('', '', $this->ticket->track_id);
346  if (!$result) {
347  throw new RestException(404, 'Ticket not found');
348  }
349  $this->ticket->message = $ticketMessageText;
350  if (!$this->ticket->createTicketMessage(DolibarrApiAccess::$user)) {
351  throw new RestException(500, 'Error when creating ticket');
352  }
353  return $this->ticket->id;
354  }
355 
364  public function put($id, $request_data = null)
365  {
366  if (!DolibarrApiAccess::$user->rights->ticket->write) {
367  throw new RestException(401);
368  }
369 
370  $result = $this->ticket->fetch($id);
371  if (!$result) {
372  throw new RestException(404, 'Ticket not found');
373  }
374 
375  if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) {
376  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
377  }
378 
379  foreach ($request_data as $field => $value) {
380  $this->ticket->$field = $value;
381  }
382 
383  if ($this->ticket->update($id, DolibarrApiAccess::$user)) {
384  return $this->get($id);
385  }
386 
387  return false;
388  }
389 
397  public function delete($id)
398  {
399  if (!DolibarrApiAccess::$user->rights->ticket->delete) {
400  throw new RestException(401);
401  }
402  $result = $this->ticket->fetch($id);
403  if (!$result) {
404  throw new RestException(404, 'Ticket not found');
405  }
406 
407  if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) {
408  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
409  }
410 
411  if (!$this->ticket->delete($id)) {
412  throw new RestException(500, 'Error when deleting ticket');
413  }
414 
415  return array(
416  'success' => array(
417  'code' => 200,
418  'message' => 'Ticket deleted'
419  )
420  );
421  }
422 
431  private function _validate($data)
432  {
433  $ticket = array();
434  foreach (Tickets::$FIELDS as $field) {
435  if (!isset($data[$field])) {
436  throw new RestException(400, "$field field missing");
437  }
438  $ticket[$field] = $data[$field];
439  }
440  return $ticket;
441  }
442 
451  private function _validateMessage($data)
452  {
453  $ticket = array();
454  foreach (Tickets::$FIELDS_MESSAGES as $field) {
455  if (!isset($data[$field])) {
456  throw new RestException(400, "$field field missing");
457  }
458  $ticket[$field] = $data[$field];
459  }
460  return $ticket;
461  }
462 
463  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
473  protected function _cleanObjectDatas($object)
474  {
475  // phpcs:enable
476  $object = parent::_cleanObjectDatas($object);
477 
478  // Other attributes to clean
479  $attr2clean = array(
480  "contact",
481  "contact_id",
482  "ref_previous",
483  "ref_next",
484  "ref_ext",
485  "table_element_line",
486  "statut",
487  "country",
488  "country_id",
489  "country_code",
490  "barcode_type",
491  "barcode_type_code",
492  "barcode_type_label",
493  "barcode_type_coder",
494  "mode_reglement_id",
495  "cond_reglement_id",
496  "cond_reglement",
497  "fk_delivery_address",
498  "shipping_method_id",
499  "modelpdf",
500  "fk_account",
501  "note_public",
502  "note_private",
503  "note",
504  "total_ht",
505  "total_tva",
506  "total_localtax1",
507  "total_localtax2",
508  "total_ttc",
509  "fk_incoterms",
510  "label_incoterms",
511  "location_incoterms",
512  "name",
513  "lastname",
514  "firstname",
515  "civility_id",
516  "canvas",
517  "cache_msgs_ticket",
518  "cache_logs_ticket",
519  "cache_types_tickets",
520  "cache_category_tickets",
521  "regeximgext",
522  "statuts_short",
523  "statuts"
524  );
525  foreach ($attr2clean as $toclean) {
526  unset($object->$toclean);
527  }
528 
529  // If object has lines, remove $db property
530  if (isset($object->lines) && count($object->lines) > 0) {
531  $nboflines = count($object->lines);
532  for ($i = 0; $i < $nboflines; $i++) {
533  $this->_cleanObjectDatas($object->lines[$i]);
534  }
535  }
536 
537  // If object has linked objects, remove $db property
538  if (isset($object->linkedObjects) && count($object->linkedObjects) > 0) {
539  foreach ($object->linkedObjects as $type_object => $linked_object) {
540  foreach ($linked_object as $object2clean) {
541  $this->_cleanObjectDatas($object2clean);
542  }
543  }
544  }
545  return $object;
546  }
547 }
Class for API REST v1.
Definition: api.class.php:31
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
Check access by user to a given resource.
Definition: api.class.php:282
getCommon($id=0, $track_id='', $ref='')
Get properties of a Ticket object Return an array with ticket informations.
getByRef($ref)
Get properties of a Ticket object from ref.
__construct()
Constructor.
_cleanObjectDatas($object)
Clean sensible object datas.
postNewMessage($request_data=null)
Create ticket object.
post($request_data=null)
Create ticket object.
put($id, $request_data=null)
Update ticket.
index($socid=0, $sortfield="t.rowid", $sortorder="ASC", $limit=100, $page=0, $sqlfilters='')
List tickets.
_validateMessage($data)
Validate fields before create or update object message.
getByTrackId($track_id)
Get properties of a Ticket object from track id.
_validate($data)
Validate fields before create or update object.
Class to manage Dolibarr users.
Definition: user.class.php:48
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
Class to generate the form for creating a new ticket.
generate_random_id($car=16)
Generate a random id.
Definition: ticket.lib.php:194