Passed
Pull Request — master (#2)
by
unknown
26:19
created

Invoices::addPayment()   C

Complexity

Conditions 16
Paths 36

Size

Total Lines 95
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 56
nc 36
nop 9
dl 0
loc 95
rs 5.5666
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* Copyright (C) 2015   Jean-François Ferry     <[email protected]>
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 <http://www.gnu.org/licenses/>.
16
 */
17
18
use Luracast\Restler\RestException;
19
20
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
21
22
/**
23
 * API class for invoices
24
 *
25
 * @access protected
26
 * @class  DolibarrApiAccess {@requires user,external}
27
 */
28
class Invoices extends DolibarrApi
29
{
30
    /**
31
     *
32
     * @var array   $FIELDS     Mandatory fields, checked when create and update object
33
     */
34
    static $FIELDS = array(
35
        'socid',
36
    );
37
38
    /**
39
     * @var Facture $invoice {@type Facture}
40
     */
41
    public $invoice;
42
43
    /**
44
     * Constructor
45
     */
46
    function __construct()
47
    {
48
		global $db, $conf;
49
		$this->db = $db;
50
        $this->invoice = new Facture($this->db);
51
    }
52
53
    /**
54
     * Get properties of a invoice object
55
     *
56
     * Return an array with invoice informations
57
     *
58
     * @param 	int 	$id ID of invoice
59
     * @return 	array|mixed data without useless information
60
     *
61
     * @throws 	RestException
62
     */
63
	function get($id)
64
	{
65
		if(! DolibarrApiAccess::$user->rights->facture->lire) {
66
			throw new RestException(401);
67
		}
68
69
		$result = $this->invoice->fetch($id);
70
		if (! $result) {
71
			throw new RestException(404, 'Invoice not found');
72
		}
73
74
		// Get payment details
75
		$this->invoice->totalpaye = $this->invoice->getSommePaiement();
76
		$this->invoice->totalcreditnotes = $this->invoice->getSumCreditNotesUsed();
77
		$this->invoice->totaldeposits = $this->invoice->getSumDepositsUsed();
78
		$this->invoice->resteapayer = price2num($this->invoice->total_ttc - $this->invoice->totalpaye - $this->invoice->totalcreditnotes - $this->invoice->totaldeposits, 'MT');
79
80
		if (! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
81
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
82
		}
83
84
		// Add external contacts ids
85
		$this->invoice->contacts_ids = $this->invoice->liste_contact(-1,'external',1);
0 ignored issues
show
Bug introduced by
The property contacts_ids does not exist on Facture. Did you mean contact?
Loading history...
86
87
		$this->invoice->fetchObjectLinked();
88
		return $this->_cleanObjectDatas($this->invoice);
89
	}
90
91
    /**
92
     * List invoices
93
     *
94
     * Get a list of invoices
95
     *
96
     * @param string	$sortfield	      Sort field
97
     * @param string	$sortorder	      Sort order
98
     * @param int		$limit		      Limit for list
99
     * @param int		$page		      Page number
100
     * @param string   	$thirdparty_ids	  Thirdparty ids to filter orders of. {@example '1' or '1,2,3'} {@pattern /^[0-9,]*$/i}
101
     * @param string	$status		      Filter by invoice status : draft | unpaid | paid | cancelled
102
     * @param string    $sqlfilters       Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
103
     * @return array                      Array of invoice objects
104
     *
105
	 * @throws RestException
106
     */
107
    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '')
108
    {
109
        global $db, $conf;
110
111
        $obj_ret = array();
112
113
        // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
114
        $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids;
115
116
        // If the internal user must only see his customers, force searching by him
117
        $search_sale = 0;
118
        if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
119
120
        $sql = "SELECT t.rowid";
121
        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)
122
        $sql.= " FROM ".MAIN_DB_PREFIX."facture as t";
123
124
        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
125
126
        $sql.= ' WHERE t.entity IN ('.getEntity('invoice').')';
127
        if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc";
128
        if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")";
129
130
        if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc";		// Join for the needed table to filter by sale
131
132
		// Filter by status
133
        if ($status == 'draft')     $sql.= " AND t.fk_statut IN (0)";
134
        if ($status == 'unpaid')    $sql.= " AND t.fk_statut IN (1)";
135
        if ($status == 'paid')      $sql.= " AND t.fk_statut IN (2)";
136
        if ($status == 'cancelled') $sql.= " AND t.fk_statut IN (3)";
137
        // Insert sale filter
138
        if ($search_sale > 0)
139
        {
140
            $sql .= " AND sc.fk_user = ".$search_sale;
141
        }
142
        // Add sql filters
143
        if ($sqlfilters)
144
        {
145
            if (! DolibarrApi::_checkFilters($sqlfilters))
146
            {
147
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
148
            }
149
	        $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
150
            $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
151
        }
152
153
        $sql.= $db->order($sortfield, $sortorder);
154
        if ($limit)
155
        {
156
            if ($page < 0)
157
            {
158
                $page = 0;
159
            }
160
            $offset = $limit * $page;
161
162
            $sql.= $db->plimit($limit + 1, $offset);
163
        }
164
165
        $result = $db->query($sql);
166
        if ($result)
167
        {
168
            $i=0;
169
            $num = $db->num_rows($result);
170
            $min = min($num, ($limit <= 0 ? $num : $limit));
171
            while ($i < $min)
172
            {
173
                $obj = $db->fetch_object($result);
174
                $invoice_static = new Facture($db);
175
                if ($invoice_static->fetch($obj->rowid))
176
                {
177
                	// Get payment details
178
                	$invoice_static->totalpaid = $invoice_static->getSommePaiement();
179
                	$invoice_static->totalcreditnotes = $invoice_static->getSumCreditNotesUsed();
180
                	$invoice_static->totaldeposits = $invoice_static->getSumDepositsUsed();
181
                	$invoice_static->remaintopay = price2num($invoice_static->total_ttc - $invoice_static->totalpaid - $invoice_static->totalcreditnotes - $invoice_static->totaldeposits, 'MT');
182
183
					// Add external contacts ids
184
					$invoice_static->contacts_ids = $invoice_static->liste_contact(-1,'external',1);
0 ignored issues
show
Bug introduced by
The property contacts_ids does not exist on Facture. Did you mean contact?
Loading history...
185
186
                	$obj_ret[] = $this->_cleanObjectDatas($invoice_static);
187
                }
188
                $i++;
189
            }
190
        }
191
        else {
192
            throw new RestException(503, 'Error when retrieve invoice list : '.$db->lasterror());
193
        }
194
        if( ! count($obj_ret)) {
195
            throw new RestException(404, 'No invoice found');
196
        }
197
		return $obj_ret;
198
    }
