Passed
Push — dev ( f7d146...05f415 )
by Rafael
60:50
created

PaiementFourn::create()   F

Complexity

Conditions 47
Paths 1106

Size

Total Lines 254
Code Lines 172

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 47
eloc 172
nc 1106
nop 3
dl 0
loc 254
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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:

1
<?php
2
3
/* Copyright (C) 2002-2004  Rodolphe Quiedeville        <[email protected]>
4
 * Copyright (C) 2004-2007  Laurent Destailleur         <[email protected]>
5
 * Copyright (C) 2005       Marc Barilley / Ocebo       <[email protected]>
6
 * Copyright (C) 2005-2009  Regis Houssin               <[email protected]>
7
 * Copyright (C) 2010-2011  Juanjo Menent               <[email protected]>
8
 * Copyright (C) 2014       Marcos García               <[email protected]>
9
 * Copyright (C) 2018       Nicolas ZABOURI	            <[email protected]>
10
 * Copyright (C) 2018       Frédéric France             <frederic.francenetlogic.fr>
11
 * Copyright (C) 2023       Joachim Kueter		        <[email protected]>
12
 * Copyright (C) 2023       Sylvain Legrand		        <[email protected]>
13
 * Copyright (C) 2024       Frédéric France             <[email protected]>
14
 * Copyright (C) 2024		MDW							<[email protected]>
15
 * Copyright (C) 2024       Rafael San José             <[email protected]>
16
 *
17
 * This program is free software; you can redistribute it and/or modify
18
 * it under the terms of the GNU General Public License as published by
19
 * the Free Software Foundation; either version 3 of the License, or
20
 * (at your option) any later version.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
 * GNU General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU General Public License
28
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
29
 */
30
31
namespace Dolibarr\Code\Fourn\Classes;
32
33
use Dolibarr\Code\Compta\Classes\Paiement;
34
use Dolibarr\Code\MultiCurrency\Classes\MultiCurrency;
35
use DoliDB;
36
37
/**
38
 *      \file       htdocs/fourn/class/paiementfourn.class.php
39
 *      \ingroup    fournisseur, facture
40
 *      \brief      File of class to manage payments of suppliers invoices
41
 */
42
43
/**
44
 *  Class to manage payments for supplier invoices
45
 */
46
class PaiementFourn extends Paiement
47
{
48
    /**
49
     * @var string ID to identify managed object
50
     */
51
    public $element = 'payment_supplier';
52
53
    /**
54
     * @var string Name of table without prefix where object is stored
55
     */
56
    public $table_element = 'paiementfourn';
57
58
    /**
59
     * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
60
     */
61
    public $picto = 'payment';
62
63
    public $statut; //Status of payment. 0 = unvalidated; 1 = validated
64
    // fk_paiement dans llx_paiement est l'id du type de paiement (7 pour CHQ, ...)
65
    // fk_paiement dans llx_paiement_facture est le rowid du paiement
66
67
    /**
68
     * Label of payment type
69
     * @var string
70
     */
71
    public $type_label;
72
73
    /**
74
     * Code of Payment type
75
     * @var string
76
     */
77
    public $type_code;
78
79
    /**
80
     * @var string Id of prelevement
81
     */
82
    public $id_prelevement;
83
84
    /**
85
     * @var string num_prelevement
86
     */
87
    public $num_prelevement;
88
89
90
    /**
91
     *  Constructor
92
     *
93
     *  @param      DoliDB      $db      Database handler
94
     */
95
    public function __construct($db)
96
    {
97
        $this->db = $db;
98
    }
99
100
    /**
101
     *  Load payment object
102
     *
103
     *  @param  int     $id         Id if payment to get
104
     *  @param  string  $ref        Ref of payment to get
105
     *  @param  int     $fk_bank    Id of bank line associated to payment
106
     *  @return int                 Return integer <0 if KO, -2 if not found, >0 if OK
107
     */
108
    public function fetch($id, $ref = '', $fk_bank = 0)
109
    {
110
        $error = 0;
111
112
        $sql = 'SELECT p.rowid, p.ref, p.entity, p.datep as dp, p.amount, p.statut, p.fk_bank, p.multicurrency_amount,';
113
        $sql .= ' c.code as payment_code, c.libelle as payment_type,';
114
        $sql .= ' p.num_paiement as num_payment, p.note, b.fk_account, p.fk_paiement';
115
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiementfourn as p';
116
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_paiement as c ON p.fk_paiement = c.id';
117
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank as b ON p.fk_bank = b.rowid';
118
        $sql .= ' WHERE p.entity IN (' . getEntity('facture_fourn') . ')';
119
        if ($id > 0) {
120
            $sql .= ' AND p.rowid = ' . ((int) $id);
121
        } elseif ($ref) {
122
            $sql .= " AND p.ref = '" . $this->db->escape($ref) . "'";
123
        } elseif ($fk_bank > 0) {
124
            $sql .= ' AND p.fk_bank = ' . ((int) $fk_bank);
125
        }
126
        //print $sql;
127
128
        $resql = $this->db->query($sql);
129
        if ($resql) {
130
            $num = $this->db->num_rows($resql);
131
            if ($num > 0) {
132
                $obj = $this->db->fetch_object($resql);
133
134
                $this->id             = $obj->rowid;
135
                $this->ref            = $obj->ref;
136
                $this->entity         = $obj->entity;
137
                $this->date           = $this->db->jdate($obj->dp);
138
                $this->datepaye       = $this->db->jdate($obj->dp);
139
                $this->num_payment    = $obj->num_payment;
140
                $this->bank_account   = $obj->fk_account;
141
                $this->fk_account     = $obj->fk_account;
142
                $this->bank_line      = $obj->fk_bank;
143
                $this->montant        = $obj->amount; // deprecated
144
                $this->amount         = $obj->amount;
145
                $this->multicurrency_amount = $obj->multicurrency_amount;
146
                $this->note                 = $obj->note;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$note has been deprecated: Use $note_private instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

146
                /** @scrutinizer ignore-deprecated */ $this->note                 = $obj->note;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
147
                $this->note_private         = $obj->note;
148
                $this->type_code            = $obj->payment_code;
149
                $this->type_label           = $obj->payment_type;
150
                $this->fk_paiement           = $obj->fk_paiement;
151
                $this->statut               = $obj->statut;
152
153
                $error = 1;
154
            } else {
155
                $error = -2; // TODO Use 0 instead
156
            }
157
            $this->db->free($resql);
158
        } else {
159
            dol_print_error($this->db);
160
            $error = -1;
161
        }
162
        return $error;
163
    }
164
165
    /**
166
     *  Create payment in database
167
     *
168
     *  @param      User       $user                Object of creating user
169
     *  @param      int        $closepaidinvoices   1=Also close paid invoices to paid, 0=Do nothing more
170
     *  @param      Societe    $thirdparty          Thirdparty
171
     *  @return     int                             id of created payment, < 0 if error
172
     */
173
    public function create($user, $closepaidinvoices = 0, $thirdparty = null)
174
    {
175
        global $langs, $conf;
176
177
        $error = 0;
178
        $way = $this->getWay();
179
180
        $now = dol_now();
181
182
        // Clean parameters
183
        $totalamount = 0;
184
        $totalamount_converted = 0;
185
        $atleastonepaymentnotnull = 0;
186
187
        if ($way == 'dolibarr') {
188
            $amounts = &$this->amounts;
189
            $amounts_to_update = &$this->multicurrency_amounts;
190
        } else {
191
            $amounts = &$this->multicurrency_amounts;
192
            $amounts_to_update = &$this->amounts;
193
        }
194
195
        $currencyofpayment = '';
196
        $currencytxofpayment = '';
197
198
        foreach ($amounts as $key => $value) {
199
            if (empty($value)) {
200
                continue;
201
            }
202
            // $key is id of invoice, $value is amount, $way is a 'dolibarr' if amount is in main currency, 'customer' if in foreign currency
203
            $value_converted = MultiCurrency::getAmountConversionFromInvoiceRate($key, $value ? $value : 0, $way, 'facture_fourn');
204
            // Add controls of input validity
205
            if ($value_converted === false) {
206
                // We failed to find the conversion for one invoice
207
                $this->error = $langs->trans('FailedToFoundTheConversionRateForInvoice');
208
                return -1;
209
            }
210
            if (empty($currencyofpayment)) {
211
                $currencyofpayment = $this->multicurrency_code[$key];
212
            }
213
            if ($currencyofpayment != $this->multicurrency_code[$key]) {
214
                // If we have invoices with different currencies in the payment, we stop here
215
                $this->error = 'ErrorYouTryToPayInvoicesWithDifferentCurrenciesInSamePayment';
216
                return -1;
217
            }
218
            if (empty($currencytxofpayment)) {
219
                $currencytxofpayment = $this->multicurrency_tx[$key];
220
            }
221
222
            $totalamount_converted += $value_converted;
223
            $amounts_to_update[$key] = price2num($value_converted, 'MT');
224
225
            $newvalue = price2num($value, 'MT');
226
            $amounts[$key] = $newvalue;
227
            $totalamount += $newvalue;
228
            if (!empty($newvalue)) {
229
                $atleastonepaymentnotnull++;
230
            }
231
        }
232
233
        if (!empty($currencyofpayment)) {
234
            // We must check that the currency of invoices is the same than the currency of the bank
235
            $bankaccount = new Account($this->db);
236
            $bankaccount->fetch($this->fk_account);
237
            $bankcurrencycode = empty($bankaccount->currency_code) ? $conf->currency : $bankaccount->currency_code;
238
            if ($currencyofpayment != $bankcurrencycode && $currencyofpayment != $conf->currency && $bankcurrencycode != $conf->currency) {
239
                $langs->load("errors");
240
                $this->error = $langs->trans('ErrorYouTryToPayInvoicesInACurrencyFromBankWithAnotherCurrency', $currencyofpayment, $bankcurrencycode);
241
                return -1;
242
            }
243
        }
244
245
246
        $totalamount = (float) price2num($totalamount);
247
        $totalamount_converted = (float) price2num($totalamount_converted);
248
249
        dol_syslog(get_only_class($this) . "::create", LOG_DEBUG);
250
251
        $this->db->begin();
252
253
        if ($totalamount != 0) { // On accepte les montants negatifs
254
            $ref = $this->getNextNumRef(is_object($thirdparty) ? $thirdparty : '');
255
256
            if ($way == 'dolibarr') {
257
                $total = $totalamount;
258
                $mtotal = $totalamount_converted; // Maybe use price2num with MT for the converted value
259
            } else {
260
                $total = $totalamount_converted; // Maybe use price2num with MT for the converted value
261
                $mtotal = $totalamount;
262
            }
263
264
            $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'paiementfourn (';
265
            $sql .= 'ref, entity, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, fk_user_author, fk_bank)';
266
            $sql .= " VALUES ('" . $this->db->escape($ref) . "', " . ((int) $conf->entity) . ", '" . $this->db->idate($now) . "',";
267
            $sql .= " '" . $this->db->idate($this->datepaye) . "', " . ((float) $total) . ", " . ((float) $mtotal) . ", " . ((int) $this->paiementid) . ", '" . $this->db->escape($this->num_payment) . "', '" . $this->db->escape($this->note_private) . "', " . ((int) $user->id) . ", 0)";
268
269
            $resql = $this->db->query($sql);
270
            if ($resql) {
271
                $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . 'paiementfourn');
272
273
                // Insere tableau des montants / factures
274
                foreach ($this->amounts as $key => $amount) {
275
                    $facid = $key;
276
                    if (is_numeric($amount) && $amount != 0) {
277
                        $amount = price2num($amount);
278
                        $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'paiementfourn_facturefourn (fk_facturefourn, fk_paiementfourn, amount, multicurrency_amount, multicurrency_code, multicurrency_tx)';
279
                        $sql .= " VALUES (" . ((int) $facid) . ", " . ((int) $this->id) . ", " . ((float) $amount) . ', ' . ((float) $this->multicurrency_amounts[$key]) . ', ' . ($currencyofpayment ? "'" . $this->db->escape($currencyofpayment) . "'" : 'NULL') . ', ' . (!empty($currencytxofpayment) ? (float) $currencytxofpayment : 1) . ')';
280
                        $resql = $this->db->query($sql);
281
                        if ($resql) {
282
                            $invoice = new FactureFournisseur($this->db);
283
                            $invoice->fetch($facid);
284
285
                            // If we want to closed paid invoices
286
                            if ($closepaidinvoices) {
287
                                $paiement = $invoice->getSommePaiement();
288
                                $creditnotes = $invoice->getSumCreditNotesUsed();
289
                                //$creditnotes = 0;
290
                                $deposits = $invoice->getSumDepositsUsed();
291
                                //$deposits = 0;
292
                                $alreadypayed = price2num($paiement + $creditnotes + $deposits, 'MT');
293
                                $remaintopay = price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits, 'MT');
294
                                if ($remaintopay == 0) {
295
                                    // If invoice is a down payment, we also convert down payment to discount
296
                                    if ($invoice->type == FactureFournisseur::TYPE_DEPOSIT) {
297
                                        $amount_ht = $amount_tva = $amount_ttc = array();
298
                                        $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array();
299
300
                                        // Insert one discount by VAT rate category
301
                                        $discount = new DiscountAbsolute($this->db);
302
                                        $discount->fetch('', 0, $invoice->id);
303
                                        if (empty($discount->id)) {    // If the invoice was not yet converted into a discount (this may have been done manually before we come here)
304
                                            $discount->discount_type = 1; // Supplier discount
305
                                            $discount->description = '(DEPOSIT)';
306
                                            $discount->fk_soc = $invoice->socid;
307
                                            $discount->socid = $invoice->socid;
308
                                            $discount->fk_invoice_supplier_source = $invoice->id;
309
310
                                            // Loop on each vat rate
311
                                            $i = 0;
312
                                            foreach ($invoice->lines as $line) {
313
                                                if ($line->total_ht != 0) {    // no need to create discount if amount is null
314
                                                    $amount_ht[$line->tva_tx] += $line->total_ht;
315
                                                    $amount_tva[$line->tva_tx] += $line->total_tva;
316
                                                    $amount_ttc[$line->tva_tx] += $line->total_ttc;
317
                                                    $multicurrency_amount_ht[$line->tva_tx] += $line->multicurrency_total_ht;
318
                                                    $multicurrency_amount_tva[$line->tva_tx] += $line->multicurrency_total_tva;
319
                                                    $multicurrency_amount_ttc[$line->tva_tx] += $line->multicurrency_total_ttc;
320
                                                    $i++;
321
                                                }
322
                                            }
323
324
                                            foreach ($amount_ht as $tva_tx => $xxx) {
325
                                                $discount->amount_ht = abs($amount_ht[$tva_tx]);
326
                                                $discount->amount_tva = abs($amount_tva[$tva_tx]);
327
                                                $discount->amount_ttc = abs($amount_ttc[$tva_tx]);
328
                                                $discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]);
329
                                                $discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]);
330
                                                $discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]);
331
                                                $discount->tva_tx = abs($tva_tx);
332
333
                                                $result = $discount->create($user);
334
                                                if ($result < 0) {
335
                                                    $error++;
336
                                                    break;
337
                                                }
338
                                            }
339
                                        }
340
341
                                        if ($error) {
342
                                            setEventMessages($discount->error, $discount->errors, 'errors');
343
                                            $error++;
344
                                        }
345
                                    }
346
347
                                    // Set invoice to paid
348
                                    if (!$error) {
349
                                        $result = $invoice->setPaid($user, '', '');
350
                                        if ($result < 0) {
351
                                            $this->error = $invoice->error;
352
                                            $error++;
353
                                        }
354
                                    }
355
                                } else {
356
                                    // hook to have an option to automatically close a closable invoice with less payment than the total amount (e.g. agreed cash discount terms)
357
                                    global $hookmanager;
358
                                    $hookmanager->initHooks(array('payment_supplierdao'));
359
                                    $parameters = array('facid' => $facid, 'invoice' => $invoice, 'remaintopay' => $remaintopay);
360
                                    $action = 'CLOSEPAIDSUPPLIERINVOICE';
361
                                    $reshook = $hookmanager->executeHooks('createPayment', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
362
                                    if ($reshook < 0) {
363
                                        $this->error = $hookmanager->error;
364
                                        $error++;
365
                                    } elseif ($reshook == 0) {
366
                                        dol_syslog("Remain to pay for invoice " . $facid . " not null. We do nothing more.");
367
                                    }
368
                                }
369
                            }
370
371
                            // Regenerate documents of invoices
372
                            if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
373
                                $newlang = '';
374
                                $outputlangs = $langs;
375
                                if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
376
                                    $invoice->fetch_thirdparty();
377
                                    $newlang = $invoice->thirdparty->default_lang;
378
                                }
379
                                if (!empty($newlang)) {
380
                                    $outputlangs = new Translate("", $conf);
381
                                    $outputlangs->setDefaultLang($newlang);
382
                                }
383
                                $ret = $invoice->fetch($facid); // Reload to get new records
384
                                $result = $invoice->generateDocument($invoice->model_pdf, $outputlangs);
385
                                if ($result < 0) {
386
                                    setEventMessages($invoice->error, $invoice->errors, 'errors');
387
                                    $error++;
388
                                }
389
                            }
390
                        } else {
391
                            $this->error = $this->db->lasterror();
392
                            $error++;
393
                        }
394
                    } else {
395
                        dol_syslog(get_only_class($this) . '::Create Amount line ' . $key . ' not a number. We discard it.');
396
                    }
397
                }
398
399
                if (!$error) {
400
                    // Call trigger
401
                    $result = $this->call_trigger('PAYMENT_SUPPLIER_CREATE', $user);
402
                    if ($result < 0) {
403
                        $error++;
404
                    }
405
                    // End call triggers
406
                }
407
            } else {
408
                $this->error = $this->db->lasterror();
409
                $error++;
410
            }
411
        } else {
412
            $this->error = "ErrorTotalIsNull";
413
            dol_syslog('PaiementFourn::Create Error ' . $this->error, LOG_ERR);
414
            $error++;
415
        }
416
417
        if ($totalamount != 0 && $error == 0) { // On accepte les montants negatifs
418
            $this->amount = $total;
419
            $this->total = $total;
420
            $this->multicurrency_amount = $mtotal;
421
            $this->db->commit();
422
            dol_syslog('PaiementFourn::Create Ok Total = ' . $this->amount . ', Total currency = ' . $this->multicurrency_amount);
423
            return $this->id;
424
        } else {
425
            $this->db->rollback();
426
            return -1;
427
        }
428
    }
429
430
431
    /**
432
     *  Delete a payment and lines generated into accounts
433
     *  Si le paiement porte sur un ecriture compte qui est rapprochee, on refuse
434
     *  Si le paiement porte sur au moins une facture a "payee", on refuse
435
     *  @TODO Add User $user as first param
436
     *  @param      User    $user           User making the deletion
437
     *  @param      int     $notrigger      No trigger
438
     *  @return     int                     Return integer <0 si ko, >0 si ok
439
     */
