diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php
index e42fdf61f25..bf5d0b711ab 100644
--- a/htdocs/mrp/class/mo.class.php
+++ b/htdocs/mrp/class/mo.class.php
@@ -777,49 +777,8 @@ class Mo extends CommonObject
if ($this->fk_bom > 0 && is_object($bom)) { // If a BOM is defined, we know what to consume.
if ($bom->id > 0) {
- // Lines to consume
- if (!$error) {
- foreach ($bom->lines as $line) {
- $moline = new MoLine($this->db);
-
- $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 {
- $moline->qty = (float) price2num(($line->qty / (!empty($bom->qty) ? $bom->qty : 1)) * $this->qty / (!empty($line->efficiency) ? $line->efficiency : 1), 'MS'); // Calculate with Qty to produce and more presition
- }
- if ($moline->qty <= 0) {
- $error++;
- $this->error = "BadValueForquantityToConsume";
- $this->errors[] = $this->error;
- break;
- } else {
- $moline->fk_product = $line->fk_product;
- $moline->role = $role;
- $moline->position = $line->position;
- $moline->qty_frozen = $line->qty_frozen;
- $moline->disable_stock_change = $line->disable_stock_change;
- if (!empty($line->fk_default_workstation)) {
- $moline->fk_default_workstation = $line->fk_default_workstation;
- }
-
- $resultline = $moline->create($user, 0); // Never use triggers here
- if ($resultline <= 0) {
- $error++;
- $this->error = $moline->error;
- $this->errors[] = $moline->error;
- $this->errors = array_merge($this->errors, $moline->errors);
- dol_print_error($this->db, $moline->error, $moline->errors);
- break;
- }
- }
- }
- }
+ // process lines to consume, this needs to recurse through BOM's
+ $error += $this->processBOM($user, $role, $bom, $this->qty);
}
}
}
@@ -833,6 +792,69 @@ class Mo extends CommonObject
}
}
+
+ /**
+ * Recurse through BOM only adding products to list to consume/produce
+ *
+ * @param User $user User that modifies
+ * @param string $role MoLine Role that products are added as
+ * @param BOM $bom BOM to parse lines from
+ * @param float $quantity Quantity modifier for sub products/BOM
+ * @return int Return integer <0 if KO, >0 if OK
+ */
+ public function processBOM(User $user, $role, $bom, $quantity)
+ {
+ $error = 0;
+
+ $quantity /= $bom->qty;
+ foreach ($bom->lines as $line) {
+ $quantity_line = !$line->qty_frozen ? $line->qty * $quantity / (!empty($line->efficiency) ? $line->efficiency : 1) : 1;
+
+ $tmpproduct = new Product($this->db);
+ $tmpproduct->fetch($line->fk_product);
+ if ($line->fk_bom_child > 0) {
+ $bom = new BOM($this->db);
+ $bom->fetch((int) $line->fk_bom_child);
+ $error += $this->processBOM($user, $role, $bom, $quantity_line);
+ } else {
+ $moline = new MoLine($this->db);
+ $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;
+ }
+
+ $moline->qty = (float) price2num($quantity_line, 'MS'); // Calculate with Qty to produce and more presition
+ if ($moline->qty <= 0) {
+ $error++;
+ $this->error = "BadValueForquantityToConsume";
+ $this->errors[] = $this->error;
+ } else {
+ $moline->fk_product = $line->fk_product;
+ $moline->role = $role;
+ $moline->position = $line->position;
+ $moline->qty_frozen = $line->qty_frozen;
+ $moline->disable_stock_change = $line->disable_stock_change;
+ if (!empty($line->fk_default_workstation)) {
+ $moline->fk_default_workstation = $line->fk_default_workstation;
+ }
+ $resultline = $moline->create($user, 0); // Never use triggers here
+ if ($resultline <= 0) {
+ $error++;
+ $this->error = $moline->error;
+ $this->errors[] = $moline->error;
+ $this->errors = array_merge($this->errors, $moline->errors);
+ dol_print_error($this->db, $moline->error, $moline->errors);
+ }
+ }
+ }
+ if ($error) break;
+ }
+ return $error;
+ }
+
+
/**
* Update quantities in lines to consume and/or lines to produce.
*
diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php
index 3dcca3373ca..53621bbd866 100644
--- a/htdocs/mrp/mo_card.php
+++ b/htdocs/mrp/mo_card.php
@@ -544,6 +544,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
}
+ // Reload BOM to consume and produce
+ if ($action == 'reload') {
+ $object->createProduction($user, 0);
+ }
+
// Confirmation of validation
if ($action == 'validate') {
// We check that object has a temporary ref
@@ -804,6 +809,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
}
}
+ // Reload BOM
+ if ($object->status == $object::STATUS_DRAFT && $object->fk_bom > 0) {
+ if ($permissiontoadd) {
+ print ''.$langs->trans("Reload").'';
+ } else {
+ print ''.$langs->trans('Reload').''."\n";
+ }
+ }
+
// Validate
if ($object->status == $object::STATUS_DRAFT) {
if ($permissiontoadd) {
diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php
index 86e926b1770..1d0e6b249ea 100644
--- a/htdocs/mrp/mo_production.php
+++ b/htdocs/mrp/mo_production.php
@@ -550,7 +550,7 @@ llxHeader('', $title, $help_url, '', 0, 0, $morejs, '', '', 'mod-mrp page-card_p
$newToken = newToken();
// Part to show record
-if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
+if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create' && $action != 'reload'))) {
$res = $object->fetch_thirdparty();
$res = $object->fetch_optionals();