BonPrelevement::getListInvoices()   B
last analyzed

Complexity

Conditions 11
Paths 72

Size

Total Lines 66
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 46
nc 72
nop 2
dl 0
loc 66
rs 7.3166
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) 2004-2005  Rodolphe Quiedeville        <[email protected]>
4
 * Copyright (C) 2005-2012  Regis Houssin               <[email protected]>
5
 * Copyright (C) 2010-2015  Juanjo Menent               <[email protected]>
6
 * Copyright (C) 2010-2014  Laurent Destailleur         <[email protected]>
7
 * Copyright (C) 2014-2016  Ferran Marcet               <[email protected]>
8
 * Copyright (C) 2018       Nicolas ZABOURI             <[email protected]>
9
 * Copyright (C) 2019       JC Prieto			        <[email protected]><[email protected]>
10
 * Copyright (C) 2024       MDW					        <[email protected]>
11
 * Copyright (C) 2024       Frédéric France             <[email protected]>
12
 * Copyright (C) 2024       Rafael San José             <[email protected]>
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 3 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26
 */
27
28
namespace Dolibarr\Code\Compta\Classes;
29
30
use Dolibarr\Code\Fourn\Classes\FactureFournisseur;
31
use Dolibarr\Code\Fourn\Classes\PaiementFourn;
32
use Dolibarr\Code\Salaries\Classes\PaymentSalary;
33
use Dolibarr\Code\Salaries\Classes\Salary;
34
use Dolibarr\Code\User\Classes\User;
35
use Dolibarr\Core\Base\CommonObject;
36
use Dolibarr\Code\Societe\Classes\Societe;
37
use DoliDB;
38
39
/**
40
 * \file       htdocs/compta/prelevement/class/bonprelevement.class.php
41
 * \ingroup    prelevement
42
 * \brief      File of withdrawal receipts class
43
 */
44
45
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/bank.lib.php';
46
47
/**
48
 *  Class to manage withdrawal receipts
49
 * Model PrelevementBon
50
 */
51
class BonPrelevement extends CommonObject
52
{
53
    /**
54
     * @var string ID to identify managed object
55
     */
56
    public $element = 'widthdraw';
57
58
    /**
59
     * @var string Name of table without prefix where object is stored
60
     */
61
    public $table_element = 'prelevement_bons';
62
63
    /**
64
     * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
65
     */
66
    public $picto = 'payment';
67
68
    public $date_echeance;
69
    public $raison_sociale;
70
    public $reference_remise;
71
    public $emetteur_code_guichet;
72
    public $emetteur_numero_compte;
73
    public $emetteur_code_banque;
74
    public $emetteur_number_key;
75
    public $sepa_xml_pti_in_ctti;
76
77
    public $emetteur_iban;
78
    public $emetteur_bic;
79
    public $emetteur_ics;
80
81
    public $user_trans;
82
    public $user_credit;
83
84
    public $total;
85
    public $fetched;
86
    public $labelStatus = array();
87
88
    public $factures = array();
89
90
    /**
91
     * @var array<int,string>
92
     */
93
    public $methodes_trans = array();
94
95
    public $invoice_in_error = array();
96
    public $thirdparty_in_error = array();
97
98
    /**
99
     * @var resource    Handler of the file for direct debit or credit transfer order
100
     */
101
    public $file;
102
103
    /**
104
     * @var string filename
105
     */
106
    public $filename;
107
108
    const STATUS_DRAFT = 0;
109
    const STATUS_TRANSFERED = 1;
110
    const STATUS_CREDITED = 2;      // STATUS_CREDITED and STATUS_DEBITED is same. Difference is in ->type
111
    const STATUS_DEBITED = 2;       // STATUS_CREDITED and STATUS_DEBITED is same. Difference is in ->type
112
113
114
    /**
115
     *  'type' field format:
116
     *      'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',
117
     *      'select' (list of values are in 'options'),
118
     *      'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]',
119
     *      'chkbxlst:...',
120
     *      'varchar(x)',
121
     *      'text', 'text:none', 'html',
122
     *      'double(24,8)', 'real', 'price',
123
     *      'date', 'datetime', 'timestamp', 'duration',
124
     *      'boolean', 'checkbox', 'radio', 'array',
125
     *      'mail', 'phone', 'url', 'password', 'ip'
126
     *      Note: Filter must be a Dolibarr filter syntax string. Example: "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.status:!=:0) or (t.nature:is:NULL)"
127
     *  'label' the translation key.
128
     *  'picto' is code of a picto to show before value in forms
129
     *  'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM' or 'isModEnabled("multicurrency")' ...)
130
     *  'position' is the sort order of field.
131
     *  'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
132
     *  'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing)
133
     *  'noteditable' says if field is not editable (1 or 0)
134
     *  'alwayseditable' says if field can be modified also when status is not draft ('1' or '0')
135
     *  'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created.
136
     *  'index' if we want an index in database.
137
     *  'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommended to name the field fk_...).
138
     *  'searchall' is 1 if we want to search in this field when making a search from the quick search button.
139
     *  'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage)
140
     *  'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200'
141
     *  'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click.
142
     *  'showoncombobox' if value of the field must be visible into the label of the combobox that list record
143
     *  'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code.
144
     *  'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar'
145
     *  'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1.
146
     *  'comment' is not used. You can store here any text of your choice. It is not used by application.
147
     *  'validate' is 1 if need to validate with $this->validateField()
148
     *  'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value)
149
     *
150
     *  Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor.
151
     */
152
153
    // BEGIN MODULEBUILDER PROPERTIES
154
    /**
155
     * @var array<string,array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array<int,string>,comment?:string}>  Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string,array{type:...ring>,comment?:string}> at position 16 could not be parsed: Expected '}' at position 16, but found 'int'.
Loading history...
156
     */
157
    public $fields = array(
158
        'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 10, 'notnull' => 1, 'visible' => 0,),
159
        'ref' => array('type' => 'varchar(12)', 'label' => 'Ref', 'enabled' => 1, 'position' => 15, 'notnull' => 0, 'visible' => -1, 'csslist' => 'tdoverflowmax150', 'showoncombobox' => 1,),
160
        'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 25, 'notnull' => 0, 'visible' => -1,),
161
        'amount' => array('type' => 'double(24,8)', 'label' => 'Amount', 'enabled' => 1, 'position' => 30, 'notnull' => 0, 'visible' => -1,),
162
        'statut' => array('type' => 'smallint(6)', 'label' => 'Statut', 'enabled' => 1, 'position' => 500, 'notnull' => 0, 'visible' => -1, 'arrayofkeyval' => array(0 => 'Wait', 1 => 'Transfered', 2 => 'Credited')),
163
        'credite' => array('type' => 'smallint(6)', 'label' => 'Credite', 'enabled' => 1, 'position' => 40, 'notnull' => 0, 'visible' => -1,),
164
        'note' => array('type' => 'text', 'label' => 'Note', 'enabled' => 1, 'position' => 45, 'notnull' => 0, 'visible' => -1,),
165
        'date_trans' => array('type' => 'datetime', 'label' => 'Datetrans', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => -1,),
166
        'method_trans' => array('type' => 'smallint(6)', 'label' => 'Methodtrans', 'enabled' => 1, 'position' => 55, 'notnull' => 0, 'visible' => -1,),
167
        'fk_user_trans' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fkusertrans', 'enabled' => 1, 'position' => 60, 'notnull' => 0, 'visible' => -1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150',),
168
        'date_credit' => array('type' => 'datetime', 'label' => 'Datecredit', 'enabled' => 1, 'position' => 65, 'notnull' => 0, 'visible' => -1,),
169
        'fk_user_credit' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fkusercredit', 'enabled' => 1, 'position' => 70, 'notnull' => 0, 'visible' => -1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150',),
170
        'type' => array('type' => 'varchar(16)', 'label' => 'Type', 'enabled' => 1, 'position' => 75, 'notnull' => 0, 'visible' => -1,),
171
        'fk_bank_account' => array('type' => 'integer', 'label' => 'Fkbankaccount', 'enabled' => 1, 'position' => 80, 'notnull' => 0, 'visible' => -1, 'css' => 'maxwidth500 widthcentpercentminusxx',),
172
    );
173
    public $rowid;
174
    public $ref;
175
    public $datec;
176
    public $amount;
177
178
    /**
179
     * @var int Status
180
     * @deprecated
181
     */
182
    public $statut;
183
    /**
184
     * @var int Status
185
     */
186
    public $status;
187
188
    public $credite;
189
    public $note;
190
    public $date_trans;
191
    /**
192
     * @var int Current transport method, index to $methodes_trans
193
     */
194
    public $method_trans;
195
    public $fk_user_trans;
196
    public $date_credit;
197
    public $fk_user_credit;
198
    public $type;
199
    public $fk_bank_account;
200
    // END MODULEBUILDER PROPERTIES
201
202
    /**
203
     *  Constructor
204
     *
205
     *  @param      DoliDB      $db         Database handler
206
     */
207
    public function __construct($db)
208
    {
209
        $this->db = $db;
210
211
        $this->filename = '';
212
213
        $this->date_echeance = dol_now();
214
        $this->raison_sociale = "";
215
        $this->reference_remise = "";
216
217
        $this->emetteur_code_guichet = "";
218
        $this->emetteur_numero_compte = "";
219
        $this->emetteur_code_banque = "";
220
        $this->emetteur_number_key = "";
221
        $this->sepa_xml_pti_in_ctti = false;
222
223
        $this->emetteur_iban = "";
224
        $this->emetteur_bic = "";
225
        $this->emetteur_ics = "";
226
227
        $this->factures = array();
228
229
        $this->methodes_trans = array(0 => 'Internet', 2 => 'Email', 3 => 'Api');
230
231
        $this->fetched = 0;
232
    }
233
234
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
235
    /**
236
     * Add invoice to withdrawal
237
     *
238
     * @param   int     $invoice_id     ID of invoice to add or ID of salary to add
239
     * @param   int     $client_id      id invoice customer
240
     * @param   string  $client_nom     customer name
241
     * @param   int     $amount         amount of invoice
242
     * @param   string  $code_banque    code of bank withdrawal
243
     * @param   string  $code_guichet   code of bank's office
244
     * @param   string  $number bank    account number
245
     * @param   string  $number_key     number key of account number
246
     * @param   string  $type           'debit-order' or 'bank-transfer'
247
     * @param   string  $sourcetype     'salary' for salary, '' for invoices
248
     * @return  int                     >0 if OK, <0 if KO
249
     */
250
    public function AddFacture($invoice_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key, $type = 'debit-order', $sourcetype = '')
251
    {
252
		// phpcs:enable
253
        $result = 0;
254
        $line_id = 0;
255
256
        // Add lines into prelevement_lignes
257
        $result = $this->addline($line_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key, $sourcetype);
258
259
260
        if ($result == 0) {
261
            if ($line_id > 0) {
262
                $sql = "INSERT INTO " . MAIN_DB_PREFIX . "prelevement (";
263
                if ($type != 'bank-transfer') {
264
                    $sql .= "fk_facture";
265
                } else {
266
                    if ($sourcetype == 'salary') {
267
                        $sql .= "fk_salary";
268
                    } else {
269
                        $sql .= "fk_facture_fourn";
270
                    }
271
                }
272
                $sql .= ",fk_prelevement_lignes";
273
                $sql .= ") VALUES (";
274
                $sql .= ((int) $invoice_id);
275
                $sql .= ", " . ((int) $line_id);
276
                $sql .= ")";
277
278
                if ($this->db->query($sql)) {
279
                    $result = 0;
280
                } else {
281
                    $result = -1;
282
                    $this->errors[] = get_only_class($this) . "::AddFacture " . $this->db->lasterror;
283
                    dol_syslog(get_only_class($this) . "::AddFacture Error $result");
284
                }
285
            } else {
286
                $result = -2;
287
                $this->errors[] = get_only_class($this) . "::AddFacture linedid Empty";
288
                dol_syslog(get_only_class($this) . "::AddFacture Error $result");
289
            }
290
        } else {
291
            $result = -3;
292
            dol_syslog(get_only_class($this) . "::AddFacture Error $result");
293
        }
294
295
        return $result;
296
    }
297
298
    /**
299
     *  Add line to withdrawal
300
     *
301
     *  @param  int     $line_id        ID of line added (returned parameter)
302
     *  @param  int     $client_id      ID of thirdparty for invoices, ID of user for salaries
303
     *  @param  string  $client_nom     customer name
304
     *  @param  int     $amount         amount of invoice
305
     *  @param  string  $code_banque    code of bank withdrawal
306
     *  @param  string  $code_guichet   code of bank's office
307
     *  @param  string  $number         bank account number
308
     *  @param  string  $number_key     number key of account number
309
     *  @param  string  $sourcetype     'salary' for salary, '' for invoices
310
     *  @return int                     >0 if OK, <0 if KO
311
     */
312
    public function addline(&$line_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key, $sourcetype = '')
313
    {
314
        $result = -1;
315
        $concat = 0;    // ??? what is this for. Seems not used.
316
317
        if ($concat == 1) {
318
            /*
319
             * We aggregate the lines
320
             */
321
            $sql = "SELECT rowid";
322
            $sql .= " FROM  " . MAIN_DB_PREFIX . "prelevement_lignes";
323
            $sql .= " WHERE fk_prelevement_bons = " . ((int) $this->id);
324
            if ($sourcetype == 'salary') {
325
                $sql .= " AND fk_soc = " . ((int) $client_id);
326
            } else {
327
                $sql .= " AND fk_user = " . ((int) $client_id);
328
            }
329
            $sql .= " AND code_banque = '" . $this->db->escape($code_banque) . "'";
330
            $sql .= " AND code_guichet = '" . $this->db->escape($code_guichet) . "'";
331
            $sql .= " AND number = '" . $this->db->escape($number) . "'";
332
333
            $resql = $this->db->query($sql);
334
            if ($resql) {
335
                $num = $this->db->num_rows($resql);
336
            } else {
337
                $result = -1;
338
            }
339
        } else {
340
            /*
341
             * No aggregate
342
             */
343
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "prelevement_lignes (";
344
            $sql .= "fk_prelevement_bons";
345
            $sql .= ", fk_soc";
346
            $sql .= ", client_nom";
347
            $sql .= ", amount";
348
            $sql .= ", code_banque";
349
            $sql .= ", code_guichet";
350
            $sql .= ", number";
351
            $sql .= ", cle_rib";
352
            $sql .= ($sourcetype == 'salary' ? ", fk_user" : "");
353
            $sql .= ") VALUES (";
354
            $sql .= $this->id;
355
            $sql .= ", " . (($sourcetype != 'salary') ? ((int) $client_id) : "0");  // fk_soc can't be null
356
            $sql .= ", '" . $this->db->escape($client_nom) . "'";
357
            $sql .= ", " . ((float) price2num($amount));
358
            $sql .= ", '" . $this->db->escape($code_banque) . "'";
359
            $sql .= ", '" . $this->db->escape($code_guichet) . "'";
360
            $sql .= ", '" . $this->db->escape($number) . "'";
361
            $sql .= ", '" . $this->db->escape($number_key) . "'";
362
            $sql .= (($sourcetype == 'salary') ? ", " . ((int) $client_id) : '');
363
            $sql .= ")";
364
            if ($this->db->query($sql)) {
365
                $line_id = $this->db->last_insert_id(MAIN_DB_PREFIX . "prelevement_lignes");
366
                $result = 0;
367
            } else {
368
                $this->errors[] = get_only_class($this) . "::addline Error -2 " . $this->db->lasterror;
369
                dol_syslog(get_only_class($this) . "::addline Error -2");
370
                $result = -2;
371
            }
372
        }
373
374
        return $result;
375
    }
376
377
    /**
378
     *  Return error string
379
     *
380
     *  @param  int     $error       Id of error
381
     *  @return string               Error string
382
     */
383
    public function getErrorString($error)
384
    {
385
        global $langs;
386
387
        $errors = array();
388
389
        $errors[1027] = $langs->trans("DateInvalid");
390
391
        return $errors[abs($error)];
392
    }
393
394
    /**
395
     *  Get object and lines from database
396
     *
397
     *  @param  int     $rowid      Id of object to load
398
     *  @param  string  $ref        Ref of direct debit
399
     *  @return int                 >0 if OK, <0 if KO
400
     */
401
    public function fetch($rowid, $ref = '')
