浏览代码

NEW Add PDF document templates for warehouses (list of stock)

Laurent Destailleur 4 年之前
父节点
当前提交
58e25768a7

+ 239 - 0
htdocs/admin/stock.php

@@ -37,12 +37,18 @@ $langs->loadLangs(array("admin", "stocks"));
 if (!$user->admin) accessforbidden();
 
 $action = GETPOST('action', 'alpha');
+$value = GETPOST('value', 'alpha');
+$label = GETPOST('label', 'alpha');
+$scandir = GETPOST('scan_dir', 'alpha');
+$type = 'stock';
 
 
 /*
  * Action
  */
 
+$reg =array();
+
 if (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg))
 {
     $code = $reg[1];
@@ -77,11 +83,84 @@ if ($action == 'warehouse')
 	if (!$res > 0) $error++;
 }
 
+if ($action == 'specimen')
+{
+	$modele = GETPOST('module', 'alpha');
+
+	$object = new Entrepot($db);
+	$object->initAsSpecimen();
+
+	// Search template files
+	$file = ''; $classname = ''; $filefound = 0;
+	$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+	foreach ($dirmodels as $reldir)
+	{
+		$file = dol_buildpath($reldir."core/modules/stock/doc/pdf_".$modele.".modules.php", 0);
+		if (file_exists($file))
+		{
+			$filefound = 1;
+			$classname = "pdf_".$modele;
+			break;
+		}
+	}
+
+	if ($filefound)
+	{
+		require_once $file;
+
+		$module = new $classname($db);
+
+		if ($module->write_file($object, $langs) > 0)
+		{
+			header("Location: ".DOL_URL_ROOT."/document.php?modulepart=stock&file=SPECIMEN.pdf");
+			return;
+		} else {
+			setEventMessages($module->error, null, 'errors');
+			dol_syslog($module->error, LOG_ERR);
+		}
+	} else {
+		setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
+		dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
+	}
+}
+
+// Activate a model
+elseif ($action == 'set') {
+	$ret = addDocumentModel($value, $type, $label, $scandir);
+} elseif ($action == 'del') {
+	$ret = delDocumentModel($value, $type);
+	if ($ret > 0)
+	{
+		if ($conf->global->STOCK_ADDON_PDF == "$value") dolibarr_del_const($db, 'STOCK_ADDON_PDF', $conf->entity);
+	}
+}
+
+// Set default model
+elseif ($action == 'setdoc')
+{
+	if (dolibarr_set_const($db, "STOCK_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity))
+	{
+		// The constant that was read before the new set
+		// We therefore requires a variable to have a coherent view
+		$conf->global->STOCK_ADDON_PDF = $value;
+	}
+
+	// On active le modele
+	$ret = delDocumentModel($value, $type);
+	if ($ret > 0)
+	{
+		$ret = addDocumentModel($value, $type, $label, $scandir);
+	}
+}
+
 
 /*
  * View
  */
 
+$form = new Form($db);
+$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+
 llxHeader('', $langs->trans("StockSetup"));
 
 $linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
@@ -409,6 +488,166 @@ if ($virtualdiffersfromphysical)
 	print '<br>';
 }
 
+
+
+/*
+ * Document templates generators
+ */
+
+print load_fiche_titre($langs->trans("WarehouseModelModule"), '', '');
+
+// Load array def with activated templates
+$def = array();
+$sql = "SELECT nom";
+$sql .= " FROM ".MAIN_DB_PREFIX."document_model";
+$sql .= " WHERE type = '".$type."'";
+$sql .= " AND entity = ".$conf->entity;
+$resql = $db->query($sql);
+if ($resql)
+{
+	$i = 0;
+	$num_rows = $db->num_rows($resql);
+	while ($i < $num_rows)
+	{
+		$array = $db->fetch_array($resql);
+		array_push($def, $array[0]);
+		$i++;
+	}
+} else {
+	dol_print_error($db);
+}
+
+
+print "<table class=\"noborder\" width=\"100%\">\n";
+print "<tr class=\"liste_titre\">\n";
+print '<td>'.$langs->trans("Name").'</td>';
+print '<td>'.$langs->trans("Description").'</td>';
+print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
+print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
+print '<td class="center" width="38">'.$langs->trans("ShortInfo").'</td>';
+print '<td class="center" width="38">'.$langs->trans("Preview").'</td>';
+print "</tr>\n";
+
+clearstatcache();
+
+foreach ($dirmodels as $reldir)
+{
+	foreach (array('', '/doc') as $valdir)
+	{
+		$realpath = $reldir."core/modules/stock".$valdir;
+		$dir = dol_buildpath($realpath);
+
+		if (is_dir($dir))
+		{
+			$handle = opendir($dir);
+			if (is_resource($handle))
+			{
+				while (($file = readdir($handle)) !== false)
+				{
+					$filelist[] = $file;
+				}
+				closedir($handle);
+				arsort($filelist);
+
+				foreach ($filelist as $file)
+				{
+					if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file))
+					{
+						if (file_exists($dir.'/'.$file))
+						{
+							$name = substr($file, 4, dol_strlen($file) - 16);
+							$classname = substr($file, 0, dol_strlen($file) - 12);
+
+							require_once $dir.'/'.$file;
+							$module = new $classname($db);
+
+							$modulequalified = 1;
+							if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified = 0;
+							if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified = 0;
+
+							if ($modulequalified)
+							{
+								print '<tr class="oddeven"><td width="100">';
+								print (empty($module->name) ? $name : $module->name);
+								print "</td><td>\n";
+								if (method_exists($module, 'info')) print $module->info($langs);
+								else print $module->description;
+								print '</td>';
+
+								// Active
+								if (in_array($name, $def))
+								{
+									print '<td class="center">'."\n";
+									print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=del&value='.$name.'">';
+									print img_picto($langs->trans("Enabled"), 'switch_on');
+									print '</a>';
+									print '</td>';
+								} else {
+									print '<td class="center">'."\n";
+									print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=set&value='.$name.'&amp;scan_dir='.$module->scandir.'&amp;label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
+									print "</td>";
+								}
+
+								// Default
+								print '<td class="center">';
+								if ($conf->global->STOCK_ADDON_PDF == $name)
+								{
+									print img_picto($langs->trans("Default"), 'on');
+								} else {
+									print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setdoc&value='.$name.'&amp;scan_dir='.$module->scandir.'&amp;label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
+								}
+								print '</td>';
+
+								// Info
+								$htmltooltip = ''.$langs->trans("Name").': '.$module->name;
+								$htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
+								if ($module->type == 'pdf')
+								{
+									$htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
+								}
+								$htmltooltip .= '<br>'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file;
+
+								$htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
+								$htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
+								$htmltooltip .= '<br>'.$langs->trans("PaymentMode").': '.yn($module->option_modereg, 1, 1);
+								$htmltooltip .= '<br>'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg, 1, 1);
+								$htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
+								//$htmltooltip .= '<br>'.$langs->trans("Discounts").': '.yn($module->option_escompte,1,1);
+								//$htmltooltip .= '<br>'.$langs->trans("CreditNote").': '.yn($module->option_credit_note,1,1);
+								$htmltooltip .= '<br>'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark, 1, 1);
+
+
+								print '<td class="center">';
+								print $form->textwithpicto('', $htmltooltip, 1, 0);
+								print '</td>';
+
+								// Preview
+								print '<td class="center">';
+								if ($module->type == 'pdf')
+								{
+									print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"), 'bill').'</a>';
+								} else {
+									print img_object($langs->trans("PreviewNotAvailable"), 'generic');
+								}
+								print '</td>';
+
+								print "</tr>\n";
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+print '</table>';
+
+
+// Other
+
+print load_fiche_titre($langs->trans("Other"), '', '');
+
 print '<table class="noborder centpercent">';
 
 print '<tr class="liste_titre">';

+ 1 - 1
htdocs/core/lib/functions2.lib.php

@@ -1570,7 +1570,7 @@ function getListOfModels($db, $type, $maxfilenamelength = 0)
 
     $sql = "SELECT nom as id, nom as doc_template_name, libelle as label, description as description";
     $sql .= " FROM ".MAIN_DB_PREFIX."document_model";
-    $sql .= " WHERE type = '".$type."'";
+    $sql .= " WHERE type = '".$db->escape($type)."'";
     $sql .= " AND entity IN (0,".$conf->entity.")";
     $sql .= " ORDER BY description DESC";
 

+ 2 - 2
htdocs/core/modules/modStock.class.php

@@ -81,14 +81,14 @@ class modStock extends DolibarrModules
 		$r++;
 		$this->const[$r][0] = "STOCK_ADDON_PDF";
 		$this->const[$r][1] = "chaine";
-		$this->const[$r][2] = "Standard";
+		$this->const[$r][2] = "standard";
 		$this->const[$r][3] = 'Name of PDF model of stock';
 		$this->const[$r][4] = 0;
 
 		$r++;
 		$this->const[$r][0] = "MOUVEMENT_ADDON_PDF";
 		$this->const[$r][1] = "chaine";
-		$this->const[$r][2] = "StdMouvement";
+		$this->const[$r][2] = "stdmovement";
 		$this->const[$r][3] = 'Name of PDF model of stock mouvement';
 		$this->const[$r][4] = 0;
 

+ 2 - 2
htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php → htdocs/core/modules/movement/doc/pdf_standard.modules.php

@@ -17,7 +17,7 @@
  */
 
 /**
- *	\file       htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php
+ *	\file       htdocs/core/modules/movement/doc/pdf_standard.modules.php
  *	\ingroup    societe
  *	\brief      File of class to build PDF documents for stocks movements
  */
@@ -35,7 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
 /**
  *	Class to build documents using ODF templates generator
  */
-class pdf_stdmovement extends ModelePDFMovement
+class pdf_stdandard extends ModelePDFMovement
 {
     /**
      * @var DoliDb Database handler

+ 5 - 3
htdocs/core/modules/stock/modules_movement.php → htdocs/core/modules/movement/modules_movement.php

@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2018 Laurent Destailleur  <eldy@users.sourceforge.net>
+/* Copyright (C) 2018-2020 Laurent Destailleur  <eldy@users.sourceforge.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 /**
  *  \file       htdocs/core/modules/stock/modules_movement.php
  *  \ingroup    stock
- *  \brief      File with parent class for generating warehouse to PDF and File of class to manage warehouse movement
+ *  \brief      File with parent class for generating PDF of a stock movements
  */
 
 require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
@@ -49,10 +49,12 @@ abstract class ModelePDFMovement extends CommonDocGenerator
         // phpcs:enable
 		global $conf;
 
-		$type = 'mouvement';
+		$type = 'movement';
 		$liste = array();
+
 		include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 		$liste = getListOfModels($db, $type, $maxfilenamelength);
+
 		return $liste;
 	}
 }

+ 2 - 2
htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php

@@ -36,7 +36,7 @@ class pdf_standardlabel extends CommonStickerGenerator
 	/**
 	 * Output a sticker on page at position _COUNTX, _COUNTY (_COUNTX and _COUNTY start from 0)
 	 *
-	 * @param	PDF			$pdf			PDF reference
+	 * @param	TCPDF		$pdf			PDF reference
 	 * @param	Translate	$outputlangs	Output langs
 	 * @param	array		$param			Associative array containing label content and optional parameters
 	 * @return	void
@@ -52,7 +52,7 @@ class pdf_standardlabel extends CommonStickerGenerator
 	 * - %LOGO% is replace with company logo
 	 * - %PHOTO% is replace with photo provided as parameter
 	 *
-	 * @param	PDF			$pdf			PDF reference
+	 * @param	TCPDF		$pdf			PDF reference
 	 * @param	string		$textleft		Text left
 	 * @param	string		$header			Header
 	 * @param	string		$footer			Footer

+ 2 - 2
htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php

@@ -69,7 +69,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
 	/**
 	 * write barcode to pdf
 	 *
-	 * @param PDF	  $pdf		  PDF reference
+	 * @param TCPDF	  $pdf		   PDF reference
 	 * @param string  $code		   code to print
 	 * @param string  $encoding	   type of barcode
 	 * @param boolean $is2d		   true if 2d barcode
@@ -91,7 +91,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
 	/**
 	 * Output a sticker on page at position _COUNTX, _COUNTY (_COUNTX and _COUNTY start from 0)
 	 *
-	 * @param	PDF			$pdf			PDF reference
+	 * @param	TCPDF		$pdf			PDF reference
 	 * @param	Translate	$outputlangs	Output langs
 	 * @param	array		$param			Associative array containing label content and optional parameters
 	 * @return	void

+ 1 - 1
htdocs/core/modules/propale/mod_propale_marbre.php

@@ -47,7 +47,7 @@ class mod_propale_marbre extends ModeleNumRefPropales
 	/**
 	 * @var string Nom du modele
 	 * @deprecated
-	 * @see name
+	 * @see $name
 	 */
 	public $nom = 'Marbre';
 

+ 1 - 1
htdocs/core/modules/propale/mod_propale_saphir.php

@@ -47,7 +47,7 @@ class mod_propale_saphir extends ModeleNumRefPropales
 	/**
 	 * @var string Nom du modele
 	 * @deprecated
-	 * @see name
+	 * @see $name
 	 */
 	public $nom = 'Saphir';
 

+ 2 - 2
htdocs/core/modules/rapport/pdf_paiement.class.php

@@ -347,7 +347,7 @@ class pdf_paiement
 	/**
 	 *  Show top header of page.
 	 *
-	 *  @param	PDF			$pdf     		Object PDF
+	 *  @param	TCPDF			$pdf     		Object PDF
 	 *  @param  int			$page	     	Object to show
 	 *  @param  int	    	$showaddress    0=no, 1=yes
 	 *  @param  Translate	$outputlangs	Object lang for output
@@ -421,7 +421,7 @@ class pdf_paiement
 	/**
 	 *	Output body
 	 *
-	 *	@param	PDF			$pdf			PDF object
+	 *	@param	TCPDF		$pdf			PDF object
 	 *	@param	string		$page			Page
 	 *	@param	array		$lines			Array of lines
 	 *	@param	Translate	$outputlangs	Object langs

+ 2 - 2
htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php

@@ -24,8 +24,8 @@
  *	\brief      File of class to build ODT documents for stocks/services
  */
 
-require_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_stock.class.php';
-require_once DOL_DOCUMENT_ROOT.'/stock/class/stock.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_stock.php';
+require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';

+ 74 - 240
htdocs/core/modules/stock/doc/pdf_standard.modules.php

@@ -147,7 +147,7 @@ class pdf_standard extends ModelePDFStock
 		if (!$this->emetteur->country_code) $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default if not defined
 
 		// Define position of columns
-		$this->wref = 15;
+		$this->wref = 35;
 		$this->posxdesc = $this->marge_gauche + 1;
 		$this->posxlabel = $this->posxdesc + $this->wref;
 		$this->posxtva = 80;
@@ -189,7 +189,7 @@ class pdf_standard extends ModelePDFStock
 	 *  @param		int			$hideref			Do not show ref
 	 *	@return		int         					1 if OK, <=0 if KO
 	 */
-	public function write_file($object, $outputlangs, $srctemplatepath, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
+	public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
 	{
         // phpcs:enable
 		global $user, $langs, $conf, $mysoc, $db, $hookmanager;
@@ -284,29 +284,29 @@ class pdf_standard extends ModelePDFStock
 				$pdf->AddPage();
 				if (!empty($tplidx)) $pdf->useTemplate($tplidx);
 				$pagenb++;
-				$this->_pagehead($pdf, $object, 1, $outputlangs);
+				$top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
 				$pdf->SetFont('', '', $default_font_size - 1);
 				$pdf->MultiCell(0, 3, ''); // Set interline to 3
 				$pdf->SetTextColor(0, 0, 0);
 
-				$tab_top = 42;
-				$tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 : 10);
+				$tab_top = 80 + $top_shift;
+				$tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10);
+
 				$tab_height = 130;
-				$tab_height_newpage = 150;
+
 
 				/* ************************************************************************** */
 				/*                                                                            */
-				/* Affichage de la liste des produits de l'entrepot                           */
+				/* Show list of product in warehouse                                          */
 				/*                                                                            */
 				/* ************************************************************************** */
 
-				$nexY += 5;
-				$nexY = $pdf->GetY();
-				$nexY += 10;
-
 				$totalunit = 0;
 				$totalvalue = $totalvaluesell = 0;
 
+				$sortfield = 'p.ref';
+				$sortorder = 'ASC';
+
 				$sql = "SELECT p.rowid as rowid, p.ref, p.label as produit, p.tobatch, p.fk_product_type as type, p.pmp as ppmp, p.price, p.price_ttc, p.entity,";
 				$sql .= " ps.reel as value";
 				$sql .= " FROM ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product as p";
@@ -322,8 +322,14 @@ class pdf_standard extends ModelePDFStock
 					$num = $db->num_rows($resql);
 					$i = 0;
 					$nblines = $num;
+
+					$this->tabTitleHeight = 0;
+					$nexY = $tab_top + $this->tabTitleHeight;
+
 					for ($i = 0; $i < $nblines; $i++)
 					{
+						$curY = $nexY;
+
 						$objp = $db->fetch_object($resql);
 
 						// Multilangs
@@ -343,7 +349,6 @@ class pdf_standard extends ModelePDFStock
 							}
 						}
 
-						$curY = $nexY;
 						$pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
 						$pdf->SetTextColor(0, 0, 0);
 
@@ -418,7 +423,7 @@ class pdf_standard extends ModelePDFStock
 
 						// Label
 						$pdf->SetXY($this->posxlabel + 0.8, $curY);
-						$pdf->MultiCell($this->posxqty - $this->posxlabel - 0.8, 3, $objp->produit, 0, 'L');
+						$pdf->MultiCell($this->posxqty - $this->posxlabel - 0.8, 3, dol_trunc($objp->produit, 24), 0, 'L');
 
 						// Quantity
 						$valtoshow = price2num($objp->value, 'MS');
@@ -427,6 +432,7 @@ class pdf_standard extends ModelePDFStock
 						$pdf->SetXY($this->posxqty, $curY);
 						$pdf->MultiCell($this->posxup - $this->posxqty - 0.8, 3, $towrite, 0, 'R');
 
+						// AWP
 						$totalunit += $objp->value;
 
 						$pdf->SetXY($this->posxup, $curY);
@@ -498,45 +504,50 @@ class pdf_standard extends ModelePDFStock
 					$db->free($resql);
 
 					/**
-					 * footer table
+					 * Footer table
 					 */
 					$nexY = $pdf->GetY();
 					$nexY += 2;
 					$curY = $nexY;
 
-					$pdf->SetLineStyle(array('dash'=>'0', 'color'=>array(220, 26, 26)));
-					$pdf->line($this->marge_gauche, $curY - 1, $this->page_largeur - $this->marge_droite, $curY - 1);
-					$pdf->SetLineStyle(array('dash'=>0));
+					if (! $object->specimen) {
+						$pdf->SetLineStyle(array('dash'=>'0', 'color'=>array(200, 200, 200)));
+						$pdf->line($this->marge_gauche, $curY - 1, $this->page_largeur - $this->marge_droite, $curY - 1);
+						$pdf->SetLineStyle(array('dash'=>0));
 
-					$pdf->SetFont('', 'B', $default_font_size - 1);
-					$pdf->SetTextColor(0, 0, 120);
+						$pdf->SetFont('', 'B', $default_font_size - 1);
+						$pdf->SetTextColor(0, 0, 120);
 
-					// Ref.
-					$pdf->SetXY($this->posxdesc, $curY);
-					$pdf->MultiCell($this->wref, 3, $langs->trans("Total"), 0, 'L');
+						// Ref.
+						$pdf->SetXY($this->posxdesc, $curY);
+						$pdf->MultiCell($this->wref, 3, $langs->trans("Total"), 0, 'L');
 
-					// Quantity
-					$valtoshow = price2num($totalunit, 'MS');
-					$towrite = empty($valtoshow) ? '0' : $valtoshow;
+						// Quantity
+						$valtoshow = price2num($totalunit, 'MS');
+						$towrite = empty($valtoshow) ? '0' : $valtoshow;
 
-					$pdf->SetXY($this->posxqty, $curY);
-					$pdf->MultiCell($this->posxup - $this->posxqty - 0.8, 3, $towrite, 0, 'R');
+						$pdf->SetXY($this->posxqty, $curY);
+						$pdf->MultiCell($this->posxup - $this->posxqty - 0.8, 3, $towrite, 0, 'R');
 
-					// Total PMP
-					$pdf->SetXY($this->posxunit, $curY);
-					$pdf->MultiCell($this->posxdiscount - $this->posxunit - 0.8, 3, price(price2num($totalvalue, 'MT'), 0, $outputlangs), 0, 'R');
+						// Total PMP
+						$pdf->SetXY($this->posxunit, $curY);
+						$pdf->MultiCell($this->posxdiscount - $this->posxunit - 0.8, 3, price(price2num($totalvalue, 'MT'), 0, $outputlangs), 0, 'R');
 
-					// Price sell min
-					if (empty($conf->global->PRODUIT_MULTIPRICES))
-					{
-						// Total sell min
-						$pdf->SetXY($this->postotalht, $curY);
-						$pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, price(price2num($totalvaluesell, 'MT'), 0, $outputlangs), 0, 'R', 0);
+						// Price sell min
+						if (empty($conf->global->PRODUIT_MULTIPRICES))
+						{
+							// Total sell min
+							$pdf->SetXY($this->postotalht, $curY);
+							$pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, price(price2num($totalvaluesell, 'MT'), 0, $outputlangs), 0, 'R', 0);
+						}
 					}
 				} else {
 					dol_print_error($db);
 				}
 
+				// Displays notes
+				$notetoshow = empty($object->note_public) ? '' : $object->note_public;
+
 				if ($notetoshow)
 				{
 					$substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
@@ -565,125 +576,7 @@ class pdf_standard extends ModelePDFStock
 				$curY = $tab_top + 7;
 				$nexY = $tab_top + 7;
 
-				// Loop on each lines
-				/*
-				for ($i = 0 ; $i < $nblines ; $i++)
-				{
-					$curY = $nexY;
-					$pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
-					$pdf->SetTextColor(0,0,0);
-
-					$pdf->setTopMargin($tab_top_newpage);
-					$pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
-					$pageposbefore=$pdf->getPage();
-
-					// Description of stock line
-					$curX = $this->posxdesc-1;
-
-					$showpricebeforepagebreak=1;
-
-					$pdf->startTransaction();
-					pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxtva-$curX,3,$curX,$curY,$hideref,$hidedesc);
-					$pageposafter=$pdf->getPage();
-					if ($pageposafter > $pageposbefore)	// There is a pagebreak
-					{
-						$pdf->rollbackTransaction(true);
-						$pageposafter=$pageposbefore;
-						//print $pageposafter.'-'.$pageposbefore;exit;
-						$pdf->setPageOrientation('', 1, $heightforfooter);	// The only function to edit the bottom margin of current page to set it.
-						pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxtva-$curX,4,$curX,$curY,$hideref,$hidedesc);
-						$pageposafter=$pdf->getPage();
-						$posyafter=$pdf->GetY();
-						if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot)))	// There is no space left for total+free text
-						{
-							if ($i == ($nblines-1))	// No more lines, and no space left to show total, so we create a new page
-							{
-								$pdf->AddPage('','',true);
-								if (! empty($tplidx)) $pdf->useTemplate($tplidx);
-								if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
-								$pdf->setPage($pageposafter+1);
-							}
-						}
-						else
-						{
-							// We found a page break
-							$showpricebeforepagebreak=0;
-						}
-					}
-					else	// No pagebreak
-					{
-						$pdf->commitTransaction();
-					}
-
-					$nexY = $pdf->GetY();
-					$pageposafter=$pdf->getPage();
-					$pdf->setPage($pageposbefore);
-					$pdf->setTopMargin($this->marge_haute);
-					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
-
-					// We suppose that a too long description is moved completely on next page
-					if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
-						$pdf->setPage($pageposafter); $curY = $tab_top_newpage;
-					}
-
-					$pdf->SetFont('','',  $default_font_size - 1);   // On repositionne la police par defaut
-
-					// Quantity
-					$qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
-					$pdf->SetXY($this->posxqty, $curY);
-					// Enough for 6 chars
-					$pdf->MultiCell($this->posxdiscount-$this->posxqty-0.8, 4, $qty, 0, 'R');
-
-					// Add line
-					if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1))
-					{
-						$pdf->setPage($pageposafter);
-						$pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80)));
-						//$pdf->SetDrawColor(190,190,200);
-						$pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
-						$pdf->SetLineStyle(array('dash'=>0));
-					}
-
-					$nexY+=2;    // Add space between lines
-
-					// Detect if some page were added automatically and output _tableau for past pages
-					while ($pagenb < $pageposafter)
-					{
-						$pdf->setPage($pagenb);
-						if ($pagenb == 1)
-						{
-							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
-						}
-						else
-						{
-							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
-						}
-						$this->_pagefoot($pdf,$object,$outputlangs,1);
-						$pagenb++;
-						$pdf->setPage($pagenb);
-						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
-						if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
-					}
-					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
-					{
-						if ($pagenb == 1)
-						{
-							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
-						}
-						else
-						{
-							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
-						}
-						$this->_pagefoot($pdf,$object,$outputlangs,1);
-						// New page
-						$pdf->AddPage();
-						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
-						$pagenb++;
-						if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
-					}
-				}
-				*/
-				$tab_top = $tab_top_newpage + 21;
+				$tab_top = $tab_top_newpage + 25 + $top_shift;
 
 				// Show square
 				if ($pagenb == 1)
@@ -783,8 +676,8 @@ class pdf_standard extends ModelePDFStock
 	    // Output Rect
 	    //$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
 
-		$pdf->SetLineStyle(array('dash'=>'0', 'color'=>array(220, 26, 26)));
-		$pdf->SetDrawColor(220, 26, 26);
+		$pdf->SetLineStyle(array('dash'=>'0', 'color'=>array(200, 200, 200)));
+		$pdf->SetDrawColor(200, 200, 200);
 		$pdf->line($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite, $tab_top);
 		$pdf->SetLineStyle(array('dash'=>0));
 		$pdf->SetDrawColor(128, 128, 128);
@@ -800,47 +693,47 @@ class pdf_standard extends ModelePDFStock
 		//$pdf->line($this->posxlabel-1, $tab_top, $this->posxlabel-1, $tab_top + $tab_height);
 		if (empty($hidetop))
 		{
-			$pdf->SetXY($this->posxlabel - 3, $tab_top + 1);
-			$pdf->MultiCell($this->posxqty - $this->posxlabel + 3, 2, $outputlangs->transnoentities("Label"), '', 'C');
+			$pdf->SetXY($this->posxlabel - 1, $tab_top + 1);
+			$pdf->MultiCell($this->posxqty - $this->posxlabel - 1, 2, $outputlangs->transnoentities("Label"), '', 'L');
 		}
 
 	    //$pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height);
 	    if (empty($hidetop))
 	    {
 	        $pdf->SetXY($this->posxqty - 1, $tab_top + 1);
-	        $pdf->MultiCell($this->posxup - $this->posxqty - 1, 2, $outputlangs->transnoentities("Units"), '', 'C');
+	        $pdf->MultiCell($this->posxup - $this->posxqty - 1, 2, $outputlangs->transnoentities("Units"), '', 'R');
 	    }
 
 	    //$pdf->line($this->posxup-1, $tab_top, $this->posxup-1, $tab_top + $tab_height);
 	    if (empty($hidetop))
 	    {
 	        $pdf->SetXY($this->posxup - 1, $tab_top + 1);
-			$pdf->MultiCell($this->posxunit - $this->posxup - 1, 2, $outputlangs->transnoentities("AverageUnitPricePMPShort"), '', 'C');
+			$pdf->MultiCell($this->posxunit - $this->posxup - 1, 2, $outputlangs->transnoentities("AverageUnitPricePMPShort"), '', 'R');
 	    }
 
 		//$pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height);
 		if (empty($hidetop))
 		{
 			$pdf->SetXY($this->posxunit - 1, $tab_top + 1);
-            $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("EstimatedStockValueShort"), '', 'C');
+            $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("EstimatedStockValueShort"), '', 'R');
 		}
 
 	    //$pdf->line($this->posxdiscount-1, $tab_top, $this->posxdiscount-1, $tab_top + $tab_height);
 	    if (empty($hidetop))
 	    {
 			$pdf->SetXY($this->posxdiscount - 1, $tab_top + 1);
-			$pdf->MultiCell($this->postotalht - $this->posxdiscount + 1, 2, $outputlangs->transnoentities("SellPriceMin"), '', 'C');
+			$pdf->MultiCell($this->postotalht - $this->posxdiscount + 1, 2, $outputlangs->transnoentities("SellPriceMin"), '', 'R');
 	    }
 
 	    //$pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
 	    if (empty($hidetop))
 	    {
 	        $pdf->SetXY($this->postotalht - 1, $tab_top + 1);
-	        $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 2, $outputlangs->transnoentities("EstimatedStockValueSellShort"), '', 'C');
+	        $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 2, $outputlangs->transnoentities("EstimatedStockValueSellShort"), '', 'R');
 	    }
 
