Passed
Push — master ( 0f9140...c4489d )
by Alxarafe
22:27
created

htdocs/accountancy/class/bookkeeping.class.php (1 issue)

1
<?php
2
/* Copyright (C) 2014-2017  Olivier Geffroy     <[email protected]>
3
 * Copyright (C) 2015-2017  Alexandre Spangaro  <[email protected]>
4
 * Copyright (C) 2015-2017  Florian Henry       <[email protected]>
5
 * Copyright (C) 2018       Frédéric France     <[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
/**
22
 * \file        htdocs/accountancy/class/bookkeeping.class.php
23
 * \ingroup     Advanced accountancy
24
 * \brief       File of class to manage Ledger (General Ledger and Subledger)
25
 */
26
27
// Class
28
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
29
30
/**
31
 * Class to manage Ledger (General Ledger and Subledger)
32
 */
33
class BookKeeping extends CommonObject
34
{
35
	/**
36
	 * @var string Error code (or message)
37
	 */
38
	public $error;
39
40
	/**
41
	 * @var string[] Error codes (or messages)
42
	 */
43
	public $errors = array();
44
45
	/**
46
	 * @var string Id to identify managed objects
47
	 */
48
	public $element = 'accountingbookkeeping';
49
50
	/**
51
	 * @var string Name of table without prefix where object is stored
52
	 */
53
	public $table_element = 'accounting_bookkeeping';
54
55
	/**
56
	 * @var int Entity
57
	 */
58
	public $entity;
59
60
	/**
61
	 * @var BookKeepingLine[] Lines
62
	 */
63
	public $lines = array ();
64
65
	/**
66
	 * @var int ID
67
	 */
68
	public $id;
69
70
	public $doc_date;
71
	public $date_lim_reglement;
72
73
    /**
74
     * @var string doc_type
75
     */
76
    public $doc_type;
77
78
    /**
79
     * @var string doc_ref
80
     */
81
	public $doc_ref;
82
83
	/**
84
     * @var int ID
85
     */
86
	public $fk_doc;
87
88
	/**
89
     * @var int ID
90
     */
91
	public $fk_docdet;
92
93
    /**
94
     * @var string thirdparty code
95
     */
96
    public $thirdparty_code;
97
98
    /**
99
     * @var string subledger account
100
     */
101
	public $subledger_account;
102
103
    /**
104
     * @var string subledger label
105
     */
106
	public $subledger_label;
107
108
    /**
109
     * @var string  doc_type
110
     */
111
	public $numero_compte;
112
113
    /**
114
     * @var string label compte
115
     */
116
    public $label_compte;
117
118
    /**
119
     * @var string label operation
120
     */
121
    public $label_operation;
122
	public $debit;
123
	public $credit;
124
	public $montant;
125
	public $sens;
126
127
	/**
128
     * @var int ID
129
     */
130
	public $fk_user_author;
131
132
	public $import_key;
133
	public $code_journal;
134
	public $journal_label;
135
	public $piece_num;
136
137
	/**
138
	 * Constructor
139
	 *
140
	 * @param DoliDb $db Database handler
141
	 */
142
    public function __construct(DoliDB $db)
143
    {
144
		$this->db = $db;
145
	}
146
147
	/**
148
	 * Create object into database
149
	 *
150
	 * @param  User	$user		User that creates
151
	 * @param  bool	$notrigger	false=launch triggers after, true=disable triggers
152
	 * @return int				<0 if KO, Id of created object if OK
153
	 */
154
    public function create(User $user, $notrigger = false)
155
    {
156
		global $conf, $langs;
157
158
		dol_syslog(__METHOD__, LOG_DEBUG);
159
160
		$error = 0;
161
162
		// Clean parameters
163
		if (isset($this->doc_type)) {
164
			$this->doc_type = trim($this->doc_type);
165
		}
166
		if (isset($this->doc_ref)) {
167
			$this->doc_ref = trim($this->doc_ref);
168
		}
169
		if (isset($this->fk_doc)) {
170
			$this->fk_doc = trim($this->fk_doc);
171
		}
172
		if (isset($this->fk_docdet)) {
173
			$this->fk_docdet = trim($this->fk_docdet);
174
		}
175
		if (isset($this->thirdparty_code)) {
176
			$this->thirdparty_code = trim($this->thirdparty_code);
177
		}
178
		if (isset($this->subledger_account)) {
179
			$this->subledger_account = trim($this->subledger_account);
180
		}
181
		if (isset($this->subledger_label)) {
182
			$this->subledger_label = trim($this->subledger_label);
183
		}
184
		if (isset($this->numero_compte)) {
185
			$this->numero_compte = trim($this->numero_compte);
186
		}
187
		if (isset($this->label_compte)) {
188
			$this->label_compte = trim($this->label_compte);
189
		}
190
		if (isset($this->label_operation)) {
191
			$this->label_operation = trim($this->label_operation);
192
		}
193
		if (isset($this->debit)) {
194
			$this->debit = trim($this->debit);
195
		}
196
		if (isset($this->credit)) {
197
			$this->credit = trim($this->credit);
198
		}
199
		if (isset($this->montant)) {
200
			$this->montant = trim($this->montant);
201
		}
202
		if (isset($this->sens)) {
203
			$this->sens = trim($this->sens);
204
		}
205
		if (isset($this->fk_user_author)) {
206
			$this->fk_user_author = trim($this->fk_user_author);
207
		}
208
		if (isset($this->import_key)) {
209
			$this->import_key = trim($this->import_key);
210
		}
211
		if (isset($this->code_journal)) {
212
			$this->code_journal = trim($this->code_journal);
213
		}
214
		if (isset($this->journal_label)) {
215
			$this->journal_label = trim($this->journal_label);
216
		}
217
		if (isset($this->piece_num)) {
218
			$this->piece_num = trim($this->piece_num);
219
		}
220
		if (empty($this->debit)) $this->debit = 0;
221
		if (empty($this->credit)) $this->credit = 0;
222
223
		// Check parameters
224
		if (empty($this->numero_compte) || $this->numero_compte == '-1' || $this->numero_compte == 'NotDefined')
225
		{
226
			$langs->loadLangs(array("errors"));
227
			if (in_array($this->doc_type, array('bank', 'expense_report')))
228
			{
229
				$this->errors[]=$langs->trans('ErrorFieldAccountNotDefinedForBankLine', $this->fk_docdet,  $this->doc_type);
230
			}
231
			else
232
			{
233
				//$this->errors[]=$langs->trans('ErrorFieldAccountNotDefinedForInvoiceLine', $this->doc_ref,  $this->label_compte);
234
				$mesg=$this->doc_ref.', '.$langs->trans("AccountAccounting").': '.$this->numero_compte;
235
				if ($this->subledger_account && $this->subledger_account != $this->numero_compte)
236
				{
237
					$mesg.=', '.$langs->trans("SubledgerAccount").': '.$this->subledger_account;
238
				}
239
				$this->errors[]=$langs->trans('ErrorFieldAccountNotDefinedForLine', $mesg);
240
			}
241
242
			return -1;
243
		}
244
245
		$this->db->begin();
246
247
		$this->piece_num = 0;
248
249
		// First check if line not yet already in bookkeeping.
250
		// Note that we must include doc_type - fk_doc - numero_compte - label to be sure to have unicity of line (we may have several lines
251
		// with same doc_type, fk_odc, numero_compte for 1 invoice line when using localtaxes with same account)
252
		// WARNING: This is not reliable, label may have been modified. This is just a small protection.
253
		// The page to make journalization make the test on couple doc_type - fk_doc only.
254
		$sql = "SELECT count(*) as nb";
255
		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
256
		$sql .= " WHERE doc_type = '" . $this->db->escape($this->doc_type) . "'";
257
		$sql .= " AND fk_doc = " . $this->fk_doc;
258
		//$sql .= " AND fk_docdet = " . $this->fk_docdet;					// This field can be 0 if record is for several lines
259
		$sql .= " AND numero_compte = '" . $this->db->escape($this->numero_compte) . "'";
260
		$sql .= " AND label_operation = '" . $this->db->escape($this->label_operation) . "'";
261
		$sql .= " AND entity IN (" . getEntity('accountancy') . ")";
262
263
		$resql = $this->db->query($sql);
264
265
		if ($resql) {
266
			$row = $this->db->fetch_object($resql);
267
			if ($row->nb == 0)
268
			{
269
				// Determine piece_num
270
				$sqlnum = "SELECT piece_num";
271
				$sqlnum .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
272
				$sqlnum .= " WHERE doc_type = '" . $this->db->escape($this->doc_type) . "'";		// For example doc_type = 'bank'
273
				$sqlnum .= " AND fk_docdet = " . $this->db->escape($this->fk_docdet);				// fk_docdet is rowid into llx_bank or llx_facturedet or llx_facturefourndet, or ...
274
				$sqlnum .= " AND doc_ref = '" . $this->db->escape($this->doc_ref) . "'";			// ref of source object
275
				$sqlnum .= " AND entity IN (" . getEntity('accountancy') . ")";
276
277
				dol_syslog(get_class($this) . ":: create sqlnum=" . $sqlnum, LOG_DEBUG);
278
				$resqlnum = $this->db->query($sqlnum);
279
				if ($resqlnum) {
280
					$objnum = $this->db->fetch_object($resqlnum);
281
					$this->piece_num = $objnum->piece_num;
282
				}
283
				dol_syslog(get_class($this) . ":: create this->piece_num=" . $this->piece_num, LOG_DEBUG);
284
				if (empty($this->piece_num)) {
285
					$sqlnum = "SELECT MAX(piece_num)+1 as maxpiecenum";
286
					$sqlnum .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
287
					$sqlnum .= " WHERE entity IN (" . getEntity('accountancy') . ")";
288
289
					dol_syslog(get_class($this) . ":: create sqlnum=" . $sqlnum, LOG_DEBUG);
290
					$resqlnum = $this->db->query($sqlnum);
291
					if ($resqlnum) {
292
						$objnum = $this->db->fetch_object($resqlnum);
293
						$this->piece_num = $objnum->maxpiecenum;
294
					}
295
				}
296
				dol_syslog(get_class($this) . ":: create this->piece_num=" . $this->piece_num, LOG_DEBUG);
297
				if (empty($this->piece_num)) {
298
					$this->piece_num = 1;
299
				}
300
301
				$now = dol_now();
302
303
				$sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " (";
304
				$sql .= "doc_date";
305
				$sql .= ", date_lim_reglement";
306
				$sql .= ", doc_type";
307
				$sql .= ", doc_ref";
308
				$sql .= ", fk_doc";
309
				$sql .= ", fk_docdet";
310
				$sql .= ", thirdparty_code";
311
				$sql .= ", subledger_account";
312
				$sql .= ", subledger_label";
313
				$sql .= ", numero_compte";
314
				$sql .= ", label_compte";
315
				$sql .= ", label_operation";
316
				$sql .= ", debit";
317
				$sql .= ", credit";
318
				$sql .= ", montant";
319
				$sql .= ", sens";
320
				$sql .= ", fk_user_author";
321
				$sql .= ", date_creation";
322
				$sql .= ", code_journal";
323
				$sql .= ", journal_label";
324
				$sql .= ", piece_num";
325
				$sql .= ', entity';
326
				$sql .= ") VALUES (";
327
				$sql .= "'" . $this->db->idate($this->doc_date) . "'";
328
				$sql .= ", ".(! isset($this->date_lim_reglement) || dol_strlen($this->date_lim_reglement) == 0 ? 'NULL' : "'" . $this->db->idate($this->date_lim_reglement) . "'");
329
				$sql .= ",'" . $this->db->escape($this->doc_type) . "'";
330
				$sql .= ",'" . $this->db->escape($this->doc_ref) . "'";
331
				$sql .= "," . $this->fk_doc;
332
				$sql .= "," . $this->fk_docdet;
333
				$sql .= ",'" . $this->db->escape($this->thirdparty_code) . "'";
334
				$sql .= ",'" . $this->db->escape($this->subledger_account) . "'";
335
				$sql .= ",'" . $this->db->escape($this->subledger_label) . "'";
336
				$sql .= ",'" . $this->db->escape($this->numero_compte) . "'";
337
				$sql .= ",'" . $this->db->escape($this->label_compte) . "'";
338
				$sql .= ",'" . $this->db->escape($this->label_operation) . "'";
339
				$sql .= "," . $this->debit;
340
				$sql .= "," . $this->credit;
341
				$sql .= "," . $this->montant;
342
				$sql .= ",'" . $this->db->escape($this->sens) . "'";
343
				$sql .= ",'" . $this->db->escape($this->fk_user_author) . "'";
344
				$sql .= ",'" . $this->db->idate($now). "'";
345
				$sql .= ",'" . $this->db->escape($this->code_journal) . "'";
346
				$sql .= ",'" . $this->db->escape($this->journal_label) . "'";
347
				$sql .= "," . $this->db->escape($this->piece_num);
348
				$sql .= ", " . (! isset($this->entity) ? $conf->entity : $this->entity);
349
				$sql .= ")";
350
351
				dol_syslog(get_class($this) . ":: create sql=" . $sql, LOG_DEBUG);
352
				$resql = $this->db->query($sql);
353
				if ($resql) {
354
					$id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
355
356
					if ($id > 0) {
357
						$this->id = $id;
358
						$result = 0;
359
					} else {
360
						$result = -2;
361
						$error ++;
362
						$this->errors[] = 'Error Create Error ' . $result . ' lecture ID';
363
						dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
364
					}
365
				} else {
366
					$result = -1;
367
					$error ++;
368
					$this->errors[] = 'Error ' . $this->db->lasterror();
369
					dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
370
				}
371
			} else {	// Already exists
372
				$result = -3;
373
				$error++;
374
				$this->error='BookkeepingRecordAlreadyExists';
375
				dol_syslog(__METHOD__ . ' ' . $this->error, LOG_WARNING);
376
			}
377
		} else {
378
			$result = -5;
379
			$error ++;
380
			$this->errors[] = 'Error ' . $this->db->lasterror();
381
			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
382
		}
383
384
		// Uncomment this and change MYOBJECT to your own tag if you
385
		// want this action to call a trigger.
386
		//if (! $error && ! $notrigger) {
387
388
		// // Call triggers
389
		// $result=$this->call_trigger('MYOBJECT_CREATE',$user);
390
		// if ($result < 0) $error++;
391
		// // End call triggers
392
		//}
393
394
		// Commit or rollback
395
		if ($error) {
396
			$this->db->rollback();
397
			return -1 * $error;
398
		} else {
399
			$this->db->commit();
400
			return $result;
401
		}
402
	}
403
404
	/**
405
	 *  Return a link to the object card (with optionaly the picto)
406
	 *
407
	 *	@param	int		$withpicto					Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
408
	 *	@param	string	$option						On what the link point to ('nolink', ...)
409
	 *  @param	int  	$notooltip					1=Disable tooltip
410
	 *  @param  string  $morecss            		Add more css on link
411
	 *  @param  int     $save_lastsearch_value    	-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
412
	 *	@return	string								String with URL
413
	 */
414
	function getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
415
	{
416
		global $db, $conf, $langs;
417
		global $dolibarr_main_authentication, $dolibarr_main_demo;
418
		global $menumanager;
419
420
		if (! empty($conf->dol_no_mouse_hover)) $notooltip=1;   // Force disable tooltips
421
422
		$result = '';
423
		$companylink = '';
424
425
		$label = '<u>' . $langs->trans("Transaction") . '</u>';
426
		$label.= '<br>';
427
		$label.= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->piece_num;
428
429
		$url = DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?piece_num='.$this->piece_num;
430
431
		if ($option != 'nolink')
432
		{
433
			// Add param to save lastsearch_values or not
434
			$add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
435
			if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
436
			if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
437
		}
438
439
		$linkclose='';
440
		if (empty($notooltip))
441
		{
442
			if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
443
			{
444
				$label=$langs->trans("ShowTransaction");
445
				$linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
446
			}
447
			$linkclose.=' title="'.dol_escape_htmltag($label, 1).'"';
448
			$linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
449
		}
450
		else $linkclose = ($morecss?' class="'.$morecss.'"':'');
451
452
		$linkstart = '<a href="'.$url.'"';
453
		$linkstart.=$linkclose.'>';
454
		$linkend='</a>';
455
456
		$result .= $linkstart;
457
		if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
0 ignored issues
show
Bug Best Practice introduced by
The property picto does not exist on BookKeeping. Did you maybe forget to declare it?
Loading history...
458
		if ($withpicto != 2) $result.= $this->piece_num;
459
		$result .= $linkend;
460
		//if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
461
462
		return $result;
463
	}
464
465
	/**
466
	 * Create object into database
467
	 *
468
	 * @param  User	$user	   User that creates
469
	 * @param  bool	$notrigger  false=launch triggers after, true=disable triggers
470
	 * @param  string  $mode 	   Mode
471
	 * @return int				 <0 if KO, Id of created object if OK
472
	 */
473
    public function createStd(User $user, $notrigger = false, $mode='')
474
    {
475
		global $conf;
476
477
		dol_syslog(__METHOD__, LOG_DEBUG);
478
479
		$error = 0;
480
481
		// Clean parameters
482
483
		if (isset($this->doc_type)) {
484
			$this->doc_type = trim($this->doc_type);
485
		}
486
		if (isset($this->doc_ref)) {
487
			$this->doc_ref = trim($this->doc_ref);
488
		}
489
		if (isset($this->fk_doc)) {
490
			$this->fk_doc = trim($this->fk_doc);
491
		}
492
		if (isset($this->fk_docdet)) {
493
			$this->fk_docdet = trim($this->fk_docdet);
494
		}
495
		if (isset($this->thirdparty_code)) {
496
			$this->thirdparty_code = trim($this->thirdparty_code);
497
		}
498
		if (isset($this->subledger_account)) {
499
			$this->subledger_account = trim($this->subledger_account);
500
		}
501
		if (isset($this->subledger_label)) {
502
			$this->subledger_label = trim($this->subledger_label);
503
		}
504
		if (isset($this->numero_compte)) {
505
			$this->numero_compte = trim($this->numero_compte);
506
		}
507
		if (isset($this->label_compte)) {
508
			$this->label_compte = trim($this->label_compte);
509
		}
510
		if (isset($this->label_operation)) {
511
			$this->label_operation = trim($this->label_operation);
512
		}
513
		if (isset($this->debit)) {
514
			$this->debit = trim($this->debit);
515
		}
516
		if (isset($this->credit)) {
517
			$this->credit = trim($this->credit);
518
		}
519
		if (isset($this->montant)) {
520
			$this->montant = trim($this->montant);
521
		}
522
		if (isset($this->sens)) {
523
			$this->sens = trim($this->sens);
524
		}
525
		if (isset($this->fk_user_author)) {
526
			$this->fk_user_author = trim($this->fk_user_author);
527
		}
528
		if (isset($this->import_key)) {
529
			$this->import_key = trim($this->import_key);
530
		}
531
		if (isset($this->code_journal)) {
532
			$this->code_journal = trim($this->code_journal);
533
		}
534
		if (isset($this->journal_label)) {
535
			$this->journal_label = trim($this->journal_label);
536
		}
537
		if (isset($this->piece_num)) {
538
			$this->piece_num = trim($this->piece_num);
539
		}
540
		if (empty($this->debit)) $this->debit = 0;
541
		if (empty($this->credit)) $this->credit = 0;
542
543
		$this->debit = price2num($this->debit, 'MT');
544
		$this->credit = price2num($this->credit, 'MT');
545
546
		$now = dol_now();
547
548
		// Check parameters
549
		// Put here code to add control on parameters values
550
551
		// Insert request
552
		$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . $mode.'(';
553
		$sql .= 'doc_date,';
554
		$sql .= 'date_lim_reglement,';
555
		$sql .= 'doc_type,';
556
		$sql .= 'doc_ref,';
557
		$sql .= 'fk_doc,';
558
		$sql .= 'fk_docdet,';
559
		$sql .= 'thirdparty_code,';
560
		$sql .= 'subledger_account,';
561
		$sql .= 'subledger_label,';
562
		$sql .= 'numero_compte,';
563
		$sql .= 'label_compte,';
564
		$sql .= 'label_operation,';
565
		$sql .= 'debit,';
566
		$sql .= 'credit,';
567
		$sql .= 'montant,';
568
		$sql .= 'sens,';
569
		$sql .= 'fk_user_author,';
570
		$sql .= 'date_creation,';
571
		$sql .= 'code_journal,';
572
		$sql .= 'journal_label,';
573
		$sql .= 'piece_num,';
574
		$sql .= 'entity';
575
		$sql .= ') VALUES (';
576
		$sql .= ' ' . (! isset($this->doc_date) || dol_strlen($this->doc_date) == 0 ? 'NULL' : "'" . $this->db->idate($this->doc_date) . "'") . ',';
577
		$sql .= ' ' . (! isset($this->date_lim_reglement) || dol_strlen($this->date_lim_reglement) == 0 ? 'NULL' : "'" . $this->db->idate($this->date_lim_reglement) . "'") . ',';
578
		$sql .= ' ' . (! isset($this->doc_type) ? 'NULL' : "'" . $this->db->escape($this->doc_type) . "'") . ',';
579
		$sql .= ' ' . (! isset($this->doc_ref) ? 'NULL' : "'" . $this->db->escape($this->doc_ref) . "'") . ',';
580
		$sql .= ' ' . (empty($this->fk_doc) ? '0' : $this->fk_doc) . ',';
581
		$sql .= ' ' . (empty($this->fk_docdet) ? '0' : $this->fk_docdet) . ',';
582
		$sql .= ' ' . (! isset($this->thirdparty_code) ? 'NULL' : "'" . $this->db->escape($this->thirdparty_code) . "'") . ',';
583
		$sql .= ' ' . (! isset($this->subledger_account) ? 'NULL' : "'" . $this->db->escape($this->subledger_account) . "'") . ',';
584
		$sql .= ' ' . (! isset($this->subledger_label) ? 'NULL' : "'" . $this->db->escape($this->subledger_label) . "'") . ',';
585
		$sql .= ' ' . (! isset($this->numero_compte) ? 'NULL' : "'" . $this->db->escape($this->numero_compte) . "'") . ',';
586
		$sql .= ' ' . (! isset($this->label_compte) ? 'NULL' : "'" . $this->db->escape($this->label_compte) . "'") . ',';
587
		$sql .= ' ' . (! isset($this->label_operation) ? 'NULL' : "'" . $this->db->escape($this->label_operation) . "'") . ',';
588
		$sql .= ' ' . (! isset($this->debit) ? 'NULL' : $this->debit ). ',';
589
		$sql .= ' ' . (! isset($this->credit) ? 'NULL' : $this->credit ). ',';
590
		$sql .= ' ' . (! isset($this->montant) ? 'NULL' : $this->montant ). ',';
591
		$sql .= ' ' . (! isset($this->sens) ? 'NULL' : "'" . $this->db->escape($this->sens) . "'") . ',';
592
		$sql .= ' ' . $user->id . ',';
593
		$sql .= ' ' . "'" . $this->db->idate($now) . "',";
594
		$sql .= ' ' . (empty($this->code_journal) ? 'NULL' : "'" . $this->db->escape($this->code_journal) . "'") . ',';
595
		$sql .= ' ' . (empty($this->journal_label) ? 'NULL' : "'" . $this->db->escape($this->journal_label) . "'") . ',';
596
		$sql .= ' ' . (empty($this->piece_num) ? 'NULL' : $this->db->escape($this->piece_num)).',';
597
		$sql .= ' ' . (! isset($this->entity) ? $conf->entity : $this->entity);
598
		$sql .= ')';
599
600
		$this->db->begin();
601
602
		$resql = $this->db->query($sql);
603
		if (! $resql) {
604
			$error ++;
605
			$this->errors[] = 'Error ' . $this->db->lasterror();
606
			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
607
		}
608
609
		if (! $error) {
610
			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element . $mode);
611
612
			// Uncomment this and change MYOBJECT to your own tag if you
613
			// want this action to call a trigger.
614
			//if (! $notrigger) {
615
616
			// // Call triggers
617
			// $result=$this->call_trigger('MYOBJECT_CREATE',$user);
618
			// if ($result < 0) $error++;
619
			// // End call triggers
620
			//}
621
		}
622
623
		// Commit or rollback
624
		if ($error) {
625
			$this->db->rollback();
626
627
			return - 1 * $error;
628
		} else {
629
			$this->db->commit();
630
631
			return $this->id;
632
		}
633
	}
