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