440
    public function delete($user = null, $notrigger = 0)
441
    {
442
        if (empty($user)) {
443
            global $user;
444
        }
445
446
        $bank_line_id = $this->bank_line;
447
448
        $this->db->begin();
449
450
        // Verifier si paiement porte pas sur une facture a l'etat payee
451
        // Si c'est le cas, on refuse la suppression
452
        $billsarray = $this->getBillsArray('paye=1');
453
        if (is_array($billsarray)) {
454
            if (count($billsarray)) {
455
                $this->error = "ErrorCantDeletePaymentSharedWithPayedInvoice";
456
                $this->db->rollback();
457
                return -1;
458
            }
459
        } else {
460
            $this->db->rollback();
461
            return -2;
462
        }
463
464
        // Verifier si paiement ne porte pas sur ecriture bancaire rapprochee
465
        // Si c'est le cas, on refuse le delete
466
        if ($bank_line_id) {
467
            $accline = new AccountLine($this->db);
468
            $accline->fetch($bank_line_id);
469
            if ($accline->rappro) {
470
                $this->error = "ErrorCantDeletePaymentReconciliated";
471
                $this->db->rollback();
472
                return -3;
473
            }
474
        }
475
476
        // Efface la ligne de paiement (dans paiement_facture et paiement)
477
        $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'paiementfourn_facturefourn';
478
        $sql .= ' WHERE fk_paiementfourn = ' . ((int) $this->id);
479
        $resql = $this->db->query($sql);
480
        if ($resql) {
481
            $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'paiementfourn';
482
            $sql .= " WHERE rowid = " . ((int) $this->id);
483
            $result = $this->db->query($sql);
484
            if (!$result) {
485
                $this->error = $this->db->error();
486
                $this->db->rollback();
487
                return -3;
488
            }
489
490
            // Supprimer l'ecriture bancaire si paiement lie a ecriture
491
            if ($bank_line_id) {
492
                $accline = new AccountLine($this->db);
493
                $result = $accline->fetch($bank_line_id);
494
                if ($result > 0) { // If result = 0, record not found, we don't try to delete
495
                    $result = $accline->delete($user);
496
                }
497
                if ($result < 0) {
498
                    $this->error = $accline->error;
499
                    $this->db->rollback();
500
                    return -4;
501
                }
502
            }
503
504
            if (!$notrigger) {
505
                // Appel des triggers
506
                $result = $this->call_trigger('PAYMENT_SUPPLIER_DELETE', $user);
507
                if ($result < 0) {
508
                    $this->db->rollback();
509
                    return -1;
510
                }
511
                // Fin appel triggers
512
            }
513
514
            $this->db->commit();
515
            return 1;
516
        } else {
517
            $this->error = $this->db->error;
518
            $this->db->rollback();
519
            return -5;
520
        }
521
    }
522
523
    /**
524
     *  Information on object
525
     *
526
     *  @param  int     $id      Id du paiement don't il faut afficher les infos
527
     *  @return void
528
     */
529
    public function info($id)
530
    {
531
        $sql = 'SELECT c.rowid, datec, fk_user_author as fk_user_creat, tms as fk_user_modif';
532
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiementfourn as c';
533
        $sql .= ' WHERE c.rowid = ' . ((int) $id);
534
535
        $resql = $this->db->query($sql);
536
        if ($resql) {
537
            $num = $this->db->num_rows($resql);
538
            if ($num) {
539
                $obj = $this->db->fetch_object($resql);
540
541
                $this->id = $obj->rowid;
542
                $this->user_creation_id = $obj->fk_user_creat;
543
                $this->user_modification_id = $obj->fk_user_modif;
544
                $this->date_creation     = $this->db->jdate($obj->datec);
545
                $this->date_modification = $this->db->jdate($obj->tms);
546
            }
547
            $this->db->free($resql);
548
        } else {
549
            dol_print_error($this->db);
550
        }
551
    }
