Passed
Branch develop (01f96b)
by
unknown
30:45
created

pdf_sponge::drawInfoTable()   F

Complexity

Conditions 45
Paths > 20000

Size

Total Lines 158
Code Lines 92

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 45
eloc 92
c 0
b 0
f 0
nc 36726
nop 4
dl 0
loc 158
rs 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* Copyright (C) 2004-2014  Laurent Destailleur     <[email protected]>
3
 * Copyright (C) 2005-2012  Regis Houssin           <[email protected]>
4
 * Copyright (C) 2008       Raphael Bertrand        <[email protected]>
5
 * Copyright (C) 2010-2014  Juanjo Menent           <[email protected]>
6
 * Copyright (C) 2012       Christophe Battarel     <[email protected]>
7
 * Copyright (C) 2012       Cédric Salvador         <[email protected]>
8
 * Copyright (C) 2012-2014  Raphaël Doursenaud      <[email protected]>
9
 * Copyright (C) 2015       Marcos García           <[email protected]>
10
 * Copyright (C) 2017       Ferran Marcet           <[email protected]>
11
 * Copyright (C) 2018       Frédéric France         <[email protected]>
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 3 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25
 * or see https://www.gnu.org/
26
 */
27
28
/**
29
 *  \file       htdocs/core/modules/facture/doc/pdf_sponge.modules.php
30
 *  \ingroup    facture
31
 *  \brief      File of class to generate customers invoices from sponge model
32
 */
33
34
require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
35
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
36
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
37
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
38
require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
39
40
41
/**
42
 *	Class to manage PDF invoice template sponge
43
 */
44
class pdf_sponge extends ModelePDFFactures
45
{
46
    /**
47
     * @var DoliDb Database handler
48
     */
49
    public $db;
50
51
	/**
52
     * @var string model name
53
     */
54
    public $name;
55
56
	/**
57
     * @var string model description (short text)
58
     */
59
    public $description;
60
61
    /**
62
     * @var int     Save the name of generated file as the main doc when generating a doc with this template
63
     */
64
    public $update_main_doc_field;
65
66
	/**
67
     * @var string document type
68
     */
69
    public $type;
70
71
	/**
72
     * @var array Minimum version of PHP required by module.
73
     * e.g.: PHP ≥ 5.5 = array(5, 5)
74
     */
75
	public $phpmin = array(5, 5);
76
77
	/**
78
     * Dolibarr version of the loaded document
79
     * @var string
80
     */
81
	public $version = 'dolibarr';
82
83
     /**
84
     * @var int page_largeur
85
     */
86
    public $page_largeur;
87
88
	/**
89
     * @var int page_hauteur
90
     */
91
    public $page_hauteur;
92
93
	/**
94
     * @var array format
95
     */
96
    public $format;
97
98
	/**
99
     * @var int marge_gauche
100
     */
101
	public $marge_gauche;
102
103
	/**
104
     * @var int marge_droite
105
     */
106
	public $marge_droite;
107
108
	/**
109
     * @var int marge_haute
110
     */
111
	public $marge_haute;
112
113
	/**
114
     * @var int marge_basse
115
     */
116
	public $marge_basse;
117
118
    /**
119
	* Issuer
120
	* @var Societe Object that emits
121
	*/
122
	public $emetteur;
123
124
	/**
125
	 * @var bool Situation invoice type
126
	 */
127
	public $situationinvoice;
128
129
130
	/**
131
	 * @var array of document table collumns
132
	 */
133
	public $cols;
134
135
136
	/**
137
	 *	Constructor
138
	 *
139
	 *  @param		DoliDB		$db      Database handler
140
	 */
141
	public function __construct($db)
142
	{
143
		global $conf, $langs, $mysoc;
144
145
		// Translations
146
		$langs->loadLangs(array("main", "bills"));
147
148
		$this->db = $db;
149
		$this->name = "sponge";
150
		$this->description = $langs->trans('PDFSpongeDescription');
151
		$this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
152
153
		// Dimension page
154
		$this->type = 'pdf';
155
		$formatarray = pdf_getFormat();
156
		$this->page_largeur = $formatarray['width'];
157
		$this->page_hauteur = $formatarray['height'];
158
		$this->format = array($this->page_largeur, $this->page_hauteur);
159
		$this->marge_gauche = isset($conf->global->MAIN_PDF_MARGIN_LEFT) ? $conf->global->MAIN_PDF_MARGIN_LEFT : 10;
160
		$this->marge_droite = isset($conf->global->MAIN_PDF_MARGIN_RIGHT) ? $conf->global->MAIN_PDF_MARGIN_RIGHT : 10;
161
		$this->marge_haute = isset($conf->global->MAIN_PDF_MARGIN_TOP) ? $conf->global->MAIN_PDF_MARGIN_TOP : 10;
162
		$this->marge_basse = isset($conf->global->MAIN_PDF_MARGIN_BOTTOM) ? $conf->global->MAIN_PDF_MARGIN_BOTTOM : 10;
163
164
		$this->option_logo = 1; // Display logo
165
		$this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
166
		$this->option_modereg = 1; // Display payment mode
167
		$this->option_condreg = 1; // Display payment terms
168
		$this->option_codeproduitservice = 1; // Display product-service code
169
		$this->option_multilang = 1; // Available in several languages
170
		$this->option_escompte = 1; // Displays if there has been a discount
171
		$this->option_credit_note = 1; // Support credit notes
172
		$this->option_freetext = 1; // Support add of a personalised text
173
		$this->option_draft_watermark = 1; // Support add of a watermark on drafts
174
175
		// Get source company
176
		$this->emetteur = $mysoc;
177
		if (empty($this->emetteur->country_code)) $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
178
179
		// Define position of columns
180
		$this->posxdesc = $this->marge_gauche + 1; // used for notes ans other stuff
181
182
183
		$this->tabTitleHeight = 5; // default height
184
185
		//  Use new system for position of columns, view  $this->defineColumnField()
186
187
		$this->tva = array();
188
		$this->localtax1 = array();
189
		$this->localtax2 = array();
190
		$this->atleastoneratenotnull = 0;
191
		$this->atleastonediscount = 0;
192
		$this->situationinvoice = false;
193
	}
194
195
196
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
197
    /**
198
     *  Function to build pdf onto disk
199
     *
200
     *  @param		Object		$object				Object to generate
201
     *  @param		Translate	$outputlangs		Lang output object
202
     *  @param		string		$srctemplatepath	Full path of source filename for generator using a template file
203
     *  @param		int			$hidedetails		Do not show line details
204
     *  @param		int			$hidedesc			Do not show desc
205
     *  @param		int			$hideref			Do not show ref
206
     *  @return     int         	    			1=OK, 0=KO
207
	 */
208
	public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
209
	{
210
	    // phpcs:enable
211
	    global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
212
213
	    dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null'));
214
215
	    if (!is_object($outputlangs)) $outputlangs = $langs;
216
	    // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
217
	    if (!empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output = 'ISO-8859-1';
218
219
	    // Load translation files required by the page
220
	    $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
221
222
	    if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
223
	    	global $outputlangsbis;
224
	    	$outputlangsbis = new Translate('', $conf);
225
	    	$outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
226
	    	$outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies"));
227
	    }
228
229
	    $nblines = count($object->lines);
230
231
	    $hidetop = 0;
232
	    if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) {
233
	        $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE;
234
	    }
235
236
	    // Loop on each lines to detect if there is at least one image to show
237
	    $realpatharray = array();
238
	    $this->atleastonephoto = false;
239
	    if (!empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE))
240
	    {
241
	        $objphoto = new Product($this->db);
242
243
	        for ($i = 0; $i < $nblines; $i++)
244
	        {
245
	            if (empty($object->lines[$i]->fk_product)) continue;
246
247
	            $objphoto->fetch($object->lines[$i]->fk_product);
248
	            //var_dump($objphoto->ref);exit;
249
	            if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
250
	            {
251
	                $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
252
	                $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
253
	            }
254
	            else
255
	            {
256
	                $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; // default
257
	                $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
258
	            }
259
260
	            $arephoto = false;
261
	            foreach ($pdir as $midir)
262
	            {
263
	                if (!$arephoto)
264
	                {
265
	                    $dir = $conf->product->dir_output.'/'.$midir;
266
267
	                    foreach ($objphoto->liste_photos($dir, 1) as $key => $obj)
268
	                    {
269
	                        if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES))		// If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
270
	                        {
271
	                            if ($obj['photo_vignette'])
272
	                            {
273
	                                $filename = $obj['photo_vignette'];
274
	                            }
275
	                            else
276
	                            {
277
	                                $filename = $obj['photo'];
278
	                            }
279
	                        }
280
	                        else
281
	                        {
282
	                            $filename = $obj['photo'];
283
	                        }
284
285
	                        $realpath = $dir.$filename;
286
	                        $arephoto = true;
287
	                        $this->atleastonephoto = true;
288
	                    }
289
	                }
290
	            }
291
292
	            if ($realpath && $arephoto) $realpatharray[$i] = $realpath;
293
	        }
294
	    }
295
296
	    //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
297
298
	    if ($conf->facture->dir_output)
