[FIX] sale_timesheet: fix pricing_type search method
Before this commit, when a project has no SOL set and has an employee
mapping, then the domain builds in the search method of `pricing_type`
is the following:
`[
('sale_line_id', '!=', False),
('sale_line_employee_ids', '!=', False),
('allow_billable', '=', True),
]`
The problem is we don't need to have a SOL set into the project to
define the pricing_type as employee rate. We should find the project
with at least an employee mapping set in that project.
Moreover, this commit fixes the domain built in the
`_search_pricing_type` method.
Some unit tests are added to check the domain built in the
`_search_pricing_type` method.
The issue has been found during the development of task-2680425
closes odoo/odoo#83874
X-original-commit: 490747c85f2d2e390a44e8f375e24dc3a8425409
Related: odoo/enterprise#23951
Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
This commit is contained in:
@@ -78,9 +78,9 @@ class Project(models.Model):
|
||||
- value = 'employee_rate': [('sale_line_employee_ids', '!=', False), ('allow_billable', '=', True)]
|
||||
- value is False: [('allow_billable', '=', False)]
|
||||
- operator = '!=':
|
||||
- value = 'task_rate': ['|', ('sale_line_employee_ids', '!=', False), ('sale_line_id', '!=', False), ('allow_billable', '=', True)]
|
||||
- value = 'fixed_rate': ['|', ('sale_line_employee_ids', '!=', False), ('sale_line_id', '=', False), ('allow_billable', '=', True)]
|
||||
- value = 'employee_rate': [('sale_line_employee_ids', '=', False), ('allow_billable', '=', True)]
|
||||
- value = 'task_rate': ['|', '|', ('sale_line_employee_ids', '!=', False), ('sale_line_id', '!=', False), ('allow_billable', '=', False)]
|
||||
- value = 'fixed_rate': ['|', '|', ('sale_line_employee_ids', '!=', False), ('sale_line_id', '=', False), ('allow_billable', '=', False)]
|
||||
- value = 'employee_rate': ['|', ('sale_line_employee_ids', '=', False), ('allow_billable', '=', False)]
|
||||
- value is False: [('allow_billable', '!=', False)]
|
||||
|
||||
:param operator: the supported operator is either '=' or '!='.
|
||||
@@ -102,13 +102,13 @@ class Project(models.Model):
|
||||
elif value == 'fixed_rate':
|
||||
domain = [sol_cond, expression.NOT_OPERATOR, mapping_cond]
|
||||
else: # value == 'employee_rate'
|
||||
domain = [sol_cond, mapping_cond]
|
||||
domain = [mapping_cond]
|
||||
|
||||
domain = expression.AND([domain, [('allow_billable', '=', True)]])
|
||||
domain = expression.normalize_domain(domain)
|
||||
if operator != '=':
|
||||
domain.insert(0, expression.NOT_OPERATOR)
|
||||
domain = expression.distribute_not(domain)
|
||||
domain = expression.AND([domain, [('allow_billable', '=', True)]])
|
||||
return domain
|
||||
|
||||
@api.depends('analytic_account_id', 'timesheet_ids')
|
||||
|
||||
@@ -23,6 +23,14 @@ class TestProjectPricingType(TestCommonSaleTimesheet):
|
||||
project = self.project_non_billable
|
||||
self.assertFalse(project.allow_billable, 'The allow_billable should be false if the project is non billable.')
|
||||
self.assertFalse(project.pricing_type, 'The pricing type of this project should be equal to False since it is non billable.')
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'task_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'fixed_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'employee_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('=', False)))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'task_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'fixed_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'employee_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('!=', False)))
|
||||
|
||||
# 2) Set allow_billable to True and check if the pricing_type is equal to task_rate (if no SOL and no mappings)
|
||||
project.write({
|
||||
@@ -34,6 +42,14 @@ class TestProjectPricingType(TestCommonSaleTimesheet):
|
||||
self.assertFalse(project.sale_line_id, 'The sales order item should be unset.')
|
||||
self.assertFalse(project.sale_line_employee_ids, 'The employee mappings should be empty.')
|
||||
self.assertEqual(project.pricing_type, 'task_rate', 'The pricing type should be equal to task_rate.')
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('=', 'task_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'fixed_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'employee_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', False)))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('!=', 'task_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'fixed_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'employee_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', False)))
|
||||
|
||||
# 3) Set a customer and a SOL in the project and check if the pricing_type is equal to fixed_rate (project rate)
|
||||
project.write({
|
||||
@@ -44,6 +60,14 @@ class TestProjectPricingType(TestCommonSaleTimesheet):
|
||||
self.assertEqual(project.sale_order_id, self.so, 'The sales order should be equal to the one set in the project.')
|
||||
self.assertEqual(project.sale_line_id, self.so.order_line[0], 'The sales order item should be the one chosen.')
|
||||
self.assertEqual(project.pricing_type, 'fixed_rate', 'The pricing type should be equal to fixed_rate since the project has a sales order item.')
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'task_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('=', 'fixed_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'employee_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', False)))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'task_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('!=', 'fixed_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'employee_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', False)))
|
||||
|
||||
# 4) Set a employee mapping and check if the pricing_type is equal to employee_rate
|
||||
project.write({
|
||||
@@ -55,6 +79,14 @@ class TestProjectPricingType(TestCommonSaleTimesheet):
|
||||
|
||||
self.assertEqual(len(project.sale_line_employee_ids), 1, 'The project should have an employee mapping.')
|
||||
self.assertEqual(project.pricing_type, 'employee_rate', 'The pricing type should be equal to employee_rate since the project has an employee mapping.')
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'task_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'fixed_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('=', 'employee_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', False)))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'task_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'fixed_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('!=', 'employee_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', False)))
|
||||
|
||||
# Even if the project has no sales order item, since it has an employee mapping, the pricing type must be equal to employee_rate.
|
||||
project.write({
|
||||
@@ -63,3 +95,11 @@ class TestProjectPricingType(TestCommonSaleTimesheet):
|
||||
self.assertFalse(project.sale_order_id, 'The sales order of the project should be empty.')
|
||||
self.assertFalse(project.sale_line_id, 'The sales order item of the project should be empty.')
|
||||
self.assertEqual(project.pricing_type, 'employee_rate', 'The pricing type should always be equal to employee_rate.')
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'task_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', 'fixed_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('=', 'employee_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('=', False)))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'task_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', 'fixed_rate')))
|
||||
self.assertFalse(project.filtered_domain(project._search_pricing_type('!=', 'employee_rate')))
|
||||
self.assertTrue(project.filtered_domain(project._search_pricing_type('!=', False)))
|
||||
|
||||
Reference in New Issue
Block a user