402
    {
403
        $sql = "SELECT p.rowid, p.ref, p.amount, p.note";
404
        $sql .= ", p.datec as dc";
405
        $sql .= ", p.date_trans as date_trans";
406
        $sql .= ", p.method_trans, p.fk_user_trans";
407
        $sql .= ", p.date_credit as date_credit";
408
        $sql .= ", p.fk_user_credit";
409
        $sql .= ", p.type";
410
        $sql .= ", p.fk_bank_account";
411
        $sql .= ", p.statut as status";
412
        $sql .= " FROM " . MAIN_DB_PREFIX . "prelevement_bons as p";
413
        $sql .= " WHERE p.entity IN (" . getEntity('invoice') . ")";
414
        if ($rowid > 0) {
415
            $sql .= " AND p.rowid = " . ((int) $rowid);
416
        } else {
417
            $sql .= " AND p.ref = '" . $this->db->escape($ref) . "'";
418
        }
419
420
        dol_syslog(get_only_class($this) . "::fetch", LOG_DEBUG);
421
        $result = $this->db->query($sql);
422
        if ($result) {
423
            if ($this->db->num_rows($result)) {
424
                $obj = $this->db->fetch_object($result);
425
426
                $this->id             = $obj->rowid;
427
                $this->ref            = $obj->ref;
428
                $this->amount         = $obj->amount;
429
                $this->note           = $obj->note;
430
                $this->datec          = $this->db->jdate($obj->dc);
431
432
                $this->date_trans     = $this->db->jdate($obj->date_trans);
433
                $this->method_trans   = $obj->method_trans;
434
                $this->user_trans     = $obj->fk_user_trans;
435
436
                $this->date_credit    = $this->db->jdate($obj->date_credit);
437
                $this->user_credit    = $obj->fk_user_credit;
438
439
                $this->type           = $obj->type;
440
                $this->fk_bank_account = $obj->fk_bank_account;
441
442
                $this->status         = $obj->status;
443
                if (empty($this->status)) {     // Value is sometimes null in database
444
                    $this->status = 0;
445
                }
446
                $this->statut         = $this->status; // For backward compatibility
447
448
                $this->fetched = 1;
449
450
                return 1;
451
            } else {
452
                dol_syslog(get_only_class($this) . "::Fetch Erreur aucune ligne retournee");
453
                return -1;
454
            }
455
        } else {
456
            return -2;
457
        }
458
    }
459
460
    /**
461
     * Update object into database
462
     *
463
     * @param  User $user      User that modifies
464
     * @param  int  $notrigger 0=launch triggers after, 1=disable triggers
465
     * @return int             Return integer <0 if KO, >0 if OK
466
     */
467
    public function update(User $user, $notrigger = 0)
468
    {
469
        return $this->updateCommon($user, $notrigger);
470
    }
471
472
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
473
    /**
474
     *  Set direct debit or credit transfer order to "paid" status.
475
     *  Then create the payment for each invoice or salary of the prelemevement_bon.
476
     *
477
     *  @param  User    $user           Id of user
478
     *  @param  int     $date           date of action
479
     *  @param  string  $type           'salary' for type=salary
480
     *  @return int                     >0 if OK, <0 if KO
481
     */
482
    public function set_infocredit($user, $date, $type = '')
483
    {
484
		// phpcs:enable
485
        global $conf, $langs;
486
487
        $error = 0;
488
489
        if ($this->fetched == 1) {
490
            if ($date < $this->date_trans) {
491
                $langs->load("errors");
492
                $this->error = $langs->trans('ErrorDateOfMovementLowerThanDateOfFileTransmission');
493
                dol_syslog("bon-prelevment::set_infocredit 1027 " . $this->error);
494
                return -1027;
495
            }
496
497
            $this->db->begin();
498
499
            $sql = " UPDATE " . MAIN_DB_PREFIX . "prelevement_bons";
500
            $sql .= " SET fk_user_credit = " . ((int) $user->id);
501
            $sql .= ", statut = " . self::STATUS_CREDITED;
502
            $sql .= ", date_credit = '" . $this->db->idate($date) . "'";
503
            $sql .= " WHERE rowid = " . ((int) $this->id);
504
            $sql .= " AND entity = " . ((int) $conf->entity);
505
            $sql .= " AND statut = " . self::STATUS_TRANSFERED;
506
507
            $resql = $this->db->query($sql);
508
            if ($resql) {
509
                $langs->load('withdrawals');
510
                $subject = $langs->trans("InfoCreditSubject", $this->ref);
511
                $message = $langs->trans("InfoCreditMessage", $this->ref, dol_print_date($date, 'dayhour'));
512
513
                // Add payment of withdrawal into bank
514
                $fk_bank_account = $this->fk_bank_account;
515
                if (empty($fk_bank_account)) {
516
                    $fk_bank_account = ($this->type == 'bank-transfer' ? getDolGlobalInt('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT') : getDolGlobalInt('PRELEVEMENT_ID_BANKACCOUNT'));
517
                }
518
519
                $facs = array();
520
                $amounts = array();
521
                $amountsperthirdparty = array();
522
523
                $facs = $this->getListInvoices(1, $type);
524
                if ($this->error) {
525
                    $error++;
526
                }
527
528
                // Loop on each invoice or salary.
529
                // $facs should be array(0=>id, 1=>amount requested)
530
                $num = count($facs);
531
                for ($i = 0; $i < $num; $i++) {
532
                    if ($this->type == 'bank-transfer') {
533
                        if ($type == 'salary') {
534
                            $fac = new Salary($this->db);
535
                        } else {
536
                            $fac = new FactureFournisseur($this->db);
537
                        }
538
                    } else {
539
                        $fac = new Facture($this->db);
540
                    }
541
542
                    $result = $fac->fetch($facs[$i][0]);
543
544
                    $amounts[$fac->id] = $facs[$i][1];
545
                    if ($this->type == 'bank-transfer') {
546
                        if ($type == 'salary') {
547
                            $amountsperthirdparty[$fac->fk_user][$fac->id] = $facs[$i][1];
548
                        } else {
549
                            $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1];
550
                        }
551
                    } else {
552
                        $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1];
553
                    }
554
555
                    $totalpaid = $fac->getSommePaiement();
556
                    $totalcreditnotes = 0;
557
                    if (method_exists($fac, 'getSumCreditNotesUsed')) {
558
                        $totalcreditnotes = $fac->getSumCreditNotesUsed();
0 ignored issues
show
Bug introduced by
The method getSumCreditNotesUsed() does not exist on Dolibarr\Code\Salaries\Classes\Salary. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

558
                        /** @scrutinizer ignore-call */ 
559
                        $totalcreditnotes = $fac->getSumCreditNotesUsed();
Loading history...
559
                    }
560
                    $totaldeposits = 0;
561
                    if (method_exists($fac, 'getSumDepositsUsed')) {
562
                        $totaldeposits = $fac->getSumDepositsUsed();
0 ignored issues
show
Bug introduced by
The method getSumDepositsUsed() does not exist on Dolibarr\Code\Salaries\Classes\Salary. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

562
                        /** @scrutinizer ignore-call */ 
563
                        $totaldeposits = $fac->getSumDepositsUsed();
Loading history...
563
                    }
564
                    $alreadypayed = $totalpaid + $totalcreditnotes + $totaldeposits;
565
566
                    // Set the main document to pay with status Paid.
567
                    // @TODO Move this after creation of payments done after
568
                    $amountofdocument = $fac->total_ttc;
569
                    if ($type == 'salary') {
570
                        $amountofdocument = $fac->amount;
571
                    }
572
                    if (price2num($alreadypayed + $facs[$i][1], 'MT') == price2num($amountofdocument, 'MT')) {
573
                        $result = $fac->setPaid($user);
574
                        if ($result < 0) {
575
                            $this->error = $fac->error;
576
                            $this->errors = $fac->errors;
577
                        }
578
                    }
579
                }
580
581
                // Make one payment per customer or employee
582
                foreach ($amountsperthirdparty as $thirdpartyid => $cursoramounts) {
583
                    if ($this->type == 'bank-transfer') {
584
                        if ($type == 'salary') {
585
                            $paiement = new PaymentSalary($this->db);
586
                        } else {
587
                            $paiement = new PaiementFourn($this->db);
588
                        }
589
                    } else {
590
                        $paiement = new Paiement($this->db);
591
                    }
592
                    $paiement->datepaye = $date;
593
                    $paiement->amounts = $cursoramounts; // Array with detail of dispatching of payments for each invoice
594
595
                    if ($this->type == 'bank-transfer') {
596
                        if ($type == 'salary') {
597
                            $paiement->datep = $date;
0 ignored issues
show
Bug Best Practice introduced by
The property datep does not exist on Dolibarr\Code\Fourn\Classes\PaiementFourn. Since you implemented __set, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property datep does not exist on Dolibarr\Code\Compta\Classes\Paiement. Since you implemented __set, consider adding a @property annotation.
Loading history...
598
599
                            $paiement->paiementid = 2;
0 ignored issues
show
Bug Best Practice introduced by
The property paiementid does not exist on Dolibarr\Code\Salaries\Classes\PaymentSalary. Since you implemented __set, consider adding a @property annotation.
Loading history...
600
                            $paiement->fk_typepayment = 2;
0 ignored issues
show
Bug Best Practice introduced by
The property fk_typepayment does not exist on Dolibarr\Code\Compta\Classes\Paiement. Since you implemented __set, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property fk_typepayment does not exist on Dolibarr\Code\Fourn\Classes\PaiementFourn. Since you implemented __set, consider adding a @property annotation.
Loading history...
601
                            $paiement->paiementcode = 'VIR';
0 ignored issues
show
Bug Best Practice introduced by
The property paiementcode does not exist on Dolibarr\Code\Salaries\Classes\PaymentSalary. Since you implemented __set, consider adding a @property annotation.
Loading history...
602
                        } else {
603
                            $paiement->paiementid = 2;
604
                            $paiement->paiementcode = 'VIR';
605
                        }
606
                    } else {
607
                        $paiement->paiementid = 3;
608
                        $paiement->paiementcode = 'PRE';
609
                    }
610
611
                    $paiement->num_payment = $this->ref; // Set ref of direct debit note
612
                    $paiement->id_prelevement = $this->id;
0 ignored issues
show
Bug Best Practice introduced by
The property id_prelevement does not exist on Dolibarr\Code\Salaries\Classes\PaymentSalary. Since you implemented __set, consider adding a @property annotation.
Loading history...
613
614
                    $result = $paiement->create($user); // This use ->paiementid, that is ID of payment mode
615
616
                    if ($result < 0) {
617
                        $error++;
618
                        $this->error = $paiement->error;
619
                        $this->errors = $paiement->errors;
620
                        dol_syslog(get_only_class($this) . "::set_infocredit AddPayment Error " . $this->error);
621
                    } else {
622
                        if ($this->type == 'bank-transfer') {
623
                            if ($type == 'salary') {
624
                                $modeforaddpayment = 'payment_salary';
625
                                $labelforaddpayment = '(SalaryPayment)';
626
                                $addbankurl = 'credit-transfer';
627
                            } else {
628
                                $modeforaddpayment = 'payment_supplier';
629
                                $labelforaddpayment = '(SupplierInvoicePayment)';
630
                                $addbankurl = 'credit-transfer';
631
                            }
632
                        } else {
633
                            $modeforaddpayment = 'payment';
634
                            $labelforaddpayment = '(CustomerInvoicePayment)';
635
                            $addbankurl = 'direct-debit';   // = 'directdebit'
636
                        }
637
638
                        $result = $paiement->addPaymentToBank($user, $modeforaddpayment, $labelforaddpayment, $fk_bank_account, '', '', 0, '', $addbankurl);
639
640
                        if ($result < 0) {
641
                            $error++;
642
                            $this->error = $paiement->error;
643
                            $this->errors = $paiement->errors;
644
                            dol_syslog(get_only_class($this) . "::set_infocredit AddPaymentToBank Error " . $this->error);
645
                        }
646
                    }
647
                }
648
649
                // Update withdrawal line
650
                // TODO: Translate to ligneprelevement.class.php
651
                if (!$error) {
652
                    $sql = " UPDATE " . MAIN_DB_PREFIX . "prelevement_lignes";
653
                    $sql .= " SET statut = 2";
654
                    $sql .= " WHERE fk_prelevement_bons = " . ((int) $this->id);
655
656
                    if (!$this->db->query($sql)) {
657
                        dol_syslog(get_only_class($this) . "::set_infocredit Update lines Error");
658
                        $error++;
659
                    }
660
                }
661
            } else {
662
                $this->error = $this->db->lasterror();
663
                dol_syslog(get_only_class($this) . "::set_infocredit Update Bons Error");
664
                $error++;
665
            }
666
667
            // End of procedure
668
            if ($error == 0) {
669
                $this->date_credit = $date;     // date credit or debit
670
                $this->statut = self::STATUS_CREDITED;
671
                $this->status = self::STATUS_CREDITED;
672
673
                $this->db->commit();
674
                return 0;
675
            } else {
676
                $this->db->rollback();
677
                return -1;
678
            }
679
        } else {
680
            return -1026;
681
        }
682
    }
683
684
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
685
    /**
686
     *  Set withdrawal to transmitted status
687
     *
688
     *  @param  User        $user       Id of user
689
     *  @param  int         $date       Date of action
690
     *  @param  int         $method     Method of transmission to bank (0=Internet, 1=Api...)
691
     *  @return int                     >0 if OK, <0 if KO
692
     */
693
    public function set_infotrans($user, $date, $method)
694
    {
695
		// phpcs:enable
696
        global $conf, $langs;
697
698
        $error = 0;
699
700
        dol_syslog(get_only_class($this) . "::set_infotrans Start", LOG_INFO);
701
702
        if ($this->db->begin()) {
703
            $sql = "UPDATE " . MAIN_DB_PREFIX . "prelevement_bons ";
704
            $sql .= " SET fk_user_trans = " . $user->id;
705
            $sql .= " , date_trans = '" . $this->db->idate($date) . "'";
706
            $sql .= " , method_trans = " . ((int) $method);
707
            $sql .= " , statut = " . self::STATUS_TRANSFERED;
708
            $sql .= " WHERE rowid = " . ((int) $this->id);
709
            $sql .= " AND entity = " . ((int) $conf->entity);
710
            $sql .= " AND statut = " . self::STATUS_DRAFT;
711
712
            if ($this->db->query($sql)) {
713
                $this->method_trans = $method;
714
                $langs->load('withdrawals');
715
                $subject = $langs->trans("InfoTransSubject", $this->ref);
716
                $message = $langs->trans("InfoTransMessage", $this->ref, dolGetFirstLastname($user->firstname, $user->lastname));
717
                $message .= $langs->trans("InfoTransData", price($this->amount), $this->methodes_trans[$this->method_trans], dol_print_date($date, 'day'));
718
719
                // TODO Call trigger to create a notification using notification module
720
            } else {
721
                $error++;
722
            }
723
724
            if ($error == 0) {
725
                $this->date_trans = $date;
726
                $this->statut = self::STATUS_TRANSFERED;
727
                $this->status = self::STATUS_TRANSFERED;
728
                $this->user_trans = $user->id;
729
730
                $this->db->commit();
731
732
                return 0;
733
            } else {
734
                $this->db->rollback();
735
                dol_syslog(get_only_class($this) . "::set_infotrans ROLLBACK", LOG_ERR);
736
737
                return -1;
738
            }
739
        } else {
740
            dol_syslog(get_only_class($this) . "::set_infotrans Ouverture transaction SQL impossible", LOG_CRIT);
741
            return -2;
742
        }
743
    }
744
745
    /**
746
     *  Get invoice or salary list (with amount or not)
747
     *
748
     *  @param  int     $amounts    If you want to get the amount of the order for each invoice or salary
749
     *  @param  string  $type       'salary' for type=salary
750
     *  @return array               Array(Id of invoices/salary, Amount to pay)
751
     */
752
    private function getListInvoices($amounts = 0, $type = '')
753
    {
754
        global $conf;
755
756
        $arr = array();
757
758
        dol_syslog(get_only_class($this) . "::getListInvoices");
759
760
        // Returns all invoices presented within same order
761
        $sql = "SELECT ";
762
        if ($this->type == 'bank-transfer') {
763
            if ($type == 'salary') {
764
                $sql .= " p.fk_salary";
765
            } else {
766
                $sql .= " p.fk_facture_fourn";
767
            }
768
        } else {
769
            $sql .= " p.fk_facture";
770
        }
771
        if ($amounts) {
772
            $sql .= ", SUM(pl.amount)";
773
        }
774
        $sql .= " FROM " . MAIN_DB_PREFIX . "prelevement_bons as pb,";
775
        $sql .= " " . MAIN_DB_PREFIX . "prelevement_lignes as pl,";
776
        $sql .= " " . MAIN_DB_PREFIX . "prelevement as p";
777
        $sql .= " WHERE p.fk_prelevement_lignes = pl.rowid";
778
        $sql .= " AND pl.fk_prelevement_bons = pb.rowid";
779
        $sql .= " AND pb.rowid = " . ((int) $this->id);
780
        $sql .= " AND pb.entity = " . ((int) $conf->entity);
781
        if ($amounts) {
782
            if ($this->type == 'bank-transfer') {
783
                if ($type == 'salary') {
784
                    $sql .= " GROUP BY p.fk_salary";
785
                } else {
786
                    $sql .= " GROUP BY p.fk_facture_fourn";
787
                }
788
            } else {
789
                $sql .= " GROUP BY p.fk_facture";
790
            }
791
        }
792
793
        $resql = $this->db->query($sql);
794
        if ($resql) {
795
            $num = $this->db->num_rows($resql);
796
797
            if ($num) {
798
                $i = 0;
799
                while ($i < $num) {
800
                    $row = $this->db->fetch_row($resql);
801
                    if (!$amounts) {
802
                        $arr[$i] = $row[0];
803
                    } else {
804
                        $arr[$i] = array(
805
                            $row[0],
806
                            $row[1]
807
                        );
808
                    }
809
                    $i++;
810
                }
811
            }
812
            $this->db->free($resql);
813
        } else {
814
            $this->error = $this->db->lasterror();
815
        }
816
817
        return $arr;
818
    }
