bemade_fsm: copying sale order now copies visits properly.
This commit is contained in:
parent
49d00269fa
commit
32def36af0
4 changed files with 32 additions and 15 deletions
|
|
@ -5,9 +5,9 @@ class FSMVisit(models.Model):
|
||||||
_name = "bemade_fsm.visit"
|
_name = "bemade_fsm.visit"
|
||||||
_description = 'Represents a single visit by assigned service personnel.'
|
_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(
|
so_section_id = fields.Many2one(
|
||||||
comodel_name="sale.order.line",
|
comodel_name="sale.order.line",
|
||||||
|
|
@ -19,7 +19,7 @@ class FSMVisit(models.Model):
|
||||||
sale_order_id = fields.Many2one(
|
sale_order_id = fields.Many2one(
|
||||||
comodel_name="sale.order",
|
comodel_name="sale.order",
|
||||||
string="Sales Order",
|
string="Sales Order",
|
||||||
required=True
|
readonly=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
is_completed = fields.Boolean(string="Completed", related="so_section_id.is_fully_delivered")
|
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
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
recs = super().create(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({
|
rec.so_section_id = rec.env['sale.order.line'].create({
|
||||||
'order_id': rec.sale_order_id.id,
|
'order_id': rec.sale_order_id.id,
|
||||||
'display_type': 'line_section',
|
'display_type': 'line_section',
|
||||||
'name': vals_list[i]['label'],
|
'name': vals_list[i].get('label', False),
|
||||||
})
|
})
|
||||||
return recs
|
return recs
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ class SaleOrder(models.Model):
|
||||||
def get_relevant_order_lines(self, task_id):
|
def get_relevant_order_lines(self, task_id):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
linked_lines = self.order_line.filtered(lambda l: l.task_id == task_id
|
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)
|
visit_lines = linked_lines.filtered(lambda l: l.visit_id)
|
||||||
for line in visit_lines:
|
for line in visit_lines:
|
||||||
linked_lines |= line.get_section_line_ids()
|
linked_lines |= line.get_section_line_ids()
|
||||||
|
|
@ -97,4 +97,7 @@ class SaleOrder(models.Model):
|
||||||
def _inverse_default_equipment(self):
|
def _inverse_default_equipment(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def copy(self, default=None):
|
||||||
|
rec = super().copy(default)
|
||||||
|
rec.visit_ids = [Command.set(rec.order_line.visit_ids.ids)]
|
||||||
|
return rec
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ class SaleOrderLine(models.Model):
|
||||||
visit_ids = fields.One2many(
|
visit_ids = fields.One2many(
|
||||||
comodel_name="bemade_fsm.visit",
|
comodel_name="bemade_fsm.visit",
|
||||||
inverse_name="so_section_id",
|
inverse_name="so_section_id",
|
||||||
string="Visits"
|
string="Visits",
|
||||||
|
copy=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
visit_id = fields.Many2one(
|
visit_id = fields.Many2one(
|
||||||
|
|
@ -22,7 +23,7 @@ class SaleOrderLine(models.Model):
|
||||||
compute="_compute_visit_id",
|
compute="_compute_visit_id",
|
||||||
string="Visit",
|
string="Visit",
|
||||||
ondelete='cascade',
|
ondelete='cascade',
|
||||||
store=True
|
store=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
is_fully_delivered = fields.Boolean(
|
is_fully_delivered = fields.Boolean(
|
||||||
|
|
@ -74,6 +75,13 @@ class SaleOrderLine(models.Model):
|
||||||
rec.equipment_ids = rec.order_id.default_equipment_ids
|
rec.equipment_ids = rec.order_id.default_equipment_ids
|
||||||
return recs
|
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):
|
def _timesheet_create_task(self, project):
|
||||||
""" Generate task for the given so line, and link it.
|
""" Generate task for the given so line, and link it.
|
||||||
:param project: record of project.project in which the task should be created
|
: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
|
# Can't group up the tasks if they're part of different projects
|
||||||
return
|
return
|
||||||
project_id = task_ids[0].project_id
|
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})
|
task_ids.write({'parent_id': line.visit_id.task_id.id})
|
||||||
(self.mapped('task_id') | self.visit_ids.task_id).synchronize_name_fsm()
|
(self.mapped('task_id') | self.visit_ids.task_id).synchronize_name_fsm()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -288,9 +288,15 @@ class TestSalesOrder(BemadeFSMBaseTest):
|
||||||
for t in task.child_ids[1:]:
|
for t in task.child_ids[1:]:
|
||||||
self.assertFalse(t.description)
|
self.assertFalse(t.description)
|
||||||
|
|
||||||
def test_cancel_sales_order_completes_successfully(self):
|
def test_duplicate_sale_order_duplicates_visits(self):
|
||||||
so, *others = self._generate_so_with_one_visit_two_lines()
|
""" Duplicated sales orders should have visits tied to their SO lines as in the original. The copied visits
|
||||||
so.action_confirm()
|
should not have approximate dates set, however."""
|
||||||
|
so, visit, line1, line2 = self._generate_so_with_one_visit_two_lines()
|
||||||
|
|
||||||
so.action_cancel()
|
so2 = so.copy()
|
||||||
self.assertEqual(so.state, 'cancel')
|
|
||||||
|
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)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue