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