161 public function write_file(
$object, $outputlangs, $srctemplatepath =
'', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
166 if (!is_object($outputlangs)) {
167 $outputlangs = $langs;
171 $outputlangs->charset_output =
'ISO-8859-1';
175 $outputlangs->loadLangs(array(
"main",
"dict",
"companies",
"stocks",
"products"));
177 $isspecimen = empty(
$object->id);
180 $this->error =
'Error: no output dir defined for module stock';
187 $file = $dir.
'/SPECIMEN.pdf';
190 $dir = $basedir.
'/'.$objectref;
191 $file = $dir.
'/'.$objectref.
'.pdf';
194 if (!file_exists($dir)) {
196 $this->error = $langs->transnoentities(
"ErrorCanNotCreateDir", $dir);
204 for ($i = 1; $i <= 5; $i++) {
206 $line->product_ref =
'PROD'.sprintf(
'%04d', $i);
207 $line->product_label =
'Product '.$i;
208 $line->warehouse_ref =
'WH-A';
210 $line->qty_stock = 10 * $i;
211 $line->qty_view = 10 * $i - ($i % 2);
212 $line->pmp = 2.5 * $i;
217 $recorded = ((int)
$object->status >= Inventory::STATUS_RECORDED);
218 $sql =
"SELECT id.rowid, id.qty_stock, id.qty_view, id.qty_regulated, id.batch, id.pmp_real, id.pmp_expected,";
219 $sql .=
" p.ref as product_ref, p.label as product_label, e.ref as warehouse_ref";
220 $sql .=
" FROM ".MAIN_DB_PREFIX.
"inventorydet as id";
221 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"product as p ON p.rowid = id.fk_product";
222 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"entrepot as e ON e.rowid = id.fk_warehouse";
223 $sql .=
" WHERE id.fk_inventory = ".((int)
$object->id);
224 $sql .=
" ORDER BY e.ref, p.ref";
225 $resql = $this->db->query($sql);
227 $this->error = $this->db->lasterror();
230 while ($obj = $this->db->fetch_object($resql)) {
232 $line->product_ref = (
string) $obj->product_ref;
233 $line->product_label = (
string) $obj->product_label;
234 $line->warehouse_ref = (
string) $obj->warehouse_ref;
235 $line->batch = (
string) $obj->batch;
236 $line->qty_stock = $obj->qty_stock;
237 $line->qty_view = $recorded ? ($obj->qty_view !==
null ? $obj->qty_view : ($obj->qty_stock + $obj->qty_regulated)) : $obj->qty_view;
238 $line->pmp = ($obj->pmp_real !==
null && (float) $obj->pmp_real != 0) ? $obj->pmp_real : $obj->pmp_expected;
246 $pdf->SetAutoPageBreak(
true, 0);
248 $heightforinfotot = 30;
249 $heightforsignature = ($isspecimen || !$recorded) ? 25 : 0;
251 $heightforfooter = $this->marge_basse + 8;
253 if (class_exists(
'TCPDF')) {
254 $pdf->setPrintHeader(
false);
255 $pdf->setPrintFooter(
false);
261 $pdf->SetDrawColor(128, 128, 128);
263 $pdf->SetTitle($outputlangs->convToOutputCharset($isspecimen ?
'SPECIMEN' :
$object->ref));
264 $pdf->SetSubject($outputlangs->transnoentities(
"Inventory"));
265 $pdf->SetCreator(
"Dolibarr ".DOL_VERSION);
266 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
267 $pdf->SetKeyWords($outputlangs->convToOutputCharset($isspecimen ?
'SPECIMEN' :
$object->ref).
" ".$outputlangs->transnoentities(
"Inventory"));
269 $pdf->SetCompression(
false);
273 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);
276 $this->posxproduct = $this->marge_gauche;
277 $this->posxlabel = $this->marge_gauche + 30;
278 $this->posxwarehouse = $this->page_largeur - $this->marge_droite - 92;
279 $this->posxbatch = $this->page_largeur - $this->marge_droite - 70;
280 $this->posxqtystock = $this->page_largeur - $this->marge_droite - 50;
281 $this->posxqtyview = $this->page_largeur - $this->marge_droite - 34;
282 $this->posxgap = $this->page_largeur - $this->marge_droite - 18;
283 $this->posxend = $this->page_largeur - $this->marge_droite;
288 $top_shift = $this->
pageHead($pdf,
$object, 1, $outputlangs, $recorded, $isspecimen);
289 $pdf->SetFont(
'',
'', $default_font_size - 1);
290 $pdf->MultiCell(0, 3,
'');
291 $pdf->SetTextColor(0, 0, 0);
293 $tab_top = 42 + $top_shift;
294 $tab_top_newpage = 10;
297 $this->
tableHeader($pdf, $tab_top, $outputlangs, $recorded);
298 $nexY = $tab_top + 7;
300 $nblines = count($lines);
305 for ($i = 0; $i < $nblines; $i++) {
308 $pdf->SetFont(
'',
'', $default_font_size - 2);
311 if ($curY > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot + $heightforsignature))) {
315 $this->
tableHeader($pdf, $tab_top_newpage, $outputlangs, $recorded);
316 $curY = $tab_top_newpage + 7;
317 $pdf->SetFont(
'',
'', $default_font_size - 2);
318 $pdf->SetTextColor(0, 0, 0);
322 $pdf->SetXY($this->posxproduct, $curY);
323 $pdf->MultiCell($this->posxlabel - $this->posxproduct - 1, 3, $outputlangs->convToOutputCharset($line->product_ref), 0,
'L');
325 $pdf->SetXY($this->posxlabel, $curY);
326 $pdf->MultiCell($this->posxwarehouse - $this->posxlabel - 1, 3, $outputlangs->convToOutputCharset(
dol_trunc($line->product_label, 45)), 0,
'L');
328 $pdf->SetXY($this->posxwarehouse, $curY);
329 $pdf->MultiCell($this->posxbatch - $this->posxwarehouse - 1, 3, $outputlangs->convToOutputCharset(
dol_trunc($line->warehouse_ref, 12)), 0,
'L');
331 $pdf->SetXY($this->posxbatch, $curY);
332 $pdf->MultiCell($this->posxqtystock - $this->posxbatch - 1, 3, $outputlangs->convToOutputCharset(
dol_trunc($line->batch, 10)), 0,
'L');
334 $pdf->SetXY($this->posxqtystock, $curY);
335 $pdf->MultiCell($this->posxqtyview - $this->posxqtystock - 1, 3, ($line->qty_stock !==
null && $line->qty_stock !==
'') ?
price2num($line->qty_stock,
'MS') :
'', 0,
'R');
338 $gap = (float) $line->qty_view - (
float) $line->qty_stock;
340 $pdf->SetXY($this->posxqtyview, $curY);
341 $pdf->MultiCell($this->posxgap - $this->posxqtyview - 1, 3,
price2num($line->qty_view,
'MS'), 0,
'R');
344 $pdf->SetTextColor(150, 0, 0);
347 $pdf->SetXY($this->posxgap, $curY);
348 $pdf->MultiCell($this->posxend - $this->posxgap, 3, ($gap > 0 ?
'+' :
'').
price2num($gap,
'MS'), 0,
'R');
349 $pdf->SetTextColor(0, 0, 0);
351 $totalgapvalue += $gap * (float) $line->pmp;
354 $pdf->SetXY($this->posxqtyview, $curY - 1);
355 $pdf->MultiCell($this->posxgap - $this->posxqtyview - 1, 5,
'', 1,
'R');
356 $pdf->SetXY($this->posxgap, $curY - 1);
357 $pdf->MultiCell($this->posxend - $this->posxgap, 5,
'', 1,
'R');
360 $nexY = $curY + ($recorded ? 5 : 6);
364 $pdf->SetFont(
'',
'B', $default_font_size - 1);
366 if ($curY > ($this->page_hauteur - ($heightforfooter + $heightforinfotot + $heightforsignature))) {
370 $curY = $tab_top_newpage;
372 $pdf->SetXY($this->posxproduct, $curY);
373 $pdf->MultiCell(60, 4, $outputlangs->transnoentities(
"NbOfLines").
' : '.$nblines, 0,
'L');
375 $pdf->SetXY($this->posxproduct, $curY + 5);
376 $pdf->MultiCell(120, 4, $outputlangs->transnoentities(
"Difference").
' : '.($totalgap > 0 ?
'+' :
'').
price2num($totalgap,
'MS').
' ('.$nbgap.
' '.$outputlangs->transnoentities(
"Lines").
')', 0,
'L');
377 $pdf->SetXY($this->posxproduct, $curY + 10);
378 $pdf->MultiCell(120, 4, $outputlangs->transnoentities(
"Valuation").
' : '.
price(
price2num($totalgapvalue,
'MT'), 0, $outputlangs, 1, -1, -1,
$conf->currency), 0,
'L');
384 $pdf->SetFont(
'',
'', $default_font_size - 1);
385 $pdf->SetXY($this->posxproduct, $posy);
386 $pdf->MultiCell(80, 4, $outputlangs->transnoentities(
"CountedBy").
' : ____________________', 0,
'L');
387 $pdf->SetXY($this->page_largeur - $this->marge_droite - 80, $posy);
388 $pdf->MultiCell(80, 4, $outputlangs->transnoentities(
"DateAndSignature").
' :', 0,
'L');
389 $pdf->Rect($this->page_largeur - $this->marge_droite - 80, $posy + 5, 80, 15);
394 if (method_exists($pdf,
'AliasNbPages')) {
395 $pdf->AliasNbPages();
400 $pdf->Output($file,
'F');
403 $hookmanager->initHooks(array(
'pdfgeneration'));
404 $parameters = array(
'file' => $file,
'object' =>
$object,
'outputlangs' => $outputlangs);
406 $reshook = $hookmanager->executeHooks(
'afterPDFCreation', $parameters, $this, $action);
408 $this->error = $hookmanager->error;
409 $this->errors = $hookmanager->errors;
414 $this->result = array(
'fullpath' => $file);
428 protected function tableHeader(&$pdf, $tab_top, $outputlangs, $recorded)
434 $pdf->SetFont(
'',
'B', $default_font_size - 2);
435 $pdf->SetDrawColor(128, 128, 128);
436 $pdf->line($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite, $tab_top);
438 $posy = $tab_top + 1;
439 $pdf->SetXY($this->posxproduct, $posy);
440 $pdf->MultiCell($this->posxlabel - $this->posxproduct - 1, 3, $outputlangs->transnoentities(
"ProductRef"), 0,
'L');
441 $pdf->SetXY($this->posxlabel, $posy);
442 $pdf->MultiCell($this->posxwarehouse - $this->posxlabel - 1, 3, $outputlangs->transnoentities(
"Label"), 0,
'L');
443 $pdf->SetXY($this->posxwarehouse, $posy);
444 $pdf->MultiCell($this->posxbatch - $this->posxwarehouse - 1, 3, $outputlangs->transnoentities(
"Warehouse"), 0,
'L');
445 $pdf->SetXY($this->posxbatch, $posy);
446 $pdf->MultiCell($this->posxqtystock - $this->posxbatch - 1, 3, $outputlangs->transnoentities(
"Batch"), 0,
'L');
447 $pdf->SetXY($this->posxqtystock, $posy);
448 $pdf->MultiCell($this->posxqtyview - $this->posxqtystock - 1, 3, $outputlangs->transnoentities(
"ExpectedQty"), 0,
'R');
449 $pdf->SetXY($this->posxqtyview, $posy);
450 $pdf->MultiCell($this->posxgap - $this->posxqtyview - 1, 3, $outputlangs->transnoentities(
"RealQty"), 0,
'R');
451 $pdf->SetXY($this->posxgap, $posy);
452 $pdf->MultiCell($this->posxend - $this->posxgap, 3, $outputlangs->transnoentities(
"Difference"), 0,
'R');
454 $pdf->line($this->marge_gauche, $tab_top + 6, $this->page_largeur - $this->marge_droite, $tab_top + 6);
468 protected function pageHead(&$pdf,
$object, $showaddress, $outputlangs, $recorded, $isspecimen)
476 $pdf->SetTextColor(0, 0, 60);
477 $pdf->SetFont(
'',
'B', $default_font_size + 3);
479 $posy = $this->marge_haute;
480 $posx = $this->page_largeur - $this->marge_droite - 100;
482 $pdf->SetXY($this->marge_gauche, $posy);
485 $logo =
$conf->mycompany->dir_output.
'/logos/'.
$mysoc->logo;
487 if (is_readable($logo)) {
489 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);
491 $pdf->SetTextColor(200, 0, 0);
492 $pdf->SetFont(
'',
'B', $default_font_size - 2);
493 $pdf->MultiCell(100, 3, $outputlangs->transnoentities(
"ErrorLogoFileNotFound", $logo), 0,
'L');
494 $pdf->SetTextColor(0, 0, 60);
497 $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset(
$mysoc->name), 0,
'L');
500 $pdf->SetFont(
'',
'B', $default_font_size + 3);
501 $pdf->SetXY($posx, $posy);
502 $pdf->SetTextColor(0, 0, 60);
503 $title = $outputlangs->transnoentities(
"Inventory");
505 $title .=
' - '.$outputlangs->transnoentities(
"Draft");
507 $pdf->MultiCell(100, 4, $title,
'',
'R');
509 $pdf->SetFont(
'',
'B', $default_font_size);
511 $pdf->SetXY($posx, $posy);
512 $pdf->SetTextColor(0, 0, 60);
513 $pdf->MultiCell(100, 4, $outputlangs->transnoentities(
"Ref").
" : ".($isspecimen ?
'SPECIMEN' : $outputlangs->convToOutputCharset(
$object->ref)),
'',
'R');
515 $pdf->SetFont(
'',
'', $default_font_size - 1);
517 if (!$isspecimen && !empty(
$object->date_inventory)) {
519 $pdf->SetXY($posx, $posy);
520 $pdf->SetTextColor(0, 0, 60);
521 $pdf->MultiCell(100, 3, $outputlangs->transnoentities(
"Date").
" : ".
dol_print_date($this->db->jdate(
$object->date_inventory),
"day",
false, $outputlangs,
true),
'',
'R');
523 if (!$isspecimen && !empty(
$object->title)) {
525 $pdf->SetXY($posx, $posy);
526 $pdf->SetTextColor(0, 0, 60);
527 $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset(
$object->title),
'',
'R');
530 $pdf->SetTextColor(0, 0, 0);