-
+
+
-
+
- Signed
-
-
-
+ Signed
+
+
+
-
Signature
-
![]()
-
-
+ style="page-break-inside: avoid"
+ >
+
Signature
+
![]()
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/bemade_fsm/reports/worksheet_custom_reports.py b/bemade_fsm/reports/worksheet_custom_reports.py
index a6e1c8b..88d3bac 100644
--- a/bemade_fsm/reports/worksheet_custom_reports.py
+++ b/bemade_fsm/reports/worksheet_custom_reports.py
@@ -6,6 +6,8 @@ class TaskCustomReport(models.AbstractModel):
def _get_report_values(self, docids, data=None):
vals = super()._get_report_values(docids, data)
- split_time_materials = self.env.company.split_time_from_materials_on_service_work_orders
+ split_time_materials = (
+ self.env.company.split_time_from_materials_on_service_work_orders
+ )
vals.update({"split_time_materials": split_time_materials})
return vals
diff --git a/bemade_fsm/reports/worksheet_custom_reports.xml b/bemade_fsm/reports/worksheet_custom_reports.xml
index 5dd1bd7..bde5bc8 100644
--- a/bemade_fsm/reports/worksheet_custom_reports.xml
+++ b/bemade_fsm/reports/worksheet_custom_reports.xml
@@ -1,12 +1,11 @@
-
-
- '%s %s' % (
- object.planned_date_begin.strftime('%Y-%m-%d') if object.planned_date_begin else time.strftime('%Y-%m-%d'),
- object.name
- )
-
-
-
+
+ '%s %s' % (
+ object.planned_date_begin.strftime(
+ '%Y-%m-%d') if object.planned_date_begin else time.strftime('%Y-%m-%d'),
+ object.name
+ )
+
+
diff --git a/bemade_fsm/tests/test_bemade_fsm_common.py b/bemade_fsm/tests/test_bemade_fsm_common.py
index 4a6059e..21cfca0 100644
--- a/bemade_fsm/tests/test_bemade_fsm_common.py
+++ b/bemade_fsm/tests/test_bemade_fsm_common.py
@@ -7,8 +7,8 @@ class BemadeFSMBaseTest(TransactionCase):
@classmethod
def _generate_project_manager_user(cls, name, login):
group_ids = cls.__get_user_groups()
- user_group_project_manager = cls.env.ref('project.group_project_manager')
- user_group_fsm_manager = cls.env.ref('industry_fsm.group_fsm_manager')
+ user_group_project_manager = cls.env.ref("project.group_project_manager")
+ user_group_fsm_manager = cls.env.ref("industry_fsm.group_fsm_manager")
group_ids.append(user_group_fsm_manager.id)
group_ids.append(user_group_project_manager.id)
@@ -21,118 +21,170 @@ class BemadeFSMBaseTest(TransactionCase):
@classmethod
def __generate_user(cls, name, login, group_ids):
- return cls.env['res.users'].with_context({'no_reset_password': True}).create({
- 'name': name,
- 'login': login,
- 'password': login,
- 'email': f"{login}@test.co",
- 'groups_id': [Command.set(group_ids)]
- })
+ return (
+ cls.env["res.users"]
+ .with_context(no_reset_password=True)
+ .create(
+ {
+ "name": name,
+ "login": login,
+ "password": login,
+ "email": f"{login}@test.co",
+ "groups_id": [Command.set(group_ids)],
+ }
+ )
+ )
@classmethod
def __get_user_groups(cls):
- user_group_employee = cls.env.ref('base.group_user')
- user_group_project_user = cls.env.ref('project.group_project_user')
- user_group_fsm_user = cls.env.ref('industry_fsm.group_fsm_user')
- user_group_sales_user = cls.env.ref('sales_team.group_sale_salesman')
- user_group_sales_manager = cls.env.ref('sales_team.group_sale_manager')
+ user_group_employee = cls.env.ref("base.group_user")
+ user_group_project_user = cls.env.ref("project.group_project_user")
+ user_group_fsm_user = cls.env.ref("industry_fsm.group_fsm_user")
+ user_group_sales_user = cls.env.ref("sales_team.group_sale_salesman")
+ user_group_sales_manager = cls.env.ref("sales_team.group_sale_manager")
user_product_customer = cls.env.ref(
- 'customer_product_code.group_product_customer_code_user',
- raise_if_not_found=False
+ "customer_product_code.group_product_customer_code_user",
+ raise_if_not_found=False,
)
- group_ids = [user_group_employee.id,
- user_group_project_user.id,
- user_group_fsm_user.id,
- user_group_sales_manager.id,
- user_group_sales_user.id, ]
+ group_ids = [
+ user_group_employee.id,
+ user_group_project_user.id,
+ user_group_fsm_user.id,
+ user_group_sales_manager.id,
+ user_group_sales_user.id,
+ ]
if user_product_customer:
group_ids.append(user_product_customer.id)
return group_ids
@classmethod
- def _generate_partner(cls, name: str = 'Test Company', company_type: str = 'company', parent=None,
- location_type='other'):
- """ Generates a partner with basic address filled in.
+ def _generate_partner(
+ cls,
+ name: str = "Test Company",
+ company_type: str = "company",
+ parent=None,
+ location_type="other",
+ ):
+ """Generates a partner with basic address filled in.
:param name: The partner's name.
- :param company_type: The type of partner, either 'company' or 'person' are accepted."""
- return cls.env['res.partner'].create({
- 'name': name,
- 'company_type': company_type,
- 'street': '123 Street St.',
- 'city': 'Montreal',
- 'state_id': cls.env.ref('base.state_ca_qc').id,
- 'country_id': cls.env.ref('base.ca').id,
- 'parent_id': parent and parent.id or False,
- 'type': location_type,
- })
+ :param company_type: The type of partner, either 'company' or 'person' are accepted.
+ """
+ return cls.env["res.partner"].create(
+ {
+ "name": name,
+ "company_type": company_type,
+ "street": "123 Street St.",
+ "city": "Montreal",
+ "state_id": cls.env.ref("base.state_ca_qc").id,
+ "country_id": cls.env.ref("base.ca").id,
+ "parent_id": parent and parent.id or False,
+ "type": location_type,
+ }
+ )
@classmethod
- def _generate_sale_order(cls, partner=None, client_order_ref='Test Order', equipment=None, shipping_location=None):
+ def _generate_sale_order(
+ cls,
+ partner=None,
+ client_order_ref="Test Order",
+ equipment=None,
+ shipping_location=None,
+ ):
partner = partner or cls._generate_partner()
- vals = {'partner_id': partner.id,
- 'client_order_ref': client_order_ref}
+ vals = {"partner_id": partner.id, "client_order_ref": client_order_ref}
if equipment:
- vals.update({'default_equipment_ids': [Command.set([equipment.id])]})
+ 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)
+ 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=None, 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,
- 'product_uom_qty': qty,
- 'product_uom': uom and uom.id or cls.env.ref("uom.product_uom_hour").id,
- 'price_unit': price,
- 'tax_id': tax_id,
- })
+ return cls.env["sale.order.line"].create(
+ {
+ "order_id": sale_order.id,
+ "product_id": product.id,
+ "product_uom_qty": qty,
+ "product_uom": uom and uom.id or cls.env.ref("uom.product_uom_hour").id,
+ "price_unit": price,
+ "tax_id": tax_id,
+ }
+ )
@classmethod
- def _generate_equipment(cls, name='test equipment', partner=None):
- return cls.env['bemade_fsm.equipment'].create({
- 'name': name,
- 'partner_location_id': partner and partner.id or False,
- })
+ def _generate_equipment(cls, name="test equipment", partner=None):
+ return cls.env["bemade_fsm.equipment"].create(
+ {
+ "name": name,
+ "partner_location_id": partner and partner.id or False,
+ }
+ )
@classmethod
- def _generate_product(cls, name='Test Product', product_type='service', service_tracking='task_global_project',
- project=None, task_template=None, service_policy='delivered_manual', uom=None):
- if 'project' in service_tracking and not project:
+ def _generate_product(
+ cls,
+ name="Test Product",
+ product_type="service",
+ service_tracking="task_global_project",
+ project=None,
+ task_template=None,
+ service_policy="delivered_manual",
+ uom=None,
+ ):
+ if "project" in service_tracking and not project:
project = cls.env.ref("industry_fsm.fsm_project")
uom_id = uom and uom.id or cls.env.ref("uom.product_uom_hour").id or False
- return cls.env['product.product'].create({
- 'name': name,
- 'type': product_type,
- 'service_tracking': service_tracking,
- 'service_type': 'timesheet',
- 'project_id': service_tracking in ('task_global_project', 'project_only') and project.id or False,
- 'project_template_id': service_tracking == 'task_in_project' and project.id or False,
- 'task_template_id': task_template and task_template.id or False,
- 'service_policy': service_policy,
- 'uom_id': uom_id,
- 'uom_po_id': uom_id,
- })
+ return cls.env["product.product"].create(
+ {
+ "name": name,
+ "type": product_type,
+ "service_tracking": service_tracking,
+ "service_type": "timesheet",
+ "project_id": (
+ service_tracking in ("task_global_project", "project_only")
+ and project.id
+ or False
+ ),
+ "project_template_id": (
+ service_tracking == "task_in_project" and project.id or False
+ ),
+ "task_template_id": task_template and task_template.id or False,
+ "service_policy": service_policy,
+ "uom_id": uom_id,
+ "uom_po_id": uom_id,
+ }
+ )
@classmethod
- def _generate_fsm_project(cls, name='Test Project'):
- return cls.env['project.project'].create({
- 'name': name,
- 'allow_material': True,
- 'allow_timesheets': True,
- 'allow_quotations': True,
- 'allow_worksheets': True,
- 'is_fsm': True,
- })
+ def _generate_fsm_project(cls, name="Test Project"):
+ return cls.env["project.project"].create(
+ {
+ "name": name,
+ "allow_material": True,
+ "allow_timesheets": True,
+ "allow_quotations": True,
+ "allow_worksheets": True,
+ "is_fsm": True,
+ }
+ )
@classmethod
- def _generate_task_template(cls, parent=None, structure=None, names=None, planned_hours=1,
- equipment=None, customer=None):
- """ Generates a task template with the specified structure and naming.
+ def _generate_task_template(
+ cls,
+ parent=None,
+ structure=None,
+ names=None,
+ planned_hours=1,
+ equipment=None,
+ customer=None,
+ ):
+ """Generates a task template with the specified structure and naming.
:param parent: The parent task template for the top-level task template being generated
:param structure: A list of integers describing the number of tasks for each level of descendants. An empty
@@ -142,48 +194,64 @@ class BemadeFSMBaseTest(TransactionCase):
by a sequential integer for its level. Child 1, Child 2, Grandchild 1, etc. If no names argument
is passed, a default ['Task Template'] argument will be used.
:param planned_hours: The number of planned hours for the top-level task template being generated.
- :param equipment: The equipment to add as linked equipment to the task template."""
+ :param equipment: The equipment to add as linked equipment to the task template.
+ """
if not names:
- names = ['Task Template']
+ names = ["Task Template"]
if not structure:
structure = []
if len(structure) != len(names) - 1:
- raise ValueError("The length of the structure argument must contain exactly one element less than the "
- "names argument.")
+ raise ValueError(
+ "The length of the structure argument must contain exactly one element"
+ " less than the names argument."
+ )
name = names.pop(0)
- template = cls.env['project.task.template'].create({
- 'name': name,
- 'parent': parent and parent.id or False,
- 'planned_hours': planned_hours,
- 'equipment_ids': [Command.set(equipment and [equipment.id] or [])],
- 'customer': customer and customer.id or False,
- })
+ template = cls.env["project.task.template"].create(
+ {
+ "name": name,
+ "parent": parent and parent.id or False,
+ "planned_hours": planned_hours,
+ "equipment_ids": [Command.set(equipment and [equipment.id] or [])],
+ "customer": customer and customer.id or False,
+ }
+ )
parent = template
while structure:
subtasks = []
for i in range(0, structure[0]):
- subtasks.append(cls.env['project.task.template'].create({
- 'parent': parent.id,
- 'name': names[0] + f" {i}",
- }))
+ subtasks.append(
+ cls.env["project.task.template"].create(
+ {
+ "parent": parent.id,
+ "name": names[0] + f" {i}",
+ }
+ )
+ )
structure.pop(0)
names.pop(0)
parent = subtasks[0]
return template
def _invoice_sale_order(self, so):
- wiz = self.env['sale.advance.payment.inv'].with_context(
- {'active_ids': [so.id]}).create({})
+ wiz = (
+ self.env["sale.advance.payment.inv"]
+ .with_context(active_ids=[so.id])
+ .create({})
+ )
wiz.create_invoices()
inv = so.invoice_ids[-1]
inv.action_post()
return inv
def _generate_visit(self, sale_order, label="Test Label"):
- return self.env['bemade_fsm.visit'].create([{
- 'sale_order_id': sale_order.id,
- 'label': label,
- }])
+ return self.env["bemade_fsm.visit"].create(
+ [
+ {
+ "sale_order_id": sale_order.id,
+ "label": label,
+ }
+ ]
+ )
def _generate_so_with_one_visit_two_lines(self):
so = self._generate_sale_order()
@@ -198,8 +266,10 @@ class BemadeFSMBaseTest(TransactionCase):
def _generate_so_with_one_visit_two_lines_and_descendants(self):
so = self._generate_sale_order()
visit = self._generate_visit(sale_order=so)
- task_template = self._generate_task_template(structure=[2, 2, 2],
- names=['Parent', 'Child', 'Grandchild', 'Great-grandchild'])
+ task_template = self._generate_task_template(
+ structure=[2, 2, 2],
+ names=["Parent", "Child", "Grandchild", "Great-grandchild"],
+ )
product = self._generate_product(task_template=task_template)
sol1 = self._generate_sale_order_line(sale_order=so, product=product)
sol2 = self._generate_sale_order_line(sale_order=so, product=product)
diff --git a/bemade_fsm/tests/test_equipment.py b/bemade_fsm/tests/test_equipment.py
index 16e06e2..8aa68e7 100644
--- a/bemade_fsm/tests/test_equipment.py
+++ b/bemade_fsm/tests/test_equipment.py
@@ -1,4 +1,4 @@
-from odoo.tests.common import HttpCase, tagged
+from odoo.tests.common import tagged
from .test_bemade_fsm_common import BemadeFSMBaseTest
from odoo import Command
from odoo.exceptions import MissingError
@@ -8,14 +8,14 @@ from odoo.exceptions import MissingError
class TestEquipment(BemadeFSMBaseTest):
def test_crud(self):
partner_company = self._generate_partner()
- partner_contact = self._generate_partner('Site Contact', 'person', partner_company)
- equipment = self._generate_equipment('Test Equipment 1', partner_company)
+ self._generate_partner("Site Contact", "person", partner_company)
+ equipment = self._generate_equipment("Test Equipment 1", partner_company)
# Just make sure the basic ORM stuff is OK
self.assertTrue(equipment in partner_company.equipment_ids)
self.assertTrue(len(partner_company.equipment_ids) == 1)
# Delete should cascade
- partner_company.write({'equipment_ids': [Command.set([])]})
+ partner_company.write({"equipment_ids": [Command.set([])]})
with self.assertRaises(MissingError):
- equipment.name
+ _ = equipment.name
diff --git a/bemade_fsm/tests/test_fsm_contact_setting.py b/bemade_fsm/tests/test_fsm_contact_setting.py
index 8920f88..2344b10 100644
--- a/bemade_fsm/tests/test_fsm_contact_setting.py
+++ b/bemade_fsm/tests/test_fsm_contact_setting.py
@@ -1,34 +1,38 @@
-from odoo.tests import TransactionCase, HttpCase, tagged, Form
+from odoo.tests import tagged, Form
from odoo import Command
from .test_bemade_fsm_common import BemadeFSMBaseTest
@tagged("-at_install", "post_install")
class SaleOrderFSMContactsCase(BemadeFSMBaseTest):
-
def test_site_contacts(self):
- parent_co = self._generate_partner('Parent Co')
- contact_1 = self._generate_partner('Contact 1', 'person', parent_co)
- contact_2 = self._generate_partner('Contact 2', 'person', parent_co)
+ parent_co = self._generate_partner("Parent Co")
+ contact_1 = self._generate_partner("Contact 1", "person", parent_co)
+ contact_2 = self._generate_partner("Contact 2", "person", parent_co)
# Make sure the SO pulls the defaults from the partner correctly
- parent_co.write({'site_contacts': [Command.set([contact_1.id, contact_2.id])]})
+ parent_co.write({"site_contacts": [Command.set([contact_1.id, contact_2.id])]})
so = self._generate_sale_order(parent_co)
self.assertTrue(so.site_contacts == parent_co.site_contacts)
# Make sure updating the site contacts on the SO doesn't feed back to the partner
- so.write({'site_contacts': [Command.set([contact_1.id])]})
+ so.write({"site_contacts": [Command.set([contact_1.id])]})
self.assertTrue(contact_1 in so.site_contacts)
self.assertTrue(contact_2 not in so.site_contacts)
- self.assertTrue(so.site_contacts != so.partner_id.site_contacts and len(so.partner_id.site_contacts) == 2)
+ self.assertTrue(
+ so.site_contacts != so.partner_id.site_contacts
+ and len(so.partner_id.site_contacts) == 2
+ )
def test_default_workorder_contacts(self):
- parent_co = self._generate_partner('Parent Co')
- contact_1 = self._generate_partner('Contact 1', 'person', parent_co)
- contact_2 = self._generate_partner('Contact 2', 'person', parent_co)
+ parent_co = self._generate_partner("Parent Co")
+ contact_1 = self._generate_partner("Contact 1", "person", parent_co)
+ contact_2 = self._generate_partner("Contact 2", "person", parent_co)
# Make sure the SO pulls the defaults from the partner correctly
- parent_co.write({'work_order_contacts': [Command.set([contact_1.id, contact_2.id])]})
+ parent_co.write(
+ {"work_order_contacts": [Command.set([contact_1.id, contact_2.id])]}
+ )
so = self._generate_sale_order(parent_co)
self.assertTrue(contact_1 in parent_co.work_order_contacts)
self.assertTrue(contact_2 in parent_co.work_order_contacts)
@@ -36,42 +40,74 @@ class SaleOrderFSMContactsCase(BemadeFSMBaseTest):
self.assertTrue(contact_2 in so.work_order_contacts)
# Make sure setting the work order contacts on the SO doesn't feed back to the partner
- so.write({'work_order_contacts': [Command.set([contact_1.id])]})
+ so.write({"work_order_contacts": [Command.set([contact_1.id])]})
self.assertTrue(contact_1 in so.work_order_contacts)
self.assertTrue(contact_2 not in so.work_order_contacts)
self.assertTrue(
- so.work_order_contacts != so.partner_id.work_order_contacts and len(so.partner_id.work_order_contacts) == 2)
+ so.work_order_contacts != so.partner_id.work_order_contacts
+ and len(so.partner_id.work_order_contacts) == 2
+ )
def test_multilayer_site_contacts(self):
- parent_co = self._generate_partner('Parent Co')
- shipping_location = self._generate_partner('Shipping Location', 'company', parent_co, 'delivery')
- wo_contact_1 = self._generate_partner('WO Contact 1', 'person', shipping_location)
- wo_contact_2 = self._generate_partner('WO Contact 2', 'person', shipping_location)
- site_contact_1 = self._generate_partner('Site Contact 1', 'person', shipping_location)
- site_contact_2 = self._generate_partner('Site Contact 2', 'person', shipping_location)
- shipping_location.write({
- 'work_order_contacts': [Command.set([wo_contact_1.id, wo_contact_2.id])],
- 'site_contacts': [Command.set([site_contact_1.id, site_contact_2.id])]
- })
+ parent_co = self._generate_partner("Parent Co")
+ shipping_location = self._generate_partner(
+ "Shipping Location", "company", parent_co, "delivery"
+ )
+ wo_contact_1 = self._generate_partner(
+ "WO Contact 1", "person", shipping_location
+ )
+ wo_contact_2 = self._generate_partner(
+ "WO Contact 2", "person", shipping_location
+ )
+ site_contact_1 = self._generate_partner(
+ "Site Contact 1", "person", shipping_location
+ )
+ site_contact_2 = self._generate_partner(
+ "Site Contact 2", "person", shipping_location
+ )
+ shipping_location.write(
+ {
+ "work_order_contacts": [
+ Command.set([wo_contact_1.id, wo_contact_2.id])
+ ],
+ "site_contacts": [Command.set([site_contact_1.id, site_contact_2.id])],
+ }
+ )
so = self._generate_sale_order(parent_co)
- so.write({'partner_shipping_id': shipping_location.id})
+ so.write({"partner_shipping_id": shipping_location.id})
self.assertEqual(so.site_contacts, shipping_location.site_contacts)
self.assertEqual(so.work_order_contacts, shipping_location.work_order_contacts)
def test_onchange_shipping_address(self):
- self.env.user.groups_id += self.env.ref('account.group_delivery_invoice_address')
- parent_co = self._generate_partner('Parent Co')
- shipping_location = self._generate_partner('Shipping Location', 'company', parent_co, 'delivery')
- wo_contact_1 = self._generate_partner('WO Contact 1', 'person', shipping_location)
- wo_contact_2 = self._generate_partner('WO Contact 2', 'person', shipping_location)
- site_contact_1 = self._generate_partner('Site Contact 1', 'person', shipping_location)
- site_contact_2 = self._generate_partner('Site Contact 2', 'person', shipping_location)
- shipping_location.write({
- 'work_order_contacts': [Command.set([wo_contact_1.id, wo_contact_2.id])],
- 'site_contacts': [Command.set([site_contact_1.id, site_contact_2.id])]
- })
+ self.env.user.groups_id += self.env.ref(
+ "account.group_delivery_invoice_address"
+ )
+ parent_co = self._generate_partner("Parent Co")
+ shipping_location = self._generate_partner(
+ "Shipping Location", "company", parent_co, "delivery"
+ )
+ wo_contact_1 = self._generate_partner(
+ "WO Contact 1", "person", shipping_location
+ )
+ wo_contact_2 = self._generate_partner(
+ "WO Contact 2", "person", shipping_location
+ )
+ site_contact_1 = self._generate_partner(
+ "Site Contact 1", "person", shipping_location
+ )
+ site_contact_2 = self._generate_partner(
+ "Site Contact 2", "person", shipping_location
+ )
+ shipping_location.write(
+ {
+ "work_order_contacts": [
+ Command.set([wo_contact_1.id, wo_contact_2.id])
+ ],
+ "site_contacts": [Command.set([site_contact_1.id, site_contact_2.id])],
+ }
+ )
so = self._generate_sale_order(parent_co)
diff --git a/bemade_fsm/tests/test_fsm_visit.py b/bemade_fsm/tests/test_fsm_visit.py
index 5f9a693..ee76d7c 100644
--- a/bemade_fsm/tests/test_fsm_visit.py
+++ b/bemade_fsm/tests/test_fsm_visit.py
@@ -1,11 +1,10 @@
-from odoo.tests import TransactionCase, tagged, Form
+from odoo.tests import tagged
from .test_bemade_fsm_common import BemadeFSMBaseTest
from datetime import date, timedelta
-@tagged('-at_install', 'post_install')
+@tagged("-at_install", "post_install")
class FSMVisitTest(BemadeFSMBaseTest):
-
def test_create_visit_sets_name_on_section(self):
so = self._generate_sale_order()
self._generate_sale_order_line(sale_order=so)
@@ -38,7 +37,7 @@ class FSMVisitTest(BemadeFSMBaseTest):
visit = self._generate_visit(so)
self._generate_sale_order_line(so)
so.action_confirm()
- task = so.order_line.filtered(lambda l: l.task_id).task_id
+ task = so.order_line.filtered(lambda line: line.task_id).task_id
task.action_fsm_validate()
@@ -49,7 +48,7 @@ class FSMVisitTest(BemadeFSMBaseTest):
visit = self._generate_visit(so)
self._generate_sale_order_line(so)
so.action_confirm()
- task = so.order_line.filtered(lambda l: l.task_id).task_id
+ task = so.order_line.filtered(lambda line: line.task_id).task_id
task.action_fsm_validate()
self._invoice_sale_order(so)
@@ -65,7 +64,10 @@ class FSMVisitTest(BemadeFSMBaseTest):
self.assertTrue(visit_task)
visit_subtasks = visit_task.child_ids
self.assertTrue(
- visit_subtasks and sol1.task_id in visit_subtasks and sol2.task_id in visit_subtasks)
+ visit_subtasks
+ and sol1.task_id in visit_subtasks
+ and sol2.task_id in visit_subtasks
+ )
def test_visit_task_gets_correct_due_date_on_confirmation(self):
so, visit, sol1, sol2 = self._generate_so_with_one_visit_two_lines()
@@ -94,7 +96,7 @@ class FSMVisitTest(BemadeFSMBaseTest):
self.assertEqual(visit_task.allocated_hours, 8.0)
def test_adding_visit_creates_one_sale_order_line(self):
- partner = self._generate_partner()
+ self._generate_partner()
so = self._generate_sale_order()
self._generate_sale_order_line(sale_order=so)
self._generate_sale_order_line(sale_order=so)
@@ -104,7 +106,12 @@ class FSMVisitTest(BemadeFSMBaseTest):
self.assertEqual(len(so.order_line), 3)
def test_marking_visit_task_done_completes_descendants(self):
- so, visit, sol1, sol2 = self._generate_so_with_one_visit_two_lines_and_descendants()
+ (
+ so,
+ visit,
+ sol1,
+ sol2,
+ ) = self._generate_so_with_one_visit_two_lines_and_descendants()
so.action_confirm()
parent = visit.task_id
@@ -113,7 +120,7 @@ class FSMVisitTest(BemadeFSMBaseTest):
self._assert_is_done(parent)
def _assert_is_done(self, task):
- """ Recursively assert all tasks in a hierarchy are complete """
+ """Recursively assert all tasks in a hierarchy are complete"""
self.assertTrue(task.is_closed)
for child in task.child_ids:
self._assert_is_done(child)
@@ -127,11 +134,11 @@ class FSMVisitTest(BemadeFSMBaseTest):
self.assertEqual(len(so.order_line), 3)
def test_confirming_so_names_visit_properly(self):
- """ Visits should be named
- Visit - """
+ """Visits should be named - Visit - """
so, visit, sol1, sol2 = self._generate_so_with_one_visit_two_lines()
so.name = "SO12345"
so.action_confirm()
task = visit.task_id
- supposed_name = f"SVR12345-1 - Test Company - Test Label"
+ supposed_name = "SVR12345-1 - Test Company - Test Label"
self.assertEqual(task.name, supposed_name)
diff --git a/bemade_fsm/tests/test_sale_order.py b/bemade_fsm/tests/test_sale_order.py
index fd5d620..a8869a9 100644
--- a/bemade_fsm/tests/test_sale_order.py
+++ b/bemade_fsm/tests/test_sale_order.py
@@ -1,13 +1,14 @@
from .test_task_template import BemadeFSMBaseTest
-from odoo.tests.common import tagged, HttpCase, Form
+from odoo.tests.common import tagged, Form
from odoo import Command
@tagged("-at_install", "post_install")
class TestSalesOrder(BemadeFSMBaseTest):
- @tagged('-at_install', 'post_install')
+ @tagged("-at_install", "post_install")
def test_order_confirmation_simple_template(self):
- """ Confirming the order should create a task in the global project based on the task template. """
+ """Confirming the order should create a task in the global project based on the
+ task template."""
partner = self._generate_partner()
so = self._generate_sale_order(partner=partner)
task_template = self._generate_task_template(planned_hours=8)
@@ -24,10 +25,10 @@ class TestSalesOrder(BemadeFSMBaseTest):
def test_task_template_tree_order_confirmation(self):
partner = self._generate_partner()
so = self._generate_sale_order(partner=partner)
- parent_template = self._generate_task_template(structure=[2, 1],
- names=['Parent Template',
- 'Child Template',
- 'Grandchild Template'])
+ parent_template = self._generate_task_template(
+ structure=[2, 1],
+ names=["Parent Template", "Child Template", "Grandchild Template"],
+ )
child_template_1 = parent_template.subtasks[0]
child_template_2 = parent_template.subtasks[1]
grandchild_template = parent_template.subtasks[0].subtasks[0]
@@ -47,7 +48,7 @@ class TestSalesOrder(BemadeFSMBaseTest):
self.assertEqual(grandchild_template.name, gc.name)
def test_order_confirmation_single_equipment(self):
- """ The equipment selected on the SO should transfer to the task."""
+ """The equipment selected on the SO should transfer to the task."""
partner = self._generate_partner()
equipment = self._generate_equipment(partner=partner)
so = self._generate_sale_order(partner=partner, equipment=equipment)
@@ -65,18 +66,22 @@ class TestSalesOrder(BemadeFSMBaseTest):
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 """
+ """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)]
+ partner=partner
+ ) # No default equipment since more than 3 on partner
+ sol1, sol2, sol3 = [
+ self._generate_sale_order_line(sale_order=sale_order) for _ in range(3)
+ ]
sol1.equipment_ids = [
- Command.set([partner.equipment_ids[i].id for i in range(2)])]
+ 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)])]
+ Command.set([partner.equipment_ids[i].id for i in range(2, 5)])
+ ]
sale_order.action_confirm()
@@ -85,7 +90,8 @@ class TestSalesOrder(BemadeFSMBaseTest):
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."""
+ """The equipment selected on a task template should flow down to the task
+ created on SO confirmation."""
partner = self._generate_partner()
equipment = self._generate_equipment(partner=partner)
so = self._generate_sale_order(partner=partner)
@@ -98,7 +104,8 @@ 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. """
+ """Sale order lines created on a 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)
@@ -108,7 +115,7 @@ class TestSalesOrder(BemadeFSMBaseTest):
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."""
+ """Should pick up equipment from the partner."""
partner = self._generate_partner()
self._generate_equipment(partner=partner)
@@ -126,7 +133,9 @@ class TestSalesOrder(BemadeFSMBaseTest):
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):
+ 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):
@@ -150,7 +159,7 @@ class TestSalesOrder(BemadeFSMBaseTest):
def test_sale_order_prioritize_shipping_location_equipments(self):
parent = self._generate_partner()
- child = self._generate_partner(parent=parent, location_type='delivery')
+ child = self._generate_partner(parent=parent, location_type="delivery")
self._generate_equipment(partner=parent)
self._generate_equipment(partner=child)
@@ -171,11 +180,13 @@ class TestSalesOrder(BemadeFSMBaseTest):
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."""
+ """Marking the task linked to a SO line should mark the line delivered.
+ Marking sub-tasks done should not."""
partner = self._generate_partner()
so = self._generate_sale_order(partner=partner)
- task_template = self._generate_task_template(structure=[2],
- names=["Parent Task", "Subtask"])
+ task_template = self._generate_task_template(
+ structure=[2], names=["Parent Task", "Subtask"]
+ )
product = self._generate_product(task_template=task_template)
sol = self._generate_sale_order_line(so, product=product)
so.action_confirm()
@@ -186,20 +197,24 @@ class TestSalesOrder(BemadeFSMBaseTest):
subtasks.action_fsm_validate(True)
self.assertEqual(sol.qty_delivered, 0)
- # Marking the top-level tasks done should set the delivered quantity to some non-zero value based on the UOM
+ # Marking the top-level tasks done should set the delivered quantity to some
+ # non-zero value based on the UOM
parent_task.action_fsm_validate(True)
self.assertTrue(sol.qty_delivered != 0)
def test_task_contacts_through_sale_order(self):
- """ Make sure the site contacts and work order contacts transfer correctly from the SO to the task."""
+ """Make sure the site contacts and work order contacts transfer correctly
+ from the SO to the task."""
partner = self._generate_partner()
- contact1 = self._generate_partner('Site contact', 'person', partner)
- contact2 = self._generate_partner('Work order contact', 'person', partner)
- partner.write({
- 'site_contacts': [Command.set([contact1.id])],
- 'work_order_contacts': [Command.set([contact2.id])],
- })
+ contact1 = self._generate_partner("Site contact", "person", partner)
+ contact2 = self._generate_partner("Work order contact", "person", partner)
+ partner.write(
+ {
+ "site_contacts": [Command.set([contact1.id])],
+ "work_order_contacts": [Command.set([contact2.id])],
+ }
+ )
so = self._generate_sale_order(partner)
product = self._generate_product()
sol = self._generate_sale_order_line(sale_order=so, product=product)
@@ -213,7 +228,7 @@ class TestSalesOrder(BemadeFSMBaseTest):
def test_tasks_created_at_order_confirmation_have_no_assignees(self):
so, visit, sol1, sol2 = self._generate_so_with_one_visit_two_lines()
- user = self._generate_project_user(name="User", login='login')
+ user = self._generate_project_user(name="User", login="login")
# We test as a specific user since testing as root may not produce the error
so.with_user(user).action_confirm()
@@ -224,13 +239,15 @@ class TestSalesOrder(BemadeFSMBaseTest):
self.assertFalse(visit_task.user_ids)
self.assertFalse(subtask1.user_ids)
self.assertFalse(subtask2.user_ids)
-
+
def test_long_line_name_overflows_to_task_description(self):
so = self._generate_sale_order()
product = self._generate_product()
- product.description_sale = "This is a long product description.\n" \
- "It even spans multiple lines.\n" \
- "One could find this annoying in a task name."
+ product.description_sale = (
+ "This is a long product description.\n"
+ "It even spans multiple lines.\n"
+ "One could find this annoying in a task name."
+ )
sol = self._generate_sale_order_line(sale_order=so, product=product)
@@ -241,12 +258,15 @@ class TestSalesOrder(BemadeFSMBaseTest):
self.assertFalse("It even spans multiple lines." in task.name)
self.assertFalse("One could find this annoying in a task name." in task.name)
self.assertTrue("It even spans multiple lines." in task.description)
- self.assertTrue("One could find this annoying in a task name."
- in task.description)
+ self.assertTrue(
+ "One could find this annoying in a task name." in task.description
+ )
def test_subtask_templates_no_description_if_blank_on_template(self):
so = self._generate_sale_order()
- template = self._generate_task_template(structure=[5], names=['Parent', 'Child'])
+ template = self._generate_task_template(
+ structure=[5], names=["Parent", "Child"]
+ )
template.description = ""
template.subtasks[0].description = "Some fixed description"
for t in template.subtasks[1:]:
@@ -257,13 +277,15 @@ class TestSalesOrder(BemadeFSMBaseTest):
so.action_confirm()
task = sol.task_id
- self.assertEqual(task.child_ids[0].description, template.subtasks[0].description)
+ self.assertEqual(
+ task.child_ids[0].description, template.subtasks[0].description
+ )
for t in task.child_ids[1:]:
self.assertFalse(t.description)
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."""
+ """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()
so2 = so.copy()
@@ -278,19 +300,19 @@ class TestSalesOrder(BemadeFSMBaseTest):
so = self._generate_sale_order()
so.company_id.create_default_fsm_visit = True
product = self._generate_product()
- sol = self._generate_sale_order_line(so, product)
+ self._generate_sale_order_line(so, product)
so.action_confirm()
- visit_line = so.order_line.sorted('sequence')[0]
+ visit_line = so.order_line.sorted("sequence")[0]
self.assertTrue(so.visit_ids)
self.assertEqual(visit_line.visit_id, so.visit_ids)
def test_confirming_sale_order_with_visit_creates_no_new_lines(self):
so = self._generate_sale_order()
so.company_id.create_default_fsm_visit = True
- product = self._generate_product()
- visit = self._generate_visit(so)
+ self._generate_product()
+ self._generate_visit(so)
so.action_confirm()
@@ -300,9 +322,8 @@ class TestSalesOrder(BemadeFSMBaseTest):
so = self._generate_sale_order()
so.company_id.create_default_fsm_visit = False
product = self._generate_product()
- sol = self._generate_sale_order_line(so, product)
+ self._generate_sale_order_line(so, product)
so.action_confirm()
- visit_line = so.order_line.sorted('sequence')[0]
self.assertFalse(so.visit_ids)
diff --git a/bemade_fsm/tests/test_settings.py b/bemade_fsm/tests/test_settings.py
index e07a8d0..0ee4ba8 100644
--- a/bemade_fsm/tests/test_settings.py
+++ b/bemade_fsm/tests/test_settings.py
@@ -1,54 +1,48 @@
from odoo.tests import TransactionCase, Form, tagged
+
@tagged("-at_install", "post_install")
class TestSettings(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
- cls.test_partner_co = cls.env['res.partner'].create({
- 'name': 'Test Co',
- })
- cls.test_co = cls.env['res.company'].create({
- 'name': 'Test Co',
- 'country_id': cls.env.ref('base.ca').id,
-
- })
+ cls.test_partner_co = cls.env["res.partner"].create(
+ {
+ "name": "Test Co",
+ }
+ )
+ cls.test_co = cls.env["res.company"].create(
+ {
+ "name": "Test Co",
+ "country_id": cls.env.ref("base.ca").id,
+ }
+ )
cls.env.user.company_id = cls.test_co
def test_enabling_separate_time_on_work_orders(self):
- wizard = self.env['res.config.settings'].create({})
- self.assertFalse(
- self.test_co.split_time_from_materials_on_service_work_orders
- )
+ wizard = self.env["res.config.settings"].create({})
+ self.assertFalse(self.test_co.split_time_from_materials_on_service_work_orders)
with Form(wizard) as form:
form.separate_time_on_work_orders = True
- self.assertTrue(
- self.test_co.split_time_from_materials_on_service_work_orders
- )
+ self.assertTrue(self.test_co.split_time_from_materials_on_service_work_orders)
def test_disabling_separate_time_on_work_orders(self):
- wizard = self.env['res.config.settings'].create({})
+ wizard = self.env["res.config.settings"].create({})
self.test_co.split_time_from_materials_on_service_work_orders = True
with Form(wizard) as form:
form.separate_time_on_work_orders = False
- self.assertFalse(
- self.test_co.split_time_from_materials_on_service_work_orders
- )
+ self.assertFalse(self.test_co.split_time_from_materials_on_service_work_orders)
def test_enabling_create_default_fsm_visit(self):
- wizard = self.env['res.config.settings'].create({})
+ wizard = self.env["res.config.settings"].create({})
self.test_co.create_default_fsm_visit = False
with Form(wizard) as form:
form.create_default_fsm_visit = True
- self.assertTrue(
- self.test_co.create_default_fsm_visit
- )
+ self.assertTrue(self.test_co.create_default_fsm_visit)
def test_disabling_create_default_fsm_visit(self):
- wizard = self.env['res.config.settings'].create({})
+ wizard = self.env["res.config.settings"].create({})
self.test_co.create_default_fsm_visit = True
with Form(wizard) as form:
form.create_default_fsm_visit = False
- self.assertFalse(
- self.test_co.create_default_fsm_visit
- )
+ self.assertFalse(self.test_co.create_default_fsm_visit)
diff --git a/bemade_fsm/tests/test_task.py b/bemade_fsm/tests/test_task.py
index 8d5a3ef..156acbe 100644
--- a/bemade_fsm/tests/test_task.py
+++ b/bemade_fsm/tests/test_task.py
@@ -3,18 +3,19 @@ from odoo.tests.common import tagged, Form
from odoo import Command
-@tagged('post_install', '-at_install')
+@tagged("post_install", "-at_install")
class TaskTest(BemadeFSMBaseTest):
-
@classmethod
def setUpClass(cls):
# Chose to set up all tests the same way since this code was becoming very redundant
super().setUpClass()
- cls.user = cls._generate_project_manager_user('Bob', 'Bob')
+ cls.user = cls._generate_project_manager_user("Bob", "Bob")
def _generate_so_with_multilevel_task_template(self):
so = self._generate_sale_order()
- template = self._generate_task_template(names=['Parent', 'Child', 'Grandchild'], structure=[2, 1])
+ template = self._generate_task_template(
+ names=["Parent", "Child", "Grandchild"], structure=[2, 1]
+ )
product = self._generate_product(task_template=template)
sol = self._generate_sale_order_line(sale_order=so, product=product)
return so, sol
@@ -25,21 +26,27 @@ class TaskTest(BemadeFSMBaseTest):
task = sol.task_id
task.propagate_assignment = True
- task.write({
- 'user_ids': [Command.set([self.user.id])],
- 'propagate_assignment': True,
- })
+ task.write(
+ {
+ "user_ids": [Command.set([self.user.id])],
+ "propagate_assignment": True,
+ }
+ )
- self.assertTrue(all([t.user_ids == self.user for t in task | task._get_all_subtasks()]))
+ self.assertTrue(
+ all([t.user_ids == self.user for t in task | task._get_all_subtasks()])
+ )
def test_reassigning_task_doesnt_propagate_by_default(self):
so, sol = self._generate_so_with_multilevel_task_template()
so.action_confirm()
task = sol.task_id
- task.write({
- 'user_ids': [Command.set([self.user.id])],
- })
+ task.write(
+ {
+ "user_ids": [Command.set([self.user.id])],
+ }
+ )
self.assertFalse(any([t.user_ids for t in task.child_ids.child_ids]))
@@ -49,24 +56,25 @@ class TaskTest(BemadeFSMBaseTest):
task = sol.task_id
# First, set propagation and assign
task.propagate_assignment = True
- task.write({
- 'user_ids': [Command.set([self.user.id])]
- })
+ task.write({"user_ids": [Command.set([self.user.id])]})
# Then, unset propagation for the children and re-set assignment
- task.child_ids.write({'propagate_assignment': False})
- self.assertFalse(any([t.propagate_assignment for t in task._get_all_subtasks()]))
+ task.child_ids.write({"propagate_assignment": False})
+ self.assertFalse(
+ any([t.propagate_assignment for t in task._get_all_subtasks()])
+ )
# Then, test that assigning the parent only assigns its children, not its grandchildren
- task.write({
- 'user_ids': [Command.set([])]
- })
+ task.write({"user_ids": [Command.set([])]})
self.assertTrue(all([not t.user_ids for t in task | task.child_ids]))
- self.assertTrue(all([t.user_ids == self.user for t in task.child_ids.child_ids]))
+ self.assertTrue(
+ all([t.user_ids == self.user for t in task.child_ids.child_ids])
+ )
def test_task_gets_work_order_contacts_from_sale_order(self):
so, sol = self._generate_so_with_multilevel_task_template()
- work_order_contacts = self._generate_partner(parent=so.partner_id) | self._generate_partner(
- parent=so.partner_id)
- so.write({'work_order_contacts': [(6, 0, work_order_contacts.ids)]})
+ work_order_contacts = self._generate_partner(
+ parent=so.partner_id
+ ) | self._generate_partner(parent=so.partner_id)
+ so.write({"work_order_contacts": [(6, 0, work_order_contacts.ids)]})
so.action_confirm()
task = sol.task_id
@@ -80,8 +88,10 @@ class TaskTest(BemadeFSMBaseTest):
def test_task_gets_site_contacts_from_sale_order(self):
so, sol = self._generate_so_with_multilevel_task_template()
- site_contacts = self._generate_partner(parent=so.partner_id) | self._generate_partner(parent=so.partner_id)
- so.write({'site_contacts': [(6, 0, site_contacts.ids)]})
+ site_contacts = self._generate_partner(
+ parent=so.partner_id
+ ) | self._generate_partner(parent=so.partner_id)
+ so.write({"site_contacts": [(6, 0, site_contacts.ids)]})
so.action_confirm()
task = sol.task_id
@@ -95,12 +105,20 @@ class TaskTest(BemadeFSMBaseTest):
def test_task_gets_work_order_contacts_from_parent(self):
so, sol = self._generate_so_with_multilevel_task_template()
- work_order_contacts = self._generate_partner(parent=so.partner_id) | self._generate_partner(parent=so.partner_id)
- so.write({'work_order_contacts': [(6, 0, work_order_contacts.ids)]})
+ work_order_contacts = self._generate_partner(
+ parent=so.partner_id
+ ) | self._generate_partner(parent=so.partner_id)
+ so.write({"work_order_contacts": [(6, 0, work_order_contacts.ids)]})
so.action_confirm()
task = sol.task_id
- task.write({'work_order_contacts': [Command.link(self._generate_partner(parent=so.partner_id).id)]})
+ task.write(
+ {
+ "work_order_contacts": [
+ Command.link(self._generate_partner(parent=so.partner_id).id)
+ ]
+ }
+ )
for subtask in task._get_all_subtasks():
self.assertEqual(subtask.work_order_contacts, task.work_order_contacts)
with Form(task) as task_form:
@@ -111,12 +129,20 @@ class TaskTest(BemadeFSMBaseTest):
def test_task_gets_site_contacts_from_parent(self):
so, sol = self._generate_so_with_multilevel_task_template()
- site_contacts = self._generate_partner(parent=so.partner_id) | self._generate_partner(parent=so.partner_id)
- so.write({'site_contacts': [(6, 0, site_contacts.ids)]})
+ site_contacts = self._generate_partner(
+ parent=so.partner_id
+ ) | self._generate_partner(parent=so.partner_id)
+ so.write({"site_contacts": [(6, 0, site_contacts.ids)]})
so.action_confirm()
task = sol.task_id
- task.write({'site_contacts': [Command.link(self._generate_partner(parent=so.partner_id).id)]})
+ task.write(
+ {
+ "site_contacts": [
+ Command.link(self._generate_partner(parent=so.partner_id).id)
+ ]
+ }
+ )
for subtask in task._get_all_subtasks():
self.assertEqual(subtask.site_contacts, task.site_contacts)
with Form(task) as task_form:
diff --git a/bemade_fsm/tests/test_task_report.py b/bemade_fsm/tests/test_task_report.py
index c12295f..fab5521 100644
--- a/bemade_fsm/tests/test_task_report.py
+++ b/bemade_fsm/tests/test_task_report.py
@@ -4,34 +4,36 @@ from odoo.tests import Form
class TestTaskReport(BemadeFSMBaseTest):
def test_split_time_materials_setting(self):
- with Form(self.env['res.config.settings']) as settings:
+ with Form(self.env["res.config.settings"]) as settings:
settings.separate_time_on_work_orders = True
- with Form(self.env['res.config.settings']) as new_settings:
+ with Form(self.env["res.config.settings"]):
self.assertTrue(settings.separate_time_on_work_orders)
so = self._generate_sale_order()
service_product = self._generate_product()
material_product = self._generate_product(
name="Material Product",
- product_type='product',
- service_tracking='no',
+ product_type="product",
+ service_tracking="no",
)
visit = self._generate_visit(sale_order=so)
- sol = self._generate_sale_order_line(sale_order=so, product=service_product)
- sol2 = self._generate_sale_order_line(sale_order=so, product=material_product)
+ self._generate_sale_order_line(sale_order=so, product=service_product)
+ self._generate_sale_order_line(sale_order=so, product=material_product)
so.action_confirm()
task = visit.task_id
- html_content = self.env['ir.actions.report']._render(
- 'industry_fsm_report.worksheet_custom',
- [task.id],
- )[0].decode('utf-8').split('\n')
+ html_content = (
+ self.env["ir.actions.report"]
+ ._render(
+ "industry_fsm_report.worksheet_custom",
+ [task.id],
+ )[0]
+ .decode("utf-8")
+ .split("\n")
+ )
- strings_to_find = [
- "Materials
",
- "Material Product"
- ]
+ strings_to_find = ["Materials
", "Material Product"]
for line in strings_to_find:
line_found = False
diff --git a/bemade_fsm/tests/test_task_template.py b/bemade_fsm/tests/test_task_template.py
index 11479bb..ba6bd70 100644
--- a/bemade_fsm/tests/test_task_template.py
+++ b/bemade_fsm/tests/test_task_template.py
@@ -1,35 +1,34 @@
from .test_bemade_fsm_common import BemadeFSMBaseTest
-from odoo.tests.common import HttpCase, tagged, Form
+from odoo.tests.common import tagged, Form
from odoo.exceptions import MissingError
-from odoo import Command
from odoo.tools import mute_logger
-from psycopg2.errors import ForeignKeyViolation
+import psycopg2
-@tagged('-at_install', 'post_install')
+@tagged("-at_install", "post_install")
class TestTaskTemplate(BemadeFSMBaseTest):
-
def test_delete_task_template(self):
"""User should never be able to delete a task template used on a product"""
- task_template = self._generate_task_template(names=['Template 1'])
- product = self._generate_product(name="Test Product 1", task_template=task_template)
- with self.assertRaises(ForeignKeyViolation):
- with mute_logger('odoo.sql_db'):
+ task_template = self._generate_task_template(names=["Template 1"])
+ self._generate_product(name="Test Product 1", task_template=task_template)
+ with self.assertRaises(psycopg2.errors.ForeignKeyViolation):
+ with mute_logger("odoo.sql_db"):
task_template.unlink()
def test_delete_subtask_template(self):
- """ Deletion of a child task should be OK even if the parent is on a product. Children of the deleted
- subtask should be deleted."""
- parent_task = self._generate_task_template(structure=[2, 1],
- names=['Parent Template', 'Child Template',
- 'Grandchild Template'])
+ """Deletion of a child task should be OK even if the parent is on a product.
+ Children of the deleted subtask should be deleted."""
+ parent_task = self._generate_task_template(
+ structure=[2, 1],
+ names=["Parent Template", "Child Template", "Grandchild Template"],
+ )
grandchild_task = parent_task.subtasks[0].subtasks[0]
parent_task.subtasks[0].unlink()
# Reading deleted child's name field should be impossible
with self.assertRaises(MissingError):
- test = grandchild_task.name
+ _ = grandchild_task.name
def test_dissociating_customer_resets_equipment_appropriately(self):
partner1 = self._generate_partner()
@@ -38,7 +37,8 @@ class TestTaskTemplate(BemadeFSMBaseTest):
task = self._generate_task_template(customer=partner1, equipment=equipment1)
form = Form(task)
- # Switching the partner should trigger on_change that makes sure equipments are linked to the new partner
+ # Switching the partner should trigger on_change that makes sure equipments are
+ # linked to the new partner
form.customer = partner2
form.save()
@@ -46,7 +46,7 @@ class TestTaskTemplate(BemadeFSMBaseTest):
def test_child_task_names_are_short_version(self):
so, visit, sol1, sol2 = self._generate_so_with_one_visit_two_lines()
- template = self._generate_task_template(names=['Task'])
+ template = self._generate_task_template(names=["Task"])
product = self._generate_product(task_template=template)
sol1.name = "Short Name 1"
sol2.name = "Short Name 2"
@@ -60,14 +60,21 @@ class TestTaskTemplate(BemadeFSMBaseTest):
def test_task_creation_directly_from_template(self):
project = self.env.ref("industry_fsm.fsm_project")
- template = self._generate_task_template(names=['Task', 'Child', 'Grandchild'], structure=[2, 1])
+ template = self._generate_task_template(
+ names=["Task", "Child", "Grandchild"], structure=[2, 1]
+ )
task = template.create_task_from_self(project, "My new task")
self.assertEqual(len(task.child_ids), len(template.subtasks))
- self.assertEqual(len(task.child_ids[0].child_ids), len(template.subtasks[0].subtasks))
- self.assertEqual(len(task.child_ids[1].child_ids), len(template.subtasks[1].subtasks))
+ self.assertEqual(
+ len(task.child_ids[0].child_ids), len(template.subtasks[0].subtasks)
+ )
+ self.assertEqual(
+ len(task.child_ids[1].child_ids), len(template.subtasks[1].subtasks)
+ )
self.assertEqual(task.name, "My new task")
self.assertEqual(task.child_ids[0].name, template.subtasks[0].name)
- self.assertTrue(all([t.project_id == project for t in task | task._get_all_subtasks()]))
-
+ self.assertTrue(
+ all([t.project_id == project for t in task | task._get_all_subtasks()])
+ )
diff --git a/bemade_fsm/views/equipment.xml b/bemade_fsm/views/equipment.xml
index 3cf6a14..fca156f 100644
--- a/bemade_fsm/views/equipment.xml
+++ b/bemade_fsm/views/equipment.xml
@@ -1,32 +1,38 @@
-
+
bemade_fsm.equipment.form
bemade_fsm.equipment
-
@@ -36,12 +42,16 @@
bemade_fsm.equipment.tree
bemade_fsm.equipment
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/bemade_fsm/views/menus.xml b/bemade_fsm/views/menus.xml
index d5dce9e..5ee0f1c 100644
--- a/bemade_fsm/views/menus.xml
+++ b/bemade_fsm/views/menus.xml
@@ -1,32 +1,40 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
diff --git a/bemade_fsm/views/product_views.xml b/bemade_fsm/views/product_views.xml
index 56b669d..5efd9f7 100644
--- a/bemade_fsm/views/product_views.xml
+++ b/bemade_fsm/views/product_views.xml
@@ -1,30 +1,32 @@
-
+
-
+
+ bemade_fsm.product.template.form
+ product.template
+
+
+
+
+
+
+
-
- bemade_fsm.product.template.form
- product.template
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bemade_fsm/views/res_partner.xml b/bemade_fsm/views/res_partner.xml
index 7cbe295..df3b70e 100644
--- a/bemade_fsm/views/res_partner.xml
+++ b/bemade_fsm/views/res_partner.xml
@@ -1,4 +1,4 @@
-
+
Equipments
@@ -11,44 +11,71 @@
bemade_fsm.partner.equipment.location.form
res.partner
-
+
-
-
-
-
+
+
+
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
@@ -58,9 +85,9 @@
-
-
-
+
+
+
@@ -69,13 +96,15 @@
bemade_fsm.equipment
-
-
-
-
+
+
+
+
diff --git a/bemade_fsm/views/sale_order_views.xml b/bemade_fsm/views/sale_order_views.xml
index 369b30b..4fb8882 100644
--- a/bemade_fsm/views/sale_order_views.xml
+++ b/bemade_fsm/views/sale_order_views.xml
@@ -1,55 +1,65 @@
-
+
-
-
- bemade_fsm.sale_order.form
- sale.order
-
-
-
-
-
-
-
-
-
-
-
-
+
+ bemade_fsm.sale_order.form
+ sale.order
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
- bemade_fsm.visit.tree
- bemade_fsm.visit
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+ bemade_fsm.visit.tree
+ bemade_fsm.visit
+
+
+
+
+
+
+
+
+
+
diff --git a/bemade_fsm/views/task_template_views.xml b/bemade_fsm/views/task_template_views.xml
index 2b92ddf..aa61f5c 100644
--- a/bemade_fsm/views/task_template_views.xml
+++ b/bemade_fsm/views/task_template_views.xml
@@ -1,105 +1,127 @@
-
+
-
-
-
- bemade_fsm.task_template.form
- project.task.template
-
-
+
+
-
- Task Template
- ir.actions.act_window
- project.task.template
- tree,form
-
-
- There are no task templates, click above to create one.
-
-
-
+
+ project.task_template.tree
+ project.task.template
+
+
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
+
+ project.task_template.search
+ project.task.template
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Task Template
+ ir.actions.act_window
+ project.task.template
+ tree,form
+
+
+ There are no task templates, click above to create one.
+
+
+
+
diff --git a/bemade_fsm/views/task_views.xml b/bemade_fsm/views/task_views.xml
index fde605a..0a196b9 100644
--- a/bemade_fsm/views/task_views.xml
+++ b/bemade_fsm/views/task_views.xml
@@ -1,228 +1,222 @@
-
+
-
-
- bemade_fsm.project_task.form
- project.task
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mark as Delivered
- industry_fsm.group_fsm_manager
-
-
- Mark as Delivered
- industry_fsm.group_fsm_manager
-
+
+ bemade_fsm.project_task.form
+ project.task
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mark as Delivered
+ industry_fsm.group_fsm_manager
+
+
+ Mark as Delivered
+ industry_fsm.group_fsm_manager
+
+
+
+
+
+ project.task
+ bemade_fsm.project_task.form2
+
+
+
+
+
+
-
-
-
- project.task
- bemade_fsm.project_task.form2
-
-
-
-
-
-
-
+
+
+
+
+ {'search_default_is_parent_task': True}
+
+
+ project.task.view.list.fsm.inherit
+ project.task
+
+
+
+ project_list
+
+
+
-
-
-
- {'search_default_is_parent_task': True}
-
-
- {'search_default_is_parent_task': True}
-
-
- {'search_default_is_parent_task': True}
-
-
- {'search_default_is_parent_task': True}
-
-
- {'search_default_is_parent_task': True}
-
-
- {'search_default_is_parent_task': True}
-
-
- {'search_default_is_parent_task': True}
-
-
- {'search_default_is_parent_task': True}
-
-
- bemade_fsm.project_task_view_calendar_no_worksheet
-
- project.task
-
-
-
- user_ids
-
+
+ hide
-
-
- project.task.view.list.fsm.inherit
- project.task
-
-
-
- project_list
-
-
-
-
-
- hide
-
-
- hide
-
-
- hide
-
+
+ hide
-
-
- [('is_fsm', '=', True),
- ('project_id', '!=', False),
- ('display_in_project', '=', True),
- ('parent_id', '=', False)]
+
+ hide
-
-
- [('is_fsm', '=', True),
- ('project_id', '!=', False),
- ('display_in_project', '=', True),
- ('parent_id', '=', False)]
-
-
-
- [('is_fsm', '=', True),
- ('project_id', '!=', False),
- ('display_in_project', '=', True),
- ('parent_id', '=', False)]
-
-
-
- [('is_fsm', '=', True),
- ('project_id', '!=', False),
- ('display_in_project', '=', True),
- ('parent_id', '=', False),
- ('invoice_status', '=', 'to invoice')]
-
-
-
-
- [('is_fsm', '=', True),
- ('project_id', '!=', False),
- ('display_in_project', '=', True),
- ('parent_id', '=', False)]
-
-
-
- [('is_fsm', '=', True),
- ('project_id', '!=', False),
- ('display_in_project', '=', True),
- ('parent_id', '=', False)]
-
-
-
- [('is_fsm', '=', True),
- ('project_id', '!=', False),
- ('display_in_project', '=', True),
- ('parent_id', '=', False)]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- bemade_fsm.project_task_view_calendar_no_worksheet
-
- project.task
-
-
-
- user_ids
-
-
-
-
- project.task.view.search.fsm.inherit
- project.task
-
-
-
-
- [
- '&',
- ('fsm_done', '=', False),
- '|',
- ('user_ids', '=', False),
- '&',
- ('planned_date_start', '=', False),
- ('date_deadline', '=', False),
- ]
-
-
-
-
-
-
-
-
+
+
+
+ {'search_default_is_parent_task': True}
+ [('is_fsm', '=', True),
+ ('project_id', '!=', False),
+ ('display_in_project', '=', True),
+ ('parent_id', '=', False)]
+
+
+
+ {'search_default_is_parent_task': True}
+ [('is_fsm', '=', True),
+ ('project_id', '!=', False),
+ ('display_in_project', '=', True),
+ ('parent_id', '=', False)]
+
+
+
+ {'search_default_is_parent_task': True}
+ [('is_fsm', '=', True),
+ ('project_id', '!=', False),
+ ('display_in_project', '=', True),
+ ('parent_id', '=', False)]
+
+
+
+ {'search_default_is_parent_task': True}
+ [('is_fsm', '=', True),
+ ('project_id', '!=', False),
+ ('display_in_project', '=', True),
+ ('parent_id', '=', False),
+ ('invoice_status', '=', 'to invoice')]
+
+
+
+
+ {'search_default_is_parent_task': True}
+ [('is_fsm', '=', True),
+ ('project_id', '!=', False),
+ ('display_in_project', '=', True),
+ ('parent_id', '=', False)]
+
+
+
+ {'search_default_is_parent_task': True}
+ [('is_fsm', '=', True),
+ ('project_id', '!=', False),
+ ('display_in_project', '=', True),
+ ('parent_id', '=', False)]
+
+
+
+ {'search_default_is_parent_task': True}
+ [('is_fsm', '=', True),
+ ('project_id', '!=', False),
+ ('display_in_project', '=', True),
+ ('parent_id', '=', False)]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ bemade_fsm.project_task_view_calendar_no_worksheet
+
+ project.task
+
+
+
+
+ user_ids
+
+
+
+
+ project.task.view.search.fsm.inherit
+ project.task
+
+
+
+
+ [
+ '&',
+ ('fsm_done', '=', False),
+ '|',
+ ('user_ids', '=', False),
+ '&',
+ ('planned_date_start', '=', False),
+ ('date_deadline', '=', False),
+ ]
+
+
+
+
+
+
+
diff --git a/bemade_fsm/wizard/new_task_from_template.py b/bemade_fsm/wizard/new_task_from_template.py
index 6c8c5e1..519e1c7 100644
--- a/bemade_fsm/wizard/new_task_from_template.py
+++ b/bemade_fsm/wizard/new_task_from_template.py
@@ -1,5 +1,4 @@
-from odoo import models, fields, api, _
-from odoo.exceptions import UserError
+from odoo import models, fields
class NewTaskFromTemplateWizard(models.TransientModel):
@@ -7,45 +6,52 @@ class NewTaskFromTemplateWizard(models.TransientModel):
_description = "Create Task from Template Wizard"
project_id = fields.Many2one(
- comodel_name='project.project',
- string='Project',
- help='The project the new task should be created in.',
+ comodel_name="project.project",
+ string="Project",
+ help="The project the new task should be created in.",
required=True,
)
task_template_id = fields.Many2one(
- comodel_name='project.task.template',
- string='Task Template',
- help='The template to use when creating the new task.',
+ comodel_name="project.task.template",
+ string="Task Template",
+ help="The template to use when creating the new task.",
required=True,
)
new_task_title = fields.Char(
- help='The title (name) for the newly created task. If left blank, the name of the template will be used.',
+ help=(
+ "The title (name) for the newly created task. If left blank, the name of"
+ " the template will be used."
+ ),
)
def default_get(self, fields_list):
res = super().default_get(fields_list)
- active_id = self.env.context.get('active_id', False)
- active_model = self.env.context.get('active_model', False)
+ active_id = self.env.context.get("active_id", False)
+ active_model = self.env.context.get("active_model", False)
if not active_model:
- params = self.env.context.get('params', False)
- active_model = params and params.get('model', False)
- if active_model == 'project.task.template' and active_id and 'task_template_id' in fields_list:
- res.update({'task_template_id': active_id})
- if active_model == 'project.task' and 'project_id' in fields_list:
- res.update({'project_id': self.env.ref('industry_fsm.fsm_project').id})
+ params = self.env.context.get("params", False)
+ active_model = params and params.get("model", False)
+ if (
+ active_model == "project.task.template"
+ and active_id
+ and "task_template_id" in fields_list
+ ):
+ res.update({"task_template_id": active_id})
+ if active_model == "project.task" and "project_id" in fields_list:
+ res.update({"project_id": self.env.ref("industry_fsm.fsm_project").id})
return res
def action_create_task_from_template(self):
self.ensure_one()
- task = self.task_template_id.create_task_from_self(self.project_id, self.new_task_title)
+ task = self.task_template_id.create_task_from_self(
+ self.project_id, self.new_task_title
+ )
return {
- 'type': 'ir.actions.act_window',
- 'res_model': 'project.task',
- 'res_id': task.id,
- 'view_mode': 'form',
- 'target': 'current',
+ "type": "ir.actions.act_window",
+ "res_model": "project.task",
+ "res_id": task.id,
+ "view_mode": "form",
+ "target": "current",
}
-
-
diff --git a/bemade_fsm/wizard/res_config_settings.py b/bemade_fsm/wizard/res_config_settings.py
index 458c9b9..b4c371e 100644
--- a/bemade_fsm/wizard/res_config_settings.py
+++ b/bemade_fsm/wizard/res_config_settings.py
@@ -1,11 +1,11 @@
-from odoo import models, fields, api
+from odoo import models, fields
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
company_id = fields.Many2one(
- 'res.company',
+ "res.company",
default=lambda self: self.env.company or self.env.user.company_id,
)
separate_time_on_work_orders = fields.Boolean(