634
635
	/**
636
	 * Load object in memory from the database
637
	 *
638
	 * @param int $id Id object
639
	 * @param string $ref Ref
640
	 * @param string $mode 	Mode
641
	 *
642
	 * @return int <0 if KO, 0 if not found, >0 if OK
643
	 */
644
    public function fetch($id, $ref = null, $mode='')
645
    {
646
		global $conf;
647
648
		dol_syslog(__METHOD__, LOG_DEBUG);
649
650
		$sql = 'SELECT';
651
		$sql .= ' t.rowid,';
652
		$sql .= " t.doc_date,";
653
		$sql .= " t.date_lim_reglement,";
654
		$sql .= " t.doc_type,";
655
		$sql .= " t.doc_ref,";
656
		$sql .= " t.fk_doc,";
657
		$sql .= " t.fk_docdet,";
658
		$sql .= " t.thirdparty_code,";
659
		$sql .= " t.subledger_account,";
660
		$sql .= " t.subledger_label,";
661
		$sql .= " t.numero_compte,";
662
		$sql .= " t.label_compte,";
663
		$sql .= " t.label_operation,";
664
		$sql .= " t.debit,";
665
		$sql .= " t.credit,";
666
		$sql .= " t.montant,";
667
		$sql .= " t.sens,";
668
		$sql .= " t.fk_user_author,";
669
		$sql .= " t.import_key,";
670
		$sql .= " t.code_journal,";
671
		$sql .= " t.journal_label,";
672
		$sql .= " t.piece_num,";
673
		$sql .= " t.date_creation";
674
		$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element.$mode. ' as t';
675
		$sql .= ' WHERE 1 = 1';
676
		$sql .= " AND entity IN (" . getEntity('accountancy') . ")";
677
		if (null !== $ref) {
678
			$sql .= ' AND t.ref = ' . '\'' . $ref . '\'';
679
		} else {
680
			$sql .= ' AND t.rowid = ' . $id;
681
		}
682
683
		$resql = $this->db->query($sql);
684
		if ($resql) {
685
			$numrows = $this->db->num_rows($resql);
686
			if ($numrows) {
687
				$obj = $this->db->fetch_object($resql);
688
689
				$this->id = $obj->rowid;
690
691
				$this->doc_date = $this->db->jdate($obj->doc_date);
692
				$this->date_lim_reglement = $this->db->jdate($obj->date_lim_reglement);
693
				$this->doc_type = $obj->doc_type;
694
				$this->doc_ref = $obj->doc_ref;
695
				$this->fk_doc = $obj->fk_doc;
696
				$this->fk_docdet = $obj->fk_docdet;
697
				$this->thirdparty_code = $obj->thirdparty_code;
698
				$this->subledger_account = $obj->subledger_account;
699
				$this->subledger_label = $obj->subledger_label;
700
				$this->numero_compte = $obj->numero_compte;
701
				$this->label_compte = $obj->label_compte;
702
				$this->label_operation = $obj->label_operation;
703
				$this->debit = $obj->debit;
704
				$this->credit = $obj->credit;
705
				$this->montant = $obj->montant;
706
				$this->sens = $obj->sens;
707
				$this->fk_user_author = $obj->fk_user_author;
708
				$this->import_key = $obj->import_key;
709
				$this->code_journal = $obj->code_journal;
710
				$this->journal_label = $obj->journal_label;
711
				$this->piece_num = $obj->piece_num;
712
				$this->date_creation = $this->db->jdate($obj->date_creation);
713
			}
714
			$this->db->free($resql);
715
716
			if ($numrows) {
717
				return 1;
718
			} else {
719
				return 0;
720
			}
721
		} else {
722
			$this->errors[] = 'Error ' . $this->db->lasterror();
723
			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
724
725
			return - 1;
726
		}
727
	}
