Completed
Branch develop (451d3e)
by
unknown
27:33
created

Contracts::delete()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 5
nop 1
dl 0
loc 26
rs 8.439
c 0
b 0
f 0
1
<?php
2
/* Copyright (C) 2015   Jean-François Ferry     <[email protected]>
3
 * Copyright (C) 2016	Laurent Destailleur		<[email protected]>
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.'/contrat/class/contrat.class.php';
22
23
/**
24
 * API class for contracts
25
 *
26
 * @access protected
27
 * @class  DolibarrApiAccess {@requires user,external}
28
 */
29
class Contracts extends DolibarrApi
30
{
31
32
    /**
33
     * @var array   $FIELDS     Mandatory fields, checked when create and update object
34
     */
35
    static $FIELDS = array(
36
        'socid',
37
    	'date_contrat',
38
    	'commercial_signature_id',
39
    	'commercial_suivi_id'
40
    );
41
42
    /**
43
     * @var Contrat $contract {@type Contrat}
44
     */
45
    public $contract;
46
47
    /**
48
     * Constructor
49
     */
50
    function __construct()
51
    {
52
		global $db, $conf;
53
		$this->db = $db;
54
        $this->contract = new Contrat($this->db);
55
    }
56
57
    /**
58
     * Get properties of a contrat object
59
     *
60
     * Return an array with contrat informations
61
     *
62
     * @param       int         $id         ID of contract
63
     * @return 	array|mixed data without useless information
64
	 *
65
     * @throws 	RestException
66
     */
67
    function get($id)
68
    {
69
		if(! DolibarrApiAccess::$user->rights->contrat->lire) {
70
			throw new RestException(401);
71
		}
72
73
        $result = $this->contract->fetch($id);
74
        if( ! $result ) {
75
            throw new RestException(404, 'Contract not found');
76
        }
77
78
		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
79
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
80
		}
81
82
        $this->contract->fetchObjectLinked();
83
		return $this->_cleanObjectDatas($this->contract);
84
    }
85
86
87
88
    /**
89
     * List contracts
90
     *
91
     * Get a list of contracts
92
     *
93
     * @param string	       $sortfield	        Sort field
94
     * @param string	       $sortorder	        Sort order
95
     * @param int		       $limit		        Limit for list
96
     * @param int		       $page		        Page number
97
     * @param string   	       $thirdparty_ids	    Thirdparty ids to filter contracts of. {@example '1' or '1,2,3'} {@pattern /^[0-9,]*$/i}
98
     * @param string           $sqlfilters          Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
99
     * @return  array                               Array of contract objects
100
     *
101
	 * @throws RestException
102
     */
103
    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
104
        global $db, $conf;
105
106
        $obj_ret = array();
107
108
        // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
109
        $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids;
110
111
        // If the internal user must only see his customers, force searching by him
112
        $search_sale = 0;
113
        if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
114
115
        $sql = "SELECT t.rowid";
116
        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)
117
        $sql.= " FROM ".MAIN_DB_PREFIX."contrat as t";
118
119
        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
120
121
        $sql.= ' WHERE t.entity IN ('.getEntity('contrat').')';
122
        if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc";
123
        if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")";
124
        if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc";		// Join for the needed table to filter by sale
125
        // Insert sale filter
126
        if ($search_sale > 0)
127
        {
128
            $sql .= " AND sc.fk_user = ".$search_sale;
129
        }
130
        // Add sql filters
131
        if ($sqlfilters)
132
        {
133
            if (! DolibarrApi::_checkFilters($sqlfilters))
134
            {
135
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
136
            }
137
	        $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
138
            $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
139
        }
140
141
        $sql.= $db->order($sortfield, $sortorder);
142
        if ($limit)	{
143
            if ($page < 0)
144
            {
145
                $page = 0;
146
            }
147
            $offset = $limit * $page;
148
149
            $sql.= $db->plimit($limit + 1, $offset);
150
        }
151
152
        dol_syslog("API Rest request");
153
        $result = $db->query($sql);
154
155
        if ($result)
156
        {
157
            $num = $db->num_rows($result);
158
            $min = min($num, ($limit <= 0 ? $num : $limit));
159
            $i=0;
160
            while ($i < $min)
161
            {
162
                $obj = $db->fetch_object($result);
163
                $contrat_static = new Contrat($db);
164
                if($contrat_static->fetch($obj->rowid)) {
165
                    $obj_ret[] = $this->_cleanObjectDatas($contrat_static);
166
                }
167
                $i++;
168
            }
169
        }
170
        else {
171
            throw new RestException(503, 'Error when retrieve contrat list : '.$db->lasterror());
172
        }
173
        if( ! count($obj_ret)) {
174
            throw new RestException(404, 'No contract found');
175
        }
176
		return $obj_ret;
