1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* Copyright (C) 2007-2012 Laurent Destailleur <[email protected]> |
5
|
|
|
* Copyright (C) 2014 Juanjo Menent <[email protected]> |
6
|
|
|
* Copyright (C) 2015 Florian Henry <[email protected]> |
7
|
|
|
* Copyright (C) 2015 Raphaël Doursenaud <[email protected]> |
8
|
|
|
* Copyright (C) 2016 Pierre-Henry Favre <[email protected]> |
9
|
|
|
* Copyright (C) 2016-2020 Alexandre Spangaro <[email protected]> |
10
|
|
|
* Copyright (C) 2013-2017 Olivier Geffroy <[email protected]> |
11
|
|
|
* Copyright (C) 2017 Elarifr. Ari Elbaz <[email protected]> |
12
|
|
|
* Copyright (C) 2017-2019 Frédéric France <[email protected]> |
13
|
|
|
* Copyright (C) 2017 André Schild <[email protected]> |
14
|
|
|
* Copyright (C) 2020 Guillaume Alexandre <[email protected]> |
15
|
|
|
* Copyright (C) 2024 Rafael San José <[email protected]> |
16
|
|
|
* |
17
|
|
|
* This program is free software; you can redistribute it and/or modify |
18
|
|
|
* it under the terms of the GNU General Public License as published by |
19
|
|
|
* the Free Software Foundation; either version 3 of the License, or |
20
|
|
|
* (at your option) any later version. |
21
|
|
|
* |
22
|
|
|
* This program is distributed in the hope that it will be useful, |
23
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
24
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
25
|
|
|
* GNU General Public License for more details. |
26
|
|
|
* |
27
|
|
|
* You should have received a copy of the GNU General Public License |
28
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. |
29
|
|
|
*/ |
30
|
|
|
|
31
|
|
|
namespace Dolibarr\Code\Accountancy\Classes; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* \file htdocs/accountancy/class/accountancyimport.class.php |
35
|
|
|
* \ingroup Accountancy (Double entries) |
36
|
|
|
* \brief Class with methods for accountancy import |
37
|
|
|
*/ |
38
|
|
|
|
39
|
|
|
|
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Manage the different format accountancy import |
43
|
|
|
*/ |
44
|
|
|
class AccountancyImport |
45
|
|
|
{ |
46
|
|
|
/** |
47
|
|
|
* @var DoliDB Database handler |
|
|
|
|
48
|
|
|
*/ |
49
|
|
|
public $db; |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @var string[] Array of error strings |
53
|
|
|
*/ |
54
|
|
|
public $errors = array(); |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* Constructor |
58
|
|
|
* |
59
|
|
|
* @param DoliDB $db Database handler |
60
|
|
|
*/ |
61
|
|
|
public function __construct(DoliDB $db) |
62
|
|
|
{ |
63
|
|
|
$this->db = $db; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Clean amount |
68
|
|
|
* |
69
|
|
|
* @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... |
70
|
|
|
* @param array $listfields Fields list to add |
71
|
|
|
* @param int $record_key Record key |
72
|
|
|
* @return float Value |
73
|
|
|
*/ |
74
|
|
|
public function cleanAmount(&$arrayrecord, $listfields, $record_key) |
75
|
|
|
{ |
76
|
|
|
$value_trim = trim($arrayrecord[$record_key]['val']); |
77
|
|
|
return (float) price2num($value_trim); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Clean value with trim |
82
|
|
|
* |
83
|
|
|
* @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... |
84
|
|
|
* @param array $listfields Fields list to add |
85
|
|
|
* @param int $record_key Record key |
86
|
|
|
* @return mixed Value |
87
|
|
|
*/ |
88
|
|
|
public function cleanValue(&$arrayrecord, $listfields, $record_key) |
89
|
|
|
{ |
90
|
|
|
return trim($arrayrecord[$record_key]['val']); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Compute amount |
95
|
|
|
* |
96
|
|
|
* @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... |
97
|
|
|
* @param array $listfields Fields list to add |
98
|
|
|
* @param int $record_key Record key |
99
|
|
|
* @return string Value |
100
|
|
|
*/ |
101
|
|
|
public function computeAmount(&$arrayrecord, $listfields, $record_key) |
102
|
|
|
{ |
103
|
|
|
// get fields indexes |
104
|
|
|
if (isset($listfields['b.debit']) && isset($listfields['b.credit'])) { |
105
|
|
|
$debit_index = $listfields['b.debit']; |
106
|
|
|
|
107
|
|
|
$debitFloat = (float) price2num($arrayrecord[$debit_index]['val']); |
108
|
|
|
if (!empty($debitFloat)) { |
109
|
|
|
$amount = $debitFloat; |
110
|
|
|
} else { |
111
|
|
|
$credit_index = $listfields['b.credit']; |
112
|
|
|
$amount = (float) price2num($arrayrecord[$credit_index]['val']); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
return "'" . $this->db->escape(abs($amount)) . "'"; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
return "''"; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* Compute direction |
124
|
|
|
* |
125
|
|
|
* @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... |
126
|
|
|
* @param array $listfields Fields list to add |
127
|
|
|
* @param int $record_key Record key |
128
|
|
|
* @return string Value |
129
|
|
|
*/ |
130
|
|
|
public function computeDirection(&$arrayrecord, $listfields, $record_key) |
131
|
|
|
{ |
132
|
|
|
if (isset($listfields['b.debit'])) { |
133
|
|
|
$debit_index = $listfields['b.debit']; |
134
|
|
|
|
135
|
|
|
$debitFloat = (float) price2num($arrayrecord[$debit_index]['val']); |
136
|
|
|
if (!empty($debitFloat)) { |
137
|
|
|
$sens = 'D'; |
138
|
|
|
} else { |
139
|
|
|
$sens = 'C'; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
return "'" . $this->db->escape($sens) . "'"; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
return "''"; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Compute piece number |
150
|
|
|
* |
151
|
|
|
* @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... |
152
|
|
|
* @param array $listfields Fields list to add |
153
|
|
|
* @param int $record_key Record key |
154
|
|
|
* @return string Value |
155
|
|
|
*/ |
156
|
|
|
public function computePieceNum(&$arrayrecord, $listfields, $record_key) |
157
|
|
|
{ |
158
|
|
|
global $conf; |
159
|
|
|
|
160
|
|
|
$pieceNum = trim($arrayrecord[$record_key]['val']); |
161
|
|
|
|
162
|
|
|
// auto-determine the next value for piece number |
163
|
|
|
if ($pieceNum == '') { |
164
|
|
|
if (isset($listfields['b.code_journal']) && isset($listfields['b.doc_date'])) { |
165
|
|
|
// define memory for last record values and keep next piece number |
166
|
|
|
if (!isset($conf->cache['accounting'])) { |
167
|
|
|
$conf->cache['accounting'] = array( |
168
|
|
|
'lastRecordCompareValues' => array(), |
169
|
|
|
'nextPieceNum' => 0, |
170
|
|
|
); |
171
|
|
|
} |
172
|
|
|
$codeJournalIndex = $listfields['b.code_journal']; |
173
|
|
|
$docDateIndex = $listfields['b.doc_date']; |
174
|
|
|
$atLeastOneLastRecordChanged = false; |
175
|
|
|
if (empty($conf->cache['accounting']['lastRecordCompareValues'])) { |
176
|
|
|
$atLeastOneLastRecordChanged = true; |
177
|
|
|
} else { |
178
|
|
|
if ( |
179
|
|
|
$arrayrecord[$codeJournalIndex]['val'] != $conf->cache['accounting']['lastRecordCompareValues']['b.code_journal'] |
180
|
|
|
|| $arrayrecord[$docDateIndex]['val'] != $conf->cache['accounting']['lastRecordCompareValues']['b.doc_date'] |
181
|
|
|
) { |
182
|
|
|
$atLeastOneLastRecordChanged = true; |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
// at least one record value has changed, so we search for the next piece number from database or increment it |
187
|
|
|
if ($atLeastOneLastRecordChanged === true) { |
188
|
|
|
$lastPieceNum = 0; |
189
|
|
|
if (empty($conf->cache['accounting']['nextPieceNum'])) { |
190
|
|
|
// get last piece number from database |
191
|
|
|
$sql = "SELECT MAX(piece_num) as last_piece_num"; |
192
|
|
|
$sql .= " FROM " . $this->db->prefix() . "accounting_bookkeeping"; |
193
|
|
|
$sql .= " WHERE entity IN (" . getEntity('accountingbookkeeping') . ")"; |
194
|
|
|
$res = $this->db->query($sql); |
195
|
|
|
if (!$res) { |
196
|
|
|
$this->errors[] = $this->db->lasterror(); |
197
|
|
|
return ''; |
198
|
|
|
} |
199
|
|
|
if ($obj = $this->db->fetch_object($res)) { |
200
|
|
|
$lastPieceNum = (int) $obj->last_piece_num; |
201
|
|
|
} |
202
|
|
|
$this->db->free($res); |
203
|
|
|
} |
204
|
|
|
// set next piece number in memory |
205
|
|
|
if (empty($conf->cache['accounting']['nextPieceNum'])) { |
206
|
|
|
$conf->cache['accounting']['nextPieceNum'] = $lastPieceNum; |
207
|
|
|
} |
208
|
|
|
$conf->cache['accounting']['nextPieceNum']++; |
209
|
|
|
|
210
|
|
|
// set last records values in memory |
211
|
|
|
$conf->cache['accounting']['lastRecordCompareValues'] = array( |
212
|
|
|
'b.code_journal' => $arrayrecord[$codeJournalIndex]['val'], |
213
|
|
|
'b.doc_date' => $arrayrecord[$docDateIndex]['val'], |
214
|
|
|
); |
215
|
|
|
} |
216
|
|
|
$pieceNum = (string) $conf->cache['accounting']['nextPieceNum']; |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
return $pieceNum; |
221
|
|
|
} |
222
|
|
|
} |
223
|
|
|
|