299
	    {
300
	        $object->fetch_thirdparty();
301
302
	        $deja_regle = $object->getSommePaiement(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
303
	        $amount_credit_notes_included = $object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
304
	        $amount_deposits_included = $object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
305
306
	        // Definition of $dir and $file
307
	        if ($object->specimen)
308
	        {
309
	            $dir = $conf->facture->dir_output;
310
	            $file = $dir."/SPECIMEN.pdf";
311
	        }
312
	        else
313
	        {
314
	            $objectref = dol_sanitizeFileName($object->ref);
315
	            $dir = $conf->facture->dir_output."/".$objectref;
316
	            $file = $dir."/".$objectref.".pdf";
317
	        }
318
	        if (!file_exists($dir))
319
	        {
320
	            if (dol_mkdir($dir) < 0)
321
	            {
322
	                $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
323
	                return 0;
324
	            }
325
	        }
326
327
	        if (file_exists($dir))
328
	        {
329
	            // Add pdfgeneration hook
330
	            if (!is_object($hookmanager))
331
	            {
332
	                include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
333
	                $hookmanager = new HookManager($this->db);
334
	            }
335
	            $hookmanager->initHooks(array('pdfgeneration'));
336
	            $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
337
	            global $action;
338
	            $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
339
340
	            // Set nblines with the new facture lines content after hook
341
	            $nblines = count($object->lines);
342
	            $nbpayments = count($object->getListOfPayments());
343
344
	            // Create pdf instance
345
	            $pdf = pdf_getInstance($this->format);
346
	            $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
347
	            $pdf->SetAutoPageBreak(1, 0);
348
349
	            $heightforinfotot = 50 + (4 * $nbpayments); // Height reserved to output the info and total part and payment part
350
	            $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page
351
	            $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin)
352
353
	            if (class_exists('TCPDF'))
354
	            {
355
	                $pdf->setPrintHeader(false);
356
	                $pdf->setPrintFooter(false);
357
	            }
358
	            $pdf->SetFont(pdf_getPDFFont($outputlangs));
359
360
	            // Set path to the background PDF File
361
                if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
362
	            {
363
	            	$pagecount = $pdf->setSourceFile($conf->mycompany->multidir_output[$object->entity].'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
364
	                $tplidx = $pdf->importPage(1);
365
	            }
366
367
	            $pdf->Open();
368
	            $pagenb = 0;
369
	            $pdf->SetDrawColor(128, 128, 128);
370
371
	            $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
372
	            $pdf->SetSubject($outputlangs->transnoentities("PdfInvoiceTitle"));
373
	            $pdf->SetCreator("Dolibarr ".DOL_VERSION);
374
	            $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
375
	            $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfInvoiceTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
376
	            if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
377
378
	            // Set certificate
379
	            $cert = empty($user->conf->CERTIFICATE_CRT) ? '' : $user->conf->CERTIFICATE_CRT;
380
	            // If use has no certificate, we try to take the company one
381
	            if (!$cert) {
382
	            	$cert = empty($conf->global->CERTIFICATE_CRT) ? '' : $conf->global->CERTIFICATE_CRT;
383
	            }
384
	            // If a certificate is found
385
	            if ($cert) {
386
	            	$info = array(
387
	            		'Name' => $this->emetteur->name,
388
	            		'Location' => getCountry($this->emetteur->country_code, 0),
389
	            		'Reason' => 'INVOICE',
390
	            		'ContactInfo' => $this->emetteur->email
391
	            	);
392
	            	$pdf->setSignature($cert, $cert, $this->emetteur->name, '', 2, $info);
393
	            }
394
395
	            $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
396
397
	            // Does we have at least one line with discount $this->atleastonediscount
398
	            foreach ($object->lines as $line) {
399
                    if ($line->remise_percent) {
400
	                    $this->atleastonediscount = true;
401
	                    break;
402
	                }
403
	            }
404
405
406
	            // Situation invoice handling
407
	            if ($object->situation_cycle_ref)
408
	            {
409
	                $this->situationinvoice = true;
410
	            }
411
412
	            // New page
413
	            $pdf->AddPage();
414
	            if (!empty($tplidx)) $pdf->useTemplate($tplidx);
415
	            $pagenb++;
416
417
	            $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis);
418
	            $pdf->SetFont('', '', $default_font_size - 1);
419
	            $pdf->MultiCell(0, 3, ''); // Set interline to 3
420
	            $pdf->SetTextColor(0, 0, 0);
421
422
	            $tab_top = 90 + $top_shift;
423
	            $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10);
424
	            $tab_height = 130 - $top_shift;
425
	            $tab_height_newpage = 150;
426
	            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift;
427
428
                $nexY = $tab_top - 1;
429
430
	            // Incoterm
431
	            $height_incoterms = 0;
432
	            if ($conf->incoterm->enabled)
433
	            {
434
	                $desc_incoterms = $object->getIncotermsForPDF();
435
	                if ($desc_incoterms)
436
	                {
437
						$tab_top -= 2;
438
439
	                    $pdf->SetFont('', '', $default_font_size - 1);
440
	                    $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
441
	                    $nexY = max($pdf->GetY(), $nexY);
442
	                    $height_incoterms = $nexY - $tab_top;
443
444
	                    // Rect takes a length in 3rd parameter
445
	                    $pdf->SetDrawColor(192, 192, 192);
446
	                    $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1);
447
448
	                    $tab_top = $nexY + 6;
449
	                    $height_incoterms += 4;
450
	                }
451
	            }
452
453
	            // Display notes
454
	            $notetoshow = empty($object->note_public) ? '' : $object->note_public;
455
	            if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
456
	            {
457
	                // Get first sale rep
458
	                if (is_object($object->thirdparty))
459
	                {
460
	                    $salereparray = $object->thirdparty->getSalesRepresentatives($user);
461
	                    $salerepobj = new User($this->db);
462
	                    $salerepobj->fetch($salereparray[0]['id']);
463
	                    if (!empty($salerepobj->signature)) $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
464
	                }
465
	            }
466
467
	            // Extrafields in note
468
                $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
469
                if (!empty($extranote))
470
                {
471
                    $notetoshow = dol_concatdesc($notetoshow, $extranote);
472
                }
473
474
	            $pagenb = $pdf->getPage();
475
	            if ($notetoshow)
476
	            {
477
					$tab_top -= 2;
478
479
	                $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
480
	                $pageposbeforenote = $pagenb;
481
482
	                $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
483
	                complete_substitutions_array($substitutionarray, $outputlangs, $object);
484
	                $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
485
	                $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
486
487
	                $pdf->startTransaction();
488
489
	                $pdf->SetFont('', '', $default_font_size - 1);
490
	                $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
491
	                // Description
492
	                $pageposafternote = $pdf->getPage();
493
	                $posyafter = $pdf->GetY();
494
495
	                if ($pageposafternote > $pageposbeforenote)
496
	                {
497
	                    $pdf->rollbackTransaction(true);
498
499
	                    // prepare pages to receive notes
500
	                    while ($pagenb < $pageposafternote) {
501
	                        $pdf->AddPage();
502
	                        $pagenb++;
503
	                        if (!empty($tplidx)) $pdf->useTemplate($tplidx);
504
	                        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
505
	                        // $this->_pagefoot($pdf,$object,$outputlangs,1);
506
	                        $pdf->setTopMargin($tab_top_newpage);
507
	                        // The only function to edit the bottom margin of current page to set it.
508
	                        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
509
	                    }
510
511
	                    // back to start
512
	                    $pdf->setPage($pageposbeforenote);
513
	                    $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
514
	                    $pdf->SetFont('', '', $default_font_size - 1);
515
	                    $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
516
	                    $pageposafternote = $pdf->getPage();
517
518
	                    $posyafter = $pdf->GetY();
519
520
	                    if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20)))	// There is no space left for total+free text
521
	                    {
522
	                        $pdf->AddPage('', '', true);
523
	                        $pagenb++;
524
	                        $pageposafternote++;
525
	                        $pdf->setPage($pageposafternote);
526
	                        $pdf->setTopMargin($tab_top_newpage);
527
	                        // The only function to edit the bottom margin of current page to set it.
528
	                        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
529
	                        //$posyafter = $tab_top_newpage;
530
	                    }
531
532
533
	                    // apply note frame to previous pages
534
	                    $i = $pageposbeforenote;
535
	                    while ($i < $pageposafternote) {
536
	                        $pdf->setPage($i);
537
538
539
	                        $pdf->SetDrawColor(128, 128, 128);
540
	                        // Draw note frame
541
	                        if ($i > $pageposbeforenote) {
542
	                            $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
543
	                            $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
544
	                        }
545
	                        else {
546
	                            $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
547
	                            $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
548
	                        }
549
550
	                        // Add footer
551
	                        $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
552
	                        $this->_pagefoot($pdf, $object, $outputlangs, 1);
553
554
	                        $i++;
555
	                    }
556
557
	                    // apply note frame to last page
558
	                    $pdf->setPage($pageposafternote);
559
	                    if (!empty($tplidx)) $pdf->useTemplate($tplidx);
560
	                    if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
561
	                    $height_note = $posyafter - $tab_top_newpage;
562
	                    $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
563
	                }
564
	                else // No pagebreak
565
	                {
566
	                    $pdf->commitTransaction();
567
	                    $posyafter = $pdf->GetY();
568
	                    $height_note = $posyafter - $tab_top;
569
	                    $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
570
571
572
	                    if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20)))
573
	                    {
574
	                        // not enough space, need to add page
575
	                        $pdf->AddPage('', '', true);
576
	                        $pagenb++;
577
	                        $pageposafternote++;
578
	                        $pdf->setPage($pageposafternote);
579
	                        if (!empty($tplidx)) $pdf->useTemplate($tplidx);
580
	                        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
581
582
	                        $posyafter = $tab_top_newpage;
583
	                    }
584
	                }
585
586
	                $tab_height = $tab_height - $height_note;
587
	                $tab_top = $posyafter + 6;
588
	            }
589
	            else
590
	            {
591
	                $height_note = 0;
592
	            }
593
594
	            // Use new auto column system
595
	            $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
596
597
	            // Table simulation to know the height of the title line
598
			    $pdf->startTransaction();
599
			    $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
600
			    $pdf->rollbackTransaction(true);
601
602
			    $nexY = $tab_top + $this->tabTitleHeight;
603
604
	            // Loop on each lines
605
	            $pageposbeforeprintlines = $pdf->getPage();
606
	            $pagenb = $pageposbeforeprintlines;
607
	            for ($i = 0; $i < $nblines; $i++)
608
	            {
609
	                $curY = $nexY;
610
	                $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
611
	                $pdf->SetTextColor(0, 0, 0);
612
613
	                // Define size of image if we need it
614
	                $imglinesize = array();
615
	                if (!empty($realpatharray[$i])) $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
616
617
	                $pdf->setTopMargin($tab_top_newpage);
618
	                $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
619
	                $pageposbefore = $pdf->getPage();
620
621
	                $showpricebeforepagebreak = 1;
622
	                $posYAfterImage = 0;
623
624
	                if ($this->getColumnStatus('photo'))
625
	                {
626
    	                // We start with Photo of product line
627
    	                if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot)))	// If photo too high, we moved completely on new page
628
    	                {
629
    	                    $pdf->AddPage('', '', true);
630
    	                    if (!empty($tplidx)) $pdf->useTemplate($tplidx);
631
    	                    $pdf->setPage($pageposbefore + 1);
632
633
    	                    $curY = $tab_top_newpage;
634
635
							// Allows data in the first page if description is long enough to break in multiples pages
636
							if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
637
								$showpricebeforepagebreak = 1;
638
							else
639
								$showpricebeforepagebreak = 0;
640
    	                }
641
642
    	                if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
643
    	                {
644
    	                    $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
645
    	                    // $pdf->Image does not increase value return by getY, so we save it manually
646
    	                    $posYAfterImage = $curY + $imglinesize['height'];
647
    	                }
648
	                }
649
650
	                // Description of product line
651
	                if ($this->getColumnStatus('desc'))
