Completed
Branch develop (96aaeb)
by
unknown
31:19
created

Account::addline()   D

Complexity

Conditions 14
Paths 142

Size

Total Lines 100
Code Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 62
nc 142
nop 10
dl 0
loc 100
rs 4.6283
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
/* Copyright (C) 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
	public $element = 'bank_account';
40
	public $table_element = 'bank_account';
41
	public $picto = 'account';
42
43
	/**
44
	 * @var	int		Use id instead of rowid
45
	 * @deprecated
46
	 * @see id
47
	 */
48
	public $rowid;
49
50
	/**
51
	 * Label
52
	 * @var string
53
	 */
54
	public $label;
55
56
	/**
57
	 * Bank account type. Check TYPE_ constants
58
	 * @var int
59
	 */
60
	public $courant;
61
62
	/**
63
	 * Bank account type. Check TYPE_ constants
64
	 * @var int
65
	 */
66
	public $type;
67
68
	/**
69
	 * Bank name
70
	 * @var string
71
	 */
72
	public $bank;
73
74
	/**
75
	 * Status
76
	 * @var int
77
	 */
78
	public $clos = self::STATUS_OPEN;
79
80
	/**
81
	 * Does it need to be conciliated?
82
	 * @var int
83
	 */
84
	public $rappro=1;
85
86
	/**
87
	 * Webpage
88
	 * @var string
89
	 */
90
	public $url;
91
92
	/**
93
	 * Bank number. If in SEPA area, you should move to IBAN field
94
	 * @var string
95
	 */
96
	public $code_banque;
97
98
	/**
99
	 * Branch number. If in SEPA area, you should move to IBAN field
100
	 * @var string
101
	 */
102
	public $code_guichet;
103
104
	/**
105
	 * Account number. If in SEPA area, you should move to IBAN field
106
	 * @var string
107
	 */
108
	public $number;
109
110
	/**
111
	 * Bank account number control digit. If in SEPA area, you should move to IBAN field
112
	 * @var string
113
	 */
114
	public $cle_rib;
115
116
	/**
117
	 * BIC/Swift code
118
	 * @var string
119
	 */
120
	public $bic;
121
122
	/**
123
	 * IBAN number (International Bank Account Number). Stored into iban_prefix field into database
124
	 * @var
125
	 */
126
	public $iban;
127
128
	/**
129
	 * Name of account holder
130
	 * @var string
131
	 */
132
	public $proprio;
133
134
	/**
135
	 * Address of account holder
136
	 * @var string
137
	 */
138
	public $owner_address;
139
140
	public $state_id;
141
	public $state_code;
142
	public $state;
143
144
	/**
145
	 * Variable containing all account types with their respective translated label.
146
	 * Defined in __construct
147
	 * @var array
148
	 */
149
	public $type_lib = array();
150
151
	/**
152
	 * Variable containing all account statuses with their respective translated label.
153
	 * Defined in __construct
154
	 * @var array
155
	 */
156
	public $status = array();
157
158
	/**
159
	 * Accountancy code
160
	 * @var string
161
	 */
162
	public $account_number;
163
	public $fk_accountancy_journal;
164
165
	/**
166
	 * Currency code
167
	 * @var string
168
	 */
169
	public $currency_code;
170
171
	/**
172
	 * Currency code
173
	 * @var string
174
	 * @deprecated Use currency_code instead
175
	 */
176
	public $account_currency_code;
177
178
	/**
179
	 * Authorized minimum balance
180
	 * @var float
181
	 */
182
	public $min_allowed;
183
184
	/**
185
	 * Desired minimum balance
186
	 * @var float
187
	 */
188
	public $min_desired;
189
190
	/**
191
	 * Notes
192
	 * @var string
193
	 */
194
	public $comment;
195
196
	/**
197
	 * Date of the initial balance. Used in Account::create
198
	 * @var int
199
	 */
200
	public $date_solde;
201
202
	/**
203
	 * Current account
204
	 */
205
	const TYPE_CURRENT = 1;
206
	/**
207
	 * Cash account
208
	 */
209
	const TYPE_CASH = 2;
210
	/**
211
	 * Savings account
212
	 */
213
	const TYPE_SAVINGS = 0;
214
215
	const STATUS_OPEN = 0;
216
	const STATUS_CLOSED = 1;
217
218
	/**
219
	 *  Constructor
220
	 *
221
	 *  @param	DoliDB		$db		Database handler
222
	 */
223
	function __construct(DoliDB $db)
