dolibarr 20.0.4
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, 0, 0);
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
824 // set alpha to semi-transparency
825 $pdf->SetAlpha(0.3);
826 $pdf->Cell($w - 20, 25, $outputlangs->convToOutputCharset($text), "", 2, "C", 0);
827
828 //antirotate
829 $pdf->_out('Q');
830
831 $pdf->SetXY($savx, $savy);
832
833 // Restore alpha
834 $pdf->SetAlpha(1);
835}
836
837
850function pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, $default_font_size = 10)
851{
852 global $mysoc, $conf;
853
854 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbank.class.php';
855
856 $diffsizetitle = getDolGlobalInt('PDF_DIFFSIZE_TITLE', 3);
857 $diffsizecontent = getDolGlobalInt('PDF_DIFFSIZE_CONTENT', 4);
858 $pdf->SetXY($curx, $cury);
859
860 if (empty($onlynumber)) {
861 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
862 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByTransferOnThisBankAccount').':', 0, 'L', 0);
863 $cury += 4;
864 }
865
866 $outputlangs->load("banks");
867
868 // Use correct name of bank id according to country
869 $bickey = "BICNumber";
870 if ($account->getCountryCode() == 'IN') {
871 $bickey = "SWIFT";
872 }
873
874 // Get format of bank account according to its country
875 $usedetailedbban = $account->useDetailedBBAN();
876
877 //$onlynumber=0; $usedetailedbban=1; // For tests
878 if ($usedetailedbban) {
879 $savcurx = $curx;
880
881 if (empty($onlynumber)) {
882 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
883 $pdf->SetXY($curx, $cury);
884 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
885 $cury += 3;
886 }
887
888 if (!getDolGlobalString('PDF_BANK_HIDE_NUMBER_SHOW_ONLY_BICIBAN')) { // Note that some countries still need bank number, BIC/IBAN not enough for them
889 // Note:
890 // bank = code_banque (FR), sort code (GB, IR. Example: 12-34-56)
891 // desk = code guichet (FR), used only when $usedetailedbban = 1
892 // number = account number
893 // key = check control key used only when $usedetailedbban = 1
894 if (empty($onlynumber)) {
895 $pdf->line($curx + 1, $cury + 1, $curx + 1, $cury + 6);
896 }
897
898
899 foreach ($account->getFieldsToShow() as $val) {
900 $pdf->SetXY($curx, $cury + 4);
901 $pdf->SetFont('', '', $default_font_size - 3);
902
903 if ($val == 'BankCode') {
904 // Bank code
905 $tmplength = 18;
906 $content = $account->code_banque;
907 } elseif ($val == 'DeskCode') {
908 // Desk
909 $tmplength = 18;
910 $content = $account->code_guichet;
911 } elseif ($val == 'BankAccountNumber') {
912 // Number
913 $tmplength = 24;
914 $content = $account->number;
915 } elseif ($val == 'BankAccountNumberKey') {
916 // Key
917 $tmplength = 15;
918 $content = $account->cle_rib;
919 } elseif ($val == 'IBAN' || $val == 'BIC') {
920 // Key
921 $tmplength = 0;
922 $content = '';
923 } else {
924 dol_print_error($account->db, 'Unexpected value for getFieldsToShow: '.$val);
925 break;
926 }
927
928 $pdf->MultiCell($tmplength, 3, $outputlangs->convToOutputCharset($content), 0, 'C', 0);
929 $pdf->SetXY($curx, $cury + 1);
930 $curx += $tmplength;
931 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
932 $pdf->MultiCell($tmplength, 3, $outputlangs->transnoentities($val), 0, 'C', 0);
933 if (empty($onlynumber)) {
934 $pdf->line($curx, $cury + 1, $curx, $cury + 7);
935 }
936 }
937
938 $curx = $savcurx;
939 $cury += 8;
940 }
941 } elseif (!empty($account->number)) {
942 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
943 $pdf->SetXY($curx, $cury);
944 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
945 $cury += 3;
946
947 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
948 $pdf->SetXY($curx, $cury);
949 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("BankAccountNumber").': '.$outputlangs->convToOutputCharset($account->number), 0, 'L', 0);
950 $cury += 3;
951
952 if ($diffsizecontent <= 2) {
953 $cury += 1;
954 }
955 }
956
957 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
958
959 if (empty($onlynumber) && (!empty($account->domiciliation) || !empty($account->address))) {
960 $pdf->SetXY($curx, $cury);
961 $val = $outputlangs->transnoentities("Residence").': '.$outputlangs->convToOutputCharset(empty($account->address) ? $account->domiciliation : $account->address);
962 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
963 //$nboflines=dol_nboflines_bis($val,120);
964 //$cury+=($nboflines*3)+2;
965 $tmpy = $pdf->getStringHeight(100, $val);
966 $cury += $tmpy;
967 }
968
969 if (!empty($account->owner_name)) {
970 $pdf->SetXY($curx, $cury);
971 $val = $outputlangs->transnoentities("BankAccountOwner").': '.$outputlangs->convToOutputCharset($account->owner_name);
972 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
973 $tmpy = $pdf->getStringHeight(100, $val);
974 $cury += $tmpy;
975 } elseif (!$usedetailedbban) {
976 $cury += 1;
977 }
978
979 // Use correct name of bank id according to country
980 $ibankey = FormBank::getIBANLabel($account);
981
982 if (!empty($account->iban)) {
983 //Remove whitespaces to ensure we are dealing with the format we expect
984 $ibanDisplay_temp = str_replace(' ', '', $outputlangs->convToOutputCharset($account->iban));
985 $ibanDisplay = "";
986
987 $nbIbanDisplay_temp = dol_strlen($ibanDisplay_temp);
988 for ($i = 0; $i < $nbIbanDisplay_temp; $i++) {
989 $ibanDisplay .= $ibanDisplay_temp[$i];
990 if ($i % 4 == 3 && $i > 0) {
991 $ibanDisplay .= " ";
992 }
993 }
994
995 $pdf->SetFont('', 'B', $default_font_size - 3);
996 $pdf->SetXY($curx, $cury);
997 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($ibankey).': '.$ibanDisplay, 0, 'L', 0);
998 $cury += 3;
999 }
1000
1001 if (!empty($account->bic)) {
1002 $pdf->SetFont('', 'B', $default_font_size - 3);
1003 $pdf->SetXY($curx, $cury);
1004 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($bickey).': '.$outputlangs->convToOutputCharset($account->bic), 0, 'L', 0);
1005 }
1006
1007 return $pdf->getY();
1008}
1009
1027function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails = 0, $hidefreetext = 0, $page_largeur = 0, $watermark = '')
1028{
1029 global $conf, $hookmanager;
1030
1031 $outputlangs->load("dict");
1032 $line = '';
1033 $reg = array();
1034 $marginwithfooter = 0; // Return value
1035
1036 $dims = $pdf->getPageDimensions();
1037
1038 // Line of free text
1039 if (empty($hidefreetext) && !empty($conf->global->$paramfreetext)) {
1040 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
1041 // More substitution keys
1042 $substitutionarray['__FROM_NAME__'] = $fromcompany->name;
1043 $substitutionarray['__FROM_EMAIL__'] = $fromcompany->email;
1044 complete_substitutions_array($substitutionarray, $outputlangs, $object);
1045 $newfreetext = make_substitutions(getDolGlobalString($paramfreetext), $substitutionarray, $outputlangs);
1046
1047 // Make a change into HTML code to allow to include images from medias directory.
1048 // <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1049 // become
1050 // <img alt="" src="'.DOL_DATA_ROOT.'/medias/image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1051 $newfreetext = preg_replace('/(<img.*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)("[^\/]*\/>)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $newfreetext);
1052
1053 $line .= $outputlangs->convToOutputCharset($newfreetext);
1054 }
1055
1056 // First line of company infos
1057 $line1 = "";
1058 $line2 = "";
1059 $line3 = "";
1060 $line4 = "";
1061
1062 if ($showdetails == 1 || $showdetails == 3) {
1063 // Company name
1064 if ($fromcompany->name) {
1065 $line1 .= ($line1 ? " - " : "").$outputlangs->transnoentities("RegisteredOffice").": ".$fromcompany->name;
1066 }
1067 // Address
1068 if ($fromcompany->address) {
1069 $line1 .= ($line1 ? " - " : "").str_replace("\n", ", ", $fromcompany->address);
1070 }
1071 // Zip code
1072 if ($fromcompany->zip) {
1073 $line1 .= ($line1 ? " - " : "").$fromcompany->zip;
1074 }
1075 // Town
1076 if ($fromcompany->town) {
1077 $line1 .= ($line1 ? " " : "").$fromcompany->town;
1078 }
1079 // Country
1080 if ($fromcompany->country) {
1081 $line1 .= ($line1 ? ", " : "").$fromcompany->country;
1082 }
1083 // Phone
1084 if ($fromcompany->phone) {
1085 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Phone").": ".$fromcompany->phone;
1086 }
1087 // Fax
1088 if ($fromcompany->fax) {
1089 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Fax").": ".$fromcompany->fax;
1090 }
1091
1092 // URL
1093 if ($fromcompany->url) {
1094 $line2 .= ($line2 ? " - " : "").$fromcompany->url;
1095 }
1096 // Email
1097 if ($fromcompany->email) {
1098 $line2 .= ($line2 ? " - " : "").$fromcompany->email;
1099 }
1100 }
1101 if ($showdetails == 2 || $showdetails == 3 || (!empty($fromcompany->country_code) && $fromcompany->country_code == 'DE')) {
1102 // Managers
1103 if ($fromcompany->managers) {
1104 $line2 .= ($line2 ? " - " : "").$fromcompany->managers;
1105 }
1106 }
1107
1108 // Line 3 of company infos
1109 // Juridical status
1110 if (!empty($fromcompany->forme_juridique_code) && $fromcompany->forme_juridique_code) {
1111 $line3 .= ($line3 ? " - " : "").$outputlangs->convToOutputCharset(getFormeJuridiqueLabel($fromcompany->forme_juridique_code));
1112 }
1113 // Capital
1114 if (!empty($fromcompany->capital)) {
1115 $tmpamounttoshow = price2num($fromcompany->capital); // This field is a free string or a float
1116 if (is_numeric($tmpamounttoshow) && $tmpamounttoshow > 0) {
1117 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", price($tmpamounttoshow, 0, $outputlangs, 0, 0, 0, $conf->currency));
1118 } elseif (!empty($fromcompany->capital)) {
1119 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", $fromcompany->capital, $outputlangs);
1120 }
1121 }
1122 // Prof Id 1
1123 if (!empty($fromcompany->idprof1) && $fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || !$fromcompany->idprof2)) {
1124 $field = $outputlangs->transcountrynoentities("ProfId1", $fromcompany->country_code);
1125 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1126 $field = $reg[1];
1127 }
1128 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof1);
1129 }
1130 // Prof Id 2
1131 if (!empty($fromcompany->idprof2) && $fromcompany->idprof2) {
1132 $field = $outputlangs->transcountrynoentities("ProfId2", $fromcompany->country_code);
1133 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1134 $field = $reg[1];
1135 }
1136 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof2);
1137 }
1138
1139 // Line 4 of company infos
1140 // Prof Id 3
1141 if (!empty($fromcompany->idprof3) && $fromcompany->idprof3) {
1142 $field = $outputlangs->transcountrynoentities("ProfId3", $fromcompany->country_code);
1143 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1144 $field = $reg[1];
1145 }
1146 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof3);
1147 }
1148 // Prof Id 4
1149 if (!empty($fromcompany->idprof4) && $fromcompany->idprof4) {
1150 $field = $outputlangs->transcountrynoentities("ProfId4", $fromcompany->country_code);
1151 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1152 $field = $reg[1];
1153 }
1154 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof4);
1155 }
1156 // Prof Id 5
1157 if (!empty($fromcompany->idprof5) && $fromcompany->idprof5) {
1158 $field = $outputlangs->transcountrynoentities("ProfId5", $fromcompany->country_code);
1159 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1160 $field = $reg[1];
1161 }
1162 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof5);
1163 }
1164 // Prof Id 6
1165 if (!empty($fromcompany->idprof6) && $fromcompany->idprof6) {
1166 $field = $outputlangs->transcountrynoentities("ProfId6", $fromcompany->country_code);
1167 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1168 $field = $reg[1];
1169 }
1170 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof6);
1171 }
1172 // Prof Id 7
1173 if (!empty($fromcompany->idprof7) && $fromcompany->idprof7) {
1174 $field = $outputlangs->transcountrynoentities("ProfId7", $fromcompany->country_code);
1175 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1176 $field = $reg[1];
1177 }
1178 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof7);
1179 }
1180 // Prof Id 8
1181 if (!empty($fromcompany->idprof8) && $fromcompany->idprof8) {
1182 $field = $outputlangs->transcountrynoentities("ProfId8", $fromcompany->country_code);
1183 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1184 $field = $reg[1];
1185 }
1186 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof8);
1187 }
1188 // Prof Id 9
1189 if (!empty($fromcompany->idprof9) && $fromcompany->idprof9) {
1190 $field = $outputlangs->transcountrynoentities("ProfId9", $fromcompany->country_code);
1191 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1192 $field = $reg[1];
1193 }
1194 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof9);
1195 }
1196 // Prof Id 10
1197 if (!empty($fromcompany->idprof10) && $fromcompany->idprof10) {
1198 $field = $outputlangs->transcountrynoentities("ProfId10", $fromcompany->country_code);
1199 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1200 $field = $reg[1];
1201 }
1202 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof10);
1203 }
1204 // IntraCommunautary VAT
1205 if (!empty($fromcompany->tva_intra) && $fromcompany->tva_intra != '') {
1206 $line4 .= ($line4 ? " - " : "").$outputlangs->transnoentities("VATIntraShort").": ".$outputlangs->convToOutputCharset($fromcompany->tva_intra);
1207 }
1208
1209 $pdf->SetFont('', '', 7);
1210 $pdf->SetDrawColor(224, 224, 224);
1211 // Option for footer text color
1212 if (getDolGlobalString('PDF_FOOTER_TEXT_COLOR')) {
1213 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_TEXT_COLOR, '%d, %d, %d');
1214 $pdf->SetTextColor($r, $g, $b);
1215 }
1216
1217 // The start of the bottom of this page footer is positioned according to # of lines
1218 $freetextheight = 0;
1219 if ($line) { // Free text
1220 //$line="sample text<br>\nfd<strong>sf</strong>sdf<br>\nghfghg<br>";
1221 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) {
1222 $width = 20000;
1223 $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.
1224 if (getDolGlobalString('MAIN_USE_AUTOWRAP_ON_FREETEXT')) {
1225 $width = 200;
1226 $align = 'C';
1227 }
1228 $freetextheight = $pdf->getStringHeight($width, $line);
1229 } else {
1230 $freetextheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); // New method (works for HTML content)
1231 //print '<br>'.$freetextheight;exit;
1232 }
1233 }
1234
1235 // For customize footer
1236 if (is_object($hookmanager)) {
1237 $parameters = array('line1' => $line1, 'line2' => $line2, 'line3' => $line3, 'line4' => $line4, 'outputlangs' => $outputlangs);
1238 $action = '';
1239 $hookmanager->executeHooks('pdf_pagefoot', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1240 if (!empty($hookmanager->resPrint) && $hidefreetext == 0) {
1241 $mycustomfooter = $hookmanager->resPrint;
1242 $mycustomfooterheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1243
1244 $marginwithfooter = $marge_basse + $freetextheight + $mycustomfooterheight;
1245 $posy = (float) $marginwithfooter;
1246
1247 // Option for footer background color (without freetext zone)
1248 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1249 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1250 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1251 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b));
1252 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1253 }
1254
1255 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1256 $pdf->SetAutoPageBreak(0, 0);
1257 } // Option for disable auto pagebreak
1258 if ($line) { // Free text
1259 $pdf->SetXY($dims['lm'], -$posy);
1260 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1261 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1262 } else {
1263 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1264 }
1265 $posy -= $freetextheight;
1266 }
1267 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1268 $pdf->SetAutoPageBreak(1, 0);
1269 } // Restore pagebreak
1270
1271 $pdf->SetY(-$posy);
1272
1273 // Hide footer line if footer background color is set
1274 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1275 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1276 }
1277
1278 // Option for set top margin height of footer after freetext
1279 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1280 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1281 } else {
1282 $posy--;
1283 }
1284
1285 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1286 $pdf->SetAutoPageBreak(0, 0);
1287 } // Option for disable auto pagebreak
1288 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1289 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1290 $pdf->SetAutoPageBreak(1, 0);
1291 } // Restore pagebreak
1292
1293 $posy -= $mycustomfooterheight - 3;
1294 } else {
1295 // Else default footer
1296 $marginwithfooter = $marge_basse + $freetextheight + (!empty($line1) ? 3 : 0) + (!empty($line2) ? 3 : 0) + (!empty($line3) ? 3 : 0) + (!empty($line4) ? 3 : 0);
1297 $posy = (float) $marginwithfooter;
1298
1299 // Option for footer background color (without freetext zone)
1300 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1301 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1302 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1303 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b));
1304 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1305 }
1306
1307 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1308 $pdf->SetAutoPageBreak(0, 0);
1309 } // Option for disable auto pagebreak
1310 if ($line) { // Free text
1311 $pdf->SetXY($dims['lm'], -$posy);
1312 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1313 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1314 } else {
1315 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1316 }
1317 $posy -= $freetextheight;
1318 }
1319 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1320 $pdf->SetAutoPageBreak(1, 0);
1321 } // Restore pagebreak
1322
1323 $pdf->SetY(-$posy);
1324
1325 // Option for hide all footer (page number will no hidden)
1326 if (!getDolGlobalInt('PDF_FOOTER_HIDDEN')) {
1327 // Hide footer line if footer background color is set
1328 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1329 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1330 }
1331
1332 // Option for set top margin height of footer after freetext
1333 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1334 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1335 } else {
1336 $posy--;
1337 }
1338
1339 if (!empty($line1)) {
1340 $pdf->SetFont('', 'B', 7);
1341 $pdf->SetXY($dims['lm'], -$posy);
1342 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line1, 0, 'C', 0);
1343 $posy -= 3;
1344 $pdf->SetFont('', '', 7);
1345 }
1346
1347 if (!empty($line2)) {
1348 $pdf->SetFont('', 'B', 7);
1349 $pdf->SetXY($dims['lm'], -$posy);
1350 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line2, 0, 'C', 0);
1351 $posy -= 3;
1352 $pdf->SetFont('', '', 7);
1353 }
1354
1355 if (!empty($line3)) {
1356 $pdf->SetXY($dims['lm'], -$posy);
1357 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line3, 0, 'C', 0);
1358 }
1359
1360 if (!empty($line4)) {
1361 $posy -= 3;
1362 $pdf->SetXY($dims['lm'], -$posy);
1363 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line4, 0, 'C', 0);
1364 }
1365 }
1366 }
1367 }
1368
1369 // Show page nb and apply correction for some font.
1370 $pdf->SetXY($dims['wk'] - $dims['rm'] - 18 - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_X', 0), -$posy - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_Y', 0));
1371
1372 $pagination = $pdf->PageNo().' / '.$pdf->getAliasNbPages();
1373 $fontRenderCorrection = 0;
1374 if (in_array(pdf_getPDFFont($outputlangs), array('freemono', 'DejaVuSans'))) {
1375 $fontRenderCorrection = 10;
1376 }
1377 $pdf->MultiCell(18 + $fontRenderCorrection, 2, $pagination, 0, 'R', 0);
1378
1379 // Show Draft Watermark
1380 if (!empty($watermark)) {
1381 pdf_watermark($pdf, $outputlangs, $page_hauteur, $page_largeur, 'mm', $watermark);
1382 }
1383
1384 return $marginwithfooter;
1385}
1386
1401function pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
1402{
1403 $linkedobjects = pdf_getLinkedObjects($object, $outputlangs);
1404 if (!empty($linkedobjects)) {
1405 foreach ($linkedobjects as $linkedobject) {
1406 $reftoshow = $linkedobject["ref_title"].' : '.$linkedobject["ref_value"];
1407 if (!empty($linkedobject["date_value"])) {
1408 $reftoshow .= ' / '.$linkedobject["date_value"];
1409 }
1410
1411 $posy += 3;
1412 $pdf->SetXY($posx, $posy);
1413 $pdf->SetFont('', '', $default_font_size - 2);
1414 $pdf->MultiCell($w, $h, $reftoshow, '', $align);
1415 }
1416 }
1417
1418 return $pdf->getY();
1419}
1420
1438function pdf_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref = 0, $hidedesc = 0, $issupplierline = 0, $align = 'J')
1439{
1440 global $db, $conf, $langs, $hookmanager;
1441
1442 $reshook = 0;
1443 $result = '';
1444 //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) ) )
1445 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
1446 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1447 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1448 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1449 }
1450 $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);
1451 $action = '';
1452 $reshook = $hookmanager->executeHooks('pdf_writelinedesc', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1453
1454 if (!empty($hookmanager->resPrint)) {
1455 $result .= $hookmanager->resPrint;
1456 }
1457 }
1458 if (empty($reshook)) {
1459 $labelproductservice = pdf_getlinedesc($object, $i, $outputlangs, $hideref, $hidedesc, $issupplierline);
1460 $labelproductservice = preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $labelproductservice, -1, $nbrep);
1461
1462 //var_dump($labelproductservice);exit;
1463
1464 // 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"
1465 // We make the reverse, so PDF generation has the real URL.
1466 $nbrep = 0;
1467 $labelproductservice = preg_replace('/(<img[^>]*src=")([^"]*)(&amp;)([^"]*")/', '\1\2&\4', $labelproductservice, -1, $nbrep);
1468
1469 if (getDolGlobalString('MARGIN_TOP_ZERO_UL')) {
1470 $pdf->setListIndentWidth(5);
1471 $TMarginList = ['ul' => [['h'=>0.1, ],['h'=>0.1, ]], 'li' => [['h'=>0.1, ],],];
1472 $pdf->setHtmlVSpace($TMarginList);
1473 }
1474
1475 // Description
1476 $pdf->writeHTMLCell($w, $h, $posx, $posy, $outputlangs->convToOutputCharset($labelproductservice), 0, 1, false, true, $align, true);
1477 $result .= $labelproductservice;
1478 }
1479 return $result;
1480}
1481
1493function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1494{
1495 global $db, $conf, $langs;
1496
1497 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1498 $label = (!empty($object->lines[$i]->label) ? $object->lines[$i]->label : (!empty($object->lines[$i]->product_label) ? $object->lines[$i]->product_label : ''));
1499 $product_barcode = (!empty($object->lines[$i]->product_barcode) ? $object->lines[$i]->product_barcode : "");
1500 $desc = (!empty($object->lines[$i]->desc) ? $object->lines[$i]->desc : (!empty($object->lines[$i]->description) ? $object->lines[$i]->description : ''));
1501 $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
1502 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1503 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1504
1505 $multilangsactive = getDolGlobalInt('MAIN_MULTILANGS');
1506
1507 if ($issupplierline) {
1508 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
1509 $prodser = new ProductFournisseur($db);
1510 } else {
1511 include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1512 $prodser = new Product($db);
1513
1514 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
1515 include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
1516 }
1517 }
1518
1519 //id
1520 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1521 if ($idprod) {
1522 $prodser->fetch($idprod);
1523 //load multilangs
1524 if ($multilangsactive) {
1525 $prodser->getMultiLangs();
1526 $object->lines[$i]->multilangs = $prodser->multilangs;
1527 }
1528 }
1529 //label
1530 if (!empty($object->lines[$i]->label)) {
1531 $label = $object->lines[$i]->label;
1532 } else {
1533 if (!empty($object->lines[$i]->multilangs[$outputlangs->defaultlang]['label']) && $multilangsactive) {
1534 $label = $object->lines[$i]->multilangs[$outputlangs->defaultlang]['label'];
1535 } else {
1536 if (!empty($object->lines[$i]->product_label)) {
1537 $label = $object->lines[$i]->product_label;
1538 } else {
1539 $label = '';
1540 }
1541 }
1542 }
1543 //description
1544 if (!empty($object->lines[$i]->desc)) {
1545 $desc = $object->lines[$i]->desc;
1546 } else {
1547 if (!empty($object->lines[$i]->multilangs[$outputlangs->defaultlang]['description']) && $multilangsactive) {
1548 $desc = $object->lines[$i]->multilangs[$outputlangs->defaultlang]['description'];
1549 } else {
1550 if (!empty($object->lines[$i]->description)) {
1551 $desc = $object->lines[$i]->description;
1552 } else {
1553 $desc = '';
1554 }
1555 }
1556 }
1557 //ref supplier
1558 $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
1559 //note
1560 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1561 //dbatch
1562 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1563
1564 if ($idprod) {
1565 // If a predefined product and multilang and on other lang, we renamed label with label translated
1566 if ($multilangsactive && ($outputlangs->defaultlang != $langs->defaultlang)) {
1567 $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)
1568
1569 // 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
1570 // ($textwasnotmodified is replaced with $textwasmodifiedorcompleted and we add completion).
1571
1572 // Set label
1573 // 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.
1574 //var_dump($outputlangs->defaultlang.' - '.$langs->defaultlang.' - '.$label.' - '.$prodser->label);exit;
1575 $textwasnotmodified = ($label == $prodser->label);
1576 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["label"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1577 $label = $prodser->multilangs[$outputlangs->defaultlang]["label"];
1578 }
1579
1580 // Set desc
1581 // Manage HTML entities description test because $prodser->description is store with htmlentities but $desc no
1582 $textwasnotmodified = false;
1583 if (!empty($desc) && dol_textishtml($desc) && !empty($prodser->description) && dol_textishtml($prodser->description)) {
1584 $textwasnotmodified = (strpos(dol_html_entity_decode($desc, ENT_QUOTES | ENT_HTML5), dol_html_entity_decode($prodser->description, ENT_QUOTES | ENT_HTML5)) !== false);
1585 } else {
1586 $textwasnotmodified = ($desc == $prodser->description);
1587 }
1588 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["description"])) {
1589 if ($textwasnotmodified) {
1590 $desc = str_replace($prodser->description, $prodser->multilangs[$outputlangs->defaultlang]["description"], $desc);
1591 } elseif ($translatealsoifmodified) {
1592 $desc = $prodser->multilangs[$outputlangs->defaultlang]["description"];
1593 }
1594 }
1595
1596 // Set note
1597 $textwasnotmodified = ($note == $prodser->note_public);
1598 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["other"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1599 $note = $prodser->multilangs[$outputlangs->defaultlang]["other"];
1600 }
1601 }
1602 } 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
1603 $desc = str_replace('(DEPOSIT)', $outputlangs->trans('Deposit'), $desc);
1604 }
1605
1606 if (!getDolGlobalString('PDF_HIDE_PRODUCT_LABEL_IN_SUPPLIER_LINES')) {
1607 // Description short of product line
1608 $libelleproduitservice = $label;
1609 if (!empty($libelleproduitservice) && getDolGlobalString('PDF_BOLD_PRODUCT_LABEL')) {
1610 // Adding <b> may convert the original string into a HTML string. So we have to first
1611 // convert \n into <br> we text is not already HTML.
1612 if (!dol_textishtml($libelleproduitservice)) {
1613 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1614 }
1615 $libelleproduitservice = '<b>'.$libelleproduitservice.'</b>';
1616 }
1617 }
1618
1619
1620 // Add ref of subproducts
1621 if (getDolGlobalString('SHOW_SUBPRODUCT_REF_IN_PDF')) {
1622 $prodser->get_sousproduits_arbo();
1623 if (!empty($prodser->sousprods) && is_array($prodser->sousprods) && count($prodser->sousprods)) {
1624 $outputlangs->load('mrp');
1625 $tmparrayofsubproducts = reset($prodser->sousprods);
1626
1627 $qtyText = null;
1628 if (isset($object->lines[$i]->qty) && !empty($object->lines[$i]->qty)) {
1629 $qtyText = $object->lines[$i]->qty;
1630 } elseif (isset($object->lines[$i]->qty_shipped) && !empty($object->lines[$i]->qty_shipped)) {
1631 $qtyText = $object->lines[$i]->qty;
1632 }
1633
1634 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF')) {
1635 foreach ($tmparrayofsubproducts as $subprodval) {
1636 $libelleproduitservice = dol_concatdesc(
1637 dol_concatdesc($libelleproduitservice, " * ".$subprodval[3]),
1638 (!empty($qtyText) ?
1639 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1] * $qtyText :
1640 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1641 );
1642 }
1643 } else {
1644 foreach ($tmparrayofsubproducts as $subprodval) {
1645 $libelleproduitservice = dol_concatdesc(
1646 dol_concatdesc($libelleproduitservice, " * ".$subprodval[5].(($subprodval[5] && $subprodval[3]) ? ' - ' : '').$subprodval[3]),
1647 (!empty($qtyText) ?
1648 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1] * $qtyText :
1649 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1650 );
1651 }
1652 }
1653 }
1654 }
1655
1656 if (isModEnabled('barcode') && getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_PRODUCT_BARCODE') && !empty($product_barcode)) {
1657 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $outputlangs->trans("BarCode")." ".$product_barcode);
1658 }
1659
1660 // Description long of product line
1661 if (!empty($desc) && ($desc != $label)) {
1662 if ($desc == '(CREDIT_NOTE)' && $object->lines[$i]->fk_remise_except) {
1663 $discount = new DiscountAbsolute($db);
1664 $discount->fetch($object->lines[$i]->fk_remise_except);
1665 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1666 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromCreditNote", $sourceref);
1667 } elseif ($desc == '(DEPOSIT)' && $object->lines[$i]->fk_remise_except) {
1668 $discount = new DiscountAbsolute($db);
1669 $discount->fetch($object->lines[$i]->fk_remise_except);
1670 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1671 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromDeposit", $sourceref);
1672 // Add date of deposit
1673 if (getDolGlobalString('INVOICE_ADD_DEPOSIT_DATE')) {
1674 $libelleproduitservice .= ' ('.dol_print_date($discount->datec, 'day', '', $outputlangs).')';
1675 }
1676 } elseif ($desc == '(EXCESS RECEIVED)' && $object->lines[$i]->fk_remise_except) {
1677 $discount = new DiscountAbsolute($db);
1678 $discount->fetch($object->lines[$i]->fk_remise_except);
1679 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived", $discount->ref_facture_source);
1680 } elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except) {
1681 $discount = new DiscountAbsolute($db);
1682 $discount->fetch($object->lines[$i]->fk_remise_except);
1683 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid", $discount->ref_invoice_supplier_source);
1684 } else {
1685 if ($idprod) {
1686 // Check if description must be output
1687 if (!empty($object->element)) {
1688 $tmpkey = 'MAIN_DOCUMENTS_HIDE_DESCRIPTION_FOR_'.strtoupper($object->element);
1689 if (!empty($conf->global->$tmpkey)) {
1690 $hidedesc = 1;
1691 }
1692 }
1693 if (empty($hidedesc)) {
1694 if (getDolGlobalString('MAIN_DOCUMENTS_DESCRIPTION_FIRST')) {
1695 $libelleproduitservice = dol_concatdesc($desc, $libelleproduitservice);
1696 } else {
1697 if (getDolGlobalString('HIDE_LABEL_VARIANT_PDF') && $prodser->isVariant()) {
1698 $libelleproduitservice = $desc;
1699 } else {
1700 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1701 }
1702 }
1703 }
1704 } else {
1705 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1706 }
1707 }
1708 }
1709
1710 // We add ref of product (and supplier ref if defined)
1711 $prefix_prodserv = "";
1712 $ref_prodserv = "";
1713 if (getDolGlobalString('PRODUCT_ADD_TYPE_IN_DOCUMENTS')) { // In standard mode, we do not show this
1714 if ($prodser->isService()) {
1715 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." ";
1716 } else {
1717 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." ";
1718 }
1719 }
1720
1721 if (empty($hideref)) {
1722 if ($issupplierline) {
1723 if (!getDolGlobalString('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES')) { // Common case
1724 $ref_prodserv = $prodser->ref; // Show local ref
1725 if ($ref_supplier) {
1726 $ref_prodserv .= ($prodser->ref ? ' (' : '').$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.($prodser->ref ? ')' : '');
1727 }
1728 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 1) {
1729 $ref_prodserv = $ref_supplier;
1730 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 2) {
1731 $ref_prodserv = $ref_supplier.' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')';
1732 }
1733 } else {
1734 $ref_prodserv = $prodser->ref; // Show local ref only
1735
1736 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
1737 $productCustomerPriceStatic = new ProductCustomerPrice($db);
1738 $filter = array('fk_product' => $idprod, 'fk_soc' => $object->socid);
1739
1740 $nbCustomerPrices = $productCustomerPriceStatic->fetchAll('', '', 1, 0, $filter);
1741
1742 if ($nbCustomerPrices > 0) {
1743 $productCustomerPrice = $productCustomerPriceStatic->lines[0];
1744
1745 if (!empty($productCustomerPrice->ref_customer)) {
1746 switch ($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
1747 case 1:
1748 $ref_prodserv = $productCustomerPrice->ref_customer;
1749 break;
1750
1751 case 2:
1752 $ref_prodserv = $productCustomerPrice->ref_customer . ' (' . $outputlangs->transnoentitiesnoconv('InternalRef') . ' ' . $ref_prodserv . ')';
1753 break;
1754
1755 default:
1756 $ref_prodserv = $ref_prodserv . ' (' . $outputlangs->transnoentitiesnoconv('RefCustomer') . ' ' . $productCustomerPrice->ref_customer . ')';
1757 }
1758 }
1759 }
1760 }
1761 }
1762
1763 if (!empty($libelleproduitservice) && !empty($ref_prodserv)) {
1764 $ref_prodserv .= " - ";
1765 }
1766 }
1767
1768 if (!empty($ref_prodserv) && getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1769 if (!dol_textishtml($libelleproduitservice)) {
1770 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1771 }
1772 $ref_prodserv = '<b>'.$ref_prodserv.'</b>';
1773 // $prefix_prodserv and $ref_prodser are not HTML var
1774 }
1775 $libelleproduitservice = $prefix_prodserv.$ref_prodserv.$libelleproduitservice;
1776
1777 // Add an additional description for the category products
1778 if (getDolGlobalString('CATEGORY_ADD_DESC_INTO_DOC') && $idprod && isModEnabled('category')) {
1779 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1780 $categstatic = new Categorie($db);
1781 // recovering the list of all the categories linked to product
1782 $tblcateg = $categstatic->containing($idprod, Categorie::TYPE_PRODUCT);
1783 foreach ($tblcateg as $cate) {
1784 // Adding the descriptions if they are filled
1785 $desccateg = $cate->description;
1786 if ($desccateg) {
1787 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desccateg);
1788 }
1789 }
1790 }
1791
1792 if (!empty($object->lines[$i]->date_start) || !empty($object->lines[$i]->date_end)) {
1793 $format = 'day';
1794 $period = '';
1795 // Show duration if exists
1796 if ($object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1797 $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)).')';
1798 }
1799 if ($object->lines[$i]->date_start && !$object->lines[$i]->date_end) {
1800 $period = '('.$outputlangs->transnoentitiesnoconv('DateFrom', dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs)).')';
1801 }
1802 if (!$object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1803 $period = '('.$outputlangs->transnoentitiesnoconv('DateUntil', dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
1804 }
1805 //print '>'.$outputlangs->charset_output.','.$period;
1806 if (getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1807 if (!dol_textishtml($libelleproduitservice)) {
1808 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1809 }
1810 $libelleproduitservice .= '<br><b style="color:#333666;" ><em>'.$period.'</em></b>';
1811 } else {
1812 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $period);
1813 }
1814 //print $libelleproduitservice;
1815 }
1816
1817 // Show information for lot
1818 if (!empty($dbatch)) {
1819 // $object is a shipment.
1820 //var_dump($object->lines[$i]->details_entrepot); // array from llx_expeditiondet (we can have several lines for one fk_origin_line)
1821 //var_dump($object->lines[$i]->detail_batch); // array from llx_expeditiondet_batch (each line with a lot is linked to llx_expeditiondet)
1822
1823 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1824 include_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
1825 $tmpwarehouse = new Entrepot($db);
1826 $tmpproductbatch = new Productbatch($db);
1827
1828 $format = 'day';
1829 foreach ($dbatch as $detail) {
1830 $dte = array();
1831 if ($detail->eatby) {
1832 $dte[] = $outputlangs->transnoentitiesnoconv('printEatby', dol_print_date($detail->eatby, $format, false, $outputlangs));
1833 }
1834 if ($detail->sellby) {
1835 $dte[] = $outputlangs->transnoentitiesnoconv('printSellby', dol_print_date($detail->sellby, $format, false, $outputlangs));
1836 }
1837 if ($detail->batch) {
1838 $dte[] = $outputlangs->transnoentitiesnoconv('printBatch', $detail->batch);
1839 }
1840 $dte[] = $outputlangs->transnoentitiesnoconv('printQty', $detail->qty);
1841
1842 // Add also info of planned warehouse for lot
1843 if ($object->element == 'shipping' && $detail->fk_origin_stock > 0 && getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1844 $resproductbatch = $tmpproductbatch->fetch($detail->fk_origin_stock);
1845 if ($resproductbatch > 0) {
1846 $reswarehouse = $tmpwarehouse->fetch($tmpproductbatch->warehouseid);
1847 if ($reswarehouse > 0) {
1848 $dte[] = $tmpwarehouse->ref;
1849 }
1850 }
1851 }
1852
1853 $libelleproduitservice .= "__N__ ".implode(" - ", $dte);
1854 }
1855 } else {
1856 if (getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1857 // TODO Show warehouse for shipment line without batch
1858 }
1859 }
1860
1861 // Now we convert \n into br
1862 if (dol_textishtml($libelleproduitservice)) {
1863 $libelleproduitservice = preg_replace('/__N__/', '<br>', $libelleproduitservice);
1864 } else {
1865 $libelleproduitservice = preg_replace('/__N__/', "\n", $libelleproduitservice);
1866 }
1867 $libelleproduitservice = dol_htmlentitiesbr($libelleproduitservice, 1);
1868
1869 return $libelleproduitservice;
1870}
1871
1881function pdf_getlinenum($object, $i, $outputlangs, $hidedetails = 0)
1882{
1883 global $hookmanager;
1884
1885 $reshook = 0;
1886 $result = '';
1887 //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) ) )
1888 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
1889 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1890 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1891 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1892 }
1893 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1894 $action = '';
1895 $reshook = $hookmanager->executeHooks('pdf_getlinenum', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1896 $result .= $hookmanager->resPrint;
1897 }
1898 if (empty($reshook)) {
1899 $result .= dol_htmlentitiesbr($object->lines[$i]->num);
1900 }
1901 return $result;
1902}
1903
1904
1914function pdf_getlineref($object, $i, $outputlangs, $hidedetails = 0)
1915{
1916 global $hookmanager;
1917
1918 $reshook = 0;
1919 $result = '';
1920 //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) ) )
1921 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
1922 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1923 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1924 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1925 }
1926 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1927 $action = '';
1928 $reshook = $hookmanager->executeHooks('pdf_getlineref', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1929 $result .= $hookmanager->resPrint;
1930 }
1931 if (empty($reshook)) {
1932 $result .= dol_htmlentitiesbr($object->lines[$i]->product_ref);
1933 }
1934 return $result;
1935}
1936
1946function pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails = 0)
1947{
1948 global $hookmanager;
1949
1950 $reshook = 0;
1951 $result = '';
1952 //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) ) )
1953 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
1954 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1955 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1956 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1957 }
1958 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1959 $action = '';
1960 $reshook = $hookmanager->executeHooks('pdf_getlineref_supplier', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1961 $result .= $hookmanager->resPrint;
1962 }
1963 if (empty($reshook)) {
1964 $result .= dol_htmlentitiesbr($object->lines[$i]->ref_supplier);
1965 }
1966 return $result;
1967}
1968
1978function pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails = 0)
1979{
1980 global $conf, $hookmanager, $mysoc;
1981
1982 $result = '';
1983 $reshook = 0;
1984 //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) ) )
1985 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
1986 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1987 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1988 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1989 }
1990 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1991 $action = '';
1992 $reshook = $hookmanager->executeHooks('pdf_getlinevatrate', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1993
1994 if (!empty($hookmanager->resPrint)) {
1995 $result .= $hookmanager->resPrint;
1996 }
1997 }
1998 if (empty($reshook)) {
1999 if (empty($hidedetails) || $hidedetails > 1) {
2000 $tmpresult = '';
2001
2002 $tmpresult .= vatrate($object->lines[$i]->tva_tx, 0, $object->lines[$i]->info_bits, -1);
2003 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_SECOND_TAX')) {
2004 if ($object->lines[$i]->total_localtax1 != 0) {
2005 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
2006 $tmpresult .= '/';
2007 } else {
2008 $tmpresult = '';
2009 }
2010 $tmpresult .= vatrate(abs($object->lines[$i]->localtax1_tx), 0);
2011 }
2012 }
2013 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_THIRD_TAX')) {
2014 if ($object->lines[$i]->total_localtax2 != 0) {
2015 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
2016 $tmpresult .= '/';
2017 } else {
2018 $tmpresult = '';
2019 }
2020 $tmpresult .= vatrate(abs($object->lines[$i]->localtax2_tx), 0);
2021 }
2022 }
2023 $tmpresult .= '%';
2024
2025 $result .= $tmpresult;
2026 }
2027 }
2028 return $result;
2029}
2030
2040function pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails = 0)
2041{
2042 global $conf, $hookmanager;
2043
2044 $sign = 1;
2045 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2046 $sign = -1;
2047 }
2048
2049 $result = '';
2050 $reshook = 0;
2051 //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) ) )
2052 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
2053 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2054 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2055 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2056 }
2057 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2058 $action = '';
2059 $reshook = $hookmanager->executeHooks('pdf_getlineupexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2060
2061 if (!empty($hookmanager->resPrint)) {
2062 $result .= $hookmanager->resPrint;
2063 }
2064 }
2065 if (empty($reshook)) {
2066 if (empty($hidedetails) || $hidedetails > 1) {
2067 $subprice = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_subprice : $object->lines[$i]->subprice);
2068 $result .= price($sign * $subprice, 0, $outputlangs);
2069 }
2070 }
2071 return $result;
2072}
2073
2083function pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails = 0)
2084{
2085 global $hookmanager, $conf;
2086
2087 $sign = 1;
2088 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2089 $sign = -1;
2090 }
2091
2092 $result = '';
2093 $reshook = 0;
2094 //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) ) )
2095 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
2096 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2097 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2098 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2099 }
2100 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2101 $action = '';
2102 $reshook = $hookmanager->executeHooks('pdf_getlineupwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2103
2104 if (!empty($hookmanager->resPrint)) {
2105 $result .= $hookmanager->resPrint;
2106 }
2107 }
2108 if (empty($reshook)) {
2109 if (empty($hidedetails) || $hidedetails > 1) {
2110 $result .= price($sign * (($object->lines[$i]->subprice) + ($object->lines[$i]->subprice) * ($object->lines[$i]->tva_tx) / 100), 0, $outputlangs);
2111 }
2112 }
2113 return $result;
2114}
2115
2125function pdf_getlineqty($object, $i, $outputlangs, $hidedetails = 0)
2126{
2127 global $hookmanager;
2128
2129 $result = '';
2130 $reshook = 0;
2131 //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) ) )
2132 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
2133 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2134 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2135 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2136 }
2137 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2138 $action = '';
2139 $reshook = $hookmanager->executeHooks('pdf_getlineqty', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2140
2141 if (!empty($hookmanager->resPrint)) {
2142 $result = $hookmanager->resPrint;
2143 }
2144 }
2145 if (empty($reshook)) {
2146 if ($object->lines[$i]->special_code == 3) {
2147 return '';
2148 }
2149 if (empty($hidedetails) || $hidedetails > 1) {
2150 $result .= $object->lines[$i]->qty;
2151 }
2152 }
2153 return $result;
2154}
2155
2165function pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails = 0)
2166{
2167 global $hookmanager;
2168
2169 $reshook = 0;
2170 $result = '';
2171 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2172 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2173 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2174 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2175 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2176 }
2177 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2178 $action = '';
2179 $reshook = $hookmanager->executeHooks('pdf_getlineqty_asked', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2180
2181 if (!empty($hookmanager->resPrint)) {
2182 $result .= $hookmanager->resPrint;
2183 }
2184 }
2185 if (empty($reshook)) {
2186 if ($object->lines[$i]->special_code == 3) {
2187 return '';
2188 }
2189 if (empty($hidedetails) || $hidedetails > 1) {
2190 $result .= $object->lines[$i]->qty_asked;
2191 }
2192 }
2193 return $result;
2194}
2195
2205function pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails = 0)
2206{
2207 global $hookmanager;
2208
2209 $reshook = 0;
2210 $result = '';
2211 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2212 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2213 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2214 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2215 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2216 }
2217 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2218 $action = '';
2219 $reshook = $hookmanager->executeHooks('pdf_getlineqty_shipped', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2220
2221 if (!empty($hookmanager->resPrint)) {
2222 $result .= $hookmanager->resPrint;
2223 }
2224 }
2225 if (empty($reshook)) {
2226 if ($object->lines[$i]->special_code == 3) {
2227 return '';
2228 }
2229 if (empty($hidedetails) || $hidedetails > 1) {
2230 $result .= $object->lines[$i]->qty_shipped;
2231 }
2232 }
2233 return $result;
2234}
2235
2245function pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails = 0)
2246{
2247 global $hookmanager;
2248
2249 $reshook = 0;
2250 $result = '';
2251 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2252 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2253 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2254 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2255 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2256 }
2257 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2258 $action = '';
2259 $reshook = $hookmanager->executeHooks('pdf_getlineqty_keeptoship', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2260
2261 if (!empty($hookmanager->resPrint)) {
2262 $result .= $hookmanager->resPrint;
2263 }
2264 }
2265 if (empty($reshook)) {
2266 if ($object->lines[$i]->special_code == 3) {
2267 return '';
2268 }
2269 if (empty($hidedetails) || $hidedetails > 1) {
2270 $result .= ($object->lines[$i]->qty_asked - $object->lines[$i]->qty_shipped);
2271 }
2272 }
2273 return $result;
2274}
2275
2285function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0)
2286{
2287 global $hookmanager, $langs;
2288
2289 $reshook = 0;
2290 $result = '';
2291 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2292 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2293 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2294 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2295 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2296 }
2297 $parameters = array(
2298 'i' => $i,
2299 'outputlangs' => $outputlangs,
2300 'hidedetails' => $hidedetails,
2301 'special_code' => $special_code
2302 );
2303 $action = '';
2304 $reshook = $hookmanager->executeHooks('pdf_getlineunit', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2305
2306 if (!empty($hookmanager->resPrint)) {
2307 $result .= $hookmanager->resPrint;
2308 }
2309 }
2310 if (empty($reshook)) {
2311 if (empty($hidedetails) || $hidedetails > 1) {
2312 $result .= $langs->transnoentitiesnoconv($object->lines[$i]->getLabelOfUnit('short'));
2313 }
2314 }
2315 return $result;
2316}
2317
2318
2328function pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails = 0)
2329{
2330 global $hookmanager;
2331
2332 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2333
2334 $reshook = 0;
2335 $result = '';
2336 //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) ) )
2337 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
2338 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2339 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2340 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2341 }
2342 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2343 $action = '';
2344 $reshook = $hookmanager->executeHooks('pdf_getlineremisepercent', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2345
2346 if (!empty($hookmanager->resPrint)) {
2347 $result .= $hookmanager->resPrint;
2348 }
2349 }
2350 if (empty($reshook)) {
2351 if ($object->lines[$i]->special_code == 3) {
2352 return '';
2353 }
2354 if (empty($hidedetails) || $hidedetails > 1) {
2355 $result .= dol_print_reduction($object->lines[$i]->remise_percent, $outputlangs);
2356 }
2357 }
2358 return $result;
2359}
2360
2371function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = null)
2372{
2373 if (empty($hookmanager)) {
2374 global $hookmanager;
2375 }
2376 global $conf;
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);
2387 $action = '';
2388 $reshook = $hookmanager->executeHooks('pdf_getlineprogress', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2389
2390 if (!empty($hookmanager->resPrint)) {
2391 return $hookmanager->resPrint;
2392 }
2393 }
2394 if (empty($reshook)) {
2395 if ($object->lines[$i]->special_code == 3) {
2396 return '';
2397 }
2398 if (empty($hidedetails) || $hidedetails > 1) {
2399 if (getDolGlobalString('SITUATION_DISPLAY_DIFF_ON_PDF')) {
2400 $prev_progress = 0;
2401 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2402 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2403 }
2404 $result = round($object->lines[$i]->situation_percent - $prev_progress, 1).'%';
2405 } else {
2406 $result = round($object->lines[$i]->situation_percent, 1).'%';
2407 }
2408 }
2409 }
2410 return $result;
2411}
2412
2422function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0)
2423{
2424 global $conf, $hookmanager;
2425
2426 $sign = 1;
2427 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2428 $sign = -1;
2429 }
2430
2431 $reshook = 0;
2432 $result = '';
2433 //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) ) )
2434 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
2435 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2436 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2437 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2438 }
2439 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code, 'sign' => $sign);
2440 $action = '';
2441 $reshook = $hookmanager->executeHooks('pdf_getlinetotalexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2442
2443 if (!empty($hookmanager->resPrint)) {
2444 $result .= $hookmanager->resPrint;
2445 }
2446 }
2447 if (empty($reshook)) {
2448 if (!empty($object->lines[$i]) && $object->lines[$i]->special_code == 3) {
2449 $result .= $outputlangs->transnoentities("Option");
2450 } elseif (empty($hidedetails) || $hidedetails > 1) {
2451 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht);
2452 if (!empty($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2453 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2454 $prev_progress = 0;
2455 $progress = 1;
2456 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2457 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2458 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2459 }
2460 $result .= price($sign * ($total_ht / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2461 } else {
2462 $result .= price($sign * $total_ht, 0, $outputlangs);
2463 }
2464 }
2465 }
2466 return $result;
2467}
2468
2478function pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails = 0)
2479{
2480 global $hookmanager, $conf;
2481
2482 $sign = 1;
2483 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2484 $sign = -1;
2485 }
2486
2487 $reshook = 0;
2488 $result = '';
2489 //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) ) )
2490 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
2491 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2492 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2493 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2494 }
2495 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2496 $action = '';
2497 $reshook = $hookmanager->executeHooks('pdf_getlinetotalwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2498
2499 if (!empty($hookmanager->resPrint)) {
2500 $result .= $hookmanager->resPrint;
2501 }
2502 }
2503 if (empty($reshook)) {
2504 if ($object->lines[$i]->special_code == 3) {
2505 $result .= $outputlangs->transnoentities("Option");
2506 } elseif (empty($hidedetails) || $hidedetails > 1) {
2507 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ttc : $object->lines[$i]->total_ttc);
2508 if (isset($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2509 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2510 $prev_progress = 0;
2511 $progress = 1;
2512 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2513 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2514 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2515 }
2516 $result .= price($sign * ($total_ttc / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2517 } else {
2518 $result .= price($sign * $total_ttc, 0, $outputlangs);
2519 }
2520 }
2521 }
2522 return $result;
2523}
2524
2533function pdf_getLinkedObjects(&$object, $outputlangs)
2534{
2535 global $db, $hookmanager;
2536
2537 $linkedobjects = array();
2538
2539 $object->fetchObjectLinked();
2540
2541 foreach ($object->linkedObjects as $objecttype => $objects) {
2542 if ($objecttype == 'facture') {
2543 // 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.
2544 } elseif ($objecttype == 'propal' || $objecttype == 'supplier_proposal') {
2545 $outputlangs->load('propal');
2546
2547 foreach ($objects as $elementobject) {
2548 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefProposal");
2549 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2550 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DatePropal");
2551 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2552 }
2553 } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order') {
2554 $outputlangs->load('orders');
2555
2556 if (count($objects) > 1 && count($objects) <= (getDolGlobalInt("MAXREFONDOC") ? getDolGlobalInt("MAXREFONDOC") : 10)) {
2557 if (empty($object->context['DolPublicNoteAppendedGetLinkedObjects'])) { // Check if already appended before add to avoid repeat data
2558 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' :');
2559 foreach ($objects as $elementobject) {
2560 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref).(empty($elementobject->ref_client) ? '' : ' ('.$elementobject->ref_client.')').(empty($elementobject->ref_supplier) ? '' : ' ('.$elementobject->ref_supplier.')').' ');
2561 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("OrderDate").' : '.dol_print_date($elementobject->date, 'day', '', $outputlangs));
2562 }
2563 }
2564 } elseif (count($objects) == 1) {
2565 $elementobject = array_shift($objects);
2566 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder");
2567 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref).(!empty($elementobject->ref_client) ? ' ('.$elementobject->ref_client.')' : '').(!empty($elementobject->ref_supplier) ? ' ('.$elementobject->ref_supplier.')' : '');
2568 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate");
2569 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2570 }
2571 } elseif ($objecttype == 'contrat') {
2572 $outputlangs->load('contracts');
2573 foreach ($objects as $elementobject) {
2574 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefContract");
2575 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2576 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateContract");
2577 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat, 'day', '', $outputlangs);
2578 }
2579 } elseif ($objecttype == 'fichinter') {
2580 $outputlangs->load('interventions');
2581 foreach ($objects as $elementobject) {
2582 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("InterRef");
2583 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2584 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("InterDate");
2585 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->datec, 'day', '', $outputlangs);
2586 }
2587 } elseif ($objecttype == 'shipping') {
2588 $outputlangs->loadLangs(array("orders", "sendings"));
2589
2590 if (count($objects) > 1) {
2591 $order = null;
2592
2593 $refListsTxt = '';
2594 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') {
2595 $refListsTxt.= $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :';
2596 } else {
2597 $refListsTxt.=$outputlangs->transnoentities("RefSending").' :';
2598 }
2599 // We concat this record info into fields xxx_value. title is overwrote.
2600 foreach ($objects as $elementobject) {
2601 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
2602 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2603 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2604 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2605 $order = new Commande($db);
2606 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2607 if ($ret < 1) {
2608 $order = null;
2609 }
2610 }
2611 }
2612 $refListsTxt.= (!empty($refListsTxt)?' ':'');
2613 if (! is_object($order)) {
2614 $refListsTxt.= $outputlangs->transnoentities($elementobject->ref);
2615 } else {
2616 $refListsTxt.= $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
2617 $refListsTxt.= ' / '.$outputlangs->transnoentities($elementobject->ref);
2618 }
2619 }
2620
2621 if (empty($object->context['DolPublicNoteAppendedGetLinkedObjects'])) { // Check if already appended before add to avoid repeat data
2622 $object->note_public = dol_concatdesc($object->note_public, $refListsTxt);
2623 }
2624 } elseif (count($objects) == 1) {
2625 $elementobject = array_shift($objects);
2626 $order = null;
2627 // We concat this record info into fields xxx_value. title is overwrote.
2628 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
2629 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2630 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2631 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2632 $order = new Commande($db);
2633 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2634 if ($ret < 1) {
2635 $order = null;
2636 }
2637 }
2638 }
2639
2640 if (! is_object($order)) {
2641 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
2642 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2643 $linkedobjects[$objecttype]['ref_value'] = '';
2644 } else {
2645 $linkedobjects[$objecttype]['ref_value'] .= ' / ';
2646 }
2647 $linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref);
2648 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2649 } else {
2650 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending");
2651 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2652 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
2653 }
2654 $linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref);
2655 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2656 }
2657 }
2658 }
2659 }
2660
2661 $object->context['DolPublicNoteAppendedGetLinkedObjects'] = 1;
2662
2663 // For add external linked objects
2664 if (is_object($hookmanager)) {
2665 $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs' => $outputlangs);
2666 $action = '';
2667 $reshook = $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2668 if (empty($reshook)) {
2669 $linkedobjects = array_replace($linkedobjects, $hookmanager->resArray); // array_replace is used to preserve keys
2670 } elseif ($reshook>0) {
2671 // The array must be reinserted even if it is empty because clearing the array could be one of the actions performed by the hook.
2672 $linkedobjects = $hookmanager->resArray;
2673 }
2674 }
2675
2676 return $linkedobjects;
2677}
2678
2686function pdf_getSizeForImage($realpath)
2687{
2688 global $conf;
2689
2690 $maxwidth = getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH', 20);
2691 $maxheight = getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT', 32);
2692 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2693 $tmp = dol_getImageSize($realpath);
2694 $width = 0;
2695 $height = 0;
2696 if ($tmp['height']) {
2697 $width = (int) round($maxheight * $tmp['width'] / $tmp['height']); // I try to use maxheight
2698 if ($width > $maxwidth) { // Pb with maxheight, so i use maxwidth
2699 $width = $maxwidth;
2700 $height = (int) round($maxwidth * $tmp['height'] / $tmp['width']);
2701 } else { // No pb with maxheight
2702 $height = $maxheight;
2703 }
2704 }
2705 return array('width' => $width, 'height' => $height);
2706}
2707
2717function pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails = 0)
2718{
2719 global $conf, $hookmanager;
2720
2721 $sign = 1;
2722 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2723 $sign = -1;
2724 }
2725 if ($object->lines[$i]->special_code == 3) {
2726 return $outputlangs->transnoentities("Option");
2727 } else {
2728 if (is_object($hookmanager)) {
2729 $special_code = $object->lines[$i]->special_code;
2730 if (!empty($object->lines[$i]->fk_parent_line)) {
2731 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2732 }
2733
2734 $parameters = array(
2735 'i' => $i,
2736 'outputlangs' => $outputlangs,
2737 'hidedetails' => $hidedetails,
2738 'special_code' => $special_code
2739 );
2740
2741 $action = '';
2742
2743 if ($hookmanager->executeHooks('getlinetotalremise', $parameters, $object, $action) > 0) { // Note that $action and $object may have been modified by some hooks
2744 if (isset($hookmanager->resArray['linetotalremise'])) {
2745 return $hookmanager->resArray['linetotalremise'];
2746 } else {
2747 return (float) $hookmanager->resPrint; // For backward compatibility
2748 }
2749 }
2750 }
2751
2752 if (empty($hidedetails) || $hidedetails > 1) {
2753 return $sign * (($object->lines[$i]->subprice * (float) $object->lines[$i]->qty) - $object->lines[$i]->total_ht);
2754 }
2755 }
2756 return 0;
2757}
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:2686
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:1438
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2422
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:1493
pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails=0)
Return line total amount discount.
Definition pdf.lib.php:2717
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:2205
pdf_getlinenum($object, $i, $outputlangs, $hidedetails=0)
Return line num.
Definition pdf.lib.php:1881
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:2083
pdf_getLinkedObjects(&$object, $outputlangs)
Return linked objects to use for document generation.
Definition pdf.lib.php:2533
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:1946
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition pdf.lib.php:2478
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:1027
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:2040
pdf_getlineprogress($object, $i, $outputlangs, $hidedetails=0, $hookmanager=null)
Return line percent.
Definition pdf.lib.php:2371
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:1978
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:1401
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank information for PDF generation.
Definition pdf.lib.php:850
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:2245
pdf_getlineref($object, $i, $outputlangs, $hidedetails=0)
Return line product ref.
Definition pdf.lib.php:1914
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:2285
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2328
pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails=0)
Return line quantity asked.
Definition pdf.lib.php:2165
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2125
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