Passed
Branch develop (5cbde9)
by
unknown
26:38
created

pdf_sponge::_tableau()   A

Complexity

Conditions 6

Size

Total Lines 36
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 18
c 0
b 0
f 0
nop 8
dl 0
loc 36
rs 9.0444

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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 <http://www.gnu.org/licenses/>.
25
 * or see http://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 = 'development';
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
121
	*/
122
	public $emetteur;
123
124
	/**
125
	 * @var bool Situation invoice type
126
	 */
127
	public $situationinvoice;
128
129
	/**
130
	 * @var float X position for the situation progress column
131
	 */
132
	public $posxprogress;
133
134
135
	/**
136
	 *	Constructor
137
	 *
138
	 *  @param		DoliDB		$db      Database handler
139
	 */
140
	public function __construct($db)
141
	{
142
		global $conf,$langs,$mysoc;
143
144
		// Translations
145
		$langs->loadLangs(array("main", "bills"));
146
147
		$this->db = $db;
148
		$this->name = "sponge";
149
		$this->description = $langs->trans('PDFSpongeDescription');
150
		$this->update_main_doc_field = 1;		// Save the name of generated file as the main doc when generating a doc with this template
151
152
		// Dimensiont page
153
		$this->type = 'pdf';
154
		$formatarray=pdf_getFormat();
155
		$this->page_largeur = $formatarray['width'];
156
		$this->page_hauteur = $formatarray['height'];
157
		$this->format = array($this->page_largeur,$this->page_hauteur);
158
		$this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10;
159
		$this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10;
160
		$this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
161
		$this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
162
163
		$this->option_logo = 1;                    // Display logo
164
		$this->option_tva = 1;                     // Manage the vat option FACTURE_TVAOPTION
165
		$this->option_modereg = 1;                 // Display payment mode
166
		$this->option_condreg = 1;                 // Display payment terms
167
		$this->option_codeproduitservice = 1;      // Display product-service code
168
		$this->option_multilang = 1;               // Available in several languages
169
		$this->option_escompte = 1;                // Displays if there has been a discount
170
		$this->option_credit_note = 1;             // Support credit notes
171
		$this->option_freetext = 1;				   // Support add of a personalised text
172
		$this->option_draft_watermark = 1;		   // Support add of a watermark on drafts
173
174
		$this->franchise=!$mysoc->tva_assuj;
175
176
		// Get source company
177
		$this->emetteur=$mysoc;
178
		if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang, -2);    // By default, if was not defined
179
180
		// Define position of columns
181
		$this->posxdesc=$this->marge_gauche+1; // used for notes ans other stuff
182
183
184
		$this->tabTitleHeight = 5; // default height
185
186
		//  Use new system for position of columns, view  $this->defineColumnField()
187
188
		$this->tva=array();
189
		$this->localtax1=array();
190
		$this->localtax2=array();
191
		$this->atleastoneratenotnull=0;
192
		$this->atleastonediscount=0;
193
		$this->situationinvoice=false;
194
	}
195
196
197
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
198
    /**
199
     *  Function to build pdf onto disk
200
     *
201
     *  @param		Object		$object				Object to generate
202
     *  @param		Translate	$outputlangs		Lang output object
203
     *  @param		string		$srctemplatepath	Full path of source filename for generator using a template file
204
     *  @param		int			$hidedetails		Do not show line details
205
     *  @param		int			$hidedesc			Do not show desc
206
     *  @param		int			$hideref			Do not show ref
207
     *  @return     int         	    			1=OK, 0=KO
208
	 */
209
	public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
210
	{
211
	    // phpcs:enable
212
	    global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblines;
213
214
	    if (! is_object($outputlangs)) $outputlangs=$langs;
215
	    // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
216
	    if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
217
218
	    // Translations
219
	    $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
220
221
	    $nblines = count($object->lines);
222
223
	    $hidetop=0;
224
	    if(!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)){
225
	        $hidetop=$conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE;
226
	    }
227
228
	    // Loop on each lines to detect if there is at least one image to show
229
	    $realpatharray=array();
230
	    $this->atleastonephoto = false;
231
	    if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE))
232
	    {
233
	        $objphoto = new Product($this->db);
234
235
	        for ($i = 0 ; $i < $nblines ; $i++)
236
	        {
237
	            if (empty($object->lines[$i]->fk_product)) continue;
238
239
	            $objphoto->fetch($object->lines[$i]->fk_product);
240
	            //var_dump($objphoto->ref);exit;
241
	            if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
242
	            {
243
	                $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product') . $objphoto->id ."/photos/";
244
	                $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product') . dol_sanitizeFileName($objphoto->ref).'/';
245
	            }
246
	            else
247
	            {
248
	                $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product') . dol_sanitizeFileName($objphoto->ref).'/';				// default
249
	                $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product') . $objphoto->id ."/photos/";	// alternative
250
	            }
251
252
	            $arephoto = false;
253
	            foreach ($pdir as $midir)
254
	            {
255
	                if (! $arephoto)
256
	                {
257
	                    $dir = $conf->product->dir_output.'/'.$midir;
258
259
	                    foreach ($objphoto->liste_photos($dir, 1) as $key => $obj)
260
	                    {
261
	                        if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES))		// If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
262
	                        {
263
	                            if ($obj['photo_vignette'])
264
	                            {
265
	                                $filename= $obj['photo_vignette'];
266
	                            }
267
	                            else
268
	                            {
269
	                                $filename=$obj['photo'];
270
	                            }
271
	                        }
272
	                        else
273
	                        {
274
	                            $filename=$obj['photo'];
275
	                        }
276
277
	                        $realpath = $dir.$filename;
278
	                        $arephoto = true;
279
	                        $this->atleastonephoto = true;
280
	                    }
281
	                }
282
	            }
283
284
	            if ($realpath && $arephoto) $realpatharray[$i]=$realpath;
285
	        }
286
	    }
287
288
	    //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
289
290
	    if ($conf->facture->dir_output)
291
	    {
292
	        $object->fetch_thirdparty();
293
294
	        $deja_regle = $object->getSommePaiement(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
295
	        $amount_credit_notes_included = $object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
296
	        $amount_deposits_included = $object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
297
298
	        // Definition of $dir and $file
299
	        if ($object->specimen)
300
	        {
301
	            $dir = $conf->facture->dir_output;
302
	            $file = $dir . "/SPECIMEN.pdf";
303
	        }
304
	        else
305
	        {
306
	            $objectref = dol_sanitizeFileName($object->ref);
307
	            $dir = $conf->facture->dir_output . "/" . $objectref;
308
	            $file = $dir . "/" . $objectref . ".pdf";
309
	        }
310
	        if (! file_exists($dir))
311
	        {
312
	            if (dol_mkdir($dir) < 0)
313
	            {
314
	                $this->error=$langs->transnoentities("ErrorCanNotCreateDir", $dir);
315
	                return 0;
316
	            }
317
	        }
318
319
	        if (file_exists($dir))
320
	        {
321
	            // Add pdfgeneration hook
322
	            if (! is_object($hookmanager))
323
	            {
324
	                include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
325
	                $hookmanager=new HookManager($this->db);
326
	            }
327
	            $hookmanager->initHooks(array('pdfgeneration'));
328
	            $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
329
	            global $action;
330
	            $reshook=$hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action);    // Note that $action and $object may have been modified by some hooks
331
332
	            // Set nblines with the new facture lines content after hook
333
	            $nblines = count($object->lines);
334
	            $nbpayments = count($object->getListOfPayments());
335
336
	            // Create pdf instance
337
	            $pdf=pdf_getInstance($this->format);
338
	            $default_font_size = pdf_getPDFFontSize($outputlangs);	// Must be after pdf_getInstance
339
	            $pdf->SetAutoPageBreak(1, 0);
340
341
	            $heightforinfotot = 50+(4*$nbpayments);	// Height reserved to output the info and total part and payment part
342
	            $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
343
	            $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)
344
345
	            if (class_exists('TCPDF'))
346
	            {
347
	                $pdf->setPrintHeader(false);
348
	                $pdf->setPrintFooter(false);
349
	            }
350
	            $pdf->SetFont(pdf_getPDFFont($outputlangs));
351
352
	            // Set path to the background PDF File
353
                if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
354
	            {
355
	                $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
356
	                $tplidx = $pdf->importPage(1);
357
	            }
358
359
	            $pdf->Open();
360
	            $pagenb=0;
361
	            $pdf->SetDrawColor(128, 128, 128);
362
363
	            $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
364
	            $pdf->SetSubject($outputlangs->transnoentities("PdfInvoiceTitle"));
365
	            $pdf->SetCreator("Dolibarr ".DOL_VERSION);
366
	            $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
367
	            $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfInvoiceTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
368
	            if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
369
370
	            $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
371
372
	            // Does we have at least one line with discount $this->atleastonediscount
373
	            foreach ($object->lines as $line) {
374
	               if ($line->remise_percent){
375
	                    $this->atleastonediscount = true;
376
	                    break;
377
	               }
378
	            }
379
380
381
	            // Situation invoice handling
382
	            if ($object->situation_cycle_ref)
383
	            {
384
	                $this->situationinvoice = true;
385
	            }
386
387
	            // New page
388
	            $pdf->AddPage();
389
	            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
390
	            $pagenb++;
391
392
	            $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
393
	            $pdf->SetFont('', '', $default_font_size - 1);
394
	            $pdf->MultiCell(0, 3, '');		// Set interline to 3
395
	            $pdf->SetTextColor(0, 0, 0);
396
397
	            $tab_top = 90+$top_shift;
398
	            $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
399
	            $tab_height = 130-$top_shift;
400
	            $tab_height_newpage = 150;
401
	            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift;
402
403
	            // Incoterm
404
	            $height_incoterms = 0;
405
	            if ($conf->incoterm->enabled)
406
	            {
407
	                $desc_incoterms = $object->getIncotermsForPDF();
408
	                if ($desc_incoterms)
409
	                {
410
						$tab_top -= 2;
411
412
	                    $pdf->SetFont('', '', $default_font_size - 1);
413
	                    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
414
	                    $nexY = max($pdf->GetY(), $nexY);
415
	                    $height_incoterms=$nexY-$tab_top;
416
417
	                    // Rect prend une longueur en 3eme param
418
	                    $pdf->SetDrawColor(192, 192, 192);
419
	                    $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1);
420
421
	                    $tab_top = $nexY+6;
422
	                    $height_incoterms += 4;
423
	                }
424
	            }
425
426
	            // Affiche notes
427
	            $notetoshow=empty($object->note_public)?'':$object->note_public;
428
	            if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
429
	            {
430
	                // Get first sale rep
431
	                if (is_object($object->thirdparty))
432
	                {
433
	                    $salereparray=$object->thirdparty->getSalesRepresentatives($user);
434
	                    $salerepobj=new User($this->db);
435
	                    $salerepobj->fetch($salereparray[0]['id']);
436
	                    if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature);
437
	                }
438
	            }
439
440
	            $pagenb = $pdf->getPage();
441
	            if ($notetoshow)
442
	            {
443
					$tab_top -= 2;
444
445
	                $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
446
	                $pageposbeforenote = $pagenb;
447
448
	                $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
449
	                complete_substitutions_array($substitutionarray, $outputlangs, $object);
450
	                $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
451
	                $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
452
453
	                $pdf->startTransaction();
454
455
	                $pdf->SetFont('', '', $default_font_size - 1);
456
	                $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
457
	                // Description
458
	                $pageposafternote=$pdf->getPage();
459
	                $posyafter = $pdf->GetY();
460
461
	                if($pageposafternote>$pageposbeforenote )
462
	                {
463
	                    $pdf->rollbackTransaction(true);
464
465
	                    // prepar pages to receive notes
466
	                    while ($pagenb < $pageposafternote) {
467
	                        $pdf->AddPage();
468
	                        $pagenb++;
469
	                        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
470
	                        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
471
	                        // $this->_pagefoot($pdf,$object,$outputlangs,1);
472
	                        $pdf->setTopMargin($tab_top_newpage);
473
	                        // The only function to edit the bottom margin of current page to set it.
474
	                        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
475
	                    }
476
477
	                    // back to start
478
	                    $pdf->setPage($pageposbeforenote);
479
	                    $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
480
	                    $pdf->SetFont('', '', $default_font_size - 1);
481
	                    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
482
	                    $pageposafternote=$pdf->getPage();
483
484
	                    $posyafter = $pdf->GetY();
485
486
	                    if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)))	// There is no space left for total+free text
487
	                    {
488
	                        $pdf->AddPage('', '', true);
489
	                        $pagenb++;
490
	                        $pageposafternote++;
491
	                        $pdf->setPage($pageposafternote);
492
	                        $pdf->setTopMargin($tab_top_newpage);
493
	                        // The only function to edit the bottom margin of current page to set it.
494
	                        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
495
	                        //$posyafter = $tab_top_newpage;
496
	                    }
497
498
499
	                    // apply note frame to previus pages
500
	                    $i = $pageposbeforenote;
501
	                    while ($i < $pageposafternote) {
502
	                        $pdf->setPage($i);
503
504
505
	                        $pdf->SetDrawColor(128, 128, 128);
506
	                        // Draw note frame
507
	                        if($i>$pageposbeforenote){
508
	                            $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
509
	                            $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note + 1);
510
	                        }
511
	                        else{
512
	                            $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
513
	                            $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
514
	                        }
515
516
	                        // Add footer
517
	                        $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
518
	                        $this->_pagefoot($pdf, $object, $outputlangs, 1);
519
520
	                        $i++;
521
	                    }
522
523
	                    // apply note frame to last page
524
	                    $pdf->setPage($pageposafternote);
525
	                    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
526
	                    if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
527
	                    $height_note=$posyafter-$tab_top_newpage;
528
	                    $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
529
	                }
530
	                else // No pagebreak
531
	                {
532
	                    $pdf->commitTransaction();
533
	                    $posyafter = $pdf->GetY();
534
	                    $height_note=$posyafter-$tab_top;
535
	                    $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
536
537
538
	                    if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
539
	                    {
540
	                        // not enough space, need to add page
541
	                        $pdf->AddPage('', '', true);
542
	                        $pagenb++;
543
	                        $pageposafternote++;
544
	                        $pdf->setPage($pageposafternote);
545
	                        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
546
	                        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
547
548
	                        $posyafter = $tab_top_newpage;
549
	                    }
550
	                }
551
552
	                $tab_height = $tab_height - $height_note;
553
	                $tab_top = $posyafter +6;
554
	            }
555
	            else
556
	            {
557
	                $height_note=0;
558
	            }
559
560
	            // Use new auto collum system
561
	            $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
562
563
			// Simulation de tableau pour connaitre la hauteur de la ligne de titre
564
			$pdf->startTransaction();
565
			$this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
566
			$pdf->rollbackTransaction(true);
567
568
			$iniY = $tab_top + $this->tabTitleHeight + 2;
569
			$curY = $tab_top + $this->tabTitleHeight + 2;
570
			$nexY = $tab_top + $this->tabTitleHeight + 2;
571
572
	            // Loop on each lines
573
	            $pageposbeforeprintlines=$pdf->getPage();
574
	            $pagenb = $pageposbeforeprintlines;
575
	            for ($i = 0; $i < $nblines; $i++)
576
	            {
577
578
	                $curY = $nexY;
579
	                $pdf->SetFont('', '', $default_font_size - 1);   // Into loop to work with multipage
580
	                $pdf->SetTextColor(0, 0, 0);
581
582
	                // Define size of image if we need it
583
	                $imglinesize=array();
584
	                if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]);
585
586
	                $pdf->setTopMargin($tab_top_newpage);
587
	                $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
588
	                $pageposbefore=$pdf->getPage();
589
590
	                $showpricebeforepagebreak=1;
591
	                $posYAfterImage=0;
592
	                $posYAfterDescription=0;
593
594
	                if($this->getColumnStatus('photo'))
595
	                {
596
    	                // We start with Photo of product line
597
    	                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
598
    	                {
599
    	                    $pdf->AddPage('', '', true);
600
    	                    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
601
    	                    $pdf->setPage($pageposbefore+1);
602
603
    	                    $curY = $tab_top_newpage;
604
    	                    $showpricebeforepagebreak=0;
605
    	                }
606
607
    	                if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
608
    	                {
609
    	                    $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300);	// Use 300 dpi
610
    	                    // $pdf->Image does not increase value return by getY, so we save it manually
611
    	                    $posYAfterImage=$curY+$imglinesize['height'];
612
    	                }
613
	                }
614
615
	                // Description of product line
616
	                if ($this->getColumnStatus('desc'))