652
	                {
653
    	                $pdf->startTransaction();
654
655
                        $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
656
    	                $pageposafter = $pdf->getPage();
657
658
    	                if ($pageposafter > $pageposbefore)	// There is a pagebreak
659
    	                {
660
    	                    $pdf->rollbackTransaction(true);
661
    	                    $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
662
663
                            $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
664
665
    	                    $pageposafter = $pdf->getPage();
666
    	                    $posyafter = $pdf->GetY();
667
    	                    //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
668
    	                    if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot)))	// There is no space left for total+free text
669
    	                    {
670
    	                        if ($i == ($nblines - 1))	// No more lines, and no space left to show total, so we create a new page
671
    	                        {
672
    	                            $pdf->AddPage('', '', true);
673
    	                            if (!empty($tplidx)) $pdf->useTemplate($tplidx);
674
    	                            $pdf->setPage($pageposafter + 1);
675
    	                        }
676
    	                    }
677
    	                    else
678
    	                    {
679
    	                        // We found a page break
680
								// Allows data in the first page if description is long enough to break in multiples pages
681
								if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
682
									$showpricebeforepagebreak = 1;
683
								else
684
									$showpricebeforepagebreak = 0;
685
    	                    }
686
    	                }
687
    	                else	// No pagebreak
688
    	                {
689
    	                    $pdf->commitTransaction();
690
    	                }
691
	                }
692
693
                    $nexY = $pdf->GetY();
694
	                $pageposafter = $pdf->getPage();
695
	                $pdf->setPage($pageposbefore);
696
	                $pdf->setTopMargin($this->marge_haute);
697
	                $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
698
699
	                // We suppose that a too long description or photo were moved completely on next page
700
	                if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
701
	                    $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
702
	                }
703
704
	                $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut
705
706
	                // VAT Rate
707
	                if ($this->getColumnStatus('vat'))
708
	                {
709
	                    $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
710
	                    $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
711
	                    $nexY = max($pdf->GetY(), $nexY);
712
	                }
713
714
	                // Unit price before discount
715
	                if ($this->getColumnStatus('subprice'))
716
	                {
717
	                    $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
718
	                    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
719
	                    $nexY = max($pdf->GetY(), $nexY);
720
	                }
721
722
	                // Quantity
723
	                // Enough for 6 chars
724
	                if ($this->getColumnStatus('qty'))
725
	                {
726
	                    $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
727
	                    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
728
	                    $nexY = max($pdf->GetY(), $nexY);
729
	                }
730
731
	                // Situation progress
732
	                if ($this->getColumnStatus('progress'))
733
	                {
734
	                    $progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails);
735
	                    $this->printStdColumnContent($pdf, $curY, 'progress', $progress);
736
	                    $nexY = max($pdf->GetY(), $nexY);
737
	                }
738
739
	                // Unit
740
	                if ($this->getColumnStatus('unit'))
741
	                {
742
	                    $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
743
	                    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
744
	                    $nexY = max($pdf->GetY(), $nexY);
745
	                }
746
747
	                // Discount on line
748
	                if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
749
	                {
750
	                    $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
751
	                    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
752
	                    $nexY = max($pdf->GetY(), $nexY);
753
	                }
754
755
	                // Total HT line
756
	                if ($this->getColumnStatus('totalexcltax'))
757
	                {
758
	                    $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
759
	                    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
760
	                    $nexY = max($pdf->GetY(), $nexY);
761
	                }
762
763
                    // Extrafields
764
	                if (!empty($object->lines[$i]->array_options)) {
765
	                    foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
766
                            if ($this->getColumnStatus($extrafieldColKey))
767
                            {
768
                                $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey);
769
                                $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
770
                                $nexY = max($pdf->GetY(), $nexY);
771
                            }
772
                        }
773
                    }
774
775
776
	                $parameters = array(
777
	                    'object' => $object,
778
	                    'i' => $i,
779
	                    'pdf' =>& $pdf,
780
	                    'curY' =>& $curY,
781
	                    'nexY' =>& $nexY,
782
	                    'outputlangs' => $outputlangs,
783
	                    'hidedetails' => $hidedetails
784
	                );
785
	                $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook
786
787
788
	                $sign = 1;
789
	                if (isset($object->type) && $object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign = -1;
790
	                // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
791
	                $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
792
	                if ($prev_progress > 0 && !empty($object->lines[$i]->situation_percent)) // Compute progress from previous situation
793
	                {
794
	                    if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
795
	                    else $tvaligne = $sign * $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
796
	                } else {
797
	                    if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva;
798
	                    else $tvaligne = $sign * $object->lines[$i]->total_tva;
799
	                }
800
801
	                $localtax1ligne = $object->lines[$i]->total_localtax1;
802
	                $localtax2ligne = $object->lines[$i]->total_localtax2;
803
	                $localtax1_rate = $object->lines[$i]->localtax1_tx;
804
	                $localtax2_rate = $object->lines[$i]->localtax2_tx;
805
	                $localtax1_type = $object->lines[$i]->localtax1_type;
806
	                $localtax2_type = $object->lines[$i]->localtax2_type;
807
808
	                if ($object->remise_percent) $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
809
	                if ($object->remise_percent) $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
810
	                if ($object->remise_percent) $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
811
812
	                $vatrate = (string) $object->lines[$i]->tva_tx;
813
814
	                // Retrieve type from database for backward compatibility with old records
815
	                if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
816
	                    && (!empty($localtax1_rate) || !empty($localtax2_rate))) // and there is local tax
817
	                {
818
	                    $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
819
	                    $localtax1_type = $localtaxtmp_array[0];
820
	                    $localtax2_type = $localtaxtmp_array[2];
821
	                }
822
823
	                // retrieve global local tax
824
                    if ($localtax1_type && $localtax1ligne != 0) {
825
                        $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
826
                    }
827
                    if ($localtax2_type && $localtax2ligne != 0) {
828
                        $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
829
                    }
830
831
                    if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate .= '*';
832
                    if (!isset($this->tva[$vatrate])) 				$this->tva[$vatrate] = 0;
833
                    $this->tva[$vatrate] += $tvaligne;
834
835
                    $nexY = max($nexY, $posYAfterImage);
836
837
                    // Add line
838
                    if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) {
839
                        $pdf->setPage($pageposafter);
840
                        $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
841
                        //$pdf->SetDrawColor(190,190,200);
842
                        $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
843
                        $pdf->SetLineStyle(array('dash'=>0));
844
                    }
845
846
                    // Detect if some page were added automatically and output _tableau for past pages
847
                    while ($pagenb < $pageposafter) {
848
                        $pdf->setPage($pagenb);
849
                        if ($pagenb == $pageposbeforeprintlines) {
850
                            $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
851
                        }
852
                        else
853
                        {
854
                        	$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
855
                        }
856
                        $this->_pagefoot($pdf, $object, $outputlangs, 1);
857
                        $pagenb++;
858
                        $pdf->setPage($pagenb);
859
                        $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
860
                        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
861
                    }
862
863
                    if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
864
                        if ($pagenb == $pageposafter) {
865
                        	$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
866
                        }
867
                        else
868
                        {
869
                        	$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
870
                        }
871
                        $this->_pagefoot($pdf, $object, $outputlangs, 1);
872
                        // New page
873
                        $pdf->AddPage();
874
                        if (!empty($tplidx)) $pdf->useTemplate($tplidx);
875
                        $pagenb++;
876
                        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
877
                    }
878
	            }
879
880
	            // Show square
881
	            if ($pagenb == $pageposbeforeprintlines)
882
	            {
883
	            	$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis);
884
	                $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
885
	            }
886
	            else
887
	            {
888
	            	$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis);
889
	                $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
890
	            }
891
892
	            // Display infos area
893
	            $posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
894
895
	            // Display total zone
896
	            $posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
897
898
	            // Display payment area
899
	            if (($deja_regle || $amount_credit_notes_included || $amount_deposits_included) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
900
	            {
901
	                $posy = $this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
902
	            }
903
904
	            // Pagefoot
905
	            $this->_pagefoot($pdf, $object, $outputlangs);
906
	            if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages();
907
908
	            $pdf->Close();
909
910
	            $pdf->Output($file, 'F');
911
912
	            // Add pdfgeneration hook
913
	            $hookmanager->initHooks(array('pdfgeneration'));
914
	            $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
915
	            global $action;
916
	            $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
917
	            if ($reshook < 0)
918
	            {
919
	                $this->error = $hookmanager->error;
920
	                $this->errors = $hookmanager->errors;
921
	            }
922
923
	            if (!empty($conf->global->MAIN_UMASK))
924
	                @chmod($file, octdec($conf->global->MAIN_UMASK));
925
926
	                $this->result = array('fullpath'=>$file);
927
928
	                return 1; // No error
929
	        }
930
	        else
931
	        {
932
	            $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
933
	            return 0;
934
	        }
935
	    }
936
	    else
937
	    {
938
	        $this->error = $langs->transnoentities("ErrorConstantNotDefined", "FAC_OUTPUTDIR");
939
	        return 0;
940
	    }
941
	}
942
943
944
	/**
945
	 *  Show payments table
946
	 *
947
     *  @param	PDF			$pdf           Object PDF
948
     *  @param  Object		$object         Object invoice
949
     *  @param  int			$posy           Position y in PDF
950
     *  @param  Translate	$outputlangs    Object langs for output
951
     *  @return int             			<0 if KO, >0 if OK
952
	 */
953
	public function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