819
820
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
821
    /**
822
     *  Returns amount waiting for direct debit payment or credit transfer payment
823
     *
824
     *  @param  string  $mode       'direct-debit' or 'bank-transfer'
825
     *  @param  string  $type        for type=salary
826
     *  @return double              Return integer <O if KO, Total amount
827
     */
828
    public function SommeAPrelever($mode = 'direct-debit', $type = '')
829
    {
830
		// phpcs:enable
831
        $sql = "SELECT sum(pd.amount) as nb";
832
        if ($type !== 'salary') {
833
            if ($mode != 'bank-transfer') {
834
                $sql .= " FROM " . MAIN_DB_PREFIX . "facture as f,";
835
            } else {
836
                $sql .= " FROM " . MAIN_DB_PREFIX . "facture_fourn as f,";
837
            }
838
        } else {
839
            $sql .= " FROM " . MAIN_DB_PREFIX . "salary as s,";
840
        }
841
        $sql .= " " . MAIN_DB_PREFIX . "prelevement_demande as pd";
842
        $sql .= ($type !== 'salary' ? " WHERE f.entity IN (" . getEntity('invoice') . ")" : " WHERE s.entity IN (" . getEntity('salary') . ")");
843
        if (!getDolGlobalString('WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS')) {
844
            $sql .= ($type !== 'salary' ? " AND f.fk_statut = " . Facture::STATUS_VALIDATED : " AND s.paye = " . Salary::STATUS_UNPAID);
845
        }
846
        if ($type !== 'salary') {
847
            if ($mode != 'bank-transfer') {
848
                $sql .= " AND f.rowid = pd.fk_facture";
849
            } else {
850
                $sql .= " AND f.rowid = pd.fk_facture_fourn";
851
            }
852
        } else {
853
            $sql .= " AND s.rowid = pd.fk_salary";
854
        }
855
        $sql .= ($type !== 'salary' ? " AND f.paye = 0" : "");
856
        $sql .= " AND pd.traite = 0";
857
        $sql .= " AND pd.ext_payment_id IS NULL";
858
        $sql .= ($type !== 'salary' ? " AND f.total_ttc > 0" : "");
859
860
        $resql = $this->db->query($sql);
861
        if ($resql) {
862
            $obj = $this->db->fetch_object($resql);
863
864
            $this->db->free($resql);
865
866
            return $obj->nb;
867
        } else {
868
            $error = 1;
869
            dol_syslog(get_only_class($this) . "::SommeAPrelever Erreur -1");
870
            dol_syslog($this->db->error());
871
872
            return -1;
873
        }
874
    }
875
876
    /**
877
     *  Get number of invoices waiting for payment
878
     *
879
     *  @param  string  $mode       'direct-debit' or 'bank-transfer'
880
     *  @param  string  $type        for salary invoice
881
     *  @return int                 Return integer <O if KO, number of invoices if OK
882
     */
883
    public function nbOfInvoiceToPay($mode = 'direct-debit', $type = '')
884
    {
885
        if ($type === 'salary') {
886
            return $this->NbFactureAPrelever($mode, 1);
887
        } else {
888
            return $this->NbFactureAPrelever($mode);
889
        }
890
    }
891
892
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
893
    /**
894
     *  Get number of invoices to pay
895
     *
896
     *  @param  string  $type       'direct-debit' or 'bank-transfer'
897
     *  @param  int     $forsalary  0= for facture & facture_supplier, 1=for salary
898
     *  @return int                 Return integer <O if KO, number of invoices if OK
899
     */
900
    public function NbFactureAPrelever($type = 'direct-debit', $forsalary = 0)
901
    {
902
		// phpcs:enable
903
        if ($forsalary == 1) {
904
            $sql = "SELECT count(s.rowid) as nb";
905
            $sql .= " FROM " . MAIN_DB_PREFIX . "salary as s";
906
        } else {
907
            $sql = "SELECT count(f.rowid) as nb";
908
909
            if ($type == 'bank-transfer') {
910
                $sql .= " FROM " . MAIN_DB_PREFIX . "facture_fourn as f";
911
            } else {
912
                $sql .= " FROM " . MAIN_DB_PREFIX . "facture as f";
913
            }
914
        }
915
        $sql .= ", " . MAIN_DB_PREFIX . "prelevement_demande as pd";
916
        if ($forsalary == 1) {
917
            $sql .= " WHERE s.entity IN (" . getEntity('invoice') . ")";
918
            if (!getDolGlobalString('WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS')) {
919
                $sql .= " AND s.paye = 0";
920
            }
921
        } else {
922
            $sql .= " WHERE f.entity IN (" . getEntity('invoice') . ")";
923
            if (!getDolGlobalString('WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS')) {
924
                $sql .= " AND f.fk_statut = " . Facture::STATUS_VALIDATED;
925
            }
926
        }
927
        if ($forsalary == 1) {
928
            $sql .= " AND s.rowid = pd.fk_salary";
929
        } else {
930
            if ($type == 'bank-transfer') {
931
                $sql .= " AND f.rowid = pd.fk_facture_fourn";
932
            } else {
933
                $sql .= " AND f.rowid = pd.fk_facture";
934
            }
935
        }
936
        $sql .= " AND pd.traite = 0";
937
        $sql .= " AND pd.ext_payment_id IS NULL";
938
        if (!$forsalary == 1) {
939
            $sql .= " AND f.total_ttc > 0";
940
        } else {
941
            $sql .= " AND s.paye = 0";
942
        }
943
944
        dol_syslog(get_only_class($this) . "::NbFactureAPrelever");
945
        $resql = $this->db->query($sql);
946
947
        if ($resql) {
948
            $obj = $this->db->fetch_object($resql);
949
            $this->db->free($resql);
950
951
            return $obj->nb;
952
        } else {
953
            $this->error = get_only_class($this) . "::NbFactureAPrelever Erreur -1 sql=" . $this->db->error();
954
            return -1;
955
        }
956
    }
957
958
959
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
960
    /**
961
     *  Create a BAN payment order:
962
     *  - Select waiting requests from prelevement_demande (or use $did if provided)
963
     *  - Check BAN values
964
     *  - Then create a direct debit order or a credit transfer order
965
     *  - Link the order with the prelevement_demande lines
966
     *  TODO delete params banque and agence when not necessary
967
     *
968
     *  @param  int     $banque             dolibarr mysoc bank
969
     *  @param  int     $agence             dolibarr mysoc bank office (guichet)
970
     *  @param  string  $mode               real=do action, simu=test only
971
     *  @param  string  $format             FRST, RCUR or ALL
972
     *  @param  string  $executiondate      Date to execute the transfer
973
     *  @param  int     $notrigger          Disable triggers
974
     *  @param  string  $type               'direct-debit' or 'bank-transfer'
975
     *  @param  int     $did                ID of an existing payment request. If $did is defined, we use the existing payment request.
976
     *  @param  int     $fk_bank_account    Bank account ID the receipt is generated for. Will use the ID into the setup of module Direct Debit or Credit Transfer if 0.
977
     *  @param  string  $sourcetype         'invoice' or 'salary'
978
     *  @return int                         Return integer <0 if KO, No of invoice included into file if OK
979
     */
980
    public function create($banque = 0, $agence = 0, $mode = 'real', $format = 'ALL', $executiondate = '', $notrigger = 0, $type = 'direct-debit', $did = 0, $fk_bank_account = 0, $sourcetype = 'invoice')
