[FIX] hr_timesheet: _get_view dependent on company.timesheet_encode_uom_id

`hr_timesheet`, and other timesheet related modules,
overrides `_get_view` to change some timesheet time field label
from "Hours" to "Days" according if the company uses hours as
timesheet encoding UOM or days.

Since odoo/odoo#99417, and the fact back-end views are cached,
keys on which the model views depends on for the cache must be added
through an override of the method `_get_view_cache_key`.

Without this revision, if a database has
one company using hours as timesheet encoding uom,
and a second company using days as timesheet encoding uom,
the label for one of the two company could be wrong according
to which user/company accessed first the view,
for which company the view has been put in the cache first.

These overrides of `_get_view` should be replaced by another mechanism,
for instance by a Javascript widget,
as this mechanism doesn't really make sense when browsing
multiple companies at a time
(selecting multiple companies in the companies dropdown menu).
When going from one record to another with the left/right arrows,
the company can depend from one record to another,
and therefore the label should change from one record to another
according to its company, which is not the case with the current
implementation.
It could also be achieved by setting two different labels,
with an invisible attrs based on a related field
of company.timesheet_encode_uom_id.

However, as we are close to release, and 16.0 is already frozen,
no unstable changes should be done,
hence I restore the behavior which was there
before odoo/odoo#99417.

closes odoo/odoo#101964

X-original-commit: b2a9868b4a0db5a091a1faae38b7d4de29dfd2f4
Related: odoo/enterprise#32198
Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
This commit is contained in:
Denis Ledoux
2022-10-03 18:19:50 +02:00
parent 5c6640eb3d
commit 60dc29e0df
6 changed files with 71 additions and 0 deletions
@@ -214,6 +214,13 @@ class AccountAnalyticLine(models.Model):
self.filtered(lambda t: t.project_id)._timesheet_postprocess(values)
return result
@api.model
def _get_view_cache_key(self, view_id=None, view_type='form', **options):
"""The override of _get_view changing the time field labels according to the company timesheet encoding UOM
makes the view cache dependent on the company timesheet encoding uom"""
key = super()._get_view_cache_key(view_id, view_type, **options)
return key + (self.env.company.timesheet_encode_uom_id,)
@api.model
def _get_view(self, view_id=None, view_type='form', **options):
""" Set the correct label for `unit_amount`, depending on company UoM """
+14
View File
@@ -80,6 +80,13 @@ class Project(models.Model):
operator_new = 'not inselect'
return [('id', operator_new, (query, ()))]
@api.model
def _get_view_cache_key(self, view_id=None, view_type='form', **options):
"""The override of _get_view changing the time field labels according to the company timesheet encoding UOM
makes the view cache dependent on the company timesheet encoding uom"""
key = super()._get_view_cache_key(view_id, view_type, **options)
return key + (self.env.company.timesheet_encode_uom_id,)
@api.model
def _get_view(self, view_id=None, view_type='form', **options):
arch, view = super()._get_view(view_id, view_type, **options)
@@ -373,6 +380,13 @@ class Task(models.Model):
return list(name_mapping.items())
return super().name_get()
@api.model
def _get_view_cache_key(self, view_id=None, view_type='form', **options):
"""The override of _get_view changing the time field labels according to the company timesheet encoding UOM
makes the view cache dependent on the company timesheet encoding uom"""
key = super()._get_view_cache_key(view_id, view_type, **options)
return key + (self.env.company.timesheet_encode_uom_id,)
@api.model
def _get_view(self, view_id=None, view_type='form', **options):
""" Set the correct label for `unit_amount`, depending on company UoM """
@@ -32,6 +32,13 @@ class ReportProjectTaskUser(models.Model):
"""
return super(ReportProjectTaskUser, self)._group_by() + group_by_append
@api.model
def _get_view_cache_key(self, view_id=None, view_type='form', **options):
"""The override of _get_view changing the time field labels according to the company timesheet encoding UOM
makes the view cache dependent on the company timesheet encoding uom"""
key = super()._get_view_cache_key(view_id, view_type, **options)
return key + (self.env.company.timesheet_encode_uom_id,)
@api.model
def _get_view(self, view_id=None, view_type='form', **options):
arch, view = super()._get_view(view_id, view_type, **options)
@@ -56,6 +56,13 @@ class TimesheetsAnalysisReport(models.Model):
def _where(self):
return "WHERE A.project_id IS NOT NULL"
@api.model
def _get_view_cache_key(self, view_id=None, view_type='form', **options):
"""The override of _get_view changing the time field labels according to the company timesheet encoding UOM
makes the view cache dependent on the company timesheet encoding uom"""
key = super()._get_view_cache_key(view_id, view_type, **options)
return key + (self.env.company.timesheet_encode_uom_id,)
@api.model
def _get_view(self, view_id=None, view_type='form', **options):
arch, view = super()._get_view(view_id, view_type, **options)
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from lxml import etree
from odoo.fields import Command
from odoo.tests.common import TransactionCase
from odoo.exceptions import AccessError, UserError, ValidationError
@@ -90,6 +92,20 @@ class TestCommonTimesheet(TransactionCase):
'user_id': cls.user_manager.id,
})
def assert_get_view_timesheet_encode_uom(self, expected):
companies = self.env['res.company'].create([
{'name': 'foo', 'timesheet_encode_uom_id': self.env.ref('uom.product_uom_hour').id},
{'name': 'bar', 'timesheet_encode_uom_id': self.env.ref('uom.product_uom_day').id},
])
for view_xml_id, xpath_expr, expected_labels in expected:
for company, expected_label in zip(companies, expected_labels):
view = self.env.ref(view_xml_id)
view = self.env[view.model].with_company(company).get_view(view.id, view.type)
tree = etree.fromstring(view['arch'])
field_node = tree.xpath(xpath_expr)[0]
self.assertEqual(field_node.get('string'), expected_label)
class TestTimesheet(TestCommonTimesheet):
def setUp(self):
@@ -492,3 +508,14 @@ class TestTimesheet(TestCommonTimesheet):
with self.assertRaises(UserError):
timesheet.employee_id = self.empl_employee2
def test_get_view_timesheet_encode_uom(self):
""" Test the label of timesheet time spent fields according to the company encoding timesheet uom """
self.assert_get_view_timesheet_encode_uom([
('hr_timesheet.hr_timesheet_line_form', '//field[@name="unit_amount"]', ['Hours Spent', 'Days Spent']),
('hr_timesheet.project_invoice_form', '//field[@name="allocated_hours"]', [None, 'Allocated Days']),
('hr_timesheet.view_task_form2_inherited', '//field[@name="unit_amount"]', ['Hours Spent', 'Days Spent']),
('hr_timesheet.view_task_tree2_inherited', '//field[@name="planned_hours"]', [None, 'Initially Planned Days']),
('hr_timesheet.view_task_project_user_graph_inherited', '//field[@name="hours_planned"]', [None, 'Planned Days']),
('hr_timesheet.timesheets_analysis_report_pivot_employee', '//field[@name="unit_amount"]', [None, 'Days Spent']),
])
@@ -5,6 +5,7 @@ from datetime import date, timedelta
from odoo.fields import Date
from odoo.tools import float_is_zero
from odoo.exceptions import UserError
from odoo.addons.hr_timesheet.tests.test_timesheet import TestCommonTimesheet
from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheet
from odoo.tests import tagged
@@ -724,3 +725,11 @@ class TestSaleTimesheet(TestCommonSaleTimesheet):
move.with_context(check_move_validity=False).line_ids[0].unlink()
self.assertFalse(analytic_line.timesheet_invoice_id, "The timesheet should have been unlinked from move")
class TestSaleTimesheetView(TestCommonTimesheet):
def test_get_view_timesheet_encode_uom(self):
""" Test the label of timesheet time spent fields according to the company encoding timesheet uom """
self.assert_get_view_timesheet_encode_uom([
('sale_timesheet.project_project_view_form', '//field[@name="display_cost"]', [None, 'Daily Cost']),
])