bemade_fsm: Simplified implementation of equipment to allow for one equipment per sales order. Re #38.
This commit is contained in:
parent
653e22d13c
commit
7d84d85980
5 changed files with 45 additions and 45 deletions
|
|
@ -4,6 +4,10 @@ from odoo import fields, models, api, _, Command
|
||||||
class SaleOrder(models.Model):
|
class SaleOrder(models.Model):
|
||||||
_inherit = 'sale.order'
|
_inherit = 'sale.order'
|
||||||
|
|
||||||
|
equipment_id = fields.Many2one(comodel_name="bemade_fsm.equipment",
|
||||||
|
string="Equipment to Service",
|
||||||
|
tracking=True)
|
||||||
|
|
||||||
site_contacts = fields.Many2many(comodel_name='res.partner',
|
site_contacts = fields.Many2many(comodel_name='res.partner',
|
||||||
relation="sale_order_site_contacts_rel",
|
relation="sale_order_site_contacts_rel",
|
||||||
compute="_compute_default_contacts",
|
compute="_compute_default_contacts",
|
||||||
|
|
@ -18,13 +22,6 @@ class SaleOrder(models.Model):
|
||||||
string='Work Order Recipients',
|
string='Work Order Recipients',
|
||||||
store=True)
|
store=True)
|
||||||
|
|
||||||
equipment_ids = fields.Many2many(comodel_name='bemade_fsm.equipment',
|
|
||||||
compute='_compute_equipment',
|
|
||||||
inverse='_inverse_equipment',
|
|
||||||
string='Equipment to Service',
|
|
||||||
store=True,
|
|
||||||
ondelete='restrict')
|
|
||||||
|
|
||||||
@api.depends('partner_id')
|
@api.depends('partner_id')
|
||||||
def _compute_default_contacts(self):
|
def _compute_default_contacts(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
from odoo import fields, models, api
|
from odoo import fields, models, api, Command, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
class Task(models.Model):
|
class Task(models.Model):
|
||||||
_inherit = "project.task"
|
_inherit = "project.task"
|
||||||
|
|
||||||
|
equipment_id = fields.Many2one("bemade_fsm.equipment", string="Equipment to Service", tracking=True)
|
||||||
|
|
||||||
work_order_contacts = fields.Many2many(comodel_name="res.partner",
|
work_order_contacts = fields.Many2many(comodel_name="res.partner",
|
||||||
relation="task_work_order_contact_rel",
|
relation="task_work_order_contact_rel",
|
||||||
column1="task_id",
|
column1="task_id",
|
||||||
|
|
@ -11,17 +14,34 @@ class Task(models.Model):
|
||||||
compute="_compute_contacts",
|
compute="_compute_contacts",
|
||||||
inverse="_inverse_contacts",
|
inverse="_inverse_contacts",
|
||||||
store=True)
|
store=True)
|
||||||
|
|
||||||
site_contacts = fields.Many2many(comodel_name="res.partner",
|
site_contacts = fields.Many2many(comodel_name="res.partner",
|
||||||
relation="task_site_contact_rel",
|
relation="task_site_contact_rel",
|
||||||
column1="task_id",
|
|
||||||
column2="res_partner_id",
|
|
||||||
compute="_compute_contacts",
|
|
||||||
inverse="_inverse_contacts",
|
|
||||||
store=True)
|
|
||||||
equipment_ids = fields.Many2many(comodel_name="bemade_fsm.equipment",
|
|
||||||
relation="task_equipment_rel",
|
|
||||||
column1="task_id",
|
column1="task_id",
|
||||||
column2="res_partner_id",
|
column2="res_partner_id",
|
||||||
compute="_compute_equipment",
|
compute="_compute_contacts",
|
||||||
inverse="_inverse_equipment",
|
inverse="_inverse_contacts",
|
||||||
store=True)
|
store=True)
|
||||||
|
|
||||||
|
@api.depends('sale_line_id.order_id.site_contacts', 'sale_line_id.order_id.work_order_contacts')
|
||||||
|
def _compute_contacts(self):
|
||||||
|
""" The work order contacts and site contacts for a given task are taken from the sale order if the task
|
||||||
|
is related to one, and from the task's customer if there is no sale order related to the task."""
|
||||||
|
for rec in self:
|
||||||
|
site_contacts = self.sale_line_id and self.sale_line_id.order_id.site_contacts or \
|
||||||
|
self.partner_id.site_contacts
|
||||||
|
work_order_contacts = self.sale_line_id and self.sale_line_id.order_id.work_order_contacts or \
|
||||||
|
self.partner_id.work_order_contacts
|
||||||
|
rec.write({
|
||||||
|
'site_contacts': [Command.set(site_contacts.ids)],
|
||||||
|
'work_order_contacts': [Command.set(work_order_contacts.ids)]
|
||||||
|
})
|
||||||
|
|
||||||
|
def _inverse_contacts(self):
|
||||||
|
""" If the task is linked to a sales order, the sales order should have its contacts updated to match."""
|
||||||
|
for rec in self:
|
||||||
|
if rec.sale_line_id:
|
||||||
|
rec.sale_line_id.order_id.write({
|
||||||
|
'work_order_contacts': [Command.set(rec.work_order_contacts.ids)],
|
||||||
|
'site_contacts': [Command.set(rec.site_contacts.ids)],
|
||||||
|
})
|
||||||
|
|
|
||||||
|
|
@ -100,27 +100,13 @@ tour.register('equipment_sale_order_tour', {
|
||||||
content: 'Navigate to the Field Service tab.',
|
content: 'Navigate to the Field Service tab.',
|
||||||
trigger: 'a.nav-link[role="tab"]:contains(Field Service)'
|
trigger: 'a.nav-link[role="tab"]:contains(Field Service)'
|
||||||
}, {
|
}, {
|
||||||
content: 'Check that default equipment shows up.',
|
content: 'Click Edit',
|
||||||
trigger: `.o_field_cell:contains(${TEST_EQPT1})`,
|
trigger: 'button.o_form_button_edit',
|
||||||
}, {
|
}, {
|
||||||
content: 'Add test equipment 2',
|
content: 'Click the equipment dropdown.',
|
||||||
trigger: `div[name="equipment_ids"] a:contains(Add a line)`,
|
trigger: '.o_field_widget[name="equipment_id"] input',
|
||||||
}, {
|
}, {
|
||||||
content: 'Click create',
|
content: 'Check that the equipment is in the dropdown.',
|
||||||
trigger: '.modal-footer > button:has(span:contains(Create))',
|
trigger: `li.ui-menu-item > a:contains(${TEST_EQPT1})`,
|
||||||
}, {
|
|
||||||
content: 'Name the new equipment',
|
|
||||||
trigger: 'input.o_field_widget[name="name"]',
|
|
||||||
run: `text ${TEST_EQPT2}`,
|
|
||||||
}, {
|
|
||||||
content: 'Save & Close',
|
|
||||||
trigger: 'button:has(span:contains(Save & Close))',
|
|
||||||
}, {
|
|
||||||
content: 'Save',
|
|
||||||
trigger: 'button.o_form_button_save',
|
|
||||||
}, {
|
|
||||||
content: 'Check that the new equipment was added',
|
|
||||||
trigger: `.o_field_cell:contains(${TEST_EQPT2})`,
|
|
||||||
run: function () {},
|
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
@ -55,5 +55,3 @@ class TestEquipmentTours(HttpCase, TestEquipmentCommon):
|
||||||
|
|
||||||
def test_equipment_sale_order_tour(self):
|
def test_equipment_sale_order_tour(self):
|
||||||
self.start_tour('/web', 'equipment_sale_order_tour', login=self.user.login)
|
self.start_tour('/web', 'equipment_sale_order_tour', login=self.user.login)
|
||||||
# Make sure the equipment added to the SO in the test tour was added to the partner
|
|
||||||
self.assertEqual(len(self.partner_company.equipment_ids), 2)
|
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,14 @@
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//page[@name='other_information']" position="before">
|
<xpath expr="//page[@name='other_information']" position="before">
|
||||||
<page name="field_service" string="Field Service">
|
<page name="field_service" string="Field Service">
|
||||||
<group name="contacts">
|
<group name="field_service_info">
|
||||||
|
<field name="equipment_id"
|
||||||
|
domain="[('partner_location_id', '=', partner_shipping_id)]"
|
||||||
|
context="{'default_partner_location_id': partner_shipping_id,}"/>
|
||||||
<field name="site_contacts"
|
<field name="site_contacts"
|
||||||
context="{'tree_view_ref': 'bemade_fsm.fsm_contacts_view_tree'}"/>
|
context="{'tree_view_ref': 'bemade_fsm.fsm_contacts_view_tree'}"/>
|
||||||
<field name="work_order_contacts"
|
<field name="work_order_contacts"
|
||||||
context="{'tree_view_ref': 'bemade_fsm.fsm_contacts_view_tree'}"/>
|
context="{'tree_view_ref': 'bemade_fsm.fsm_contacts_view_tree'}"/>
|
||||||
<field name="equipment_ids"
|
|
||||||
domain="[('partner_location_id', '=', partner_shipping_id)]"
|
|
||||||
context="{'default_partner_location_id': partner_shipping_id,
|
|
||||||
'tree_view_ref': 'bemade_fsm.equipment_view_tree'}"/>
|
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue