dolibarr 19.0.3
pdf_cyan.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2008 Raphael Bertrand <raphael.bertrand@resultic.fr>
5 * Copyright (C) 2010-2015 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
7 * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
8 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
10 * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 * or see https://www.gnu.org/
25 */
26
32require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
33require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
37
38
43{
47 public $db;
48
52 public $name;
53
57 public $description;
58
62 public $update_main_doc_field;
63
67 public $type;
68
73 public $version = 'dolibarr';
74
78 public $cols;
79
80
86 public function __construct($db)
87 {
88 global $langs, $mysoc;
89
90 // Translations
91 $langs->loadLangs(array("main", "bills"));
92
93 $this->db = $db;
94 $this->name = "cyan";
95 $this->description = $langs->trans('DocModelCyanDescription');
96 $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
97
98 // Dimension page
99 $this->type = 'pdf';
100 $formatarray = pdf_getFormat();
101 $this->page_largeur = $formatarray['width'];
102 $this->page_hauteur = $formatarray['height'];
103 $this->format = array($this->page_largeur, $this->page_hauteur);
104 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
105 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
106 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
107 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
108
109 $this->option_logo = 1; // Display logo
110 $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
111 $this->option_modereg = 1; // Display payment mode
112 $this->option_condreg = 1; // Display payment terms
113 $this->option_multilang = 1; // Available in several languages
114 $this->option_escompte = 0; // Displays if there has been a discount
115 $this->option_credit_note = 0; // Support credit notes
116 $this->option_freetext = 1; // Support add of a personalised text
117 $this->option_draft_watermark = 1; // Support add of a watermark on drafts
118 $this->watermark = '';
119
120 // Get source company
121 $this->emetteur = $mysoc;
122 if (empty($this->emetteur->country_code)) {
123 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
124 }
125
126 // Define position of columns
127 $this->posxdesc = $this->marge_gauche + 1; // used for notes ans other stuff
128
129
130 $this->tabTitleHeight = 5; // default height
131
132 // Use new system for position of columns, view $this->defineColumnField()
133
134 $this->tva = array();
135 $this->tva_array = array();
136 $this->localtax1 = array();
137 $this->localtax2 = array();
138 $this->atleastoneratenotnull = 0;
139 $this->atleastonediscount = 0;
140 }
141
142 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
154 public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
155 {
156 // phpcs:enable
157 global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
158
159 dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null'));
160
161 if (!is_object($outputlangs)) {
162 $outputlangs = $langs;
163 }
164 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
165 if (getDolGlobalString('MAIN_USE_FPDF')) {
166 $outputlangs->charset_output = 'ISO-8859-1';
167 }
168
169 // Load translation files required by page
170 $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
171
172 // Show Draft Watermark
173 if ($object->statut == $object::STATUS_DRAFT && getDolGlobalString('PROPALE_DRAFT_WATERMARK')) {
174 $this->watermark = getDolGlobalString('PROPALE_DRAFT_WATERMARK');
175 }
176
177 global $outputlangsbis;
178 $outputlangsbis = null;
179 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
180 $outputlangsbis = new Translate('', $conf);
181 $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
182 $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
183 }
184
185 $nblines = count($object->lines);
186
187 $hidetop = 0;
188 if (getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE')) {
189 $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE;
190 }
191
192 // Loop on each lines to detect if there is at least one image to show
193 $realpatharray = array();
194 $this->atleastonephoto = false;
195 if (getDolGlobalString('MAIN_GENERATE_PROPOSALS_WITH_PICTURE')) {
196 $objphoto = new Product($this->db);
197
198 for ($i = 0; $i < $nblines; $i++) {
199 if (empty($object->lines[$i]->fk_product)) {
200 continue;
201 }
202
203 $objphoto->fetch($object->lines[$i]->fk_product);
204 //var_dump($objphoto->ref);exit;
205 if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
206 $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
207 $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
208 } else {
209 $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product'); // default
210 $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
211 }
212
213 $arephoto = false;
214 foreach ($pdir as $midir) {
215 if (!$arephoto) {
216 if ($conf->entity != $objphoto->entity) {
217 $dir = $conf->product->multidir_output[$objphoto->entity].'/'.$midir; //Check repertories of current entities
218 } else {
219 $dir = $conf->product->dir_output.'/'.$midir; //Check repertory of the current product
220 }
221
222 foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
223 if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES')) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
224 if ($obj['photo_vignette']) {
225 $filename = $obj['photo_vignette'];
226 } else {
227 $filename = $obj['photo'];
228 }
229 } else {
230 $filename = $obj['photo'];
231 }
232
233 $realpath = $dir.$filename;
234 $arephoto = true;
235 $this->atleastonephoto = true;
236 }
237 }
238 }
239
240 if ($realpath && $arephoto) {
241 $realpatharray[$i] = $realpath;
242 }
243 }
244 }
245
246 if (count($realpatharray) == 0) {
247 $this->posxpicture = $this->posxtva;
248 }
249
250 if ($conf->propal->multidir_output[$conf->entity]) {
251 $object->fetch_thirdparty();
252
253 $deja_regle = 0;
254
255 // Definition of $dir and $file
256 if ($object->specimen) {
257 $dir = $conf->propal->multidir_output[$conf->entity];
258 $file = $dir."/SPECIMEN.pdf";
259 } else {
260 $objectref = dol_sanitizeFileName($object->ref);
261 $dir = $conf->propal->multidir_output[$object->entity]."/".$objectref;
262 $file = $dir."/".$objectref.".pdf";
263 }
264
265 if (!file_exists($dir)) {
266 if (dol_mkdir($dir) < 0) {
267 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
268 return 0;
269 }
270 }
271
272 if (file_exists($dir)) {
273 // Add pdfgeneration hook
274 if (!is_object($hookmanager)) {
275 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
276 $hookmanager = new HookManager($this->db);
277 }
278 $hookmanager->initHooks(array('pdfgeneration'));
279 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
280 global $action;
281 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
282
283 // Set nblines with the new content of lines after hook
284 $nblines = count($object->lines);
285 //$nbpayments = count($object->getListOfPayments());
286
287 // Create pdf instance
288 $pdf = pdf_getInstance($this->format);
289 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
290 $pdf->SetAutoPageBreak(1, 0);
291
292 if (class_exists('TCPDF')) {
293 $pdf->setPrintHeader(false);
294 $pdf->setPrintFooter(false);
295 }
296 $pdf->SetFont(pdf_getPDFFont($outputlangs));
297 // Set path to the background PDF File
298 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
299 $logodir = $conf->mycompany->dir_output;
300 if (!empty($conf->mycompany->multidir_output[$object->entity])) {
301 $logodir = $conf->mycompany->multidir_output[$object->entity];
302 }
303 $pagecount = $pdf->setSourceFile($logodir.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
304 $tplidx = $pdf->importPage(1);
305 }
306
307 $pdf->Open();
308 $pagenb = 0;
309 $pdf->SetDrawColor(128, 128, 128);
310
311 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
312 $pdf->SetSubject($outputlangs->transnoentities("PdfCommercialProposalTitle"));
313 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
314 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
315 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfCommercialProposalTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
316 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
317 $pdf->SetCompression(false);
318 }
319
320 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
321
322 // Set $this->atleastonediscount if you have at least one discount
323 for ($i = 0; $i < $nblines; $i++) {
324 if ($object->lines[$i]->remise_percent) {
325 $this->atleastonediscount++;
326 }
327 }
328
329
330 // New page
331 $pdf->AddPage();
332 if (!empty($tplidx)) {
333 $pdf->useTemplate($tplidx);
334 }
335 $pagenb++;
336
337 $heightforinfotot = 40; // Height reserved to output the info and total part
338 $heightforsignature = !getDolGlobalString('PROPAL_DISABLE_SIGNATURE') ? (pdfGetHeightForHtmlContent($pdf, $outputlangs->transnoentities("ProposalCustomerSignature")) + 10) : 0;
339 $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
340 $heightforfooter = $this->marge_basse + (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS') ? 12 : 22); // Height reserved to output the footer (value include bottom margin)
341 //print $heightforinfotot + $heightforsignature + $heightforfreetext + $heightforfooter;exit;
342
343 $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis);
344 $pdf->SetFont('', '', $default_font_size - 1);
345 $pdf->MultiCell(0, 3, ''); // Set interline to 3
346 $pdf->SetTextColor(0, 0, 0);
347
348
349 $tab_top = 90 + $top_shift;
350 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
351
352 $nexY = $tab_top;
353
354 // Incoterm
355 $height_incoterms = 0;
356 if (isModEnabled('incoterm')) {
357 $desc_incoterms = $object->getIncotermsForPDF();
358 if ($desc_incoterms) {
359 $tab_top -= 2;
360
361 $pdf->SetFont('', '', $default_font_size - 1);
362 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
363 $nexY = max($pdf->GetY(), $nexY);
364 $height_incoterms = $nexY - $tab_top;
365
366 // Rect takes a length in 3rd parameter
367 $pdf->SetDrawColor(192, 192, 192);
368 $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1);
369
370 $tab_top = $nexY + 6;
371 $height_incoterms += 4;
372 }
373 }
374
375 // Displays notes
376 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
377 if (getDolGlobalString('MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE')) {
378 // Get first sale rep
379 if (is_object($object->thirdparty)) {
380 $salereparray = $object->thirdparty->getSalesRepresentatives($user);
381 $salerepobj = new User($this->db);
382 $salerepobj->fetch($salereparray[0]['id']);
383 if (!empty($salerepobj->signature)) {
384 $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
385 }
386 }
387 }
388
389 // Extrafields in note
390 $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
391 if (!empty($extranote)) {
392 $notetoshow = dol_concatdesc($notetoshow, $extranote);
393 }
394
395 if (getDolGlobalString('MAIN_ADD_CREATOR_IN_NOTE') && $object->user_author_id > 0) {
396 $tmpuser = new User($this->db);
397 $tmpuser->fetch($object->user_author_id);
398
399 $creator_info = $langs->trans("CaseFollowedBy").' '.$tmpuser->getFullName($langs);
400 if ($tmpuser->email) {
401 $creator_info .= ', '.$langs->trans("EMail").': '.$tmpuser->email;
402 }
403 if ($tmpuser->office_phone) {
404 $creator_info .= ', '.$langs->trans("Phone").': '.$tmpuser->office_phone;
405 }
406
407 $notetoshow = dol_concatdesc($notetoshow, $creator_info);
408 }
409
410 $tab_height = $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter;
411
412 $pagenb = $pdf->getPage();
413 if ($notetoshow) {
414 $tab_top -= 2;
415
416 $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
417 $pageposbeforenote = $pagenb;
418
419 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
420 complete_substitutions_array($substitutionarray, $outputlangs, $object);
421 $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
422 $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
423
424 $pdf->startTransaction();
425
426 $pdf->SetFont('', '', $default_font_size - 1);
427 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
428 // Description
429 $pageposafternote = $pdf->getPage();
430 $posyafter = $pdf->GetY();
431
432 if ($pageposafternote > $pageposbeforenote) {
433 $pdf->rollbackTransaction(true);
434
435 // prepare pages to receive notes
436 while ($pagenb < $pageposafternote) {
437 $pdf->AddPage();
438 $pagenb++;
439 if (!empty($tplidx)) {
440 $pdf->useTemplate($tplidx);
441 }
442 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
443 $this->_pagehead($pdf, $object, 0, $outputlangs);
444 }
445 // $this->_pagefoot($pdf,$object,$outputlangs,1);
446 $pdf->setTopMargin($tab_top_newpage);
447 // The only function to edit the bottom margin of current page to set it.
448 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
449 }
450
451 // back to start
452 $pdf->setPage($pageposbeforenote);
453 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
454 $pdf->SetFont('', '', $default_font_size - 1);
455 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
456 $pageposafternote = $pdf->getPage();
457
458 $posyafter = $pdf->GetY();
459
460 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text
461 $pdf->AddPage('', '', true);
462 $pagenb++;
463 $pageposafternote++;
464 $pdf->setPage($pageposafternote);
465 $pdf->setTopMargin($tab_top_newpage);
466 // The only function to edit the bottom margin of current page to set it.
467 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
468 //$posyafter = $tab_top_newpage;
469 }
470
471
472 // apply note frame to previous pages
473 $i = $pageposbeforenote;
474 while ($i < $pageposafternote) {
475 $pdf->setPage($i);
476
477
478 $pdf->SetDrawColor(128, 128, 128);
479 // Draw note frame
480 if ($i > $pageposbeforenote) {
481 $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
482 $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
483 } else {
484 $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
485 $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
486 }
487
488 // Add footer
489 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
490 $this->_pagefoot($pdf, $object, $outputlangs, 1);
491
492 $i++;
493 }
494
495 // apply note frame to last page
496 $pdf->setPage($pageposafternote);
497 if (!empty($tplidx)) {
498 $pdf->useTemplate($tplidx);
499 }
500 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
501 $this->_pagehead($pdf, $object, 0, $outputlangs);
502 }
503 $height_note = $posyafter - $tab_top_newpage;
504 $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
505 } else {
506 // No pagebreak
507 $pdf->commitTransaction();
508 $posyafter = $pdf->GetY();
509 $height_note = $posyafter - $tab_top;
510 $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
511
512
513 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
514 // not enough space, need to add page
515 $pdf->AddPage('', '', true);
516 $pagenb++;
517 $pageposafternote++;
518 $pdf->setPage($pageposafternote);
519 if (!empty($tplidx)) {
520 $pdf->useTemplate($tplidx);
521 }
522 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
523 $this->_pagehead($pdf, $object, 0, $outputlangs);
524 }
525
526 $posyafter = $tab_top_newpage;
527 }
528 }
529 $tab_height = $tab_height - $height_note;
530 $tab_top = $posyafter + 6;
531 } else {
532 $height_note = 0;
533 }
534
535 // Use new auto column system
536 $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
537
538 // Table simulation to know the height of the title line
539 $pdf->startTransaction();
540 $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
541 $pdf->rollbackTransaction(true);
542
543 $nexY = $tab_top + $this->tabTitleHeight;
544
545 // Loop on each lines
546 $pageposbeforeprintlines = $pdf->getPage();
547 $pagenb = $pageposbeforeprintlines;
548 for ($i = 0; $i < $nblines; $i++) {
549 $curY = $nexY;
550 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
551 $pdf->SetTextColor(0, 0, 0);
552
553 // Define size of image if we need it
554 $imglinesize = array();
555 if (!empty($realpatharray[$i])) {
556 $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
557 }
558
559 $pdf->setTopMargin($tab_top_newpage);
560 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
561 $pageposbefore = $pdf->getPage();
562
563 $showpricebeforepagebreak = 1;
564 $posYAfterImage = 0;
565 $posYAfterDescription = 0;
566
567 if ($this->getColumnStatus('photo')) {
568 // We start with Photo of product line
569 if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot))) { // If photo too high, we moved completely on new page
570 $pdf->AddPage('', '', true);
571 if (!empty($tplidx)) {
572 $pdf->useTemplate($tplidx);
573 }
574 $pdf->setPage($pageposbefore + 1);
575
576 $curY = $tab_top_newpage;
577
578 // Allows data in the first page if description is long enough to break in multiples pages
579 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
580 $showpricebeforepagebreak = 1;
581 } else {
582 $showpricebeforepagebreak = 0;
583 }
584 }
585
586
587 if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) {
588 $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
589 // $pdf->Image does not increase value return by getY, so we save it manually
590 $posYAfterImage = $curY + $imglinesize['height'];
591 }
592 }
593
594 // Description of product line
595 if ($this->getColumnStatus('desc')) {
596 $pdf->startTransaction();
597
598 $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
599 $pageposafter = $pdf->getPage();
600
601 if ($pageposafter > $pageposbefore) { // There is a pagebreak
602 $pdf->rollbackTransaction(true);
603
604 $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
605
606 $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
607
608 $pageposafter = $pdf->getPage();
609 $posyafter = $pdf->GetY();
610 //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
611 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot))) { // There is no space left for total+free text
612 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
613 $pdf->AddPage('', '', true);
614 if (!empty($tplidx)) {
615 $pdf->useTemplate($tplidx);
616 }
617 $pdf->setPage($pageposafter + 1);
618 }
619 } else {
620 // We found a page break
621 // Allows data in the first page if description is long enough to break in multiples pages
622 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
623 $showpricebeforepagebreak = 1;
624 } else {
625 $showpricebeforepagebreak = 0;
626 }
627 }
628 } else { // No pagebreak
629 $pdf->commitTransaction();
630 }
631 $posYAfterDescription = $pdf->GetY();
632 }
633
634 $nexY = $pdf->GetY();
635 $pageposafter = $pdf->getPage();
636
637 $pdf->setPage($pageposbefore);
638 $pdf->setTopMargin($this->marge_haute);
639 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
640
641 // We suppose that a too long description or photo were moved completely on next page
642 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
643 $pdf->setPage($pageposafter);
644 $curY = $tab_top_newpage;
645 }
646
647 $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font
648
649 // VAT Rate
650 if ($this->getColumnStatus('vat')) {
651 $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
652 $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
653 $nexY = max($pdf->GetY(), $nexY);
654 }
655
656 // Unit price before discount
657 if ($this->getColumnStatus('subprice')) {
658 $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
659 $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
660 $nexY = max($pdf->GetY(), $nexY);
661 }
662
663 // Quantity
664 // Enough for 6 chars
665 if ($this->getColumnStatus('qty')) {
666 $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
667 $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
668 $nexY = max($pdf->GetY(), $nexY);
669 }
670
671
672 // Unit
673 if ($this->getColumnStatus('unit')) {
674 $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
675 $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
676 $nexY = max($pdf->GetY(), $nexY);
677 }
678
679 // Discount on line
680 if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) {
681 $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
682 $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
683 $nexY = max($pdf->GetY(), $nexY);
684 }
685
686 // Total excl tax line (HT)
687 if ($this->getColumnStatus('totalexcltax')) {
688 $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
689 $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
690 $nexY = max($pdf->GetY(), $nexY);
691 }
692
693 // Total with tax line (TTC)
694 if ($this->getColumnStatus('totalincltax')) {
695 $total_incl_tax = pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails);
696 $this->printStdColumnContent($pdf, $curY, 'totalincltax', $total_incl_tax);
697 $nexY = max($pdf->GetY(), $nexY);
698 }
699
700 // Extrafields
701 if (!empty($object->lines[$i]->array_options)) {
702 foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
703 if ($this->getColumnStatus($extrafieldColKey)) {
704 $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs);
705 $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
706 $nexY = max($pdf->GetY(), $nexY);
707 }
708 }
709 }
710
711 $parameters = array(
712 'object' => $object,
713 'i' => $i,
714 'pdf' =>& $pdf,
715 'curY' =>& $curY,
716 'nexY' =>& $nexY,
717 'outputlangs' => $outputlangs,
718 'hidedetails' => $hidedetails
719 );
720 $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook
721
722
723 // Collection of totals by value of vat in $this->tva["rate"] = total_tva
724 if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) {
725 $tvaligne = $object->lines[$i]->multicurrency_total_tva;
726 } else {
727 $tvaligne = $object->lines[$i]->total_tva;
728 }
729
730 $localtax1ligne = $object->lines[$i]->total_localtax1;
731 $localtax2ligne = $object->lines[$i]->total_localtax2;
732 $localtax1_rate = $object->lines[$i]->localtax1_tx;
733 $localtax2_rate = $object->lines[$i]->localtax2_tx;
734 $localtax1_type = $object->lines[$i]->localtax1_type;
735 $localtax2_type = $object->lines[$i]->localtax2_type;
736
737 // TODO remise_percent is an obsolete field for object parent
738 /*if ($object->remise_percent) {
739 $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
740 }
741 if ($object->remise_percent) {
742 $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
743 }
744 if ($object->remise_percent) {
745 $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
746 }*/
747
748 $vatrate = (string) $object->lines[$i]->tva_tx;
749
750 // Retrieve type from database for backward compatibility with old records
751 if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
752 && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
753 $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
754 $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
755 $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
756 }
757
758 // retrieve global local tax
759 if ($localtax1_type && $localtax1ligne != 0) {
760 if (empty($this->localtax1[$localtax1_type][$localtax1_rate])) {
761 $this->localtax1[$localtax1_type][$localtax1_rate] = $localtax1ligne;
762 } else {
763 $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
764 }
765 }
766 if ($localtax2_type && $localtax2ligne != 0) {
767 if (empty($this->localtax2[$localtax2_type][$localtax2_rate])) {
768 $this->localtax2[$localtax2_type][$localtax2_rate] = $localtax2ligne;
769 } else {
770 $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
771 }
772 }
773
774 if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
775 $vatrate .= '*';
776 }
777
778 // Fill $this->tva and $this->tva_array
779 if (!isset($this->tva[$vatrate])) {
780 $this->tva[$vatrate] = 0;
781 }
782 $this->tva[$vatrate] += $tvaligne;
783 $vatcode = $object->lines[$i]->vat_src_code;
784 if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
785 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
786 }
787 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate'=>$vatrate, 'vatcode'=>$vatcode, 'amount'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
788
789 if ($posYAfterImage > $posYAfterDescription) {
790 $nexY = max($nexY, $posYAfterImage);
791 }
792
793 // Add line
794 if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) {
795 $pdf->setPage($pageposafter);
796 $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
797 //$pdf->SetDrawColor(190,190,200);
798 $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
799 $pdf->SetLineStyle(array('dash'=>0));
800 }
801
802 $nexY += 2; // Add space between lines
803
804 // Detect if some page were added automatically and output _tableau for past pages
805 while ($pagenb < $pageposafter) {
806 $pdf->setPage($pagenb);
807 if ($pagenb == $pageposbeforeprintlines) {
808 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
809 } else {
810 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
811 }
812 $this->_pagefoot($pdf, $object, $outputlangs, 1);
813 $pagenb++;
814 $pdf->setPage($pagenb);
815 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
816 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
817 $this->_pagehead($pdf, $object, 0, $outputlangs);
818 }
819 if (!empty($tplidx)) {
820 $pdf->useTemplate($tplidx);
821 }
822 }
823
824 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
825 if ($pagenb == $pageposafter) {
826 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
827 } else {
828 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
829 }
830 $this->_pagefoot($pdf, $object, $outputlangs, 1);
831 // New page
832 $pdf->AddPage();
833 if (!empty($tplidx)) {
834 $pdf->useTemplate($tplidx);
835 }
836 $pagenb++;
837 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
838 $this->_pagehead($pdf, $object, 0, $outputlangs);
839 }
840 }
841 }
842
843 // Show square
844 if ($pagenb == $pageposbeforeprintlines) {
845 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis);
846 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
847 } else {
848 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis);
849 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
850 }
851
852 // Display infos area
853 $posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
854
855 // Display total zone
856 $posy = $this->drawTotalTable($pdf, $object, 0, $bottomlasttab, $outputlangs);
857
858 // Customer signature area
859 if (!getDolGlobalString('PROPAL_DISABLE_SIGNATURE')) {
860 $posy = $this->drawSignatureArea($pdf, $object, $posy, $outputlangs);
861 }
862
863 // Pagefoot
864 $this->_pagefoot($pdf, $object, $outputlangs);
865 if (method_exists($pdf, 'AliasNbPages')) {
866 $pdf->AliasNbPages();
867 }
868
869 //If propal merge product PDF is active
870 if (getDolGlobalString('PRODUIT_PDF_MERGE_PROPAL')) {
871 require_once DOL_DOCUMENT_ROOT.'/product/class/propalmergepdfproduct.class.php';
872
873 $already_merged = array();
874 foreach ($object->lines as $line) {
875 if (!empty($line->fk_product) && !(in_array($line->fk_product, $already_merged))) {
876 // Find the desire PDF
877 $filetomerge = new Propalmergepdfproduct($this->db);
878
879 if (getDolGlobalInt('MAIN_MULTILANGS')) {
880 $filetomerge->fetch_by_product($line->fk_product, $outputlangs->defaultlang);
881 } else {
882 $filetomerge->fetch_by_product($line->fk_product);
883 }
884
885 $already_merged[] = $line->fk_product;
886
887 $product = new Product($this->db);
888 $product->fetch($line->fk_product);
889
890 if ($product->entity != $conf->entity) {
891 $entity_product_file = $product->entity;
892 } else {
893 $entity_product_file = $conf->entity;
894 }
895
896 // If PDF is selected and file is not empty
897 if (count($filetomerge->lines) > 0) {
898 foreach ($filetomerge->lines as $linefile) {
899 if (!empty($linefile->id) && !empty($linefile->file_name)) {
900 if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
901 if (isModEnabled("product")) {
902 $filetomerge_dir = $conf->product->multidir_output[$entity_product_file].'/'.get_exdir($product->id, 2, 0, 0, $product, 'product').$product->id."/photos";
903 } elseif (isModEnabled("service")) {
904 $filetomerge_dir = $conf->service->multidir_output[$entity_product_file].'/'.get_exdir($product->id, 2, 0, 0, $product, 'product').$product->id."/photos";
905 }
906 } else {
907 if (isModEnabled("product")) {
908 $filetomerge_dir = $conf->product->multidir_output[$entity_product_file].'/'.get_exdir(0, 0, 0, 0, $product, 'product');
909 } elseif (isModEnabled("service")) {
910 $filetomerge_dir = $conf->service->multidir_output[$entity_product_file].'/'.get_exdir(0, 0, 0, 0, $product, 'product');
911 }
912 }
913
914 dol_syslog(get_class($this).':: upload_dir='.$filetomerge_dir, LOG_DEBUG);
915
916 $infile = $filetomerge_dir.'/'.$linefile->file_name;
917 if (file_exists($infile) && is_readable($infile)) {
918 $pagecount = $pdf->setSourceFile($infile);
919 for ($i = 1; $i <= $pagecount; $i++) {
920 $tplIdx = $pdf->importPage($i);
921 if ($tplIdx !== false) {
922 $s = $pdf->getTemplatesize($tplIdx);
923 $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
924 $pdf->useTemplate($tplIdx);
925 } else {
926 setEventMessages(null, array($infile.' cannot be added, probably protected PDF'), 'warnings');
927 }
928 }
929 }
930 }
931 }
932 }
933 }
934 }
935 }
936
937 $pdf->Close();
938
939 $pdf->Output($file, 'F');
940
941 //Add pdfgeneration hook
942 $hookmanager->initHooks(array('pdfgeneration'));
943 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
944 global $action;
945 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
946 if ($reshook < 0) {
947 $this->error = $hookmanager->error;
948 $this->errors = $hookmanager->errors;
949 }
950
951 dolChmod($file);
952
953 $this->result = array('fullpath'=>$file);
954
955 return 1; // No error
956 } else {
957 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
958 return 0;
959 }
960 } else {
961 $this->error = $langs->trans("ErrorConstantNotDefined", "PROP_OUTPUTDIR");
962 return 0;
963 }
964 }
965
975 public function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
976 {
977 global $conf, $mysoc;
978 $default_font_size = pdf_getPDFFontSize($outputlangs);
979
980 $pdf->SetFont('', '', $default_font_size - 1);
981
982 $diffsizetitle = (!getDolGlobalString('PDF_DIFFSIZE_TITLE') ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
983
984 // If France, show VAT mention if not applicable
985 if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
986 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
987 $pdf->SetXY($this->marge_gauche, $posy);
988 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
989
990 $posy = $pdf->GetY() + 4;
991 }
992
993 $posxval = 52;
994 if (getDolGlobalString('MAIN_PDF_DATE_TEXT')) {
995 $displaydate = "daytext";
996 } else {
997 $displaydate = "day";
998 }
999
1000 // Show shipping date
1001 if (!empty($object->delivery_date)) {
1002 $outputlangs->load("sendings");
1003 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1004 $pdf->SetXY($this->marge_gauche, $posy);
1005 $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
1006 $pdf->MultiCell(80, 4, $titre, 0, 'L');
1007 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1008 $pdf->SetXY($posxval, $posy);
1009 $dlp = dol_print_date($object->delivery_date, $displaydate, false, $outputlangs, true);
1010 $pdf->MultiCell(80, 4, $dlp, 0, 'L');
1011
1012 $posy = $pdf->GetY() + 1;
1013 } elseif ($object->availability_code || $object->availability) { // Show availability conditions
1014 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1015 $pdf->SetXY($this->marge_gauche, $posy);
1016 $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
1017 $pdf->MultiCell(80, 4, $titre, 0, 'L');
1018 $pdf->SetTextColor(0, 0, 0);
1019 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1020 $pdf->SetXY($posxval, $posy);
1021 $lib_availability = ($outputlangs->transnoentities("AvailabilityType".$object->availability_code) != 'AvailabilityType'.$object->availability_code) ? $outputlangs->transnoentities("AvailabilityType".$object->availability_code) : $outputlangs->convToOutputCharset($object->availability);
1022 $lib_availability = str_replace('\n', "\n", $lib_availability);
1023 $pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
1024
1025 $posy = $pdf->GetY() + 1;
1026 }
1027
1028 // Show delivery mode
1029 if (!getDolGlobalString('PROPOSAL_PDF_HIDE_DELIVERYMODE') && $object->shipping_method_id > 0) {
1030 $outputlangs->load("sendings");
1031
1032 $shipping_method_id = $object->shipping_method_id;
1033 if (getDolGlobalString('SOCIETE_ASK_FOR_SHIPPING_METHOD') && !empty($this->emetteur->shipping_method_id)) {
1034 $shipping_method_id = $this->emetteur->shipping_method_id;
1035 }
1036 $shipping_method_code = dol_getIdFromCode($this->db, $shipping_method_id, 'c_shipment_mode', 'rowid', 'code');
1037 $shipping_method_label = dol_getIdFromCode($this->db, $shipping_method_id, 'c_shipment_mode', 'rowid', 'libelle');
1038
1039 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1040 $pdf->SetXY($this->marge_gauche, $posy);
1041 $titre = $outputlangs->transnoentities("SendingMethod").':';
1042 $pdf->MultiCell(43, 4, $titre, 0, 'L');
1043
1044 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1045 $pdf->SetXY($posxval, $posy);
1046 $lib_condition_paiement = ($outputlangs->transnoentities("SendingMethod".strtoupper($shipping_method_code)) != "SendingMethod".strtoupper($shipping_method_code)) ? $outputlangs->trans("SendingMethod".strtoupper($shipping_method_code)) : $shipping_method_label;
1047 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
1048 $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
1049
1050 $posy = $pdf->GetY() + 1;
1051 }
1052
1053 // Show payments conditions
1054 if (!getDolGlobalString('PROPOSAL_PDF_HIDE_PAYMENTTERM') && $object->cond_reglement_code) {
1055 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1056 $pdf->SetXY($this->marge_gauche, $posy);
1057 $titre = $outputlangs->transnoentities("PaymentConditions").':';
1058 $pdf->MultiCell(43, 4, $titre, 0, 'L');
1059
1060 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1061 $pdf->SetXY($posxval, $posy);
1062 $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 ? $object->cond_reglement_doc : $object->cond_reglement_label);
1063 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
1064 if ($object->deposit_percent > 0) {
1065 $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', $object->deposit_percent, $lib_condition_paiement);
1066 }
1067 $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
1068
1069 $posy = $pdf->GetY() + 3;
1070 }
1071
1072 if (!getDolGlobalString('PROPOSAL_PDF_HIDE_PAYMENTMODE')) {
1073 // Show payment mode
1074 if ($object->mode_reglement_code
1075 && $object->mode_reglement_code != 'CHQ'
1076 && $object->mode_reglement_code != 'VIR') {
1077 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1078 $pdf->SetXY($this->marge_gauche, $posy);
1079 $titre = $outputlangs->transnoentities("PaymentMode").':';
1080 $pdf->MultiCell(80, 5, $titre, 0, 'L');
1081 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1082 $pdf->SetXY($posxval, $posy);
1083 $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);
1084 $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
1085
1086 $posy = $pdf->GetY() + 2;
1087 }
1088
1089 // Show payment mode CHQ
1090 if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') {
1091 // Si mode reglement non force ou si force a CHQ
1092 if (getDolGlobalInt('FACTURE_CHQ_NUMBER')) {
1093 if (getDolGlobalInt('FACTURE_CHQ_NUMBER') > 0) {
1094 $account = new Account($this->db);
1095 $account->fetch(getDolGlobalInt('FACTURE_CHQ_NUMBER'));
1096
1097 $pdf->SetXY($this->marge_gauche, $posy);
1098 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1099 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0);
1100 $posy = $pdf->GetY() + 1;
1101
1102 if (!getDolGlobalString('MAIN_PDF_HIDE_CHQ_ADDRESS')) {
1103 $pdf->SetXY($this->marge_gauche, $posy);
1104 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1105 $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
1106 $posy = $pdf->GetY() + 2;
1107 }
1108 }
1109 if (getDolGlobalInt('FACTURE_CHQ_NUMBER') == -1) {
1110 $pdf->SetXY($this->marge_gauche, $posy);
1111 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1112 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
1113 $posy = $pdf->GetY() + 1;
1114
1115 if (!getDolGlobalString('MAIN_PDF_HIDE_CHQ_ADDRESS')) {
1116 $pdf->SetXY($this->marge_gauche, $posy);
1117 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1118 $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
1119 $posy = $pdf->GetY() + 2;
1120 }
1121 }
1122 }
1123 }
1124
1125 // If payment mode not forced or forced to VIR, show payment with BAN
1126 if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') {
1127 if ($object->fk_account > 0 || $object->fk_bank > 0 || getDolGlobalInt('FACTURE_RIB_NUMBER')) {
1128 $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
1129 if ($object->fk_bank > 0) {
1130 $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
1131 }
1132 $account = new Account($this->db);
1133 $account->fetch($bankid);
1134
1135 $curx = $this->marge_gauche;
1136 $cury = $posy;
1137
1138 $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
1139
1140 $posy += 2;
1141 }
1142 }
1143 }
1144
1145 return $posy;
1146 }
1147
1148
1160 protected function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis = null)
1161 {
1162 global $conf, $mysoc, $hookmanager;
1163
1164 $default_font_size = pdf_getPDFFontSize($outputlangs);
1165
1166 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
1167 $outputlangsbis = new Translate('', $conf);
1168 $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
1169 $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
1170 $default_font_size--;
1171 }
1172
1173 $tab2_top = $posy;
1174 $tab2_hl = 4;
1175 $pdf->SetFont('', '', $default_font_size - 1);
1176
1177 // Total table
1178 $col1x = 120;
1179 $col2x = 170;
1180 if ($this->page_largeur < 210) { // To work with US executive format
1181 $col2x -= 20;
1182 }
1183 $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
1184
1185 $useborder = 0;
1186 $index = 0;
1187
1188 // Total HT
1189 $pdf->SetFillColor(255, 255, 255);
1190 $pdf->SetXY($col1x, $tab2_top);
1191 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1);
1192
1193 $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
1194 $pdf->SetXY($col2x, $tab2_top);
1195 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0), 0, $outputlangs), 0, 'R', 1);
1196
1197 // Show VAT by rates and total
1198 $pdf->SetFillColor(248, 248, 248);
1199
1200 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
1201
1202 $this->atleastoneratenotnull = 0;
1203 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
1204 $tvaisnull = ((!empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
1205 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL') && $tvaisnull) {
1206 // Nothing to do
1207 } else {
1208 //Local tax 1 before VAT
1209 //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1210 //{
1211 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1212 if (in_array((string) $localtax_type, array('1', '3', '5'))) {
1213 continue;
1214 }
1215
1216 foreach ($localtax_rate as $tvakey => $tvaval) {
1217 if ($tvakey != 0) { // On affiche pas taux 0
1218 //$this->atleastoneratenotnull++;
1219
1220 $index++;
1221 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1222
1223 $tvacompl = '';
1224 if (preg_match('/\*/', $tvakey)) {
1225 $tvakey = str_replace('*', '', $tvakey);
1226 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1227 }
1228 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1229 $totalvat .= ' ';
1230 $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1231 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1232
1233 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1234
1235 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1236 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1237 }
1238 }
1239 }
1240 //}
1241 //Local tax 2 before VAT
1242 //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1243 //{
1244 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1245 if (in_array((string) $localtax_type, array('1', '3', '5'))) {
1246 continue;
1247 }
1248
1249 foreach ($localtax_rate as $tvakey => $tvaval) {
1250 if ($tvakey != 0) { // On affiche pas taux 0
1251 //$this->atleastoneratenotnull++;
1252
1253 $index++;
1254 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1255
1256 $tvacompl = '';
1257 if (preg_match('/\*/', $tvakey)) {
1258 $tvakey = str_replace('*', '', $tvakey);
1259 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1260 }
1261 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1262 $totalvat .= ' ';
1263 $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1264 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1265
1266 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1267
1268 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1269 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1270 }
1271 }
1272 }
1273 //}
1274
1275 // VAT
1276 foreach ($this->tva as $tvakey => $tvaval) {
1277 if ($tvakey != 0) { // On affiche pas taux 0
1278 $this->atleastoneratenotnull++;
1279
1280 $index++;
1281 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1282
1283 $tvacompl = '';
1284 if (preg_match('/\*/', $tvakey)) {
1285 $tvakey = str_replace('*', '', $tvakey);
1286 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1287 }
1288 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
1289 $totalvat .= ' ';
1290 $totalvat .= vatrate($tvakey, 1).$tvacompl;
1291 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1292
1293 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1294 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1295 }
1296 }
1297
1298 //Local tax 1 after VAT
1299 //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1300 //{
1301 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1302 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1303 continue;
1304 }
1305
1306 foreach ($localtax_rate as $tvakey => $tvaval) {
1307 if ($tvakey != 0) { // On affiche pas taux 0
1308 //$this->atleastoneratenotnull++;
1309
1310 $index++;
1311 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1312
1313 $tvacompl = '';
1314 if (preg_match('/\*/', $tvakey)) {
1315 $tvakey = str_replace('*', '', $tvakey);
1316 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1317 }
1318 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1319 $totalvat .= ' ';
1320
1321 $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1322 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1323
1324 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1325
1326 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1327 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1328 }
1329 }
1330 }
1331 //}
1332 //Local tax 2 after VAT
1333 //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1334 //{
1335 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1336 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1337 continue;
1338 }
1339
1340 foreach ($localtax_rate as $tvakey => $tvaval) {
1341 // retrieve global local tax
1342 if ($tvakey != 0) { // On affiche pas taux 0
1343 //$this->atleastoneratenotnull++;
1344
1345 $index++;
1346 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1347
1348 $tvacompl = '';
1349 if (preg_match('/\*/', $tvakey)) {
1350 $tvakey = str_replace('*', '', $tvakey);
1351 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1352 }
1353 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1354 $totalvat .= ' ';
1355
1356 $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1357 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1358
1359 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1360
1361 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1362 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1363 }
1364 }
1365 }
1366 //}
1367
1368 // Total TTC
1369 $index++;
1370 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1371 $pdf->SetTextColor(0, 0, 60);
1372 $pdf->SetFillColor(224, 224, 224);
1373 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalTTC") : ''), $useborder, 'L', 1);
1374
1375 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1376 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
1377 }
1378 }
1379
1380 $pdf->SetTextColor(0, 0, 0);
1381
1382 $resteapayer = 0;
1383 /*
1384 $resteapayer = $object->total_ttc - $deja_regle;
1385 if (!empty($object->paye)) $resteapayer=0;
1386 */
1387
1388 if ($deja_regle > 0) {
1389 // Already paid + Deposits
1390 $index++;
1391
1392 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1393 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), 0, 'L', 0);
1394
1395 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1396 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
1397
1398 /*
1399 if ($object->close_code == 'discount_vat')
1400 {
1401 $index++;
1402 $pdf->SetFillColor(255,255,255);
1403
1404 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1405 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1);
1406
1407 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1408 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle, 0, $outputlangs), $useborder, 'R', 1);
1409
1410 $resteapayer=0;
1411 }
1412 */
1413
1414 $index++;
1415 $pdf->SetTextColor(0, 0, 60);
1416 $pdf->SetFillColor(224, 224, 224);
1417 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1418 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RemainderToPay") : ''), $useborder, 'L', 1);
1419
1420 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1421 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
1422
1423 $pdf->SetFont('', '', $default_font_size - 1);
1424 $pdf->SetTextColor(0, 0, 0);
1425 }
1426
1427 $index++;
1428 return ($tab2_top + ($tab2_hl * $index));
1429 }
1430
1431 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1446 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
1447 {
1448 global $conf;
1449
1450 // Force to disable hidetop and hidebottom
1451 $hidebottom = 0;
1452 if ($hidetop) {
1453 $hidetop = -1;
1454 }
1455
1456 $currency = !empty($currency) ? $currency : $conf->currency;
1457 $default_font_size = pdf_getPDFFontSize($outputlangs);
1458
1459 // Amount in (at tab_top - 1)
1460 $pdf->SetTextColor(0, 0, 0);
1461 $pdf->SetFont('', '', $default_font_size - 2);
1462
1463 if (empty($hidetop)) {
1464 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1465 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && is_object($outputlangsbis)) {
1466 $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency));
1467 }
1468
1469 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1470 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1471
1472 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1473 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
1474 $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')));
1475 }
1476 }
1477
1478 $pdf->SetDrawColor(128, 128, 128);
1479 $pdf->SetFont('', '', $default_font_size - 1);
1480
1481 // Output Rect
1482 $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
1483
1484 if (getDolGlobalString('MAIN_PDF_TITLE_TEXT_COLOR')) {
1485 $arrayColorTextTitle = explode(',', getDolGlobalString('MAIN_PDF_TITLE_TEXT_COLOR'));
1486 $pdf->SetTextColor($arrayColorTextTitle[0], $arrayColorTextTitle[1], $arrayColorTextTitle[2]);
1487 }
1488
1489 $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
1490
1491 if (getDolGlobalString('MAIN_PDF_TITLE_TEXT_COLOR')) {
1492 $pdf->SetTextColor(0, 0, 0);
1493 }
1494
1495 if (empty($hidetop)) {
1496 $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
1497 }
1498 }
1499
1500 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1511 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null)
1512 {
1513 global $conf, $langs;
1514
1515 $ltrdirection = 'L';
1516 if ($outputlangs->trans("DIRECTION") == 'rtl') {
1517 $ltrdirection = 'R';
1518 }
1519
1520 // Load traductions files required by page
1521 $outputlangs->loadLangs(array("main", "propal", "companies", "bills"));
1522
1523 $default_font_size = pdf_getPDFFontSize($outputlangs);
1524
1525 pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
1526
1527 $pdf->SetTextColor(0, 0, 60);
1528 $pdf->SetFont('', 'B', $default_font_size + 3);
1529
1530 $w = 100;
1531
1532 $posy = $this->marge_haute;
1533 $posx = $this->page_largeur - $this->marge_droite - $w;
1534
1535 $pdf->SetXY($this->marge_gauche, $posy);
1536
1537 // Logo
1538 if (!getDolGlobalInt('PDF_DISABLE_MYCOMPANY_LOGO')) {
1539 if ($this->emetteur->logo) {
1540 $logodir = $conf->mycompany->dir_output;
1541 if (!empty($conf->mycompany->multidir_output[$object->entity])) {
1542 $logodir = $conf->mycompany->multidir_output[$object->entity];
1543 }
1544 if (!getDolGlobalInt('MAIN_PDF_USE_LARGE_LOGO')) {
1545 $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1546 } else {
1547 $logo = $logodir.'/logos/'.$this->emetteur->logo;
1548 }
1549 if (is_readable($logo)) {
1550 $height = pdf_getHeightForLogo($logo);
1551 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1552 } else {
1553 $pdf->SetTextColor(200, 0, 0);
1554 $pdf->SetFont('', 'B', $default_font_size - 2);
1555 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1556 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1557 }
1558 } else {
1559 $text = $this->emetteur->name;
1560 $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
1561 }
1562 }
1563
1564 $pdf->SetFont('', 'B', $default_font_size + 3);
1565 $pdf->SetXY($posx, $posy);
1566 $pdf->SetTextColor(0, 0, 60);
1567 $title = $outputlangs->transnoentities("PdfCommercialProposalTitle");
1568 $title .= ' '.$outputlangs->convToOutputCharset($object->ref);
1569 if ($object->statut == $object::STATUS_DRAFT) {
1570 $pdf->SetTextColor(128, 0, 0);
1571 $title .= ' - '.$outputlangs->transnoentities("NotValidated");
1572 }
1573
1574 $pdf->MultiCell($w, 4, $title, '', 'R');
1575
1576 $pdf->SetFont('', 'B', $default_font_size);
1577
1578 /*
1579 $posy += 5;
1580 $pdf->SetXY($posx, $posy);
1581 $pdf->SetTextColor(0, 0, 60);
1582 $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref);
1583 if ($object->statut == $object::STATUS_DRAFT) {
1584 $pdf->SetTextColor(128, 0, 0);
1585 $textref .= ' - '.$outputlangs->transnoentities("NotValidated");
1586 }
1587 $pdf->MultiCell($w, 4, $textref, '', 'R');
1588 */
1589
1590 $posy += 3;
1591 $pdf->SetFont('', '', $default_font_size - 2);
1592
1593 if ($object->ref_client) {
1594 $posy += 4;
1595 $pdf->SetXY($posx, $posy);
1596 $pdf->SetTextColor(0, 0, 60);
1597 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".dol_trunc($outputlangs->convToOutputCharset($object->ref_client), 65), '', 'R');
1598 }
1599
1600 if (getDolGlobalString('PDF_SHOW_PROJECT_TITLE')) {
1601 $object->fetch_projet();
1602 if (!empty($object->project->ref)) {
1603 $posy += 3;
1604 $pdf->SetXY($posx, $posy);
1605 $pdf->SetTextColor(0, 0, 60);
1606 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1607 }
1608 }
1609
1610 if (getDolGlobalString('PDF_SHOW_PROJECT')) {
1611 $object->fetch_projet();
1612 if (!empty($object->project->ref)) {
1613 $outputlangs->load("projects");
1614 $posy += 3;
1615 $pdf->SetXY($posx, $posy);
1616 $pdf->SetTextColor(0, 0, 60);
1617 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1618 }
1619 }
1620
1621 if (getDolGlobalString('MAIN_PDF_DATE_TEXT')) {
1622 $displaydate = "daytext";
1623 } else {
1624 $displaydate = "day";
1625 }
1626
1627 //$posy += 4;
1628 $posy = $pdf->getY();
1629 $pdf->SetXY($posx, $posy);
1630 $pdf->SetTextColor(0, 0, 60);
1631 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Date")." : ".dol_print_date($object->date, $displaydate, false, $outputlangs, true), '', 'R');
1632
1633 $posy += 4;
1634 $pdf->SetXY($posx, $posy);
1635 $pdf->SetTextColor(0, 0, 60);
1636
1637 $title = $outputlangs->transnoentities("DateEndPropal");
1638 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && is_object($outputlangsbis)) {
1639 $title .= ' - '.$outputlangsbis->transnoentities("DateEndPropal");
1640 }
1641 $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->fin_validite, $displaydate, false, $outputlangs, true), '', 'R');
1642
1643 if (!getDolGlobalString('MAIN_PDF_HIDE_CUSTOMER_CODE') && $object->thirdparty->code_client) {
1644 $posy += 4;
1645 $pdf->SetXY($posx, $posy);
1646 $pdf->SetTextColor(0, 0, 60);
1647 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
1648 }
1649
1650 // Get contact
1651 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1652 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1653 if (count($arrayidcontact) > 0) {
1654 $usertmp = new User($this->db);
1655 $usertmp->fetch($arrayidcontact[0]);
1656 $posy += 4;
1657 $pdf->SetXY($posx, $posy);
1658 $pdf->SetTextColor(0, 0, 60);
1659 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
1660 }
1661 }
1662
1663 $posy += 2;
1664
1665 $top_shift = 0;
1666 // Show list of linked objects
1667 $current_y = $pdf->getY();
1668 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
1669 if ($current_y < $pdf->getY()) {
1670 $top_shift = $pdf->getY() - $current_y;
1671 }
1672
1673 if ($showaddress) {
1674 // Sender properties
1675 $carac_emetteur = '';
1676 // Add internal contact of object if defined
1677 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1678 if (count($arrayidcontact) > 0) {
1679 $object->fetch_user($arrayidcontact[0]);
1680 $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1681 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1682 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1683 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1684 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1685 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1686 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1687 $carac_emetteur .= "\n";
1688 }
1689
1690 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1691
1692 // Show sender
1693 $posy = getDolGlobalString('MAIN_PDF_USE_ISO_LOCATION') ? 40 : 42;
1694 $posy += $top_shift;
1695 $posx = $this->marge_gauche;
1696 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1697 $posx = $this->page_largeur - $this->marge_droite - 80;
1698 }
1699
1700 $hautcadre = getDolGlobalString('MAIN_PDF_USE_ISO_LOCATION') ? 38 : 40;
1701 $widthrecbox = getDolGlobalString('MAIN_PDF_USE_ISO_LOCATION') ? 92 : 82;
1702
1703 // Show sender frame
1704 if (!getDolGlobalString('MAIN_PDF_NO_SENDER_FRAME')) {
1705 $pdf->SetTextColor(0, 0, 0);
1706 $pdf->SetFont('', '', $default_font_size - 2);
1707 $pdf->SetXY($posx, $posy - 5);
1708 $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1709 $pdf->SetXY($posx, $posy);
1710 $pdf->SetFillColor(230, 230, 230);
1711 $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
1712 $pdf->SetTextColor(0, 0, 60);
1713 }
1714
1715 // Show sender name
1716 if (!getDolGlobalString('MAIN_PDF_HIDE_SENDER_NAME')) {
1717 $pdf->SetXY($posx + 2, $posy + 3);
1718 $pdf->SetFont('', 'B', $default_font_size);
1719 $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1720 $posy = $pdf->getY();
1721 }
1722
1723 // Show sender information
1724 $pdf->SetXY($posx + 2, $posy);
1725 $pdf->SetFont('', '', $default_font_size - 1);
1726 $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, $ltrdirection);
1727
1728
1729 // If CUSTOMER contact defined, we use it
1730 $usecontact = false;
1731 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1732 if (count($arrayidcontact) > 0) {
1733 $usecontact = true;
1734 $result = $object->fetch_contact($arrayidcontact[0]);
1735 }
1736
1737 // Recipient name
1738 if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || getDolGlobalString('MAIN_USE_COMPANY_NAME_OF_CONTACT')))) {
1739 $thirdparty = $object->contact;
1740 } else {
1741 $thirdparty = $object->thirdparty;
1742 }
1743
1744 $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1745
1746 $mode = 'target';
1747 $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, $mode, $object);
1748
1749 // Show recipient
1750 $widthrecbox = getDolGlobalString('MAIN_PDF_USE_ISO_LOCATION') ? 92 : 100;
1751 if ($this->page_largeur < 210) {
1752 $widthrecbox = 84; // To work with US executive format
1753 }
1754 $posy = getDolGlobalString('MAIN_PDF_USE_ISO_LOCATION') ? 40 : 42;
1755 $posy += $top_shift;
1756 $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1757 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1758 $posx = $this->marge_gauche;
1759 }
1760
1761 // Show recipient frame
1762 if (!getDolGlobalString('MAIN_PDF_NO_RECIPENT_FRAME')) {
1763 $pdf->SetTextColor(0, 0, 0);
1764 $pdf->SetFont('', '', $default_font_size - 2);
1765 $pdf->SetXY($posx + 2, $posy - 5);
1766 $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1767 $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
1768 }
1769
1770 // Show recipient name
1771 $pdf->SetXY($posx + 2, $posy + 3);
1772 $pdf->SetFont('', 'B', $default_font_size);
1773 $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, $ltrdirection);
1774
1775 $posy = $pdf->getY();
1776
1777 // Show recipient information
1778 $pdf->SetFont('', '', $default_font_size - 1);
1779 $pdf->SetXY($posx + 2, $posy);
1780 $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1781 }
1782
1783 $pdf->SetTextColor(0, 0, 0);
1784 return $top_shift;
1785 }
1786
1787 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1797 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1798 {
1799 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1800 return pdf_pagefoot($pdf, $outputlangs, 'PROPOSAL_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext, $this->page_largeur, $this->watermark);
1801 }
1802
1812 protected function drawSignatureArea(&$pdf, $object, $posy, $outputlangs)
1813 {
1814 $default_font_size = pdf_getPDFFontSize($outputlangs);
1815 $tab_top = $posy + 4;
1816 $tab_hl = 4;
1817
1818 $posx = 120;
1819 $largcol = ($this->page_largeur - $this->marge_droite - $posx);
1820
1821 // Total HT
1822 $pdf->SetFillColor(255, 255, 255);
1823 $pdf->SetXY($posx, $tab_top);
1824 $pdf->SetFont('', '', $default_font_size - 2);
1825 $pdf->MultiCell($largcol, $tab_hl, $outputlangs->transnoentities("ProposalCustomerSignature"), 0, 'L', 1);
1826
1827 $pdf->SetXY($posx, $tab_top + $tab_hl);
1828 $pdf->MultiCell($largcol, $tab_hl * 3, '', 1, 'R');
1829 if (getDolGlobalString('MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING')) {
1830 $pdf->addEmptySignatureAppearance($posx, $tab_top + $tab_hl, $largcol, $tab_hl * 3);
1831 }
1832
1833 return ($tab_hl * 7);
1834 }
1835
1836
1847 public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1848 {
1849 global $conf, $hookmanager;
1850
1851 // Default field style for content
1852 $this->defaultContentsFieldsStyle = array(
1853 'align' => 'R', // R,C,L
1854 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1855 );
1856
1857 // Default field style for content
1858 $this->defaultTitlesFieldsStyle = array(
1859 'align' => 'C', // R,C,L
1860 'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1861 );
1862
1863 /*
1864 * For exemple
1865 $this->cols['theColKey'] = array(
1866 'rank' => $rank, // int : use for ordering columns
1867 'width' => 20, // the column width in mm
1868 'title' => array(
1869 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1870 'label' => ' ', // the final label : used fore final generated text
1871 'align' => 'L', // text alignement : R,C,L
1872 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1873 ),
1874 'content' => array(
1875 'align' => 'L', // text alignement : R,C,L
1876 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1877 ),
1878 );
1879 */
1880
1881 $rank = 0; // do not use negative rank
1882 $this->cols['desc'] = array(
1883 'rank' => $rank,
1884 'width' => false, // only for desc
1885 'status' => true,
1886 'title' => array(
1887 'textkey' => 'Designation', // use lang key is usefull in somme case with module
1888 'align' => 'L',
1889 // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1890 // 'label' => ' ', // the final label
1891 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1892 ),
1893 'content' => array(
1894 'align' => 'L',
1895 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1896 ),
1897 );
1898
1899 // Image of product
1900 $rank = $rank + 10;
1901 $this->cols['photo'] = array(
1902 'rank' => $rank,
1903 'width' => (!getDolGlobalString('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH') ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
1904 'status' => false,
1905 'title' => array(
1906 'textkey' => 'Photo',
1907 'label' => ' '
1908 ),
1909 'content' => array(
1910 'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1911 ),
1912 'border-left' => false, // remove left line separator
1913 );
1914
1915 if (getDolGlobalString('MAIN_GENERATE_PROPOSALS_WITH_PICTURE') && !empty($this->atleastonephoto)) {
1916 $this->cols['photo']['status'] = true;
1917 $this->cols['photo']['border-left'] = true;
1918 }
1919
1920
1921 $rank = $rank + 10;
1922 $this->cols['vat'] = array(
1923 'rank' => $rank,
1924 'status' => false,
1925 'width' => 16, // in mm
1926 'title' => array(
1927 'textkey' => 'VAT'
1928 ),
1929 'border-left' => true, // add left line separator
1930 );
1931
1932 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
1933 $this->cols['vat']['status'] = true;
1934 }
1935
1936 $rank = $rank + 10;
1937 $this->cols['subprice'] = array(
1938 'rank' => $rank,
1939 'width' => 19, // in mm
1940 'status' => true,
1941 'title' => array(
1942 'textkey' => 'PriceUHT'
1943 ),
1944 'border-left' => true, // add left line separator
1945 );
1946
1947 // Adapt dynamically the width of subprice, if text is too long.
1948 $tmpwidth = 0;
1949 $nblines = count($object->lines);
1950 for ($i = 0; $i < $nblines; $i++) {
1951 $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails)));
1952 $tmpwidth = max($tmpwidth, $tmpwidth2);
1953 }
1954 if ($tmpwidth > 10) {
1955 $this->cols['subprice']['width'] += (2 * ($tmpwidth - 10));
1956 }
1957
1958 $rank = $rank + 10;
1959 $this->cols['qty'] = array(
1960 'rank' => $rank,
1961 'width' => 16, // in mm
1962 'status' => true,
1963 'title' => array(
1964 'textkey' => 'Qty'
1965 ),
1966 'border-left' => true, // add left line separator
1967 );
1968
1969 $rank = $rank + 10;
1970 $this->cols['unit'] = array(
1971 'rank' => $rank,
1972 'width' => 11, // in mm
1973 'status' => false,
1974 'title' => array(
1975 'textkey' => 'Unit'
1976 ),
1977 'border-left' => true, // add left line separator
1978 );
1979 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1980 $this->cols['unit']['status'] = true;
1981 }
1982
1983 $rank = $rank + 10;
1984 $this->cols['discount'] = array(
1985 'rank' => $rank,
1986 'width' => 13, // in mm
1987 'status' => false,
1988 'title' => array(
1989 'textkey' => 'ReductionShort'
1990 ),
1991 'border-left' => true, // add left line separator
1992 );
1993 if ($this->atleastonediscount) {
1994 $this->cols['discount']['status'] = true;
1995 }
1996
1997 $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
1998 $this->cols['totalexcltax'] = array(
1999 'rank' => $rank,
2000 'width' => 26, // in mm
2001 'status' => !getDolGlobalString('PDF_PROPAL_HIDE_PRICE_EXCL_TAX') ? true : false,
2002 'title' => array(
2003 'textkey' => 'TotalHTShort'
2004 ),
2005 'border-left' => true, // add left line separator
2006 );
2007
2008 $rank = $rank + 1010; // add a big offset to be sure is the last col because default extrafield rank is 100
2009 $this->cols['totalincltax'] = array(
2010 'rank' => $rank,
2011 'width' => 26, // in mm
2012 'status' => !getDolGlobalString('PDF_PROPAL_SHOW_PRICE_INCL_TAX') ? false : true,
2013 'title' => array(
2014 'textkey' => 'TotalTTCShort'
2015 ),
2016 'border-left' => true, // add left line separator
2017 );
2018
2019 // Add extrafields cols
2020 if (!empty($object->lines)) {
2021 $line = reset($object->lines);
2022 $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
2023 }
2024
2025 $parameters = array(
2026 'object' => $object,
2027 'outputlangs' => $outputlangs,
2028 'hidedetails' => $hidedetails,
2029 'hidedesc' => $hidedesc,
2030 'hideref' => $hideref
2031 );
2032
2033 $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
2034 if ($reshook < 0) {
2035 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2036 } elseif (empty($reshook)) {
2037 $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
2038 } else {
2039 $this->cols = $hookmanager->resArray;
2040 }
2041 }
2042}
Class to manage bank accounts.
prepareArrayColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Prepare Array Column Field.
getColumnStatus($colKey)
get column status from column key
printStdColumnContent($pdf, &$curY, $colKey, $columnText='')
print standard column content
pdfTabTitles(&$pdf, $tab_top, $tab_height, $outputlangs, $hidetop=0)
Print standard column content.
printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref=0, $hidedesc=0, $issupplierline=0)
print description column content
getColumnContentXStart($colKey)
get column content X (abscissa) left position from column key
printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
Rect pdf.
getExtrafieldContent($object, $extrafieldKey, $outputlangs=null)
get extrafield content for pdf writeHtmlCell compatibility usage for PDF line columns and object note...
defineColumnExtrafield($object, $outputlangs, $hidedetails=0)
Define Array Column Field for extrafields.
Class to manage hooks.
Classe mere des modeles de propale.
Class to manage products or services.
Put here description of your class.
Class to manage translations.
Class to manage Dolibarr users.
Class to generate PDF proposal Cyan.
drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis=null)
Show total to pay.
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='', $outputlangsbis=null)
Show table for lines.
__construct($db)
Constructor.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
_pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis=null)
Show top header of page.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
drawSignatureArea(&$pdf, $object, $posy, $outputlangs)
Show area for the customer to sign.
drawInfoTable(&$pdf, $object, $posy, $outputlangs)
Show miscellaneous information (payment mode, payment term, ...)
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!function_exists( 'dolEscapeXML')) convertBackOfficeMediasLinksToPublicLinks($notetoshow)
Convert links to local wrapper to medias files into a string into a public external URL readable on i...
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='')
Return an id or code from a code or id.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
pdf_getSizeForImage($realpath)
Return dimensions to use for images onto PDF checking that width and height are not higher than maxim...
Definition pdf.lib.php:2611
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2360
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:289
pdf_getFormat(Translate $outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:85
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:314
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition pdf.lib.php:2416
pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails=0, $hidefreetext=0, $page_largeur=0, $watermark='')
Show footer of page for PDF generation.
Definition pdf.lib.php:1014
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:1977
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:1915
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0, $hookmanager=false)
Return line unit.
Definition pdf.lib.php:2223
pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
Function to try to calculate height of a HTML Content.
Definition pdf.lib.php:339
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition pdf.lib.php:726
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1386
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank informations for PDF generation.
Definition pdf.lib.php:837
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:266
pdf_build_address($outputlangs, $sourcecompany, $targetcompany='', $targetcontact='', $usecontact=0, $mode='source', $object=null)
Return a string with full address formated for output on documents.
Definition pdf.lib.php:435
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2266
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2062
pdf_getSubstitutionArray($outputlangs, $exclude=null, $object=null, $onlykey=0, $include=null)
Return array of possible substitutions for PDF content (without external module substitutions).
Definition pdf.lib.php:762
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:127
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition pdf.lib.php:387
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:121
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:124