[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
This commit is contained in:
yhu-odoo
2020-06-15 16:59:41 +02:00
committed by Simon Lejeune
parent 48672703aa
commit 5311f01e65
3 changed files with 32 additions and 32 deletions
+19
View File
@@ -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'
+5 -5
View File
@@ -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) ]}"/>
+8 -27
View File
@@ -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