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