diff --git a/__manifest__.py b/__manifest__.py
index d4715c4..3c9b327 100644
--- a/__manifest__.py
+++ b/__manifest__.py
@@ -37,11 +37,11 @@
],
'data': ['views/task_template_views.xml',
'views/equipment.xml',
- 'views/equipment_location.xml',
'security/ir.model.access.csv',
'views/product_views.xml',
'views/res_partner.xml',
'views/menus.xml',
+ 'views/task_views.xml',
],
'assets': {
'web.assets_tests': [
diff --git a/models/equipment.py b/models/equipment.py
index c928988..203037e 100644
--- a/models/equipment.py
+++ b/models/equipment.py
@@ -2,7 +2,6 @@ from odoo import api, fields, models
class EquipmentTag(models.Model):
-
_name = "bemade_fsm.equipment.tag"
_description = 'Field service equipment category'
@@ -21,36 +20,6 @@ class EquipmentType(models.Model):
name = fields.Char(string='Intervention Name', required=True, translate=True)
-
-class EquipmentLocation(models.Model):
- _name = 'bemade_fsm.equipment.location'
- _description = 'Field service location for equipment'
- _inherit = ['mail.thread', 'mail.activity.mixin']
-
- name = fields.Char(string='Name', required=True, translate=True)
-
- more_info = fields.Char(string='MOre info')
-
- partner_id = fields.Many2one(comodel_name='res.partner',
- string="Address",
- tracking=True,
- domain="[('is_site', '=', True)]",
- required=True)
-
- equipment_count = fields.Integer(compute='_compute_equipment_count',
- string='Equipment Count')
-
- equipment_ids = fields.One2many(comodel_name='bemade_fsm.equipment',
- inverse_name='equipment_location_id',
- string='Equipments')
-
- @api.depends('equipment_ids')
- def _compute_equipment_count(self):
- for rec in self:
- all_equipmemt_ids = self.env['bemade_fsm.equipment'].search([('equipment_location_id', '=', rec.id)])
- rec.equipment_count = len(all_equipmemt_ids)
-
-
class Equipment(models.Model):
_name = 'bemade_fsm.equipment'
_rec_name = 'complete_name'
@@ -68,35 +37,26 @@ class Equipment(models.Model):
tracking=True,
help="Classify and analyze your equipment categories like: Boiler, Laboratory, "
"Waste water, Pure water")
-
partner_id = fields.Many2one('res.partner',
string="Owner",
- tracking=True,
- domain="[('is_company', '=', True)]",
- required=True)
-
+ compute="_compute_partner")
description = fields.Text(string="Description",
- tracking=True,
- )
+ tracking=True)
partner_location_id = fields.Many2one('res.partner',
- string="Physical Location",
- tracking=True,
- domain="[('parent_id', '=', partner_id), ('is_site', '=', 'True')]",
- required=True)
-
- equipment_location_id = fields.Many2one('bemade_fsm.equipment.location',
- string="Location",
- tracking=True,
- domain="[('partner_id', '=', partner_location_id)]")
+ string="Physical Address",
+ tracking=True,)
location_notes = fields.Text(string="Physical Location Notes",
- tracking=True,
- )
+ tracking=True)
+ task_ids = fields.One2many(comodel_name='project.task',
+ inverse_name='equipment_id',
+ string='Interventions')
- intervention_ids = fields.One2many(comodel_name='project.task',
- inverse_name='equipment_id',
- string='Interventions')
+ @api.depends('partner_location_id')
+ def _compute_partner(self):
+ for rec in self:
+ rec.partner_id = rec.partner_location_id and rec.partner_location_id.get_root_ancestor()
@api.depends('pid_tag', 'name')
def _compute_complete_name(self):
@@ -108,12 +68,23 @@ class Equipment(models.Model):
args = args or []
if name:
equipments = self.search([
- '|', '|', '|',
- ('pid_tag', operator, name),
- ('name', operator, name),
- ('partner_id.name', operator, name),
- ('partner_location_id.name', operator, name)],
+ '|', '|', '|',
+ ('pid_tag', operator, name),
+ ('name', operator, name),
+ ('partner_id.name', operator, name),
+ ('partner_location_id.name', operator, name)],
limit=limit)
else:
equipments = self.search(args, limit=limit)
return equipments.name_get()
+
+ def action_view_equipment(self):
+ return {
+ 'name': 'Equipment',
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_id': self.id,
+ 'context': self.env.context,
+ 'res_model': 'bemade_fsm.equipment',
+ 'type': 'ir.actions.act_window',
+ }
\ No newline at end of file
diff --git a/models/res_partner.py b/models/res_partner.py
index ab516d3..574a0f2 100644
--- a/models/res_partner.py
+++ b/models/res_partner.py
@@ -1,5 +1,4 @@
-from odoo import api, fields, models
-
+from odoo import api, fields, models, Command
class Partner(models.Model):
_inherit = 'res.partner'
@@ -7,26 +6,37 @@ class Partner(models.Model):
equipment_count = fields.Integer(compute='_compute_equipment_count',
string='Equipment Count')
+ owned_equipment_ids = fields.One2many(comodel_name="bemade_fsm.equipment",
+ inverse_name="partner_id",
+ string="Owned Equipments")
+
+
equipment_ids = fields.One2many(comodel_name='bemade_fsm.equipment',
- inverse_name='partner_id',
- string='Equipments')
-
- equipment_location_count = fields.Integer(compute='_compute_equipment_location_count',
- string='Equipment Location Count')
-
- equipment_location_ids = fields.One2many(comodel_name='bemade_fsm.equipment.location',
- inverse_name='partner_id',
- string='Equipment Location')
-
- is_site = fields.Boolean(string='Is an Equipment Site',
- tracking=True,
- default=False,
- help="Check if the contact is an equipment site, otherwise it is not in that list")
+ inverse_name='partner_location_id',
+ string='Site Equipment')
is_site_contact = fields.Boolean(string='Is a site contact',
- tracking=True,
- default=False,
- help="Check if the contact is a site contact, otherwise it is a not in that list")
+ compute="_compute_is_site_contact")
+
+ site_ids = fields.Many2many(string='Work Sites',
+ comodel_name='res.partner',
+ relation='res_partner_site_contact_rel',
+ column1='site_contact_id',
+ column2='site_id',
+ tracking=True)
+
+ site_contacts = fields.Many2many(string='Site Contacts',
+ comodel_name='res.partner',
+ relation='res_partner_site_contact_rel',
+ column1='site_id',
+ column2='site_contact_id',
+ domain=[('is_company', '=', False)],
+ tracking=True)
+
+ @api.depends('site_ids')
+ def _compute_is_site_contact(self):
+ for rec in self:
+ rec.is_site_contact = rec.site_ids is not False
@api.depends('equipment_ids')
def _compute_equipment_count(self):
@@ -34,8 +44,12 @@ class Partner(models.Model):
all_equipmemt_ids = self.env['bemade_fsm.equipment'].search([('partner_id', '=', rec.id)])
rec.equipment_count = len(all_equipmemt_ids)
- @api.depends('equipment_location_ids')
- def _compute_equipment_location_count(self):
- for rec in self:
- all_equipmemt_location_ids = self.env['bemade_fsm.equipment.location'].search([('partner_id', '=', rec.id)])
- rec.equipment_location_count = len(all_equipmemt_location_ids)
+ def get_root_ancestor(self):
+ """ Returns the partner at the top of the parent-child hierarchy. """
+ self.ensure_one()
+ return self.parent_id and self.parent_id.get_root_ancestor() or self
+
+ def get_first_company_ancestor(self):
+ """ Returns the first ancestor that is a company """
+ self.ensure_one()
+ return self.is_company and self or self.parent_id and self.parent_id.get_first_company_ancestor()
diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv
index 086f935..82eb4f7 100644
--- a/security/ir.model.access.csv
+++ b/security/ir.model.access.csv
@@ -3,5 +3,4 @@ access_bemade_fsm_task_template,bemade_fsm_task_template,model_project_task_temp
access_bemade_fsm_task_template,bemade_fsm_task_template,model_project_task_template,project.group_project_user,1,1,1,1
access_bemade_fsm_equipment,bemade_fsm_equipment,model_bemade_fsm_equipment,base.group_user,1,1,1,1
access_bemade_fsm_equipment_tag,bemade_fsm_equipment_tag,model_bemade_fsm_equipment_tag,base.group_user,1,1,1,1
-access_bemade_fsm_equipment_type,access_bemade_fsm_equipment_type,model_bemade_fsm_equipment_type,base.group_user,1,0,0,0
-access_bemade_fsm_equipment_location,access_bemade_fsm_equipment_location,model_bemade_fsm_equipment_location,base.group_user,1,0,0,0
\ No newline at end of file
+access_bemade_fsm_equipment_type,access_bemade_fsm_equipment_type,model_bemade_fsm_equipment_type,base.group_user,1,0,0,0
\ No newline at end of file
diff --git a/static/tests/tours/task_equipment_tour.js b/static/tests/tours/task_equipment_tour.js
new file mode 100644
index 0000000..8abdd1d
--- /dev/null
+++ b/static/tests/tours/task_equipment_tour.js
@@ -0,0 +1,14 @@
+/** @odoo-module **/
+
+// Navigate to the Service > Clients > Equipment menu
+// Click the Create button
+// Fill in the required fields, including creating a new Client Location and PID Tag
+// Navigate to the client location, then to the client, making sure that the equipment and client location links appear
+
+// Now make another one, but from the Partner interface
+// Navigate to Service > Clients > Clients
+// Search for and open the test client
+// On the "Locations" tab, add a location
+// Open the location and add a new Equipment to its equipment list
+
+// Create a task in the test project
diff --git a/tests/__init__.py b/tests/__init__.py
index 9df0958..a66b934 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,2 +1,4 @@
+from . import test_bemade_fsm_common
from . import test_task_template
from . import test_task_template_sale_order
+from . import test_equipment
diff --git a/tests/test_bemade_fsm_common.py b/tests/test_bemade_fsm_common.py
new file mode 100644
index 0000000..1d74b7a
--- /dev/null
+++ b/tests/test_bemade_fsm_common.py
@@ -0,0 +1,42 @@
+from odoo.tests.common import TransactionCase, HttpCase, tagged
+from odoo.tools import mute_logger
+from odoo.exceptions import MissingError
+from odoo import Command
+from psycopg2.errors import ForeignKeyViolation
+
+
+class FSMManagerUserTransactionCase(TransactionCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ user_group_employee = cls.env.ref('base.group_user')
+ user_group_project_user = cls.env.ref('project.group_project_user')
+ user_group_project_manager = cls.env.ref('project.group_project_manager')
+ user_group_fsm_user = cls.env.ref('industry_fsm.group_fsm_user')
+ user_group_fsm_manager = cls.env.ref('industry_fsm.group_fsm_manager')
+ user_group_sales_manager = cls.env.ref('sales_team.group_sale_manager')
+ user_group_sales_user = cls.env.ref('sales_team.group_sale_salesman')
+ user_product_customer = cls.env.ref('customer_product_code.group_product_customer_code_user')
+
+ group_ids = [user_group_employee,
+ user_group_project_user,
+ user_group_project_manager,
+ user_group_fsm_user,
+ user_group_fsm_manager,
+ user_group_sales_user,
+ user_group_sales_manager, ]
+ if user_product_customer:
+ group_ids.append(user_product_customer)
+
+ # Test user with project access rights for the various tests
+ Users = cls.env['res.users'].with_context({'no_reset_password': True})
+ cls.user = Users.create({
+ 'name': 'Project Manager',
+ 'login': 'misterpm',
+ 'password': 'misterpm',
+ 'email': 'mrpm@testco.com',
+ 'signature': 'Mr. PM',
+ 'groups_id': [(6, 0, [user_group_employee.id, user_group_project_user.id, user_group_project_manager.id,
+ user_group_sales_user.id])],
+ })
diff --git a/tests/test_equipment.py b/tests/test_equipment.py
new file mode 100644
index 0000000..0920878
--- /dev/null
+++ b/tests/test_equipment.py
@@ -0,0 +1,32 @@
+from odoo.tests.common import HttpCase, tagged
+from odoo.tools import mute_logger
+from odoo.exceptions import MissingError
+from odoo import Command
+from psycopg2.errors import ForeignKeyViolation
+from .test_bemade_fsm_common import FSMManagerUserTransactionCase
+
+class TestEquipmentCommon(FSMManagerUserTransactionCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+
+ # Set up the test partner
+ cls.partner_company = cls.env['res.partner'].create({
+ 'name': 'Test Partner Company',
+ 'company_type': 'company',
+ 'street': '123 Street St.',
+ 'city': 'Montreal',
+ 'state_id': cls.env['res.country.state'].search([('name','ilike','Quebec%')]),
+ 'country_id': cls.env['res.country'].search([('name','=','Canada')])
+ })
+
+ cls.partner_contact = cls.env['res.partner'].create({
+ 'name': 'Site Contact',
+ 'company_type': 'person',
+ 'parent_id': cls.partner_company.id,
+ })
+
+ cls.equipment = cls.env['bemade_fsm.equipment'].create({
+ 'name': 'Test Equipment 1',
+ })
\ No newline at end of file
diff --git a/tests/test_task_template.py b/tests/test_task_template.py
index ad84734..ec42aca 100644
--- a/tests/test_task_template.py
+++ b/tests/test_task_template.py
@@ -1,38 +1,16 @@
-from odoo.tests.common import TransactionCase, HttpCase, tagged
+from .test_bemade_fsm_common import FSMManagerUserTransactionCase
+from odoo.tests.common import HttpCase, tagged
from odoo.tools import mute_logger
from odoo.exceptions import MissingError
from odoo import Command
from psycopg2.errors import ForeignKeyViolation
-class TestTaskTemplateCommon(TransactionCase):
+class TestTaskTemplateCommon(FSMManagerUserTransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
- user_group_employee = cls.env.ref('base.group_user')
- user_group_project_user = cls.env.ref('project.group_project_user')
- user_group_project_manager = cls.env.ref('project.group_project_manager')
- user_group_sales_manager = cls.env.ref('sales_team.group_sale_manager')
- user_group_sales_user = cls.env.ref('sales_team.group_sale_salesman')
- user_product_customer = cls.env.ref('customer_product_code.group_product_customer_code_user')
-
- group_ids = [user_group_employee, user_group_project_user, user_group_project_manager, user_group_sales_user,
- user_group_sales_manager]
- if user_product_customer:
- group_ids.append(user_product_customer)
-
- # Test user with project access rights for the various tests
- Users = cls.env['res.users'].with_context({'no_reset_password': True})
- cls.user = Users.create({
- 'name': 'Project Manager',
- 'login': 'misterpm',
- 'password': 'misterpm',
- 'email': 'mrpm@testco.com',
- 'signature': 'Mr. PM',
- 'groups_id': [(6, 0, [user_group_employee.id, user_group_project_user.id, user_group_project_manager.id,
- user_group_sales_user.id])],
- })
hours_uom = cls.env['uom.uom'].search([('name', '=', 'Hour')]) or False
# Test product to use with the various tests
cls.task1 = cls.env['project.task.template'].create({
diff --git a/views/equipment.xml b/views/equipment.xml
index 505d613..4047df6 100644
--- a/views/equipment.xml
+++ b/views/equipment.xml
@@ -20,7 +20,6 @@
groups="sale.group_delivery_invoice_address"
context="{'default_type': 'delivery', 'show_address': 1}"
options='{"always_reload": True}'/>
-
diff --git a/views/equipment_location.xml b/views/equipment_location.xml
deleted file mode 100644
index 9f2cd0b..0000000
--- a/views/equipment_location.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
-
- bemade_fsm.partner.equipment.location.form
- res.partner
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- bemade_fsm.equipment.location.form
- bemade_fsm.equipment.location
-
-
-
-
-
-
- bemade_fsm.equipment.location.tree
- bemade_fsm.equipment.location
-
-
-
-
-
-
-
-
-
-
- bemade_fsm.equipment.location.search
- bemade_fsm.equipment.location
-
-
-
-
-
-
-
-
-
-
-
-
-
- Equipment Location
- bemade_fsm.equipment.location
- tree,form
-
-
diff --git a/views/menus.xml b/views/menus.xml
new file mode 100644
index 0000000..76c5464
--- /dev/null
+++ b/views/menus.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/views/res_partner.xml b/views/res_partner.xml
index 165a83f..d451cb9 100644
--- a/views/res_partner.xml
+++ b/views/res_partner.xml
@@ -8,29 +8,63 @@
[("partner_id", "=", active_id)]
-
- res.partner.view.buttons.fso
+
+ bemade_fsm.partner.equipment.location.form
res.partner
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
diff --git a/views/task_views.xml b/views/task_views.xml
new file mode 100644
index 0000000..6d2ccce
--- /dev/null
+++ b/views/task_views.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ bemade_fsm.project_task.form
+ project.task
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file