dolibarr 19.0.3
pdf_standard.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@stocks.sourceforge.net>
3 * Copyright (C) 2022 Ferran Marcet <fmarcet@2byte.es>
4 * Copyright (C) 2022 Nicolas Silobre <nsilobre@ns-info90.fr>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 * or see https://www.gnu.org/
19 */
20
27require_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_stock.php';
28require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
29require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
31require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
34
35
39class pdf_standard extends ModelePDFStock
40{
41 public $wref;
42 public $posxdesc;
43 public $posxlabel;
44 public $posxtva;
45 public $posxqty;
46 public $posxup;
47 public $posxunit;
48 public $posxdiscount;
49 public $postotalht;
50
51 public $tabTitleHeight;
52
53
59 public function __construct($db)
60 {
61 global $conf, $langs, $mysoc;
62
63 // Load traductions files required by page
64 $langs->loadLangs(array("main", "companies"));
65
66 $this->db = $db;
67 $this->name = "standard";
68 $this->description = $langs->trans("DocumentModelStandardPDF");
69
70 // Page size for A4 format
71 $this->type = 'pdf';
72 $formatarray = pdf_getFormat();
73 $this->page_largeur = $formatarray['width'];
74 $this->page_hauteur = $formatarray['height'];
75 $this->format = array($this->page_largeur, $this->page_hauteur);
76 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
77 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
78 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
79 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
80
81 $this->option_logo = 1; // Display logo
82 $this->option_multilang = 1; // Available in several languages
83 $this->option_freetext = 0; // Support add of a personalised text
84
85 // Get source company
86 $this->emetteur = $mysoc;
87 if (!$this->emetteur->country_code) {
88 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default if not defined
89 }
90
91 // Define position of columns
92 $this->wref = 35;
93 $this->posxdesc = $this->marge_gauche + 1;
94 $this->posxlabel = $this->posxdesc + $this->wref;
95 $this->posxtva = 80;
96 $this->posxqty = 95;
97 $this->posxup = 115;
98 $this->posxunit = 135;
99 $this->posxdiscount = 155;
100 $this->postotalht = 175;
101
102 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') || getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
103 $this->posxtva = $this->posxup;
104 }
105 $this->posxpicture = $this->posxtva - (!getDolGlobalString('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH') ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images
106 if ($this->page_largeur < 210) { // To work with US executive format
107 $this->posxpicture -= 20;
108 $this->posxtva -= 20;
109 $this->posxup -= 20;
110 $this->posxqty -= 20;
111 $this->posxunit -= 20;
112 $this->posxdiscount -= 20;
113 $this->postotalht -= 20;
114 }
115
116 $this->tabTitleHeight = 11;
117 }
118
119
120 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
132 public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
133 {
134 // phpcs:enable
135 global $user, $langs, $conf, $mysoc, $db, $hookmanager;
136
137 if (!is_object($outputlangs)) {
138 $outputlangs = $langs;
139 }
140 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
141 if (getDolGlobalString('MAIN_USE_FPDF')) {
142 $outputlangs->charset_output = 'ISO-8859-1';
143 }
144
145 // Load traductions files required by page
146 $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "stocks", "orders", "deliveries"));
147
148 if ($conf->stock->dir_output) {
149 // Definition of $dir and $file
150 if ($object->specimen) {
151 $dir = $conf->stock->dir_output;
152 $file = $dir."/SPECIMEN.pdf";
153 } else {
154 $objectref = dol_sanitizeFileName($object->ref);
155 $dir = $conf->stock->dir_output."/".$objectref;
156 $file = $dir."/".$objectref.".pdf";
157 }
158
159 $stockFournisseur = new ProductFournisseur($this->db);
160 $supplierprices = $stockFournisseur->list_product_fournisseur_price($object->id);
161 $object->supplierprices = $supplierprices;
162
163 $productstatic = new Product($this->db);
164
165 if (!file_exists($dir)) {
166 if (dol_mkdir($dir) < 0) {
167 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
168 return -1;
169 }
170 }
171
172 if (file_exists($dir)) {
173 // Add pdfgeneration hook
174 if (!is_object($hookmanager)) {
175 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
176 $hookmanager = new HookManager($this->db);
177 }
178 $hookmanager->initHooks(array('pdfgeneration'));
179 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
180 global $action;
181 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
182
183 // Create pdf instance
184 $pdf = pdf_getInstance($this->format);
185 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
186 $pdf->SetAutoPageBreak(1, 0);
187
188 $heightforinfotot = 40; // Height reserved to output the info and total part
189 $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page
190 $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
191 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
192 $heightforfooter += 6;
193 }
194
195 if (class_exists('TCPDF')) {
196 $pdf->setPrintHeader(false);
197 $pdf->setPrintFooter(false);
198 }
199 $pdf->SetFont(pdf_getPDFFont($outputlangs));
200 // Set path to the background PDF File
201 if (!getDolGlobalString('MAIN_DISABLE_FPDI') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
202 $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
203 $tplidx = $pdf->importPage(1);
204 }
205
206 $pdf->Open();
207 $pagenb = 0;
208 $pdf->SetDrawColor(128, 128, 128);
209
210 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
211 $pdf->SetSubject($outputlangs->transnoentities("Stock"));
212 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
213 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
214 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Stock")." ".$outputlangs->convToOutputCharset($object->label));
215 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
216 $pdf->SetCompression(false);
217 }
218
219 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
220
221
222 // New page
223 $pdf->AddPage();
224 if (!empty($tplidx)) {
225 $pdf->useTemplate($tplidx);
226 }
227 $pagenb++;
228 $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
229 $pdf->SetFont('', '', $default_font_size - 1);
230 $pdf->MultiCell(0, 3, ''); // Set interline to 3
231 $pdf->SetTextColor(0, 0, 0);
232
233 $tab_top = 65 + $top_shift;
234 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
235
236 $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
237
238
239 // Show list of product in warehouse */
240
241 $totalunit = 0;
242 $totalvalue = $totalvaluesell = 0;
243
244 $sortfield = 'p.ref';
245 $sortorder = 'ASC';
246
247 $sql = "SELECT p.rowid as rowid, p.ref, p.label as produit, p.tobatch, p.fk_product_type as type, p.pmp as ppmp, p.price, p.price_ttc, p.entity,";
248 $sql .= " ps.reel as value";
249 $sql .= " FROM ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product as p";
250 $sql .= " WHERE ps.fk_product = p.rowid";
251 $sql .= " AND ps.reel <> 0"; // We do not show if stock is 0 (no product in this warehouse)
252 $sql .= " AND ps.fk_entrepot = ".((int) $object->id);
253 $sql .= $this->db->order($sortfield, $sortorder);
254
255 //dol_syslog('List products', LOG_DEBUG);
256 $resql = $this->db->query($sql);
257 if ($resql) {
258 $num = $this->db->num_rows($resql);
259 $i = 0;
260 $nblines = $num;
261
262 $nexY = $tab_top + $this->tabTitleHeight;
263
264 for ($i = 0; $i < $nblines; $i++) {
265 $curY = $nexY;
266
267 $objp = $this->db->fetch_object($resql);
268
269 // Multilangs
270 if (getDolGlobalInt('MAIN_MULTILANGS')) { // si l'option est active
271 $sql = "SELECT label";
272 $sql .= " FROM ".MAIN_DB_PREFIX."product_lang";
273 $sql .= " WHERE fk_product = ".((int) $objp->rowid);
274 $sql .= " AND lang = '".$this->db->escape($langs->getDefaultLang())."'";
275 $sql .= " LIMIT 1";
276
277 $result = $this->db->query($sql);
278 if ($result) {
279 $objtp = $this->db->fetch_object($result);
280 if ($objtp->label != '') {
281 $objp->produit = $objtp->label;
282 }
283 }
284 }
285
286 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
287 $pdf->SetTextColor(0, 0, 0);
288
289 $pdf->setTopMargin($tab_top_newpage);
290 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
291 $pageposbefore = $pdf->getPage();
292
293 // Description of product line
294 $curX = $this->posxdesc - 1;
295
296 $showpricebeforepagebreak = 1;
297
298 $pdf->startTransaction();
299 $pdf->writeHTMLCell($this->wref, 3, $curX, $curY, $outputlangs->convToOutputCharset($objp->ref), 0, 1, false, true, 'J', true);
300 //pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxtva - $curX, 3, $curX, $curY, $hideref, $hidedesc);
301 $pageposafter = $pdf->getPage();
302 if ($pageposafter > $pageposbefore) { // There is a pagebreak
303 $pdf->rollbackTransaction(true);
304 $pageposafter = $pageposbefore;
305 //print $pageposafter.'-'.$pageposbefore;exit;
306 $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
307 $pdf->writeHTMLCell($this->wref, 4, $curX, $curY, $outputlangs->convToOutputCharset($objp->ref), 0, 1, false, true, 'J', true);
308 //pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxtva - $curX, 4, $curX, $curY, $hideref, $hidedesc);
309 $pageposafter = $pdf->getPage();
310 $posyafter = $pdf->GetY();
311 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
312 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
313 $pdf->AddPage('', '', true);
314 if (!empty($tplidx)) {
315 $pdf->useTemplate($tplidx);
316 }
317 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
318 $this->_pagehead($pdf, $object, 0, $outputlangs);
319 }
320 $pdf->setPage($pageposafter + 1);
321 }
322 } else {
323 // We found a page break
324
325 // Allows data in the first page if description is long enough to break in multiples pages
326 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
327 $showpricebeforepagebreak = 1;
328 } else {
329 $showpricebeforepagebreak = 0;
330 }
331 }
332 } else { // No pagebreak
333 $pdf->commitTransaction();
334 }
335 $posYAfterDescription = $pdf->GetY();
336
337 $nexY = $pdf->GetY();
338 $pageposafter = $pdf->getPage();
339
340 $pdf->setPage($pageposbefore);
341 $pdf->setTopMargin($this->marge_haute);
342 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
343
344 // We suppose that a too long description is moved completely on next page
345 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
346 $pdf->setPage($pageposafter);
347 $curY = $tab_top_newpage;
348 }
349
350 $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut
351
352 $productstatic->id = $objp->rowid;
353 $productstatic->ref = $objp->ref;
354 $productstatic->label = $objp->produit;
355 $productstatic->type = $objp->type;
356 $productstatic->entity = $objp->entity;
357 $productstatic->status_batch = $objp->tobatch;
358
359 // Ref.
360 //$pdf->SetXY($this->posxdesc, $curY);
361 //$pdf->MultiCell($this->wref, 3, $productstatic->ref, 0, 'L');
362
363 // Label
364 $pdf->SetXY($this->posxlabel + 0.8, $curY);
365 $pdf->MultiCell($this->posxqty - $this->posxlabel - 0.8, 3, dol_trunc($productstatic->label, 24), 0, 'L');
366
367 // Quantity
368 $valtoshow = price2num($objp->value, 'MS');
369 $towrite = (empty($valtoshow) ? '0' : $valtoshow);
370
371 $pdf->SetXY($this->posxqty, $curY);
372 $pdf->MultiCell($this->posxup - $this->posxqty - 0.8, 3, $towrite, 0, 'R');
373
374 // AWP
375 $totalunit += $objp->value;
376
377 $pdf->SetXY($this->posxup, $curY);
378 $pdf->MultiCell($this->posxunit - $this->posxup - 0.8, 3, price(price2num($objp->ppmp, 'MU'), 0, $outputlangs), 0, 'R');
379
380 // Total PMP
381 $pdf->SetXY($this->posxunit, $curY);
382 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 0.8, 3, price(price2num($objp->ppmp * $objp->value, 'MT'), 0, $outputlangs), 0, 'R');
383 $totalvalue += price2num($objp->ppmp * $objp->value, 'MT');
384
385 // Price sell min
386 if (!getDolGlobalString('PRODUIT_MULTIPRICES')) {
387 $pricemin = $objp->price;
388 $pdf->SetXY($this->posxdiscount, $curY);
389 $pdf->MultiCell($this->postotalht - $this->posxdiscount, 3, price(price2num($pricemin, 'MU'), 0, $outputlangs), 0, 'R', 0);
390
391 // Total sell min
392 $pdf->SetXY($this->postotalht, $curY);
393 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, price(price2num($pricemin * $objp->value, 'MT'), 0, $outputlangs), 0, 'R', 0);
394 }
395 $totalvaluesell += price2num($pricemin * $objp->value, 'MT');
396
397 // Add line
398 if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) {
399 $pdf->setPage($pageposafter);
400 $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
401 //$pdf->SetDrawColor(190,190,200);
402 $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
403 $pdf->SetLineStyle(array('dash'=>0));
404 }
405
406 $nexY += 2; // Add space between lines
407
408 // Detect if some page were added automatically and output _tableau for past pages
409 while ($pagenb < $pageposafter) {
410 $pdf->setPage($pagenb);
411 if ($pagenb == 1) {
412 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
413 } else {
414 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
415 }
416 $this->_pagefoot($pdf, $object, $outputlangs, 1);
417 $pagenb++;
418 $pdf->setPage($pagenb);
419 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
420 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
421 $this->_pagehead($pdf, $object, 0, $outputlangs);
422 }
423 if (!empty($tplidx)) {
424 $pdf->useTemplate($tplidx);
425 }
426 }
427 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
428 if ($pagenb == 1) {
429 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
430 } else {
431 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
432 }
433 $this->_pagefoot($pdf, $object, $outputlangs, 1);
434 // New page
435 $pdf->AddPage();
436 if (!empty($tplidx)) {
437 $pdf->useTemplate($tplidx);
438 }
439 $pagenb++;
440 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
441 $this->_pagehead($pdf, $object, 0, $outputlangs);
442 }
443 }
444 }
445
446 $this->db->free($resql);
447
451 //$nexY = $pdf->GetY();
452 $nexY += 2;
453 $curY = $nexY;
454
455 if ($nblines > 0) {
456 $pdf->SetLineStyle(array('dash'=>'0', 'color'=>array(200, 200, 200)));
457 $pdf->line($this->marge_gauche, $curY - 1, $this->page_largeur - $this->marge_droite, $curY - 1);
458 $pdf->SetLineStyle(array('dash'=>0));
459
460 $pdf->SetFont('', 'B', $default_font_size - 1);
461 $pdf->SetTextColor(0, 0, 0);
462
463 // Ref.
464 $pdf->SetXY($this->posxdesc, $curY);
465 $pdf->MultiCell($this->wref, 3, $langs->trans("Total"), 0, 'L');
466
467 // Quantity
468 $valtoshow = price2num($totalunit, 'MS');
469 $towrite = empty($valtoshow) ? '0' : $valtoshow;
470
471 $pdf->SetXY($this->posxqty, $curY);
472 $pdf->MultiCell($this->posxup - $this->posxqty - 0.8, 3, $towrite, 0, 'R');
473
474 // Total PMP
475 $pdf->SetXY($this->posxunit, $curY);
476 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 0.8, 3, price(price2num($totalvalue, 'MT'), 0, $outputlangs), 0, 'R');
477
478 // Price sell min
479 if (!getDolGlobalString('PRODUIT_MULTIPRICES')) {
480 // Total sell min
481 $pdf->SetXY($this->postotalht, $curY);
482 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, price(price2num($totalvaluesell, 'MT'), 0, $outputlangs), 0, 'R', 0);
483 }
484 }
485 } else {
486 dol_print_error($this->db);
487 }
488
489 // Displays notes
490 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
491
492 if ($notetoshow) {
493 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
494 complete_substitutions_array($substitutionarray, $outputlangs, $object);
495 $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
496 $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
497
498 $tab_top = 88;
499
500 $pdf->SetFont('', '', $default_font_size - 1);
501 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
502 $nexY = $pdf->GetY();
503 $height_note = $nexY - $tab_top;
504
505 // Rect takes a length in 3rd parameter
506 $pdf->SetDrawColor(192, 192, 192);
507 $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 1);
508
509 $tab_height = $tab_height - $height_note;
510 $tab_top = $nexY + 6;
511 } else {
512 $height_note = 0;
513 }
514
515 /*$iniY = $tab_top + 7;
516 $curY = $tab_top + 7;
517 $nexY = $tab_top + 7;
518
519 $tab_top = $tab_top_newpage + 25 + $top_shift;*/
520
521 // Show square
522 if ($pagenb == 1) {
523 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
524 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
525 } else {
526 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
527 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
528 }
529
530 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
531
532 // Affiche zone infos
533 //$posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
534
535 // Affiche zone totaux
536 //$posy=$this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
537
538 // Pied de page
539 $this->_pagefoot($pdf, $object, $outputlangs);
540 if (method_exists($pdf, 'AliasNbPages')) {
541 $pdf->AliasNbPages();
542 }
543
544 $pdf->Close();
545
546 $pdf->Output($file, 'F');
547
548 // Add pdfgeneration hook
549 $hookmanager->initHooks(array('pdfgeneration'));
550 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
551 global $action;
552 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
553 if ($reshook < 0) {
554 $this->error = $hookmanager->error;
555 $this->errors = $hookmanager->errors;
556 }
557
558 dolChmod($file);
559
560 $this->result = array('fullpath'=>$file);
561
562 return 1; // No error
563 } else {
564 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
565 return 0;
566 }
567 } else {
568 $this->error = $langs->trans("ErrorConstantNotDefined", "PRODUCT_OUTPUTDIR");
569 return 0;
570 }
571 }
572
573 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
587 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
588 {
589 global $conf;
590
591 // Force to disable hidetop and hidebottom
592 $hidebottom = 0;
593 if ($hidetop) {
594 $hidetop = -1;
595 }
596
597 $currency = !empty($currency) ? $currency : $conf->currency;
598 $default_font_size = pdf_getPDFFontSize($outputlangs);
599
600 // Amount in (at tab_top - 1)
601 $pdf->SetTextColor(0, 0, 0);
602 $pdf->SetFont('', '', $default_font_size - 2);
603
604 if (empty($hidetop)) {
605 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
606 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
607 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
608
609 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
610 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
611 $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')));
612 }
613 }
614
615 $pdf->SetDrawColor(128, 128, 128);
616
617 $pdf->SetFont('', 'B', $default_font_size - 3);
618
619 // Output Rect
620 $this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect takes a length in 3rd parameter and 4th parameter
621
622 $pdf->SetLineStyle(array('dash'=>'0', 'color'=>array(200, 200, 200)));
623 $pdf->SetDrawColor(200, 200, 200);
624 $pdf->line($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite, $tab_top);
625 $pdf->SetLineStyle(array('dash'=>0));
626 $pdf->SetDrawColor(128, 128, 128);
627 $pdf->SetTextColor(0, 0, 0);
628
629
630 if (empty($hidetop)) {
631 $pdf->line($this->marge_gauche, $tab_top+11, $this->page_largeur-$this->marge_droite, $tab_top+11); // line takes a position y in 2nd parameter and 4th parameter
632 $pdf->SetXY($this->posxdesc - 1, $tab_top + 1);
633 $pdf->MultiCell($this->wref, 3, $outputlangs->transnoentities("Ref"), '', 'L');
634 }
635
636 $pdf->line($this->posxlabel-1, $tab_top, $this->posxlabel-1, $tab_top + $tab_height);
637 if (empty($hidetop)) {
638 $pdf->SetXY($this->posxlabel - 1, $tab_top + 1);
639 $pdf->MultiCell($this->posxqty - $this->posxlabel - 1, 2, $outputlangs->transnoentities("Label"), '', 'C');
640 }
641
642 $pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height);
643 if (empty($hidetop)) {
644 $pdf->SetXY($this->posxqty - 1, $tab_top + 1);
645 $pdf->MultiCell($this->posxup - $this->posxqty - 1, 2, $outputlangs->transnoentities("Units"), '', 'C');
646 }
647
648 $pdf->line($this->posxup-1, $tab_top, $this->posxup-1, $tab_top + $tab_height);
649 if (empty($hidetop)) {
650 $pdf->SetXY($this->posxup - 1, $tab_top + 1);
651 $pdf->MultiCell($this->posxunit - $this->posxup - 1, 2, $outputlangs->transnoentities("AverageUnitPricePMPShort"), '', 'C');
652 }
653
654 $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height);
655 if (empty($hidetop)) {
656 $pdf->SetXY($this->posxunit - 1, $tab_top + 1);
657 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("EstimatedStockValueShort"), '', 'C');
658 }
659
660 $pdf->line($this->posxdiscount-1, $tab_top, $this->posxdiscount-1, $tab_top + $tab_height);
661 if (empty($hidetop)) {
662 $pdf->SetXY($this->posxdiscount - 1, $tab_top + 1);
663 $pdf->MultiCell($this->postotalht - $this->posxdiscount + 1, 2, $outputlangs->transnoentities("SellPriceMin"), '', 'C');
664 }
665
666 $pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
667 if (empty($hidetop)) {
668 $pdf->SetXY($this->postotalht - 1, $tab_top + 1);
669 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 2, $outputlangs->transnoentities("EstimatedStockValueSellShort"), '', 'C');
670 }
671
672 if (empty($hidetop)) {
673 $pdf->SetDrawColor(200, 200, 200);
674 $pdf->SetLineStyle(array('dash' => '0', 'color' => array(200, 200, 200)));
675 $pdf->line($this->marge_gauche, $tab_top + $this->tabTitleHeight, $this->page_largeur - $this->marge_droite, $tab_top + $this->tabTitleHeight);
676 $pdf->SetLineStyle(array('dash' => 0));
677 }
678 }
679
680 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
691 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey = "")
692 {
693 global $conf, $langs, $db, $hookmanager;
694
695 // Load traductions files required by page
696 $outputlangs->loadLangs(array("main", "propal", "companies", "bills", "orders", "stocks"));
697
698 $default_font_size = pdf_getPDFFontSize($outputlangs);
699
700 if ($object->type == 1) {
701 $titlekey = 'ServiceSheet';
702 } else {
703 $titlekey = 'StockSheet';
704 }
705
706 pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
707
708 // Show Draft Watermark
709 if ($object->statut == 0 && (getDolGlobalString('STOCK_DRAFT_WATERMARK'))) {
710 pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->STOCK_DRAFT_WATERMARK);
711 }
712
713 $pdf->SetTextColor(0, 0, 60);
714 $pdf->SetFont('', 'B', $default_font_size + 3);
715
716 $posy = $this->marge_haute;
717 $posx = $this->page_largeur - $this->marge_droite - 100;
718
719 $pdf->SetXY($this->marge_gauche, $posy);
720
721 // Logo
722 $height = 0;
723 $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
724 if ($this->emetteur->logo) {
725 if (is_readable($logo)) {
726 $height = pdf_getHeightForLogo($logo);
727 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
728 } else {
729 $pdf->SetTextColor(200, 0, 0);
730 $pdf->SetFont('', 'B', $default_font_size - 2);
731 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
732 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
733 }
734 } else {
735 $text = $this->emetteur->name;
736 $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
737 }
738
739 $yafterleft = $pdf->GetY() + $height;
740
741 $pdf->SetFont('', 'B', $default_font_size + 3);
742 $pdf->SetXY($posx, $posy);
743 $pdf->SetTextColor(0, 0, 60);
744
745 $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Warehouse").' '.$outputlangs->convToOutputCharset($object->label), '', 'R');
746
747 $posy += 6;
748 $pdf->SetFont('', '', $default_font_size - 1);
749 $pdf->SetXY($posx, $posy);
750 $pdf->SetTextColor(0, 0, 60);
751 if (!empty($object->lieu)) {
752 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Label").' : '.$object->lieu, '', 'R');
753 }
754
755
756 $posy += 4;
757 $pdf->SetXY($posx, $posy);
758 $pdf->SetTextColor(0, 0, 60);
759
760 // Parent warehouse
761 $e = new Entrepot($this->db);
762 $hasparent = (!empty($object->fk_parent) && $e->fetch($object->fk_parent) > 0);
763
764 if ($hasparent) {
765 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ParentWarehouse").' :', '', 'R');
766
767 $posy += 4;
768 $pdf->SetXY($posx - 50, $posy);
769 $pdf->MultiCell(150, 3, $e->label, '', 'R');
770 }
771
772 $yafterright = $pdf->GetY();
773
774 // Description
775 $nbpage = $pdf->getPage();
776 if ($nbpage == 1) {
777 $nexY = max($yafterleft, $yafterright);
778 $nexY += 5;
779 $pdf->SetXY($posx, $posy);
780 $pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("Description").' : </b>'.nl2br($object->description), 0, 1);
781 $nexY = $pdf->GetY();
782
783 $calcproductsunique = $object->nb_different_products();
784 $calcproducts = $object->nb_products();
785
786 // Total nb of different products
787 $pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("NumberOfDifferentProducts").' : </b>'.(empty($calcproductsunique['nb']) ? '0' : $calcproductsunique['nb']), 0, 1);
788 $nexY = $pdf->GetY();
789
790 // Nb of products
791 $valtoshow = price2num($calcproducts['nb'], 'MS');
792 $pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("NumberOfProducts").' : </b>'.(empty($valtoshow) ? '0' : $valtoshow), 0, 1);
793 $nexY = $pdf->GetY();
794
795 // Value
796 $pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("EstimatedStockValueShort").' : </b>'.price((empty($calcproducts['value']) ? '0' : price2num($calcproducts['value'], 'MT')), 0, $langs, 0, -1, -1, $conf->currency), 0, 1);
797 $nexY = $pdf->GetY();
798
799 // Value
800 $pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("Date").' : </b>'.dol_print_date(dol_now(), 'dayhour'), 0, 1);
801 $nexY = $pdf->GetY();
802
803 // Last movement
804 $sql = "SELECT max(m.datem) as datem";
805 $sql .= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m";
806 $sql .= " WHERE m.fk_entrepot = ".((int) $object->id);
807 $resqlbis = $this->db->query($sql);
808 if ($resqlbis) {
809 $obj = $this->db->fetch_object($resqlbis);
810 $lastmovementdate = $this->db->jdate($obj->datem);
811 } else {
812 dol_print_error($this->db);
813 }
814
815 if ($lastmovementdate) {
816 $toWrite = dol_print_date($lastmovementdate, 'dayhour').' ';
817 } else {
818 $toWrite = $outputlangs->transnoentities("None");
819 }
820
821 $pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("LastMovement").' : </b>'.$toWrite, 0, 1);
822 }
823 $nexY = $pdf->GetY();
824
825 $posy += 2;
826
827 $top_shift = 0;
828 // Show list of linked objects
829 $current_y = $pdf->getY();
830 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
831 if ($current_y < $pdf->getY()) {
832 $top_shift = $pdf->getY() - $current_y;
833 }
834
835 $pdf->SetTextColor(0, 0, 0);
836
837 return $top_shift;
838 }
839
840 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
850 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
851 {
852 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
853 return pdf_pagefoot($pdf, $outputlangs, 'PRODUCT_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
854 }
855}
printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
Rect pdf.
Class to manage warehouses.
Class to manage hooks.
Parent class for stock models of doc generators.
Class to manage predefined suppliers products.
Class to manage products or services.
Class to generate expense report based on standard model.
__construct($db)
Constructor.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
Show table for lines.
_pagehead(&$pdf, $object, $showaddress, $outputlangs)
Show top header of page.
_pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey="")
Show top header of page.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build a document on disk using the generic odt module.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!function_exists( 'dolEscapeXML')) convertBackOfficeMediasLinksToPublicLinks($notetoshow)
Convert links to local wrapper to medias files into a string into a public external URL readable on i...
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...
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).
dolChmod($filepath, $newmask='')
Change mod of a file.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
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...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
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_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:314
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_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_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:266
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
pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition pdf.lib.php:782
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:121
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:124