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(Translate $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-1.3
184 if (getDolGlobalString('PDF_USE_A')) {
185 $pdfa = getDolGlobalString('PDF_USE_A'); // PDF/A-1 ou PDF/A-3
186 }
187
188 if (!getDolGlobalString('MAIN_DISABLE_TCPDI') && class_exists('TCPDI')) {
189 $pdf = new TCPDI($pagetype, $metric, $format, true, 'UTF-8', false, $pdfa);
190 } else {
191 $pdf = new TCPDF($pagetype, $metric, $format, true, 'UTF-8', false, $pdfa);
192 }
193
194 // Protection and encryption of pdf
195 if (getDolGlobalString('PDF_SECURITY_ENCRYPTION')) {
196 /* Permission supported by TCPDF
197 - print : Print the document;
198 - modify : Modify the contents of the document by operations other than those controlled by 'fill-forms', 'extract' and 'assemble';
199 - copy : Copy or otherwise extract text and graphics from the document;
200 - 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);
201 - fill-forms : Fill in existing interactive form fields (including signature fields), even if 'annot-forms' is not specified;
202 - extract : Extract text and graphics (in support of accessibility to users with disabilities or for other purposes);
203 - assemble : Assemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even if 'modify' is not set;
204 - 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.
205 - owner : (inverted logic - only for public-key) when set permits change of encryption and enables all other permissions.
206 */
207
208 // For TCPDF, we specify permission we want to block
209 $pdfrights = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_RIGHTS') ? json_decode($conf->global->PDF_SECURITY_ENCRYPTION_RIGHTS, true) : array('modify', 'copy')); // Json format in llx_const
210
211 // Password for the end user
212 $pdfuserpass = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_USERPASS') ? $conf->global->PDF_SECURITY_ENCRYPTION_USERPASS : '');
213
214 // Password of the owner, created randomly if not defined
215 $pdfownerpass = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_OWNERPASS') ? $conf->global->PDF_SECURITY_ENCRYPTION_OWNERPASS : null);
216
217 // For encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit
218 $encstrength = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_STRENGTH') ? $conf->global->PDF_SECURITY_ENCRYPTION_STRENGTH : 0);
219
220 // Array of recipients containing public-key certificates ('c') and permissions ('p').
221 // For example: array(array('c' => 'file://../examples/data/cert/tcpdf.crt', 'p' => array('print')))
222 $pubkeys = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_PUBKEYS') ? json_decode($conf->global->PDF_SECURITY_ENCRYPTION_PUBKEYS, true) : null); // Json format in llx_const
223
224 $pdf->SetProtection($pdfrights, $pdfuserpass, $pdfownerpass, $encstrength, $pubkeys);
225 }
226
227 return $pdf;
228}
229
236function pdf_getEncryption($pathoffile)
237{
238 require_once TCPDF_PATH.'tcpdf_parser.php';
239
240 $isencrypted = false;
241
242 $content = file_get_contents($pathoffile);
243
244 //ob_start();
245 @($parser = new TCPDF_PARSER(ltrim($content)));
246 list($xref, $data) = $parser->getParsedData();
247 unset($parser);
248 //ob_end_clean();
249
250 if (isset($xref['trailer']['encrypt'])) {
251 $isencrypted = true; // Secured pdf file are currently not supported
252 }
253
254 if (empty($data)) {
255 $isencrypted = true; // Object list not found. Possible secured file
256 }
257
258 return $isencrypted;
259}
260
267function pdf_getPDFFont($outputlangs)
268{
269 global $conf;
270
271 if (getDolGlobalString('MAIN_PDF_FORCE_FONT')) {
272 return $conf->global->MAIN_PDF_FORCE_FONT;
273 }
274
275 $font = 'Helvetica'; // By default, for FPDI, or ISO language on TCPDF
276 if (class_exists('TCPDF')) { // If TCPDF on, we can use an UTF8 one like DejaVuSans if required (slower)
277 if ($outputlangs->trans('FONTFORPDF') != 'FONTFORPDF') {
278 $font = $outputlangs->trans('FONTFORPDF');
279 }
280 }
281 return $font;
282}
283
290function pdf_getPDFFontSize($outputlangs)
291{
292 global $conf;
293
294 $size = 10; // By default, for FPDI or ISO language on TCPDF
295 if (class_exists('TCPDF')) { // If TCPDF on, we can use an UTF8 font like DejaVuSans if required (slower)
296 if ($outputlangs->trans('FONTSIZEFORPDF') != 'FONTSIZEFORPDF') {
297 $size = (int) $outputlangs->trans('FONTSIZEFORPDF');
298 }
299 }
300 if (getDolGlobalString('MAIN_PDF_FORCE_FONT_SIZE')) {
301 $size = getDolGlobalString('MAIN_PDF_FORCE_FONT_SIZE');
302 }
303
304 return $size;
305}
306
307
315function pdf_getHeightForLogo($logo, $url = false)
316{
317 global $conf;
318 $height = (!getDolGlobalString('MAIN_DOCUMENTS_LOGO_HEIGHT') ? 20 : $conf->global->MAIN_DOCUMENTS_LOGO_HEIGHT);
319 $maxwidth = 130;
320 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
321 $tmp = dol_getImageSize($logo, $url);
322 if ($tmp['height']) {
323 $width = round($height * $tmp['width'] / $tmp['height']);
324 if ($width > $maxwidth) {
325 $height = $height * $maxwidth / $width;
326 }
327 }
328 //print $tmp['width'].' '.$tmp['height'].' '.$width; exit;
329 return $height;
330}
331
340function pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
341{
342 // store current object
343 $pdf->startTransaction();
344 // store starting values
345 $start_y = $pdf->GetY();
346 //var_dump($start_y);
347 $start_page = $pdf->getPage();
348 // call printing functions with content
349 $pdf->writeHTMLCell(0, 0, 0, $start_y, $htmlcontent, 0, 1, false, true, 'J', true);
350 // get the new Y
351 $end_y = $pdf->GetY();
352 $end_page = $pdf->getPage();
353 // calculate height
354 $height = 0;
355 if ($end_page == $start_page) {
356 $height = $end_y - $start_y;
357 } else {
358 for ($page = $start_page; $page <= $end_page; ++$page) {
359 $pdf->setPage($page);
360 $tmpm = $pdf->getMargins();
361 $tMargin = $tmpm['top'];
362 if ($page == $start_page) {
363 // first page
364 $height = $pdf->getPageHeight() - $start_y - $pdf->getBreakMargin();
365 } elseif ($page == $end_page) {
366 // last page
367 $height = $end_y - $tMargin;
368 } else {
369 $height = $pdf->getPageHeight() - $tMargin - $pdf->getBreakMargin();
370 }
371 }
372 }
373 // restore previous object
374 $pdf = $pdf->rollbackTransaction();
375
376 return $height;
377}
378
379
388function pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias = 0)
389{
390 global $conf;
391
392 // Recipient name
393 $socname = '';
394
395 if ($thirdparty instanceof Societe) {
396 $socname = $thirdparty->name;
397 if (($includealias || getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME')) && !empty($thirdparty->name_alias)) {
398 if (getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME') == 2) {
399 $socname = $thirdparty->name_alias." - ".$thirdparty->name;
400 } else {
401 $socname = $thirdparty->name." - ".$thirdparty->name_alias;
402 }
403 }
404 } elseif ($thirdparty instanceof Contact) {
405 if ($thirdparty->socid > 0) {
406 $thirdparty->fetch_thirdparty();
407 $socname = $thirdparty->thirdparty->name;
408 if (($includealias || getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME')) && !empty($thirdparty->thirdparty->name_alias)) {
409 if (getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME') == 2) {
410 $socname = $thirdparty->thirdparty->name_alias." - ".$thirdparty->thirdparty->name;
411 } else {
412 $socname = $thirdparty->thirdparty->name." - ".$thirdparty->thirdparty->name_alias;
413 }
414 }
415 }
416 } else {
417 throw new InvalidArgumentException('Parameter 1 $thirdparty is not a Societe nor Contact');
418 }
419
420 return $outputlangs->convToOutputCharset($socname);
421}
422
423
436function pdf_build_address($outputlangs, $sourcecompany, $targetcompany = '', $targetcontact = '', $usecontact = 0, $mode = 'source', $object = null)
437{
438 global $hookmanager;
439
440 if ($mode == 'source' && !is_object($sourcecompany)) {
441 return -1;
442 }
443 if ($mode == 'target' && !is_object($targetcompany)) {
444 return -1;
445 }
446
447 if (!empty($sourcecompany->state_id) && empty($sourcecompany->state)) {
448 $sourcecompany->state = getState($sourcecompany->state_id);
449 }
450 if (!empty($targetcompany->state_id) && empty($targetcompany->state)) {
451 $targetcompany->state = getState($targetcompany->state_id);
452 }
453
454 $reshook = 0;
455 $stringaddress = '';
456 if (is_object($hookmanager)) {
457 $parameters = array('sourcecompany' => &$sourcecompany, 'targetcompany' => &$targetcompany, 'targetcontact' => &$targetcontact, 'outputlangs' => $outputlangs, 'mode' => $mode, 'usecontact' => $usecontact);
458 $action = '';
459 $reshook = $hookmanager->executeHooks('pdf_build_address', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
460 $stringaddress .= $hookmanager->resPrint;
461 }
462 if (empty($reshook)) {
463 if ($mode == 'source') {
464 $withCountry = 0;
465 if (isset($targetcompany->country_code) && !empty($sourcecompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
466 $withCountry = 1;
467 }
468
469 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($sourcecompany, $withCountry, "\n", $outputlangs))."\n";
470
471 if (!getDolGlobalString('MAIN_PDF_DISABLESOURCEDETAILS')) {
472 // Phone
473 if ($sourcecompany->phone) {
474 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("PhoneShort").": ".$outputlangs->convToOutputCharset($sourcecompany->phone);
475 }
476 // Fax
477 if ($sourcecompany->fax) {
478 $stringaddress .= ($stringaddress ? ($sourcecompany->phone ? " - " : "\n") : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($sourcecompany->fax);
479 }
480 // EMail
481 if ($sourcecompany->email) {
482 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($sourcecompany->email);
483 }
484 // Web
485 if ($sourcecompany->url) {
486 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($sourcecompany->url);
487 }
488 }
489 // Intra VAT
490 if (getDolGlobalString('MAIN_TVAINTRA_IN_SOURCE_ADDRESS')) {
491 if ($sourcecompany->tva_intra) {
492 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($sourcecompany->tva_intra);
493 }
494 }
495 // Professional Ids
496 $reg = array();
497 if (getDolGlobalString('MAIN_PROFID1_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof1)) {
498 $tmp = $outputlangs->transcountrynoentities("ProfId1", $sourcecompany->country_code);
499 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
500 $tmp = $reg[1];
501 }
502 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof1);
503 }
504 if (getDolGlobalString('MAIN_PROFID2_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof2)) {
505 $tmp = $outputlangs->transcountrynoentities("ProfId2", $sourcecompany->country_code);
506 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
507 $tmp = $reg[1];
508 }
509 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof2);
510 }
511 if (getDolGlobalString('MAIN_PROFID3_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof3)) {
512 $tmp = $outputlangs->transcountrynoentities("ProfId3", $sourcecompany->country_code);
513 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
514 $tmp = $reg[1];
515 }
516 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof3);
517 }
518 if (getDolGlobalString('MAIN_PROFID4_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof4)) {
519 $tmp = $outputlangs->transcountrynoentities("ProfId4", $sourcecompany->country_code);
520 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
521 $tmp = $reg[1];
522 }
523 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof4);
524 }
525 if (getDolGlobalString('MAIN_PROFID5_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof5)) {
526 $tmp = $outputlangs->transcountrynoentities("ProfId5", $sourcecompany->country_code);
527 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
528 $tmp = $reg[1];
529 }
530 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof5);
531 }
532 if (getDolGlobalString('MAIN_PROFID6_IN_SOURCE_ADDRESS') && !empty($sourcecompany->idprof6)) {
533 $tmp = $outputlangs->transcountrynoentities("ProfId6", $sourcecompany->country_code);
534 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
535 $tmp = $reg[1];
536 }
537 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof6);
538 }
539 if (getDolGlobalString('PDF_ADD_MORE_AFTER_SOURCE_ADDRESS')) {
540 $stringaddress .= ($stringaddress ? "\n" : '') . getDolGlobalString('PDF_ADD_MORE_AFTER_SOURCE_ADDRESS');
541 }
542 }
543
544 if ($mode == 'target' || preg_match('/targetwithdetails/', $mode)) {
545 if ($usecontact) {
546 if (is_object($targetcontact)) {
547 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($targetcontact->getFullName($outputlangs, 1));
548
549 if (!empty($targetcontact->address)) {
550 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcontact))."\n";
551 } else {
552 $companytouseforaddress = $targetcompany;
553
554 // Contact on a thirdparty that is a different thirdparty than the thirdparty of object
555 if ($targetcontact->socid > 0 && $targetcontact->socid != $targetcompany->id) {
556 $targetcontact->fetch_thirdparty();
557 $companytouseforaddress = $targetcontact->thirdparty;
558 }
559
560 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($companytouseforaddress))."\n";
561 }
562 // Country
563 if (!empty($targetcontact->country_code) && $targetcontact->country_code != $sourcecompany->country_code) {
564 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcontact->country_code));
565 } elseif (empty($targetcontact->country_code) && !empty($targetcompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
566 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
567 }
568
569 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
570 // Phone
571 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) {
572 if (!empty($targetcontact->phone_pro) || !empty($targetcontact->phone_mobile)) {
573 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": ";
574 }
575 if (!empty($targetcontact->phone_pro)) {
576 $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_pro);
577 }
578 if (!empty($targetcontact->phone_pro) && !empty($targetcontact->phone_mobile)) {
579 $stringaddress .= " / ";
580 }
581 if (!empty($targetcontact->phone_mobile)) {
582 $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_mobile);
583 }
584 }
585 // Fax
586 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) {
587 if ($targetcontact->fax) {
588 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcontact->fax);
589 }
590 }
591 // EMail
592 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) {
593 if ($targetcontact->email) {
594 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcontact->email);
595 }
596 }
597 // Web
598 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) {
599 if ($targetcontact->url) {
600 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcontact->url);
601 }
602 }
603 }
604 }
605 } else {
606 if (is_object($targetcompany)) {
607 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcompany));
608 // Country
609 if (!empty($targetcompany->country_code) && $targetcompany->country_code != $sourcecompany->country_code) {
610 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
611 } else {
612 $stringaddress .= ($stringaddress ? "\n" : '');
613 }
614
615 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
616 // Phone
617 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) {
618 if (!empty($targetcompany->phone)) {
619 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": ";
620 }
621 if (!empty($targetcompany->phone)) {
622 $stringaddress .= $outputlangs->convToOutputCharset($targetcompany->phone);
623 }
624 }
625 // Fax
626 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) {
627 if ($targetcompany->fax) {
628 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcompany->fax);
629 }
630 }
631 // EMail
632 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) {
633 if ($targetcompany->email) {
634 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcompany->email);
635 }
636 }
637 // Web
638 if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) {
639 if ($targetcompany->url) {
640 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcompany->url);
641 }
642 }
643 }
644 }
645 }
646
647 // Intra VAT
648 if (!getDolGlobalString('MAIN_TVAINTRA_NOT_IN_ADDRESS')) {
649 if ($usecontact && is_object($targetcontact) && getDolGlobalInt('MAIN_USE_COMPANY_NAME_OF_CONTACT')) {
650 $targetcontact->fetch_thirdparty();
651 if (!empty($targetcontact->thirdparty->id) && $targetcontact->thirdparty->tva_intra) {
652 $stringaddress .= ($stringaddress ? "\n" : '') . $outputlangs->transnoentities("VATIntraShort") . ': ' . $outputlangs->convToOutputCharset($targetcontact->thirdparty->tva_intra);
653 }
654 } elseif (!empty($targetcompany->tva_intra)) {
655 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($targetcompany->tva_intra);
656 }
657 }
658
659 // Legal form
660 if (getDolGlobalString('MAIN_LEGALFORM_IN_ADDRESS') && !empty($targetcompany->forme_juridique_code)) {
661 $tmp = getFormeJuridiqueLabel($targetcompany->forme_juridique_code);
662 $stringaddress .= ($stringaddress ? "\n" : '').$tmp;
663 }
664
665 // Professional Ids
666 if (getDolGlobalString('MAIN_PROFID1_IN_ADDRESS') && !empty($targetcompany->idprof1)) {
667 $tmp = $outputlangs->transcountrynoentities("ProfId1", $targetcompany->country_code);
668 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
669 $tmp = $reg[1];
670 }
671 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof1);
672 }
673 if (getDolGlobalString('MAIN_PROFID2_IN_ADDRESS') && !empty($targetcompany->idprof2)) {
674 $tmp = $outputlangs->transcountrynoentities("ProfId2", $targetcompany->country_code);
675 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
676 $tmp = $reg[1];
677 }
678 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof2);
679 }
680 if (getDolGlobalString('MAIN_PROFID3_IN_ADDRESS') && !empty($targetcompany->idprof3)) {
681 $tmp = $outputlangs->transcountrynoentities("ProfId3", $targetcompany->country_code);
682 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
683 $tmp = $reg[1];
684 }
685 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof3);
686 }
687 if (getDolGlobalString('MAIN_PROFID4_IN_ADDRESS') && !empty($targetcompany->idprof4)) {
688 $tmp = $outputlangs->transcountrynoentities("ProfId4", $targetcompany->country_code);
689 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
690 $tmp = $reg[1];
691 }
692 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof4);
693 }
694 if (getDolGlobalString('MAIN_PROFID5_IN_ADDRESS') && !empty($targetcompany->idprof5)) {
695 $tmp = $outputlangs->transcountrynoentities("ProfId5", $targetcompany->country_code);
696 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
697 $tmp = $reg[1];
698 }
699 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof5);
700 }
701 if (getDolGlobalString('MAIN_PROFID6_IN_ADDRESS') && !empty($targetcompany->idprof6)) {
702 $tmp = $outputlangs->transcountrynoentities("ProfId6", $targetcompany->country_code);
703 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
704 $tmp = $reg[1];
705 }
706 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof6);
707 }
708
709 // Public note
710 if (getDolGlobalString('MAIN_PUBLIC_NOTE_IN_ADDRESS')) {
711 if ($mode == 'source' && !empty($sourcecompany->note_public)) {
712 $stringaddress .= ($stringaddress ? "\n" : '').dol_string_nohtmltag($sourcecompany->note_public);
713 }
714 if (($mode == 'target' || preg_match('/targetwithdetails/', $mode)) && !empty($targetcompany->note_public)) {
715 $stringaddress .= ($stringaddress ? "\n" : '').dol_string_nohtmltag($targetcompany->note_public);
716 }
717 }
718 }
719 }
720
721 return $stringaddress;
722}
723
724
733function pdf_pagehead(&$pdf, $outputlangs, $page_height)
734{
735 global $conf;
736
737 // Add a background image on document only if good setup of const
738 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
739 $filepath = $conf->mycompany->dir_output.'/logos/' . getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF');
740 if (file_exists($filepath)) {
741 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak before adding image
742 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) {
743 $pdf->SetAlpha($conf->global->MAIN_USE_BACKGROUND_ON_PDF_ALPHA);
744 } // Option for change opacity of background
745 $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);
746 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) {
747 $pdf->SetAlpha(1);
748 }
749 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
750 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
751 }
752 }
753 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') != '-1') {
754 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
755 }
756}
757
758
769function pdf_getSubstitutionArray($outputlangs, $exclude = null, $object = null, $onlykey = 0, $include = null)
770{
771 $substitutionarray = getCommonSubstitutionArray($outputlangs, $onlykey, $exclude, $object, $include);
772 $substitutionarray['__FROM_NAME__'] = '__FROM_NAME__';
773 $substitutionarray['__FROM_EMAIL__'] = '__FROM_EMAIL__';
774 return $substitutionarray;
775}
776
777
789function pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
790{
791 // Print Draft Watermark
792 if ($unit == 'pt') {
793 $k = 1;
794 } elseif ($unit == 'mm') {
795 $k = 72 / 25.4;
796 } elseif ($unit == 'cm') {
797 $k = 72 / 2.54;
798 } elseif ($unit == 'in') {
799 $k = 72;
800 }
801
802 // Make substitution
803 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, null);
804 complete_substitutions_array($substitutionarray, $outputlangs, null);
805 $text = make_substitutions($text, $substitutionarray, $outputlangs);
806 $text = $outputlangs->convToOutputCharset($text);
807
808 $savx = $pdf->getX();
809 $savy = $pdf->getY();
810
811 $watermark_angle = atan($h / $w) / 2;
812 $watermark_x_pos = 0;
813 $watermark_y_pos = $h / 3;
814 $watermark_x = $w / 2;
815 $watermark_y = $h / 3;
816 $pdf->SetFont('', 'B', 40);
817 $pdf->SetTextColor(255, 192, 203);
818
819 //rotate
820 $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));
821 //print watermark
822 $pdf->SetXY($watermark_x_pos, $watermark_y_pos);
823 $pdf->Cell($w - 20, 25, $outputlangs->convToOutputCharset($text), "", 2, "C", 0);
824 //antirotate
825 $pdf->_out('Q');
826
827 $pdf->SetXY($savx, $savy);
828}
829
830
843function pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, $default_font_size = 10)
844{
845 global $mysoc, $conf;
846
847 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbank.class.php';
848
849 $diffsizetitle = getDolGlobalInt('PDF_DIFFSIZE_TITLE', 3);
850 $diffsizecontent = getDolGlobalInt('PDF_DIFFSIZE_CONTENT', 4);
851 $pdf->SetXY($curx, $cury);
852
853 if (empty($onlynumber)) {
854 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
855 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByTransferOnThisBankAccount').':', 0, 'L', 0);
856 $cury += 4;
857 }
858
859 $outputlangs->load("banks");
860
861 // Use correct name of bank id according to country
862 $bickey = "BICNumber";
863 if ($account->getCountryCode() == 'IN') {
864 $bickey = "SWIFT";
865 }
866
867 // Get format of bank account according to its country
868 $usedetailedbban = $account->useDetailedBBAN();
869
870 //$onlynumber=0; $usedetailedbban=1; // For tests
871 if ($usedetailedbban) {
872 $savcurx = $curx;
873
874 if (empty($onlynumber)) {
875 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
876 $pdf->SetXY($curx, $cury);
877 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
878 $cury += 3;
879 }
880
881 if (!getDolGlobalString('PDF_BANK_HIDE_NUMBER_SHOW_ONLY_BICIBAN')) { // Note that some countries still need bank number, BIC/IBAN not enough for them
882 // Note:
883 // bank = code_banque (FR), sort code (GB, IR. Example: 12-34-56)
884 // desk = code guichet (FR), used only when $usedetailedbban = 1
885 // number = account number
886 // key = check control key used only when $usedetailedbban = 1
887 if (empty($onlynumber)) {
888 $pdf->line($curx + 1, $cury + 1, $curx + 1, $cury + 6);
889 }
890
891
892 foreach ($account->getFieldsToShow() as $val) {
893 $pdf->SetXY($curx, $cury + 4);
894 $pdf->SetFont('', '', $default_font_size - 3);
895
896 if ($val == 'BankCode') {
897 // Bank code
898 $tmplength = 18;
899 $content = $account->code_banque;
900 } elseif ($val == 'DeskCode') {
901 // Desk
902 $tmplength = 18;
903 $content = $account->code_guichet;
904 } elseif ($val == 'BankAccountNumber') {
905 // Number
906 $tmplength = 24;
907 $content = $account->number;
908 } elseif ($val == 'BankAccountNumberKey') {
909 // Key
910 $tmplength = 15;
911 $content = $account->cle_rib;
912 } elseif ($val == 'IBAN' || $val == 'BIC') {
913 // Key
914 $tmplength = 0;
915 $content = '';
916 } else {
917 dol_print_error($account->db, 'Unexpected value for getFieldsToShow: '.$val);
918 break;
919 }
920
921 $pdf->MultiCell($tmplength, 3, $outputlangs->convToOutputCharset($content), 0, 'C', 0);
922 $pdf->SetXY($curx, $cury + 1);
923 $curx += $tmplength;
924 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
925 $pdf->MultiCell($tmplength, 3, $outputlangs->transnoentities($val), 0, 'C', 0);
926 if (empty($onlynumber)) {
927 $pdf->line($curx, $cury + 1, $curx, $cury + 7);
928 }
929 }
930
931 $curx = $savcurx;
932 $cury += 8;
933 }
934 } elseif (!empty($account->number)) {
935 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
936 $pdf->SetXY($curx, $cury);
937 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
938 $cury += 3;
939
940 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
941 $pdf->SetXY($curx, $cury);
942 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("BankAccountNumber").': '.$outputlangs->convToOutputCharset($account->number), 0, 'L', 0);
943 $cury += 3;
944
945 if ($diffsizecontent <= 2) {
946 $cury += 1;
947 }
948 }
949
950 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
951
952 if (empty($onlynumber) && (!empty($account->domiciliation) || !empty($account->address))) {
953 $pdf->SetXY($curx, $cury);
954 $val = $outputlangs->transnoentities("Residence").': '.$outputlangs->convToOutputCharset(empty($account->address) ? $account->domiciliation : $account->address);
955 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
956 //$nboflines=dol_nboflines_bis($val,120);
957 //$cury+=($nboflines*3)+2;
958 $tmpy = $pdf->getStringHeight(100, $val);
959 $cury += $tmpy;
960 }
961
962 if (!empty($account->owner_name)) {
963 $pdf->SetXY($curx, $cury);
964 $val = $outputlangs->transnoentities("BankAccountOwner").': '.$outputlangs->convToOutputCharset($account->owner_name);
965 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
966 $tmpy = $pdf->getStringHeight(100, $val);
967 $cury += $tmpy;
968 } elseif (!$usedetailedbban) {
969 $cury += 1;
970 }
971
972 // Use correct name of bank id according to country
973 $ibankey = FormBank::getIBANLabel($account);
974
975 if (!empty($account->iban)) {
976 //Remove whitespaces to ensure we are dealing with the format we expect
977 $ibanDisplay_temp = str_replace(' ', '', $outputlangs->convToOutputCharset($account->iban));
978 $ibanDisplay = "";
979
980 $nbIbanDisplay_temp = dol_strlen($ibanDisplay_temp);
981 for ($i = 0; $i < $nbIbanDisplay_temp; $i++) {
982 $ibanDisplay .= $ibanDisplay_temp[$i];
983 if ($i % 4 == 3 && $i > 0) {
984 $ibanDisplay .= " ";
985 }
986 }
987
988 $pdf->SetFont('', 'B', $default_font_size - 3);
989 $pdf->SetXY($curx, $cury);
990 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($ibankey).': '.$ibanDisplay, 0, 'L', 0);
991 $cury += 3;
992 }
993
994 if (!empty($account->bic)) {
995 $pdf->SetFont('', 'B', $default_font_size - 3);
996 $pdf->SetXY($curx, $cury);
997 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($bickey).': '.$outputlangs->convToOutputCharset($account->bic), 0, 'L', 0);
998 }
999
1000 return $pdf->getY();
1001}
1002
1020function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails = 0, $hidefreetext = 0, $page_largeur = 0, $watermark = '')
1021{
1022 global $conf, $hookmanager;
1023
1024 $outputlangs->load("dict");
1025 $line = '';
1026 $reg = array();
1027 $marginwithfooter = 0; // Return value
1028
1029 $dims = $pdf->getPageDimensions();
1030
1031 // Line of free text
1032 if (empty($hidefreetext) && getDolGlobalString($paramfreetext)) {
1033 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
1034 // More substitution keys
1035 $substitutionarray['__FROM_NAME__'] = $fromcompany->name;
1036 $substitutionarray['__FROM_EMAIL__'] = $fromcompany->email;
1037 complete_substitutions_array($substitutionarray, $outputlangs, $object);
1038 $newfreetext = make_substitutions(getDolGlobalString($paramfreetext), $substitutionarray, $outputlangs);
1039
1040 // Make a change into HTML code to allow to include images from medias directory.
1041 // <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1042 // become
1043 // <img alt="" src="'.DOL_DATA_ROOT.'/medias/image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1044 $newfreetext = preg_replace('/(<img.*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)("[^\/]*\/>)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $newfreetext);
1045
1046 $line .= $outputlangs->convToOutputCharset($newfreetext);
1047 }
1048
1049 // First line of company infos
1050 $line1 = "";
1051 $line2 = "";
1052 $line3 = "";
1053 $line4 = "";
1054
1055 if ($showdetails == 1 || $showdetails == 3) {
1056 // Company name
1057 if ($fromcompany->name) {
1058 $line1 .= ($line1 ? " - " : "").$outputlangs->transnoentities("RegisteredOffice").": ".$fromcompany->name;
1059 }
1060 // Address
1061 if ($fromcompany->address) {
1062 $line1 .= ($line1 ? " - " : "").str_replace("\n", ", ", $fromcompany->address);
1063 }
1064 // Zip code
1065 if ($fromcompany->zip) {
1066 $line1 .= ($line1 ? " - " : "").$fromcompany->zip;
1067 }
1068 // Town
1069 if ($fromcompany->town) {
1070 $line1 .= ($line1 ? " " : "").$fromcompany->town;
1071 }
1072 // Country
1073 if ($fromcompany->country) {
1074 $line1 .= ($line1 ? ", " : "").$fromcompany->country;
1075 }
1076 // Phone
1077 if ($fromcompany->phone) {
1078 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Phone").": ".$fromcompany->phone;
1079 }
1080 // Fax
1081 if ($fromcompany->fax) {
1082 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Fax").": ".$fromcompany->fax;
1083 }
1084
1085 // URL
1086 if ($fromcompany->url) {
1087 $line2 .= ($line2 ? " - " : "").$fromcompany->url;
1088 }
1089 // Email
1090 if ($fromcompany->email) {
1091 $line2 .= ($line2 ? " - " : "").$fromcompany->email;
1092 }
1093 }
1094 if ($showdetails == 2 || $showdetails == 3 || (!empty($fromcompany->country_code) && $fromcompany->country_code == 'DE')) {
1095 // Managers
1096 if ($fromcompany->managers) {
1097 $line2 .= ($line2 ? " - " : "").$fromcompany->managers;
1098 }
1099 }
1100
1101 // Line 3 of company infos
1102 // Juridical status
1103 if (!empty($fromcompany->forme_juridique_code) && $fromcompany->forme_juridique_code) {
1104 $line3 .= ($line3 ? " - " : "").$outputlangs->convToOutputCharset(getFormeJuridiqueLabel($fromcompany->forme_juridique_code));
1105 }
1106 // Capital
1107 if (!empty($fromcompany->capital)) {
1108 $tmpamounttoshow = price2num($fromcompany->capital); // This field is a free string or a float
1109 if (is_numeric($tmpamounttoshow) && $tmpamounttoshow > 0) {
1110 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", price($tmpamounttoshow, 0, $outputlangs, 0, 0, 0, $conf->currency));
1111 } elseif (!empty($fromcompany->capital)) {
1112 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", $fromcompany->capital, $outputlangs);
1113 }
1114 }
1115 // Prof Id 1
1116 if (!empty($fromcompany->idprof1) && $fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || !$fromcompany->idprof2)) {
1117 $field = $outputlangs->transcountrynoentities("ProfId1", $fromcompany->country_code);
1118 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1119 $field = $reg[1];
1120 }
1121 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof1);
1122 }
1123 // Prof Id 2
1124 if (!empty($fromcompany->idprof2) && $fromcompany->idprof2) {
1125 $field = $outputlangs->transcountrynoentities("ProfId2", $fromcompany->country_code);
1126 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1127 $field = $reg[1];
1128 }
1129 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof2);
1130 }
1131
1132 // Line 4 of company infos
1133 // Prof Id 3
1134 if (!empty($fromcompany->idprof3) && $fromcompany->idprof3) {
1135 $field = $outputlangs->transcountrynoentities("ProfId3", $fromcompany->country_code);
1136 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1137 $field = $reg[1];
1138 }
1139 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof3);
1140 }
1141 // Prof Id 4
1142 if (!empty($fromcompany->idprof4) && $fromcompany->idprof4) {
1143 $field = $outputlangs->transcountrynoentities("ProfId4", $fromcompany->country_code);
1144 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1145 $field = $reg[1];
1146 }
1147 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof4);
1148 }
1149 // Prof Id 5
1150 if (!empty($fromcompany->idprof5) && $fromcompany->idprof5) {
1151 $field = $outputlangs->transcountrynoentities("ProfId5", $fromcompany->country_code);
1152 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1153 $field = $reg[1];
1154 }
1155 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof5);
1156 }
1157 // Prof Id 6
1158 if (!empty($fromcompany->idprof6) && $fromcompany->idprof6) {
1159 $field = $outputlangs->transcountrynoentities("ProfId6", $fromcompany->country_code);
1160 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1161 $field = $reg[1];
1162 }
1163 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof6);
1164 }
1165 // Prof Id 7
1166 if (!empty($fromcompany->idprof7) && $fromcompany->idprof7) {
1167 $field = $outputlangs->transcountrynoentities("ProfId7", $fromcompany->country_code);
1168 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1169 $field = $reg[1];
1170 }
1171 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof7);
1172 }
1173 // Prof Id 8
1174 if (!empty($fromcompany->idprof8) && $fromcompany->idprof8) {
1175 $field = $outputlangs->transcountrynoentities("ProfId8", $fromcompany->country_code);
1176 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1177 $field = $reg[1];
1178 }
1179 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof8);
1180 }
1181 // Prof Id 9
1182 if (!empty($fromcompany->idprof9) && $fromcompany->idprof9) {
1183 $field = $outputlangs->transcountrynoentities("ProfId9", $fromcompany->country_code);
1184 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1185 $field = $reg[1];
1186 }
1187 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof9);
1188 }
1189 // Prof Id 10
1190 if (!empty($fromcompany->idprof10) && $fromcompany->idprof10) {
1191 $field = $outputlangs->transcountrynoentities("ProfId10", $fromcompany->country_code);
1192 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1193 $field = $reg[1];
1194 }
1195 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof10);
1196 }
1197 // IntraCommunautary VAT
1198 if (!empty($fromcompany->tva_intra) && $fromcompany->tva_intra != '') {
1199 $line4 .= ($line4 ? " - " : "").$outputlangs->transnoentities("VATIntraShort").": ".$outputlangs->convToOutputCharset($fromcompany->tva_intra);
1200 }
1201
1202 $pdf->SetFont('', '', 7);
1203 $pdf->SetDrawColor(224, 224, 224);
1204 // Option for footer text color
1205 if (getDolGlobalString('PDF_FOOTER_TEXT_COLOR')) {
1206 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_TEXT_COLOR, '%d, %d, %d');
1207 $pdf->SetTextColor($r, $g, $b);
1208 }
1209
1210 // The start of the bottom of this page footer is positioned according to # of lines
1211 $freetextheight = 0;
1212 if ($line) { // Free text
1213 //$line="sample text<br>\nfd<strong>sf</strong>sdf<br>\nghfghg<br>";
1214 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) {
1215 $width = 20000;
1216 $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.
1217 if (getDolGlobalString('MAIN_USE_AUTOWRAP_ON_FREETEXT')) {
1218 $width = 200;
1219 $align = 'C';
1220 }
1221 $freetextheight = $pdf->getStringHeight($width, $line);
1222 } else {
1223 $freetextheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); // New method (works for HTML content)
1224 //print '<br>'.$freetextheight;exit;
1225 }
1226 }
1227
1228 // For customize footer
1229 if (is_object($hookmanager)) {
1230 $parameters = array('line1' => $line1, 'line2' => $line2, 'line3' => $line3, 'line4' => $line4, 'outputlangs' => $outputlangs);
1231 $action = '';
1232 $hookmanager->executeHooks('pdf_pagefoot', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1233 if (!empty($hookmanager->resPrint) && $hidefreetext == 0) {
1234 $mycustomfooter = $hookmanager->resPrint;
1235 $mycustomfooterheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1236
1237 $marginwithfooter = $marge_basse + $freetextheight + $mycustomfooterheight;
1238 $posy = (float) $marginwithfooter;
1239
1240 // Option for footer background color (without freetext zone)
1241 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1242 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1243 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1244 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b));
1245 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1246 }
1247
1248 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1249 $pdf->SetAutoPageBreak(0, 0);
1250 } // Option for disable auto pagebreak
1251 if ($line) { // Free text
1252 $pdf->SetXY($dims['lm'], -$posy);
1253 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1254 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1255 } else {
1256 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1257 }
1258 $posy -= $freetextheight;
1259 }
1260 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1261 $pdf->SetAutoPageBreak(1, 0);
1262 } // Restore pagebreak
1263
1264 $pdf->SetY(-$posy);
1265
1266 // Hide footer line if footer background color is set
1267 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1268 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1269 }
1270
1271 // Option for set top margin height of footer after freetext
1272 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1273 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1274 } else {
1275 $posy--;
1276 }
1277
1278 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1279 $pdf->SetAutoPageBreak(0, 0);
1280 } // Option for disable auto pagebreak
1281 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1282 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1283 $pdf->SetAutoPageBreak(1, 0);
1284 } // Restore pagebreak
1285
1286 $posy -= $mycustomfooterheight - 3;
1287 } else {
1288 // Else default footer
1289 $marginwithfooter = $marge_basse + $freetextheight + (!empty($line1) ? 3 : 0) + (!empty($line2) ? 3 : 0) + (!empty($line3) ? 3 : 0) + (!empty($line4) ? 3 : 0);
1290 $posy = (float) $marginwithfooter;
1291
1292 // Option for footer background color (without freetext zone)
1293 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1294 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1295 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1296 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b));
1297 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1298 }
1299
1300 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1301 $pdf->SetAutoPageBreak(0, 0);
1302 } // Option for disable auto pagebreak
1303 if ($line) { // Free text
1304 $pdf->SetXY($dims['lm'], -$posy);
1305 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1306 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1307 } else {
1308 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1309 }
1310 $posy -= $freetextheight;
1311 }
1312 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1313 $pdf->SetAutoPageBreak(1, 0);
1314 } // Restore pagebreak
1315
1316 $pdf->SetY(-$posy);
1317
1318 // Option for hide all footer (page number will no hidden)
1319 if (!getDolGlobalInt('PDF_FOOTER_HIDDEN')) {
1320 // Hide footer line if footer background color is set
1321 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1322 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1323 }
1324
1325 // Option for set top margin height of footer after freetext
1326 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1327 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1328 } else {
1329 $posy--;
1330 }
1331
1332 if (!empty($line1)) {
1333 $pdf->SetFont('', 'B', 7);
1334 $pdf->SetXY($dims['lm'], -$posy);
1335 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line1, 0, 'C', 0);
1336 $posy -= 3;
1337 $pdf->SetFont('', '', 7);
1338 }
1339
1340 if (!empty($line2)) {
1341 $pdf->SetFont('', 'B', 7);
1342 $pdf->SetXY($dims['lm'], -$posy);
1343 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line2, 0, 'C', 0);
1344 $posy -= 3;
1345 $pdf->SetFont('', '', 7);
1346 }
1347
1348 if (!empty($line3)) {
1349 $pdf->SetXY($dims['lm'], -$posy);
1350 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line3, 0, 'C', 0);
1351 }
1352
1353 if (!empty($line4)) {
1354 $posy -= 3;
1355 $pdf->SetXY($dims['lm'], -$posy);
1356 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line4, 0, 'C', 0);
1357 }
1358 }
1359 }
1360 }
1361
1362 // Show page nb and apply correction for some font.
1363 $pdf->SetXY($dims['wk'] - $dims['rm'] - 18 - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_X', 0), -$posy - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_Y', 0));
1364
1365 $pagination = $pdf->PageNo().' / '.$pdf->getAliasNbPages();
1366 $fontRenderCorrection = 0;
1367 if (in_array(pdf_getPDFFont($outputlangs), array('freemono', 'DejaVuSans'))) {
1368 $fontRenderCorrection = 10;
1369 }
1370 $pdf->MultiCell(18 + $fontRenderCorrection, 2, $pagination, 0, 'R', 0);
1371
1372 // Show Draft Watermark
1373 if (!empty($watermark)) {
1374 pdf_watermark($pdf, $outputlangs, $page_hauteur, $page_largeur, 'mm', $watermark);
1375 }
1376
1377 return $marginwithfooter;
1378}
1379
1394function pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
1395{
1396 $linkedobjects = pdf_getLinkedObjects($object, $outputlangs);
1397 if (!empty($linkedobjects)) {
1398 foreach ($linkedobjects as $linkedobject) {
1399 $reftoshow = $linkedobject["ref_title"].' : '.$linkedobject["ref_value"];
1400 if (!empty($linkedobject["date_value"])) {
1401 $reftoshow .= ' / '.$linkedobject["date_value"];
1402 }
1403
1404 $posy += 3;
1405 $pdf->SetXY($posx, $posy);
1406 $pdf->SetFont('', '', $default_font_size - 2);
1407 $pdf->MultiCell($w, $h, $reftoshow, '', $align);
1408 }
1409 }
1410
1411 return $pdf->getY();
1412}
1413
1431function pdf_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref = 0, $hidedesc = 0, $issupplierline = 0, $align = 'J')
1432{
1433 global $db, $conf, $langs, $hookmanager;
1434
1435 $reshook = 0;
1436 $result = '';
1437 //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) ) )
1438 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1439 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1440 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1441 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1442 }
1443 $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);
1444 $action = '';
1445 $reshook = $hookmanager->executeHooks('pdf_writelinedesc', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1446
1447 if (!empty($hookmanager->resPrint)) {
1448 $result .= $hookmanager->resPrint;
1449 }
1450 }
1451 if (empty($reshook)) {
1452 $labelproductservice = pdf_getlinedesc($object, $i, $outputlangs, $hideref, $hidedesc, $issupplierline);
1453 $labelproductservice = preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $labelproductservice, -1, $nbrep);
1454
1455 //var_dump($labelproductservice);exit;
1456
1457 // 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"
1458 // We make the reverse, so PDF generation has the real URL.
1459 $nbrep = 0;
1460 $labelproductservice = preg_replace('/(<img[^>]*src=")([^"]*)(&amp;)([^"]*")/', '\1\2&\4', $labelproductservice, -1, $nbrep);
1461
1462 if (getDolGlobalString('MARGIN_TOP_ZERO_UL')) {
1463 $pdf->setListIndentWidth(5);
1464 $TMarginList = ['ul' => [['h'=>0.1, ],['h'=>0.1, ]], 'li' => [['h'=>0.1, ],],];
1465 $pdf->setHtmlVSpace($TMarginList);
1466 }
1467
1468 // Description
1469 $pdf->writeHTMLCell($w, $h, $posx, $posy, $outputlangs->convToOutputCharset($labelproductservice), 0, 1, false, true, $align, true);
1470 $result .= $labelproductservice;
1471 }
1472 return $result;
1473}
1474
1486function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1487{
1488 global $db, $conf, $langs;
1489
1490 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1491 $label = (!empty($object->lines[$i]->label) ? $object->lines[$i]->label : (!empty($object->lines[$i]->product_label) ? $object->lines[$i]->product_label : ''));
1492 $product_barcode = (!empty($object->lines[$i]->product_barcode) ? $object->lines[$i]->product_barcode : "");
1493 $desc = (!empty($object->lines[$i]->desc) ? $object->lines[$i]->desc : (!empty($object->lines[$i]->description) ? $object->lines[$i]->description : ''));
1494 $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
1495 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1496 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1497
1498 if ($issupplierline) {
1499 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
1500 $prodser = new ProductFournisseur($db);
1501 } else {
1502 include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1503 $prodser = new Product($db);
1504
1505 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
1506 include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
1507 }
1508 }
1509
1510 if ($idprod) {
1511 $prodser->fetch($idprod);
1512 // If a predefined product and multilang and on other lang, we renamed label with label translated
1513 if (getDolGlobalInt('MAIN_MULTILANGS') && ($outputlangs->defaultlang != $langs->defaultlang)) {
1514 $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)
1515
1516 // 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
1517 // ($textwasnotmodified is replaced with $textwasmodifiedorcompleted and we add completion).
1518
1519 // Set label
1520 // 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.
1521 //var_dump($outputlangs->defaultlang.' - '.$langs->defaultlang.' - '.$label.' - '.$prodser->label);exit;
1522 $textwasnotmodified = ($label == $prodser->label);
1523 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["label"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1524 $label = $prodser->multilangs[$outputlangs->defaultlang]["label"];
1525 }
1526
1527 // Set desc
1528 // Manage HTML entities description test because $prodser->description is store with htmlentities but $desc no
1529 $textwasnotmodified = false;
1530 if (!empty($desc) && dol_textishtml($desc) && !empty($prodser->description) && dol_textishtml($prodser->description)) {
1531 $textwasnotmodified = (strpos(dol_html_entity_decode($desc, ENT_QUOTES | ENT_HTML5), dol_html_entity_decode($prodser->description, ENT_QUOTES | ENT_HTML5)) !== false);
1532 } else {
1533 $textwasnotmodified = ($desc == $prodser->description);
1534 }
1535 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["description"])) {
1536 if ($textwasnotmodified) {
1537 $desc = str_replace($prodser->description, $prodser->multilangs[$outputlangs->defaultlang]["description"], $desc);
1538 } elseif ($translatealsoifmodified) {
1539 $desc = $prodser->multilangs[$outputlangs->defaultlang]["description"];
1540 }
1541 }
1542
1543 // Set note
1544 $textwasnotmodified = ($note == $prodser->note_public);
1545 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["other"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1546 $note = $prodser->multilangs[$outputlangs->defaultlang]["other"];
1547 }
1548 }
1549 } 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
1550 $desc = str_replace('(DEPOSIT)', $outputlangs->trans('Deposit'), $desc);
1551 }
1552
1553 if (!getDolGlobalString('PDF_HIDE_PRODUCT_LABEL_IN_SUPPLIER_LINES')) {
1554 // Description short of product line
1555 $libelleproduitservice = $label;
1556 if (!empty($libelleproduitservice) && getDolGlobalString('PDF_BOLD_PRODUCT_LABEL')) {
1557 // Adding <b> may convert the original string into a HTML string. So we have to first
1558 // convert \n into <br> we text is not already HTML.
1559 if (!dol_textishtml($libelleproduitservice)) {
1560 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1561 }
1562 $libelleproduitservice = '<b>'.$libelleproduitservice.'</b>';
1563 }
1564 }
1565
1566
1567 // Add ref of subproducts
1568 if (getDolGlobalString('SHOW_SUBPRODUCT_REF_IN_PDF')) {
1569 $prodser->get_sousproduits_arbo();
1570 if (!empty($prodser->sousprods) && is_array($prodser->sousprods) && count($prodser->sousprods)) {
1571 $outputlangs->load('mrp');
1572 $tmparrayofsubproducts = reset($prodser->sousprods);
1573
1574 $qtyText = null;
1575 if (isset($object->lines[$i]->qty) && !empty($object->lines[$i]->qty)) {
1576 $qtyText = $object->lines[$i]->qty;
1577 } elseif (isset($object->lines[$i]->qty_shipped) && !empty($object->lines[$i]->qty_shipped)) {
1578 $qtyText = $object->lines[$i]->qty;
1579 }
1580
1581 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF')) {
1582 foreach ($tmparrayofsubproducts as $subprodval) {
1583 $libelleproduitservice = dol_concatdesc(
1584 dol_concatdesc($libelleproduitservice, " * ".$subprodval[3]),
1585 (!empty($qtyText) ?
1586 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1] * $qtyText :
1587 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1588 );
1589 }
1590 } else {
1591 foreach ($tmparrayofsubproducts as $subprodval) {
1592 $libelleproduitservice = dol_concatdesc(
1593 dol_concatdesc($libelleproduitservice, " * ".$subprodval[5].(($subprodval[5] && $subprodval[3]) ? ' - ' : '').$subprodval[3]),
1594 (!empty($qtyText) ?
1595 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1] * $qtyText :
1596 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1597 );
1598 }
1599 }
1600 }
1601 }
1602
1603 if (isModEnabled('barcode') && getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_PRODUCT_BARCODE') && !empty($product_barcode)) {
1604 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $outputlangs->trans("BarCode")." ".$product_barcode);
1605 }
1606
1607 // Description long of product line
1608 if (!empty($desc) && ($desc != $label)) {
1609 if ($desc == '(CREDIT_NOTE)' && $object->lines[$i]->fk_remise_except) {
1610 $discount = new DiscountAbsolute($db);
1611 $discount->fetch($object->lines[$i]->fk_remise_except);
1612 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1613 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromCreditNote", $sourceref);
1614 } elseif ($desc == '(DEPOSIT)' && $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("DiscountFromDeposit", $sourceref);
1619 // Add date of deposit
1620 if (getDolGlobalString('INVOICE_ADD_DEPOSIT_DATE')) {
1621 $libelleproduitservice .= ' ('.dol_print_date($discount->datec, 'day', '', $outputlangs).')';
1622 }
1623 } elseif ($desc == '(EXCESS RECEIVED)' && $object->lines[$i]->fk_remise_except) {
1624 $discount = new DiscountAbsolute($db);
1625 $discount->fetch($object->lines[$i]->fk_remise_except);
1626 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived", $discount->ref_facture_source);
1627 } elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except) {
1628 $discount = new DiscountAbsolute($db);
1629 $discount->fetch($object->lines[$i]->fk_remise_except);
1630 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid", $discount->ref_invoice_supplier_source);
1631 } else {
1632 if ($idprod) {
1633 // Check if description must be output
1634 if (!empty($object->element)) {
1635 $tmpkey = 'MAIN_DOCUMENTS_HIDE_DESCRIPTION_FOR_'.strtoupper($object->element);
1636 if (getDolGlobalString($tmpkey)) {
1637 $hidedesc = 1;
1638 }
1639 }
1640 if (empty($hidedesc)) {
1641 if (getDolGlobalString('MAIN_DOCUMENTS_DESCRIPTION_FIRST')) {
1642 $libelleproduitservice = dol_concatdesc($desc, $libelleproduitservice);
1643 } else {
1644 if (getDolGlobalString('HIDE_LABEL_VARIANT_PDF') && $prodser->isVariant()) {
1645 $libelleproduitservice = $desc;
1646 } else {
1647 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1648 }
1649 }
1650 }
1651 } else {
1652 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1653 }
1654 }
1655 }
1656
1657 // We add ref of product (and supplier ref if defined)
1658 $prefix_prodserv = "";
1659 $ref_prodserv = "";
1660 if (getDolGlobalString('PRODUCT_ADD_TYPE_IN_DOCUMENTS')) { // In standard mode, we do not show this
1661 if ($prodser->isService()) {
1662 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." ";
1663 } else {
1664 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." ";
1665 }
1666 }
1667
1668 if (empty($hideref)) {
1669 if ($issupplierline) {
1670 if (!getDolGlobalString('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES')) { // Common case
1671 $ref_prodserv = $prodser->ref; // Show local ref
1672 if ($ref_supplier) {
1673 $ref_prodserv .= ($prodser->ref ? ' (' : '').$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.($prodser->ref ? ')' : '');
1674 }
1675 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 1) {
1676 $ref_prodserv = $ref_supplier;
1677 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 2) {
1678 $ref_prodserv = $ref_supplier.' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')';
1679 }
1680 } else {
1681 $ref_prodserv = $prodser->ref; // Show local ref only
1682
1683 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
1684 $productCustomerPriceStatic = new ProductCustomerPrice($db);
1685 $filter = array('fk_product' => $idprod, 'fk_soc' => $object->socid);
1686
1687 $nbCustomerPrices = $productCustomerPriceStatic->fetchAll('', '', 1, 0, $filter);
1688
1689 if ($nbCustomerPrices > 0) {
1690 $productCustomerPrice = $productCustomerPriceStatic->lines[0];
1691
1692 if (!empty($productCustomerPrice->ref_customer)) {
1693 switch ($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
1694 case 1:
1695 $ref_prodserv = $productCustomerPrice->ref_customer;
1696 break;
1697
1698 case 2:
1699 $ref_prodserv = $productCustomerPrice->ref_customer . ' (' . $outputlangs->transnoentitiesnoconv('InternalRef') . ' ' . $ref_prodserv . ')';
1700 break;
1701
1702 default:
1703 $ref_prodserv = $ref_prodserv . ' (' . $outputlangs->transnoentitiesnoconv('RefCustomer') . ' ' . $productCustomerPrice->ref_customer . ')';
1704 }
1705 }
1706 }
1707 }
1708 }
1709
1710 if (!empty($libelleproduitservice) && !empty($ref_prodserv)) {
1711 $ref_prodserv .= " - ";
1712 }
1713 }
1714
1715 if (!empty($ref_prodserv) && getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1716 if (!dol_textishtml($libelleproduitservice)) {
1717 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1718 }
1719 $ref_prodserv = '<b>'.$ref_prodserv.'</b>';
1720 // $prefix_prodserv and $ref_prodser are not HTML var
1721 }
1722 $libelleproduitservice = $prefix_prodserv.$ref_prodserv.$libelleproduitservice;
1723
1724 // Add an additional description for the category products
1725 if (getDolGlobalString('CATEGORY_ADD_DESC_INTO_DOC') && $idprod && isModEnabled('category')) {
1726 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1727 $categstatic = new Categorie($db);
1728 // recovering the list of all the categories linked to product
1729 $tblcateg = $categstatic->containing($idprod, Categorie::TYPE_PRODUCT);
1730 foreach ($tblcateg as $cate) {
1731 // Adding the descriptions if they are filled
1732 $desccateg = $cate->description;
1733 if ($desccateg) {
1734 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desccateg);
1735 }
1736 }
1737 }
1738
1739 if (!empty($object->lines[$i]->date_start) || !empty($object->lines[$i]->date_end)) {
1740 $format = 'day';
1741 $period = '';
1742 // Show duration if exists
1743 if ($object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1744 $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)).')';
1745 }
1746 if ($object->lines[$i]->date_start && !$object->lines[$i]->date_end) {
1747 $period = '('.$outputlangs->transnoentitiesnoconv('DateFrom', dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs)).')';
1748 }
1749 if (!$object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1750 $period = '('.$outputlangs->transnoentitiesnoconv('DateUntil', dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
1751 }
1752 //print '>'.$outputlangs->charset_output.','.$period;
1753 if (getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1754 if (!dol_textishtml($libelleproduitservice)) {
1755 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1756 }
1757 $libelleproduitservice .= '<br><b style="color:#333666;" ><em>'.$period.'</em></b>';
1758 } else {
1759 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $period);
1760 }
1761 //print $libelleproduitservice;
1762 }
1763
1764 // Show information for lot
1765 if (!empty($dbatch)) {
1766 // $object is a shipment.
1767 //var_dump($object->lines[$i]->details_entrepot); // array from llx_expeditiondet (we can have several lines for one fk_origin_line)
1768 //var_dump($object->lines[$i]->detail_batch); // array from llx_expeditiondet_batch (each line with a lot is linked to llx_expeditiondet)
1769
1770 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1771 include_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
1772 $tmpwarehouse = new Entrepot($db);
1773 $tmpproductbatch = new Productbatch($db);
1774
1775 $format = 'day';
1776 foreach ($dbatch as $detail) {
1777 $dte = array();
1778 if ($detail->eatby) {
1779 $dte[] = $outputlangs->transnoentitiesnoconv('printEatby', dol_print_date($detail->eatby, $format, false, $outputlangs));
1780 }
1781 if ($detail->sellby) {
1782 $dte[] = $outputlangs->transnoentitiesnoconv('printSellby', dol_print_date($detail->sellby, $format, false, $outputlangs));
1783 }
1784 if ($detail->batch) {
1785 $dte[] = $outputlangs->transnoentitiesnoconv('printBatch', $detail->batch);
1786 }
1787 $dte[] = $outputlangs->transnoentitiesnoconv('printQty', $detail->qty);
1788
1789 // Add also info of planned warehouse for lot
1790 if ($object->element == 'shipping' && $detail->fk_origin_stock > 0 && getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1791 $resproductbatch = $tmpproductbatch->fetch($detail->fk_origin_stock);
1792 if ($resproductbatch > 0) {
1793 $reswarehouse = $tmpwarehouse->fetch($tmpproductbatch->warehouseid);
1794 if ($reswarehouse > 0) {
1795 $dte[] = $tmpwarehouse->ref;
1796 }
1797 }
1798 }
1799
1800 $libelleproduitservice .= "__N__ ".implode(" - ", $dte);
1801 }
1802 } else {
1803 if (getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1804 // TODO Show warehouse for shipment line without batch
1805 }
1806 }
1807
1808 // Now we convert \n into br
1809 if (dol_textishtml($libelleproduitservice)) {
1810 $libelleproduitservice = preg_replace('/__N__/', '<br>', $libelleproduitservice);
1811 } else {
1812 $libelleproduitservice = preg_replace('/__N__/', "\n", $libelleproduitservice);
1813 }
1814 $libelleproduitservice = dol_htmlentitiesbr($libelleproduitservice, 1);
1815
1816 return $libelleproduitservice;
1817}
1818
1828function pdf_getlinenum($object, $i, $outputlangs, $hidedetails = 0)
1829{
1830 global $hookmanager;
1831
1832 $reshook = 0;
1833 $result = '';
1834 //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) ) )
1835 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1836 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1837 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1838 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1839 }
1840 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1841 $action = '';
1842 $reshook = $hookmanager->executeHooks('pdf_getlinenum', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1843 $result .= $hookmanager->resPrint;
1844 }
1845 if (empty($reshook)) {
1846 $result .= dol_htmlentitiesbr($object->lines[$i]->num);
1847 }
1848 return $result;
1849}
1850
1851
1861function pdf_getlineref($object, $i, $outputlangs, $hidedetails = 0)
1862{
1863 global $hookmanager;
1864
1865 $reshook = 0;
1866 $result = '';
1867 //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) ) )
1868 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1869 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1870 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1871 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1872 }
1873 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1874 $action = '';
1875 $reshook = $hookmanager->executeHooks('pdf_getlineref', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1876 $result .= $hookmanager->resPrint;
1877 }
1878 if (empty($reshook)) {
1879 $result .= dol_htmlentitiesbr($object->lines[$i]->product_ref);
1880 }
1881 return $result;
1882}
1883
1893function pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails = 0)
1894{
1895 global $hookmanager;
1896
1897 $reshook = 0;
1898 $result = '';
1899 //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) ) )
1900 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1901 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1902 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1903 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1904 }
1905 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1906 $action = '';
1907 $reshook = $hookmanager->executeHooks('pdf_getlineref_supplier', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1908 $result .= $hookmanager->resPrint;
1909 }
1910 if (empty($reshook)) {
1911 $result .= dol_htmlentitiesbr($object->lines[$i]->ref_supplier);
1912 }
1913 return $result;
1914}
1915
1925function pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails = 0)
1926{
1927 global $conf, $hookmanager, $mysoc;
1928
1929 $result = '';
1930 $reshook = 0;
1931 //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) ) )
1932 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
1933 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1934 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1935 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1936 }
1937 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1938 $action = '';
1939 $reshook = $hookmanager->executeHooks('pdf_getlinevatrate', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1940
1941 if (!empty($hookmanager->resPrint)) {
1942 $result .= $hookmanager->resPrint;
1943 }
1944 }
1945 if (empty($reshook)) {
1946 if (empty($hidedetails) || $hidedetails > 1) {
1947 $tmpresult = '';
1948
1949 $tmpresult .= vatrate($object->lines[$i]->tva_tx, 0, $object->lines[$i]->info_bits, -1);
1950 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_SECOND_TAX')) {
1951 if ($object->lines[$i]->total_localtax1 != 0) {
1952 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
1953 $tmpresult .= '/';
1954 } else {
1955 $tmpresult = '';
1956 }
1957 $tmpresult .= vatrate(abs($object->lines[$i]->localtax1_tx), 0);
1958 }
1959 }
1960 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_THIRD_TAX')) {
1961 if ($object->lines[$i]->total_localtax2 != 0) {
1962 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
1963 $tmpresult .= '/';
1964 } else {
1965 $tmpresult = '';
1966 }
1967 $tmpresult .= vatrate(abs($object->lines[$i]->localtax2_tx), 0);
1968 }
1969 }
1970 $tmpresult .= '%';
1971
1972 $result .= $tmpresult;
1973 }
1974 }
1975 return $result;
1976}
1977
1987function pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails = 0)
1988{
1989 global $conf, $hookmanager;
1990
1991 $sign = 1;
1992 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
1993 $sign = -1;
1994 }
1995
1996 $result = '';
1997 $reshook = 0;
1998 //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) ) )
1999 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2000 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2001 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2002 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2003 }
2004 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2005 $action = '';
2006 $reshook = $hookmanager->executeHooks('pdf_getlineupexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2007
2008 if (!empty($hookmanager->resPrint)) {
2009 $result .= $hookmanager->resPrint;
2010 }
2011 }
2012 if (empty($reshook)) {
2013 if (empty($hidedetails) || $hidedetails > 1) {
2014 $subprice = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_subprice : $object->lines[$i]->subprice);
2015 $result .= price($sign * $subprice, 0, $outputlangs);
2016 }
2017 }
2018 return $result;
2019}
2020
2030function pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails = 0)
2031{
2032 global $hookmanager, $conf;
2033
2034 $sign = 1;
2035 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2036 $sign = -1;
2037 }
2038
2039 $result = '';
2040 $reshook = 0;
2041 //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) ) )
2042 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2043 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2044 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2045 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2046 }
2047 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2048 $action = '';
2049 $reshook = $hookmanager->executeHooks('pdf_getlineupwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2050
2051 if (!empty($hookmanager->resPrint)) {
2052 $result .= $hookmanager->resPrint;
2053 }
2054 }
2055 if (empty($reshook)) {
2056 if (empty($hidedetails) || $hidedetails > 1) {
2057 $result .= price($sign * (($object->lines[$i]->subprice) + ($object->lines[$i]->subprice) * ($object->lines[$i]->tva_tx) / 100), 0, $outputlangs);
2058 }
2059 }
2060 return $result;
2061}
2062
2072function pdf_getlineqty($object, $i, $outputlangs, $hidedetails = 0)
2073{
2074 global $hookmanager;
2075
2076 $result = '';
2077 $reshook = 0;
2078 //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) ) )
2079 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2080 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2081 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2082 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2083 }
2084 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2085 $action = '';
2086 $reshook = $hookmanager->executeHooks('pdf_getlineqty', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2087
2088 if (!empty($hookmanager->resPrint)) {
2089 $result = $hookmanager->resPrint;
2090 }
2091 }
2092 if (empty($reshook)) {
2093 if ($object->lines[$i]->special_code == 3) {
2094 return '';
2095 }
2096 if (empty($hidedetails) || $hidedetails > 1) {
2097 $result .= $object->lines[$i]->qty;
2098 }
2099 }
2100 return $result;
2101}
2102
2112function pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails = 0)
2113{
2114 global $hookmanager;
2115
2116 $reshook = 0;
2117 $result = '';
2118 //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) ) )
2119 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2120 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2121 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2122 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2123 }
2124 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2125 $action = '';
2126 $reshook = $hookmanager->executeHooks('pdf_getlineqty_asked', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2127
2128 if (!empty($hookmanager->resPrint)) {
2129 $result .= $hookmanager->resPrint;
2130 }
2131 }
2132 if (empty($reshook)) {
2133 if ($object->lines[$i]->special_code == 3) {
2134 return '';
2135 }
2136 if (empty($hidedetails) || $hidedetails > 1) {
2137 $result .= $object->lines[$i]->qty_asked;
2138 }
2139 }
2140 return $result;
2141}
2142
2152function pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails = 0)
2153{
2154 global $hookmanager;
2155
2156 $reshook = 0;
2157 $result = '';
2158 //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) ) )
2159 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2160 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2161 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2162 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2163 }
2164 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2165 $action = '';
2166 $reshook = $hookmanager->executeHooks('pdf_getlineqty_shipped', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2167
2168 if (!empty($hookmanager->resPrint)) {
2169 $result .= $hookmanager->resPrint;
2170 }
2171 }
2172 if (empty($reshook)) {
2173 if ($object->lines[$i]->special_code == 3) {
2174 return '';
2175 }
2176 if (empty($hidedetails) || $hidedetails > 1) {
2177 $result .= $object->lines[$i]->qty_shipped;
2178 }
2179 }
2180 return $result;
2181}
2182
2192function pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails = 0)
2193{
2194 global $hookmanager;
2195
2196 $reshook = 0;
2197 $result = '';
2198 //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) ) )
2199 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2200 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2201 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2202 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2203 }
2204 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2205 $action = '';
2206 $reshook = $hookmanager->executeHooks('pdf_getlineqty_keeptoship', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2207
2208 if (!empty($hookmanager->resPrint)) {
2209 $result .= $hookmanager->resPrint;
2210 }
2211 }
2212 if (empty($reshook)) {
2213 if ($object->lines[$i]->special_code == 3) {
2214 return '';
2215 }
2216 if (empty($hidedetails) || $hidedetails > 1) {
2217 $result .= ($object->lines[$i]->qty_asked - $object->lines[$i]->qty_shipped);
2218 }
2219 }
2220 return $result;
2221}
2222
2232function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0)
2233{
2234 global $hookmanager, $langs;
2235
2236 $reshook = 0;
2237 $result = '';
2238 //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) ) )
2239 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2240 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2241 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2242 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2243 }
2244 $parameters = array(
2245 'i' => $i,
2246 'outputlangs' => $outputlangs,
2247 'hidedetails' => $hidedetails,
2248 'special_code' => $special_code
2249 );
2250 $action = '';
2251 $reshook = $hookmanager->executeHooks('pdf_getlineunit', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2252
2253 if (!empty($hookmanager->resPrint)) {
2254 $result .= $hookmanager->resPrint;
2255 }
2256 }
2257 if (empty($reshook)) {
2258 if (empty($hidedetails) || $hidedetails > 1) {
2259 $result .= $langs->transnoentitiesnoconv($object->lines[$i]->getLabelOfUnit('short'));
2260 }
2261 }
2262 return $result;
2263}
2264
2265
2275function pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails = 0)
2276{
2277 global $hookmanager;
2278
2279 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2280
2281 $reshook = 0;
2282 $result = '';
2283 //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) ) )
2284 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2285 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2286 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2287 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2288 }
2289 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2290 $action = '';
2291 $reshook = $hookmanager->executeHooks('pdf_getlineremisepercent', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2292
2293 if (!empty($hookmanager->resPrint)) {
2294 $result .= $hookmanager->resPrint;
2295 }
2296 }
2297 if (empty($reshook)) {
2298 if ($object->lines[$i]->special_code == 3) {
2299 return '';
2300 }
2301 if (empty($hidedetails) || $hidedetails > 1) {
2302 $result .= dol_print_reduction($object->lines[$i]->remise_percent, $outputlangs);
2303 }
2304 }
2305 return $result;
2306}
2307
2318function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = null)
2319{
2320 if (empty($hookmanager)) {
2321 global $hookmanager;
2322 }
2323 global $conf;
2324
2325 $reshook = 0;
2326 $result = '';
2327 //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) ) )
2328 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2329 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2330 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2331 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2332 }
2333 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2334 $action = '';
2335 $reshook = $hookmanager->executeHooks('pdf_getlineprogress', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2336
2337 if (!empty($hookmanager->resPrint)) {
2338 return $hookmanager->resPrint;
2339 }
2340 }
2341 if (empty($reshook)) {
2342 if ($object->lines[$i]->special_code == 3) {
2343 return '';
2344 }
2345 if (empty($hidedetails) || $hidedetails > 1) {
2346 if (getDolGlobalString('SITUATION_DISPLAY_DIFF_ON_PDF')) {
2347 $prev_progress = 0;
2348 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2349 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2350 }
2351 $result = round($object->lines[$i]->situation_percent - $prev_progress, 1).'%';
2352 } else {
2353 $result = round($object->lines[$i]->situation_percent, 1).'%';
2354 }
2355 }
2356 }
2357 return $result;
2358}
2359
2369function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0)
2370{
2371 global $conf, $hookmanager;
2372
2373 $sign = 1;
2374 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2375 $sign = -1;
2376 }
2377
2378 $reshook = 0;
2379 $result = '';
2380 //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) ) )
2381 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2382 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2383 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2384 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2385 }
2386 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code, 'sign' => $sign);
2387 $action = '';
2388 $reshook = $hookmanager->executeHooks('pdf_getlinetotalexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2389
2390 if (!empty($hookmanager->resPrint)) {
2391 $result .= $hookmanager->resPrint;
2392 }
2393 }
2394 if (empty($reshook)) {
2395 if (!empty($object->lines[$i]) && $object->lines[$i]->special_code == 3) {
2396 $result .= $outputlangs->transnoentities("Option");
2397 } elseif (empty($hidedetails) || $hidedetails > 1) {
2398 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht);
2399 if (!empty($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2400 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2401 $prev_progress = 0;
2402 $progress = 1;
2403 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2404 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2405 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2406 }
2407 $result .= price($sign * ($total_ht / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2408 } else {
2409 $result .= price($sign * $total_ht, 0, $outputlangs);
2410 }
2411 }
2412 }
2413 return $result;
2414}
2415
2425function pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails = 0)
2426{
2427 global $hookmanager, $conf;
2428
2429 $sign = 1;
2430 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2431 $sign = -1;
2432 }
2433
2434 $reshook = 0;
2435 $result = '';
2436 //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) ) )
2437 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2438 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2439 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2440 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2441 }
2442 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2443 $action = '';
2444 $reshook = $hookmanager->executeHooks('pdf_getlinetotalwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2445
2446 if (!empty($hookmanager->resPrint)) {
2447 $result .= $hookmanager->resPrint;
2448 }
2449 }
2450 if (empty($reshook)) {
2451 if ($object->lines[$i]->special_code == 3) {
2452 $result .= $outputlangs->transnoentities("Option");
2453 } elseif (empty($hidedetails) || $hidedetails > 1) {
2454 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ttc : $object->lines[$i]->total_ttc);
2455 if (isset($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2456 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2457 $prev_progress = 0;
2458 $progress = 1;
2459 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2460 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2461 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2462 }
2463 $result .= price($sign * ($total_ttc / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2464 } else {
2465 $result .= price($sign * $total_ttc, 0, $outputlangs);
2466 }
2467 }
2468 }
2469 return $result;
2470}
2471
2480function pdf_getLinkedObjects(&$object, $outputlangs)
2481{
2482 global $db, $hookmanager;
2483
2484 $linkedobjects = array();
2485
2486 $object->fetchObjectLinked();
2487
2488 foreach ($object->linkedObjects as $objecttype => $objects) {
2489 if ($objecttype == 'facture') {
2490 // 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.
2491 } elseif ($objecttype == 'propal' || $objecttype == 'supplier_proposal') {
2492 $outputlangs->load('propal');
2493
2494 foreach ($objects as $elementobject) {
2495 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefProposal");
2496 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2497 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DatePropal");
2498 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2499 }
2500 } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order') {
2501 $outputlangs->load('orders');
2502
2503 if (count($objects) == 1) {
2504 $elementobject = array_shift($objects);
2505 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder");
2506 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref).(!empty($elementobject->ref_client) ? ' ('.$elementobject->ref_client.')' : '').(!empty($elementobject->ref_supplier) ? ' ('.$elementobject->ref_supplier.')' : '');
2507 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate");
2508 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2509 }
2510 } elseif ($objecttype == 'contrat') {
2511 $outputlangs->load('contracts');
2512 foreach ($objects as $elementobject) {
2513 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefContract");
2514 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2515 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateContract");
2516 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat, 'day', '', $outputlangs);
2517 }
2518 } elseif ($objecttype == 'fichinter') {
2519 $outputlangs->load('interventions');
2520 foreach ($objects as $elementobject) {
2521 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("InterRef");
2522 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2523 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("InterDate");
2524 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->datec, 'day', '', $outputlangs);
2525 }
2526 } elseif ($objecttype == 'shipping') {
2527 $outputlangs->loadLangs(array("orders", "sendings"));
2528
2529 if (count($objects) > 1) {
2530 $order = null;
2531 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') {
2532 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :');
2533 } else {
2534 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefSending").' :');
2535 }
2536 // We concat this record info into fields xxx_value. title is overwrote.
2537 foreach ($objects as $elementobject) {
2538 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
2539 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2540 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2541 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2542 $order = new Commande($db);
2543 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2544 if ($ret < 1) {
2545 $order = null;
2546 }
2547 }
2548 }
2549
2550 if (! is_object($order)) {
2551 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref));
2552 } else {
2553 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : ''));
2554 $object->note_public = dol_concatdesc($object->note_public, ' / '.$outputlangs->transnoentities($elementobject->ref));
2555 }
2556 }
2557 } elseif (count($objects) == 1) {
2558 $elementobject = array_shift($objects);
2559 $order = null;
2560 // We concat this record info into fields xxx_value. title is overwrote.
2561 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
2562 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2563 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2564 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2565 $order = new Commande($db);
2566 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2567 if ($ret < 1) {
2568 $order = null;
2569 }
2570 }
2571 }
2572
2573 if (! is_object($order)) {
2574 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
2575 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2576 $linkedobjects[$objecttype]['ref_value'] = '';
2577 } else {
2578 $linkedobjects[$objecttype]['ref_value'] .= ' / ';
2579 }
2580 $linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref);
2581 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2582 } else {
2583 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending");
2584 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2585 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
2586 }
2587 $linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref);
2588 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2589 }
2590 }
2591 }
2592 }
2593
2594 // For add external linked objects
2595 if (is_object($hookmanager)) {
2596 $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs' => $outputlangs);
2597 $action = '';
2598 $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2599 if (!empty($hookmanager->resArray)) {
2600 $linkedobjects = $hookmanager->resArray;
2601 }
2602 }
2603
2604 return $linkedobjects;
2605}
2606
2614function pdf_getSizeForImage($realpath)
2615{
2616 global $conf;
2617
2618 $maxwidth = getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH', 20);
2619 $maxheight = getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT', 32);
2620 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2621 $tmp = dol_getImageSize($realpath);
2622 $width = 0;
2623 $height = 0;
2624 if ($tmp['height']) {
2625 $width = (int) round($maxheight * $tmp['width'] / $tmp['height']); // I try to use maxheight
2626 if ($width > $maxwidth) { // Pb with maxheight, so i use maxwidth
2627 $width = $maxwidth;
2628 $height = (int) round($maxwidth * $tmp['height'] / $tmp['width']);
2629 } else { // No pb with maxheight
2630 $height = $maxheight;
2631 }
2632 }
2633 return array('width' => $width, 'height' => $height);
2634}
2635
2645function pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails = 0)
2646{
2647 global $conf, $hookmanager;
2648
2649 $sign = 1;
2650 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2651 $sign = -1;
2652 }
2653 if ($object->lines[$i]->special_code == 3) {
2654 return $outputlangs->transnoentities("Option");
2655 } else {
2656 if (is_object($hookmanager)) {
2657 $special_code = $object->lines[$i]->special_code;
2658 if (!empty($object->lines[$i]->fk_parent_line)) {
2659 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2660 }
2661
2662 $parameters = array(
2663 'i' => $i,
2664 'outputlangs' => $outputlangs,
2665 'hidedetails' => $hidedetails,
2666 'special_code' => $special_code
2667 );
2668
2669 $action = '';
2670
2671 if ($hookmanager->executeHooks('getlinetotalremise', $parameters, $object, $action) > 0) { // Note that $action and $object may have been modified by some hooks
2672 if (isset($hookmanager->resArray['linetotalremise'])) {
2673 return $hookmanager->resArray['linetotalremise'];
2674 } else {
2675 return (float) $hookmanager->resPrint; // For backward compatibility
2676 }
2677 }
2678 }
2679
2680 if (empty($hidedetails) || $hidedetails > 1) {
2681 return $sign * (($object->lines[$i]->subprice * (float) $object->lines[$i]->qty) - $object->lines[$i]->total_ht);
2682 }
2683 }
2684 return 0;
2685}
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(Translate $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 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:2614
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:1431
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2369
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:1486
pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails=0)
Return line total amount discount.
Definition pdf.lib.php:2645
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:290
pdf_getFormat(Translate $outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:86
pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails=0)
Return line quantity shipped.
Definition pdf.lib.php:2152
pdf_getlinenum($object, $i, $outputlangs, $hidedetails=0)
Return line num.
Definition pdf.lib.php:1828
pdf_getEncryption($pathoffile)
Return if pdf file is protected/encrypted.
Definition pdf.lib.php:236
pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price including tax.
Definition pdf.lib.php:2030
pdf_getLinkedObjects(&$object, $outputlangs)
Return linked objects to use for document generation.
Definition pdf.lib.php:2480
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:315
pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails=0)
Return line ref_supplier.
Definition pdf.lib.php:1893
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition pdf.lib.php:2425
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:1020
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:1987
pdf_getlineprogress($object, $i, $outputlangs, $hidedetails=0, $hookmanager=null)
Return line percent.
Definition pdf.lib.php:2318
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:1925
pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
Function to try to calculate height of a HTML Content.
Definition pdf.lib.php:340
pdf_admin_prepare_head()
Return array head with list of tabs to view object information.
Definition pdf.lib.php:48
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition pdf.lib.php:733
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1394
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank information for PDF generation.
Definition pdf.lib.php:843
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:267
pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails=0)
Return line keep to ship quantity.
Definition pdf.lib.php:2192
pdf_getlineref($object, $i, $outputlangs, $hidedetails=0)
Return line product ref.
Definition pdf.lib.php:1861
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:436
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0)
Return line unit.
Definition pdf.lib.php:2232
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2275
pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails=0)
Return line quantity asked.
Definition pdf.lib.php:2112
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2072
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:769
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:388
pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition pdf.lib.php:789