bemade_fsm: Equipment to sale order line connection made. Fixes #71.
This commit is contained in:
parent
f997215aca
commit
454656159c
6 changed files with 127 additions and 62 deletions
|
|
@ -37,10 +37,6 @@ class Equipment(models.Model):
|
|||
string='Application',
|
||||
help="Classify and analyze your equipment categories like: Boiler, Laboratory, "
|
||||
"Waste water, Pure water")
|
||||
partner_id = fields.Many2one('res.partner',
|
||||
string="Owner",
|
||||
compute="_compute_partner",
|
||||
search="_search_partner", )
|
||||
|
||||
description = fields.Text(string="Description",
|
||||
tracking=True)
|
||||
|
|
@ -63,15 +59,6 @@ class Equipment(models.Model):
|
|||
for rec in self:
|
||||
rec.partner_id = rec.partner_location_id and rec.partner_location_id.root_ancestor
|
||||
|
||||
@api.model
|
||||
def _search_partner(self, operator, value):
|
||||
return [('partner_location_id.root_ancestor', operator, value)]
|
||||
|
||||
@api.depends('pid_tag', 'name')
|
||||
def _compute_complete_name(self):
|
||||
for rec in self:
|
||||
rec.complete_name = "[%s] %s" % (rec.pid_tag or ' ', rec.name)
|
||||
|
||||
@api.model
|
||||
def name_search(self, name='', args=None, operator='ilike', limit=100):
|
||||
args = args or []
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from odoo import api, fields, models, Command
|
||||
|
||||
|
||||
class Partner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
|
|
@ -7,17 +8,16 @@ class Partner(models.Model):
|
|||
string='Equipment Count')
|
||||
|
||||
owned_equipment_ids = fields.One2many(comodel_name="bemade_fsm.equipment",
|
||||
inverse_name="partner_id",
|
||||
compute="_compute_owned_equipment_ids",
|
||||
string="Owned Equipments")
|
||||
|
||||
|
||||
equipment_ids = fields.One2many(comodel_name='bemade_fsm.equipment',
|
||||
inverse_name='partner_location_id',
|
||||
string='Site Equipment')
|
||||
|
||||
is_site_contact = fields.Boolean(string='Is a site contact',
|
||||
compute="_compute_is_site_contact",
|
||||
search="_search_is_site_contact",)
|
||||
search="_search_is_site_contact", )
|
||||
|
||||
site_ids = fields.Many2many(string='Work Sites',
|
||||
comodel_name='res.partner',
|
||||
|
|
@ -42,6 +42,13 @@ class Partner(models.Model):
|
|||
domain=[('is_company', '=', False)],
|
||||
tracking=True)
|
||||
|
||||
@api.depends('equipment_ids', 'child_ids.company_type', 'child_ids.equipment_ids')
|
||||
def _compute_owned_equipment_ids(self):
|
||||
for rec in self:
|
||||
ids = rec.equipment_ids | rec.child_ids.filtered(lambda l: l.company_type == 'company').mapped(
|
||||
'equipment_ids')
|
||||
rec.owned_equipment_ids = ids or False
|
||||
|
||||
@api.depends('site_ids')
|
||||
def _compute_is_site_contact(self):
|
||||
for rec in self:
|
||||
|
|
|
|||
|
|
@ -55,10 +55,13 @@ class SaleOrder(models.Model):
|
|||
def _inverse_default_contacts(self):
|
||||
pass
|
||||
|
||||
@api.depends('partner_shipping_id')
|
||||
@api.depends('partner_id', 'partner_shipping_id', 'partner_shipping_id.equipment_ids', 'partner_id.owned_equipment_ids')
|
||||
def _compute_default_equipment(self):
|
||||
ids = self.partner_shipping_id.equipment_ids
|
||||
for rec in self:
|
||||
if rec.partner_shipping_id.equipment_ids:
|
||||
ids = rec.partner_shipping_id.equipment_ids
|
||||
else:
|
||||
ids = rec.partner_id.owned_equipment_ids
|
||||
rec.default_equipment_ids = ids if len(ids) < 4 else False
|
||||
|
||||
def _inverse_default_equipment(self):
|
||||
|
|
@ -86,6 +89,14 @@ class SaleOrderLine(models.Model):
|
|||
column1="sale_order_line_id",
|
||||
column2="equipment_id")
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals):
|
||||
recs = super().create(vals)
|
||||
for rec in recs:
|
||||
if rec.order_id.default_equipment_ids and not rec.equipment_ids:
|
||||
rec.equipment_ids = rec.order_id.default_equipment_ids
|
||||
return recs
|
||||
|
||||
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
|
||||
|
|
@ -132,7 +143,7 @@ class SaleOrderLine(models.Model):
|
|||
vals['tag_ids'] = template.tags.ids
|
||||
vals['planned_hours'] = template.planned_hours
|
||||
if template.equipment_ids:
|
||||
vals['equipment_ids'] = [Command.set(template.equipment_ids.ids)]
|
||||
vals['equipment_ids'] = template.equipment_ids.ids
|
||||
return vals
|
||||
|
||||
tmpl = self.product_id.task_template_id
|
||||
|
|
@ -147,7 +158,7 @@ class SaleOrderLine(models.Model):
|
|||
self.order_id.id, self.order_id.name, self.product_id.name)
|
||||
task.message_post(body=task_msg)
|
||||
if not task.equipment_ids and self.equipment_ids:
|
||||
task.write({'equipment_ids': [Command.set([self.equipment_ids.ids])]})
|
||||
task.equipment_ids = self.equipment_ids.ids
|
||||
task.name = _generate_task_name(tmpl)
|
||||
return task
|
||||
|
||||
|
|
|
|||
|
|
@ -67,16 +67,20 @@ class BemadeFSMBaseTest(TransactionCase):
|
|||
})
|
||||
|
||||
@classmethod
|
||||
def _generate_sale_order(cls, partner=None, client_order_ref='Test Order', equipment=None):
|
||||
def _generate_sale_order(cls, partner=None, client_order_ref='Test Order', equipment=None, shipping_location=None):
|
||||
partner = partner or cls._generate_partner()
|
||||
return cls.env['sale.order'].create({
|
||||
'partner_id': partner.id,
|
||||
'client_order_ref': client_order_ref,
|
||||
'equipment_id': equipment and equipment.id or False,
|
||||
})
|
||||
vals = {'partner_id': partner.id,
|
||||
'client_order_ref': client_order_ref}
|
||||
if equipment:
|
||||
vals.update({'default_equipment_ids': [Command.set([equipment.id])]})
|
||||
if shipping_location:
|
||||
vals.update({'partner_shipping_id': shipping_location.id})
|
||||
return cls.env['sale.order'].create(vals)
|
||||
|
||||
@classmethod
|
||||
def _generate_sale_order_line(cls, sale_order, product, qty=1.0, uom=None, price=100.0, tax_id=False):
|
||||
def _generate_sale_order_line(cls, sale_order, product=None, qty=1.0, uom=None, price=100.0, tax_id=False):
|
||||
if not product:
|
||||
product = cls._generate_product()
|
||||
return cls.env['sale.order.line'].create({
|
||||
'order_id': sale_order.id,
|
||||
'product_id': product.id,
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class TestSalesOrder(BemadeFSMBaseTest):
|
|||
self.assertTrue(sol.task_id.child_ids[0].child_ids and len(sol.task_id.child_ids[0].child_ids) == 1)
|
||||
self.assertTrue(grandchild_task.name in sol.task_id.child_ids.child_ids[0].name)
|
||||
|
||||
def test_order_confirmation_equipment(self):
|
||||
def test_order_confirmation_single_equipment(self):
|
||||
""" The equipment selected on the SO should transfer to the task."""
|
||||
partner = self._generate_partner()
|
||||
equipment = self._generate_equipment(partner=partner)
|
||||
|
|
@ -60,6 +60,23 @@ class TestSalesOrder(BemadeFSMBaseTest):
|
|||
self.assertEqual(task1.equipment_ids[0], equipment)
|
||||
self.assertEqual(task2.equipment_ids[0], equipment)
|
||||
|
||||
def test_order_confirmation_multiple_equipment(self):
|
||||
""" All equipment items should flow from the sale order line to the final task """
|
||||
partner = self._generate_partner()
|
||||
for i in range(5):
|
||||
self._generate_equipment(partner=partner)
|
||||
sale_order = self._generate_sale_order(partner=partner) # No default equipment since more than 3 on partner
|
||||
sol1, sol2, sol3 = [self._generate_sale_order_line(sale_order=sale_order) for i in range(3)]
|
||||
sol1.equipment_ids = [Command.set([partner.equipment_ids[i].id for i in range(2)])]
|
||||
sol3.equipment_ids = [Command.set([partner.equipment_ids[i].id for i in range(2, 5)])]
|
||||
|
||||
sale_order.action_confirm()
|
||||
|
||||
self.assertEqual(sol1.equipment_ids, sol1.task_id.equipment_ids)
|
||||
self.assertEqual(sol2.equipment_ids, sol2.task_id.equipment_ids)
|
||||
self.assertEqual(sol3.equipment_ids, sol3.task_id.equipment_ids)
|
||||
|
||||
|
||||
def test_task_template_with_equipment_flow(self):
|
||||
""" The equipment selected on a task template should flow down to the task created on SO confirmation."""
|
||||
partner = self._generate_partner()
|
||||
|
|
@ -73,6 +90,79 @@ class TestSalesOrder(BemadeFSMBaseTest):
|
|||
|
||||
self.assertEqual(sol.task_id.equipment_ids[0], equipment)
|
||||
|
||||
def test_sale_order_line_gets_default_equipment(self):
|
||||
""" Sale order lines created on an SO with default equipment set should inherit that default equipment. """
|
||||
partner = self._generate_partner()
|
||||
self._generate_equipment(partner=partner)
|
||||
sale_order = self._generate_sale_order(partner=partner)
|
||||
|
||||
sol = self._generate_sale_order_line(sale_order=sale_order)
|
||||
|
||||
self.assertEqual(sol.equipment_ids, partner.equipment_ids)
|
||||
|
||||
def test_sale_order_gets_correct_default_equipment_from_partner(self):
|
||||
""" Should pick up equipment from the partner."""
|
||||
partner = self._generate_partner()
|
||||
self._generate_equipment(partner=partner)
|
||||
|
||||
sale_order = self._generate_sale_order(partner=partner)
|
||||
|
||||
self.assertEqual(sale_order.default_equipment_ids, partner.owned_equipment_ids)
|
||||
|
||||
def test_sale_order_default_equipment_maximum_number(self):
|
||||
parent = self._generate_partner()
|
||||
child = self._generate_partner(parent=parent)
|
||||
for i in range(3):
|
||||
self._generate_equipment(child)
|
||||
|
||||
sale_order = self._generate_sale_order(partner=parent)
|
||||
|
||||
self.assertEqual(sale_order.default_equipment_ids, parent.owned_equipment_ids)
|
||||
|
||||
def test_sale_order_no_default_equipment_with_more_than_three_owned_on_partner(self):
|
||||
parent = self._generate_partner()
|
||||
child = self._generate_partner(parent=parent)
|
||||
for i in range(4):
|
||||
self._generate_equipment(child)
|
||||
|
||||
sale_order = self._generate_sale_order(partner=parent)
|
||||
|
||||
self.assertEqual(sale_order.default_equipment_ids, parent.owned_equipment_ids)
|
||||
|
||||
def test_sale_order_resets_default_equipment_on_partner_change(self):
|
||||
partner_1 = self._generate_partner()
|
||||
partner_2 = self._generate_partner()
|
||||
self._generate_equipment(partner=partner_1)
|
||||
sale_order = self._generate_sale_order(partner_1)
|
||||
form = Form(sale_order)
|
||||
|
||||
form.partner_id = partner_2
|
||||
form.save()
|
||||
|
||||
self.assertFalse(sale_order.default_equipment_ids)
|
||||
|
||||
def test_sale_order_prioritize_shipping_location_equipments(self):
|
||||
parent = self._generate_partner()
|
||||
child = self._generate_partner(parent=parent, location_type='delivery')
|
||||
self._generate_equipment(partner=parent)
|
||||
self._generate_equipment(partner=child)
|
||||
|
||||
sale_order = self._generate_sale_order(partner=parent, shipping_location=child)
|
||||
|
||||
self.assertEqual(sale_order.default_equipment_ids, child.equipment_ids)
|
||||
|
||||
def test_default_equipment_transfers_to_sale_order_line(self):
|
||||
partner = self._generate_partner()
|
||||
for i in range(3):
|
||||
self._generate_equipment(partner=partner)
|
||||
sale_order = self._generate_sale_order(partner=partner)
|
||||
|
||||
for i in range(3):
|
||||
self._generate_sale_order_line(sale_order=sale_order)
|
||||
|
||||
for line in sale_order.order_line:
|
||||
self.assertEqual(line.equipment_ids, partner.equipment_ids)
|
||||
|
||||
def test_task_mark_done(self):
|
||||
""" Marking the task linked to an SO line should mark the line delivered. Marking sub-tasks done should not."""
|
||||
partner = self._generate_partner()
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
<field name="location_notes"/>
|
||||
</group>
|
||||
<group name="right">
|
||||
<field name="partner_id"/>
|
||||
<field name="partner_location_id"
|
||||
groups="sale.group_delivery_invoice_address"
|
||||
context="{'default_type': 'delivery', 'show_address': 1}"
|
||||
|
|
@ -23,19 +22,6 @@
|
|||
<field name="tag_ids" widget="many2many_tags" options="{'no_open': False}"/>
|
||||
</group>
|
||||
</group>
|
||||
<!-- <notebook>-->
|
||||
<!-- <page string="Interventions">-->
|
||||
<!-- <field name="intervention_ids" mode="tree">-->
|
||||
<!-- <tree string="Interventions" create="0" edit="0">-->
|
||||
<!-- <field name="name"/>-->
|
||||
<!-- <field name="description"/>-->
|
||||
<!-- <field name="date_planned"/>-->
|
||||
<!-- <field name="state"/>-->
|
||||
<!-- </tree>-->
|
||||
<!-- </field>-->
|
||||
<!-- </page>-->
|
||||
<!-- </notebook>-->
|
||||
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
|
|
@ -60,26 +46,6 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<!-- BV: AN OTHER SEARCH VIEW TO BRING BACK
|
||||
<record id="equipment_view_search" model="ir.ui.view">
|
||||
<field name="name">bemade_fsm.equipment.search</field>
|
||||
<field name="model">bemade_fsm.equipment</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Equipments">
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="pid_tag"/>
|
||||
<field name="partner_location_id"/>
|
||||
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Partner" context="{'group_by':'partner_id'}"/>
|
||||
<filter string="Location" context="{'group_by':'partner_location_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
-->
|
||||
|
||||
<record model="ir.actions.act_window" id="action_window_equipment">
|
||||
<field name="name">Equipment</field>
|
||||
<field name="res_model">bemade_fsm.equipment</field>
|
||||
|
|
|
|||
Loading…
Reference in a new issue