954
	{
955
		global $conf;
956
957
        $sign = 1;
958
        if ($object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign = -1;
959
960
        $tab3_posx = 120;
961
		$tab3_top = $posy + 8;
962
		$tab3_width = 80;
963
		$tab3_height = 4;
964
		if ($this->page_largeur < 210) // To work with US executive format
965
		{
966
			$tab3_posx -= 20;
967
		}
968
969
		$default_font_size = pdf_getPDFFontSize($outputlangs);
970
971
		$title = $outputlangs->transnoentities("PaymentsAlreadyDone");
972
		if ($object->type == 2) $title = $outputlangs->transnoentities("PaymentsBackAlreadyDone");
973
974
		$pdf->SetFont('', '', $default_font_size - 3);
975
		$pdf->SetXY($tab3_posx, $tab3_top - 4);
976
		$pdf->MultiCell(60, 3, $title, 0, 'L', 0);
977
978
		$pdf->line($tab3_posx, $tab3_top, $tab3_posx + $tab3_width, $tab3_top);
979
980
		$pdf->SetFont('', '', $default_font_size - 4);
981
		$pdf->SetXY($tab3_posx, $tab3_top);
982
		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Payment"), 0, 'L', 0);
983
		$pdf->SetXY($tab3_posx + 21, $tab3_top);
984
		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Amount"), 0, 'L', 0);
985
		$pdf->SetXY($tab3_posx + 40, $tab3_top);
986
		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Type"), 0, 'L', 0);
987
		$pdf->SetXY($tab3_posx + 58, $tab3_top);
988
		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Num"), 0, 'L', 0);
989
990
		$pdf->line($tab3_posx, $tab3_top - 1 + $tab3_height, $tab3_posx + $tab3_width, $tab3_top - 1 + $tab3_height);
991
992
		$y = 0;
993
994
		$pdf->SetFont('', '', $default_font_size - 4);
995
996
997
		// Loop on each discount available (deposits and credit notes and excess of payment included)
998
		$sql = "SELECT re.rowid, re.amount_ht, re.multicurrency_amount_ht, re.amount_tva, re.multicurrency_amount_tva,  re.amount_ttc, re.multicurrency_amount_ttc,";
999
		$sql .= " re.description, re.fk_facture_source,";
1000
		$sql .= " f.type, f.datef";
1001
		$sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re, ".MAIN_DB_PREFIX."facture as f";
1002
		$sql .= " WHERE re.fk_facture_source = f.rowid AND re.fk_facture = ".$object->id;
1003
		$resql = $this->db->query($sql);
1004
		if ($resql)
1005
		{
1006
			$num = $this->db->num_rows($resql);
1007
			$i = 0;
1008
			$invoice = new Facture($this->db);
1009
			while ($i < $num)
1010
			{
1011
				$y += 3;
1012
				$obj = $this->db->fetch_object($resql);
1013
1014
				if ($obj->type == 2) $text = $outputlangs->transnoentities("CreditNote");
1015
				elseif ($obj->type == 3) $text = $outputlangs->transnoentities("Deposit");
1016
				elseif ($obj->type == 0) $text = $outputlangs->transnoentities("ExcessReceived");
1017
				else $text = $outputlangs->transnoentities("UnknownType");
1018
1019
				$invoice->fetch($obj->fk_facture_source);
1020
1021
				$pdf->SetXY($tab3_posx, $tab3_top + $y);
1022
				$pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($obj->datef), 'day', false, $outputlangs, true), 0, 'L', 0);
1023
				$pdf->SetXY($tab3_posx + 21, $tab3_top + $y);
1024
				$pdf->MultiCell(20, 3, price(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $obj->multicurrency_amount_ttc : $obj->amount_ttc, 0, $outputlangs), 0, 'L', 0);
1025
				$pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1026
				$pdf->MultiCell(20, 3, $text, 0, 'L', 0);
1027
				$pdf->SetXY($tab3_posx + 58, $tab3_top + $y);
1028
				$pdf->MultiCell(20, 3, $invoice->ref, 0, 'L', 0);
1029
1030
				$pdf->line($tab3_posx, $tab3_top + $y + 3, $tab3_posx + $tab3_width, $tab3_top + $y + 3);
1031
1032
				$i++;
1033
			}
1034
		}
1035
		else
1036
		{
1037
			$this->error = $this->db->lasterror();
1038
			return -1;
1039
		}
1040
1041
		// Loop on each payment
1042
		// TODO Call getListOfPaymentsgetListOfPayments instead of hard coded sql
1043
		$sql = "SELECT p.datep as date, p.fk_paiement, p.num_paiement as num, pf.amount as amount, pf.multicurrency_amount,";
1044
		$sql .= " cp.code";
1045
		$sql .= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p";
1046
		$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id";
1047
		$sql .= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = ".$object->id;
1048
		//$sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = 1";
1049
		$sql .= " ORDER BY p.datep";
1050
1051
		$resql = $this->db->query($sql);
1052
		if ($resql)
1053
		{
1054
			$num = $this->db->num_rows($resql);
1055
			$i = 0;
1056
			while ($i < $num) {
1057
				$y += 3;
1058
				$row = $this->db->fetch_object($resql);
1059
1060
				$pdf->SetXY($tab3_posx, $tab3_top + $y);
1061
				$pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($row->date), 'day', false, $outputlangs, true), 0, 'L', 0);
1062
				$pdf->SetXY($tab3_posx + 21, $tab3_top + $y);
1063
				$pdf->MultiCell(20, 3, price($sign * (($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $row->multicurrency_amount : $row->amount), 0, $outputlangs), 0, 'L', 0);
1064
				$pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1065
				$oper = $outputlangs->transnoentitiesnoconv("PaymentTypeShort".$row->code);
1066
1067
				$pdf->MultiCell(20, 3, $oper, 0, 'L', 0);
1068
				$pdf->SetXY($tab3_posx + 58, $tab3_top + $y);
1069
				$pdf->MultiCell(30, 3, $row->num, 0, 'L', 0);
1070
1071
				$pdf->line($tab3_posx, $tab3_top + $y + 3, $tab3_posx + $tab3_width, $tab3_top + $y + 3);
1072
1073
				$i++;
1074
			}
1075
1076
			return $tab3_top + $y + 3;
1077
		}
1078
		else
1079
		{
1080
			$this->error = $this->db->lasterror();
1081
			return -1;
1082
		}
1083
	}
1084
1085
1086
	/**
1087
	 *   Show miscellaneous information (payment mode, payment term, ...)
1088
	 *
1089
	 *   @param		tcpdf			$pdf     		Object PDF
1090
	 *   @param		Object		$object			Object to show
1091
	 *   @param		int			$posy			Y
1092
	 *   @param		Translate	$outputlangs	Langs object
1093
	 *   @return	int							Pos y
1094
	 */
1095
	protected function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
1096
	{
1097
		global $conf, $mysoc;
1098
1099
		$default_font_size = pdf_getPDFFontSize($outputlangs);
1100
1101
		$pdf->SetFont('', '', $default_font_size - 1);
1102
1103
		// If France, show VAT mention if not applicable
1104
		if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj))
1105
		{
1106
			$pdf->SetFont('', 'B', $default_font_size - 2);
1107
			$pdf->SetXY($this->marge_gauche, $posy);
1108
			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
1109
1110
			$posy = $pdf->GetY() + 4;
1111
		}
1112
1113
		$posxval = 52;
1114
1115
		// Show payments conditions
1116
		if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement))
1117
		{
1118
			$pdf->SetFont('', 'B', $default_font_size - 2);
1119
			$pdf->SetXY($this->marge_gauche, $posy);
1120
			$titre = $outputlangs->transnoentities("PaymentConditions").':';
1121
			$pdf->MultiCell(43, 4, $titre, 0, 'L');
1122
1123
			$pdf->SetFont('', '', $default_font_size - 2);
1124
			$pdf->SetXY($posxval, $posy);
1125
			$lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc);
1126
			$lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
1127
			$pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
1128
1129
			$posy = $pdf->GetY() + 3;
1130
		}
1131
1132
		if ($object->type != 2)
1133
		{
1134
			// Check a payment mode is defined
1135
			if (empty($object->mode_reglement_code)
1136
			&& empty($conf->global->FACTURE_CHQ_NUMBER)
1137
			&& empty($conf->global->FACTURE_RIB_NUMBER))
1138
			{
1139
				$this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured");
1140
			}
1141
			// Avoid having any valid PDF with setup that is not complete
1142
			elseif (($object->mode_reglement_code == 'CHQ' && empty($conf->global->FACTURE_CHQ_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))
1143
				|| ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank)))
1144
			{
1145
				$outputlangs->load("errors");
1146
1147
				$pdf->SetXY($this->marge_gauche, $posy);
1148
				$pdf->SetTextColor(200, 0, 0);
1149
				$pdf->SetFont('', 'B', $default_font_size - 2);
1150
				$this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup", $object->mode_reglement_code);
1151
				$pdf->MultiCell(80, 3, $this->error, 0, 'L', 0);
1152
				$pdf->SetTextColor(0, 0, 0);
1153
1154
				$posy = $pdf->GetY() + 1;
1155
			}
1156
1157
			// Show payment mode
1158
			if ($object->mode_reglement_code
1159
			&& $object->mode_reglement_code != 'CHQ'
1160
			&& $object->mode_reglement_code != 'VIR')
1161
			{
1162
				$pdf->SetFont('', 'B', $default_font_size - 2);
1163
				$pdf->SetXY($this->marge_gauche, $posy);
1164
				$titre = $outputlangs->transnoentities("PaymentMode").':';
1165
				$pdf->MultiCell(80, 5, $titre, 0, 'L');
1166
1167
				$pdf->SetFont('', '', $default_font_size - 2);
1168
				$pdf->SetXY($posxval, $posy);
1169
				$lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement);
1170
				$pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
1171
1172
				// Show online payment link
1173
				$useonlinepayment = ((!empty($conf->paypal->enabled) || !empty($conf->stripe->enabled) || !empty($conf->paybox->enabled)) && !empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT));
1174
				if (($object->mode_reglement_code == 'CB' || $object->mode_reglement_code == 'VAD') && $object->statut != Facture::STATUS_DRAFT && $useonlinepayment) {
1175
					require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
1176
					global $langs;
1177
1178
					$langs->loadLangs(array('payment', 'paybox'));
1179
					$servicename = $langs->transnoentities('Online');
1180
					$paiement_url = getOnlinePaymentUrl('', 'invoice', $object->ref, '', '', '');
1181
					$linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' <a href="'.$paiement_url.'">'.$outputlangs->transnoentities("ClickHere").'</a>';
1182
1183
					$pdf->writeHTMLCell(80, 10, '', '', dol_htmlentitiesbr($linktopay), 0, 1);
1184
				}
1185
1186
				$posy = $pdf->GetY() + 2;
1187
			}
1188
1189
			// Show payment mode CHQ
1190
			if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
1191
			{
1192
				// If payment mode unregulated or payment mode forced to CHQ
1193
				if (!empty($conf->global->FACTURE_CHQ_NUMBER))
1194
				{
1195
					$diffsizetitle = (empty($conf->global->PDF_DIFFSIZE_TITLE) ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
1196
1197
					if ($conf->global->FACTURE_CHQ_NUMBER > 0)
1198
					{
1199
						$account = new Account($this->db);
1200
						$account->fetch($conf->global->FACTURE_CHQ_NUMBER);
1201
1202
						$pdf->SetXY($this->marge_gauche, $posy);
1203
						$pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1204
						$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0);
1205
						$posy = $pdf->GetY() + 1;
1206
1207
			            if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
1208
			            {
1209
							$pdf->SetXY($this->marge_gauche, $posy);
1210
							$pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1211
							$pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
1212
							$posy = $pdf->GetY() + 2;
1213
			            }
1214
					}
1215
					if ($conf->global->FACTURE_CHQ_NUMBER == -1)
1216
					{
1217
						$pdf->SetXY($this->marge_gauche, $posy);
1218
						$pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1219
						$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
1220
						$posy = $pdf->GetY() + 1;
1221
1222
			            if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
1223
			            {
1224
							$pdf->SetXY($this->marge_gauche, $posy);
1225
							$pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1226
							$pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
1227
							$posy = $pdf->GetY() + 2;
1228
			            }
1229
					}
1230
				}
1231
			}
