dolibarr  17.0.4
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  try {
116  return $this->getCommon(0, '', $ref);
117  } catch (Exception $e) {
118  throw $e;
119  }
120  }
121 
131  private function getCommon($id = 0, $track_id = '', $ref = '')
132  {
133  if (!DolibarrApiAccess::$user->rights->ticket->read) {
134  throw new RestException(403);
135  }
136 
137  // Check parameters
138  if (($id < 0) && !$track_id && !$ref) {
139  throw new RestException(401, 'Wrong parameters');
140  }
141  if ($id == 0) {
142  $result = $this->ticket->initAsSpecimen();
143  } else {
144  $result = $this->ticket->fetch($id, $ref, $track_id);
145  }
146  if (!$result) {
147  throw new RestException(404, 'Ticket not found');
148  }
149 
150  // String for user assigned
151  if ($this->ticket->fk_user_assign > 0) {
152  $userStatic = new User($this->db);
153  $userStatic->fetch($this->ticket->fk_user_assign);
154  $this->ticket->fk_user_assign_string = $userStatic->firstname.' '.$userStatic->lastname;
155  }
156 
157  // Messages of ticket
158  $messages = array();
159  $this->ticket->loadCacheMsgsTicket();
160  if (is_array($this->ticket->cache_msgs_ticket) && count($this->ticket->cache_msgs_ticket) > 0) {
161  $num = count($this->ticket->cache_msgs_ticket);
162  $i = 0;
163  while ($i < $num) {
164  if ($this->ticket->cache_msgs_ticket[$i]['fk_user_author'] > 0) {
165  $user_action = new User($this->db);
166  $user_action->fetch($this->ticket->cache_msgs_ticket[$i]['fk_user_author']);
167  }
168 
169  // Now define messages
170  $messages[] = array(
171  'id' => $this->ticket->cache_msgs_ticket[$i]['id'],
172  'fk_user_action' => $this->ticket->cache_msgs_ticket[$i]['fk_user_author'],
173  'fk_user_action_socid' => $user_action->socid,
174  'fk_user_action_string' => dolGetFirstLastname($user_action->firstname, $user_action->lastname),
175  'message' => $this->ticket->cache_msgs_ticket[$i]['message'],
176  'datec' => $this->ticket->cache_msgs_ticket[$i]['datec'],
177  'private' => $this->ticket->cache_msgs_ticket[$i]['private']
178  );
179  $i++;
180  }
181  $this->ticket->messages = $messages;
182  }
183 
184  if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) {
185  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
186  }
187  return $this->_cleanObjectDatas($this->ticket);
188  }
189 
205  public function index($socid = 0, $sortfield = "t.rowid", $sortorder = "ASC", $limit = 100, $page = 0, $sqlfilters = '')
206  {
207  global $db, $conf;
208 
209  if (!DolibarrApiAccess::$user->rights->ticket->read) {
210  throw new RestException(403);
211  }
212 
213  $obj_ret = array();
214 
215  if (!$socid && DolibarrApiAccess::$user->socid) {
216  $socid = DolibarrApiAccess::$user->socid;
217  }
218 
219  $search_sale = null;
220  // If the internal user must only see his customers, force searching by him
221  $search_sale = 0;
222  if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) {
223  $search_sale = DolibarrApiAccess::$user->id;
224  }
225 
226  $sql = "SELECT t.rowid";
227  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
228  $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)
229  }
230  $sql .= " FROM ".MAIN_DB_PREFIX."ticket as t";
231 
232  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
233  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
234  }
235 
236  $sql .= ' WHERE t.entity IN ('.getEntity('ticket', 1).')';
237  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
238  $sql .= " AND t.fk_soc = sc.fk_soc";
239  }
240  if ($socid > 0) {
241  $sql .= " AND t.fk_soc = ".((int) $socid);
242  }
243  if ($search_sale > 0) {
244  $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
245  }
246 
247  // Insert sale filter
248  if ($search_sale > 0) {
249  $sql .= " AND sc.fk_user = ".((int) $search_sale);
250  }
251  // Add sql filters
252  if ($sqlfilters) {
253  $errormessage = '';
254  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
255  if ($errormessage) {
256  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
257  }
258  }
259 
260  $sql .= $this->db->order($sortfield, $sortorder);
261 
262  if ($limit) {
263  if ($page < 0) {
264  $page = 0;
265  }
266  $offset = $limit * $page;
267 
268  $sql .= $this->db->plimit($limit, $offset);
269  }
270 
271  $result = $this->db->query($sql);
272  if ($result) {
273  $num = $this->db->num_rows($result);
274  $i = 0;
275  while ($i < $num) {
276  $obj = $this->db->fetch_object($result);
277  $ticket_static = new Ticket($this->db);
278  if ($ticket_static->fetch($obj->rowid)) {
279  if ($ticket_static->fk_user_assign > 0) {
280  $userStatic = new User($this->db);
281  $userStatic->fetch($ticket_static->fk_user_assign);
282  $ticket_static->fk_user_assign_string = $userStatic->firstname.' '.$userStatic->lastname;
283  }
284  $obj_ret[] = $this->_cleanObjectDatas($ticket_static);
285  }
286  $i++;
287  }
288  } else {
289  throw new RestException(503, 'Error when retrieve ticket list');
290  }
291  if (!count($obj_ret)) {
292  throw new RestException(404, 'No ticket found');
293  }
294  return $obj_ret;
295  }
296 
303  public function post($request_data = null)
304  {
305  $ticketstatic = new Ticket($this->db);
306  if (!DolibarrApiAccess::$user->rights->ticket->write) {
307  throw new RestException(401);
308  }
309  // Check mandatory fields
310  $result = $this->_validate($request_data);
311 
312  foreach ($request_data as $field => $value) {
313  $this->ticket->$field = $value;
314  }
315  if (empty($this->ticket->ref)) {
316  $this->ticket->ref = $ticketstatic->getDefaultRef();
317  }
318  if (empty($this->ticket->track_id)) {
319  $this->ticket->track_id = generate_random_id(16);
320  }
321 
322  if ($this->ticket->create(DolibarrApiAccess::$user) < 0) {
323  throw new RestException(500, "Error creating ticket", array_merge(array($this->ticket->error), $this->ticket->errors));
324  }
325 
326  return $this->ticket->id;
327  }
328 
336  public function postNewMessage($request_data = null)
337  {
338  $ticketstatic = new Ticket($this->db);
339  if (!DolibarrApiAccess::$user->rights->ticket->write) {
340  throw new RestException(401);
341  }
342  // Check mandatory fields
343  $result = $this->_validateMessage($request_data);
344 
345  foreach ($request_data as $field => $value) {
346  $this->ticket->$field = $value;
347  }
348  $ticketMessageText = $this->ticket->message;
349  $result = $this->ticket->fetch('', '', $this->ticket->track_id);
350  if (!$result) {
351  throw new RestException(404, 'Ticket not found');
352  }
353  $this->ticket->message = $ticketMessageText;
354  if (!$this->ticket->createTicketMessage(DolibarrApiAccess::$user)) {
355  throw new RestException(500, 'Error when creating ticket');
356  }
357  return $this->ticket->id;
358  }
359 
368  public function put($id, $request_data = null)
369  {
370  if (!DolibarrApiAccess::$user->rights->ticket->write) {
371  throw new RestException(401);
372  }
373 
374  $result = $this->ticket->fetch($id);
375  if (!$result) {
376  throw new RestException(404, 'Ticket not found');
377  }
378 
379  if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) {
380  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
381  }
382 
383  foreach ($request_data as $field => $value) {
384  $this->ticket->$field = $value;
385  }
386 
387  if ($this->ticket->update($id, DolibarrApiAccess::$user)) {
388  return $this->get($id);
389  }
390 
391  return false;
392  }
393 
401  public function delete($id)
402  {
403  if (!DolibarrApiAccess::$user->rights->ticket->delete) {
404  throw new RestException(401);
405  }
406  $result = $this->ticket->fetch($id);
407  if (!$result) {
408  throw new RestException(404, 'Ticket not found');
409  }
410 
411  if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) {
412  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
413  }
414 
415  if (!$this->ticket->delete($id)) {
416  throw new RestException(500, 'Error when deleting ticket');
417  }
418 
419  return array(
420  'success' => array(
421  'code' => 200,
422  'message' => 'Ticket deleted'
423  )
424  );
425  }
426 
435  private function _validate($data)
436  {
437  $ticket = array();
438  foreach (Tickets::$FIELDS as $field) {
439  if (!isset($data[$field])) {
440  throw new RestException(400, "$field field missing");
441  }
442  $ticket[$field] = $data[$field];
443  }
444  return $ticket;
445  }
446 
455  private function _validateMessage($data)
456  {
457  $ticket = array();
458  foreach (Tickets::$FIELDS_MESSAGES as $field) {
459  if (!isset($data[$field])) {
460  throw new RestException(400, "$field field missing");
461  }
462  $ticket[$field] = $data[$field];
463  }
464  return $ticket;
465  }
466 
467  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
477  protected function _cleanObjectDatas($object)
478  {
479  // phpcs:enable
480  $object = parent::_cleanObjectDatas($object);
481 
482  // Other attributes to clean
483  $attr2clean = array(
484  "contact",
485  "contact_id",
486  "ref_previous",
487  "ref_next",
488  "ref_ext",
489  "table_element_line",
490  "statut",
491  "country",
492  "country_id",
493  "country_code",
494  "barcode_type",
495  "barcode_type_code",
496  "barcode_type_label",
497  "barcode_type_coder",
498  "mode_reglement_id",
499  "cond_reglement_id",
500  "cond_reglement",
501  "fk_delivery_address",
502  "shipping_method_id",
503  "modelpdf",
504  "fk_account",
505  "note_public",
506  "note_private",
507  "note",
508  "total_ht",
509  "total_tva",
510  "total_localtax1",
511  "total_localtax2",
512  "total_ttc",
513  "fk_incoterms",
514  "label_incoterms",
515  "location_incoterms",
516  "name",
517  "lastname",
518  "firstname",
519  "civility_id",
520  "canvas",
521  "cache_msgs_ticket",
522  "cache_logs_ticket",
523  "cache_types_tickets",
524  "cache_category_tickets",
525  "regeximgext",
526  "statuts_short",
527  "statuts"
528  );
529  foreach ($attr2clean as $toclean) {
530  unset($object->$toclean);
531  }
532 
533  // If object has lines, remove $db property
534  if (isset($object->lines) && count($object->lines) > 0) {
535  $nboflines = count($object->lines);
536  for ($i = 0; $i < $nboflines; $i++) {
537  $this->_cleanObjectDatas($object->lines[$i]);
538  }
539  }
540 
541  // If object has linked objects, remove $db property
542  if (isset($object->linkedObjects) && count($object->linkedObjects) > 0) {
543  foreach ($object->linkedObjects as $type_object => $linked_object) {
544  foreach ($linked_object as $object2clean) {
545  $this->_cleanObjectDatas($object2clean);
546  }
547  }
548  }
549  return $object;
550  }
551 }
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:283
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:47
forgeSQLFromUniversalSearchCriteria($filter, &$error='')
forgeSQLFromUniversalSearchCriteria
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
Class to generate the form for creating a new ticket.
$conf db
API class for accounts.
Definition: inc.php:41
generate_random_id($car=16)
Generate a random id.
Definition: ticket.lib.php:194