224
	{
225
		global $langs;
226
227
		$this->db = $db;
228
229
		$this->solde = 0;
230
231
		$this->type_lib = array(
232
			self::TYPE_SAVINGS => $langs->trans("BankType0"),
233
			self::TYPE_CURRENT => $langs->trans("BankType1"),
234
			self::TYPE_CASH => $langs->trans("BankType2"),
235
		);
236
237
		$this->status = array(
238
			self::STATUS_OPEN => $langs->trans("StatusAccountOpened"),
239
			self::STATUS_CLOSED => $langs->trans("StatusAccountClosed")
240
		);
241
	}
242
243
	/**
244
	 * Shows the account number in the appropiate format
245
	 *
246
	 * @return string
247
	 */
248
	public function __toString()
249
	{
250
		$string = '';
251
252
		foreach ($this->getFieldsToShow() as $val) {
253
254
			if ($val == 'BankCode') {
255
				$string .= $this->code_banque.' ';
256
			} elseif ($val == 'BankAccountNumber') {
257
				$string .= $this->number.' ';
258
			} elseif ($val == 'DeskCode') {
259
				$string .= $this->code_guichet.' ';
260
			} elseif ($val == 'BankAccountNumberKey') {
261
				$string .= $this->cle_rib.' ';
262
			}elseif ($val == 'BIC') {
263
				$string .= $this->bic.' ';
264
			}elseif ($val == 'IBAN') {
265
				$string .= $this->iban.' ';
266
			}
267
		}
268
269
		return trim($string);
270
	}
271
272
273
	/**
274
	 *  Return if a bank account need to be conciliated
275
	 *
276
	 *  @return     int         1 if need to be concialiated, < 0 otherwise.
277
	 */
278
	function canBeConciliated()
279
	{
280
		global $conf;
281
282
		if (empty($this->rappro)) return -1;
283
		if ($this->courant == Account::TYPE_CASH && empty($conf->global->BANK_CAN_RECONCILIATE_CASHACCOUNT)) return -2;
284
		if ($this->clos) return -3;
285
		return 1;
286
	}
287
288
289
	/**
290
	 *      Add a link between bank line record and its source
291
	 *
292
	 *      @param	int		$line_id    Id ecriture bancaire
293
	 *      @param  int		$url_id     Id parametre url
294
	 *      @param  string	$url        Url
295
	 *      @param  string	$label      Link label
296
	 *      @param  string	$type       Type of link ('payment', 'company', 'member', ...)
297
	 *      @return int         		<0 if KO, id line if OK
298
	 */
299
	function add_url_line($line_id, $url_id, $url, $label, $type)
300
	{
301
		$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
302
		$sql.= "fk_bank";
303
		$sql.= ", url_id";
304
		$sql.= ", url";
305
		$sql.= ", label";
306
		$sql.= ", type";
307
		$sql.= ") VALUES (";
308
		$sql.= "'".$line_id."'";
309
		$sql.= ", '".$url_id."'";
310
		$sql.= ", '".$url."'";
311
		$sql.= ", '".$this->db->escape($label)."'";
312
		$sql.= ", '".$type."'";
313
		$sql.= ")";
314
315
		dol_syslog(get_class($this)."::add_url_line", LOG_DEBUG);
316
		if ($this->db->query($sql))
317
		{
318
			$rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
319
			return $rowid;
320
		}
321
		else
322
		{
323
			$this->error=$this->db->lasterror();
324
			return -1;
325
		}
326
	}
327
328
	/**
329
	 * 		TODO Move this into AccountLine
330
	 *      Return array with links from llx_bank_url
331
	 *
332
	 *      @param  int         $fk_bank    To search using bank transaction id
333
	 *      @param  int         $url_id     To search using link to
334
	 *      @param  string      $type       To search using type
335
	 *      @return array|-1                Array of links or -1 on error
336
	 */
337
	function get_url($fk_bank='', $url_id='', $type='')
338
	{
339
		$lines = array();
340
341
		// Check parameters
342
		if (! empty($fk_bank) && (! empty($url_id) || ! empty($type)))
343
		{
344
			$this->error="ErrorBadParameter";
345
			return -1;
346
		}
347
348
		$sql = "SELECT fk_bank, url_id, url, label, type";
349
		$sql.= " FROM ".MAIN_DB_PREFIX."bank_url";
350
		if ($fk_bank > 0) {
351
			$sql.= " WHERE fk_bank = ".$fk_bank;
352
		}
353
		else { $sql.= " WHERE url_id = ".$url_id." AND type = '".$type."'";
354
		}
355
		$sql.= " ORDER BY type, label";
356
357
		dol_syslog(get_class($this)."::get_url", LOG_DEBUG);
358
		$result = $this->db->query($sql);
359
		if ($result)
360
		{
361
			$i = 0;
362
			$num = $this->db->num_rows($result);
363
			while ($i < $num)
364
			{
365
				$obj = $this->db->fetch_object($result);
366
				// Anciens liens (pour compatibilite)
367
				$lines[$i][0] = $obj->url;
368
				$lines[$i][1] = $obj->url_id;
369
				$lines[$i][2] = $obj->label;
370
				$lines[$i][3] = $obj->type;
371
				// Nouveaux liens
372
				$lines[$i]['url'] = $obj->url;
373
				$lines[$i]['url_id'] = $obj->url_id;
374
				$lines[$i]['label'] = $obj->label;
375
				$lines[$i]['type'] = $obj->type;
376
				$lines[$i]['fk_bank'] = $obj->fk_bank;
377
				$i++;
378
			}
379
		}
380
		else dol_print_error($this->db);
381
382
		return $lines;
383
	}
384
385
	/**
386
	 *  Add an entry into table ".MAIN_DB_PREFIX."bank
387
	 *
388
	 *  @param	int	        $date			Date operation
389
	 *  @param	string		$oper			1,2,3,4... (deprecated) or 'TYP','VIR','PRE','LIQ','VAD','CB','CHQ'...
390
	 *  @param	string		$label			Descripton
391
	 *  @param	float		$amount			Amount
392
	 *  @param	string		$num_chq		Numero cheque ou virement
393
	 *  @param	int  		$categorie		Category id (optionnal)
394
	 *  @param	User		$user			User that create
395
	 *  @param	string		$emetteur		Name of cheque writer
396
	 *  @param	string		$banque			Bank of cheque writer
397
	 *  @param	string		$accountancycode	When we record a free bank entry, we must provide accounting account if accountancy module is on.
398
	 *  @return	int							Rowid of added entry, <0 if KO
399
	 */
400
	function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur='',$banque='', $accountancycode='')
401
	{
402
		// Deprecatîon warning
403
		if (is_numeric($oper)) {
404
			dol_syslog(__METHOD__ . ": using numeric operations is deprecated", LOG_WARNING);
405
		}
406
407
		// Clean parameters
408
		$emetteur=trim($emetteur);
409
		$banque=trim($banque);
410
411
		$now=dol_now();
412
413
		if (is_numeric($oper))    // Clean oper to have a code instead of a rowid
414
		{
415
			$sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
416
			$sql.= " WHERE id=".$oper;
417
			$sql.= " AND entity IN (".getEntity('c_paiement').")";
418
			$resql=$this->db->query($sql);
419
			if ($resql)
420
			{
421
				$obj=$this->db->fetch_object($resql);
422
				$oper=$obj->code;
423
			}
424
			else
425
			{
426
				dol_print_error($this->db,'Failed to get payment type code');
427
				return -1;
428
			}
429
		}
430
431
		// Check parameters
432
		if (! $oper)
433
		{
434
			$this->error="oper not defined";
435
			return -1;
436
		}
437
		if (! $this->rowid)
438
		{
439
			$this->error="this->rowid not defined";
440
			return -2;
441
		}
442
		if ($this->courant == Account::TYPE_CASH && $oper != 'LIQ')
443
		{
444
			$this->error="ErrorCashAccountAcceptsOnlyCashMoney";
445
			return -3;
446
		}
447
448
		$this->db->begin();
449
450
		$datev = $date;
451
452
		$accline = new AccountLine($this->db);
453
		$accline->datec = $now;
454
		$accline->dateo = $date;
455
		$accline->datev = $datev;
456
		$accline->label = $label;
457
		$accline->amount = $amount;
458
		$accline->fk_user_author = $user->id;
459
		$accline->fk_account = $this->rowid;
460
		$accline->fk_type = $oper;
461
		$accline->numero_compte = $accountancycode;
462
463
		if ($num_chq) {
464
			$accline->num_chq = $num_chq;
465
		}
466
467
		if ($emetteur) {
468
			$accline->emetteur = $emetteur;
469
		}
470
471
		if ($banque) {
472
			$accline->bank_chq = $banque;
473
		}
474
475
		if ($accline->insert() > 0) {
476
477
			if ($categorie>0) {
478
				$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (";
479
				$sql .= "lineid, fk_categ";
480
				$sql .= ") VALUES (";
481
				$sql .= $accline->id.", ".$categorie;
482
				$sql .= ")";
483
484
				$result = $this->db->query($sql);
485
				if (!$result) {
486
					$this->error = $this->db->lasterror();
487
					$this->db->rollback();
488
					return -3;
489
				}
490
			}
491
492
			$this->db->commit();
493
			return $accline->id;
494
		} else {
495
			$this->error = $this->db->lasterror();
496
			$this->db->rollback();
497
			return -2;
498
		}
499
	}
500
501
	/**
502
	 *  Create bank account into database
503
	 *
504
	 *  @param	User	$user		Object user making creation
505
	 *  @param  int     $notrigger  1=Disable triggers
506
	 *  @return int        			< 0 if KO, > 0 if OK
507
	 */
508
	function create(User $user = null, $notrigger=0)
509
	{
510
		global $langs,$conf, $hookmanager;
511
512
		$error=0;
513
514
		// Clean parameters
515
		if (! $this->min_allowed) $this->min_allowed=0;
516
		if (! $this->min_desired) $this->min_desired=0;
517
		$this->state_id = ($this->state_id?$this->state_id:$this->state_id);
518
		$this->country_id = ($this->country_id?$this->country_id:$this->country_id);
519
520
		// Check parameters
521
		if (empty($this->country_id))
522
		{
523
			$this->error=$langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Country"));
524
			dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
525
			return -1;
526
		}
527
		if (empty($this->ref))
528
		{
529
			$this->error=$langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref"));
530
			dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
531
			return -1;
532
		}
533
		if (empty($this->date_solde))
534
		{
535
			$this->error=$langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("DateInitialBalance"));
536
			dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
537
			return -1;
538
		}
539
540
		// Chargement librairie pour acces fonction controle RIB
541
		require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
542
543
		$now=dol_now();
544
545
		$this->db->begin();
546
547
		$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
548
		$sql.= "datec";
549
		$sql.= ", ref";
550
		$sql.= ", label";
551
		$sql.= ", entity";
552
		$sql.= ", account_number";
553
		$sql.= ", fk_accountancy_journal";
554
		$sql.= ", bank";
555
		$sql.= ", code_banque";
556
		$sql.= ", code_guichet";
557
		$sql.= ", number";
558
		$sql.= ", cle_rib";
559
		$sql.= ", bic";
560
		$sql.= ", iban_prefix";
561
		$sql.= ", domiciliation";
562
		$sql.= ", proprio";
563
		$sql.= ", owner_address";
564
		$sql.= ", currency_code";
565
		$sql.= ", rappro";
566
		$sql.= ", min_allowed";
567
		$sql.= ", min_desired";
568
		$sql.= ", comment";
569
		$sql.= ", state_id";
570
		$sql.= ", fk_pays";
571
		$sql.= ") VALUES (";
572
		$sql.= "'".$this->db->idate($now)."'";
573
		$sql.= ", '".$this->db->escape($this->ref)."'";
574
		$sql.= ", '".$this->db->escape($this->label)."'";
575
		$sql.= ", ".$conf->entity;
576
		$sql.= ", '".$this->db->escape($this->account_number)."'";
577
		$sql.= ", ".($this->fk_accountancy_journal > 0 ? $this->db->escape($this->fk_accountancy_journal) : "null");
578
		$sql.= ", '".$this->db->escape($this->bank)."'";
579
		$sql.= ", '".$this->db->escape($this->code_banque)."'";
580
		$sql.= ", '".$this->db->escape($this->code_guichet)."'";
581
		$sql.= ", '".$this->db->escape($this->number)."'";
582
		$sql.= ", '".$this->db->escape($this->cle_rib)."'";
583
		$sql.= ", '".$this->db->escape($this->bic)."'";
584
		$sql.= ", '".$this->db->escape($this->iban)."'";
585
		$sql.= ", '".$this->db->escape($this->domiciliation)."'";
586
		$sql.= ", '".$this->db->escape($this->proprio)."'";
587
		$sql.= ", '".$this->db->escape($this->owner_address)."'";
588
		$sql.= ", '".$this->db->escape($this->currency_code)."'";
589
		$sql.= ", ".$this->rappro;
590
		$sql.= ", ".price2num($this->min_allowed);
591
		$sql.= ", ".price2num($this->min_desired);
592
		$sql.= ", '".$this->db->escape($this->comment)."'";
593
		$sql.= ", ".($this->state_id>0?$this->state_id:"null");
594
		$sql.= ", ".$this->country_id;
595
		$sql.= ")";
596
597
		dol_syslog(get_class($this)."::create", LOG_DEBUG);
598
		$resql=$this->db->query($sql);
599
		if ($resql)
600
		{
601
			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
602
603
			$result=$this->update($user, 1);
0 ignored issues
show
Bug introduced by
It seems like $user defined by parameter $user on line 508 can be null; however, Account::update() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

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