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