199
200
    /**
201
     * Create invoice object
202
     *
203
     * @param array $request_data   Request datas
204
     * @return int                  ID of invoice
205
     */
206
    function post($request_data = null)
207
    {
208
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
209
			throw new RestException(401, "Insuffisant rights");
210
		}
211
        // Check mandatory fields
212
        $result = $this->_validate($request_data);
213
214
        foreach($request_data as $field => $value) {
215
            $this->invoice->$field = $value;
216
        }
217
        if(! array_key_exists('date', $request_data)) {
218
            $this->invoice->date = dol_now();
219
        }
220
        /* We keep lines as an array
221
         if (isset($request_data["lines"])) {
222
            $lines = array();
223
            foreach ($request_data["lines"] as $line) {
224
                array_push($lines, (object) $line);
225
            }
226
            $this->invoice->lines = $lines;
227
        }*/
228
229
        if ($this->invoice->create(DolibarrApiAccess::$user) < 0) {
230
            throw new RestException(500, "Error creating invoice", array_merge(array($this->invoice->error), $this->invoice->errors));
231
        }
232
        return $this->invoice->id;
233
    }
234
235
     /**
236
     * Create an invoice using an existing order.
237
     *
238
     *
239
     * @param int   $orderid       Id of the order
240
     *
241
     * @url     POST /createfromorder/{orderid}
242
     *
243
     * @return int
244
     * @throws 400
245
     * @throws 401
246
     * @throws 404
247
     * @throws 405
248
     */
249
    function createInvoiceFromOrder($orderid)
250
    {
251
252
        require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
253
254
        if(! DolibarrApiAccess::$user->rights->commande->lire) {
255
            throw new RestException(401);
256
        }
257
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
258
            throw new RestException(401);
259
        }
260
        if(empty($orderid)) {
261
            throw new RestException(400, 'Order ID is mandatory');
262
        }
263
264
        $order = new Commande($this->db);
265
        $result = $order->fetch($orderid);
266
        if( ! $result ) {
267
            throw new RestException(404, 'Order not found');
268
        }
269
270
        $result = $this->invoice->createFromOrder($order, DolibarrApiAccess::$user);
271
        if( $result < 0) {
272
            throw new RestException(405, $this->invoice->error);
273
        }
274
        $this->invoice->fetchObjectLinked();
275
        return $this->_cleanObjectDatas($this->invoice);
276
    }
277
278
    /**
279
     * Get lines of an invoice
280
     *
281
     * @param int   $id             Id of invoice
282
     *
283
     * @url	GET {id}/lines
284
     *
285
     * @return int
286
     */
287
    function getLines($id)
288
    {
289
    	if(! DolibarrApiAccess::$user->rights->facture->lire) {
290
    		throw new RestException(401);
291
    	}
292
293
    	$result = $this->invoice->fetch($id);
294
    	if( ! $result ) {
295
    		throw new RestException(404, 'Invoice not found');
296
    	}
297
298
    	if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
299
    		throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
300
    	}
301
    	$this->invoice->getLinesArray();
302
    	$result = array();
303
    	foreach ($this->invoice->lines as $line) {
304
    		array_push($result,$this->_cleanObjectDatas($line));
305
    	}
306
    	return $result;
307
    }
308
309
    /**
310
     * Update a line to a given invoice
311
     *
312
     * @param int   $id             Id of invoice to update
313
     * @param int   $lineid         Id of line to update
314
     * @param array $request_data   InvoiceLine data
315
     *
316
     * @url	PUT {id}/lines/{lineid}
317
     *
318
     * @return object
319
     *
320
     * @throws 200
321
     * @throws 304
322
     * @throws 401
323
     * @throws 404
324
     */
325
    function putLine($id, $lineid, $request_data = null)