-		$pdf->SetDrawColor(220, 26, 26);
-		$pdf->SetLineStyle(array('dash'=>'0', 'color'=>array(220, 26, 26)));
+		$pdf->SetDrawColor(200, 200, 200);
+		$pdf->SetLineStyle(array('dash'=>'0', 'color'=>array(200, 200, 200)));
 		$pdf->line($this->marge_gauche, $tab_top + 11, $this->page_largeur - $this->marge_droite, $tab_top + 11);
 		$pdf->SetLineStyle(array('dash'=>0));
 	}
@@ -854,7 +747,7 @@ class pdf_standard extends ModelePDFStock
 	 *  @param  int	    	$showaddress    0=no, 1=yes
 	 *  @param  Translate	$outputlangs	Object lang for output
 	 *  @param	string		$titlekey		Translation key to show as title of document
-	 *  @return	void
+	 *  @return	int                         Return topshift value
 	 */
 	protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey = "")
 	{
@@ -927,21 +820,20 @@ class pdf_standard extends ModelePDFStock
 		$pdf->SetXY($posx - 50, $posy);
 		$pdf->MultiCell(150, 3, $object->lieu, '', 'R');
 
-
-		// Parent entrepot
 		$posy += 4;
 		$pdf->SetXY($posx, $posy);
 		$pdf->SetTextColor(0, 0, 60);
-		$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ParentWarehouse").' :', '', 'R');
 
-		$posy += 4;
-		$pdf->SetXY($posx - 50, $posy);
+		// Parent entrepot
 		$e = new Entrepot($db);
-		if (!empty($object->fk_parent) && $e->fetch($object->fk_parent) > 0)
-		{
+		$hasparent = (!empty($object->fk_parent) && $e->fetch($object->fk_parent) > 0);
+
+		if ($hasparent) {
+			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ParentWarehouse").' :', '', 'R');
+
+			$posy += 4;
+			$pdf->SetXY($posx - 50, $posy);
 			$pdf->MultiCell(150, 3, $e->label, '', 'R');
-		} else {
-			$pdf->MultiCell(150, 3, $outputlangs->transnoentities("None"), '', 'R');
 		}
 
 		// Description
@@ -991,78 +883,20 @@ class pdf_standard extends ModelePDFStock
 		$pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("LastMovement").' : </b>'.$toWrite, 0, 1);
 		$nexY = $pdf->GetY();
 
-
-	    /*if ($object->ref_client)
-	    {
-	        $posy+=5;
-	        $pdf->SetXY($posx,$posy);
-	        $pdf->SetTextColor(0,0,60);
-	        $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
-	    }*/
-
-	    /*$posy+=4;
-	    $pdf->SetXY($posx,$posy);
-	    $pdf->SetTextColor(0,0,60);
-	    $pdf->MultiCell(100, 3, $outputlangs->transnoentities("OrderDate")." : " . dol_print_date($object->date,"%d %b %Y",false,$outputlangs,true), '', 'R');
-	    */
-
-	    // Get contact
-	    /*
-	    if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
-	    {
-	        $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
-	        if (count($arrayidcontact) > 0)
-	        {
-	            $usertmp=new User($this->db);
-	            $usertmp->fetch($arrayidcontact[0]);
-	            $posy+=4;
-	            $pdf->SetXY($posx,$posy);
-	            $pdf->SetTextColor(0,0,60);
-	            $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
-	        }
-	    }*/
-
 	    $posy += 2;
 
+	    $top_shift = 0;
 	    // Show list of linked objects
+	    $current_y = $pdf->getY();
 	    $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
-
-	    if ($showaddress)
+	    if ($current_y < $pdf->getY())
 	    {
-	        /*
-	        // Sender properties
-	        $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty);
-
-	        // Show sender
-	        $posy=42;
-	        $posx=$this->marge_gauche;
-	        if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
-	        $hautcadre=40;
-
-	        // Show sender frame
-	        $pdf->SetTextColor(0,0,0);
-	        $pdf->SetFont('','', $default_font_size - 2);
-	        $pdf->SetXY($posx,$posy-5);
-	        $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
-	        $pdf->SetXY($posx,$posy);
-	        $pdf->SetFillColor(230,230,230);
-	        $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
-	        $pdf->SetTextColor(0,0,60);
-
-	        // Show sender name
-	        $pdf->SetXY($posx+2,$posy+3);
-	        $pdf->SetFont('','B', $default_font_size);
-	        $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
-	        $posy=$pdf->getY();
-
-	        // Show sender information
-	        $pdf->SetXY($posx+2,$posy);
-	        $pdf->SetFont('','', $default_font_size - 1);
-	        $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
-	        */
+	    	$top_shift = $pdf->getY() - $current_y;
 	    }
 
 	    $pdf->SetTextColor(0, 0, 0);
+
+	    return $top_shift;
 	}
 
 	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore

+ 4 - 2
htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php

@@ -356,8 +356,10 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
 					}
 				}
 
-				// Display notes
-				if (!empty($object->note_public))
+				// Displays notes
+				$notetoshow = empty($object->note_public) ? '' : $object->note_public;
+
+				if ($notetoshow)
 				{
 					$tab_top -= 2;
 

+ 4 - 0
htdocs/install/mysql/migration/12.0.0-13.0.0.sql

@@ -40,6 +40,10 @@ ALTER TABLE llx_bom_bom MODIFY COLUMN duration double(24,8);
 
 -- For v13
 
+UPDATE llx_document_model set nom = 'standard' where nom = 'Standard' and type ='stock';
+UPDATE llx_document_model set nom = 'stdmovement', type = 'movement' where nom = 'StdMouvement' and type ='mouvement';
+
+
 UPDATE llx_const SET value = 0 WHERE name = 'FACTURE_TVAOPTION' and value = 'franchise';
 UPDATE llx_const SET value = 1 WHERE name = 'FACTURE_TVAOPTION' and value <> 'franchise' AND value <> '0' AND value <> '1';
 

+ 27 - 30
htdocs/product/stock/card.php

@@ -783,46 +783,43 @@ if ($action == 'create')
 }
 
 /*
- * Documents generes
+ * Documents generated
  */
 
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2)
-{
-	$modulepart = 'stock';
+$modulepart = 'stock';
 
-	if ($action != 'create' && $action != 'edit' && $action != 'delete')
-	{
-		print '<br/>';
-	    print '<div class="fichecenter"><div class="fichehalfleft">';
-	    print '<a name="builddoc"></a>'; // ancre
+if ($action != 'create' && $action != 'edit' && $action != 'delete')
+{
+	print '<br/>';
+    print '<div class="fichecenter"><div class="fichehalfleft">';
+    print '<a name="builddoc"></a>'; // ancre
 
-	    // Documents
-	    $objectref = dol_sanitizeFileName($object->ref);
-	    $relativepath = $comref.'/'.$objectref.'.pdf';
-	    $filedir = $conf->stock->dir_output.'/'.$objectref;
-	    $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
-	    $genallowed = $usercanread;
-	    $delallowed = $usercancreate;
-	    $modulepart = 'stock';
+    // Documents
+    $objectref = dol_sanitizeFileName($object->ref);
+    $relativepath = $comref.'/'.$objectref.'.pdf';
+    $filedir = $conf->stock->dir_output.'/'.$objectref;
+    $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
+    $genallowed = $usercanread;
+    $delallowed = $usercancreate;
+    $modulepart = 'stock';
 
-	    print $formfile->showdocuments($modulepart, $object->ref, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 28, 0, '', 0, '', $object->default_lang, '', $object);
-	    $somethingshown = $formfile->numoffiles;
+    print $formfile->showdocuments($modulepart, $object->ref, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 28, 0, '', 0, '', $object->default_lang, '', $object);
+    $somethingshown = $formfile->numoffiles;
 
-	    print '</div><div class="fichehalfright"><div class="ficheaddleft">';
+    print '</div><div class="fichehalfright"><div class="ficheaddleft">';
 
-	    $MAXEVENT = 10;
+    $MAXEVENT = 10;
 
-	    $morehtmlright = '<a href="'.DOL_URL_ROOT.'/product/agenda.php?id='.$object->id.'">';
-	    $morehtmlright .= $langs->trans("SeeAll");
-	    $morehtmlright .= '</a>';
+    $morehtmlright = '<a href="'.DOL_URL_ROOT.'/product/agenda.php?id='.$object->id.'">';
+    $morehtmlright .= $langs->trans("SeeAll");
+    $morehtmlright .= '</a>';
 
-	    // List of actions on element
-	    include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
-	    $formactions = new FormActions($db);
-	    $somethingshown = $formactions->showactions($object, 'stock', 0, 1, '', $MAXEVENT, '', $morehtmlright); // Show all action for product
+    // List of actions on element
+    include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
+    $formactions = new FormActions($db);
+    $somethingshown = $formactions->showactions($object, 'stock', 0, 1, '', $MAXEVENT, '', $morehtmlright); // Show all action for product
 
-	    print '</div></div></div>';
-	}
+    print '</div></div></div>';
 }
 
 // End of page