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