Passed
Branch develop (96ac0e)
by
unknown
23:19
created

pdf_stdandard::_tableau()   C

Complexity

Conditions 14

Size

Total Lines 108
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 53
nop 8
dl 0
loc 108
rs 6.2666
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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