1232
1233
			// If payment mode not forced or forced to VIR, show payment with BAN
1234
			if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
1235
			{
1236
				if ($object->fk_account > 0 || $object->fk_bank > 0 || !empty($conf->global->FACTURE_RIB_NUMBER)) {
1237
					$bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
1238
					if ($object->fk_bank > 0) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
1239
					$account = new Account($this->db);
1240
					$account->fetch($bankid);
1241
1242
					$curx = $this->marge_gauche;
1243
					$cury = $posy;
1244
1245
					$posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
1246
1247
					$posy += 2;
1248
				}
1249
			}
1250
		}
1251
1252
		return $posy;
1253
	}
1254
1255
1256
	/**
1257
	 *  Show total to pay
1258
	 *
1259
	 *  @param	TCPDI			$pdf            Object PDF
1260
	 *	@param  Facture		$object         Object invoice
1261
	 *	@param  int			$deja_regle     Amount already paid (in the currency of invoice)
1262
	 *	@param	int			$posy			Position depart
1263
	 *	@param	Translate	$outputlangs	Objet langs
1264
	 *	@return int							Position pour suite
1265
	 */
1266
	protected function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
1267
	{
1268
		global $conf, $mysoc, $hookmanager;
1269
1270
        $sign = 1;
1271
        if ($object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign = -1;
1272
1273
        $default_font_size = pdf_getPDFFontSize($outputlangs);
1274
1275
		$tab2_top = $posy;
1276
		$tab2_hl = 4;
1277
		$pdf->SetFont('', '', $default_font_size - 1);
1278
1279
		// Total table
1280
		$col1x = 120; $col2x = 170;
1281
		if ($this->page_largeur < 210) // To work with US executive format
1282
		{
1283
			$col2x -= 20;
1284
		}
1285
		$largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
1286
1287
		$useborder = 0;
1288
		$index = 0;
1289
1290
		$outputlangsbis = null;
1291
		if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
1292
			$outputlangsbis = new Translate('', $conf);
1293
			$outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
1294
			$outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
1295
		}
1296
1297
		// Add trigger to allow to edit $object
1298
		$parameters = array(
1299
			'object' => &$object,
1300
			'outputlangs' => $outputlangs,
1301
		);
1302
		$hookmanager->executeHooks('beforePercentCalculation', $parameters, $this); // Note that $object may have been modified by hook
1303
1304
		// overall percentage of advancement
1305
		$percent = 0;
1306
		$i = 0;
1307
		foreach ($object->lines as $line)
1308
		{
1309
			$percent += $line->situation_percent;
1310
			$i++;
1311
		}
1312
1313
		if (!empty($i)) {
1314
		    $avancementGlobal = $percent / $i;
1315
		}
1316
		else {
1317
		    $avancementGlobal = 0;
1318
		}
1319
1320
		$object->fetchPreviousNextSituationInvoice();
1321
		$TPreviousIncoice = $object->tab_previous_situation_invoice;
1322
1323
		$total_a_payer = 0;
1324
		$total_a_payer_ttc = 0;
1325
		foreach ($TPreviousIncoice as &$fac) {
1326
		    $total_a_payer += $fac->total_ht;
1327
		    $total_a_payer_ttc += $fac->total_ttc;
1328
		}
1329
		$total_a_payer += $object->total_ht;
1330
		$total_a_payer_ttc += $object->total_ttc;
1331
1332
		if (!empty($avancementGlobal)) {
1333
		    $total_a_payer = $total_a_payer * 100 / $avancementGlobal;
1334
		    $total_a_payer_ttc = $total_a_payer_ttc * 100 / $avancementGlobal;
1335
		}
1336
		else {
1337
		    $total_a_payer = 0;
1338
		    $total_a_payer_ttc = 0;
1339
		}
1340
1341
		$i = 1;
1342
		if (!empty($TPreviousIncoice)) {
1343
		    $pdf->setY($tab2_top);
1344
		    $posy = $pdf->GetY();
1345
1346
		    foreach ($TPreviousIncoice as &$fac) {
1347
		        if ($posy > $this->page_hauteur - 4) {
1348
		            $this->_pagefoot($pdf, $object, $outputlangs, 1);
1349
		            $pdf->addPage();
1350
		            $pdf->setY($this->marge_haute);
1351
		            $posy = $pdf->GetY();
1352
		        }
1353
1354
		        // cumul TVA précédent
1355
		        $index++;
1356
		        $pdf->SetFillColor(255, 255, 255);
1357
		        $pdf->SetXY($col1x, $posy);
1358
		        $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("PDFSituationTitle", $fac->situation_counter).' '.$outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
1359
1360
		        $pdf->SetXY($col2x, $posy);
1361
1362
		        $facSign = '';
1363
		        if ($i > 1) {
1364
		            $facSign = $fac->total_ht >= 0 ? '+' : '';
1365
		        }
1366
1367
		        $displayAmount = ' '.$facSign.' '.price($fac->total_ht, 0, $outputlangs);
1368
1369
		        $pdf->MultiCell($largcol2, $tab2_hl, $displayAmount, 0, 'R', 1);
1370
1371
		        $i++;
1372
		        $posy += $tab2_hl;
1373
1374
		        $pdf->setY($posy);
1375
		    }
1376
1377
		    // Display current total
1378
		    $pdf->SetFillColor(255, 255, 255);
1379
		    $pdf->SetXY($col1x, $posy);
1380
		    $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("PDFSituationTitle", $object->situation_counter).' '.$outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
1381
1382
		    $pdf->SetXY($col2x, $posy);
1383
		    $facSign = '';
1384
		    if ($i > 1) {
1385
		        $facSign = $object->total_ht >= 0 ? '+' : ''; // management of a particular customer case
1386
		    }
1387
1388
		    if ($fac->type === facture::TYPE_CREDIT_NOTE) {
1389
		        $facSign = '-'; // les avoirs
1390
		    }
1391
1392
1393
		    $displayAmount = ' '.$facSign.' '.price($object->total_ht, 0, $outputlangs);
1394
		    $pdf->MultiCell($largcol2, $tab2_hl, $displayAmount, 0, 'R', 1);
1395
1396
		    $posy += $tab2_hl;
1397
1398
		    // Display all total
1399
		    $pdf->SetFont('', '', $default_font_size - 1);
1400
		    $pdf->SetFillColor(255, 255, 255);
1401
		    $pdf->SetXY($col1x, $posy);
1402
		    $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("SituationTotalProgress", $avancementGlobal), 0, 'L', 1);
1403
1404
		    $pdf->SetXY($col2x, $posy);
1405
		    $pdf->MultiCell($largcol2, $tab2_hl, price($total_a_payer * $avancementGlobal / 100, 0, $outputlangs), 0, 'R', 1);
1406
		    $pdf->SetFont('', '', $default_font_size - 2);
1407
1408
		    $posy += $tab2_hl;
1409
1410
		    if ($posy > $this->page_hauteur - 4) {
1411
		        $pdf->addPage();
1412
		        $pdf->setY($this->marge_haute);
1413
		        $posy = $pdf->GetY();
1414
		    }
1415
1416
		    $tab2_top = $posy;
1417
		    $index = 0;
1418
		}
1419
1420
		$tab2_top += 3;
1421
1422
		// Get Total HT
1423
		$total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
1424
1425
		// Total remise
1426
		$total_line_remise = 0;
1427
		foreach ($object->lines as $i => $line) {
1428
		    $total_line_remise += pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, 2); // TODO: add this methode to core/lib/pdf.lib
1429
		    // Gestion remise sous forme de ligne négative
1430
		    if ($line->total_ht < 0) $total_line_remise += -$line->total_ht;
1431
		}
1432
		if ($total_line_remise > 0) {
1433
		    if (!empty($conf->global->MAIN_SHOW_AMOUNT_DISCOUNT)) {
1434
		        $pdf->SetFillColor(255, 255, 255);
1435
		        $pdf->SetXY($col1x, $tab2_top + $tab2_hl);
1436
		        $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalDiscount").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalDiscount") : ''), 0, 'L', 1);
1437
		        $pdf->SetXY($col2x, $tab2_top + $tab2_hl);
1438
		        $pdf->MultiCell($largcol2, $tab2_hl, price($total_line_remise, 0, $outputlangs), 0, 'R', 1);
1439
1440
		        $index++;
1441
		    }
1442
		    // Show total NET before discount
1443
		    if (!empty($conf->global->MAIN_SHOW_AMOUNT_BEFORE_DISCOUNT)) {
1444
		        $pdf->SetFillColor(255, 255, 255);
1445
		        $pdf->SetXY($col1x, $tab2_top + 0);
1446
		        $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHTBeforeDiscount").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHTBeforeDiscount") : ''), 0, 'L', 1);
1447
                $pdf->SetXY($col2x, $tab2_top + 0);
1448
		        $pdf->MultiCell($largcol2, $tab2_hl, price($total_line_remise + $total_ht, 0, $outputlangs), 0, 'R', 1);
1449
1450
		        $index++;
1451
		    }
1452
		}
1453
1454
		// Total HT
1455
		$pdf->SetFillColor(255, 255, 255);
1456
		$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1457
		$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1);