617
	                {
618
    	                $pdf->startTransaction();
619
    	                pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
620
    	                $pageposafter=$pdf->getPage();
621
    	                if ($pageposafter > $pageposbefore)	// There is a pagebreak
622
    	                {
623
    	                    $pdf->rollbackTransaction(true);
624
    	                    $pageposafter=$pageposbefore;
625
    	                    //print $pageposafter.'-'.$pageposbefore;exit;
626
    	                    $pdf->setPageOrientation('', 1, $heightforfooter);	// The only function to edit the bottom margin of current page to set it.
627
    	                    pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
628
    	                    $pageposafter=$pdf->getPage();
629
    	                    $posyafter=$pdf->GetY();
630
    	                    //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
631
    	                    if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot)))	// There is no space left for total+free text
632
    	                    {
633
    	                        if ($i == ($nblines-1))	// No more lines, and no space left to show total, so we create a new page
634
    	                        {
635
    	                            $pdf->AddPage('', '', true);
636
    	                            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
637
    	                            $pdf->setPage($pageposafter+1);
638
    	                        }
639
    	                    }
640
    	                    else
641
    	                    {
642
    	                        // We found a page break
643
    	                        $showpricebeforepagebreak=0;
644
    	                    }
645
    	                }
646
    	                else	// No pagebreak
647
    	                {
648
    	                    $pdf->commitTransaction();
649
    	                }
650
    	                $posYAfterDescription=$pdf->GetY();
651
	                }
652
653
	                $nexY = $pdf->GetY();
654
	                $pageposafter=$pdf->getPage();
655
	                $pdf->setPage($pageposbefore);
656
	                $pdf->setTopMargin($this->marge_haute);
657
	                $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
658
659
	                // We suppose that a too long description or photo were moved completely on next page
660
	                if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
661
	                    $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
662
	                }
663
664
	                $pdf->SetFont('', '', $default_font_size - 1);   // On repositionne la police par defaut
665
666
	                // VAT Rate
667
	                if ($this->getColumnStatus('vat'))
668
	                {
669
	                    $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
670
	                    $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
671
	                    $nexY = max($pdf->GetY(), $nexY);
672
	                }
673
674
	                // Unit price before discount
675
	                if ($this->getColumnStatus('subprice'))
676
	                {
677
	                    $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
678
	                    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
679
	                    $nexY = max($pdf->GetY(), $nexY);
680
	                }
681
682
	                // Quantity
683
	                // Enough for 6 chars
684
	                if ($this->getColumnStatus('qty'))
685
	                {
686
	                    $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
687
	                    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
688
	                    $nexY = max($pdf->GetY(), $nexY);
689
	                }
690
691
	                // Situation progress
692
	                if ($this->getColumnStatus('progress'))
693
	                {
694
	                    $progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails);
695
	                    $this->printStdColumnContent($pdf, $curY, 'progress', $progress);
696
	                    $nexY = max($pdf->GetY(), $nexY);
697
	                }
698
699
	                // Unit
700
	                if ($this->getColumnStatus('unit'))
701
	                {
702
	                    $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
703
	                    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
704
	                    $nexY = max($pdf->GetY(), $nexY);
705
	                }
706
707
	                // Discount on line
708
	                if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
709
	                {
710
	                    $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
711
	                    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
712
	                    $nexY = max($pdf->GetY(), $nexY);
713
	                }
714
715
	                // Total HT line
716
	                if ($this->getColumnStatus('totalexcltax'))
717
	                {
718
	                    $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
719
	                    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
720
	                    $nexY = max($pdf->GetY(), $nexY);
721
	                }
722
723
724
	                $parameters=array(
725
	                    'object' => $object,
726
	                    'i' => $i,
727
	                    'pdf' =>& $pdf,
728
	                    'curY' =>& $curY,
729
	                    'nexY' =>& $nexY,
730
	                    'outputlangs' => $outputlangs,
731
	                    'hidedetails' => $hidedetails
732
	                );
733
	                $reshook=$hookmanager->executeHooks('printPDFline', $parameters, $this);    // Note that $object may have been modified by hook
734
735
736
737
	                $sign=1;
738
	                if (isset($object->type) && $object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
739
	                // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
740
	                $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
741
	                if ($prev_progress > 0 && !empty($object->lines[$i]->situation_percent)) // Compute progress from previous situation
742
	                {
743
	                    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;
744
	                    else $tvaligne = $sign * $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
745
	                } else {
746
	                    if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne= $sign * $object->lines[$i]->multicurrency_total_tva;
747
	                    else $tvaligne= $sign * $object->lines[$i]->total_tva;
748
	                }
749
750
	                $localtax1ligne=$object->lines[$i]->total_localtax1;
751
	                $localtax2ligne=$object->lines[$i]->total_localtax2;
752
	                $localtax1_rate=$object->lines[$i]->localtax1_tx;
753
	                $localtax2_rate=$object->lines[$i]->localtax2_tx;
754
	                $localtax1_type=$object->lines[$i]->localtax1_type;
755
	                $localtax2_type=$object->lines[$i]->localtax2_type;
756
757
	                if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
758
	                if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
759
	                if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
760
761
	                $vatrate=(string) $object->lines[$i]->tva_tx;
762
763
	                // Retrieve type from database for backward compatibility with old records
764
	                if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined
765
	                    && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax
766
	                {
767
	                    $localtaxtmp_array=getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
768
	                    $localtax1_type = $localtaxtmp_array[0];
769
	                    $localtax2_type = $localtaxtmp_array[2];
770
	                }
771
772
	                // retrieve global local tax
773
	                if ($localtax1_type && $localtax1ligne != 0)
774
	                    $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne;
775
	                    if ($localtax2_type && $localtax2ligne != 0)
776
	                        $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne;
777
778
	                        if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
779
	                        if (! isset($this->tva[$vatrate])) 				$this->tva[$vatrate]=0;
780
	                        $this->tva[$vatrate] += $tvaligne;
781
782
	                        $nexY = max($nexY, $posYAfterImage);
783
784
	                        // Add line
785
	                        if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1))
786
	                        {
787
	                            $pdf->setPage($pageposafter);
788
	                            $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80)));
789
	                            //$pdf->SetDrawColor(190,190,200);
790
	                            $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
791
	                            $pdf->SetLineStyle(array('dash'=>0));
792
	                        }
793
794
	                        $nexY+=2;    // Add space between lines
795
796
	                        // Detect if some page were added automatically and output _tableau for past pages
797
	                        while ($pagenb < $pageposafter)
798
	                        {
799
	                            $pdf->setPage($pagenb);
800
	                            if ($pagenb == $pageposbeforeprintlines)
801
	                            {
802
	                                $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
803
	                            }
804
	                            else
805
	                            {
806
	                                $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
807
	                            }
808
	                            $this->_pagefoot($pdf, $object, $outputlangs, 1);
809
	                            $pagenb++;
810
	                            $pdf->setPage($pagenb);
811
	                            $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
812
	                            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
813
	                        }
814
815
	                        if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
816
	                        {
817
	                            if ($pagenb == $pageposafter)
818
	                            {
819
	                                $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
820
	                            }
821
	                            else
822
	                            {
823
	                                $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
824
	                            }
825
	                            $this->_pagefoot($pdf, $object, $outputlangs, 1);
826
	                            // New page
827
	                            $pdf->AddPage();
828
	                            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
829
	                            $pagenb++;
830
	                            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
831
	                        }
832
	            }
833
834
	            // Show square
835
	            if ($pagenb == $pageposbeforeprintlines)
836
	            {
837
	                $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
838
	                $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
839
	            }
840
	            else
841
	            {
842
	                $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
843
	                $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
844
	            }
845
846
	            // Affiche zone infos
847
	            $posy=$this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
848
849
	            // Affiche zone totaux
850
	            $posy=$this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
851
852
	            // Affiche zone versements
853
	            if (($deja_regle || $amount_credit_notes_included || $amount_deposits_included) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
854
	            {
855
	                $posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
856
	            }
857
858
	            // Pied de page
859
	            $this->_pagefoot($pdf, $object, $outputlangs);
860
	            if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages();
861
862
	            $pdf->Close();
863
864
	            $pdf->Output($file, 'F');
865
866
	            // Add pdfgeneration hook
867
	            $hookmanager->initHooks(array('pdfgeneration'));
868
	            $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
869
	            global $action;
870
	            $reshook=$hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action);    // Note that $action and $object may have been modified by some hooks
871
	            if ($reshook < 0)
872
	            {
873
	                $this->error = $hookmanager->error;
874
	                $this->errors = $hookmanager->errors;
875
	            }
