diff --git a/addons/sale_timesheet/models/sale_order.py b/addons/sale_timesheet/models/sale_order.py index 4d9d707f333..2c80fa04888 100644 --- a/addons/sale_timesheet/models/sale_order.py +++ b/addons/sale_timesheet/models/sale_order.py @@ -177,6 +177,19 @@ class SaleOrderLine(models.Model): line.order_id.message_post(body=msg_body) return line + @api.multi + def write(self, values): + result = super(SaleOrderLine, self).write(values) + # changing the ordered quantity should change the planned hours on the + # task, whatever the SO state. It will be blocked by the super in case + # of a locked sale order. + if 'product_uom_qty' in values: + for line in self: + if line.task_id: + planned_hours = line._convert_qty_company_hours() + line.task_id.write({'planned_hours': planned_hours}) + return result + ########################################### # Service : Project and task generation ########################################### diff --git a/addons/sale_timesheet/tests/test_sale_service.py b/addons/sale_timesheet/tests/test_sale_service.py index 0fd318085a0..e0b9c44669e 100644 --- a/addons/sale_timesheet/tests/test_sale_service.py +++ b/addons/sale_timesheet/tests/test_sale_service.py @@ -373,3 +373,28 @@ class TestSaleService(TestCommonSaleTimesheetNoChart): subtask.write({'project_id': self.project_global.id}) self.assertEqual(subtask.sale_line_id, task.sale_line_id, "A child task should always have the same SO line than its mother, even when changing project") + + def test_change_ordered_qty(self): + """ Changing the ordered quantity of a SO line that have created a task should update the planned hours of this task """ + sale_order_line = self.env['sale.order.line'].create({ + 'order_id': self.sale_order.id, + 'name': self.product_delivery_timesheet2.name, + 'product_id': self.product_delivery_timesheet2.id, + 'product_uom_qty': 50, + 'product_uom': self.product_delivery_timesheet2.uom_id.id, + 'price_unit': self.product_delivery_timesheet2.list_price + }) + + self.sale_order.action_confirm() + self.assertEqual(sale_order_line.product_uom_qty, sale_order_line.task_id.planned_hours, "The planned hours should be the same as the ordered quantity of the native SO line") + + sale_order_line.write({'product_uom_qty': 20}) + self.assertEqual(sale_order_line.product_uom_qty, sale_order_line.task_id.planned_hours, "The planned hours should have changed when updating the ordered quantity of the native SO line") + + self.sale_order.action_cancel() + sale_order_line.write({'product_uom_qty': 30}) + self.assertEqual(sale_order_line.product_uom_qty, sale_order_line.task_id.planned_hours, "The planned hours should have changed when updating the ordered quantity, even after SO cancellation") + + self.sale_order.action_done() + with self.assertRaises(UserError): + sale_order_line.write({'product_uom_qty': 20})