1458
1459
		$total_ht = (($conf->multicurrency->enabled && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
1460
		$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1461
		$pdf->MultiCell($largcol2, $tab2_hl, price($sign * ($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, $outputlangs), 0, 'R', 1);
1462
1463
		// Show VAT by rates and total
1464
		$pdf->SetFillColor(248, 248, 248);
1465
1466
		$total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
1467
1468
		$this->atleastoneratenotnull = 0;
1469
		if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
1470
		{
1471
			$tvaisnull = ((!empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
1472
			if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull)
1473
			{
1474
				// Nothing to do
1475
			}
1476
			else
1477
			{
1478
			    // FIXME amount of vat not supported with multicurrency
1479
1480
				//Local tax 1 before VAT
1481
				//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1482
				//{
1483
				foreach ($this->localtax1 as $localtax_type => $localtax_rate)
1484
				{
1485
					if (in_array((string) $localtax_type, array('1', '3', '5'))) continue;
1486
1487
					foreach ($localtax_rate as $tvakey => $tvaval)
1488
					{
1489
						if ($tvakey != 0)    // On affiche pas taux 0
1490
						{
1491
							//$this->atleastoneratenotnull++;
1492
1493
							$index++;
1494
							$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1495
1496
							$tvacompl = '';
1497
							if (preg_match('/\*/', $tvakey))
1498
							{
1499
								$tvakey = str_replace('*', '', $tvakey);
1500
								$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1501
							}
1502
1503
							$totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1504
							$totalvat .= ' ';
1505
							$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1506
							$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1507
1508
							$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1509
							$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1510
						}
1511
					}
1512
				}
1513
	      		//}
1514
				//Local tax 2 before VAT
1515
				//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1516
				//{
1517
				foreach ($this->localtax2 as $localtax_type => $localtax_rate)
1518
				{
1519
					if (in_array((string) $localtax_type, array('1', '3', '5'))) continue;
1520
1521
					foreach ($localtax_rate as $tvakey => $tvaval)
1522
					{
1523
						if ($tvakey != 0)    // On affiche pas taux 0
1524
						{
1525
							//$this->atleastoneratenotnull++;
1526
1527
							$index++;
1528
							$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1529
1530
							$tvacompl = '';
1531
							if (preg_match('/\*/', $tvakey))
1532
							{
1533
								$tvakey = str_replace('*', '', $tvakey);
1534
								$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1535
							}
1536
							$totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1537
							$totalvat .= ' ';
1538
							$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1539
							$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1540
1541
							$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1542
							$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1543
						}
1544
					}
1545
				}
1546
                //}
1547
1548
				// VAT
1549
				// Situations totals migth be wrong on huge amounts
1550
				if ($object->situation_cycle_ref && $object->situation_counter > 1) {
1551
					$sum_pdf_tva = 0;
1552
					foreach ($this->tva as $tvakey => $tvaval) {
1553
						$sum_pdf_tva += $tvaval; // sum VAT amounts to compare to object
1554
					}
1555
1556
					if ($sum_pdf_tva != $object->total_tva) { // apply coef to recover the VAT object amount (the good one)
1557
					    if (!empty($sum_pdf_tva))
1558
					    {
1559
							$coef_fix_tva = $object->total_tva / $sum_pdf_tva;
1560
					    }
1561
					    else {
1562
					        $coef_fix_tva = 1;
1563
					    }
1564
1565
1566
						foreach ($this->tva as $tvakey => $tvaval) {
1567
							$this->tva[$tvakey] = $tvaval * $coef_fix_tva;
1568
						}
1569
					}
1570
				}
1571
1572
				foreach ($this->tva as $tvakey => $tvaval)
1573
				{
1574
					if ($tvakey != 0)    // On affiche pas taux 0
1575
					{
1576
						$this->atleastoneratenotnull++;
1577
1578
						$index++;
1579
						$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1580
1581
						$tvacompl = '';
1582
						if (preg_match('/\*/', $tvakey))
1583
						{
1584
							$tvakey = str_replace('*', '', $tvakey);
1585
							$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1586
						}
1587
						$totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
1588
						$totalvat .= ' ';
1589
						$totalvat .= vatrate($tvakey, 1).$tvacompl;
1590
						$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1591
1592
						$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1593
						$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1594
					}
1595
				}
1596
1597
				//Local tax 1 after VAT
1598
				//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1599
				//{
1600
				foreach ($this->localtax1 as $localtax_type => $localtax_rate)
1601
				{
1602
					if (in_array((string) $localtax_type, array('2', '4', '6'))) continue;
1603
1604
					foreach ($localtax_rate as $tvakey => $tvaval)
1605
					{
1606
						if ($tvakey != 0)    // On affiche pas taux 0
1607
						{
1608
							//$this->atleastoneratenotnull++;
1609
1610
							$index++;
1611
							$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1612
1613
							$tvacompl = '';
1614
							if (preg_match('/\*/', $tvakey))
1615
							{
1616
								$tvakey = str_replace('*', '', $tvakey);
1617
								$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1618
							}
1619
							$totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1620
							$totalvat .= ' ';
1621
							$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1622
1623
							$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1624
							$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1625
							$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1626
						}
1627
					}
1628
				}
1629
	      		//}
1630
				//Local tax 2 after VAT
1631
				//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1632
				//{
1633
				foreach ($this->localtax2 as $localtax_type => $localtax_rate)
1634
				{
1635
					if (in_array((string) $localtax_type, array('2', '4', '6'))) continue;
1636
1637
					foreach ($localtax_rate as $tvakey => $tvaval)
1638
					{
1639
					    // retrieve global local tax
1640
						if ($tvakey != 0)    // On affiche pas taux 0
1641
						{
1642
							//$this->atleastoneratenotnull++;
1643
1644
							$index++;
1645
							$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1646
1647
							$tvacompl = '';
1648
							if (preg_match('/\*/', $tvakey))
1649
							{
1650
								$tvakey = str_replace('*', '', $tvakey);
1651
								$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1652
							}
1653
							$totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1654
							$totalvat .= ' ';
1655
1656
							$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1657
							$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1658
1659
							$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1660
							$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1661
						}
1662
					}
1663
				}
1664
1665
1666
				// Revenue stamp
1667
				if (price2num($object->revenuestamp) != 0)
1668
				{
1669
					$index++;
1670
					$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1671
					$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RevenueStamp").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RevenueStamp", $mysoc->country_code) : ''), $useborder, 'L', 1);
1672
1673
					$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1674
					$pdf->MultiCell($largcol2, $tab2_hl, price($sign * $object->revenuestamp), $useborder, 'R', 1);
1675
				}
1676
1677
				// Total TTC
1678
				$index++;
1679
				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1680
				$pdf->SetTextColor(0, 0, 60);
1681
				$pdf->SetFillColor(224, 224, 224);
1682
				$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalTTC") : ''), $useborder, 'L', 1);
1683
1684
				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1685
				$pdf->MultiCell($largcol2, $tab2_hl, price($sign * $total_ttc, 0, $outputlangs), $useborder, 'R', 1);
1686
1687
1688
1689
1690
				// Retained warranty
1691
				if ($object->displayRetainedWarranty())
1692
				{
1693
					$pdf->SetTextColor(40, 40, 40);
1694
					$pdf->SetFillColor(255, 255, 255);
1695
1696
					$retainedWarranty = $object->getRetainedWarrantyAmount();
1697
					$billedWithRetainedWarranty = $object->total_ttc - $retainedWarranty;
1698
1699
					// Billed - retained warranty
1700
					$index++;
1701
					$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1702
					$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("ToPayOn", dol_print_date($object->date_lim_reglement, 'day')), $useborder, 'L', 1);
1703
1704
					$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1705
					$pdf->MultiCell($largcol2, $tab2_hl, price($billedWithRetainedWarranty), $useborder, 'R', 1);
1706
1707
					// retained warranty
1708
					$index++;
1709
					$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1710
1711
					$retainedWarrantyToPayOn = $outputlangs->transnoentities("RetainedWarranty").' ('.$object->retained_warranty.'%)';
1712
					$retainedWarrantyToPayOn .= !empty($object->retained_warranty_date_limit) ? ' '.$outputlangs->transnoentities("toPayOn", dol_print_date($object->retained_warranty_date_limit, 'day')) : '';
1713
1714
					$pdf->MultiCell($col2x - $col1x, $tab2_hl, $retainedWarrantyToPayOn, $useborder, 'L', 1);
1715
					$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1716
					$pdf->MultiCell($largcol2, $tab2_hl, price($retainedWarranty), $useborder, 'R', 1);
1717
				}
1718
			}
1719
		}
1720
1721
		$pdf->SetTextColor(0, 0, 0);
1722
1723
		$creditnoteamount = $object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); // Warning, this also include excess received
1724
		$depositsamount = $object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
1725
1726
		$resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
1727
		if (!empty($object->paye)) $resteapayer = 0;
1728
1729
		if (($deja_regle > 0 || $creditnoteamount > 0 || $depositsamount > 0) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
1730
		{
1731
			// Already paid + Deposits
1732
			$index++;
1733
			$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1734
			$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Paid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("Paid") : ''), 0, 'L', 0);
1735
			$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1736
			$pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle + $depositsamount, 0, $outputlangs), 0, 'R', 0);
1737
1738
			// Credit note
1739
			if ($creditnoteamount)
1740
			{
1741
				$labeltouse = ($outputlangs->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangs->transnoentities("CreditNotesOrExcessReceived") : $outputlangs->transnoentities("CreditNotes");
1742
				$labeltouse .= (is_object($outputlangsbis) ? ' / '.($outputlangsbis->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangsbis->transnoentities("CreditNotesOrExcessReceived") : $outputlangsbis->transnoentities("CreditNotes") : '');
1743
				$index++;
1744
				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1745
				$pdf->MultiCell($col2x - $col1x, $tab2_hl, $labeltouse, 0, 'L', 0);
1746
				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1747
				$pdf->MultiCell($largcol2, $tab2_hl, price($creditnoteamount, 0, $outputlangs), 0, 'R', 0);
1748
			}
1749
1750
			// Escompte
1751
			if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT)
1752
			{
1753
				$index++;
1754
				$pdf->SetFillColor(255, 255, 255);
1755
1756
				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1757
				$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("EscompteOfferedShort") : ''), $useborder, 'L', 1);
1758
				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1759
				$pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1);
1760
1761
				$resteapayer = 0;
1762
			}
1763
1764
			$index++;
1765
			$pdf->SetTextColor(0, 0, 60);
1766
			$pdf->SetFillColor(224, 224, 224);
1767
			$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1768
			$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RemainderToPay") : ''), $useborder, 'L', 1);
1769
			$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1770
			$pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
1771
1772
			$pdf->SetFont('', '', $default_font_size - 1);
1773
			$pdf->SetTextColor(0, 0, 0);
1774
		}
1775
1776
		$index++;
1777
		return ($tab2_top + ($tab2_hl * $index));
1778
	}
1779
1780
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1781
	/**
1782
	 *  Return list of active generation modules
1783
	 *
1784
	 *  @param	DoliDB	$db     			Database handler
1785
	 *  @param  integer	$maxfilenamelength  Max length of value to show
1786
	 *  @return	array						List of templates
1787
	 */
1788
	public static function liste_modeles($db, $maxfilenamelength = 0)
1789
	{
1790
		// phpcs:enable
1791
		return parent::liste_modeles($db, $maxfilenamelength); // TODO: Change the autogenerated stub
1792
	}