876
877
	            if (! empty($conf->global->MAIN_UMASK))
878
	                @chmod($file, octdec($conf->global->MAIN_UMASK));
879
880
	                $this->result = array('fullpath'=>$file);
881
882
	                return 1;   // No error
883
	        }
884
	        else
885
	        {
886
	            $this->error=$langs->transnoentities("ErrorCanNotCreateDir", $dir);
887
	            return 0;
888
	        }
889
	    }
890
	    else
891
	    {
892
	        $this->error=$langs->transnoentities("ErrorConstantNotDefined", "FAC_OUTPUTDIR");
893
	        return 0;
894
	    }
895
	}
896
897
898
	/**
899
	 *  Show payments table
900
	 *
901
     *  @param	PDF			$pdf           Object PDF
902
     *  @param  Object		$object         Object invoice
903
     *  @param  int			$posy           Position y in PDF
904
     *  @param  Translate	$outputlangs    Object langs for output
905
     *  @return int             			<0 if KO, >0 if OK
906
	 */
907
	public function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
908
	{
909
		global $conf;
910
911
        $sign=1;
912
        if ($object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
913
914
        $tab3_posx = 120;
915
		$tab3_top = $posy + 8;
916
		$tab3_width = 80;
917
		$tab3_height = 4;
918
		if ($this->page_largeur < 210) // To work with US executive format
919
		{
920
			$tab3_posx -= 20;
921
		}
922
923
		$default_font_size = pdf_getPDFFontSize($outputlangs);
924
925
		$title=$outputlangs->transnoentities("PaymentsAlreadyDone");
926
		if ($object->type == 2) $title=$outputlangs->transnoentities("PaymentsBackAlreadyDone");
927
928
		$pdf->SetFont('', '', $default_font_size - 3);
929
		$pdf->SetXY($tab3_posx, $tab3_top - 4);
930
		$pdf->MultiCell(60, 3, $title, 0, 'L', 0);
931
932
		$pdf->line($tab3_posx, $tab3_top, $tab3_posx+$tab3_width, $tab3_top);
933
934
		$pdf->SetFont('', '', $default_font_size - 4);
935
		$pdf->SetXY($tab3_posx, $tab3_top);
936
		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Payment"), 0, 'L', 0);
937
		$pdf->SetXY($tab3_posx+21, $tab3_top);
938
		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Amount"), 0, 'L', 0);
939
		$pdf->SetXY($tab3_posx+40, $tab3_top);
940
		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Type"), 0, 'L', 0);
941
		$pdf->SetXY($tab3_posx+58, $tab3_top);
942
		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Num"), 0, 'L', 0);
943
944
		$pdf->line($tab3_posx, $tab3_top-1+$tab3_height, $tab3_posx+$tab3_width, $tab3_top-1+$tab3_height);
945
946
		$y=0;
947
948
		$pdf->SetFont('', '', $default_font_size - 4);
949
950
951
		// Loop on each deposits and credit notes included
952
		$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,";
953
		$sql.= " re.description, re.fk_facture_source,";
954
		$sql.= " f.type, f.datef";
955
		$sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re, ".MAIN_DB_PREFIX ."facture as f";
956
		$sql.= " WHERE re.fk_facture_source = f.rowid AND re.fk_facture = ".$object->id;
957
		$resql=$this->db->query($sql);
958
		if ($resql)
959
		{
960
			$num = $this->db->num_rows($resql);
961
			$i=0;
962
			$invoice=new Facture($this->db);
963
			while ($i < $num)
964
			{
965
				$y+=3;
966
				$obj = $this->db->fetch_object($resql);
967
968
				if ($obj->type == 2) $text=$outputlangs->trans("CreditNote");
969
				elseif ($obj->type == 3) $text=$outputlangs->trans("Deposit");
970
				else $text=$outputlangs->trans("UnknownType");
971
972
				$invoice->fetch($obj->fk_facture_source);
973
974
				$pdf->SetXY($tab3_posx, $tab3_top+$y);
975
				$pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($obj->datef), 'day', false, $outputlangs, true), 0, 'L', 0);
976
				$pdf->SetXY($tab3_posx+21, $tab3_top+$y);
977
				$pdf->MultiCell(20, 3, price(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $obj->multicurrency_amount_ttc : $obj->amount_ttc, 0, $outputlangs), 0, 'L', 0);
978
				$pdf->SetXY($tab3_posx+40, $tab3_top+$y);
979
				$pdf->MultiCell(20, 3, $text, 0, 'L', 0);
980
				$pdf->SetXY($tab3_posx+58, $tab3_top+$y);
981
				$pdf->MultiCell(20, 3, $invoice->ref, 0, 'L', 0);
982
983
				$pdf->line($tab3_posx, $tab3_top+$y+3, $tab3_posx+$tab3_width, $tab3_top+$y+3);
984
985
				$i++;
986
			}
987
		}
988
		else
989
		{
990
			$this->error=$this->db->lasterror();
991
			return -1;
992
		}
993
994
		// Loop on each payment
995
		// TODO Call getListOfPaymentsgetListOfPayments instead of hard coded sql
996
		$sql = "SELECT p.datep as date, p.fk_paiement, p.num_paiement as num, pf.amount as amount, pf.multicurrency_amount,";
997
		$sql.= " cp.code";
998
		$sql.= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p";
999
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id";
1000
		$sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = ".$object->id;
1001
		//$sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = 1";
1002
		$sql.= " ORDER BY p.datep";
1003
1004
		$resql=$this->db->query($sql);
1005
		if ($resql)
1006
		{
1007
			$num = $this->db->num_rows($resql);
1008
			$i=0;
1009
			while ($i < $num) {
1010
				$y+=3;
1011
				$row = $this->db->fetch_object($resql);
1012
1013
				$pdf->SetXY($tab3_posx, $tab3_top+$y);
1014
				$pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($row->date), 'day', false, $outputlangs, true), 0, 'L', 0);
1015
				$pdf->SetXY($tab3_posx+21, $tab3_top+$y);
1016
				$pdf->MultiCell(20, 3, price($sign * (($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $row->multicurrency_amount : $row->amount), 0, $outputlangs), 0, 'L', 0);
1017
				$pdf->SetXY($tab3_posx+40, $tab3_top+$y);
1018
				$oper = $outputlangs->transnoentitiesnoconv("PaymentTypeShort" . $row->code);
1019
1020
				$pdf->MultiCell(20, 3, $oper, 0, 'L', 0);
1021
				$pdf->SetXY($tab3_posx+58, $tab3_top+$y);
1022
				$pdf->MultiCell(30, 3, $row->num, 0, 'L', 0);
1023
1024
				$pdf->line($tab3_posx, $tab3_top+$y+3, $tab3_posx+$tab3_width, $tab3_top+$y+3);
1025
1026
				$i++;
1027
			}
1028
		}
1029
		else
1030
		{
1031
			$this->error=$this->db->lasterror();
1032
			return -1;
1033
		}
1034
	}
1035
1036
1037
	/**
1038
	 *   Show miscellaneous information (payment mode, payment term, ...)
1039
	 *
1040
	 *   @param		PDF			$pdf     		Object PDF
1041
	 *   @param		Object		$object			Object to show
1042
	 *   @param		int			$posy			Y
1043
	 *   @param		Translate	$outputlangs	Langs object
1044
	 *   @return	void
1045
	 */
1046
	private function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
1047
	{
1048
		global $conf;
1049
1050
		$default_font_size = pdf_getPDFFontSize($outputlangs);
1051
1052
		$pdf->SetFont('', '', $default_font_size - 1);
1053
1054
		// If France, show VAT mention if not applicable
1055
		if ($this->emetteur->country_code == 'FR' && $this->franchise == 1)
1056
		{
1057
			$pdf->SetFont('', 'B', $default_font_size - 2);
1058
			$pdf->SetXY($this->marge_gauche, $posy);
1059
			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
1060
1061
			$posy=$pdf->GetY()+4;
1062
		}
1063
1064
		$posxval=52;
1065
1066
		// Show payments conditions
1067
		if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement))
1068
		{
1069
			$pdf->SetFont('', 'B', $default_font_size - 2);
1070
			$pdf->SetXY($this->marge_gauche, $posy);
1071
			$titre = $outputlangs->transnoentities("PaymentConditions").':';
1072
			$pdf->MultiCell(43, 4, $titre, 0, 'L');
1073
1074
			$pdf->SetFont('', '', $default_font_size - 2);
1075
			$pdf->SetXY($posxval, $posy);
1076
			$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);