728
729
730
	/**
731
	 * Load object in memory from the database
732
	 *
733
	 * @param string $sortorder Sort Order
734
	 * @param string $sortfield Sort field
735
	 * @param int $limit offset limit
736
	 * @param int $offset offset limit
737
	 * @param array $filter filter array
738
	 * @param string $filtermode filter mode (AND or OR)
739
	 *
740
	 * @return int <0 if KO, >=0 if OK
741
	 */
742
    public function fetchAllByAccount($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
743
    {
744
		global $conf;
745
746
		dol_syslog(__METHOD__, LOG_DEBUG);
747
748
		$this->lines = array();
749
750
		$sql = 'SELECT';
751
		$sql .= ' t.rowid,';
752
		$sql .= " t.doc_date,";
753
		$sql .= " t.doc_type,";
754
		$sql .= " t.doc_ref,";
755
		$sql .= " t.fk_doc,";
756
		$sql .= " t.fk_docdet,";
757
		$sql .= " t.thirdparty_code,";
758
		$sql .= " t.subledger_account,";
759
		$sql .= " t.subledger_label,";
760
		$sql .= " t.numero_compte,";
761
		$sql .= " t.label_compte,";
762
		$sql .= " t.label_operation,";
763
		$sql .= " t.debit,";
764
		$sql .= " t.credit,";
765
		$sql .= " t.montant,";
766
		$sql .= " t.sens,";
767
		$sql .= " t.multicurrency_amount,";
768
		$sql .= " t.multicurrency_code,";
769
		$sql .= " t.lettering_code,";
770
		$sql .= " t.date_lettering,";
771
		$sql .= " t.fk_user_author,";
772
		$sql .= " t.import_key,";
773
		$sql .= " t.code_journal,";
774
		$sql .= " t.journal_label,";
775
		$sql .= " t.piece_num,";
776
		$sql .= " t.date_creation";
777
		// Manage filter
778
		$sqlwhere = array ();
779
		if (count($filter) > 0) {
780
			foreach ( $filter as $key => $value ) {
781
				if ($key == 't.doc_date') {
782
					$sqlwhere[] = $key . '=\'' . $this->db->idate($value) . '\'';
783
				} elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=') {
784
					$sqlwhere[] = $key . '\'' . $this->db->idate($value) . '\'';
785
				} elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=' || $key == 't.subledger_account>=' || $key == 't.subledger_account<=') {
786
					$sqlwhere[] = $key . '\'' . $this->db->escape($value) . '\'';
787
				} elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') {
788
					$sqlwhere[] = $key . '=' . $value;
789
				} elseif ($key == 't.subledger_account' || $key == 't.numero_compte') {
790
					$sqlwhere[] = $key . ' LIKE \'' . $this->db->escape($value) . '%\'';
791
				} elseif ($key == 't.date_creation>=' || $key == 't.date_creation<=') {
792
					$sqlwhere[] = $key . '\'' . $this->db->idate($value) . '\'';
793
				} elseif ($key == 't.credit' || $key == 't.debit') {
794
					$sqlwhere[] = natural_search($key, $value, 1, 1);
795
				} else {
796
					$sqlwhere[] = natural_search($key, $value, 0, 1);
797
				}
798
			}