981
    {
982
		// phpcs:enable
983
        global $conf, $langs, $user;
984
985
        dol_syslog(__METHOD__ . " Bank=" . $banque . " Office=" . $agence . " mode=" . $mode . " format=" . $format, LOG_DEBUG);
986
987
988
        // Check params
989
        if ($type != 'bank-transfer') {
990
            if (empty($format)) {
991
                $this->error = 'ErrorBadParametersForDirectDebitFileCreate';
992
                return -1;
993
            }
994
        }
995
996
        // Clean params
997
        if (empty($fk_bank_account)) {
998
            $fk_bank_account = ($type == 'bank-transfer' ? getDolGlobalInt('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT') : getDolGlobalInt('PRELEVEMENT_ID_BANKACCOUNT'));
999
        }
1000
1001
        $error = 0;
1002
1003
        $datetimeprev = dol_now('gmt');
1004
        // Choice the date of the execution direct debit
1005
        if (!empty($executiondate)) {
1006
            $datetimeprev = $executiondate;
1007
        }
1008
1009
        $month = dol_print_date($datetimeprev, "%m", 'gmt');
1010
        $year = dol_print_date($datetimeprev, "%Y", 'gmt');
1011
1012
        $this->invoice_in_error = array();
1013
        $this->thirdparty_in_error = array();
1014
1015
        // Read invoices
1016
        $factures = array();
1017
        $factures_prev = array();
1018
        $factures_result = array();
1019
        $factures_prev_id = array();
1020
        $factures_errors = array();
1021
        if (!$error) {
1022
            dol_syslog(__METHOD__ . " Read invoices for did=" . ((int) $did), LOG_DEBUG);
1023
1024
            $sql = "SELECT f.rowid, pd.rowid as pfdrowid";
1025
            if ($sourcetype != 'salary') {
1026
                $sql .= ", f.fk_soc";
1027
            } else {
1028
                $sql .= ", f.fk_user";
1029
            }
1030
            $sql .= ", pd.code_banque, pd.code_guichet, pd.number, pd.cle_rib";
1031
            $sql .= ", pd.amount";
1032
            if ($sourcetype != 'salary') {
1033
                $sql .= ", s.nom as name";
1034
                $sql .= ", f.ref, sr.bic, sr.iban_prefix, sr.frstrecur";
1035
            } else {
1036
                $sql .= ", CONCAT(s.firstname,' ',s.lastname) as name";
1037
                $sql .= ", f.ref, sr.bic, sr.iban_prefix, 'FRST' as frstrecur";
1038
            }
1039
            if ($sourcetype != 'salary') {
1040
                if ($type != 'bank-transfer') {
1041
                    $sql .= " FROM " . MAIN_DB_PREFIX . "facture as f";
1042
                    $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "prelevement_demande as pd ON f.rowid = pd.fk_facture";
1043
                } else {
1044
                    $sql .= " FROM " . MAIN_DB_PREFIX . "facture_fourn as f";
1045
                    $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "prelevement_demande as pd ON f.rowid = pd.fk_facture_fourn";
1046
                }
1047
                $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON s.rowid = f.fk_soc";
1048
                $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_rib as sr ON s.rowid = sr.fk_soc AND sr.default_rib = 1";
1049
            } else {
1050
                $sql .= " FROM " . MAIN_DB_PREFIX . "salary as f";
1051
                $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "prelevement_demande as pd ON f.rowid = pd.fk_salary";
1052
                $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "user as s ON s.rowid = f.fk_user";
1053
                $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "user_rib as sr ON s.rowid = sr.fk_user";  // TODO Add AND sr.default_rib = 1 here
1054
            }
1055
            if ($sourcetype != 'salary') {
1056
                if ($type != 'bank-transfer') {
1057
                    $sql .= " WHERE f.entity IN (" . getEntity('invoice') . ')';
1058
                } else {
1059
                    $sql .= " WHERE f.entity IN (" . getEntity('supplier_invoice') . ')';
1060
                }
1061
            } else {
1062
                $sql .= " WHERE f.entity IN (" . getEntity('salary') . ')';
1063
            }
1064
            if ($sourcetype != 'salary') {
1065
                $sql .= " AND f.fk_statut = 1"; // Invoice validated
1066
                $sql .= " AND f.paye = 0";
1067
                $sql .= " AND f.total_ttc > 0";
1068
            } else {
1069
                //$sql .= " AND f.fk_statut = 1"; // Invoice validated
1070
                $sql .= " AND f.paye = 0";
1071
                $sql .= " AND f.amount > 0";
1072
            }
1073
            $sql .= " AND pd.traite = 0";
1074
            $sql .= " AND pd.ext_payment_id IS NULL";
1075
            if ($sourcetype != 'salary') {
1076
                $sql .= " AND sr.type = 'ban'";     // TODO Add AND sr.type = 'ban' for users too
1077
            }
1078
            if ($did > 0) {
1079
                $sql .= " AND pd.rowid = " . ((int) $did);
1080
            }
1081
1082
            $resql = $this->db->query($sql);
1083
            if ($resql) {
1084
                $num = $this->db->num_rows($resql);
1085
                $i = 0;
1086
1087
                while ($i < $num) {
1088
                    $row = $this->db->fetch_row($resql);    // TODO Replace with fetch_object()
1089
                    $factures[$i] = $row; // All fields
1090
1091
                    if ($row[7] == 0) {
1092
                        $error++;
1093
                        dol_syslog(__METHOD__ . " Read invoices/salary error Found a null amount", LOG_ERR);
1094
                        $this->invoice_in_error[$row[0]] = "Error for invoice or salary id " . $row[0] . ", found a null amount";
1095
                        break;
1096
                    }
1097
                    $i++;
1098
                }
1099
1100
                $this->db->free($resql);
1101
                dol_syslog(__METHOD__ . " Read invoices/salary, " . $i . " invoices/salary to withdraw", LOG_DEBUG);
1102
            } else {
1103
                $error++;
1104
                $this->error = $this->db->lasterror();
1105
                dol_syslog(__METHOD__ . " Read invoices/salary error " . $this->db->lasterror(), LOG_ERR);
1106
                return -1;
1107
            }
1108
        }
1109
1110
        if (!$error) {
1111
            require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/bank.lib.php';
1112
1113
            $tmpsoc = new Societe($this->db);
1114
            $tmpuser = new User($this->db);
1115
1116
            // Check BAN
1117
            $i = 0;
1118
            dol_syslog(__METHOD__ . " Check BAN", LOG_DEBUG);
1119
1120
            if (count($factures) > 0) {
1121
                foreach ($factures as $key => $fac) {
1122
                    /*
1123
                    if ($type != 'bank-transfer') {
1124
                        $tmpinvoice = new Facture($this->db);
1125
                    } else {
1126
                        $tmpinvoice = new FactureFournisseur($this->db);
1127
                    }
1128
                    $resfetch = $tmpinvoice->fetch($fac[0]);
1129
                    if ($resfetch >= 0) {       // Field 0 of $fac is rowid of invoice
1130
                    */
1131
1132
                    // Check if $fac[8] s.nom is null
1133
                    if ($fac[8] != null) {
1134
                        if ($type != 'bank-transfer') {
1135
                            if ($format == 'FRST' && $fac[12] != 'FRST') {
1136
                                continue;
1137
                            }
1138
                            if ($format == 'RCUR' && $fac[12] != 'RCUR') {
1139
                                continue;
1140
                            }
1141
                        }
1142
1143
                        $verif = checkSwiftForAccount(null, $fac[10]);
1144
                        if ($verif) {
1145
                            $verif = checkIbanForAccount(null, $fac[11]);
1146
                        }
1147
1148
                        if ($verif) {
1149
                            $factures_prev[$i] = $fac;
1150
                            /* second array necessary for BonPrelevement */
1151
                            $factures_prev_id[$i] = $fac[0];
1152
                            $i++;
1153
                            //dol_syslog(__METHOD__."::RIB is ok", LOG_DEBUG);
1154
                        } else {
1155
                            if ($type != 'bank-transfer') {
1156
                                $tmpsoc->id = $fac[2];
1157
                                $tmpsoc->name = $fac[8];
1158
                                $invoice_url = "<a href='" . constant('BASE_URL') . '/compta/facture/card.php?facid=' . $fac[0] . "'>" . $fac[9] . "</a>";
1159
                                $this->invoice_in_error[$fac[0]] = "Error on default bank number IBAN/BIC for invoice " . $invoice_url . " for thirdparty " . $tmpsoc->getNomUrl(0);
1160
                                $this->thirdparty_in_error[$tmpsoc->id] = "Error on default bank number IBAN/BIC for invoice " . $invoice_url . " for thirdparty " . $tmpsoc->getNomUrl(0);
1161
                                $error++;
1162
                            }
1163
                            if ($type == 'bank-transfer' && $sourcetype != 'salary') {
1164
                                $tmpsoc->id = $fac[2];
1165
                                $tmpsoc->name = $fac[8];
1166
                                $invoice_url = "<a href='" . constant('BASE_URL') . '/fourn/facture/card.php?facid=' . $fac[0] . "'>" . $fac[9] . "</a>";
1167
                                $this->invoice_in_error[$fac[0]] = "Error on default bank number IBAN/BIC for invoice " . $invoice_url . " for thirdparty " . $tmpsoc->getNomUrl(0);
1168
                                $this->thirdparty_in_error[$tmpsoc->id] = "Error on default bank number IBAN/BIC for invoice " . $invoice_url . " for thirdparty " . $tmpsoc->getNomUrl(0);
1169
                                $error++;
1170
                            }
1171
                            if ($type == 'bank-transfer' && $sourcetype == 'salary') {
1172
                                $tmpuser->id = $fac[2];
1173
                                $tmpuser->firstname = $fac[8];
1174
                                $salary_url = "<a href='" . constant('BASE_URL') . '/salaries/card.php?id=' . $fac[0] . "'>" . $fac[0] . "</a>";
1175
                                $this->invoice_in_error[$fac[0]] = "Error on default bank number IBAN/BIC for salary " . $salary_url . " for employee " . $tmpuser->getNomUrl(0);
1176
                                $this->thirdparty_in_error[$tmpuser->id] = "Error on default bank number IBAN/BIC for salary " . $salary_url . " for employee " . $tmpuser->getNomUrl(0);
1177
                                $error++;
1178
                            }
1179
                            dol_syslog(__METHOD__ . " Check BAN Error on default bank number IBAN/BIC reported by verif(): " . implode(', ', $fac), LOG_WARNING);
1180
                        }
1181
                    } else {
1182
                        dol_syslog(__METHOD__ . " Check BAN Failed to read company", LOG_WARNING);
1183
                    }
1184
                    /*
1185
                    } else {
1186
                        dol_syslog(__METHOD__." Check BAN Failed to read invoice", LOG_WARNING);
1187
                    }
1188
                    */
1189
                }
1190
            } else {
1191
                dol_syslog(__METHOD__ . " Check BAN No invoice to process", LOG_WARNING);
1192
            }
1193
        }
1194
1195
        $ok = 0;
1196
1197
        // Withdraw invoices in factures_prev array
1198
        $out = count($factures_prev) . " invoices will be included.";
1199
        //print $out."\n";
1200
        dol_syslog($out);
1201
1202
        // Return warning
1203
        /*$i=0;
1204
         foreach ($this->thirdparty_in_error as $key => $val)
1205
         {
1206
         if ($i < 10) setEventMessages($val, null, 'warnings');
1207
         else setEventMessages('More error were discarded...', null, 'warnings');
1208
         $i++;
1209
         }*/
1210
1211
        if (count($factures_prev) > 0) {
1212
            if ($mode == 'real') {
1213
                $ok = 1;
1214
            } else {
1215
                print $langs->trans("ModeWarning"); // "Option for real mode was not set, we stop after this simulation\n";
1216
            }
1217
        }
1218
        if ($ok) {
1219
            /*
1220
             * We are in real mode.
1221
             * We create order and build file into disk
1222
             */
1223
            $this->db->begin();
1224
1225
            $now = dol_now();
1226
            $ref = '';
1227
1228
            /*
1229
             * Process order generation
1230
             */
1231
            if (!$error) {
1232
                $ref = substr($year, -2) . $month;
1233
1234
                // Get next free number for the ref of bon prelevement
1235
                $sql = "SELECT substring(ref from char_length(ref) - 1)";   // To extract "YYMMXX" from "TYYMMXX"
1236
                $sql .= " FROM " . MAIN_DB_PREFIX . "prelevement_bons";
1237
                $sql .= " WHERE ref LIKE '_" . $this->db->escape($ref) . "%'";
1238
                $sql .= " AND entity = " . ((int) $conf->entity);
1239
                $sql .= " ORDER BY ref DESC LIMIT 1";
1240
1241
                dol_syslog(get_only_class($this) . " get next free number", LOG_DEBUG);
1242
                $resql = $this->db->query($sql);
1243
1244
                if ($resql) {
1245
                    $row = $this->db->fetch_row($resql);
1246
1247
                    // Build the new ref
1248
                    $ref = "T" . $ref . sprintf("%02d", (intval($row[0]) + 1));
1249
1250
                    // $conf->abc->dir_output may be:
1251
                    // /home/ldestailleur/git/dolibarr_15.0/documents/abc/
1252
                    // or
1253
                    // /home/ldestailleur/git/dolibarr_15.0/documents/X/abc with X >= 2 with multicompany.
1254
                    if ($type != 'bank-transfer') {
1255
                        $dir = $conf->prelevement->dir_output . '/receipts';
1256
                    } else {
1257
                        $dir = $conf->paymentbybanktransfer->dir_output . '/receipts';
1258
                    }
1259
                    if (!is_dir($dir)) {
1260
                        dol_mkdir($dir);
1261
                    }
1262
1263
                    if (isModEnabled('multicompany')) {
1264
                        $labelentity = $conf->entity;
1265
                        $this->filename = $dir . '/' . $ref . '-' . $labelentity . '.xml';
1266
                    } else {
1267
                        $this->filename = $dir . '/' . $ref . '.xml';
1268
                    }
1269
1270
                    // Create withdraw order in database
1271
                    $sql = "INSERT INTO " . MAIN_DB_PREFIX . "prelevement_bons (";
1272
                    $sql .= "ref, entity, datec, type, fk_bank_account";
1273
                    $sql .= ") VALUES (";
1274
                    $sql .= "'" . $this->db->escape($ref) . "'";
1275
                    $sql .= ", " . ((int) $conf->entity);
1276
                    $sql .= ", '" . $this->db->idate($now) . "'";
1277
                    $sql .= ", '" . ($type == 'bank-transfer' ? 'bank-transfer' : 'debit-order') . "'";
1278
                    $sql .= ", " . ((int) $fk_bank_account);
1279
                    $sql .= ")";
1280
1281
                    $resql = $this->db->query($sql);
1282
1283
1284
                    if ($resql) {
1285
                        $prev_id = $this->db->last_insert_id(MAIN_DB_PREFIX . "prelevement_bons");
1286
                        $this->id = $prev_id;
1287
                        $this->ref = $ref;
1288
                    } else {
1289
                        $error++;
1290
                        dol_syslog(__METHOD__ . " Create withdraw receipt " . $this->db->lasterror(), LOG_ERR);
1291
                    }
1292
                } else {
1293
                    $error++;
1294
                    dol_syslog(__METHOD__ . " Get last withdraw receipt " . $this->db->lasterror(), LOG_ERR);
1295
                }
1296
            }
1297
1298
            if (!$error) {
1299
                dol_syslog(__METHOD__ . " Now loop on each document to insert them in llx_prelevement_demande");
1300
1301
                // Add lines for the bon
1302
                if (count($factures_prev) > 0) {
1303
                    foreach ($factures_prev as $fac) {  // Add a link in database for each invoice ro salary
1304
                        /*
1305
                         * Add standing order. This add record into llx_prelevement_lignes and llx_prelevement
1306
                         *
1307
                         * $fac[0] : invoice_id
1308
                         * $fac[1] : ???
1309
                         * $fac[2] : third party id
1310
                         * $fac[3] : banque
1311
                         * $fac[4] : guichet
1312
                         * $fac[5] : number
1313
                         * $fac[6] : cle rib
1314
                         * $fac[7] : amount
1315
                         * $fac[8] : client nom
1316
                         * $fac[9] : Invoice ref
1317
                         * $fac[10] : BIC
1318
                         * $fac[11] : IBAN
1319
                         * $fac[12] : frstrcur
1320
                         */
1321
                        $ri = $this->AddFacture($fac[0], $fac[2], $fac[8], $fac[7], $fac[3], $fac[4], $fac[5], $fac[6], $type, $sourcetype);
1322
1323
                        if ($ri != 0) {
1324
                            $error++;
1325
                        }
1326
1327
                        // Update invoice requests as done
1328
                        $sql = "UPDATE " . MAIN_DB_PREFIX . "prelevement_demande";
1329
                        $sql .= " SET traite = 1";
1330
                        $sql .= ", date_traite = '" . $this->db->idate($now) . "'";
1331
                        $sql .= ", fk_prelevement_bons = " . ((int) $this->id);
1332
                        $sql .= " WHERE rowid = " . ((int) $fac[1]);
1333
1334
                        $resql = $this->db->query($sql);
1335
                        if (!$resql) {
1336
                            $error++;
1337
                            $this->errors[] = $this->db->lasterror();
1338
                            dol_syslog(__METHOD__ . " Update Error=" . $this->db->lasterror(), LOG_ERR);
1339
                        }
1340
                    }
1341
                }
1342
            }
1343
1344
            if (!$error) {
1345
                /*
1346
                 * Create file of type='direct-debit' for direct debit order or type='bank-transfer' for credit transfer into a XML file
1347
                 */
1348
1349
                dol_syslog(__METHOD__ . " Init direct debit or credit transfer file for " . count($factures_prev) . " invoices", LOG_DEBUG);
1350
1351
                if (count($factures_prev) > 0) {
1352
                    $this->date_echeance = $datetimeprev;
1353
                    $this->reference_remise = $ref;
1354
1355
                    $account = new Account($this->db);
1356
                    if ($account->fetch($fk_bank_account) > 0) {
1357
                        $this->emetteur_code_banque        = $account->code_banque;
1358
                        $this->emetteur_code_guichet       = $account->code_guichet;
1359
                        $this->emetteur_numero_compte      = $account->number;
1360
                        $this->emetteur_number_key         = $account->cle_rib;
1361
                        $this->sepa_xml_pti_in_ctti        = (bool) $account->pti_in_ctti;
1362
                        $this->emetteur_iban               = $account->iban;
1363
                        $this->emetteur_bic                = $account->bic;
1364
1365
                        $this->emetteur_ics = (($type == 'bank-transfer' && getDolGlobalString("SEPA_USE_IDS")) ? $account->ics_transfer : $account->ics);  // Example "FR78ZZZ123456"
1366
1367
                        $this->raison_sociale = $account->proprio;
0 ignored issues
show
Bug Best Practice introduced by
The property $proprio is declared private in Dolibarr\Code\Compta\Classes\Account. Since you implement __get, consider adding a @property or @property-read.
Loading history...
1368
                    }
1369
                    $this->factures = $factures_prev_id;
1370
                    $this->context['factures_prev'] = $factures_prev;
1371
                    // Generation of direct debit or credit transfer file $this->filename (May be a SEPA file for european countries)
1372
                    // This also set the property $this->total with amount that is included into file
1373
                    $userid = 0;
1374
                    if ($sourcetype == 'salary') {
1375
                        $userid = $this->context['factures_prev'][0][2];
1376
                    }
1377
                    $result = $this->generate($format, $executiondate, $type, $fk_bank_account, $userid);
1378
                    if ($result < 0) {
1379
                        //var_dump($this->error);
1380
                        //var_dump($this->invoice_in_error);
1381
                        $error++;
1382
                    }
1383
                }
1384
                dol_syslog(__METHOD__ . " Bank order file has been generated under filename " . $this->filename, LOG_DEBUG);
1385
            }
1386
1387
1388
            /*
1389
             * Update total defined after generation of file
1390
             */
1391
            if (!$error) {
1392
                $sql = "UPDATE " . MAIN_DB_PREFIX . "prelevement_bons";
1393
                $sql .= " SET amount = " . price2num($this->total);
1394
                $sql .= " WHERE rowid = " . ((int) $this->id);
1395
                $sql .= " AND entity = " . ((int) $conf->entity);
1396
                $resql = $this->db->query($sql);
1397
1398
                if (!$resql) {
1399
                    $error++;
1400
                    dol_syslog(__METHOD__ . " Error update total: " . $this->db->error(), LOG_ERR);
1401
                }
1402
            }
1403
1404
            if (!$error && !$notrigger) {
1405
                $triggername = 'DIRECT_DEBIT_ORDER_CREATE';
1406
                if ($type != 'bank-transfer') {
1407
                    $triggername = 'CREDIT_TRANSFER_ORDER_CREATE';
1408
                }
1409
1410
                // Call trigger
1411
                $result = $this->call_trigger($triggername, $user);
1412
                if ($result < 0) {
1413
                    $error++;
1414
                }
1415
                // End call triggers
1416
            }
1417
1418
            if (!$error) {
1419
                $this->db->commit();
1420
                return count($factures_prev);   // The error of failed lines are into $this->invoice_in_error and $this->thirdparty_in_error
1421
            } else {
1422
                $this->db->rollback();
1423
                return -1;
1424
            }
1425
        } else {
1426
            return 0;
1427
        }
1428
    }
1429
1430
1431
    /**
1432
     *  Get object and lines from database
1433
     *
1434
     *  @param  User    $user       Object user that delete
1435
     *  @param  int     $notrigger  1=Does not execute triggers, 0= execute triggers
1436
     *  @return int                 >0 if OK, <0 if KO
1437
     */
1438
    public function delete($user = null, $notrigger = 0)
1439
    {
1440
        $this->db->begin();
1441
1442
        $error = 0;
1443
        $resql1 = $resql2 = $resql3 = $resql4 = 0;
1444
1445
        if (!$notrigger) {
1446
            $triggername = 'DIRECT_DEBIT_ORDER_DELETE';
1447
            if ($this->type == 'bank-transfer') {
1448
                $triggername = 'PAYMENTBYBANKTRANFER_DELETE';
1449
            }
1450
            // Call trigger
1451
            $result = $this->call_trigger($triggername, $user);
1452
            if ($result < 0) {
1453
                $error++;
1454
            }
1455
            // End call triggers
1456
        }
1457
1458
        if (!$error) {
1459
            $sql = "DELETE FROM " . MAIN_DB_PREFIX . "prelevement WHERE fk_prelevement_lignes IN (SELECT rowid FROM " . MAIN_DB_PREFIX . "prelevement_lignes WHERE fk_prelevement_bons = " . ((int) $this->id) . ")";
1460
            $resql1 = $this->db->query($sql);
1461
            if (!$resql1) {
1462
                dol_print_error($this->db);
1463
            }
1464
        }
1465
1466
        if (!$error) {
1467
            $sql = "DELETE FROM " . MAIN_DB_PREFIX . "prelevement_lignes WHERE fk_prelevement_bons = " . ((int) $this->id);
1468
            $resql2 = $this->db->query($sql);
1469
            if (!$resql2) {
1470
                dol_print_error($this->db);
1471
            }
1472
        }
1473
1474
        if (!$error) {
1475
            $sql = "DELETE FROM " . MAIN_DB_PREFIX . "prelevement_bons WHERE rowid = " . ((int) $this->id);
1476
            $resql3 = $this->db->query($sql);
1477
            if (!$resql3) {
1478
                dol_print_error($this->db);
1479
            }
1480
        }
1481
1482
        if (!$error) {
1483
            $sql = "UPDATE " . MAIN_DB_PREFIX . "prelevement_demande SET fk_prelevement_bons = NULL, traite = 0 WHERE fk_prelevement_bons = " . ((int) $this->id);
1484
            $resql4 = $this->db->query($sql);
1485
            if (!$resql4) {
1486
                dol_print_error($this->db);
1487
            }
1488
        }
1489
1490
        if ($resql1 && $resql2 && $resql3 && $resql4 && !$error) {
1491
            $this->db->commit();
1492
            return 1;
1493
        } else {
1494
            $this->db->rollback();
1495
            return -1;
1496
        }
1497
    }
1498
1499
1500
    /**
1501
     *  Returns clickable name (with picto)
1502
     *
1503
     *  @param  int     $withpicto                  Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
1504
     *  @param  string  $option                     On what the link point to ('nolink', ...)
1505
     *  @param  int     $notooltip                  1=Disable tooltip
1506
     *  @param  string  $morecss                    Add more css on link
1507
     *  @param  int     $save_lastsearch_value      -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
1508
     *  @return string                              URL of target
1509
     */
1510
    public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
1511
    {
1512
        global $conf, $langs, $hookmanager;
1513
1514
        if (!empty($conf->dol_no_mouse_hover)) {
1515
            $notooltip = 1; // Force disable tooltips
1516
        }
1517
1518
        $result = '';
1519
1520
        $labeltoshow = 'PaymentByDirectDebit';
1521
        if (!empty($this->type) && $this->type == 'bank-transfer') {
1522
            $labeltoshow = 'PaymentByBankTransfer';
1523
        }
1524
1525
        $label = img_picto('', $this->picto) . ' <u>' . $langs->trans($labeltoshow) . '</u> ' . $this->getLibStatut(5);
1526
        $label .= '<br>';
1527
        $label .= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
1528
        if (isset($this->amount)) {
1529
            $label .= '<br><b>' . $langs->trans("Amount") . ":</b> " . price($this->amount);
1530
        }
1531
        if (isset($this->date_trans)) {
1532
            $label .= '<br><b>' . $langs->trans("TransData") . ":</b> " . dol_print_date($this->date_trans, 'dayhour', 'tzuserrel');
1533
        }
1534
        /*if (isset($this->date_credit)) {
1535
            $label .= '<br><b>'.$langs->trans("TransData").":</b> ".dol_print_date($this->date_credit, 'dayhour', 'tzuserrel');
1536
        }*/
1537
1538
        $url = constant('BASE_URL') . '/compta/prelevement/card.php?id=' . $this->id;
1539
        if (!empty($this->type) && $this->type == 'bank-transfer') {
1540
            $url = constant('BASE_URL') . '/compta/prelevement/card.php?id=' . $this->id;
1541
        }
1542
1543
        if ($option != 'nolink') {
1544
            // Add param to save lastsearch_values or not
1545
            $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1546
            if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1547
                $add_save_lastsearch_values = 1;
1548
            }
1549
            if ($add_save_lastsearch_values) {
1550
                $url .= '&save_lastsearch_values=1';
1551
            }
1552
        }
1553
1554
        $linkclose = '';
1555
        if (empty($notooltip)) {
1556
            if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1557
                $label = $langs->trans("ShowMyObject");
1558
                $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
1559
            }