1077
			$lib_condition_paiement=str_replace('\n', "\n", $lib_condition_paiement);
1078
			$pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
1079
1080
			$posy=$pdf->GetY()+3;
1081
		}
1082
1083
		if ($object->type != 2)
1084
		{
1085
			// Check a payment mode is defined
1086
			if (empty($object->mode_reglement_code)
1087
			&& empty($conf->global->FACTURE_CHQ_NUMBER)
1088
			&& empty($conf->global->FACTURE_RIB_NUMBER))
1089
			{
1090
				$this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured");
1091
			}
1092
			// Avoid having any valid PDF with setup that is not complete
1093
			elseif (($object->mode_reglement_code == 'CHQ' && empty($conf->global->FACTURE_CHQ_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))
1094
				|| ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank)))
1095
			{
1096
				$outputlangs->load("errors");
1097
1098
				$pdf->SetXY($this->marge_gauche, $posy);
1099
				$pdf->SetTextColor(200, 0, 0);
1100
				$pdf->SetFont('', 'B', $default_font_size - 2);
1101
				$this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup", $object->mode_reglement_code);
1102
				$pdf->MultiCell(80, 3, $this->error, 0, 'L', 0);
1103
				$pdf->SetTextColor(0, 0, 0);
1104
1105
				$posy=$pdf->GetY()+1;
1106
			}
1107
1108
			// Show payment mode
1109
			if ($object->mode_reglement_code
1110
			&& $object->mode_reglement_code != 'CHQ'
1111
			&& $object->mode_reglement_code != 'VIR')
1112
			{
1113
				$pdf->SetFont('', 'B', $default_font_size - 2);
1114
				$pdf->SetXY($this->marge_gauche, $posy);
1115
				$titre = $outputlangs->transnoentities("PaymentMode").':';
1116
				$pdf->MultiCell(80, 5, $titre, 0, 'L');
1117
1118
				$pdf->SetFont('', '', $default_font_size - 2);
1119
				$pdf->SetXY($posxval, $posy);
1120
				$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);
1121
				$pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
1122
1123
				$posy=$pdf->GetY()+2;
1124
			}
1125
1126
			// Show payment mode CHQ
1127
			if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
1128
			{
1129
				// Si mode reglement non force ou si force a CHQ
1130
				if (! empty($conf->global->FACTURE_CHQ_NUMBER))
1131
				{
1132
					$diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE);
1133
1134
					if ($conf->global->FACTURE_CHQ_NUMBER > 0)
1135
					{
1136
						$account = new Account($this->db);
1137
						$account->fetch($conf->global->FACTURE_CHQ_NUMBER);
1138
1139
						$pdf->SetXY($this->marge_gauche, $posy);
1140
						$pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1141
						$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0);
1142
						$posy=$pdf->GetY()+1;
1143
1144
			            if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
1145
			            {
1146
							$pdf->SetXY($this->marge_gauche, $posy);
1147
							$pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1148
							$pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
1149
							$posy=$pdf->GetY()+2;
1150
			            }
1151
					}
1152
					if ($conf->global->FACTURE_CHQ_NUMBER == -1)
1153
					{
1154
						$pdf->SetXY($this->marge_gauche, $posy);
1155
						$pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1156
						$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
1157
						$posy=$pdf->GetY()+1;
1158
1159
			            if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
1160
			            {
1161
							$pdf->SetXY($this->marge_gauche, $posy);
1162
							$pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1163
							$pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
1164
							$posy=$pdf->GetY()+2;
1165
			            }
1166
					}
1167
				}
1168
			}
1169
1170
			// If payment mode not forced or forced to VIR, show payment with BAN
1171
			if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
1172
			{
1173
				if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER))
1174
				{
1175
					$bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account);
1176
					if (! empty($object->fk_bank)) $bankid=$object->fk_bank;   // For backward compatibility when object->fk_account is forced with object->fk_bank
1177
					$account = new Account($this->db);
1178
					$account->fetch($bankid);
1179
1180
					$curx=$this->marge_gauche;
1181
					$cury=$posy;
1182
1183
					$posy=pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
1184
1185
					$posy+=2;
1186
				}
1187
			}
1188
		}
1189
1190
		return $posy;
1191
	}
1192
1193
1194
	/**
1195
	 *  Show total to pay
1196
	 *
1197
	 *  @param	PDF			$pdf           Object PDF
1198
	 *	@param  Facture		$object         Object invoice
1199
	 *	@param  int			$deja_regle     Montant deja regle
1200
	 *	@param	int			$posy			Position depart
1201
	 *	@param	Translate	$outputlangs	Objet langs
1202
	 *	@return int							Position pour suite
1203
	 */
1204
	private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