552
553
    /**
554
     *  Return list of supplier invoices the payment point to
555
     *
556
     *  @param      string  $filter         SQL filter. Warning: This value must not come from a user input.
557
     *  @return     array|int                   Array of supplier invoice id | <0 si ko
558
     */
559
    public function getBillsArray($filter = '')
560
    {
561
        $sql = 'SELECT fk_facturefourn';
562
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiementfourn_facturefourn as pf, ' . MAIN_DB_PREFIX . 'facture_fourn as f';
563
        $sql .= ' WHERE pf.fk_facturefourn = f.rowid AND fk_paiementfourn = ' . ((int) $this->id);
564
        if ($filter) {
565
            $sql .= " AND " . $filter;
566
        }
567
568
        dol_syslog(get_only_class($this) . '::getBillsArray', LOG_DEBUG);
569
        $resql = $this->db->query($sql);
570
        if ($resql) {
571
            $i = 0;
572
            $num = $this->db->num_rows($resql);
573
            $billsarray = array();
574
575
            while ($i < $num) {
576
                $obj = $this->db->fetch_object($resql);
577
                $billsarray[$i] = $obj->fk_facturefourn;
578
                $i++;
579
            }
580
581
            return $billsarray;
582
        } else {
583
            $this->error = $this->db->error();
584
            dol_syslog(get_only_class($this) . '::getBillsArray Error ' . $this->error);
585
            return -1;
586
        }
587
    }
588
589
    /**
590
     *  Return the label of the status
591
     *
592
     *  @param  int     $mode          0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
593
     *  @return string                 Label of status
594
     */
595
    public function getLibStatut($mode = 0)
596
    {
597
        return $this->LibStatut($this->statut, $mode);
598
    }
599
600
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
601
    /**
602
     *  Return the label of a given status
603
     *
604
     *  @param  int     $status        Id status
605
     *  @param  int     $mode          0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
606
     *  @return string                 Label of status
607
     */
608
    public function LibStatut($status, $mode = 0)
609
    {
610
		// phpcs:enable
611
        global $langs;
612
613
        $langs->load('compta');
614
        /*if ($mode == 0)
615
        {
616
            if ($status == 0) return $langs->trans('ToValidate');
617
            if ($status == 1) return $langs->trans('Validated');
618
        }
619
        if ($mode == 1)
620
        {
621
            if ($status == 0) return $langs->trans('ToValidate');
622
            if ($status == 1) return $langs->trans('Validated');
623
        }
624
        if ($mode == 2)
625
        {
626
            if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate');
627
            if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated');
628
        }
629
        if ($mode == 3)
630
        {
631
            if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1');
632
            if ($status == 1) return img_picto($langs->trans('Validated'),'statut4');
633
        }
634
        if ($mode == 4)
635
        {
636
            if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate');
637
            if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated');
638
        }
639
        if ($mode == 5)
640
        {
641
            if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1');
642
            if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4');
643
        }
644
        if ($mode == 6)
645
        {
646
            if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1');
647
            if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4');
648
        }*/
649
        return '';
650
    }
651
652
653
    /**
654
     *  Return clicable name (with picto eventually)
655
     *
656
     *  @param      int     $withpicto      0=No picto, 1=Include picto into link, 2=Only picto
657
     *  @param      string  $option         Sur quoi pointe le lien
658
     *  @param      string  $mode           'withlistofinvoices'=Include list of invoices into tooltip
659
     *  @param      int     $notooltip      1=Disable tooltip
660
     *  @param      string  $morecss        Add more CSS
661
     *  @return     string                  Chaine avec URL
662
     */
663
    public function getNomUrl($withpicto = 0, $option = '', $mode = 'withlistofinvoices', $notooltip = 0, $morecss = '')
