summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryhu-odoo <yhu@odoo.com>2020-04-30 16:01:42 +0200
committerSimon Lejeune <sle@openerp.com>2020-06-15 16:59:41 +0200
commit5311f01e65b3d544d00e956e095e37331bf3a4f2 (patch)
treec6e75f81fbf09cb75ac38f0b9daa30dfae18cd73
parent48672703aa92336cb8fcee4984037e364ae7e657 (diff)
[REF] mrp: update MO according to "To Comsume"
Previously, when we upate the "Quantity to Produce" on a MO, we update the components to consume according to the BOM we use. After this commit, we now update the components according their current number set on the MO. For example, if we have a MO to use x component A to produce y product B. When we update the number y to z, the number of A we want to consume will be updated from x to x / y * z, regardless of the setting on the BOM. If multiple components are used, all components will be updated according to this rule. Task: 2241471
-rw-r--r--addons/mrp/models/mrp_production.py19
-rw-r--r--addons/mrp/views/mrp_production_views.xml10
-rw-r--r--addons/mrp/wizard/change_production_qty.py35
3 files changed, 32 insertions, 32 deletions
diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py
index 289454d6a3e..fc3fa98a9f5 100644
--- a/addons/mrp/models/mrp_production.py
+++ b/addons/mrp/models/mrp_production.py
@@ -861,6 +861,25 @@ class MrpProduction(models.Model):
move = self.env['stock.move'].create(move_values)
return move, 0, quantity
+ def _update_raw_moves(self, factor):
+ self.ensure_one()
+ update_info = []
+ move_to_unlink = self.env['stock.move']
+ for move in self.move_raw_ids.filtered(lambda m: m.state not in ('done', 'cancel')):
+ old_qty = move.product_uom_qty
+ new_qty = old_qty * factor
+ if new_qty > 0:
+ move.write({'product_uom_qty': new_qty})
+ move._action_assign()
+ update_info.append((move, old_qty, new_qty))
+ else:
+ if move.quantity_done > 0:
+ raise UserError(_('Lines need to be deleted, but can not as you still have some quantities to consume in them. '))
+ move._action_cancel()
+ move_to_unlink |= move
+ move_to_unlink.unlink()
+ return update_info
+
def _get_ready_to_produce_state(self):
""" returns 'assigned' if enough components are reserved in order to complete
the first operation of the bom. If not returns 'waiting'
diff --git a/addons/mrp/views/mrp_production_views.xml b/addons/mrp/views/mrp_production_views.xml
index a972822f35d..f1d5a82f4d5 100644
--- a/addons/mrp/views/mrp_production_views.xml
+++ b/addons/mrp/views/mrp_production_views.xml
@@ -137,7 +137,11 @@
<field name="qty_producing" digits="[12,3]" class="text-left" attrs="{'readonly': ['|', ('state', '=', 'cancel'), '&amp;', ('state', '=', 'done'), ('is_locked', '=', True)]}"/>
/
</div>
- <field name="product_qty" class="oe_inline text-left" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
+ <field name="product_qty" class="oe_inline text-left" attrs="{'readonly': [('state', '!=', 'draft')], 'invisible': [('state', 'not in', ('draft', 'done'))]}"/>
+ <button type="action" name="%(mrp.action_change_production_qty)d"
+ context="{'default_mo_id': id}" class="oe_link oe_inline" attrs="{'invisible': ['|', ('state', 'in', ('draft', 'done','cancel')), ('id', '=', False)]}">
+ <field name="product_qty" class="oe_inline" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
+ </button>
<label for="product_uom_id" string="" class="oe_inline"/>
<field name="product_uom_category_id" invisible="1"/>
<field name="product_uom_id" options="{'no_open': True, 'no_create': True}" force_save="1" groups="uom.group_uom" attrs="{'readonly': [('state', '!=', 'draft')]}" class="oe_inline"/>
@@ -206,13 +210,9 @@
</group>
<notebook>
<page string="Components" name="components">
-<<<<<<< HEAD
- <field name="move_raw_ids" context="{'default_location_id': location_src_id, 'default_location_dest_id': production_location_id, 'default_state': 'draft', 'default_raw_material_production_id': id, 'default_picking_type_id': picking_type_id, 'default_company_id': company_id}" attrs="{'readonly': ['|', ('state', '=', 'cancel'), '&amp;', ('state', '=', 'done'), ('is_locked', '=', True)]}">
-=======
<field name="move_raw_ids"
context="{'default_date_expected': date_planned_start, 'default_location_id': location_src_id, 'default_location_dest_id': production_location_id, 'default_state': 'draft', 'default_raw_material_production_id': id, 'default_picking_type_id': picking_type_id, 'default_company_id': company_id}"
attrs="{'readonly': ['|', ('state', '=', 'cancel'), '&amp;', ('state', '=', 'done'), ('is_locked', '=', True)]}">
->>>>>>> dd9359b6fbe... fixup! [REF] mrp: no more produce wizard
<tree delete="0" default_order="is_done,sequence" editable="bottom">
<field name="product_id" required="1" attrs="{'readonly': ['|', '|', ('has_move_lines', '=', True), ('state', '=', 'cancel'), '&amp;', ('state', '!=', 'draft'), ('additional', '=', False) ]}"/>
diff --git a/addons/mrp/wizard/change_production_qty.py b/addons/mrp/wizard/change_production_qty.py
index bb589ac9bdb..72d00e9b348 100644
--- a/addons/mrp/wizard/change_production_qty.py
+++ b/addons/mrp/wizard/change_production_qty.py
@@ -53,46 +53,27 @@ class ChangeProductionQty(models.TransientModel):
production.write({'product_qty': wizard.product_qty})
done_moves = production.move_finished_ids.filtered(lambda x: x.state == 'done' and x.product_id == production.product_id)
qty_produced = production.product_id.uom_id._compute_quantity(sum(done_moves.mapped('product_qty')), production.product_uom_id)
- factor = production.product_uom_id._compute_quantity(production.product_qty - qty_produced, production.bom_id.product_uom_id) / production.bom_id.product_qty
- boms, lines = production.bom_id.explode(production.product_id, factor, picking_type=production.bom_id.picking_type_id)
+
+ factor = (production.product_qty - qty_produced) / (old_production_qty - qty_produced)
+ update_info = production._update_raw_moves(factor)
documents = {}
- for line, line_data in lines:
- if line.child_bom_id and line.child_bom_id.type == 'phantom' or\
- line.product_id.type not in ['product', 'consu']:
- continue
- move = production.move_raw_ids.filtered(lambda x: x.bom_line_id.id == line.id and x.state not in ('done', 'cancel'))
- if move:
- move = move[0]
- old_qty = move.product_uom_qty
- else:
- old_qty = 0
+ for move, old_qty, new_qty in update_info:
iterate_key = production._get_document_iterate_key(move)
if iterate_key:
- document = self.env['stock.picking']._log_activity_get_documents({move: (line_data['qty'], old_qty)}, iterate_key, 'UP')
+ document = self.env['stock.picking']._log_activity_get_documents({move: (new_qty, old_qty)}, iterate_key, 'UP')
for key, value in document.items():
if documents.get(key):
documents[key] += [value]
else:
documents[key] = [value]
-
- production._update_raw_move(line, line_data)
production._log_manufacture_exception(documents)
- operation_bom_qty = {}
- for bom, bom_data in boms:
- for operation in bom.operation_ids:
- operation_bom_qty[operation.id] = bom_data['qty']
- finished_moves_modification = self._update_finished_moves(production, production.product_qty - qty_produced, old_production_qty)
+ finished_moves_modification = self._update_finished_moves(production, production.product_qty - qty_produced, old_production_qty - qty_produced)
if finished_moves_modification:
production._log_downside_manufactured_quantity(finished_moves_modification)
- moves = production.move_raw_ids.filtered(lambda x: x.state not in ('done', 'cancel'))
- moves._action_assign()
+
for wo in production.workorder_ids:
operation = wo.operation_id
- if operation_bom_qty.get(operation.id):
- cycle_number = float_round(operation_bom_qty[operation.id] / operation.workcenter_id.capacity, precision_digits=0, rounding_method='UP')
- wo.duration_expected = (operation.workcenter_id.time_start +
- operation.workcenter_id.time_stop +
- cycle_number * operation.time_cycle * 100.0 / operation.workcenter_id.time_efficiency)
+ wo._onchange_expected_duration()
quantity = wo.qty_production - wo.qty_produced
if production.product_id.tracking == 'serial':
quantity = 1.0 if not float_is_zero(quantity, precision_digits=precision) else 0.0