dolibarr 24.0.0-beta
pdf_standard_movementstock.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@stocks.sourceforge.net>
3 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
4 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024 Nick Fragoulis
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * or see https://www.gnu.org/
20 */
21
28require_once DOL_DOCUMENT_ROOT.'/core/modules/movement/modules_movement.php';
29require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
30require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
31require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
36
37
42{
46 public $update_main_doc_field;
47
51 public $wref;
55 public $posxidref;
59 public $posxdatemouv;
63 public $posxdesc;
67 public $posxlabel;
71 public $posxtva;
75 public $posxqty;
79 public $posxup;
83 public $posxunit;
87 public $posxdiscount;
91 public $postotalht;
92
93
99 public function __construct($db)
100 {
101 global $conf, $langs, $mysoc;
102
103 // Load traductions files required by page
104 $langs->loadLangs(array("main", "companies", "productbatch"));
105
106 $this->db = $db;
107 $this->name = "stdmouvement";
108 $this->description = $langs->trans("DocumentModelStandardPDF");
109
110 // Dimension page
111 $this->type = 'pdf';
112 $formatarray = pdf_getFormat();
113 $this->page_largeur = $formatarray['width'];
114 $this->page_hauteur = $formatarray['height'];
115 $this->format = array($this->page_largeur, $this->page_hauteur);
116 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
117 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
118 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
119 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
120 $this->corner_radius = getDolGlobalInt('MAIN_PDF_FRAME_CORNER_RADIUS', 0);
121 $this->option_logo = 1; // Display logo
122 $this->option_multilang = 1; // Available in several languages
123 $this->option_freetext = 0; // Support add of a personalised text
124
125 // Define position of columns
126 $this->wref = 15;
127 $this->posxidref = $this->marge_gauche;
128 $this->posxdatemouv = $this->marge_gauche + 8;
129 $this->posxdesc = 37;
130 $this->posxlabel = 50;
131 $this->posxtva = 80;
132 $this->posxqty = 105;
133 $this->posxup = 119;
134 $this->posxunit = 136;
135 $this->posxdiscount = 167;
136 $this->postotalht = 180;
137
138 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') || getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
139 $this->posxtva = $this->posxup;
140 }
141 $this->posxpicture = $this->posxtva - getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH', 20); // width of images
142 if ($this->page_largeur < 210) { // To work with US executive format
143 $this->posxpicture -= 20;
144 $this->posxtva -= 20;
145 $this->posxup -= 20;
146 $this->posxqty -= 20;
147 $this->posxunit -= 20;
148 $this->posxdiscount -= 20;
149 $this->postotalht -= 20;
150 }
151
152 if ($mysoc === null) {
153 dol_syslog(get_class($this).'::__construct() Global $mysoc should not be null.'. getCallerInfoString(), LOG_ERR);
154 return;
155 }
156
157 // Get source company
158 $this->emetteur = $mysoc;
159 if (empty($this->emetteur->country_code)) {
160 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default if not defined
161 }
162 }
163
164
165 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
177 public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
178 {
179 // phpcs:enable
180 global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
181
182 dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null'));
183
184 if (!is_object($outputlangs)) {
185 $outputlangs = $langs;
186 }
187 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
188 if (getDolGlobalString('MAIN_USE_FPDF')) {
189 $outputlangs->charset_output = 'ISO-8859-1';
190 }
191
192 // Load traductions files required by the page
193 $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "stocks", "orders", "sendings"));
194
199 $id = GETPOSTINT('id');
200 $ref = GETPOST('ref', 'alpha');
201 $msid = GETPOSTINT('msid');
202 $product_id = GETPOST("product_id");
203 $action = GETPOST('action', 'aZ09');
204 $cancel = GETPOST('cancel', 'alpha');
205 $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'movementlist';
206
207 $idproduct = GETPOSTINT('idproduct');
208 $year = GETPOSTINT("year");
209 $month = GETPOSTINT("month");
210 $search_ref = GETPOST('search_ref', 'alpha');
211 $search_movement = GETPOST("search_movement");
212 $search_product_ref = trim(GETPOST("search_product_ref"));
213 $search_product = trim(GETPOST("search_product"));
214 $search_warehouse = trim(GETPOST("search_warehouse"));
215 $search_inventorycode = trim(GETPOST("search_inventorycode"));
216 $search_user = trim(GETPOST("search_user"));
217 $search_batch = trim(GETPOST("search_batch"));
218 $search_qty = trim(GETPOST("search_qty"));
219 $search_type_mouvement = GETPOST('search_type_mouvement', "intcomma");
220
221 $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
222 $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
223 $sortfield = GETPOST('sortfield', 'aZ09comma');
224 $sortorder = GETPOST('sortorder', 'aZ09comma');
225 if (empty($page) || $page == -1) {
226 $page = 0;
227 } // If $page is not defined, or '' or -1
228 $offset = $limit * $page;
229 if (!$sortfield) {
230 $sortfield = "m.datem";
231 }
232 if (!$sortorder) {
233 $sortorder = "DESC";
234 }
235
236 $pdluoid = GETPOSTINT('pdluoid');
237
238 // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
239 $hookmanager->initHooks(array('movementlist'));
240 $extrafields = new ExtraFields($this->db);
241
242 // fetch optionals attributes and labels
243 $extrafields->fetch_name_optionals_label('movement');
244 $search_array_options = $extrafields->getOptionalsFromPost('movement', '', 'search_');
245
246 $productlot = new Productlot($this->db);
247 $productstatic = new Product($this->db);
248 $warehousestatic = new Entrepot($this->db);
249 $movement = new MouvementStock($this->db);
250 $userstatic = new User($this->db);
251 $element = 'movement';
252
253 $sql = "SELECT p.rowid, p.ref as product_ref, p.label as produit, p.tobatch, p.fk_product_type as type, p.entity,";
254 $sql .= " e.ref as warehouse_ref, e.rowid as entrepot_id, e.lieu,";
255 $sql .= " m.rowid as mid, m.value as qty, m.datem, m.fk_user_author, m.label, m.inventorycode, m.fk_origin, m.origintype,";
256 $sql .= " m.batch, m.price,";
257 $sql .= " m.type_mouvement,";
258 $sql .= " pl.rowid as lotid, pl.eatby, pl.sellby,";
259 $sql .= " u.login, u.photo, u.lastname, u.firstname";
260 // Add fields from extrafields
261 if (!empty($extrafields->attributes[$element]['label'])) {
262 foreach ($extrafields->attributes[$element]['label'] as $key => $val) {
263 $sql .= ($extrafields->attributes[$element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
264 }
265 }
266 // Add fields from hooks
267 $parameters = array();
268 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
269 $sql .= $hookmanager->resPrint;
270 $sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e,";
271 $sql .= " ".MAIN_DB_PREFIX."product as p,";
272 $sql .= " ".MAIN_DB_PREFIX."stock_mouvement as m";
273 if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
274 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (m.rowid = ef.fk_object)";
275 }
276 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON m.fk_user_author = u.rowid";
277 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_lot as pl ON m.batch = pl.batch AND m.fk_product = pl.fk_product";
278 $sql .= " WHERE m.fk_product = p.rowid";
279 if ($msid > 0) {
280 $sql .= " AND m.rowid = ".((int) $msid);
281 }
282 $sql .= " AND m.fk_entrepot = e.rowid";
283 $sql .= " AND e.entity IN (".getEntity('stock').")";
284 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
285 $sql .= " AND p.fk_product_type = 0";
286 }
287 if ($id > 0) {
288 $sql .= " AND e.rowid = ".((int) $id);
289 }
290 if ($month > 0) {
291 if ($year > 0) {
292 $sql .= " AND m.datem BETWEEN '".$this->db->idate(dol_get_first_day($year, $month, false))."' AND '".$this->db->idate(dol_get_last_day($year, $month, false))."'";
293 } else {
294 $sql .= " AND date_format(m.datem, '%m') = '".((int) $month)."'";
295 }
296 } elseif ($year > 0) {
297 $sql .= " AND m.datem BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'";
298 }
299 if ($idproduct > 0) {
300 $sql .= " AND p.rowid = ".((int) $idproduct);
301 }
302 if (!empty($search_ref)) {
303 $sql .= natural_search('m.rowid', $search_ref, 1);
304 }
305 if (!empty($search_movement)) {
306 $sql .= natural_search('m.label', $search_movement);
307 }
308 if (!empty($search_inventorycode)) {
309 $sql .= natural_search('m.inventorycode', $search_inventorycode);
310 }
311 if (!empty($search_product_ref)) {
312 $sql .= natural_search('p.ref', $search_product_ref);
313 }
314 if (!empty($search_product)) {
315 $sql .= natural_search('p.label', $search_product);
316 }
317 if ($search_warehouse > 0) {
318 $sql .= " AND e.rowid = ".((int) $search_warehouse);
319 }
320 if (!empty($search_user)) {
321 $sql .= natural_search('u.login', $search_user);
322 }
323 if (!empty($search_batch)) {
324 $sql .= natural_search('m.batch', $search_batch);
325 }
326 if ($search_qty != '') {
327 $sql .= natural_search('m.value', $search_qty, 1);
328 }
329 if ($search_type_mouvement > 0) {
330 $sql .= " AND m.type_mouvement = '".$this->db->escape($search_type_mouvement)."'";
331 }
332 // Add where from extra fields
333 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
334 // Add where from hooks
335 $parameters = array();
336 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
337 $sql .= $hookmanager->resPrint;
338 $sql .= $this->db->order($sortfield, $sortorder);
339
340 $nbtotalofrecords = '';
341 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
342 $result = $this->db->query($sql);
343 $nbtotalofrecords = $this->db->num_rows($result);
344 if (($page * $limit) > (int) $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
345 $page = 0;
346 $offset = 0;
347 }
348 }
349
350 if (empty($search_inventorycode)) {
351 $sql .= $this->db->plimit($limit + 1, $offset);
352 }
353
354
355 $resql = $this->db->query($sql);
356 $nbtotalofrecords = $this->db->num_rows($resql);
357
358 /*
359 * END TODO
360 **/
361
362 //$nblines = count($object->lines);
363
364 if ($conf->stock->dir_output) {
365 if ($resql) {
366 $product = new Product($this->db);
367 $object = new Entrepot($this->db);
368
369 if ($idproduct > 0) {
370 $product->fetch($idproduct);
371 }
372 if ($id > 0 || $ref) {
373 $result = $object->fetch($id, $ref);
374 if ($result < 0) {
375 dol_print_error($this->db);
376 }
377 }
378
379 $num = $this->db->num_rows($resql);
380 }
381
382 // Definition of $dir and $file
383 if ($object->specimen) {
384 $dir = $conf->stock->dir_output."/movement";
385 $file = $dir."/SPECIMEN.pdf";
386 } else {
387 $objectref = dol_sanitizeFileName($object->ref);
388 if (!empty($search_inventorycode)) {
389 $objectref .= "_".$id."_".$search_inventorycode;
390 }
391 if ($search_type_mouvement) {
392 $objectref .= "_".$search_type_mouvement;
393 }
394 $dir = $conf->stock->dir_output."/movement/".$objectref;
395 $file = $dir."/".$objectref.".pdf";
396 }
397
398 $productstatic = new Product($this->db);
399
400 if (!file_exists($dir)) {
401 if (dol_mkdir($dir) < 0) {
402 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
403 return -1;
404 }
405 }
406
407 if (file_exists($dir)) {
408 // Add pdfgeneration hook
409 if (!is_object($hookmanager)) {
410 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
411 $hookmanager = new HookManager($this->db);
412 }
413 $hookmanager->initHooks(array('pdfgeneration'));
414 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
415 global $action;
416 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
417
418 // Create pdf instance
419 $pdf = pdf_getInstance($this->format);
420 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
421 $pdf->setAutoPageBreak(true, 0);
422
423 $heightforinfotot = 40; // Height reserved to output the info and total part
424 $heightforfreetext = getDolGlobalInt('MAIN_PDF_FREETEXT_HEIGHT', 5); // Height reserved to output the free text on last page
425 $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
426
427 if (class_exists('TCPDF')) {
428 $pdf->setPrintHeader(false);
429 $pdf->setPrintFooter(false);
430 }
431 $pdf->SetFont(pdf_getPDFFont($outputlangs));
432 // Set path to the background PDF File
433 if (!getDolGlobalString('MAIN_DISABLE_FPDI') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
434 $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
435 $tplidx = $pdf->importPage(1);
436 }
437
438 $pdf->Open();
439 $pagenb = 0;
440 $pdf->SetDrawColor(128, 128, 128);
441
442 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
443 $pdf->SetSubject($outputlangs->transnoentities("Stock"));
444 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
445 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getAnonymisableFullName($outputlangs)));
446 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Stock")." ".$outputlangs->convToOutputCharset($object->label));
447 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
448 $pdf->SetCompression(false);
449 }
450
451 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
452 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
453
454
455 // New page
456 $pdf->AddPage();
457 if (!empty($tplidx)) {
458 $pdf->useTemplate($tplidx);
459 }
460 $pagenb++;
461 $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
462 $pdf->SetFont('', '', $default_font_size - 1);
463 $pdf->MultiCell(0, 3, ''); // Set interline to 3
464 $pdf->SetTextColor(0, 0, 0);
465
466 $tab_top = 42;
467 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 : 10);
468
469 $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
470
471 // Show list of product of the MouvementStock
472
473 $nexY = $tab_top - 1;
474
475 $nexY = $pdf->GetY();
476 $nexY += 10;
477
478 $totalunit = 0;
479 $totalvalue = $totalvaluesell = 0;
480 $arrayofuniqueproduct = array();
481
482 //dol_syslog('List products', LOG_DEBUG);
483 $resql = $this->db->query($sql);
484 if ($resql) {
485 $num = $this->db->num_rows($resql);
486 $nblines = $num;
487 for ($i = 0; $i < $nblines; $i++) {
488 $objp = $this->db->fetch_object($resql);
489
490 // Multilangs
491 if (getDolGlobalInt('MAIN_MULTILANGS')) { // si l'option est active
492 $sql = "SELECT label";
493 $sql .= " FROM ".MAIN_DB_PREFIX."product_lang";
494 $sql .= " WHERE fk_product = ".((int) $objp->rowid);
495 $sql .= " AND lang = '".$this->db->escape($langs->getDefaultLang())."'";
496 $sql .= " LIMIT 1";
497
498 $result = $this->db->query($sql);
499 if ($result) {
500 $objtp = $this->db->fetch_object($result);
501 if ($objtp->label != '') {
502 $objp->produit = $objtp->label;
503 }
504 }
505 }
506
507 $curY = $nexY;
508 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
509 $pdf->SetTextColor(0, 0, 0);
510
511 $pdf->setTopMargin($tab_top_newpage);
512 $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
513 $pageposbefore = $pdf->getPage();
514
515 // Description of product line
516 $curX = $this->posxdesc - 1;
517
518 $showpricebeforepagebreak = 1;
519
520 $pdf->startTransaction();
521 pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxtva - $curX, 3, $curX, $curY, $hideref, $hidedesc);
522 $pageposafter = $pdf->getPage();
523 if ($pageposafter > $pageposbefore) { // There is a pagebreak
524 $pdf->rollbackTransaction(true);
525 $pageposafter = $pageposbefore;
526 //print $pageposafter.'-'.$pageposbefore;exit;
527 $pdf->setPageOrientation('', true, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
528 pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxtva - $curX, 4, $curX, $curY, $hideref, $hidedesc);
529 $pageposafter = $pdf->getPage();
530 $posyafter = $pdf->GetY();
531 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
532 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
533 $pdf->AddPage('', '', true);
534 if (!empty($tplidx)) {
535 $pdf->useTemplate($tplidx);
536 }
537 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
538 $this->_pagehead($pdf, $object, 0, $outputlangs);
539 }
540 $pdf->setPage($pageposafter + 1);
541 }
542 } else {
543 // We found a page break
544
545 // Allows data in the first page if description is long enough to break in multiples pages
546 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
547 $showpricebeforepagebreak = 1;
548 } else {
549 $showpricebeforepagebreak = 0;
550 }
551 }
552 } else { // No pagebreak
553 $pdf->commitTransaction();
554 }
555 $posYAfterDescription = $pdf->GetY();
556
557 $nexY = $pdf->GetY();
558 $pageposafter = $pdf->getPage();
559
560 $pdf->setPage($pageposbefore);
561 $pdf->setTopMargin($this->marge_haute);
562 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
563
564 // We suppose that a too long description is moved completely on next page
565 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
566 $pdf->setPage($pageposafter);
567 $curY = $tab_top_newpage;
568 }
569
570 $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par default
571
572 // $objp = $this->db->fetch_object($resql);
573
574 $userstatic->id = $objp->fk_user_author;
575 $userstatic->login = $objp->login;
576 $userstatic->lastname = $objp->lastname;
577 $userstatic->firstname = $objp->firstname;
578 $userstatic->photo = $objp->photo;
579
580 $productstatic->id = $objp->rowid;
581 $productstatic->ref = $objp->product_ref;
582 $productstatic->label = $objp->produit;
583 $productstatic->type = $objp->type;
584 $productstatic->entity = $objp->entity;
585 $productstatic->status_batch = $objp->tobatch;
586
587 $productlot->id = $objp->lotid;
588 $productlot->batch = $objp->batch;
589 $productlot->eatby = $objp->eatby;
590 $productlot->sellby = $objp->sellby;
591
592 $warehousestatic->id = $objp->entrepot_id;
593 $warehousestatic->label = $objp->warehouse_ref;
594 $warehousestatic->lieu = $objp->lieu;
595
596 $arrayofuniqueproduct[$objp->rowid] = $objp->produit;
597 if (!empty($objp->fk_origin)) {
598 $origin = $movement->get_origin($objp->fk_origin, $objp->origintype);
599 } else {
600 $origin = '';
601 }
602
603 // Id movement.
604 $pdf->SetXY($this->posxidref, $curY);
605 $pdf->MultiCell($this->posxdesc - $this->posxidref - 0.8, 3, $objp->mid, 0, 'L');
606
607 // Date.
608 $pdf->SetXY($this->posxdatemouv, $curY);
609 $pdf->MultiCell($this->posxdesc - $this->posxdatemouv - 0.8, 6, dol_print_date($this->db->jdate($objp->datem), 'dayhour'), 0, 'L');
610
611 // Ref.
612 $pdf->SetXY($this->posxdesc, $curY);
613 $pdf->MultiCell($this->posxlabel - $this->posxdesc - 0.8, 3, $productstatic->ref, 0, 'L');
614
615 // Label
616 $pdf->SetXY($this->posxlabel + 0.8, $curY);
617 $pdf->MultiCell($this->posxqty - $this->posxlabel - 0.8, 6, $productstatic->label, 0, 'L');
618
619 // Lot/series
620 $pdf->SetXY($this->posxqty, $curY);
621 $pdf->MultiCell($this->posxup - $this->posxqty - 0.8, 3, (string) $productlot->batch, 0, 'R');
622
623 // Inv. code
624 $pdf->SetXY($this->posxup, $curY);
625 $pdf->MultiCell($this->posxunit - $this->posxup - 0.8, 3, $objp->inventorycode, 0, 'R');
626
627 // Label movement
628 $pdf->SetXY($this->posxunit, $curY);
629 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 0.8, 3, $objp->label, 0, 'R');
630 $totalvalue += price2num($objp->ppmp * $objp->value, 'MT');
631
632 // Origin
633 $pricemin = $objp->price;
634 $pdf->SetXY($this->posxdiscount, $curY);
635 $pdf->MultiCell($this->postotalht - $this->posxdiscount - 0.8, 3, $origin, 0, 'R', false);
636
637 // Qty
638 $valtoshow = price2num($objp->qty, 'MS');
639 $towrite = (empty($valtoshow) ? '0' : $valtoshow);
640 $totalunit += $objp->qty;
641
642 $pdf->SetXY($this->postotalht, $curY);
643 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, $objp->qty, 0, 'R', false);
644
645 $totalvaluesell += price2num($pricemin * $objp->value, 'MT');
646
647 $nexY += 3.5; // Add space between lines
648 // Add line
649 if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) {
650 $pdf->setPage($pageposafter);
651 $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(80, 80, 80)));
652 //$pdf->SetDrawColor(190,190,200);
653 $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
654 $pdf->SetLineStyle(array('dash' => 0));
655 }
656
657 $nexY += 2; // Add space between lines
658
659 // Detect if some page were added automatically and output _tableau for past pages
660 while ($pagenb < $pageposafter) {
661 $pdf->setPage($pagenb);
662 if ($pagenb == 1) {
663 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
664 } else {
665 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
666 }
667 $this->_pagefoot($pdf, $object, $outputlangs, 1);
668 $pagenb++;
669 $pdf->setPage($pagenb);
670 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
671 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
672 $this->_pagehead($pdf, $object, 0, $outputlangs);
673 }
674 if (!empty($tplidx)) {
675 $pdf->useTemplate($tplidx);
676 }
677 }
678 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
679 if ($pagenb == 1) {
680 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
681 } else {
682 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
683 }
684 $this->_pagefoot($pdf, $object, $outputlangs, 1);
685 // New page
686 $pdf->AddPage();
687 if (!empty($tplidx)) {
688 $pdf->useTemplate($tplidx);
689 }
690 $pagenb++;
691 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
692 $this->_pagehead($pdf, $object, 0, $outputlangs);
693 }
694 }
695 }
696
697 $this->db->free($resql);
698
702 $nexY = $pdf->GetY();
703 $nexY += 5;
704 $curY = $nexY;
705
706 $pdf->SetLineStyle(array('dash' => '0', 'color' => array(220, 26, 26)));
707 $pdf->line($this->marge_gauche, $curY - 1, $this->page_largeur - $this->marge_droite, $curY - 1);
708 $pdf->SetLineStyle(array('dash' => 0));
709
710 $pdf->SetFont('', 'B', $default_font_size - 1);
711 $pdf->SetTextColor(0, 0, 120);
712
713 // Total
714 $pdf->SetXY($this->posxidref, $curY);
715 $pdf->MultiCell($this->posxdesc - $this->posxidref, 3, $langs->trans("Total"), 0, 'L');
716
717 // Total Qty
718 $pdf->SetXY($this->postotalht, $curY);
719 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, (string) $totalunit, 0, 'R', false);
720 } else {
721 dol_print_error($this->db);
722 }
723
724 // Display notes
725 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
726 // Extrafields in note
727 $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
728 if (!empty($extranote)) {
729 $notetoshow = dol_concatdesc($notetoshow, $extranote);
730 }
731
732 if ($notetoshow) {
733 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
734 complete_substitutions_array($substitutionarray, $outputlangs, $object);
735 $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
736 $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
737
738 $tab_top = 88;
739
740 $pdf->SetFont('', '', $default_font_size - 1);
741 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
742 $nexY = $pdf->GetY();
743 $height_note = $nexY - $tab_top;
744
745 // Rect takes a length in 3rd parameter
746 $pdf->SetDrawColor(192, 192, 192);
747 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 2, $this->corner_radius, '1234', 'D');
748
749 $tab_height -= $height_note;
750 $tab_top = $nexY + 6;
751 } else {
752 $height_note = 0;
753 }
754
755 $iniY = $tab_top + 7;
756 $curY = $tab_top + 7;
757 $nexY = $tab_top + 7;
758
759 $tab_top = $tab_top_newpage + 21;
760
761 // Show square
762 if ($pagenb == 1) {
763 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
764 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
765 } else {
766 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
767 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
768 }
769
770 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
771
772 // Affiche zone infos
773 //$posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
774
775 // Affiche zone totaux
776 //$posy=$this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
777
778 // Pied de page
779 $this->_pagefoot($pdf, $object, $outputlangs);
780 if (method_exists($pdf, 'AliasNbPages')) {
781 $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod
782 }
783
784 $pdf->Close();
785
786 $pdf->Output($file, 'F');
787
788 // Add pdfgeneration hook
789 $hookmanager->initHooks(array('pdfgeneration'));
790 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
791 global $action;
792 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
793 $this->warnings = $hookmanager->warnings;
794 if ($reshook < 0) {
795 $this->error = $hookmanager->error;
796 $this->errors = $hookmanager->errors;
797 dolChmod($file);
798 return -1;
799 }
800
801 dolChmod($file);
802
803 $this->result = array('fullpath' => $file);
804
805 return 1; // No error
806 } else {
807 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
808 return 0;
809 }
810 } else {
811 $this->error = $langs->trans("ErrorConstantNotDefined", "PRODUCT_OUTPUTDIR");
812 return 0;
813 }
814 }
815
816 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
830 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
831 {
832 global $conf;
833
834 // Force to disable hidetop and hidebottom
835 $hidebottom = 0;
836 if ($hidetop) {
837 $hidetop = -1;
838 }
839
840 $currency = !empty($currency) ? $currency : $conf->currency;
841 $default_font_size = pdf_getPDFFontSize($outputlangs);
842
843 // Amount in (at tab_top - 1)
844 $pdf->SetTextColor(0, 0, 0);
845 $pdf->SetFont('', '', $default_font_size - 2);
846
847 if (empty($hidetop)) {
848 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
849 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
850 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
851
852 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
853 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
854 $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')));
855 }
856 }
857
858 $pdf->SetDrawColor(128, 128, 128);
859 $pdf->SetFont('', 'B', $default_font_size - 3);
860
861 // Output Rect
862 //$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
863
864 $pdf->SetLineStyle(array('dash' => '0', 'color' => array(220, 26, 26)));
865 $pdf->SetDrawColor(220, 26, 26);
866 $pdf->line($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite, $tab_top);
867 $pdf->SetLineStyle(array('dash' => 0));
868 $pdf->SetDrawColor(128, 128, 128);
869 $pdf->SetTextColor(0, 0, 120);
870
871 //Ref mouv
872 if (empty($hidetop)) {
873 //$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); // line takes a position y in 2nd parameter and 4th parameter
874 $pdf->SetXY($this->posxidref, $tab_top + 1);
875 $pdf->MultiCell($this->posxdesc - $this->posxdatemouv - 0.8, 3, $outputlangs->transnoentities("Ref"), '', 'L');
876 }
877
878 //Date mouv
879 //$pdf->line($this->posxlabel-1, $tab_top, $this->posxlabel-1, $tab_top + $tab_height);
880 if (empty($hidetop)) {
881 $pdf->SetXY($this->posxdatemouv, $tab_top + 1);
882 $pdf->MultiCell($this->posxdesc - $this->posxdatemouv, 2, $outputlangs->transnoentities("Date"), '', 'C');
883 }
884
885 //Ref Product
886 //$pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height);
887 if (empty($hidetop)) {
888 $pdf->SetXY($this->posxdesc - 1, $tab_top + 1);
889 $pdf->MultiCell($this->posxlabel - $this->posxdesc, 2, $outputlangs->transnoentities("Ref. Product"), '', 'C');
890 }
891
892 //Label Product
893 //$pdf->line($this->posxup-1, $tab_top, $this->posxup-1, $tab_top + $tab_height);
894 if (empty($hidetop)) {
895 $pdf->SetXY($this->posxlabel - 1, $tab_top + 1);
896 $pdf->MultiCell($this->posxqty - $this->posxlabel, 2, $outputlangs->transnoentities("Label"), '', 'C');
897 }
898
899 //Lot/series Product
900 //$pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height);
901 if (empty($hidetop)) {
902 $pdf->SetXY($this->posxqty, $tab_top + 1);
903 $pdf->MultiCell($this->posxup - $this->posxqty, 2, $outputlangs->transnoentities("Batch"), '', 'C');
904 }
905
906 //Code Inv
907 //$pdf->line($this->posxup-1, $tab_top, $this->posxup-1, $tab_top + $tab_height);
908 if (empty($hidetop)) {
909 $pdf->SetXY($this->posxup - 1, $tab_top + 1);
910 $pdf->MultiCell($this->posxunit - $this->posxup, 2, $outputlangs->transnoentities("InventoryCode"), '', 'C');
911 }
912
913 //Label movement
914 //$pdf->line($this->posxunit, $tab_top, $this->posxunit, $tab_top + $tab_height);
915 if (empty($hidetop)) {
916 $pdf->SetXY($this->posxunit, $tab_top + 1);
917 $pdf->MultiCell($this->posxdiscount - $this->posxunit, 2, $outputlangs->transnoentities("LabelMovement"), '', 'C');
918 }
919
920 //Origin
921 //$pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
922 if (empty($hidetop)) {
923 $pdf->SetXY($this->posxdiscount + 2, $tab_top + 1);
924 $pdf->MultiCell($this->postotalht - $this->posxdiscount - 0.8, 2, $outputlangs->transnoentities("Origin"), '', 'C');
925 }
926
927 //Qty
928 //$pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
929 if (empty($hidetop)) {
930 $pdf->SetXY($this->postotalht + 2, $tab_top + 1);
931 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 2, $outputlangs->transnoentities("Qty"), '', 'C');
932 }
933
934 $pdf->SetDrawColor(220, 26, 26);
935 $pdf->SetLineStyle(array('dash' => '0', 'color' => array(220, 26, 26)));
936 $pdf->line($this->marge_gauche, $tab_top + 11, $this->page_largeur - $this->marge_droite, $tab_top + 11);
937 $pdf->SetLineStyle(array('dash' => 0));
938 }
939
940 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
951 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey = "")
952 {
953 global $conf, $langs;
954
955 // Load traductions files required by page
956 $outputlangs->loadLangs(array("main", "propal", "companies", "bills", "orders", "stocks"));
957
958 $default_font_size = pdf_getPDFFontSize($outputlangs);
959
960 // if ($object->type == 1) {
961 // $titlekey = 'ServiceSheet';
962 // } else {
963 // $titlekey = 'StockSheet';
964 // }
965
966 pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
967
968 // Show Draft Watermark
969 if ($object->status == 0 && getDolGlobalString('WAREHOUSE_DRAFT_WATERMARK')) {
970 pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', getDolGlobalString('WAREHOUSE_DRAFT_WATERMARK'));
971 }
972
973 $pdf->SetTextColor(0, 0, 60);
974 $pdf->SetFont('', 'B', $default_font_size + 3);
975
976 $posy = $this->marge_haute;
977 $posx = $this->page_largeur - $this->marge_droite - 100;
978
979 $pdf->SetXY($this->marge_gauche, $posy);
980
981 // Logo
982 $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
983 if ($this->emetteur->logo) {
984 if (is_readable($logo)) {
985 $height = pdf_getHeightForLogo($logo);
986 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
987 } else {
988 $pdf->SetTextColor(200, 0, 0);
989 $pdf->SetFont('', 'B', $default_font_size - 2);
990 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
991 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
992 }
993 } else {
994 $text = $this->emetteur->name;
995 $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
996 }
997
998 $pdf->SetFont('', 'B', $default_font_size + 3);
999 $pdf->SetXY($posx, $posy);
1000 $pdf->SetTextColor(0, 0, 60);
1001 $title = $outputlangs->transnoentities("Warehouse");
1002 $pdf->MultiCell(100, 3, $title, '', 'R');
1003
1004 $pdf->SetFont('', 'B', $default_font_size);
1005
1006 $posy += 5;
1007 $pdf->SetXY($posx, $posy);
1008 $pdf->SetTextColor(0, 0, 60);
1009
1010 $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->label), '', 'R');
1011
1012 $posy += 5;
1013 $pdf->SetFont('', '', $default_font_size - 1);
1014 $pdf->SetXY($posx, $posy);
1015 $pdf->SetTextColor(0, 0, 60);
1016 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("LocationSummary").' :', '', 'R');
1017
1018 $posy += 4;
1019 $pdf->SetXY($posx - 50, $posy);
1020 $pdf->MultiCell(150, 3, $object->lieu, '', 'R');
1021
1022
1023 // Parent MouvementStock
1024 $posy += 4;
1025 $pdf->SetXY($posx, $posy);
1026 $pdf->SetTextColor(0, 0, 60);
1027 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ParentWarehouse").' :', '', 'R');
1028
1029 $posy += 4;
1030 $pdf->SetXY($posx - 50, $posy);
1031 $e = new MouvementStock($this->db);
1032 if (!empty($object->fk_parent) && $e->fetch($object->fk_parent) > 0) {
1033 $pdf->MultiCell(150, 3, $e->label, '', 'R');
1034 } else {
1035 $pdf->MultiCell(150, 3, $outputlangs->transnoentities("None"), '', 'R');
1036 }
1037
1038 // Description
1039 $nexY = $pdf->GetY();
1040 $nexY += 5;
1041 $pdf->SetXY($posx, $posy);
1042 $pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("Description").' : </b>'.nl2br($object->description), 0, 1);
1043 $nexY = $pdf->GetY();
1044
1045 $calcproductsunique = $object->nb_different_products();
1046 $calcproducts = $object->nb_products();
1047
1048 // Total nb of different products
1049 $pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("NumberOfDifferentProducts").' : </b>'.(empty($calcproductsunique['nb']) ? '0' : $calcproductsunique['nb']), 0, 1);
1050 $nexY = $pdf->GetY();
1051
1052 // Nb of products
1053 $valtoshow = price2num($calcproducts['nb'], 'MS');
1054 $pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("NumberOfProducts").' : </b>'.(empty($valtoshow) ? '0' : $valtoshow), 0, 1);
1055 $nexY = $pdf->GetY();
1056
1057 // Value
1058 $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);
1059 $nexY = $pdf->GetY();
1060
1061
1062 // Last movement
1063 $sql = "SELECT max(m.datem) as datem";
1064 $sql .= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m";
1065 $sql .= " WHERE m.fk_entrepot = ".((int) $object->id);
1066 $resqlbis = $this->db->query($sql);
1067 if ($resqlbis) {
1068 $obj = $this->db->fetch_object($resqlbis);
1069 $lastmovementdate = $this->db->jdate($obj->datem);
1070 } else {
1071 $lastmovementdate = 0;
1072 dol_print_error($this->db);
1073 }
1074
1075 if ($lastmovementdate) {
1076 $toWrite = dol_print_date($lastmovementdate, 'dayhour').' ';
1077 } else {
1078 $toWrite = $outputlangs->transnoentities("None");
1079 }
1080
1081 $pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("LastMovement").' : </b>'.$toWrite, 0, 1);
1082 $nexY = $pdf->GetY();
1083
1084
1085 /*if ($object->ref_client)
1086 {
1087 $posy+=5;
1088 $pdf->SetXY($posx,$posy);
1089 $pdf->SetTextColor(0,0,60);
1090 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
1091 }*/
1092
1093 /*$posy+=4;
1094 $pdf->SetXY($posx,$posy);
1095 $pdf->SetTextColor(0,0,60);
1096 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("OrderDate")." : " . dol_print_date($object->date,"%d %b %Y",false,$outputlangs,true), '', 'R');
1097 */
1098
1099 // Get contact
1100 /*
1101 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1102 $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
1103 if (count($arrayidcontact) > 0)
1104 {
1105 $usertmp=new User($this->db);
1106 $usertmp->fetch($arrayidcontact[0]);
1107 $posy+=4;
1108 $pdf->SetXY($posx,$posy);
1109 $pdf->SetTextColor(0,0,60);
1110 $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
1111 }
1112 }*/
1113
1114 $posy += 2;
1115
1116 $top_shift = 0;
1117 // Show list of linked objects
1118 $current_y = $pdf->getY();
1119 //$posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
1120 //if ($current_y < $pdf->getY()) {
1121 // $top_shift = $pdf->getY() - $current_y;
1122 //}
1123
1124 //if ($showaddress) {
1125 /*
1126 // Sender properties
1127 $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty);
1128
1129 // Show sender
1130 $posy=42;
1131 $posx=$this->marge_gauche;
1132 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) $posx=$this->page_largeur-$this->marge_droite-80;
1133 $hautcadre=40;
1134
1135 // Show sender frame
1136 $pdf->SetTextColor(0,0,0);
1137 $pdf->SetFont('','', $default_font_size - 2);
1138 $pdf->SetXY($posx,$posy-5);
1139 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, 'L');
1140 $pdf->SetXY($posx,$posy);
1141 $pdf->SetFillColor(230,230,230);
1142 $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
1143 $pdf->SetTextColor(0,0,60);
1144
1145 // Show sender name
1146 $pdf->SetXY($posx+2,$posy+3);
1147 $pdf->SetFont('','B', $default_font_size);
1148 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
1149 $posy=$pdf->getY();
1150
1151 // Show sender information
1152 $pdf->SetXY($posx+2,$posy);
1153 $pdf->SetFont('','', $default_font_size - 1);
1154 $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
1155 */
1156 //}
1157
1158 $pdf->SetTextColor(0, 0, 0);
1159
1160 return $top_shift;
1161 }
1162
1163 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1173 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1174 {
1175 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1176 return pdf_pagefoot($pdf, $outputlangs, 'PRODUCT_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1177 }
1178}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class to manage warehouses.
Class to manage standard extra fields.
Class to manage hooks.
Parent class to manage warehouse movement document templates.
Class to manage stock movements.
Class to manage products or services.
Class with list of lots and properties.
Class to manage Dolibarr users.
Class to build documents using ODF templates generator.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
Show table for lines.
_pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey="")
Show top header of page.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
global $mysoc
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:604
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:623
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(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
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...
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
getCallerInfoString()
Get caller info as a string that can be appended to a log message.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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.
dolChmod($filepath, $newmask='')
Change mod of a file.
natural_search($fields, $value, $mode=0, $nofirstand=0, $sqltoadd='')
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
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...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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 a 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)
pdf_watermark($pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition pdf.lib.php:1155
pdf_getFormat($outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:87
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:294
pdf_writelinedesc($pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref=0, $hidedesc=0, $issupplierline=0, $align='J')
Output line description into PDF.
Definition pdf.lib.php:1846
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:317
pdf_pagehead($pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition pdf.lib.php:747
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:1421
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:273
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:1135
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:129
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:130
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:133