dolibarr 24.0.1
pdf.lib.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (C) 2006-2017 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
5 * Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com>
6 * Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2010-2017 Juanjo Menent <jmenent@2byte.es>
8 * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
9 * Copyright (C) 2012 Cédric Salvador <csalvador@gpcsolutions.fr>
10 * Copyright (C) 2012-2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
11 * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
12 * Copyright (C) 2014 Teddy Andreotti <125155@supinfo.com>
13 * Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
14 * Copyright (C) 2019 Lenin Rivas <lenin.rivas@servcom-it.com>
15 * Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com>
16 * Copyright (C) 2021-2022 Anthony Berton <anthony.berton@bb2a.fr>
17 * Copyright (C) 2023-2026 Frédéric France <frederic.france@free.fr>
18 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 3 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program. If not, see <https://www.gnu.org/licenses/>.
32 * or see https://www.gnu.org/
33 */
34
41include_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php';
42
43
50{
51 global $langs, $conf;
52
53 $h = 0;
54 $head = array();
55
56 $head[$h][0] = DOL_URL_ROOT.'/admin/pdf.php';
57 $head[$h][1] = $langs->trans("GlobalParameters");
58 $head[$h][2] = 'general';
59 $h++;
60
61 // Show more tabs from modules
62 // Entries must be declared in modules descriptor with line
63 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
64 // $this->tabs = array('entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to remove a tab
65 complete_head_from_modules($conf, $langs, null, $head, $h, 'pdf_admin');
66
67 if (isModEnabled("propal") || isModEnabled('invoice') || isModEnabled('reception')) {
68 $head[$h][0] = DOL_URL_ROOT.'/admin/pdf_other.php';
69 $head[$h][1] = $langs->trans("SpecificParameters");
70 $head[$h][2] = 'other';
71 $h++;
72 }
73
74 complete_head_from_modules($conf, $langs, null, $head, $h, 'pdf_admin', 'remove');
75
76 return $head;
77}
78
79
87function pdf_getFormat($outputlangs = null, $mode = 'setup')
88{
89 global $conf, $db, $langs;
90
91 dol_syslog("pdf_getFormat Get paper format with mode=".$mode." MAIN_PDF_FORMAT=".getDolGlobalString('MAIN_PDF_FORMAT')." outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null')." and langs->defaultlang=".(is_object($langs) ? $langs->defaultlang : 'null'));
92
93 // Default value if setup was not done and/or entry into c_paper_format not defined
94 $width = 210;
95 $height = 297;
96 $unit = 'mm';
97
98 if ($mode == 'auto' || !getDolGlobalString('MAIN_PDF_FORMAT') || getDolGlobalString('MAIN_PDF_FORMAT') == 'auto') {
99 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
100 $pdfformat = dol_getDefaultFormat($outputlangs);
101 } else {
102 $pdfformat = getDolGlobalString('MAIN_PDF_FORMAT');
103 }
104
105 $sql = "SELECT code, label, width, height, unit FROM ".MAIN_DB_PREFIX."c_paper_format";
106 $sql .= " WHERE code = '".$db->escape($pdfformat)."'";
107 $resql = $db->query($sql);
108 if ($resql) {
109 $obj = $db->fetch_object($resql);
110 if ($obj) {
111 $width = (int) $obj->width;
112 $height = (int) $obj->height;
113 $unit = $obj->unit;
114 }
115 }
116
117 //print "pdfformat=".$pdfformat." width=".$width." height=".$height." unit=".$unit;
118 return array('width' => $width, 'height' => $height, 'unit' => $unit);
119}
120
129function pdf_getInstance($format = '', $metric = 'mm', $pagetype = 'P')
130{
131 global $conf;
132
133 // Define constant for TCPDF
134 if (!defined('K_TCPDF_EXTERNAL_CONFIG')) {
135 define('K_TCPDF_EXTERNAL_CONFIG', 1); // this avoid using tcpdf_config file
136 define('K_PATH_CACHE', DOL_DATA_ROOT.'/admin/temp/');
137 define('K_PATH_URL_CACHE', DOL_DATA_ROOT.'/admin/temp/');
138 dol_mkdir(K_PATH_CACHE);
139 define('K_BLANK_IMAGE', '_blank.png');
140 define('PDF_PAGE_FORMAT', 'A4');
141 define('PDF_PAGE_ORIENTATION', 'P');
142 define('PDF_CREATOR', 'TCPDF');
143 define('PDF_AUTHOR', 'TCPDF');
144 define('PDF_HEADER_TITLE', 'TCPDF Example');
145 define('PDF_HEADER_STRING', "by Dolibarr ERP CRM");
146 define('PDF_UNIT', 'mm');
147 define('PDF_MARGIN_HEADER', 5);
148 define('PDF_MARGIN_FOOTER', 10);
149 define('PDF_MARGIN_TOP', 27);
150 define('PDF_MARGIN_BOTTOM', 25);
151 define('PDF_MARGIN_LEFT', 15);
152 define('PDF_MARGIN_RIGHT', 15);
153 define('PDF_FONT_NAME_MAIN', 'helvetica');
154 define('PDF_FONT_SIZE_MAIN', 10);
155 define('PDF_FONT_NAME_DATA', 'helvetica');
156 define('PDF_FONT_SIZE_DATA', 8);
157 define('PDF_FONT_MONOSPACED', 'courier');
158 define('PDF_IMAGE_SCALE_RATIO', 1.25);
159 define('HEAD_MAGNIFICATION', 1.1);
160 define('K_CELL_HEIGHT_RATIO', 1.25);
161 define('K_TITLE_MAGNIFICATION', 1.3);
162 define('K_SMALL_RATIO', 2 / 3);
163 define('K_THAI_TOPCHARS', true);
164 define('K_TCPDF_CALLS_IN_HTML', true);
165 // Default: throw exceptions on TCPDF/TCPDI errors instead of die().
166 // A die() in a PDF library produces white pages on web requests and kills
167 // batch jobs on the first bad PDF. Exceptions can be caught and surfaced as
168 // normal Dolibarr errors. Users can opt out by setting
169 // TCPDF_THROW_ERRORS_INSTEAD_OF_DIE = 0 to restore the legacy die() behavior.
170 if (getDolGlobalString('TCPDF_THROW_ERRORS_INSTEAD_OF_DIE', '1')) {
171 define('K_TCPDF_THROW_EXCEPTION_ERROR', true);
172 } else {
173 define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
174 }
175 }
176
177 // Load TCPDF
178 require_once TCPDF_PATH.'tcpdf.php';
179
180 // We need to instantiate tcpdi object (instead of tcpdf) to use merging features. But we can disable it (this will break all merge features).
181 if (!getDolGlobalString('MAIN_DISABLE_TCPDI')) {
182 require_once TCPDI_PATH.'tcpdi.php';
183 }
184
185 //$arrayformat=pdf_getFormat();
186 //$format=array($arrayformat['width'],$arrayformat['height']);
187 //$metric=$arrayformat['unit'];
188
189 //$pdfa = false; // PDF default version
190 $pdfa = getDolGlobalInt('PDF_USE_A', 0); // PDF/A-1 ou PDF/A-3
191
192 if (!getDolGlobalString('MAIN_DISABLE_TCPDI') && class_exists('TCPDI')) {
193 $pdf = new TCPDI($pagetype, $metric, $format, true, 'UTF-8', false, $pdfa);
194 } else {
195 $pdf = new TCPDF($pagetype, $metric, $format, true, 'UTF-8', false, $pdfa);
196 }
197
198 // Protection and encryption of pdf
199 if (getDolGlobalString('PDF_SECURITY_ENCRYPTION')) {
200 /* Permission supported by TCPDF
201 - print : Print the document;
202 - modify : Modify the contents of the document by operations other than those controlled by 'fill-forms', 'extract' and 'assemble';
203 - copy : Copy or otherwise extract text and graphics from the document;
204 - annot-forms : Add or modify text annotations, fill in interactive form fields, and, if 'modify' is also set, create or modify interactive form fields (including signature fields);
205 - fill-forms : Fill in existing interactive form fields (including signature fields), even if 'annot-forms' is not specified;
206 - extract : Extract text and graphics (in support of accessibility to users with disabilities or for other purposes);
207 - assemble : Assemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even if 'modify' is not set;
208 - print-high : Print the document to a representation from which a faithful digital copy of the PDF content could be generated. When this is not set, printing is limited to a low-level representation of the appearance, possibly of degraded quality.
209 - owner : (inverted logic - only for public-key) when set permits change of encryption and enables all other permissions.
210 */
211
212 // For TCPDF, we specify permission we want to block
213 $pdfrights = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_RIGHTS') ? json_decode(getDolGlobalString('PDF_SECURITY_ENCRYPTION_RIGHTS'), true) : array('modify', 'copy')); // Json format in llx_const
214
215 // Password for the end user
216 $pdfuserpass = getDolGlobalString('PDF_SECURITY_ENCRYPTION_USERPASS');
217
218 // Password of the owner, created randomly if not defined
219 $pdfownerpass = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_OWNERPASS') ? getDolGlobalString('PDF_SECURITY_ENCRYPTION_OWNERPASS') : null);
220
221 // For encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit
222 $encstrength = getDolGlobalInt('PDF_SECURITY_ENCRYPTION_STRENGTH', 0);
223
224 // Array of recipients containing public-key certificates ('c') and permissions ('p').
225 // For example: array(array('c' => 'file://../examples/data/cert/tcpdf.crt', 'p' => array('print')))
226 $pubkeys = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_PUBKEYS') ? json_decode(getDolGlobalString('PDF_SECURITY_ENCRYPTION_PUBKEYS'), true) : null); // Json format in llx_const
227
228 $pdf->SetProtection($pdfrights, $pdfuserpass, $pdfownerpass, $encstrength, $pubkeys);
229 }
230
231 return $pdf;
232}
233
240function pdf_getEncryption($pathoffile)
241{
242 require_once TCPDF_PATH.'tcpdf_parser.php';
243
244 $isencrypted = false;
245
246 $content = file_get_contents($pathoffile);
247
248 //ob_start();
249 @($parser = new TCPDF_PARSER(ltrim($content)));
250 $tmp = $parser->getParsedData();
251 $xref = $tmp[0];
252 $data = $tmp[1] ?? null;
253 unset($parser);
254 //ob_end_clean();
255
256 if (isset($xref['trailer']['encrypt'])) {
257 $isencrypted = true; // Secured pdf file are currently not supported
258 }
259
260 if (empty($data)) {
261 $isencrypted = true; // Object list not found. Possible secured file
262 }
263
264 return $isencrypted;
265}
266
273function pdf_getPDFFont($outputlangs)
274{
275 if (getDolGlobalString('MAIN_PDF_FORCE_FONT')) {
276 return getDolGlobalString('MAIN_PDF_FORCE_FONT');
277 }
278
279 $font = 'Helvetica'; // By default, for FPDI, or ISO language on TCPDF
280 if (class_exists('TCPDF')) { // If TCPDF on, we can use an UTF8 one like DejaVuSans if required (slower)
281 if ($outputlangs->trans('FONTFORPDF') != 'FONTFORPDF') {
282 $font = $outputlangs->trans('FONTFORPDF');
283 }
284 }
285 return $font;
286}
287
294function pdf_getPDFFontSize($outputlangs)
295{
296 $size = 10; // By default, for FPDI or ISO language on TCPDF
297 if (class_exists('TCPDF')) { // If TCPDF on, we can use an UTF8 font like DejaVuSans if required (slower)
298 if ($outputlangs->trans('FONTSIZEFORPDF') != 'FONTSIZEFORPDF') {
299 $size = (int) $outputlangs->trans('FONTSIZEFORPDF');
300 }
301 }
302 if (getDolGlobalString('MAIN_PDF_FORCE_FONT_SIZE')) {
303 $size = getDolGlobalString('MAIN_PDF_FORCE_FONT_SIZE');
304 }
305
306 return $size;
307}
308
309
317function pdf_getHeightForLogo($logo, $url = false)
318{
319 $height = getDolGlobalFloat('MAIN_DOCUMENTS_LOGO_HEIGHT', 20);
320 $maxwidth = 130;
321 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
322 $tmp = dol_getImageSize($logo, $url);
323 if ($tmp['height']) {
324 $width = round($height * $tmp['width'] / $tmp['height']);
325 if ($width > $maxwidth) {
326 $height = $height * $maxwidth / $width;
327 }
328 }
329
330 return $height;
331}
332
342function pdfGetHeightForHtmlContent($pdf, $htmlcontent)
343{
344 // store current object
345 $pdf->startTransaction();
346 // To avoid pagebreak effect or strange behavior of writeHTMLCell when we are out of page, we imagine we are at the begin of page to test the height of the text
347 // Another solution would be to do the test on another PDF instance with samefont, width...
348 $pdf->setY(0);
349 // store starting values
350 $start_y = $pdf->GetY();
351 //var_dump($start_y);
352 $start_page = $pdf->getPage();
353 // call printing functions with content
354 $pdf->writeHTMLCell(0, 0, 0, $start_y, $htmlcontent, 0, 1, false, true, 'J', true);
355 // get the new Y
356 $end_y = $pdf->GetY();
357 $end_page = $pdf->getPage();
358 // calculate height
359 $height = 0;
360 if ($end_page == $start_page) {
361 $height = $end_y - $start_y;
362 } else {
363 for ($page = $start_page; $page <= $end_page; ++$page) {
364 $pdf->setPage($page);
365 $tmpm = $pdf->getMargins();
366 $tMargin = $tmpm['top'];
367 if ($page == $start_page) {
368 // first page
369 $height = $pdf->getPageHeight() - $start_y - $pdf->getBreakMargin();
370 } elseif ($page == $end_page) {
371 // last page
372 $height = $end_y - $tMargin;
373 } else {
374 $height = $pdf->getPageHeight() - $tMargin - $pdf->getBreakMargin();
375 }
376 }
377 }
378 // restore previous object state
379 $pdf->rollbackTransaction(true);
380
381 return $height;
382}
383
384
393function pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias = 0)
394{
395 // Recipient name
396 $socname = '';
397
398 if ($thirdparty instanceof Societe) {
399 $socname = $thirdparty->name;
400 if (($includealias || getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME')) && !empty($thirdparty->name_alias)) {
401 if (getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME') == 2) {
402 $socname = $thirdparty->name_alias." - ".$thirdparty->name;
403 } else {
404 $socname = $thirdparty->name." - ".$thirdparty->name_alias;
405 }
406 }
407 } elseif ($thirdparty instanceof Contact) {
408 if ($thirdparty->socid > 0) {
409 $thirdparty->fetch_thirdparty();
410 $socname = $thirdparty->thirdparty->name;
411 if (($includealias || getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME')) && !empty($thirdparty->thirdparty->name_alias)) {
412 if (getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME') == 2) {
413 $socname = $thirdparty->thirdparty->name_alias." - ".$thirdparty->thirdparty->name;
414 } else {
415 $socname = $thirdparty->thirdparty->name." - ".$thirdparty->thirdparty->name_alias;
416 }
417 }
418 }
419 } else {
420 throw new InvalidArgumentException('Parameter 1 $thirdparty is not a Societe nor Contact');
421 }
422
423 return $outputlangs->convToOutputCharset((string) $socname);
424}
425
438function pdf_build_address($outputlangs, $sourcecompany, $targetcompany = '', $targetcontact = '', $usecontact = 0, $mode = 'source', $object = null)
439{
440 global $hookmanager;
441
442 if ($mode == 'source' && !is_object($sourcecompany)) {
443 return -1;
444 }
445 if ($mode == 'target' && !is_object($targetcompany)) {
446 return -1;
447 }
448
449 if (!empty($sourcecompany->state_id) && empty($sourcecompany->state)) {
450 $sourcecompany->state = getState($sourcecompany->state_id);
451 }
452 if (!empty($targetcompany->state_id) && empty($targetcompany->state)) {
453 $targetcompany->state = getState($targetcompany->state_id);
454 }
455
456 $reshook = 0;
457 $stringaddress = '';
458 if (is_object($hookmanager)) {
459 $parameters = array('sourcecompany' => &$sourcecompany, 'targetcompany' => &$targetcompany, 'targetcontact' => &$targetcontact, 'outputlangs' => $outputlangs, 'mode' => $mode, 'usecontact' => $usecontact);
460 $action = '';
461 // @phan-suppress-next-line PhanTypeMismatchArgumentNullable
462 $reshook = $hookmanager->executeHooks('pdf_build_address', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
463 $stringaddress .= $hookmanager->resPrint;
464 }
465 if (empty($reshook)) {
466 if ($mode == 'source') {
467 $withCountry = 0;
468 if (isset($targetcompany->country_code) && !empty($sourcecompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
469 $withCountry = 1;
470 }
471
472 $fulladdress = dol_format_address($sourcecompany, $withCountry, "\n", $outputlangs);
473 if ($fulladdress) {
474 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($fulladdress)."\n";
475 }
476
477 if (!getDolGlobalString('MAIN_PDF_DISABLESOURCEDETAILS')) {
478 // Phone
479 if ($sourcecompany->phone) {
480 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("PhoneShort").": ".$outputlangs->convToOutputCharset($sourcecompany->phone);
481 }
482 // Phone mobile
483 if ($sourcecompany->phone_mobile && getDolGlobalString('MAIN_PDF_SHOW_SOURCE_PHONE_MOBILE')) {
484 $stringaddress .= ($stringaddress ? ($sourcecompany->phone ? " - " : "\n") : '').$outputlangs->transnoentities("PhoneShort").": ".$outputlangs->convToOutputCharset($sourcecompany->phone_mobile);
485 }
486 // Fax
487 if ($sourcecompany->fax) {
488 $stringaddress .= ($stringaddress ? ($sourcecompany->phone ? " - " : "\n") : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($sourcecompany->fax);
489 }
490 // EMail
491 if ($sourcecompany->email) {
492 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($sourcecompany->email);
493 }
494 // Web
495 if ($sourcecompany->url) {
496 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($sourcecompany->url);
497 }
498 }
499 // Intra VAT
500 if (getDolGlobalString('MAIN_TVAINTRA_IN_SOURCE_ADDRESS')) {
501 if ($sourcecompany->tva_intra) {
502 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($sourcecompany->tva_intra);
503 }
504 }
505 // Professional Ids
506 $reg = array();
507 if (getDolGlobalString('MAIN_PROFID1_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof1)) {
508 $tmp = $outputlangs->transcountrynoentities("ProfId1", $sourcecompany->country_code);
509 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
510 $tmp = $reg[1];
511 }
512 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof1);
513 }
514 if (getDolGlobalString('MAIN_PROFID2_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof2)) {
515 $tmp = $outputlangs->transcountrynoentities("ProfId2", $sourcecompany->country_code);
516 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
517 $tmp = $reg[1];
518 }
519 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof2);
520 }
521 if (getDolGlobalString('MAIN_PROFID3_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof3)) {
522 $tmp = $outputlangs->transcountrynoentities("ProfId3", $sourcecompany->country_code);
523 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
524 $tmp = $reg[1];
525 }
526 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof3);
527 }
528 if (getDolGlobalString('MAIN_PROFID4_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof4)) {
529 $tmp = $outputlangs->transcountrynoentities("ProfId4", $sourcecompany->country_code);
530 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
531 $tmp = $reg[1];
532 }
533 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof4);
534 }
535 if (getDolGlobalString('MAIN_PROFID5_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof5)) {
536 $tmp = $outputlangs->transcountrynoentities("ProfId5", $sourcecompany->country_code);
537 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
538 $tmp = $reg[1];
539 }
540 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof5);
541 }
542 if (getDolGlobalString('MAIN_PROFID6_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof6)) {
543 $tmp = $outputlangs->transcountrynoentities("ProfId6", $sourcecompany->country_code);
544 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
545 $tmp = $reg[1];
546 }
547 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof6);
548 }
549 if (getDolGlobalString('PDF_ADD_MORE_AFTER_SOURCE_ADDRESS')) {
550 $stringaddress .= ($stringaddress ? "\n" : '') . getDolGlobalString('PDF_ADD_MORE_AFTER_SOURCE_ADDRESS');
551 }
552 }
553
554 if ($mode == 'target' || preg_match('/targetwithdetails/', $mode)) {
555 if ($usecontact && (is_object($targetcontact))) {
556 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($targetcontact->getFullName($outputlangs, 1));
557
558 if (!empty($targetcontact->address)) {
559 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcontact))."\n";
560 } elseif (is_object($targetcompany)) {
561 $companytouseforaddress = $targetcompany;
562
563 // Contact on a thirdparty that is a different thirdparty than the thirdparty of object
564 if ($targetcontact->socid > 0 && $targetcontact->socid != $targetcompany->id) {
565 $targetcontact->fetch_thirdparty();
566 $companytouseforaddress = $targetcontact->thirdparty;
567 }
568
569 if (is_object($companytouseforaddress)) {
570 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($companytouseforaddress))."\n";
571 }
572 }
573 // Country
574 if (!empty($targetcontact->country_code) && $targetcontact->country_code != $sourcecompany->country_code) {
575 $stringaddress .= (($stringaddress && !getDolGlobalString('MAIN_PDF_REMOVE_BREAK_BEFORE_COUNTRY')) ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcontact->country_code));
576 } elseif (empty($targetcontact->country_code) && !empty($targetcompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
577 $stringaddress .= (($stringaddress && !getDolGlobalString('MAIN_PDF_REMOVE_BREAK_BEFORE_COUNTRY')) ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
578 }
579
580 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
581 // Phone
582 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) {
583 if (!empty($targetcontact->phone_pro) || !empty($targetcontact->phone_mobile)) {
584 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": ";
585 }
586 if (!empty($targetcontact->phone_pro)) {
587 $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_pro);
588 }
589 if (!empty($targetcontact->phone_pro) && !empty($targetcontact->phone_mobile)) {
590 $stringaddress .= " / ";
591 }
592 if (!empty($targetcontact->phone_mobile)) {
593 $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_mobile);
594 }
595 }
596 // Fax
597 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) {
598 if ($targetcontact->fax) {
599 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcontact->fax);
600 }
601 }
602 // EMail
603 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) {
604 if ($targetcontact->email) {
605 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcontact->email);
606 }
607 }
608 // Web
609 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) {
610 if ($targetcontact->url) {
611 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset((string) $targetcontact->url);
612 }
613 }
614 }
615 } else {
616 if (is_object($targetcompany)) {
617 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcompany));
618 // Country
619 if (!empty($targetcompany->country_code) && $targetcompany->country_code != $sourcecompany->country_code) {
620 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
621 } else {
622 $stringaddress .= ($stringaddress ? "\n" : '');
623 }
624
625 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
626 // Phone
627 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) {
628 if (!empty($targetcompany->phone) || !empty($targetcompany->phone_mobile)) {
629 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": ";
630 }
631 if (!empty($targetcompany->phone)) {
632 $stringaddress .= $outputlangs->convToOutputCharset($targetcompany->phone);
633 }
634 if (!empty($targetcompany->phone) && !empty($targetcompany->phone_mobile)) {
635 $stringaddress .= " / ";
636 }
637 if (!empty($targetcompany->phone_mobile)) {
638 $stringaddress .= $outputlangs->convToOutputCharset($targetcompany->phone_mobile);
639 }
640 }
641 // Fax
642 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) {
643 if ($targetcompany->fax) {
644 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcompany->fax);
645 }
646 }
647 // EMail
648 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) {
649 if ($targetcompany->email) {
650 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcompany->email);
651 }
652 }
653 // Web
654 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) {
655 if ($targetcompany->url) {
656 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcompany->url);
657 }
658 }
659 }
660 }
661 }
662
663 // Intra VAT
664 if (!getDolGlobalString('MAIN_TVAINTRA_NOT_IN_ADDRESS')) {
665 if ($usecontact && is_object($targetcontact) && getDolGlobalInt('MAIN_USE_COMPANY_NAME_OF_CONTACT')) {
666 $targetcontact->fetch_thirdparty();
667 if (!empty($targetcontact->thirdparty->id) && $targetcontact->thirdparty->tva_intra) {
668 $stringaddress .= ($stringaddress ? "\n" : '') . $outputlangs->transnoentities("VATIntraShort") . ': ' . $outputlangs->convToOutputCharset($targetcontact->thirdparty->tva_intra);
669 }
670 } elseif (!empty($targetcompany->tva_intra)) {
671 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($targetcompany->tva_intra);
672 }
673 }
674
675 // Legal form
676 if (getDolGlobalString('MAIN_LEGALFORM_IN_ADDRESS') && !empty($targetcompany->forme_juridique_code)) {
677 $tmp = getFormeJuridiqueLabel((string) $targetcompany->forme_juridique_code);
678 $stringaddress .= ($stringaddress ? "\n" : '').$tmp;
679 }
680
681 // Professional Ids
682 if (getDolGlobalString('MAIN_PROFID1_IN_ADDRESS') && !empty($targetcompany->idprof1)) {
683 $tmp = $outputlangs->transcountrynoentities("ProfId1", $targetcompany->country_code);
684 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
685 $tmp = $reg[1];
686 }
687 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof1);
688 }
689 if (getDolGlobalString('MAIN_PROFID2_IN_ADDRESS') && !empty($targetcompany->idprof2)) {
690 $tmp = $outputlangs->transcountrynoentities("ProfId2", $targetcompany->country_code);
691 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
692 $tmp = $reg[1];
693 }
694 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof2);
695 }
696 if (getDolGlobalString('MAIN_PROFID3_IN_ADDRESS') && !empty($targetcompany->idprof3)) {
697 $tmp = $outputlangs->transcountrynoentities("ProfId3", $targetcompany->country_code);
698 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
699 $tmp = $reg[1];
700 }
701 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof3);
702 }
703 if (getDolGlobalString('MAIN_PROFID4_IN_ADDRESS') && !empty($targetcompany->idprof4)) {
704 $tmp = $outputlangs->transcountrynoentities("ProfId4", $targetcompany->country_code);
705 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
706 $tmp = $reg[1];
707 }
708 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof4);
709 }
710 if (getDolGlobalString('MAIN_PROFID5_IN_ADDRESS') && !empty($targetcompany->idprof5)) {
711 $tmp = $outputlangs->transcountrynoentities("ProfId5", $targetcompany->country_code);
712 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
713 $tmp = $reg[1];
714 }
715 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof5);
716 }
717 if (getDolGlobalString('MAIN_PROFID6_IN_ADDRESS') && !empty($targetcompany->idprof6)) {
718 $tmp = $outputlangs->transcountrynoentities("ProfId6", $targetcompany->country_code);
719 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
720 $tmp = $reg[1];
721 }
722 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof6);
723 }
724
725 // Public note
726 if (getDolGlobalString('MAIN_PUBLIC_NOTE_IN_ADDRESS')) {
727 if ($mode == 'source' && !empty($sourcecompany->note_public)) {
728 $stringaddress .= ($stringaddress ? "\n" : '').dol_string_nohtmltag($sourcecompany->note_public);
729 }
730 if (($mode == 'target' || preg_match('/targetwithdetails/', $mode)) && !empty($targetcompany->note_public)) {
731 $stringaddress .= ($stringaddress ? "\n" : '').dol_string_nohtmltag($targetcompany->note_public);
732 }
733 }
734 }
735 }
736
737 return $stringaddress;
738}
739
740
749function pdf_pagehead($pdf, $outputlangs, $page_height)
750{
751 global $conf;
752
753 // Add a background image on document only if good setup of const
754 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF') && (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF') != '-1')) { // Warning, this option make TCPDF generation being crazy and some content disappeared behind the image
755 $filepath = $conf->mycompany->dir_output.'/logos/' . getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF');
756 if (file_exists($filepath)) {
757 $pdf->setAutoPageBreak(false, 0); // Disable auto pagebreak before adding image
758 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) {
759 $pdf->SetAlpha(getDolGlobalFloat('MAIN_USE_BACKGROUND_ON_PDF_ALPHA'));
760 } // Option for change opacity of background
761 $pdf->Image($filepath, getDolGlobalFloat('MAIN_USE_BACKGROUND_ON_PDF_X'), getDolGlobalFloat('MAIN_USE_BACKGROUND_ON_PDF_Y'), 0, $page_height);
762 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) {
763 $pdf->SetAlpha(1);
764 }
765 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
766 $pdf->setAutoPageBreak(true, 0); // Restore pagebreak
767 }
768 }
769 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') != '-1') {
770 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
771 }
772}
773
774
787function pdfWriteAdditionnalTitle($pdf, $outputlangs, $page_height, $object, &$w, &$posx, &$posy)
788{
789 // Transaction/Signature ID + Duplicate or Temporary info
790 include_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php';
791
792 pdfWriteBlockedLogSignature($pdf, $outputlangs, $page_height, $object, $w, $posx, $posy);
793}
794
795
812function pdfWriteVATArray($docgenerator, &$index, $pdf, $outputlangs, $outputlangsbis, $object, $col1x, $col2x, $largcol2, $tab2_top, $tab2_hl)
813{
814 global $mysoc;
815
816 $tmpatleastoneratenotnull = 0;
817
818 // Local tax 1 before VAT
819 foreach ($docgenerator->localtax1 as $localtax_type => $localtax_rate) {
820 if (in_array((string) $localtax_type, array('1', '3', '5'))) {
821 continue;
822 }
823
824 foreach ($localtax_rate as $tvakey => $tvaval) {
825 if ($tvakey != 0 || getDolGlobalString('INVOICE_SHOW_ALSO_LOCALTAX1_LINE_IF_ZERO')) {
826 //$tmpatleastoneratenotnull++;
827
828 $index++;
829 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
830
831 $tvacompl = '';
832 if (preg_match('/\*/', (string) $tvakey)) {
833 $tvakey = str_replace('*', '', (string) $tvakey);
834 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
835 }
836
837 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
838 $totalvat .= ' ';
839
840 if (getDolGlobalString('PDF_LOCALTAX1_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
841 $totalvat .= $tvacompl;
842 } else {
843 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
844 }
845
846 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
847
848 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
849
850 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
851 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', true);
852 }
853 }
854 }
855
856 // Local tax 2 before VAT
857 foreach ($docgenerator->localtax2 as $localtax_type => $localtax_rate) {
858 if (in_array((string) $localtax_type, array('1', '3', '5'))) {
859 continue;
860 }
861
862 foreach ($localtax_rate as $tvakey => $tvaval) {
863 if ($tvakey != 0 || getDolGlobalString('INVOICE_SHOW_ALSO_LOCALTAX2_LINE_IF_ZERO')) {
864 //$tmpatleastoneratenotnull++;
865
866 $index++;
867 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
868
869 $tvacompl = '';
870 if (preg_match('/\*/', (string) $tvakey)) {
871 $tvakey = str_replace('*', '', (string) $tvakey);
872 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
873 }
874 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
875 $totalvat .= ' ';
876
877 if (getDolGlobalString('PDF_LOCALTAX2_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
878 $totalvat .= $tvacompl;
879 } else {
880 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
881 }
882
883 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
884
885 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
886
887 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
888 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', true);
889 }
890 }
891 }
892
893 // Situations totals might be wrong on huge amounts with old mode 1
894 if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1 && $object->situation_cycle_ref && $object->situation_counter > 1) {
895 $sum_pdf_tva = 0;
896 foreach ($docgenerator->tva as $tvakey => $tvaval) {
897 $sum_pdf_tva += $tvaval; // sum VAT amounts to compare to object
898 }
899
900 if ($sum_pdf_tva != $object->total_tva) { // apply coef to recover the VAT object amount (the good one)
901 if (!empty($sum_pdf_tva)) {
902 $coef_fix_tva = $object->total_tva / $sum_pdf_tva;
903 } else {
904 $coef_fix_tva = 1;
905 }
906
907
908 foreach ($docgenerator->tva as $tvakey => $tvaval) {
909 $docgenerator->tva[$tvakey] = $tvaval * $coef_fix_tva;
910 }
911 foreach ($docgenerator->tva_array as $tvakey => $tvaval) {
912 $docgenerator->tva_array[$tvakey]['amount'] = $tvaval['amount'] * $coef_fix_tva;
913 }
914 }
915 }
916
917 if (!getDolGlobalInt('PDF_INVOICE_SHOW_VAT_ANALYSIS')) { // by default, we show detail of vat here
918 // VAT
919 foreach ($docgenerator->tva_array as $tvakey => $tvaval) {
920 if ($tvakey != 0 || getDolGlobalString('INVOICE_SHOW_ALSO_VAT_LINE_IF_ZERO')) {
921 $tmpatleastoneratenotnull++;
922
923 $index++;
924 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
925
926 $tvacompl = '';
927 if (preg_match('/\*/', $tvakey)) {
928 $tvakey = str_replace('*', '', $tvakey);
929 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
930 }
931 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
932 $totalvat .= ' ';
933 if (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'rateonly') {
934 $totalvat .= vatrate((string) $tvaval['vatrate'], true).$tvacompl;
935 } elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'codeonly') {
936 $totalvat .= $tvaval['vatcode'].$tvacompl;
937 } elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
938 $totalvat .= $tvacompl;
939 } else {
940 $totalvat .= vatrate((string) $tvaval['vatrate'], true).($tvaval['vatcode'] ? ' ('.$tvaval['vatcode'].')' : '').$tvacompl;
941 }
942
943 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
944
945 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
946
947 $pdf->MultiCell($largcol2, $tab2_hl, price(price2num($tvaval['amount'], 'MT'), 0, $outputlangs), 0, 'R', true);
948 }
949 }
950 }
951
952 // Local tax 1 after VAT
953 foreach ($docgenerator->localtax1 as $localtax_type => $localtax_rate) {
954 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
955 continue;
956 }
957
958 foreach ($localtax_rate as $tvakey => $tvaval) {
959 if ($tvakey != 0 || getDolGlobalString('INVOICE_SHOW_ALSO_LOCALTAX1_LINE_IF_ZERO')) {
960 //$tmpatleastoneratenotnull++;
961
962 $index++;
963 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
964
965 $tvacompl = '';
966 if (preg_match('/\*/', (string) $tvakey)) {
967 $tvakey = str_replace('*', '', (string) $tvakey);
968 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
969 }
970 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
971 $totalvat .= ' ';
972
973 if (getDolGlobalString('PDF_LOCALTAX1_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
974 $totalvat .= $tvacompl;
975 } else {
976 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
977 }
978
979 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
980
981 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
982
983 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
984 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', true);
985 }
986 }
987 }
988
989 // Local tax 2 after VAT
990 foreach ($docgenerator->localtax2 as $localtax_type => $localtax_rate) {
991 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
992 continue;
993 }
994
995 foreach ($localtax_rate as $tvakey => $tvaval) {
996 // retrieve global local tax
997 if ($tvakey != 0 || getDolGlobalString('INVOICE_SHOW_ALSO_LOCALTAX2_LINE_IF_ZERO')) {
998 //$tmpatleastoneratenotnull++;
999
1000 $index++;
1001 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1002
1003 $tvacompl = '';
1004 if (preg_match('/\*/', (string) $tvakey)) {
1005 $tvakey = str_replace('*', '', (string) $tvakey);
1006 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1007 }
1008 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1009 $totalvat .= ' ';
1010
1011 if (getDolGlobalString('PDF_LOCALTAX2_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1012 $totalvat .= $tvacompl;
1013 } else {
1014 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
1015 }
1016
1017 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
1018
1019 $total_localtax = ((isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1020
1021 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1022 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', true);
1023 }
1024 }
1025 }
1026
1027 $docgenerator->atleastoneratenotnull = $tmpatleastoneratenotnull;
1028}
1029
1030
1052function pdfWriteAlreadyPaid($docgenerator, &$index, $pdf, $outputlangs, $outputlangsbis, $object, $col1x, $col2x, $largcol2, $tab2_top, $tab2_hl, $deja_regle, $creditnoteamount, $depositsamount, $resteapayer, $resteapayer_origin)
1053{
1054 global $mysoc;
1055
1056 $useborder = 0;
1057
1058 if ((($deja_regle > 0 || $creditnoteamount > 0 || $depositsamount > 0) && !getDolGlobalString('INVOICE_NO_PAYMENT_DETAILS'))
1059 || isALNERunningVersion()) {
1060 // Already paid + Deposits
1061 $index++;
1062 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1063 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Paid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("Paid") : ''), 0, 'L', false);
1064 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1065 //if (!isModEnabled("multicurrency") || $object->multicurrency_tx == 1 || getDolGlobalInt('MULTICURRENCY_SHOW_ALSO_MAIN_CURRENCY_ON_PDF') == 0) {
1066 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle + $depositsamount, 0, $outputlangs), 0, 'R', false);
1067 //} else {
1068 // $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle + $depositsamount, 0, $outputlangs), 0, 'R', false);
1069 //
1070 // $index++;
1071 // $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1072 // $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Paid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("Paid") : '').' ('.$outputlangs->getCurrencySymbol($mysoc->currency_code).')', $useborder, 'L', true);
1073
1074 // $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1075 // $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle_origin + $depositsamount_origin, 0, $outputlangs, 1, -1, -1, $mysoc->currency_code), $useborder, 'L', true);
1076 //}
1077
1078 // Credit note
1079 if ($creditnoteamount) {
1080 $labeltouse = ($outputlangs->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangs->transnoentities("CreditNotesOrExcessReceived") : $outputlangs->transnoentities("CreditNotes");
1081 $labeltouse .= (is_object($outputlangsbis) ? (' / '.(($outputlangsbis->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangsbis->transnoentities("CreditNotesOrExcessReceived") : $outputlangsbis->transnoentities("CreditNotes"))) : '');
1082 $index++;
1083 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1084 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $labeltouse, 0, 'L', false);
1085 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1086 $pdf->MultiCell($largcol2, $tab2_hl, price($creditnoteamount, 0, $outputlangs), 0, 'R', false);
1087 }
1088
1089 if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT) {
1090 $index++;
1091 $pdf->SetFillColor(255, 255, 255);
1092
1093 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1094 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("EscompteOfferedShort") : ''), $useborder, 'L', true);
1095 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1096 $pdf->MultiCell($largcol2, $tab2_hl, price(price2num($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT'), 0, $outputlangs), $useborder, 'R', true);
1097
1098 $resteapayer = 0;
1099 $resteapayer_origin = 0;
1100 }
1101
1102 $index++;
1103 $pdf->SetTextColor(0, 0, 60);
1104 $pdf->SetFillColor(224, 224, 224);
1105 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1106 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RemainderToPay") : ''), $useborder, 'L', true);
1107 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1108 if (!isModEnabled("multicurrency") || $object->multicurrency_tx == 1 || getDolGlobalInt('MULTICURRENCY_SHOW_ALSO_MAIN_CURRENCY_ON_PDF') == 0) {
1109 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', true);
1110 } else {
1111 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', true);
1112
1113 //$pdf->MultiCell($largcol2, $tab2_hl, '('.price($resteapayer_origin, 0, $outputlangs, 1, -1, 'MT', $mysoc->currency_code).') '.price($resteapayer, 0, $outputlangs), 0, 'R', true);
1114 $index++;
1115 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1116 $pdf->SetTextColor(0, 0, 60);
1117 $pdf->SetFillColor(224, 224, 224);
1118 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RemainderToPay") : '').' ('.$outputlangs->getCurrencySymbol($mysoc->currency_code).')', $useborder, 'L', true);
1119
1120 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1121 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer_origin, 0, $outputlangs, 1, -1, -1, $mysoc->currency_code), $useborder, 'L', true);
1122 }
1123 }
1124}
1125
1126
1137function pdf_getSubstitutionArray($outputlangs, $exclude = null, $object = null, $onlykey = 0, $include = null)
1138{
1139 $substitutionarray = getCommonSubstitutionArray($outputlangs, $onlykey, $exclude, $object, $include);
1140 $substitutionarray['__FROM_NAME__'] = '__FROM_NAME__';
1141 $substitutionarray['__FROM_EMAIL__'] = '__FROM_EMAIL__';
1142 return $substitutionarray;
1143}
1144
1145
1157function pdf_watermark($pdf, $outputlangs, $h, $w, $unit, $text)
1158{
1159 // Print Draft Watermark
1160 if ($unit == 'pt') {
1161 $k = 1;
1162 } elseif ($unit == 'mm') {
1163 $k = 72 / 25.4;
1164 } elseif ($unit == 'cm') {
1165 $k = 72 / 2.54;
1166 } elseif ($unit == 'in') {
1167 $k = 72;
1168 } else {
1169 $k = 1;
1170 dol_print_error(null, 'Unexpected unit "'.$unit.'" for pdf_watermark');
1171 }
1172
1173 // Make substitution
1174 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, null);
1175 complete_substitutions_array($substitutionarray, $outputlangs, null);
1176 $text = make_substitutions($text, $substitutionarray, $outputlangs);
1177 $text = $outputlangs->convToOutputCharset($text);
1178
1179 $savx = $pdf->getX();
1180 $savy = $pdf->getY();
1181
1182 $watermark_angle = atan($h / $w) / 2;
1183 $watermark_x_pos = 0;
1184 $watermark_y_pos = $h / 3;
1185 $watermark_x = $w / 2;
1186 $watermark_y = $h / 3;
1187 $pdf->SetFont('', 'B', 40);
1188 $pdf->SetTextColor(255, 0, 0);
1189
1190 // rotate
1191 $pdf->_out(sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm', cos($watermark_angle), sin($watermark_angle), -sin($watermark_angle), cos($watermark_angle), $watermark_x * $k, ($h - $watermark_y) * $k, -$watermark_x * $k, -($h - $watermark_y) * $k));
1192 // print watermark
1193 $pdf->SetAlpha(0.5);
1194 $pdf->SetXY($watermark_x_pos, $watermark_y_pos);
1195
1196 // set alpha to semi-transparency
1197 $pdf->SetAlpha(0.3);
1198 $pdf->Cell($w - 20, 25, $outputlangs->convToOutputCharset($text), "", 2, "C", false);
1199
1200 // antirotate
1201 $pdf->_out('Q');
1202
1203 $pdf->SetXY($savx, $savy);
1204
1205 // Restore alpha
1206 $pdf->SetAlpha(1);
1207}
1208
1209
1221function pdfCertifMention($pdf, $outputlangs, $seller, $default_font_size, &$posy, $pdftemplate)
1222{
1223 include_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php';
1224
1225 return pdfCertifMentionblockedLog($pdf, $outputlangs, $seller, $default_font_size, $posy, $pdftemplate);
1226}
1227
1228
1241function pdf_bank($pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, $default_font_size = 10)
1242{
1243 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbank.class.php';
1244
1245 $diffsizetitle = getDolGlobalInt('PDF_DIFFSIZE_TITLE', 3);
1246 $diffsizecontent = getDolGlobalInt('PDF_DIFFSIZE_CONTENT', 4);
1247 $pdf->SetXY($curx, $cury);
1248
1249 if (empty($onlynumber)) {
1250 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1251 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByTransferOnThisBankAccount').':', 0, 'L', false);
1252 $cury += 4;
1253 }
1254
1255 $outputlangs->load("banks");
1256
1257 // Use correct name of bank id according to country
1258 $bickey = "BICNumber";
1259 if ($account->getCountryCode() == 'IN') {
1260 $bickey = "SWIFT";
1261 }
1262
1263 // Get format of bank account according to its country
1264 $usedetailedbban = $account->useDetailedBBAN();
1265
1266 //$onlynumber=0; $usedetailedbban=1; // For tests
1267 if ($usedetailedbban) {
1268 $savcurx = $curx;
1269
1270 if (empty($onlynumber)) {
1271 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
1272 $pdf->SetXY($curx, $cury);
1273 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', false);
1274 $cury += 3;
1275 }
1276
1277 if (!getDolGlobalString('PDF_BANK_HIDE_NUMBER_SHOW_ONLY_BICIBAN')) { // Note that some countries still need bank number, BIC/IBAN not enough for them
1278 // Note:
1279 // bank = code_banque (FR), sort code (GB, IR. Example: 12-34-56)
1280 // desk = code guichet (FR), used only when $usedetailedbban = 1
1281 // number = account number
1282 // key = check control key used only when $usedetailedbban = 1
1283 if (empty($onlynumber)) {
1284 $pdf->line($curx + 1, $cury + 1, $curx + 1, $cury + 6);
1285 }
1286
1287 $bank_number_length = 0;
1288 foreach ($account->getFieldsToShow() as $val) {
1289 $pdf->SetXY($curx, $cury + 4);
1290 $pdf->SetFont('', '', $default_font_size - 3);
1291
1292 if ($val == 'BankCode') {
1293 // Bank code
1294 $tmplength = 18;
1295 $content = $account->code_banque;
1296 } elseif ($val == 'DeskCode') {
1297 // Desk
1298 $tmplength = 18;
1299 $content = $account->code_guichet;
1300 } elseif ($val == 'BankAccountNumber') {
1301 // Number
1302 $tmplength = 24;
1303 $content = $account->number;
1304 } elseif ($val == 'BankAccountNumberKey') {
1305 // Key
1306 $tmplength = 15;
1307 $content = $account->cle_rib;
1308 } elseif ($val == 'IBAN' || $val == 'BIC') {
1309 // Key
1310 $tmplength = 0;
1311 $content = '';
1312 } else {
1313 dol_print_error($account->db, 'Unexpected value for getFieldsToShow: '.$val);
1314 break;
1315 }
1316
1317 if ($content == '') {
1318 continue;
1319 }
1320
1321 $pdf->MultiCell($tmplength, 3, $outputlangs->convToOutputCharset($content), 0, 'C', false);
1322 $pdf->SetXY($curx, $cury + 1);
1323 $curx += $tmplength;
1324 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
1325 $pdf->MultiCell($tmplength, 3, $outputlangs->transnoentities($val), 0, 'C', false);
1326 if (empty($onlynumber)) {
1327 $pdf->line($curx, $cury + 1, $curx, $cury + 7);
1328 }
1329
1330 // Only set this variable when table was printed
1331 $bank_number_length = 8;
1332 }
1333
1334 $curx = $savcurx;
1335 $cury += $bank_number_length;
1336 }
1337 } elseif (!empty($account->number)) {
1338 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
1339 $pdf->SetXY($curx, $cury);
1340 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', false);
1341 $cury += 3;
1342
1343 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
1344 $pdf->SetXY($curx, $cury);
1345 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("BankAccountNumber").': '.$outputlangs->convToOutputCharset($account->number), 0, 'L', false);
1346 $cury += 3;
1347
1348 if ($diffsizecontent <= 2) {
1349 $cury += 1;
1350 }
1351 }
1352
1353 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
1354
1355 if (empty($onlynumber) && !empty($account->address)) {
1356 $pdf->SetXY($curx, $cury);
1357 $val = $outputlangs->transnoentities("Residence").': '.$outputlangs->convToOutputCharset($account->address);
1358 $pdf->MultiCell(100, 3, $val, 0, 'L', false);
1359 //$nboflines=dol_nboflines_bis($val,120);
1360 //$cury+=($nboflines*3)+2;
1361 $tmpy = $pdf->getStringHeight(100, $val);
1362 $cury += $tmpy;
1363 }
1364
1365 if (!empty($account->owner_name)) {
1366 $pdf->SetXY($curx, $cury);
1367 $val = $outputlangs->transnoentities("BankAccountOwner").': '.$outputlangs->convToOutputCharset($account->owner_name);
1368 $pdf->MultiCell(100, 3, $val, 0, 'L', false);
1369 $tmpy = $pdf->getStringHeight(100, $val);
1370 $cury += $tmpy;
1371 } elseif (!$usedetailedbban) {
1372 $cury += 1;
1373 }
1374
1375 // Use correct name of bank id according to country
1376 $ibankey = FormBank::getIBANLabel($account);
1377
1378 if (!empty($account->iban)) {
1379 //Remove whitespaces to ensure we are dealing with the format we expect
1380 $ibanDisplay_temp = str_replace(' ', '', $outputlangs->convToOutputCharset($account->iban));
1381 $ibanDisplay = "";
1382
1383 $nbIbanDisplay_temp = dol_strlen($ibanDisplay_temp);
1384 for ($i = 0; $i < $nbIbanDisplay_temp; $i++) {
1385 $ibanDisplay .= $ibanDisplay_temp[$i];
1386 if ($i % 4 == 3 && $i > 0) {
1387 $ibanDisplay .= " ";
1388 }
1389 }
1390
1391 $pdf->SetFont('', 'B', $default_font_size - 3);
1392 $pdf->SetXY($curx, $cury);
1393 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($ibankey).': '.$ibanDisplay, 0, 'L', false);
1394 $cury += 3;
1395 }
1396
1397 if (!empty($account->bic)) {
1398 $pdf->SetFont('', 'B', $default_font_size - 3);
1399 $pdf->SetXY($curx, $cury);
1400 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($bickey).': '.$outputlangs->convToOutputCharset($account->bic), 0, 'L', false);
1401 }
1402
1403 return $pdf->getY();
1404}
1405
1423function pdf_pagefoot($pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails = 0, $hidefreetext = 0, $page_largeur = 0, $watermark = '')
1424{
1425 global $conf, $hookmanager;
1426
1427 $outputlangs->load("dict");
1428 $line = '';
1429 $reg = array();
1430 $marginwithfooter = 0; // Return value
1431
1432 $dims = $pdf->getPageDimensions();
1433
1434 // Line of free text
1435 if (empty($hidefreetext) && getDolGlobalString($paramfreetext)) {
1436 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
1437 // More substitution keys
1438 if (is_object($fromcompany)) {
1439 $substitutionarray['__FROM_NAME__'] = $fromcompany->name;
1440 $substitutionarray['__FROM_EMAIL__'] = $fromcompany->email;
1441 }
1442 complete_substitutions_array($substitutionarray, $outputlangs, $object);
1443 $newfreetext = make_substitutions(getDolGlobalString($paramfreetext), $substitutionarray, $outputlangs);
1444
1445 // Make a change into HTML code to allow to include images from medias directory.
1446 // <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1447 // become
1448 // <img alt="" src="'.DOL_DATA_ROOT.'/medias/image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1449 $newfreetext = preg_replace('/(<img.*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)("[^\/]*\/>)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $newfreetext);
1450
1451 $line .= $outputlangs->convToOutputCharset($newfreetext);
1452 }
1453
1454 // First line of company infos
1455 $line1 = "";
1456 $line2 = "";
1457 $line3 = "";
1458 $line4 = "";
1459
1460 if (is_object($fromcompany) && in_array($showdetails, array(1, 3))) {
1461 // Company name
1462 if ($fromcompany->name) {
1463 $line1 .= ($line1 ? " - " : "").$outputlangs->transnoentities("RegisteredOffice").": ".$fromcompany->name;
1464 }
1465 // Address
1466 if ($fromcompany->address) {
1467 $line1 .= ($line1 ? " - " : "").str_replace("\n", ", ", $fromcompany->address);
1468 }
1469 // Zip code
1470 if ($fromcompany->zip) {
1471 $line1 .= ($line1 ? " - " : "").$fromcompany->zip;
1472 }
1473 // Town
1474 if ($fromcompany->town) {
1475 $line1 .= ($line1 ? " " : "").$fromcompany->town;
1476 }
1477 // Country
1478 if ($fromcompany->country) {
1479 $line1 .= ($line1 ? ", " : "").$fromcompany->country;
1480 }
1481 // Phone
1482 if ($fromcompany->phone) {
1483 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Phone").": ".$fromcompany->phone;
1484 }
1485 // Fax
1486 if ($fromcompany->fax) {
1487 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Fax").": ".$fromcompany->fax;
1488 }
1489
1490 // URL
1491 if ($fromcompany->url) {
1492 $line2 .= ($line2 ? " - " : "").$fromcompany->url;
1493 }
1494 // Email
1495 if ($fromcompany->email) {
1496 $line2 .= ($line2 ? " - " : "").$fromcompany->email;
1497 }
1498 }
1499 if ($showdetails == 2 || $showdetails == 3 || (!empty($fromcompany->country_code) && $fromcompany->country_code == 'DE')) {
1500 // Managers
1501 if ($fromcompany->managers) {
1502 $line2 .= ($line2 ? " - " : "").$fromcompany->managers;
1503 }
1504 }
1505
1506 // Line 3 of company infos
1507 // Juridical status
1508 if (!empty($fromcompany->forme_juridique_code)) {
1509 $line3 .= ($line3 ? " - " : "").$outputlangs->convToOutputCharset(getFormeJuridiqueLabel((string) $fromcompany->forme_juridique_code));
1510 }
1511 // Capital
1512 if (!empty($fromcompany->capital)) {
1513 $tmpamounttoshow = price2num($fromcompany->capital); // This field is a free string or a float
1514 if (is_numeric($tmpamounttoshow) && $tmpamounttoshow > 0) {
1515 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", price($tmpamounttoshow, 0, $outputlangs, 0, 0, 0, getDolCurrency()));
1516 } elseif (!empty($fromcompany->capital)) {
1517 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", (string) $fromcompany->capital);
1518 }
1519 }
1520 // Prof Id 1
1521 if (!empty($fromcompany->idprof1) && ($fromcompany->country_code != 'FR' || (empty($fromcompany->idprof2) || strpos($fromcompany->idprof2, $fromcompany->idprof1) !== 0))) {
1522 $field = $outputlangs->transcountrynoentities("ProfId1", $fromcompany->country_code);
1523 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1524 $field = $reg[1];
1525 }
1526 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof1);
1527 }
1528 // Prof Id 2
1529 if (!empty($fromcompany->idprof2)) {
1530 $field = $outputlangs->transcountrynoentities("ProfId2", $fromcompany->country_code);
1531 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1532 $field = $reg[1];
1533 }
1534 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof2);
1535 }
1536
1537 // Line 4 of company infos
1538 // Prof Id 3
1539 if (!empty($fromcompany->idprof3)) {
1540 $field = $outputlangs->transcountrynoentities("ProfId3", $fromcompany->country_code);
1541 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1542 $field = $reg[1];
1543 }
1544 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof3);
1545 }
1546 // Prof Id 4
1547 if (!empty($fromcompany->idprof4)) {
1548 $field = $outputlangs->transcountrynoentities("ProfId4", $fromcompany->country_code);
1549 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1550 $field = $reg[1];
1551 }
1552 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof4);
1553 }
1554 // Prof Id 5
1555 if (!empty($fromcompany->idprof5)) {
1556 $field = $outputlangs->transcountrynoentities("ProfId5", $fromcompany->country_code);
1557 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1558 $field = $reg[1];
1559 }
1560 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof5);
1561 }
1562 // Prof Id 6
1563 if (!empty($fromcompany->idprof6)) {
1564 $field = $outputlangs->transcountrynoentities("ProfId6", $fromcompany->country_code);
1565 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1566 $field = $reg[1];
1567 }
1568 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof6);
1569 }
1570 // Prof Id 7
1571 if (!empty($fromcompany->idprof7)) {
1572 $field = $outputlangs->transcountrynoentities("ProfId7", $fromcompany->country_code);
1573 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1574 $field = $reg[1];
1575 }
1576 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof7);
1577 }
1578 // Prof Id 8
1579 if (!empty($fromcompany->idprof8)) {
1580 $field = $outputlangs->transcountrynoentities("ProfId8", $fromcompany->country_code);
1581 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1582 $field = $reg[1];
1583 }
1584 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof8);
1585 }
1586 // Prof Id 9
1587 if (!empty($fromcompany->idprof9)) {
1588 $field = $outputlangs->transcountrynoentities("ProfId9", $fromcompany->country_code);
1589 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1590 $field = $reg[1];
1591 }
1592 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof9);
1593 }
1594 // Prof Id 10
1595 if (!empty($fromcompany->idprof10)) {
1596 $field = $outputlangs->transcountrynoentities("ProfId10", $fromcompany->country_code);
1597 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1598 $field = $reg[1];
1599 }
1600 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof10);
1601 }
1602 // IntraCommunautary VAT
1603 if (!empty($fromcompany->tva_intra) && $fromcompany->tva_intra != '') {
1604 $line4 .= ($line4 ? " - " : "").$outputlangs->transnoentities("VATIntraShort").": ".$outputlangs->convToOutputCharset($fromcompany->tva_intra);
1605 }
1606
1607 $pdf->SetFont('', '', 7);
1608 $pdf->SetDrawColor(224, 224, 224);
1609 // Option for footer text color
1610 if (getDolGlobalString('PDF_FOOTER_TEXT_COLOR')) {
1611 $tmparray = sscanf(getDolGlobalString('PDF_FOOTER_TEXT_COLOR'), '%d, %d, %d');
1612 $r = $tmparray[0];
1613 $g = $tmparray[1];
1614 $b = $tmparray[2];
1615 $pdf->SetTextColor($r, $g, $b);
1616 }
1617
1618 // The start of the bottom of this page footer is positioned according to # of lines
1619 $freetextheight = 0;
1620 $align = '';
1621 if ($line) { // Free text
1622 //$line="sample text<br>\nfd<strong>sf</strong>sdf<br>\nghfghg<br>";
1623 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) {
1624 $width = 20000;
1625 $align = 'L'; // By default, ask a manual break: We use a large value 20000, to not have automatic wrap. This make user understand, he need to add CR on its text.
1626 if (getDolGlobalString('MAIN_USE_AUTOWRAP_ON_FREETEXT')) {
1627 $width = 200;
1628 $align = 'C';
1629 }
1630 $freetextheight = $pdf->getStringHeight($width, $line);
1631 } else {
1632 $freetextheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); // New method (works for HTML content)
1633 //print '<br>'.$freetextheight;
1634 }
1635 }
1636
1637 $posy = 0;
1638 // For customized footer
1639 if (is_object($hookmanager)) {
1640 $parameters = array('line1' => $line1, 'line2' => $line2, 'line3' => $line3, 'line4' => $line4, 'outputlangs' => $outputlangs);
1641 $action = '';
1642 $hookmanager->executeHooks('pdf_pagefoot', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1643 if (!empty($hookmanager->resPrint) && $hidefreetext == 0) {
1644 $mycustomfooter = $hookmanager->resPrint;
1645 $mycustomfooterheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1646
1647 $marginwithfooter = $marge_basse + $freetextheight + $mycustomfooterheight;
1648 $posy = (float) $marginwithfooter;
1649
1650 // Option for footer background color (without freetext zone)
1651 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1652 $tmparray = sscanf(getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR'), '%d, %d, %d');
1653 $r = $tmparray[0];
1654 $g = $tmparray[1];
1655 $b = $tmparray[2];
1656 $pdf->setAutoPageBreak(false, 0); // Disable auto pagebreak
1657 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', array(), $fill_color = array($r, $g, $b));
1658 $pdf->setAutoPageBreak(true, 0); // Restore pagebreak
1659 }
1660
1661 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1662 $pdf->setAutoPageBreak(false, 0);
1663 } // Option for disable auto pagebreak
1664 if ($line) { // Free text
1665 $pdf->SetXY($dims['lm'], -$posy);
1666 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1667 $pdf->MultiCell(0, 3, $line, 0, $align, false);
1668 } else {
1669 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1670 }
1671 $posy -= $freetextheight;
1672 }
1673 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1674 $pdf->setAutoPageBreak(true, 0);
1675 } // Restore pagebreak
1676
1677 $pdf->SetY(-$posy);
1678
1679 // Hide footer line if footer background color is set
1680 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1681 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1682 }
1683
1684 // Option for set top margin height of footer after freetext
1685 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1686 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1687 } else {
1688 $posy--;
1689 }
1690
1691 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1692 $pdf->setAutoPageBreak(false, 0);
1693 } // Option for disable auto pagebreak
1694 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1695 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1696 $pdf->setAutoPageBreak(true, 0);
1697 } // Restore pagebreak
1698
1699 $posy -= $mycustomfooterheight - 3;
1700 } else {
1701 // Else default footer
1702 $marginwithfooter = $marge_basse + $freetextheight + (!empty($line1) ? 3 : 0) + (!empty($line2) ? 3 : 0) + (!empty($line3) ? 3 : 0) + (!empty($line4) ? 3 : 0);
1703 $posy = (float) $marginwithfooter;
1704
1705 // Option for footer background color (without freetext zone)
1706 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1707 $tmparray = sscanf(getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR'), '%d, %d, %d');
1708 $r = $tmparray[0];
1709 $g = $tmparray[1];
1710 $b = $tmparray[2];
1711 $pdf->setAutoPageBreak(false, 0); // Disable auto pagebreak
1712 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', array(), $fill_color = array($r, $g, $b));
1713 $pdf->setAutoPageBreak(true, 0); // Restore pagebreak
1714 }
1715
1716 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1717 $pdf->setAutoPageBreak(false, 0);
1718 } // Option for disable auto pagebreak
1719 if ($line) { // Free text
1720 $pdf->SetXY($dims['lm'], -$posy);
1721 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1722 $pdf->MultiCell(0, 3, $line, 0, $align, false);
1723 } else {
1724 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1725 }
1726 $posy -= $freetextheight;
1727 }
1728 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1729 $pdf->setAutoPageBreak(true, 0);
1730 } // Restore pagebreak
1731
1732 $pdf->SetY(-$posy);
1733
1734 // Option for hide all footer (page number will no hidden)
1735 if (!getDolGlobalInt('PDF_FOOTER_HIDDEN')) {
1736 // Hide footer line if footer background color is set
1737 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1738 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1739 }
1740
1741 // Option for set top margin height of footer after freetext
1742 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1743 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1744 } else {
1745 $posy--;
1746 }
1747
1748 if (!empty($line1)) {
1749 $pdf->SetFont('', 'B', 7);
1750 $pdf->SetXY($dims['lm'], -$posy);
1751 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line1, 0, 'C', false);
1752 $posy -= 3;
1753 $pdf->SetFont('', '', 7);
1754 }
1755
1756 if (!empty($line2)) {
1757 $pdf->SetFont('', 'B', 7);
1758 $pdf->SetXY($dims['lm'], -$posy);
1759 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line2, 0, 'C', false);
1760 $posy -= 3;
1761 $pdf->SetFont('', '', 7);
1762 }
1763
1764 if (!empty($line3)) {
1765 $pdf->SetXY($dims['lm'], -$posy);
1766 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line3, 0, 'C', false);
1767 }
1768
1769 if (!empty($line4)) {
1770 $posy -= 3;
1771 $pdf->SetXY($dims['lm'], -$posy);
1772 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line4, 0, 'C', false);
1773 }
1774 }
1775 }
1776 }
1777
1778 // Show page nb and apply correction for some font.
1779 $pdf->SetXY($dims['wk'] - $dims['rm'] - 18 - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_X', 0), -$posy - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_Y', 0));
1780
1781 $pagination = $pdf->PageNo().' / '.$pdf->getAliasNbPages();
1782 $fontRenderCorrection = 0;
1783 if (in_array(pdf_getPDFFont($outputlangs), array('freemono', 'DejaVuSans'))) {
1784 $fontRenderCorrection = 10;
1785 }
1786 $pdf->MultiCell(18 + $fontRenderCorrection, 2, $pagination, 0, 'R', false);
1787
1788 // Show Draft Watermark
1789 if (!empty($watermark)) {
1790 pdf_watermark($pdf, $outputlangs, $page_hauteur, $page_largeur, 'mm', $watermark);
1791 }
1792
1793 return $marginwithfooter;
1794}
1795
1810function pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
1811{
1812 $linkedobjects = pdf_getLinkedObjects($object, $outputlangs); // May update $object->note_public
1813
1814 if (!empty($linkedobjects)) {
1815 foreach ($linkedobjects as $linkedobject) {
1816 $reftoshow = $linkedobject["ref_title"].' : '.$linkedobject["ref_value"];
1817 if (!empty($linkedobject["date_value"])) {
1818 $reftoshow .= ' / '.$linkedobject["date_value"];
1819 }
1820
1821 $posy += 3;
1822 $pdf->SetXY($posx, $posy);
1823 $pdf->SetFont('', '', (float) $default_font_size - 2);
1824 $pdf->MultiCell($w, $h, $reftoshow, '', $align);
1825 }
1826 }
1827
1828 return $pdf->getY();
1829}
1830
1848function pdf_writelinedesc($pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref = 0, $hidedesc = 0, $issupplierline = 0, $align = 'J')
1849{
1850 global $hookmanager;
1851
1852 $reshook = 0;
1853 $result = '';
1854 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
1855 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
1856 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1857 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1858 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1859 }
1860 $parameters = array('pdf' => $pdf, 'i' => $i, 'outputlangs' => $outputlangs, 'w' => $w, 'h' => $h, 'posx' => $posx, 'posy' => $posy, 'hideref' => $hideref, 'hidedesc' => $hidedesc, 'issupplierline' => $issupplierline, 'special_code' => $special_code);
1861 $action = '';
1862 // WARNING: A hook must not close/open the PDF transaction. Doing this generates a lot of trouble.
1863 // Test to know if content added by the hooks is already done by the main caller of pdf_writelinedesc
1864 $reshook = $hookmanager->executeHooks('pdf_writelinedesc', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1865
1866 if (!empty($hookmanager->resPrint)) {
1867 $result .= $hookmanager->resPrint;
1868 }
1869 }
1870 if (empty($reshook)) {
1871 $labelproductservice = pdf_getlinedesc($object, $i, $outputlangs, $hideref, $hidedesc, $issupplierline);
1872 $labelproductservice = preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $labelproductservice, -1, $nbrep);
1873
1874 //var_dump($labelproductservice);exit;
1875
1876 // Fix bug of some HTML editors that replace links <img src="http://localhostgit/viewimage.php?modulepart=medias&file=image/efd.png" into <img src="http://localhostgit/viewimage.php?modulepart=medias&amp;file=image/efd.png"
1877 // We make the reverse, so PDF generation has the real URL.
1878 $nbrep = 0;
1879 $labelproductservice = preg_replace('/(<img[^>]*src=")([^"]*)(&amp;)([^"]*")/', '\1\2&\4', $labelproductservice, -1, $nbrep);
1880
1881 if (getDolGlobalString('MARGIN_TOP_ZERO_UL')) {
1882 $pdf->setListIndentWidth(5);
1883 $TMarginList = ['ul' => [['h' => 0.1, ],['h' => 0.1, ]], 'li' => [['h' => 0.1, ],],];
1884 $pdf->setHtmlVSpace($TMarginList);
1885 }
1886
1887 // Description
1888 $pdf->writeHTMLCell($w, $h, $posx, $posy, $outputlangs->convToOutputCharset($labelproductservice), 0, 1, false, true, $align, true);
1889 $result .= $labelproductservice;
1890 }
1891 return $result;
1892}
1893
1905function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1906{
1907 global $db, $conf, $langs;
1908
1909 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1910 $label = (!empty($object->lines[$i]->label) ? $object->lines[$i]->label : (!empty($object->lines[$i]->product_label) ? $object->lines[$i]->product_label : ''));
1911 $product_barcode = (!empty($object->lines[$i]->product_barcode) ? $object->lines[$i]->product_barcode : "");
1912 $desc = (!empty($object->lines[$i]->desc) ? $object->lines[$i]->desc : (!empty($object->lines[$i]->description) ? $object->lines[$i]->description : ''));
1913 $ref_supplier = (!empty($object->lines[$i]->ref_supplier) ? $object->lines[$i]->ref_supplier : (!empty($object->lines[$i]->ref_fourn) ? $object->lines[$i]->ref_fourn : '')); // TODO Not yet saved for supplier invoices, only supplier orders
1914 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1915 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1916
1917 $multilangsactive = getDolGlobalInt('MAIN_MULTILANGS');
1918
1919 if ($issupplierline) {
1920 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
1921 $prodser = new ProductFournisseur($db);
1922 } else {
1923 include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1924 $prodser = new Product($db);
1925
1926 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
1927 include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
1928 }
1929 }
1930
1931 //id
1932 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1933 if ($idprod) {
1934 $prodser->fetch($idprod);
1935 //load multilangs
1936 if ($multilangsactive) {
1937 $prodser->getMultiLangs();
1938 $object->lines[$i]->multilangs = $prodser->multilangs;
1939 }
1940 }
1941 //label
1942 if (!empty($object->lines[$i]->label)) {
1943 $label = $object->lines[$i]->label;
1944 } else {
1945 if (!empty($object->lines[$i]->multilangs[$outputlangs->defaultlang]['label']) && $multilangsactive) {
1946 $label = $object->lines[$i]->multilangs[$outputlangs->defaultlang]['label'];
1947 } else {
1948 if (!empty($object->lines[$i]->product_label)) {
1949 $label = $object->lines[$i]->product_label;
1950 } else {
1951 $label = '';
1952 }
1953 }
1954 }
1955 //description
1956 if (!empty($object->lines[$i]->desc)) {
1957 $desc = $object->lines[$i]->desc;
1958 } else {
1959 if (!empty($object->lines[$i]->multilangs[$outputlangs->defaultlang]['description']) && $multilangsactive) {
1960 $desc = $object->lines[$i]->multilangs[$outputlangs->defaultlang]['description'];
1961 } else {
1962 if (!empty($object->lines[$i]->description)) {
1963 $desc = $object->lines[$i]->description;
1964 } else {
1965 $desc = '';
1966 }
1967 }
1968 }
1969 //ref supplier
1970 $ref_supplier = (!empty($object->lines[$i]->ref_supplier) ? $object->lines[$i]->ref_supplier : (!empty($object->lines[$i]->ref_fourn) ? $object->lines[$i]->ref_fourn : '')); // TODO Not yet saved for supplier invoices, only supplier orders
1971 //note
1972 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1973 //dbatch
1974 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1975
1976 if ($idprod) {
1977 // If a predefined product and multilang and on other lang, we renamed label with label translated
1978 if ($multilangsactive && ($outputlangs->defaultlang != $langs->defaultlang)) {
1979 $translatealsoifmodified = getDolGlobalString('MAIN_MULTILANG_TRANSLATE_EVEN_IF_MODIFIED'); // By default if value was modified manually, we keep it (no translation because we don't have it)
1980
1981 // TODO Instead of making a compare to see if param was modified, check that content contains reference translation. If yes, add the added part to the new translation
1982 // ($textwasnotmodified is replaced with $textwasmodifiedorcompleted and we add completion).
1983
1984 // Set label
1985 // If we want another language, and if label is same than default language (we did not force it to a specific value), we can use translation.
1986 //var_dump($outputlangs->defaultlang.' - '.$langs->defaultlang.' - '.$label.' - '.$prodser->label);exit;
1987 $textwasnotmodified = ($label == $prodser->label);
1988 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["label"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1989 $label = $prodser->multilangs[$outputlangs->defaultlang]["label"];
1990 }
1991
1992 // Set desc
1993 // Manage HTML entities description test because $prodser->description is store with htmlentities but $desc no
1994 $textwasnotmodified = false;
1995 $textdiffersonlybymarkup = false;
1996 if (!empty($desc) && dol_textishtml($desc) && !empty($prodser->description) && dol_textishtml($prodser->description)) {
1997 $textwasnotmodified = (strpos(dol_html_entity_decode($desc, ENT_QUOTES | ENT_HTML5), dol_html_entity_decode($prodser->description, ENT_QUOTES | ENT_HTML5)) !== false);
1998 } elseif (!empty($desc) && !empty($prodser->description) && dol_textishtml($desc) != dol_textishtml($prodser->description)) {
1999 // One side is HTML and the other is not. This happens as soon as a line is saved while the
2000 // WYSIWYG editor is enabled on line details: the plain product description becomes "<p>...</p>".
2001 // Comparing the raw strings would then report a manual change and silently drop the translation,
2002 // so compare the text content instead.
2003 $desctextonly = trim(dol_html_entity_decode(dol_string_nohtmltag($desc, 1), ENT_QUOTES | ENT_HTML5));
2004 $prodtextonly = trim(dol_html_entity_decode(dol_string_nohtmltag($prodser->description, 1), ENT_QUOTES | ENT_HTML5));
2005 $textwasnotmodified = ($prodtextonly !== '' && strpos($desctextonly, $prodtextonly) !== false);
2006 $textdiffersonlybymarkup = ($textwasnotmodified && $desctextonly === $prodtextonly);
2007 } else {
2008 $textwasnotmodified = ($desc == $prodser->description);
2009 }
2010 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["description"])) {
2011 if ($textwasnotmodified) {
2012 if ($textdiffersonlybymarkup && strpos($desc, $prodser->description) === false) {
2013 // Same text, but wrapped in tags or written with HTML entities: the product description
2014 // is not present verbatim, so the str_replace below would find nothing to replace.
2015 $desc = $prodser->multilangs[$outputlangs->defaultlang]["description"];
2016 } else {
2017 $desc = str_replace($prodser->description, $prodser->multilangs[$outputlangs->defaultlang]["description"], $desc);
2018 }
2019 } elseif ($translatealsoifmodified) {
2020 $desc = $prodser->multilangs[$outputlangs->defaultlang]["description"];
2021 }
2022 }
2023
2024 // Set note
2025 $textwasnotmodified = ($note == $prodser->note_public);
2026 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["other"]) && ($textwasnotmodified || $translatealsoifmodified)) {
2027 $note = $prodser->multilangs[$outputlangs->defaultlang]["other"];
2028 }
2029 }
2030 } elseif (($object->element == 'facture' || $object->element == 'facturefourn') && preg_match('/^\‍(DEPOSIT\‍).+/', $desc)) { // We must not replace '(DEPOSIT)' when it is alone, it will be translated and detailed later
2031 $desc = str_replace('(DEPOSIT)', $outputlangs->trans('Deposit'), $desc);
2032 }
2033
2034 $libelleproduitservice = ''; // Default value
2035 if (!getDolGlobalString('PDF_HIDE_PRODUCT_LABEL_IN_SUPPLIER_LINES')) {
2036 // Description short of product line
2037 $libelleproduitservice = $label;
2038 if (!empty($libelleproduitservice) && getDolGlobalString('PDF_BOLD_PRODUCT_LABEL')) {
2039 // Adding <b> may convert the original string into a HTML string. So we have to first
2040 // convert \n into <br> we text is not already HTML.
2041 if (!dol_textishtml($libelleproduitservice)) {
2042 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
2043 }
2044 $libelleproduitservice = '<b>'.$libelleproduitservice.'</b>';
2045 }
2046 }
2047
2048
2049 // Add ref of subproducts
2050 if (getDolGlobalString('SHOW_SUBPRODUCT_REF_IN_PDF')) {
2051 $prodser->get_sousproduits_arbo();
2052 if (!empty($prodser->sousprods) && is_array($prodser->sousprods) && count($prodser->sousprods)) {
2053 $outputlangs->load('mrp');
2054 $tmparrayofsubproducts = reset($prodser->sousprods);
2055
2056 $qtyText = null;
2057 if (isset($object->lines[$i]->qty) && !empty($object->lines[$i]->qty)) {
2058 $qtyText = $object->lines[$i]->qty;
2059 } elseif (isset($object->lines[$i]->qty_shipped) && !empty($object->lines[$i]->qty_shipped)) {
2060 $qtyText = $object->lines[$i]->qty;
2061 }
2062
2063 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF')) {
2064 foreach ($tmparrayofsubproducts as $subprodval) {
2065 $libelleproduitservice = dol_concatdesc(
2066 dol_concatdesc($libelleproduitservice, " * ".$subprodval[3]),
2067 (!empty($qtyText) ?
2068 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1] * $qtyText :
2069 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
2070 );
2071 }
2072 } else {
2073 foreach ($tmparrayofsubproducts as $subprodval) {
2074 $libelleproduitservice = dol_concatdesc(
2075 dol_concatdesc($libelleproduitservice, " * ".$subprodval[5].(($subprodval[5] && $subprodval[3]) ? ' - ' : '').$subprodval[3]),
2076 (!empty($qtyText) ?
2077 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1] * $qtyText :
2078 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
2079 );
2080 }
2081 }
2082 }
2083 }
2084
2085 if (isModEnabled('barcode') && getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_PRODUCT_BARCODE') && !empty($product_barcode)) {
2086 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $outputlangs->trans("BarCode")." ".$product_barcode);
2087 }
2088
2089 // Description long of product line
2090 if (!empty($desc) && ($desc != $label)) {
2091 if ($desc == '(CREDIT_NOTE)' && $object->lines[$i]->fk_remise_except) {
2092 $discount = new DiscountAbsolute($db);
2093 $discount->fetch($object->lines[$i]->fk_remise_except);
2094 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
2095 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromCreditNote", $sourceref);
2096 } elseif ($desc == '(DEPOSIT)' && $object->lines[$i]->fk_remise_except) {
2097 $discount = new DiscountAbsolute($db);
2098 $discount->fetch($object->lines[$i]->fk_remise_except);
2099 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
2100 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromDeposit", $sourceref);
2101 // Add date of deposit
2102 if (getDolGlobalString('INVOICE_ADD_DEPOSIT_DATE')) {
2103 $libelleproduitservice .= ' ('.dol_print_date($discount->datec, 'day', '', $outputlangs).')';
2104 }
2105 } elseif ($desc == '(EXCESS RECEIVED)' && $object->lines[$i]->fk_remise_except) {
2106 $discount = new DiscountAbsolute($db);
2107 $discount->fetch($object->lines[$i]->fk_remise_except);
2108 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived", $discount->ref_facture_source);
2109 } elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except) {
2110 $discount = new DiscountAbsolute($db);
2111 $discount->fetch($object->lines[$i]->fk_remise_except);
2112 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid", $discount->ref_invoice_supplier_source);
2113 } else {
2114 if ($idprod) {
2115 // Check if description must be output
2116 if (!empty($object->element)) {
2117 $tmpkey = 'MAIN_DOCUMENTS_HIDE_DESCRIPTION_FOR_'.strtoupper($object->element);
2118 if (getDolGlobalString($tmpkey)) {
2119 $hidedesc = 1;
2120 }
2121 }
2122 if (empty($hidedesc)) {
2123 if (getDolGlobalString('MAIN_DOCUMENTS_DESCRIPTION_FIRST')) {
2124 $libelleproduitservice = dol_concatdesc($desc, $libelleproduitservice);
2125 } else {
2126 if (getDolGlobalString('HIDE_LABEL_VARIANT_PDF') && $prodser->isVariant()) {
2127 $libelleproduitservice = $desc;
2128 } else {
2129 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
2130 }
2131 }
2132 }
2133 } else {
2134 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
2135 }
2136 }
2137 }
2138
2139 // We add ref of product (and supplier ref if defined)
2140 $prefix_prodserv = "";
2141 $ref_prodserv = "";
2142 if (getDolGlobalString('PRODUCT_ADD_TYPE_IN_DOCUMENTS')) { // In standard mode, we do not show this
2143 if ($prodser->isService()) {
2144 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." ";
2145 } else {
2146 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." ";
2147 }
2148 }
2149
2150 if (empty($hideref)) {
2151 if ($issupplierline) {
2152 if (!getDolGlobalString('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES')) { // Common case
2153 $ref_prodserv = $prodser->ref; // Show local ref
2154 if ($ref_supplier) {
2155 $ref_prodserv .= ($prodser->ref ? ' (' : '').$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.($prodser->ref ? ')' : '');
2156 }
2157 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 1) {
2158 $ref_prodserv = $ref_supplier;
2159 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 2) {
2160 $ref_prodserv = $ref_supplier.' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')';
2161 }
2162 } else {
2163 $ref_prodserv = $prodser->ref; // Show local ref only
2164
2165 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
2166 $productCustomerPriceStatic = new ProductCustomerPrice($db);
2167 $filter = array('fk_product' => (string) $idprod, 'fk_soc' => (string) $object->socid);
2168
2169 $nbCustomerPrices = $productCustomerPriceStatic->fetchAll('', '', 1, 0, $filter);
2170
2171 if ($nbCustomerPrices > 0) {
2172 $productCustomerPrice = null;
2173 if (count($productCustomerPriceStatic->lines) > 0) {
2174 $date_now = (int) floor(dol_now() / 86400) * 86400; // date without hours
2175 foreach ($productCustomerPriceStatic->lines as $k => $custprice_line) {
2176 if ($custprice_line->date_begin <= $date_now && (empty($custprice_line->date_end) || $date_now <= $custprice_line->date_end)) {
2177 $productCustomerPrice = $custprice_line;
2178 break;
2179 }
2180 }
2181 }
2182
2183 if (isset($productCustomerPrice) && !empty($productCustomerPrice->ref_customer)) {
2184 $idcustprice = getDolGlobalInt('PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE');
2185 switch ($idcustprice) {
2186 case 1:
2187 $ref_prodserv = $productCustomerPrice->ref_customer;
2188 break;
2189
2190 case 2:
2191 $ref_prodserv = $productCustomerPrice->ref_customer . ' (' . $outputlangs->transnoentitiesnoconv('InternalRef') . ' ' . $ref_prodserv . ')';
2192 break;
2193
2194 default:
2195 $ref_prodserv = $ref_prodserv . ' (' . $outputlangs->transnoentitiesnoconv('RefCustomer') . ' ' . $productCustomerPrice->ref_customer . ')';
2196 }
2197 }
2198 }
2199 }
2200 }
2201
2202 if (!empty($libelleproduitservice) && !empty($ref_prodserv)) {
2203 $ref_prodserv .= " - ";
2204 }
2205 }
2206
2207 if (!empty($ref_prodserv) && getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
2208 if (!dol_textishtml($libelleproduitservice)) {
2209 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
2210 }
2211 $ref_prodserv = '<b>'.$ref_prodserv.'</b>';
2212 // $prefix_prodserv and $ref_prodser are not HTML var
2213 }
2214 $libelleproduitservice = $prefix_prodserv.$ref_prodserv.$libelleproduitservice;
2215
2216 // Add an additional description for the category products
2217 if (getDolGlobalString('CATEGORY_ADD_DESC_INTO_DOC') && $idprod && isModEnabled('category')) {
2218 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
2219 $categstatic = new Categorie($db);
2220 // recovering the list of all the categories linked to product
2221 $tblcateg = $categstatic->containing($idprod, Categorie::TYPE_PRODUCT);
2222 foreach ($tblcateg as $cate) {
2223 // Adding the descriptions if they are filled
2224 $desccateg = $cate->description;
2225 if ($desccateg) {
2226 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desccateg);
2227 }
2228 }
2229 }
2230
2231 if (!empty($object->lines[$i]->date_start) || !empty($object->lines[$i]->date_end)) {
2232 $format = 'day';
2233 $period = '';
2234 // Show duration if exists
2235 if ($object->lines[$i]->date_start && $object->lines[$i]->date_end) {
2236 $period = '('.$outputlangs->transnoentitiesnoconv('DateFromTo', dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs), dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
2237 }
2238 if ($object->lines[$i]->date_start && !$object->lines[$i]->date_end) {
2239 $period = '('.$outputlangs->transnoentitiesnoconv('DateFrom', dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs)).')';
2240 }
2241 if (!$object->lines[$i]->date_start && $object->lines[$i]->date_end) {
2242 $period = '('.$outputlangs->transnoentitiesnoconv('DateUntil', dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
2243 }
2244 //print '>'.$outputlangs->charset_output.','.$period;
2245 if (getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
2246 if (!dol_textishtml($libelleproduitservice)) {
2247 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
2248 }
2249 $libelleproduitservice .= '<br><b style="color:#333666;" ><em>'.$period.'</em></b>';
2250 } else {
2251 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $period);
2252 }
2253 //print $libelleproduitservice;
2254 }
2255
2256 // Show information for lot
2257 if (!empty($dbatch)) {
2258 // $object is a shipment.
2259 //var_dump($object->lines[$i]->details_entrepot); // array from llx_expeditiondet (we can have several lines for one fk_origin_line)
2260 //var_dump($object->lines[$i]->detail_batch); // array from llx_expeditiondet_batch (each line with a lot is linked to llx_expeditiondet)
2261
2262 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
2263 include_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
2264 $tmpwarehouse = new Entrepot($db);
2265 $tmpproductbatch = new Productbatch($db);
2266
2267 $format = 'day';
2268 foreach ($dbatch as $detail) {
2269 $dte = array();
2270 if ($detail->eatby) {
2271 $dte[] = $outputlangs->transnoentitiesnoconv('printEatby', dol_print_date($detail->eatby, $format, false, $outputlangs));
2272 }
2273 if ($detail->sellby) {
2274 $dte[] = $outputlangs->transnoentitiesnoconv('printSellby', dol_print_date($detail->sellby, $format, false, $outputlangs));
2275 }
2276 if ($detail->batch) {
2277 $dte[] = $outputlangs->transnoentitiesnoconv('printBatch', $detail->batch);
2278 }
2279 if ($detail->qty) {
2280 $dte[] = $outputlangs->transnoentitiesnoconv('printQty', (string) $detail->qty);
2281 }
2282
2283 // Add also info of planned warehouse for lot
2284 if ($object->element == 'shipping' && $detail->fk_origin_stock > 0 && getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
2285 $resproductbatch = $tmpproductbatch->fetch($detail->fk_origin_stock);
2286 if ($resproductbatch > 0) {
2287 $reswarehouse = $tmpwarehouse->fetch($tmpproductbatch->warehouseid);
2288 if ($reswarehouse > 0) {
2289 $dte[] = $tmpwarehouse->ref;
2290 }
2291 }
2292 }
2293
2294 $libelleproduitservice .= "__N__ ".implode(" - ", $dte);
2295 }
2296 } else {
2297 if (getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
2298 // TODO Show warehouse for shipment line without batch
2299 }
2300 }
2301
2302 // Now we convert \n into br
2303 if (dol_textishtml($libelleproduitservice)) {
2304 $libelleproduitservice = preg_replace('/__N__/', '<br>', $libelleproduitservice);
2305 } else {
2306 $libelleproduitservice = preg_replace('/__N__/', "\n", $libelleproduitservice);
2307 }
2308 $libelleproduitservice = dol_htmlentitiesbr($libelleproduitservice, 1);
2309
2310 return $libelleproduitservice;
2311}
2312
2322function pdf_getlinenum($object, $i, $outputlangs, $hidedetails = 0)
2323{
2324 global $hookmanager;
2325
2326 $reshook = 0;
2327 $result = '';
2328 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2329 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2330 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2331 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2332 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2333 }
2334 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2335 $action = '';
2336 $reshook = $hookmanager->executeHooks('pdf_getlinenum', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2337 $result .= $hookmanager->resPrint;
2338 }
2339 if (empty($reshook)) {
2340 $result .= dol_htmlentitiesbr($object->lines[$i]->num);
2341 }
2342 return $result;
2343}
2344
2345
2355function pdf_getlineref($object, $i, $outputlangs, $hidedetails = 0)
2356{
2357 global $hookmanager;
2358
2359 $reshook = 0;
2360 $result = '';
2361 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2362 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2363 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2364 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2365 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2366 }
2367 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2368 $action = '';
2369 $reshook = $hookmanager->executeHooks('pdf_getlineref', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2370 $result .= $hookmanager->resPrint;
2371 }
2372 if (empty($reshook)) {
2373 $result .= dol_htmlentitiesbr($object->lines[$i]->product_ref);
2374 }
2375 return $result;
2376}
2377
2378
2388function pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails = 0)
2389{
2390 global $hookmanager;
2391
2392 $reshook = 0;
2393 $result = '';
2394 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2395 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2396 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2397 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2398 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2399 }
2400 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2401 $action = '';
2402 $reshook = $hookmanager->executeHooks('pdf_getlineref_supplier', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2403 $result .= $hookmanager->resPrint;
2404 }
2405 if (empty($reshook)) {
2406 $result .= dol_htmlentitiesbr($object->lines[$i]->ref_supplier);
2407 }
2408 return $result;
2409}
2410
2420function pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails = 0)
2421{
2422 global $conf, $hookmanager, $mysoc;
2423
2424 $result = '';
2425 $reshook = 0;
2426 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2427 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2428 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2429 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2430 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2431 }
2432 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2433 $action = '';
2434 $reshook = $hookmanager->executeHooks('pdf_getlinevatrate', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2435
2436 if (!empty($hookmanager->resPrint)) {
2437 $result .= $hookmanager->resPrint;
2438 }
2439 }
2440 if (empty($reshook)) {
2441 if (empty($hidedetails) || $hidedetails > 1) {
2442 $tmpresult = '';
2443
2444 $tmpresult .= vatrate($object->lines[$i]->tva_tx, false, $object->lines[$i]->info_bits, -1);
2445 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_SECOND_TAX')) {
2446 if (price2num($object->lines[$i]->localtax1_tx)) {
2447 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
2448 $tmpresult .= '/';
2449 } else {
2450 $tmpresult = '';
2451 }
2452 $tmpresult .= vatrate((string) abs($object->lines[$i]->localtax1_tx), false);
2453 }
2454 }
2455 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_THIRD_TAX')) {
2456 if (price2num($object->lines[$i]->localtax2_tx)) {
2457 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
2458 $tmpresult .= '/';
2459 } else {
2460 $tmpresult = '';
2461 }
2462 $tmpresult .= vatrate((string) abs($object->lines[$i]->localtax2_tx), false);
2463 }
2464 }
2465 $tmpresult .= '%';
2466
2467 $result .= $tmpresult;
2468 }
2469 }
2470 return $result;
2471}
2472
2482function pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails = 0)
2483{
2484 global $hookmanager;
2485
2486 $sign = 1;
2487 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2488 $sign = -1;
2489 }
2490
2491 $result = '';
2492 $reshook = 0;
2493 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2494 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2495 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2496 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2497 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2498 }
2499 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2500 $action = '';
2501 $reshook = $hookmanager->executeHooks('pdf_getlineupexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2502
2503 if (!empty($hookmanager->resPrint)) {
2504 $result .= $hookmanager->resPrint;
2505 }
2506 }
2507 if (empty($reshook)) {
2508 if (empty($hidedetails) || $hidedetails > 1) {
2509 $subprice = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_subprice : $object->lines[$i]->subprice);
2510 $result .= price($sign * $subprice, 0, $outputlangs);
2511 }
2512 }
2513 return $result;
2514}
2515
2525function pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails = 0)
2526{
2527 global $hookmanager;
2528
2529 $sign = 1;
2530 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2531 $sign = -1;
2532 }
2533
2534 $result = '';
2535 $reshook = 0;
2536 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2537 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2538 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2539 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2540 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2541 }
2542 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2543 $action = '';
2544 $reshook = $hookmanager->executeHooks('pdf_getlineupwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2545
2546 if (!empty($hookmanager->resPrint)) {
2547 $result .= $hookmanager->resPrint;
2548 }
2549 }
2550 if (empty($reshook)) {
2551 if (empty($hidedetails) || $hidedetails > 1) {
2552 $result .= price($sign * (($object->lines[$i]->subprice) + ($object->lines[$i]->subprice) * ($object->lines[$i]->tva_tx) / 100), 0, $outputlangs);
2553 }
2554 }
2555 return $result;
2556}
2557
2567function pdf_getlineqty($object, $i, $outputlangs, $hidedetails = 0)
2568{
2569 global $hookmanager;
2570
2571 $result = '';
2572 $reshook = 0;
2573 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2574 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2575 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2576 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2577 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2578 }
2579 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2580 $action = '';
2581 $reshook = $hookmanager->executeHooks('pdf_getlineqty', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2582
2583 if (!empty($hookmanager->resPrint)) {
2584 $result = $hookmanager->resPrint;
2585 }
2586 }
2587 if (empty($reshook)) {
2588 if ($object->lines[$i]->special_code == 3) {
2589 return '';
2590 }
2591 if (empty($hidedetails) || $hidedetails > 1) {
2592 $result .= $object->lines[$i]->qty;
2593 }
2594 }
2595 return $result;
2596}
2597
2607function pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails = 0)
2608{
2609 global $hookmanager;
2610
2611 $reshook = 0;
2612 $result = '';
2613 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2614 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2615 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2616 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2617 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2618 }
2619 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2620 $action = '';
2621 $reshook = $hookmanager->executeHooks('pdf_getlineqty_asked', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2622
2623 if (!empty($hookmanager->resPrint)) {
2624 $result .= $hookmanager->resPrint;
2625 }
2626 }
2627 if (empty($reshook)) {
2628 if ($object->lines[$i]->special_code == 3) {
2629 return '';
2630 }
2631 if (empty($hidedetails) || $hidedetails > 1) {
2632 $result .= $object->lines[$i]->qty_asked;
2633 }
2634 }
2635 return $result;
2636}
2637
2647function pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails = 0)
2648{
2649 global $hookmanager;
2650
2651 $reshook = 0;
2652 $result = '';
2653 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2654 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2655 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2656 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2657 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2658 }
2659 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2660 $action = '';
2661 $reshook = $hookmanager->executeHooks('pdf_getlineqty_shipped', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2662
2663 if (!empty($hookmanager->resPrint)) {
2664 $result .= $hookmanager->resPrint;
2665 }
2666 }
2667 if (empty($reshook)) {
2668 if ($object->lines[$i]->special_code == 3) {
2669 return '';
2670 }
2671 if (empty($hidedetails) || $hidedetails > 1) {
2672 $result .= $object->lines[$i]->qty_shipped;
2673 }
2674 }
2675 return $result;
2676}
2677
2687function pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails = 0)
2688{
2689 global $hookmanager;
2690
2691 $reshook = 0;
2692 $result = '';
2693 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2694 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2695 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2696 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) { // @phan-suppress-current-line PhanUndeclaredProperty
2697 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2698 }
2699 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2700 $action = '';
2701 $reshook = $hookmanager->executeHooks('pdf_getlineqty_keeptoship', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2702
2703 if (!empty($hookmanager->resPrint)) {
2704 $result .= $hookmanager->resPrint;
2705 }
2706 }
2707 if (empty($reshook)) {
2708 if ($object->lines[$i]->special_code == 3) {
2709 return '';
2710 }
2711 if (empty($hidedetails) || $hidedetails > 1) {
2712 $result .= ($object->lines[$i]->qty_asked - $object->lines[$i]->qty_shipped);
2713 }
2714 }
2715 return $result;
2716}
2717
2727function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0)
2728{
2729 global $hookmanager;
2730
2731 $reshook = 0;
2732 $result = '';
2733 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2734 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2735 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2736 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2737 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2738 }
2739 $parameters = array(
2740 'i' => $i,
2741 'outputlangs' => $outputlangs,
2742 'hidedetails' => $hidedetails,
2743 'special_code' => $special_code
2744 );
2745 $action = '';
2746 $reshook = $hookmanager->executeHooks('pdf_getlineunit', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2747
2748 if (!empty($hookmanager->resPrint)) {
2749 $result .= $hookmanager->resPrint;
2750 }
2751 }
2752 if (empty($reshook)) {
2753 if (empty($hidedetails) || $hidedetails > 1) {
2754 $result .= $object->lines[$i]->getLabelOfUnit('short', $outputlangs, 1);
2755 }
2756 }
2757 return $result;
2758}
2759
2760
2770function pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails = 0)
2771{
2772 global $hookmanager;
2773
2774 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2775
2776 $reshook = 0;
2777 $result = '';
2778 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2779 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2780 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2781 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2782 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2783 }
2784 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2785 $action = '';
2786 $reshook = $hookmanager->executeHooks('pdf_getlineremisepercent', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2787
2788 if (!empty($hookmanager->resPrint)) {
2789 $result .= $hookmanager->resPrint;
2790 }
2791 }
2792 if (empty($reshook)) {
2793 if ($object->lines[$i]->special_code == 3) {
2794 return '';
2795 }
2796 if (empty($hidedetails) || $hidedetails > 1) {
2797 $result .= dol_print_reduction($object->lines[$i]->remise_percent, $outputlangs);
2798 }
2799 }
2800 return $result;
2801}
2802
2813function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = null)
2814{
2815 if (empty($hookmanager)) {
2816 global $hookmanager;
2817 }
2818
2819 $reshook = 0;
2820 $result = '';
2821 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2822 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2823 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2824 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2825 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2826 }
2827 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2828 $action = '';
2829 $reshook = $hookmanager->executeHooks('pdf_getlineprogress', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2830
2831 if (!empty($hookmanager->resPrint)) {
2832 return $hookmanager->resPrint;
2833 }
2834 }
2835 if (empty($reshook)) {
2836 if ($object->lines[$i]->special_code == 3) {
2837 return '';
2838 }
2839 if (empty($hidedetails) || $hidedetails > 1) {
2840 // 2 = situation_percent is non-cumulative (delta of current situation)
2841 // 1 = (old mode): situation_percent is cumulative (state at situation)
2842 $isCumulative = getDolGlobalInt('INVOICE_USE_SITUATION') === 1;
2843 $showDelta = (bool) getDolGlobalInt('SITUATION_DISPLAY_DIFF_ON_PDF');
2844
2845 if ($isCumulative xor $showDelta) {
2846 // Either:
2847 // - old mode and we want to show a total or
2848 // - new mode and we want to show a delta
2849 $result = $object->lines[$i]->situation_percent;
2850 } else {
2851 // Either:
2852 // - old mode but we want to show a delta or
2853 // - new mode but we want to show a total
2854 $prev_progress = 0;
2855 if ($isCumulative) {
2856 // old mode: the previous line already holds the running total
2857 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2858 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2859 }
2860 } else {
2861 // new mode: each line holds its own delta, so we must sum every previous one.
2862 // get_prev_progress() only reads the line pointed by fk_prev_id, which is the last
2863 // delta and not the accumulated progress, so it under-reports from the third
2864 // situation on. getAllPrevProgress() walks the whole fk_prev_id chain, and it is
2865 // what the screen uses to compute the same value.
2866 if (method_exists($object->lines[$i], 'getAllPrevProgress')) {
2867 $prev_progress = $object->lines[$i]->getAllPrevProgress($object->id);
2868 } elseif (method_exists($object->lines[$i], 'get_prev_progress')) {
2869 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2870 }
2871 }
2872 $result = $isCumulative ?
2873 // old mode: we need to compute the delta (total - sum of previous)
2874 $object->lines[$i]->situation_percent - $prev_progress :
2875 // new mode: we need to compute the total (sum of previous + delta)
2876 $prev_progress + $object->lines[$i]->situation_percent;
2877 }
2878 $result = round($result, 1).'%';
2879 }
2880 }
2881 return $result;
2882}
2883
2893function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0)
2894{
2895 global $hookmanager;
2896
2897 $sign = 1;
2898 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2899 $sign = -1;
2900 }
2901
2902 $reshook = 0;
2903 $result = '';
2904 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2905 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2906 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2907 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2908 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2909 }
2910 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code, 'sign' => $sign);
2911 $action = '';
2912 $reshook = $hookmanager->executeHooks('pdf_getlinetotalexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2913
2914 if (!empty($hookmanager->resPrint)) {
2915 $result .= $hookmanager->resPrint;
2916 }
2917 }
2918 if (empty($reshook)) {
2919 if (!empty($object->lines[$i]) && $object->lines[$i]->special_code == 3) {
2920 $result .= $outputlangs->transnoentities("Option");
2921 } elseif (empty($hidedetails) || $hidedetails > 1) {
2922 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht);
2923 if (!empty($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2924 if (method_exists($object->lines[$i], 'getSituationRatio')) {
2925 $total_ht *= $object->lines[$i]->getSituationRatio();
2926 }
2927 }
2928 $result .= price($sign * $total_ht, 0, $outputlangs);
2929 }
2930 }
2931 return $result;
2932}
2933
2943function pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails = 0)
2944{
2945 global $hookmanager;
2946
2947 $sign = 1;
2948 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2949 $sign = -1;
2950 }
2951
2952 $reshook = 0;
2953 $result = '';
2954 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2955 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
2956 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2957 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2958 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2959 }
2960 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2961 $action = '';
2962 $reshook = $hookmanager->executeHooks('pdf_getlinetotalwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2963
2964 if (!empty($hookmanager->resPrint)) {
2965 $result .= $hookmanager->resPrint;
2966 }
2967 }
2968 if (empty($reshook)) {
2969 if ($object->lines[$i]->special_code == 3) {
2970 $result .= $outputlangs->transnoentities("Option");
2971 } elseif (empty($hidedetails) || $hidedetails > 1) {
2972 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ttc : $object->lines[$i]->total_ttc);
2973 if (isset($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2974 $total_ttc *= $object->lines[$i]->getSituationRatio();
2975 }
2976 $result .= price($sign * $total_ttc, 0, $outputlangs);
2977 }
2978 }
2979 return $result;
2980}
2981
2992function canDisplayLinkedObjectInPDF($object, $elementobject)
2993{
2994 $objectSocId = getObjectSocId($object);
2995 $elementSocId = getObjectSocId($elementobject);
2996
2997 if (getDolGlobalBool("PDF_ALLOW_DISPLAY_LINKED_OBJECT_FOR_OTHER_SOC")) {
2998 return true;
2999 }
3000
3001 if (!empty($objectSocId) && !empty($elementSocId) && $objectSocId != $elementSocId) {
3002 return false;
3003 }
3004
3005 return true;
3006}
3007
3016function pdf_getLinkedObjects($object, $outputlangs)
3017{
3018 global $db, $hookmanager;
3019
3020 $linkedobjects = array();
3021
3022 $object->fetchObjectLinked();
3023
3024 foreach ($object->linkedObjects as $objecttype => $objects) {
3025 if ($objecttype == 'facture') {
3026 // For invoice, we don't want to have a reference line on document. Image we are using recurring invoice, we will have a line longer than document width.
3027 } elseif ($objecttype == 'propal' || $objecttype == 'supplier_proposal') {
3028 '@phan-var-force array<Propal|SupplierProposal> $objects';
3030 $outputlangs->load('propal');
3031
3032 foreach ($objects as $elementobject) {
3033 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefProposal");
3034 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
3035 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DatePropal");
3036 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
3037 }
3038 } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order' || $objecttype == 'order_supplier') {
3039 $optiontohidelinkedorders = "PDF_HIDE_LINKED_ORDERS_ON_SAME_THIRDPARTY";
3040 if ($objecttype == 'supplier_order' || $objecttype == 'order_supplier') {
3041 $optiontohidelinkedorders = "PDF_HIDE_LINKED_PURCHASE_ORDERS_ON_SAME_THIRDPARTY";
3042 }
3043 '@phan-var-force array<Commande|CommandeFournisseur> $objects';
3044 $outputlangs->load('orders');
3045
3046 if (count($objects) > 1 && count($objects) <= getDolGlobalInt("MAXREFONDOC", 10) && !getDolGlobalString($optiontohidelinkedorders)) {
3047 if (empty($object->context['DolPublicNoteAppendedGetLinkedObjects'])) { // Check if already appended before add to avoid repeat data
3048 $outputList = '';
3049 foreach ($objects as $elementobject) {
3050 if (canDisplayLinkedObjectInPDF($object, $elementobject)) {
3051 $outputList = dol_concatdesc($outputList, $outputlangs->transnoentities($elementobject->ref) . (empty($elementobject->ref_client) ? '' : ' (' . $elementobject->ref_client . ')') . (empty($elementobject->ref_supplier) ? '' : ' (' . $elementobject->ref_supplier . ')') . ' ');
3052 $outputList = dol_concatdesc($outputList, $outputlangs->transnoentities("OrderDate") . ' : ' . dol_print_date($elementobject->date, 'day', '', $outputlangs));
3053 }
3054 }
3055
3056 if (!empty($outputList)) {
3057 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' :');
3058 $object->note_public = dol_concatdesc($object->note_public, $outputList);
3059 }
3060 }
3061 } elseif (count($objects) == 1 && !getDolGlobalString($optiontohidelinkedorders)) {
3062 $elementobject = array_shift($objects);
3063 if (canDisplayLinkedObjectInPDF($object, $elementobject)) {
3064 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder");
3065 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref).(!empty($elementobject->ref_client) ? ' ('.$elementobject->ref_client.')' : '').(!empty($elementobject->ref_supplier) ? ' ('.$elementobject->ref_supplier.')' : '');
3066 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate");
3067 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
3068 }
3069 }
3070 } elseif ($objecttype == 'contrat') {
3071 '@phan-var-force Contrat[] $objects';
3072 $outputlangs->load('contracts');
3073 foreach ($objects as $elementobject) {
3074 if (canDisplayLinkedObjectInPDF($object, $elementobject)) {
3075 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefContract");
3076 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
3077 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateContract");
3078 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat, 'day', '', $outputlangs);
3079 }
3080 }
3081 } elseif ($objecttype == 'fichinter') {
3082 '@phan-var-force Fichinter[] $objects';
3083 $outputlangs->load('interventions');
3084 foreach ($objects as $elementobject) {
3085 if (canDisplayLinkedObjectInPDF($object, $elementobject)) {
3086 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("InterRef");
3087 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
3088 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("InterDate");
3089 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->datec, 'day', '', $outputlangs);
3090 }
3091 }
3092 } elseif ($objecttype == 'shipping') {
3093 '@phan-var-force Expedition[] $objects';
3094 $outputlangs->loadLangs(array("orders", "sendings"));
3095
3096 if (count($objects) > 1) {
3097 $order = null;
3098
3099 $refListsTxt = '';
3100 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') {
3101 $refListsTxt .= $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :';
3102 } else {
3103 $refListsTxt .= $outputlangs->transnoentities("RefSending").' :';
3104 }
3105 // We concat this record info into fields xxx_value. title is overwrote.
3106 foreach ($objects as $elementobject) {
3107 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') { // There is not already a link to order and object is not the order, so we show also info with order
3108 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
3109 if (!empty($elementobject->linkedObjectsIds['commande'])) {
3110 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
3111 $order = new Commande($db);
3112 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
3113 if ($ret < 1) {
3114 $order = null;
3115 }
3116 }
3117 }
3118 $refListsTxt .= (!empty($refListsTxt) ? ' ' : '');
3119 if (! is_object($order)) {
3120 $refListsTxt .= $outputlangs->transnoentities($elementobject->ref);
3121 } else {
3122 $refListsTxt .= $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
3123 $refListsTxt .= ' / '.$outputlangs->transnoentities($elementobject->ref);
3124 }
3125 }
3126
3127 if (empty($object->context['DolPublicNoteAppendedGetLinkedObjects']) && !getDolGlobalString("PDF_HIDE_LINKED_OBJECT_IN_PUBLIC_NOTE")) { // Check if already appended before add to avoid repeat data
3128 $object->note_public = dol_concatdesc($object->note_public, $refListsTxt);
3129 }
3130 } elseif (count($objects) == 1) {
3131 $elementobject = array_shift($objects);
3132 $order = null;
3133 // We concat this record info into fields xxx_value. title is overwrote.
3134 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') { // There is not already a link to order and object is not the order, so we show also info with order
3135 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
3136 if (!empty($elementobject->linkedObjectsIds['commande'])) {
3137 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
3138 $order = new Commande($db);
3139 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
3140 if ($ret < 1) {
3141 $order = null;
3142 }
3143 }
3144 }
3145
3146 if (! is_object($order)) {
3147 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
3148 if (empty($linkedobjects[$objecttype]['ref_value'])) {
3149 $linkedobjects[$objecttype]['ref_value'] = '';
3150 } else {
3151 $linkedobjects[$objecttype]['ref_value'] .= ' / ';
3152 }
3153 $linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref);
3154 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
3155 } else {
3156 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending");
3157 if (empty($linkedobjects[$objecttype]['ref_value'])) {
3158 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
3159 }
3160 $linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref);
3161 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
3162 }
3163 }
3164 }
3165 }
3166
3167 $object->context['DolPublicNoteAppendedGetLinkedObjects'] = 1;
3168
3169 // For add external linked objects
3170 if (is_object($hookmanager)) {
3171 $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs' => $outputlangs);
3172 $action = '';
3173 $reshook = $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
3174 if (empty($reshook)) {
3175 $linkedobjects = array_replace($linkedobjects, $hookmanager->resArray); // array_replace is used to preserve keys
3176 } elseif ($reshook > 0) {
3177 // The array must be reinserted even if it is empty because clearing the array could be one of the actions performed by the hook.
3178 $linkedobjects = $hookmanager->resArray;
3179 }
3180 }
3181
3182 return $linkedobjects;
3183}
3184
3192function pdf_getSizeForImage($realpath)
3193{
3194 $maxwidth = getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH', 20);
3195 $maxheight = getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT', 32);
3196
3197 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
3198 $tmp = dol_getImageSize($realpath);
3199 $width = 0;
3200 $height = 0;
3201 if ($tmp['height']) {
3202 $width = (int) round($maxheight * $tmp['width'] / $tmp['height']); // I try to use maxheight
3203 if ($width > $maxwidth) { // Pb with maxheight, so i use maxwidth
3204 $width = $maxwidth;
3205 $height = (int) round($maxwidth * $tmp['height'] / $tmp['width']);
3206 } else { // No pb with maxheight
3207 $height = $maxheight;
3208 }
3209 }
3210 return array('width' => $width, 'height' => $height);
3211}
3212
3224function pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails = 0, $multicurrency = 0)
3225{
3226 global $hookmanager;
3227
3228 $sign = 1;
3229 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
3230 $sign = -1;
3231 }
3232 if ($object->lines[$i]->special_code == 3) {
3233 // If option
3234 return $outputlangs->transnoentities("Option");
3235 } else {
3236 if (is_object($hookmanager)) {
3237 $special_code = $object->lines[$i]->special_code;
3238 if (!empty($object->lines[$i]->fk_parent_line)) {
3239 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
3240 }
3241
3242 $parameters = array(
3243 'i' => $i,
3244 'outputlangs' => $outputlangs,
3245 'hidedetails' => $hidedetails,
3246 'special_code' => $special_code,
3247 'multicurrency' => $multicurrency
3248 );
3249
3250 $action = '';
3251
3252 if ($hookmanager->executeHooks('getlinetotalremise', $parameters, $object, $action) > 0) { // Note that $action and $object may have been modified by some hooks
3253 if (isset($hookmanager->resArray['linetotalremise'])) {
3254 return (float) $hookmanager->resArray['linetotalremise'];
3255 } else {
3256 return (float) $hookmanager->resPrint; // For backward compatibility
3257 }
3258 }
3259 }
3260
3261 if (empty($hidedetails) || $hidedetails > 1) {
3262 if (empty($multicurrency)) {
3263 $diff = (float) price2num($sign * $object->lines[$i]->subprice * (float) $object->lines[$i]->qty, 'MT', 1) - $object->lines[$i]->total_ht;
3264 return (float) price2num($diff, 'MT', 1);
3265 } else {
3266 $diff = (float) price2num($sign * $object->lines[$i]->multicurrency_subprice * (float) $object->lines[$i]->qty, 'MT', 1) - $object->lines[$i]->multicurrency_total_ht;
3267 return (float) price2num($diff, 'MT', 1);
3268 }
3269 }
3270 }
3271 return 0;
3272}
3273
3281function pdfExtractMetadata($file, $field = 'Keywords')
3282{
3283 if (!dol_is_file($file)) {
3284 return "ERROR: FILE NOT FOUND OR NOT VALID";
3285 }
3286
3287 // Get content of PDF file
3288 $content = file_get_contents(dol_osencode($file));
3289
3290 // Use a regex to capture the metadata
3291 if ($content) {
3292 $matches = array();
3293
3294 // Remove non printablecaracters
3295 $content = preg_replace('/[^(\x20-\x7F)]*/', '', $content);
3296 if (preg_match('/\/' . preg_quote($field, '/') . '\s*\‍((.*?)\‍)/', $content, $matches)) {
3297 return trim($matches[1]);
3298 }
3299 return "ERROR: NOT FOUND";
3300 } else {
3301 return "ERROR: FAILED TO READ PDF";
3302 }
3303}
3304
3323 TCPDF $pdf,
3324 CommonDocGenerator $generator,
3325 float $curY,
3327 int $i,
3328 Translate $outputlangs,
3329 int $hideref,
3330 int $hidedesc,
3331 array $bgColor,
3332 bool $isSubtotal = false,
3333 bool $applySubtotalLogic = true
3334) {
3335 $savePage = $pdf->getPage();
3336 $saveX = $pdf->GetX();
3337 $prevAlign = $generator->cols['desc']['content']['align'];
3338
3339 if ($isSubtotal && $applySubtotalLogic && $object->lines[$i]->qty < 0) {
3340 $outputlangs->load("subtotals");
3341 $object->lines[$i]->desc = getDolGlobalString("SUBTOTAL_LINE_TEXT_DOES_NOT_INCLUDE_TITLE_TEXT") ? $outputlangs->trans("SubTotal") : $outputlangs->trans("SubtotalOf", $object->lines[$i]->desc);
3342 $generator->cols['desc']['content']['align'] = ($prevAlign === 'L') ? 'R' : 'L';
3343 }
3344
3345 $pdf->startTransaction();
3346 $pdf->SetXY($saveX, $curY);
3347 $generator->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
3348 $pageAfter = $pdf->getPage();
3349 $yAfter = $pdf->GetY();
3350 $pdf->rollbackTransaction(true);
3351
3352 $pdf->SetFillColor($bgColor[0], $bgColor[1], $bgColor[2]);
3353 $width = $generator->page_largeur - $generator->marge_droite - $generator->marge_gauche;
3354
3355 $pdf->SetXY($generator->marge_gauche, $curY);
3356 if ($pageAfter === $savePage) {
3357 $pdf->MultiCell($width, max(0, $yAfter - $curY), '', 0, '', true);
3358 } else {
3359 $pdf->MultiCell($width, $pdf->getPageHeight() - $pdf->getBreakMargin() - $curY, '', 0, '', true);
3360
3361 $pdf->setPage($pageAfter);
3362 $pdf->SetXY($generator->marge_gauche, $pdf->getMargins()['top']);
3363 $pdf->MultiCell($width, max(0, $yAfter - $pdf->getMargins()['top']), '', 0, '', true);
3364
3365 $pdf->setPage($savePage);
3366 }
3367
3368 $pdf->SetTextColor(colorIsLight(implode(',', $bgColor)));
3369 $pdf->SetXY($saveX, $curY);
3370 $generator->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
3371 $generator->setAfterColsLinePositionsData('desc', $pdf->GetY(), $pdf->getPage());
3372
3373 $generator->cols['desc']['content']['align'] = $prevAlign;
3374}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
pdfWriteBlockedLogSignature(&$pdf, $outputlangs, $page_height, $object, &$w, &$posx, &$posy)
Add some information from the blockedlog module.
pdfCertifMentionblockedLog(&$pdf, $outputlangs, $seller, $default_font_size, &$posy, $pdftemplate)
Add legal mention.
isALNERunningVersion($blockedlogtestalreadydone=0, $blockedlogmodulealreadydone=0)
Return if the application is executed with the LNE requirements on.
Class to manage categories.
Class to manage customers orders.
Parent class for documents (PDF, ODT, ...) generators.
printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref=0, $hidedesc=0, $issupplierline=0)
print description column content
setAfterColsLinePositionsData(string $colId, float $y, int $pageNumb)
Used for to set afterColsLinePositions var in a pdf draw line loop.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
Class to manage contact/addresses.
Class to manage absolute discounts.
Class to manage warehouses.
static getIBANLabel(Account $account)
Returns the name of the Iban label.
File of class to manage predefined price products or services by customer.
Class to manage predefined suppliers products.
Class to manage products or services.
Manage record for batch number management.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
getState($id, $withcode='0', $dbtouse=null, $withregion=0, $outputlangs=null, $entconv=1)
Return state translated from an id.
getFormeJuridiqueLabel($code)
Return the name translated of juridical status.
global $mysoc
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_is_file($pathoffile)
Return if path is a file.
dol_print_reduction($reduction, $langs)
Returns formatted reduction.
dol_getDefaultFormat($outputlangs=null)
Try to guess default paper format according to language into $langs.
dol_html_entity_decode($a, $b, $c='UTF-8', $keepsomeentities=0)
Replace html_entity_decode functions to manage errors.
dol_now($mode='gmt')
Return date for now.
getDolGlobalFloat($key, $default=0)
Return a Dolibarr global constant float value.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
dol_format_address($object, $withcountry=0, $sep="\n", $outputlangs=null, $mode=0, $extralangcode='')
Return a formatted address (part address/zip/town/state) according to country rules.
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
getObjectSocId($obj)
Get the socid of an object, supporting legacy attribute names.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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...
getDolCurrency()
Return the main currency ('EUR', 'USD', ...)
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...
dol_textishtml($msg, $option=0)
Return if a text is a html content.
colorIsLight($stringcolor)
Return true if the color is light.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalBool($key, $default=false)
Return a Dolibarr global constant boolean value.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add', $filterorigmodule='')
Complete or removed entries into a head array (used to build tabs).
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 a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
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)
dol_getImageSize($file, $url=false)
Return size of image file on disk (Supported extensions are gif, jpg, png, bmp and webp)
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:3192
pdf_watermark($pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition pdf.lib.php:1157
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2893
pdfCertifMention($pdf, $outputlangs, $seller, $default_font_size, &$posy, $pdftemplate)
Add legal certificate mention.
Definition pdf.lib.php:1221
pdf_getlinedesc($object, $i, $outputlangs, $hideref=0, $hidedesc=0, $issupplierline=0)
Return line description translated in outputlangs and encoded into htmlentities and with
Definition pdf.lib.php:1905
pdf_getFormat($outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:87
pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails=0, $multicurrency=0)
Return line total amount discount.
Definition pdf.lib.php:3224
pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1810
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:294
pdfExtractMetadata($file, $field='Keywords')
Function to extract metadata from a PDF file by doing a binary parsing of the PDF file.
Definition pdf.lib.php:3281
pdf_bank($pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank information for PDF generation.
Definition pdf.lib.php:1241
pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails=0)
Return line quantity shipped.
Definition pdf.lib.php:2647
pdf_getlinenum($object, $i, $outputlangs, $hidedetails=0)
Return line num.
Definition pdf.lib.php:2322
pdf_getEncryption($pathoffile)
Return if pdf file is protected/encrypted.
Definition pdf.lib.php:240
pdf_writelinedesc($pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref=0, $hidedesc=0, $issupplierline=0, $align='J')
Output line description into PDF.
Definition pdf.lib.php:1848
pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price including tax.
Definition pdf.lib.php:2525
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:317
pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails=0)
Return line ref_supplier.
Definition pdf.lib.php:2388
pdfWriteVATArray($docgenerator, &$index, $pdf, $outputlangs, $outputlangsbis, $object, $col1x, $col2x, $largcol2, $tab2_top, $tab2_hl)
Add some information from the blockedlog module.
Definition pdf.lib.php:812
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition pdf.lib.php:2943
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:2482
pdf_getlineprogress($object, $i, $outputlangs, $hidedetails=0, $hookmanager=null)
Return line percent.
Definition pdf.lib.php:2813
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:2420
pdf_admin_prepare_head()
Return array head with list of tabs to view object information.
Definition pdf.lib.php:49
canDisplayLinkedObjectInPDF($object, $elementobject)
Check if a linked object can be displayed based on third-party privacy rules.
Definition pdf.lib.php:2992
pdf_pagehead($pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition pdf.lib.php:749
pdfGetHeightForHtmlContent($pdf, $htmlcontent)
Function to try to calculate height of a HTML Content.
Definition pdf.lib.php:342
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:1423
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:273
pdf_render_subtotals(TCPDF $pdf, CommonDocGenerator $generator, float $curY, CommonObject $object, int $i, Translate $outputlangs, int $hideref, int $hidedesc, array $bgColor, bool $isSubtotal=false, bool $applySubtotalLogic=true)
Render subtotals line with a colored background and adapted text color .
Definition pdf.lib.php:3322
pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails=0)
Return line keep to ship quantity.
Definition pdf.lib.php:2687
pdf_getlineref($object, $i, $outputlangs, $hidedetails=0)
Return line product ref.
Definition pdf.lib.php:2355
pdfWriteAdditionnalTitle($pdf, $outputlangs, $page_height, $object, &$w, &$posx, &$posy)
Add some information from the blockedlog module.
Definition pdf.lib.php:787
pdfWriteAlreadyPaid($docgenerator, &$index, $pdf, $outputlangs, $outputlangsbis, $object, $col1x, $col2x, $largcol2, $tab2_top, $tab2_hl, $deja_regle, $creditnoteamount, $depositsamount, $resteapayer, $resteapayer_origin)
Add some information from the blockedlog module.
Definition pdf.lib.php:1052
pdf_build_address($outputlangs, $sourcecompany, $targetcompany='', $targetcontact='', $usecontact=0, $mode='source', $object=null)
Return a string with full address formatted for output on PDF documents.
Definition pdf.lib.php:438
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0)
Return line unit.
Definition pdf.lib.php:2727
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2770
pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails=0)
Return line quantity asked.
Definition pdf.lib.php:2607
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2567
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:1137
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:129
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition pdf.lib.php:393