1793
1794
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1795
	/**
1796
	 *   Show table for lines
1797
	 *
1798
	 *   @param		tcpdf			$pdf     		Object PDF
1799
	 *   @param		string		$tab_top		Top position of table
1800
	 *   @param		string		$tab_height		Height of table (rectangle)
1801
	 *   @param		int			$nexY			Y (not used)
1802
	 *   @param		Translate	$outputlangs	Langs object
1803
	 *   @param		int			$hidetop		1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
1804
	 *   @param		int			$hidebottom		Hide bottom bar of array
1805
	 *   @param		string		$currency		Currency code
1806
	 *   @param		Translate	$outputlangsbis	Langs object bis
1807
	 *   @return	void
1808
	 */
1809
	protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
1810
	{
1811
		global $conf;
1812
1813
		// Force to disable hidetop and hidebottom
1814
		$hidebottom = 0;
1815
		if ($hidetop) $hidetop = -1;
1816
1817
		$currency = !empty($currency) ? $currency : $conf->currency;
1818
		$default_font_size = pdf_getPDFFontSize($outputlangs);
1819
1820
		// Amount in (at tab_top - 1)
1821
		$pdf->SetTextColor(0, 0, 0);
1822
		$pdf->SetFont('', '', $default_font_size - 2);
1823
1824
		if (empty($hidetop))
1825
		{
1826
			$titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1827
			if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
1828
				$titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency));
1829
			}
1830
1831
			$pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1832
			$pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1833
1834
			//$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1835
			if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) {
1836
				$pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, 'F', null, explode(',', $conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
1837
			}
1838
		}
1839
1840
		$pdf->SetDrawColor(128, 128, 128);
1841
		$pdf->SetFont('', '', $default_font_size - 1);
1842
1843
		// Output Rect
1844
		$this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect takes a length in 3rd parameter and 4th parameter
1845
1846
1847
		$this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
1848
1849
		if (empty($hidetop)) {
1850
		    $pdf->line($this->marge_gauche, $tab_top + $this->tabTitleHeight, $this->page_largeur - $this->marge_droite, $tab_top + $this->tabTitleHeight); // line takes a position y in 2nd parameter and 4th parameter
1851
		}
1852
	}
1853
1854
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1855
	/**
1856
	 *  Show top header of page.
1857
	 *
1858
	 *  @param	Tcpdf			$pdf     		Object PDF
1859
	 *  @param  Object		$object     	Object to show
1860
	 *  @param  int	    	$showaddress    0=no, 1=yes
1861
	 *  @param  Translate	$outputlangs	Object lang for output
1862
	 *  @param  Translate	$outputlangsbis	Object lang for output bis
1863
	 *  @return	void
1864
	 */
1865
	protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null)
1866
	{
1867
		global $conf, $langs;
1868
1869
		// Load traductions files required by page
1870
		$outputlangs->loadLangs(array("main", "bills", "propal", "companies"));
1871
1872
		$default_font_size = pdf_getPDFFontSize($outputlangs);
1873
1874
		pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
1875
1876
		// Show Draft Watermark
1877
		if ($object->statut == Facture::STATUS_DRAFT && (!empty($conf->global->FACTURE_DRAFT_WATERMARK)))
1878
        {
1879
		      pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK);
1880
        }
1881
1882
		$pdf->SetTextColor(0, 0, 60);
1883
		$pdf->SetFont('', 'B', $default_font_size + 3);
1884
1885
		$w = 110;
1886
1887
		$posy = $this->marge_haute;
1888
        $posx = $this->page_largeur - $this->marge_droite - $w;
1889
1890
		$pdf->SetXY($this->marge_gauche, $posy);
1891
1892
		// Logo
1893
		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
1894
		{
1895
			if ($this->emetteur->logo)
1896
			{
1897
				$logodir = $conf->mycompany->dir_output;
1898
				if (!empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity];
1899
				if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO))
1900
				{
1901
					$logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1902
				}
1903
				else {
1904
					$logo = $logodir.'/logos/'.$this->emetteur->logo;
1905
				}
1906
				if (is_readable($logo))
1907
				{
1908
				    $height = pdf_getHeightForLogo($logo);
1909
					$pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1910
				}
1911
				else
1912
				{
1913
					$pdf->SetTextColor(200, 0, 0);
1914
					$pdf->SetFont('', 'B', $default_font_size - 2);
1915
					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1916
					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1917
				}
1918
			}
1919
			else
1920
			{
1921
				$text = $this->emetteur->name;
1922
				$pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
1923
			}
1924
		}
1925
1926
		$pdf->SetFont('', 'B', $default_font_size + 3);
1927
		$pdf->SetXY($posx, $posy);
1928
		$pdf->SetTextColor(0, 0, 60);
1929
		$title = $outputlangs->transnoentities("PdfInvoiceTitle");
1930
		if ($object->type == 1) $title = $outputlangs->transnoentities("InvoiceReplacement");
1931
		if ($object->type == 2) $title = $outputlangs->transnoentities("InvoiceAvoir");
1932
		if ($object->type == 3) $title = $outputlangs->transnoentities("InvoiceDeposit");
1933
		if ($object->type == 4) $title = $outputlangs->transnoentities("InvoiceProForma");
1934
		if ($this->situationinvoice) $title = $outputlangs->transnoentities("InvoiceSituation");
1935
		if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
1936
			$title .= ' - ';
1937
			if ($object->type == 0) {
1938
				if ($this->situationinvoice) $title .= $outputlangsbis->transnoentities("InvoiceSituation");
1939
				$title .= $outputlangsbis->transnoentities("PdfInvoiceTitle");
1940
			}
1941
			elseif ($object->type == 1) $title .= $outputlangsbis->transnoentities("InvoiceReplacement");
1942
			elseif ($object->type == 2) $title .= $outputlangsbis->transnoentities("InvoiceAvoir");
1943
			elseif ($object->type == 3) $title .= $outputlangsbis->transnoentities("InvoiceDeposit");
1944
			elseif ($object->type == 4) $title .= $outputlangsbis->transnoentities("InvoiceProForma");
1945
		}
1946
		$pdf->MultiCell($w, 3, $title, '', 'R');
1947
1948
		$pdf->SetFont('', 'B', $default_font_size);
1949
1950
		$posy += 5;
1951
		$pdf->SetXY($posx, $posy);
1952
		$pdf->SetTextColor(0, 0, 60);
1953
		$textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref);
1954
		if ($object->statut == Facture::STATUS_DRAFT)
1955
		{
1956
			$pdf->SetTextColor(128, 0, 0);
1957
			$textref .= ' - '.$outputlangs->transnoentities("NotValidated");
1958
		}
1959
		$pdf->MultiCell($w, 4, $textref, '', 'R');
1960
1961
		$posy += 1;
1962
		$pdf->SetFont('', '', $default_font_size - 2);
1963
1964
		if ($object->ref_client)
1965
		{
1966
			$posy += 4;
1967
			$pdf->SetXY($posx, $posy);
1968
			$pdf->SetTextColor(0, 0, 60);
1969
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R');
1970
		}
1971
1972
		if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE))
1973
		{
1974
			$object->fetch_projet();
1975
			if (!empty($object->project->ref))
1976
			{
1977
				$posy += 3;
1978
				$pdf->SetXY($posx, $posy);
1979
				$pdf->SetTextColor(0, 0, 60);
1980
				$pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R');
1981
			}
1982
		}
1983
1984
		if (!empty($conf->global->PDF_SHOW_PROJECT))
1985
		{
1986
			$object->fetch_projet();
1987
			if (!empty($object->project->ref))
1988
			{
1989
				$posy += 3;
1990
				$pdf->SetXY($posx, $posy);
1991
				$pdf->SetTextColor(0, 0, 60);
1992
				$pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R');
1993
			}
1994
		}
1995
1996
		$objectidnext = $object->getIdReplacingInvoice('validated');
1997
		if ($object->type == 0 && $objectidnext)
1998
		{
1999
			$objectreplacing = new Facture($this->db);
2000
			$objectreplacing->fetch($objectidnext);
2001
2002
			$posy += 3;
2003
			$pdf->SetXY($posx, $posy);
2004
			$pdf->SetTextColor(0, 0, 60);
2005
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementByInvoice").' : '.$outputlangs->convToOutputCharset($objectreplacing->ref), '', 'R');
2006
		}
2007
		if ($object->type == 1)
2008
		{
2009
			$objectreplaced = new Facture($this->db);
2010
			$objectreplaced->fetch($object->fk_facture_source);
2011
2012
			$posy += 4;
2013
			$pdf->SetXY($posx, $posy);
2014
			$pdf->SetTextColor(0, 0, 60);
2015
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
2016
		}
2017
		if ($object->type == 2 && !empty($object->fk_facture_source))
2018
		{
2019
			$objectreplaced = new Facture($this->db);
2020
			$objectreplaced->fetch($object->fk_facture_source);
2021
2022
			$posy += 3;
2023
			$pdf->SetXY($posx, $posy);
2024
			$pdf->SetTextColor(0, 0, 60);
2025
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("CorrectionInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
2026
		}
2027
2028
		$posy += 4;
2029
		$pdf->SetXY($posx, $posy);
2030
		$pdf->SetTextColor(0, 0, 60);
2031
		$pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateInvoice")." : ".dol_print_date($object->date, "day", false, $outputlangs), '', 'R');
2032
2033
		if (!empty($conf->global->INVOICE_POINTOFTAX_DATE))
2034
		{
2035
			$posy += 4;
2036
			$pdf->SetXY($posx, $posy);
2037
			$pdf->SetTextColor(0, 0, 60);
2038
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("DatePointOfTax")." : ".dol_print_date($object->date_pointoftax, "day", false, $outputlangs), '', 'R');
2039
		}
2040
2041
		if ($object->type != 2)
2042
		{
2043
			$posy += 3;
2044
			$pdf->SetXY($posx, $posy);
2045
			$pdf->SetTextColor(0, 0, 60);
2046
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateDue")." : ".dol_print_date($object->date_lim_reglement, "day", false, $outputlangs, true), '', 'R');
2047
		}
2048
2049
		if ($object->thirdparty->code_client)
2050
		{
2051
			$posy += 3;
2052
			$pdf->SetXY($posx, $posy);
2053
			$pdf->SetTextColor(0, 0, 60);
2054
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
2055
		}
2056
2057
		// Get contact
2058
		if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
2059
		{
2060
		    $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
2061
		    if (count($arrayidcontact) > 0)
2062
		    {
2063
		        $usertmp = new User($this->db);
2064
		        $usertmp->fetch($arrayidcontact[0]);
2065
                $posy += 4;
2066
                $pdf->SetXY($posx, $posy);
2067
		        $pdf->SetTextColor(0, 0, 60);
2068
		        $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
2069
		    }
2070
		}
