dolibarr 19.0.3
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;
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=".(!getDolGlobalString('MAIN_PDF_FORMAT') ? 'null' : $conf->global->MAIN_PDF_FORMAT)." outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null')." and langs->defaultlang=".(is_object($langs) ? $langs->defaultlang : 'null'));
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' || !getDolGlobalString('MAIN_PDF_FORMAT') || getDolGlobalString('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 (getDolGlobalString('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 (!getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 = (getDolGlobalString('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 = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_USERPASS') ? $conf->global->PDF_SECURITY_ENCRYPTION_USERPASS : '');
212
213 // Password of the owner, created randomly if not defined
214 $pdfownerpass = (getDolGlobalString('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 = (getDolGlobalString('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 = (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 = (!getDolGlobalString('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 (!getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('PDF_ADD_MORE_AFTER_SOURCE_ADDRESS')) {
539 $stringaddress .= ($stringaddress ? "\n" : '') . getDolGlobalString('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 (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
569 // Phone
570 if (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
615 // Phone
616 if (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (!getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF') && (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF') != '-1')) { // Warning, this option make TCPDF generation being crazy and some content disappeared behind the image
732 $filepath = $conf->mycompany->dir_output.'/logos/' . getDolGlobalString('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')) {
736 $pdf->SetAlpha($conf->global->MAIN_USE_BACKGROUND_ON_PDF_ALPHA);
737 } // Option for change opacity of background
738 $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);
739 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) {
740 $pdf->SetAlpha(1);
741 }
742 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
743 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
744 }
745 }
746 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') != '-1') {
747 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
748 }
749}
750
751
762function pdf_getSubstitutionArray($outputlangs, $exclude = null, $object = null, $onlykey = 0, $include = null)
763{
764 $substitutionarray = getCommonSubstitutionArray($outputlangs, $onlykey, $exclude, $object, $include);
765 $substitutionarray['__FROM_NAME__'] = '__FROM_NAME__';
766 $substitutionarray['__FROM_EMAIL__'] = '__FROM_EMAIL__';
767 return $substitutionarray;
768}
769
770
782function pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
783{
784 global $langs, $mysoc, $user;
785
786 // Print Draft Watermark
787 if ($unit == 'pt') {
788 $k = 1;
789 } elseif ($unit == 'mm') {
790 $k = 72 / 25.4;
791 } elseif ($unit == 'cm') {
792 $k = 72 / 2.54;
793 } elseif ($unit == 'in') {
794 $k = 72;
795 }
796
797 // Make substitution
798 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, null);
799 complete_substitutions_array($substitutionarray, $outputlangs, null);
800 $text = make_substitutions($text, $substitutionarray, $outputlangs);
801 $text = $outputlangs->convToOutputCharset($text);
802
803 $savx = $pdf->getX();
804 $savy = $pdf->getY();
805
806 $watermark_angle = atan($h / $w) / 2;
807 $watermark_x_pos = 0;
808 $watermark_y_pos = $h / 3;
809 $watermark_x = $w / 2;
810 $watermark_y = $h / 3;
811 $pdf->SetFont('', 'B', 40);
812 $pdf->SetTextColor(255, 192, 203);
813 //rotate
814 $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));
815 //print watermark
816 $pdf->SetXY($watermark_x_pos, $watermark_y_pos);
817 $pdf->Cell($w - 20, 25, $outputlangs->convToOutputCharset($text), "", 2, "C", 0);
818 //antirotate
819 $pdf->_out('Q');
820
821 $pdf->SetXY($savx, $savy);
822}
823
824
837function pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, $default_font_size = 10)
838{
839 global $mysoc, $conf;
840
841 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbank.class.php';
842
843 $diffsizetitle = (!getDolGlobalString('PDF_DIFFSIZE_TITLE') ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
844 $diffsizecontent = (!getDolGlobalString('PDF_DIFFSIZE_CONTENT') ? 4 : $conf->global->PDF_DIFFSIZE_CONTENT);
845 $pdf->SetXY($curx, $cury);
846
847 if (empty($onlynumber)) {
848 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
849 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByTransferOnThisBankAccount').':', 0, 'L', 0);
850 $cury += 4;
851 }
852
853 $outputlangs->load("banks");
854
855 // Use correct name of bank id according to country
856 $bickey = "BICNumber";
857 if ($account->getCountryCode() == 'IN') {
858 $bickey = "SWIFT";
859 }
860
861 // Get format of bank account according to its country
862 $usedetailedbban = $account->useDetailedBBAN();
863
864 //$onlynumber=0; $usedetailedbban=1; // For tests
865 if ($usedetailedbban) {
866 $savcurx = $curx;
867
868 if (empty($onlynumber)) {
869 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
870 $pdf->SetXY($curx, $cury);
871 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
872 $cury += 3;
873 }
874
875 if (!getDolGlobalString('PDF_BANK_HIDE_NUMBER_SHOW_ONLY_BICIBAN')) { // Note that some countries still need bank number, BIC/IBAN not enougth for them
876 // Note:
877 // bank = code_banque (FR), sort code (GB, IR. Example: 12-34-56)
878 // desk = code guichet (FR), used only when $usedetailedbban = 1
879 // number = account number
880 // key = check control key used only when $usedetailedbban = 1
881 if (empty($onlynumber)) {
882 $pdf->line($curx + 1, $cury + 1, $curx + 1, $cury + 6);
883 }
884
885
886 foreach ($account->getFieldsToShow() as $val) {
887 $pdf->SetXY($curx, $cury + 4);
888 $pdf->SetFont('', '', $default_font_size - 3);
889
890 if ($val == 'BankCode') {
891 // Bank code
892 $tmplength = 18;
893 $content = $account->code_banque;
894 } elseif ($val == 'DeskCode') {
895 // Desk
896 $tmplength = 18;
897 $content = $account->code_guichet;
898 } elseif ($val == 'BankAccountNumber') {
899 // Number
900 $tmplength = 24;
901 $content = $account->number;
902 } elseif ($val == 'BankAccountNumberKey') {
903 // Key
904 $tmplength = 15;
905 $content = $account->cle_rib;
906 } elseif ($val == 'IBAN' || $val == 'BIC') {
907 // Key
908 $tmplength = 0;
909 $content = '';
910 } else {
911 dol_print_error($account->db, 'Unexpected value for getFieldsToShow: '.$val);
912 break;
913 }
914
915 $pdf->MultiCell($tmplength, 3, $outputlangs->convToOutputCharset($content), 0, 'C', 0);
916 $pdf->SetXY($curx, $cury + 1);
917 $curx += $tmplength;
918 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
919 $pdf->MultiCell($tmplength, 3, $outputlangs->transnoentities($val), 0, 'C', 0);
920 if (empty($onlynumber)) {
921 $pdf->line($curx, $cury + 1, $curx, $cury + 7);
922 }
923 }
924
925 $curx = $savcurx;
926 $cury += 8;
927 }
928 } else {
929 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
930 $pdf->SetXY($curx, $cury);
931 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
932 $cury += 3;
933
934 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
935 $pdf->SetXY($curx, $cury);
936 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("BankAccountNumber").': '.$outputlangs->convToOutputCharset($account->number), 0, 'L', 0);
937 $cury += 3;
938
939 if ($diffsizecontent <= 2) {
940 $cury += 1;
941 }
942 }
943
944 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
945
946 if (empty($onlynumber) && !empty($account->domiciliation)) {
947 $pdf->SetXY($curx, $cury);
948 $val = $outputlangs->transnoentities("Residence").': '.$outputlangs->convToOutputCharset($account->domiciliation);
949 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
950 //$nboflines=dol_nboflines_bis($val,120);
951 //$cury+=($nboflines*3)+2;
952 $tmpy = $pdf->getStringHeight(100, $val);
953 $cury += $tmpy;
954 }
955
956 if (!empty($account->proprio)) {
957 $pdf->SetXY($curx, $cury);
958 $val = $outputlangs->transnoentities("BankAccountOwner").': '.$outputlangs->convToOutputCharset($account->proprio);
959 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
960 $tmpy = $pdf->getStringHeight(100, $val);
961 $cury += $tmpy;
962 } elseif (!$usedetailedbban) {
963 $cury += 1;
964 }
965
966 // Use correct name of bank id according to country
967 $ibankey = FormBank::getIBANLabel($account);
968
969 if (!empty($account->iban)) {
970 //Remove whitespaces to ensure we are dealing with the format we expect
971 $ibanDisplay_temp = str_replace(' ', '', $outputlangs->convToOutputCharset($account->iban));
972 $ibanDisplay = "";
973
974 $nbIbanDisplay_temp = dol_strlen($ibanDisplay_temp);
975 for ($i = 0; $i < $nbIbanDisplay_temp; $i++) {
976 $ibanDisplay .= $ibanDisplay_temp[$i];
977 if ($i % 4 == 3 && $i > 0) {
978 $ibanDisplay .= " ";
979 }
980 }
981
982 $pdf->SetFont('', 'B', $default_font_size - 3);
983 $pdf->SetXY($curx, $cury);
984 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($ibankey).': '.$ibanDisplay, 0, 'L', 0);
985 $cury += 3;
986 }
987
988 if (!empty($account->bic)) {
989 $pdf->SetFont('', 'B', $default_font_size - 3);
990 $pdf->SetXY($curx, $cury);
991 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($bickey).': '.$outputlangs->convToOutputCharset($account->bic), 0, 'L', 0);
992 }
993
994 return $pdf->getY();
995}
996
1014function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails = 0, $hidefreetext = 0, $page_largeur = 0, $watermark = '')
1015{
1016 global $conf, $user, $mysoc, $hookmanager;
1017
1018 $outputlangs->load("dict");
1019 $line = '';
1020 $reg = array();
1021
1022 $dims = $pdf->getPageDimensions();
1023
1024 // Line of free text
1025 if (empty($hidefreetext) && !empty($conf->global->$paramfreetext)) {
1026 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
1027 // More substitution keys
1028 $substitutionarray['__FROM_NAME__'] = $fromcompany->name;
1029 $substitutionarray['__FROM_EMAIL__'] = $fromcompany->email;
1030 complete_substitutions_array($substitutionarray, $outputlangs, $object);
1031 $newfreetext = make_substitutions(getDolGlobalString($paramfreetext), $substitutionarray, $outputlangs);
1032
1033 // Make a change into HTML code to allow to include images from medias directory.
1034 // <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1035 // become
1036 // <img alt="" src="'.DOL_DATA_ROOT.'/medias/image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1037 $newfreetext = preg_replace('/(<img.*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)("[^\/]*\/>)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $newfreetext);
1038
1039 $line .= $outputlangs->convToOutputCharset($newfreetext);
1040 }
1041
1042 // First line of company infos
1043 $line1 = "";
1044 $line2 = "";
1045 $line3 = "";
1046 $line4 = "";
1047
1048 if ($showdetails == 1 || $showdetails == 3) {
1049 // Company name
1050 if ($fromcompany->name) {
1051 $line1 .= ($line1 ? " - " : "").$outputlangs->transnoentities("RegisteredOffice").": ".$fromcompany->name;
1052 }
1053 // Address
1054 if ($fromcompany->address) {
1055 $line1 .= ($line1 ? " - " : "").str_replace("\n", ", ", $fromcompany->address);
1056 }
1057 // Zip code
1058 if ($fromcompany->zip) {
1059 $line1 .= ($line1 ? " - " : "").$fromcompany->zip;
1060 }
1061 // Town
1062 if ($fromcompany->town) {
1063 $line1 .= ($line1 ? " " : "").$fromcompany->town;
1064 }
1065 // Country
1066 if ($fromcompany->country) {
1067 $line1 .= ($line1 ? ", " : "").$fromcompany->country;
1068 }
1069 // Phone
1070 if ($fromcompany->phone) {
1071 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Phone").": ".$fromcompany->phone;
1072 }
1073 // Fax
1074 if ($fromcompany->fax) {
1075 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Fax").": ".$fromcompany->fax;
1076 }
1077
1078 // URL
1079 if ($fromcompany->url) {
1080 $line2 .= ($line2 ? " - " : "").$fromcompany->url;
1081 }
1082 // Email
1083 if ($fromcompany->email) {
1084 $line2 .= ($line2 ? " - " : "").$fromcompany->email;
1085 }
1086 }
1087 if ($showdetails == 2 || $showdetails == 3 || (!empty($fromcompany->country_code) && $fromcompany->country_code == 'DE')) {
1088 // Managers
1089 if ($fromcompany->managers) {
1090 $line2 .= ($line2 ? " - " : "").$fromcompany->managers;
1091 }
1092 }
1093
1094 // Line 3 of company infos
1095 // Juridical status
1096 if (!empty($fromcompany->forme_juridique_code) && $fromcompany->forme_juridique_code) {
1097 $line3 .= ($line3 ? " - " : "").$outputlangs->convToOutputCharset(getFormeJuridiqueLabel($fromcompany->forme_juridique_code));
1098 }
1099 // Capital
1100 if (!empty($fromcompany->capital)) {
1101 $tmpamounttoshow = price2num($fromcompany->capital); // This field is a free string or a float
1102 if (is_numeric($tmpamounttoshow) && $tmpamounttoshow > 0) {
1103 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", price($tmpamounttoshow, 0, $outputlangs, 0, 0, 0, $conf->currency));
1104 } elseif (!empty($fromcompany->capital)) {
1105 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", $fromcompany->capital, $outputlangs);
1106 }
1107 }
1108 // Prof Id 1
1109 if (!empty($fromcompany->idprof1) && $fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || !$fromcompany->idprof2)) {
1110 $field = $outputlangs->transcountrynoentities("ProfId1", $fromcompany->country_code);
1111 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1112 $field = $reg[1];
1113 }
1114 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof1);
1115 }
1116 // Prof Id 2
1117 if (!empty($fromcompany->idprof2) && $fromcompany->idprof2) {
1118 $field = $outputlangs->transcountrynoentities("ProfId2", $fromcompany->country_code);
1119 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1120 $field = $reg[1];
1121 }
1122 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof2);
1123 }
1124
1125 // Line 4 of company infos
1126 // Prof Id 3
1127 if (!empty($fromcompany->idprof3) && $fromcompany->idprof3) {
1128 $field = $outputlangs->transcountrynoentities("ProfId3", $fromcompany->country_code);
1129 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1130 $field = $reg[1];
1131 }
1132 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof3);
1133 }
1134 // Prof Id 4
1135 if (!empty($fromcompany->idprof4) && $fromcompany->idprof4) {
1136 $field = $outputlangs->transcountrynoentities("ProfId4", $fromcompany->country_code);
1137 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1138 $field = $reg[1];
1139 }
1140 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof4);
1141 }
1142 // Prof Id 5
1143 if (!empty($fromcompany->idprof5) && $fromcompany->idprof5) {
1144 $field = $outputlangs->transcountrynoentities("ProfId5", $fromcompany->country_code);
1145 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1146 $field = $reg[1];
1147 }
1148 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof5);
1149 }
1150 // Prof Id 6
1151 if (!empty($fromcompany->idprof6) && $fromcompany->idprof6) {
1152 $field = $outputlangs->transcountrynoentities("ProfId6", $fromcompany->country_code);
1153 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1154 $field = $reg[1];
1155 }
1156 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof6);
1157 }
1158 // Prof Id 7
1159 if (!empty($fromcompany->idprof7) && $fromcompany->idprof7) {
1160 $field = $outputlangs->transcountrynoentities("ProfId7", $fromcompany->country_code);
1161 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1162 $field = $reg[1];
1163 }
1164 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof7);
1165 }
1166 // Prof Id 8
1167 if (!empty($fromcompany->idprof8) && $fromcompany->idprof8) {
1168 $field = $outputlangs->transcountrynoentities("ProfId8", $fromcompany->country_code);
1169 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1170 $field = $reg[1];
1171 }
1172 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof8);
1173 }
1174 // Prof Id 9
1175 if (!empty($fromcompany->idprof9) && $fromcompany->idprof9) {
1176 $field = $outputlangs->transcountrynoentities("ProfId9", $fromcompany->country_code);
1177 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1178 $field = $reg[1];
1179 }
1180 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof9);
1181 }
1182 // Prof Id 10
1183 if (!empty($fromcompany->idprof10) && $fromcompany->idprof10) {
1184 $field = $outputlangs->transcountrynoentities("ProfId10", $fromcompany->country_code);
1185 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1186 $field = $reg[1];
1187 }
1188 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof10);
1189 }
1190 // IntraCommunautary VAT
1191 if (!empty($fromcompany->tva_intra) && $fromcompany->tva_intra != '') {
1192 $line4 .= ($line4 ? " - " : "").$outputlangs->transnoentities("VATIntraShort").": ".$outputlangs->convToOutputCharset($fromcompany->tva_intra);
1193 }
1194
1195 $pdf->SetFont('', '', 7);
1196 $pdf->SetDrawColor(224, 224, 224);
1197 // Option for footer text color
1198 if (getDolGlobalString('PDF_FOOTER_TEXT_COLOR')) {
1199 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_TEXT_COLOR, '%d, %d, %d');
1200 $pdf->SetTextColor($r, $g, $b);
1201 }
1202
1203 // The start of the bottom of this page footer is positioned according to # of lines
1204 $freetextheight = 0;
1205 if ($line) { // Free text
1206 //$line="sample text<br>\nfd<strong>sf</strong>sdf<br>\nghfghg<br>";
1207 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) {
1208 $width = 20000;
1209 $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.
1210 if (getDolGlobalString('MAIN_USE_AUTOWRAP_ON_FREETEXT')) {
1211 $width = 200;
1212 $align = 'C';
1213 }
1214 $freetextheight = $pdf->getStringHeight($width, $line);
1215 } else {
1216 $freetextheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); // New method (works for HTML content)
1217 //print '<br>'.$freetextheight;exit;
1218 }
1219 }
1220
1221 // For customize footer
1222 if (is_object($hookmanager)) {
1223 $parameters = array('line1' => $line1, 'line2' => $line2, 'line3' => $line3, 'line4' => $line4, 'outputlangs'=>$outputlangs);
1224 $action = '';
1225 $hookmanager->executeHooks('pdf_pagefoot', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1226 if (!empty($hookmanager->resPrint) && $hidefreetext == 0) {
1227 $mycustomfooter = $hookmanager->resPrint;
1228 $mycustomfooterheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1229
1230 $marginwithfooter = $marge_basse + $freetextheight + $mycustomfooterheight;
1231 $posy = (float) $marginwithfooter;
1232
1233 // Option for footer background color (without freetext zone)
1234 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1235 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1236 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1237 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b));
1238 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1239 }
1240
1241 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1242 $pdf->SetAutoPageBreak(0, 0);
1243 } // Option for disable auto pagebreak
1244 if ($line) { // Free text
1245 $pdf->SetXY($dims['lm'], -$posy);
1246 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1247 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1248 } else {
1249 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1250 }
1251 $posy -= $freetextheight;
1252 }
1253 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1254 $pdf->SetAutoPageBreak(1, 0);
1255 } // Restore pagebreak
1256
1257 $pdf->SetY(-$posy);
1258
1259 // Hide footer line if footer background color is set
1260 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1261 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1262 }
1263
1264 // Option for set top margin height of footer after freetext
1265 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1266 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1267 } else {
1268 $posy--;
1269 }
1270
1271 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1272 $pdf->SetAutoPageBreak(0, 0);
1273 } // Option for disable auto pagebreak
1274 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1275 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1276 $pdf->SetAutoPageBreak(1, 0);
1277 } // Restore pagebreak
1278
1279 $posy -= $mycustomfooterheight - 3;
1280 } else {
1281 // Else default footer
1282 $marginwithfooter = $marge_basse + $freetextheight + (!empty($line1) ? 3 : 0) + (!empty($line2) ? 3 : 0) + (!empty($line3) ? 3 : 0) + (!empty($line4) ? 3 : 0);
1283 $posy = (float) $marginwithfooter;
1284
1285 // Option for footer background color (without freetext zone)
1286 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1287 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1288 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1289 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b));
1290 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1291 }
1292
1293 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1294 $pdf->SetAutoPageBreak(0, 0);
1295 } // Option for disable auto pagebreak
1296 if ($line) { // Free text
1297 $pdf->SetXY($dims['lm'], -$posy);
1298 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1299 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1300 } else {
1301 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1302 }
1303 $posy -= $freetextheight;
1304 }
1305 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1306 $pdf->SetAutoPageBreak(1, 0);
1307 } // Restore pagebreak
1308
1309 $pdf->SetY(-$posy);
1310
1311 // Option for hide all footer (page number will no hidden)
1312 if (!getDolGlobalInt('PDF_FOOTER_HIDDEN')) {
1313 // Hide footer line if footer background color is set
1314 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1315 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1316 }
1317
1318 // Option for set top margin height of footer after freetext
1319 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1320 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1321 } else {
1322 $posy--;
1323 }
1324
1325 if (!empty($line1)) {
1326 $pdf->SetFont('', 'B', 7);
1327 $pdf->SetXY($dims['lm'], -$posy);
1328 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line1, 0, 'C', 0);
1329 $posy -= 3;
1330 $pdf->SetFont('', '', 7);
1331 }
1332
1333 if (!empty($line2)) {
1334 $pdf->SetFont('', 'B', 7);
1335 $pdf->SetXY($dims['lm'], -$posy);
1336 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line2, 0, 'C', 0);
1337 $posy -= 3;
1338 $pdf->SetFont('', '', 7);
1339 }
1340
1341 if (!empty($line3)) {
1342 $pdf->SetXY($dims['lm'], -$posy);
1343 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line3, 0, 'C', 0);
1344 }
1345
1346 if (!empty($line4)) {
1347 $posy -= 3;
1348 $pdf->SetXY($dims['lm'], -$posy);
1349 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line4, 0, 'C', 0);
1350 }
1351 }
1352 }
1353 }
1354
1355 // Show page nb and apply correction for some font.
1356 $pdf->SetXY($dims['wk'] - $dims['rm'] - 18 - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_X', 0), -$posy - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_Y', 0));
1357 $pagination = $pdf->PageNo().' / '.$pdf->getAliasNbPages();
1358 $fontRenderCorrection = 0;
1359 if (in_array(pdf_getPDFFont($outputlangs), array('freemono', 'DejaVuSans'))) {
1360 $fontRenderCorrection = 10;
1361 }
1362 $pdf->MultiCell(18 + $fontRenderCorrection, 2, $pagination, 0, 'R', 0);
1363
1364 // Show Draft Watermark
1365 if (!empty($watermark)) {
1366 pdf_watermark($pdf, $outputlangs, $page_hauteur, $page_largeur, 'mm', $watermark);
1367 }
1368
1369 return $marginwithfooter;
1370}
1371
1386function pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
1387{
1388 $linkedobjects = pdf_getLinkedObjects($object, $outputlangs);
1389 if (!empty($linkedobjects)) {
1390 foreach ($linkedobjects as $linkedobject) {
1391 $reftoshow = $linkedobject["ref_title"].' : '.$linkedobject["ref_value"];
1392 if (!empty($linkedobject["date_value"])) {
1393 $reftoshow .= ' / '.$linkedobject["date_value"];
1394 }
1395
1396 $posy += 3;
1397 $pdf->SetXY($posx, $posy);
1398 $pdf->SetFont('', '', $default_font_size - 2);
1399 $pdf->MultiCell($w, $h, $reftoshow, '', $align);
1400 }
1401 }
1402
1403 return $pdf->getY();
1404}
1405
1422function pdf_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1423{
1424 global $db, $conf, $langs, $hookmanager;
1425
1426 $reshook = 0;
1427 $result = '';
1428 //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) ) )
1429 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
1430 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1431 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1432 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1433 }
1434 $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);
1435 $action = '';
1436 $reshook = $hookmanager->executeHooks('pdf_writelinedesc', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1437
1438 if (!empty($hookmanager->resPrint)) {
1439 $result .= $hookmanager->resPrint;
1440 }
1441 }
1442 if (empty($reshook)) {
1443 $labelproductservice = pdf_getlinedesc($object, $i, $outputlangs, $hideref, $hidedesc, $issupplierline);
1444
1445 //var_dump($labelproductservice);exit;
1446
1447 // 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"
1448 // We make the reverse, so PDF generation has the real URL.
1449 $nbrep = 0;
1450 $labelproductservice = preg_replace('/(<img[^>]*src=")([^"]*)(&amp;)([^"]*")/', '\1\2&\4', $labelproductservice, -1, $nbrep);
1451
1452 if (getDolGlobalString('MARGIN_TOP_ZERO_UL')) {
1453 $pdf->setListIndentWidth(5);
1454 $TMarginList = ['ul' => [['h'=>0.1, ],['h'=>0.1, ]], 'li' => [['h'=>0.1, ],],];
1455 $pdf->setHtmlVSpace($TMarginList);
1456 }
1457
1458 // Description
1459 $pdf->writeHTMLCell($w, $h, $posx, $posy, $outputlangs->convToOutputCharset($labelproductservice), 0, 1, false, true, 'J', true);
1460 $result .= $labelproductservice;
1461 }
1462 return $result;
1463}
1464
1476function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1477{
1478 global $db, $conf, $langs;
1479
1480 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1481 $label = (!empty($object->lines[$i]->label) ? $object->lines[$i]->label : (!empty($object->lines[$i]->product_label) ? $object->lines[$i]->product_label : ''));
1482 $product_barcode = (!empty($object->lines[$i]->product_barcode) ? $object->lines[$i]->product_barcode : "");
1483 $desc = (!empty($object->lines[$i]->desc) ? $object->lines[$i]->desc : (!empty($object->lines[$i]->description) ? $object->lines[$i]->description : ''));
1484 $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
1485 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1486 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1487
1488 if ($issupplierline) {
1489 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
1490 $prodser = new ProductFournisseur($db);
1491 } else {
1492 include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1493 $prodser = new Product($db);
1494
1495 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
1496 include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
1497 }
1498 }
1499
1500 if ($idprod) {
1501 $prodser->fetch($idprod);
1502 // If a predefined product and multilang and on other lang, we renamed label with label translated
1503 if (getDolGlobalInt('MAIN_MULTILANGS') && ($outputlangs->defaultlang != $langs->defaultlang)) {
1504 $translatealsoifmodified = (getDolGlobalString('MAIN_MULTILANG_TRANSLATE_EVEN_IF_MODIFIED')); // By default if value was modified manually, we keep it (no translation because we don't have it)
1505
1506 // 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
1507 // ($textwasnotmodified is replaced with $textwasmodifiedorcompleted and we add completion).
1508
1509 // Set label
1510 // 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.
1511 //var_dump($outputlangs->defaultlang.' - '.$langs->defaultlang.' - '.$label.' - '.$prodser->label);exit;
1512 $textwasnotmodified = ($label == $prodser->label);
1513 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["label"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1514 $label = $prodser->multilangs[$outputlangs->defaultlang]["label"];
1515 }
1516
1517 // Set desc
1518 // Manage HTML entities description test because $prodser->description is store with htmlentities but $desc no
1519 $textwasnotmodified = false;
1520 if (!empty($desc) && dol_textishtml($desc) && !empty($prodser->description) && dol_textishtml($prodser->description)) {
1521 $textwasnotmodified = (strpos(dol_html_entity_decode($desc, ENT_QUOTES | ENT_HTML5), dol_html_entity_decode($prodser->description, ENT_QUOTES | ENT_HTML5)) !== false);
1522 } else {
1523 $textwasnotmodified = ($desc == $prodser->description);
1524 }
1525 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["description"])) {
1526 if ($textwasnotmodified) {
1527 $desc = str_replace($prodser->description, $prodser->multilangs[$outputlangs->defaultlang]["description"], $desc);
1528 } elseif ($translatealsoifmodified) {
1529 $desc = $prodser->multilangs[$outputlangs->defaultlang]["description"];
1530 }
1531 }
1532
1533 // Set note
1534 $textwasnotmodified = ($note == $prodser->note_public);
1535 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["other"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1536 $note = $prodser->multilangs[$outputlangs->defaultlang]["other"];
1537 }
1538 }
1539 } 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
1540 $desc = str_replace('(DEPOSIT)', $outputlangs->trans('Deposit'), $desc);
1541 }
1542
1543 if (!getDolGlobalString('PDF_HIDE_PRODUCT_LABEL_IN_SUPPLIER_LINES')) {
1544 // Description short of product line
1545 $libelleproduitservice = $label;
1546 if (!empty($libelleproduitservice) && getDolGlobalString('PDF_BOLD_PRODUCT_LABEL')) {
1547 // Adding <b> may convert the original string into a HTML string. Sowe have to first
1548 // convert \n into <br> we text is not already HTML.
1549 if (!dol_textishtml($libelleproduitservice)) {
1550 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1551 }
1552 $libelleproduitservice = '<b>'.$libelleproduitservice.'</b>';
1553 }
1554 }
1555
1556
1557 // Add ref of subproducts
1558 if (getDolGlobalString('SHOW_SUBPRODUCT_REF_IN_PDF')) {
1559 $prodser->get_sousproduits_arbo();
1560 if (!empty($prodser->sousprods) && is_array($prodser->sousprods) && count($prodser->sousprods)) {
1561 $outputlangs->load('mrp');
1562 $tmparrayofsubproducts = reset($prodser->sousprods);
1563
1564 $qtyText = null;
1565 if (isset($object->lines[$i]->qty) && !empty($object->lines[$i]->qty)) {
1566 $qtyText = $object->lines[$i]->qty;
1567 } elseif (isset($object->lines[$i]->qty_shipped) && !empty($object->lines[$i]->qty_shipped)) {
1568 $qtyText = $object->lines[$i]->qty;
1569 }
1570
1571 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF')) {
1572 foreach ($tmparrayofsubproducts as $subprodval) {
1573 $libelleproduitservice = dol_concatdesc(
1574 dol_concatdesc($libelleproduitservice, " * ".$subprodval[3]),
1575 (!empty($qtyText) ?
1576 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1]*$qtyText :
1577 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1578 );
1579 }
1580 } else {
1581 foreach ($tmparrayofsubproducts as $subprodval) {
1582 $libelleproduitservice = dol_concatdesc(
1583 dol_concatdesc($libelleproduitservice, " * ".$subprodval[5].(($subprodval[5] && $subprodval[3]) ? ' - ' : '').$subprodval[3]),
1584 (!empty($qtyText) ?
1585 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1]*$qtyText :
1586 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1587 );
1588 }
1589 }
1590 }
1591 }
1592
1593 if (isModEnabled('barcode') && getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_PRODUCT_BARCODE') && !empty($product_barcode)) {
1594 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $outputlangs->trans("BarCode")." ".$product_barcode);
1595 }
1596
1597 // Description long of product line
1598 if (!empty($desc) && ($desc != $label)) {
1599 if ($desc == '(CREDIT_NOTE)' && $object->lines[$i]->fk_remise_except) {
1600 $discount = new DiscountAbsolute($db);
1601 $discount->fetch($object->lines[$i]->fk_remise_except);
1602 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1603 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromCreditNote", $sourceref);
1604 } elseif ($desc == '(DEPOSIT)' && $object->lines[$i]->fk_remise_except) {
1605 $discount = new DiscountAbsolute($db);
1606 $discount->fetch($object->lines[$i]->fk_remise_except);
1607 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1608 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromDeposit", $sourceref);
1609 // Add date of deposit
1610 if (getDolGlobalString('INVOICE_ADD_DEPOSIT_DATE')) {
1611 $libelleproduitservice .= ' ('.dol_print_date($discount->datec, 'day', '', $outputlangs).')';
1612 }
1613 } elseif ($desc == '(EXCESS RECEIVED)' && $object->lines[$i]->fk_remise_except) {
1614 $discount = new DiscountAbsolute($db);
1615 $discount->fetch($object->lines[$i]->fk_remise_except);
1616 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived", $discount->ref_facture_source);
1617 } elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except) {
1618 $discount = new DiscountAbsolute($db);
1619 $discount->fetch($object->lines[$i]->fk_remise_except);
1620 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid", $discount->ref_invoice_supplier_source);
1621 } else {
1622 if ($idprod) {
1623 // Check if description must be output
1624 if (!empty($object->element)) {
1625 $tmpkey = 'MAIN_DOCUMENTS_HIDE_DESCRIPTION_FOR_'.strtoupper($object->element);
1626 if (!empty($conf->global->$tmpkey)) {
1627 $hidedesc = 1;
1628 }
1629 }
1630 if (empty($hidedesc)) {
1631 if (getDolGlobalString('MAIN_DOCUMENTS_DESCRIPTION_FIRST')) {
1632 $libelleproduitservice = dol_concatdesc($desc, $libelleproduitservice);
1633 } else {
1634 if (getDolGlobalString('HIDE_LABEL_VARIANT_PDF') && $prodser->isVariant()) {
1635 $libelleproduitservice = $desc;
1636 } else {
1637 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1638 }
1639 }
1640 }
1641 } else {
1642 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1643 }
1644 }
1645 }
1646
1647 // We add ref of product (and supplier ref if defined)
1648 $prefix_prodserv = "";
1649 $ref_prodserv = "";
1650 if (getDolGlobalString('PRODUCT_ADD_TYPE_IN_DOCUMENTS')) { // In standard mode, we do not show this
1651 if ($prodser->isService()) {
1652 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." ";
1653 } else {
1654 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." ";
1655 }
1656 }
1657
1658 if (empty($hideref)) {
1659 if ($issupplierline) {
1660 if (!getDolGlobalString('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES')) { // Common case
1661 $ref_prodserv = $prodser->ref; // Show local ref
1662 if ($ref_supplier) {
1663 $ref_prodserv .= ($prodser->ref ? ' (' : '').$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.($prodser->ref ? ')' : '');
1664 }
1665 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 1) {
1666 $ref_prodserv = $ref_supplier;
1667 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 2) {
1668 $ref_prodserv = $ref_supplier.' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')';
1669 }
1670 } else {
1671 $ref_prodserv = $prodser->ref; // Show local ref only
1672
1673 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
1674 $productCustomerPriceStatic = new ProductCustomerPrice($db);
1675 $filter = array('fk_product' => $idprod, 'fk_soc' => $object->socid);
1676
1677 $nbCustomerPrices = $productCustomerPriceStatic->fetchAll('', '', 1, 0, $filter);
1678
1679 if ($nbCustomerPrices > 0) {
1680 $productCustomerPrice = $productCustomerPriceStatic->lines[0];
1681
1682 if (!empty($productCustomerPrice->ref_customer)) {
1683 switch ($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
1684 case 1:
1685 $ref_prodserv = $productCustomerPrice->ref_customer;
1686 break;
1687
1688 case 2:
1689 $ref_prodserv = $productCustomerPrice->ref_customer . ' (' . $outputlangs->transnoentitiesnoconv('InternalRef') . ' ' . $ref_prodserv . ')';
1690 break;
1691
1692 default:
1693 $ref_prodserv = $ref_prodserv . ' (' . $outputlangs->transnoentitiesnoconv('RefCustomer') . ' ' . $productCustomerPrice->ref_customer . ')';
1694 }
1695 }
1696 }
1697 }
1698 }
1699
1700 if (!empty($libelleproduitservice) && !empty($ref_prodserv)) {
1701 $ref_prodserv .= " - ";
1702 }
1703 }
1704
1705 if (!empty($ref_prodserv) && getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1706 if (!dol_textishtml($libelleproduitservice)) {
1707 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1708 }
1709 $ref_prodserv = '<b>'.$ref_prodserv.'</b>';
1710 // $prefix_prodserv and $ref_prodser are not HTML var
1711 }
1712 $libelleproduitservice = $prefix_prodserv.$ref_prodserv.$libelleproduitservice;
1713
1714 // Add an additional description for the category products
1715 if (getDolGlobalString('CATEGORY_ADD_DESC_INTO_DOC') && $idprod && isModEnabled('categorie')) {
1716 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1717 $categstatic = new Categorie($db);
1718 // recovering the list of all the categories linked to product
1719 $tblcateg = $categstatic->containing($idprod, Categorie::TYPE_PRODUCT);
1720 foreach ($tblcateg as $cate) {
1721 // Adding the descriptions if they are filled
1722 $desccateg = $cate->description;
1723 if ($desccateg) {
1724 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desccateg);
1725 }
1726 }
1727 }
1728
1729 if (!empty($object->lines[$i]->date_start) || !empty($object->lines[$i]->date_end)) {
1730 $format = 'day';
1731 $period = '';
1732 // Show duration if exists
1733 if ($object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1734 $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)).')';
1735 }
1736 if ($object->lines[$i]->date_start && !$object->lines[$i]->date_end) {
1737 $period = '('.$outputlangs->transnoentitiesnoconv('DateFrom', dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs)).')';
1738 }
1739 if (!$object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1740 $period = '('.$outputlangs->transnoentitiesnoconv('DateUntil', dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
1741 }
1742 //print '>'.$outputlangs->charset_output.','.$period;
1743 if (getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1744 if (!dol_textishtml($libelleproduitservice)) {
1745 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1746 }
1747 $libelleproduitservice .= '<br><b style="color:#333666;" ><em>'.$period.'</em></b>';
1748 } else {
1749 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $period);
1750 }
1751 //print $libelleproduitservice;
1752 }
1753
1754 // Show information for lot
1755 if (!empty($dbatch)) {
1756 // $object is a shipment.
1757 //var_dump($object->lines[$i]->details_entrepot); // array from llx_expeditiondet (we can have several lines for one fk_origin_line)
1758 //var_dump($object->lines[$i]->detail_batch); // array from llx_expeditiondet_batch (each line with a lot is linked to llx_expeditiondet)
1759
1760 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1761 include_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
1762 $tmpwarehouse = new Entrepot($db);
1763 $tmpproductbatch = new Productbatch($db);
1764
1765 $format = 'day';
1766 foreach ($dbatch as $detail) {
1767 $dte = array();
1768 if ($detail->eatby) {
1769 $dte[] = $outputlangs->transnoentitiesnoconv('printEatby', dol_print_date($detail->eatby, $format, false, $outputlangs));
1770 }
1771 if ($detail->sellby) {
1772 $dte[] = $outputlangs->transnoentitiesnoconv('printSellby', dol_print_date($detail->sellby, $format, false, $outputlangs));
1773 }
1774 if ($detail->batch) {
1775 $dte[] = $outputlangs->transnoentitiesnoconv('printBatch', $detail->batch);
1776 }
1777 $dte[] = $outputlangs->transnoentitiesnoconv('printQty', $detail->qty);
1778
1779 // Add also info of planned warehouse for lot
1780 if ($object->element == 'shipping' && $detail->fk_origin_stock > 0 && getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1781 $resproductbatch = $tmpproductbatch->fetch($detail->fk_origin_stock);
1782 if ($resproductbatch > 0) {
1783 $reswarehouse = $tmpwarehouse->fetch($tmpproductbatch->warehouseid);
1784 if ($reswarehouse > 0) {
1785 $dte[] = $tmpwarehouse->ref;
1786 }
1787 }
1788 }
1789
1790 $libelleproduitservice .= "__N__ ".implode(" - ", $dte);
1791 }
1792 } else {
1793 if (getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1794 // TODO Show warehouse for shipment line without batch
1795 }
1796 }
1797
1798 // Now we convert \n into br
1799 if (dol_textishtml($libelleproduitservice)) {
1800 $libelleproduitservice = preg_replace('/__N__/', '<br>', $libelleproduitservice);
1801 } else {
1802 $libelleproduitservice = preg_replace('/__N__/', "\n", $libelleproduitservice);
1803 }
1804 $libelleproduitservice = dol_htmlentitiesbr($libelleproduitservice, 1);
1805
1806 return $libelleproduitservice;
1807}
1808
1818function pdf_getlinenum($object, $i, $outputlangs, $hidedetails = 0)
1819{
1820 global $hookmanager;
1821
1822 $reshook = 0;
1823 $result = '';
1824 //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) ) )
1825 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
1826 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1827 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1828 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1829 }
1830 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1831 $action = '';
1832 $reshook = $hookmanager->executeHooks('pdf_getlinenum', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1833 $result .= $hookmanager->resPrint;
1834 }
1835 if (empty($reshook)) {
1836 $result .= dol_htmlentitiesbr($object->lines[$i]->num);
1837 }
1838 return $result;
1839}
1840
1841
1851function pdf_getlineref($object, $i, $outputlangs, $hidedetails = 0)
1852{
1853 global $hookmanager;
1854
1855 $reshook = 0;
1856 $result = '';
1857 //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) ) )
1858 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
1859 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1860 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1861 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1862 }
1863 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1864 $action = '';
1865 $reshook = $hookmanager->executeHooks('pdf_getlineref', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1866 $result .= $hookmanager->resPrint;
1867 }
1868 if (empty($reshook)) {
1869 $result .= dol_htmlentitiesbr($object->lines[$i]->product_ref);
1870 }
1871 return $result;
1872}
1873
1883function pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails = 0)
1884{
1885 global $hookmanager;
1886
1887 $reshook = 0;
1888 $result = '';
1889 //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) ) )
1890 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
1891 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1892 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1893 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1894 }
1895 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1896 $action = '';
1897 $reshook = $hookmanager->executeHooks('pdf_getlineref_supplier', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1898 $result .= $hookmanager->resPrint;
1899 }
1900 if (empty($reshook)) {
1901 $result .= dol_htmlentitiesbr($object->lines[$i]->ref_supplier);
1902 }
1903 return $result;
1904}
1905
1915function pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails = 0)
1916{
1917 global $conf, $hookmanager, $mysoc;
1918
1919 $result = '';
1920 $reshook = 0;
1921 //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) ) )
1922 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
1923 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1924 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1925 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1926 }
1927 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1928 $action = '';
1929 $reshook = $hookmanager->executeHooks('pdf_getlinevatrate', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1930
1931 if (!empty($hookmanager->resPrint)) {
1932 $result .= $hookmanager->resPrint;
1933 }
1934 }
1935 if (empty($reshook)) {
1936 if (empty($hidedetails) || $hidedetails > 1) {
1937 $tmpresult = '';
1938
1939 $tmpresult .= vatrate($object->lines[$i]->tva_tx, 0, $object->lines[$i]->info_bits, -1);
1940 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_SECOND_TAX')) {
1941 if ($object->lines[$i]->total_localtax1 != 0) {
1942 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
1943 $tmpresult .= '/';
1944 } else {
1945 $tmpresult = '';
1946 }
1947 $tmpresult .= vatrate(abs($object->lines[$i]->localtax1_tx), 0);
1948 }
1949 }
1950 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_THIRD_TAX')) {
1951 if ($object->lines[$i]->total_localtax2 != 0) {
1952 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
1953 $tmpresult .= '/';
1954 } else {
1955 $tmpresult = '';
1956 }
1957 $tmpresult .= vatrate(abs($object->lines[$i]->localtax2_tx), 0);
1958 }
1959 }
1960 $tmpresult .= '%';
1961
1962 $result .= $tmpresult;
1963 }
1964 }
1965 return $result;
1966}
1967
1977function pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails = 0)
1978{
1979 global $conf, $hookmanager;
1980
1981 $sign = 1;
1982 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
1983 $sign = -1;
1984 }
1985
1986 $result = '';
1987 $reshook = 0;
1988 //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) ) )
1989 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
1990 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1991 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1992 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1993 }
1994 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1995 $action = '';
1996 $reshook = $hookmanager->executeHooks('pdf_getlineupexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1997
1998 if (!empty($hookmanager->resPrint)) {
1999 $result .= $hookmanager->resPrint;
2000 }
2001 }
2002 if (empty($reshook)) {
2003 if (empty($hidedetails) || $hidedetails > 1) {
2004 $subprice = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_subprice : $object->lines[$i]->subprice);
2005 $result .= price($sign * $subprice, 0, $outputlangs);
2006 }
2007 }
2008 return $result;
2009}
2010
2020function pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails = 0)
2021{
2022 global $hookmanager, $conf;
2023
2024 $sign = 1;
2025 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2026 $sign = -1;
2027 }
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]->special_code) ? '' : $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_getlineupwithtax', $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 (empty($hidedetails) || $hidedetails > 1) {
2047 $result .= price($sign * (($object->lines[$i]->subprice) + ($object->lines[$i]->subprice) * ($object->lines[$i]->tva_tx) / 100), 0, $outputlangs);
2048 }
2049 }
2050 return $result;
2051}
2052
2062function pdf_getlineqty($object, $i, $outputlangs, $hidedetails = 0)
2063{
2064 global $hookmanager;
2065
2066 $result = '';
2067 $reshook = 0;
2068 //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) ) )
2069 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
2070 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2071 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2072 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2073 }
2074 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2075 $action = '';
2076 $reshook = $hookmanager->executeHooks('pdf_getlineqty', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2077
2078 if (!empty($hookmanager->resPrint)) {
2079 $result = $hookmanager->resPrint;
2080 }
2081 }
2082 if (empty($reshook)) {
2083 if ($object->lines[$i]->special_code == 3) {
2084 return '';
2085 }
2086 if (empty($hidedetails) || $hidedetails > 1) {
2087 $result .= $object->lines[$i]->qty;
2088 }
2089 }
2090 return $result;
2091}
2092
2102function pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails = 0)
2103{
2104 global $hookmanager;
2105
2106 $reshook = 0;
2107 $result = '';
2108 //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) ) )
2109 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
2110 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2111 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2112 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2113 }
2114 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2115 $action = '';
2116 $reshook = $hookmanager->executeHooks('pdf_getlineqty_asked', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2117
2118 if (!empty($hookmanager->resPrint)) {
2119 $result .= $hookmanager->resPrint;
2120 }
2121 }
2122 if (empty($reshook)) {
2123 if ($object->lines[$i]->special_code == 3) {
2124 return '';
2125 }
2126 if (empty($hidedetails) || $hidedetails > 1) {
2127 $result .= $object->lines[$i]->qty_asked;
2128 }
2129 }
2130 return $result;
2131}
2132
2142function pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails = 0)
2143{
2144 global $hookmanager;
2145
2146 $reshook = 0;
2147 $result = '';
2148 //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) ) )
2149 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
2150 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2151 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2152 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2153 }
2154 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2155 $action = '';
2156 $reshook = $hookmanager->executeHooks('pdf_getlineqty_shipped', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2157
2158 if (!empty($hookmanager->resPrint)) {
2159 $result .= $hookmanager->resPrint;
2160 }
2161 }
2162 if (empty($reshook)) {
2163 if ($object->lines[$i]->special_code == 3) {
2164 return '';
2165 }
2166 if (empty($hidedetails) || $hidedetails > 1) {
2167 $result .= $object->lines[$i]->qty_shipped;
2168 }
2169 }
2170 return $result;
2171}
2172
2182function pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails = 0)
2183{
2184 global $hookmanager;
2185
2186 $reshook = 0;
2187 $result = '';
2188 //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) ) )
2189 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
2190 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2191 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2192 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2193 }
2194 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2195 $action = '';
2196 $reshook = $hookmanager->executeHooks('pdf_getlineqty_keeptoship', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2197
2198 if (!empty($hookmanager->resPrint)) {
2199 $result .= $hookmanager->resPrint;
2200 }
2201 }
2202 if (empty($reshook)) {
2203 if ($object->lines[$i]->special_code == 3) {
2204 return '';
2205 }
2206 if (empty($hidedetails) || $hidedetails > 1) {
2207 $result .= ($object->lines[$i]->qty_asked - $object->lines[$i]->qty_shipped);
2208 }
2209 }
2210 return $result;
2211}
2212
2223function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = false)
2224{
2225 global $langs;
2226
2227 $reshook = 0;
2228 $result = '';
2229 //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) ) )
2230 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
2231 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2232 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2233 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2234 }
2235 $parameters = array(
2236 'i' => $i,
2237 'outputlangs' => $outputlangs,
2238 'hidedetails' => $hidedetails,
2239 'special_code' => $special_code
2240 );
2241 $action = '';
2242 $reshook = $hookmanager->executeHooks('pdf_getlineunit', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2243
2244 if (!empty($hookmanager->resPrint)) {
2245 $result .= $hookmanager->resPrint;
2246 }
2247 }
2248 if (empty($reshook)) {
2249 if (empty($hidedetails) || $hidedetails > 1) {
2250 $result .= $langs->transnoentitiesnoconv($object->lines[$i]->getLabelOfUnit('short'));
2251 }
2252 }
2253 return $result;
2254}
2255
2256
2266function pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails = 0)
2267{
2268 global $hookmanager;
2269
2270 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2271
2272 $reshook = 0;
2273 $result = '';
2274 //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) ) )
2275 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
2276 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2277 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2278 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2279 }
2280 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2281 $action = '';
2282 $reshook = $hookmanager->executeHooks('pdf_getlineremisepercent', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2283
2284 if (!empty($hookmanager->resPrint)) {
2285 $result .= $hookmanager->resPrint;
2286 }
2287 }
2288 if (empty($reshook)) {
2289 if ($object->lines[$i]->special_code == 3) {
2290 return '';
2291 }
2292 if (empty($hidedetails) || $hidedetails > 1) {
2293 $result .= dol_print_reduction($object->lines[$i]->remise_percent, $outputlangs);
2294 }
2295 }
2296 return $result;
2297}
2298
2309function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = null)
2310{
2311 if (empty($hookmanager)) {
2312 global $hookmanager;
2313 }
2314 global $conf;
2315
2316 $reshook = 0;
2317 $result = '';
2318 //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) ) )
2319 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
2320 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2321 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2322 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2323 }
2324 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2325 $action = '';
2326 $reshook = $hookmanager->executeHooks('pdf_getlineprogress', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2327
2328 if (!empty($hookmanager->resPrint)) {
2329 return $hookmanager->resPrint;
2330 }
2331 }
2332 if (empty($reshook)) {
2333 if ($object->lines[$i]->special_code == 3) {
2334 return '';
2335 }
2336 if (empty($hidedetails) || $hidedetails > 1) {
2337 if (getDolGlobalString('SITUATION_DISPLAY_DIFF_ON_PDF')) {
2338 $prev_progress = 0;
2339 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2340 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2341 }
2342 $result = round($object->lines[$i]->situation_percent - $prev_progress, 1).'%';
2343 } else {
2344 $result = round($object->lines[$i]->situation_percent, 1).'%';
2345 }
2346 }
2347 }
2348 return $result;
2349}
2350
2360function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0)
2361{
2362 global $conf, $hookmanager;
2363
2364 $sign = 1;
2365 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2366 $sign = -1;
2367 }
2368
2369 $reshook = 0;
2370 $result = '';
2371 //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) ) )
2372 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
2373 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2374 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2375 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2376 }
2377 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code, 'sign'=>$sign);
2378 $action = '';
2379 $reshook = $hookmanager->executeHooks('pdf_getlinetotalexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2380
2381 if (!empty($hookmanager->resPrint)) {
2382 $result .= $hookmanager->resPrint;
2383 }
2384 }
2385 if (empty($reshook)) {
2386 if (!empty($object->lines[$i]) && $object->lines[$i]->special_code == 3) {
2387 $result .= $outputlangs->transnoentities("Option");
2388 } elseif (empty($hidedetails) || $hidedetails > 1) {
2389 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht);
2390 if (!empty($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2391 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2392 $prev_progress = 0;
2393 $progress = 1;
2394 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2395 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2396 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2397 }
2398 $result .= price($sign * ($total_ht / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2399 } else {
2400 $result .= price($sign * $total_ht, 0, $outputlangs);
2401 }
2402 }
2403 }
2404 return $result;
2405}
2406
2416function pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails = 0)
2417{
2418 global $hookmanager, $conf;
2419
2420 $sign = 1;
2421 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2422 $sign = -1;
2423 }
2424
2425 $reshook = 0;
2426 $result = '';
2427 //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) ) )
2428 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
2429 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2430 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2431 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2432 }
2433 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2434 $action = '';
2435 $reshook = $hookmanager->executeHooks('pdf_getlinetotalwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2436
2437 if (!empty($hookmanager->resPrint)) {
2438 $result .= $hookmanager->resPrint;
2439 }
2440 }
2441 if (empty($reshook)) {
2442 if ($object->lines[$i]->special_code == 3) {
2443 $result .= $outputlangs->transnoentities("Option");
2444 } elseif (empty($hidedetails) || $hidedetails > 1) {
2445 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ttc : $object->lines[$i]->total_ttc);
2446 if (isset($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2447 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2448 $prev_progress = 0;
2449 $progress = 1;
2450 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2451 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2452 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2453 }
2454 $result .= price($sign * ($total_ttc / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2455 } else {
2456 $result .= price($sign * $total_ttc, 0, $outputlangs);
2457 }
2458 }
2459 }
2460 return $result;
2461}
2462
2471function pdf_getLinkedObjects(&$object, $outputlangs)
2472{
2473 global $db, $hookmanager;
2474
2475 $linkedobjects = array();
2476
2477 $object->fetchObjectLinked();
2478
2479 foreach ($object->linkedObjects as $objecttype => $objects) {
2480 if ($objecttype == 'facture') {
2481 // 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.
2482 } elseif ($objecttype == 'propal' || $objecttype == 'supplier_proposal') {
2483 $outputlangs->load('propal');
2484
2485 foreach ($objects as $elementobject) {
2486 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefProposal");
2487 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2488 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DatePropal");
2489 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2490 }
2491 } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order') {
2492 $outputlangs->load('orders');
2493
2494 if (count($objects) > 1 && count($objects) <= (getDolGlobalInt("MAXREFONDOC") ? getDolGlobalInt("MAXREFONDOC") : 10)) {
2495 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' :');
2496 foreach ($objects as $elementobject) {
2497 $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.')').' ');
2498 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("OrderDate").' : '.dol_print_date($elementobject->date, 'day', '', $outputlangs));
2499 }
2500 } elseif (count($objects) == 1) {
2501 $elementobject = array_shift($objects);
2502 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder");
2503 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref).(!empty($elementobject->ref_client) ? ' ('.$elementobject->ref_client.')' : '').(!empty($elementobject->ref_supplier) ? ' ('.$elementobject->ref_supplier.')' : '');
2504 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate");
2505 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2506 }
2507 } elseif ($objecttype == 'contrat') {
2508 $outputlangs->load('contracts');
2509 foreach ($objects as $elementobject) {
2510 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefContract");
2511 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2512 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateContract");
2513 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat, 'day', '', $outputlangs);
2514 }
2515 } elseif ($objecttype == 'fichinter') {
2516 $outputlangs->load('interventions');
2517 foreach ($objects as $elementobject) {
2518 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("InterRef");
2519 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2520 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("InterDate");
2521 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->datec, 'day', '', $outputlangs);
2522 }
2523 } elseif ($objecttype == 'shipping') {
2524 $outputlangs->loadLangs(array("orders", "sendings"));
2525
2526 if (count($objects) > 1) {
2527 $order = null;
2528 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') {
2529 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :');
2530 } else {
2531 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefSending").' :');
2532 }
2533 // We concat this record info into fields xxx_value. title is overwrote.
2534 foreach ($objects as $elementobject) {
2535 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
2536 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2537 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2538 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2539 $order = new Commande($db);
2540 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2541 if ($ret < 1) {
2542 $order = null;
2543 }
2544 }
2545 }
2546
2547 if (! is_object($order)) {
2548 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref));
2549 } else {
2550 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : ''));
2551 $object->note_public = dol_concatdesc($object->note_public, ' / '.$outputlangs->transnoentities($elementobject->ref));
2552 }
2553 }
2554 } elseif (count($objects) == 1) {
2555 $elementobject = array_shift($objects);
2556 $order = null;
2557 // We concat this record info into fields xxx_value. title is overwrote.
2558 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
2559 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2560 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2561 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2562 $order = new Commande($db);
2563 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2564 if ($ret < 1) {
2565 $order = null;
2566 }
2567 }
2568 }
2569
2570 if (! is_object($order)) {
2571 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
2572 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2573 $linkedobjects[$objecttype]['ref_value'] = '';
2574 } else {
2575 $linkedobjects[$objecttype]['ref_value'] .= ' / ';
2576 }
2577 $linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref);
2578 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2579 } else {
2580 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending");
2581 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2582 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
2583 }
2584 $linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref);
2585 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2586 }
2587 }
2588 }
2589 }
2590
2591 // For add external linked objects
2592 if (is_object($hookmanager)) {
2593 $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs'=>$outputlangs);
2594 $action = '';
2595 $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2596 if (!empty($hookmanager->resArray)) {
2597 $linkedobjects = $hookmanager->resArray;
2598 }
2599 }
2600
2601 return $linkedobjects;
2602}
2603
2611function pdf_getSizeForImage($realpath)
2612{
2613 global $conf;
2614
2615 $maxwidth = (!getDolGlobalString('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH') ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH);
2616 $maxheight = (!getDolGlobalString('MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT') ? 32 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT);
2617 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2618 $tmp = dol_getImageSize($realpath);
2619 $width = 0;
2620 $height = 0;
2621 if ($tmp['height']) {
2622 $width = (int) round($maxheight * $tmp['width'] / $tmp['height']); // I try to use maxheight
2623 if ($width > $maxwidth) { // Pb with maxheight, so i use maxwidth
2624 $width = $maxwidth;
2625 $height = (int) round($maxwidth * $tmp['height'] / $tmp['width']);
2626 } else { // No pb with maxheight
2627 $height = $maxheight;
2628 }
2629 }
2630 return array('width'=>$width, 'height'=>$height);
2631}
2632
2642function pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails = 0)
2643{
2644 global $conf, $hookmanager;
2645
2646 $sign = 1;
2647 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2648 $sign = -1;
2649 }
2650 if ($object->lines[$i]->special_code == 3) {
2651 return $outputlangs->transnoentities("Option");
2652 } else {
2653 if (is_object($hookmanager)) {
2654 $special_code = $object->lines[$i]->special_code;
2655 if (!empty($object->lines[$i]->fk_parent_line)) {
2656 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2657 }
2658
2659 $parameters = array(
2660 'i'=>$i,
2661 'outputlangs'=>$outputlangs,
2662 'hidedetails'=>$hidedetails,
2663 'special_code'=>$special_code
2664 );
2665
2666 $action = '';
2667
2668 if ($hookmanager->executeHooks('getlinetotalremise', $parameters, $object, $action) > 0) { // Note that $action and $object may have been modified by some hooks
2669 if (isset($hookmanager->resArray['linetotalremise'])) {
2670 return $hookmanager->resArray['linetotalremise'];
2671 } else {
2672 return (float) $hookmanager->resPrint; // For backward compatibility
2673 }
2674 }
2675 }
2676
2677 if (empty($hidedetails) || $hidedetails > 1) {
2678 return $sign * (($object->lines[$i]->subprice * $object->lines[$i]->qty) - $object->lines[$i]->total_ht);
2679 }
2680 }
2681 return 0;
2682}
Class to manage categories.
Class to manage customers orders.
Class to manage contact/addresses.
Class to manage absolute discounts.
Class to manage warehouses.
static getIBANLabel(Account $account)
Returns the name of the Iban label.
File of class to manage predefined price products or services by customer.
Class to manage predefined suppliers products.
Class to manage products or services.
Manage record for batch number management.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
getState($id, $withcode='', $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 a Dolibarr global constant int value.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
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:2611
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2360
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:1476
pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails=0)
Return line total amount discount.
Definition pdf.lib.php:2642
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:2142
pdf_getlinenum($object, $i, $outputlangs, $hidedetails=0)
Return line num.
Definition pdf.lib.php:1818
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:2020
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:1422
pdf_getLinkedObjects(&$object, $outputlangs)
Return linked objects to use for document generation.
Definition pdf.lib.php:2471
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:1883
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition pdf.lib.php:2416
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:1014
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:1977
pdf_getlineprogress($object, $i, $outputlangs, $hidedetails=0, $hookmanager=null)
Return line percent.
Definition pdf.lib.php:2309
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:1915
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0, $hookmanager=false)
Return line unit.
Definition pdf.lib.php:2223
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:1386
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank informations for PDF generation.
Definition pdf.lib.php:837
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:2182
pdf_getlineref($object, $i, $outputlangs, $hidedetails=0)
Return line product ref.
Definition pdf.lib.php:1851
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:2266
pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails=0)
Return line quantity asked.
Definition pdf.lib.php:2102
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2062
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:762
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:782