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();