1205
	{
1206
		global $conf,$mysoc;
1207
1208
        $sign=1;
1209
        if ($object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
1210
1211
        $default_font_size = pdf_getPDFFontSize($outputlangs);
1212
1213
		$tab2_top = $posy;
1214
		$tab2_hl = 4;
1215
		$pdf->SetFont('', '', $default_font_size - 1);
1216
1217
		// Tableau total
1218
		$col1x = 120; $col2x = 170;
1219
		if ($this->page_largeur < 210) // To work with US executive format
1220
		{
1221
			$col2x-=20;
1222
		}
1223
		$largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
1224
1225
		$useborder=0;
1226
		$index = 0;
1227
1228
		// Total HT
1229
		$pdf->SetFillColor(255, 255, 255);
1230
		$pdf->SetXY($col1x, $tab2_top + 0);
1231
		$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
1232
1233
		$total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
1234
		$pdf->SetXY($col2x, $tab2_top + 0);
1235
		$pdf->MultiCell($largcol2, $tab2_hl, price($sign * ($total_ht + (! empty($object->remise)?$object->remise:0)), 0, $outputlangs), 0, 'R', 1);
1236
1237
		// Show VAT by rates and total
1238
		$pdf->SetFillColor(248, 248, 248);
1239
1240
		$total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
1241
1242
		$this->atleastoneratenotnull=0;
1243
		if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
1244
		{
1245
			$tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
1246
			if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull)
1247
			{
1248
				// Nothing to do
1249
			}
1250
			else
1251
			{
1252
			    // FIXME amount of vat not supported with multicurrency
1253
1254
				//Local tax 1 before VAT
1255
				//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1256
				//{
1257
					foreach($this->localtax1 as $localtax_type => $localtax_rate)
1258
					{
1259
						if (in_array((string) $localtax_type, array('1','3','5'))) continue;
1260
1261
						foreach($localtax_rate as $tvakey => $tvaval)
1262
						{
1263
							if ($tvakey!=0)    // On affiche pas taux 0
1264
							{
1265
								//$this->atleastoneratenotnull++;
1266
1267
								$index++;
1268
								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1269
1270
								$tvacompl='';
1271
								if (preg_match('/\*/', $tvakey))
1272
								{
1273
									$tvakey=str_replace('*', '', $tvakey);
1274
									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1275
								}
1276
1277
								$totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
1278
								$totalvat.=vatrate(abs($tvakey), 1).$tvacompl;
1279
								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1280
1281
								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1282
								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1283
							}
1284
						}
1285
					}
1286
	      		//}
1287
				//Local tax 2 before VAT
1288
				//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1289
				//{
1290
					foreach($this->localtax2 as $localtax_type => $localtax_rate)
1291
					{
1292
						if (in_array((string) $localtax_type, array('1','3','5'))) continue;
1293
1294
						foreach($localtax_rate as $tvakey => $tvaval)
1295
						{
1296
							if ($tvakey!=0)    // On affiche pas taux 0
1297
							{
1298
								//$this->atleastoneratenotnull++;
1299
1300
1301
1302
								$index++;
1303
								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1304
1305
								$tvacompl='';
1306
								if (preg_match('/\*/', $tvakey))
1307
								{
1308
									$tvakey=str_replace('*', '', $tvakey);
1309
									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1310
								}
1311
								$totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
1312
								$totalvat.=vatrate(abs($tvakey), 1).$tvacompl;
1313
								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1314
1315
								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1316
								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1317
							}
1318
						}
1319
					}
1320
1321
                //}
1322
1323
				// VAT
1324
				// Situations totals migth be wrong on huge amounts
1325
				if ($object->situation_cycle_ref && $object->situation_counter > 1) {
1326
1327
					$sum_pdf_tva = 0;
1328
					foreach($this->tva as $tvakey => $tvaval){
1329
						$sum_pdf_tva+=$tvaval; // sum VAT amounts to compare to object
1330
					}
1331
1332
					if($sum_pdf_tva!=$object->total_tva) { // apply coef to recover the VAT object amount (the good one)
1333
						$coef_fix_tva = $object->total_tva / $sum_pdf_tva;
1334
1335
						foreach($this->tva as $tvakey => $tvaval) {
1336
							$this->tva[$tvakey]=$tvaval * $coef_fix_tva;
1337
						}
1338
					}
1339
				}
1340
1341
				foreach($this->tva as $tvakey => $tvaval)
1342
				{
1343
					if ($tvakey != 0)    // On affiche pas taux 0
1344
					{
1345
						$this->atleastoneratenotnull++;
1346
1347
						$index++;
1348
						$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1349
1350
						$tvacompl='';
1351
						if (preg_match('/\*/', $tvakey))
1352
						{
1353
							$tvakey=str_replace('*', '', $tvakey);
1354
							$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1355
						}
1356
						$totalvat =$outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).' ';
1357
						$totalvat.=vatrate($tvakey, 1).$tvacompl;
1358
						$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1359
1360
						$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1361
						$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1362
					}
1363
				}
1364
1365
				//Local tax 1 after VAT
1366
				//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1367
				//{
1368
					foreach($this->localtax1 as $localtax_type => $localtax_rate)
1369
					{
1370
						if (in_array((string) $localtax_type, array('2','4','6'))) continue;
1371
1372
						foreach($localtax_rate as $tvakey => $tvaval)
1373
						{
1374
							if ($tvakey != 0)    // On affiche pas taux 0
1375
							{
1376
								//$this->atleastoneratenotnull++;
1377
1378
								$index++;
1379
								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1380
1381
								$tvacompl='';
1382
								if (preg_match('/\*/', $tvakey))
1383
								{
1384
									$tvakey=str_replace('*', '', $tvakey);
1385
									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1386
								}
1387
								$totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
1388
								$totalvat.=vatrate(abs($tvakey), 1).$tvacompl;
1389
1390
								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1391
								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1392
								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1393
							}
1394
						}
1395
					}
1396
	      		//}
1397
				//Local tax 2 after VAT
1398
				//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1399
				//{
1400
					foreach($this->localtax2 as $localtax_type => $localtax_rate)
1401
					{
1402
						if (in_array((string) $localtax_type, array('2','4','6'))) continue;
1403
1404
						foreach($localtax_rate as $tvakey => $tvaval)
1405
						{
1406
						    // retrieve global local tax
1407
							if ($tvakey != 0)    // On affiche pas taux 0
1408
							{
1409
								//$this->atleastoneratenotnull++;
1410
1411
								$index++;
1412
								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1413
1414
								$tvacompl='';
1415
								if (preg_match('/\*/', $tvakey))
1416
								{
1417
									$tvakey=str_replace('*', '', $tvakey);
1418
									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1419
								}
1420
								$totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
1421
1422
								$totalvat.=vatrate(abs($tvakey), 1).$tvacompl;
1423
								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1424
1425
								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1426
								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1427
							}
1428
						}
1429
					}
1430
				//}
1431
1432
				// Revenue stamp
1433
				if (price2num($object->revenuestamp) != 0)
1434
				{
1435
					$index++;
1436
					$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1437
					$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RevenueStamp"), $useborder, 'L', 1);
1438
1439
					$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1440
					$pdf->MultiCell($largcol2, $tab2_hl, price($sign * $object->revenuestamp), $useborder, 'R', 1);
1441
				}
1442
1443
				// Total TTC
1444
				$index++;
1445
				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1446
				$pdf->SetTextColor(0, 0, 60);
1447
				$pdf->SetFillColor(224, 224, 224);
1448
				$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
1449
1450
				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1451
				$pdf->MultiCell($largcol2, $tab2_hl, price($sign * $total_ttc, 0, $outputlangs), $useborder, 'R', 1);
1452
			}
1453
		}
1454
1455
		$pdf->SetTextColor(0, 0, 0);
1456
1457
		$creditnoteamount=$object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
1458
		$depositsamount=$object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
1459
		//print "x".$creditnoteamount."-".$depositsamount;exit;
1460
		$resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
1461
		if ($object->paye) $resteapayer=0;
1462
1463
		if (($deja_regle > 0 || $creditnoteamount > 0 || $depositsamount > 0) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
1464
		{
1465
			// Already paid + Deposits
1466
			$index++;
1467
			$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1468
			$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("Paid"), 0, 'L', 0);
1469
			$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1470
			$pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle + $depositsamount, 0, $outputlangs), 0, 'R', 0);
1471
1472
			// Credit note
1473
			if ($creditnoteamount)
1474
			{
1475
				$index++;
1476
				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1477
				$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("CreditNotes"), 0, 'L', 0);
1478
				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1479
				$pdf->MultiCell($largcol2, $tab2_hl, price($creditnoteamount, 0, $outputlangs), 0, 'R', 0);
1480
			}
1481
1482
			// Escompte
1483
			if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT)
1484
			{
1485
				$index++;
1486
				$pdf->SetFillColor(255, 255, 255);
1487
1488
				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1489
				$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1);
1490
				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1491
				$pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1);
1492
1493
				$resteapayer=0;
1494
			}
1495
1496
			$index++;
1497
			$pdf->SetTextColor(0, 0, 60);
1498
			$pdf->SetFillColor(224, 224, 224);
1499
			$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1500
			$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
1501
			$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1502
			$pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
1503
1504
			$pdf->SetFont('', '', $default_font_size - 1);
1505
			$pdf->SetTextColor(0, 0, 0);
1506
		}
1507
1508
		$index++;
1509
		return ($tab2_top + ($tab2_hl * $index));
1510
	}
1511
1512
	/**
1513
	 *   Show table for lines
1514
	 *
1515
	 *   @param		PDF			$pdf     		Object PDF
1516
	 *   @param		string		$tab_top		Top position of table
1517
	 *   @param		string		$tab_height		Height of table (rectangle)
1518
	 *   @param		int			$nexY			Y (not used)
1519
	 *   @param		Translate	$outputlangs	Langs object
1520
	 *   @param		int			$hidetop		1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
1521
	 *   @param		int			$hidebottom		Hide bottom bar of array
1522
	 *   @param		string		$currency		Currency code
1523
	 *   @return	void
1524
	 */
1525
	private function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
1526
	{
1527
		global $conf;
1528
1529
		// Force to disable hidetop and hidebottom
1530
		$hidebottom=0;
1531
		if ($hidetop) $hidetop=-1;
1532
1533
		$currency = !empty($currency) ? $currency : $conf->currency;
1534
		$default_font_size = pdf_getPDFFontSize($outputlangs);
1535
1536
		// Amount in (at tab_top - 1)
1537
		$pdf->SetTextColor(0, 0, 0);
1538
		$pdf->SetFont('', '', $default_font_size - 2);
1539
1540
		if (empty($hidetop))
1541
		{
1542
			$titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1543
			$pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
1544
			$pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1545
1546
			//$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1547
			if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',', $conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
1548
		}
1549
1550
		$pdf->SetDrawColor(128, 128, 128);
1551
		$pdf->SetFont('', '', $default_font_size - 1);
1552
1553
		// Output Rect
1554
		$this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom);	// Rect prend une longueur en 3eme param et 4eme param
1555
1556
1557
		$this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
1558
1559
		if (empty($hidetop)){
1560
		    $pdf->line($this->marge_gauche, $tab_top+$this->tabTitleHeight, $this->page_largeur-$this->marge_droite, $tab_top+$this->tabTitleHeight);	// line prend une position y en 2eme param et 4eme param
1561
		}
1562
	}
1563
1564
	/**
1565
	 *  Show top header of page.
1566
	 *
1567
	 *  @param	PDF			$pdf     		Object PDF
1568
	 *  @param  Object		$object     	Object to show
1569
	 *  @param  int	    	$showaddress    0=no, 1=yes
1570
	 *  @param  Translate	$outputlangs	Object lang for output
1571
	 *  @return	void
1572
	 */
1573
	private function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