177
    }
178
179
    /**
180
     * Create contract object
181
     *
182
     * @param   array   $request_data   Request data
183
     * @return  int     ID of contrat
184
     */
185
    function post($request_data = NULL)
186
    {
187
      if(! DolibarrApiAccess::$user->rights->contrat->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->contract->$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->contract->lines = $lines;
202
        }*/
203
        if ($this->contract->create(DolibarrApiAccess::$user) < 0) {
204
            throw new RestException(500, "Error creating contract", array_merge(array($this->contract->error), $this->contract->errors));
205
        }
206
207
        return $this->contract->id;
208
    }
209
210
    /**
211
     * Get lines of a contract
212
     *
213
     * @param int   $id             Id of contract
214
     *
215
     * @url	GET {id}/lines
216
     *
217
     * @return int
218
     */
219
    function getLines($id) {
220
      if(! DolibarrApiAccess::$user->rights->contrat->lire) {
221
		  	throw new RestException(401);
222
		  }
223
224
      $result = $this->contract->fetch($id);
225
      if( ! $result ) {
226
         throw new RestException(404, 'Contract not found');
227
      }
228
229
		  if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
230
			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
231
      }
232
      $this->contract->getLinesArray();
233
      $result = array();
234
      foreach ($this->contract->lines as $line) {
235
        array_push($result,$this->_cleanObjectDatas($line));
236
      }
237
      return $result;
238
    }
239
240
    /**
241
     * Add a line to given contract
242
     *
243
     * @param int   $id             Id of contrat to update
244
     * @param array $request_data   Contractline data
245
     *
246
     * @url	POST {id}/lines
247
     *
248
     * @return int
249
     */
250
    function postLine($id, $request_data = NULL) {
251
      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
252
		  	throw new RestException(401);
253
		  }
254
255
      $result = $this->contract->fetch($id);
256
      if( ! $result ) {
257
         throw new RestException(404, 'Contract not found');
258
      }
259
260
		  if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
261
			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
262
      }
263
			$request_data = (object) $request_data;
264
      $updateRes = $this->contract->addline(
265
                        $request_data->desc,
266
                        $request_data->subprice,
267
                        $request_data->qty,
268
                        $request_data->tva_tx,
269
                        $request_data->localtax1_tx,
270
                        $request_data->localtax2_tx,
271
                        $request_data->fk_product,
272
                        $request_data->remise_percent,
273
                        $request_data->date_start,			// date_start = date planned start, date ouverture = date_start_real
274
                        $request_data->date_end,			// date_end = date planned end, date_cloture = date_end_real
275
                        $request_data->HT,
276
      					$request_data->subprice_excl_tax,
277
      					$request_data->info_bits,
278
                        $request_data->fk_fournprice,
279
				      	$request_data->pa_ht,
280
      					$request_data->array_options,
281
      					$request_data->fk_unit,
282
      					$request_data->rang
283
      );
284
285
      if ($updateRes > 0) {
286
        return $updateRes;
287
288
      }
289
      return false;
290
    }
291
292
    /**
293
     * Update a line to given contract
294
     *
295
     * @param int   $id             Id of contrat to update
296
     * @param int   $lineid         Id of line to update
297
     * @param array $request_data   Contractline data
298
     *
299
     * @url	PUT {id}/lines/{lineid}
300
     *
301
     * @return object
302
     */
303
    function putLine($id, $lineid, $request_data = NULL) {
304
      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
305
		  	throw new RestException(401);
306
		  }
307
308
      $result = $this->contract->fetch($id);
309
      if( ! $result ) {
310
         throw new RestException(404, 'Contrat not found');
311
      }
312
313
		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
314
			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
315
		}
316
317
      $request_data = (object) $request_data;
318
319
      $updateRes = $this->contract->updateline(
320
                        $lineid,
321
                        $request_data->desc,
322
                        $request_data->subprice,
323
                        $request_data->qty,
324
                        $request_data->remise_percent,
325
                        $request_data->date_ouveture_prevue,
326
                        $request_data->date_fin_validite,
327
      					$request_data->tva_tx,
328
                        $request_data->localtax1_tx,
329
                        $request_data->localtax2_tx,
330
                        $request_data->date_ouverture,
331
                        $request_data->date_cloture,
332
      					'HT',
333
                        $request_data->info_bits,
334
                        $request_data->fk_fourn_price,
335
                        $request_data->pa_ht,
336
                        $request_data->array_options,
337
                        $request_data->fk_unit
338
      );
339
340
      if ($updateRes > 0) {
341
        $result = $this->get($id);
342
        unset($result->line);
343
        return $this->_cleanObjectDatas($result);
344
      }
345
346
      return false;
347
    }