799
		}
800
		$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
801
		$sql .= ' WHERE 1 = 1';
802
		$sql .= " AND entity IN (" . getEntity('accountancy') . ")";
803
		if (count($sqlwhere) > 0) {
804
			$sql .= ' AND ' . implode(' ' . $filtermode . ' ', $sqlwhere);
805
		}
806
		// Affichage par compte comptable
807
		$sql .= ' ORDER BY t.numero_compte ASC';
808
		if (! empty($sortfield)) {
809
			$sql .= ', ' . $sortfield . ' ' .$sortorder;
810
		}
811
		if (! empty($limit)) {
812
			$sql .= ' ' . $this->db->plimit($limit + 1, $offset);
813
		}
814
815
		$resql = $this->db->query($sql);
816
		if ($resql) {
817
			$num = $this->db->num_rows($resql);
818
819
			$i = 0;
820
			while (($obj = $this->db->fetch_object($resql)) && (empty($limit) || $i < min($limit, $num))) {
821
				$line = new BookKeepingLine();
822
823
				$line->id = $obj->rowid;
824
825
				$line->doc_date = $this->db->jdate($obj->doc_date);
826
				$line->doc_type = $obj->doc_type;
827
				$line->doc_ref = $obj->doc_ref;
828
				$line->fk_doc = $obj->fk_doc;
829
				$line->fk_docdet = $obj->fk_docdet;
830
				$line->thirdparty_code = $obj->thirdparty_code;
831
				$line->subledger_account = $obj->subledger_account;
832
				$line->subledger_label = $obj->subledger_label;
833
				$line->numero_compte = $obj->numero_compte;
834
				$line->label_compte = $obj->label_compte;
835
				$line->label_operation = $obj->label_operation;
836
				$line->debit = $obj->debit;
837
				$line->credit = $obj->credit;
838
				$line->montant = $obj->montant;
839
				$line->sens = $obj->sens;
840
				$line->multicurrency_amount = $obj->multicurrency_amount;
841
				$line->multicurrency_code = $obj->multicurrency_code;
842
				$line->lettering_code = $obj->lettering_code;
843
				$line->date_lettering = $obj->date_lettering;
844
				$line->fk_user_author = $obj->fk_user_author;
845
				$line->import_key = $obj->import_key;
846
				$line->code_journal = $obj->code_journal;
847
				$line->journal_label = $obj->journal_label;
848
				$line->piece_num = $obj->piece_num;
849
				$line->date_creation = $obj->date_creation;
850
851
				$this->lines[] = $line;
852
853
				$i++;
854
			}
855
			$this->db->free($resql);
856
857
			return $num;
858
		} else {
859
			$this->errors[] = 'Error ' . $this->db->lasterror();
860
			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
861
862
			return -1;
863
		}
864
	}
865
866
	/**
867
	 * Load object in memory from the database
868
	 *
869
	 * @param string 		$sortorder 		Sort Order
870
	 * @param string 		$sortfield 		Sort field
871
	 * @param int 			$limit 			Offset limit
872
	 * @param int 			$offset 		Offset limit
873
	 * @param array 		$filter 		Filter array
874
	 * @param string 		$filtermode 	Filter mode (AND or OR)
875
	 * @return int 							<0 if KO, >0 if OK
876
	 */
877
    public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
878
    {
879
		global $conf;
880
881
		dol_syslog(__METHOD__, LOG_DEBUG);
882
883
		$sql = 'SELECT';
884
		$sql .= ' t.rowid,';
885
		$sql .= " t.doc_date,";
886
		$sql .= " t.doc_type,";
887
		$sql .= " t.doc_ref,";
888
		$sql .= " t.fk_doc,";
889
		$sql .= " t.fk_docdet,";
890
		$sql .= " t.thirdparty_code,";
891
		$sql .= " t.subledger_account,";
892
		$sql .= " t.subledger_label,";
893
		$sql .= " t.numero_compte,";
894
		$sql .= " t.label_compte,";
895
		$sql .= " t.label_operation,";
896
		$sql .= " t.debit,";
897
		$sql .= " t.credit,";
898
		$sql .= " t.lettering_code,";
899
		$sql .= " t.montant,";
900
		$sql .= " t.sens,";
901
		$sql .= " t.fk_user_author,";
902
		$sql .= " t.import_key,";
903
		$sql .= " t.code_journal,";
904
		$sql .= " t.journal_label,";
905
		$sql .= " t.piece_num,";
906
		$sql .= " t.date_creation,";
907
		$sql .= " t.tms as date_modification";
908
		$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
909
		// Manage filter
910
		$sqlwhere = array ();
911
		if (count($filter) > 0) {
912
			foreach ( $filter as $key => $value ) {
913
				if ($key == 't.doc_date') {
914
					$sqlwhere[] = $key . '=\'' . $this->db->idate($value) . '\'';
915
				} elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=') {
916
					$sqlwhere[] = $key . '\'' . $this->db->idate($value) . '\'';
917
				} elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=' || $key == 't.subledger_account>=' || $key == 't.subledger_account<=') {
918
					$sqlwhere[] = $key . '\'' . $this->db->escape($value) . '\'';
919
				} elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') {
920
					$sqlwhere[] = $key . '=' . $value;
921
				} elseif ($key == 't.subledger_account' || $key == 't.numero_compte') {
922
					$sqlwhere[] = $key . ' LIKE \'' . $this->db->escape($value) . '%\'';
923
				} elseif ($key == 't.date_creation>=' || $key == 't.date_creation<=') {
924
					$sqlwhere[] = $key . '\'' . $this->db->idate($value) . '\'';
925
				} elseif ($key == 't.tms>=' || $key == 't.tms<=') {
926
					$sqlwhere[] = $key . '\'' . $this->db->idate($value) . '\'';
927
				} elseif ($key == 't.credit' || $key == 't.debit') {
928
					$sqlwhere[] = natural_search($key, $value, 1, 1);
929
				} else {
930
					$sqlwhere[] = natural_search($key, $value, 0, 1);
931
				}
932
			}
933
		}
934
		$sql.= ' WHERE t.entity IN (' . getEntity('accountancy') . ')';
935
		if (count($sqlwhere) > 0) {
936
			$sql .= ' AND ' . implode(' ' . $filtermode . ' ', $sqlwhere);
937
		}
938
939
		if (! empty($sortfield)) {
940
			$sql .= $this->db->order($sortfield, $sortorder);
941
		}
942
		if (! empty($limit)) {
943
			$sql .= ' ' . $this->db->plimit($limit + 1, $offset);
944
		}
945
		$this->lines = array();
946
947
		$resql = $this->db->query($sql);