1574
	{
1575
		global $conf, $langs;
1576
1577
		// Translations
1578
		$outputlangs->loadLangs(array("main", "bills", "propal", "companies"));
1579
1580
		$default_font_size = pdf_getPDFFontSize($outputlangs);
1581
1582
		pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
1583
1584
		// Show Draft Watermark
1585
		if($object->statut==Facture::STATUS_DRAFT && (! empty($conf->global->FACTURE_DRAFT_WATERMARK)) )
1586
        {
1587
		      pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK);
1588
        }
1589
1590
		$pdf->SetTextColor(0, 0, 60);
1591
		$pdf->SetFont('', 'B', $default_font_size + 3);
1592
1593
		$w = 110;
1594
1595
		$posy=$this->marge_haute;
1596
        $posx=$this->page_largeur-$this->marge_droite-$w;
1597
1598
		$pdf->SetXY($this->marge_gauche, $posy);
1599
1600
		// Logo
1601
		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
1602
		{
1603
			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
1604
			if ($this->emetteur->logo)
1605
			{
1606
				if (is_readable($logo))
1607
				{
1608
				    $height=pdf_getHeightForLogo($logo);
1609
					$pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
1610
				}
1611
				else
1612
				{
1613
					$pdf->SetTextColor(200, 0, 0);
1614
					$pdf->SetFont('', 'B', $default_font_size - 2);
1615
					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1616
					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1617
				}
1618
			}
1619
			else
1620
			{
1621
				$text=$this->emetteur->name;
1622
				$pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
1623
			}
1624
		}
1625
1626
		$pdf->SetFont('', 'B', $default_font_size + 3);
1627
		$pdf->SetXY($posx, $posy);
1628
		$pdf->SetTextColor(0, 0, 60);
1629
		$title=$outputlangs->transnoentities("PdfInvoiceTitle");
1630
		if ($object->type == 1) $title=$outputlangs->transnoentities("InvoiceReplacement");
1631
		if ($object->type == 2) $title=$outputlangs->transnoentities("InvoiceAvoir");
1632
		if ($object->type == 3) $title=$outputlangs->transnoentities("InvoiceDeposit");
1633
		if ($object->type == 4) $title=$outputlangs->transnoentities("InvoiceProForma");
1634
		if ($this->situationinvoice) $title=$outputlangs->transnoentities("InvoiceSituation");
1635
		$pdf->MultiCell($w, 3, $title, '', 'R');
1636
1637
		$pdf->SetFont('', 'B', $default_font_size);
1638
1639
		$posy+=5;
1640
		$pdf->SetXY($posx, $posy);
1641
		$pdf->SetTextColor(0, 0, 60);
1642
		$textref=$outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref);
1643
		if ($object->statut == Facture::STATUS_DRAFT)
1644
		{
1645
			$pdf->SetTextColor(128, 0, 0);
1646
			$textref.=' - '.$outputlangs->transnoentities("NotValidated");
1647
		}
1648
		$pdf->MultiCell($w, 4, $textref, '', 'R');
1649
1650
		$posy+=1;
1651
		$pdf->SetFont('', '', $default_font_size - 2);
1652
1653
		if ($object->ref_client)
1654
		{
1655
			$posy+=4;
1656
			$pdf->SetXY($posx, $posy);
1657
			$pdf->SetTextColor(0, 0, 60);
1658
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
1659
		}
1660
1661
		$objectidnext=$object->getIdReplacingInvoice('validated');
1662
		if ($object->type == 0 && $objectidnext)
1663
		{
1664
			$objectreplacing=new Facture($this->db);
1665
			$objectreplacing->fetch($objectidnext);
1666
1667
			$posy+=3;
1668
			$pdf->SetXY($posx, $posy);
1669
			$pdf->SetTextColor(0, 0, 60);
1670
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementByInvoice").' : '.$outputlangs->convToOutputCharset($objectreplacing->ref), '', 'R');
1671
		}
1672
		if ($object->type == 1)
1673
		{
1674
			$objectreplaced=new Facture($this->db);
1675
			$objectreplaced->fetch($object->fk_facture_source);
1676
1677
			$posy+=4;
1678
			$pdf->SetXY($posx, $posy);
1679
			$pdf->SetTextColor(0, 0, 60);
1680
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
1681
		}
1682
		if ($object->type == 2 && !empty($object->fk_facture_source))
1683
		{
1684
			$objectreplaced=new Facture($this->db);
1685
			$objectreplaced->fetch($object->fk_facture_source);
1686
1687
			$posy+=3;
1688
			$pdf->SetXY($posx, $posy);
1689
			$pdf->SetTextColor(0, 0, 60);
1690
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("CorrectionInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
1691
		}
1692
1693
		$posy+=4;
1694
		$pdf->SetXY($posx, $posy);
1695
		$pdf->SetTextColor(0, 0, 60);
1696
		$pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateInvoice")." : " . dol_print_date($object->date, "day", false, $outputlangs), '', 'R');
1697
1698
		if (! empty($conf->global->INVOICE_POINTOFTAX_DATE))
1699
		{
1700
			$posy+=4;
1701
			$pdf->SetXY($posx, $posy);
1702
			$pdf->SetTextColor(0, 0, 60);
1703
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("DatePointOfTax")." : " . dol_print_date($object->date_pointoftax, "day", false, $outputlangs), '', 'R');
1704
		}
1705
1706
		if ($object->type != 2)
1707
		{
1708
			$posy+=3;
1709
			$pdf->SetXY($posx, $posy);
1710
			$pdf->SetTextColor(0, 0, 60);
1711
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateDue")." : " . dol_print_date($object->date_lim_reglement, "day", false, $outputlangs, true), '', 'R');
1712
		}
1713
1714
		if ($object->thirdparty->code_client)
1715
		{
1716
			$posy+=3;
1717
			$pdf->SetXY($posx, $posy);
1718
			$pdf->SetTextColor(0, 0, 60);
1719
			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : " . $outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
1720
		}
1721
1722
		// Get contact
1723
		if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
1724
		{
1725
		    $arrayidcontact=$object->getIdContact('internal', 'SALESREPFOLL');
1726
		    if (count($arrayidcontact) > 0)
1727
		    {
1728
		        $usertmp=new User($this->db);
1729
		        $usertmp->fetch($arrayidcontact[0]);
1730
                $posy+=4;
1731
                $pdf->SetXY($posx, $posy);
1732
		        $pdf->SetTextColor(0, 0, 60);
1733
		        $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
1734
		    }
1735
		}
1736
1737
		$posy+=1;
1738
1739
		$top_shift = 0;
1740
		// Show list of linked objects
1741
		$current_y = $pdf->getY();
1742
		$posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
1743
		if ($current_y < $pdf->getY())
1744
		{
1745
			$top_shift = $pdf->getY() - $current_y;
1746
		}
1747
1748
		if ($showaddress)
1749
		{
1750
			// Sender properties
1751
			$carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1752
1753
			// Show sender
1754
			$posy=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
1755
			$posy+=$top_shift;
1756
			$posx=$this->marge_gauche;
1757
			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
1758
1759
			$hautcadre=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
1760
			$widthrecbox=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
1761
1762
1763
			// Show sender frame
1764
			$pdf->SetTextColor(0, 0, 0);
1765
			$pdf->SetFont('', '', $default_font_size - 2);
1766
			$pdf->SetXY($posx, $posy-5);
1767
			$pdf->MultiCell(66, 5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
1768
			$pdf->SetXY($posx, $posy);
1769
			$pdf->SetFillColor(230, 230, 230);
1770
			$pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
1771
			$pdf->SetTextColor(0, 0, 60);
1772
1773
			// Show sender name
1774
			$pdf->SetXY($posx+2, $posy+3);
1775
			$pdf->SetFont('', 'B', $default_font_size);
1776
			$pdf->MultiCell($widthrecbox-2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
1777
			$posy=$pdf->getY();
1778
1779
			// Show sender information
1780
			$pdf->SetXY($posx+2, $posy);
1781
			$pdf->SetFont('', '', $default_font_size - 1);
1782
			$pdf->MultiCell($widthrecbox-2, 4, $carac_emetteur, 0, 'L');
1783
1784
			// If BILLING contact defined on invoice, we use it
1785
			$usecontact=false;
1786
			$arrayidcontact=$object->getIdContact('external', 'BILLING');
1787
			if (count($arrayidcontact) > 0)
1788
			{
1789
				$usecontact=true;
1790
				$result=$object->fetch_contact($arrayidcontact[0]);
1791
			}
1792
1793
			//Recipient name
1794
			// On peut utiliser le nom de la societe du contact
1795
			if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) {
1796
				$thirdparty = $object->contact;
1797
			} else {
1798
				$thirdparty = $object->thirdparty;
1799
			}
1800
1801
			$carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs);
1802
1803
			$carac_client=pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact?$object->contact:''), $usecontact, 'target', $object);