2071
2072
		$posy += 1;
2073
2074
		$top_shift = 0;
2075
		// Show list of linked objects
2076
		$current_y = $pdf->getY();
2077
		$posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
2078
		if ($current_y < $pdf->getY())
2079
		{
2080
			$top_shift = $pdf->getY() - $current_y;
2081
		}
2082
2083
		if ($showaddress)
2084
		{
2085
			// Sender properties
2086
			$carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
2087
2088
			// Show sender
2089
			$posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
2090
			$posy += $top_shift;
2091
			$posx = $this->marge_gauche;
2092
			if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->page_largeur - $this->marge_droite - 80;
2093
2094
			$hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
2095
			$widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
2096
2097
2098
			// Show sender frame
2099
			$pdf->SetTextColor(0, 0, 0);
2100
			$pdf->SetFont('', '', $default_font_size - 2);
2101
			$pdf->SetXY($posx, $posy - 5);
2102
			$pdf->MultiCell(66, 5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
2103
			$pdf->SetXY($posx, $posy);
2104
			$pdf->SetFillColor(230, 230, 230);
2105
			$pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
2106
			$pdf->SetTextColor(0, 0, 60);
2107
2108
			// Show sender name
2109
			$pdf->SetXY($posx + 2, $posy + 3);
2110
			$pdf->SetFont('', 'B', $default_font_size);
2111
			$pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
2112
			$posy = $pdf->getY();
2113
2114
			// Show sender information
2115
			$pdf->SetXY($posx + 2, $posy);
2116
			$pdf->SetFont('', '', $default_font_size - 1);
2117
			$pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, 'L');
2118
2119
			// If BILLING contact defined on invoice, we use it
2120
			$usecontact = false;
2121
			$arrayidcontact = $object->getIdContact('external', 'BILLING');
2122
			if (count($arrayidcontact) > 0)
2123
			{
2124
				$usecontact = true;
2125
				$result = $object->fetch_contact($arrayidcontact[0]);
2126
			}
2127
2128
			//Recipient name
2129
			// On peut utiliser le nom de la societe du contact
2130
			if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) {
2131
				$thirdparty = $object->contact;
2132
			} else {
2133
				$thirdparty = $object->thirdparty;
2134
			}
2135
2136
			$carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
2137
2138
			$carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object);
2139
2140
			// Show recipient
2141
			$widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
2142
			if ($this->page_largeur < 210) $widthrecbox = 84; // To work with US executive format
2143
			$posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
2144
			$posy += $top_shift;
2145
			$posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
2146
			if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->marge_gauche;
2147
2148
			// Show recipient frame
2149
			$pdf->SetTextColor(0, 0, 0);
2150
			$pdf->SetFont('', '', $default_font_size - 2);
2151
			$pdf->SetXY($posx + 2, $posy - 5);
2152
			$pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":", 0, 'L');
2153
			$pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
2154
2155
			// Show recipient name
2156
			$pdf->SetXY($posx + 2, $posy + 3);
2157
			$pdf->SetFont('', 'B', $default_font_size);
2158
			$pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L');
2159
2160
			$posy = $pdf->getY();
2161
2162
			// Show recipient information
2163
			$pdf->SetFont('', '', $default_font_size - 1);
2164
			$pdf->SetXY($posx + 2, $posy);
2165
			$pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
2166
		}
2167
2168
		$pdf->SetTextColor(0, 0, 0);
2169
		return $top_shift;
2170
	}
2171
2172
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2173
	/**
2174
	 *   	Show footer of page. Need this->emetteur object
2175
     *
2176
	 *   	@param	PDF			$pdf     			PDF
2177
	 * 		@param	Object		$object				Object to show
2178
	 *      @param	Translate	$outputlangs		Object lang for output
2179
	 *      @param	int			$hidefreetext		1=Hide free text
2180
	 *      @return	int								Return height of bottom margin including footer text
2181
	 */
2182
	protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
2183
	{
2184
		global $conf;
2185
		$showdetails = $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
2186
		return pdf_pagefoot($pdf, $outputlangs, 'INVOICE_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
2187
	}
2188
2189
	/**
2190
	 *  Define Array Column Field
2191
	 *
2192
	 *  @param	object			$object    		common object
2193
	 *  @param	Translate		$outputlangs    langs
2194
     *  @param	int			   $hidedetails		Do not show line details
2195
     *  @param	int			   $hidedesc		Do not show desc
2196
     *  @param	int			   $hideref			Do not show ref
2197
     *  @return	null
2198
     */
2199
    public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
2200
    {
2201
	    global $conf, $hookmanager;
2202
2203
	    // Default field style for content
2204
	    $this->defaultContentsFieldsStyle = array(
2205
	        'align' => 'R', // R,C,L
2206
	        'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2207
	    );
2208
2209
	    // Default field style for content
2210
	    $this->defaultTitlesFieldsStyle = array(
2211
	        'align' => 'C', // R,C,L
2212
	        'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2213
	    );
2214
2215
	    /*
2216
	     * For exemple
2217
	    $this->cols['theColKey'] = array(
2218
	        'rank' => $rank, // int : use for ordering columns
2219
	        'width' => 20, // the column width in mm
2220
	        'title' => array(
2221
	            'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
2222
	            'label' => ' ', // the final label : used fore final generated text
2223
	            'align' => 'L', // text alignement :  R,C,L
2224
	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2225
	        ),
2226
	        'content' => array(
2227
	            'align' => 'L', // text alignement :  R,C,L
2228
	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2229
	        ),
2230
	    );
2231
	    */
2232
2233
	    $rank = 0; // do not use negative rank
2234
	    $this->cols['desc'] = array(
2235
	        'rank' => $rank,
2236
	        'width' => false, // only for desc
2237
	        'status' => true,
2238
	        'title' => array(
2239
	            'textkey' => 'Designation', // use lang key is usefull in somme case with module
2240
	            'align' => 'L',
2241
	            // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
2242
	            // 'label' => ' ', // the final label
2243
	            'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2244
	        ),
2245
	        'content' => array(
2246
	            'align' => 'L',
2247
                'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2248
	        ),
2249
	    );
2250
2251
	    // PHOTO
2252
        $rank = $rank + 10;
2253
        $this->cols['photo'] = array(
2254
            'rank' => $rank,
2255
            'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
2256
            'status' => false,
2257
            'title' => array(
2258
                'textkey' => 'Photo',
2259
                'label' => ' '
2260
            ),
2261
            'content' => array(
2262
                'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2263
            ),
2264
            'border-left' => false, // remove left line separator
2265
        );
2266
2267
	    if (!empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto))
2268
	    {
2269
	        $this->cols['photo']['status'] = true;
2270
	    }
2271
2272
2273
	    $rank = $rank + 10;
2274
	    $this->cols['vat'] = array(
2275
	        'rank' => $rank,
2276
	        'status' => false,
2277
	        'width' => 16, // in mm
2278
	        'title' => array(
2279
	            'textkey' => 'VAT'
2280
	        ),
2281
	        'border-left' => true, // add left line separator
2282
	    );
2283
2284
	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
2285
	    {
2286
	        $this->cols['vat']['status'] = true;
2287
	    }
2288
2289
	    $rank = $rank + 10;
2290
	    $this->cols['subprice'] = array(
2291
	        'rank' => $rank,
2292
	        'width' => 19, // in mm
2293
	        'status' => true,
2294
	        'title' => array(
2295
	            'textkey' => 'PriceUHT'
2296
	        ),
2297
	        'border-left' => true, // add left line separator
2298
	    );
2299
2300
	    $rank = $rank + 10;
2301
	    $this->cols['qty'] = array(
2302
	        'rank' => $rank,
2303
	        'width' => 16, // in mm
2304
	        'status' => true,
2305
	        'title' => array(
2306
	            'textkey' => 'Qty'
2307
	        ),
2308
	        'border-left' => true, // add left line separator
2309
	    );
2310
2311
	    $rank = $rank + 10;
2312
	    $this->cols['progress'] = array(
2313
	        'rank' => $rank,
2314
	        'width' => 19, // in mm
2315
	        'status' => false,
2316
	        'title' => array(
2317
	            'textkey' => 'Progress'
2318
	        ),
2319
	        'border-left' => true, // add left line separator
2320
	    );
2321
2322
	    if ($this->situationinvoice)
2323
	    {
2324
	        $this->cols['progress']['status'] = true;
2325
	    }
2326
2327
	    $rank = $rank + 10;
2328
	    $this->cols['unit'] = array(
2329
	        'rank' => $rank,
2330
	        'width' => 11, // in mm
2331
	        'status' => false,
2332
	        'title' => array(
2333
	            'textkey' => 'Unit'
2334
	        ),
2335
	        'border-left' => true, // add left line separator
2336
	    );
2337
	    if ($conf->global->PRODUCT_USE_UNITS) {
2338
	        $this->cols['unit']['status'] = true;
2339
	    }
2340
2341
	    $rank = $rank + 10;
2342
	    $this->cols['discount'] = array(
2343
	        'rank' => $rank,
2344
	        'width' => 13, // in mm
2345
	        'status' => false,
2346
	        'title' => array(
2347
	            'textkey' => 'ReductionShort'
2348
	        ),
2349
	        'border-left' => true, // add left line separator
2350
	    );
2351
	    if ($this->atleastonediscount) {
2352
	        $this->cols['discount']['status'] = true;
2353
	    }
2354
2355
	    $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
2356
	    $this->cols['totalexcltax'] = array(
2357
	        'rank' => $rank,
2358
	        'width' => 26, // in mm
2359
	        'status' => true,
2360
	        'title' => array(
2361
	            'textkey' => 'TotalHT'
2362
	        ),
2363
	        'border-left' => true, // add left line separator
2364
	    );
2365
2366
	    // Add extrafields cols
2367
        if (!empty($object->lines)) {
2368
            $line = reset($object->lines);
2369
            $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
2370
        }
2371
2372
	    $parameters = array(
2373
	        'object' => $object,
2374
	        'outputlangs' => $outputlangs,
2375
	        'hidedetails' => $hidedetails,
2376
	        'hidedesc' => $hidedesc,
2377
	        'hideref' => $hideref
2378
	    );
2379
2380
	    $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
2381
	    if ($reshook < 0)
2382
	    {
2383
	        setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2384
	    }
2385
	    elseif (empty($reshook))
2386
	    {
2387
	        $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
2388
	    }
2389
	    else
2390
	    {
2391
	        $this->cols = $hookmanager->resArray;
2392
	    }
2393
	}
2394
}
2395