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

Account::load_board()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 46
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 30
nc 9
nop 2
dl 0
loc 46
rs 8.8177
c 0
b 0
f 0
1
<?php
2
/* Copyright (C) 2001-2007	Rodolphe Quiedeville	<[email protected]>
3
 * Copyright (C) 2003		Jean-Louis Bergamo		<[email protected]>
4
 * Copyright (C) 2004-2012	Laurent Destailleur		<[email protected]>
5
 * Copyright (C) 2004		Christophe Combelles	<[email protected]>
6
 * Copyright (C) 2005-2010	Regis Houssin			<[email protected]>
7
 * Copyright (C) 2013		Florian Henry			<[email protected]>
8
 * Copyright (C) 2015-2016	Marcos García			<[email protected]>
9
 * Copyright (C) 2015-2017	Alexandre Spangaro		<[email protected]>
10
 * Copyright (C) 2016		Ferran Marcet   		<[email protected]>
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 3 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24
 */
25
26
/**
27
 *	\file       htdocs/compta/bank/class/account.class.php
28
 *	\ingroup    bank
29
 *	\brief      File of class to manage bank accounts
30
 */
31
require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
32
33
34
/**
35
 *	Class to manage bank accounts
36
 */
37
class Account extends CommonObject
38
{
39
	/**
40
	 * @var string ID to identify managed object
41
	 */
42
	public $element = 'bank_account';
43
44
	/**
45
	 * @var string Name of table without prefix where object is stored
46
	 */
47
	public $table_element = 'bank_account';
48
49
	/**
50
	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
51
	 */
52
	public $picto = 'account';
53
54
	/**
55
	 * @var	int		Use id instead of rowid
56
	 * @deprecated
57
	 * @see $id
58
	 */
59
	public $rowid;
60
61
	/**
62
	 * Account Label
63
	 * @var string
64
	 */
65
	public $label;
66
67
	/**
68
	 * Bank account type. Check TYPE_ constants
69
	 * @var int
70
	 */
71
	public $courant;
72
73
	/**
74
	 * Bank account type. Check TYPE_ constants
75
	 * @var int
76
	 */
77
	public $type;
78
79
	/**
80
	 * Bank name
81
	 * @var string
82
	 */
83
	public $bank;
84
85
	/**
86
	 * Status
87
	 * @var int
88
	 */
89
	public $clos = self::STATUS_OPEN;
90
91
	/**
92
	 * Does it need to be conciliated?
93
	 * @var int
94
	 */
95
	public $rappro=1;
96
97
	/**
98
	 * Webpage
99
	 * @var string
100
	 */
101
	public $url;
102
103
	/**
104
	 * Bank number. If in SEPA area, you should move to IBAN field
105
	 * @var string
106
	 */
107
	public $code_banque;
108
109
	/**
110
	 * Branch number. If in SEPA area, you should move to IBAN field
111
	 * @var string
112
	 */
113
	public $code_guichet;
114
115
	/**
116
	 * Account number. If in SEPA area, you should move to IBAN field
117
	 * @var string
118
	 */
119
	public $number;
120
121
	/**
122
	 * Bank account number control digit. If in SEPA area, you should move to IBAN field
123
	 * @var string
124
	 */
125
	public $cle_rib;
126
127
	/**
128
	 * BIC/Swift code
129
	 * @var string
130
	 */
131
	public $bic;
132
133
	/**
134
	 * IBAN number (International Bank Account Number). Stored into iban_prefix field into database
135
	 * @var
136
	 */
137
	public $iban;
138
139
	/**
140
	 * Name of account holder
141
	 * @var string
142
	 */
143
	public $proprio;
144
145
	/**
146
	 * Address of account holder
147
	 * @var string
148
	 */
149
	public $owner_address;
150
151
	public $state_id;
152
	public $state_code;
153
	public $state;
154
155
	/**
156
	 * Variable containing all account types with their respective translated label.
157
	 * Defined in __construct
158
	 * @var array
159
	 */
160
	public $type_lib = array();
161
162
	/**
163
	 * Variable containing all account statuses with their respective translated label.
164
	 * Defined in __construct
165
	 * @var array
166
	 */
167
	public $status = array();
168
169
	/**
170
	 * Accountancy code
171
	 * @var string
172
	 */
173
	public $account_number;
174
175
	/**
176
     * @var int ID
177
     */
178
	public $fk_accountancy_journal;
179
180
	/**
181
	 * Currency code
182
	 * @var string
183
	 */
184
	public $currency_code;
185
186
	/**
187
	 * Currency code
188
	 * @var string
189
	 * @deprecated Use currency_code instead
190
	 */
191
	public $account_currency_code;
192
193
	/**
194
	 * Authorized minimum balance
195
	 * @var float
196
	 */
197
	public $min_allowed;
198
199
	/**
200
	 * Desired minimum balance
201
	 * @var float
202
	 */
203
	public $min_desired;
204
205
	/**
206
	 * Notes
207
	 * @var string
208
	 */
209
	public $comment;
210
211
	/**
212
	 * Date of the initial balance. Used in Account::create
213
	 * @var int
214
	 */
215
	public $date_solde;
216
217
	/**
218
	 * Current account
219
	 */
220
	const TYPE_CURRENT = 1;
221
	/**
222
	 * Cash account
223
	 */
224
	const TYPE_CASH = 2;
225
	/**
226
	 * Savings account
227
	 */
228
	const TYPE_SAVINGS = 0;
229
230
	const STATUS_OPEN = 0;
231
	const STATUS_CLOSED = 1;
232
233
	/**
234
	 *  Constructor
235
	 *
236
	 *  @param	DoliDB		$db		Database handler
237
	 */
238
	function __construct(DoliDB $db)
239
	{
240
		global $langs;
241
242
		$this->db = $db;
243
244
		$this->solde = 0;
245
246
		$this->type_lib = array(
247
			self::TYPE_SAVINGS => $langs->trans("BankType0"),
248
			self::TYPE_CURRENT => $langs->trans("BankType1"),
249
			self::TYPE_CASH => $langs->trans("BankType2"),
250
		);
251
252
		$this->status = array(
253
			self::STATUS_OPEN => $langs->trans("StatusAccountOpened"),
254
			self::STATUS_CLOSED => $langs->trans("StatusAccountClosed")
255
		);
256
	}
257
258
	/**
259
	 * Shows the account number in the appropriate format
260
	 *
261
	 * @return string
262
	 */
263
	public function __toString()
264
	{
265
		$string = '';
266
267
		foreach ($this->getFieldsToShow() as $val) {
268
269
			if ($val == 'BankCode') {
270
				$string .= $this->code_banque.' ';
271
			} elseif ($val == 'BankAccountNumber') {
272
				$string .= $this->number.' ';
273
			} elseif ($val == 'DeskCode') {
274
				$string .= $this->code_guichet.' ';
275
			} elseif ($val == 'BankAccountNumberKey') {
276
				$string .= $this->cle_rib.' ';
277
			}elseif ($val == 'BIC') {
278
				$string .= $this->bic.' ';
279
			}elseif ($val == 'IBAN') {
280
				$string .= $this->iban.' ';
281
			}
282
		}
283
284
		return trim($string);
285
	}
286
287
288
	/**
289
	 *  Return if a bank account need to be conciliated
290
	 *
291
	 *  @return     int         1 if need to be concialiated, < 0 otherwise.
292
	 */
293
	function canBeConciliated()
294
	{
295
		global $conf;
296
297
		if (empty($this->rappro)) return -1;
298
		if ($this->courant == Account::TYPE_CASH && empty($conf->global->BANK_CAN_RECONCILIATE_CASHACCOUNT)) return -2;
299
		if ($this->clos) return -3;
300
		return 1;
301
	}
302
303
304
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
305
	/**
306
	 *      Add a link between bank line record and its source
307
	 *
308
	 *      @param	int		$line_id    Id ecriture bancaire
309
	 *      @param  int		$url_id     Id parametre url
310
	 *      @param  string	$url        Url
311
	 *      @param  string	$label      Link label
312
	 *      @param  string	$type       Type of link ('payment', 'company', 'member', ...)
313
	 *      @return int         		<0 if KO, id line if OK
314
	 */
315
	function add_url_line($line_id, $url_id, $url, $label, $type)
316
	{
317
        // phpcs:enable
318
		$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
319
		$sql.= "fk_bank";
320
		$sql.= ", url_id";
321
		$sql.= ", url";
322
		$sql.= ", label";
323
		$sql.= ", type";
324
		$sql.= ") VALUES (";
325
		$sql.= "'".$line_id."'";
326
		$sql.= ", '".$url_id."'";
327
		$sql.= ", '".$url."'";
328
		$sql.= ", '".$this->db->escape($label)."'";
329
		$sql.= ", '".$type."'";
330
		$sql.= ")";
331
332
		dol_syslog(get_class($this)."::add_url_line", LOG_DEBUG);
333
		if ($this->db->query($sql))
334
		{
335
			$rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
336
			return $rowid;
337
		}
338
		else
339
		{
340
			$this->error=$this->db->lasterror();
341
			return -1;
342
		}
343
	}
344
345
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
346
	/**
347
	 * 		TODO Move this into AccountLine
348
	 *      Return array with links from llx_bank_url
349
	 *
350
	 *      @param  int         $fk_bank    To search using bank transaction id
351
	 *      @param  int         $url_id     To search using link to
352
	 *      @param  string      $type       To search using type
353
	 *      @return array|int               Array of links array('url'=>, 'url_id'=>, 'label'=>, 'type'=> 'fk_bank'=> ) or -1 on error
354
	 */
355
	function get_url($fk_bank='', $url_id='', $type='')
356
	{
357
        // phpcs:enable
358
		$lines = array();
359
360
		// Check parameters
361
		if (! empty($fk_bank) && (! empty($url_id) || ! empty($type)))
362
		{
363
			$this->error="ErrorBadParameter";
364
			return -1;
365
		}
366
367
		$sql = "SELECT fk_bank, url_id, url, label, type";
368
		$sql.= " FROM ".MAIN_DB_PREFIX."bank_url";
369
		if ($fk_bank > 0) {
370
			$sql.= " WHERE fk_bank = ".$fk_bank;
371
		}
372
		else { $sql.= " WHERE url_id = ".$url_id." AND type = '".$type."'";
373
		}
374
		$sql.= " ORDER BY type, label";
375
376
		dol_syslog(get_class($this)."::get_url", LOG_DEBUG);
377
		$result = $this->db->query($sql);
378
		if ($result)
379
		{
380
			$i = 0;
381
			$num = $this->db->num_rows($result);
382
			while ($i < $num)
383
			{
384
				$obj = $this->db->fetch_object($result);
385
				// Anciens liens (pour compatibilite)
386
				$lines[$i][0] = $obj->url;
387
				$lines[$i][1] = $obj->url_id;
388
				$lines[$i][2] = $obj->label;
389
				$lines[$i][3] = $obj->type;
390
				// Nouveaux liens
391
				$lines[$i]['url'] = $obj->url;
392
				$lines[$i]['url_id'] = $obj->url_id;
393
				$lines[$i]['label'] = $obj->label;
394
				$lines[$i]['type'] = $obj->type;
395
				$lines[$i]['fk_bank'] = $obj->fk_bank;
396
				$i++;
397
			}
398
		}
399
		else dol_print_error($this->db);
400
401
		return $lines;
402
	}
403
404
	/**
405
	 *  Add an entry into table ".MAIN_DB_PREFIX."bank
406
	 *
407
	 *  @param	int	        $date			Date operation
408
	 *  @param	string		$oper			1,2,3,4... (deprecated) or 'TYP','VIR','PRE','LIQ','VAD','CB','CHQ'...
409
	 *  @param	string		$label			Descripton
410
	 *  @param	float		$amount			Amount
411
	 *  @param	string		$num_chq		Numero cheque ou virement
412
	 *  @param	int  		$categorie		Category id (optionnal)
413
	 *  @param	User		$user			User that create
414
	 *  @param	string		$emetteur		Name of cheque writer
415
	 *  @param	string		$banque			Bank of cheque writer
416
	 *  @param	string		$accountancycode	When we record a free bank entry, we must provide accounting account if accountancy module is on.
417
	 *  @param	int			$datev			Date value
418
	 *  @return	int							Rowid of added entry, <0 if KO
419
	 */
420
	function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur='',$banque='', $accountancycode='', $datev=null)
