浏览代码

Unit Management for MO lines (#26120)

* Unit Management for products in bom and mo

* WIP

* Unit in to produce tab

* FIX wip

* float val

* Fix Travis

* fk_unit type int

* Clean code

* Clean code

* FIX code sniffer

* Update llx_mrp_production.sql

* Update 18.0.0-19.0.0.sql

---------

Co-authored-by: atm-lena <lena.papazian@atm-consulting.fr>
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
atm-lena 1 年之前
父节点
当前提交
85beb3ea5d

+ 1 - 0
htdocs/bom/bom_card.php

@@ -177,6 +177,7 @@ if (empty($reshook)) {
 			$product = new Product($db);
 			$res = $product->fetch($idprod);
 			if ($res > 0 && $product->type == Product::TYPE_SERVICE) $fk_default_workstation = $product->fk_default_workstation;
+			if (empty($fk_unit)) $fk_unit = $product->fk_unit;
 		}
 
 		if ($qty == '') {

+ 3 - 3
htdocs/bom/class/bom.class.php

@@ -780,9 +780,9 @@ class BOM extends CommonObject
 			$line->efficiency = $efficiency;
 			$line->import_key = $import_key;
 			$line->position = $rankToUse;
-			if (!empty($fk_unit)) {
-				$line->fk_unit = $fk_unit;
-			}
+
+			if (!empty($fk_unit)) $line->fk_unit = $fk_unit;
+
 
 			if (is_array($array_options) && count($array_options) > 0) {
 				// We replace values in this->line->array_options only for entries defined into $array_options

+ 2 - 1
htdocs/bom/tpl/objectline_edit.tpl.php

@@ -128,7 +128,8 @@ print '</td>';
 if ($filtertype != 1) {
 	if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
 		$coldisplay++;
-		print '<td class="nobottom linecoluseunit left">';
+		print '<td class="nobottom nowrap linecolunit right">';
+		print  $formproduct->selectMeasuringUnits("fk_unit",  '',  (($line->fk_unit) ? $line->fk_unit : ''),  0,  0);
 		print '</td>';
 	}
 

+ 1 - 1
htdocs/bom/tpl/objectline_view.tpl.php

@@ -128,7 +128,7 @@ print '</td>';
 if ($filtertype != 1) {
 	if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
 		print '<td class="linecoluseunit nowrap left">';
-		$label = $tmpproduct->getLabelOfUnit('long');
+		$label = measuringUnitString($line->fk_unit, '',  '', 1);
 		if ($label !== '') {
 			print $langs->trans($label);
 		}

+ 4 - 0
htdocs/install/mysql/migration/18.0.0-19.0.0.sql

@@ -173,3 +173,7 @@ ALTER TABLE llx_facturedet ADD COLUMN fk_warehouse integer NULL;	-- To store the
 
 ALTER TABLE llx_multicurrency_rate ADD COLUMN rate_indirect double DEFAULT 0;
 
+ALTER TABLE llx_mrp_production ADD COLUMN fk_unit integer DEFAULT NULL;
+-- VMYSQL4.1 UPDATE llx_mrp_production as mp INNER JOIN llx_bom_bomline as bbl ON mp.origin_id = bbl.rowid SET mp.fk_unit = bbl.fk_unit WHERE mp.origin_type = 'bomline' AND mk.fk_unit IS NULL;
+-- VMYSQL4.1 UPDATE llx_bom_bomline as bbl INNER JOIN llx_product as p ON p.rowid = bbl.fk_product SET bbl.fk_unit = p.fk_unit WHERE bbl.fk_unit IS NULL;
+

+ 2 - 1
htdocs/install/mysql/tables/llx_mrp_production.sql

@@ -34,6 +34,7 @@ CREATE TABLE llx_mrp_production(
 	fk_user_creat integer NOT NULL, 
 	fk_user_modif integer, 
 	import_key varchar(14),
-	fk_default_workstation integer DEFAULT NULL
+	fk_default_workstation integer DEFAULT NULL,
+	fk_unit integer DEFAULT NULL
 ) ENGINE=innodb;
 

+ 13 - 2
htdocs/mrp/class/mo.class.php

@@ -584,7 +584,8 @@ class Mo extends CommonObject
 						'fk_product' => $obj->fk_product,
 						'fk_warehouse' => $obj->fk_warehouse,
 						'batch' => $obj->batch,
-						'fk_stock_movement' => $obj->fk_stock_movement
+						'fk_stock_movement' => $obj->fk_stock_movement,
+						'fk_unit' => $obj->fk_unit
 					);
 				}
 
@@ -696,6 +697,9 @@ class Mo extends CommonObject
 			$moline->qty = $this->qty;
 			$moline->fk_product = $this->fk_product;
 			$moline->position = 1;
+			$tmpproduct = new Product($this->db);
+			$tmpproduct->fetch($this->fk_product);
+			$moline->fk_unit = $tmpproduct->fk_unit;
 
 			if ($this->fk_bom > 0) {	// If a BOM is defined, we know what to produce.
 				include_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
@@ -734,6 +738,7 @@ class Mo extends CommonObject
 							$moline->fk_mo = $this->id;
 							$moline->origin_id = $line->id;
 							$moline->origin_type = 'bomline';
+							if (!empty($line->fk_unit)) $moline->fk_unit = $line->fk_unit;
 							if ($line->qty_frozen) {
 								$moline->qty = $line->qty; // Qty to consume does not depends on quantity to produce
 							} else {
@@ -1691,6 +1696,9 @@ class Mo extends CommonObject
 		} else {
 			print ' <span class="opacitymedium">('.$langs->trans("ForAQuantityToConsumeOf", $this->bom->qty).')</span>';
 		}
+		// Unit
+		print '<td class="right">'.$langs->trans('Unit');
+
 		print '</td>';
 		print '<td class="center">'.$form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1).'</td>';
 		print '<td class="center">'.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).'</td>';
@@ -1760,6 +1768,7 @@ class Mo extends CommonObject
 		$this->tpl['seuil_stock_alerte'] = $productstatic->seuil_stock_alerte;
 		$this->tpl['virtual_stock'] = $productstatic->stock_theorique;
 		$this->tpl['qty'] = $line->qty;
+		$this->tpl['fk_unit'] = $line->fk_unit;
 		$this->tpl['qty_frozen'] = $line->qty_frozen;
 		$this->tpl['disable_stock_change'] = $line->disable_stock_change;
 		$this->tpl['efficiency'] = $line->efficiency;
@@ -1985,7 +1994,8 @@ class MoLine extends CommonObjectLine
 		'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>170),
 		'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModification', 'enabled'=>1, 'visible'=>-1, 'position'=>175),
 		'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'position'=>180),