664
    {
665
        global $langs, $conf, $hookmanager;
666
667
        if (!empty($conf->dol_no_mouse_hover)) {
668
            $notooltip = 1; // Force disable tooltips
669
        }
670
671
        $result = '';
672
673
        $text = $this->ref; // Sometimes ref contains label
674
        $reg = array();
675
        if (preg_match('/^\((.*)\)$/i', $text, $reg)) {
676
            // Label generique car entre parentheses. On l'affiche en le traduisant
677
            if ($reg[1] == 'paiement') {
678
                $reg[1] = 'Payment';
679
            }
680
            $text = $langs->trans($reg[1]);
681
        }
682
683
        $label = img_picto('', $this->picto) . ' <u>' . $langs->trans("Payment") . '</u><br>';
684
        $label .= '<strong>' . $langs->trans("Ref") . ':</strong> ' . $text;
685
        $dateofpayment = ($this->datepaye ? $this->datepaye : $this->date);
686
        if ($dateofpayment) {
687
            $label .= '<br><strong>' . $langs->trans("Date") . ':</strong> ' . dol_print_date($dateofpayment, 'dayhour', 'tzuser');
688
        }
689
        if ($this->amount) {
690
            $label .= '<br><strong>' . $langs->trans("Amount") . ':</strong> ' . price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
691
        }
692
693
        $linkclose = '';
694
        if (empty($notooltip)) {
695
            if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
696
                $label = $langs->trans("Payment");
697
                $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
698
            }
699
            $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
700
            $linkclose .= ' class="classfortooltip' . ($morecss ? ' ' . $morecss : '') . '"';
701
        } else {
702
            $linkclose = ($morecss ? ' class="' . $morecss . '"' : '');
703
        }
704
705
        $linkstart = '<a href="' . constant('BASE_URL') . 'fourn/paiement/card.php?id=' . $this->id . '"';
706
        $linkstart .= $linkclose . '>';
707
        $linkend = '</a>';
708
709
        $result .= $linkstart;
710
        if ($withpicto) {
711
            $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="' . (($withpicto != 2) ? 'paddingright ' : '') . 'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
712
        }
713
        if ($withpicto != 2) {
714
            $result .= $this->ref;
715
        }
716
        $result .= $linkend;
717
718
        global $action;
719
        $hookmanager->initHooks(array($this->element . 'dao'));
720
        $parameters = array('id' => $this->id, 'getnomurl' => &$result);
721
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
722
        if ($reshook > 0) {
723
            $result = $hookmanager->resPrint;
724
        } else {
725
            $result .= $hookmanager->resPrint;
726
        }
727
        return $result;
728
    }
729
730
    /**
731
     *  Initialise an instance with random values.
732
     *  Used to build previews or test instances.
733
     *  id must be 0 if object instance is a specimen.
734
     *
735
     *  @param  string      $option     ''=Create a specimen invoice with lines, 'nolines'=No lines
736
     *  @return int
737
     */
738
    public function initAsSpecimen($option = '')
739
    {
740
        $now = dol_now();
741
        $arraynow = dol_getdate($now);
742
        $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
743
744
        // Initialize parameters
745
        $this->id = 0;
746
        $this->ref = 'SPECIMEN';
747
        $this->specimen = 1;
748
        $this->facid = 1;
749
        $this->socid = 1;
750
        $this->datepaye = $nownotime;
751
752
        return 1;
753
    }
754
755
    /**
756
     *      Return next reference of supplier invoice not already used (or last reference)
757
     *      according to numbering module defined into constant SUPPLIER_PAYMENT_ADDON
758
     *
759
     *      @param     Societe      $soc        object company
760
     *      @param     string       $mode       'next' for next value or 'last' for last value
761
     *      @return    string                   free ref or last ref
762
     */
763
    public function getNextNumRef($soc, $mode = 'next')
764
    {
765
        global $conf, $db, $langs;
766
        $langs->load("bills");
767
768
        // Clean parameters (if not defined or using deprecated value)
769
        if (!getDolGlobalString('SUPPLIER_PAYMENT_ADDON')) {
770
            $conf->global->SUPPLIER_PAYMENT_ADDON = 'mod_supplier_payment_bronan';
771
        } elseif (getDolGlobalString('SUPPLIER_PAYMENT_ADDON') == 'brodator') {
772
            $conf->global->SUPPLIER_PAYMENT_ADDON = 'mod_supplier_payment_brodator';
773
        } elseif (getDolGlobalString('SUPPLIER_PAYMENT_ADDON') == 'bronan') {
774
            $conf->global->SUPPLIER_PAYMENT_ADDON = 'mod_supplier_payment_bronan';
775
        }
776
777
        if (getDolGlobalString('SUPPLIER_PAYMENT_ADDON')) {
778
            $mybool = false;
779
780
            $file = getDolGlobalString('SUPPLIER_PAYMENT_ADDON') . ".php";
781
            $classname = getDolGlobalString('SUPPLIER_PAYMENT_ADDON');
782
783
            // Include file with class
784
            $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
785
786
            foreach ($dirmodels as $reldir) {
787
                $dir = dol_buildpath($reldir . "core/modules/supplier_payment/");
788
789
                // Load file with numbering class (if found)
790
                if (is_file($dir . $file) && is_readable($dir . $file)) {
791
                    $mybool = (include_once $dir . $file) || $mybool;
792
                }
793
            }
794
795
            // For compatibility
796
            if ($mybool === false) {
797
                $file = getDolGlobalString('SUPPLIER_PAYMENT_ADDON') . ".php";
798
                $classname = "mod_supplier_payment_" . getDolGlobalString('SUPPLIER_PAYMENT_ADDON');
799
                $classname = preg_replace('/\-.*$/', '', $classname);
800
                // Include file with class
801
                foreach ($conf->file->dol_document_root as $dirroot) {
802
                    $dir = $dirroot . "/core/modules/supplier_payment/";
803
804
                    // Load file with numbering class (if found)
805
                    if (is_file($dir . $file) && is_readable($dir . $file)) {
806
                        $mybool = (include_once $dir . $file) || $mybool;
807
                    }
808
                }
809
            }
810
811
            if ($mybool === false) {
812
                dol_print_error(null, "Failed to include file " . $file);
813
                return '';
814
            }
815
816
            $obj = new $classname();
817
            $numref = "";
818
            $numref = $obj->getNextValue($soc, $this);
819
820
            /**
821
             * $numref can be empty in case we ask for the last value because if there is no invoice created with the
822
             * set up mask.
823
             */
824
            if ($mode != 'last' && !$numref) {
825
                dol_print_error($db, "SupplierPayment::getNextNumRef " . $obj->error);
826
                return "";
827
            }
828
829
            return $numref;
830
        } else {
831
            $langs->load("errors");
832
            print $langs->trans("Error") . " " . $langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Supplier"));
833
            return "";
834
        }
835
    }
836
837
    /**
838
     *  Create a document onto disk according to template model.
839
     *
840
     *  @param      string      $modele         Force template to use ('' to not force)
841
     *  @param      Translate   $outputlangs    Object lang a utiliser pour traduction
842
     *  @param      int         $hidedetails    Hide details of lines
843
     *  @param      int         $hidedesc       Hide description
844
     *  @param      int         $hideref        Hide ref
845
     *  @param   null|array  $moreparams     Array to provide more information
846
     *  @return     int                         Return integer <0 if KO, 0 if nothing done, >0 if OK
847
     */
848
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
849
    {
850
        global $conf, $user, $langs;
851
852
        $langs->load("suppliers");
853
854
        // Set the model on the model name to use
855
        if (empty($modele)) {
856
            if (getDolGlobalString('SUPPLIER_PAYMENT_ADDON_PDF')) {
857
                $modele = getDolGlobalString('SUPPLIER_PAYMENT_ADDON_PDF');
858
            } else {
859
                $modele = ''; // No default value. For supplier invoice, we allow to disable all PDF generation
860
            }
861
        }
862
863
        if (empty($modele)) {
864
            return 0;
865
        } else {
866
            $modelpath = "core/modules/supplier_payment/doc/";
867
868
            return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
869
        }
870
    }
871
872
873
874
    /**
875
     *  get the right way of payment
876
     *
877
     *  @return     string  'dolibarr' if standard comportment or paid in dolibarr currency, 'customer' if payment received from multicurrency inputs
878
     */
879
    public function getWay()
880
    {
881
        global $conf;
882
883
        $way = 'dolibarr';
884
        if (isModEnabled("multicurrency")) {
885
            foreach ($this->multicurrency_amounts as $value) {
886
                if (!empty($value)) { // one value found then payment is in invoice currency
887
                    $way = 'customer';
888
                    break;
889
                }
890
            }
891
        }
892
893
        return $way;
894
    }
895
896
897
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
898
    /**
899
     *  Load the third party of object, from id into this->thirdparty
900
     *
901
     *  @param      int     $force_thirdparty_id    Force thirdparty id
902
     *  @return     int                             Return integer <0 if KO, >0 if OK
903
     */
904
    public function fetch_thirdparty($force_thirdparty_id = 0)
905
    {
906
		// phpcs:enable
907
908
        if (empty($force_thirdparty_id)) {
909
            $billsarray = $this->getBillsArray(); // From payment, the fk_soc isn't available, we should load the first supplier invoice to get him
910
            if (!empty($billsarray)) {
911
                $supplier_invoice = new FactureFournisseur($this->db);
912
                if ($supplier_invoice->fetch($billsarray[0]) > 0) {
913
                    $force_thirdparty_id = $supplier_invoice->socid;
914
                }
915
            }
916
        }
917
918
        return parent::fetch_thirdparty($force_thirdparty_id);
919
    }
920
}
921