421
	{
422
		// Deprecation warning
423
		if (is_numeric($oper)) {
424
			dol_syslog(__METHOD__ . ": using numeric operations is deprecated", LOG_WARNING);
425
		}
426
427
		// Clean parameters
428
		$emetteur=trim($emetteur);
429
		$banque=trim($banque);
430
431
		$now=dol_now();
432
433
		if (is_numeric($oper))    // Clean operation to have a code instead of a rowid
434
		{
435
			$sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
436
			$sql.= " WHERE id=".$oper;
437
			$sql.= " AND entity IN (".getEntity('c_paiement').")";
438
			$resql=$this->db->query($sql);
439
			if ($resql)
440
			{
441
				$obj=$this->db->fetch_object($resql);
442
				$oper=$obj->code;
443
			}
444
			else
445
			{
446
				dol_print_error($this->db,'Failed to get payment type code');
447
				return -1;
448
			}
449
		}
450
451
		// Check parameters
452
		if (! $oper)
453
		{
454
			$this->error="oper not defined";
455
			return -1;
456
		}
457
		if (! $this->rowid)
458
		{
459
			$this->error="this->rowid not defined";
460
			return -2;
461
		}
462
		if ($this->courant == Account::TYPE_CASH && $oper != 'LIQ')
463
		{
464
			$this->error="ErrorCashAccountAcceptsOnlyCashMoney";
465
			return -3;
466
		}
467
468
		$this->db->begin();
469
470
		if (is_null($datev) || empty($datev)) $datev = $date;
471
472
		$accline = new AccountLine($this->db);
473
		$accline->datec = $now;
474
		$accline->dateo = $date;
475
		$accline->datev = $datev;
476
		$accline->label = $label;
477
		$accline->amount = $amount;
478
		$accline->fk_user_author = $user->id;
479
		$accline->fk_account = $this->rowid;
480
		$accline->fk_type = $oper;
0 ignored issues
show
Documentation Bug introduced by
The property $fk_type was declared of type integer, but $oper is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
481
		$accline->numero_compte = $accountancycode;
482
483
		if ($num_chq) {
484
			$accline->num_chq = $num_chq;
485
		}
486
487
		if ($emetteur) {
488
			$accline->emetteur = $emetteur;
0 ignored issues
show
Documentation Bug introduced by
It seems like $emetteur of type string is incompatible with the declared type Societe of property $emetteur.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
489
		}
490
491
		if ($banque) {
492
			$accline->bank_chq = $banque;
493
		}
494
495
		if ($accline->insert() > 0) {
496
497
			if ($categorie>0) {
498
				$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (";
499
				$sql .= "lineid, fk_categ";
500
				$sql .= ") VALUES (";
501
				$sql .= $accline->id.", ".$categorie;
502
				$sql .= ")";
503
504
				$result = $this->db->query($sql);
505
				if (!$result) {
506
					$this->error = $this->db->lasterror();
507
					$this->db->rollback();
508
					return -3;
509
				}
510
			}
511
512
			$this->db->commit();
513
			return $accline->id;
514
		} else {
515
			$this->error = $this->db->lasterror();
516
			$this->db->rollback();
517
			return -2;
518
		}
519
	}
520
521
	/**
522
	 *  Create bank account into database
523
	 *
524
	 *  @param	User	$user		Object user making creation
525
	 *  @param  int     $notrigger  1=Disable triggers
526
	 *  @return int        			< 0 if KO, > 0 if OK
527
	 */
528
	function create(User $user, $notrigger=0)
529
	{
530
		global $langs,$conf, $hookmanager;
531
532
		$error=0;
533
534
		// Clean parameters
535
		if (! $this->min_allowed) $this->min_allowed=0;
536
		if (! $this->min_desired) $this->min_desired=0;
537
		$this->state_id = ($this->state_id?$this->state_id:$this->state_id);
538
		$this->country_id = ($this->country_id?$this->country_id:$this->country_id);
539
540
		// Check parameters
541
		if (empty($this->country_id))
542
		{
543
			$this->error=$langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Country"));
544
			dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
545
			return -1;
546
		}
547
		if (empty($this->ref))
548
		{
549
			$this->error=$langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref"));
550
			dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
551
			return -1;
552
		}
553
		if (empty($this->date_solde))
554
		{
555
			$this->error=$langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("DateInitialBalance"));
556
			dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
557
			return -1;
558
		}
559
560
		// Chargement librairie pour acces fonction controle RIB
561
		require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
562
563
		$now=dol_now();
564
565
		$this->db->begin();
566
567
		$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
568
		$sql.= "datec";
569
		$sql.= ", ref";
570
		$sql.= ", label";
571
		$sql.= ", entity";
572
		$sql.= ", account_number";
573
		$sql.= ", fk_accountancy_journal";
574
		$sql.= ", bank";
575
		$sql.= ", code_banque";
576
		$sql.= ", code_guichet";
577
		$sql.= ", number";
578
		$sql.= ", cle_rib";
579
		$sql.= ", bic";
580
		$sql.= ", iban_prefix";
581
		$sql.= ", domiciliation";
582
		$sql.= ", proprio";
583
		$sql.= ", owner_address";
584
		$sql.= ", currency_code";
585
		$sql.= ", rappro";
586
		$sql.= ", min_allowed";
587
		$sql.= ", min_desired";
588
		$sql.= ", comment";
589
		$sql.= ", state_id";
590
		$sql.= ", fk_pays";
591
		$sql.= ") VALUES (";
592
		$sql.= "'".$this->db->idate($now)."'";
593
		$sql.= ", '".$this->db->escape($this->ref)."'";
594
		$sql.= ", '".$this->db->escape($this->label)."'";
595
		$sql.= ", ".$conf->entity;
596
		$sql.= ", '".$this->db->escape($this->account_number)."'";
597
		$sql.= ", ".($this->fk_accountancy_journal > 0 ? $this->db->escape($this->fk_accountancy_journal) : "null");
598
		$sql.= ", '".$this->db->escape($this->bank)."'";
599
		$sql.= ", '".$this->db->escape($this->code_banque)."'";
600
		$sql.= ", '".$this->db->escape($this->code_guichet)."'";
601
		$sql.= ", '".$this->db->escape($this->number)."'";
602
		$sql.= ", '".$this->db->escape($this->cle_rib)."'";
603
		$sql.= ", '".$this->db->escape($this->bic)."'";
604
		$sql.= ", '".$this->db->escape($this->iban)."'";
605
		$sql.= ", '".$this->db->escape($this->domiciliation)."'";
606
		$sql.= ", '".$this->db->escape($this->proprio)."'";
607
		$sql.= ", '".$this->db->escape($this->owner_address)."'";
608
		$sql.= ", '".$this->db->escape($this->currency_code)."'";
609
		$sql.= ", ".$this->rappro;
610
		$sql.= ", ".price2num($this->min_allowed);
611
		$sql.= ", ".price2num($this->min_desired);
612
		$sql.= ", '".$this->db->escape($this->comment)."'";
613
		$sql.= ", ".($this->state_id>0?$this->state_id:"null");
614
		$sql.= ", ".$this->country_id;
615
		$sql.= ")";
616
617
		dol_syslog(get_class($this)."::create", LOG_DEBUG);
618
		$resql=$this->db->query($sql);
619
		if ($resql)
620
		{
621
			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
622
623
			$result=$this->update($user, 1);
624
			if ($result > 0)
625
			{
626
				$accline = new AccountLine($this->db);
627
				$accline->datec = $this->db->idate($now);
628
				$accline->label = '('.$langs->trans("InitialBankBalance").')';
629
				$accline->amount = price2num($this->solde);
630
				$accline->fk_user_author = $user->id;
631
				$accline->fk_account = $this->id;
632
				$accline->datev = $this->db->idate($this->date_solde);
633
				$accline->dateo = $this->db->idate($this->date_solde);
634
				$accline->fk_type = 'SOLD';
635
636
				if ($accline->insert() < 0) {
637
					$error++;
638
					$this->error = $accline->error;
639
					$this->errors = $accline->errors;
640
				}
641
642
				if (! $error)
643
				{
644
					$result=$this->insertExtraFields();
645
					if ($result < 0) $error++;
646
				}
647
648
				if (! $error && ! $notrigger)
649
				{
650
					// Call trigger
651
					$result=$this->call_trigger('BANKACCOUNT_CREATE',$user);
652
					if ($result < 0) $error++;
653
					// End call triggers
654
				}
655
			}
656
			else
657
			{
658
				$error++;
659
			}
660
		}
661
		else
662
		{
663
			if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
664
			{
665
				$this->error=$langs->trans("ErrorBankLabelAlreadyExists");
666
				$error++;
667
			}
668
			else {
669
				$this->error=$this->db->error()." sql=".$sql;
670
				$error++;
671
			}
672
		}
673
674
		if (! $error)
675
		{
676
			$this->db->commit();
677
			return $this->id;
678
		}
679
		else
680
		{
681
			$this->db->rollback();
682
			return -1*$error;
683
		}
684
	}
685
686
	/**
687
	 *    	Update bank account card
688
	 *
689
	 *    	@param	User	$user       Object user making action
690
	 *      @param  int     $notrigger  1=Disable triggers
691
	 *		@return	int					<0 if KO, >0 if OK
692
	 */
693
	function update(User $user, $notrigger = 0)
694
	{
695
		global $langs,$conf, $hookmanager;
696
697
		$error=0;
698
699
		$this->db->begin();
700
701
		// Clean parameters
702
		$this->state_id = ($this->state_id?$this->state_id:$this->state_id);
703
		$this->country_id = ($this->country_id?$this->country_id:$this->country_id);
704
705
		// Check parameters
706
		if (empty($this->country_id))
707
		{
708
			$this->error=$langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Country"));
709
			dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
710
			return -1;
711
		}
712
		if (empty($this->ref))
713
		{
714
			$this->error=$langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref"));
715
			dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
716
			return -1;
717
		}
718
		if (! $this->label) $this->label = "???";
719
720
		$sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
721
722
		$sql.= " ref   = '".$this->db->escape($this->ref)."'";
723
		$sql.= ",label = '".$this->db->escape($this->label)."'";
724
725
		$sql.= ",courant = ".$this->courant;
726
		$sql.= ",clos = ".$this->clos;
727
		$sql.= ",rappro = ".$this->rappro;
728
		$sql.= ",url = ".($this->url?"'".$this->db->escape($this->url)."'":"null");
729
		$sql.= ",account_number = '".$this->db->escape($this->account_number)."'";
730
		$sql.= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? $this->db->escape($this->fk_accountancy_journal) : "null");
731
		$sql.= ",bank  = '".$this->db->escape($this->bank)."'";
732
		$sql.= ",code_banque='".$this->db->escape($this->code_banque)."'";
733
		$sql.= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
734
		$sql.= ",number='".$this->db->escape($this->number)."'";
735
		$sql.= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
736
		$sql.= ",bic='".$this->db->escape($this->bic)."'";
737
		$sql.= ",iban_prefix = '".$this->db->escape($this->iban)."'";
738
		$sql.= ",domiciliation='".$this->db->escape($this->domiciliation)."'";
739
		$sql.= ",proprio = '".$this->db->escape($this->proprio)."'";
740
		$sql.= ",owner_address = '".$this->db->escape($this->owner_address)."'";
741
742
		$sql.= ",currency_code = '".$this->db->escape($this->currency_code)."'";
743
744
		$sql.= ",min_allowed = ".($this->min_allowed != '' ? price2num($this->min_allowed) : "null");
745
		$sql.= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null");
746
		$sql.= ",comment     = '".$this->db->escape($this->comment)."'";
747
748
		$sql.= ",state_id = ".($this->state_id>0?$this->state_id:"null");
749
		$sql.= ",fk_pays = ".$this->country_id;
750
751
		$sql.= " WHERE rowid = ".$this->id;
752
		$sql.= " AND entity = ".$conf->entity;
753
754
		dol_syslog(get_class($this)."::update", LOG_DEBUG);
755
		$result = $this->db->query($sql);
756
		if ($result)
757
		{
758
			// Actions on extra fields (by external module or standard code)
759
			if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
760
			{
761
				if (! $error)
762
				{
763
					$result=$this->insertExtraFields();
764
					if ($result < 0) $error++;
765
				}
766
			}
767
768
			if (! $error && ! $notrigger)
769
			{
770
				// Call trigger
771
				$result=$this->call_trigger('BANKACCOUNT_UPDATE',$user);
772
				if ($result < 0) $error++;
773
				// End call triggers
774
			}
775
		}
776
		else
777
		{
778
			$error++;
779
			$this->error=$this->db->lasterror();
780
			dol_print_error($this->db);
781
		}
782
783
		if (! $error)
784
		{
785
			$this->db->commit();
786
			return $this->id;
787
		}
788
		else
789
		{
790
			$this->db->rollback();
791
			return -1*$error;
792
		}
793
	}
794
795
796
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
797
	/**
798
	 *  Update BBAN (RIB) account fields
799
	 *
800
	 *  @param	User	$user       Object user making update
801
	 *	@return	int					<0 if KO, >0 if OK
802
	 */
803
	function update_bban(User $user = null)
804
	{
805
        // phpcs:enable
806
		global $conf,$langs;
807
808
		// Clean parameters
809
		$this->state_id = ($this->state_id?$this->state_id:$this->state_id);
810
		$this->country_id = ($this->country_id?$this->country_id:$this->country_id);
811
812
		// Chargement librairie pour acces fonction controle RIB
813
		require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
814
815
		dol_syslog(get_class($this)."::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
816
817
		// Check parameters
818
		if (! $this->ref)
819
		{
820
			$this->error=$langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->trans("Ref"));
821
			return -2;
822
		}
823
824
		$sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
825
		$sql.= " bank  = '".$this->db->escape($this->bank)."'";
826
		$sql.= ",code_banque='".$this->db->escape($this->code_banque)."'";
827
		$sql.= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
828
		$sql.= ",number='".$this->db->escape($this->number)."'";
829
		$sql.= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
830
		$sql.= ",bic='".$this->db->escape($this->bic)."'";
831
		$sql.= ",iban_prefix = '".$this->db->escape($this->iban)."'";
832
		$sql.= ",domiciliation='".$this->db->escape($this->domiciliation)."'";
833
		$sql.= ",proprio = '".$this->db->escape($this->proprio)."'";
834
		$sql.= ",owner_address = '".$this->db->escape($this->owner_address)."'";
835
		$sql.= ",state_id = ".($this->state_id>0?$this->state_id:"null");
836
		$sql.= ",fk_pays = ".$this->country_id;
837
		$sql.= " WHERE rowid = ".$this->id;
838
		$sql.= " AND entity = ".$conf->entity;
839
840
		dol_syslog(get_class($this)."::update_bban", LOG_DEBUG);
841
842
		$result = $this->db->query($sql);
843
		if ($result)
844
		{
845
			return 1;
846
		}
847
		else
848
		{
849
			$this->error=$this->db->lasterror();
850
			dol_print_error($this->db);
851
			return -1;
852
		}
853
	}
854
855
856
	/**
857
	 *      Load a bank account into memory from database
858
	 *
859
	 *      @param	int		$id      	Id of bank account to get
860
	 *      @param  string	$ref     	Ref of bank account to get
861
	 *      @return	int					<0 if KO, >0 if OK
862
	 */
863
	function fetch($id, $ref='')
864
	{
865
		global $conf;
866
867
		if (empty($id) && empty($ref))
868
		{
869
			$this->error="ErrorBadParameters";
870
			return -1;
871
		}
872
873
		$sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant, ba.clos, ba.rappro, ba.url,";
874
		$sql.= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
875
		$sql.= " ba.domiciliation, ba.proprio, ba.owner_address, ba.state_id, ba.fk_pays as country_id,";
876
		$sql.= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,";
877
		$sql.= " ba.min_allowed, ba.min_desired, ba.comment,";
878
		$sql.= " ba.datec as date_creation, ba.tms as date_update,";
879
		$sql.= ' c.code as country_code, c.label as country,';
880
		$sql.= ' d.code_departement as state_code, d.nom as state';
881
        $sql.= ' , aj.code as accountancy_journal';
882
		$sql.= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
883
		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid';
884
		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid';
885
        $sql.= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'accounting_journal as aj ON aj.rowid=ba.fk_accountancy_journal';
886
		$sql.= " WHERE ba.entity IN (".getEntity($this->element).")";
887
		if ($id)  $sql.= " AND ba.rowid  = ".$id;
888
		if ($ref) $sql.= " AND ba.ref = '".$this->db->escape($ref)."'";
889
890
		dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
891
		$result = $this->db->query($sql);
892
		if ($result)
893
		{
894
			if ($this->db->num_rows($result))
895
			{
896
				$obj = $this->db->fetch_object($result);
897
898
				$this->id            = $obj->rowid;
899
				$this->rowid         = $obj->rowid;
900
				$this->ref           = $obj->ref;
901
				$this->label         = $obj->label;
902
				$this->type          = $obj->courant;
903
				$this->courant       = $obj->courant;
904
				$this->bank          = $obj->bank;
905
				$this->clos          = $obj->clos;
906
				$this->rappro        = $obj->rappro;
907
				$this->url           = $obj->url;
908
909
				$this->code_banque   = $obj->code_banque;
910
				$this->code_guichet  = $obj->code_guichet;
911
				$this->number        = $obj->number;
912
				$this->cle_rib       = $obj->cle_rib;
913
				$this->bic           = $obj->bic;
914
				$this->iban          = $obj->iban;
915
				$this->domiciliation = $obj->domiciliation;
916
				$this->proprio       = $obj->proprio;
917
				$this->owner_address = $obj->owner_address;
918
919
				$this->state_id        = $obj->state_id;
920
				$this->state_code      = $obj->state_code;
921
				$this->state           = $obj->state;
922
923
				$this->country_id    = $obj->country_id;
924
				$this->country_code  = $obj->country_code;
925
				$this->country       = $obj->country;
926
927
				$this->account_number = $obj->account_number;
928
				$this->fk_accountancy_journal = $obj->fk_accountancy_journal;
929
				$this->accountancy_journal = $obj->accountancy_journal;
930
931
				$this->currency_code  = $obj->currency_code;
932
				$this->account_currency_code  = $obj->currency_code;
933
				$this->min_allowed    = $obj->min_allowed;
934
				$this->min_desired    = $obj->min_desired;
935
				$this->comment        = $obj->comment;
936
937
				$this->date_creation  = $this->db->jdate($obj->date_creation);
938
				$this->date_update    = $this->db->jdate($obj->date_update);
939
940
				// Retreive all extrafield
941
				// fetch optionals attributes and labels
942
				$this->fetch_optionals();
943
944
				return 1;
945
			}
946
			else
947
			{
948
				return 0;
949
			}
950
		}
951
		else
952
		{
953
			$this->error=$this->db->lasterror;
954
			$this->errors[]=$this->error;
955
			return -1;
956
		}
957
	}
958
959
	/**
960
	 * Sets object to supplied categories.
961
	 *
962
	 * Deletes object from existing categories not supplied.
963
	 * Adds it to non existing supplied categories.
964
	 * Existing categories are left untouch.
965
	 *
966
	 * @param int[]|int $categories Category or categories IDs
967
     * @return void
968
	 */
969
    public function setCategories($categories)
970
    {
971
		// Handle single category
972
		if (! is_array($categories)) {
973
			$categories = array($categories);
974
		}
975
976
		// Get current categories
977
		require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
978
		$c = new Categorie($this->db);
979
		$existing = $c->containing($this->id, Categorie::TYPE_ACCOUNT, 'id');
980
981
		// Diff
982
		if (is_array($existing)) {
983
			$to_del = array_diff($existing, $categories);
984
			$to_add = array_diff($categories, $existing);
985
		} else {
986
			$to_del = array(); // Nothing to delete
987
			$to_add = $categories;
988
		}
989
990
		// Process
991
		foreach($to_del as $del) {
992
			if ($c->fetch($del) > 0) {
993
				$c->del_type($this, 'account');
994
			}
995
		}
996
		foreach ($to_add as $add) {
997
			if ($c->fetch($add) > 0) {
998
				$c->add_type($this, 'account');
999
			}
1000
		}
1001
1002
		return;
1003
	}
1004
1005
	/**
1006
	 *  Delete bank account from database
1007
	 *
1008
	 *	@param	User	$user	User deleting
1009
	 *  @return int             <0 if KO, >0 if OK
1010
	 */
1011
	function delete(User $user = null)
1012
	{
1013
		global $conf;
1014
1015
		$error=0;
1016
1017
		$this->db->begin();
1018
1019
		// Delete link between tag and bank account
1020
		if (! $error)
1021
		{
1022
			$sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
1023
			$sql.= " WHERE fk_account = ".$this->id;
1024
1025
			$resql = $this->db->query($sql);
1026
			if (!$resql)
1027
			{
1028
				$error++;
1029
				$this->error = "Error ".$this->db->lasterror();
1030
			}
1031
		}
1032
1033
		if (! $error)
1034
		{
1035
			$sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_account";
1036
			$sql.= " WHERE rowid = ".$this->rowid;
1037
1038
			dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1039
			$result = $this->db->query($sql);
1040
			if ($result)
1041
			{
1042
				// Remove extrafields
1043
				if ((empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
1044
				{
1045
					$result=$this->deleteExtraFields();
1046
					if ($result < 0)
1047
					{
1048
						$error++;
1049
						dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1050
					}
1051
				}
1052
			}
1053
			else
1054
			{
1055
				$error++;
1056
				$this->error = "Error ".$this->db->lasterror();
1057
			}
1058
		}
1059
1060
		if (! $error)
1061
		{
1062
			$this->db->commit();
1063
			return 1;
1064
		}
1065
		else
1066
		{
1067
			$this->db->rollback();
1068
			return -1;
1069
		}
1070
	}
1071
1072
1073
	/**
1074
	 *  Return label of object status
1075
	 *
1076
	 *  @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
1077
	 *  @return     string        		    Label
1078
	 */
1079
	function getLibStatut($mode=0)
1080
	{
1081
		return $this->LibStatut($this->clos,$mode);
1082
	}
1083
1084
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1085
	/**
1086
	 *  Return label of given object status
1087
	 *
1088
	 *  @param	 int		$statut        	Id statut
1089
	 *  @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
1090
	 *  @return  string        			    Label
1091
	 */
1092
	function LibStatut($statut, $mode = 0)
1093
	{
1094
        // phpcs:enable
1095
		global $langs;
1096
		$langs->load('banks');
1097
1098
		if ($statut == self::STATUS_OPEN) {
1099
			$label = $langs->trans("StatusAccountOpened");
1100
			$picto = img_picto($label, 'statut4');
1101
		} else {
1102
			$label = $langs->trans("StatusAccountClosed");
1103
			$picto = img_picto($label, 'statut5');
1104
		}
1105
1106
		if ($mode == 2) {
1107
			return $picto.' '.$label;
1108
		} elseif ($mode == 3) {
1109
			return $picto;
1110
		} elseif ($mode == 4) {
1111
			return $picto.' '.$label;
1112
		} elseif ($mode == 5) {
1113
			return $label.' '.$picto;
1114
		} elseif ($mode == 6) {
1115
			return $label.' '.$picto;
1116
		}
1117
1118
		//There is no short mode for this label
1119
		return $label;
1120
	}
1121
1122
1123
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1124
	/**
1125
	 *    Renvoi si un compte peut etre supprimer ou non (sans mouvements)
1126
	 *
1127
	 *    @return     boolean     vrai si peut etre supprime, faux sinon
1128
	 */
1129
	function can_be_deleted()
1130
	{
1131
        // phpcs:enable
1132
		$can_be_deleted=false;
1133
1134
		$sql = "SELECT COUNT(rowid) as nb";
1135
		$sql.= " FROM ".MAIN_DB_PREFIX."bank";
1136
		$sql.= " WHERE fk_account=".$this->id;
1137
1138
		$resql = $this->db->query($sql);
1139
		if ($resql) {
1140
			$obj=$this->db->fetch_object($resql);
1141
			if ($obj->nb <= 1) $can_be_deleted=true;    // Juste le solde
1142
		}
1143
		else {
1144
			dol_print_error($this->db);
1145
		}
1146
		return $can_be_deleted;
1147
	}
1148
1149
1150
	/**
1151
	 *   Return error
1152
	 *
1153
	 *   @return	string		Error string
1154
	 */
1155
	function error()
1156
	{
1157
		return $this->error;
1158
	}
1159
1160
	/**
1161
	 * 	Return current sold
1162
	 *
1163
	 * 	@param	int		$option		1=Exclude future operation date (this is to exclude input made in advance and have real account sold)
1164
	 *	@return	int					Current sold (value date <= today)
1165
	 */
1166
	function solde($option=0)
1167
	{
1168
		$solde=0;
1169
1170
		$sql = "SELECT sum(amount) as amount";
1171
		$sql.= " FROM ".MAIN_DB_PREFIX."bank";
1172
		$sql.= " WHERE fk_account = ".$this->id;
1173
		if ($option == 1) $sql.= " AND dateo <= '".$this->db->idate(dol_now())."'";
1174
1175
		$resql = $this->db->query($sql);
1176
		if ($resql)
1177
		{
1178
			if ($this->db->num_rows($resql))
1179
			{
1180
				$obj=$this->db->fetch_object($resql);
1181
				$solde = $obj->amount;
1182
			}
1183
			$this->db->free($resql);
1184
		} else {
1185
			$this->errors[]=$this->db->lasterror;
1186
			return -1;
1187
		}
1188
1189
		return price2num($solde, 'MU');
1190
	}
1191
1192
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1193
	/**
1194
	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
1195
	 *
1196
	 *      @param	User	$user        		Objet user
1197
	 *		@param	int		$filteraccountid	To get info for a particular account id
1198
	 *      @return WorkboardResponse|int 		<0 if KO, WorkboardResponse if OK
1199
	 */
1200
	function load_board(User $user, $filteraccountid = 0)
1201
	{
1202
        // phpcs:enable
1203
		global $conf, $langs;
1204
1205
		if ($user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
1206
1207
		$sql = "SELECT b.rowid, b.datev as datefin";
1208
		$sql.= " FROM ".MAIN_DB_PREFIX."bank as b,";
1209
		$sql.= " ".MAIN_DB_PREFIX."bank_account as ba";
1210
		$sql.= " WHERE b.rappro=0";
1211
		$sql.= " AND b.fk_account = ba.rowid";
1212
		$sql.= " AND ba.entity IN (".getEntity('bank_account').")";
1213
		$sql.= " AND (ba.rappro = 1 AND ba.courant != 2)";	// Compte rapprochable
1214
		$sql.= " AND clos = 0";
1215
		if ($filteraccountid) $sql.=" AND ba.rowid = ".$filteraccountid;
1216
1217
		$resql=$this->db->query($sql);
1218
		if ($resql)
1219
		{
1220
			$langs->load("banks");
1221
			$now=dol_now();
1222
1223
			require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
1224
1225
			$response = new WorkboardResponse();
1226
			$response->warning_delay=$conf->bank->rappro->warning_delay/60/60/24;
1227
			$response->label=$langs->trans("TransactionsToConciliate");
1228
			$response->url=DOL_URL_ROOT.'/compta/bank/list.php?leftmenu=bank&amp;mainmenu=bank';
1229
			$response->img=img_object('',"payment");
1230
1231
			while ($obj=$this->db->fetch_object($resql))
1232
			{
1233
				$response->nbtodo++;
1234
				if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) {
1235
					$response->nbtodolate++;
1236
				}
1237
			}
1238
1239
			return $response;
1240
		}
1241
		else
1242
		{
1243
			dol_print_error($this->db);
1244
			$this->error=$this->db->error();
1245
			return -1;
1246
		}
1247
	}
1248
1249
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1250
	/**
1251
	 *      Charge indicateurs this->nb de tableau de bord
1252
	 *		@param		int			$filteraccountid	To get info for a particular account id
1253
	 *      @return     int         <0 if ko, >0 if ok
1254
	 */
1255
	function load_state_board($filteraccountid = 0)
1256
	{
1257
        // phpcs:enable
1258
		global $user;
1259
1260
		if ($user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
1261
1262
		$sql = "SELECT count(b.rowid) as nb";
1263
		$sql.= " FROM ".MAIN_DB_PREFIX."bank as b,";
1264
		$sql.= " ".MAIN_DB_PREFIX."bank_account as ba";
1265
		$sql.= " WHERE b.fk_account = ba.rowid";
1266
		$sql.= " AND ba.entity IN (".getEntity('bank_account').")";
1267
		$sql.= " AND (ba.rappro = 1 AND ba.courant != 2)";	// Compte rapprochable
1268
		$sql.= " AND clos = 0";
1269
		if ($filteraccountid) $sql.=" AND ba.rowid = ".$filteraccountid;
1270
1271
		$resql=$this->db->query($sql);
1272
		if ($resql)
1273
		{
1274
			while ($obj=$this->db->fetch_object($resql))
1275
			{
1276
				$this->nb["banklines"]=$obj->nb;
1277
			}
1278
			$this->db->free($resql);
1279
			return 1;
1280
		}
1281
		else
1282
		{
1283
			dol_print_error($this->db);
1284
			$this->error=$this->db->error();
1285
			return -1;
1286
		}
1287
	}
1288
1289
1290
	/**
1291
	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
1292
	 *
1293
	 *      @return int     Nb of account we can reconciliate
1294
	 */
1295
	public static function countAccountToReconcile()
1296
	{
1297
		global $db, $conf, $user;
1298
1299
		//Protection against external users
1300
		if ($user->societe_id) {
1301
			return 0;
1302
		}
1303
1304
		$nb=0;
1305
1306
		$sql = "SELECT COUNT(ba.rowid) as nb";
1307
		$sql.= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1308
		$sql.= " WHERE ba.rappro > 0 and ba.clos = 0";
1309
		$sql.= " AND ba.entity IN (".getEntity('bank_account').")";
1310
		if (empty($conf->global->BANK_CAN_RECONCILIATE_CASHACCOUNT)) $sql.= " AND ba.courant != 2";
1311
		$resql=$db->query($sql);
1312
		if ($resql)
1313
		{
1314
			$obj = $db->fetch_object($resql);
1315
			$nb = $obj->nb;
1316
		}
1317
		else dol_print_error($db);
1318
1319
		return $nb;
1320
	}
1321
1322
	/**
1323
	 *  Return clicable name (with picto eventually)
1324
	 *
1325
	 *	@param	int		$withpicto					Include picto into link
1326
	 *  @param  string	$mode           			''=Link to card, 'transactions'=Link to transactions card
1327
	 *  @param  string  $option         			''=Show ref, 'reflabel'=Show ref+label
1328
	 *  @param  int     $save_lastsearch_value    	-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
1329
     *  @param	int  	$notooltip		 			1=Disable tooltip
1330
	 *	@return	string								Chaine avec URL
1331
	 */
1332
	function getNomUrl($withpicto=0, $mode='', $option='', $save_lastsearch_value=-1, $notooltip=0)
1333
	{
1334
		global $conf, $langs, $user;
1335
1336
		$result='';
1337
		$label = '<u>' . $langs->trans("ShowAccount") . '</u>';
1338
		$label .= '<br><b>' . $langs->trans('BankAccount') . ':</b> ' . $this->label;
1339
		$label .= '<br><b>' . $langs->trans('AccountNumber') . ':</b> ' . $this->number;
1340
		$label .= '<br><b>' . $langs->trans("AccountCurrency") . ':</b> ' . $this->currency_code;
1341
1342
		if (empty($user->rights->banque->lire) || !empty($user->socid))
1343
		{
1344
			$option = 'nolink';
1345
		}
1346
1347
		if (! empty($conf->accounting->enabled))
1348
		{
1349
			include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1350
			$langs->load("accountancy");
1351
			$label .= '<br><b>' . $langs->trans('AccountAccounting') . ':</b> ' . length_accountg($this->account_number);
1352
			$label .= '<br><b>' . $langs->trans('AccountancyJournal') . ':</b> ' . $this->accountancy_journal;
1353
		}
1354
		$linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
1355
1356
		$url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id;
1357
		if ($mode == 'transactions')
1358
		{
1359
			$url = DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id;
1360
		}
1361
		else if ($mode == 'receipts')
1362
		{
1363
			$url = DOL_URL_ROOT.'/compta/bank/releve.php?account='.$this->id;
1364
		}
1365
1366
		if ($option != 'nolink')
1367
		{
1368
			// Add param to save lastsearch_values or not
1369
			$add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
1370
			if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
1371
			if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
1372
		}
1373
1374
		$linkstart = '<a href="'.$url.$linkclose;
1375
		$linkend = '</a>';
1376
1377
                if ($option == 'nolink') {
1378
                    $linkstart = '';
1379
                    $linkend = '';
1380
                }
1381
1382
		$result .= $linkstart;
1383
		if ($withpicto) $result.=img_object(($notooltip?'':$label), $this->picto, ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
1384
		if ($withpicto != 2) $result.= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
1385
		$result .= $linkend;
1386
1387
		return $result;
1388
	}
1389
1390
1391
	// Method after here are common to Account and CompanyBankAccount
1392
1393
1394
	/**
1395
	 *     Return if an account has valid information for Direct debit payment
1396
	 *
1397
	 *     @return     int         1 if correct, <=0 if wrong
1398
	 */
1399
	function verif()
1400
	{
1401
		require_once DOL_DOCUMENT_ROOT . '/core/lib/bank.lib.php';
1402
1403
		$this->error_number = 0;
1404
1405
		// Call function to check BAN
1406
1407
		if (! checkIbanForAccount($this) || ! checkSwiftForAccount($this))
1408
		{
1409
			$this->error_number = 12;
1410
			$this->error_message = 'IBANSWIFTControlError';
1411
		}
1412
		/*if (! checkBanForAccount($this))
1413
        {
1414
            $this->error_number = 12;
1415
            $this->error_message = 'BANControlError';
1416
        }*/
1417
1418
		if ($this->error_number == 0)
1419
		{
1420
			return 1;
1421
		}
1422
		else
1423
		{
1424
			return 0;
1425
		}
1426
	}
1427
1428
	/**
1429
	 * 	Return account country code
1430
	 *
1431
	 *	@return		string		country code
1432
	 */
1433
	function getCountryCode()
1434
	{
1435
		global $mysoc;
1436
1437
		// We return country code of bank account
1438
		if (! empty($this->country_code)) return $this->country_code;
1439
1440
		// For backward compatibility, we try to guess country from other information
1441
		if (! empty($this->iban))
1442
		{
1443
			// If IBAN defined, we can know country of account from it
1444
			if (preg_match("/^([a-zA-Z][a-zA-Z])/i",$this->iban,$reg)) return $reg[1];
1445
		}
1446
1447
		// If this class is linked to a third party
1448
		if (! empty($this->socid))
1449
		{
1450
			require_once DOL_DOCUMENT_ROOT .'/societe/class/societe.class.php';
1451
			$company=new Societe($this->db);
1452
			$result=$company->fetch($this->socid);
1453
			if (! empty($company->country_code)) return $company->country_code;
1454
		}
1455
1456
		// We return country code of managed company
1457
		if (! empty($mysoc->country_code)) return $mysoc->country_code;
1458
1459
		return '';
1460
	}
1461
1462
	/**
1463
	 * Return if a bank account is defined with detailed information (bank code, desk code, number and key).
1464
	 * More information on codes used by countries on page http://en.wikipedia.org/wiki/Bank_code
1465
	 *
1466
	 * @return		int        0=No bank code need + Account number is enough
1467
	 *                         1=Need 2 fields for bank code: Bank, Desk (France, Spain, ...) + Account number and key
1468
	 *                         2=Need 1 field for bank code:  Bank only (Sort code for Great Britain, BSB for Australia) + Account number
1469
	 */
1470
	function useDetailedBBAN()
1471
	{
1472
		$country_code=$this->getCountryCode();
1473
1474
		if (in_array($country_code,array('FR','ES','GA','IT','NC'))) return 1; // France, Spain, Gabon, ... - Not valid for CH
1475
		if (in_array($country_code,array('AU','BE','CA','DE','DK','GR','GB','ID','IE','IR','KR','NL','NZ','UK','US'))) return 2;      // Australia, England...
1476
		return 0;
1477
	}
1478
1479
	/**
1480
	 * Return 1 if IBAN / BIC is mandatory (otherwise option)
1481
	 *
1482
	 * @return		int        1 = mandatory / 0 = Not mandatory
1483
	 */
1484
	function needIBAN()
1485
	{
1486
		$country_code=$this->getCountryCode();
1487
1488
		$country_code_in_EEC=array(
1489
				'AT',	// Austria
1490
				'BE',	// Belgium
1491
				'BG',	// Bulgaria
1492
				'CY',	// Cyprus
1493
				'CZ',	// Czech republic
1494
				'DE',	// Germany
1495
				'DK',	// Danemark
1496
				'EE',	// Estonia
1497
				'ES',	// Spain
1498
				'FI',	// Finland
1499
				'FR',	// France
1500
				'GB',	// United Kingdom
1501
				'GR',	// Greece
1502
				'HR',   // Croatia
1503
				'NL',	// Holland
1504
				'HU',	// Hungary
1505
				'IE',	// Ireland
1506
				'IM',	// Isle of Man - Included in UK
1507
				'IT',	// Italy
1508
				'LT',	// Lithuania
1509
				'LU',	// Luxembourg
1510
				'LV',	// Latvia
1511
				'MC',	// Monaco - Included in France
1512
				'MT',	// Malta
1513
				//'NO',	// Norway
1514
				'PL',	// Poland
1515
				'PT',	// Portugal
1516
				'RO',	// Romania
1517
				'SE',	// Sweden
1518
				'SK',	// Slovakia
1519
				'SI',	// Slovenia
1520
				'UK',	// United Kingdom
1521
				//'CH',	// Switzerland - No. Swizerland in not in EEC
1522
		);
1523
1524
		if (in_array($country_code,$country_code_in_EEC)) return 1; // France, Spain, ...
1525
		return 0;
1526
	}
1527
1528
	/**
1529
	 *	Load miscellaneous information for tab "Info"
1530
	 *
1531
	 *	@param  int		$id		Id of object to load
1532
	 *	@return	void
1533
	 */
1534
	function info($id)
1535
	{
1536
	}
1537
1538
	/**
1539
	 * Returns the fields in order that this bank account should show to the user
1540
	 * Will return an array with the following values:
1541
	 * - BankAccountNumber
1542
	 * - BankCode
1543
	 * - BankAccountNumberKey
1544
	 * - DeskCode
1545
	 *
1546
	 * Some countries show less or more bank account properties to the user
1547
	 *
1548
	 * @param  int     $includeibanbic         1=Return also key for IBAN and BIC
1549
	 * @return array
1550
	 * @see useDetailedBBAN
1551
	 */
1552
	public function getFieldsToShow($includeibanbic=0)
1553
	{
1554
		//Get the required properties depending on the country
1555
		$detailedBBAN = $this->useDetailedBBAN();
1556
1557
		if ($detailedBBAN == 0) {
1558
			$fieldarray= array(
1559
					'BankAccountNumber'
1560
			);
1561
		} elseif ($detailedBBAN == 2) {
1562
			$fieldarray= array(
1563
					'BankCode',
1564
					'BankAccountNumber'
1565
			);
1566
		} else {
1567
			$fieldarray=self::getAccountNumberOrder();
1568
		}
1569
1570
		//if ($this->needIBAN()) {    // return always IBAN and BIC (this was old behaviour)
1571
		if ($includeibanbic)
1572
		{
1573
			$fieldarray[]='IBAN';
1574
			$fieldarray[]='BIC';
1575
		}
1576
		//}
1577
1578
		//Get the order the properties are shown
1579
		return $fieldarray;
1580
	}
1581
1582
	/**
1583
	 * Returns the components of the bank account in order.
1584
	 * Will return an array with the following values:
1585
	 * - BankAccountNumber
1586
	 * - BankCode
1587
	 * - BankAccountNumberKey
1588
	 * - DeskCode
1589
	 *
1590
	 * @return array
1591
	 */
1592
	public static function getAccountNumberOrder()
1593
	{
1594
		global $conf;
1595
1596
		$fieldlists = array(
1597
				'BankCode',
1598
				'DeskCode',
1599
				'BankAccountNumber',
1600
				'BankAccountNumberKey'
1601
		);
1602
1603
		if (!empty($conf->global->BANK_SHOW_ORDER_OPTION)) {
1604
			if (is_numeric($conf->global->BANK_SHOW_ORDER_OPTION)) {
1605
				if ($conf->global->BANK_SHOW_ORDER_OPTION == '1') {
1606
					$fieldlists = array(
1607
						'BankCode',
1608
						'DeskCode',
1609
						'BankAccountNumberKey',
1610
						'BankAccountNumber'
1611
					);
1612
				}
1613
			} else {
1614
				//Replace the old AccountNumber key with the new BankAccountNumber key
1615
				$fieldlists = explode(
1616
					' ',
1617
					preg_replace('/ ?[^Bank]AccountNumber ?/', 'BankAccountNumber',
1618
						$conf->global->BANK_SHOW_ORDER_OPTION)
1619
				);
1620
			}
1621
		}
1622
1623
		return $fieldlists;
1624
	}
1625
1626
1627
	/**
1628
	 *  Initialise an instance with random values.
1629
	 *  Used to build previews or test instances.
1630
	 *	id must be 0 if object instance is a specimen.
1631
	 *
1632
	 *  @return	void
1633
	 */
1634
	function initAsSpecimen()
1635
	{
1636
		$this->specimen        = 1;
1637
		$this->ref             = 'MBA';
1638
		$this->label           = 'My Big Company Bank account';
1639
		$this->bank            = 'MyBank';
1640
		$this->courant         = Account::TYPE_CURRENT;
1641
		$this->clos            = Account::STATUS_OPEN;
1642
		$this->code_banque     = '123';
1643
		$this->code_guichet    = '456';
1644
		$this->number          = 'ABC12345';
1645
		$this->cle_rib         = '50';
1646
		$this->bic             = 'AA12';
1647
		$this->iban            = 'FR999999999';
1648
		$this->domiciliation   = 'My bank address';
1649
		$this->proprio         = 'Owner';
1650
		$this->owner_address   = 'Owner address';
1651
		$this->country_id      = 1;
1652
	}
1653
}
1654
1655
1656
/**
1657
 *	Class to manage bank transaction lines
1658
 */
1659
class AccountLine extends CommonObject
1660
{
1661
	/**
1662
	 * @var string Error code (or message)
1663
	 */
1664
	public $error='';
1665
1666
    /**
1667
     * @var DoliDB Database handler.
1668
     */
1669
    public $db;
1670
1671
	/**
1672
	 * @var string ID to identify managed object
1673
	 */
1674
	public $element='bank';
1675
1676
	/**
1677
	 * @var string Name of table without prefix where object is stored
1678
	 */
1679
	public $table_element='bank';
1680
1681
	/**
1682
	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
1683
	 */
1684
	public $picto = 'generic';
1685
1686
	/**
1687
	 * @var int ID
1688
	 */
1689
	public $id;
1690
1691
    /**
1692
     * @var string Ref
1693
     */
1694
    public $ref;
1695
1696
	public $datec;
1697
	public $dateo;
1698
1699
	/**
1700
	 * Value date
1701
	 */
1702
	public $datev;
1703
	public $amount;
1704
1705
    /**
1706
     * @var string bank transaction lines label
1707
     */
1708
    public $label;
1709
1710
    public $note;
1711
1712
    /**
1713
     * @var int ID
1714
     */
1715
	public $fk_user_author;
1716
1717
	/**
1718
     * @var int ID
1719
     */
1720
	public $fk_user_rappro;
1721
1722
	/**
1723
     * @var int ID
1724
     */
1725
	public $fk_type;
1726
1727
	public $rappro;        // Is it conciliated
1728
	public $num_releve;    // If conciliated, what is bank statement
1729
	public $num_chq;       // Num of cheque
1730
	public $bank_chq;      // Bank of cheque
1731
1732
	/**
1733
     * @var int ID of cheque receipt
1734
     */
1735
	public $fk_bordereau;
1736
1737
	/**
1738
     * @var int ID of bank account
1739
     */
1740
	public $fk_account;
1741
1742
	public $bank_account_label;    // Label of bank account
1743
1744
    /**
1745
	 * Issuer
1746
	 * @var Societe
1747
	 */
1748
	public $emetteur;
1749
1750
	/**
1751
	 *  Constructor
1752
	 *
1753
	 *  @param	DoliDB	$db		Database handler
1754
	 */
1755
	function __construct(DoliDB $db)
1756
	{
1757
		$this->db = $db;
1758
	}
1759
1760
	/**
1761
	 *  Load into memory content of a bank transaction line
1762
	 *
1763
	 *  @param		int		$rowid   	Id of bank transaction to load
1764
	 *  @param      string	$ref     	Ref of bank transaction to load
1765
	 *  @param      string	$num     	External num to load (ex: num of transaction for paypal fee)
1766
	 *	@return		int					<0 if KO, 0 if OK but not found, >0 if OK and found
1767
	 */
1768
	function fetch($rowid,$ref='',$num='')
1769
	{
1770
		global $conf;
1771
1772
		// Check parameters
1773
		if (empty($rowid) && empty($ref) && empty($num)) return -1;
1774
1775
		$sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
1776
		$sql.= " b.fk_user_author, b.fk_user_rappro,";
1777
		$sql.= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
1778
		$sql.= " b.fk_bordereau, b.banque, b.emetteur,";
1779
		//$sql.= " b.author"; // Is this used ?
1780
		$sql.= " ba.ref as bank_account_ref, ba.label as bank_account_label";
1781
		$sql.= " FROM ".MAIN_DB_PREFIX."bank as b,";
1782
		$sql.= " ".MAIN_DB_PREFIX."bank_account as ba";
1783
		$sql.= " WHERE b.fk_account = ba.rowid";
1784
		$sql.= " AND ba.entity IN (".getEntity('bank_account').")";
1785
		if ($num) $sql.= " AND b.num_chq='".$this->db->escape($num)."'";
1786
		else if ($ref) $sql.= " AND b.rowid='".$this->db->escape($ref)."'";
1787
		else $sql.= " AND b.rowid=".$rowid;
1788
1789
		dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1790
		$result = $this->db->query($sql);
1791
		if ($result)
1792
		{
1793
			$ret=0;
1794
1795
			$obj = $this->db->fetch_object($result);
1796
			if ($obj)
1797
			{
1798
				$this->id				= $obj->rowid;
1799
				$this->rowid			= $obj->rowid;
1800
				$this->ref				= $obj->rowid;
1801
1802
				$this->datec			= $obj->datec;
1803
				$this->datev			= $obj->datev;
1804
				$this->dateo			= $obj->dateo;
1805
				$this->amount			= $obj->amount;
1806
				$this->label			= $obj->label;
1807
				$this->note				= $obj->note;
1808
1809
				$this->fk_user_author	= $obj->fk_user_author;
1810
				$this->fk_user_rappro	= $obj->fk_user_rappro;
1811
1812
				$this->fk_type			= $obj->fk_type;      // Type of transaction
1813
				$this->rappro			= $obj->rappro;
1814
				$this->num_releve		= $obj->num_releve;
1815
1816
				$this->num_chq			= $obj->num_chq;
1817
				$this->bank_chq			= $obj->banque;
1818
				$this->fk_bordereau		= $obj->fk_bordereau;
1819
1820
				$this->fk_account		= $obj->fk_account;
1821
				$this->bank_account_ref   = $obj->bank_account_ref;
1822
				$this->bank_account_label = $obj->bank_account_label;
1823
1824
				$ret=1;
1825
			}
1826
			$this->db->free($result);
1827
			return $ret;
1828
		}
1829
		else
1830
		{
1831
			return -1;
1832
		}
1833
	}
1834
1835
	/**
1836
	 * Inserts a transaction to a bank account
1837
	 *
1838
	 * @return int <0 if KO, rowid of the line if OK
1839
	 */
1840
	public function insert()
1841
	{
1842
		$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
1843
		$sql .= "datec";
1844
		$sql .= ", dateo";
1845
		$sql .= ", datev";
1846
		$sql .= ", label";
1847
		$sql .= ", amount";
1848
		$sql .= ", fk_user_author";
1849
		$sql .= ", num_chq";
1850
		$sql .= ", fk_account";
1851
		$sql .= ", fk_type";
1852
		$sql .= ", emetteur,banque";
1853
		$sql .= ", rappro";
1854
		$sql .= ", numero_compte";
1855
		$sql .= ") VALUES (";
1856
		$sql .= "'".$this->db->idate($this->datec)."'";
1857
		$sql .= ", '".$this->db->idate($this->dateo)."'";
1858
		$sql .= ", '".$this->db->idate($this->datev)."'";
1859
		$sql .= ", '".$this->db->escape($this->label)."'";
1860
		$sql .= ", ".price2num($this->amount);
1861
		$sql .= ", ".($this->fk_user_author > 0 ? $this->fk_user_author :"null");
1862
		$sql .= ", ".($this->num_chq ? "'".$this->db->escape($this->num_chq)."'" : "null");
1863
		$sql .= ", '".$this->db->escape($this->fk_account)."'";
1864
		$sql .= ", '".$this->db->escape($this->fk_type)."'";
1865
		$sql .= ", ".($this->emetteur ? "'".$this->db->escape($this->emetteur)."'" : "null");
1866
		$sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null");
1867
		$sql .= ", ".(int) $this->rappro;
1868
		$sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''");
0 ignored issues
show
Bug Best Practice introduced by
The property numero_compte does not exist on AccountLine. Did you maybe forget to declare it?
Loading history...
1869
		$sql .= ")";
1870
1871
		dol_syslog(get_class($this)."::insert", LOG_DEBUG);
1872
		$resql = $this->db->query($sql);
1873
1874
		if (!$resql) {
1875
			$this->error = $this->db->lasterror();
1876
			return -1;
1877
		}
1878
1879
		$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'bank');
1880
1881
		return $this->id;
1882
	}
1883
1884
	/**
1885
	 *      Delete transaction bank line record
1886
	 *
1887
	 *		@param	User	$user	User object that delete
1888
	 *      @return	int 			<0 if KO, >0 if OK
1889
	 */
1890
	function delete(User $user = null)
1891
	{
1892
		$nbko=0;
1893
1894
		if ($this->rappro)
1895
		{
1896
			// Protection to avoid any delete of consolidated lines
1897
			$this->error="ErrorDeleteNotPossibleLineIsConsolidated";
1898
			return -1;
1899
		}
1900
1901
		$this->db->begin();
1902
1903
		// Delete urls
1904
		$result=$this->delete_urls($user);
1905
		if ($result < 0)
1906
		{
1907
			$nbko++;
1908
		}
1909
1910
		$sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid=".(int) $this->rowid;
1911
		dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1912
		$result = $this->db->query($sql);
1913
		if (! $result) $nbko++;
1914
1915
		$sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".(int) $this->rowid;
1916
		dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1917
		$result = $this->db->query($sql);
1918
		if (! $result) $nbko++;
1919
1920
		if (! $nbko)
1921
		{
1922
			$this->db->commit();
1923
			return 1;
1924
		}
1925
		else
1926
		{
1927
			$this->db->rollback();
1928
			return -$nbko;
1929
		}
1930
	}
1931
1932
1933
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1934
	/**
1935
	 *      Delete bank line records
1936
	 *
1937
	 *		@param	User	$user	User object that delete
1938
	 *      @return	int 			<0 if KO, >0 if OK
1939
	 */
1940
	function delete_urls(User $user = null)
1941
	{
1942
        // phpcs:enable
1943
		$nbko=0;
1944
1945
		if ($this->rappro)
1946
		{
1947
			// Protection to avoid any delete of consolidated lines
1948
			$this->error="ErrorDeleteNotPossibleLineIsConsolidated";
1949
			return -1;
1950
		}
1951
1952
		$this->db->begin();
1953
1954
		$sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".(int) $this->rowid;
1955
		dol_syslog(get_class($this)."::delete_urls", LOG_DEBUG);
1956
		$result = $this->db->query($sql);
1957
		if (! $result) $nbko++;
1958
1959
		if (! $nbko)
1960
		{
1961
			$this->db->commit();
1962
			return 1;
1963
		}
1964
		else
1965
		{
1966
			$this->db->rollback();
1967
			return -$nbko;
1968
		}
1969
	}
1970
1971
1972
	/**
1973
	 *		Update bank account record in database
1974
	 *
1975
	 *		@param	User	$user			Object user making update
1976
	 *		@param 	int		$notrigger		0=Disable all triggers
1977
	 *		@return	int						<0 if KO, >0 if OK
1978
	 */
1979
	function update(User $user, $notrigger = 0)
1980
	{
1981
		$this->db->begin();
1982
1983
		$sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
1984
		$sql.= " amount = ".price2num($this->amount).",";
1985
		$sql.= " datev='".$this->db->idate($this->datev)."',";
1986
		$sql.= " dateo='".$this->db->idate($this->dateo)."'";
1987
		$sql.= " WHERE rowid = ".$this->rowid;
1988
1989
		dol_syslog(get_class($this)."::update", LOG_DEBUG);
1990
		$resql = $this->db->query($sql);
1991
		if ($resql)
1992
		{
1993
			$this->db->commit();
1994
			return 1;
1995
		}
1996
		else
1997
		{
1998
			$this->db->rollback();
1999
			$this->error=$this->db->error();
2000
			return -1;
2001
		}
2002
	}
2003
2004
2005
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2006
	/**
2007
	 *	Update conciliation field
2008
	 *
2009
	 *	@param	User	$user			Objet user making update
2010
	 *	@param 	int		$cat			Category id
2011
	 *	@param	int		$conciliated	1=Set transaction to conciliated, 0=Keep transaction non conciliated
2012
	 *	@return	int						<0 if KO, >0 if OK
2013
	 */
2014
	function update_conciliation(User $user, $cat, $conciliated=1)
2015
	{
2016
        // phpcs:enable
2017
		global $conf,$langs;
2018
2019
		$this->db->begin();
2020
2021
		// Check statement field
2022
		if (! empty($conf->global->BANK_STATEMENT_REGEX_RULE))
2023
		{
2024
			if (! preg_match('/'.$conf->global->BANK_STATEMENT_REGEX_RULE.'/', $this->num_releve))
2025
			{
2026
				$this->errors[]=$langs->trans("ErrorBankStatementNameMustFollowRegex", $conf->global->BANK_STATEMENT_REGEX_RULE);
2027
				return -1;
2028
			}
2029
		}
2030
2031
		$sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2032
		$sql.= " rappro = ".$conciliated;
2033
		$sql.= ", num_releve = '".$this->db->escape($this->num_releve)."'";
2034
		if ($conciliated) $sql.= ", fk_user_rappro = ".$user->id;
2035
		$sql.= " WHERE rowid = ".$this->id;
2036
2037
		dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2038
		$resql = $this->db->query($sql);
2039
		if ($resql)
2040
		{
2041
			if (! empty($cat))
2042
			{
2043
				$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (";
2044
				$sql.= "lineid";
2045
				$sql.= ", fk_categ";
2046
				$sql.= ") VALUES (";
2047
				$sql.= $this->id;
2048
				$sql.= ", ".$cat;
2049
				$sql.= ")";
2050
2051
				dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2052
				$this->db->query($sql);
2053
2054
				// No error check. Can fail if category already affected
2055
			}
2056
2057
			$this->rappro=1;
2058
2059
			$this->db->commit();
2060
			return 1;
2061
		}
2062
		else
2063
		{
2064
			$this->db->rollback();
2065
			return -1;
2066
		}
2067
	}
2068
2069
2070
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2071
	/**
2072
	 * 	Increase/decrease value date of a rowid
2073
	 *
2074
	 *	@param	int		$rowid		Id of line
2075
	 *	@param	int		$sign		1 or -1
2076
	 *	@return	int					>0 if OK, 0 if KO
2077
	 */
2078
	function datev_change($rowid,$sign=1)
2079
	{
2080
        // phpcs:enable
2081
		$sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".$rowid;
2082
		$resql = $this->db->query($sql);
2083
		if ($resql)
2084
		{
2085
			$obj=$this->db->fetch_object($resql);
2086
			$newdate=$this->db->jdate($obj->datev)+(3600*24*$sign);
2087
2088
			$sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2089
			$sql.= " datev = '".$this->db->idate($newdate)."'";
2090
			$sql.= " WHERE rowid = ".$rowid;
2091
2092
			$result = $this->db->query($sql);
2093
			if ($result)
2094
			{
2095
				if ($this->db->affected_rows($result))
2096
				{
2097
					return 1;
2098
				}
2099
			}
2100
			else
2101
			{
2102
				dol_print_error($this->db);
2103
				return 0;
2104
			}
2105
		}
2106
		else dol_print_error($this->db);
2107
		return 0;
2108
	}
2109
2110
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2111
	/**
2112
	 * 	Increase value date of a rowid
2113
	 *
2114
	 *	@param	int		$id		Id of line to change
2115
	 *	@return	int				>0 if OK, 0 if KO
2116
	 */
2117
	function datev_next($id)
2118
	{
2119
        // phpcs:enable
2120
		return $this->datev_change($id,1);
2121
	}
2122
2123
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2124
	/**
2125
	 * 	Decrease value date of a rowid
2126
	 *
2127
	 *	@param	int		$id		Id of line to change
2128
	 *	@return	int				>0 if OK, 0 if KO
2129
	 */
2130
	function datev_previous($id)
2131
	{
2132
        // phpcs:enable
2133
		return $this->datev_change($id,-1);
2134
	}
2135
2136
2137
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2138
	/**
2139
	 * 	Increase/decrease operation date of a rowid
2140
	 *
2141
	 *	@param	int		$rowid		Id of line
2142
	 *	@param	int		$sign		1 or -1
2143
	 *	@return	int					>0 if OK, 0 if KO
2144
	 */
2145
	function dateo_change($rowid,$sign=1)
2146
	{
2147
        // phpcs:enable
2148
		$sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".$rowid;
2149
		$resql = $this->db->query($sql);
2150
		if ($resql)
2151
		{
2152
			$obj=$this->db->fetch_object($resql);
2153
			$newdate=$this->db->jdate($obj->dateo)+(3600*24*$sign);
2154
2155
			$sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2156
			$sql.= " dateo = '".$this->db->idate($newdate)."'";
2157
			$sql.= " WHERE rowid = ".$rowid;
2158
2159
			$result = $this->db->query($sql);
2160
			if ($result)
2161
			{
2162
				if ($this->db->affected_rows($result))
2163
				{
2164
					return 1;
2165
				}
2166
			}
2167
			else
2168
			{
2169
				dol_print_error($this->db);
2170
				return 0;
2171
			}
2172
		}
2173
		else dol_print_error($this->db);
2174
		return 0;
2175
	}
2176
2177
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2178
	/**
2179
	 * 	Increase operation date of a rowid
2180
	 *
2181
	 *	@param	int		$id		Id of line to change
2182
	 *	@return	int				>0 if OK, 0 if KO
2183
	 */
2184
	function dateo_next($id)
2185
	{
2186
        // phpcs:enable
2187
		return $this->dateo_change($id,1);
2188
	}
2189
2190
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2191
	/**
2192
	 * 	Decrease operation date of a rowid
2193
	 *
2194
	 *	@param	int		$id		Id of line to change
2195
	 *	@return	int				>0 if OK, 0 if KO
2196
	 */
2197
	function dateo_previous($id)
2198
	{
2199
        // phpcs:enable
2200
		return $this->dateo_change($id,-1);
2201
	}
2202
2203
2204
	/**
2205
	 *	Load miscellaneous information for tab "Info"
2206
	 *
2207
	 *	@param  int		$id		Id of object to load
2208
	 *	@return	void
2209
	 */
2210
	function info($id)
2211
	{
2212
		$sql = 'SELECT b.rowid, b.datec, b.tms as datem,';
2213
		$sql.= ' b.fk_user_author, b.fk_user_rappro';
2214
		$sql.= ' FROM '.MAIN_DB_PREFIX.'bank as b';
2215
		$sql.= ' WHERE b.rowid = '.$id;
2216
2217
		$result=$this->db->query($sql);
2218
		if ($result)
2219
		{
2220
			if ($this->db->num_rows($result))
2221
			{
2222
				$obj = $this->db->fetch_object($result);
2223
				$this->id = $obj->rowid;
2224
2225
				if ($obj->fk_user_author)
2226
				{
2227
					$cuser = new User($this->db);
2228
					$cuser->fetch($obj->fk_user_author);
2229
					$this->user_creation     = $cuser;
2230
				}
2231
				if ($obj->fk_user_rappro)
2232
				{
2233
					$ruser = new User($this->db);
2234
					$ruser->fetch($obj->fk_user_rappro);
2235
					$this->user_rappro = $ruser;
2236
				}
2237
2238
				$this->date_creation     = $this->db->jdate($obj->datec);
2239
				$this->date_modification = $this->db->jdate($obj->datem);
2240
				//$this->date_rappro       = $obj->daterappro;    // Not yet managed
2241
			}
2242
			$this->db->free($result);
2243
		}
2244
		else
2245
		{
2246
			dol_print_error($this->db);
2247
		}
2248
	}
2249
2250
2251
	/**
2252
	 *    	Return clicable name (with picto eventually)
2253
	 *
2254
	 *		@param	int		$withpicto		0=No picto, 1=Include picto into link, 2=Only picto
2255
	 *		@param	int		$maxlen			Longueur max libelle
2256
	 *		@param	string	$option			Option ('showall')
2257
	 * 		@param	int     $notooltip		1=Disable tooltip
2258
	 *		@return	string					Chaine avec URL
2259
	 */
2260
	function getNomUrl($withpicto=0,$maxlen=0,$option='',$notooltip=0)
2261
	{
2262
		global $langs;
2263
2264
		$result='';
2265
		$label=$langs->trans("ShowTransaction").': '.$this->rowid;
2266
		$linkstart = '<a href="'.DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$this->rowid.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
2267
		$linkend='</a>';
2268
2269
		$result .= $linkstart;
2270
		if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'account'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
2271
		if ($withpicto != 2) $result.=($this->ref?$this->ref:$this->rowid);
2272
		$result .= $linkend;
2273
2274
		if ($option == 'showall' || $option == 'showconciliated') $result.=' (';
2275
		if ($option == 'showall')
2276
		{
2277
			$result.=$langs->trans("BankAccount").': ';
2278
			$accountstatic=new Account($this->db);
2279
			$accountstatic->id=$this->fk_account;
2280
			$accountstatic->ref=$this->bank_account_ref;
2281
			$accountstatic->label=$this->bank_account_label;
2282
			$result.=$accountstatic->getNomUrl(0).', ';
2283
		}
2284
		if ($option == 'showall' || $option == 'showconciliated')
2285
		{
2286
			$result.=$langs->trans("BankLineConciliated").': ';
2287
			$result.=yn($this->rappro);
2288
		}
2289
		if ($option == 'showall' || $option == 'showconciliated') $result.=')';
2290
2291
		return $result;
2292
	}
2293
2294
2295
	/**
2296
	 *    Return label of status (activity, closed)
2297
	 *
2298
	 *    @param	int		$mode       0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long
2299
	 *    @return   string        		Libelle
2300
	 */
2301
	function getLibStatut($mode=0)
2302
	{
2303
		return $this->LibStatut($this->status,$mode);
2304
	}
2305
2306
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2307
	/**
2308
	 *  Renvoi le libelle d'un statut donne
2309
	 *
2310
	 *  @param	int		$statut         Id statut
2311
	 *  @param	int		$mode           0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
2312
	 *  @return	string          		Libelle du statut
2313
	 */
2314
	function LibStatut($statut,$mode=0)
2315
	{
2316
        // phpcs:enable
2317
		global $langs;
2318
		//$langs->load('companies');
2319
		/*
2320
        if ($mode == 0)
2321
        {
2322
            if ($statut==0) return $langs->trans("ActivityCeased");
2323
            if ($statut==1) return $langs->trans("InActivity");
2324
        }
2325
        if ($mode == 1)
2326
        {
2327
            if ($statut==0) return $langs->trans("ActivityCeased");
2328
            if ($statut==1) return $langs->trans("InActivity");
2329
        }
2330
        if ($mode == 2)
2331
        {
2332
            if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
2333
            if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
2334
        }
2335
        if ($mode == 3)
2336
        {
2337
            if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2338
            if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2339
        }
2340
        if ($mode == 4)
2341
        {
2342
            if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
2343
            if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
2344
        }
2345
        if ($mode == 5)
2346
        {
2347
            if ($statut==0) return $langs->trans("ActivityCeased").' '.img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2348
            if ($statut==1) return $langs->trans("InActivity").' '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2349
        }*/
2350
	}
2351
2352
2353
	/**
2354
	 *	Return if a bank line was dispatched into bookkeeping
2355
	 *
2356
	 *	@return     int         <0 if KO, 0=no, 1=yes
2357
	 */
2358
	public function getVentilExportCompta()
2359
	{
2360
		$alreadydispatched = 0;
2361
2362
		$type = 'bank';
2363
2364
		$sql = " SELECT COUNT(ab.rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='".$type."' AND ab.fk_doc = ".$this->id;
2365
		$resql = $this->db->query($sql);
2366
		if ($resql)
2367
		{
2368
			$obj = $this->db->fetch_object($resql);
2369
			if ($obj)
2370
			{
2371
				$alreadydispatched = $obj->nb;
2372
			}
2373
		}
2374
		else
2375
		{
2376
			$this->error = $this->db->lasterror();
2377
			return -1;
2378
		}
2379
2380
		if ($alreadydispatched)
2381
		{
2382
			return 1;
2383
		}
2384
		return 0;
2385
	}
2386
}
2387