326
    {
327
    	if(! DolibarrApiAccess::$user->rights->facture->creer) {
328
    		throw new RestException(401);
329
    	}
330
331
    	$result = $this->invoice->fetch($id);
332
    	if( ! $result ) {
333
    		throw new RestException(404, 'Invoice not found');
334
    	}
335
336
    	if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
337
    		throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
338
    	}
339
    	$request_data = (object) $request_data;
340
    	$updateRes = $this->invoice->updateline(
341
    		$lineid,
342
    		$request_data->desc,
343
    		$request_data->subprice,
344
    		$request_data->qty,
345
    		$request_data->remise_percent,
346
    		$request_data->date_start,
347
    		$request_data->date_end,
348
    		$request_data->tva_tx,
349
    		$request_data->localtax1_tx,
350
    		$request_data->localtax2_tx,
351
    		'HT',
352
    		$request_data->info_bits,
353
    		$request_data->product_type,
354
    		$request_data->fk_parent_line,
355
    		0,
356
    		$request_data->fk_fournprice,
357
    		$request_data->pa_ht,
358
    		$request_data->label,
359
    		$request_data->special_code,
360
    		$request_data->array_options,
361
    		$request_data->situation_percent,
362
    		$request_data->fk_unit,
363
    		$request_data->multicurrency_subprice
364
    		);
365
366
    	if ($updateRes > 0) {
367
    		$result = $this->get($id);
368
    		unset($result->line);
369
    		return $this->_cleanObjectDatas($result);
370
	    } else {
371
	    	throw new RestException(304, $this->invoice->error);
372
    	}
373
    }
374
375
    /**
376
     * Deletes a line of a given invoice
377
     *
378
     * @param int   $id             Id of invoice
379
     * @param int   $lineid 		Id of the line to delete
380
     *
381
     * @url     DELETE {id}/lines/{lineid}
382
     *
383
     * @return array
384
     *
385
     * @throws 400
386
     * @throws 401
387
     * @throws 404
388
     * @throws 405
389
     */
390
    function deleteLine($id, $lineid)
391
    {
392
393
    	if(! DolibarrApiAccess::$user->rights->facture->creer) {
394
    		throw new RestException(401);
395
    	}
396
    	if(empty($lineid)) {
397
    		throw new RestException(400, 'Line ID is mandatory');
398
    	}
399
400
    	if( ! DolibarrApi::_checkAccessToResource('facture',$id)) {
401
    		throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
402
    	}
403
404
    	$result = $this->invoice->fetch($id);
405
    	if( ! $result ) {
406
    		throw new RestException(404, 'Invoice not found');
407
    	}
408
409
    	// TODO Check the lineid $lineid is a line of ojbect
410
411
    	$updateRes = $this->invoice->deleteline($lineid);
412
    	if ($updateRes > 0) {
413
    		return $this->get($id);
414
    	}
415
    	else
416
    	{
417
    		throw new RestException(405, $this->invoice->error);
418
    	}
419
    }
420
421
    /**
422
     * Update invoice
423
     *
424
     * @param int   $id             Id of invoice to update
425
     * @param array $request_data   Datas
426
     * @return int
427
     */
428
    function put($id, $request_data = null)
429
    {
430
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
431
			throw new RestException(401);
432
		}
433
434
        $result = $this->invoice->fetch($id);
435
        if( ! $result ) {
436
            throw new RestException(404, 'Invoice not found');
437
        }
438
439
		if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
440
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
441
		}
442
443
        foreach($request_data as $field => $value) {
444
            if ($field == 'id') continue;
445
            $this->invoice->$field = $value;
446
        }
447
448
        // update bank account
449
        if (!empty($this->invoice->fk_account))
450
        {
451
             if($this->invoice->setBankAccount($this->invoice->fk_account) == 0)
452
             {
453
                 throw new RestException(400,$this->invoice->error);
454
             }
455
        }
456
457
        if($this->invoice->update($id, DolibarrApiAccess::$user))
458
            return $this->get($id);
459
460
        return false;
461
    }
462
463
    /**
464
     * Delete invoice
465
     *
466
     * @param int   $id Invoice ID
467
     * @return array
468
     */
469
    function delete($id)
470
    {
471
        if(! DolibarrApiAccess::$user->rights->facture->supprimer) {
472
			throw new RestException(401);
473
		}
474
        $result = $this->invoice->fetch($id);
475
        if( ! $result ) {
476
            throw new RestException(404, 'Invoice not found');
477
        }
478
479
		if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
480
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
481
		}
482
483
        if( $this->invoice->delete($id) < 0)
484
        {
485
            throw new RestException(500);
486
        }
487
488
         return array(
489
            'success' => array(
490
                'code' => 200,
491
                'message' => 'Invoice deleted'
492
            )
493
        );
494
    }
495
496
    /**
497
     * Add a line to a given invoice
498
     *
499
     * Exemple of POST query :
500
     * {
501
     *     "desc": "Desc", "subprice": "1.00000000", "qty": "1", "tva_tx": "20.000", "localtax1_tx": "0.000", "localtax2_tx": "0.000",
502
     *     "fk_product": "1", "remise_percent": "0", "date_start": "", "date_end": "", "fk_code_ventilation": 0,  "info_bits": "0",
503
     *     "fk_remise_except": null,  "product_type": "1", "rang": "-1", "special_code": "0", "fk_parent_line": null, "fk_fournprice": null,
504
     *     "pa_ht": "0.00000000", "label": "", "array_options": [], "situation_percent": "100", "fk_prev_id": null, "fk_unit": null
505
     * }
506
     *
507
     * @param int   $id             Id of invoice
508
     * @param array $request_data   InvoiceLine data
509
     *
510
     * @url     POST {id}/lines
511
     *
512
     * @return int
513
     *
514
     * @throws 200
515
     * @throws 401
516
     * @throws 404
517
     * @throws 400
518
     */