-		'fk_default_workstation' =>array('type'=>'integer', 'label'=>'DefaultWorkstation', 'enabled'=>1, 'visible'=>1, 'notnull'=>0, 'position'=>185)
+		'fk_default_workstation' =>array('type'=>'integer', 'label'=>'DefaultWorkstation', 'enabled'=>1, 'visible'=>1, 'notnull'=>0, 'position'=>185),
+		'fk_unit' =>array('type'=>'int', 'label'=>'Unit', 'enabled'=>1, 'visible'=>1, 'notnull'=>0, 'position'=>186)
 	);
 
 	public $rowid;
@@ -2009,6 +2019,7 @@ class MoLine extends CommonObjectLine
 	public $fk_user_modif;
 	public $import_key;
 	public $fk_parent_line;
+	public $fk_unit;
 
 	/**
 	 * @var int Service Workstation

+ 28 - 0
htdocs/mrp/mo_production.php

@@ -203,6 +203,7 @@ if (empty($reshook)) {
 				$moline->fk_default_workstation = $tmpproduct->fk_default_workstation;
 			}
 			$moline->disable_stock_change = ($tmpproduct->type == Product::TYPE_SERVICE ? 1 : 0);
+			if ($conf->global->PRODUCT_USE_UNITS) $moline->fk_unit = $tmpproduct->fk_unit;
 		}
 
 		$resultline = $moline->create($user, false); // Never use triggers here
@@ -812,6 +813,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 		print '<td>'.$langs->trans("Product").'</td>';
 		// Qty
 		print '<td class="right">'.$langs->trans("Qty").'</td>';
+		// Unit
+		if ($conf->global->PRODUCT_USE_UNITS) print '<td class="right">' . $langs->trans("Unit") . '</td>';
 		// Cost price
 		if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) {
 			print '<td class="right">'.$langs->trans("UnitCost").'</td>';
@@ -977,6 +980,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 						print '<td class="right nowraponall">';
 						print '<input name="qty_lineProduce" type="number" value="'. $line->qty.'" width="25px">';
 						print '</td>';
+						// Unit
+						if ($conf->global->PRODUCT_USE_UNITS) {
+							print '<td class="right nowraponall">';
+							print measuringUnitString($line->fk_unit, '', '', 1);
+							print '</td>';
+						}
 						// Qty consumed
 						print '<td class="right">';
 						print ' ' . price2num($alreadyconsumed, 'MS');
@@ -1033,6 +1042,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 						}
 						print price2num($line->qty, 'MS');
 						print '</td>';
+						// Unit
+						if ($conf->global->PRODUCT_USE_UNITS) {
+							print '<td class="right nowraponall">';
+							print measuringUnitString($line->fk_unit, '', '', 1);
+							print '</td>';
+						}
 						// Cost price
 						if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) {
 							print '<td class="right nowraponall">';
@@ -1228,6 +1243,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 						// Qty
 						print '<td class="right"><input type="text" class="width50 right" id="qtytoconsume-' . $line->id . '-' . $i . '" name="qty-' . $line->id . '-' . $i . '" value="' . $preselected . '" ' . $disable . '></td>';
 
+						// Unit
+						if ($conf->global->PRODUCT_USE_UNITS)  print '<td></td>';
+
 						// Cost
 						if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) {
 							print '<td></td>';
@@ -1348,6 +1366,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 		print '<td>'.$langs->trans("Product").'</td>';
 		// Qty
 		print '<td class="right">'.$langs->trans("Qty").'</td>';
+		/// Unit
+		if ($conf->global->PRODUCT_USE_UNITS) print '<td class="right">'.$langs->trans("Unit").'</td>';
 		// Cost price
 		if ($permissiontoupdatecost) {
 			if (empty($bomcostupdated)) {
@@ -1397,6 +1417,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 			print '</td>';
 			// Qty
 			print '<td class="right"><input type="text" name="qtytoadd" value="1" class="width50 right"></td>';
+			//Unit
+			if ($conf->global->PRODUCT_USE_UNITS) print '<td></td>';
 			// Cost price
 			if ($permissiontoupdatecost) {
 				print '<td></td>';
@@ -1460,6 +1482,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 					print '</td>';
 					// Qty
 					print '<td class="right">'.$line->qty.'</td>';
+					// Unit
+					if ($conf->global->PRODUCT_USE_UNITS) print '<td class="right">'.measuringUnitString($line->fk_unit, '', '', 1).'</td>';
 					// Cost price
 					if ($permissiontoupdatecost) {
 						// Defined $manufacturingcost
@@ -1555,6 +1579,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 						print '</td>';
 						// Qty
 						print '<td></td>';
+						// Unit
+						if ($conf->global->PRODUCT_USE_UNITS) print '<td></td>';
 						// Cost price
 						if ($permissiontoupdatecost) {
 							print '<td></td>';
@@ -1604,6 +1630,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 						}
 						// Qty
 						print '<td class="right"><input type="text" class="width50 right" id="qtytoproduce-'.$line->id.'-'.$i.'" name="qtytoproduce-'.$line->id.'-'.$i.'" value="'.$preselected.'"></td>';
+						//Unit
+						if ($conf->global->PRODUCT_USE_UNITS) print '<td class="right"></td>';
 						// Cost
 						if ($permissiontoupdatecost) {
 							// Defined $manufacturingcost

+ 5 - 0
htdocs/mrp/tpl/originproductline.tpl.php

@@ -61,6 +61,8 @@ if ($res) {
 print '</td>';
 // Qty
 print '<td class="right">'.$this->tpl['qty'].(($this->tpl['efficiency'] > 0 && $this->tpl['efficiency'] < 1) ? ' / '.$form->textwithpicto($this->tpl['efficiency'], $langs->trans("ValueOfMeansLoss")).' = '.$qtytoconsumeforline : '').'</td>';
+// Unit
+print '<td class="right">'.measuringUnitString($this->tpl['fk_unit'], '', '', 1).'</td>';
 print '<td class="center">'.(empty($this->tpl['stock']) ? 0 : price2num($this->tpl['stock'], 'MS'));
 if ($this->tpl['seuil_stock_alerte'] != '' && ($this->tpl['stock'] < $this->tpl['seuil_stock_alerte'])) {
 	print ' '.img_warning($langs->trans("StockLowerThanLimit", $this->tpl['seuil_stock_alerte']));
@@ -137,6 +139,9 @@ if ($resql) {
 			print '<td class="linecolqty nowrap right" id="sub_bom_qty_'.$sub_bom_line->id.'">'.price($sub_bom_line->qty * $line->qty, 0, '', 0, 0).'</td>';
 		}
 
+		// Unit
+		print '<td class="linecolunit nowrap right" id="sub_bom_unit_'.$sub_bom_line->id.'">'.measuringUnitString($sub_bom_line->fk_unit, '', '', 1).'</td>';
+
 		// Stock réel
 		if ($sub_bom_product->stock_reel > 0) {
 			print '<td class="linecolstockreel nowrap center" id="sub_bom_stock_reel_'.$sub_bom_product->stock_reel.'">'.$sub_bom_product->stock_reel.'</td>';