1560
            $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
1561
            $linkclose .= ' class="classfortooltip' . ($morecss ? ' ' . $morecss : '') . '"';
1562
        } else {
1563
            $linkclose = ($morecss ? ' class="' . $morecss . '"' : '');
1564
        }
1565
1566
        $linkstart = '<a href="' . $url . '"';
1567
        $linkstart .= $linkclose . '>';
1568
        $linkend = '</a>';
1569
1570
        $result .= $linkstart;
1571
        if ($withpicto) {
1572
            $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);
1573
        }
1574
        if ($withpicto != 2) {
1575
            $result .= $this->ref;
1576
        }
1577
        $result .= $linkend;
1578
1579
        global $action, $hookmanager;
1580
        $hookmanager->initHooks(array('banktransferdao'));
1581
        $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1582
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1583
        if ($reshook > 0) {
1584
            $result = $hookmanager->resPrint;
1585
        } else {
1586
            $result .= $hookmanager->resPrint;
1587
        }
1588
1589
        return $result;
1590
    }
1591
1592
1593
    /**
1594
     *  Delete a notification def by id
1595
     *
1596
     *  @param  int     $rowid      id of notification
1597
     *  @return int                 0 if OK, <0 if KO
1598
     */
1599
    public function deleteNotificationById($rowid)
1600
    {
1601
        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "notify_def";
1602
        $sql .= " WHERE rowid = " . ((int) $rowid);
1603
1604
        if ($this->db->query($sql)) {
1605
            return 0;
1606
        } else {
1607
            return -1;
1608
        }
1609
    }
1610
1611
    /**
1612
     *  Delete a notification
1613
     *
1614
     *  @param  int|User    $user       notification user
1615
     *  @param  string      $action     notification action
1616
     *  @return int                     >0 if OK, <0 if KO
1617
     */
1618
    public function deleteNotification($user, $action)
1619
    {
1620
        if (is_object($user)) {
1621
            $userid = $user->id;
1622
        } else {    // If user is an id
1623
            $userid = $user;
1624
        }
1625
1626
        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "notify_def";
1627
        $sql .= " WHERE fk_user=" . ((int) $userid) . " AND fk_action='" . $this->db->escape($action) . "'";
1628
1629
        if ($this->db->query($sql)) {
1630
            return 0;
1631
        } else {
1632
            return -1;
1633
        }
1634
    }
1635
1636
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1637
    /**
1638
     *  Add a notification
1639
     *
1640
     *  @param  DoliDB      $db         database handler
1641
     *  @param  int|User    $user       notification user
1642
     *  @param  string      $action     notification action
1643
     *  @return int                     0 if OK, <0 if KO
1644
     */
1645
    public function addNotification($db, $user, $action)
1646
    {
1647
		// phpcs:enable
1648
        $result = 0;
1649
1650
        if (is_object($user)) {
1651
            $userid = $user->id;
1652
        } else {    // If user is an id
1653
            $userid = $user;
1654
        }
1655
1656
        if ($this->deleteNotification($user, $action) == 0) {
1657
            $now = dol_now();
1658
1659
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "notify_def (datec,fk_user, fk_soc, fk_contact, fk_action)";
1660
            $sql .= " VALUES ('" . $this->db->idate($now) . "', " . ((int) $userid) . ", 'NULL', 'NULL', '" . $this->db->escape($action) . "')";
1661
1662
            dol_syslog("adnotiff: " . $sql);
1663
            if ($this->db->query($sql)) {
1664
                $result = 0;
1665
            } else {
1666
                $result = -1;
1667
                dol_syslog(get_only_class($this) . "::addNotification Error $result");
1668
            }
1669
        }
1670
1671
        return $result;
1672
    }
1673
1674
1675
    /**
1676
     * Generate a direct debit or credit transfer file.
1677
     * Generation Formats:
1678
     * - Europe: SEPA (France: CFONB no more supported, Spain: AEB19 if external module EsAEB is enabled)
1679
     * - Others countries: Warning message
1680
     * File is generated with name this->filename
1681
     *
1682
     * @param   string  $format             FRST, RCUR or ALL
1683
     * @param   int     $executiondate      Timestamp date to execute transfer
1684
     * @param   string  $type               'direct-debit' or 'bank-transfer'
1685
     * @param   int     $fk_bank_account    Bank account ID the receipt is generated for. Will use the ID into the setup of module Direct Debit or Credit Transfer if 0.
1686
     * @param   int     $forsalary          If the SEPA is to pay salaries
1687
     * @return  int                         >=0 if OK, <0 if KO
1688
     */
1689
    public function generate($format = 'ALL', $executiondate = 0, $type = 'direct-debit', $fk_bank_account = 0, $forsalary = 0)
1690
    {
1691
        global $conf, $langs, $mysoc;
1692
1693
        //TODO: Optimize code to read lines in a single function
1694
1695
        // Clean params
1696
        if (empty($fk_bank_account)) {
1697
            $fk_bank_account = ($type == 'bank-transfer' ? getDolGlobalInt('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT') : getDolGlobalInt('PRELEVEMENT_ID_BANKACCOUNT'));
1698
        }
1699
1700
        $result = 0;
1701
1702
        dol_syslog(get_only_class($this) . "::generate build file=" . $this->filename . " type=" . $type);
1703
1704
        $this->file = fopen($this->filename, "w");
1705
        if ($this->file == false) {
1706
            $this->error = $langs->trans('ErrorFailedToOpenFile', $this->filename);
1707
            return -1;
1708
        }
1709
1710
        $found = 0;
1711
        $this->total = 0;
1712
1713
        // Build file for European countries
1714
        if ($mysoc->isInEEC()) {
1715
            $found++;
1716
1717
            if ($type != 'bank-transfer') {
1718
                /**
1719
                 * SECTION CREATION FICHIER SEPA - DIRECT DEBIT
1720
                 */
1721
                // SEPA Initialisation
1722
                $CrLf = "\n";
1723
1724
                $now = dol_now();
1725
1726
                $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S');
1727
1728
                $date_actu = $now;
1729
                if (!empty($executiondate)) {
1730
                    $date_actu = $executiondate;
1731
                }
1732
1733
                $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d');
1734
                $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S');
1735
                $fileDebiteurSection = '';
1736
                $fileEmetteurSection = '';
1737
                $i = 0;
1738
1739
                /*
1740
                 * Section Debitor (sepa Debiteurs block lines)
1741
                 */
1742
1743
                $sql = "SELECT soc.rowid as socid, soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,";
1744
                $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,";
1745
                $sql .= " f.ref as reffac, p.fk_facture as idfac,";
1746
                $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum";
1747
                $sql .= " FROM";
1748
                $sql .= " " . MAIN_DB_PREFIX . "prelevement_lignes as pl,";
1749
                $sql .= " " . MAIN_DB_PREFIX . "facture as f,";
1750
                $sql .= " " . MAIN_DB_PREFIX . "prelevement as p,";
1751
                $sql .= " " . MAIN_DB_PREFIX . "societe as soc,";
1752
                $sql .= " " . MAIN_DB_PREFIX . "c_country as c,";
1753
                $sql .= " " . MAIN_DB_PREFIX . "societe_rib as rib";
1754
                $sql .= " WHERE pl.fk_prelevement_bons = " . ((int) $this->id);
1755
                $sql .= " AND pl.rowid = p.fk_prelevement_lignes";
1756
                $sql .= " AND p.fk_facture = f.rowid";
1757
                $sql .= " AND f.fk_soc = soc.rowid";
1758
                $sql .= " AND soc.fk_pays = c.rowid";
1759
                $sql .= " AND rib.fk_soc = f.fk_soc";
1760
                $sql .= " AND rib.default_rib = 1";
1761
                $sql .= " AND rib.type = 'ban'";
1762
1763
                // Define $fileDebiteurSection. One section DrctDbtTxInf per invoice.
1764
                $resql = $this->db->query($sql);
1765
                if ($resql) {
1766
                    $cachearraytotestduplicate = array();
1767
1768
                    $num = $this->db->num_rows($resql);
1769
                    while ($i < $num) {
1770
                        $obj = $this->db->fetch_object($resql);
1771
1772
                        if (!empty($cachearraytotestduplicate[$obj->idfac])) {
1773
                            $this->error = $langs->trans('ErrorCompanyHasDuplicateDefaultBAN', $obj->socid);
1774
                            $this->invoice_in_error[$obj->idfac] = $this->error;
1775
                            $result = -2;
1776
                            break;
1777
                        }
1778
                        $cachearraytotestduplicate[$obj->idfac] = $obj->rowid;
1779
1780
                        $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec);
1781
1782
                        $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->reffac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type);
1783
1784
                        $this->total = $this->total + $obj->somme;
1785
                        $i++;
1786
                    }
1787
                    $nbtotalDrctDbtTxInf = $i;
1788
                } else {
1789
                    $this->error = $this->db->lasterror();
1790
                    fwrite($this->file, 'ERROR DEBITOR ' . $sql . $CrLf); // DEBITOR = Customers
1791
                    $result = -2;
1792
                }
1793
1794
                // Define $fileEmetteurSection. Start of block PmtInf. Will contains all $nbtotalDrctDbtTxInf
1795
                if ($result != -2) {
1796
                    $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type, $fk_bank_account);
1797
                }
1798
1799
                if (getDolGlobalString('SEPA_FORCE_TWO_DECIMAL')) {
1800
                    $this->total = number_format((float) price2num($this->total, 'MT'), 2, ".", "");
1801
                }
1802
1803
                /**
1804
                 * SECTION CREATION SEPA FILE - ISO200022
1805
                 */
1806
                // SEPA File Header
1807
                fwrite($this->file, '<' . '?xml version="1.0" encoding="UTF-8" standalone="yes"?' . '>' . $CrLf);
1808
                fwrite($this->file, '<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . $CrLf);
1809
                fwrite($this->file, '	<CstmrDrctDbtInitn>' . $CrLf);
1810
                // SEPA Group header
1811
                fwrite($this->file, '		<GrpHdr>' . $CrLf);
1812
                fwrite($this->file, '			<MsgId>' . ('DD/' . $dateTime_YMD . '/REF' . $this->id) . '</MsgId>' . $CrLf);
1813
                fwrite($this->file, '			<CreDtTm>' . $dateTime_ECMA . '</CreDtTm>' . $CrLf);
1814
                fwrite($this->file, '			<NbOfTxs>' . $i . '</NbOfTxs>' . $CrLf);
1815
                fwrite($this->file, '			<CtrlSum>' . $this->total . '</CtrlSum>' . $CrLf);
1816
                fwrite($this->file, '			<InitgPty>' . $CrLf);
1817
                fwrite($this->file, '				<Nm>' . dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))) . '</Nm>' . $CrLf);
1818
                fwrite($this->file, '				<Id>' . $CrLf);
1819
                fwrite($this->file, '				    <PrvtId>' . $CrLf);
1820
                fwrite($this->file, '					<Othr>' . $CrLf);
1821
                fwrite($this->file, '						<Id>' . $this->emetteur_ics . '</Id>' . $CrLf);
1822
                fwrite($this->file, '					</Othr>' . $CrLf);
1823
                fwrite($this->file, '				    </PrvtId>' . $CrLf);
1824
                fwrite($this->file, '				</Id>' . $CrLf);
1825
                fwrite($this->file, '			</InitgPty>' . $CrLf);
1826
                fwrite($this->file, '		</GrpHdr>' . $CrLf);
1827
                // SEPA File Emetteur
1828
                if ($result != -2) {
1829
                    fwrite($this->file, $fileEmetteurSection);
1830
                }
1831
                // SEPA File Debiteurs
1832
                if ($result != -2) {
1833
                    fwrite($this->file, $fileDebiteurSection);
1834
                }
1835
                // SEPA FILE FOOTER
1836
                fwrite($this->file, '		</PmtInf>' . $CrLf);
1837
                fwrite($this->file, '	</CstmrDrctDbtInitn>' . $CrLf);
1838
                fwrite($this->file, '</Document>' . $CrLf);
1839
            } else {
1840
                /**
1841
                 * SECTION CREATION FICHIER SEPA - CREDIT TRANSFER
1842
                 */
1843
                // SEPA Initialisation
1844
                $CrLf = "\n";
1845
1846
                $now = dol_now();
1847
1848
                $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S');
1849
1850
                $date_actu = $now;
1851
                if (!empty($executiondate)) {
1852
                    $date_actu = $executiondate;
1853
                }
1854
1855
                $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d');
1856
                $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S');
1857
                $fileCrediteurSection = '';
1858
                $fileEmetteurSection = '';
1859
                $i = 0;
1860
1861
                /*
1862
                 * Section Creditor (sepa Crediteurs block lines)
1863
                 */
1864
                if (!empty($forsalary)) {
1865
                    $sql = "SELECT u.rowid as userId, u.address, u.zip, u.town, c.code as country_code, CONCAT(u.firstname,' ',u.lastname) as nom,";
1866
                    $sql .= " pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,";
1867
                    $sql .= " s.ref as reffac, p.fk_salary as idfac,";
1868
                    $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, '' as rum, '' as date_rum";
1869
                    $sql .= " FROM";
1870
                    $sql .= " " . MAIN_DB_PREFIX . "prelevement_lignes as pl,";
1871
                    $sql .= " " . MAIN_DB_PREFIX . "salary as s,";
1872
                    $sql .= " " . MAIN_DB_PREFIX . "prelevement as p,";
1873
                    $sql .= " " . MAIN_DB_PREFIX . "user as u";
1874
                    $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_country as c ON u.fk_country = c.rowid,";
1875
                    $sql .= " " . MAIN_DB_PREFIX . "user_rib as rib";
1876
                    $sql .= " WHERE pl.fk_prelevement_bons=" . ((int) $this->id);
1877
                    $sql .= " AND pl.rowid = p.fk_prelevement_lignes";
1878
                    $sql .= " AND p.fk_salary = s.rowid";
1879
                    $sql .= " AND s.fk_user = u.rowid";
1880
                    $sql .= " AND rib.fk_user = s.fk_user";
1881
                } else {
1882
                    $sql = "SELECT soc.rowid as socid, soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,";
1883
                    $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,";
1884
                    $sql .= " f.ref as reffac, f.ref_supplier as fac_ref_supplier, p.fk_facture_fourn as idfac,";
1885
                    $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum";
1886
                    $sql .= " FROM";
1887
                    $sql .= " " . MAIN_DB_PREFIX . "prelevement_lignes as pl,";
1888
                    $sql .= " " . MAIN_DB_PREFIX . "facture_fourn as f,";
1889
                    $sql .= " " . MAIN_DB_PREFIX . "prelevement as p,";
1890
                    $sql .= " " . MAIN_DB_PREFIX . "societe as soc";
1891
                    $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_country as c ON soc.fk_pays = c.rowid,";
1892
                    $sql .= " " . MAIN_DB_PREFIX . "societe_rib as rib";
1893
                    $sql .= " WHERE pl.fk_prelevement_bons = " . ((int) $this->id);
1894
                    $sql .= " AND pl.rowid = p.fk_prelevement_lignes";
1895
                    $sql .= " AND p.fk_facture_fourn = f.rowid";
1896
                    $sql .= " AND f.fk_soc = soc.rowid";
1897
                    $sql .= " AND rib.fk_soc = f.fk_soc";
1898
                    $sql .= " AND rib.default_rib = 1";
1899
                    $sql .= " AND rib.type = 'ban'";
1900
                }
1901
                // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice.
1902
                $resql = $this->db->query($sql);
1903
                if ($resql) {
1904
                    $cachearraytotestduplicate = array();
1905
1906
                    $num = $this->db->num_rows($resql);
1907
                    while ($i < $num) {
1908
                        $obj = $this->db->fetch_object($resql);
1909
                        if (!empty($cachearraytotestduplicate[$obj->idfac])) {
1910
                            $this->error = $langs->trans('ErrorCompanyHasDuplicateDefaultBAN', $obj->socid);
1911
                            $this->invoice_in_error[$obj->idfac] = $this->error;
1912
                            $result = -2;
1913
                            break;
1914
                        }
1915
                        $cachearraytotestduplicate[$obj->idfac] = $obj->rowid;
1916
1917
                        $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec);
1918
                        $refobj = $obj->reffac;
1919
                        if (empty($refobj) && !empty($forsalary)) { // If ref of salary not defined, we force a value
1920
                            $refobj = "SAL" . $obj->idfac;
1921
                        }
1922
1923
                        $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $refobj, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type, $obj->fac_ref_supplier);
1924
1925
                        $this->total = $this->total + $obj->somme;
1926
                        $i++;
1927
                    }
1928
                    $nbtotalDrctDbtTxInf = $i;
1929
                } else {
1930
                    $this->error = $this->db->lasterror();
1931
                    fwrite($this->file, 'ERROR CREDITOR ' . $sql . $CrLf); // CREDITORS = Suppliers
1932
                    $result = -2;
1933
                }
1934
                // Define $fileEmetteurSection. Start of block PmtInf. Will contains all $nbtotalDrctDbtTxInf
1935
                if ($result != -2) {
1936
                    $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type);
1937
                }