519
    function postLine($id, $request_data = null)
520
    {
521
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
522
            throw new RestException(401);
523
        }
524
525
        $result = $this->invoice->fetch($id);
526
        if( ! $result ) {
527
            throw new RestException(404, 'Invoice not found');
528
        }
529
530
        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
531
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
532
        }
533
534
        $request_data = (object) $request_data;
535
536
        // Reset fk_parent_line for no child products and special product
537
        if (($request_data->product_type != 9 && empty($request_data->fk_parent_line)) || $request_data->product_type == 9) {
538
            $request_data->fk_parent_line = 0;
539
        }
540
541
        // calculate pa_ht
542
        $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht);
543
        $pa_ht = $marginInfos[0];
544
545
        $updateRes = $this->invoice->addline(
546
            $request_data->desc,
547
            $request_data->subprice,
548
            $request_data->qty,
549
            $request_data->tva_tx,
550
            $request_data->localtax1_tx,
551
            $request_data->localtax2_tx,
552
            $request_data->fk_product,
553
            $request_data->remise_percent,
554
            $request_data->date_start,
555
            $request_data->date_end,
556
            $request_data->fk_code_ventilation,
557
            $request_data->info_bits,
558
            $request_data->fk_remise_except,
559
            'HT',
560
            0,
561
            $request_data->product_type,
562
            $request_data->rang,
563
            $request_data->special_code,
564
            $request_data->origin,
565
            $request_data->origin_id,
566
            $request_data->fk_parent_line,
567
            empty($request_data->fk_fournprice)?null:$request_data->fk_fournprice,
568
            $pa_ht,
569
            $request_data->label,
570
            $request_data->array_options,
571
            $request_data->situation_percent,
572
            $request_data->fk_prev_id,
573
            $request_data->fk_unit
574
        );
575
576
        if ($updateRes < 0) {
577
            throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error);
578
        }
579
580
        return $updateRes;
581
    }
582
583
    /**
584
     * Adds a contact to an invoice
585
     *
586
     * @param   int 	$id             	Order ID
587
     * @param   int 	$fk_socpeople       	Id of thirdparty contact (if source = 'external') or id of user (if souce = 'internal') to link
588
     * @param   string 	$type_contact           Type of contact (code). Must a code found into table llx_c_type_contact. For example: BILLING
589
     * @param   string  $source             	external=Contact extern (llx_socpeople), internal=Contact intern (llx_user)
590
     * @param   int     $notrigger              Disable all triggers
591
     *
592
     * @url POST    {id}/contacts
593
     *
594
     * @return  array
595
     *
596
     * @throws 200
597
     * @throws 304
598
     * @throws 401
599
     * @throws 404
600
     * @throws 500
601
     *
602
     */
603
    function addContact($id, $fk_socpeople, $type_contact, $source, $notrigger=0)
604
    {
605
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
606
                throw new RestException(401);
607
        }
608
        $result = $this->invoice->fetch($id);
609
        if( ! $result ) {
610
                throw new RestException(404, 'Invoice not found');
611
        }
612
613
        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
614
                throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
615
        }
616
617
        $result = $this->invoice->add_contact($fk_socpeople,$type_contact,$source,$notrigger);
618
        if ($result < 0) {
619
                throw new RestException(500, 'Error : '.$this->invoice->error);
620
        }
621
622
        $result = $this->invoice->fetch($id);
623
        if( ! $result ) {
624
            throw new RestException(404, 'Invoice not found');
625
        }
626
627
        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
628
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
629
        }
630
631
        return $this->_cleanObjectDatas($this->invoice);
632
    }
633
634
635
636
    /**
637
     * Sets an invoice as draft
638
     *
639
     * @param   int $id             Order ID
640
     * @param   int $idwarehouse    Warehouse ID
641
     *
642
     * @url POST    {id}/settodraft
643
     *
644
     * @return  array
645
     *
646
     * @throws 200
647
     * @throws 304
648
     * @throws 401
649
     * @throws 404
650
     * @throws 500
651
     *
652
     */
653
    function settodraft($id, $idwarehouse=-1)
654
    {
655
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
656
            throw new RestException(401);
657
        }
658
        $result = $this->invoice->fetch($id);
659
        if( ! $result ) {
660
            throw new RestException(404, 'Invoice not found');
661
        }
662
663
        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
664
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
665
        }
666
667
        $result = $this->invoice->set_draft(DolibarrApiAccess::$user, $idwarehouse);
668
        if ($result == 0) {
669
            throw new RestException(304, 'Nothing done.');
670
        }
671
        if ($result < 0) {
672
            throw new RestException(500, 'Error : '.$this->invoice->error);
673
        }
674
675
        $result = $this->invoice->fetch($id);
676
        if( ! $result ) {
677
            throw new RestException(404, 'Invoice not found');
678
        }
679
680
        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
681
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
682
        }
