dolibarr 22.0.5
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-2025 Frédéric France <frederic.france@free.fr>
18 * Copyright (C) 2024-2025 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("Parameters");
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("Others");
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') ? 'null' : $conf->global->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 if (getDolGlobalString('TCPDF_THROW_ERRORS_INSTEAD_OF_DIE')) {
166 define('K_TCPDF_THROW_EXCEPTION_ERROR', true);
167 } else {
168 define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
169 }
170 }
171
172 // Load TCPDF
173 require_once TCPDF_PATH.'tcpdf.php';
174
175 // We need to instantiate tcpdi object (instead of tcpdf) to use merging features. But we can disable it (this will break all merge features).
176 if (!getDolGlobalString('MAIN_DISABLE_TCPDI')) {
177 require_once TCPDI_PATH.'tcpdi.php';
178 }
179
180 //$arrayformat=pdf_getFormat();
181 //$format=array($arrayformat['width'],$arrayformat['height']);
182 //$metric=$arrayformat['unit'];
183
184 //$pdfa = false; // PDF default version
185 $pdfa = getDolGlobalInt('PDF_USE_A', 0); // PDF/A-1 ou PDF/A-3
186
187 if (!getDolGlobalString('MAIN_DISABLE_TCPDI') && class_exists('TCPDI')) {
188 $pdf = new TCPDI($pagetype, $metric, $format, true, 'UTF-8', false, $pdfa);
189 } else {
190 $pdf = new TCPDF($pagetype, $metric, $format, true, 'UTF-8', false, $pdfa);
191 }
192
193 // Protection and encryption of pdf
194 if (getDolGlobalString('PDF_SECURITY_ENCRYPTION')) {
195 /* Permission supported by TCPDF
196 - print : Print the document;
197 - modify : Modify the contents of the document by operations other than those controlled by 'fill-forms', 'extract' and 'assemble';
198 - copy : Copy or otherwise extract text and graphics from the document;
199 - 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);
200 - fill-forms : Fill in existing interactive form fields (including signature fields), even if 'annot-forms' is not specified;
201 - extract : Extract text and graphics (in support of accessibility to users with disabilities or for other purposes);
202 - assemble : Assemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even if 'modify' is not set;
203 - 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.
204 - owner : (inverted logic - only for public-key) when set permits change of encryption and enables all other permissions.
205 */
206
207 // For TCPDF, we specify permission we want to block
208 $pdfrights = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_RIGHTS') ? json_decode(getDolGlobalString('PDF_SECURITY_ENCRYPTION_RIGHTS'), true) : array('modify', 'copy')); // Json format in llx_const
209
210 // Password for the end user
211 $pdfuserpass = getDolGlobalString('PDF_SECURITY_ENCRYPTION_USERPASS');
212
213 // Password of the owner, created randomly if not defined
214 $pdfownerpass = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_OWNERPASS') ? getDolGlobalString('PDF_SECURITY_ENCRYPTION_OWNERPASS') : null);
215
216 // For encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit
217 $encstrength = getDolGlobalInt('PDF_SECURITY_ENCRYPTION_STRENGTH', 0);
218
219 // Array of recipients containing public-key certificates ('c') and permissions ('p').
220 // For example: array(array('c' => 'file://../examples/data/cert/tcpdf.crt', 'p' => array('print')))
221 $pubkeys = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_PUBKEYS') ? json_decode(getDolGlobalString('PDF_SECURITY_ENCRYPTION_PUBKEYS'), true) : null); // Json format in llx_const
222
223 $pdf->SetProtection($pdfrights, $pdfuserpass, $pdfownerpass, $encstrength, $pubkeys);
224 }
225
226 return $pdf;
227}
228
235function pdf_getEncryption($pathoffile)
236{
237 require_once TCPDF_PATH.'tcpdf_parser.php';
238
239 $isencrypted = false;
240
241 $content = file_get_contents($pathoffile);
242
243 //ob_start();
244 @($parser = new TCPDF_PARSER(ltrim($content)));
245 list($xref, $data) = $parser->getParsedData();
246 unset($parser);
247 //ob_end_clean();
248
249 if (isset($xref['trailer']['encrypt'])) {
250 $isencrypted = true; // Secured pdf file are currently not supported
251 }
252
253 if (empty($data)) {
254 $isencrypted = true; // Object list not found. Possible secured file
255 }
256
257 return $isencrypted;
258}
259
266function pdf_getPDFFont($outputlangs)
267{
268 global $conf;
269
270 if (getDolGlobalString('MAIN_PDF_FORCE_FONT')) {
271 return $conf->global->MAIN_PDF_FORCE_FONT;
272 }
273
274 $font = 'Helvetica'; // By default, for FPDI, or ISO language on TCPDF
275 if (class_exists('TCPDF')) { // If TCPDF on, we can use an UTF8 one like DejaVuSans if required (slower)
276 if ($outputlangs->trans('FONTFORPDF') != 'FONTFORPDF') {
277 $font = $outputlangs->trans('FONTFORPDF');
278 }
279 }
280 return $font;
281}
282
289function pdf_getPDFFontSize($outputlangs)
290{
291 global $conf;
292
293 $size = 10; // By default, for FPDI or ISO language on TCPDF
294 if (class_exists('TCPDF')) { // If TCPDF on, we can use an UTF8 font like DejaVuSans if required (slower)
295 if ($outputlangs->trans('FONTSIZEFORPDF') != 'FONTSIZEFORPDF') {
296 $size = (int) $outputlangs->trans('FONTSIZEFORPDF');
297 }
298 }
299 if (getDolGlobalString('MAIN_PDF_FORCE_FONT_SIZE')) {
300 $size = getDolGlobalString('MAIN_PDF_FORCE_FONT_SIZE');
301 }
302
303 return $size;
304}
305
306
314function pdf_getHeightForLogo($logo, $url = false)
315{
316 global $conf;
317 $height = (!getDolGlobalString('MAIN_DOCUMENTS_LOGO_HEIGHT') ? 20 : $conf->global->MAIN_DOCUMENTS_LOGO_HEIGHT);
318 $maxwidth = 130;
319 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
320 $tmp = dol_getImageSize($logo, $url);
321 if ($tmp['height']) {
322 $width = round($height * $tmp['width'] / $tmp['height']);
323 if ($width > $maxwidth) {
324 $height = $height * $maxwidth / $width;
325 }
326 }
327 //print $tmp['width'].' '.$tmp['height'].' '.$width; exit;
328 return $height;
329}
330
340function pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
341{
342 // store current object
343 $pdf->startTransaction();
344 // 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
345 // Another solution would be to do the test on another PDF instance with samefont, width...
346 $pdf->setY(0);
347 // store starting values
348 $start_y = $pdf->GetY();
349 //var_dump($start_y);
350 $start_page = $pdf->getPage();
351 // call printing functions with content
352 $pdf->writeHTMLCell(0, 0, 0, $start_y, $htmlcontent, 0, 1, false, true, 'J', true);
353 // get the new Y
354 $end_y = $pdf->GetY();
355 $end_page = $pdf->getPage();
356 // calculate height
357 $height = 0;
358 if ($end_page == $start_page) {
359 $height = $end_y - $start_y;
360 } else {
361 for ($page = $start_page; $page <= $end_page; ++$page) {
362 $pdf->setPage($page);
363 $tmpm = $pdf->getMargins();
364 $tMargin = $tmpm['top'];
365 if ($page == $start_page) {
366 // first page
367 $height = $pdf->getPageHeight() - $start_y - $pdf->getBreakMargin();
368 } elseif ($page == $end_page) {
369 // last page
370 $height = $end_y - $tMargin;
371 } else {
372 $height = $pdf->getPageHeight() - $tMargin - $pdf->getBreakMargin();
373 }
374 }
375 }
376 // restore previous object
377 $pdf = $pdf->rollbackTransaction();
378
379 return $height;
380}
381
382
391function pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias = 0)
392{
393 global $conf;
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
426
439function pdf_build_address($outputlangs, $sourcecompany, $targetcompany = '', $targetcontact = '', $usecontact = 0, $mode = 'source', $object = null)
440{
441 global $hookmanager;
442
443 if ($mode == 'source' && !is_object($sourcecompany)) {
444 return -1;
445 }
446 if ($mode == 'target' && !is_object($targetcompany)) {
447 return -1;
448 }
449
450 if (!empty($sourcecompany->state_id) && empty($sourcecompany->state)) {
451 $sourcecompany->state = getState($sourcecompany->state_id);
452 }
453 if (!empty($targetcompany->state_id) && empty($targetcompany->state)) {
454 $targetcompany->state = getState($targetcompany->state_id);
455 }
456
457 $reshook = 0;
458 $stringaddress = '';
459 if (is_object($hookmanager)) {
460 $parameters = array('sourcecompany' => &$sourcecompany, 'targetcompany' => &$targetcompany, 'targetcontact' => &$targetcontact, 'outputlangs' => $outputlangs, 'mode' => $mode, 'usecontact' => $usecontact);
461 $action = '';
462 // @phan-suppress-next-line PhanTypeMismatchArgumentNullable
463 $reshook = $hookmanager->executeHooks('pdf_build_address', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
464 $stringaddress .= $hookmanager->resPrint;
465 }
466 if (empty($reshook)) {
467 if ($mode == 'source') {
468 $withCountry = 0;
469 if (isset($targetcompany->country_code) && !empty($sourcecompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
470 $withCountry = 1;
471 }
472
473 $fulladdress = dol_format_address($sourcecompany, $withCountry, "\n", $outputlangs);
474 if ($fulladdress) {
475 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($fulladdress)."\n";
476 }
477
478 if (!getDolGlobalString('MAIN_PDF_DISABLESOURCEDETAILS')) {
479 // Phone
480 if ($sourcecompany->phone) {
481 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("PhoneShort").": ".$outputlangs->convToOutputCharset($sourcecompany->phone);
482 }
483 // Phone mobile
484 if ($sourcecompany->phone_mobile && getDolGlobalString('MAIN_PDF_SHOW_SOURCE_PHONE_MOBILE')) {
485 $stringaddress .= ($stringaddress ? ($sourcecompany->phone ? " - " : "\n") : '').$outputlangs->transnoentities("PhoneShort").": ".$outputlangs->convToOutputCharset($sourcecompany->phone_mobile);
486 }
487 // Fax
488 if ($sourcecompany->fax) {
489 $stringaddress .= ($stringaddress ? ($sourcecompany->phone ? " - " : "\n") : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($sourcecompany->fax);
490 }
491 // EMail
492 if ($sourcecompany->email) {
493 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($sourcecompany->email);
494 }
495 // Web
496 if ($sourcecompany->url) {
497 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($sourcecompany->url);
498 }
499 }
500 // Intra VAT
501 if (getDolGlobalString('MAIN_TVAINTRA_IN_SOURCE_ADDRESS')) {
502 if ($sourcecompany->tva_intra) {
503 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($sourcecompany->tva_intra);
504 }
505 }
506 // Professional Ids
507 $reg = array();
508 if (getDolGlobalString('MAIN_PROFID1_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof1)) {
509 $tmp = $outputlangs->transcountrynoentities("ProfId1", $sourcecompany->country_code);
510 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
511 $tmp = $reg[1];
512 }
513 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof1);
514 }
515 if (getDolGlobalString('MAIN_PROFID2_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof2)) {
516 $tmp = $outputlangs->transcountrynoentities("ProfId2", $sourcecompany->country_code);
517 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
518 $tmp = $reg[1];
519 }
520 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof2);
521 }
522 if (getDolGlobalString('MAIN_PROFID3_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof3)) {
523 $tmp = $outputlangs->transcountrynoentities("ProfId3", $sourcecompany->country_code);
524 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
525 $tmp = $reg[1];
526 }
527 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof3);
528 }
529 if (getDolGlobalString('MAIN_PROFID4_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof4)) {
530 $tmp = $outputlangs->transcountrynoentities("ProfId4", $sourcecompany->country_code);
531 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
532 $tmp = $reg[1];
533 }
534 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof4);
535 }
536 if (getDolGlobalString('MAIN_PROFID5_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof5)) {
537 $tmp = $outputlangs->transcountrynoentities("ProfId5", $sourcecompany->country_code);
538 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
539 $tmp = $reg[1];
540 }
541 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof5);
542 }
543 if (getDolGlobalString('MAIN_PROFID6_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof6)) {
544 $tmp = $outputlangs->transcountrynoentities("ProfId6", $sourcecompany->country_code);
545 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
546 $tmp = $reg[1];
547 }
548 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof6);
549 }
550 if (getDolGlobalString('PDF_ADD_MORE_AFTER_SOURCE_ADDRESS')) {
551 $stringaddress .= ($stringaddress ? "\n" : '') . getDolGlobalString('PDF_ADD_MORE_AFTER_SOURCE_ADDRESS');
552 }
553 }
554
555 if ($mode == 'target' || preg_match('/targetwithdetails/', $mode)) {
556 if ($usecontact && (is_object($targetcontact))) {
557 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($targetcontact->getFullName($outputlangs, 1));
558
559 if (!empty($targetcontact->address)) {
560 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcontact))."\n";
561 } elseif (is_object($targetcompany)) {
562 $companytouseforaddress = $targetcompany;
563
564 // Contact on a thirdparty that is a different thirdparty than the thirdparty of object
565 if ($targetcontact->socid > 0 && $targetcontact->socid != $targetcompany->id) {
566 $targetcontact->fetch_thirdparty();
567 $companytouseforaddress = $targetcontact->thirdparty;
568 }
569
570 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($companytouseforaddress))."\n";
571 }
572 // Country
573 if (!empty($targetcontact->country_code) && $targetcontact->country_code != $sourcecompany->country_code) {
574 $stringaddress .= (($stringaddress && !getDolGlobalString('MAIN_PDF_REMOVE_BREAK_BEFORE_COUNTRY')) ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcontact->country_code));
575 } elseif (empty($targetcontact->country_code) && !empty($targetcompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
576 $stringaddress .= (($stringaddress && !getDolGlobalString('MAIN_PDF_REMOVE_BREAK_BEFORE_COUNTRY')) ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
577 }
578
579 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
580 // Phone
581 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) {
582 if (!empty($targetcontact->phone_pro) || !empty($targetcontact->phone_mobile)) {
583 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": ";
584 }
585 if (!empty($targetcontact->phone_pro)) {
586 $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_pro);
587 }
588 if (!empty($targetcontact->phone_pro) && !empty($targetcontact->phone_mobile)) {
589 $stringaddress .= " / ";
590 }
591 if (!empty($targetcontact->phone_mobile)) {
592 $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_mobile);
593 }
594 }
595 // Fax
596 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) {
597 if ($targetcontact->fax) {
598 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcontact->fax);
599 }
600 }
601 // EMail
602 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) {
603 if ($targetcontact->email) {
604 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcontact->email);
605 }
606 }
607 // Web
608 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) {
609 if ($targetcontact->url) {
610 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset((string) $targetcontact->url);
611 }
612 }
613 }
614 } else {
615 if (is_object($targetcompany)) {
616 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcompany));
617 // Country
618 if (!empty($targetcompany->country_code) && $targetcompany->country_code != $sourcecompany->country_code) {
619 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
620 } else {
621 $stringaddress .= ($stringaddress ? "\n" : '');
622 }
623
624 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
625 // Phone
626 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) {
627 if (!empty($targetcompany->phone)) {
628 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": ";
629 }
630 if (!empty($targetcompany->phone)) {
631 $stringaddress .= $outputlangs->convToOutputCharset($targetcompany->phone);
632 }
633 }
634 // Fax
635 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) {
636 if ($targetcompany->fax) {
637 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcompany->fax);
638 }
639 }
640 // EMail
641 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) {
642 if ($targetcompany->email) {
643 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcompany->email);
644 }
645 }
646 // Web
647 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) {
648 if ($targetcompany->url) {
649 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcompany->url);
650 }
651 }
652 }
653 }
654 }
655
656 // Intra VAT
657 if (!getDolGlobalString('MAIN_TVAINTRA_NOT_IN_ADDRESS')) {
658 if ($usecontact && is_object($targetcontact) && getDolGlobalInt('MAIN_USE_COMPANY_NAME_OF_CONTACT')) {
659 $targetcontact->fetch_thirdparty();
660 if (!empty($targetcontact->thirdparty->id) && $targetcontact->thirdparty->tva_intra) {
661 $stringaddress .= ($stringaddress ? "\n" : '') . $outputlangs->transnoentities("VATIntraShort") . ': ' . $outputlangs->convToOutputCharset($targetcontact->thirdparty->tva_intra);
662 }
663 } elseif (!empty($targetcompany->tva_intra)) {
664 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($targetcompany->tva_intra);
665 }
666 }
667
668 // Legal form
669 if (getDolGlobalString('MAIN_LEGALFORM_IN_ADDRESS') && !empty($targetcompany->forme_juridique_code)) {
670 $tmp = getFormeJuridiqueLabel((string) $targetcompany->forme_juridique_code);
671 $stringaddress .= ($stringaddress ? "\n" : '').$tmp;
672 }
673
674 // Professional Ids
675 if (getDolGlobalString('MAIN_PROFID1_IN_ADDRESS') && !empty($targetcompany->idprof1)) {
676 $tmp = $outputlangs->transcountrynoentities("ProfId1", $targetcompany->country_code);
677 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
678 $tmp = $reg[1];
679 }
680 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof1);
681 }
682 if (getDolGlobalString('MAIN_PROFID2_IN_ADDRESS') && !empty($targetcompany->idprof2)) {
683 $tmp = $outputlangs->transcountrynoentities("ProfId2", $targetcompany->country_code);
684 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
685 $tmp = $reg[1];
686 }
687 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof2);
688 }
689 if (getDolGlobalString('MAIN_PROFID3_IN_ADDRESS') && !empty($targetcompany->idprof3)) {
690 $tmp = $outputlangs->transcountrynoentities("ProfId3", $targetcompany->country_code);
691 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
692 $tmp = $reg[1];
693 }
694 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof3);
695 }
696 if (getDolGlobalString('MAIN_PROFID4_IN_ADDRESS') && !empty($targetcompany->idprof4)) {
697 $tmp = $outputlangs->transcountrynoentities("ProfId4", $targetcompany->country_code);
698 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
699 $tmp = $reg[1];
700 }
701 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof4);
702 }
703 if (getDolGlobalString('MAIN_PROFID5_IN_ADDRESS') && !empty($targetcompany->idprof5)) {
704 $tmp = $outputlangs->transcountrynoentities("ProfId5", $targetcompany->country_code);
705 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
706 $tmp = $reg[1];
707 }
708 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof5);
709 }
710 if (getDolGlobalString('MAIN_PROFID6_IN_ADDRESS') && !empty($targetcompany->idprof6)) {
711 $tmp = $outputlangs->transcountrynoentities("ProfId6", $targetcompany->country_code);
712 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
713 $tmp = $reg[1];
714 }
715 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof6);
716 }
717
718 // Public note
719 if (getDolGlobalString('MAIN_PUBLIC_NOTE_IN_ADDRESS')) {
720 if ($mode == 'source' && !empty($sourcecompany->note_public)) {
721 $stringaddress .= ($stringaddress ? "\n" : '').dol_string_nohtmltag($sourcecompany->note_public);
722 }
723 if (($mode == 'target' || preg_match('/targetwithdetails/', $mode)) && !empty($targetcompany->note_public)) {
724 $stringaddress .= ($stringaddress ? "\n" : '').dol_string_nohtmltag($targetcompany->note_public);
725 }
726 }
727 }
728 }
729
730 return $stringaddress;
731}
732
733
742function pdf_pagehead(&$pdf, $outputlangs, $page_height)
743{
744 global $conf;
745
746 // Add a background image on document only if good setup of const
747 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
748 $filepath = $conf->mycompany->dir_output.'/logos/' . getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF');
749 if (file_exists($filepath)) {
750 $pdf->setAutoPageBreak(false, 0); // Disable auto pagebreak before adding image
751 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) {
752 $pdf->SetAlpha(getDolGlobalFloat('MAIN_USE_BACKGROUND_ON_PDF_ALPHA'));
753 } // Option for change opacity of background
754 $pdf->Image($filepath, getDolGlobalFloat('MAIN_USE_BACKGROUND_ON_PDF_X'), getDolGlobalFloat('MAIN_USE_BACKGROUND_ON_PDF_Y'), 0, $page_height);
755 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) {
756 $pdf->SetAlpha(1);
757 }
758 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
759 $pdf->setAutoPageBreak(true, 0); // Restore pagebreak
760 }
761 }
762 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') != '-1') {
763 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
764 }
765}
766
767
778function pdf_getSubstitutionArray($outputlangs, $exclude = null, $object = null, $onlykey = 0, $include = null)
779{
780 $substitutionarray = getCommonSubstitutionArray($outputlangs, $onlykey, $exclude, $object, $include);
781 $substitutionarray['__FROM_NAME__'] = '__FROM_NAME__';
782 $substitutionarray['__FROM_EMAIL__'] = '__FROM_EMAIL__';
783 return $substitutionarray;
784}
785
786
798function pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
799{
800 // Print Draft Watermark
801 if ($unit == 'pt') {
802 $k = 1;
803 } elseif ($unit == 'mm') {
804 $k = 72 / 25.4;
805 } elseif ($unit == 'cm') {
806 $k = 72 / 2.54;
807 } elseif ($unit == 'in') {
808 $k = 72;
809 } else {
810 $k = 1;
811 dol_print_error(null, 'Unexpected unit "'.$unit.'" for pdf_watermark');
812 }
813
814 // Make substitution
815 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, null);
816 complete_substitutions_array($substitutionarray, $outputlangs, null);
817 $text = make_substitutions($text, $substitutionarray, $outputlangs);
818 $text = $outputlangs->convToOutputCharset($text);
819
820 $savx = $pdf->getX();
821 $savy = $pdf->getY();
822
823 $watermark_angle = atan($h / $w) / 2;
824 $watermark_x_pos = 0;
825 $watermark_y_pos = $h / 3;
826 $watermark_x = $w / 2;
827 $watermark_y = $h / 3;
828 $pdf->SetFont('', 'B', 40);
829 $pdf->SetTextColor(255, 0, 0);
830
831 // rotate
832 $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));
833 // print watermark
834 $pdf->SetAlpha(0.5);
835 $pdf->SetXY($watermark_x_pos, $watermark_y_pos);
836
837 // set alpha to semi-transparency
838 $pdf->SetAlpha(0.3);
839 $pdf->Cell($w - 20, 25, $outputlangs->convToOutputCharset($text), "", 2, "C", false);
840
841 // antirotate
842 $pdf->_out('Q');
843
844 $pdf->SetXY($savx, $savy);
845
846 // Restore alpha
847 $pdf->SetAlpha(1);
848}
849
850
863function pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, $default_font_size = 10)
864{
865 global $mysoc, $conf;
866
867 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbank.class.php';
868
869 $diffsizetitle = getDolGlobalInt('PDF_DIFFSIZE_TITLE', 3);
870 $diffsizecontent = getDolGlobalInt('PDF_DIFFSIZE_CONTENT', 4);
871 $pdf->SetXY($curx, $cury);
872
873 if (empty($onlynumber)) {
874 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
875 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByTransferOnThisBankAccount').':', 0, 'L', false);
876 $cury += 4;
877 }
878
879 $outputlangs->load("banks");
880
881 // Use correct name of bank id according to country
882 $bickey = "BICNumber";
883 if ($account->getCountryCode() == 'IN') {
884 $bickey = "SWIFT";
885 }
886
887 // Get format of bank account according to its country
888 $usedetailedbban = $account->useDetailedBBAN();
889
890 //$onlynumber=0; $usedetailedbban=1; // For tests
891 if ($usedetailedbban) {
892 $savcurx = $curx;
893
894 if (empty($onlynumber)) {
895 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
896 $pdf->SetXY($curx, $cury);
897 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', false);
898 $cury += 3;
899 }
900
901 if (!getDolGlobalString('PDF_BANK_HIDE_NUMBER_SHOW_ONLY_BICIBAN')) { // Note that some countries still need bank number, BIC/IBAN not enough for them
902 // Note:
903 // bank = code_banque (FR), sort code (GB, IR. Example: 12-34-56)
904 // desk = code guichet (FR), used only when $usedetailedbban = 1
905 // number = account number
906 // key = check control key used only when $usedetailedbban = 1
907 if (empty($onlynumber)) {
908 $pdf->line($curx + 1, $cury + 1, $curx + 1, $cury + 6);
909 }
910
911 $bank_number_length = 0;
912 foreach ($account->getFieldsToShow() as $val) {
913 $pdf->SetXY($curx, $cury + 4);
914 $pdf->SetFont('', '', $default_font_size - 3);
915
916 if ($val == 'BankCode') {
917 // Bank code
918 $tmplength = 18;
919 $content = $account->code_banque;
920 } elseif ($val == 'DeskCode') {
921 // Desk
922 $tmplength = 18;
923 $content = $account->code_guichet;
924 } elseif ($val == 'BankAccountNumber') {
925 // Number
926 $tmplength = 24;
927 $content = $account->number;
928 } elseif ($val == 'BankAccountNumberKey') {
929 // Key
930 $tmplength = 15;
931 $content = $account->cle_rib;
932 } elseif ($val == 'IBAN' || $val == 'BIC') {
933 // Key
934 $tmplength = 0;
935 $content = '';
936 } else {
937 dol_print_error($account->db, 'Unexpected value for getFieldsToShow: '.$val);
938 break;
939 }
940
941 if ($content == '') {
942 continue;
943 }
944
945 $pdf->MultiCell($tmplength, 3, $outputlangs->convToOutputCharset($content), 0, 'C', false);
946 $pdf->SetXY($curx, $cury + 1);
947 $curx += $tmplength;
948 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
949 $pdf->MultiCell($tmplength, 3, $outputlangs->transnoentities($val), 0, 'C', false);
950 if (empty($onlynumber)) {
951 $pdf->line($curx, $cury + 1, $curx, $cury + 7);
952 }
953
954 // Only set this variable when table was printed
955 $bank_number_length = 8;
956 }
957
958 $curx = $savcurx;
959 $cury += $bank_number_length;
960 }
961 } elseif (!empty($account->number)) {
962 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
963 $pdf->SetXY($curx, $cury);
964 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', false);
965 $cury += 3;
966
967 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
968 $pdf->SetXY($curx, $cury);
969 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("BankAccountNumber").': '.$outputlangs->convToOutputCharset($account->number), 0, 'L', false);
970 $cury += 3;
971
972 if ($diffsizecontent <= 2) {
973 $cury += 1;
974 }
975 }
976
977 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
978
979 if (empty($onlynumber) && !empty($account->address)) {
980 $pdf->SetXY($curx, $cury);
981 $val = $outputlangs->transnoentities("Residence").': '.$outputlangs->convToOutputCharset($account->address);
982 $pdf->MultiCell(100, 3, $val, 0, 'L', false);
983 //$nboflines=dol_nboflines_bis($val,120);
984 //$cury+=($nboflines*3)+2;
985 $tmpy = $pdf->getStringHeight(100, $val);
986 $cury += $tmpy;
987 }
988
989 if (!empty($account->owner_name)) {
990 $pdf->SetXY($curx, $cury);
991 $val = $outputlangs->transnoentities("BankAccountOwner").': '.$outputlangs->convToOutputCharset($account->owner_name);
992 $pdf->MultiCell(100, 3, $val, 0, 'L', false);
993 $tmpy = $pdf->getStringHeight(100, $val);
994 $cury += $tmpy;
995 } elseif (!$usedetailedbban) {
996 $cury += 1;
997 }
998
999 // Use correct name of bank id according to country
1000 $ibankey = FormBank::getIBANLabel($account);
1001
1002 if (!empty($account->iban)) {
1003 //Remove whitespaces to ensure we are dealing with the format we expect
1004 $ibanDisplay_temp = str_replace(' ', '', $outputlangs->convToOutputCharset($account->iban));
1005 $ibanDisplay = "";
1006
1007 $nbIbanDisplay_temp = dol_strlen($ibanDisplay_temp);
1008 for ($i = 0; $i < $nbIbanDisplay_temp; $i++) {
1009 $ibanDisplay .= $ibanDisplay_temp[$i];
1010 if ($i % 4 == 3 && $i > 0) {
1011 $ibanDisplay .= " ";
1012 }
1013 }
1014
1015 $pdf->SetFont('', 'B', $default_font_size - 3);
1016 $pdf->SetXY($curx, $cury);
1017 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($ibankey).': '.$ibanDisplay, 0, 'L', false);
1018 $cury += 3;
1019 }
1020
1021 if (!empty($account->bic)) {
1022 $pdf->SetFont('', 'B', $default_font_size - 3);
1023 $pdf->SetXY($curx, $cury);
1024 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($bickey).': '.$outputlangs->convToOutputCharset($account->bic), 0, 'L', false);
1025 }
1026
1027 return $pdf->getY();
1028}
1029
1047function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails = 0, $hidefreetext = 0, $page_largeur = 0, $watermark = '')
1048{
1049 global $conf, $hookmanager;
1050
1051 $outputlangs->load("dict");
1052 $line = '';
1053 $reg = array();
1054 $marginwithfooter = 0; // Return value
1055
1056 $dims = $pdf->getPageDimensions();
1057
1058 // Line of free text
1059 if (empty($hidefreetext) && getDolGlobalString($paramfreetext)) {
1060 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
1061 // More substitution keys
1062 if (is_object($fromcompany)) {
1063 $substitutionarray['__FROM_NAME__'] = $fromcompany->name;
1064 $substitutionarray['__FROM_EMAIL__'] = $fromcompany->email;
1065 }
1066 complete_substitutions_array($substitutionarray, $outputlangs, $object);
1067 $newfreetext = make_substitutions(getDolGlobalString($paramfreetext), $substitutionarray, $outputlangs);
1068
1069 // Make a change into HTML code to allow to include images from medias directory.
1070 // <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1071 // become
1072 // <img alt="" src="'.DOL_DATA_ROOT.'/medias/image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1073 $newfreetext = preg_replace('/(<img.*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)("[^\/]*\/>)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $newfreetext);
1074
1075 $line .= $outputlangs->convToOutputCharset($newfreetext);
1076 }
1077
1078 // First line of company infos
1079 $line1 = "";
1080 $line2 = "";
1081 $line3 = "";
1082 $line4 = "";
1083
1084 if (is_object($fromcompany) && in_array($showdetails, array(1, 3))) {
1085 // Company name
1086 if ($fromcompany->name) {
1087 $line1 .= ($line1 ? " - " : "").$outputlangs->transnoentities("RegisteredOffice").": ".$fromcompany->name;
1088 }
1089 // Address
1090 if ($fromcompany->address) {
1091 $line1 .= ($line1 ? " - " : "").str_replace("\n", ", ", $fromcompany->address);
1092 }
1093 // Zip code
1094 if ($fromcompany->zip) {
1095 $line1 .= ($line1 ? " - " : "").$fromcompany->zip;
1096 }
1097 // Town
1098 if ($fromcompany->town) {
1099 $line1 .= ($line1 ? " " : "").$fromcompany->town;
1100 }
1101 // Country
1102 if ($fromcompany->country) {
1103 $line1 .= ($line1 ? ", " : "").$fromcompany->country;
1104 }
1105 // Phone
1106 if ($fromcompany->phone) {
1107 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Phone").": ".$fromcompany->phone;
1108 }
1109 // Fax
1110 if ($fromcompany->fax) {
1111 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Fax").": ".$fromcompany->fax;
1112 }
1113
1114 // URL
1115 if ($fromcompany->url) {
1116 $line2 .= ($line2 ? " - " : "").$fromcompany->url;
1117 }
1118 // Email
1119 if ($fromcompany->email) {
1120 $line2 .= ($line2 ? " - " : "").$fromcompany->email;
1121 }
1122 }
1123 if ($showdetails == 2 || $showdetails == 3 || (!empty($fromcompany->country_code) && $fromcompany->country_code == 'DE')) {
1124 // Managers
1125 if ($fromcompany->managers) {
1126 $line2 .= ($line2 ? " - " : "").$fromcompany->managers;
1127 }
1128 }
1129
1130 // Line 3 of company infos
1131 // Juridical status
1132 if (!empty($fromcompany->forme_juridique_code) && $fromcompany->forme_juridique_code) {
1133 $line3 .= ($line3 ? " - " : "").$outputlangs->convToOutputCharset(getFormeJuridiqueLabel((string) $fromcompany->forme_juridique_code));
1134 }
1135 // Capital
1136 if (!empty($fromcompany->capital)) {
1137 $tmpamounttoshow = price2num($fromcompany->capital); // This field is a free string or a float
1138 if (is_numeric($tmpamounttoshow) && $tmpamounttoshow > 0) {
1139 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", price($tmpamounttoshow, 0, $outputlangs, 0, 0, 0, $conf->currency));
1140 } elseif (!empty($fromcompany->capital)) {
1141 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", (string) $fromcompany->capital);
1142 }
1143 }
1144 // Prof Id 1
1145 if (!empty($fromcompany->idprof1) && $fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || !$fromcompany->idprof2)) {
1146 $field = $outputlangs->transcountrynoentities("ProfId1", $fromcompany->country_code);
1147 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1148 $field = $reg[1];
1149 }
1150 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof1);
1151 }
1152 // Prof Id 2
1153 if (!empty($fromcompany->idprof2) && $fromcompany->idprof2) {
1154 $field = $outputlangs->transcountrynoentities("ProfId2", $fromcompany->country_code);
1155 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1156 $field = $reg[1];
1157 }
1158 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof2);
1159 }
1160
1161 // Line 4 of company infos
1162 // Prof Id 3
1163 if (!empty($fromcompany->idprof3) && $fromcompany->idprof3) {
1164 $field = $outputlangs->transcountrynoentities("ProfId3", $fromcompany->country_code);
1165 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1166 $field = $reg[1];
1167 }
1168 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof3);
1169 }
1170 // Prof Id 4
1171 if (!empty($fromcompany->idprof4) && $fromcompany->idprof4) {
1172 $field = $outputlangs->transcountrynoentities("ProfId4", $fromcompany->country_code);
1173 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1174 $field = $reg[1];
1175 }
1176 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof4);
1177 }
1178 // Prof Id 5
1179 if (!empty($fromcompany->idprof5) && $fromcompany->idprof5) {
1180 $field = $outputlangs->transcountrynoentities("ProfId5", $fromcompany->country_code);
1181 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1182 $field = $reg[1];
1183 }
1184 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof5);
1185 }
1186 // Prof Id 6
1187 if (!empty($fromcompany->idprof6) && $fromcompany->idprof6) {
1188 $field = $outputlangs->transcountrynoentities("ProfId6", $fromcompany->country_code);
1189 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1190 $field = $reg[1];
1191 }
1192 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof6);
1193 }
1194 // Prof Id 7
1195 if (!empty($fromcompany->idprof7) && $fromcompany->idprof7) {
1196 $field = $outputlangs->transcountrynoentities("ProfId7", $fromcompany->country_code);
1197 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1198 $field = $reg[1];
1199 }
1200 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof7);
1201 }
1202 // Prof Id 8
1203 if (!empty($fromcompany->idprof8) && $fromcompany->idprof8) {
1204 $field = $outputlangs->transcountrynoentities("ProfId8", $fromcompany->country_code);
1205 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1206 $field = $reg[1];
1207 }
1208 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof8);
1209 }
1210 // Prof Id 9
1211 if (!empty($fromcompany->idprof9) && $fromcompany->idprof9) {
1212 $field = $outputlangs->transcountrynoentities("ProfId9", $fromcompany->country_code);
1213 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1214 $field = $reg[1];
1215 }
1216 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof9);
1217 }
1218 // Prof Id 10
1219 if (!empty($fromcompany->idprof10) && $fromcompany->idprof10) {
1220 $field = $outputlangs->transcountrynoentities("ProfId10", $fromcompany->country_code);
1221 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1222 $field = $reg[1];
1223 }
1224 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof10);
1225 }
1226 // IntraCommunautary VAT
1227 if (!empty($fromcompany->tva_intra) && $fromcompany->tva_intra != '') {
1228 $line4 .= ($line4 ? " - " : "").$outputlangs->transnoentities("VATIntraShort").": ".$outputlangs->convToOutputCharset($fromcompany->tva_intra);
1229 }
1230
1231 $pdf->SetFont('', '', 7);
1232 $pdf->SetDrawColor(224, 224, 224);
1233 // Option for footer text color
1234 if (getDolGlobalString('PDF_FOOTER_TEXT_COLOR')) {
1235 list($r, $g, $b) = sscanf(getDolGlobalString('PDF_FOOTER_TEXT_COLOR'), '%d, %d, %d');
1236 $pdf->SetTextColor($r, $g, $b);
1237 }
1238
1239 // The start of the bottom of this page footer is positioned according to # of lines
1240 $freetextheight = 0;
1241 $align = '';
1242 if ($line) { // Free text
1243 //$line="sample text<br>\nfd<strong>sf</strong>sdf<br>\nghfghg<br>";
1244 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) {
1245 $width = 20000;
1246 $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.
1247 if (getDolGlobalString('MAIN_USE_AUTOWRAP_ON_FREETEXT')) {
1248 $width = 200;
1249 $align = 'C';
1250 }
1251 $freetextheight = $pdf->getStringHeight($width, $line);
1252 } else {
1253 $freetextheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); // New method (works for HTML content)
1254 //print '<br>'.$freetextheight;
1255 }
1256 }
1257
1258 $posy = 0;
1259 // For customized footer
1260 if (is_object($hookmanager)) {
1261 $parameters = array('line1' => $line1, 'line2' => $line2, 'line3' => $line3, 'line4' => $line4, 'outputlangs' => $outputlangs);
1262 $action = '';
1263 $hookmanager->executeHooks('pdf_pagefoot', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1264 if (!empty($hookmanager->resPrint) && $hidefreetext == 0) {
1265 $mycustomfooter = $hookmanager->resPrint;
1266 $mycustomfooterheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1267
1268 $marginwithfooter = $marge_basse + $freetextheight + $mycustomfooterheight;
1269 $posy = (float) $marginwithfooter;
1270
1271 // Option for footer background color (without freetext zone)
1272 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1273 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1274 $pdf->setAutoPageBreak(false, 0); // Disable auto pagebreak
1275 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', array(), $fill_color = array($r, $g, $b));
1276 $pdf->setAutoPageBreak(true, 0); // Restore pagebreak
1277 }
1278
1279 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1280 $pdf->setAutoPageBreak(false, 0);
1281 } // Option for disable auto pagebreak
1282 if ($line) { // Free text
1283 $pdf->SetXY($dims['lm'], -$posy);
1284 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1285 $pdf->MultiCell(0, 3, $line, 0, $align, false);
1286 } else {
1287 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1288 }
1289 $posy -= $freetextheight;
1290 }
1291 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1292 $pdf->setAutoPageBreak(true, 0);
1293 } // Restore pagebreak
1294
1295 $pdf->SetY(-$posy);
1296
1297 // Hide footer line if footer background color is set
1298 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1299 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1300 }
1301
1302 // Option for set top margin height of footer after freetext
1303 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1304 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1305 } else {
1306 $posy--;
1307 }
1308
1309 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1310 $pdf->setAutoPageBreak(false, 0);
1311 } // Option for disable auto pagebreak
1312 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1313 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1314 $pdf->setAutoPageBreak(true, 0);
1315 } // Restore pagebreak
1316
1317 $posy -= $mycustomfooterheight - 3;
1318 } else {
1319 // Else default footer
1320 $marginwithfooter = $marge_basse + $freetextheight + (!empty($line1) ? 3 : 0) + (!empty($line2) ? 3 : 0) + (!empty($line3) ? 3 : 0) + (!empty($line4) ? 3 : 0);
1321 $posy = (float) $marginwithfooter;
1322
1323 // Option for footer background color (without freetext zone)
1324 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1325 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1326 $pdf->setAutoPageBreak(false, 0); // Disable auto pagebreak
1327 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', array(), $fill_color = array($r, $g, $b));
1328 $pdf->setAutoPageBreak(true, 0); // Restore pagebreak
1329 }
1330
1331 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1332 $pdf->setAutoPageBreak(false, 0);
1333 } // Option for disable auto pagebreak
1334 if ($line) { // Free text
1335 $pdf->SetXY($dims['lm'], -$posy);
1336 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1337 $pdf->MultiCell(0, 3, $line, 0, $align, false);
1338 } else {
1339 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1340 }
1341 $posy -= $freetextheight;
1342 }
1343 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1344 $pdf->setAutoPageBreak(true, 0);
1345 } // Restore pagebreak
1346
1347 $pdf->SetY(-$posy);
1348
1349 // Option for hide all footer (page number will no hidden)
1350 if (!getDolGlobalInt('PDF_FOOTER_HIDDEN')) {
1351 // Hide footer line if footer background color is set
1352 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1353 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1354 }
1355
1356 // Option for set top margin height of footer after freetext
1357 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1358 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1359 } else {
1360 $posy--;
1361 }
1362
1363 if (!empty($line1)) {
1364 $pdf->SetFont('', 'B', 7);
1365 $pdf->SetXY($dims['lm'], -$posy);
1366 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line1, 0, 'C', false);
1367 $posy -= 3;
1368 $pdf->SetFont('', '', 7);
1369 }
1370
1371 if (!empty($line2)) {
1372 $pdf->SetFont('', 'B', 7);
1373 $pdf->SetXY($dims['lm'], -$posy);
1374 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line2, 0, 'C', false);
1375 $posy -= 3;
1376 $pdf->SetFont('', '', 7);
1377 }
1378
1379 if (!empty($line3)) {
1380 $pdf->SetXY($dims['lm'], -$posy);
1381 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line3, 0, 'C', false);
1382 }
1383
1384 if (!empty($line4)) {
1385 $posy -= 3;
1386 $pdf->SetXY($dims['lm'], -$posy);
1387 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line4, 0, 'C', false);
1388 }
1389 }
1390 }
1391 }
1392
1393 // Show page nb and apply correction for some font.
1394 $pdf->SetXY($dims['wk'] - $dims['rm'] - 18 - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_X', 0), -$posy - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_Y', 0));
1395
1396 $pagination = $pdf->PageNo().' / '.$pdf->getAliasNbPages();
1397 $fontRenderCorrection = 0;
1398 if (in_array(pdf_getPDFFont($outputlangs), array('freemono', 'DejaVuSans'))) {
1399 $fontRenderCorrection = 10;
1400 }
1401 $pdf->MultiCell(18 + $fontRenderCorrection, 2, $pagination, 0, 'R', false);
1402
1403 // Show Draft Watermark
1404 if (!empty($watermark)) {
1405 pdf_watermark($pdf, $outputlangs, $page_hauteur, $page_largeur, 'mm', $watermark);
1406 }
1407
1408 return $marginwithfooter;
1409}
1410
1425function pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
1426{
1427 $linkedobjects = pdf_getLinkedObjects($object, $outputlangs); // May update $object->note_public
1428
1429 if (!empty($linkedobjects)) {
1430 foreach ($linkedobjects as $linkedobject) {
1431 $reftoshow = $linkedobject["ref_title"].' : '.$linkedobject["ref_value"];
1432 if (!empty($linkedobject["date_value"])) {
1433 $reftoshow .= ' / '.$linkedobject["date_value"];
1434 }
1435
1436 $posy += 3;
1437 $pdf->SetXY($posx, $posy);
1438 $pdf->SetFont('', '', (float) $default_font_size - 2);
1439 $pdf->MultiCell($w, $h, $reftoshow, '', $align);
1440 }
1441 }
1442
1443 return $pdf->getY();
1444}
1445
1463function pdf_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref = 0, $hidedesc = 0, $issupplierline = 0, $align = 'J')
1464{
1465 global $db, $conf, $langs, $hookmanager;
1466
1467 $reshook = 0;
1468 $result = '';
1469 //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) ) )
1470 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
1471 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1472 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1473 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1474 }
1475 $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);
1476 $action = '';
1477 // WARNING: A hook must not close/open the PDF transaction. Doing this generates a lot of trouble.
1478 // Test to know if content added by the hooks is already done by the main caller of pdf_writelinedesc
1479 $reshook = $hookmanager->executeHooks('pdf_writelinedesc', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1480
1481 if (!empty($hookmanager->resPrint)) {
1482 $result .= $hookmanager->resPrint;
1483 }
1484 }
1485 if (empty($reshook)) {
1486 $labelproductservice = pdf_getlinedesc($object, $i, $outputlangs, $hideref, $hidedesc, $issupplierline);
1487 $labelproductservice = preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $labelproductservice, -1, $nbrep);
1488
1489 //var_dump($labelproductservice);exit;
1490
1491 // 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"
1492 // We make the reverse, so PDF generation has the real URL.
1493 $nbrep = 0;
1494 $labelproductservice = preg_replace('/(<img[^>]*src=")([^"]*)(&amp;)([^"]*")/', '\1\2&\4', $labelproductservice, -1, $nbrep);
1495
1496 if (getDolGlobalString('MARGIN_TOP_ZERO_UL')) {
1497 $pdf->setListIndentWidth(5);
1498 $TMarginList = ['ul' => [['h' => 0.1, ],['h' => 0.1, ]], 'li' => [['h' => 0.1, ],],];
1499 $pdf->setHtmlVSpace($TMarginList);
1500 }
1501
1502 // Description
1503 $pdf->writeHTMLCell($w, $h, $posx, $posy, $outputlangs->convToOutputCharset($labelproductservice), 0, 1, false, true, $align, true);
1504 $result .= $labelproductservice;
1505 }
1506 return $result;
1507}
1508
1520function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1521{
1522 global $db, $conf, $langs;
1523
1524 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1525 $label = (!empty($object->lines[$i]->label) ? $object->lines[$i]->label : (!empty($object->lines[$i]->product_label) ? $object->lines[$i]->product_label : ''));
1526 $product_barcode = (!empty($object->lines[$i]->product_barcode) ? $object->lines[$i]->product_barcode : "");
1527 $desc = (!empty($object->lines[$i]->desc) ? $object->lines[$i]->desc : (!empty($object->lines[$i]->description) ? $object->lines[$i]->description : ''));
1528 $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
1529 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1530 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1531
1532 $multilangsactive = getDolGlobalInt('MAIN_MULTILANGS');
1533
1534 if ($issupplierline) {
1535 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
1536 $prodser = new ProductFournisseur($db);
1537 } else {
1538 include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1539 $prodser = new Product($db);
1540
1541 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
1542 include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
1543 }
1544 }
1545
1546 //id
1547 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1548 if ($idprod) {
1549 $prodser->fetch($idprod);
1550 //load multilangs
1551 if ($multilangsactive) {
1552 $prodser->getMultiLangs();
1553 $object->lines[$i]->multilangs = $prodser->multilangs;
1554 }
1555 }
1556 //label
1557 if (!empty($object->lines[$i]->label)) {
1558 $label = $object->lines[$i]->label;
1559 } else {
1560 if (!empty($object->lines[$i]->multilangs[$outputlangs->defaultlang]['label']) && $multilangsactive) {
1561 $label = $object->lines[$i]->multilangs[$outputlangs->defaultlang]['label'];
1562 } else {
1563 if (!empty($object->lines[$i]->product_label)) {
1564 $label = $object->lines[$i]->product_label;
1565 } else {
1566 $label = '';
1567 }
1568 }
1569 }
1570 //description
1571 if (!empty($object->lines[$i]->desc)) {
1572 $desc = $object->lines[$i]->desc;
1573 } else {
1574 if (!empty($object->lines[$i]->multilangs[$outputlangs->defaultlang]['description']) && $multilangsactive) {
1575 $desc = $object->lines[$i]->multilangs[$outputlangs->defaultlang]['description'];
1576 } else {
1577 if (!empty($object->lines[$i]->description)) {
1578 $desc = $object->lines[$i]->description;
1579 } else {
1580 $desc = '';
1581 }
1582 }
1583 }
1584 //ref supplier
1585 $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
1586 //note
1587 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1588 //dbatch
1589 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1590
1591 if ($idprod) {
1592 // If a predefined product and multilang and on other lang, we renamed label with label translated
1593 if ($multilangsactive && ($outputlangs->defaultlang != $langs->defaultlang)) {
1594 $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)
1595
1596 // 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
1597 // ($textwasnotmodified is replaced with $textwasmodifiedorcompleted and we add completion).
1598
1599 // Set label
1600 // 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.
1601 //var_dump($outputlangs->defaultlang.' - '.$langs->defaultlang.' - '.$label.' - '.$prodser->label);exit;
1602 $textwasnotmodified = ($label == $prodser->label);
1603 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["label"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1604 $label = $prodser->multilangs[$outputlangs->defaultlang]["label"];
1605 }
1606
1607 // Set desc
1608 // Manage HTML entities description test because $prodser->description is store with htmlentities but $desc no
1609 $textwasnotmodified = false;
1610 if (!empty($desc) && dol_textishtml($desc) && !empty($prodser->description) && dol_textishtml($prodser->description)) {
1611 $textwasnotmodified = (strpos(dol_html_entity_decode($desc, ENT_QUOTES | ENT_HTML5), dol_html_entity_decode($prodser->description, ENT_QUOTES | ENT_HTML5)) !== false);
1612 } else {
1613 $textwasnotmodified = ($desc == $prodser->description);
1614 }
1615 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["description"])) {
1616 if ($textwasnotmodified) {
1617 $desc = str_replace($prodser->description, $prodser->multilangs[$outputlangs->defaultlang]["description"], $desc);
1618 } elseif ($translatealsoifmodified) {
1619 $desc = $prodser->multilangs[$outputlangs->defaultlang]["description"];
1620 }
1621 }
1622
1623 // Set note
1624 $textwasnotmodified = ($note == $prodser->note_public);
1625 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["other"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1626 $note = $prodser->multilangs[$outputlangs->defaultlang]["other"];
1627 }
1628 }
1629 } 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
1630 $desc = str_replace('(DEPOSIT)', $outputlangs->trans('Deposit'), $desc);
1631 }
1632
1633 $libelleproduitservice = ''; // Default value
1634 if (!getDolGlobalString('PDF_HIDE_PRODUCT_LABEL_IN_SUPPLIER_LINES')) {
1635 // Description short of product line
1636 $libelleproduitservice = $label;
1637 if (!empty($libelleproduitservice) && getDolGlobalString('PDF_BOLD_PRODUCT_LABEL')) {
1638 // Adding <b> may convert the original string into a HTML string. So we have to first
1639 // convert \n into <br> we text is not already HTML.
1640 if (!dol_textishtml($libelleproduitservice)) {
1641 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1642 }
1643 $libelleproduitservice = '<b>'.$libelleproduitservice.'</b>';
1644 }
1645 }
1646
1647
1648 // Add ref of subproducts
1649 if (getDolGlobalString('SHOW_SUBPRODUCT_REF_IN_PDF')) {
1650 $prodser->get_sousproduits_arbo();
1651 if (!empty($prodser->sousprods) && is_array($prodser->sousprods) && count($prodser->sousprods)) {
1652 $outputlangs->load('mrp');
1653 $tmparrayofsubproducts = reset($prodser->sousprods);
1654
1655 $qtyText = null;
1656 if (isset($object->lines[$i]->qty) && !empty($object->lines[$i]->qty)) {
1657 $qtyText = $object->lines[$i]->qty;
1658 } elseif (isset($object->lines[$i]->qty_shipped) && !empty($object->lines[$i]->qty_shipped)) {
1659 $qtyText = $object->lines[$i]->qty;
1660 }
1661
1662 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF')) {
1663 foreach ($tmparrayofsubproducts as $subprodval) {
1664 $libelleproduitservice = dol_concatdesc(
1665 dol_concatdesc($libelleproduitservice, " * ".$subprodval[3]),
1666 (!empty($qtyText) ?
1667 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1] * $qtyText :
1668 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1669 );
1670 }
1671 } else {
1672 foreach ($tmparrayofsubproducts as $subprodval) {
1673 $libelleproduitservice = dol_concatdesc(
1674 dol_concatdesc($libelleproduitservice, " * ".$subprodval[5].(($subprodval[5] && $subprodval[3]) ? ' - ' : '').$subprodval[3]),
1675 (!empty($qtyText) ?
1676 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1] * $qtyText :
1677 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1678 );
1679 }
1680 }
1681 }
1682 }
1683
1684 if (isModEnabled('barcode') && getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_PRODUCT_BARCODE') && !empty($product_barcode)) {
1685 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $outputlangs->trans("BarCode")." ".$product_barcode);
1686 }
1687
1688 // Description long of product line
1689 if (!empty($desc) && ($desc != $label)) {
1690 if ($desc == '(CREDIT_NOTE)' && $object->lines[$i]->fk_remise_except) {
1691 $discount = new DiscountAbsolute($db);
1692 $discount->fetch($object->lines[$i]->fk_remise_except);
1693 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1694 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromCreditNote", $sourceref);
1695 } elseif ($desc == '(DEPOSIT)' && $object->lines[$i]->fk_remise_except) {
1696 $discount = new DiscountAbsolute($db);
1697 $discount->fetch($object->lines[$i]->fk_remise_except);
1698 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1699 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromDeposit", $sourceref);
1700 // Add date of deposit
1701 if (getDolGlobalString('INVOICE_ADD_DEPOSIT_DATE')) {
1702 $libelleproduitservice .= ' ('.dol_print_date($discount->datec, 'day', '', $outputlangs).')';
1703 }
1704 } elseif ($desc == '(EXCESS RECEIVED)' && $object->lines[$i]->fk_remise_except) {
1705 $discount = new DiscountAbsolute($db);
1706 $discount->fetch($object->lines[$i]->fk_remise_except);
1707 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived", $discount->ref_facture_source);
1708 } elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except) {
1709 $discount = new DiscountAbsolute($db);
1710 $discount->fetch($object->lines[$i]->fk_remise_except);
1711 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid", $discount->ref_invoice_supplier_source);
1712 } else {
1713 if ($idprod) {
1714 // Check if description must be output
1715 if (!empty($object->element)) {
1716 $tmpkey = 'MAIN_DOCUMENTS_HIDE_DESCRIPTION_FOR_'.strtoupper($object->element);
1717 if (getDolGlobalString($tmpkey)) {
1718 $hidedesc = 1;
1719 }
1720 }
1721 if (empty($hidedesc)) {
1722 if (getDolGlobalString('MAIN_DOCUMENTS_DESCRIPTION_FIRST')) {
1723 $libelleproduitservice = dol_concatdesc($desc, $libelleproduitservice);
1724 } else {
1725 if (getDolGlobalString('HIDE_LABEL_VARIANT_PDF') && $prodser->isVariant()) {
1726 $libelleproduitservice = $desc;
1727 } else {
1728 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1729 }
1730 }
1731 }
1732 } else {
1733 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1734 }
1735 }
1736 }
1737
1738 // We add ref of product (and supplier ref if defined)
1739 $prefix_prodserv = "";
1740 $ref_prodserv = "";
1741 if (getDolGlobalString('PRODUCT_ADD_TYPE_IN_DOCUMENTS')) { // In standard mode, we do not show this
1742 if ($prodser->isService()) {
1743 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." ";
1744 } else {
1745 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." ";
1746 }
1747 }
1748
1749 if (empty($hideref)) {
1750 if ($issupplierline) {
1751 if (!getDolGlobalString('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES')) { // Common case
1752 $ref_prodserv = $prodser->ref; // Show local ref
1753 if ($ref_supplier) {
1754 $ref_prodserv .= ($prodser->ref ? ' (' : '').$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.($prodser->ref ? ')' : '');
1755 }
1756 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 1) {
1757 $ref_prodserv = $ref_supplier;
1758 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 2) {
1759 $ref_prodserv = $ref_supplier.' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')';
1760 }
1761 } else {
1762 $ref_prodserv = $prodser->ref; // Show local ref only
1763
1764 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
1765 $productCustomerPriceStatic = new ProductCustomerPrice($db);
1766 $filter = array('fk_product' => (string) $idprod, 'fk_soc' => (string) $object->socid);
1767
1768 $nbCustomerPrices = $productCustomerPriceStatic->fetchAll('', '', 1, 0, $filter);
1769
1770 if ($nbCustomerPrices > 0) {
1771 $productCustomerPrice = null;
1772 if (count($productCustomerPriceStatic->lines) > 0) {
1773 $date_now = (int) floor(dol_now() / 86400) * 86400; // date without hours
1774 foreach ($productCustomerPriceStatic->lines as $k => $custprice_line) {
1775 if ($custprice_line->date_begin <= $date_now && (empty($custprice_line->date_end) || $date_now <= $custprice_line->date_end)) {
1776 $productCustomerPrice = $custprice_line;
1777 break;
1778 }
1779 }
1780 }
1781
1782 if (isset($productCustomerPrice) && !empty($productCustomerPrice->ref_customer)) {
1783 switch ($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
1784 case 1:
1785 $ref_prodserv = $productCustomerPrice->ref_customer;
1786 break;
1787
1788 case 2:
1789 $ref_prodserv = $productCustomerPrice->ref_customer . ' (' . $outputlangs->transnoentitiesnoconv('InternalRef') . ' ' . $ref_prodserv . ')';
1790 break;
1791
1792 default:
1793 $ref_prodserv = $ref_prodserv . ' (' . $outputlangs->transnoentitiesnoconv('RefCustomer') . ' ' . $productCustomerPrice->ref_customer . ')';
1794 }
1795 }
1796 }
1797 }
1798 }
1799
1800 if (!empty($libelleproduitservice) && !empty($ref_prodserv)) {
1801 $ref_prodserv .= " - ";
1802 }
1803 }
1804
1805 if (!empty($ref_prodserv) && getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1806 if (!dol_textishtml($libelleproduitservice)) {
1807 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1808 }
1809 $ref_prodserv = '<b>'.$ref_prodserv.'</b>';
1810 // $prefix_prodserv and $ref_prodser are not HTML var
1811 }
1812 $libelleproduitservice = $prefix_prodserv.$ref_prodserv.$libelleproduitservice;
1813
1814 // Add an additional description for the category products
1815 if (getDolGlobalString('CATEGORY_ADD_DESC_INTO_DOC') && $idprod && isModEnabled('category')) {
1816 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1817 $categstatic = new Categorie($db);
1818 // recovering the list of all the categories linked to product
1819 $tblcateg = $categstatic->containing($idprod, Categorie::TYPE_PRODUCT);
1820 foreach ($tblcateg as $cate) {
1821 // Adding the descriptions if they are filled
1822 $desccateg = $cate->description;
1823 if ($desccateg) {
1824 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desccateg);
1825 }
1826 }
1827 }
1828
1829 if (!empty($object->lines[$i]->date_start) || !empty($object->lines[$i]->date_end)) {
1830 $format = 'day';
1831 $period = '';
1832 // Show duration if exists
1833 if ($object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1834 $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)).')';
1835 }
1836 if ($object->lines[$i]->date_start && !$object->lines[$i]->date_end) {
1837 $period = '('.$outputlangs->transnoentitiesnoconv('DateFrom', dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs)).')';
1838 }
1839 if (!$object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1840 $period = '('.$outputlangs->transnoentitiesnoconv('DateUntil', dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
1841 }
1842 //print '>'.$outputlangs->charset_output.','.$period;
1843 if (getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1844 if (!dol_textishtml($libelleproduitservice)) {
1845 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1846 }
1847 $libelleproduitservice .= '<br><b style="color:#333666;" ><em>'.$period.'</em></b>';
1848 } else {
1849 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $period);
1850 }
1851 //print $libelleproduitservice;
1852 }
1853
1854 // Show information for lot
1855 if (!empty($dbatch)) {
1856 // $object is a shipment.
1857 //var_dump($object->lines[$i]->details_entrepot); // array from llx_expeditiondet (we can have several lines for one fk_origin_line)
1858 //var_dump($object->lines[$i]->detail_batch); // array from llx_expeditiondet_batch (each line with a lot is linked to llx_expeditiondet)
1859
1860 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1861 include_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
1862 $tmpwarehouse = new Entrepot($db);
1863 $tmpproductbatch = new Productbatch($db);
1864
1865 $format = 'day';
1866 foreach ($dbatch as $detail) {
1867 $dte = array();
1868 if ($detail->eatby) {
1869 $dte[] = $outputlangs->transnoentitiesnoconv('printEatby', dol_print_date($detail->eatby, $format, false, $outputlangs));
1870 }
1871 if ($detail->sellby) {
1872 $dte[] = $outputlangs->transnoentitiesnoconv('printSellby', dol_print_date($detail->sellby, $format, false, $outputlangs));
1873 }
1874 if ($detail->batch) {
1875 $dte[] = $outputlangs->transnoentitiesnoconv('printBatch', $detail->batch);
1876 }
1877 if ($detail->qty) {
1878 $dte[] = $outputlangs->transnoentitiesnoconv('printQty', (string) $detail->qty);
1879 }
1880
1881 // Add also info of planned warehouse for lot
1882 if ($object->element == 'shipping' && $detail->fk_origin_stock > 0 && getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1883 $resproductbatch = $tmpproductbatch->fetch($detail->fk_origin_stock);
1884 if ($resproductbatch > 0) {
1885 $reswarehouse = $tmpwarehouse->fetch($tmpproductbatch->warehouseid);
1886 if ($reswarehouse > 0) {
1887 $dte[] = $tmpwarehouse->ref;
1888 }
1889 }
1890 }
1891
1892 $libelleproduitservice .= "__N__ ".implode(" - ", $dte);
1893 }
1894 } else {
1895 if (getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1896 // TODO Show warehouse for shipment line without batch
1897 }
1898 }
1899
1900 // Now we convert \n into br
1901 if (dol_textishtml($libelleproduitservice)) {
1902 $libelleproduitservice = preg_replace('/__N__/', '<br>', $libelleproduitservice);
1903 } else {
1904 $libelleproduitservice = preg_replace('/__N__/', "\n", $libelleproduitservice);
1905 }
1906 $libelleproduitservice = dol_htmlentitiesbr($libelleproduitservice, 1);
1907
1908 return $libelleproduitservice;
1909}
1910
1920function pdf_getlinenum($object, $i, $outputlangs, $hidedetails = 0)
1921{
1922 global $hookmanager;
1923
1924 $reshook = 0;
1925 $result = '';
1926 //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) ) )
1927 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
1928 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1929 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1930 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1931 }
1932 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1933 $action = '';
1934 $reshook = $hookmanager->executeHooks('pdf_getlinenum', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1935 $result .= $hookmanager->resPrint;
1936 }
1937 if (empty($reshook)) {
1938 $result .= dol_htmlentitiesbr($object->lines[$i]->num);
1939 }
1940 return $result;
1941}
1942
1943
1953function pdf_getlineref($object, $i, $outputlangs, $hidedetails = 0)
1954{
1955 global $hookmanager;
1956
1957 $reshook = 0;
1958 $result = '';
1959 //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) ) )
1960 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
1961 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1962 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1963 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1964 }
1965 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1966 $action = '';
1967 $reshook = $hookmanager->executeHooks('pdf_getlineref', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1968 $result .= $hookmanager->resPrint;
1969 }
1970 if (empty($reshook)) {
1971 $result .= dol_htmlentitiesbr($object->lines[$i]->product_ref);
1972 }
1973 return $result;
1974}
1975
1976
1986function pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails = 0)
1987{
1988 global $hookmanager;
1989
1990 $reshook = 0;
1991 $result = '';
1992 //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) ) )
1993 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
1994 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1995 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1996 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1997 }
1998 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1999 $action = '';
2000 $reshook = $hookmanager->executeHooks('pdf_getlineref_supplier', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2001 $result .= $hookmanager->resPrint;
2002 }
2003 if (empty($reshook)) {
2004 $result .= dol_htmlentitiesbr($object->lines[$i]->ref_supplier);
2005 }
2006 return $result;
2007}
2008
2018function pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails = 0)
2019{
2020 global $conf, $hookmanager, $mysoc;
2021
2022 $result = '';
2023 $reshook = 0;
2024 //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) ) )
2025 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
2026 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2027 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2028 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2029 }
2030 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2031 $action = '';
2032 $reshook = $hookmanager->executeHooks('pdf_getlinevatrate', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2033
2034 if (!empty($hookmanager->resPrint)) {
2035 $result .= $hookmanager->resPrint;
2036 }
2037 }
2038 if (empty($reshook)) {
2039 if (empty($hidedetails) || $hidedetails > 1) {
2040 $tmpresult = '';
2041
2042 $tmpresult .= vatrate($object->lines[$i]->tva_tx, false, $object->lines[$i]->info_bits, -1);
2043 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_SECOND_TAX')) {
2044 if (price2num($object->lines[$i]->localtax1_tx)) {
2045 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
2046 $tmpresult .= '/';
2047 } else {
2048 $tmpresult = '';
2049 }
2050 $tmpresult .= vatrate((string) abs($object->lines[$i]->localtax1_tx), false);
2051 }
2052 }
2053 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_THIRD_TAX')) {
2054 if (price2num($object->lines[$i]->localtax2_tx)) {
2055 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
2056 $tmpresult .= '/';
2057 } else {
2058 $tmpresult = '';
2059 }
2060 $tmpresult .= vatrate((string) abs($object->lines[$i]->localtax2_tx), false);
2061 }
2062 }
2063 $tmpresult .= '%';
2064
2065 $result .= $tmpresult;
2066 }
2067 }
2068 return $result;
2069}
2070
2080function pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails = 0)
2081{
2082 global $conf, $hookmanager;
2083
2084 $sign = 1;
2085 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2086 $sign = -1;
2087 }
2088
2089 $result = '';
2090 $reshook = 0;
2091 //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) ) )
2092 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
2093 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2094 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2095 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2096 }
2097 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2098 $action = '';
2099 $reshook = $hookmanager->executeHooks('pdf_getlineupexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2100
2101 if (!empty($hookmanager->resPrint)) {
2102 $result .= $hookmanager->resPrint;
2103 }
2104 }
2105 if (empty($reshook)) {
2106 if (empty($hidedetails) || $hidedetails > 1) {
2107 $subprice = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_subprice : $object->lines[$i]->subprice);
2108 $result .= price($sign * $subprice, 0, $outputlangs);
2109 }
2110 }
2111 return $result;
2112}
2113
2123function pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails = 0)
2124{
2125 global $hookmanager, $conf;
2126
2127 $sign = 1;
2128 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2129 $sign = -1;
2130 }
2131
2132 $result = '';
2133 $reshook = 0;
2134 //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) ) )
2135 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
2136 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2137 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2138 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2139 }
2140 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2141 $action = '';
2142 $reshook = $hookmanager->executeHooks('pdf_getlineupwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2143
2144 if (!empty($hookmanager->resPrint)) {
2145 $result .= $hookmanager->resPrint;
2146 }
2147 }
2148 if (empty($reshook)) {
2149 if (empty($hidedetails) || $hidedetails > 1) {
2150 $result .= price($sign * (($object->lines[$i]->subprice) + ($object->lines[$i]->subprice) * ($object->lines[$i]->tva_tx) / 100), 0, $outputlangs);
2151 }
2152 }
2153 return $result;
2154}
2155
2165function pdf_getlineqty($object, $i, $outputlangs, $hidedetails = 0)
2166{
2167 global $hookmanager;
2168
2169 $result = '';
2170 $reshook = 0;
2171 //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) ) )
2172 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
2173 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2174 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2175 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2176 }
2177 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2178 $action = '';
2179 $reshook = $hookmanager->executeHooks('pdf_getlineqty', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2180
2181 if (!empty($hookmanager->resPrint)) {
2182 $result = $hookmanager->resPrint;
2183 }
2184 }
2185 if (empty($reshook)) {
2186 if ($object->lines[$i]->special_code == 3) {
2187 return '';
2188 }
2189 if (empty($hidedetails) || $hidedetails > 1) {
2190 $result .= $object->lines[$i]->qty;
2191 }
2192 }
2193 return $result;
2194}
2195
2205function pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails = 0)
2206{
2207 global $hookmanager;
2208
2209 $reshook = 0;
2210 $result = '';
2211 //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) ) )
2212 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
2213 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2214 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2215 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2216 }
2217 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2218 $action = '';
2219 $reshook = $hookmanager->executeHooks('pdf_getlineqty_asked', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2220
2221 if (!empty($hookmanager->resPrint)) {
2222 $result .= $hookmanager->resPrint;
2223 }
2224 }
2225 if (empty($reshook)) {
2226 if ($object->lines[$i]->special_code == 3) {
2227 return '';
2228 }
2229 if (empty($hidedetails) || $hidedetails > 1) {
2230 $result .= $object->lines[$i]->qty_asked;
2231 }
2232 }
2233 return $result;
2234}
2235
2245function pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails = 0)
2246{
2247 global $hookmanager;
2248
2249 $reshook = 0;
2250 $result = '';
2251 //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) ) )
2252 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
2253 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2254 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2255 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2256 }
2257 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2258 $action = '';
2259 $reshook = $hookmanager->executeHooks('pdf_getlineqty_shipped', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2260
2261 if (!empty($hookmanager->resPrint)) {
2262 $result .= $hookmanager->resPrint;
2263 }
2264 }
2265 if (empty($reshook)) {
2266 if ($object->lines[$i]->special_code == 3) {
2267 return '';
2268 }
2269 if (empty($hidedetails) || $hidedetails > 1) {
2270 $result .= $object->lines[$i]->qty_shipped;
2271 }
2272 }
2273 return $result;
2274}
2275
2285function pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails = 0)
2286{
2287 global $hookmanager;
2288
2289 $reshook = 0;
2290 $result = '';
2291 //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) ) )
2292 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
2293 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2294 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) { // @phan-suppress-current-line PhanUndeclaredProperty
2295 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2296 }
2297 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2298 $action = '';
2299 $reshook = $hookmanager->executeHooks('pdf_getlineqty_keeptoship', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2300
2301 if (!empty($hookmanager->resPrint)) {
2302 $result .= $hookmanager->resPrint;
2303 }
2304 }
2305 if (empty($reshook)) {
2306 if ($object->lines[$i]->special_code == 3) {
2307 return '';
2308 }
2309 if (empty($hidedetails) || $hidedetails > 1) {
2310 $result .= ($object->lines[$i]->qty_asked - $object->lines[$i]->qty_shipped);
2311 }
2312 }
2313 return $result;
2314}
2315
2325function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0)
2326{
2327 global $hookmanager;
2328
2329 $reshook = 0;
2330 $result = '';
2331 //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) ) )
2332 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
2333 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2334 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2335 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2336 }
2337 $parameters = array(
2338 'i' => $i,
2339 'outputlangs' => $outputlangs,
2340 'hidedetails' => $hidedetails,
2341 'special_code' => $special_code
2342 );
2343 $action = '';
2344 $reshook = $hookmanager->executeHooks('pdf_getlineunit', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2345
2346 if (!empty($hookmanager->resPrint)) {
2347 $result .= $hookmanager->resPrint;
2348 }
2349 }
2350 if (empty($reshook)) {
2351 if (empty($hidedetails) || $hidedetails > 1) {
2352 $result .= $object->lines[$i]->getLabelOfUnit('short', $outputlangs, 1);
2353 }
2354 }
2355 return $result;
2356}
2357
2358
2368function pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails = 0)
2369{
2370 global $hookmanager;
2371
2372 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2373
2374 $reshook = 0;
2375 $result = '';
2376 //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) ) )
2377 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
2378 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2379 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2380 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2381 }
2382 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2383 $action = '';
2384 $reshook = $hookmanager->executeHooks('pdf_getlineremisepercent', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2385
2386 if (!empty($hookmanager->resPrint)) {
2387 $result .= $hookmanager->resPrint;
2388 }
2389 }
2390 if (empty($reshook)) {
2391 if ($object->lines[$i]->special_code == 3) {
2392 return '';
2393 }
2394 if (empty($hidedetails) || $hidedetails > 1) {
2395 $result .= dol_print_reduction($object->lines[$i]->remise_percent, $outputlangs);
2396 }
2397 }
2398 return $result;
2399}
2400
2411function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = null)
2412{
2413 if (empty($hookmanager)) {
2414 global $hookmanager;
2415 }
2416 global $conf;
2417
2418 $reshook = 0;
2419 $result = '';
2420 //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) ) )
2421 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
2422 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2423 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2424 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2425 }
2426 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2427 $action = '';
2428 $reshook = $hookmanager->executeHooks('pdf_getlineprogress', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2429
2430 if (!empty($hookmanager->resPrint)) {
2431 return $hookmanager->resPrint;
2432 }
2433 }
2434 if (empty($reshook)) {
2435 if ($object->lines[$i]->special_code == 3) {
2436 return '';
2437 }
2438 if (empty($hidedetails) || $hidedetails > 1) {
2439 if (getDolGlobalString('SITUATION_DISPLAY_DIFF_ON_PDF')) {
2440 $prev_progress = 0;
2441 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2442 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2443 }
2444 $result = round($object->lines[$i]->situation_percent - $prev_progress, 1).'%';
2445 } else {
2446 $result = round($object->lines[$i]->situation_percent, 1).'%';
2447 }
2448 }
2449 }
2450 return $result;
2451}
2452
2462function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0)
2463{
2464 global $conf, $hookmanager;
2465
2466 $sign = 1;
2467 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2468 $sign = -1;
2469 }
2470
2471 $reshook = 0;
2472 $result = '';
2473 //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) ) )
2474 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
2475 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2476 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2477 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2478 }
2479 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code, 'sign' => $sign);
2480 $action = '';
2481 $reshook = $hookmanager->executeHooks('pdf_getlinetotalexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2482
2483 if (!empty($hookmanager->resPrint)) {
2484 $result .= $hookmanager->resPrint;
2485 }
2486 }
2487 if (empty($reshook)) {
2488 if (!empty($object->lines[$i]) && $object->lines[$i]->special_code == 3) {
2489 $result .= $outputlangs->transnoentities("Option");
2490 } elseif (empty($hidedetails) || $hidedetails > 1) {
2491 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht);
2492 if (!empty($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2493 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2494 $prev_progress = 0;
2495 $progress = 1;
2496 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2497 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2498 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2499 }
2500 $result .= price($sign * ($total_ht / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2501 } else {
2502 $result .= price($sign * $total_ht, 0, $outputlangs);
2503 }
2504 }
2505 }
2506 return $result;
2507}
2508
2518function pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails = 0)
2519{
2520 global $hookmanager, $conf;
2521
2522 $sign = 1;
2523 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2524 $sign = -1;
2525 }
2526
2527 $reshook = 0;
2528 $result = '';
2529 //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) ) )
2530 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
2531 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2532 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2533 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2534 }
2535 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2536 $action = '';
2537 $reshook = $hookmanager->executeHooks('pdf_getlinetotalwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2538
2539 if (!empty($hookmanager->resPrint)) {
2540 $result .= $hookmanager->resPrint;
2541 }
2542 }
2543 if (empty($reshook)) {
2544 if ($object->lines[$i]->special_code == 3) {
2545 $result .= $outputlangs->transnoentities("Option");
2546 } elseif (empty($hidedetails) || $hidedetails > 1) {
2547 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ttc : $object->lines[$i]->total_ttc);
2548 if (isset($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2549 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2550 $prev_progress = 0;
2551 $progress = 1;
2552 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2553 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2554 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2555 }
2556 $result .= price($sign * ($total_ttc / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2557 } else {
2558 $result .= price($sign * $total_ttc, 0, $outputlangs);
2559 }
2560 }
2561 }
2562 return $result;
2563}
2564
2573function pdf_getLinkedObjects(&$object, $outputlangs)
2574{
2575 global $db, $hookmanager;
2576
2577 $linkedobjects = array();
2578
2579 $object->fetchObjectLinked();
2580
2581 foreach ($object->linkedObjects as $objecttype => $objects) {
2582 if ($objecttype == 'facture') {
2583 // 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.
2584 } elseif ($objecttype == 'propal' || $objecttype == 'supplier_proposal') {
2585 '@phan-var-force array<Propal|SupplierProposal> $objects';
2586 $outputlangs->load('propal');
2587
2588 foreach ($objects as $elementobject) {
2589 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefProposal");
2590 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2591 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DatePropal");
2592 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2593 }
2594 } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order' || $objecttype == 'order_supplier') {
2595 '@phan-var-force array<Commande|CommandeFournisseur> $objects';
2596 $outputlangs->load('orders');
2597
2598 if (count($objects) > 1 && count($objects) <= getDolGlobalInt("MAXREFONDOC", 10) && !getDolGlobalString("PDF_HIDE_LINKED_OBJECT_IN_PUBLIC_NOTE")) {
2599 if (empty($object->context['DolPublicNoteAppendedGetLinkedObjects'])) { // Check if already appended before add to avoid repeat data
2600 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' :');
2601 foreach ($objects as $elementobject) {
2602 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref).(empty($elementobject->ref_client) ? '' : ' ('.$elementobject->ref_client.')').(empty($elementobject->ref_supplier) ? '' : ' ('.$elementobject->ref_supplier.')').' ');
2603 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("OrderDate").' : '.dol_print_date($elementobject->date, 'day', '', $outputlangs));
2604 }
2605 }
2606 } elseif (count($objects) == 1) {
2607 $elementobject = array_shift($objects);
2608 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder");
2609 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref).(!empty($elementobject->ref_client) ? ' ('.$elementobject->ref_client.')' : '').(!empty($elementobject->ref_supplier) ? ' ('.$elementobject->ref_supplier.')' : '');
2610 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate");
2611 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2612 }
2613 } elseif ($objecttype == 'contrat') {
2614 '@phan-var-force Contrat[] $objects';
2615 $outputlangs->load('contracts');
2616 foreach ($objects as $elementobject) {
2617 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefContract");
2618 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2619 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateContract");
2620 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat, 'day', '', $outputlangs);
2621 }
2622 } elseif ($objecttype == 'fichinter') {
2623 '@phan-var-force Fichinter[] $objects';
2624 $outputlangs->load('interventions');
2625 foreach ($objects as $elementobject) {
2626 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("InterRef");
2627 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2628 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("InterDate");
2629 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->datec, 'day', '', $outputlangs);
2630 }
2631 } elseif ($objecttype == 'shipping') {
2632 '@phan-var-force Expedition[] $objects';
2633 $outputlangs->loadLangs(array("orders", "sendings"));
2634
2635 if (count($objects) > 1) {
2636 $order = null;
2637
2638 $refListsTxt = '';
2639 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') {
2640 $refListsTxt .= $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :';
2641 } else {
2642 $refListsTxt .= $outputlangs->transnoentities("RefSending").' :';
2643 }
2644 // We concat this record info into fields xxx_value. title is overwrote.
2645 foreach ($objects as $elementobject) {
2646 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
2647 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2648 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2649 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2650 $order = new Commande($db);
2651 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2652 if ($ret < 1) {
2653 $order = null;
2654 }
2655 }
2656 }
2657 $refListsTxt .= (!empty($refListsTxt) ? ' ' : '');
2658 if (! is_object($order)) {
2659 $refListsTxt .= $outputlangs->transnoentities($elementobject->ref);
2660 } else {
2661 $refListsTxt .= $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
2662 $refListsTxt .= ' / '.$outputlangs->transnoentities($elementobject->ref);
2663 }
2664 }
2665
2666 if (empty($object->context['DolPublicNoteAppendedGetLinkedObjects']) && !getDolGlobalString("PDF_HIDE_LINKED_OBJECT_IN_PUBLIC_NOTE")) { // Check if already appended before add to avoid repeat data
2667 $object->note_public = dol_concatdesc($object->note_public, $refListsTxt);
2668 }
2669 } elseif (count($objects) == 1) {
2670 $elementobject = array_shift($objects);
2671 $order = null;
2672 // We concat this record info into fields xxx_value. title is overwrote.
2673 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
2674 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2675 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2676 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2677 $order = new Commande($db);
2678 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2679 if ($ret < 1) {
2680 $order = null;
2681 }
2682 }
2683 }
2684
2685 if (! is_object($order)) {
2686 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
2687 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2688 $linkedobjects[$objecttype]['ref_value'] = '';
2689 } else {
2690 $linkedobjects[$objecttype]['ref_value'] .= ' / ';
2691 }
2692 $linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref);
2693 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2694 } else {
2695 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending");
2696 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2697 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
2698 }
2699 $linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref);
2700 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2701 }
2702 }
2703 }
2704 }
2705
2706 $object->context['DolPublicNoteAppendedGetLinkedObjects'] = 1;
2707
2708 // For add external linked objects
2709 if (is_object($hookmanager)) {
2710 $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs' => $outputlangs);
2711 $action = '';
2712 $reshook = $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2713 if (empty($reshook)) {
2714 $linkedobjects = array_replace($linkedobjects, $hookmanager->resArray); // array_replace is used to preserve keys
2715 } elseif ($reshook > 0) {
2716 // The array must be reinserted even if it is empty because clearing the array could be one of the actions performed by the hook.
2717 $linkedobjects = $hookmanager->resArray;
2718 }
2719 }
2720
2721 return $linkedobjects;
2722}
2723
2731function pdf_getSizeForImage($realpath)
2732{
2733 $maxwidth = getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH', 20);
2734 $maxheight = getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT', 32);
2735
2736 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2737 $tmp = dol_getImageSize($realpath);
2738 $width = 0;
2739 $height = 0;
2740 if ($tmp['height']) {
2741 $width = (int) round($maxheight * $tmp['width'] / $tmp['height']); // I try to use maxheight
2742 if ($width > $maxwidth) { // Pb with maxheight, so i use maxwidth
2743 $width = $maxwidth;
2744 $height = (int) round($maxwidth * $tmp['height'] / $tmp['width']);
2745 } else { // No pb with maxheight
2746 $height = $maxheight;
2747 }
2748 }
2749 return array('width' => $width, 'height' => $height);
2750}
2751
2763function pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails = 0, $multicurrency = 0)
2764{
2765 global $hookmanager;
2766
2767 $sign = 1;
2768 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2769 $sign = -1;
2770 }
2771 if ($object->lines[$i]->special_code == 3) {
2772 // If option
2773 return $outputlangs->transnoentities("Option");
2774 } else {
2775 if (is_object($hookmanager)) {
2776 $special_code = $object->lines[$i]->special_code;
2777 if (!empty($object->lines[$i]->fk_parent_line)) {
2778 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2779 }
2780
2781 $parameters = array(
2782 'i' => $i,
2783 'outputlangs' => $outputlangs,
2784 'hidedetails' => $hidedetails,
2785 'special_code' => $special_code,
2786 'multicurrency' => $multicurrency
2787 );
2788
2789 $action = '';
2790
2791 if ($hookmanager->executeHooks('getlinetotalremise', $parameters, $object, $action) > 0) { // Note that $action and $object may have been modified by some hooks
2792 if (isset($hookmanager->resArray['linetotalremise'])) {
2793 return (float) $hookmanager->resArray['linetotalremise'];
2794 } else {
2795 return (float) $hookmanager->resPrint; // For backward compatibility
2796 }
2797 }
2798 }
2799
2800 if (empty($hidedetails) || $hidedetails > 1) {
2801 if (empty($multicurrency)) {
2802 return (float) price2num($sign * (($object->lines[$i]->subprice * (float) $object->lines[$i]->qty) - $object->lines[$i]->total_ht), 'MT', 1);
2803 } else {
2804 return (float) price2num($sign * (($object->lines[$i]->multicurrency_subprice * (float) $object->lines[$i]->qty) - $object->lines[$i]->multicurrency_total_ht), 'MT', 1);
2805 }
2806 }
2807 }
2808 return 0;
2809}
2810
2818function pdfExtractMetadata($file, $field = 'Keywords')
2819{
2820 if (!dol_is_file($file)) {
2821 return "ERROR: FILE NOT FOUND OR NOT VALID";
2822 }
2823
2824 // Get content of PDF file
2825 $content = file_get_contents(dol_osencode($file));
2826
2827 // Use a regex to capture the metadata
2828 if ($content) {
2829 $matches = array();
2830
2831 // Remove non printablecaracters
2832 $content = preg_replace('/[^(\x20-\x7F)]*/', '', $content);
2833 if (preg_match('/\/' . preg_quote($field, '/') . '\s*\‍((.*?)\‍)/', $content, $matches)) {
2834 return trim($matches[1]);
2835 }
2836 return "ERROR: NOT FOUND";
2837 } else {
2838 return "ERROR: FAILED TO READ PDF";
2839 }
2840}
2841
2860 TCPDF $pdf,
2861 CommonDocGenerator $generator,
2862 float $curY,
2864 int $i,
2865 Translate $outputlangs,
2866 int $hideref,
2867 int $hidedesc,
2868 array $bgColor,
2869 bool $isSubtotal = false,
2870 bool $applySubtotalLogic = true
2871) {
2872 $savePage = $pdf->getPage();
2873 $saveX = $pdf->GetX();
2874 $prevAlign = $generator->cols['desc']['content']['align'];
2875
2876 if ($isSubtotal && $applySubtotalLogic && $object->lines[$i]->qty < 0) {
2877 $outputlangs->load("subtotals");
2878 $object->lines[$i]->desc = $outputlangs->trans("SubtotalOf", $object->lines[$i]->desc);
2879 $generator->cols['desc']['content']['align'] = ($prevAlign === 'L') ? 'R' : 'L';
2880 }
2881
2882 $pdf->startTransaction();
2883 $pdf->SetXY($saveX, $curY);
2884 $generator->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
2885 $pageAfter = $pdf->getPage();
2886 $yAfter = $pdf->GetY();
2887 $pdf->rollbackTransaction(true);
2888
2889 $pdf->SetFillColor($bgColor[0], $bgColor[1], $bgColor[2]);
2890 $width = $generator->page_largeur - $generator->marge_droite - $generator->marge_gauche;
2891
2892 $pdf->SetXY($generator->marge_gauche, $curY);
2893 if ($pageAfter === $savePage) {
2894 $pdf->MultiCell($width, max(0, $yAfter - $curY), '', 0, '', true);
2895 } else {
2896 $pdf->MultiCell($width, $pdf->getPageHeight() - $pdf->getBreakMargin() - $curY, '', 0, '', true);
2897
2898 $pdf->setPage($pageAfter);
2899 $pdf->SetXY($generator->marge_gauche, $pdf->getMargins()['top']);
2900 $pdf->MultiCell($width, max(0, $yAfter - $pdf->getMargins()['top']), '', 0, '', true);
2901
2902 $pdf->setPage($savePage);
2903 }
2904
2905 $pdf->SetTextColor(colorIsLight(implode(',', $bgColor)));
2906 $pdf->SetXY($saveX, $curY);
2907 $generator->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
2908 $generator->setAfterColsLinePositionsData('desc', $pdf->GetY(), $pdf->getPage());
2909
2910 $generator->cols['desc']['content']['align'] = $prevAlign;
2911}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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.
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.
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.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
dol_textishtml($msg, $option=0)
Return if a text is a html content.
colorIsLight($stringcolor)
Return true if the color is light.
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.
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)
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
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:2731
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:1463
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2462
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:1520
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:2763
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:289
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:2818
pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails=0)
Return line quantity shipped.
Definition pdf.lib.php:2245
pdf_getlinenum($object, $i, $outputlangs, $hidedetails=0)
Return line num.
Definition pdf.lib.php:1920
pdf_getEncryption($pathoffile)
Return if pdf file is protected/encrypted.
Definition pdf.lib.php:235
pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price including tax.
Definition pdf.lib.php:2123
pdf_getLinkedObjects(&$object, $outputlangs)
Return linked objects to use for document generation.
Definition pdf.lib.php:2573
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:314
pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails=0)
Return line ref_supplier.
Definition pdf.lib.php:1986
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition pdf.lib.php:2518
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:1047
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:2080
pdf_getlineprogress($object, $i, $outputlangs, $hidedetails=0, $hookmanager=null)
Return line percent.
Definition pdf.lib.php:2411
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:2018
pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
Function to try to calculate height of a HTML Content.
Definition pdf.lib.php:340
pdf_admin_prepare_head()
Return array head with list of tabs to view object information.
Definition pdf.lib.php:49
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition pdf.lib.php:742
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1425
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank information for PDF generation.
Definition pdf.lib.php:863
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:266
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:2859
pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails=0)
Return line keep to ship quantity.
Definition pdf.lib.php:2285
pdf_getlineref($object, $i, $outputlangs, $hidedetails=0)
Return line product ref.
Definition pdf.lib.php:1953
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:439
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0)
Return line unit.
Definition pdf.lib.php:2325
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2368
pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails=0)
Return line quantity asked.
Definition pdf.lib.php:2205
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2165
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:778
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:391
pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition pdf.lib.php:798