948
		if ($resql) {
949
			$num = $this->db->num_rows($resql);
950
951
			$i = 0;
952
			while (($obj = $this->db->fetch_object($resql)) && (empty($limit) || $i < min($limit, $num)))
953
			{
954
				$line = new BookKeepingLine();
955
956
				$line->id = $obj->rowid;
957
958
				$line->doc_date = $this->db->jdate($obj->doc_date);
959
				$line->doc_type = $obj->doc_type;
960
				$line->doc_ref = $obj->doc_ref;
961
				$line->fk_doc = $obj->fk_doc;
962
				$line->fk_docdet = $obj->fk_docdet;
963
				$line->thirdparty_code = $obj->thirdparty_code;
964
				$line->subledger_account = $obj->subledger_account;
965
				$line->subledger_label = $obj->subledger_label;
966
				$line->numero_compte = $obj->numero_compte;
967
				$line->label_compte = $obj->label_compte;
968
				$line->label_operation = $obj->label_operation;
969
				$line->debit = $obj->debit;
970
				$line->credit = $obj->credit;
971
				$line->montant = $obj->montant;
972
				$line->sens = $obj->sens;
973
				$line->lettering_code = $obj->lettering_code;
974
				$line->fk_user_author = $obj->fk_user_author;
975
				$line->import_key = $obj->import_key;
976
				$line->code_journal = $obj->code_journal;
977
				$line->journal_label = $obj->journal_label;
978
				$line->piece_num = $obj->piece_num;
979
				$line->date_creation = $this->db->jdate($obj->date_creation);
980
				$line->date_modification = $this->db->jdate($obj->date_modification);
981
982
				$this->lines[] = $line;
983
984
				$i++;
985
			}
986
			$this->db->free($resql);
987
988
			return $num;
989
		} else {
990
			$this->errors[] = 'Error ' . $this->db->lasterror();
991
			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
992
			return -1;
993
		}
994
	}
995
996
	/**
997
	 * Load object in memory from the database
998
	 *
999
	 * @param string $sortorder Sort Order
1000
	 * @param string $sortfield Sort field
1001
	 * @param int $limit offset limit
1002
	 * @param int $offset offset limit
1003
	 * @param array $filter filter array
1004
	 * @param string $filtermode filter mode (AND or OR)
1005
	 *
1006
	 * @return int <0 if KO, >0 if OK
1007
	 */
1008
	public function fetchAllBalance($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
1009
	{
1010
		global $conf;
1011
1012
		$this->lines = array();
1013
1014
		dol_syslog(__METHOD__, LOG_DEBUG);
1015
1016
		$sql = 'SELECT';
1017
		$sql .= " t.numero_compte,";
1018
		$sql .= " SUM(t.debit) as debit,";
1019
		$sql .= " SUM(t.credit) as credit";
1020
		$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
1021
		// Manage filter
1022
		$sqlwhere = array ();
1023
		if (count($filter) > 0) {
1024
			foreach ( $filter as $key => $value ) {
1025
				if ($key == 't.doc_date') {
1026
					$sqlwhere[] = $key . '=\'' . $this->db->idate($value) . '\'';
1027
				} elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=') {
1028
					$sqlwhere[] = $key . '\'' . $this->db->idate($value) . '\'';
1029
				} elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=' || $key == 't.subledger_account>=' || $key == 't.subledger_account<=') {
1030
					$sqlwhere[] = $key . '\'' . $this->db->escape($value) . '\'';
1031
				} elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') {
1032
					$sqlwhere[] = $key . '=' . $value;
1033
				} elseif ($key == 't.subledger_account' || $key == 't.numero_compte') {
1034
					$sqlwhere[] = $key . ' LIKE \'' . $this->db->escape($value) . '%\'';
1035
				} elseif ($key == 't.subledger_label') {
1036
					$sqlwhere[] = $key . ' LIKE \'' . $this->db->escape($value) . '%\'';
1037
				} else {
1038
					$sqlwhere[] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\'';
1039
				}
1040
			}
1041
		}
1042
		$sql.= ' WHERE entity IN (' . getEntity('accountancy') . ')';
1043
		if (count($sqlwhere) > 0) {
1044
			$sql .= ' AND ' . implode(' ' . $filtermode . ' ', $sqlwhere);
1045
		}
1046
1047
		$sql .= ' GROUP BY t.numero_compte';
1048
1049
		if (! empty($sortfield)) {
1050
			$sql .= $this->db->order($sortfield, $sortorder);
1051
		}
1052
		if (! empty($limit)) {
1053
			$sql .= ' ' . $this->db->plimit($limit + 1, $offset);
1054
		}
1055
1056
		$resql = $this->db->query($sql);
1057
		if ($resql)
1058
		{
1059
			$num = $this->db->num_rows($resql);
1060
1061
			$i = 0;
1062
			while (($obj = $this->db->fetch_object($resql)) && (empty($limit) || $i < min($limit, $num)))
1063
			{
1064
				$line = new BookKeepingLine();
1065
1066
				$line->numero_compte = $obj->numero_compte;
1067
				$line->debit = $obj->debit;
1068
				$line->credit = $obj->credit;
1069
1070
				$this->lines[] = $line;
1071
1072
				$i++;
1073
			}
1074
			$this->db->free($resql);
1075
1076
			return $num;
1077
		} else {
1078
			$this->errors[] = 'Error ' . $this->db->lasterror();
1079
			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
1080
1081
			return - 1;
1082
		}
1083
	}
1084
1085
	/**
1086
	 * Update object into database
1087
	 *
1088
	 * @param  User    $user       User that modifies
1089
	 * @param  bool    $notrigger  false=launch triggers after, true=disable triggers
1090
	 * @param  string  $mode       Mode
1091
	 * @return int                 <0 if KO, >0 if OK
1092
	 */
1093
    public function update(User $user, $notrigger = false, $mode='')
1094
    {
1095
		$error = 0;
1096
1097
		dol_syslog(__METHOD__, LOG_DEBUG);
1098
1099
		// Clean parameters
1100
		if (isset($this->doc_type)) {
1101
			$this->doc_type = trim($this->doc_type);
1102
		}
1103
		if (isset($this->doc_ref)) {
1104
			$this->doc_ref = trim($this->doc_ref);
1105
		}
1106
		if (isset($this->fk_doc)) {
1107
			$this->fk_doc = trim($this->fk_doc);
1108
		}
1109
		if (isset($this->fk_docdet)) {
1110
			$this->fk_docdet = trim($this->fk_docdet);
1111
		}
1112
		if (isset($this->thirdparty_code)) {
1113
			$this->thirdparty_code = trim($this->thirdparty_code);
1114
		}
1115
		if (isset($this->subledger_account)) {
1116
			$this->subledger_account = trim($this->subledger_account);
1117
		}
1118
		if (isset($this->subledger_label)) {
1119
			$this->subledger_label = trim($this->subledger_label);
1120
		}
1121
		if (isset($this->numero_compte)) {
1122
			$this->numero_compte = trim($this->numero_compte);
1123
		}
1124
		if (isset($this->label_compte)) {
1125
			$this->label_compte = trim($this->label_compte);
1126
		}
1127
		if (isset($this->label_operation)) {
1128
			$this->label_operation = trim($this->label_operation);
1129
		}
1130
		if (isset($this->debit)) {
1131
			$this->debit = trim($this->debit);
1132
		}
1133
		if (isset($this->credit)) {
1134
			$this->credit = trim($this->credit);
1135
		}
1136
		if (isset($this->montant)) {
1137
			$this->montant = trim($this->montant);
1138
		}
1139
		if (isset($this->sens)) {
1140
			$this->sens = trim($this->sens);
1141
		}
1142
		if (isset($this->fk_user_author)) {
1143
			$this->fk_user_author = trim($this->fk_user_author);
1144
		}
1145
		if (isset($this->import_key)) {
1146
			$this->import_key = trim($this->import_key);
1147
		}
1148
		if (isset($this->code_journal)) {
1149
			$this->code_journal = trim($this->code_journal);
1150
		}
1151
		if (isset($this->journal_label)) {
1152
			$this->journal_label = trim($this->journal_label);
1153
		}
1154
		if (isset($this->piece_num)) {
1155
			$this->piece_num = trim($this->piece_num);
1156
		}
1157
1158
		$this->debit = price2num($this->debit, 'MT');
1159
		$this->credit = price2num($this->credit, 'MT');
1160
1161
		// Check parameters
1162
		// Put here code to add a control on parameters values
1163
1164
		// Update request
1165
		$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . $mode.' SET';
1166
		$sql .= ' doc_date = ' . (! isset($this->doc_date) || dol_strlen($this->doc_date) != 0 ? "'" . $this->db->idate($this->doc_date) . "'" : 'null') . ',';
1167
		$sql .= ' doc_type = ' . (isset($this->doc_type) ? "'" . $this->db->escape($this->doc_type) . "'" : "null") . ',';
1168
		$sql .= ' doc_ref = ' . (isset($this->doc_ref) ? "'" . $this->db->escape($this->doc_ref) . "'" : "null") . ',';
1169
		$sql .= ' fk_doc = ' . (isset($this->fk_doc) ? $this->fk_doc : "null") . ',';
1170
		$sql .= ' fk_docdet = ' . (isset($this->fk_docdet) ? $this->fk_docdet : "null") . ',';
1171
		$sql .= ' thirdparty_code = ' . (isset($this->thirdparty_code) ? "'" . $this->db->escape($this->thirdparty_code) . "'" : "null") . ',';
1172
		$sql .= ' subledger_account = ' . (isset($this->subledger_account) ? "'" . $this->db->escape($this->subledger_account) . "'" : "null") . ',';
1173
		$sql .= ' subledger_label = ' . (isset($this->subledger_label) ? "'" . $this->db->escape($this->subledger_label) . "'" : "null") . ',';
1174
		$sql .= ' numero_compte = ' . (isset($this->numero_compte) ? "'" . $this->db->escape($this->numero_compte) . "'" : "null") . ',';
1175
		$sql .= ' label_compte = ' . (isset($this->label_compte) ? "'" . $this->db->escape($this->label_compte) . "'" : "null") . ',';
1176
		$sql .= ' label_operation = ' . (isset($this->label_operation) ? "'" . $this->db->escape($this->label_operation) . "'" : "null") . ',';
1177
		$sql .= ' debit = ' . (isset($this->debit) ? $this->debit : "null") . ',';
1178
		$sql .= ' credit = ' . (isset($this->credit) ? $this->credit : "null") . ',';
1179
		$sql .= ' montant = ' . (isset($this->montant) ? $this->montant : "null") . ',';
1180
		$sql .= ' sens = ' . (isset($this->sens) ? "'" . $this->db->escape($this->sens) . "'" : "null") . ',';
1181
		$sql .= ' fk_user_author = ' . (isset($this->fk_user_author) ? $this->fk_user_author : "null") . ',';
1182
		$sql .= ' import_key = ' . (isset($this->import_key) ? "'" . $this->db->escape($this->import_key) . "'" : "null") . ',';
1183
		$sql .= ' code_journal = ' . (isset($this->code_journal) ? "'" . $this->db->escape($this->code_journal) . "'" : "null") . ',';
1184
		$sql .= ' journal_label = ' . (isset($this->journal_label) ? "'" . $this->db->escape($this->journal_label) . "'" : "null") . ',';
1185
		$sql .= ' piece_num = ' . (isset($this->piece_num) ? $this->piece_num : "null");
1186
		$sql .= ' WHERE rowid=' . $this->id;
1187
1188
		$this->db->begin();
1189
1190
		$resql = $this->db->query($sql);
1191
		if (! $resql) {
1192
			$error ++;
1193
			$this->errors[] = 'Error ' . $this->db->lasterror();
1194
			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
1195
		}
1196
1197
		// Uncomment this and change MYOBJECT to your own tag if you
1198
		// want this action calls a trigger.
1199
		//if (! $error && ! $notrigger) {
1200
1201
		// // Call triggers
1202
		// $result=$this->call_trigger('MYOBJECT_MODIFY',$user);
1203
		// if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
1204
		// // End call triggers
1205
		//}
1206
1207
		// Commit or rollback
1208
		if ($error) {
1209
			$this->db->rollback();
1210
1211
			return - 1 * $error;
1212
		} else {
1213
			$this->db->commit();
1214
1215
			return 1;
1216
		}
1217
	}