683
684
        return $this->_cleanObjectDatas($this->invoice);
685
    }
686
687
688
    /**
689
     * Validate an invoice
690
     *
691
	 * If you get a bad value for param notrigger check that ou provide this in body
692
     * {
693
     *   "idwarehouse": 0,
694
     *   "notrigger": 0
695
     * }
696
     *
697
     * @param   int $id             Invoice ID
698
     * @param   int $idwarehouse    Warehouse ID
699
     * @param   int $notrigger      1=Does not execute triggers, 0= execute triggers
700
     *
701
     * @url POST    {id}/validate
702
     *
703
     * @return  array
704
     */
705
    function validate($id, $idwarehouse=0, $notrigger=0)
706
    {
707
    	if(! DolibarrApiAccess::$user->rights->facture->creer) {
708
    		throw new RestException(401);
709
    	}
710
    	$result = $this->invoice->fetch($id);
711
    	if( ! $result ) {
712
    		throw new RestException(404, 'Invoice not found');
713
    	}
714
715
    	if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
716
    		throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
717
    	}
718
719
    	$result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger);
720
    	if ($result == 0) {
721
    		throw new RestException(304, 'Error nothing done. May be object is already validated');
722
    	}
723
    	if ($result < 0) {
724
    		throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error);
725
    	}
726
727
        $result = $this->invoice->fetch($id);
728
        if( ! $result ) {
729
            throw new RestException(404, 'Invoice not found');
730
        }
731
732
        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
733
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
734
        }
735
736
        return $this->_cleanObjectDatas($this->invoice);
737
    }
738
739
    /**
740
     * Sets an invoice as paid
741
     *
742
     * @param   int 	$id            Order ID
743
     * @param   string 	$close_code    Code renseigne si on classe a payee completement alors que paiement incomplet (cas escompte par exemple)
744
     * @param   string 	$close_note    Commentaire renseigne si on classe a payee alors que paiement incomplet (cas escompte par exemple)
745
     *
746
     * @url POST    {id}/settopaid
747
     *
748
     * @return  array 	An invoice object
749
     *
750
     * @throws 200
751
     * @throws 304
752
     * @throws 401
753
     * @throws 404
754
     * @throws 500
755
     */
756
    function settopaid($id, $close_code='', $close_note='')
757
    {
758
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
759
            throw new RestException(401);
760
        }
761
        $result = $this->invoice->fetch($id);
762
        if( ! $result ) {
763
            throw new RestException(404, 'Invoice not found');
764
        }
765
766
        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
767
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
768
        }
769
770
        $result = $this->invoice->set_paid(DolibarrApiAccess::$user, $close_code, $close_note);
771
        if ($result == 0) {
772
            throw new RestException(304, 'Error nothing done. May be object is already validated');
773
        }
774
        if ($result < 0) {
775
            throw new RestException(500, 'Error : '.$this->invoice->error);
776
        }
777
778
779
        $result = $this->invoice->fetch($id);
780
        if( ! $result ) {
781
            throw new RestException(404, 'Invoice not found');
782
        }
783
784
        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
785
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
786
        }
787
788
        return $this->_cleanObjectDatas($this->invoice);
789
    }
790
791
792
    /**
793
     * Sets an invoice as unpaid
794
     *
795
     * @param   int     $id            Order ID
796
     *
797
     * @url POST    {id}/settounpaid
798
     *
799
     * @return  array   An invoice object
800
     *
801
     * @throws 200
802
     * @throws 304
803
     * @throws 401
804
     * @throws 404
805
     * @throws 500
806
     */
807
    function settounpaid($id)
808
    {
809
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
810
            throw new RestException(401);
811
        }
812
        $result = $this->invoice->fetch($id);
813
        if( ! $result ) {
814
            throw new RestException(404, 'Invoice not found');
815
        }
816
817
        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
818
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
819
        }
820
821
        $result = $this->invoice->set_unpaid(DolibarrApiAccess::$user);
822
        if ($result == 0) {
823
            throw new RestException(304, 'Nothing done');
824
        }
825
        if ($result < 0) {
826
            throw new RestException(500, 'Error : '.$this->invoice->error);
827
        }
828
829
830
        $result = $this->invoice->fetch($id);
831
        if( ! $result ) {
832
            throw new RestException(404, 'Invoice not found');
833
        }
834
835
        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
836
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
837
        }
838
839
        return $this->_cleanObjectDatas($this->invoice);
840
    }
841
842
     /**
843
     * Add a discount line into an invoice (as an invoice line) using an existing absolute discount
844
     *
845
     * Note that this consume the discount.
846
     *
847
     * @param int   $id             Id of invoice
848
     * @param int   $discountid     Id of discount
849
     *
850
     * @url     POST {id}/usediscount/{discountid}
851
     *
852
     * @return int
853
     * @throws 400
854
     * @throws 401
855
     * @throws 404
856
     * @throws 405
857
     */
858
    function useDiscount($id, $discountid)
859
    {
860
861
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
862
            throw new RestException(401);
863
        }
864
        if(empty($id)) {
865
            throw new RestException(400, 'Invoice ID is mandatory');
866
        }
867
        if(empty($discountid)) {
868
            throw new RestException(400, 'Discount ID is mandatory');
869
        }
870
871
        if( ! DolibarrApi::_checkAccessToResource('facture',$id)) {
872
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
873
        }
