|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* Copyright (C) 2003-2005 Rodolphe Quiedeville <[email protected]> |
|
4
|
|
|
* Copyright (C) 2004-2010 Laurent Destailleur <[email protected]> |
|
5
|
|
|
* Copyright (C) 2004 Eric Seigne <[email protected]> |
|
6
|
|
|
* Copyright (C) 2005-2012 Regis Houssin <[email protected]> |
|
7
|
|
|
* Copyright (C) 2015 Marcos García <[email protected]> |
|
8
|
|
|
* Copyright (C) 2016-2023 Charlene Benke <[email protected]> |
|
9
|
|
|
* Copyright (C) 2018-2024 Frédéric France <[email protected]> |
|
10
|
|
|
* Copyright (C) 2020 Josep Lluís Amador <[email protected]> |
|
11
|
|
|
* Copyright (C) 2024 MDW <[email protected]> |
|
12
|
|
|
* Copyright (C) 2024 Mélina Joum <[email protected]> |
|
13
|
|
|
* Copyright (C) 2024 Rafael San José <[email protected]> |
|
14
|
|
|
* |
|
15
|
|
|
* This program is free software; you can redistribute it and/or modify |
|
16
|
|
|
* it under the terms of the GNU General Public License as published by |
|
17
|
|
|
* the Free Software Foundation; either version 3 of the License, or |
|
18
|
|
|
* (at your option) any later version. |
|
19
|
|
|
* |
|
20
|
|
|
* This program is distributed in the hope that it will be useful, |
|
21
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
22
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
23
|
|
|
* GNU General Public License for more details. |
|
24
|
|
|
* |
|
25
|
|
|
* You should have received a copy of the GNU General Public License |
|
26
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. |
|
27
|
|
|
* or see https://www.gnu.org/ |
|
28
|
|
|
*/ |
|
29
|
|
|
|
|
30
|
|
|
namespace Dolibarr\Code\Core\Classes; |
|
31
|
|
|
|
|
32
|
|
|
use Dolibarr\Code\Adherents\Classes\Adherent; |
|
33
|
|
|
use Dolibarr\Code\Compta\Classes\Account; |
|
34
|
|
|
use Dolibarr\Code\Compta\Classes\Facture; |
|
35
|
|
|
use Dolibarr\Code\Contact\Classes\Contact; |
|
36
|
|
|
use Dolibarr\Code\Expedition\Classes\Expedition; |
|
37
|
|
|
use Dolibarr\Code\Fourn\Classes\CommandeFournisseur; |
|
38
|
|
|
use Dolibarr\Code\Product\Classes\Product; |
|
39
|
|
|
use Dolibarr\Code\Societe\Classes\Societe; |
|
40
|
|
|
use Dolibarr\Code\User\Classes\User; |
|
41
|
|
|
use Dolibarr\Core\Base\CommonObject; |
|
42
|
|
|
use Dolibarr\Core\Base\CommonObjectLine; |
|
43
|
|
|
use DoliDB; |
|
44
|
|
|
use stdClass; |
|
45
|
|
|
|
|
46
|
|
|
/** |
|
47
|
|
|
* \file htdocs/core/class/commondocgenerator.class.php |
|
48
|
|
|
* \ingroup core |
|
49
|
|
|
* \brief File of parent class for documents generators |
|
50
|
|
|
*/ |
|
51
|
|
|
|
|
52
|
|
|
|
|
53
|
|
|
/** |
|
54
|
|
|
* Parent class for documents (PDF, ODT, ...) generators |
|
55
|
|
|
*/ |
|
56
|
|
|
abstract class CommonDocGenerator |
|
57
|
|
|
{ |
|
58
|
|
|
/** |
|
59
|
|
|
* @var string Model name |
|
60
|
|
|
*/ |
|
61
|
|
|
public $name = ''; |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* @var string Version |
|
65
|
|
|
*/ |
|
66
|
|
|
public $version = ''; |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* @var string Error code (or message) |
|
70
|
|
|
*/ |
|
71
|
|
|
public $error = ''; |
|
72
|
|
|
|
|
73
|
|
|
/** |
|
74
|
|
|
* @var string[] Array of error strings |
|
75
|
|
|
*/ |
|
76
|
|
|
public $errors = array(); |
|
77
|
|
|
|
|
78
|
|
|
/** |
|
79
|
|
|
* @var DoliDB Database handler. |
|
80
|
|
|
*/ |
|
81
|
|
|
protected $db; |
|
82
|
|
|
|
|
83
|
|
|
/** |
|
84
|
|
|
* @var ?Extrafields object |
|
85
|
|
|
*/ |
|
86
|
|
|
public $extrafieldsCache; |
|
87
|
|
|
|
|
88
|
|
|
/** |
|
89
|
|
|
* @var int If set to 1, save the fullname of generated file with path as the main doc when generating a doc with this template. |
|
90
|
|
|
*/ |
|
91
|
|
|
public $update_main_doc_field; |
|
92
|
|
|
|
|
93
|
|
|
/** |
|
94
|
|
|
* @var string The name of constant to use to scan ODT files (Example: 'COMMANDE_ADDON_PDF_ODT_PATH') |
|
95
|
|
|
*/ |
|
96
|
|
|
public $scandir; |
|
97
|
|
|
|
|
98
|
|
|
/** |
|
99
|
|
|
* @var string model description (short text) |
|
100
|
|
|
*/ |
|
101
|
|
|
public $description; |
|
102
|
|
|
|
|
103
|
|
|
/** |
|
104
|
|
|
* @var array |
|
105
|
|
|
*/ |
|
106
|
|
|
public $format; |
|
107
|
|
|
|
|
108
|
|
|
/** |
|
109
|
|
|
* @var string pdf, odt, etc |
|
110
|
|
|
*/ |
|
111
|
|
|
public $type; |
|
112
|
|
|
|
|
113
|
|
|
public $page_hauteur; |
|
114
|
|
|
public $page_largeur; |
|
115
|
|
|
public $marge_gauche; |
|
116
|
|
|
public $marge_droite; |
|
117
|
|
|
public $marge_haute; |
|
118
|
|
|
public $marge_basse; |
|
119
|
|
|
|
|
120
|
|
|
public $option_logo; |
|
121
|
|
|
public $option_tva; |
|
122
|
|
|
public $option_multilang; |
|
123
|
|
|
public $option_freetext; |
|
124
|
|
|
public $option_draft_watermark; |
|
125
|
|
|
public $watermark; |
|
126
|
|
|
|
|
127
|
|
|
public $option_modereg; |
|
128
|
|
|
public $option_condreg; |
|
129
|
|
|
public $option_escompte; |
|
130
|
|
|
public $option_credit_note; |
|
131
|
|
|
|
|
132
|
|
|
public $tva; |
|
133
|
|
|
public $tva_array; |
|
134
|
|
|
/** |
|
135
|
|
|
* Local tax rates Array[tax_type][tax_rate] |
|
136
|
|
|
* |
|
137
|
|
|
* @var array<int,array<string,float>> |
|
138
|
|
|
*/ |
|
139
|
|
|
public $localtax1; |
|
140
|
|
|
|
|
141
|
|
|
/** |
|
142
|
|
|
* Local tax rates Array[tax_type][tax_rate] |
|
143
|
|
|
* |
|
144
|
|
|
* @var array<int,array<string,float>> |
|
145
|
|
|
*/ |
|
146
|
|
|
public $localtax2; |
|
147
|
|
|
|
|
148
|
|
|
/** |
|
149
|
|
|
* @var int Tab Title Height |
|
150
|
|
|
*/ |
|
151
|
|
|
public $tabTitleHeight; |
|
152
|
|
|
|
|
153
|
|
|
/** |
|
154
|
|
|
* @var array default title fields style |
|
155
|
|
|
*/ |
|
156
|
|
|
public $defaultTitlesFieldsStyle; |
|
157
|
|
|
|
|
158
|
|
|
/** |
|
159
|
|
|
* @var array default content fields style |
|
160
|
|
|
*/ |
|
161
|
|
|
public $defaultContentsFieldsStyle; |
|
162
|
|
|
|
|
163
|
|
|
/** |
|
164
|
|
|
* @var Societe Issuer of document |
|
165
|
|
|
*/ |
|
166
|
|
|
public $emetteur; |
|
167
|
|
|
|
|
168
|
|
|
/** |
|
169
|
|
|
* @var array{0:int,1:int} Minimum version of PHP required by module. |
|
170
|
|
|
* e.g.: PHP ≥ 7.1 = array(7, 1) |
|
171
|
|
|
*/ |
|
172
|
|
|
public $phpmin = array(7, 1); |
|
173
|
|
|
|
|
174
|
|
|
/** |
|
175
|
|
|
* @var array<string,array{rank:int,width:float|int,title:array{textkey:string,label:string,align:string,padding:array{0:float,1:float,2:float,3:float}},content:array{align:string,padding:array{0:float,1:float,2:float,3:float}}}> Array of columns |
|
176
|
|
|
*/ |
|
177
|
|
|
public $cols; |
|
178
|
|
|
|
|
179
|
|
|
/** |
|
180
|
|
|
* @var array{fullpath:string} Array with result of doc generation. content is array('fullpath'=>$file) |
|
181
|
|
|
*/ |
|
182
|
|
|
public $result; |
|
183
|
|
|
|
|
184
|
|
|
public $posxlabel; |
|
185
|
|
|
public $posxup; |
|
186
|
|
|
public $posxref; |
|
187
|
|
|
public $posxpicture; // For picture |
|
188
|
|
|
public $posxdesc; // For description |
|
189
|
|
|
public $posxqty; |
|
190
|
|
|
public $posxpuht; |
|
191
|
|
|
public $posxtva; |
|
192
|
|
|
public $posxtotalht; |
|
193
|
|
|
public $postotalht; |
|
194
|
|
|
public $posxunit; |
|
195
|
|
|
public $posxdiscount; |
|
196
|
|
|
public $posxworkload; |
|
197
|
|
|
public $posxtimespent; |
|
198
|
|
|
public $posxprogress; |
|
199
|
|
|
public $atleastonephoto; |
|
200
|
|
|
public $atleastoneratenotnull; |
|
201
|
|
|
public $atleastonediscount; |
|
202
|
|
|
|
|
203
|
|
|
/** |
|
204
|
|
|
* Constructor |
|
205
|
|
|
* |
|
206
|
|
|
* @param DoliDB $db Database handler |
|
207
|
|
|
*/ |
|
208
|
|
|
public function __construct($db) |
|
209
|
|
|
{ |
|
210
|
|
|
$this->db = $db; |
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
|
|
214
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
|
215
|
|
|
/** |
|
216
|
|
|
* Define array with couple substitution key => substitution value |
|
217
|
|
|
* |
|
218
|
|
|
* @param User $user User |
|
219
|
|
|
* @param Translate $outputlangs Language object for output |
|
220
|
|
|
* @return array Array of substitution key->code |
|
221
|
|
|
*/ |
|
222
|
|
|
public function get_substitutionarray_user($user, $outputlangs) |
|
223
|
|
|
{ |
|
224
|
|
|
// phpcs:enable |
|
225
|
|
|
global $conf, $extrafields; |
|
226
|
|
|
|
|
227
|
|
|
$logotouse = $conf->user->dir_output . '/' . get_exdir(0, 0, 0, 0, $user, 'user') . 'photos/' . getImageFileNameForSize($user->photo, '_small'); |
|
228
|
|
|
|
|
229
|
|
|
$array_user = array( |
|
230
|
|
|
'myuser_lastname' => $user->lastname, |
|
231
|
|
|
'myuser_firstname' => $user->firstname, |
|
232
|
|
|
'myuser_fullname' => $user->getFullName($outputlangs, 1), |
|
233
|
|
|
'myuser_login' => $user->login, |
|
234
|
|
|
'myuser_phone' => $user->office_phone, |
|
235
|
|
|
'myuser_address' => $user->address, |
|
236
|
|
|
'myuser_zip' => $user->zip, |
|
237
|
|
|
'myuser_town' => $user->town, |
|
238
|
|
|
'myuser_country' => $user->country, |
|
239
|
|
|
'myuser_country_code' => $user->country_code, |
|
240
|
|
|
'myuser_state' => $user->state, |
|
241
|
|
|
'myuser_state_code' => $user->state_code, |
|
242
|
|
|
'myuser_fax' => $user->office_fax, |
|
243
|
|
|
'myuser_mobile' => $user->user_mobile, |
|
244
|
|
|
'myuser_email' => $user->email, |
|
245
|
|
|
'myuser_logo' => $logotouse, |
|
246
|
|
|
'myuser_job' => $user->job, |
|
247
|
|
|
'myuser_web' => '', // url not exist in $user object |
|
248
|
|
|
'myuser_birth' => dol_print_date($user->birth, 'day', 'gmt'), |
|
249
|
|
|
'myuser_dateemployment' => dol_print_date($user->dateemployment, 'day', 'tzuser'), |
|
250
|
|
|
'myuser_dateemploymentend' => dol_print_date($user->dateemploymentend, 'day', 'tzuser'), |
|
251
|
|
|
'myuser_gender' => $user->gender, |
|
252
|
|
|
); |
|
253
|
|
|
// Retrieve extrafields |
|
254
|
|
|
if (is_array($user->array_options) && count($user->array_options)) { |
|
255
|
|
|
if (empty($extrafields->attributes[$user->table_element])) { |
|
256
|
|
|
$extrafields->fetch_name_optionals_label($user->table_element); |
|
257
|
|
|
} |
|
258
|
|
|
$array_user = $this->fill_substitutionarray_with_extrafields($user, $array_user, $extrafields, 'myuser', $outputlangs); |
|
259
|
|
|
} |
|
260
|
|
|
return $array_user; |
|
261
|
|
|
} |
|
262
|
|
|
|
|
263
|
|
|
|
|
264
|
|
|
/** |
|
265
|
|
|
* Define array with couple substitution key => substitution value |
|
266
|
|
|
* |
|
267
|
|
|
* @param Adherent $member Member |
|
268
|
|
|
* @param Translate $outputlangs Language object for output |
|
269
|
|
|
* @return array Array of substitution key->code |
|
270
|
|
|
*/ |
|
271
|
|
|
public function getSubstitutionarrayMember($member, $outputlangs) |
|
272
|
|
|
{ |
|
273
|
|
|
global $conf, $extrafields; |
|
274
|
|
|
|
|
275
|
|
|
if ($member->photo) { |
|
276
|
|
|
$logotouse = $conf->member->dir_output . '/' . get_exdir(0, 0, 0, 1, $member, 'user') . '/photos/' . $member->photo; |
|
277
|
|
|
} else { |
|
278
|
|
|
$logotouse = DOL_DOCUMENT_ROOT . '/public/theme/common/nophoto.png'; |
|
279
|
|
|
} |
|
280
|
|
|
|
|
281
|
|
|
$array_member = array( |
|
282
|
|
|
'mymember_lastname' => $member->lastname, |
|
283
|
|
|
'mymember_firstname' => $member->firstname, |
|
284
|
|
|
'mymember_fullname' => $member->getFullName($outputlangs, 1), |
|
285
|
|
|
'mymember_login' => $member->login, |
|
286
|
|
|
'mymember_address' => $member->address, |
|
287
|
|
|
'mymember_zip' => $member->zip, |
|
288
|
|
|
'mymember_town' => $member->town, |
|
289
|
|
|
'mymember_country_code' => $member->country_code, |
|
290
|
|
|
'mymember_country' => $member->country, |
|
291
|
|
|
'mymember_state_code' => $member->state_code, |
|
292
|
|
|
'mymember_state' => $member->state, |
|
293
|
|
|
'mymember_phone_perso' => $member->phone_perso, |
|
294
|
|
|
'mymember_phone_pro' => $member->phone, |
|
295
|
|
|
'mymember_phone_mobile' => $member->phone_mobile, |
|
296
|
|
|
'mymember_email' => $member->email, |
|
297
|
|
|
'mymember_logo' => $logotouse, |
|
298
|
|
|
'mymember_gender' => $member->gender, |
|
299
|
|
|
'mymember_birth_locale' => dol_print_date($member->birth, 'day', 'tzuser', $outputlangs), |
|
300
|
|
|
'mymember_birth' => dol_print_date($member->birth, 'day', 'tzuser'), |
|
301
|
|
|
); |
|
302
|
|
|
// Retrieve extrafields |
|
303
|
|
|
if (is_array($member->array_options) && count($member->array_options)) { |
|
304
|
|
|
$array_member = $this->fill_substitutionarray_with_extrafields($member, $array_member, $extrafields, 'mymember', $outputlangs); |
|
305
|
|
|
} |
|
306
|
|
|
return $array_member; |
|
307
|
|
|
} |
|
308
|
|
|
|
|
309
|
|
|
|
|
310
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
|
311
|
|
|
/** |
|
312
|
|
|
* Define array with couple substitution key => substitution value |
|
313
|
|
|
* |
|
314
|
|
|
* @param Societe $mysoc Object thirdparty |
|
315
|
|
|
* @param Translate $outputlangs Language object for output |
|
316
|
|
|
* @return array Array of substitution key->code |
|
317
|
|
|
*/ |
|
318
|
|
|
public function get_substitutionarray_mysoc($mysoc, $outputlangs) |
|
319
|
|
|
{ |
|
320
|
|
|
// phpcs:enable |
|
321
|
|
|
global $conf; |
|
322
|
|
|
|
|
323
|
|
|
if (empty($mysoc->forme_juridique) && !empty($mysoc->forme_juridique_code)) { |
|
324
|
|
|
$mysoc->forme_juridique = getFormeJuridiqueLabel($mysoc->forme_juridique_code); |
|
325
|
|
|
} |
|
326
|
|
|
if (empty($mysoc->country) && !empty($mysoc->country_code)) { |
|
327
|
|
|
$mysoc->country = $outputlangs->transnoentitiesnoconv("Country" . $mysoc->country_code); |
|
328
|
|
|
} |
|
329
|
|
|
if (empty($mysoc->state) && !empty($mysoc->state_code)) { |
|
330
|
|
|
$mysoc->state = getState($mysoc->state_code, 0); |
|
331
|
|
|
} |
|
332
|
|
|
|
|
333
|
|
|
$logotouse = $conf->mycompany->dir_output . '/logos/thumbs/' . $mysoc->logo_small; |
|
334
|
|
|
|
|
335
|
|
|
return array( |
|
336
|
|
|
'mycompany_logo' => $logotouse, |
|
337
|
|
|
'mycompany_name' => $mysoc->name, |
|
338
|
|
|
'mycompany_email' => $mysoc->email, |
|
339
|
|
|
'mycompany_phone' => $mysoc->phone, |
|
340
|
|
|
'mycompany_fax' => $mysoc->fax, |
|
341
|
|
|
'mycompany_address' => $mysoc->address, |
|
342
|
|
|
'mycompany_zip' => $mysoc->zip, |
|
343
|
|
|
'mycompany_town' => $mysoc->town, |
|
344
|
|
|
'mycompany_country' => $mysoc->country, |
|
345
|
|
|
'mycompany_country_code' => $mysoc->country_code, |
|
346
|
|
|
'mycompany_state' => $mysoc->state, |
|
347
|
|
|
'mycompany_state_code' => $mysoc->state_code, |
|
348
|
|
|
'mycompany_web' => $mysoc->url, |
|
349
|
|
|
'mycompany_juridicalstatus' => $mysoc->forme_juridique, |
|
350
|
|
|
'mycompany_managers' => $mysoc->managers, |
|
351
|
|
|
'mycompany_capital' => $mysoc->capital, |
|
352
|
|
|
'mycompany_barcode' => $mysoc->barcode, |
|
353
|
|
|
'mycompany_idprof1' => $mysoc->idprof1, |
|
354
|
|
|
'mycompany_idprof2' => $mysoc->idprof2, |
|
355
|
|
|
'mycompany_idprof3' => $mysoc->idprof3, |
|
356
|
|
|
'mycompany_idprof4' => $mysoc->idprof4, |
|
357
|
|
|
'mycompany_idprof5' => $mysoc->idprof5, |
|
358
|
|
|
'mycompany_idprof6' => $mysoc->idprof6, |
|
359
|
|
|
'mycompany_vatnumber' => $mysoc->tva_intra, |
|
360
|
|
|
'mycompany_socialobject' => $mysoc->socialobject, |
|
361
|
|
|
'mycompany_note_private' => $mysoc->note_private, |
|
362
|
|
|
//'mycompany_note_public'=>$mysoc->note_public, // Only private not exists for "mysoc" but both for thirdparties |
|
363
|
|
|
); |
|
364
|
|
|
} |
|
365
|
|
|
|
|
366
|
|
|
|
|
367
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
|
368
|
|
|
/** |
|
369
|
|
|
* Define array with couple substitution key => substitution value |
|
370
|
|
|
* For example {company_name}, {company_name_alias} |
|
371
|
|
|
* |
|
372
|
|
|
* @param Societe $object Object |
|
373
|
|
|
* @param Translate $outputlangs Language object for output |
|
374
|
|
|
* @param string $array_key Name of the key for return array |
|
375
|
|
|
* @return array Array of substitution key->code |
|
376
|
|
|
*/ |
|
377
|
|
|
public function get_substitutionarray_thirdparty($object, $outputlangs, $array_key = 'company') |
|
378
|
|
|
{ |
|
379
|
|
|
// phpcs:enable |
|
380
|
|
|
global $extrafields; |
|
381
|
|
|
|
|
382
|
|
|
if (empty($object->country) && !empty($object->country_code)) { |
|
383
|
|
|
$object->country = $outputlangs->transnoentitiesnoconv("Country" . $object->country_code); |
|
384
|
|
|
} |
|
385
|
|
|
if (empty($object->state) && !empty($object->state_code)) { |
|
386
|
|
|
$object->state = getState($object->state_code, 0); |
|
387
|
|
|
} |
|
388
|
|
|
|
|
389
|
|
|
$array_thirdparty = array( |
|
390
|
|
|
'company_name' => $object->name, |
|
391
|
|
|
'company_name_alias' => $object->name_alias, |
|
392
|
|
|
'company_email' => $object->email, |
|
393
|
|
|
'company_phone' => $object->phone, |
|
394
|
|
|
'company_fax' => $object->fax, |
|
395
|
|
|
'company_address' => $object->address, |
|
396
|
|
|
'company_zip' => $object->zip, |
|
397
|
|
|
'company_town' => $object->town, |
|
398
|
|
|
'company_country' => $object->country, |
|
399
|
|
|
'company_country_code' => $object->country_code, |
|
400
|
|
|
'company_state' => $object->state, |
|
401
|
|
|
'company_state_code' => $object->state_code, |
|
402
|
|
|
'company_web' => $object->url, |
|
403
|
|
|
'company_barcode' => $object->barcode, |
|
404
|
|
|
'company_vatnumber' => $object->tva_intra, |
|
405
|
|
|
'company_customercode' => $object->code_client, |
|
406
|
|
|
'company_suppliercode' => $object->code_fournisseur, |
|
407
|
|
|
'company_customeraccountancycode' => $object->code_compta_client, |
|
408
|
|
|
'company_supplieraccountancycode' => $object->code_compta_fournisseur, |
|
409
|
|
|
'company_juridicalstatus' => $object->forme_juridique, |
|
410
|
|
|
'company_outstanding_limit' => $object->outstanding_limit, |
|
411
|
|
|
'company_capital' => $object->capital, |
|
412
|
|
|
'company_capital_formated' => price($object->capital, 0, '', 1, -1), |
|
413
|
|
|
'company_idprof1' => $object->idprof1, |
|
414
|
|
|
'company_idprof2' => $object->idprof2, |
|
415
|
|
|
'company_idprof3' => $object->idprof3, |
|
416
|
|
|
'company_idprof4' => $object->idprof4, |
|
417
|
|
|
'company_idprof5' => $object->idprof5, |
|
418
|
|
|
'company_idprof6' => $object->idprof6, |
|
419
|
|
|
'company_note_public' => $object->note_public, |
|
420
|
|
|
'company_note_private' => $object->note_private, |
|
421
|
|
|
'company_default_bank_iban' => (is_object($object->bank_account) ? $object->bank_account->iban : ''), |
|
422
|
|
|
'company_default_bank_bic' => (is_object($object->bank_account) ? $object->bank_account->bic : '') |
|
423
|
|
|
); |
|
424
|
|
|
|
|
425
|
|
|
// Retrieve extrafields |
|
426
|
|
|
if (is_array($object->array_options) && count($object->array_options)) { |
|
427
|
|
|
$object->fetch_optionals(); |
|
428
|
|
|
|
|
429
|
|
|
$array_thirdparty = $this->fill_substitutionarray_with_extrafields($object, $array_thirdparty, $extrafields, $array_key, $outputlangs); |
|
430
|
|
|
} |
|
431
|
|
|
return $array_thirdparty; |
|
432
|
|
|
} |
|
433
|
|
|
|
|
434
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
|
435
|
|
|
/** |
|
436
|
|
|
* Define array with couple substitution key => substitution value |
|
437
|
|
|
* |
|
438
|
|
|
* @param Contact $object contact |
|
439
|
|
|
* @param Translate $outputlangs object for output |
|
440
|
|
|
* @param string $array_key Name of the key for return array |
|
441
|
|
|
* @return array Array of substitution key->code |
|
442
|
|
|
*/ |
|
443
|
|
|
public function get_substitutionarray_contact($object, $outputlangs, $array_key = 'object') |
|
444
|
|
|
{ |
|
445
|
|
|
// phpcs:enable |
|
446
|
|
|
global $conf, $extrafields; |
|
447
|
|
|
|
|
448
|
|
|
if (empty($object->country) && !empty($object->country_code)) { |
|
449
|
|
|
$object->country = $outputlangs->transnoentitiesnoconv("Country" . $object->country_code); |
|
450
|
|
|
} |
|
451
|
|
|
if (empty($object->state) && !empty($object->state_code)) { |
|
452
|
|
|
$object->state = getState($object->state_code, 0); |
|
|
|
|
|
|
453
|
|
|
} |
|
454
|
|
|
|
|
455
|
|
|
$array_contact = array( |
|
456
|
|
|
$array_key . '_fullname' => $object->getFullName($outputlangs, 1), |
|
457
|
|
|
$array_key . '_lastname' => $object->lastname, |
|
458
|
|
|
$array_key . '_firstname' => $object->firstname, |
|
459
|
|
|
$array_key . '_address' => $object->address, |
|
460
|
|
|
$array_key . '_zip' => $object->zip, |
|
461
|
|
|
$array_key . '_town' => $object->town, |
|
462
|
|
|
$array_key . '_state_id' => $object->state_id, |
|
463
|
|
|
$array_key . '_state_code' => $object->state_code, |
|
464
|
|
|
$array_key . '_state' => $object->state, |
|
465
|
|
|
$array_key . '_country_id' => $object->country_id, |
|
466
|
|
|
$array_key . '_country_code' => $object->country_code, |
|
467
|
|
|
$array_key . '_country' => $object->country, |
|
468
|
|
|
$array_key . '_poste' => $object->poste, |
|
469
|
|
|
$array_key . '_socid' => $object->socid, |
|
470
|
|
|
$array_key . '_statut' => $object->statut, |
|
471
|
|
|
$array_key . '_code' => $object->code, |
|
472
|
|
|
$array_key . '_email' => $object->email, |
|
473
|
|
|
$array_key . '_phone_pro' => $object->phone_pro, |
|
474
|
|
|
$array_key . '_phone_perso' => $object->phone_perso, |
|
475
|
|
|
$array_key . '_phone_mobile' => $object->phone_mobile, |
|
476
|
|
|
$array_key . '_fax' => $object->fax, |
|
477
|
|
|
$array_key . '_birthday' => $object->birthday, |
|
478
|
|
|
$array_key . '_default_lang' => $object->default_lang, |
|
479
|
|
|
$array_key . '_note_public' => $object->note_public, |
|
480
|
|
|
$array_key . '_note_private' => $object->note_private, |
|
481
|
|
|
$array_key . '_civility' => $object->civility, |
|
482
|
|
|
); |
|
483
|
|
|
|
|
484
|
|
|
// Retrieve extrafields |
|
485
|
|
|
if (is_array($object->array_options) && count($object->array_options)) { |
|
486
|
|
|
$object->fetch_optionals(); |
|
487
|
|
|
|
|
488
|
|
|
$array_contact = $this->fill_substitutionarray_with_extrafields($object, $array_contact, $extrafields, $array_key, $outputlangs); |
|
489
|
|
|
} |
|
490
|
|
|
return $array_contact; |
|
491
|
|
|
} |
|
492
|
|
|
|
|
493
|
|
|
|
|
494
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
|
495
|
|
|
/** |
|
496
|
|
|
* Define array with couple substitution key => substitution value |
|
497
|
|
|
* |
|
498
|
|
|
* @param Translate $outputlangs Language object for output |
|
499
|
|
|
* @return array Array of substitution key->code |
|
500
|
|
|
*/ |
|
501
|
|
|
public function get_substitutionarray_other($outputlangs) |
|
502
|
|
|
{ |
|
503
|
|
|
// phpcs:enable |
|
504
|
|
|
global $conf; |
|
505
|
|
|
|
|
506
|
|
|
$now = dol_now('gmt'); // gmt |
|
507
|
|
|
$array_other = array( |
|
508
|
|
|
// Date in default language |
|
509
|
|
|
'current_date' => dol_print_date($now, 'day', 'tzuser'), |
|
510
|
|
|
'current_datehour' => dol_print_date($now, 'dayhour', 'tzuser'), |
|
511
|
|
|
'current_server_date' => dol_print_date($now, 'day', 'tzserver'), |
|
512
|
|
|
'current_server_datehour' => dol_print_date($now, 'dayhour', 'tzserver'), |
|
513
|
|
|
// Date in requested output language |
|
514
|
|
|
'current_date_locale' => dol_print_date($now, 'day', 'tzuser', $outputlangs), |
|
515
|
|
|
'current_datehour_locale' => dol_print_date($now, 'dayhour', 'tzuser', $outputlangs), |
|
516
|
|
|
'current_server_date_locale' => dol_print_date($now, 'day', 'tzserver', $outputlangs), |
|
517
|
|
|
'current_server_datehour_locale' => dol_print_date($now, 'dayhour', 'tzserver', $outputlangs), |
|
518
|
|
|
); |
|
519
|
|
|
|
|
520
|
|
|
|
|
521
|
|
|
foreach ($conf->global as $key => $val) { |
|
522
|
|
|
if (isASecretKey($key)) { |
|
523
|
|
|
$newval = '*****forbidden*****'; |
|
524
|
|
|
} else { |
|
525
|
|
|
$newval = $val; |
|
526
|
|
|
} |
|
527
|
|
|
$array_other['__[' . $key . ']__'] = $newval; |
|
528
|
|
|
} |
|
529
|
|
|
|
|
530
|
|
|
return $array_other; |
|
531
|
|
|
} |
|
532
|
|
|
|
|
533
|
|
|
|
|
534
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
|
535
|
|
|
/** |
|
536
|
|
|
* Define array with couple substitution key => substitution value |
|
537
|
|
|
* Note that vars into substitutions array are formatted. |
|
538
|
|
|
* |
|
539
|
|
|
* @param CommonObject $object Main object to use as data source |
|
540
|
|
|
* @param Translate $outputlangs Lang object to use for output |
|
541
|
|
|
* @param string $array_key Name of the key for return array |
|
542
|
|
|
* @return array Array of substitution |
|
543
|
|
|
*/ |
|
544
|
|
|
public function get_substitutionarray_object($object, $outputlangs, $array_key = 'object') |
|
545
|
|
|
{ |
|
546
|
|
|
// phpcs:enable |
|
547
|
|
|
global $extrafields; |
|
548
|
|
|
|
|
549
|
|
|
$sumpayed = $sumdeposit = $sumcreditnote = ''; |
|
550
|
|
|
$already_payed_all = 0; |
|
551
|
|
|
|
|
552
|
|
|
if ($object->element == 'facture') { |
|
553
|
|
|
/** @var Facture $object */ |
|
554
|
|
|
$invoice_source = new Facture($this->db); |
|
555
|
|
|
if ($object->fk_facture_source > 0) { |
|
556
|
|
|
$invoice_source->fetch($object->fk_facture_source); |
|
557
|
|
|
} |
|
558
|
|
|
$sumpayed = $object->getSommePaiement(); |
|
559
|
|
|
$sumdeposit = $object->getSumDepositsUsed(); |
|
560
|
|
|
$sumcreditnote = $object->getSumCreditNotesUsed(); |
|
561
|
|
|
$already_payed_all = $sumpayed + $sumdeposit + $sumcreditnote; |
|
562
|
|
|
} |
|
563
|
|
|
|
|
564
|
|
|
$date = (isset($object->element) && $object->element == 'contrat' && isset($object->date_contrat)) ? $object->date_contrat : (isset($object->date) ? $object->date : null); |
|
|
|
|
|
|
565
|
|
|
|
|
566
|
|
|
if (get_only_class($object) == 'CommandeFournisseur') { |
|
567
|
|
|
/** @var CommandeFournisseur $object*/ |
|
568
|
|
|
$object->date_validation = $object->date_valid; |
|
569
|
|
|
$object->date_commande = $object->date; |
|
570
|
|
|
} |
|
571
|
|
|
$resarray = array( |
|
572
|
|
|
$array_key . '_id' => $object->id, |
|
573
|
|
|
$array_key . '_ref' => (property_exists($object, 'ref') ? $object->ref : ''), |
|
574
|
|
|
$array_key . '_label' => (property_exists($object, 'label') ? $object->label : ''), |
|
575
|
|
|
$array_key . '_ref_ext' => (property_exists($object, 'ref_ext') ? $object->ref_ext : ''), |
|
576
|
|
|
$array_key . '_ref_customer' => (!empty($object->ref_client) ? $object->ref_client : (empty($object->ref_customer) ? '' : $object->ref_customer)), |
|
|
|
|
|
|
577
|
|
|
$array_key . '_ref_supplier' => (!empty($object->ref_fournisseur) ? $object->ref_fournisseur : (empty($object->ref_supplier) ? '' : $object->ref_supplier)), |
|
|
|
|
|
|
578
|
|
|
$array_key . '_source_invoice_ref' => ((empty($invoice_source) || empty($invoice_source->ref)) ? '' : $invoice_source->ref), |
|
579
|
|
|
// Dates |
|
580
|
|
|
$array_key . '_hour' => dol_print_date($date, 'hour'), |
|
581
|
|
|
$array_key . '_date' => dol_print_date($date, 'day'), |
|
582
|
|
|
$array_key . '_date_rfc' => dol_print_date($date, 'dayrfc'), |
|
583
|
|
|
$array_key . '_date_limit' => (!empty($object->date_lim_reglement) ? dol_print_date($object->date_lim_reglement, 'day') : ''), |
|
|
|
|
|
|
584
|
|
|
$array_key . '_date_limit_rfc' => (!empty($object->date_lim_reglement) ? dol_print_date($object->date_lim_reglement, 'dayrfc') : ''), |
|
585
|
|
|
$array_key . '_date_end' => (!empty($object->fin_validite) ? dol_print_date($object->fin_validite, 'day') : ''), |
|
|
|
|
|
|
586
|
|
|
$array_key . '_date_creation' => dol_print_date($object->date_creation, 'day'), |
|
587
|
|
|
$array_key . '_date_modification' => (!empty($object->date_modification) ? dol_print_date($object->date_modification, 'day') : ''), |
|
588
|
|
|
$array_key . '_date_validation' => (!empty($object->date_validation) ? dol_print_date($object->date_validation, 'dayhour') : ''), |
|
589
|
|
|
$array_key . '_date_approve' => (!empty($object->date_approve) ? dol_print_date($object->date_approve, 'day') : ''), |
|
|
|
|
|
|
590
|
|
|
$array_key . '_date_delivery_planed' => (!empty($object->delivery_date) ? dol_print_date($object->delivery_date, 'day') : ''), |
|
|
|
|
|
|
591
|
|
|
$array_key . '_date_close' => (!empty($object->date_cloture) ? dol_print_date($object->date_cloture, 'dayhour') : ''), |
|
592
|
|
|
|
|
593
|
|
|
$array_key . '_payment_mode_code' => $object->mode_reglement_code, |
|
|
|
|
|
|
594
|
|
|
$array_key . '_payment_mode' => ($outputlangs->transnoentitiesnoconv('PaymentType' . $object->mode_reglement_code) != 'PaymentType' . $object->mode_reglement_code ? $outputlangs->transnoentitiesnoconv('PaymentType' . $object->mode_reglement_code) : $object->mode_reglement), |
|
|
|
|
|
|
595
|
|
|
$array_key . '_payment_term_code' => $object->cond_reglement_code, |
|
|
|
|
|
|
596
|
|
|
$array_key . '_payment_term' => ($outputlangs->transnoentitiesnoconv('PaymentCondition' . $object->cond_reglement_code) != 'PaymentCondition' . $object->cond_reglement_code ? $outputlangs->transnoentitiesnoconv('PaymentCondition' . $object->cond_reglement_code) : ($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement)), |
|
|
|
|
|
|
597
|
|
|
|
|
598
|
|
|
$array_key . '_incoterms' => (method_exists($object, 'display_incoterms') ? $object->display_incoterms() : ''), |
|
|
|
|
|
|
599
|
|
|
|
|
600
|
|
|
$array_key . '_total_ht_locale' => price($object->total_ht, 0, $outputlangs), |
|
601
|
|
|
$array_key . '_total_vat_locale' => (!empty($object->total_vat) ? price($object->total_vat, 0, $outputlangs) : price($object->total_tva, 0, $outputlangs)), |
|
|
|
|
|
|
602
|
|
|
$array_key . '_total_localtax1_locale' => price($object->total_localtax1, 0, $outputlangs), |
|
603
|
|
|
$array_key . '_total_localtax2_locale' => price($object->total_localtax2, 0, $outputlangs), |
|
604
|
|
|
$array_key . '_total_ttc_locale' => price($object->total_ttc, 0, $outputlangs), |
|
605
|
|
|
|
|
606
|
|
|
$array_key . '_total_ht' => price2num($object->total_ht), |
|
607
|
|
|
$array_key . '_total_vat' => (!empty($object->total_vat) ? price2num($object->total_vat) : price2num($object->total_tva)), |
|
608
|
|
|
$array_key . '_total_localtax1' => price2num($object->total_localtax1), |
|
609
|
|
|
$array_key . '_total_localtax2' => price2num($object->total_localtax2), |
|
610
|
|
|
$array_key . '_total_ttc' => price2num($object->total_ttc), |
|
611
|
|
|
|
|
612
|
|
|
$array_key . '_multicurrency_code' => $object->multicurrency_code, |
|
613
|
|
|
$array_key . '_multicurrency_tx' => price2num($object->multicurrency_tx), |
|
614
|
|
|
$array_key . '_multicurrency_total_ht' => price2num($object->multicurrency_total_ht), |
|
615
|
|
|
$array_key . '_multicurrency_total_tva' => price2num($object->multicurrency_total_tva), |
|
616
|
|
|
$array_key . '_multicurrency_total_ttc' => price2num($object->multicurrency_total_ttc), |
|
617
|
|
|
$array_key . '_multicurrency_total_ht_locale' => price($object->multicurrency_total_ht, 0, $outputlangs), |
|
618
|
|
|
$array_key . '_multicurrency_total_tva_locale' => price($object->multicurrency_total_tva, 0, $outputlangs), |
|
619
|
|
|
$array_key . '_multicurrency_total_ttc_locale' => price($object->multicurrency_total_ttc, 0, $outputlangs), |
|
620
|
|
|
|
|
621
|
|
|
$array_key . '_note_private' => $object->note_private, |
|
622
|
|
|
$array_key . '_note_public' => $object->note_public, |
|
623
|
|
|
$array_key . '_note' => $object->note_public, // For backward compatibility |
|
624
|
|
|
|
|
625
|
|
|
// Payments |
|
626
|
|
|
$array_key . '_already_payed_locale' => price($sumpayed, 0, $outputlangs), |
|
627
|
|
|
$array_key . '_already_payed' => price2num($sumpayed), |
|
628
|
|
|
$array_key . '_already_deposit_locale' => price($sumdeposit, 0, $outputlangs), |
|
629
|
|
|
$array_key . '_already_deposit' => price2num($sumdeposit), |
|
630
|
|
|
$array_key . '_already_creditnote_locale' => price($sumcreditnote, 0, $outputlangs), |
|
631
|
|
|
$array_key . '_already_creditnote' => price2num($sumcreditnote), |
|
632
|
|
|
|
|
633
|
|
|
$array_key . '_already_payed_all_locale' => price(price2num($already_payed_all, 'MT'), 0, $outputlangs), |
|
634
|
|
|
$array_key . '_already_payed_all' => price2num($already_payed_all, 'MT'), |
|
635
|
|
|
|
|
636
|
|
|
// Remain to pay with all known information (except open direct debit requests) |
|
637
|
|
|
$array_key . '_remain_to_pay_locale' => price(price2num($object->total_ttc - $already_payed_all, 'MT'), 0, $outputlangs), |
|
638
|
|
|
$array_key . '_remain_to_pay' => price2num($object->total_ttc - $already_payed_all, 'MT') |
|
639
|
|
|
); |
|
640
|
|
|
|
|
641
|
|
|
if (in_array($object->element, array('facture', 'invoice', 'supplier_invoice', 'facture_fournisseur'))) { |
|
642
|
|
|
$bank_account = null; |
|
643
|
|
|
|
|
644
|
|
|
if (property_exists($object, 'fk_account') && $object->fk_account > 0) { |
|
645
|
|
|
$bank_account = new Account($this->db); |
|
646
|
|
|
$bank_account->fetch($object->fk_account); |
|
647
|
|
|
} |
|
648
|
|
|
|
|
649
|
|
|
$resarray[$array_key . '_bank_iban'] = (empty($bank_account) ? '' : $bank_account->iban); |
|
650
|
|
|
$resarray[$array_key . '_bank_bic'] = (empty($bank_account) ? '' : $bank_account->bic); |
|
651
|
|
|
$resarray[$array_key . '_bank_label'] = (empty($bank_account) ? '' : $bank_account->label); |
|
652
|
|
|
$resarray[$array_key . '_bank_number'] = (empty($bank_account) ? '' : $bank_account->number); |
|
653
|
|
|
$resarray[$array_key . '_bank_proprio'] = (empty($bank_account) ? '' : $bank_account->proprio); |
|
|
|
|
|
|
654
|
|
|
$resarray[$array_key . '_bank_address'] = (empty($bank_account) ? '' : $bank_account->address); |
|
655
|
|
|
$resarray[$array_key . '_bank_state'] = (empty($bank_account) ? '' : $bank_account->state); |
|
656
|
|
|
$resarray[$array_key . '_bank_country'] = (empty($bank_account) ? '' : $bank_account->country); |
|
657
|
|
|
} |
|
658
|
|
|
|
|
659
|
|
|
if (method_exists($object, 'getTotalDiscount') && in_array(get_only_class($object), array('Propal', 'Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { |
|
660
|
|
|
$resarray[$array_key . '_total_discount_ht_locale'] = price($object->getTotalDiscount(), 0, $outputlangs); |
|
661
|
|
|
$resarray[$array_key . '_total_discount_ht'] = price2num($object->getTotalDiscount()); |
|
662
|
|
|
} else { |
|
663
|
|
|
$resarray[$array_key . '_total_discount_ht_locale'] = ''; |
|
664
|
|
|
$resarray[$array_key . '_total_discount_ht'] = ''; |
|
665
|
|
|
} |
|
666
|
|
|
|
|
667
|
|
|
// Fetch project information if there is a project assigned to this object |
|
668
|
|
|
if ($object->element != "project" && !empty($object->fk_project) && $object->fk_project > 0) { |
|
669
|
|
|
if (!is_object($object->project)) { |
|
670
|
|
|
$object->fetch_projet(); |
|
671
|
|
|
} |
|
672
|
|
|
|
|
673
|
|
|
$resarray[$array_key . '_project_ref'] = $object->project->ref; |
|
674
|
|
|
$resarray[$array_key . '_project_title'] = $object->project->title; |
|
675
|
|
|
$resarray[$array_key . '_project_description'] = $object->project->description; |
|
676
|
|
|
$resarray[$array_key . '_project_date_start'] = dol_print_date($object->project->date_start, 'day'); |
|
677
|
|
|
$resarray[$array_key . '_project_date_end'] = dol_print_date($object->project->date_end, 'day'); |
|
678
|
|
|
} else { // empty replacement |
|
679
|
|
|
$resarray[$array_key . '_project_ref'] = ''; |
|
680
|
|
|
$resarray[$array_key . '_project_title'] = ''; |
|
681
|
|
|
$resarray[$array_key . '_project_description'] = ''; |
|
682
|
|
|
$resarray[$array_key . '_project_date_start'] = ''; |
|
683
|
|
|
$resarray[$array_key . '_project_date_end'] = ''; |
|
684
|
|
|
} |
|
685
|
|
|
|
|
686
|
|
|
// Add vat by rates |
|
687
|
|
|
if (is_array($object->lines) && count($object->lines) > 0) { |
|
688
|
|
|
$totalUp = 0; |
|
689
|
|
|
// Set substitution keys for different VAT rates |
|
690
|
|
|
foreach ($object->lines as $line) { |
|
691
|
|
|
// $line->tva_tx format depends on database field accuracy, no reliable. This is kept for backward compatibility |
|
692
|
|
|
if (empty($resarray[$array_key . '_total_vat_' . $line->tva_tx])) { |
|
693
|
|
|
$resarray[$array_key . '_total_vat_' . $line->tva_tx] = 0; |
|
694
|
|
|
} |
|
695
|
|
|
$resarray[$array_key . '_total_vat_' . $line->tva_tx] += $line->total_tva; |
|
696
|
|
|
$resarray[$array_key . '_total_vat_locale_' . $line->tva_tx] = price($resarray[$array_key . '_total_vat_' . $line->tva_tx]); |
|
697
|
|
|
// $vatformated is vat without not expected chars (so 20, or 8.5 or 5.99 for example) |
|
698
|
|
|
$vatformated = vatrate($line->tva_tx); |
|
699
|
|
|
if (empty($resarray[$array_key . '_total_vat_' . $vatformated])) { |
|
700
|
|
|
$resarray[$array_key . '_total_vat_' . $vatformated] = 0; |
|
701
|
|
|
} |
|
702
|
|
|
$resarray[$array_key . '_total_vat_' . $vatformated] += $line->total_tva; |
|
703
|
|
|
$resarray[$array_key . '_total_vat_locale_' . $vatformated] = price($resarray[$array_key . '_total_vat_' . $vatformated]); |
|
704
|
|
|
|
|
705
|
|
|
$totalUp += $line->subprice * $line->qty; |
|
706
|
|
|
} |
|
707
|
|
|
|
|
708
|
|
|
// Calculate total up and total discount percentage |
|
709
|
|
|
// Note that this added fields does not match a field into database in Dolibarr (Dolibarr manage discount on lines not as a global property of object) |
|
710
|
|
|
$resarray['object_total_up'] = $totalUp; |
|
711
|
|
|
$resarray['object_total_up_locale'] = price($resarray['object_total_up'], 0, $outputlangs); |
|
712
|
|
|
if (method_exists($object, 'getTotalDiscount') && in_array(get_only_class($object), array('Propal', 'Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { |
|
713
|
|
|
$totalDiscount = $object->getTotalDiscount(); |
|
714
|
|
|
} else { |
|
715
|
|
|
$totalDiscount = 0; |
|
716
|
|
|
} |
|
717
|
|
|
if (!empty($totalUp) && !empty($totalDiscount)) { |
|
718
|
|
|
$resarray['object_total_discount'] = round(100 / $totalUp * $totalDiscount, 2); |
|
719
|
|
|
$resarray['object_total_discount_locale'] = price($resarray['object_total_discount'], 0, $outputlangs); |
|
720
|
|
|
} else { |
|
721
|
|
|
$resarray['object_total_discount'] = ''; |
|
722
|
|
|
$resarray['object_total_discount_locale'] = ''; |
|
723
|
|
|
} |
|
724
|
|
|
} |
|
725
|
|
|
|
|
726
|
|
|
// Retrieve extrafields |
|
727
|
|
|
if (is_array($object->array_options) && count($object->array_options)) { |
|
728
|
|
|
$object->fetch_optionals(); |
|
729
|
|
|
|
|
730
|
|
|
$resarray = $this->fill_substitutionarray_with_extrafields($object, $resarray, $extrafields, $array_key, $outputlangs); |
|
731
|
|
|
} |
|
732
|
|
|
|
|
733
|
|
|
return $resarray; |
|
734
|
|
|
} |
|
735
|
|
|
|
|
736
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
|
737
|
|
|
/** |
|
738
|
|
|
* Define array with couple substitution key => substitution value |
|
739
|
|
|
* Note that vars into substitutions array are formatted. |
|
740
|
|
|
* |
|
741
|
|
|
* @param CommonObjectLine $line Object line |
|
742
|
|
|
* @param Translate $outputlangs Translate object to use for output |
|
743
|
|
|
* @param int $linenumber The number of the line for the substitution of "object_line_pos" |
|
744
|
|
|
* @return array Return a substitution array |
|
745
|
|
|
*/ |
|
746
|
|
|
public function get_substitutionarray_lines($line, $outputlangs, $linenumber = 0) |
|
747
|
|
|
{ |
|
748
|
|
|
// phpcs:enable |
|
749
|
|
|
$resarray = array( |
|
750
|
|
|
'line_pos' => $linenumber, |
|
751
|
|
|
'line_fulldesc' => doc_getlinedesc($line, $outputlangs), |
|
752
|
|
|
|
|
753
|
|
|
'line_product_ref' => (empty($line->product_ref) ? '' : $line->product_ref), |
|
754
|
|
|
'line_product_ref_fourn' => (empty($line->ref_fourn) ? '' : $line->ref_fourn), // for supplier doc lines |
|
|
|
|
|
|
755
|
|
|
'line_product_label' => (empty($line->product_label) ? '' : $line->product_label), |
|
756
|
|
|
'line_product_type' => (empty($line->product_type) ? '' : $line->product_type), |
|
757
|
|
|
'line_product_barcode' => (empty($line->product_barcode) ? '' : $line->product_barcode), |
|
758
|
|
|
'line_product_desc' => (empty($line->product_desc) ? '' : $line->product_desc), |
|
759
|
|
|
|
|
760
|
|
|
'line_desc' => $line->desc, |
|
761
|
|
|
'line_vatrate' => vatrate($line->tva_tx, true, $line->info_bits), |
|
762
|
|
|
'line_localtax1_rate' => vatrate($line->localtax1_tx), |
|
|
|
|
|
|
763
|
|
|
'line_localtax2_rate' => vatrate($line->localtax1_tx), |
|
764
|
|
|
'line_up' => price2num($line->subprice), |
|
765
|
|
|
'line_up_locale' => price($line->subprice, 0, $outputlangs), |
|
766
|
|
|
'line_total_up' => price2num($line->subprice * (float) $line->qty), |
|
767
|
|
|
'line_total_up_locale' => price($line->subprice * (float) $line->qty, 0, $outputlangs), |
|
768
|
|
|
'line_qty' => $line->qty, |
|
769
|
|
|
'line_discount_percent' => ($line->remise_percent ? $line->remise_percent . '%' : ''), |
|
770
|
|
|
'line_price_ht' => price2num($line->total_ht), |
|
771
|
|
|
'line_price_ttc' => price2num($line->total_ttc), |
|
772
|
|
|
'line_price_vat' => price2num($line->total_tva), |
|
773
|
|
|
'line_price_ht_locale' => price($line->total_ht, 0, $outputlangs), |
|
774
|
|
|
'line_price_ttc_locale' => price($line->total_ttc, 0, $outputlangs), |
|
775
|
|
|
'line_price_vat_locale' => price($line->total_tva, 0, $outputlangs), |
|
776
|
|
|
// Dates |
|
777
|
|
|
'line_date_start' => dol_print_date($line->date_start, 'day'), |
|
|
|
|
|
|
778
|
|
|
'line_date_start_locale' => dol_print_date($line->date_start, 'day', 'tzserver', $outputlangs), |
|
779
|
|
|
'line_date_start_rfc' => dol_print_date($line->date_start, 'dayrfc'), |
|
780
|
|
|
'line_date_end' => dol_print_date($line->date_end, 'day'), |
|
|
|
|
|
|
781
|
|
|
'line_date_end_locale' => dol_print_date($line->date_end, 'day', 'tzserver', $outputlangs), |
|
782
|
|
|
'line_date_end_rfc' => dol_print_date($line->date_end, 'dayrfc'), |
|
783
|
|
|
|
|
784
|
|
|
'line_multicurrency_code' => price2num($line->multicurrency_code), |
|
785
|
|
|
'line_multicurrency_subprice' => price2num($line->multicurrency_subprice), |
|
786
|
|
|
'line_multicurrency_total_ht' => price2num($line->multicurrency_total_ht), |
|
787
|
|
|
'line_multicurrency_total_tva' => price2num($line->multicurrency_total_tva), |
|
788
|
|
|
'line_multicurrency_total_ttc' => price2num($line->multicurrency_total_ttc), |
|
789
|
|
|
'line_multicurrency_subprice_locale' => price($line->multicurrency_subprice, 0, $outputlangs), |
|
790
|
|
|
'line_multicurrency_total_ht_locale' => price($line->multicurrency_total_ht, 0, $outputlangs), |
|
791
|
|
|
'line_multicurrency_total_tva_locale' => price($line->multicurrency_total_tva, 0, $outputlangs), |
|
792
|
|
|
'line_multicurrency_total_ttc_locale' => price($line->multicurrency_total_ttc, 0, $outputlangs), |
|
793
|
|
|
); |
|
794
|
|
|
|
|
795
|
|
|
// Units |
|
796
|
|
|
if (getDolGlobalInt('PRODUCT_USE_UNITS')) { |
|
797
|
|
|
$resarray['line_unit'] = $outputlangs->trans($line->getLabelOfUnit('long')); |
|
798
|
|
|
$resarray['line_unit_short'] = $outputlangs->trans($line->getLabelOfUnit('short')); |
|
799
|
|
|
} |
|
800
|
|
|
|
|
801
|
|
|
// Retrieve extrafields |
|
802
|
|
|
$extrafieldkey = $line->table_element; |
|
803
|
|
|
$array_key = "line"; |
|
804
|
|
|
$extrafields = new ExtraFields($this->db); |
|
805
|
|
|
$extrafields->fetch_name_optionals_label($extrafieldkey, true); |
|
806
|
|
|
$line->fetch_optionals(); |
|
807
|
|
|
|
|
808
|
|
|
$resarray = $this->fill_substitutionarray_with_extrafields($line, $resarray, $extrafields, $array_key, $outputlangs); |
|
809
|
|
|
|
|
810
|
|
|
// Check if the current line belongs to a supplier order |
|
811
|
|
|
if (get_only_class($line) == 'CommandeFournisseurLigne') { |
|
812
|
|
|
// Add the product supplier extrafields to the substitutions |
|
813
|
|
|
$extrafields->fetch_name_optionals_label("product_fournisseur_price"); |
|
814
|
|
|
$extralabels = $extrafields->attributes["product_fournisseur_price"]['label']; |
|
815
|
|
|
|
|
816
|
|
|
if (!empty($extralabels) && is_array($extralabels)) { |
|
817
|
|
|
$columns = ""; |
|
818
|
|
|
|
|
819
|
|
|
foreach ($extralabels as $key => $label) { |
|
820
|
|
|
$columns .= "$key, "; |
|
821
|
|
|
} |
|
822
|
|
|
|
|
823
|
|
|
if ($columns != "") { |
|
824
|
|
|
$columns = substr($columns, 0, strlen($columns) - 2); |
|
825
|
|
|
$resql = $this->db->query("SELECT " . $columns . " FROM " . $this->db->prefix() . "product_fournisseur_price_extrafields AS ex INNER JOIN " . $this->db->prefix() . "product_fournisseur_price AS f ON ex.fk_object = f.rowid WHERE f.ref_fourn = '" . $this->db->escape($line->ref_supplier) . "'"); |
|
|
|
|
|
|
826
|
|
|
|
|
827
|
|
|
if ($this->db->num_rows($resql) > 0) { |
|
828
|
|
|
$resql = $this->db->fetch_object($resql); |
|
829
|
|
|
|
|
830
|
|
|
foreach ($extralabels as $key => $label) { |
|
831
|
|
|
$resarray['line_product_supplier_' . $key] = $resql->$key; |
|
832
|
|
|
} |
|
833
|
|
|
} |
|
834
|
|
|
} |
|
835
|
|
|
} |
|
836
|
|
|
} |
|
837
|
|
|
|
|
838
|
|
|
// Load product data optional fields to the line -> enables to use "line_options_{extrafield}" |
|
839
|
|
|
if (isset($line->fk_product) && $line->fk_product > 0) { |
|
840
|
|
|
$tmpproduct = new Product($this->db); |
|
841
|
|
|
$result = $tmpproduct->fetch($line->fk_product); |
|
842
|
|
|
if (!empty($tmpproduct->array_options) && is_array($tmpproduct->array_options)) { |
|
843
|
|
|
foreach ($tmpproduct->array_options as $key => $label) { |
|
844
|
|
|
$resarray["line_product_" . $key] = $label; |
|
845
|
|
|
} |
|
846
|
|
|
} |
|
847
|
|
|
} else { |
|
848
|
|
|
// Set unused placeholders as blank |
|
849
|
|
|
$extrafields->fetch_name_optionals_label("product"); |
|
850
|
|
|
if ($extrafields->attributes["product"]['count'] > 0) { |
|
851
|
|
|
$extralabels = $extrafields->attributes["product"]['label']; |
|
852
|
|
|
|
|
853
|
|
|
foreach ($extralabels as $key => $label) { |
|
854
|
|
|
$resarray['line_product_options_' . $key] = ''; |
|
855
|
|
|
} |
|
856
|
|
|
} |
|
857
|
|
|
} |
|
858
|
|
|
|
|
859
|
|
|
return $resarray; |
|
860
|
|
|
} |
|
861
|
|
|
|
|
862
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
|
863
|
|
|
/** |
|
864
|
|
|
* Define array with couple substitution key => substitution value |
|
865
|
|
|
* Note that vars into substitutions array are formatted. |
|
866
|
|
|
* |
|
867
|
|
|
* @param Expedition $object Main object to use as data source |
|
868
|
|
|
* @param Translate $outputlangs Lang object to use for output |
|
869
|
|
|
* @param string $array_key Name of the key for return array |
|
870
|
|
|
* @return array Array of substitution |
|
871
|
|
|
*/ |
|
872
|
|
|
public function get_substitutionarray_shipment($object, $outputlangs, $array_key = 'object') |
|
873
|
|
|
{ |
|
874
|
|
|
// phpcs:enable |
|
875
|
|
|
global $extrafields; |
|
876
|
|
|
|
|
877
|
|
|
include_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; |
|
878
|
|
|
|
|
879
|
|
|
$object->list_delivery_methods($object->shipping_method_id); |
|
880
|
|
|
$calculatedVolume = ((float) $object->trueWidth * (float) $object->trueHeight * (float) $object->trueDepth); |
|
881
|
|
|
|
|
882
|
|
|
$array_shipment = array( |
|
883
|
|
|
$array_key . '_id' => $object->id, |
|
884
|
|
|
$array_key . '_ref' => $object->ref, |
|
885
|
|
|
$array_key . '_ref_ext' => $object->ref_ext, |
|
886
|
|
|
$array_key . '_ref_customer' => $object->ref_customer, |
|
887
|
|
|
$array_key . '_date_delivery' => dol_print_date($object->date_delivery, 'day'), |
|
888
|
|
|
$array_key . '_hour_delivery' => dol_print_date($object->date_delivery, 'hour'), |
|
889
|
|
|
$array_key . '_date_creation' => dol_print_date($object->date_creation, 'day'), |
|
890
|
|
|
$array_key . '_total_ht' => price($object->total_ht), |
|
891
|
|
|
$array_key . '_total_vat' => price($object->total_tva), |
|
892
|
|
|
$array_key . '_total_ttc' => price($object->total_ttc), |
|
893
|
|
|
$array_key . '_total_discount_ht' => price($object->getTotalDiscount()), |
|
894
|
|
|
$array_key . '_note_private' => $object->note_private, |
|
895
|
|
|
$array_key . '_note' => $object->note_public, |
|
896
|
|
|
$array_key . '_tracking_number' => $object->tracking_number, |
|
897
|
|
|
$array_key . '_tracking_url' => $object->tracking_url, |
|
898
|
|
|
$array_key . '_shipping_method' => $object->listmeths[0]['libelle'], |
|
899
|
|
|
$array_key . '_weight' => $object->trueWeight . ' ' . measuringUnitString(0, 'weight', $object->weight_units), |
|
900
|
|
|
$array_key . '_width' => $object->trueWidth . ' ' . measuringUnitString(0, 'size', $object->width_units), |
|
901
|
|
|
$array_key . '_height' => $object->trueHeight . ' ' . measuringUnitString(0, 'size', $object->height_units), |
|
902
|
|
|
$array_key . '_depth' => $object->trueDepth . ' ' . measuringUnitString(0, 'size', $object->depth_units), |
|
903
|
|
|
$array_key . '_size' => $calculatedVolume . ' ' . measuringUnitString(0, 'volume'), |
|
904
|
|
|
); |
|
905
|
|
|
|
|
906
|
|
|
// Add vat by rates |
|
907
|
|
|
foreach ($object->lines as $line) { |
|
908
|
|
|
if (empty($array_shipment[$array_key . '_total_vat_' . $line->tva_tx])) { |
|
909
|
|
|
$array_shipment[$array_key . '_total_vat_' . $line->tva_tx] = 0; |
|
910
|
|
|
} |
|
911
|
|
|
$array_shipment[$array_key . '_total_vat_' . $line->tva_tx] += $line->total_tva; |
|
912
|
|
|
} |
|
913
|
|
|
|
|
914
|
|
|
// Retrieve extrafields |
|
915
|
|
|
if (is_array($object->array_options) && count($object->array_options)) { |
|
916
|
|
|
$object->fetch_optionals(); |
|
917
|
|
|
|
|
918
|
|
|
$array_shipment = $this->fill_substitutionarray_with_extrafields($object, $array_shipment, $extrafields, $array_key, $outputlangs); |
|
919
|
|
|
} |
|
920
|
|
|
|
|
921
|
|
|
// Add info from $object->xxx where xxx has been loaded by fetch_origin() of shipment |
|
922
|
|
|
if (is_object($object->commande) && !empty($object->commande->ref)) { |
|
923
|
|
|
$array_shipment['order_ref'] = $object->commande->ref; |
|
924
|
|
|
$array_shipment['order_ref_customer'] = $object->commande->ref_customer; |
|
925
|
|
|
} |
|
926
|
|
|
|
|
927
|
|
|
return $array_shipment; |
|
928
|
|
|
} |
|
929
|
|
|
|
|
930
|
|
|
|
|
931
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
|
932
|
|
|
/** |
|
933
|
|
|
* Define array with couple substitution key => substitution value |
|
934
|
|
|
* |
|
935
|
|
|
* @param Object $object Dolibarr Object |
|
936
|
|
|
* @param Translate $outputlangs Language object for output |
|
937
|
|
|
* @param boolean|int $recursive Want to fetch child array or child object. |
|
938
|
|
|
* @return array Array of substitution key->code |
|
939
|
|
|
*/ |
|
940
|
|
|
public function get_substitutionarray_each_var_object(&$object, $outputlangs, $recursive = 1) |
|
941
|
|
|
{ |
|
942
|
|
|
// phpcs:enable |
|
943
|
|
|
$array_other = array(); |
|
944
|
|
|
if (!empty($object)) { |
|
945
|
|
|
foreach ($object as $key => $value) { |
|
946
|
|
|
if (in_array($key, array('db', 'fields', 'lines', 'modelpdf', 'model_pdf'))) { // discard some properties |
|
947
|
|
|
continue; |
|
948
|
|
|
} |
|
949
|
|
|
if (!empty($value)) { |
|
950
|
|
|
if (!is_array($value) && !is_object($value)) { |
|
951
|
|
|
$array_other['object_' . $key] = $value; |
|
952
|
|
|
} elseif (is_array($value) && $recursive) { |
|
953
|
|
|
$tmparray = $this->get_substitutionarray_each_var_object($value, $outputlangs, 0); |
|
954
|
|
|
if (!empty($tmparray) && is_array($tmparray)) { |
|
955
|
|
|
foreach ($tmparray as $key2 => $value2) { |
|
956
|
|
|
$array_other['object_' . $key . '_' . preg_replace('/^object_/', '', $key2)] = $value2; |
|
957
|
|
|
} |
|
958
|
|
|
} |
|
959
|
|
|
} elseif (is_object($value) && $recursive) { |
|
960
|
|
|
$tmparray = $this->get_substitutionarray_each_var_object($value, $outputlangs, 0); |
|
961
|
|
|
if (!empty($tmparray) && is_array($tmparray)) { |
|
962
|
|
|
foreach ($tmparray as $key2 => $value2) { |
|
963
|
|
|
$array_other['object_' . $key . '_' . preg_replace('/^object_/', '', $key2)] = $value2; |
|
964
|
|
|
} |
|
965
|
|
|
} |
|
966
|
|
|
} |
|
967
|
|
|
} |
|
968
|
|
|
} |
|
969
|
|
|
} |
|
970
|
|
|
|
|
971
|
|
|
return $array_other; |
|
972
|
|
|
} |
|
973
|
|
|
|
|
974
|
|
|
|
|
975
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
|
976
|
|
|
/** |
|
977
|
|
|
* Fill array with couple extrafield key => extrafield value |
|
978
|
|
|
* Note that vars into substitutions array are formatted. |
|
979
|
|
|
* |
|
980
|
|
|
* @param Object $object Object with extrafields (must have $object->array_options filled) |
|
981
|
|
|
* @param array $array_to_fill Substitution array |
|
982
|
|
|
* @param Extrafields $extrafields Extrafields object |
|
983
|
|
|
* @param string $array_key Prefix for name of the keys into returned array |
|
984
|
|
|
* @param Translate $outputlangs Lang object to use for output |
|
985
|
|
|
* @return array Substitution array |
|
986
|
|
|
*/ |
|
987
|
|
|
public function fill_substitutionarray_with_extrafields($object, $array_to_fill, $extrafields, $array_key, $outputlangs) |
|
988
|
|
|
{ |
|
989
|
|
|
// phpcs:enable |
|
990
|
|
|
global $conf; |
|
991
|
|
|
|
|
992
|
|
|
if ($extrafields->attributes[$object->table_element]['count'] > 0) { |
|
993
|
|
|
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { |
|
994
|
|
|
$formatedarrayoption = $object->array_options; |
|
995
|
|
|
|
|
996
|
|
|
if ($extrafields->attributes[$object->table_element]['type'][$key] == 'price') { |
|
997
|
|
|
$formatedarrayoption['options_' . $key] = price2num($formatedarrayoption['options_' . $key]); |
|
998
|
|
|
$formatedarrayoption['options_' . $key . '_currency'] = price($formatedarrayoption['options_' . $key], 0, $outputlangs, 0, 0, -1, $conf->currency); |
|
999
|
|
|
//Add value to store price with currency |
|
1000
|
|
|
$array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key . '_currency' => $formatedarrayoption['options_' . $key . '_currency'])); |
|
1001
|
|
|
} elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'select') { |
|
1002
|
|
|
$valueofselectkey = $formatedarrayoption['options_' . $key]; |
|
1003
|
|
|
if (array_key_exists($valueofselectkey, $extrafields->attributes[$object->table_element]['param'][$key]['options'])) { |
|
1004
|
|
|
$formatedarrayoption['options_' . $key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$valueofselectkey]; |
|
1005
|
|
|
} else { |
|
1006
|
|
|
$formatedarrayoption['options_' . $key] = ''; |
|
1007
|
|
|
} |
|
1008
|
|
|
} elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox') { |
|
1009
|
|
|
$valArray = explode(',', $formatedarrayoption['options_' . $key]); |
|
1010
|
|
|
$output = array(); |
|
1011
|
|
|
foreach ($extrafields->attributes[$object->table_element]['param'][$key]['options'] as $keyopt => $valopt) { |
|
1012
|
|
|
if (in_array($keyopt, $valArray)) { |
|
1013
|
|
|
$output[] = $valopt; |
|
1014
|
|
|
} |
|
1015
|
|
|
} |
|
1016
|
|
|
$formatedarrayoption['options_' . $key] = implode(', ', $output); |
|
1017
|
|
|
} elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'date') { |
|
1018
|
|
|
if (strlen($formatedarrayoption['options_' . $key]) > 0) { |
|
1019
|
|
|
$date = $formatedarrayoption['options_' . $key]; |
|
1020
|
|
|
$formatedarrayoption['options_' . $key] = dol_print_date($date, 'day'); // using company output language |
|
1021
|
|
|
$formatedarrayoption['options_' . $key . '_locale'] = dol_print_date($date, 'day', 'tzserver', $outputlangs); // using output language format |
|
1022
|
|
|
$formatedarrayoption['options_' . $key . '_rfc'] = dol_print_date($date, 'dayrfc'); // international format |
|
1023
|
|
|
} else { |
|
1024
|
|
|
$formatedarrayoption['options_' . $key] = ''; |
|
1025
|
|
|
$formatedarrayoption['options_' . $key . '_locale'] = ''; |
|
1026
|
|
|
$formatedarrayoption['options_' . $key . '_rfc'] = ''; |
|
1027
|
|
|
} |
|
1028
|
|
|
$array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key . '_locale' => $formatedarrayoption['options_' . $key . '_locale'])); |
|
1029
|
|
|
$array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key . '_rfc' => $formatedarrayoption['options_' . $key . '_rfc'])); |
|
1030
|
|
|
} elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'datetime') { |
|
1031
|
|
|
$datetime = $formatedarrayoption['options_' . $key]; |
|
1032
|
|
|
$formatedarrayoption['options_' . $key] = ($datetime != "0000-00-00 00:00:00" ? dol_print_date($datetime, 'dayhour') : ''); // using company output language |
|
1033
|
|
|
$formatedarrayoption['options_' . $key . '_locale'] = ($datetime != "0000-00-00 00:00:00" ? dol_print_date($datetime, 'dayhour', 'tzserver', $outputlangs) : ''); // using output language format |
|
1034
|
|
|
$formatedarrayoption['options_' . $key . '_rfc'] = ($datetime != "0000-00-00 00:00:00" ? dol_print_date($datetime, 'dayhourrfc') : ''); // international format |
|
1035
|
|
|
$array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key . '_locale' => $formatedarrayoption['options_' . $key . '_locale'])); |
|
1036
|
|
|
$array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key . '_rfc' => $formatedarrayoption['options_' . $key . '_rfc'])); |
|
1037
|
|
|
} elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'link') { |
|
1038
|
|
|
$id = $formatedarrayoption['options_' . $key]; |
|
1039
|
|
|
if ($id != "") { |
|
1040
|
|
|
$param = $extrafields->attributes[$object->table_element]['param'][$key]; |
|
1041
|
|
|
$param_list = array_keys($param['options']); // $param_list='ObjectName:classPath' |
|
1042
|
|
|
$InfoFieldList = explode(":", $param_list[0]); |
|
1043
|
|
|
$classname = $InfoFieldList[0]; |
|
1044
|
|
|
$classpath = $InfoFieldList[1]; |
|
1045
|
|
|
if (!empty($classpath)) { |
|
1046
|
|
|
dol_include_once($InfoFieldList[1]); |
|
1047
|
|
|
if ($classname && class_exists($classname)) { |
|
1048
|
|
|
$tmpobject = new $classname($this->db); |
|
1049
|
|
|
$tmpobject->fetch($id); |
|
1050
|
|
|
// completely replace the id with the linked object name |
|
1051
|
|
|
$formatedarrayoption['options_' . $key] = $tmpobject->name; |
|
1052
|
|
|
} |
|
1053
|
|
|
} |
|
1054
|
|
|
} |
|
1055
|
|
|
} |
|
1056
|
|
|
|
|
1057
|
|
|
if (array_key_exists('options_' . $key, $formatedarrayoption)) { |
|
1058
|
|
|
$array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key => $formatedarrayoption['options_' . $key])); |
|
1059
|
|
|
} else { |
|
1060
|
|
|
$array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key => '')); |
|
1061
|
|
|
} |
|
1062
|
|
|
} |
|
1063
|
|
|
} |
|
1064
|
|
|
|
|
1065
|
|
|
return $array_to_fill; |
|
1066
|
|
|
} |
|
1067
|
|
|
|
|
1068
|
|
|
|
|
1069
|
|
|
/** |
|
1070
|
|
|
* Rect pdf |
|
1071
|
|
|
* |
|
1072
|
|
|
* @param TCPDI|TCPDF $pdf Pdf object |
|
|
|
|
|
|
1073
|
|
|
* @param float $x Abscissa of first point |
|
1074
|
|
|
* @param float $y Ordinate of first point |
|
1075
|
|
|
* @param float $l ?? |
|
1076
|
|
|
* @param float $h ?? |
|
1077
|
|
|
* @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title |
|
1078
|
|
|
* @param int $hidebottom Hide bottom |
|
1079
|
|
|
* @return void |
|
1080
|
|
|
*/ |
|
1081
|
|
|
public function printRect($pdf, $x, $y, $l, $h, $hidetop = 0, $hidebottom = 0) |
|
1082
|
|
|
{ |
|
1083
|
|
|
if (empty($hidetop) || $hidetop == -1) { |
|
1084
|
|
|
$pdf->line($x, $y, $x + $l, $y); |
|
1085
|
|
|
} |
|
1086
|
|
|
$pdf->line($x + $l, $y, $x + $l, $y + $h); |
|
1087
|
|
|
if (empty($hidebottom)) { |
|
1088
|
|
|
$pdf->line($x + $l, $y + $h, $x, $y + $h); |
|
1089
|
|
|
} |
|
1090
|
|
|
$pdf->line($x, $y + $h, $x, $y); |
|
1091
|
|
|
} |
|
1092
|
|
|
|
|
1093
|
|
|
|
|
1094
|
|
|
/** |
|
1095
|
|
|
* uasort callback function to Sort columns fields |
|
1096
|
|
|
* |
|
1097
|
|
|
* @param array $a PDF lines array fields configs |
|
1098
|
|
|
* @param array $b PDF lines array fields configs |
|
1099
|
|
|
* @return int Return compare result |
|
1100
|
|
|
*/ |
|
1101
|
|
|
public function columnSort($a, $b) |
|
1102
|
|
|
{ |
|
1103
|
|
|
if (empty($a['rank'])) { |
|
1104
|
|
|
$a['rank'] = 0; |
|
1105
|
|
|
} |
|
1106
|
|
|
if (empty($b['rank'])) { |
|
1107
|
|
|
$b['rank'] = 0; |
|
1108
|
|
|
} |
|
1109
|
|
|
if ($a['rank'] == $b['rank']) { |
|
1110
|
|
|
return 0; |
|
1111
|
|
|
} |
|
1112
|
|
|
return ($a['rank'] > $b['rank']) ? -1 : 1; |
|
1113
|
|
|
} |
|
1114
|
|
|
|
|
1115
|
|
|
/** |
|
1116
|
|
|
* Prepare Array Column Field |
|
1117
|
|
|
* |
|
1118
|
|
|
* @param object $object common object |
|
1119
|
|
|
* @param Translate $outputlangs langs |
|
1120
|
|
|
* @param int $hidedetails Do not show line details |
|
1121
|
|
|
* @param int $hidedesc Do not show desc |
|
1122
|
|
|
* @param int $hideref Do not show ref |
|
1123
|
|
|
* @return void |
|
1124
|
|
|
*/ |
|
1125
|
|
|
public function prepareArrayColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) |
|
1126
|
|
|
{ |
|
1127
|
|
|
$this->defineColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref); |
|
1128
|
|
|
|
|
1129
|
|
|
|
|
1130
|
|
|
// Sorting |
|
1131
|
|
|
uasort($this->cols, array($this, 'columnSort')); |
|
1132
|
|
|
|
|
1133
|
|
|
// Positioning |
|
1134
|
|
|
$curX = $this->page_largeur - $this->marge_droite; // start from right |
|
1135
|
|
|
|
|
1136
|
|
|
// Array width |
|
1137
|
|
|
$arrayWidth = $this->page_largeur - $this->marge_droite - $this->marge_gauche; |
|
1138
|
|
|
|
|
1139
|
|
|
// Count flexible column |
|
1140
|
|
|
$totalDefinedColWidth = 0; |
|
1141
|
|
|
$countFlexCol = 0; |
|
1142
|
|
|
foreach ($this->cols as $colKey => & $colDef) { |
|
1143
|
|
|
if (!$this->getColumnStatus($colKey)) { |
|
1144
|
|
|
continue; // continue if disabled |
|
1145
|
|
|
} |
|
1146
|
|
|
|
|
1147
|
|
|
if (!empty($colDef['scale'])) { |
|
1148
|
|
|
// In case of column width is defined by percentage |
|
1149
|
|
|
$colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100); |
|
1150
|
|
|
} |
|
1151
|
|
|
|
|
1152
|
|
|
if (empty($colDef['width'])) { |
|
1153
|
|
|
$countFlexCol++; |
|
1154
|
|
|
} else { |
|
1155
|
|
|
$totalDefinedColWidth += $colDef['width']; |
|
1156
|
|
|
} |
|
1157
|
|
|
} |
|
1158
|
|
|
|
|
1159
|
|
|
foreach ($this->cols as $colKey => & $colDef) { |
|
1160
|
|
|
// setting empty conf with default |
|
1161
|
|
|
if (!empty($colDef['title'])) { |
|
1162
|
|
|
$colDef['title'] = array_replace($this->defaultTitlesFieldsStyle, $colDef['title']); |
|
1163
|
|
|
} else { |
|
1164
|
|
|
$colDef['title'] = $this->defaultTitlesFieldsStyle; |
|
1165
|
|
|
} |
|
1166
|
|
|
|
|
1167
|
|
|
// setting empty conf with default |
|
1168
|
|
|
if (!empty($colDef['content'])) { |
|
1169
|
|
|
$colDef['content'] = array_replace($this->defaultContentsFieldsStyle, $colDef['content']); |
|
1170
|
|
|
} else { |
|
1171
|
|
|
$colDef['content'] = $this->defaultContentsFieldsStyle; |
|
1172
|
|
|
} |
|
1173
|
|
|
|
|
1174
|
|
|
if ($this->getColumnStatus($colKey)) { |
|
1175
|
|
|
// In case of flexible column |
|
1176
|
|
|
if (empty($colDef['width'])) { |
|
1177
|
|
|
$colDef['width'] = abs(($arrayWidth - $totalDefinedColWidth)) / $countFlexCol; |
|
1178
|
|
|
} |
|
1179
|
|
|
|
|
1180
|
|
|
// Set positions |
|
1181
|
|
|
$lastX = $curX; |
|
1182
|
|
|
$curX = $lastX - $colDef['width']; |
|
1183
|
|
|
$colDef['xStartPos'] = $curX; |
|
1184
|
|
|
$colDef['xEndPos'] = $lastX; |
|
1185
|
|
|
} |
|
1186
|
|
|
} |
|
1187
|
|
|
} |
|
1188
|
|
|
|
|
1189
|
|
|
/** |
|
1190
|
|
|
* get column content width from column key |
|
1191
|
|
|
* |
|
1192
|
|
|
* @param string $colKey the column key |
|
1193
|
|
|
* @return float width in mm |
|
1194
|
|
|
*/ |
|
1195
|
|
|
public function getColumnContentWidth($colKey) |
|
1196
|
|
|
{ |
|
1197
|
|
|
$colDef = $this->cols[$colKey]; |
|
1198
|
|
|
return $colDef['width'] - $colDef['content']['padding'][3] - $colDef['content']['padding'][1]; |
|
1199
|
|
|
} |
|
1200
|
|
|
|
|
1201
|
|
|
|
|
1202
|
|
|
/** |
|
1203
|
|
|
* get column content X (abscissa) left position from column key |
|
1204
|
|
|
* |
|
1205
|
|
|
* @param string $colKey the column key |
|
1206
|
|
|
* @return float X position in mm |
|
1207
|
|
|
*/ |
|
1208
|
|
|
public function getColumnContentXStart($colKey) |
|
1209
|
|
|
{ |
|
1210
|
|
|
$colDef = (isset($this->cols[$colKey]) ? $this->cols[$colKey] : null); |
|
1211
|
|
|
return (is_array($colDef) ? ((isset($colDef['xStartPos']) ? $colDef['xStartPos'] : 0) + $colDef['content']['padding'][3]) : 0); |
|
1212
|
|
|
} |
|
1213
|
|
|
|
|
1214
|
|
|
/** |
|
1215
|
|
|
* get column position rank from column key |
|
1216
|
|
|
* |
|
1217
|
|
|
* @param string $colKey the column key |
|
1218
|
|
|
* @return int rank on success and -1 on error |
|
1219
|
|
|
*/ |
|
1220
|
|
|
public function getColumnRank($colKey) |
|
1221
|
|
|
{ |
|
1222
|
|
|
if (!isset($this->cols[$colKey]['rank'])) { |
|
1223
|
|
|
return -1; |
|
1224
|
|
|
} |
|
1225
|
|
|
return $this->cols[$colKey]['rank']; |
|
1226
|
|
|
} |
|
1227
|
|
|
|
|
1228
|
|
|
/** |
|
1229
|
|
|
* get column position rank from column key |
|
1230
|
|
|
* |
|
1231
|
|
|
* @param string $newColKey the new column key |
|
1232
|
|
|
* @param array $defArray a single column definition array |
|
1233
|
|
|
* @param string $targetCol target column used to place the new column beside |
|
1234
|
|
|
* @param bool $insertAfterTarget insert before or after target column ? |
|
1235
|
|
|
* @return int new rank on success and -1 on error |
|
1236
|
|
|
*/ |
|
1237
|
|
|
public function insertNewColumnDef($newColKey, $defArray, $targetCol = '', $insertAfterTarget = false) |
|
1238
|
|
|
{ |
|
1239
|
|
|
// prepare wanted rank |
|
1240
|
|
|
$rank = -1; |
|
1241
|
|
|
|
|
1242
|
|
|
// try to get rank from target column |
|
1243
|
|
|
if (!empty($targetCol)) { |
|
1244
|
|
|
$rank = $this->getColumnRank($targetCol); |
|
1245
|
|
|
if ($rank >= 0 && $insertAfterTarget) { |
|
1246
|
|
|
$rank++; |
|
1247
|
|
|
} |
|
1248
|
|
|
} |
|
1249
|
|
|
|
|
1250
|
|
|
// get rank from new column definition |
|
1251
|
|
|
if ($rank < 0 && !empty($defArray['rank'])) { |
|
1252
|
|
|
$rank = $defArray['rank']; |
|
1253
|
|
|
} |
|
1254
|
|
|
|
|
1255
|
|
|
// error: no rank |
|
1256
|
|
|
if ($rank < 0) { |
|
1257
|
|
|
return -1; |
|
1258
|
|
|
} |
|
1259
|
|
|
|
|
1260
|
|
|
foreach ($this->cols as $colKey => & $colDef) { |
|
1261
|
|
|
if ($rank <= $colDef['rank']) { |
|
1262
|
|
|
$colDef['rank'] = $colDef['rank'] + 1; |
|
1263
|
|
|
} |
|
1264
|
|
|
} |
|
1265
|
|
|
|
|
1266
|
|
|
$defArray['rank'] = $rank; |
|
1267
|
|
|
$this->cols[$newColKey] = $defArray; // array_replace is used to preserve keys |
|
1268
|
|
|
|
|
1269
|
|
|
return $rank; |
|
1270
|
|
|
} |
|
1271
|
|
|
|
|
1272
|
|
|
|
|
1273
|
|
|
/** |
|
1274
|
|
|
* print standard column content |
|
1275
|
|
|
* |
|
1276
|
|
|
* @param TCPDI|TCPDF $pdf Pdf object |
|
1277
|
|
|
* @param float $curY current Y position |
|
1278
|
|
|
* @param string $colKey the column key |
|
1279
|
|
|
* @param string $columnText column text |
|
1280
|
|
|
* @return int Return integer <0 if KO, >= if OK |
|
1281
|
|
|
*/ |
|
1282
|
|
|
public function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '') |
|
1283
|
|
|
{ |
|
1284
|
|
|
global $hookmanager; |
|
1285
|
|
|
|
|
1286
|
|
|
$parameters = array( |
|
1287
|
|
|
'curY' => &$curY, |
|
1288
|
|
|
'columnText' => $columnText, |
|
1289
|
|
|
'colKey' => $colKey, |
|
1290
|
|
|
'pdf' => &$pdf, |
|
1291
|
|
|
); |
|
1292
|
|
|
$reshook = $hookmanager->executeHooks('printStdColumnContent', $parameters, $this); // Note that $action and $object may have been modified by hook |
|
1293
|
|
|
if ($reshook < 0) { |
|
1294
|
|
|
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); |
|
1295
|
|
|
} |
|
1296
|
|
|
if (!$reshook) { |
|
1297
|
|
|
if (empty($columnText)) { |
|
1298
|
|
|
return 0; |
|
1299
|
|
|
} |
|
1300
|
|
|
$pdf->SetXY($this->getColumnContentXStart($colKey), $curY); // Set current position |
|
1301
|
|
|
$colDef = $this->cols[$colKey]; |
|
1302
|
|
|
// save current cell padding |
|
1303
|
|
|
$curentCellPaddinds = $pdf->getCellPaddings(); |
|
1304
|
|
|
// set cell padding with column content definition |
|
1305
|
|
|
$pdf->setCellPaddings(isset($colDef['content']['padding'][3]) ? $colDef['content']['padding'][3] : 0, isset($colDef['content']['padding'][0]) ? $colDef['content']['padding'][0] : 0, isset($colDef['content']['padding'][1]) ? $colDef['content']['padding'][1] : 0, isset($colDef['content']['padding'][2]) ? $colDef['content']['padding'][2] : 0); |
|
1306
|
|
|
$pdf->writeHTMLCell($colDef['width'], 2, isset($colDef['xStartPos']) ? $colDef['xStartPos'] : 0, $curY, $columnText, 0, 1, 0, true, $colDef['content']['align']); |
|
1307
|
|
|
|
|
1308
|
|
|
// restore cell padding |
|
1309
|
|
|
$pdf->setCellPaddings($curentCellPaddinds['L'], $curentCellPaddinds['T'], $curentCellPaddinds['R'], $curentCellPaddinds['B']); |
|
1310
|
|
|
} |
|
1311
|
|
|
|
|
1312
|
|
|
return 0; |
|
1313
|
|
|
} |
|
1314
|
|
|
|
|
1315
|
|
|
|
|
1316
|
|
|
/** |
|
1317
|
|
|
* print description column content |
|
1318
|
|
|
* |
|
1319
|
|
|
* @param TCPDI|TCPDF $pdf Pdf object |
|
1320
|
|
|
* @param float $curY current Y position |
|
1321
|
|
|
* @param string $colKey the column key |
|
1322
|
|
|
* @param object $object CommonObject |
|
1323
|
|
|
* @param int $i the $object->lines array key |
|
1324
|
|
|
* @param Translate $outputlangs Output language |
|
1325
|
|
|
* @param int $hideref hide ref |
|
1326
|
|
|
* @param int $hidedesc hide desc |
|
1327
|
|
|
* @param int $issupplierline if object need supplier product |
|
1328
|
|
|
* @return void |
|
1329
|
|
|
*/ |
|
1330
|
|
|
public function printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0) |
|
1331
|
|
|
{ |
|
1332
|
|
|
// load desc col params |
|
1333
|
|
|
$colDef = $this->cols[$colKey]; |
|
1334
|
|
|
// save current cell padding |
|
1335
|
|
|
$curentCellPaddinds = $pdf->getCellPaddings(); |
|
1336
|
|
|
// set cell padding with column content definition |
|
1337
|
|
|
$pdf->setCellPaddings($colDef['content']['padding'][3], $colDef['content']['padding'][0], $colDef['content']['padding'][1], $colDef['content']['padding'][2]); |
|
1338
|
|
|
|
|
1339
|
|
|
// line description |
|
1340
|
|
|
pdf_writelinedesc($pdf, $object, $i, $outputlangs, $colDef['width'], 3, $colDef['xStartPos'], $curY, $hideref, $hidedesc, $issupplierline, empty($colDef['content']['align']) ? 'J' : $colDef['content']['align']); |
|
1341
|
|
|
$posYAfterDescription = $pdf->GetY() - $colDef['content']['padding'][0]; |
|
1342
|
|
|
|
|
1343
|
|
|
// restore cell padding |
|
1344
|
|
|
$pdf->setCellPaddings($curentCellPaddinds['L'], $curentCellPaddinds['T'], $curentCellPaddinds['R'], $curentCellPaddinds['B']); |
|
1345
|
|
|
|
|
1346
|
|
|
// Display extrafield if needed |
|
1347
|
|
|
$params = array( |
|
1348
|
|
|
'display' => 'list', |
|
1349
|
|
|
'printableEnable' => array(3), |
|
1350
|
|
|
'printableEnableNotEmpty' => array(4) |
|
1351
|
|
|
); |
|
1352
|
|
|
$extrafieldDesc = $this->getExtrafieldsInHtml($object->lines[$i], $outputlangs, $params); |
|
1353
|
|
|
if (!empty($extrafieldDesc)) { |
|
1354
|
|
|
$this->printStdColumnContent($pdf, $posYAfterDescription, $colKey, $extrafieldDesc); |
|
1355
|
|
|
} |
|
1356
|
|
|
} |
|
1357
|
|
|
|
|
1358
|
|
|
/** |
|
1359
|
|
|
* get extrafield content for pdf writeHtmlCell compatibility |
|
1360
|
|
|
* usage for PDF line columns and object note block |
|
1361
|
|
|
* |
|
1362
|
|
|
* @param CommonObject $object Common object |
|
1363
|
|
|
* @param string $extrafieldKey The extrafield key |
|
1364
|
|
|
* @param Translate $outputlangs The output langs (if value is __(XXX)__ we use it to translate it). |
|
1365
|
|
|
* @return string |
|
1366
|
|
|
*/ |
|
1367
|
|
|
public function getExtrafieldContent($object, $extrafieldKey, $outputlangs = null) |
|
1368
|
|
|
{ |
|
1369
|
|
|
global $hookmanager; |
|
1370
|
|
|
|
|
1371
|
|
|
if (empty($object->table_element)) { |
|
1372
|
|
|
return ''; |
|
1373
|
|
|
} |
|
1374
|
|
|
|
|
1375
|
|
|
$extrafieldsKeyPrefix = "options_"; |
|
1376
|
|
|
|
|
1377
|
|
|
// Cleanup extrafield key to remove prefix if present |
|
1378
|
|
|
$pos = strpos($extrafieldKey, $extrafieldsKeyPrefix); |
|
1379
|
|
|
if ($pos === 0) { |
|
1380
|
|
|
$extrafieldKey = substr($extrafieldKey, strlen($extrafieldsKeyPrefix)); |
|
1381
|
|
|
} |
|
1382
|
|
|
|
|
1383
|
|
|
$extrafieldOptionsKey = $extrafieldsKeyPrefix . $extrafieldKey; |
|
1384
|
|
|
|
|
1385
|
|
|
|
|
1386
|
|
|
// Load extra fields if they haven't been loaded already. |
|
1387
|
|
|
if (is_null($this->extrafieldsCache)) { |
|
1388
|
|
|
$this->extrafieldsCache = new ExtraFields($this->db); |
|
1389
|
|
|
} |
|
1390
|
|
|
if (empty($this->extrafieldsCache->attributes[$object->table_element])) { |
|
1391
|
|
|
$this->extrafieldsCache->fetch_name_optionals_label($object->table_element); |
|
1392
|
|
|
} |
|
1393
|
|
|
$extrafields = $this->extrafieldsCache; |
|
1394
|
|
|
|
|
1395
|
|
|
$extrafieldOutputContent = ''; |
|
1396
|
|
|
if (isset($object->array_options[$extrafieldOptionsKey])) { |
|
1397
|
|
|
$extrafieldOutputContent = $extrafields->showOutputField($extrafieldKey, $object->array_options[$extrafieldOptionsKey], '', $object->table_element, $outputlangs); |
|
1398
|
|
|
} |
|
1399
|
|
|
|
|
1400
|
|
|
// TODO : allow showOutputField to be pdf public friendly, ex: in a link to object, clean getNomUrl to remove link and images... like a getName methode ... |
|
1401
|
|
|
if ($extrafields->attributes[$object->table_element]['type'][$extrafieldKey] == 'link') { |
|
1402
|
|
|
// for lack of anything better we cleanup all html tags |
|
1403
|
|
|
$extrafieldOutputContent = dol_string_nohtmltag($extrafieldOutputContent); |
|
1404
|
|
|
} |
|
1405
|
|
|
|
|
1406
|
|
|
$parameters = array( |
|
1407
|
|
|
'object' => $object, |
|
1408
|
|
|
'extrafields' => $extrafields, |
|
1409
|
|
|
'extrafieldKey' => $extrafieldKey, |
|
1410
|
|
|
'extrafieldOutputContent' => & $extrafieldOutputContent |
|
1411
|
|
|
); |
|
1412
|
|
|
$reshook = $hookmanager->executeHooks('getPDFExtrafieldContent', $parameters, $this); // Note that $action and $object may have been modified by hook |
|
1413
|
|
|
if ($reshook < 0) { |
|
1414
|
|
|
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); |
|
1415
|
|
|
} |
|
1416
|
|
|
if ($reshook) { |
|
1417
|
|
|
$extrafieldOutputContent = $hookmanager->resPrint; |
|
1418
|
|
|
} |
|
1419
|
|
|
|
|
1420
|
|
|
return $extrafieldOutputContent; |
|
1421
|
|
|
} |
|
1422
|
|
|
|
|
1423
|
|
|
/** |
|
1424
|
|
|
* display extrafields columns content |
|
1425
|
|
|
* |
|
1426
|
|
|
* @param CommonObjectLine $object line of common object |
|
1427
|
|
|
* @param Translate $outputlangs Output language |
|
1428
|
|
|
* @param array $params array of additional parameters |
|
1429
|
|
|
* @return string Html string |
|
1430
|
|
|
*/ |
|
1431
|
|
|
public function getExtrafieldsInHtml($object, $outputlangs, $params = array()) |
|
1432
|
|
|
{ |
|
1433
|
|
|
global $hookmanager; |
|
1434
|
|
|
|
|
1435
|
|
|
if (empty($object->table_element)) { |
|
1436
|
|
|
return ""; |
|
1437
|
|
|
} |
|
1438
|
|
|
|
|
1439
|
|
|
// Load extrafields if not already done |
|
1440
|
|
|
if (is_null($this->extrafieldsCache)) { |
|
1441
|
|
|
$this->extrafieldsCache = new ExtraFields($this->db); |
|
1442
|
|
|
} |
|
1443
|
|
|
if (empty($this->extrafieldsCache->attributes[$object->table_element])) { |
|
1444
|
|
|
$this->extrafieldsCache->fetch_name_optionals_label($object->table_element); |
|
1445
|
|
|
} |
|
1446
|
|
|
$extrafields = $this->extrafieldsCache; |
|
1447
|
|
|
|
|
1448
|
|
|
$defaultParams = array( |
|
1449
|
|
|
'style' => '', |
|
1450
|
|
|
'display' => 'auto', // auto, table, list |
|
1451
|
|
|
'printableEnable' => array(1), |
|
1452
|
|
|
'printableEnableNotEmpty' => array(2), |
|
1453
|
|
|
|
|
1454
|
|
|
'table' => array( |
|
1455
|
|
|
'maxItemsInRow' => 2, |
|
1456
|
|
|
'cellspacing' => 0, |
|
1457
|
|
|
'cellpadding' => 0, |
|
1458
|
|
|
'border' => 0, |
|
1459
|
|
|
'labelcolwidth' => '25%', |
|
1460
|
|
|
'arrayOfLineBreakType' => array('text', 'html') |
|
1461
|
|
|
), |
|
1462
|
|
|
|
|
1463
|
|
|
'list' => array( |
|
1464
|
|
|
'separator' => '<br>' |
|
1465
|
|
|
), |
|
1466
|
|
|
|
|
1467
|
|
|
'auto' => array( |
|
1468
|
|
|
'list' => 0, // 0 for default |
|
1469
|
|
|
'table' => 4 // if there more than x extrafield to display |
|
1470
|
|
|
), |
|
1471
|
|
|
); |
|
1472
|
|
|
|
|
1473
|
|
|
$params = $params + $defaultParams; |
|
1474
|
|
|
|
|
1475
|
|
|
/** |
|
1476
|
|
|
* @var ExtraFields $extrafields |
|
1477
|
|
|
*/ |
|
1478
|
|
|
|
|
1479
|
|
|
$html = ''; |
|
1480
|
|
|
$fields = array(); |
|
1481
|
|
|
|
|
1482
|
|
|
if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label'])) { |
|
1483
|
|
|
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { |
|
1484
|
|
|
// Enable extrafield ? |
|
1485
|
|
|
$enabled = 0; |
|
1486
|
|
|
$disableOnEmpty = 0; |
|
1487
|
|
|
if (!empty($extrafields->attributes[$object->table_element]['printable'][$key])) { |
|
1488
|
|
|
$printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]); |
|
1489
|
|
|
if (in_array($printable, $params['printableEnable']) || in_array($printable, $params['printableEnableNotEmpty'])) { |
|
1490
|
|
|
$enabled = 1; |
|
1491
|
|
|
} |
|
1492
|
|
|
|
|
1493
|
|
|
if (in_array($printable, $params['printableEnableNotEmpty'])) { |
|
1494
|
|
|
$disableOnEmpty = 1; |
|
1495
|
|
|
} |
|
1496
|
|
|
} |
|
1497
|
|
|
|
|
1498
|
|
|
if (empty($enabled)) { |
|
1499
|
|
|
continue; |
|
1500
|
|
|
} |
|
1501
|
|
|
|
|
1502
|
|
|
// Load language if required |
|
1503
|
|
|
if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) { |
|
1504
|
|
|
$outputlangs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); |
|
1505
|
|
|
} |
|
1506
|
|
|
|
|
1507
|
|
|
$field = new stdClass(); |
|
1508
|
|
|
$field->rank = intval($extrafields->attributes[$object->table_element]['pos'][$key]); |
|
1509
|
|
|
$field->content = $this->getExtrafieldContent($object, $key, $outputlangs); |
|
1510
|
|
|
$field->label = $outputlangs->transnoentities($label); |
|
1511
|
|
|
$field->type = $extrafields->attributes[$object->table_element]['type'][$key]; |
|
1512
|
|
|
|
|
1513
|
|
|
// don't display if empty |
|
1514
|
|
|
if ($disableOnEmpty && empty($field->content)) { |
|
1515
|
|
|
continue; |
|
1516
|
|
|
} |
|
1517
|
|
|
|
|
1518
|
|
|
$fields[] = $field; |
|
1519
|
|
|
} |
|
1520
|
|
|
} |
|
1521
|
|
|
|
|
1522
|
|
|
if (!empty($fields)) { |
|
1523
|
|
|
// Sort extrafields by rank |
|
1524
|
|
|
uasort( |
|
1525
|
|
|
$fields, |
|
1526
|
|
|
/** |
|
1527
|
|
|
* @param stdClass $a |
|
1528
|
|
|
* @param stdClass $b |
|
1529
|
|
|
* @return int<-1,1> |
|
1530
|
|
|
*/ |
|
1531
|
|
|
static function ($a, $b) { |
|
1532
|
|
|
return ($a->rank > $b->rank) ? 1 : -1; |
|
1533
|
|
|
} |
|
1534
|
|
|
); |
|
1535
|
|
|
|
|
1536
|
|
|
// define some HTML content with style |
|
1537
|
|
|
$html .= !empty($params['style']) ? '<style>' . $params['style'] . '</style>' : ''; |
|
1538
|
|
|
|
|
1539
|
|
|
// auto select display format |
|
1540
|
|
|
if ($params['display'] == 'auto') { |
|
1541
|
|
|
$lastNnumbItems = 0; |
|
1542
|
|
|
foreach ($params['auto'] as $display => $numbItems) { |
|
1543
|
|
|
if ($lastNnumbItems <= $numbItems && count($fields) > $numbItems) { |
|
1544
|
|
|
$lastNnumbItems = $numbItems; |
|
1545
|
|
|
$params['display'] = $display; |
|
1546
|
|
|
} |
|
1547
|
|
|
} |
|
1548
|
|
|
} |
|
1549
|
|
|
|
|
1550
|
|
|
if ($params['display'] == 'list') { |
|
1551
|
|
|
// Display in list format |
|
1552
|
|
|
$i = 0; |
|
1553
|
|
|
foreach ($fields as $field) { |
|
1554
|
|
|
$html .= !empty($i) ? $params['list']['separator'] : ''; |
|
1555
|
|
|
$html .= '<strong>' . $field->label . ' : </strong>'; |
|
1556
|
|
|
$html .= $field->content; |
|
1557
|
|
|
$i++; |
|
1558
|
|
|
} |
|
1559
|
|
|
} elseif ($params['display'] == 'table') { |
|
1560
|
|
|
// Display in table format |
|
1561
|
|
|
$html .= '<table class="extrafield-table" cellspacing="' . $params['table']['cellspacing'] . '" cellpadding="' . $params['table']['cellpadding'] . '" border="' . $params['table']['border'] . '">'; |
|
1562
|
|
|
|
|
1563
|
|
|
$html .= "<tr>"; |
|
1564
|
|
|
$itemsInRow = 0; |
|
1565
|
|
|
$maxItemsInRow = $params['table']['maxItemsInRow']; |
|
1566
|
|
|
foreach ($fields as $field) { |
|
1567
|
|
|
//$html.= !empty($html)?'<br>':''; |
|
1568
|
|
|
if ($itemsInRow >= $maxItemsInRow) { |
|
1569
|
|
|
// start a new line |
|
1570
|
|
|
$html .= "</tr><tr>"; |
|
1571
|
|
|
$itemsInRow = 0; |
|
1572
|
|
|
} |
|
1573
|
|
|
|
|
1574
|
|
|
// for some type we need line break |
|
1575
|
|
|
if (in_array($field->type, $params['table']['arrayOfLineBreakType'])) { |
|
1576
|
|
|
if ($itemsInRow > 0) { |
|
1577
|
|
|
// close table row and empty cols |
|
1578
|
|
|
for ($i = $itemsInRow; $i <= $maxItemsInRow; $i++) { |
|
1579
|
|
|
$html .= "<td></td><td></td>"; |
|
1580
|
|
|
} |
|
1581
|
|
|
$html .= "</tr>"; |
|
1582
|
|
|
|
|
1583
|
|
|
// start a new line |
|
1584
|
|
|
$html .= "<tr>"; |
|
1585
|
|
|
} |
|
1586
|
|
|
|
|
1587
|
|
|
$itemsInRow = $maxItemsInRow; |
|
1588
|
|
|
$html .= '<td colspan="' . ($maxItemsInRow * 2 - 1) . '">'; |
|
1589
|
|
|
$html .= '<strong>' . $field->label . ' :</strong> '; |
|
1590
|
|
|
$html .= $field->content; |
|
1591
|
|
|
$html .= "</td>"; |
|
1592
|
|
|
} else { |
|
1593
|
|
|
$itemsInRow++; |
|
1594
|
|
|
$html .= '<td width="' . $params['table']['labelcolwidth'] . '" class="extrafield-label">'; |
|
1595
|
|
|
$html .= '<strong>' . $field->label . ' :</strong>'; |
|
1596
|
|
|
$html .= "</td>"; |
|
1597
|
|
|
|
|
1598
|
|
|
|
|
1599
|
|
|
$html .= '<td class="extrafield-content">'; |
|
1600
|
|
|
$html .= $field->content; |
|
1601
|
|
|
$html .= "</td>"; |
|
1602
|
|
|
} |
|
1603
|
|
|
} |
|
1604
|
|
|
$html .= "</tr>"; |
|
1605
|
|
|
|
|
1606
|
|
|
$html .= '</table>'; |
|
1607
|
|
|
} |
|
1608
|
|
|
} |
|
1609
|
|
|
|
|
1610
|
|
|
return $html; |
|
1611
|
|
|
} |
|
1612
|
|
|
|
|
1613
|
|
|
|
|
1614
|
|
|
/** |
|
1615
|
|
|
* get column status from column key |
|
1616
|
|
|
* |
|
1617
|
|
|
* @param string $colKey the column key |
|
1618
|
|
|
* @return boolean true if column on |
|
1619
|
|
|
*/ |
|
1620
|
|
|
public function getColumnStatus($colKey) |
|
1621
|
|
|
{ |
|
1622
|
|
|
if (!empty($this->cols[$colKey]['status'])) { |
|
1623
|
|
|
return true; |
|
1624
|
|
|
} else { |
|
1625
|
|
|
return false; |
|
1626
|
|
|
} |
|
1627
|
|
|
} |
|
1628
|
|
|
|
|
1629
|
|
|
/** |
|
1630
|
|
|
* Print standard column content |
|
1631
|
|
|
* |
|
1632
|
|
|
* @param TCPDI|TCPDF $pdf Pdf object |
|
1633
|
|
|
* @param float $tab_top Tab top position |
|
1634
|
|
|
* @param float $tab_height Default tab height |
|
1635
|
|
|
* @param Translate $outputlangs Output language |
|
1636
|
|
|
* @param int $hidetop Hide top |
|
1637
|
|
|
* @return float Height of col tab titles |
|
1638
|
|
|
*/ |
|
1639
|
|
|
public function pdfTabTitles(&$pdf, $tab_top, $tab_height, $outputlangs, $hidetop = 0) |
|
1640
|
|
|
{ |
|
1641
|
|
|
global $hookmanager, $conf; |
|
1642
|
|
|
|
|
1643
|
|
|
foreach ($this->cols as $colKey => $colDef) { |
|
1644
|
|
|
$parameters = array( |
|
1645
|
|
|
'colKey' => $colKey, |
|
1646
|
|
|
'pdf' => $pdf, |
|
1647
|
|
|
'outputlangs' => $outputlangs, |
|
1648
|
|
|
'tab_top' => $tab_top, |
|
1649
|
|
|
'tab_height' => $tab_height, |
|
1650
|
|
|
'hidetop' => $hidetop |
|
1651
|
|
|
); |
|
1652
|
|
|
|
|
1653
|
|
|
$reshook = $hookmanager->executeHooks('pdfTabTitles', $parameters, $this); // Note that $object may have been modified by hook |
|
1654
|
|
|
if ($reshook < 0) { |
|
1655
|
|
|
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); |
|
1656
|
|
|
} elseif (empty($reshook)) { |
|
1657
|
|
|
if (!$this->getColumnStatus($colKey)) { |
|
1658
|
|
|
continue; |
|
1659
|
|
|
} |
|
1660
|
|
|
|
|
1661
|
|
|
// get title label |
|
1662
|
|
|
$colDef['title']['label'] = !empty($colDef['title']['label']) ? $colDef['title']['label'] : $outputlangs->transnoentities($colDef['title']['textkey']); |
|
1663
|
|
|
|
|
1664
|
|
|
// Add column separator |
|
1665
|
|
|
if (!empty($colDef['border-left']) && isset($colDef['xStartPos'])) { |
|
1666
|
|
|
$pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height); |
|
1667
|
|
|
} |
|
1668
|
|
|
|
|
1669
|
|
|
if (empty($hidetop)) { |
|
1670
|
|
|
// save current cell padding |
|
1671
|
|
|
$curentCellPaddinds = $pdf->getCellPaddings(); |
|
1672
|
|
|
|
|
1673
|
|
|
// Add space for lines (more if we need to show a second alternative language) |
|
1674
|
|
|
global $outputlangsbis; |
|
1675
|
|
|
if (is_object($outputlangsbis)) { |
|
1676
|
|
|
// set cell padding with column title definition |
|
1677
|
|
|
$pdf->setCellPaddings($colDef['title']['padding'][3], $colDef['title']['padding'][0], $colDef['title']['padding'][1], 0.5); |
|
1678
|
|
|
} else { |
|
1679
|
|
|
// set cell padding with column title definition |
|
1680
|
|
|
$pdf->setCellPaddings($colDef['title']['padding'][3], $colDef['title']['padding'][0], $colDef['title']['padding'][1], $colDef['title']['padding'][2]); |
|
1681
|
|
|
} |
|
1682
|
|
|
if (isset($colDef['title']['align'])) { |
|
1683
|
|
|
$align = $colDef['title']['align']; |
|
1684
|
|
|
} else { |
|
1685
|
|
|
$align = ''; |
|
1686
|
|
|
} |
|
1687
|
|
|
$pdf->SetXY($colDef['xStartPos'], $tab_top); |
|
1688
|
|
|
$textWidth = $colDef['width']; |
|
1689
|
|
|
$pdf->MultiCell($textWidth, 2, $colDef['title']['label'], '', $align); |
|
1690
|
|
|
|
|
1691
|
|
|
// Add variant of translation if $outputlangsbis is an object |
|
1692
|
|
|
if (is_object($outputlangsbis) && trim($colDef['title']['label'])) { |
|
1693
|
|
|
$pdf->setCellPaddings($colDef['title']['padding'][3], 0, $colDef['title']['padding'][1], $colDef['title']['padding'][2]); |
|
1694
|
|
|
$pdf->SetXY($colDef['xStartPos'], $pdf->GetY()); |
|
1695
|
|
|
$textbis = $outputlangsbis->transnoentities($colDef['title']['textkey']); |
|
1696
|
|
|
$pdf->MultiCell($textWidth, 2, $textbis, '', $align); |
|
1697
|
|
|
} |
|
1698
|
|
|
|
|
1699
|
|
|
$this->tabTitleHeight = max($pdf->GetY() - $tab_top, $this->tabTitleHeight); |
|
1700
|
|
|
|
|
1701
|
|
|
// restore cell padding |
|
1702
|
|
|
$pdf->setCellPaddings($curentCellPaddinds['L'], $curentCellPaddinds['T'], $curentCellPaddinds['R'], $curentCellPaddinds['B']); |
|
1703
|
|
|
} |
|
1704
|
|
|
} |
|
1705
|
|
|
} |
|
1706
|
|
|
|
|
1707
|
|
|
return $this->tabTitleHeight; |
|
1708
|
|
|
} |
|
1709
|
|
|
|
|
1710
|
|
|
|
|
1711
|
|
|
|
|
1712
|
|
|
/** |
|
1713
|
|
|
* Define Array Column Field for extrafields |
|
1714
|
|
|
* |
|
1715
|
|
|
* @param object $object common object det |
|
1716
|
|
|
* @param Translate $outputlangs langs |
|
1717
|
|
|
* @param int $hidedetails Do not show line details |
|
1718
|
|
|
* @return int Return integer <0 if KO, >=0 if OK |
|
1719
|
|
|
*/ |
|
1720
|
|
|
public function defineColumnExtrafield($object, $outputlangs, $hidedetails = 0) |
|
1721
|
|
|
{ |
|
1722
|
|
|
if (!empty($hidedetails)) { |
|
1723
|
|
|
return 0; |
|
1724
|
|
|
} |
|
1725
|
|
|
|
|
1726
|
|
|
if (empty($object->table_element)) { |
|
1727
|
|
|
return 0; |
|
1728
|
|
|
} |
|
1729
|
|
|
|
|
1730
|
|
|
// Load extra fields if they haven't been loaded already. |
|
1731
|
|
|
if (is_null($this->extrafieldsCache)) { |
|
1732
|
|
|
$this->extrafieldsCache = new ExtraFields($this->db); |
|
1733
|
|
|
} |
|
1734
|
|
|
if (empty($this->extrafieldsCache->attributes[$object->table_element])) { |
|
1735
|
|
|
$this->extrafieldsCache->fetch_name_optionals_label($object->table_element); |
|
1736
|
|
|
} |
|
1737
|
|
|
$extrafields = $this->extrafieldsCache; |
|
1738
|
|
|
|
|
1739
|
|
|
|
|
1740
|
|
|
if (!empty($extrafields->attributes[$object->table_element]) && is_array($extrafields->attributes[$object->table_element]) && array_key_exists('label', $extrafields->attributes[$object->table_element]) && is_array($extrafields->attributes[$object->table_element]['label'])) { |
|
1741
|
|
|
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { |
|
1742
|
|
|
// Don't display separator yet even is set to be displayed (not compatible yet) |
|
1743
|
|
|
if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') { |
|
1744
|
|
|
continue; |
|
1745
|
|
|
} |
|
1746
|
|
|
|
|
1747
|
|
|
// Enable extrafield ? |
|
1748
|
|
|
$enabled = 0; |
|
1749
|
|
|
if (!empty($extrafields->attributes[$object->table_element]['printable'][$key])) { |
|
1750
|
|
|
$printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]); |
|
1751
|
|
|
if ($printable === 1 || $printable === 2) { |
|
1752
|
|
|
$enabled = 1; |
|
1753
|
|
|
} |
|
1754
|
|
|
// Note : if $printable === 3 or 4 so, it's displayed after line description not in cols |
|
1755
|
|
|
} |
|
1756
|
|
|
|
|
1757
|
|
|
if (!$enabled) { |
|
1758
|
|
|
continue; |
|
1759
|
|
|
} // don't waste resources if we don't need them... |
|
1760
|
|
|
|
|
1761
|
|
|
// Load language if required |
|
1762
|
|
|
if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) { |
|
1763
|
|
|
$outputlangs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); |
|
1764
|
|
|
} |
|
1765
|
|
|
|
|
1766
|
|
|
// TODO : add more extrafield customisation capacities for PDF like width, rank... |
|
1767
|
|
|
|
|
1768
|
|
|
// set column definition |
|
1769
|
|
|
$def = array( |
|
1770
|
|
|
'rank' => intval($extrafields->attributes[$object->table_element]['pos'][$key]), |
|
1771
|
|
|
'width' => 25, // in mm |
|
1772
|
|
|
'status' => (bool) $enabled, |
|
1773
|
|
|
'title' => array( |
|
1774
|
|
|
'label' => $outputlangs->transnoentities($label) |
|
1775
|
|
|
), |
|
1776
|
|
|
'content' => array( |
|
1777
|
|
|
'align' => 'C' |
|
1778
|
|
|
), |
|
1779
|
|
|
'border-left' => true, // add left line separator |
|
1780
|
|
|
); |
|
1781
|
|
|
|
|
1782
|
|
|
$alignTypeRight = array('double', 'int', 'price'); |
|
1783
|
|
|
if (in_array($extrafields->attributes[$object->table_element]['type'][$key], $alignTypeRight)) { |
|
1784
|
|
|
$def['content']['align'] = 'R'; |
|
1785
|
|
|
} |
|
1786
|
|
|
|
|
1787
|
|
|
$alignTypeLeft = array('text', 'html'); |
|
1788
|
|
|
if (in_array($extrafields->attributes[$object->table_element]['type'][$key], $alignTypeLeft)) { |
|
1789
|
|
|
$def['content']['align'] = 'L'; |
|
1790
|
|
|
} |
|
1791
|
|
|
|
|
1792
|
|
|
|
|
1793
|
|
|
// for extrafields we use rank of extrafield to place it on PDF |
|
1794
|
|
|
$this->insertNewColumnDef("options_" . $key, $def); |
|
1795
|
|
|
} |
|
1796
|
|
|
} |
|
1797
|
|
|
|
|
1798
|
|
|
return 1; |
|
1799
|
|
|
} |
|
1800
|
|
|
|
|
1801
|
|
|
/** |
|
1802
|
|
|
* Define Array Column Field into $this->cols |
|
1803
|
|
|
* This method must be implemented by the module that generate the document with its own columns. |
|
1804
|
|
|
* |
|
1805
|
|
|
* @param Object $object Common object |
|
1806
|
|
|
* @param Translate $outputlangs Langs |
|
1807
|
|
|
* @param int $hidedetails Do not show line details |
|
1808
|
|
|
* @param int $hidedesc Do not show desc |
|
1809
|
|
|
* @param int $hideref Do not show ref |
|
1810
|
|
|
* @return void |
|
1811
|
|
|
*/ |
|
1812
|
|
|
public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) |
|
1813
|
|
|
{ |
|
1814
|
|
|
// Default field style for content |
|
1815
|
|
|
$this->defaultContentsFieldsStyle = array( |
|
1816
|
|
|
'align' => 'R', // R,C,L |
|
1817
|
|
|
'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left |
|
1818
|
|
|
); |
|
1819
|
|
|
|
|
1820
|
|
|
// Default field style for content |
|
1821
|
|
|
$this->defaultTitlesFieldsStyle = array( |
|
1822
|
|
|
'align' => 'C', // R,C,L |
|
1823
|
|
|
'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left |
|
1824
|
|
|
); |
|
1825
|
|
|
|
|
1826
|
|
|
// Example |
|
1827
|
|
|
/* |
|
1828
|
|
|
$rank = 0; // do not use negative rank |
|
1829
|
|
|
$this->cols['desc'] = array( |
|
1830
|
|
|
'rank' => $rank, |
|
1831
|
|
|
'width' => false, // only for desc |
|
1832
|
|
|
'status' => true, |
|
1833
|
|
|
'title' => array( |
|
1834
|
|
|
'textkey' => 'Designation', // use lang key is useful in somme case with module |
|
1835
|
|
|
'align' => 'L', |
|
1836
|
|
|
// 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label |
|
1837
|
|
|
// 'label' => ' ', // the final label |
|
1838
|
|
|
'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left |
|
1839
|
|
|
), |
|
1840
|
|
|
'content' => array( |
|
1841
|
|
|
'align' => 'L', |
|
1842
|
|
|
'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left |
|
1843
|
|
|
), |
|
1844
|
|
|
); |
|
1845
|
|
|
*/ |
|
1846
|
|
|
} |
|
1847
|
|
|
} |
|
1848
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.