1218
1219
	/**
1220
	 * Update movement
1221
	 *
1222
	 * @param  string  $piece_num      Piece num
1223
	 * @param  string  $field          Field
1224
	 * @param  string  $value          Value
1225
	 * @param  string  $mode           Mode
1226
	 * @return number                  <0 if KO, >0 if OK
1227
	 */
1228
	public function updateByMvt($piece_num='', $field='', $value='', $mode='')
1229
	{
1230
		$error=0;
1231
1232
		$this->db->begin();
1233
1234
		$sql = "UPDATE " . MAIN_DB_PREFIX .  $this->table_element . $mode . " as ab";
1235
		$sql .= ' SET ab.' . $field . '=' . (is_numeric($value)?$value:"'".$this->db->escape($value)."'");
1236
		$sql .= ' WHERE ab.piece_num=' . $piece_num ;
1237
		$resql = $this->db->query($sql);
1238
1239
		if (! $resql) {
1240
			$error++;
1241
			$this->errors[] = 'Error ' . $this->db->lasterror();
1242
			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
1243
		}
1244
		if ($error) {
1245
			$this->db->rollback();
1246
1247
			return -1 * $error;
1248
		} else {
1249
			$this->db->commit();
1250
1251
			return 1;
1252
		}
1253
	}
1254
1255
	/**
1256
	 * Delete object in database
1257
	 *
1258
	 * @param User $user User that deletes
1259
	 * @param bool $notrigger false=launch triggers after, true=disable triggers
1260
	 * @param string $mode Mode
1261
	 * @return int <0 if KO, >0 if OK
1262
	 */
1263
    public function delete(User $user, $notrigger = false, $mode='')
1264
    {
1265
		dol_syslog(__METHOD__, LOG_DEBUG);
1266
1267
		$error = 0;
1268
1269
		$this->db->begin();
1270
1271
		// Uncomment this and change MYOBJECT to your own tag if you
1272
		// want this action calls a trigger.
1273
		//if (! $error && ! $notrigger) {
1274
1275
		// // Call triggers
1276
		// $result=$this->call_trigger('MYOBJECT_DELETE',$user);
1277
		// if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
1278
		// // End call triggers
1279
		//}
1280
1281
		if (! $error) {
1282
			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element.$mode;
1283
			$sql .= ' WHERE rowid=' . $this->id;
1284
1285
			$resql = $this->db->query($sql);
1286
			if (! $resql) {
1287
				$error ++;
1288
				$this->errors[] = 'Error ' . $this->db->lasterror();
1289
				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
1290
			}
1291
		}
1292
1293
		// Commit or rollback
1294
		if ($error) {
1295
			$this->db->rollback();
1296
1297
			return - 1 * $error;
1298
		} else {
1299
			$this->db->commit();
1300
1301
			return 1;
1302
		}
1303
	}
1304
1305
	/**
1306
	 * Delete bookkepping by importkey
1307
	 *
1308
	 * @param  string		$importkey		Import key
1309
	 * @return int Result
1310
	 */
1311
    function deleteByImportkey($importkey)
1312
    {
1313
		$this->db->begin();
1314
1315
		// first check if line not yet in bookkeeping
1316
		$sql = "DELETE";
1317
		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
1318
		$sql .= " WHERE import_key = '" . $this->db->escape($importkey) . "'";
1319
1320
		$resql = $this->db->query($sql);
1321
1322
		if (! $resql) {
1323
			$this->errors[] = "Error " . $this->db->lasterror();
1324
			dol_syslog(get_class($this)."::delete Error " . $this->db->lasterror(), LOG_ERR);
1325
			$this->db->rollback();
1326
			return - 1;
1327
		}
1328
1329
		$this->db->commit();
1330
		return 1;
1331
	}
1332
1333
	/**
1334
	 * Delete bookkepping by year
1335
	 *
1336
	 * @param  string $delyear		Year to delete
1337
	 * @param  string $journal		Journal to delete
1338
	 * @param  string $mode 		Mode
1339
	 * @return int					<0 if KO, >0 if OK
1340
	 */
1341
    function deleteByYearAndJournal($delyear='', $journal='', $mode='')
1342
    {
1343
		global $conf;
1344
1345
		if (empty($delyear) && empty($journal))
1346
		{
1347
			return -1;
1348
		}
1349
1350
		$this->db->begin();
1351
1352
		// first check if line not yet in bookkeeping
1353
		$sql = "DELETE";
1354
		$sql.= " FROM " . MAIN_DB_PREFIX . $this->table_element.$mode;
1355
		$sql.= " WHERE 1 = 1";
1356
		if (! empty($delyear)) $sql.= " AND YEAR(doc_date) = " . $delyear;		 // FIXME Must use between
1357
		if (! empty($journal)) $sql.= " AND code_journal = '".$this->db->escape($journal)."'";
1358
		$sql .= " AND entity IN (" . getEntity('accountancy') . ")";
1359
		$resql = $this->db->query($sql);
1360
1361
		if (! $resql) {
1362
			$this->errors[] = "Error " . $this->db->lasterror();
1363
			foreach ( $this->errors as $errmsg ) {
1364
				dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR);
1365
				$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
1366
			}
1367
			$this->db->rollback();
1368
			return -1;
1369
		}
1370
1371
		$this->db->commit();
1372
		return 1;
1373
	}
1374
1375
	/**
1376
	 * Delete bookkepping by piece number
1377
	 *
1378
	 * @param 	int 	$piecenum 	Piecenum to delete
1379
	 * @return 	int 				Result
1380
	 */
1381
    function deleteMvtNum($piecenum)
1382
    {
1383
		global $conf;
1384
1385
		$this->db->begin();
1386
1387
		// first check if line not yet in bookkeeping
1388
		$sql = "DELETE";
1389
		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
1390
		$sql .= " WHERE piece_num = " . (int) $piecenum;
1391
		$sql .= " AND entity IN (" . getEntity('accountancy') . ")";
1392
1393
		$resql = $this->db->query($sql);
1394
1395
		if (! $resql) {
1396
			$this->errors[] = "Error " . $this->db->lasterror();
1397
			foreach ( $this->errors as $errmsg ) {
1398
				dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR);
1399
				$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
1400
			}
1401
			$this->db->rollback();
1402
			return - 1;
1403
		}
1404
1405
		$this->db->commit();
1406
		return 1;
1407
	}
1408
1409
	/**
1410
	 * Load an object from its id and create a new one in database
1411
	 *
1412
	 * @param int $fromid Id of object to clone
1413
	 *
1414
	 * @return int New id of clone
1415
	 */
1416
    public function createFromClone($fromid)
1417
    {
1418
		dol_syslog(__METHOD__, LOG_DEBUG);
1419
1420
		global $user;
1421
		$error = 0;
1422
		$object = new BookKeeping($this->db);
1423
1424
		$this->db->begin();
1425
1426
		// Load source object
1427
		$object->fetch($fromid);
1428
		// Reset object
1429
		$object->id = 0;
1430
1431
		// Clear fields
1432
		// ...
1433
1434
		// Create clone
1435
		$result = $object->create($user);
1436
1437
		// Other options
1438
		if ($result < 0) {
1439
			$error ++;
1440
			$this->errors = $object->errors;
1441
			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
1442
		}
1443
1444
		// End
1445
		if (! $error) {
1446
			$this->db->commit();
1447
1448
			return $object->id;
1449
		} else {
1450
			$this->db->rollback();
1451
1452
			return - 1;
1453
		}
1454
	}
1455
1456
	/**
1457
	 * Initialise object with example values
1458
	 * Id must be 0 if object instance is a specimen
1459
	 *
1460
	 * @return void
1461
	 */
1462
    public function initAsSpecimen()