874
875
        $result = $this->invoice->fetch($id);
876
        if( ! $result ) {
877
            throw new RestException(404, 'Invoice not found');
878
        }
879
880
        $result = $this->invoice->insert_discount($discountid);
881
        if( $result < 0) {
882
            throw new RestException(405, $this->invoice->error);
883
        }
884
885
        return $result;
886
    }
887
888
     /**
889
     * Add an available credit note discount to payments of an existing invoice.
890
     *
891
     *  Note that this consume the credit note.
892
     *
893
     * @param int   $id            Id of invoice
894
     * @param int   $discountid    Id of a discount coming from a credit note
895
     *
896
     * @url     POST {id}/usecreditnote/{discountid}
897
     *
898
     * @return int
899
     * @throws 400
900
     * @throws 401
901
     * @throws 404
902
     * @throws 405
903
     */
904
    function useCreditNote($id, $discountid)
905
    {
906
907
        require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php';
908
909
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
910
            throw new RestException(401);
911
        }
912
        if(empty($id)) {
913
            throw new RestException(400, 'Invoice ID is mandatory');
914
        }
915
        if(empty($discountid)) {
916
            throw new RestException(400, 'Credit ID is mandatory');
917
        }
918
919
        if( ! DolibarrApi::_checkAccessToResource('facture',$id)) {
920
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
921
        }
922
        $discount = new DiscountAbsolute($this->db);
923
        $result = $discount->fetch($discountid);
924
        if( ! $result ) {
925
            throw new RestException(404, 'Credit not found');
926
        }
927
928
        $result = $discount->link_to_invoice(0, $id);
929
        if( $result < 0) {
930
            throw new RestException(405, $discount->error);
931
        }
932
933
        return $result;
934
    }
935
936
    /**
937
     * Get list of payments of a given invoice
938
     *
939
     * @param int   $id             Id of invoice
940
     *
941
     * @url     GET {id}/payments
942
     *
943
     * @return array
944
     * @throws 400
945
     * @throws 401
946
     * @throws 404
947
     * @throws 405
948
     */
949
    function getPayments($id)
950
    {
951
952
        if(! DolibarrApiAccess::$user->rights->facture->lire) {
953
            throw new RestException(401);
954
        }
955
        if(empty($id)) {
956
            throw new RestException(400, 'Invoice ID is mandatory');
957
        }
958
959
        if( ! DolibarrApi::_checkAccessToResource('facture',$id)) {
960
            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
961
        }
962
963
        $result = $this->invoice->fetch($id);
964
        if( ! $result ) {
965
            throw new RestException(404, 'Invoice not found');
966
        }
967
968
        $result = $this->invoice->getListOfPayments();
969
        if( $result < 0) {
970
            throw new RestException(405, $this->invoice->error);
971
        }
972
973
        return $result;
974
    }
975
976
977
    /**
978
     * Add payment line to a specific invoice with the remain to pay as amount.
979
     *
980
     * @param int     $id                               Id of invoice
981
     * @param string  $datepaye           {@from body}  Payment date        {@type timestamp}
982
     * @param int     $paiementid         {@from body}  Payment mode Id {@min 1}
983
     * @param string  $closepaidinvoices  {@from body}  Close paid invoices {@choice yes,no}
984
     * @param int     $accountid          {@from body}  Account Id {@min 1}
985
     * @param string  $num_paiement       {@from body}  Payment number (optional)
986
     * @param string  $comment            {@from body}  Note (optional)
987
     * @param string  $chqemetteur        {@from body}  Payment issuer (mandatory if paiementcode = 'CHQ')
988
     * @param string  $chqbank            {@from body}  Issuer bank name (optional)
989
     *
990
     * @url     POST {id}/payments
991
     *
992
     * @return int  Payment ID
993
     * @throws 400
994
     * @throws 401
995
     * @throws 404
996
     */
997
    function addPayment($id, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement='', $comment='', $chqemetteur='', $chqbank='')