1938
1939
                if (getDolGlobalString('SEPA_FORCE_TWO_DECIMAL')) {
1940
                    $this->total = number_format((float) price2num($this->total, 'MT'), 2, ".", "");
1941
                }
1942
1943
                /**
1944
                 * SECTION CREATION SEPA FILE - CREDIT TRANSFER - ISO200022
1945
                 */
1946
                // SEPA File Header
1947
                fwrite($this->file, '<' . '?xml version="1.0" encoding="UTF-8" standalone="yes"?' . '>' . $CrLf);
1948
                fwrite($this->file, '<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . $CrLf);
1949
                fwrite($this->file, '	<CstmrCdtTrfInitn>' . $CrLf);
1950
                // SEPA Group header
1951
                fwrite($this->file, '		<GrpHdr>' . $CrLf);
1952
                fwrite($this->file, '			<MsgId>' . ('TRF/' . $dateTime_YMD . '/REF' . $this->id) . '</MsgId>' . $CrLf);
1953
                fwrite($this->file, '			<CreDtTm>' . $dateTime_ECMA . '</CreDtTm>' . $CrLf);
1954
                fwrite($this->file, '			<NbOfTxs>' . $i . '</NbOfTxs>' . $CrLf);
1955
                fwrite($this->file, '			<CtrlSum>' . $this->total . '</CtrlSum>' . $CrLf);
1956
                fwrite($this->file, '			<InitgPty>' . $CrLf);
1957
                fwrite($this->file, '				<Nm>' . dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))) . '</Nm>' . $CrLf);
1958
                fwrite($this->file, '				<Id>' . $CrLf);
1959
                fwrite($this->file, '				    <PrvtId>' . $CrLf);
1960
                fwrite($this->file, '					<Othr>' . $CrLf);
1961
                fwrite($this->file, '						<Id>' . $this->emetteur_ics . '</Id>' . $CrLf);
1962
                fwrite($this->file, '					</Othr>' . $CrLf);
1963
                fwrite($this->file, '				    </PrvtId>' . $CrLf);
1964
                fwrite($this->file, '				</Id>' . $CrLf);
1965
                fwrite($this->file, '			</InitgPty>' . $CrLf);
1966
                fwrite($this->file, '		</GrpHdr>' . $CrLf);
1967
                // SEPA File Emetteur (mycompany)
1968
                if ($result != -2) {
1969
                    fwrite($this->file, $fileEmetteurSection);
1970
                }
1971
                // SEPA File Creditors
1972
                if ($result != -2) {
1973
                    fwrite($this->file, $fileCrediteurSection);
1974
                }
1975
                // SEPA FILE FOOTER
1976
                fwrite($this->file, '		</PmtInf>' . $CrLf);
1977
                fwrite($this->file, '	</CstmrCdtTrfInitn>' . $CrLf);
1978
                fwrite($this->file, '</Document>' . $CrLf);
1979
            }
1980
        }
1981
1982
        // Build file for Other Countries with unknown format
1983
        if (!$found) {
1984
            if ($type != 'bank-transfer') {
1985
                $sql = "SELECT pl.amount";
1986
                $sql .= " FROM";
1987
                $sql .= " " . MAIN_DB_PREFIX . "prelevement_lignes as pl,";
1988
                $sql .= " " . MAIN_DB_PREFIX . "facture as f,";
1989
                $sql .= " " . MAIN_DB_PREFIX . "prelevement as p";
1990
                $sql .= " WHERE pl.fk_prelevement_bons = " . ((int) $this->id);
1991
                $sql .= " AND pl.rowid = p.fk_prelevement_lignes";
1992
                $sql .= " AND p.fk_facture = f.rowid";
1993
1994
                // Lines
1995
                $i = 0;
1996
                $resql = $this->db->query($sql);
1997
                if ($resql) {
1998
                    $num = $this->db->num_rows($resql);
1999
2000
                    while ($i < $num) {
2001
                        $obj = $this->db->fetch_object($resql);
2002
                        $this->total = $this->total + $obj->amount;
2003
2004
                        // TODO Write record into file
2005
                        $i++;
2006
                    }
2007
                } else {
2008
                    $result = -2;
2009
                }
2010
            } else {
2011
                $sql = "SELECT pl.amount";
2012
                $sql .= " FROM";
2013
                $sql .= " " . MAIN_DB_PREFIX . "prelevement_lignes as pl,";
2014
                $sql .= " " . MAIN_DB_PREFIX . "facture_fourn as f,";
2015
                $sql .= " " . MAIN_DB_PREFIX . "prelevement as p";
2016
                $sql .= " WHERE pl.fk_prelevement_bons = " . ((int) $this->id);
2017
                $sql .= " AND pl.rowid = p.fk_prelevement_lignes";
2018
                $sql .= " AND p.fk_facture_fourn = f.rowid";
2019
                // Lines
2020
                $i = 0;
2021
                $resql = $this->db->query($sql);
2022
                if ($resql) {
2023
                    $num = $this->db->num_rows($resql);
2024
2025
                    while ($i < $num) {
2026
                        $obj = $this->db->fetch_object($resql);
2027
                        $this->total = $this->total + $obj->amount;
2028
2029
                        // TODO Write record into file
2030
                        $i++;
2031
                    }
2032
                } else {
2033
                    $result = -2;
2034
                }
2035
            }
2036
2037
            $langs->load('withdrawals');
2038
2039
            // TODO Add here code to generate a generic file
2040
            fwrite($this->file, $langs->transnoentitiesnoconv('WithdrawalFileNotCapable', $mysoc->country_code));
2041
        }
2042
2043
        fclose($this->file);
2044
        dolChmod($this->filename);
2045
2046
        return $result;
2047
    }
2048
2049
2050
    /**
2051
     * Generate dynamically a RUM number for a customer bank account
2052
     *
2053
     * @param   string      $row_code_client    Customer code (soc.code_client)
2054
     * @param   int         $row_datec          Creation date of bank account (rib.datec)
2055
     * @param   string      $row_drum           Id of customer bank account (rib.rowid)
2056
     * @return  string      RUM number
2057
     */
2058
    public static function buildRumNumber($row_code_client, $row_datec, $row_drum)
2059
    {
2060
        global $langs;
2061
2062
        $pre = substr(dol_string_nospecial(dol_string_unaccent($langs->transnoentitiesnoconv('RUM'))), 0, 3); // Must always be on 3 char ('RUM' or 'UMR'. This is a protection against bad translation)
2063
2064
        // 3 char + '-' + 12 + '-' + id + '-' + code        Must be lower than 32.
2065
        return $pre . '-' . dol_print_date($row_datec, 'dayhourlogsmall') . '-' . dol_trunc($row_drum . ($row_code_client ? '-' . $row_code_client : ''), 13, 'right', 'UTF-8', 1);
2066
    }
2067
2068
2069
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2070
    /**
2071
     *  Write recipient of request (customer)
2072
     *
2073
     *  @param  int     $rowid          id of line
2074
     *  @param  string  $client_nom     name of customer
2075
     *  @param  string  $rib_banque     code of bank
2076
     *  @param  string  $rib_guichet    code of bank office
2077
     *  @param  string  $rib_number     bank account
2078
     *  @param  float   $amount         amount
2079
     *  @param  string  $ref        ref of invoice
2080
     *  @param  int     $facid          id of invoice
2081
     *  @param  string  $rib_dom        bank address
2082
     *  @param  string  $type           'direct-debit' or 'bank-transfer'
2083
     *  @return void
2084
     *  @see EnregDestinataireSEPA()
2085
     */
2086
    public function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $ref, $facid, $rib_dom = '', $type = 'direct-debit')
2087
    {
2088
		// phpcs:enable
2089
        fwrite($this->file, "06");
2090
        fwrite($this->file, "08"); // Prelevement ordinaire
2091
2092
        fwrite($this->file, "        "); // Zone Reservee B2
2093
2094
        fwrite($this->file, $this->emetteur_ics); // ICS
2095
2096
        // Date d'echeance C1
2097
2098
        fwrite($this->file, "       ");
2099
        fwrite($this->file, dol_print_date($this->date_echeance, "%d%m", 'gmt'));
2100
        fwrite($this->file, substr(dol_print_date($this->date_echeance, "%y", 'gmt'), 1));
2101
2102
        // Raison Sociale Destinataire C2
2103
2104
        fwrite($this->file, substr(strtoupper($client_nom) . "                         ", 0, 24));
2105
2106
        // Address optional D1
2107
        $address = strtr($rib_dom, array(" " => "-", chr(13) => " ", chr(10) => ""));
2108
        fwrite($this->file, substr($address . "                         ", 0, 24));
2109
2110
        // Zone Reservee D2
2111
2112
        fwrite($this->file, substr("                             ", 0, 8));
2113
2114
        // Code Guichet  D3
2115
2116
        fwrite($this->file, $rib_guichet);
2117
2118
        // Numero de compte D4
2119
2120
        fwrite($this->file, substr("000000000000000" . $rib_number, -11));
2121
2122
        // Zone E Montant
2123
2124
        $montant = (round($amount, 2) * 100);
2125
2126
        fwrite($this->file, substr("000000000000000" . $montant, -16));
2127
2128
        // Label F
2129
2130
        fwrite($this->file, substr("*_" . $ref . "_RDVnet" . $rowid . "                               ", 0, 31));
2131
2132
        // Code etablissement G1
2133
2134
        fwrite($this->file, $rib_banque);
2135
2136
        // Zone Reservee G2
2137
2138
        fwrite($this->file, substr("                                        ", 0, 5));
2139
2140
        fwrite($this->file, "\n");
2141
    }
2142
2143
2144
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2145
    /**
2146
     *  Write recipient (thirdparty concerned by request)
2147
     *
2148
     *  @param  string      $row_code_client    soc.code_client as code,
2149
     *  @param  string      $row_nom            pl.client_nom AS name,
2150
     *  @param  string      $row_address        soc.address AS adr,
2151
     *  @param  string      $row_zip            soc.zip
2152
     *  @param  string      $row_town           soc.town
2153
     *  @param  string      $row_country_code   c.code AS country,
2154
     *  @param  string      $row_cb             pl.code_banque AS cb,       Not used for SEPA
2155
     *  @param  string      $row_cg             pl.code_guichet AS cg,      Not used for SEPA
2156
     *  @param  string      $row_cc             pl.number AS cc,            Not used for SEPA
2157
     *  @param  float       $row_somme          pl.amount AS somme,
2158
     *  @param  string      $row_ref            Invoice ref (f.ref) or Salary ref
2159
     *  @param  int         $row_idfac          p.fk_facture AS idfac or p.fk_facture_fourn or p.fk_salary,
2160
     *  @param  string      $row_iban           rib.iban_prefix AS iban,
2161
     *  @param  string      $row_bic            rib.bic AS bic,
2162
     *  @param  string      $row_datec          rib.datec,
2163
     *  @param  string      $row_drum           rib.rowid used to generate rum
2164
     *  @param  string      $row_rum            rib.rum Rum defined on company bank account
2165
     *  @param  string      $type               'direct-debit' or 'bank-transfer'
2166
     *  @param  string      $row_comment        A free text string for the Unstructured data field
2167
     *  @return string                          Return string with SEPA part DrctDbtTxInf
2168
     *  @see EnregDestinataire()
2169
     */
2170
    public function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_ref, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum, $row_rum, $type = 'direct-debit', $row_comment = '')
2171
    {
2172
		// phpcs:enable
2173
        global $conf;
2174
2175
        if (getDolGlobalString('SEPA_FORCE_TWO_DECIMAL')) {
2176
            $row_somme = number_format((float) price2num($row_somme, 'MT'), 2, ".", "");
2177
        } else {
2178
            $row_somme = round((float) $row_somme, 2);
2179
        }
2180
2181
        include_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
2182
2183
        $CrLf = "\n";
2184
        $Rowing = sprintf("%010d", $row_idfac);
2185
2186
        // Define value for RUM
2187
        // Example:  RUM-CustomerCode-CustomerBankAccountId-01424448606 (note: Date is the timestamp of the date of creation of CustomerBankAccountId)
2188
        $Rum = (empty($row_rum) ? $this->buildRumNumber($row_code_client, $row_datec, $row_drum) : $row_rum);
2189
2190
        // Define date of RUM signature
2191
        $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d');
2192
2193
        if ($type != 'bank-transfer') {
2194
            // SEPA Paiement Information of buyer for Direct Debit
2195
            $XML_DEBITOR = '';
2196
            $XML_DEBITOR .= '			<DrctDbtTxInf>' . $CrLf;
2197
            $XML_DEBITOR .= '				<PmtId>' . $CrLf;
2198
            // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum)
2199
            $XML_DEBITOR .= '					<EndToEndId>' . ((getDolGlobalString('PRELEVEMENT_END_TO_END') != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('DD-' . dol_trunc($row_idfac . '-' . $row_ref, 20, 'right', 'UTF-8', 1)) . '-' . $Rowing) . '</EndToEndId>' . $CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters
2200
            $XML_DEBITOR .= '				</PmtId>' . $CrLf;
2201
            $XML_DEBITOR .= '				<InstdAmt Ccy="EUR">' . $row_somme . '</InstdAmt>' . $CrLf;
2202
            $XML_DEBITOR .= '				<DrctDbtTx>' . $CrLf;
2203
            $XML_DEBITOR .= '					<MndtRltdInf>' . $CrLf;
2204
            $XML_DEBITOR .= '						<MndtId>' . $Rum . '</MndtId>' . $CrLf;
2205
            $XML_DEBITOR .= '						<DtOfSgntr>' . $DtOfSgntr . '</DtOfSgntr>' . $CrLf;
2206
            $XML_DEBITOR .= '						<AmdmntInd>false</AmdmntInd>' . $CrLf;
2207
            $XML_DEBITOR .= '					</MndtRltdInf>' . $CrLf;
2208
            $XML_DEBITOR .= '				</DrctDbtTx>' . $CrLf;
2209
            $XML_DEBITOR .= '				<DbtrAgt>' . $CrLf;
2210
            $XML_DEBITOR .= '					<FinInstnId>' . $CrLf;
2211
            $XML_DEBITOR .= '						<BIC>' . $row_bic . '</BIC>' . $CrLf;
2212
            $XML_DEBITOR .= '					</FinInstnId>' . $CrLf;
2213
            $XML_DEBITOR .= '				</DbtrAgt>' . $CrLf;
2214
            $XML_DEBITOR .= '				<Dbtr>' . $CrLf;
2215
            $XML_DEBITOR .= '					<Nm>' . dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($row_nom), ' '))) . '</Nm>' . $CrLf;
2216
            $XML_DEBITOR .= '					<PstlAdr>' . $CrLf;
2217
            $XML_DEBITOR .= '						<Ctry>' . $row_country_code . '</Ctry>' . $CrLf;
2218
            $addressline1 = strtr($row_address, array(chr(13) => ", ", chr(10) => ""));
2219
            $addressline2 = strtr($row_zip . (($row_zip && $row_town) ? ' ' : (string) $row_town), array(chr(13) => ", ", chr(10) => ""));
2220
            if (trim($addressline1)) {
2221
                $XML_DEBITOR .= '						<AdrLine>' . dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)) . '</AdrLine>' . $CrLf;
2222
            }
2223
            if (trim($addressline2)) {
2224
                $XML_DEBITOR .= '						<AdrLine>' . dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)) . '</AdrLine>' . $CrLf;
2225
            }
2226
            $XML_DEBITOR .= '					</PstlAdr>' . $CrLf;
2227
            $XML_DEBITOR .= '				</Dbtr>' . $CrLf;
2228
            $XML_DEBITOR .= '				<DbtrAcct>' . $CrLf;
2229
            $XML_DEBITOR .= '					<Id>' . $CrLf;
2230
            $XML_DEBITOR .= '						<IBAN>' . preg_replace('/\s/', '', $row_iban) . '</IBAN>' . $CrLf;
2231
            $XML_DEBITOR .= '					</Id>' . $CrLf;
2232
            $XML_DEBITOR .= '				</DbtrAcct>' . $CrLf;
2233
            $XML_DEBITOR .= '				<RmtInf>' . $CrLf;
2234
            // A string with some information on payment - 140 max
2235
            $XML_DEBITOR .= '					<Ustrd>' . getDolGlobalString('PRELEVEMENT_USTRD', dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($row_ref . ($row_comment ? ' - ' . $row_comment : '')), '', '', '', 1), 135, 'right', 'UTF-8', 1))) . '</Ustrd>' . $CrLf; // Free unstuctured data - 140 max
2236
            $XML_DEBITOR .= '				</RmtInf>' . $CrLf;
2237
            $XML_DEBITOR .= '			</DrctDbtTxInf>' . $CrLf;
2238
            return $XML_DEBITOR;
