diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 22819090b4b..ca5a20b1d20 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -99,6 +99,11 @@ class MrpProduction(models.Model): states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}) date_start = fields.Datetime('Start Date', copy=False, index=True, readonly=True) date_finished = fields.Datetime('End Date', copy=False, index=True, readonly=True) + date_start_wo = fields.Datetime( + 'Planning Start Date', copy=False, readonly=True, + states={'draft': [('readonly', False)], 'confirmed': [('readonly', False)]}, + help="The work orders will be planned based on the availability of the work centers starting from " + "this date. If emtpy, the work orders are planned as soon as possible.") bom_id = fields.Many2one( 'mrp.bom', 'Bill of Material', readonly=True, states={'draft': [('readonly', False)]}, @@ -615,7 +620,7 @@ class MrpProduction(models.Model): return True def _get_start_date(self): - return datetime.now() + return self.date_start_wo or datetime.now() def plan_workorders(self): WorkOrder = self.env['mrp.workorder'] @@ -661,7 +666,11 @@ class MrpProduction(models.Model): start_date = from_date + relativedelta(minutes=duration) def button_unplan(self): - self.mapped('workorder_ids').write({'date_planned_start': False, 'date_planned_finished': False}) + if any(wo.state == 'done' for wo in self.workorder_ids): + raise UserError(_("Some work orders are already done, you cannot unplan this manufacturing order.")) + elif any(wo.state == 'progress' for wo in self.workorder_ids): + raise UserError(_("Some work orders have already started, you cannot unplan this manufacturing order.")) + self.workorder_ids.unlink() @api.multi def _generate_workorders(self, exploded_boms): diff --git a/addons/mrp/tests/test_workorder_operation.py b/addons/mrp/tests/test_workorder_operation.py index 1a3f1a82b9b..fcfce68733d 100644 --- a/addons/mrp/tests/test_workorder_operation.py +++ b/addons/mrp/tests/test_workorder_operation.py @@ -598,3 +598,29 @@ class TestWorkOrderProcess(common.TransactionCase): # Check that the workorder is planned now and that it lasts one hour self.assertAlmostEqual(workorder.date_planned_start, datetime.now(), delta=timedelta(seconds=10), msg="Workorder should be planned now.") self.assertAlmostEqual(workorder.date_planned_finished, datetime.now() + timedelta(hours=1), delta=timedelta(seconds=10), msg="Workorder should be done in an hour.") + + def test_04b_test_planning_date(self): + """ Test that workorder are planned at the correct time when setting a start date """ + # Remove attendances linked to the calendar, this means that the workcenter is working 24/7 + self.env['resource.calendar'].search([]).write({'attendance_ids': [(5, False, False)]}) + + dining_table = self.env.ref("mrp.product_product_computer_desk") + + date_start = datetime.now() + timedelta(days=1) + + production_table_form = Form(self.env['mrp.production']) + production_table_form.product_id = dining_table + production_table_form.bom_id = self.env.ref("mrp.mrp_bom_desk") + production_table_form.product_qty = 1.0 + production_table_form.product_uom_id = dining_table.uom_id + production_table_form.date_start_wo = date_start + production_table = production_table_form.save() + production_table.action_confirm() + + # Create work order + production_table.button_plan() + workorder = production_table.workorder_ids[0] + + # Check that the workorder is planned now and that it lasts one hour + self.assertEqual(workorder.date_planned_start, date_start, msg="Workorder should be planned tomorrow.") + self.assertEqual(workorder.date_planned_finished, date_start + timedelta(hours=1), msg="Workorder should be done one hour later.") diff --git a/addons/mrp/views/mrp_production_views.xml b/addons/mrp/views/mrp_production_views.xml index 3c4ded7af34..bad8cf77f3a 100644 --- a/addons/mrp/views/mrp_production_views.xml +++ b/addons/mrp/views/mrp_production_views.xml @@ -105,6 +105,7 @@ +