1463
    {
1464
		global $user;
1465
1466
		$now=dol_now();
1467
1468
		$this->id = 0;
1469
		$this->doc_date = $now;
1470
		$this->doc_type = '';
1471
		$this->doc_ref = '';
1472
		$this->fk_doc = '';
1473
		$this->fk_docdet = '';
1474
		$this->thirdparty_code = 'CU001';
1475
		$this->subledger_account = '41100001';
1476
		$this->subledger_label = 'My customer company';
1477
		$this->numero_compte = '411';
1478
		$this->label_compte = 'Customer';
1479
		$this->label_operation = 'Sales of pea';
1480
		$this->debit = 99.9;
1481
		$this->credit = '';
1482
		$this->montant = '';
1483
		$this->sens = 'D';
1484
		$this->fk_user_author = $user->id;
1485
		$this->import_key = '';
1486
		$this->code_journal = 'VT';
1487
		$this->journal_label = 'Journal de vente';
1488
		$this->piece_num = '';
1489
		$this->date_creation = $now;
1490
	}
1491
1492
	/**
1493
	 * Load an accounting document into memory from database
1494
	 *
1495
	 * @param int $piecenum Accounting document to get
1496
	 * @param string $mode Mode
1497
	 * @return int <0 if KO, >0 if OK
1498
	 */
1499
    public function fetchPerMvt($piecenum, $mode='')
1500
    {
1501
		global $conf;
1502
1503
		$sql = "SELECT piece_num,doc_date,code_journal,journal_label,doc_ref,doc_type,date_creation";
1504
		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element.$mode;
1505
		$sql .= " WHERE piece_num = " . $piecenum;
1506
		$sql .= " AND entity IN (" . getEntity('accountancy') . ")";
1507
1508
		dol_syslog(get_class($this) . "::" . __METHOD__, LOG_DEBUG);
1509
		$result = $this->db->query($sql);
1510
		if ($result) {
1511
			$obj = $this->db->fetch_object($result);
1512
1513
			$this->piece_num = $obj->piece_num;
1514
			$this->code_journal = $obj->code_journal;
1515
			$this->journal_label = $obj->journal_label;
1516
			$this->doc_date = $this->db->jdate($obj->doc_date);
1517
			$this->doc_ref = $obj->doc_ref;
1518
			$this->doc_type = $obj->doc_type;
1519
			$this->date_creation = $obj->date_creation;
1520
		} else {
1521
			$this->error = "Error " . $this->db->lasterror();
1522
			dol_syslog(get_class($this) . "::" . __METHOD__ . $this->error, LOG_ERR);
1523
			return - 1;
1524
		}
1525
1526
		return 1;
1527
	}
1528
1529
	/**
1530
	 * Return next number movement
1531
	 *
1532
	 * @param	string	$mode	Mode
1533
	 * @return	string			Next numero to use
1534
	 */
1535
	public function getNextNumMvt($mode='')
1536
	{
1537
		global $conf;
1538
1539
		$sql = "SELECT MAX(piece_num)+1 as max FROM " . MAIN_DB_PREFIX . $this->table_element.$mode;
1540
		$sql .= " WHERE entity IN (" . getEntity('accountancy') . ")";
1541
1542
		dol_syslog(get_class($this) . "getNextNumMvt sql=" . $sql, LOG_DEBUG);
1543
		$result = $this->db->query($sql);
1544
1545
		if ($result) {
1546
			$obj = $this->db->fetch_object($result);
1547
			if ($obj) $result = $obj->max;
1548
			if (empty($result)) $result = 1;
1549
			return $result;
1550
		} else {
1551
			$this->error = "Error " . $this->db->lasterror();
1552
			dol_syslog(get_class($this) . "::getNextNumMvt " . $this->error, LOG_ERR);
1553
			return - 1;
1554
		}
1555
	}
1556
1557
	/**
1558
	 * Load all informations of accountancy document
1559
	 *
1560
	 * @param  int     $piecenum   Id of line to get
1561
	 * @param  string  $mode       Mode
1562
	 * @return int                 <0 if KO, >0 if OK
1563
	 */
1564
    function fetchAllPerMvt($piecenum, $mode='')
1565
    {
1566
		global $conf;
1567
1568
		$sql = "SELECT rowid, doc_date, doc_type,";
1569
		$sql .= " doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,";
1570
		$sql .= " numero_compte, label_compte, label_operation, debit, credit,";
1571
		$sql .= " montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num, date_creation";
1572
		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element.$mode;
1573
		$sql .= " WHERE piece_num = " . $piecenum;
1574
		$sql .= " AND entity IN (" . getEntity('accountancy') . ")";
1575
1576
		dol_syslog(get_class($this) . "::" . __METHOD__, LOG_DEBUG);
1577
		$result = $this->db->query($sql);
1578
		if ($result) {
1579
1580
			while ($obj = $this->db->fetch_object($result)) {
1581
1582
				$line = new BookKeepingLine();
1583
1584
				$line->id = $obj->rowid;
1585
1586
				$line->doc_date = $this->db->jdate($obj->doc_date);
1587
				$line->doc_type = $obj->doc_type;
1588
				$line->doc_ref = $obj->doc_ref;
1589
				$line->fk_doc = $obj->fk_doc;
1590
				$line->fk_docdet = $obj->fk_docdet;
1591
				$line->thirdparty_code = $obj->thirdparty_code;
1592
				$line->subledger_account = $obj->subledger_account;
1593
				$line->subledger_label = $obj->subledger_label;
1594
				$line->numero_compte = $obj->numero_compte;
1595
				$line->label_compte = $obj->label_compte;
1596
				$line->label_operation = $obj->label_operation;
1597
				$line->debit = $obj->debit;
1598
				$line->credit = $obj->credit;
1599
				$line->montant = $obj->montant;
1600
				$line->sens = $obj->sens;
1601
				$line->code_journal = $obj->code_journal;
1602
				$line->journal_label = $obj->journal_label;
1603
				$line->piece_num = $obj->piece_num;
1604
				$line->date_creation = $obj->date_creation;
1605
1606
				$this->linesmvt[] = $line;
1607
			}
1608
		} else {
1609
			$this->error = "Error " . $this->db->lasterror();
1610
			dol_syslog(get_class($this) . "::" . __METHOD__ . $this->error, LOG_ERR);
1611
			return - 1;
1612
		}
1613
1614
		return 1;
1615
	}
1616
1617
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1618
	/**
1619
	 * Export bookkeping
1620
	 *
1621
	 * @param	string	$model	Model
1622
	 * @return	int				Result
1623
	 */
1624
    function export_bookkeping($model = 'ebp')
1625
    {
1626
        // phpcs:enable
1627
		global $conf;
1628
1629
		$sql = "SELECT rowid, doc_date, doc_type,";
1630
		$sql .= " doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,";
1631
		$sql .= " numero_compte, label_compte, label_operation, debit, credit,";
1632
		$sql .= " montant, sens, fk_user_author, import_key, code_journal, piece_num";
1633
		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
1634
		$sql .= " WHERE entity IN (" . getEntity('accountancy') . ")";
1635
1636
		dol_syslog(get_class($this) . "::export_bookkeping", LOG_DEBUG);
1637
1638
		$resql = $this->db->query($sql);
1639
1640
		if ($resql) {
1641
			$this->linesexport = array ();
1642
1643
			$num = $this->db->num_rows($resql);
1644
			while ($obj = $this->db->fetch_object($resql)) {
1645
				$line = new BookKeepingLine();
1646
1647
				$line->id = $obj->rowid;
1648
1649
				$line->doc_date = $this->db->jdate($obj->doc_date);
1650
				$line->doc_type = $obj->doc_type;
1651
				$line->doc_ref = $obj->doc_ref;
1652
				$line->fk_doc = $obj->fk_doc;
1653
				$line->fk_docdet = $obj->fk_docdet;
1654
				$line->thirdparty_code = $obj->thirdparty_code;
1655
				$line->subledger_account = $obj->subledger_account;
1656
				$line->subledger_label = $obj->subledger_label;
1657
				$line->numero_compte = $obj->numero_compte;
1658
				$line->label_compte = $obj->label_compte;
1659
				$line->label_operation = $obj->label_operation;
1660
				$line->debit = $obj->debit;
1661
				$line->credit = $obj->credit;
1662
				$line->montant = $obj->montant;
1663
				$line->sens = $obj->sens;
1664
				$line->code_journal = $obj->code_journal;
1665
				$line->piece_num = $obj->piece_num;
1666
1667
				$this->linesexport[] = $line;
1668
			}
1669
			$this->db->free($resql);
1670
1671
			return $num;
1672
		} else {
1673
			$this->error = "Error " . $this->db->lasterror();
1674
			dol_syslog(get_class($this) . "::export_bookkeping " . $this->error, LOG_ERR);
1675
			return - 1;
1676
		}
1677
	}
1678
1679
	/**
1680
	 * Transform transaction
1681
	 *
1682
	 * @param  number   $direction      If 0 tmp => real, if 1 real => tmp
1683
	 * @param  string   $piece_num      Piece num
1684
	 * @return int                      int <0 if KO, >0 if OK
1685
	 */
1686
	public function transformTransaction($direction=0,$piece_num='')
1687
	{
1688
		$error = 0;
1689
1690
		$this->db->begin();
1691
1692
		if ($direction==0)
1693
		{
1694
			$next_piecenum=$this->getNextNumMvt();
1695
			if ($next_piecenum < 0) {
1696
				$error++;
1697
			}
1698
			$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element.'(doc_date, doc_type,';
1699
			$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
1700
			$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
1701
			$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num)';
1702
			$sql .= 'SELECT doc_date, doc_type,';
1703
			$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
1704
			$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
1705
			$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, '.$next_piecenum.'';
1706
			$sql .= ' FROM '.MAIN_DB_PREFIX . $this->table_element.'_tmp WHERE piece_num = '.$piece_num;
1707
			$resql = $this->db->query($sql);
1708
			if (! $resql) {
1709
				$error ++;
1710
				$this->errors[] = 'Error ' . $this->db->lasterror();
1711
				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
1712
			}
1713
			$sql = 'DELETE FROM '.MAIN_DB_PREFIX . $this->table_element.'_tmp WHERE piece_num = '.$piece_num;
1714
			$resql = $this->db->query($sql);
1715
			if (! $resql) {
1716
				$error ++;
1717
				$this->errors[] = 'Error ' . $this->db->lasterror();
1718
				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
1719
			}
1720
		} elseif ($direction==1) {
1721
			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element.'_tmp WHERE piece_num = '.$piece_num;
1722
			$resql = $this->db->query($sql);
1723
			if (! $resql) {
1724
				$error ++;
1725
				$this->errors[] = 'Error ' . $this->db->lasterror();
1726
				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
1727
			}
1728
			$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element.'_tmp(doc_date, doc_type,';
1729
			$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
1730
			$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
1731
			$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num)';
