dolibarr 21.0.0-alpha
pdf.lib.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2006-2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
4 * Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com>
5 * Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2010-2017 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
8 * Copyright (C) 2012 Cédric Salvador <csalvador@gpcsolutions.fr>
9 * Copyright (C) 2012-2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
10 * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
11 * Copyright (C) 2014 Teddy Andreotti <125155@supinfo.com>
12 * Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
13 * Copyright (C) 2019 Lenin Rivas <lenin.rivas@servcom-it.com>
14 * Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com>
15 * Copyright (C) 2021-2022 Anthony Berton <anthony.berton@bb2a.fr>
16 * Copyright (C) 2023-2024 Frédéric France <frederic.france@free.fr>
17 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 3 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program. If not, see <https://www.gnu.org/licenses/>.
31 * or see https://www.gnu.org/
32 */
33
40include_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php';
41
42
49{
50 global $langs, $conf;
51
52 $h = 0;
53 $head = array();
54
55 $head[$h][0] = DOL_URL_ROOT.'/admin/pdf.php';
56 $head[$h][1] = $langs->trans("Parameters");
57 $head[$h][2] = 'general';
58 $h++;
59
60 // Show more tabs from modules
61 // Entries must be declared in modules descriptor with line
62 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
63 // $this->tabs = array('entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to remove a tab
64 complete_head_from_modules($conf, $langs, null, $head, $h, 'pdf_admin');
65
66 if (isModEnabled("propal") || isModEnabled('invoice') || isModEnabled('reception')) {
67 $head[$h][0] = DOL_URL_ROOT.'/admin/pdf_other.php';
68 $head[$h][1] = $langs->trans("Others");
69 $head[$h][2] = 'other';
70 $h++;
71 }
72
73 complete_head_from_modules($conf, $langs, null, $head, $h, 'pdf_admin', 'remove');
74
75 return $head;
76}
77
78
86function pdf_getFormat($outputlangs = null, $mode = 'setup')
87{
88 global $conf, $db, $langs;
89
90 dol_syslog("pdf_getFormat Get paper format with mode=".$mode." MAIN_PDF_FORMAT=".(!getDolGlobalString('MAIN_PDF_FORMAT') ? 'null' : $conf->global->MAIN_PDF_FORMAT)." outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null')." and langs->defaultlang=".(is_object($langs) ? $langs->defaultlang : 'null'));
91
92 // Default value if setup was not done and/or entry into c_paper_format not defined
93 $width = 210;
94 $height = 297;
95 $unit = 'mm';
96
97 if ($mode == 'auto' || !getDolGlobalString('MAIN_PDF_FORMAT') || getDolGlobalString('MAIN_PDF_FORMAT') == 'auto') {
98 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
99 $pdfformat = dol_getDefaultFormat($outputlangs);
100 } else {
101 $pdfformat = getDolGlobalString('MAIN_PDF_FORMAT');
102 }
103
104 $sql = "SELECT code, label, width, height, unit FROM ".MAIN_DB_PREFIX."c_paper_format";
105 $sql .= " WHERE code = '".$db->escape($pdfformat)."'";
106 $resql = $db->query($sql);
107 if ($resql) {
108 $obj = $db->fetch_object($resql);
109 if ($obj) {
110 $width = (int) $obj->width;
111 $height = (int) $obj->height;
112 $unit = $obj->unit;
113 }
114 }
115
116 //print "pdfformat=".$pdfformat." width=".$width." height=".$height." unit=".$unit;
117 return array('width' => $width, 'height' => $height, 'unit' => $unit);
118}
119
128function pdf_getInstance($format = '', $metric = 'mm', $pagetype = 'P')
129{
130 global $conf;
131
132 // Define constant for TCPDF
133 if (!defined('K_TCPDF_EXTERNAL_CONFIG')) {
134 define('K_TCPDF_EXTERNAL_CONFIG', 1); // this avoid using tcpdf_config file
135 define('K_PATH_CACHE', DOL_DATA_ROOT.'/admin/temp/');
136 define('K_PATH_URL_CACHE', DOL_DATA_ROOT.'/admin/temp/');
137 dol_mkdir(K_PATH_CACHE);
138 define('K_BLANK_IMAGE', '_blank.png');
139 define('PDF_PAGE_FORMAT', 'A4');
140 define('PDF_PAGE_ORIENTATION', 'P');
141 define('PDF_CREATOR', 'TCPDF');
142 define('PDF_AUTHOR', 'TCPDF');
143 define('PDF_HEADER_TITLE', 'TCPDF Example');
144 define('PDF_HEADER_STRING', "by Dolibarr ERP CRM");
145 define('PDF_UNIT', 'mm');
146 define('PDF_MARGIN_HEADER', 5);
147 define('PDF_MARGIN_FOOTER', 10);
148 define('PDF_MARGIN_TOP', 27);
149 define('PDF_MARGIN_BOTTOM', 25);
150 define('PDF_MARGIN_LEFT', 15);
151 define('PDF_MARGIN_RIGHT', 15);
152 define('PDF_FONT_NAME_MAIN', 'helvetica');
153 define('PDF_FONT_SIZE_MAIN', 10);
154 define('PDF_FONT_NAME_DATA', 'helvetica');
155 define('PDF_FONT_SIZE_DATA', 8);
156 define('PDF_FONT_MONOSPACED', 'courier');
157 define('PDF_IMAGE_SCALE_RATIO', 1.25);
158 define('HEAD_MAGNIFICATION', 1.1);
159 define('K_CELL_HEIGHT_RATIO', 1.25);
160 define('K_TITLE_MAGNIFICATION', 1.3);
161 define('K_SMALL_RATIO', 2 / 3);
162 define('K_THAI_TOPCHARS', true);
163 define('K_TCPDF_CALLS_IN_HTML', true);
164 if (getDolGlobalString('TCPDF_THROW_ERRORS_INSTEAD_OF_DIE')) {
165 define('K_TCPDF_THROW_EXCEPTION_ERROR', true);
166 } else {
167 define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
168 }
169 }
170
171 // Load TCPDF
172 require_once TCPDF_PATH.'tcpdf.php';
173
174 // We need to instantiate tcpdi object (instead of tcpdf) to use merging features. But we can disable it (this will break all merge features).
175 if (!getDolGlobalString('MAIN_DISABLE_TCPDI')) {
176 require_once TCPDI_PATH.'tcpdi.php';
177 }
178
179 //$arrayformat=pdf_getFormat();
180 //$format=array($arrayformat['width'],$arrayformat['height']);
181 //$metric=$arrayformat['unit'];
182
183 //$pdfa = false; // PDF default version
184 $pdfa = getDolGlobalInt('PDF_USE_A', 0); // PDF/A-1 ou PDF/A-3
185
186 if (!getDolGlobalString('MAIN_DISABLE_TCPDI') && class_exists('TCPDI')) {
187 $pdf = new TCPDI($pagetype, $metric, $format, true, 'UTF-8', false, $pdfa);
188 } else {
189 $pdf = new TCPDF($pagetype, $metric, $format, true, 'UTF-8', false, $pdfa);
190 }
191
192 // Protection and encryption of pdf
193 if (getDolGlobalString('PDF_SECURITY_ENCRYPTION')) {
194 /* Permission supported by TCPDF
195 - print : Print the document;
196 - modify : Modify the contents of the document by operations other than those controlled by 'fill-forms', 'extract' and 'assemble';
197 - copy : Copy or otherwise extract text and graphics from the document;
198 - 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);
199 - fill-forms : Fill in existing interactive form fields (including signature fields), even if 'annot-forms' is not specified;
200 - extract : Extract text and graphics (in support of accessibility to users with disabilities or for other purposes);
201 - assemble : Assemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even if 'modify' is not set;
202 - 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.
203 - owner : (inverted logic - only for public-key) when set permits change of encryption and enables all other permissions.
204 */
205
206 // For TCPDF, we specify permission we want to block
207 $pdfrights = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_RIGHTS') ? json_decode($conf->global->PDF_SECURITY_ENCRYPTION_RIGHTS, true) : array('modify', 'copy')); // Json format in llx_const
208
209 // Password for the end user
210 $pdfuserpass = getDolGlobalString('PDF_SECURITY_ENCRYPTION_USERPASS');
211
212 // Password of the owner, created randomly if not defined
213 $pdfownerpass = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_OWNERPASS') ? getDolGlobalString('PDF_SECURITY_ENCRYPTION_OWNERPASS') : null);
214
215 // For encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit
216 $encstrength = getDolGlobalInt('PDF_SECURITY_ENCRYPTION_STRENGTH', 0);
217
218 // Array of recipients containing public-key certificates ('c') and permissions ('p').
219 // For example: array(array('c' => 'file://../examples/data/cert/tcpdf.crt', 'p' => array('print')))
220 $pubkeys = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_PUBKEYS') ? json_decode($conf->global->PDF_SECURITY_ENCRYPTION_PUBKEYS, true) : null); // Json format in llx_const
221
222 $pdf->SetProtection($pdfrights, $pdfuserpass, $pdfownerpass, $encstrength, $pubkeys);
223 }
224
225 return $pdf;
226}
227
234function pdf_getEncryption($pathoffile)
235{
236 require_once TCPDF_PATH.'tcpdf_parser.php';
237
238 $isencrypted = false;
239
240 $content = file_get_contents($pathoffile);
241
242 //ob_start();
243 @($parser = new TCPDF_PARSER(ltrim($content)));
244 list($xref, $data) = $parser->getParsedData();
245 unset($parser);
246 //ob_end_clean();
247
248 if (isset($xref['trailer']['encrypt'])) {
249 $isencrypted = true; // Secured pdf file are currently not supported
250 }
251
252 if (empty($data)) {
253 $isencrypted = true; // Object list not found. Possible secured file
254 }
255
256 return $isencrypted;
257}
258
265function pdf_getPDFFont($outputlangs)
266{
267 global $conf;
268
269 if (getDolGlobalString('MAIN_PDF_FORCE_FONT')) {
270 return $conf->global->MAIN_PDF_FORCE_FONT;
271 }
272
273 $font = 'Helvetica'; // By default, for FPDI, or ISO language on TCPDF
274 if (class_exists('TCPDF')) { // If TCPDF on, we can use an UTF8 one like DejaVuSans if required (slower)
275 if ($outputlangs->trans('FONTFORPDF') != 'FONTFORPDF') {
276 $font = $outputlangs->trans('FONTFORPDF');
277 }
278 }
279 return $font;
280}
281
288function pdf_getPDFFontSize($outputlangs)
289{
290 global $conf;
291
292 $size = 10; // By default, for FPDI or ISO language on TCPDF
293 if (class_exists('TCPDF')) { // If TCPDF on, we can use an UTF8 font like DejaVuSans if required (slower)
294 if ($outputlangs->trans('FONTSIZEFORPDF') != 'FONTSIZEFORPDF') {
295 $size = (int) $outputlangs->trans('FONTSIZEFORPDF');
296 }
297 }
298 if (getDolGlobalString('MAIN_PDF_FORCE_FONT_SIZE')) {
299 $size = getDolGlobalString('MAIN_PDF_FORCE_FONT_SIZE');
300 }
301
302 return $size;
303}
304
305
313function pdf_getHeightForLogo($logo, $url = false)
314{
315 global $conf;
316 $height = (!getDolGlobalString('MAIN_DOCUMENTS_LOGO_HEIGHT') ? 20 : $conf->global->MAIN_DOCUMENTS_LOGO_HEIGHT);
317 $maxwidth = 130;
318 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
319 $tmp = dol_getImageSize($logo, $url);
320 if ($tmp['height']) {
321 $width = round($height * $tmp['width'] / $tmp['height']);
322 if ($width > $maxwidth) {
323 $height = $height * $maxwidth / $width;
324 }
325 }
326 //print $tmp['width'].' '.$tmp['height'].' '.$width; exit;
327 return $height;
328}
329
338function pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
339{
340 // store current object
341 $pdf->startTransaction();
342 // store starting values
343 $start_y = $pdf->GetY();
344 //var_dump($start_y);
345 $start_page = $pdf->getPage();
346 // call printing functions with content
347 $pdf->writeHTMLCell(0, 0, 0, $start_y, $htmlcontent, 0, 1, false, true, 'J', true);
348 // get the new Y
349 $end_y = $pdf->GetY();
350 $end_page = $pdf->getPage();
351 // calculate height
352 $height = 0;
353 if ($end_page == $start_page) {
354 $height = $end_y - $start_y;
355 } else {
356 for ($page = $start_page; $page <= $end_page; ++$page) {
357 $pdf->setPage($page);
358 $tmpm = $pdf->getMargins();
359 $tMargin = $tmpm['top'];
360 if ($page == $start_page) {
361 // first page
362 $height = $pdf->getPageHeight() - $start_y - $pdf->getBreakMargin();
363 } elseif ($page == $end_page) {
364 // last page
365 $height = $end_y - $tMargin;
366 } else {
367 $height = $pdf->getPageHeight() - $tMargin - $pdf->getBreakMargin();
368 }
369 }
370 }
371 // restore previous object
372 $pdf = $pdf->rollbackTransaction();
373
374 return $height;
375}
376
377
386function pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias = 0)
387{
388 global $conf;
389
390 // Recipient name
391 $socname = '';
392
393 if ($thirdparty instanceof Societe) {
394 $socname = $thirdparty->name;
395 if (($includealias || getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME')) && !empty($thirdparty->name_alias)) {
396 if (getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME') == 2) {
397 $socname = $thirdparty->name_alias." - ".$thirdparty->name;
398 } else {
399 $socname = $thirdparty->name." - ".$thirdparty->name_alias;
400 }
401 }
402 } elseif ($thirdparty instanceof Contact) {
403 if ($thirdparty->socid > 0) {
404 $thirdparty->fetch_thirdparty();
405 $socname = $thirdparty->thirdparty->name;
406 if (($includealias || getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME')) && !empty($thirdparty->thirdparty->name_alias)) {
407 if (getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME') == 2) {
408 $socname = $thirdparty->thirdparty->name_alias." - ".$thirdparty->thirdparty->name;
409 } else {
410 $socname = $thirdparty->thirdparty->name." - ".$thirdparty->thirdparty->name_alias;
411 }
412 }
413 }
414 } else {
415 throw new InvalidArgumentException('Parameter 1 $thirdparty is not a Societe nor Contact');
416 }
417
418 return $outputlangs->convToOutputCharset($socname);
419}
420
421
434function pdf_build_address($outputlangs, $sourcecompany, $targetcompany = '', $targetcontact = '', $usecontact = 0, $mode = 'source', $object = null)
435{
436 global $hookmanager;
437
438 if ($mode == 'source' && !is_object($sourcecompany)) {
439 return -1;
440 }
441 if ($mode == 'target' && !is_object($targetcompany)) {
442 return -1;
443 }
444
445 if (!empty($sourcecompany->state_id) && empty($sourcecompany->state)) {
446 $sourcecompany->state = getState($sourcecompany->state_id);
447 }
448 if (!empty($targetcompany->state_id) && empty($targetcompany->state)) {
449 $targetcompany->state = getState($targetcompany->state_id);
450 }
451
452 $reshook = 0;
453 $stringaddress = '';
454 if (is_object($hookmanager)) {
455 $parameters = array('sourcecompany' => &$sourcecompany, 'targetcompany' => &$targetcompany, 'targetcontact' => &$targetcontact, 'outputlangs' => $outputlangs, 'mode' => $mode, 'usecontact' => $usecontact);
456 $action = '';
457 $reshook = $hookmanager->executeHooks('pdf_build_address', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
458 $stringaddress .= $hookmanager->resPrint;
459 }
460 if (empty($reshook)) {
461 if ($mode == 'source') {
462 $withCountry = 0;
463 if (isset($targetcompany->country_code) && !empty($sourcecompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
464 $withCountry = 1;
465 }
466
467 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($sourcecompany, $withCountry, "\n", $outputlangs))."\n";
468
469 if (!getDolGlobalString('MAIN_PDF_DISABLESOURCEDETAILS')) {
470 // Phone
471 if ($sourcecompany->phone) {
472 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("PhoneShort").": ".$outputlangs->convToOutputCharset($sourcecompany->phone);
473 }
474 // Fax
475 if ($sourcecompany->fax) {
476 $stringaddress .= ($stringaddress ? ($sourcecompany->phone ? " - " : "\n") : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($sourcecompany->fax);
477 }
478 // EMail
479 if ($sourcecompany->email) {
480 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($sourcecompany->email);
481 }
482 // Web
483 if ($sourcecompany->url) {
484 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($sourcecompany->url);
485 }
486 }
487 // Intra VAT
488 if (getDolGlobalString('MAIN_TVAINTRA_IN_SOURCE_ADDRESS')) {
489 if ($sourcecompany->tva_intra) {
490 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($sourcecompany->tva_intra);
491 }
492 }
493 // Professional Ids
494 $reg = array();
495 if (getDolGlobalString('MAIN_PROFID1_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof1)) {
496 $tmp = $outputlangs->transcountrynoentities("ProfId1", $sourcecompany->country_code);
497 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
498 $tmp = $reg[1];
499 }
500 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof1);
501 }
502 if (getDolGlobalString('MAIN_PROFID2_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof2)) {
503 $tmp = $outputlangs->transcountrynoentities("ProfId2", $sourcecompany->country_code);
504 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
505 $tmp = $reg[1];
506 }
507 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof2);
508 }
509 if (getDolGlobalString('MAIN_PROFID3_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof3)) {
510 $tmp = $outputlangs->transcountrynoentities("ProfId3", $sourcecompany->country_code);
511 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
512 $tmp = $reg[1];
513 }
514 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof3);
515 }
516 if (getDolGlobalString('MAIN_PROFID4_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof4)) {
517 $tmp = $outputlangs->transcountrynoentities("ProfId4", $sourcecompany->country_code);
518 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
519 $tmp = $reg[1];
520 }
521 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof4);
522 }
523 if (getDolGlobalString('MAIN_PROFID5_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof5)) {
524 $tmp = $outputlangs->transcountrynoentities("ProfId5", $sourcecompany->country_code);
525 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
526 $tmp = $reg[1];
527 }
528 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof5);
529 }
530 if (getDolGlobalString('MAIN_PROFID6_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof6)) {
531 $tmp = $outputlangs->transcountrynoentities("ProfId6", $sourcecompany->country_code);
532 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
533 $tmp = $reg[1];
534 }
535 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof6);
536 }
537 if (getDolGlobalString('PDF_ADD_MORE_AFTER_SOURCE_ADDRESS')) {
538 $stringaddress .= ($stringaddress ? "\n" : '') . getDolGlobalString('PDF_ADD_MORE_AFTER_SOURCE_ADDRESS');
539 }
540 }
541
542 if ($mode == 'target' || preg_match('/targetwithdetails/', $mode)) {
543 if ($usecontact) {
544 if (is_object($targetcontact)) {
545 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($targetcontact->getFullName($outputlangs, 1));
546
547 if (!empty($targetcontact->address)) {
548 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcontact))."\n";
549 } else {
550 $companytouseforaddress = $targetcompany;
551
552 // Contact on a thirdparty that is a different thirdparty than the thirdparty of object
553 if ($targetcontact->socid > 0 && $targetcontact->socid != $targetcompany->id) {
554 $targetcontact->fetch_thirdparty();
555 $companytouseforaddress = $targetcontact->thirdparty;
556 }
557
558 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($companytouseforaddress))."\n";
559 }
560 // Country
561 if (!empty($targetcontact->country_code) && $targetcontact->country_code != $sourcecompany->country_code) {
562 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcontact->country_code));
563 } elseif (empty($targetcontact->country_code) && !empty($targetcompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
564 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
565 }
566
567 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
568 // Phone
569 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) {
570 if (!empty($targetcontact->phone_pro) || !empty($targetcontact->phone_mobile)) {
571 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": ";
572 }
573 if (!empty($targetcontact->phone_pro)) {
574 $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_pro);
575 }
576 if (!empty($targetcontact->phone_pro) && !empty($targetcontact->phone_mobile)) {
577 $stringaddress .= " / ";
578 }
579 if (!empty($targetcontact->phone_mobile)) {
580 $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_mobile);
581 }
582 }
583 // Fax
584 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) {
585 if ($targetcontact->fax) {
586 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcontact->fax);
587 }
588 }
589 // EMail
590 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) {
591 if ($targetcontact->email) {
592 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcontact->email);
593 }
594 }
595 // Web
596 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) {
597 if ($targetcontact->url) {
598 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcontact->url);
599 }
600 }
601 }
602 }
603 } else {
604 if (is_object($targetcompany)) {
605 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcompany));
606 // Country
607 if (!empty($targetcompany->country_code) && $targetcompany->country_code != $sourcecompany->country_code) {
608 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
609 } else {
610 $stringaddress .= ($stringaddress ? "\n" : '');
611 }
612
613 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
614 // Phone
615 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) {
616 if (!empty($targetcompany->phone)) {
617 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": ";
618 }
619 if (!empty($targetcompany->phone)) {
620 $stringaddress .= $outputlangs->convToOutputCharset($targetcompany->phone);
621 }
622 }
623 // Fax
624 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) {
625 if ($targetcompany->fax) {
626 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcompany->fax);
627 }
628 }
629 // EMail
630 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) {
631 if ($targetcompany->email) {
632 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcompany->email);
633 }
634 }
635 // Web
636 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) {
637 if ($targetcompany->url) {
638 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcompany->url);
639 }
640 }
641 }
642 }
643 }
644
645 // Intra VAT
646 if (!getDolGlobalString('MAIN_TVAINTRA_NOT_IN_ADDRESS')) {
647 if ($usecontact && is_object($targetcontact) && getDolGlobalInt('MAIN_USE_COMPANY_NAME_OF_CONTACT')) {
648 $targetcontact->fetch_thirdparty();
649 if (!empty($targetcontact->thirdparty->id) && $targetcontact->thirdparty->tva_intra) {
650 $stringaddress .= ($stringaddress ? "\n" : '') . $outputlangs->transnoentities("VATIntraShort") . ': ' . $outputlangs->convToOutputCharset($targetcontact->thirdparty->tva_intra);
651 }
652 } elseif (!empty($targetcompany->tva_intra)) {
653 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($targetcompany->tva_intra);
654 }
655 }
656
657 // Legal form
658 if (getDolGlobalString('MAIN_LEGALFORM_IN_ADDRESS') && !empty($targetcompany->forme_juridique_code)) {
659 $tmp = getFormeJuridiqueLabel((string) $targetcompany->forme_juridique_code);
660 $stringaddress .= ($stringaddress ? "\n" : '').$tmp;
661 }
662
663 // Professional Ids
664 if (getDolGlobalString('MAIN_PROFID1_IN_ADDRESS') && !empty($targetcompany->idprof1)) {
665 $tmp = $outputlangs->transcountrynoentities("ProfId1", $targetcompany->country_code);
666 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
667 $tmp = $reg[1];
668 }
669 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof1);
670 }
671 if (getDolGlobalString('MAIN_PROFID2_IN_ADDRESS') && !empty($targetcompany->idprof2)) {
672 $tmp = $outputlangs->transcountrynoentities("ProfId2", $targetcompany->country_code);
673 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
674 $tmp = $reg[1];
675 }
676 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof2);
677 }
678 if (getDolGlobalString('MAIN_PROFID3_IN_ADDRESS') && !empty($targetcompany->idprof3)) {
679 $tmp = $outputlangs->transcountrynoentities("ProfId3", $targetcompany->country_code);
680 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
681 $tmp = $reg[1];
682 }
683 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof3);
684 }
685 if (getDolGlobalString('MAIN_PROFID4_IN_ADDRESS') && !empty($targetcompany->idprof4)) {
686 $tmp = $outputlangs->transcountrynoentities("ProfId4", $targetcompany->country_code);
687 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
688 $tmp = $reg[1];
689 }
690 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof4);
691 }
692 if (getDolGlobalString('MAIN_PROFID5_IN_ADDRESS') && !empty($targetcompany->idprof5)) {
693 $tmp = $outputlangs->transcountrynoentities("ProfId5", $targetcompany->country_code);
694 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
695 $tmp = $reg[1];
696 }
697 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof5);
698 }
699 if (getDolGlobalString('MAIN_PROFID6_IN_ADDRESS') && !empty($targetcompany->idprof6)) {
700 $tmp = $outputlangs->transcountrynoentities("ProfId6", $targetcompany->country_code);
701 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
702 $tmp = $reg[1];
703 }
704 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof6);
705 }
706
707 // Public note
708 if (getDolGlobalString('MAIN_PUBLIC_NOTE_IN_ADDRESS')) {
709 if ($mode == 'source' && !empty($sourcecompany->note_public)) {
710 $stringaddress .= ($stringaddress ? "\n" : '').dol_string_nohtmltag($sourcecompany->note_public);
711 }
712 if (($mode == 'target' || preg_match('/targetwithdetails/', $mode)) && !empty($targetcompany->note_public)) {
713 $stringaddress .= ($stringaddress ? "\n" : '').dol_string_nohtmltag($targetcompany->note_public);
714 }
715 }
716 }
717 }
718
719 return $stringaddress;
720}
721
722
731function pdf_pagehead(&$pdf, $outputlangs, $page_height)
732{
733 global $conf;
734
735 // Add a background image on document only if good setup of const
736 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
737 $filepath = $conf->mycompany->dir_output.'/logos/' . getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF');
738 if (file_exists($filepath)) {
739 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak before adding image
740 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) {
741 $pdf->SetAlpha($conf->global->MAIN_USE_BACKGROUND_ON_PDF_ALPHA);
742 } // Option for change opacity of background
743 $pdf->Image($filepath, (isset($conf->global->MAIN_USE_BACKGROUND_ON_PDF_X) ? $conf->global->MAIN_USE_BACKGROUND_ON_PDF_X : 0), (isset($conf->global->MAIN_USE_BACKGROUND_ON_PDF_Y) ? $conf->global->MAIN_USE_BACKGROUND_ON_PDF_Y : 0), 0, $page_height);
744 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) {
745 $pdf->SetAlpha(1);
746 }
747 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
748 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
749 }
750 }
751 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') != '-1') {
752 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
753 }
754}
755
756
767function pdf_getSubstitutionArray($outputlangs, $exclude = null, $object = null, $onlykey = 0, $include = null)
768{
769 $substitutionarray = getCommonSubstitutionArray($outputlangs, $onlykey, $exclude, $object, $include);
770 $substitutionarray['__FROM_NAME__'] = '__FROM_NAME__';
771 $substitutionarray['__FROM_EMAIL__'] = '__FROM_EMAIL__';
772 return $substitutionarray;
773}
774
775
787function pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
788{
789 // Print Draft Watermark
790 if ($unit == 'pt') {
791 $k = 1;
792 } elseif ($unit == 'mm') {
793 $k = 72 / 25.4;
794 } elseif ($unit == 'cm') {
795 $k = 72 / 2.54;
796 } elseif ($unit == 'in') {
797 $k = 72;
798 } else {
799 $k = 1;
800 dol_print_error(null, 'Unexpected unit "'.$unit.'" for pdf_watermark');
801 }
802
803 // Make substitution
804 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, null);
805 complete_substitutions_array($substitutionarray, $outputlangs, null);
806 $text = make_substitutions($text, $substitutionarray, $outputlangs);
807 $text = $outputlangs->convToOutputCharset($text);
808
809 $savx = $pdf->getX();
810 $savy = $pdf->getY();
811
812 $watermark_angle = atan($h / $w) / 2;
813 $watermark_x_pos = 0;
814 $watermark_y_pos = $h / 3;
815 $watermark_x = $w / 2;
816 $watermark_y = $h / 3;
817 $pdf->SetFont('', 'B', 40);
818 $pdf->SetTextColor(255, 192, 203);
819
820 //rotate
821 $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));
822 //print watermark
823 $pdf->SetAlpha(0.5);
824 $pdf->SetXY($watermark_x_pos, $watermark_y_pos);
825 $pdf->Cell($w - 20, 25, $outputlangs->convToOutputCharset($text), "", 2, "C", 0);
826 //antirotate
827 $pdf->_out('Q');
828
829 $pdf->SetXY($savx, $savy);
830}
831
832
845function pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, $default_font_size = 10)
846{
847 global $mysoc, $conf;
848
849 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbank.class.php';
850
851 $diffsizetitle = getDolGlobalInt('PDF_DIFFSIZE_TITLE', 3);
852 $diffsizecontent = getDolGlobalInt('PDF_DIFFSIZE_CONTENT', 4);
853 $pdf->SetXY($curx, $cury);
854
855 if (empty($onlynumber)) {
856 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
857 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByTransferOnThisBankAccount').':', 0, 'L', 0);
858 $cury += 4;
859 }
860
861 $outputlangs->load("banks");
862
863 // Use correct name of bank id according to country
864 $bickey = "BICNumber";
865 if ($account->getCountryCode() == 'IN') {
866 $bickey = "SWIFT";
867 }
868
869 // Get format of bank account according to its country
870 $usedetailedbban = $account->useDetailedBBAN();
871
872 //$onlynumber=0; $usedetailedbban=1; // For tests
873 if ($usedetailedbban) {
874 $savcurx = $curx;
875
876 if (empty($onlynumber)) {
877 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
878 $pdf->SetXY($curx, $cury);
879 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
880 $cury += 3;
881 }
882
883 if (!getDolGlobalString('PDF_BANK_HIDE_NUMBER_SHOW_ONLY_BICIBAN')) { // Note that some countries still need bank number, BIC/IBAN not enough for them
884 // Note:
885 // bank = code_banque (FR), sort code (GB, IR. Example: 12-34-56)
886 // desk = code guichet (FR), used only when $usedetailedbban = 1
887 // number = account number
888 // key = check control key used only when $usedetailedbban = 1
889 if (empty($onlynumber)) {
890 $pdf->line($curx + 1, $cury + 1, $curx + 1, $cury + 6);
891 }
892
893
894 foreach ($account->getFieldsToShow() as $val) {
895 $pdf->SetXY($curx, $cury + 4);
896 $pdf->SetFont('', '', $default_font_size - 3);
897
898 if ($val == 'BankCode') {
899 // Bank code
900 $tmplength = 18;
901 $content = $account->code_banque;
902 } elseif ($val == 'DeskCode') {
903 // Desk
904 $tmplength = 18;
905 $content = $account->code_guichet;
906 } elseif ($val == 'BankAccountNumber') {
907 // Number
908 $tmplength = 24;
909 $content = $account->number;
910 } elseif ($val == 'BankAccountNumberKey') {
911 // Key
912 $tmplength = 15;
913 $content = $account->cle_rib;
914 } elseif ($val == 'IBAN' || $val == 'BIC') {
915 // Key
916 $tmplength = 0;
917 $content = '';
918 } else {
919 dol_print_error($account->db, 'Unexpected value for getFieldsToShow: '.$val);
920 break;
921 }
922
923 $pdf->MultiCell($tmplength, 3, $outputlangs->convToOutputCharset($content), 0, 'C', 0);
924 $pdf->SetXY($curx, $cury + 1);
925 $curx += $tmplength;
926 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
927 $pdf->MultiCell($tmplength, 3, $outputlangs->transnoentities($val), 0, 'C', 0);
928 if (empty($onlynumber)) {
929 $pdf->line($curx, $cury + 1, $curx, $cury + 7);
930 }
931 }
932
933 $curx = $savcurx;
934 $cury += 8;
935 }
936 } elseif (!empty($account->number)) {
937 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
938 $pdf->SetXY($curx, $cury);
939 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
940 $cury += 3;
941
942 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
943 $pdf->SetXY($curx, $cury);
944 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("BankAccountNumber").': '.$outputlangs->convToOutputCharset($account->number), 0, 'L', 0);
945 $cury += 3;
946
947 if ($diffsizecontent <= 2) {
948 $cury += 1;
949 }
950 }
951
952 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
953
954 if (empty($onlynumber) && (!empty($account->domiciliation) || !empty($account->address))) {
955 $pdf->SetXY($curx, $cury);
956 $val = $outputlangs->transnoentities("Residence").': '.$outputlangs->convToOutputCharset(empty($account->address) ? $account->domiciliation : $account->address);
957 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
958 //$nboflines=dol_nboflines_bis($val,120);
959 //$cury+=($nboflines*3)+2;
960 $tmpy = $pdf->getStringHeight(100, $val);
961 $cury += $tmpy;
962 }
963
964 if (!empty($account->owner_name)) {
965 $pdf->SetXY($curx, $cury);
966 $val = $outputlangs->transnoentities("BankAccountOwner").': '.$outputlangs->convToOutputCharset($account->owner_name);
967 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
968 $tmpy = $pdf->getStringHeight(100, $val);
969 $cury += $tmpy;
970 } elseif (!$usedetailedbban) {
971 $cury += 1;
972 }
973
974 // Use correct name of bank id according to country
975 $ibankey = FormBank::getIBANLabel($account);
976
977 if (!empty($account->iban)) {
978 //Remove whitespaces to ensure we are dealing with the format we expect
979 $ibanDisplay_temp = str_replace(' ', '', $outputlangs->convToOutputCharset($account->iban));
980 $ibanDisplay = "";
981
982 $nbIbanDisplay_temp = dol_strlen($ibanDisplay_temp);
983 for ($i = 0; $i < $nbIbanDisplay_temp; $i++) {
984 $ibanDisplay .= $ibanDisplay_temp[$i];
985 if ($i % 4 == 3 && $i > 0) {
986 $ibanDisplay .= " ";
987 }
988 }
989
990 $pdf->SetFont('', 'B', $default_font_size - 3);
991 $pdf->SetXY($curx, $cury);
992 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($ibankey).': '.$ibanDisplay, 0, 'L', 0);
993 $cury += 3;
994 }
995
996 if (!empty($account->bic)) {
997 $pdf->SetFont('', 'B', $default_font_size - 3);
998 $pdf->SetXY($curx, $cury);
999 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($bickey).': '.$outputlangs->convToOutputCharset($account->bic), 0, 'L', 0);
1000 }
1001
1002 return $pdf->getY();
1003}
1004
1022function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails = 0, $hidefreetext = 0, $page_largeur = 0, $watermark = '')
1023{
1024 global $conf, $hookmanager;
1025
1026 $outputlangs->load("dict");
1027 $line = '';
1028 $reg = array();
1029 $marginwithfooter = 0; // Return value
1030
1031 $dims = $pdf->getPageDimensions();
1032
1033 // Line of free text
1034 if (empty($hidefreetext) && getDolGlobalString($paramfreetext)) {
1035 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
1036 // More substitution keys
1037 $substitutionarray['__FROM_NAME__'] = $fromcompany->name;
1038 $substitutionarray['__FROM_EMAIL__'] = $fromcompany->email;
1039 complete_substitutions_array($substitutionarray, $outputlangs, $object);
1040 $newfreetext = make_substitutions(getDolGlobalString($paramfreetext), $substitutionarray, $outputlangs);
1041
1042 // Make a change into HTML code to allow to include images from medias directory.
1043 // <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1044 // become
1045 // <img alt="" src="'.DOL_DATA_ROOT.'/medias/image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1046 $newfreetext = preg_replace('/(<img.*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)("[^\/]*\/>)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $newfreetext);
1047
1048 $line .= $outputlangs->convToOutputCharset($newfreetext);
1049 }
1050
1051 // First line of company infos
1052 $line1 = "";
1053 $line2 = "";
1054 $line3 = "";
1055 $line4 = "";
1056
1057 if ($showdetails == 1 || $showdetails == 3) {
1058 // Company name
1059 if ($fromcompany->name) {
1060 $line1 .= ($line1 ? " - " : "").$outputlangs->transnoentities("RegisteredOffice").": ".$fromcompany->name;
1061 }
1062 // Address
1063 if ($fromcompany->address) {
1064 $line1 .= ($line1 ? " - " : "").str_replace("\n", ", ", $fromcompany->address);
1065 }
1066 // Zip code
1067 if ($fromcompany->zip) {
1068 $line1 .= ($line1 ? " - " : "").$fromcompany->zip;
1069 }
1070 // Town
1071 if ($fromcompany->town) {
1072 $line1 .= ($line1 ? " " : "").$fromcompany->town;
1073 }
1074 // Country
1075 if ($fromcompany->country) {
1076 $line1 .= ($line1 ? ", " : "").$fromcompany->country;
1077 }
1078 // Phone
1079 if ($fromcompany->phone) {
1080 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Phone").": ".$fromcompany->phone;
1081 }
1082 // Fax
1083 if ($fromcompany->fax) {
1084 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Fax").": ".$fromcompany->fax;
1085 }
1086
1087 // URL
1088 if ($fromcompany->url) {
1089 $line2 .= ($line2 ? " - " : "").$fromcompany->url;
1090 }
1091 // Email
1092 if ($fromcompany->email) {
1093 $line2 .= ($line2 ? " - " : "").$fromcompany->email;
1094 }
1095 }
1096 if ($showdetails == 2 || $showdetails == 3 || (!empty($fromcompany->country_code) && $fromcompany->country_code == 'DE')) {
1097 // Managers
1098 if ($fromcompany->managers) {
1099 $line2 .= ($line2 ? " - " : "").$fromcompany->managers;
1100 }
1101 }
1102
1103 // Line 3 of company infos
1104 // Juridical status
1105 if (!empty($fromcompany->forme_juridique_code) && $fromcompany->forme_juridique_code) {
1106 $line3 .= ($line3 ? " - " : "").$outputlangs->convToOutputCharset(getFormeJuridiqueLabel((string) $fromcompany->forme_juridique_code));
1107 }
1108 // Capital
1109 if (!empty($fromcompany->capital)) {
1110 $tmpamounttoshow = price2num($fromcompany->capital); // This field is a free string or a float
1111 if (is_numeric($tmpamounttoshow) && $tmpamounttoshow > 0) {
1112 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", price($tmpamounttoshow, 0, $outputlangs, 0, 0, 0, $conf->currency));
1113 } elseif (!empty($fromcompany->capital)) {
1114 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", $fromcompany->capital, $outputlangs);
1115 }
1116 }
1117 // Prof Id 1
1118 if (!empty($fromcompany->idprof1) && $fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || !$fromcompany->idprof2)) {
1119 $field = $outputlangs->transcountrynoentities("ProfId1", $fromcompany->country_code);
1120 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1121 $field = $reg[1];
1122 }
1123 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof1);
1124 }
1125 // Prof Id 2
1126 if (!empty($fromcompany->idprof2) && $fromcompany->idprof2) {
1127 $field = $outputlangs->transcountrynoentities("ProfId2", $fromcompany->country_code);
1128 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1129 $field = $reg[1];
1130 }
1131 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof2);
1132 }
1133
1134 // Line 4 of company infos
1135 // Prof Id 3
1136 if (!empty($fromcompany->idprof3) && $fromcompany->idprof3) {
1137 $field = $outputlangs->transcountrynoentities("ProfId3", $fromcompany->country_code);
1138 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1139 $field = $reg[1];
1140 }
1141 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof3);
1142 }
1143 // Prof Id 4
1144 if (!empty($fromcompany->idprof4) && $fromcompany->idprof4) {
1145 $field = $outputlangs->transcountrynoentities("ProfId4", $fromcompany->country_code);
1146 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1147 $field = $reg[1];
1148 }
1149 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof4);
1150 }
1151 // Prof Id 5
1152 if (!empty($fromcompany->idprof5) && $fromcompany->idprof5) {
1153 $field = $outputlangs->transcountrynoentities("ProfId5", $fromcompany->country_code);
1154 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1155 $field = $reg[1];
1156 }
1157 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof5);
1158 }
1159 // Prof Id 6
1160 if (!empty($fromcompany->idprof6) && $fromcompany->idprof6) {
1161 $field = $outputlangs->transcountrynoentities("ProfId6", $fromcompany->country_code);
1162 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1163 $field = $reg[1];
1164 }
1165 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof6);
1166 }
1167 // Prof Id 7
1168 if (!empty($fromcompany->idprof7) && $fromcompany->idprof7) {
1169 $field = $outputlangs->transcountrynoentities("ProfId7", $fromcompany->country_code);
1170 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1171 $field = $reg[1];
1172 }
1173 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof7);
1174 }
1175 // Prof Id 8
1176 if (!empty($fromcompany->idprof8) && $fromcompany->idprof8) {
1177 $field = $outputlangs->transcountrynoentities("ProfId8", $fromcompany->country_code);
1178 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1179 $field = $reg[1];
1180 }
1181 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof8);
1182 }
1183 // Prof Id 9
1184 if (!empty($fromcompany->idprof9) && $fromcompany->idprof9) {
1185 $field = $outputlangs->transcountrynoentities("ProfId9", $fromcompany->country_code);
1186 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1187 $field = $reg[1];
1188 }
1189 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof9);
1190 }
1191 // Prof Id 10
1192 if (!empty($fromcompany->idprof10) && $fromcompany->idprof10) {
1193 $field = $outputlangs->transcountrynoentities("ProfId10", $fromcompany->country_code);
1194 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1195 $field = $reg[1];
1196 }
1197 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof10);
1198 }
1199 // IntraCommunautary VAT
1200 if (!empty($fromcompany->tva_intra) && $fromcompany->tva_intra != '') {
1201 $line4 .= ($line4 ? " - " : "").$outputlangs->transnoentities("VATIntraShort").": ".$outputlangs->convToOutputCharset($fromcompany->tva_intra);
1202 }
1203
1204 $pdf->SetFont('', '', 7);
1205 $pdf->SetDrawColor(224, 224, 224);
1206 // Option for footer text color
1207 if (getDolGlobalString('PDF_FOOTER_TEXT_COLOR')) {
1208 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_TEXT_COLOR, '%d, %d, %d');
1209 $pdf->SetTextColor($r, $g, $b);
1210 }
1211
1212 // The start of the bottom of this page footer is positioned according to # of lines
1213 $freetextheight = 0;
1214 $align = null;
1215 if ($line) { // Free text
1216 //$line="sample text<br>\nfd<strong>sf</strong>sdf<br>\nghfghg<br>";
1217 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) {
1218 $width = 20000;
1219 $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.
1220 if (getDolGlobalString('MAIN_USE_AUTOWRAP_ON_FREETEXT')) {
1221 $width = 200;
1222 $align = 'C';
1223 }
1224 $freetextheight = $pdf->getStringHeight($width, $line);
1225 } else {
1226 $freetextheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); // New method (works for HTML content)
1227 //print '<br>'.$freetextheight;exit;
1228 }
1229 }
1230
1231 $posy = 0;
1232 // For customized footer
1233 if (is_object($hookmanager)) {
1234 $parameters = array('line1' => $line1, 'line2' => $line2, 'line3' => $line3, 'line4' => $line4, 'outputlangs' => $outputlangs);
1235 $action = '';
1236 $hookmanager->executeHooks('pdf_pagefoot', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1237 if (!empty($hookmanager->resPrint) && $hidefreetext == 0) {
1238 $mycustomfooter = $hookmanager->resPrint;
1239 $mycustomfooterheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1240
1241 $marginwithfooter = $marge_basse + $freetextheight + $mycustomfooterheight;
1242 $posy = (float) $marginwithfooter;
1243
1244 // Option for footer background color (without freetext zone)
1245 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1246 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1247 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1248 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', array(), $fill_color = array($r, $g, $b));
1249 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1250 }
1251
1252 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1253 $pdf->SetAutoPageBreak(0, 0);
1254 } // Option for disable auto pagebreak
1255 if ($line) { // Free text
1256 $pdf->SetXY($dims['lm'], -$posy);
1257 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1258 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1259 } else {
1260 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1261 }
1262 $posy -= $freetextheight;
1263 }
1264 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1265 $pdf->SetAutoPageBreak(1, 0);
1266 } // Restore pagebreak
1267
1268 $pdf->SetY(-$posy);
1269
1270 // Hide footer line if footer background color is set
1271 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1272 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1273 }
1274
1275 // Option for set top margin height of footer after freetext
1276 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1277 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1278 } else {
1279 $posy--;
1280 }
1281
1282 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1283 $pdf->SetAutoPageBreak(0, 0);
1284 } // Option for disable auto pagebreak
1285 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1286 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1287 $pdf->SetAutoPageBreak(1, 0);
1288 } // Restore pagebreak
1289
1290 $posy -= $mycustomfooterheight - 3;
1291 } else {
1292 // Else default footer
1293 $marginwithfooter = $marge_basse + $freetextheight + (!empty($line1) ? 3 : 0) + (!empty($line2) ? 3 : 0) + (!empty($line3) ? 3 : 0) + (!empty($line4) ? 3 : 0);
1294 $posy = (float) $marginwithfooter;
1295
1296 // Option for footer background color (without freetext zone)
1297 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1298 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1299 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1300 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', array(), $fill_color = array($r, $g, $b));
1301 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1302 }
1303
1304 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1305 $pdf->SetAutoPageBreak(0, 0);
1306 } // Option for disable auto pagebreak
1307 if ($line) { // Free text
1308 $pdf->SetXY($dims['lm'], -$posy);
1309 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1310 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1311 } else {
1312 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1313 }
1314 $posy -= $freetextheight;
1315 }
1316 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1317 $pdf->SetAutoPageBreak(1, 0);
1318 } // Restore pagebreak
1319
1320 $pdf->SetY(-$posy);
1321
1322 // Option for hide all footer (page number will no hidden)
1323 if (!getDolGlobalInt('PDF_FOOTER_HIDDEN')) {
1324 // Hide footer line if footer background color is set
1325 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1326 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1327 }
1328
1329 // Option for set top margin height of footer after freetext
1330 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1331 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1332 } else {
1333 $posy--;
1334 }
1335
1336 if (!empty($line1)) {
1337 $pdf->SetFont('', 'B', 7);
1338 $pdf->SetXY($dims['lm'], -$posy);
1339 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line1, 0, 'C', 0);
1340 $posy -= 3;
1341 $pdf->SetFont('', '', 7);
1342 }
1343
1344 if (!empty($line2)) {
1345 $pdf->SetFont('', 'B', 7);
1346 $pdf->SetXY($dims['lm'], -$posy);
1347 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line2, 0, 'C', 0);
1348 $posy -= 3;
1349 $pdf->SetFont('', '', 7);
1350 }
1351
1352 if (!empty($line3)) {
1353 $pdf->SetXY($dims['lm'], -$posy);
1354 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line3, 0, 'C', 0);
1355 }
1356
1357 if (!empty($line4)) {
1358 $posy -= 3;
1359 $pdf->SetXY($dims['lm'], -$posy);
1360 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line4, 0, 'C', 0);
1361 }
1362 }
1363 }
1364 }
1365
1366 // Show page nb and apply correction for some font.
1367 $pdf->SetXY($dims['wk'] - $dims['rm'] - 18 - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_X', 0), -$posy - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_Y', 0));
1368
1369 $pagination = $pdf->PageNo().' / '.$pdf->getAliasNbPages();
1370 $fontRenderCorrection = 0;
1371 if (in_array(pdf_getPDFFont($outputlangs), array('freemono', 'DejaVuSans'))) {
1372 $fontRenderCorrection = 10;
1373 }
1374 $pdf->MultiCell(18 + $fontRenderCorrection, 2, $pagination, 0, 'R', 0);
1375
1376 // Show Draft Watermark
1377 if (!empty($watermark)) {
1378 pdf_watermark($pdf, $outputlangs, $page_hauteur, $page_largeur, 'mm', $watermark);
1379 }
1380
1381 return $marginwithfooter;
1382}
1383
1398function pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
1399{
1400 $linkedobjects = pdf_getLinkedObjects($object, $outputlangs);
1401 if (!empty($linkedobjects)) {
1402 foreach ($linkedobjects as $linkedobject) {
1403 $reftoshow = $linkedobject["ref_title"].' : '.$linkedobject["ref_value"];
1404 if (!empty($linkedobject["date_value"])) {
1405 $reftoshow .= ' / '.$linkedobject["date_value"];
1406 }
1407
1408 $posy += 3;
1409 $pdf->SetXY($posx, $posy);
1410 $pdf->SetFont('', '', (float) $default_font_size - 2);
1411 $pdf->MultiCell($w, $h, $reftoshow, '', $align);
1412 }
1413 }
1414
1415 return $pdf->getY();
1416}
1417
1435function pdf_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref = 0, $hidedesc = 0, $issupplierline = 0, $align = 'J')
1436{
1437 global $db, $conf, $langs, $hookmanager;
1438
1439 $reshook = 0;
1440 $result = '';
1441 //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) ) )
1442 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
1443 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1444 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1445 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1446 }
1447 $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);
1448 $action = '';
1449 $reshook = $hookmanager->executeHooks('pdf_writelinedesc', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1450
1451 if (!empty($hookmanager->resPrint)) {
1452 $result .= $hookmanager->resPrint;
1453 }
1454 }
1455 if (empty($reshook)) {
1456 $labelproductservice = pdf_getlinedesc($object, $i, $outputlangs, $hideref, $hidedesc, $issupplierline);
1457 $labelproductservice = preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $labelproductservice, -1, $nbrep);
1458
1459 //var_dump($labelproductservice);exit;
1460
1461 // 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"
1462 // We make the reverse, so PDF generation has the real URL.
1463 $nbrep = 0;
1464 $labelproductservice = preg_replace('/(<img[^>]*src=")([^"]*)(&amp;)([^"]*")/', '\1\2&\4', $labelproductservice, -1, $nbrep);
1465
1466 if (getDolGlobalString('MARGIN_TOP_ZERO_UL')) {
1467 $pdf->setListIndentWidth(5);
1468 $TMarginList = ['ul' => [['h' => 0.1, ],['h' => 0.1, ]], 'li' => [['h' => 0.1, ],],];
1469 $pdf->setHtmlVSpace($TMarginList);
1470 }
1471
1472 // Description
1473 $pdf->writeHTMLCell($w, $h, $posx, $posy, $outputlangs->convToOutputCharset($labelproductservice), 0, 1, false, true, $align, true);
1474 $result .= $labelproductservice;
1475 }
1476 return $result;
1477}
1478
1490function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1491{
1492 global $db, $conf, $langs;
1493
1494 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1495 $label = (!empty($object->lines[$i]->label) ? $object->lines[$i]->label : (!empty($object->lines[$i]->product_label) ? $object->lines[$i]->product_label : ''));
1496 $product_barcode = (!empty($object->lines[$i]->product_barcode) ? $object->lines[$i]->product_barcode : "");
1497 $desc = (!empty($object->lines[$i]->desc) ? $object->lines[$i]->desc : (!empty($object->lines[$i]->description) ? $object->lines[$i]->description : ''));
1498 $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
1499 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1500 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1501
1502 if ($issupplierline) {
1503 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
1504 $prodser = new ProductFournisseur($db);
1505 } else {
1506 include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1507 $prodser = new Product($db);
1508
1509 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
1510 include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
1511 }
1512 }
1513
1514 if ($idprod) {
1515 $prodser->fetch($idprod);
1516 // If a predefined product and multilang and on other lang, we renamed label with label translated
1517 if (getDolGlobalInt('MAIN_MULTILANGS') && ($outputlangs->defaultlang != $langs->defaultlang)) {
1518 $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)
1519
1520 // 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
1521 // ($textwasnotmodified is replaced with $textwasmodifiedorcompleted and we add completion).
1522
1523 // Set label
1524 // 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.
1525 //var_dump($outputlangs->defaultlang.' - '.$langs->defaultlang.' - '.$label.' - '.$prodser->label);exit;
1526 $textwasnotmodified = ($label == $prodser->label);
1527 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["label"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1528 $label = $prodser->multilangs[$outputlangs->defaultlang]["label"];
1529 }
1530
1531 // Set desc
1532 // Manage HTML entities description test because $prodser->description is store with htmlentities but $desc no
1533 $textwasnotmodified = false;
1534 if (!empty($desc) && dol_textishtml($desc) && !empty($prodser->description) && dol_textishtml($prodser->description)) {
1535 $textwasnotmodified = (strpos(dol_html_entity_decode($desc, ENT_QUOTES | ENT_HTML5), dol_html_entity_decode($prodser->description, ENT_QUOTES | ENT_HTML5)) !== false);
1536 } else {
1537 $textwasnotmodified = ($desc == $prodser->description);
1538 }
1539 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["description"])) {
1540 if ($textwasnotmodified) {
1541 $desc = str_replace($prodser->description, $prodser->multilangs[$outputlangs->defaultlang]["description"], $desc);
1542 } elseif ($translatealsoifmodified) {
1543 $desc = $prodser->multilangs[$outputlangs->defaultlang]["description"];
1544 }
1545 }
1546
1547 // Set note
1548 $textwasnotmodified = ($note == $prodser->note_public);
1549 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["other"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1550 $note = $prodser->multilangs[$outputlangs->defaultlang]["other"];
1551 }
1552 }
1553 } 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
1554 $desc = str_replace('(DEPOSIT)', $outputlangs->trans('Deposit'), $desc);
1555 }
1556
1557 $libelleproduitservice = ''; // Default value
1558 if (!getDolGlobalString('PDF_HIDE_PRODUCT_LABEL_IN_SUPPLIER_LINES')) {
1559 // Description short of product line
1560 $libelleproduitservice = $label;
1561 if (!empty($libelleproduitservice) && getDolGlobalString('PDF_BOLD_PRODUCT_LABEL')) {
1562 // Adding <b> may convert the original string into a HTML string. So we have to first
1563 // convert \n into <br> we text is not already HTML.
1564 if (!dol_textishtml($libelleproduitservice)) {
1565 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1566 }
1567 $libelleproduitservice = '<b>'.$libelleproduitservice.'</b>';
1568 }
1569 }
1570
1571
1572 // Add ref of subproducts
1573 if (getDolGlobalString('SHOW_SUBPRODUCT_REF_IN_PDF')) {
1574 $prodser->get_sousproduits_arbo();
1575 if (!empty($prodser->sousprods) && is_array($prodser->sousprods) && count($prodser->sousprods)) {
1576 $outputlangs->load('mrp');
1577 $tmparrayofsubproducts = reset($prodser->sousprods);
1578
1579 $qtyText = null;
1580 if (isset($object->lines[$i]->qty) && !empty($object->lines[$i]->qty)) {
1581 $qtyText = $object->lines[$i]->qty;
1582 } elseif (isset($object->lines[$i]->qty_shipped) && !empty($object->lines[$i]->qty_shipped)) {
1583 $qtyText = $object->lines[$i]->qty;
1584 }
1585
1586 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF')) {
1587 foreach ($tmparrayofsubproducts as $subprodval) {
1588 $libelleproduitservice = dol_concatdesc(
1589 dol_concatdesc($libelleproduitservice, " * ".$subprodval[3]),
1590 (!empty($qtyText) ?
1591 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1] * $qtyText :
1592 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1593 );
1594 }
1595 } else {
1596 foreach ($tmparrayofsubproducts as $subprodval) {
1597 $libelleproduitservice = dol_concatdesc(
1598 dol_concatdesc($libelleproduitservice, " * ".$subprodval[5].(($subprodval[5] && $subprodval[3]) ? ' - ' : '').$subprodval[3]),
1599 (!empty($qtyText) ?
1600 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1] * $qtyText :
1601 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1602 );
1603 }
1604 }
1605 }
1606 }
1607
1608 if (isModEnabled('barcode') && getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_PRODUCT_BARCODE') && !empty($product_barcode)) {
1609 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $outputlangs->trans("BarCode")." ".$product_barcode);
1610 }
1611
1612 // Description long of product line
1613 if (!empty($desc) && ($desc != $label)) {
1614 if ($desc == '(CREDIT_NOTE)' && $object->lines[$i]->fk_remise_except) {
1615 $discount = new DiscountAbsolute($db);
1616 $discount->fetch($object->lines[$i]->fk_remise_except);
1617 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1618 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromCreditNote", $sourceref);
1619 } elseif ($desc == '(DEPOSIT)' && $object->lines[$i]->fk_remise_except) {
1620 $discount = new DiscountAbsolute($db);
1621 $discount->fetch($object->lines[$i]->fk_remise_except);
1622 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1623 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromDeposit", $sourceref);
1624 // Add date of deposit
1625 if (getDolGlobalString('INVOICE_ADD_DEPOSIT_DATE')) {
1626 $libelleproduitservice .= ' ('.dol_print_date($discount->datec, 'day', '', $outputlangs).')';
1627 }
1628 } elseif ($desc == '(EXCESS RECEIVED)' && $object->lines[$i]->fk_remise_except) {
1629 $discount = new DiscountAbsolute($db);
1630 $discount->fetch($object->lines[$i]->fk_remise_except);
1631 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived", $discount->ref_facture_source);
1632 } elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except) {
1633 $discount = new DiscountAbsolute($db);
1634 $discount->fetch($object->lines[$i]->fk_remise_except);
1635 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid", $discount->ref_invoice_supplier_source);
1636 } else {
1637 if ($idprod) {
1638 // Check if description must be output
1639 if (!empty($object->element)) {
1640 $tmpkey = 'MAIN_DOCUMENTS_HIDE_DESCRIPTION_FOR_'.strtoupper($object->element);
1641 if (getDolGlobalString($tmpkey)) {
1642 $hidedesc = 1;
1643 }
1644 }
1645 if (empty($hidedesc)) {
1646 if (getDolGlobalString('MAIN_DOCUMENTS_DESCRIPTION_FIRST')) {
1647 $libelleproduitservice = dol_concatdesc($desc, $libelleproduitservice);
1648 } else {
1649 if (getDolGlobalString('HIDE_LABEL_VARIANT_PDF') && $prodser->isVariant()) {
1650 $libelleproduitservice = $desc;
1651 } else {
1652 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1653 }
1654 }
1655 }
1656 } else {
1657 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1658 }
1659 }
1660 }
1661
1662 // We add ref of product (and supplier ref if defined)
1663 $prefix_prodserv = "";
1664 $ref_prodserv = "";
1665 if (getDolGlobalString('PRODUCT_ADD_TYPE_IN_DOCUMENTS')) { // In standard mode, we do not show this
1666 if ($prodser->isService()) {
1667 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." ";
1668 } else {
1669 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." ";
1670 }
1671 }
1672
1673 if (empty($hideref)) {
1674 if ($issupplierline) {
1675 if (!getDolGlobalString('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES')) { // Common case
1676 $ref_prodserv = $prodser->ref; // Show local ref
1677 if ($ref_supplier) {
1678 $ref_prodserv .= ($prodser->ref ? ' (' : '').$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.($prodser->ref ? ')' : '');
1679 }
1680 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 1) {
1681 $ref_prodserv = $ref_supplier;
1682 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 2) {
1683 $ref_prodserv = $ref_supplier.' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')';
1684 }
1685 } else {
1686 $ref_prodserv = $prodser->ref; // Show local ref only
1687
1688 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
1689 $productCustomerPriceStatic = new ProductCustomerPrice($db);
1690 $filter = array('fk_product' => $idprod, 'fk_soc' => $object->socid);
1691
1692 $nbCustomerPrices = $productCustomerPriceStatic->fetchAll('', '', 1, 0, $filter);
1693
1694 if ($nbCustomerPrices > 0) {
1695 $productCustomerPrice = $productCustomerPriceStatic->lines[0];
1696
1697 if (!empty($productCustomerPrice->ref_customer)) {
1698 switch ($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
1699 case 1:
1700 $ref_prodserv = $productCustomerPrice->ref_customer;
1701 break;
1702
1703 case 2:
1704 $ref_prodserv = $productCustomerPrice->ref_customer . ' (' . $outputlangs->transnoentitiesnoconv('InternalRef') . ' ' . $ref_prodserv . ')';
1705 break;
1706
1707 default:
1708 $ref_prodserv = $ref_prodserv . ' (' . $outputlangs->transnoentitiesnoconv('RefCustomer') . ' ' . $productCustomerPrice->ref_customer . ')';
1709 }
1710 }
1711 }
1712 }
1713 }
1714
1715 if (!empty($libelleproduitservice) && !empty($ref_prodserv)) {
1716 $ref_prodserv .= " - ";
1717 }
1718 }
1719
1720 if (!empty($ref_prodserv) && getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1721 if (!dol_textishtml($libelleproduitservice)) {
1722 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1723 }
1724 $ref_prodserv = '<b>'.$ref_prodserv.'</b>';
1725 // $prefix_prodserv and $ref_prodser are not HTML var
1726 }
1727 $libelleproduitservice = $prefix_prodserv.$ref_prodserv.$libelleproduitservice;
1728
1729 // Add an additional description for the category products
1730 if (getDolGlobalString('CATEGORY_ADD_DESC_INTO_DOC') && $idprod && isModEnabled('category')) {
1731 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1732 $categstatic = new Categorie($db);
1733 // recovering the list of all the categories linked to product
1734 $tblcateg = $categstatic->containing($idprod, Categorie::TYPE_PRODUCT);
1735 foreach ($tblcateg as $cate) {
1736 // Adding the descriptions if they are filled
1737 $desccateg = $cate->description;
1738 if ($desccateg) {
1739 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desccateg);
1740 }
1741 }
1742 }
1743
1744 if (!empty($object->lines[$i]->date_start) || !empty($object->lines[$i]->date_end)) {
1745 $format = 'day';
1746 $period = '';
1747 // Show duration if exists
1748 if ($object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1749 $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)).')';
1750 }
1751 if ($object->lines[$i]->date_start && !$object->lines[$i]->date_end) {
1752 $period = '('.$outputlangs->transnoentitiesnoconv('DateFrom', dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs)).')';
1753 }
1754 if (!$object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1755 $period = '('.$outputlangs->transnoentitiesnoconv('DateUntil', dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
1756 }
1757 //print '>'.$outputlangs->charset_output.','.$period;
1758 if (getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1759 if (!dol_textishtml($libelleproduitservice)) {
1760 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1761 }
1762 $libelleproduitservice .= '<br><b style="color:#333666;" ><em>'.$period.'</em></b>';
1763 } else {
1764 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $period);
1765 }
1766 //print $libelleproduitservice;
1767 }
1768
1769 // Show information for lot
1770 if (!empty($dbatch)) {
1771 // $object is a shipment.
1772 //var_dump($object->lines[$i]->details_entrepot); // array from llx_expeditiondet (we can have several lines for one fk_origin_line)
1773 //var_dump($object->lines[$i]->detail_batch); // array from llx_expeditiondet_batch (each line with a lot is linked to llx_expeditiondet)
1774
1775 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1776 include_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
1777 $tmpwarehouse = new Entrepot($db);
1778 $tmpproductbatch = new Productbatch($db);
1779
1780 $format = 'day';
1781 foreach ($dbatch as $detail) {
1782 $dte = array();
1783 if ($detail->eatby) {
1784 $dte[] = $outputlangs->transnoentitiesnoconv('printEatby', dol_print_date($detail->eatby, $format, false, $outputlangs));
1785 }
1786 if ($detail->sellby) {
1787 $dte[] = $outputlangs->transnoentitiesnoconv('printSellby', dol_print_date($detail->sellby, $format, false, $outputlangs));
1788 }
1789 if ($detail->batch) {
1790 $dte[] = $outputlangs->transnoentitiesnoconv('printBatch', $detail->batch);
1791 }
1792 $dte[] = $outputlangs->transnoentitiesnoconv('printQty', $detail->qty);
1793
1794 // Add also info of planned warehouse for lot
1795 if ($object->element == 'shipping' && $detail->fk_origin_stock > 0 && getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1796 $resproductbatch = $tmpproductbatch->fetch($detail->fk_origin_stock);
1797 if ($resproductbatch > 0) {
1798 $reswarehouse = $tmpwarehouse->fetch($tmpproductbatch->warehouseid);
1799 if ($reswarehouse > 0) {
1800 $dte[] = $tmpwarehouse->ref;
1801 }
1802 }
1803 }
1804
1805 $libelleproduitservice .= "__N__ ".implode(" - ", $dte);
1806 }
1807 } else {
1808 if (getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1809 // TODO Show warehouse for shipment line without batch
1810 }
1811 }
1812
1813 // Now we convert \n into br
1814 if (dol_textishtml($libelleproduitservice)) {
1815 $libelleproduitservice = preg_replace('/__N__/', '<br>', $libelleproduitservice);
1816 } else {
1817 $libelleproduitservice = preg_replace('/__N__/', "\n", $libelleproduitservice);
1818 }
1819 $libelleproduitservice = dol_htmlentitiesbr($libelleproduitservice, 1);
1820
1821 return $libelleproduitservice;
1822}
1823
1833function pdf_getlinenum($object, $i, $outputlangs, $hidedetails = 0)
1834{
1835 global $hookmanager;
1836
1837 $reshook = 0;
1838 $result = '';
1839 //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) ) )
1840 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
1841 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1842 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1843 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1844 }
1845 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1846 $action = '';
1847 $reshook = $hookmanager->executeHooks('pdf_getlinenum', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1848 $result .= $hookmanager->resPrint;
1849 }
1850 if (empty($reshook)) {
1851 $result .= dol_htmlentitiesbr($object->lines[$i]->num);
1852 }
1853 return $result;
1854}
1855
1856
1866function pdf_getlineref($object, $i, $outputlangs, $hidedetails = 0)
1867{
1868 global $hookmanager;
1869
1870 $reshook = 0;
1871 $result = '';
1872 //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) ) )
1873 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
1874 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1875 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1876 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1877 }
1878 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1879 $action = '';
1880 $reshook = $hookmanager->executeHooks('pdf_getlineref', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1881 $result .= $hookmanager->resPrint;
1882 }
1883 if (empty($reshook)) {
1884 $result .= dol_htmlentitiesbr($object->lines[$i]->product_ref);
1885 }
1886 return $result;
1887}
1888
1889
1899function pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails = 0)
1900{
1901 global $hookmanager;
1902
1903 $reshook = 0;
1904 $result = '';
1905 //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) ) )
1906 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
1907 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1908 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1909 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1910 }
1911 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1912 $action = '';
1913 $reshook = $hookmanager->executeHooks('pdf_getlineref_supplier', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1914 $result .= $hookmanager->resPrint;
1915 }
1916 if (empty($reshook)) {
1917 $result .= dol_htmlentitiesbr($object->lines[$i]->ref_supplier);
1918 }
1919 return $result;
1920}
1921
1931function pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails = 0)
1932{
1933 global $conf, $hookmanager, $mysoc;
1934
1935 $result = '';
1936 $reshook = 0;
1937 //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) ) )
1938 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
1939 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1940 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1941 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1942 }
1943 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1944 $action = '';
1945 $reshook = $hookmanager->executeHooks('pdf_getlinevatrate', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1946
1947 if (!empty($hookmanager->resPrint)) {
1948 $result .= $hookmanager->resPrint;
1949 }
1950 }
1951 if (empty($reshook)) {
1952 if (empty($hidedetails) || $hidedetails > 1) {
1953 $tmpresult = '';
1954
1955 $tmpresult .= vatrate($object->lines[$i]->tva_tx, 0, $object->lines[$i]->info_bits, -1);
1956 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_SECOND_TAX')) {
1957 if ($object->lines[$i]->total_localtax1 != 0) {
1958 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
1959 $tmpresult .= '/';
1960 } else {
1961 $tmpresult = '';
1962 }
1963 $tmpresult .= vatrate((string) abs($object->lines[$i]->localtax1_tx), 0);
1964 }
1965 }
1966 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_THIRD_TAX')) {
1967 if ($object->lines[$i]->total_localtax2 != 0) {
1968 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
1969 $tmpresult .= '/';
1970 } else {
1971 $tmpresult = '';
1972 }
1973 $tmpresult .= vatrate((string) abs($object->lines[$i]->localtax2_tx), 0);
1974 }
1975 }
1976 $tmpresult .= '%';
1977
1978 $result .= $tmpresult;
1979 }
1980 }
1981 return $result;
1982}
1983
1993function pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails = 0)
1994{
1995 global $conf, $hookmanager;
1996
1997 $sign = 1;
1998 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
1999 $sign = -1;
2000 }
2001
2002 $result = '';
2003 $reshook = 0;
2004 //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) ) )
2005 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
2006 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2007 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2008 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2009 }
2010 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2011 $action = '';
2012 $reshook = $hookmanager->executeHooks('pdf_getlineupexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2013
2014 if (!empty($hookmanager->resPrint)) {
2015 $result .= $hookmanager->resPrint;
2016 }
2017 }
2018 if (empty($reshook)) {
2019 if (empty($hidedetails) || $hidedetails > 1) {
2020 $subprice = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_subprice : $object->lines[$i]->subprice);
2021 $result .= price($sign * $subprice, 0, $outputlangs);
2022 }
2023 }
2024 return $result;
2025}
2026
2036function pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails = 0)
2037{
2038 global $hookmanager, $conf;
2039
2040 $sign = 1;
2041 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2042 $sign = -1;
2043 }
2044
2045 $result = '';
2046 $reshook = 0;
2047 //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) ) )
2048 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
2049 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2050 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2051 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2052 }
2053 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2054 $action = '';
2055 $reshook = $hookmanager->executeHooks('pdf_getlineupwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2056
2057 if (!empty($hookmanager->resPrint)) {
2058 $result .= $hookmanager->resPrint;
2059 }
2060 }
2061 if (empty($reshook)) {
2062 if (empty($hidedetails) || $hidedetails > 1) {
2063 $result .= price($sign * (($object->lines[$i]->subprice) + ($object->lines[$i]->subprice) * ($object->lines[$i]->tva_tx) / 100), 0, $outputlangs);
2064 }
2065 }
2066 return $result;
2067}
2068
2078function pdf_getlineqty($object, $i, $outputlangs, $hidedetails = 0)
2079{
2080 global $hookmanager;
2081
2082 $result = '';
2083 $reshook = 0;
2084 //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) ) )
2085 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
2086 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2087 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2088 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2089 }
2090 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2091 $action = '';
2092 $reshook = $hookmanager->executeHooks('pdf_getlineqty', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2093
2094 if (!empty($hookmanager->resPrint)) {
2095 $result = $hookmanager->resPrint;
2096 }
2097 }
2098 if (empty($reshook)) {
2099 if ($object->lines[$i]->special_code == 3) {
2100 return '';
2101 }
2102 if (empty($hidedetails) || $hidedetails > 1) {
2103 $result .= $object->lines[$i]->qty;
2104 }
2105 }
2106 return $result;
2107}
2108
2118function pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails = 0)
2119{
2120 global $hookmanager;
2121
2122 $reshook = 0;
2123 $result = '';
2124 //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) ) )
2125 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
2126 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2127 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2128 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2129 }
2130 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2131 $action = '';
2132 $reshook = $hookmanager->executeHooks('pdf_getlineqty_asked', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2133
2134 if (!empty($hookmanager->resPrint)) {
2135 $result .= $hookmanager->resPrint;
2136 }
2137 }
2138 if (empty($reshook)) {
2139 if ($object->lines[$i]->special_code == 3) {
2140 return '';
2141 }
2142 if (empty($hidedetails) || $hidedetails > 1) {
2143 $result .= $object->lines[$i]->qty_asked;
2144 }
2145 }
2146 return $result;
2147}
2148
2158function pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails = 0)
2159{
2160 global $hookmanager;
2161
2162 $reshook = 0;
2163 $result = '';
2164 //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) ) )
2165 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
2166 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2167 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2168 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2169 }
2170 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2171 $action = '';
2172 $reshook = $hookmanager->executeHooks('pdf_getlineqty_shipped', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2173
2174 if (!empty($hookmanager->resPrint)) {
2175 $result .= $hookmanager->resPrint;
2176 }
2177 }
2178 if (empty($reshook)) {
2179 if ($object->lines[$i]->special_code == 3) {
2180 return '';
2181 }
2182 if (empty($hidedetails) || $hidedetails > 1) {
2183 $result .= $object->lines[$i]->qty_shipped;
2184 }
2185 }
2186 return $result;
2187}
2188
2198function pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails = 0)
2199{
2200 global $hookmanager;
2201
2202 $reshook = 0;
2203 $result = '';
2204 //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) ) )
2205 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
2206 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2207 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2208 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2209 }
2210 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2211 $action = '';
2212 $reshook = $hookmanager->executeHooks('pdf_getlineqty_keeptoship', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2213
2214 if (!empty($hookmanager->resPrint)) {
2215 $result .= $hookmanager->resPrint;
2216 }
2217 }
2218 if (empty($reshook)) {
2219 if ($object->lines[$i]->special_code == 3) {
2220 return '';
2221 }
2222 if (empty($hidedetails) || $hidedetails > 1) {
2223 $result .= ($object->lines[$i]->qty_asked - $object->lines[$i]->qty_shipped);
2224 }
2225 }
2226 return $result;
2227}
2228
2238function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0)
2239{
2240 global $hookmanager, $langs;
2241
2242 $reshook = 0;
2243 $result = '';
2244 //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) ) )
2245 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
2246 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2247 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2248 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2249 }
2250 $parameters = array(
2251 'i' => $i,
2252 'outputlangs' => $outputlangs,
2253 'hidedetails' => $hidedetails,
2254 'special_code' => $special_code
2255 );
2256 $action = '';
2257 $reshook = $hookmanager->executeHooks('pdf_getlineunit', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2258
2259 if (!empty($hookmanager->resPrint)) {
2260 $result .= $hookmanager->resPrint;
2261 }
2262 }
2263 if (empty($reshook)) {
2264 if (empty($hidedetails) || $hidedetails > 1) {
2265 $result .= $langs->transnoentitiesnoconv($object->lines[$i]->getLabelOfUnit('short'));
2266 }
2267 }
2268 return $result;
2269}
2270
2271
2281function pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails = 0)
2282{
2283 global $hookmanager;
2284
2285 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2286
2287 $reshook = 0;
2288 $result = '';
2289 //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) ) )
2290 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
2291 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2292 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2293 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2294 }
2295 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2296 $action = '';
2297 $reshook = $hookmanager->executeHooks('pdf_getlineremisepercent', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2298
2299 if (!empty($hookmanager->resPrint)) {
2300 $result .= $hookmanager->resPrint;
2301 }
2302 }
2303 if (empty($reshook)) {
2304 if ($object->lines[$i]->special_code == 3) {
2305 return '';
2306 }
2307 if (empty($hidedetails) || $hidedetails > 1) {
2308 $result .= dol_print_reduction($object->lines[$i]->remise_percent, $outputlangs);
2309 }
2310 }
2311 return $result;
2312}
2313
2324function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = null)
2325{
2326 if (empty($hookmanager)) {
2327 global $hookmanager;
2328 }
2329 global $conf;
2330
2331 $reshook = 0;
2332 $result = '';
2333 //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) ) )
2334 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
2335 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2336 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2337 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2338 }
2339 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2340 $action = '';
2341 $reshook = $hookmanager->executeHooks('pdf_getlineprogress', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2342
2343 if (!empty($hookmanager->resPrint)) {
2344 return $hookmanager->resPrint;
2345 }
2346 }
2347 if (empty($reshook)) {
2348 if ($object->lines[$i]->special_code == 3) {
2349 return '';
2350 }
2351 if (empty($hidedetails) || $hidedetails > 1) {
2352 if (getDolGlobalString('SITUATION_DISPLAY_DIFF_ON_PDF')) {
2353 $prev_progress = 0;
2354 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2355 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2356 }
2357 $result = round($object->lines[$i]->situation_percent - $prev_progress, 1).'%';
2358 } else {
2359 $result = round($object->lines[$i]->situation_percent, 1).'%';
2360 }
2361 }
2362 }
2363 return $result;
2364}
2365
2375function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0)
2376{
2377 global $conf, $hookmanager;
2378
2379 $sign = 1;
2380 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2381 $sign = -1;
2382 }
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, 'sign' => $sign);
2393 $action = '';
2394 $reshook = $hookmanager->executeHooks('pdf_getlinetotalexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2395
2396 if (!empty($hookmanager->resPrint)) {
2397 $result .= $hookmanager->resPrint;
2398 }
2399 }
2400 if (empty($reshook)) {
2401 if (!empty($object->lines[$i]) && $object->lines[$i]->special_code == 3) {
2402 $result .= $outputlangs->transnoentities("Option");
2403 } elseif (empty($hidedetails) || $hidedetails > 1) {
2404 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht);
2405 if (!empty($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2406 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2407 $prev_progress = 0;
2408 $progress = 1;
2409 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2410 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2411 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2412 }
2413 $result .= price($sign * ($total_ht / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2414 } else {
2415 $result .= price($sign * $total_ht, 0, $outputlangs);
2416 }
2417 }
2418 }
2419 return $result;
2420}
2421
2431function pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails = 0)
2432{
2433 global $hookmanager, $conf;
2434
2435 $sign = 1;
2436 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2437 $sign = -1;
2438 }
2439
2440 $reshook = 0;
2441 $result = '';
2442 //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) ) )
2443 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
2444 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2445 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2446 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2447 }
2448 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2449 $action = '';
2450 $reshook = $hookmanager->executeHooks('pdf_getlinetotalwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2451
2452 if (!empty($hookmanager->resPrint)) {
2453 $result .= $hookmanager->resPrint;
2454 }
2455 }
2456 if (empty($reshook)) {
2457 if ($object->lines[$i]->special_code == 3) {
2458 $result .= $outputlangs->transnoentities("Option");
2459 } elseif (empty($hidedetails) || $hidedetails > 1) {
2460 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ttc : $object->lines[$i]->total_ttc);
2461 if (isset($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2462 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2463 $prev_progress = 0;
2464 $progress = 1;
2465 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2466 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2467 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2468 }
2469 $result .= price($sign * ($total_ttc / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2470 } else {
2471 $result .= price($sign * $total_ttc, 0, $outputlangs);
2472 }
2473 }
2474 }
2475 return $result;
2476}
2477
2486function pdf_getLinkedObjects(&$object, $outputlangs)
2487{
2488 global $db, $hookmanager;
2489
2490 $linkedobjects = array();
2491
2492 $object->fetchObjectLinked();
2493
2494 foreach ($object->linkedObjects as $objecttype => $objects) {
2495 if ($objecttype == 'facture') {
2496 // 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.
2497 } elseif ($objecttype == 'propal' || $objecttype == 'supplier_proposal') {
2498 '@phan-var-force array<Propal|SupplierProposal> $objects';
2499 $outputlangs->load('propal');
2500
2501 foreach ($objects as $elementobject) {
2502 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefProposal");
2503 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2504 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DatePropal");
2505 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2506 }
2507 } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order') {
2508 '@phan-var-force array<Commande|CommandeFournisseur> $objects';
2509 $outputlangs->load('orders');
2510
2511 if (count($objects) == 1) {
2512 $elementobject = array_shift($objects);
2513 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder");
2514 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref).(!empty($elementobject->ref_client) ? ' ('.$elementobject->ref_client.')' : '').(!empty($elementobject->ref_supplier) ? ' ('.$elementobject->ref_supplier.')' : '');
2515 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate");
2516 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2517 }
2518 } elseif ($objecttype == 'contrat') {
2519 '@phan-var-force Contrat[] $objects';
2520 $outputlangs->load('contracts');
2521 foreach ($objects as $elementobject) {
2522 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefContract");
2523 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2524 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateContract");
2525 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat, 'day', '', $outputlangs);
2526 }
2527 } elseif ($objecttype == 'fichinter') {
2528 '@phan-var-force Fichinter[] $objects';
2529 $outputlangs->load('interventions');
2530 foreach ($objects as $elementobject) {
2531 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("InterRef");
2532 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2533 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("InterDate");
2534 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->datec, 'day', '', $outputlangs);
2535 }
2536 } elseif ($objecttype == 'shipping') {
2537 '@phan-var-force Expedition[] $objects';
2538 $outputlangs->loadLangs(array("orders", "sendings"));
2539
2540 if (count($objects) > 1) {
2541 $order = null;
2542 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') {
2543 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :');
2544 } else {
2545 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefSending").' :');
2546 }
2547 // We concat this record info into fields xxx_value. title is overwrote.
2548 foreach ($objects as $elementobject) {
2549 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
2550 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2551 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2552 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2553 $order = new Commande($db);
2554 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2555 if ($ret < 1) {
2556 $order = null;
2557 }
2558 }
2559 }
2560
2561 if (! is_object($order)) {
2562 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref));
2563 } else {
2564 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : ''));
2565 $object->note_public = dol_concatdesc($object->note_public, ' / '.$outputlangs->transnoentities($elementobject->ref));
2566 }
2567 }
2568 } elseif (count($objects) == 1) {
2569 $elementobject = array_shift($objects);
2570 $order = null;
2571 // We concat this record info into fields xxx_value. title is overwrote.
2572 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
2573 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2574 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2575 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2576 $order = new Commande($db);
2577 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2578 if ($ret < 1) {
2579 $order = null;
2580 }
2581 }
2582 }
2583
2584 if (! is_object($order)) {
2585 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
2586 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2587 $linkedobjects[$objecttype]['ref_value'] = '';
2588 } else {
2589 $linkedobjects[$objecttype]['ref_value'] .= ' / ';
2590 }
2591 $linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref);
2592 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2593 } else {
2594 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending");
2595 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2596 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
2597 }
2598 $linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref);
2599 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2600 }
2601 }
2602 }
2603 }
2604
2605 // For add external linked objects
2606 if (is_object($hookmanager)) {
2607 $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs' => $outputlangs);
2608 $action = '';
2609 $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2610 if (!empty($hookmanager->resArray)) {
2611 $linkedobjects = $hookmanager->resArray;
2612 }
2613 }
2614
2615 return $linkedobjects;
2616}
2617
2625function pdf_getSizeForImage($realpath)
2626{
2627 global $conf;
2628
2629 $maxwidth = getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH', 20);
2630 $maxheight = getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT', 32);
2631 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2632 $tmp = dol_getImageSize($realpath);
2633 $width = 0;
2634 $height = 0;
2635 if ($tmp['height']) {
2636 $width = (int) round($maxheight * $tmp['width'] / $tmp['height']); // I try to use maxheight
2637 if ($width > $maxwidth) { // Pb with maxheight, so i use maxwidth
2638 $width = $maxwidth;
2639 $height = (int) round($maxwidth * $tmp['height'] / $tmp['width']);
2640 } else { // No pb with maxheight
2641 $height = $maxheight;
2642 }
2643 }
2644 return array('width' => $width, 'height' => $height);
2645}
2646
2656function pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails = 0)
2657{
2658 global $conf, $hookmanager;
2659
2660 $sign = 1;
2661 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2662 $sign = -1;
2663 }
2664 if ($object->lines[$i]->special_code == 3) {
2665 return $outputlangs->transnoentities("Option");
2666 } else {
2667 if (is_object($hookmanager)) {
2668 $special_code = $object->lines[$i]->special_code;
2669 if (!empty($object->lines[$i]->fk_parent_line)) {
2670 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2671 }
2672
2673 $parameters = array(
2674 'i' => $i,
2675 'outputlangs' => $outputlangs,
2676 'hidedetails' => $hidedetails,
2677 'special_code' => $special_code
2678 );
2679
2680 $action = '';
2681
2682 if ($hookmanager->executeHooks('getlinetotalremise', $parameters, $object, $action) > 0) { // Note that $action and $object may have been modified by some hooks
2683 if (isset($hookmanager->resArray['linetotalremise'])) {
2684 return $hookmanager->resArray['linetotalremise'];
2685 } else {
2686 return (float) $hookmanager->resPrint; // For backward compatibility
2687 }
2688 }
2689 }
2690
2691 if (empty($hidedetails) || $hidedetails > 1) {
2692 return $sign * (($object->lines[$i]->subprice * (float) $object->lines[$i]->qty) - $object->lines[$i]->total_ht);
2693 }
2694 }
2695 return 0;
2696}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
Class to manage categories.
Class to manage customers orders.
Class to manage contact/addresses.
Class to manage absolute discounts.
Class to manage warehouses.
static getIBANLabel(Account $account)
Returns the name of the Iban label.
File of class to manage predefined price products or services by customer.
Class to manage predefined suppliers products.
Class to manage products or services.
Manage record for batch number management.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
getState($id, $withcode='0', $dbtouse=null, $withregion=0, $outputlangs=null, $entconv=1)
Return state translated from an id.
getFormeJuridiqueLabel($code)
Return the name translated of juridical status.
dol_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.
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_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_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
dol_textishtml($msg, $option=0)
Return if a text is a html content.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add', $filterorigmodule='')
Complete or removed entries into a head array (used to build tabs).
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
dol_getImageSize($file, $url=false)
Return size of image file on disk (Supported extensions are gif, jpg, png, bmp and webp)
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:2625
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:1435
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2375
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:1490
pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails=0)
Return line total amount discount.
Definition pdf.lib.php:2656
pdf_getFormat($outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:86
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:288
pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails=0)
Return line quantity shipped.
Definition pdf.lib.php:2158
pdf_getlinenum($object, $i, $outputlangs, $hidedetails=0)
Return line num.
Definition pdf.lib.php:1833
pdf_getEncryption($pathoffile)
Return if pdf file is protected/encrypted.
Definition pdf.lib.php:234
pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price including tax.
Definition pdf.lib.php:2036
pdf_getLinkedObjects(&$object, $outputlangs)
Return linked objects to use for document generation.
Definition pdf.lib.php:2486
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:313
pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails=0)
Return line ref_supplier.
Definition pdf.lib.php:1899
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition pdf.lib.php:2431
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:1022
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:1993
pdf_getlineprogress($object, $i, $outputlangs, $hidedetails=0, $hookmanager=null)
Return line percent.
Definition pdf.lib.php:2324
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:1931
pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
Function to try to calculate height of a HTML Content.
Definition pdf.lib.php:338
pdf_admin_prepare_head()
Return array head with list of tabs to view object information.
Definition pdf.lib.php:48
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition pdf.lib.php:731
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1398
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank information for PDF generation.
Definition pdf.lib.php:845
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:265
pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails=0)
Return line keep to ship quantity.
Definition pdf.lib.php:2198
pdf_getlineref($object, $i, $outputlangs, $hidedetails=0)
Return line product ref.
Definition pdf.lib.php:1866
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:434
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0)
Return line unit.
Definition pdf.lib.php:2238
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2281
pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails=0)
Return line quantity asked.
Definition pdf.lib.php:2118
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2078
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:767
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:128
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition pdf.lib.php:386
pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition pdf.lib.php:787