summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/mrp/models/mrp_production.py5
-rw-r--r--addons/mrp/models/mrp_workorder.py7
-rw-r--r--addons/mrp/tests/test_order.py57
-rw-r--r--addons/mrp/wizard/change_production_qty.py2
4 files changed, 68 insertions, 3 deletions
diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py
index 8594263bc64..5afd01bd5cc 100644
--- a/addons/mrp/models/mrp_production.py
+++ b/addons/mrp/models/mrp_production.py
@@ -574,7 +574,10 @@ class MrpProduction(models.Model):
def _onchange_product_qty(self):
for workorder in self.workorder_ids:
workorder.product_uom_id = self.product_uom_id
- workorder.duration_expected = workorder._get_duration_expected()
+ if self._origin.product_qty:
+ workorder.duration_expected = workorder._get_duration_expected(ratio=self.product_qty / self._origin.product_qty)
+ else:
+ workorder.duration_expected = workorder._get_duration_expected()
if workorder.date_planned_start and workorder.duration_expected:
workorder.date_planned_finished = workorder.date_planned_start + relativedelta(minutes=workorder.duration_expected)
diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py
index f100c361984..5ffb7ffc860 100644
--- a/addons/mrp/models/mrp_workorder.py
+++ b/addons/mrp/models/mrp_workorder.py
@@ -671,10 +671,15 @@ class MrpWorkorder(models.Model):
for wo in self:
wo.qty_remaining = float_round(wo.qty_production - wo.qty_produced, precision_rounding=wo.production_id.product_uom_id.rounding)
- def _get_duration_expected(self, alternative_workcenter=False):
+ def _get_duration_expected(self, alternative_workcenter=False, ratio=1):
self.ensure_one()
if not self.workcenter_id:
return False
+ if not self.operation_id:
+ duration_expected_working = (self.duration_expected - self.workcenter_id.time_start - self.workcenter_id.time_stop) * self.workcenter_id.time_efficiency / 100.0
+ if duration_expected_working < 0:
+ duration_expected_working = 0
+ return self.workcenter_id.time_start + self.workcenter_id.time_stop + duration_expected_working * ratio * 100.0 / self.workcenter_id.time_efficiency
qty_production = self.production_id.product_uom_id._compute_quantity(self.qty_production, self.production_id.product_id.uom_id)
cycle_number = float_round(qty_production / self.workcenter_id.capacity, precision_digits=0, rounding_method='UP')
if alternative_workcenter:
diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py
index cd7015a90ce..3dfa1500625 100644
--- a/addons/mrp/tests/test_order.py
+++ b/addons/mrp/tests/test_order.py
@@ -259,6 +259,63 @@ class TestMrpOrder(TestMrpCommon):
self.assertEqual(sum(mo.move_raw_ids.filtered(lambda m: m.product_id == p1).mapped('quantity_done')), 20)
self.assertEqual(sum(mo.move_finished_ids.mapped('quantity_done')), 5)
+ def test_update_quantity_3(self):
+ bom = self.env['mrp.bom'].create({
+ 'product_id': self.product_6.id,
+ 'product_tmpl_id': self.product_6.product_tmpl_id.id,
+ 'product_qty': 1,
+ 'product_uom_id': self.product_6.uom_id.id,
+ 'type': 'normal',
+ 'bom_line_ids': [
+ (0, 0, {'product_id': self.product_2.id, 'product_qty': 2.03}),
+ (0, 0, {'product_id': self.product_8.id, 'product_qty': 4.16})
+ ],
+ 'operation_ids': [
+ (0, 0, {'name': 'Gift Wrap Maching', 'workcenter_id': self.workcenter_1.id, 'time_cycle': 15, 'sequence': 1}),
+ ]
+ })
+ production_form = Form(self.env['mrp.production'])
+ production_form.product_id = self.product_6
+ production_form.bom_id = bom
+ production_form.product_qty = 1
+ production_form.product_uom_id = self.product_6.uom_id
+ production = production_form.save()
+ self.assertEqual(production.workorder_ids.duration_expected, 90)
+ mo_form = Form(production)
+ mo_form.product_qty = 3
+ production = mo_form.save()
+ self.assertEqual(production.workorder_ids.duration_expected, 165)
+
+ def test_update_quantity_4(self):
+ bom = self.env['mrp.bom'].create({
+ 'product_id': self.product_6.id,
+ 'product_tmpl_id': self.product_6.product_tmpl_id.id,
+ 'product_qty': 1,
+ 'product_uom_id': self.product_6.uom_id.id,
+ 'type': 'normal',
+ 'bom_line_ids': [
+ (0, 0, {'product_id': self.product_2.id, 'product_qty': 2.03}),
+ (0, 0, {'product_id': self.product_8.id, 'product_qty': 4.16})
+ ],
+ })
+ production_form = Form(self.env['mrp.production'])
+ production_form.product_id = self.product_6
+ production_form.bom_id = bom
+ production_form.product_qty = 1
+ production_form.product_uom_id = self.product_6.uom_id
+ production = production_form.save()
+ production_form = Form(production)
+ with production_form.workorder_ids.new() as wo:
+ wo.name = 'OP1'
+ wo.workcenter_id = self.workcenter_1
+ wo.duration_expected = 40
+ production = production_form.save()
+ self.assertEqual(production.workorder_ids.duration_expected, 40)
+ mo_form = Form(production)
+ mo_form.product_qty = 3
+ production = mo_form.save()
+ self.assertEqual(production.workorder_ids.duration_expected, 90)
+
def test_rounding(self):
""" Checks we round up when bringing goods to produce and round half-up when producing.
This implementation allows to implement an efficiency notion (see rev 347f140fe63612ee05e).
diff --git a/addons/mrp/wizard/change_production_qty.py b/addons/mrp/wizard/change_production_qty.py
index cd82ca389f6..9170d3eff2d 100644
--- a/addons/mrp/wizard/change_production_qty.py
+++ b/addons/mrp/wizard/change_production_qty.py
@@ -78,7 +78,7 @@ class ChangeProductionQty(models.TransientModel):
for wo in production.workorder_ids:
operation = wo.operation_id
- wo._onchange_expected_duration()
+ wo.duration_expected = wo._get_duration_expected(ratio=new_production_qty / old_production_qty)
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