1732
			$sql .= 'SELECT doc_date, doc_type,';
1733
			$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
1734
			$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
1735
			$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num';
1736
			$sql .= ' FROM '.MAIN_DB_PREFIX . $this->table_element.' WHERE piece_num = '.$piece_num;
1737
			$resql = $this->db->query($sql);
1738
			if (! $resql) {
1739
				$error ++;
1740
				$this->errors[] = 'Error ' . $this->db->lasterror();
1741
				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
1742
			}
1743
			$sql = 'DELETE FROM '.MAIN_DB_PREFIX . $this->table_element.'_tmp WHERE piece_num = '.$piece_num;
1744
			$resql = $this->db->query($sql);
1745
			if (! $resql) {
1746
				$error ++;
1747
				$this->errors[] = 'Error ' . $this->db->lasterror();
1748
				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
1749
			}
1750
		}
1751
		if (! $error) {
1752
			$this->db->commit();
1753
			return 1;
1754
		} else {
1755
			$this->db->rollback();
1756
			return - 1;
1757
		}
1758
		/*
1759
		$sql = "DELETE FROM ";
1760
		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab";
1761
		$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.account_number = ab.numero_compte";
1762
		$sql .= " AND aa.active = 1";
1763
		$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
1764
		$sql .= " AND asy.rowid = " . $pcgver;
1765
		$sql .= " AND ab.entity IN (" . getEntity('accountancy') . ")";
1766
		$sql .= " ORDER BY account_number ASC";
1767
		*/
1768
	}
1769
1770
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1771
	/**
1772
	* Return list of accounts with label by chart of accounts
1773
	*
1774
	* @param string     $selectid   Preselected chart of accounts
1775
	* @param string     $htmlname	Name of field in html form
1776
	* @param int		$showempty	Add an empty field
1777
	* @param array		$event		Event options
1778
	* @param int		$select_in	Value is a aa.rowid (0 default) or aa.account_number (1)
1779
	* @param int		$select_out	Set value returned by select 0=rowid (default), 1=account_number
1780
	* @param int		$aabase		Set accounting_account base class to display empty=all or from 1 to 8 will display only account beginning by this number
1781
	* @return string	String with HTML select
1782
    */
1783
    function select_account($selectid, $htmlname = 'account', $showempty = 0, $event = array(), $select_in = 0, $select_out = 0, $aabase = '')
1784
    {
1785
        // phpcs:enable
1786
		global $conf;
1787
1788
		require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
1789
1790
		$pcgver = $conf->global->CHARTOFACCOUNTS;
1791
1792
		$sql = "SELECT DISTINCT ab.numero_compte as account_number, aa.label as label, aa.rowid as rowid, aa.fk_pcg_version";
1793
		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab";
1794
		$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.account_number = ab.numero_compte";
1795
		$sql .= " AND aa.active = 1";
1796
		$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
1797
		$sql .= " AND asy.rowid = " . $pcgver;
1798
		$sql .= " AND ab.entity IN (" . getEntity('accountancy') . ")";
1799
		$sql .= " ORDER BY account_number ASC";
1800
1801
		dol_syslog(get_class($this) . "::select_account", LOG_DEBUG);
1802
		$resql = $this->db->query($sql);
1803
1804
		if (! $resql) {
1805
			$this->error = "Error " . $this->db->lasterror();
1806
			dol_syslog(get_class($this) . "::select_account " . $this->error, LOG_ERR);
1807
			return - 1;
1808
		}
1809
1810
		$out = ajax_combobox($htmlname, $event);
1811
1812
		$options = array();
1813
		$selected = null;
1814
1815
		while ($obj = $this->db->fetch_object($resql)) {
1816
			$label = length_accountg($obj->account_number) . ' - ' . $obj->label;
1817
1818
			$select_value_in = $obj->rowid;
1819
			$select_value_out = $obj->rowid;
1820
1821
			if ($select_in == 1) {
1822
				$select_value_in = $obj->account_number;
1823
			}
1824
			if ($select_out == 1) {
1825
				$select_value_out = $obj->account_number;
1826
			}
1827
1828
			// Remember guy's we store in database llx_facturedet the rowid of accounting_account and not the account_number
1829
			// Because same account_number can be share between different accounting_system and do have the same meaning
1830
			if (($selectid != '') && $selectid == $select_value_in) {
1831
				$selected = $select_value_out;
1832
			}
1833
1834
			$options[$select_value_out] = $label;
1835
		}
1836
1837
		$out .= Form::selectarray($htmlname, $options, $selected, $showempty, 0, 0, '', 0, 0, 0, '', 'maxwidth300');
1838
		$this->db->free($resql);
1839
		return $out;
1840
	}
1841
1842
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1843
	/**
1844
	 * Description of a root accounting account
1845
	 *
1846
	 * @param 	string 	$account	Accounting account
1847
	 * @return 	string 				Root account
1848
	 */
1849
	function get_compte_racine($account = null)
1850
	{
1851
        // phpcs:enable
1852
		global $conf;
1853
		$pcgver = $conf->global->CHARTOFACCOUNTS;
1854
1855
		$sql  = "SELECT root.account_number, root.label as label";
1856
		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
1857
		$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
1858
		$sql .= " AND asy.rowid = " . $pcgver;
1859
		$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as parent ON aa.account_parent = parent.rowid";
1860
		$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as root ON parent.account_parent = root.rowid";
1861
		$sql .= " WHERE aa.account_number = '" . $account . "'";
1862
		$sql .= " AND parent.active = 1";
1863
		$sql .= " AND root.active = 1";
1864
		$sql .= " AND aa.entity IN (" . getEntity('accountancy') . ")";
1865
1866
		dol_syslog(get_class($this) . "::select_account sql=" . $sql, LOG_DEBUG);
1867
		$resql = $this->db->query($sql);
1868
		if ($resql) {
1869
			$obj = '';
1870
			if ($this->db->num_rows($resql)) {
1871
				$obj = $this->db->fetch_object($resql);
1872
			}
1873
1874
			return $obj->label;
1875
		} else {
1876
			$this->error = "Error " . $this->db->lasterror();
1877
			dol_syslog(__METHOD__ . " " . $this->error, LOG_ERR);
1878
1879
			return -1;
1880
		}
1881
	}
1882
1883
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1884
	/**
1885
	 * Description of accounting account
1886
	 *
1887
	 * @param	string	$account	Accounting account
1888
	 * @return	string				Account desc
1889
	 */
1890
	function get_compte_desc($account = null)
1891
	{
1892
        // phpcs:enable
1893
		global $conf;
1894
1895
		$pcgver = $conf->global->CHARTOFACCOUNTS;
1896
		$sql  = "SELECT aa.account_number, aa.label, aa.rowid, aa.fk_pcg_version, cat.label as category";
1897
		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa ";
1898
		$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
1899
		$sql .= " AND aa.account_number = '" . $account . "'";
1900
		$sql .= " AND asy.rowid = " . $pcgver;
1901
		$sql .= " AND aa.active = 1";
1902
		$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_accounting_category as cat ON aa.fk_accounting_category = cat.rowid";
1903
		$sql .= " WHERE aa.entity IN (" . getEntity('accountancy') . ")";
1904
1905
		dol_syslog(get_class($this) . "::select_account sql=" . $sql, LOG_DEBUG);
1906
		$resql = $this->db->query($sql);
1907
		if ($resql) {
1908
			$obj = '';
1909
			if ($this->db->num_rows($resql)) {
1910
				$obj = $this->db->fetch_object($resql);
1911
			}
1912
			if(empty($obj->category)){
1913
				return $obj->label;
1914
			}else{
1915
				return $obj->label.' ('.$obj->category.')';
1916
			}
1917
		} else {
1918
			$this->error = "Error " . $this->db->lasterror();
1919
			dol_syslog(__METHOD__ . " " . $this->error, LOG_ERR);
1920
			return -1;
1921
		}
1922
	}
1923
}
1924
1925
/**
1926
 * Class BookKeepingLine
1927
 */
1928
class BookKeepingLine
1929
{
1930
	/**
1931
	 * @var int ID
1932
	 */
1933
	public $id;
1934
1935
	public $doc_date = '';
1936
	public $doc_type;
1937
	public $doc_ref;
1938
1939
	/**
1940
     * @var int ID
1941
     */
1942
	public $fk_doc;
1943
1944
	/**
1945
     * @var int ID
1946
     */
1947
	public $fk_docdet;
1948
1949
	public $thirdparty_code;
1950
	public $subledger_account;
1951
	public $subledger_label;
1952
	public $numero_compte;
1953
	public $label_compte;
1954
	public $label_operation;
1955
	public $debit;
1956
	public $credit;
1957
	public $montant;
1958
	public $sens;
1959
1960
	/**
1961
     * @var int ID
1962
     */
1963
	public $fk_user_author;
1964
1965
	public $import_key;
1966
	public $code_journal;
1967
	public $journal_label;
1968
	public $piece_num;
1969
	public $date_creation;
1970
}
1971