1804
1805
			// Show recipient
1806
			$widthrecbox=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
1807
			if ($this->page_largeur < 210) $widthrecbox=84;	// To work with US executive format
1808
			$posy=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
1809
			$posy+=$top_shift;
1810
			$posx=$this->page_largeur-$this->marge_droite-$widthrecbox;
1811
			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
1812
1813
			// Show recipient frame
1814
			$pdf->SetTextColor(0, 0, 0);
1815
			$pdf->SetFont('', '', $default_font_size - 2);
1816
			$pdf->SetXY($posx+2, $posy-5);
1817
			$pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":", 0, 'L');
1818
			$pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
1819
1820
			// Show recipient name
1821
			$pdf->SetXY($posx+2, $posy+3);
1822
			$pdf->SetFont('', 'B', $default_font_size);
1823
			$pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L');
1824
1825
			$posy = $pdf->getY();
1826
1827
			// Show recipient information
1828
			$pdf->SetFont('', '', $default_font_size - 1);
1829
			$pdf->SetXY($posx+2, $posy);
1830
			$pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
1831
		}
1832
1833
		$pdf->SetTextColor(0, 0, 0);
1834
		return $top_shift;
1835
	}
1836
1837
	/**
1838
	 *   	Show footer of page. Need this->emetteur object
1839
     *
1840
	 *   	@param	PDF			$pdf     			PDF
1841
	 * 		@param	Object		$object				Object to show
1842
	 *      @param	Translate	$outputlangs		Object lang for output
1843
	 *      @param	int			$hidefreetext		1=Hide free text
1844
	 *      @return	int								Return height of bottom margin including footer text
1845
	 */
1846
	private function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1847
	{
1848
		global $conf;
1849
		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
1850
		return pdf_pagefoot($pdf, $outputlangs, 'INVOICE_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1851
	}
1852
1853
	/**
1854
	 *  Define Array Column Field
1855
	 *
1856
	 *  @param	object			$object    		common object
1857
	 *  @param	Translate		$outputlangs    langs
1858
     *  @param	int			   $hidedetails		Do not show line details
1859
     *  @param	int			   $hidedesc		Do not show desc
1860
     *  @param	int			   $hideref			Do not show ref
1861
     *  @return	null
1862
     */
1863
    public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1864
    {
1865
	    global $conf, $hookmanager;
1866
1867
	    // Default field style for content
1868
	    $this->defaultContentsFieldsStyle = array(
1869
	        'align' => 'R', // R,C,L
1870
	        'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1871
	    );
1872
1873
	    // Default field style for content
1874
	    $this->defaultTitlesFieldsStyle = array(
1875
	        'align' => 'C', // R,C,L
1876
	        'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1877
	    );
1878
1879
	    /*
1880
	     * For exemple
1881
	    $this->cols['theColKey'] = array(
1882
	        'rank' => $rank, // int : use for ordering columns
1883
	        'width' => 20, // the column width in mm
1884
	        'title' => array(
1885
	            'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1886
	            'label' => ' ', // the final label : used fore final generated text
1887
	            'align' => 'L', // text alignement :  R,C,L
1888
	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1889
	        ),
1890
	        'content' => array(
1891
	            'align' => 'L', // text alignement :  R,C,L
1892
	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1893
	        ),
1894
	    );
1895
	    */
1896
1897
	    $rank=0; // do not use negative rank
1898
	    $this->cols['desc'] = array(
1899
	        'rank' => $rank,
1900
	        'width' => false, // only for desc
1901
	        'status' => true,
1902
	        'title' => array(
1903
	            'textkey' => 'Designation', // use lang key is usefull in somme case with module
1904
	            'align' => 'L',
1905
	            // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1906
	            // 'label' => ' ', // the final label
1907
	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1908
	        ),
1909
	        'content' => array(
1910
	            'align' => 'L',
1911
	        ),
1912
	    );
1913
1914
	    // PHOTO
1915
        $rank = $rank + 10;
1916
        $this->cols['photo'] = array(
1917
            'rank' => $rank,
1918
            'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
1919
            'status' => false,
1920
            'title' => array(
1921
                'textkey' => 'Photo',
1922
                'label' => ' '
1923
            ),
1924
            'content' => array(
1925
                'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1926
            ),
1927
            'border-left' => false, // remove left line separator
1928
        );
1929
1930
	    if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto))
1931
	    {
1932
	        $this->cols['photo']['status'] = true;
1933
	    }
1934
1935
1936
	    $rank = $rank + 10;
1937
	    $this->cols['vat'] = array(
1938
	        'rank' => $rank,
1939
	        'status' => false,
1940
	        'width' => 16, // in mm
1941
	        'title' => array(
1942
	            'textkey' => 'VAT'
1943
	        ),
1944
	        'border-left' => true, // add left line separator
1945
	    );
1946
1947
	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
1948
	    {
1949
	        $this->cols['vat']['status'] = true;
1950
	    }
1951
1952
	    $rank = $rank + 10;
1953
	    $this->cols['subprice'] = array(
1954
	        'rank' => $rank,
1955
	        'width' => 19, // in mm
1956
	        'status' => true,
1957
	        'title' => array(
1958
	            'textkey' => 'PriceUHT'
1959
	        ),
1960
	        'border-left' => true, // add left line separator
1961
	    );
1962
1963
	    $rank = $rank + 10;
1964
	    $this->cols['qty'] = array(
1965
	        'rank' => $rank,
1966
	        'width' => 16, // in mm
1967
	        'status' => true,
1968
	        'title' => array(
1969
	            'textkey' => 'Qty'
1970
	        ),
1971
	        'border-left' => true, // add left line separator
1972
	    );
1973
1974
	    $rank = $rank + 10;
1975
	    $this->cols['progress'] = array(
1976
	        'rank' => $rank,
1977
	        'width' => 19, // in mm
1978
	        'status' => false,
1979
	        'title' => array(
1980
	            'textkey' => 'Progress'
1981
	        ),
1982
	        'border-left' => true, // add left line separator
1983
	    );
1984
1985
	    if($this->situationinvoice)
1986
	    {
1987
	        $this->cols['progress']['status'] = true;
1988
	    }
1989
1990
	    $rank = $rank + 10;
1991
	    $this->cols['unit'] = array(
1992
	        'rank' => $rank,
1993
	        'width' => 11, // in mm
1994
	        'status' => false,
1995
	        'title' => array(
1996
	            'textkey' => 'Unit'
1997
	        ),
1998
	        'border-left' => true, // add left line separator
1999
	    );
2000
	    if($conf->global->PRODUCT_USE_UNITS){
2001
	        $this->cols['unit']['status'] = true;
2002
	    }
2003
2004
	    $rank = $rank + 10;
2005
	    $this->cols['discount'] = array(
2006
	        'rank' => $rank,
2007
	        'width' => 13, // in mm
2008
	        'status' => false,
2009
	        'title' => array(
2010
	            'textkey' => 'ReductionShort'
2011
	        ),
2012
	        'border-left' => true, // add left line separator
2013
	    );
2014
	    if ($this->atleastonediscount){
2015
	        $this->cols['discount']['status'] = true;
2016
	    }
2017
2018
	    $rank = $rank + 10;
2019
	    $this->cols['totalexcltax'] = array(
2020
	        'rank' => $rank,
2021
	        'width' => 26, // in mm
2022
	        'status' => true,
2023
	        'title' => array(
2024
	            'textkey' => 'TotalHT'
2025
	        ),
2026
	        'border-left' => true, // add left line separator
2027
	    );
2028
2029
2030
	    $parameters=array(
2031
	        'object' => $object,
2032
	        'outputlangs' => $outputlangs,
2033
	        'hidedetails' => $hidedetails,
2034
	        'hidedesc' => $hidedesc,
2035
	        'hideref' => $hideref
2036
	    );
2037
2038
	    $reshook=$hookmanager->executeHooks('defineColumnField', $parameters, $this);    // Note that $object may have been modified by hook
2039
	    if ($reshook < 0)
2040
	    {
2041
	        setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2042
	    }
2043
	    elseif (empty($reshook))
2044
	    {
2045
	        $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
2046
	    }
2047
	    else
2048
	    {
2049
	        $this->cols = $hookmanager->resArray;
2050
	    }
2051
	}
2052
}
2053