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

Account::getAccountNumberOrder()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 21
nc 4
nop 0
dl 0
loc 33
rs 8.5806
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
	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