2239
        } else {
2240
            // SEPA Payment Information of seller for Credit Transfer
2241
            $XML_CREDITOR = '';
2242
            $XML_CREDITOR .= '			<CdtTrfTxInf>' . $CrLf;
2243
            $XML_CREDITOR .= '				<PmtId>' . $CrLf;
2244
            // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum)
2245
            $XML_CREDITOR .= '					<EndToEndId>' . ((getDolGlobalString('PRELEVEMENT_END_TO_END') != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('CT-' . dol_trunc($row_idfac . '-' . $row_ref, 20, 'right', 'UTF-8', 1)) . '-' . $Rowing) . '</EndToEndId>' . $CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters
2246
            $XML_CREDITOR .= '				</PmtId>' . $CrLf;
2247
            if (!empty($this->sepa_xml_pti_in_ctti)) {
2248
                $XML_CREDITOR .= '				<PmtTpInf>' . $CrLf;
2249
2250
                // Can be 'NORM' for normal or 'HIGH' for high priority level
2251
                if (getDolGlobalString('PAYMENTBYBANKTRANSFER_FORCE_HIGH_PRIORITY')) {
2252
                    $instrprty = 'HIGH';
2253
                } else {
2254
                    $instrprty = 'NORM';
2255
                }
2256
                $XML_CREDITOR .= '					<InstrPrty>' . $instrprty . '</InstrPrty>' . $CrLf;
2257
                $XML_CREDITOR .= '					<SvcLvl>' . $CrLf;
2258
                $XML_CREDITOR .= '						<Cd>SEPA</Cd>' . $CrLf;
2259
                $XML_CREDITOR .= '					</SvcLvl>' . $CrLf;
2260
                $XML_CREDITOR .= '					<CtgyPurp>' . $CrLf;
2261
                $XML_CREDITOR .= '						<Cd>CORE</Cd>' . $CrLf;
2262
                $XML_CREDITOR .= '					</CtgyPurp>' . $CrLf;
2263
                $XML_CREDITOR .= '				</PmtTpInf>' . $CrLf;
2264
            }
2265
            $XML_CREDITOR .= '				<Amt>' . $CrLf;
2266
            $XML_CREDITOR .= '				<InstdAmt Ccy="EUR">' . round((float) $row_somme, 2) . '</InstdAmt>' . $CrLf;
2267
            $XML_CREDITOR .= '				</Amt>' . $CrLf;
2268
            /*
2269
             $XML_CREDITOR .= '             <DrctDbtTx>'.$CrLf;
2270
             $XML_CREDITOR .= '                 <MndtRltdInf>'.$CrLf;
2271
             $XML_CREDITOR .= '                     <MndtId>'.$Rum.'</MndtId>'.$CrLf;
2272
             $XML_CREDITOR .= '                     <DtOfSgntr>'.$DtOfSgntr.'</DtOfSgntr>'.$CrLf;
2273
             $XML_CREDITOR .= '                     <AmdmntInd>false</AmdmntInd>'.$CrLf;
2274
             $XML_CREDITOR .= '                 </MndtRltdInf>'.$CrLf;
2275
             $XML_CREDITOR .= '             </DrctDbtTx>'.$CrLf;
2276
             */
2277
            //$XML_CREDITOR .= '                <ChrgBr>SLEV</ChrgBr>'.$CrLf;
2278
            $XML_CREDITOR .= '				<CdtrAgt>' . $CrLf;
2279
            $XML_CREDITOR .= '					<FinInstnId>' . $CrLf;
2280
            $XML_CREDITOR .= '						<BIC>' . $row_bic . '</BIC>' . $CrLf;
2281
            $XML_CREDITOR .= '					</FinInstnId>' . $CrLf;
2282
            $XML_CREDITOR .= '				</CdtrAgt>' . $CrLf;
2283
            $XML_CREDITOR .= '				<Cdtr>' . $CrLf;
2284
            $XML_CREDITOR .= '					<Nm>' . dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($row_nom), ' '))) . '</Nm>' . $CrLf;
2285
            $XML_CREDITOR .= '					<PstlAdr>' . $CrLf;
2286
            $XML_CREDITOR .= '						<Ctry>' . $row_country_code . '</Ctry>' . $CrLf;
2287
            $addressline1 = strtr($row_address, array(chr(13) => ", ", chr(10) => ""));
2288
            $addressline2 = strtr($row_zip . (($row_zip && $row_town) ? ' ' : (string) $row_town), array(chr(13) => ", ", chr(10) => ""));
2289
            if (trim($addressline1)) {
2290
                $XML_CREDITOR .= '						<AdrLine>' . dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)) . '</AdrLine>' . $CrLf;
2291
            }
2292
            if (trim($addressline2)) {
2293
                $XML_CREDITOR .= '						<AdrLine>' . dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)) . '</AdrLine>' . $CrLf;
2294
            }
2295
            $XML_CREDITOR .= '					</PstlAdr>' . $CrLf;
2296
            $XML_CREDITOR .= '				</Cdtr>' . $CrLf;
2297
            $XML_CREDITOR .= '				<CdtrAcct>' . $CrLf;
2298
            $XML_CREDITOR .= '					<Id>' . $CrLf;
2299
            $XML_CREDITOR .= '						<IBAN>' . preg_replace('/\s/', '', $row_iban) . '</IBAN>' . $CrLf;
2300
            $XML_CREDITOR .= '					</Id>' . $CrLf;
2301
            $XML_CREDITOR .= '				</CdtrAcct>' . $CrLf;
2302
            $XML_CREDITOR .= '				<RmtInf>' . $CrLf;
2303
            // A string with some information on payment - 140 max
2304
            $XML_CREDITOR .= '					<Ustrd>' . getDolGlobalString('CREDITTRANSFER_USTRD', dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($row_ref . ($row_comment ? ' - ' . $row_comment : '')), '', '', '', 1), 135, 'right', 'UTF-8', 1))) . '</Ustrd>' . $CrLf; // Free unstructured data - 140 max
2305
            $XML_CREDITOR .= '				</RmtInf>' . $CrLf;
2306
            $XML_CREDITOR .= '			</CdtTrfTxInf>' . $CrLf;
2307
            return $XML_CREDITOR;
2308
        }
2309
    }
2310
2311
2312
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2313
    /**
2314
     *  Write sender of request (me).
2315
     *
2316
     *  @param  string      $type               'direct-debit' or 'bank-transfer'
2317
     *  @return void
2318
     *  @see EnregEmetteurSEPA()
2319
     */
2320
    public function EnregEmetteur($type = 'direct-debit')
2321
    {
2322
		// phpcs:enable
2323
        fwrite($this->file, "03");
2324
        fwrite($this->file, "08"); // Prelevement ordinaire
2325
2326
        fwrite($this->file, "        "); // Zone Reservee B2
2327
2328
        fwrite($this->file, $this->emetteur_ics); // ICS
2329
2330
        // Date d'echeance C1
2331
2332
        fwrite($this->file, "       ");
2333
        fwrite($this->file, dol_print_date($this->date_echeance, "%d%m", 'gmt'));
2334
        fwrite($this->file, substr(dol_print_date($this->date_echeance, "%y", 'gmt'), 1));
2335
2336
        // Raison Sociale C2
2337
2338
        fwrite($this->file, substr($this->raison_sociale . "                           ", 0, 24));
2339
2340
        // Reference de la remise creancier D1 sur 7 caracteres
2341
2342
        fwrite($this->file, substr($this->reference_remise . "                           ", 0, 7));
2343
2344
        // Zone Reservee D1-2
2345
2346
        fwrite($this->file, substr("                                    ", 0, 17));
2347
2348
        // Zone Reservee D2
2349
2350
        fwrite($this->file, substr("                             ", 0, 2));
2351
        fwrite($this->file, "E");
2352
        fwrite($this->file, substr("                             ", 0, 5));
2353
2354
        // Code Guichet  D3
2355
2356
        fwrite($this->file, $this->emetteur_code_guichet);
2357
2358
        // Numero de compte D4
2359
2360
        fwrite($this->file, substr("000000000000000" . $this->emetteur_numero_compte, -11));
2361
2362
        // Zone Reservee E
2363
2364
        fwrite($this->file, substr("                                        ", 0, 16));
2365
2366
        // Zone Reservee F
2367
2368
        fwrite($this->file, substr("                                        ", 0, 31));
2369
2370
        // Code etablissement
2371
2372
        fwrite($this->file, $this->emetteur_code_banque);
2373
2374
        // Zone Reservee G
2375
2376
        fwrite($this->file, substr("                                        ", 0, 5));
2377
2378
        fwrite($this->file, "\n");
2379
    }
2380
2381
2382
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2383
    /**
2384
     *  Write sender of request (me).
2385
     *  Note: The tag PmtInf is opened here but closed into caller
2386
     *
2387
     *  @param  Conf    $configuration      conf
2388
     *  @param  int     $ladate             Date
2389
     *  @param  int     $nombre             0 or 1
2390
     *  @param  float   $total              Total
2391
     *  @param  string  $CrLf               End of line character
2392
     *  @param  string  $format             FRST or RCUR or ALL
2393
     *  @param  string  $type               'direct-debit' or 'bank-transfer'
2394
     *  @param  int     $fk_bank_account    Bank account ID the receipt is generated for. Will use the ID into the setup of module Direct Debit or Credit Transfer if 0.
2395
     *  @return string                      String with SEPA Sender
2396
     *  @see EnregEmetteur()
2397
     */
2398
    public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf = '\n', $format = 'FRST', $type = 'direct-debit', $fk_bank_account = 0)
2399
    {
2400
		// phpcs:enable
2401
2402
        // Clean parameters
2403
        $dateTime_YMD = dol_print_date($ladate, '%Y%m%d');
2404
        $dateTime_ETAD = dol_print_date($ladate, '%Y-%m-%d');
2405
        $dateTime_YMDHMS = dol_print_date($ladate, '%Y-%m-%dT%H:%M:%S');
2406
2407
        // Clean params
2408
        if (empty($fk_bank_account)) {
2409
            $fk_bank_account = ($type == 'bank-transfer' ? getDolGlobalInt('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT') : getDolGlobalInt('PRELEVEMENT_ID_BANKACCOUNT'));
2410
        }
2411
2412
        // Get data of bank account
2413
        $account = new Account($this->db);
2414
        if ($account->fetch($fk_bank_account) > 0) {
2415
            $this->emetteur_code_banque = $account->code_banque;
2416
            $this->emetteur_code_guichet = $account->code_guichet;
2417
            $this->emetteur_numero_compte = $account->number;
2418
            $this->emetteur_number_key = $account->cle_rib;
2419
            $this->sepa_xml_pti_in_ctti = (bool) $account->pti_in_ctti;
2420
            $this->emetteur_iban = $account->iban;
2421
            $this->emetteur_bic = $account->bic;
2422
2423
            $this->emetteur_ics = (($type == 'bank-transfer' && getDolGlobalString("SEPA_USE_IDS")) ? $account->ics_transfer : $account->ics);  // Ex: PRELEVEMENT_ICS = "FR78ZZZ123456";
2424
2425
            $this->raison_sociale = $account->proprio;
0 ignored issues
show
Bug Best Practice introduced by
The property $proprio is declared private in Dolibarr\Code\Compta\Classes\Account. Since you implement __get, consider adding a @property or @property-read.
Loading history...
2426
        }
2427
2428
        // Get pending payments
2429
        $sql = "SELECT rowid, ref";
2430
        $sql .= " FROM " . MAIN_DB_PREFIX . "prelevement_bons as pb";
2431
        $sql .= " WHERE pb.rowid = " . ((int) $this->id);
2432
2433
        $resql = $this->db->query($sql);
2434
        if ($resql) {
2435
            $obj = $this->db->fetch_object($resql);
2436
2437
            $country = explode(':', $configuration->global->MAIN_INFO_SOCIETE_COUNTRY);
2438
            $IdBon  = sprintf("%05d", $obj->rowid);
2439
            $RefBon = $obj->ref;
2440
2441
            if (!empty($configuration->global->SEPA_FORCE_TWO_DECIMAL)) {
2442
                $total = number_format((float) price2num($total, 'MT'), 2, ".", "");
2443
            }
2444
2445
            if ($type != 'bank-transfer') {
2446
                // SEPA Paiement Information of my company for Direct Debit
2447
                $XML_SEPA_INFO = '';
2448
                $XML_SEPA_INFO .= '		<PmtInf>' . $CrLf;
2449
                $XML_SEPA_INFO .= '			<PmtInfId>' . ('DD/' . $dateTime_YMD . '/ID' . $IdBon . '-' . $RefBon) . '</PmtInfId>' . $CrLf;
2450
                $XML_SEPA_INFO .= '			<PmtMtd>DD</PmtMtd>' . $CrLf;
2451
                $XML_SEPA_INFO .= '			<NbOfTxs>' . $nombre . '</NbOfTxs>' . $CrLf;
2452
                $XML_SEPA_INFO .= '			<CtrlSum>' . $total . '</CtrlSum>' . $CrLf;
2453
                $XML_SEPA_INFO .= '			<PmtTpInf>' . $CrLf;
2454
                $XML_SEPA_INFO .= '				<SvcLvl>' . $CrLf;
2455
                $XML_SEPA_INFO .= '					<Cd>SEPA</Cd>' . $CrLf;
2456
                $XML_SEPA_INFO .= '				</SvcLvl>' . $CrLf;
2457
                $XML_SEPA_INFO .= '				<LclInstrm>' . $CrLf;
2458
                $XML_SEPA_INFO .= '					<Cd>CORE</Cd>' . $CrLf;
2459
                $XML_SEPA_INFO .= '				</LclInstrm>' . $CrLf;
2460
                $XML_SEPA_INFO .= '				<SeqTp>' . $format . '</SeqTp>' . $CrLf;
2461
                $XML_SEPA_INFO .= '			</PmtTpInf>' . $CrLf;
2462
                $XML_SEPA_INFO .= '			<ReqdColltnDt>' . $dateTime_ETAD . '</ReqdColltnDt>' . $CrLf;
2463
                $XML_SEPA_INFO .= '			<Cdtr>' . $CrLf;
2464
                $XML_SEPA_INFO .= '				<Nm>' . dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))) . '</Nm>' . $CrLf;
2465
                $XML_SEPA_INFO .= '				<PstlAdr>' . $CrLf;
2466
                $XML_SEPA_INFO .= '					<Ctry>' . $country[1] . '</Ctry>' . $CrLf;
2467
                $addressline1 = strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(chr(13) => ", ", chr(10) => ""));
2468
                $addressline2 = strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP . (($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' ' . $configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '') . $configuration->global->MAIN_INFO_SOCIETE_TOWN, array(chr(13) => ", ", chr(10) => ""));
2469
                if ($addressline1) {
2470
                    $XML_SEPA_INFO .= '					<AdrLine>' . dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)) . '</AdrLine>' . $CrLf;
2471
                }
2472
                if ($addressline2) {
2473
                    $XML_SEPA_INFO .= '					<AdrLine>' . dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)) . '</AdrLine>' . $CrLf;
2474
                }
2475
                $XML_SEPA_INFO .= '				</PstlAdr>' . $CrLf;
2476
                $XML_SEPA_INFO .= '			</Cdtr>' . $CrLf;
2477
                $XML_SEPA_INFO .= '			<CdtrAcct>' . $CrLf;
2478
                $XML_SEPA_INFO .= '				<Id>' . $CrLf;
2479
                $XML_SEPA_INFO .= '					<IBAN>' . preg_replace('/\s/', '', $this->emetteur_iban) . '</IBAN>' . $CrLf;
2480
                $XML_SEPA_INFO .= '				</Id>' . $CrLf;
2481
                $XML_SEPA_INFO .= '			</CdtrAcct>' . $CrLf;
2482
                $XML_SEPA_INFO .= '			<CdtrAgt>' . $CrLf;
2483
                $XML_SEPA_INFO .= '				<FinInstnId>' . $CrLf;
2484
                $XML_SEPA_INFO .= '					<BIC>' . $this->emetteur_bic . '</BIC>' . $CrLf;
2485
                $XML_SEPA_INFO .= '				</FinInstnId>' . $CrLf;
2486
                $XML_SEPA_INFO .= '			</CdtrAgt>' . $CrLf;
2487
                /* $XML_SEPA_INFO .= '          <UltmtCdtr>'.$CrLf;
2488
                 $XML_SEPA_INFO .= '                <Nm>'.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).'</Nm>'.$CrLf;
2489
                 $XML_SEPA_INFO .= '                <PstlAdr>'.$CrLf;
2490
                 $XML_SEPA_INFO .= '                    <Ctry>'.$country[1].'</Ctry>'.$CrLf;
2491
                 $XML_SEPA_INFO .= '                    <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ADDRESS), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2492
                 $XML_SEPA_INFO .= '                    <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2493
                 $XML_SEPA_INFO .= '                </PstlAdr>'.$CrLf;
2494
                 $XML_SEPA_INFO .= '            </UltmtCdtr>'.$CrLf;*/
2495
                $XML_SEPA_INFO .= '			<ChrgBr>SLEV</ChrgBr>' . $CrLf; // Field "Responsible of fees". Must be SLEV
2496
                $XML_SEPA_INFO .= '			<CdtrSchmeId>' . $CrLf;
2497
                $XML_SEPA_INFO .= '				<Id>' . $CrLf;
2498
                $XML_SEPA_INFO .= '					<PrvtId>' . $CrLf;
2499
                $XML_SEPA_INFO .= '						<Othr>' . $CrLf;
2500
                $XML_SEPA_INFO .= '							<Id>' . $this->emetteur_ics . '</Id>' . $CrLf;