998
    {
999
        global $conf;
1000
1001
    	require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
1002
1003
    	if(! DolibarrApiAccess::$user->rights->facture->creer) {
1004
    		throw new RestException(403);
1005
    	}
1006
    	if(empty($id)) {
1007
    		throw new RestException(400, 'Invoice ID is mandatory');
1008
    	}
1009
1010
    	if( ! DolibarrApi::_checkAccessToResource('facture',$id)) {
1011
    		throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1012
    	}
1013
1014
    	if (! empty($conf->banque->enabled)) {
1015
    		if(empty($accountid)) {
1016
    			throw new RestException(400, 'Account ID is mandatory');
1017
    		}
1018
    	}
1019
1020
    	if(empty($paiementid)) {
1021
    		throw new RestException(400, 'Paiement ID or Paiement Code is mandatory');
1022
    	}
1023
1024
1025
    	$result = $this->invoice->fetch($id);
1026
    	if( ! $result ) {
1027
    		throw new RestException(404, 'Invoice not found');
1028
    	}
1029
1030
    	// Calculate amount to pay
1031
    	$totalpaye = $this->invoice->getSommePaiement();
1032
    	$totalcreditnotes = $this->invoice->getSumCreditNotesUsed();
1033
    	$totaldeposits = $this->invoice->getSumDepositsUsed();
1034
    	$resteapayer = price2num($this->invoice->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT');
1035
1036
    	$this->db->begin();
1037
1038
    	$amounts = array();
1039
    	$multicurrency_amounts = array();
1040
1041
    	// Clean parameters amount if payment is for a credit note
1042
    	if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1043
    		$resteapayer = price2num($resteapayer,'MT');
1044
    		$amounts[$id] = -$resteapayer;
1045
    		// Multicurrency
1046
    		$newvalue = price2num($this->invoice->multicurrency_total_ttc,'MT');
1047
    		$multicurrency_amounts[$id] = -$newvalue;
1048
    	} else {
1049
    		$resteapayer = price2num($resteapayer,'MT');
1050
    		$amounts[$id] = $resteapayer;
1051
    		// Multicurrency
1052
    		$newvalue = price2num($this->invoice->multicurrency_total_ttc,'MT');
1053
    		$multicurrency_amounts[$id] = $newvalue;
1054
    	}
1055
1056
1057
    	// Creation of payment line
1058
    	$paiement = new Paiement($this->db);
1059
    	$paiement->datepaye     = $datepaye;
1060
    	$paiement->amounts      = $amounts;                           // Array with all payments dispatching with invoice id
1061
    	$paiement->multicurrency_amounts = $multicurrency_amounts;    // Array with all payments dispatching
1062
    	$paiement->paiementid   = $paiementid;
1063
    	$paiement->paiementcode = dol_getIdFromCode($this->db,$paiementid,'c_paiement','id','code',1);
0 ignored issues
show
Bug introduced by
The property paiementcode does not exist on Paiement. Did you mean paiementid?
Loading history...
1064
    	$paiement->num_paiement = $num_paiement;
1065
    	$paiement->note         = $comment;
1066
1067
    	$paiement_id = $paiement->create(DolibarrApiAccess::$user, ($closepaidinvoices=='yes'?1:0));    // This include closing invoices
1068
    	if ($paiement_id < 0)
1069
    	{
1070
    		$this->db->rollback();
1071
    		throw new RestException(400, 'Payment error : '.$paiement->error);
1072
    	}
1073
1074
    	if (! empty($conf->banque->enabled)) {
1075
    		$label='(CustomerInvoicePayment)';
1076
1077
    		if($paiement->paiementcode == 'CHQ' && empty($chqemetteur)) {
1078
    			throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paiement->paiementcode);
1079
    		}
1080
    		if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) $label='(CustomerInvoicePaymentBack)';  // Refund of a credit note
1081
    		$result=$paiement->addPaymentToBank(DolibarrApiAccess::$user,'payment',$label,$accountid,$chqemetteur,$chqbank);
1082
    		if ($result < 0)
1083
    		{
1084
    			$this->db->rollback();
1085
    			throw new RestException(400, 'Add payment to bank error : '.$paiement->error);
1086
    		}
1087
    	}
1088
1089
    	$this->db->commit();
1090
1091
    	return $paiement_id;
1092
    }
1093
1094
    /**
1095
     * Add a payment to pay partially or completely one or several invoices.
1096
     * Warning: Take care that all invoices are owned by the same customer.
1097
     * Example of value for parameter arrayofamounts: {"1": "99.99", "2": "10"}
1098
     *
1099
     * @param array   $arrayofamounts     {@from body}  Array with id of invoices with amount to pay for each invoice
1100
     * @param string  $datepaye           {@from body}  Payment date        {@type timestamp}
1101
     * @param int     $paiementid         {@from body}  Payment mode Id {@min 1}
1102
     * @param string  $closepaidinvoices  {@from body}  Close paid invoices {@choice yes,no}
1103
     * @param int     $accountid          {@from body}  Account Id {@min 1}
1104
     * @param string  $num_paiement       {@from body}  Payment number (optional)
1105
     * @param string  $comment            {@from body}  Note (optional)
1106
     * @param string  $chqemetteur        {@from body}  Payment issuer (mandatory if paiementcode = 'CHQ')
1107
     * @param string  $chqbank            {@from body}  Issuer bank name (optional)
1108
     *
1109
     * @url     POST /paymentsdistributed
1110
     *
1111
     * @return int  Payment ID
1112
     * @throws 400
1113
     * @throws 401
1114
     * @throws 403
1115
     * @throws 404
1116
     */
1117
    function addPaymentDistributed($arrayofamounts, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement='', $comment='', $chqemetteur='', $chqbank='')
