diff --git a/bemade_fsm/models/fsm_visit.py b/bemade_fsm/models/fsm_visit.py index 988d556..c610fc1 100644 --- a/bemade_fsm/models/fsm_visit.py +++ b/bemade_fsm/models/fsm_visit.py @@ -5,9 +5,9 @@ class FSMVisit(models.Model): _name = "bemade_fsm.visit" _description = 'Represents a single visit by assigned service personnel.' - label = fields.Text(string="Label", required=True, related='so_section_id.name', readonly=False) + label = fields.Text(string="Label", required=True, related='so_section_id.name', readonly=False, copy=True) - approx_date = fields.Date(string='Approximate Date') + approx_date = fields.Date(string='Approximate Date', copy=False) so_section_id = fields.Many2one( comodel_name="sale.order.line", @@ -19,7 +19,7 @@ class FSMVisit(models.Model): sale_order_id = fields.Many2one( comodel_name="sale.order", string="Sales Order", - required=True + readonly=True, ) is_completed = fields.Boolean(string="Completed", related="so_section_id.is_fully_delivered") @@ -61,10 +61,10 @@ class FSMVisit(models.Model): @api.model_create_multi def create(self, vals_list): recs = super().create(vals_list) - for i, rec in enumerate(recs): + for i, rec in enumerate(recs.filtered(lambda visit: not visit.so_section_id)): rec.so_section_id = rec.env['sale.order.line'].create({ 'order_id': rec.sale_order_id.id, 'display_type': 'line_section', - 'name': vals_list[i]['label'], + 'name': vals_list[i].get('label', False), }) return recs diff --git a/bemade_fsm/models/sale_order.py b/bemade_fsm/models/sale_order.py index cd69b0a..15b23df 100644 --- a/bemade_fsm/models/sale_order.py +++ b/bemade_fsm/models/sale_order.py @@ -54,7 +54,7 @@ class SaleOrder(models.Model): def get_relevant_order_lines(self, task_id): self.ensure_one() linked_lines = self.order_line.filtered(lambda l: l.task_id == task_id - or l == task_id.visit_id.so_section_id) + or l == task_id.visit_id.so_section_id) visit_lines = linked_lines.filtered(lambda l: l.visit_id) for line in visit_lines: linked_lines |= line.get_section_line_ids() @@ -97,4 +97,7 @@ class SaleOrder(models.Model): def _inverse_default_equipment(self): pass - + def copy(self, default=None): + rec = super().copy(default) + rec.visit_ids = [Command.set(rec.order_line.visit_ids.ids)] + return rec diff --git a/bemade_fsm/models/sale_order_line.py b/bemade_fsm/models/sale_order_line.py index 9b92685..bdab84f 100644 --- a/bemade_fsm/models/sale_order_line.py +++ b/bemade_fsm/models/sale_order_line.py @@ -14,7 +14,8 @@ class SaleOrderLine(models.Model): visit_ids = fields.One2many( comodel_name="bemade_fsm.visit", inverse_name="so_section_id", - string="Visits" + string="Visits", + copy=True, ) visit_id = fields.Many2one( @@ -22,7 +23,7 @@ class SaleOrderLine(models.Model): compute="_compute_visit_id", string="Visit", ondelete='cascade', - store=True + store=True, ) is_fully_delivered = fields.Boolean( @@ -74,6 +75,13 @@ class SaleOrderLine(models.Model): rec.equipment_ids = rec.order_id.default_equipment_ids return recs + def copy_data(self, default=None): + if default is None: + default = {} + if 'visit_ids' not in default: + default['visit_ids'] = [(0, 0, visit.copy_data()[0]) for visit in self.visit_ids] + return super().copy_data(default) + def _timesheet_create_task(self, project): """ Generate task for the given so line, and link it. :param project: record of project.project in which the task should be created @@ -148,7 +156,7 @@ class SaleOrderLine(models.Model): # Can't group up the tasks if they're part of different projects return project_id = task_ids[0].project_id - line.visit_id.task_id = line._generate_task_for_visit_line(project_id, index+1) + line.visit_id.task_id = line._generate_task_for_visit_line(project_id, index + 1) task_ids.write({'parent_id': line.visit_id.task_id.id}) (self.mapped('task_id') | self.visit_ids.task_id).synchronize_name_fsm() diff --git a/bemade_fsm/tests/test_sale_order.py b/bemade_fsm/tests/test_sale_order.py index bf1af3d..9fbc6c4 100644 --- a/bemade_fsm/tests/test_sale_order.py +++ b/bemade_fsm/tests/test_sale_order.py @@ -288,9 +288,15 @@ class TestSalesOrder(BemadeFSMBaseTest): for t in task.child_ids[1:]: self.assertFalse(t.description) - def test_cancel_sales_order_completes_successfully(self): - so, *others = self._generate_so_with_one_visit_two_lines() - so.action_confirm() + def test_duplicate_sale_order_duplicates_visits(self): + """ Duplicated sales orders should have visits tied to their SO lines as in the original. The copied visits + should not have approximate dates set, however.""" + so, visit, line1, line2 = self._generate_so_with_one_visit_two_lines() - so.action_cancel() - self.assertEqual(so.state, 'cancel') + so2 = so.copy() + + self.assertTrue(so2.visit_ids) + visit2 = so2.visit_ids[0] + self.assertEqual(so2.order_line[0].visit_id, visit2) + self.assertEqual(visit2.label, visit.label) + self.assertFalse(visit2.approx_date)