348
349
    /**
350
     * Activate a service line of a given contract
351
     *
352
     * @param int   	$id             Id of contract to activate
353
     * @param int   	$lineid         Id of line to activate
354
     * @param string  	$datestart		{@from body}  Date start        {@type timestamp}
355
     * @param string    $datend			{@from body}  Date end          {@type timestamp}
356
     * @param string    $comment  		{@from body}  Comment
357
     *
358
     * @url	PUT {id}/lines/{lineid}/activate
359
     *
360
     * @return object
361
     */
362
    function activateLine($id, $lineid, $datestart, $dateend = NULL, $comment = NULL) {
363
    	if(! DolibarrApiAccess::$user->rights->contrat->creer) {
364
    		throw new RestException(401);
365
    	}
366
367
    	$result = $this->contract->fetch($id);
368
    	if( ! $result ) {
369
    		throw new RestException(404, 'Contrat not found');
370
    	}
371
372
    	if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
373
    		throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
374
    	}
375
376
    	$updateRes = $this->contract->active_line(DolibarrApiAccess::$user, $lineid, $datestart, $dateend, $comment);
377
378
    	if ($updateRes > 0) {
379
    		$result = $this->get($id);
380
    		unset($result->line);
381
    		return $this->_cleanObjectDatas($result);
382
    	}
383
384
    	return false;
385
    }
386
387
    /**
388
     * Unactivate a service line of a given contract
389
     *
390
     * @param int   	$id             Id of contract to activate
391
     * @param int   	$lineid         Id of line to activate
392
     * @param string  	$datestart		{@from body}  Date start        {@type timestamp}
393
     * @param string    $comment  		{@from body}  Comment
394
     *
395
     * @url	PUT {id}/lines/{lineid}/unactivate
396
     *
397
     * @return object
398
     */
399
    function unactivateLine($id, $lineid, $datestart, $comment = NULL) {
400
    	if(! DolibarrApiAccess::$user->rights->contrat->creer) {
401
    		throw new RestException(401);
402
    	}
403
404
    	$result = $this->contract->fetch($id);
405
    	if( ! $result ) {
406
    		throw new RestException(404, 'Contrat not found');
407
    	}
408
409
    	if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
410
    		throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
411
    	}
412
413
    	$request_data = (object) $request_data;
0 ignored issues
show
Bug introduced by
The variable $request_data seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
414
415
    	$updateRes = $this->contract->close_line(DolibarrApiAccess::$user, $lineid, $datestart, $comment);
416
417
    	if ($updateRes > 0) {
418
    		$result = $this->get($id);
419
    		unset($result->line);
420
    		return $this->_cleanObjectDatas($result);
421
    	}
422
423
    	return false;
424
    }
425
426
    /**
427
     * Delete a line to given contract
428
     *
429
     *
430
     * @param int   $id             Id of contract to update
431
     * @param int   $lineid         Id of line to delete
432
     *
433
     * @url	DELETE {id}/lines/{lineid}
434
     *
435
     * @return int
436
     * @throws 401
437
     * @throws 404
438
     */
439
    function deleteLine($id, $lineid) {
440
      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
441
		  	throw new RestException(401);
442
		  }
443
444
      $result = $this->contract->fetch($id);
445
      if( ! $result ) {
446
         throw new RestException(404, 'Contrat not found');
447
      }
448
449
		  if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
450
			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
451
      }
452
453
      $request_data = (object) $request_data;
0 ignored issues
show
Bug introduced by
The variable $request_data seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
454
      $updateRes = $this->contract->deleteline($lineid, DolibarrApiAccess::$user);
455
      if ($updateRes > 0) {
456
        return $this->get($id);
457
      }
458
      return false;
459
    }
460
461
    /**
462
     * Update contract general fields (won't touch lines of contract)
463
     *
464
     * @param int   $id             Id of contrat to update
465
     * @param array $request_data   Datas
466
     *
467
     * @return int
468
     */
469
    function put($id, $request_data = NULL) {
470
      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
471
		  	throw new RestException(401);
472
		  }
473
474
        $result = $this->contract->fetch($id);
475
        if( ! $result ) {
476
            throw new RestException(404, 'Contrat not found');
477
        }
478
479
		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
480
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
481
		}
482
        foreach($request_data as $field => $value) {
483
            if ($field == 'id') continue;
484
            $this->contract->$field = $value;
485
        }
486
487
        if($this->contract->update(DolibarrApiAccess::$user, 0))
488
            return $this->get($id);
489
490
        return false;
491
    }
492
493
    /**
494
     * Delete contract
495
     *
496
     * @param   int     $id         Contract ID
497
     *
498
     * @return  array
499
     */
500
    function delete($id)
501
    {
502
        if(! DolibarrApiAccess::$user->rights->contrat->supprimer) {
503
			throw new RestException(401);
504
		}
505
        $result = $this->contract->fetch($id);
506
        if( ! $result ) {
507
            throw new RestException(404, 'Contract not found');
508
        }
509
510
		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
511
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
512
		}