2501
                $XML_SEPA_INFO .= '							<SchmeNm>' . $CrLf;
2502
                $XML_SEPA_INFO .= '								<Prtry>SEPA</Prtry>' . $CrLf;
2503
                $XML_SEPA_INFO .= '							</SchmeNm>' . $CrLf;
2504
                $XML_SEPA_INFO .= '						</Othr>' . $CrLf;
2505
                $XML_SEPA_INFO .= '					</PrvtId>' . $CrLf;
2506
                $XML_SEPA_INFO .= '				</Id>' . $CrLf;
2507
                $XML_SEPA_INFO .= '			</CdtrSchmeId>' . $CrLf;
2508
            } else {
2509
                // SEPA Paiement Information of my company for Credit Transfer
2510
                $XML_SEPA_INFO = '';
2511
                $XML_SEPA_INFO .= '		<PmtInf>' . $CrLf;
2512
                $XML_SEPA_INFO .= '			<PmtInfId>' . ('TRF/' . $dateTime_YMD . '/ID' . $IdBon . '-' . $RefBon) . '</PmtInfId>' . $CrLf;
2513
                $XML_SEPA_INFO .= '			<PmtMtd>TRF</PmtMtd>' . $CrLf;
2514
                //$XML_SEPA_INFO .= '           <BtchBookg>False</BtchBookg>'.$CrLf;
2515
                $XML_SEPA_INFO .= '			<NbOfTxs>' . $nombre . '</NbOfTxs>' . $CrLf;
2516
                $XML_SEPA_INFO .= '			<CtrlSum>' . $total . '</CtrlSum>' . $CrLf;
2517
                if (!empty($this->sepa_xml_pti_in_ctti) && !empty($format)) {   // @TODO Using $format (FRST ou RCUR) in a section for a Credit Transfer looks strange.
2518
                    $XML_SEPA_INFO .= '			<PmtTpInf>' . $CrLf;
2519
                    $XML_SEPA_INFO .= '				<SvcLvl>' . $CrLf;
2520
                    $XML_SEPA_INFO .= '					<Cd>SEPA</Cd>' . $CrLf;
2521
                    $XML_SEPA_INFO .= '				</SvcLvl>' . $CrLf;
2522
                    $XML_SEPA_INFO .= '				<LclInstrm>' . $CrLf;
2523
                    $XML_SEPA_INFO .= '					<Cd>CORE</Cd>' . $CrLf;
2524
                    $XML_SEPA_INFO .= '				</LclInstrm>' . $CrLf;
2525
                    $XML_SEPA_INFO .= '				<SeqTp>' . $format . '</SeqTp>' . $CrLf;
2526
                    $XML_SEPA_INFO .= '			</PmtTpInf>' . $CrLf;
2527
                }
2528
                $XML_SEPA_INFO .= '			<ReqdExctnDt>' . dol_print_date($dateTime_ETAD, 'dayrfc') . '</ReqdExctnDt>' . $CrLf;
2529
                $XML_SEPA_INFO .= '			<Dbtr>' . $CrLf;
2530
                $XML_SEPA_INFO .= '				<Nm>' . dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))) . '</Nm>' . $CrLf;
2531
                $XML_SEPA_INFO .= '				<PstlAdr>' . $CrLf;
2532
                $XML_SEPA_INFO .= '					<Ctry>' . $country[1] . '</Ctry>' . $CrLf;
2533
                $addressline1 = strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(chr(13) => ", ", chr(10) => ""));
2534
                $addressline2 = strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP . (($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' ' . $configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '') . $configuration->global->MAIN_INFO_SOCIETE_TOWN, array(chr(13) => ", ", chr(10) => ""));
2535
                if ($addressline1) {
2536
                    $XML_SEPA_INFO .= '					<AdrLine>' . dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)) . '</AdrLine>' . $CrLf;
2537
                }
2538
                if ($addressline2) {
2539
                    $XML_SEPA_INFO .= '					<AdrLine>' . dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)) . '</AdrLine>' . $CrLf;
2540
                }
2541
                $XML_SEPA_INFO .= '				</PstlAdr>' . $CrLf;
2542
                $XML_SEPA_INFO .= '			</Dbtr>' . $CrLf;
2543
                $XML_SEPA_INFO .= '			<DbtrAcct>' . $CrLf;
2544
                $XML_SEPA_INFO .= '				<Id>' . $CrLf;
2545
                $XML_SEPA_INFO .= '					<IBAN>' . preg_replace('/\s/', '', $this->emetteur_iban) . '</IBAN>' . $CrLf;
2546
                $XML_SEPA_INFO .= '				</Id>' . $CrLf;
2547
                $XML_SEPA_INFO .= '			</DbtrAcct>' . $CrLf;
2548
                $XML_SEPA_INFO .= '			<DbtrAgt>' . $CrLf;
2549
                $XML_SEPA_INFO .= '				<FinInstnId>' . $CrLf;
2550
                $XML_SEPA_INFO .= '					<BIC>' . $this->emetteur_bic . '</BIC>' . $CrLf;
2551
                $XML_SEPA_INFO .= '				</FinInstnId>' . $CrLf;
2552
                $XML_SEPA_INFO .= '			</DbtrAgt>' . $CrLf;
2553
                /* $XML_SEPA_INFO .= '          <UltmtCdtr>'.$CrLf;
2554
                 $XML_SEPA_INFO .= '                <Nm>'.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).'</Nm>'.$CrLf;
2555
                 $XML_SEPA_INFO .= '                <PstlAdr>'.$CrLf;
2556
                 $XML_SEPA_INFO .= '                    <Ctry>'.$country[1].'</Ctry>'.$CrLf;
2557
                 $XML_SEPA_INFO .= '                    <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ADDRESS), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2558
                 $XML_SEPA_INFO .= '                    <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2559
                 $XML_SEPA_INFO .= '                </PstlAdr>'.$CrLf;
2560
                 $XML_SEPA_INFO .= '            </UltmtCdtr>'.$CrLf;*/
2561
                $XML_SEPA_INFO .= '			<ChrgBr>SLEV</ChrgBr>' . $CrLf; // Field "Responsible of fees". Must be SLEV
2562
                /*$XML_SEPA_INFO .= '           <CdtrSchmeId>'.$CrLf;
2563
                 $XML_SEPA_INFO .= '                <Id>'.$CrLf;
2564
                 $XML_SEPA_INFO .= '                    <PrvtId>'.$CrLf;
2565
                 $XML_SEPA_INFO .= '                        <Othr>'.$CrLf;
2566
                 $XML_SEPA_INFO .= '                            <Id>'.$this->emetteur_ics.'</Id>'.$CrLf;
2567
                 $XML_SEPA_INFO .= '                            <SchmeNm>'.$CrLf;
2568
                 $XML_SEPA_INFO .= '                                <Prtry>SEPA</Prtry>'.$CrLf;
2569
                 $XML_SEPA_INFO .= '                            </SchmeNm>'.$CrLf;
2570
                 $XML_SEPA_INFO .= '                        </Othr>'.$CrLf;
2571
                 $XML_SEPA_INFO .= '                    </PrvtId>'.$CrLf;
2572
                 $XML_SEPA_INFO .= '                </Id>'.$CrLf;
2573
                 $XML_SEPA_INFO .= '            </CdtrSchmeId>'.$CrLf;*/
2574
            }
2575
        } else {
2576
            fwrite($this->file, 'INCORRECT EMETTEUR ' . $this->raison_sociale . $CrLf);
2577
            $XML_SEPA_INFO = '';
2578
        }
2579
        return $XML_SEPA_INFO;
2580
    }
2581
2582
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2583
    /**
2584
     *  Write end
2585
     *
2586
     *  @param  int     $total  total amount
2587
     *  @return void
2588
     */
2589
    public function EnregTotal($total)
2590
    {
2591
		// phpcs:enable
2592
        fwrite($this->file, "08");
2593
        fwrite($this->file, "08"); // Prelevement ordinaire
2594
2595
        fwrite($this->file, "        "); // Zone Reservee B2
2596
2597
        fwrite($this->file, $this->emetteur_ics); // ICS
2598
2599
        // Reserve C1
2600
2601
        fwrite($this->file, substr("                           ", 0, 12));
2602
2603
2604
        // Raison Sociale C2
2605
2606
        fwrite($this->file, substr("                           ", 0, 24));
2607
2608
        // D1
2609
2610
        fwrite($this->file, substr("                                    ", 0, 24));
2611
2612
        // Zone Reservee D2
2613
2614
        fwrite($this->file, substr("                             ", 0, 8));
2615
2616
        // Code Guichet  D3
2617
2618
        fwrite($this->file, substr("                             ", 0, 5));
2619
2620
        // Numero de compte D4
2621
2622
        fwrite($this->file, substr("                             ", 0, 11));
2623
2624
        // Zone E Montant
2625
2626
        $montant = ($total * 100);
2627
2628
        fwrite($this->file, substr("000000000000000" . $montant, -16));
2629
2630
        // Zone Reservee F
2631
2632
        fwrite($this->file, substr("                                        ", 0, 31));
2633
2634
        // Code etablissement
2635
2636
        fwrite($this->file, substr("                                        ", 0, 5));
2637
2638
        // Zone Reservee F
2639
2640
        fwrite($this->file, substr("                                        ", 0, 5));
2641
2642
        fwrite($this->file, "\n");
2643
    }
2644
2645
    /**
2646
     *  Return status label of object
2647
     *
2648
     *  @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
2649
     *  @return string              Label
2650
     */
2651
    public function getLibStatut($mode = 0)
2652
    {
2653
        return $this->LibStatut($this->statut, $mode);
2654
    }
2655
2656
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2657
    /**
2658
     *  Return status label for a status
2659
     *
2660
     *  @param  int     $status     Id status
2661
     *  @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
2662
     *  @return string              Label
2663
     */
2664
    public function LibStatut($status, $mode = 0)
2665
    {
2666
		// phpcs:enable
2667
        if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
2668
            global $langs;
2669
            //$langs->load("mymodule");
2670
            $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('StatusWaiting');
2671
            $this->labelStatus[self::STATUS_TRANSFERED] = $langs->transnoentitiesnoconv('StatusTrans');
2672
            $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('StatusWaiting');
2673
            $this->labelStatusShort[self::STATUS_TRANSFERED] = $langs->transnoentitiesnoconv('StatusTrans');
2674
            if ($this->type == 'bank-transfer') {
2675
                $this->labelStatus[self::STATUS_DEBITED] = $langs->transnoentitiesnoconv('StatusDebited');
2676
                $this->labelStatusShort[self::STATUS_DEBITED] = $langs->transnoentitiesnoconv('StatusDebited');
2677
            } else {
2678
                $this->labelStatus[self::STATUS_CREDITED] = $langs->transnoentitiesnoconv('StatusCredited');
2679
                $this->labelStatusShort[self::STATUS_CREDITED] = $langs->transnoentitiesnoconv('StatusCredited');
2680
            }
2681
        }
2682
2683
        $statusType = 'status1';
2684
        if ($status == self::STATUS_TRANSFERED) {
2685
            $statusType = 'status3';
2686
        }
2687
        if ($status == self::STATUS_CREDITED || $status == self::STATUS_DEBITED) {
2688
            $statusType = 'status6';
2689
        }
2690
2691
        return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
2692
    }
2693
2694
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2695
    /**
2696
     *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
2697
     *
2698
     *      @param      User    $user           Object user
2699
     *      @param      string  $mode           Mode 'direct_debit' or 'credit_transfer'
2700
     *      @return     WorkboardResponse|int   Return integer <0 if KO, WorkboardResponse if OK
2701
     */
2702
    public function load_board($user, $mode)
2703
    {
2704
		// phpcs:enable
2705
        if ($user->socid) {
2706
            return -1; // protection pour eviter appel par utilisateur externe
2707
        }
2708
2709
        /*
2710
         if ($mode == 'direct_debit') {
2711
         $sql = "SELECT b.rowid, f.datedue as datefin";
2712
         $sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
2713
         $sql .= " WHERE f.entity IN (".getEntity('facture').")";
2714
         $sql .= " AND f.total_ttc > 0";
2715
         } else {
2716
         $sql = "SELECT b.rowid, f.datedue as datefin";
2717
         $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
2718
         $sql .= " WHERE f.entity IN (".getEntity('facture_fourn').")";
2719
         $sql .= " AND f.total_ttc > 0";
2720
         }
2721
2722
         $resql = $this->db->query($sql);
2723
         if ($resql) {
2724
         $langs->load("banks");
2725
         $now = dol_now();
2726
2727
         $response = new WorkboardResponse();
2728
         if ($mode == 'direct_debit') {
2729
         $response->warning_delay = $conf->prelevement->warning_delay / 60 / 60 / 24;
2730
         $response->label = $langs->trans("PendingDirectDebitToComplete");
2731
         $response->labelShort = $langs->trans("PendingDirectDebitToCompleteShort");
2732
         $response->url = DOL_URL_ROOT.'/compta/prelevement/index.php?leftmenu=checks&mainmenu=bank';
2733
         } else {
2734
         $response->warning_delay = $conf->paymentbybanktransfer->warning_delay / 60 / 60 / 24;
2735
         $response->label = $langs->trans("PendingCreditTransferToComplete");
2736
         $response->labelShort = $langs->trans("PendingCreditTransferToCompleteShort");
2737
         $response->url = DOL_URL_ROOT.'/compta/paymentbybanktransfer/index.php?leftmenu=checks&mainmenu=bank';
2738
         }
2739
         $response->img = img_object('', "payment");
2740
2741
         while ($obj = $this->db->fetch_object($resql)) {
2742
         $response->nbtodo++;
2743
2744
         if ($this->db->jdate($obj->datefin) < ($now - $conf->withdraw->warning_delay)) {
2745
         $response->nbtodolate++;
2746
         }
2747
         }
2748
2749
         $response->nbtodo = 0;
2750
         $response->nbtodolate = 0;
2751
         // Return workboard only if quantity is not 0
2752
         if ($response->nbtodo) {
2753
         return $response;
2754
         } else {
2755
         return 0;
2756
         }
2757
         } else {
2758
         dol_print_error($this->db);
2759
         $this->error = $this->db->error();
2760
         return -1;
2761
         }
2762
         */
2763
        return 0;
2764
    }
2765
2766
    /**
2767
     *  Return clicable link of object (with eventually picto)
2768
     *
2769
     *  @param      string      $option                 Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
2770
     *  @param      array       $arraydata              Array of data
2771
     *  @return     string                              HTML Code for Kanban thumb.
2772
     */
2773
    public function getKanbanView($option = '', $arraydata = null)
2774
    {
2775
        global $langs;
2776
2777
        $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2778
2779
        $return = '<div class="box-flex-item box-flex-grow-zero">';
2780
        $return .= '<div class="info-box info-box-sm">';
2781
        $return .= '<span class="info-box-icon bg-infobox-action">';
2782
        $return .= img_picto('', $this->picto);
2783
        $return .= '</span>';
2784
        $return .= '<div class="info-box-content">';
2785
        $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . (method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref) . '</span>';
2786
        if ($selected >= 0) {
2787
            $return .= '<input id="cb' . $this->id . '" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="' . $this->id . '"' . ($selected ? ' checked="checked"' : '') . '>';
2788
        }
2789
        if (property_exists($this, 'date_echeance')) {
2790
            $return .= '<br><span class="opacitymedium">' . $langs->trans("Date") . '</span> : <span class="info-box-label">' . dol_print_date($this->db->jdate($this->date_echeance), 'day') . '</span>';
2791
        }
2792
        if (property_exists($this, 'total')) {
2793
            $return .= '<br><span class="opacitymedium">' . $langs->trans("Amount") . '</span> : <span class="amount">' . price($this->total) . '</span>';
2794
        }
2795
        if (method_exists($this, 'LibStatut')) {
2796
            $return .= '<br><div class="info-box-status">' . $this->getLibStatut(3) . '</div>';
2797
        }
2798
        $return .= '</div>';
2799
        $return .= '</div>';
2800
        $return .= '</div>';
2801
        return $return;
2802
    }
2803
2804
    /**
2805
     * Check if is bon prelevement for salary invoice
2806
     *
2807
     * @return  int     1 if OK, O if K0
2808
     */
2809
    public function checkIfSalaryBonPrelevement()
2810
    {
2811
        if (!empty($this->id)) {
2812
            $id = $this->id;
2813
        } else {
2814
            return 0;
2815
        }
2816
        if ($id) {
2817
            $sql = "SELECT COUNT(*) AS nb FROM " . MAIN_DB_PREFIX . "prelevement_lignes";
2818
            $sql .= " WHERE fk_prelevement_bons = " . ((int) $id);
2819
            $sql .= " AND fk_soc = 0";  // fk_soc can't be NULL
2820
            $sql .= " AND fk_user IS NOT NULL";
2821
2822
            $num = 0;
2823
            $resql = $this->db->query($sql);
2824
            if ($resql) {
2825
                $obj = $this->db->fetch_object($resql);
2826
                $num = $obj->nb;
2827
            }
2828
            if ($num > 0) {
2829
                return 1;
2830
            }
2831
        } else {
2832
            dol_print_error($this->db);
2833
        }
2834
2835
        return 0;
2836
    }
2837
}
2838