2
0
forked from Wavyzz/dolibarr

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>
This commit is contained in:
atm-lena
2023-11-06 11:15:43 +01:00
committed by GitHub
parent 78f1b2f02b
commit 85beb3ea5d
9 changed files with 59 additions and 8 deletions

View File

@@ -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 == '') {

View File

@@ -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

View File

@@ -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>';
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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>';