513
514
        if( ! $this->contract->delete(DolibarrApiAccess::$user)) {
515
            throw new RestException(500, 'Error when delete contract : '.$this->contract->error);
516
        }
517
518
        return array(
519
            'success' => array(
520
                'code' => 200,
521
                'message' => 'Contract deleted'
522
            )
523
        );
524
525
    }
526
527
    /**
528
     * Validate an contract
529
     *
530
     * @param   int $id             Contract ID
531
     * @param   int $notrigger      1=Does not execute triggers, 0= execute triggers
532
     *
533
     * @url POST    {id}/validate
534
     *
535
     * @return  array
536
     * FIXME An error 403 is returned if the request has an empty body.
537
     * Error message: "Forbidden: Content type `text/plain` is not supported."
538
     * Workaround: send this in the body
539
     * {
540
     *   "notrigger": 0
541
     * }
542
     */
543
    function validate($id, $notrigger=0)
544
    {
545
        if(! DolibarrApiAccess::$user->rights->contrat->creer) {
546
			throw new RestException(401);
547
		}
548
        $result = $this->contract->fetch($id);
549
        if( ! $result ) {
550
            throw new RestException(404, 'Contract not found');
551
        }
552
553
		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
554
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
555
		}
556
557
		$result = $this->contract->validate(DolibarrApiAccess::$user, '', $notrigger);
558
		if ($result == 0) {
559
		    throw new RestException(304, 'Error nothing done. May be object is already validated');
560
		}
561
		if ($result < 0) {
562
		    throw new RestException(500, 'Error when validating Contract: '.$this->contract->error);
563
		}
564
565
        return array(
566
            'success' => array(
567
                'code' => 200,
568
                'message' => 'Contract validated (Ref='.$this->contract->ref.')'
569
            )
570
        );
571
    }
572
573
    /**
574
     * Close all services of a contract
575
     *
576
     * @param   int $id             Contract ID
577
     * @param   int $notrigger      1=Does not execute triggers, 0= execute triggers
578
     *
579
     * @url POST    {id}/close
580
     *
581
     * @return  array
582
     * FIXME An error 403 is returned if the request has an empty body.
583
     * Error message: "Forbidden: Content type `text/plain` is not supported."
584
     * Workaround: send this in the body
585
     * {
586
     *   "notrigger": 0
587
     * }
588
     */
589
    function close($id, $notrigger=0)
590
    {
591
    	if(! DolibarrApiAccess::$user->rights->contrat->creer) {
592
    		throw new RestException(401);
593
    	}
594
    	$result = $this->contract->fetch($id);
595
    	if( ! $result ) {
596
    		throw new RestException(404, 'Contract not found');
597
    	}
598
599
    	if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
600
    		throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
601
    	}
602
603
    	$result = $this->contract->closeAll(DolibarrApiAccess::$user, $notrigger);
604
    	if ($result == 0) {
605
    		throw new RestException(304, 'Error nothing done. May be object is already close');
606
    	}
607
    	if ($result < 0) {
608
    		throw new RestException(500, 'Error when closing Contract: '.$this->contract->error);
609
    	}
610
611
    	return array(
612
	    	'success' => array(
613
		    	'code' => 200,
614
		    	'message' => 'Contract closed (Ref='.$this->contract->ref.'). All services were closed.'
615
	    	)
616
    	);
617
    }
618
619
620
621
    /**
622
     * Clean sensible object datas
623
     *
624
     * @param   object  $object    Object to clean
625
     * @return    array    Array of cleaned object properties
626
     */
627
    function _cleanObjectDatas($object) {
628
629
        $object = parent::_cleanObjectDatas($object);
630
631
        unset($object->address);
632
633
        unset($object->date_ouverture_prevue);
634
        unset($object->date_ouverture);
635
        unset($object->date_fin_validite);
636
        unset($object->date_cloture);
637
        unset($object->date_debut_prevue);
638
        unset($object->date_debut_reel);
639
        unset($object->date_fin_prevue);
640
        unset($object->date_fin_reel);
641
        unset($object->civility_id);
642
643
        return $object;
644
    }
645
646
    /**
647
     * Validate fields before create or update object
648
     *
649
     * @param   array           $data   Array with data to verify
650
     * @return  array
651
     * @throws  RestException
652
     */
653
    function _validate($data)
654
    {
655
        $contrat = array();
656
        foreach (Contracts::$FIELDS as $field) {
657
            if (!isset($data[$field]))
658
                throw new RestException(400, "$field field missing");
659
            $contrat[$field] = $data[$field];
660
661
        }
662
        return $contrat;
663
    }
664
}
665