1118
    {
1119
        global $conf;
1120
1121
        require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
1122
1123
        if(! DolibarrApiAccess::$user->rights->facture->creer) {
1124
            throw new RestException(403);
1125
        }
1126
        foreach($arrayofamounts as $id => $amount) {
1127
        	if(empty($id)) {
1128
        		throw new RestException(400, 'Invoice ID is mandatory. Fill the invoice id and amount into arrayofamounts parameter. For example: {"1": "99.99", "2": "10"}');
1129
        	}
1130
        	if( ! DolibarrApi::_checkAccessToResource('facture',$id)) {
1131
        		throw new RestException(403, 'Access not allowed on invoice ID '.$id.' for login '.DolibarrApiAccess::$user->login);
1132
        	}
1133
        }
1134
1135
        if (! empty($conf->banque->enabled)) {
1136
        	if(empty($accountid)) {
1137
        		throw new RestException(400, 'Account ID is mandatory');
1138
        	}
1139
        }
1140
        if(empty($paiementid)) {
1141
        	throw new RestException(400, 'Paiement ID or Paiement Code is mandatory');
1142
        }
1143
1144
        $this->db->begin();
1145
1146
        $amounts = array();
1147
        $multicurrency_amounts = array();
1148
1149
        // Loop on each invoice to pay
1150
        foreach($arrayofamounts as $id => $amount)
1151
        {
1152
        	$result = $this->invoice->fetch($id);
1153
        	if( ! $result ) {
1154
        		$this->db->rollback();
1155
        		throw new RestException(404, 'Invoice ID '.$id.' not found');
1156
        	}
1157
1158
        	// Calculate amount to pay
1159
        	$totalpaye = $this->invoice->getSommePaiement();
1160
        	$totalcreditnotes = $this->invoice->getSumCreditNotesUsed();
1161
        	$totaldeposits = $this->invoice->getSumDepositsUsed();
1162
        	$resteapayer = price2num($this->invoice->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT');
1163
        	if ($amount != 'remain')
1164
        	{
1165
        		if ($amount > $resteapayer)
1166
        		{
1167
        			$this->db->rollback();
1168
        			throw new RestException(400, 'Payment amount on invoice ID '.$id.' ('.$amount.') is higher than remain to pay ('.$resteapayer.')');
1169
        		}
1170
        		$resteapayer = $amount;
1171
        	}
1172
            // Clean parameters amount if payment is for a credit note
1173
            if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1174
                $resteapayer = price2num($resteapayer,'MT');
1175
                $amounts[$id] = -$resteapayer;
1176
                // Multicurrency
1177
                $newvalue = price2num($this->invoice->multicurrency_total_ttc,'MT');
1178
                $multicurrency_amounts[$id] = -$newvalue;
1179
            } else {
1180
                $resteapayer = price2num($resteapayer,'MT');
1181
                $amounts[$id] = $resteapayer;
1182
                // Multicurrency
1183
                $newvalue = price2num($this->invoice->multicurrency_total_ttc,'MT');
1184
                $multicurrency_amounts[$id] = $newvalue;
1185
            }
1186
        }
1187
1188
        // Creation of payment line
1189
        $paiement = new Paiement($this->db);
1190
        $paiement->datepaye     = $datepaye;
1191
        $paiement->amounts      = $amounts;                           // Array with all payments dispatching with invoice id
1192
        $paiement->multicurrency_amounts = $multicurrency_amounts;    // Array with all payments dispatching
1193
        $paiement->paiementid   = $paiementid;
1194
        $paiement->paiementcode = dol_getIdFromCode($this->db,$paiementid,'c_paiement','id','code',1);
0 ignored issues
show
Bug introduced by
The property paiementcode does not exist on Paiement. Did you mean paiementid?
Loading history...
1195
        $paiement->num_paiement = $num_paiement;
1196
        $paiement->note         = $comment;
1197
        $paiement_id = $paiement->create(DolibarrApiAccess::$user, ($closepaidinvoices=='yes'?1:0));    // This include closing invoices
1198
        if ($paiement_id < 0)
1199
        {
1200
            $this->db->rollback();
1201
            throw new RestException(400, 'Payment error : '.$paiement->error);
1202
        }
1203
        if (! empty($conf->banque->enabled)) {
1204
            $label='(CustomerInvoicePayment)';
1205
            if($paiement->paiementcode == 'CHQ' && empty($chqemetteur)) {
1206
                  throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paiement->paiementcode);
1207
            }
1208
            if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) $label='(CustomerInvoicePaymentBack)';  // Refund of a credit note
1209
            $result=$paiement->addPaymentToBank(DolibarrApiAccess::$user,'payment',$label,$accountid,$chqemetteur,$chqbank);
1210
            if ($result < 0)
1211
            {
1212
                $this->db->rollback();
1213
                throw new RestException(400, 'Add payment to bank error : '.$paiement->error);
1214
            }
1215
        }
1216
1217
        $this->db->commit();
1218
1219
        return $paiement_id;
1220
    }
1221
1222
    /**
1223
     * Clean sensible object datas
1224
     *
1225
     * @param   object  $object    Object to clean
1226
     * @return    array    Array of cleaned object properties
1227
     */
1228
    function _cleanObjectDatas($object)
1229
    {
1230
1231
        $object = parent::_cleanObjectDatas($object);
1232
1233
        unset($object->note);
1234
        unset($object->address);
1235
        unset($object->barcode_type);
1236
        unset($object->barcode_type_code);
1237
        unset($object->barcode_type_label);
1238
        unset($object->barcode_type_coder);
1239
1240
        return $object;
1241
    }
1242
1243
    /**
1244
     * Validate fields before create or update object
1245
     *
1246
     * @param array|null    $data       Datas to validate
1247
     * @return array
1248
     *
1249
     * @throws RestException
1250
     */
1251
    function _validate($data)
1252
    {
1253
        $invoice = array();
1254
        foreach (Invoices::$FIELDS as $field) {
1255
            if (!isset($data[$field])) {
1256
                throw new RestException(400, "$field field missing");
1257
            }
1258
            $invoice[$field] = $data[$field];
1259
        }
1260
        return $invoice;
1261
    }
1262
}
1263