From 9ea69adf7fff2afd3dca9110e9b7f1e26f3c84bc Mon Sep 17 00:00:00 2001 From: Simon Maillard Date: Tue, 21 Jan 2025 12:11:51 +0100 Subject: [PATCH] [IMP] hr_timesheet_report: Add day unit to the choices Allow to display times in days in the reports --- hr_timesheet_report/README.rst | 2 +- hr_timesheet_report/readme/DESCRIPTION.rst | 2 +- .../report/hr_timesheet_report.py | 17 ++++++++++++++-- .../report/hr_timesheet_report.xml | 20 ++++++++++++++++--- .../static/description/index.html | 14 +++++++------ .../tests/test_hr_timesheet_report.py | 20 ++++++++++++++++--- 6 files changed, 59 insertions(+), 16 deletions(-) diff --git a/hr_timesheet_report/README.rst b/hr_timesheet_report/README.rst index ca8062558..fb0aaf98a 100644 --- a/hr_timesheet_report/README.rst +++ b/hr_timesheet_report/README.rst @@ -34,7 +34,7 @@ Features: * Select reported fields * Select and reorder report line grouping - * Configure time format (HH:MM, HH:MM:SS, or decimal) + * Configure time format : Hours (HH:MM, HH:MM:SS, or decimal) or Days (decimal) * View in browser, export in PDF and XLSX formats **Table of contents** diff --git a/hr_timesheet_report/readme/DESCRIPTION.rst b/hr_timesheet_report/readme/DESCRIPTION.rst index 8e7da95a7..6b2fba5fb 100644 --- a/hr_timesheet_report/readme/DESCRIPTION.rst +++ b/hr_timesheet_report/readme/DESCRIPTION.rst @@ -4,5 +4,5 @@ Features: * Select reported fields * Select and reorder report line grouping - * Configure time format (HH:MM, HH:MM:SS, or decimal) + * Configure time format : Hours (HH:MM, HH:MM:SS, or decimal) or Days (decimal) * View in browser, export in PDF and XLSX formats diff --git a/hr_timesheet_report/report/hr_timesheet_report.py b/hr_timesheet_report/report/hr_timesheet_report.py index 9cac37251..14a2d3b5c 100644 --- a/hr_timesheet_report/report/hr_timesheet_report.py +++ b/hr_timesheet_report/report/hr_timesheet_report.py @@ -62,6 +62,7 @@ class HrTimesheetReport(models.TransientModel): selection=lambda self: self._selection_time_format(), required=True, ) + uom = fields.Many2one("uom.uom", compute="_compute_uom", store=True) group_ids = fields.One2many( string="Groups", comodel_name="hr.timesheet.report.group", @@ -81,6 +82,7 @@ def _selection_time_format(self): ("hh_mm", "Hours, minutes"), ("hh_mm_ss", "Hours, minutes, seconds"), ("decimal", "Decimal"), + ("days", "Days"), ] @api.model @@ -165,6 +167,14 @@ def _get_group_values(self, grouped_lines): "scope": ustr(grouped_lines["__domain"]), } + @api.depends("time_format") + def _compute_uom(self): + for report in self: + if report.time_format == "days": + report.uom = self.env.ref("uom.product_uom_day") + else: + report.uom = self.env.ref("uom.product_uom_hour") + @api.depends("group_ids.total_unit_amount") def _compute_total_unit_amount(self): for report in self: @@ -404,6 +414,7 @@ class HrTimesheetReportEntry(models.TransientModel): compute="_compute_total_unit_amount", store=True, ) + uom = fields.Many2one("uom.uom", related="group_id.report_id.uom") @api.depends("scope") def _compute_any_line_id(self): @@ -418,16 +429,16 @@ def _compute_any_line_id(self): @api.depends("scope") def _compute_total_unit_amount(self): AccountAnalyticLine = self.env["account.analytic.line"] - uom_hour = self.env.ref("uom.product_uom_hour") for entry in self: + total_unit_amount = 0.0 line_ids = AccountAnalyticLine.search( safe_eval(entry.scope) if entry.scope else TRUE_DOMAIN ) for line_id in line_ids: total_unit_amount += line_id.product_uom_id._compute_quantity( - line_id.unit_amount, uom_hour + line_id.unit_amount, entry.uom ) entry.total_unit_amount = total_unit_amount @@ -644,6 +655,8 @@ def _get_amount_num_format(self, report): return "[h]:mm" elif report.time_format == "hh_mm_ss": return "[h]:mm:ss" + elif report.time_format == "days": + return "0.00" @api.model def _convert_amount_num_format(self, report, amount): diff --git a/hr_timesheet_report/report/hr_timesheet_report.xml b/hr_timesheet_report/report/hr_timesheet_report.xml index 728d58ba8..b18340bc7 100644 --- a/hr_timesheet_report/report/hr_timesheet_report.xml +++ b/hr_timesheet_report/report/hr_timesheet_report.xml @@ -9,7 +9,6 @@ -
@@ -32,7 +31,12 @@ t-out="report.total_unit_amount" t-options="{'widget': 'float', 'precision': 2}" /> - + +
@@ -152,7 +156,7 @@ - + @@ -182,6 +186,11 @@ t-field="entry.total_unit_amount" t-options="{'widget': 'float', 'precision': 2}" /> + @@ -210,6 +219,11 @@ t-out="group.total_unit_amount" t-options="{'widget': 'float', 'precision': 2}" /> + diff --git a/hr_timesheet_report/static/description/index.html b/hr_timesheet_report/static/description/index.html index f41cf1a39..e60a198b1 100644 --- a/hr_timesheet_report/static/description/index.html +++ b/hr_timesheet_report/static/description/index.html @@ -1,4 +1,3 @@ - @@ -9,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. +Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -275,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -301,7 +301,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -376,7 +376,7 @@

Task Logs Timesheet Report

  • Select reported fields
  • Select and reorder report line grouping
  • -
  • Configure time format (HH:MM, HH:MM:SS, or decimal)
  • +
  • Configure time format : Hours (HH:MM, HH:MM:SS, or decimal) or Days (decimal)
  • View in browser, export in PDF and XLSX formats
@@ -441,7 +441,9 @@

Contributors

Maintainers

This module is maintained by the OCA.

-Odoo Community Association + +Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

diff --git a/hr_timesheet_report/tests/test_hr_timesheet_report.py b/hr_timesheet_report/tests/test_hr_timesheet_report.py index 69cd9a6d7..6f3b503b6 100644 --- a/hr_timesheet_report/tests/test_hr_timesheet_report.py +++ b/hr_timesheet_report/tests/test_hr_timesheet_report.py @@ -24,7 +24,7 @@ def setUpClass(cls): "name": "Time Entry", "employee_id": cls.employee.id, "date": cls.today, - "unit_amount": 1, + "unit_amount": 8, # 8 hours = 1 day } ) @@ -78,6 +78,20 @@ def test_no_grouping(self): self.assertTrue(wizard.entry_field_ids) report = self._create_report_from_wizard(wizard) self.assertEqual(len(report.group_ids), 1) + self.assertEqual(report.total_unit_amount, 8) + + @mute_logger("odoo.models.unlink") + def test_uom_day(self): + wizard_form = Form(self.Wizard) + wizard_form.date_from = self.today + wizard_form.date_to = self.today + wizard_form.employee_ids.add(self.employee) + wizard_form.time_format = "days" + wizard = wizard_form.save() + self.assertTrue(wizard.grouping_field_ids) + self.assertTrue(wizard.entry_field_ids) + report = self._create_report_from_wizard(wizard) + self.assertEqual(report.uom.id, self.env.ref("uom.product_uom_day").id) self.assertEqual(report.total_unit_amount, 1) @@ -109,7 +123,7 @@ def test_multi_project_01(self): self.assertEqual(len(report.line_ids), 2) self.assertIn(self.timesheet_1, report.line_ids) self.assertIn(self.timesheet_2, report.line_ids) - self.assertEqual(report.total_unit_amount, 3) + self.assertEqual(report.total_unit_amount, 10) # 8 + 2 @mute_logger("odoo.models.unlink") def test_multi_project_02(self): @@ -122,4 +136,4 @@ def test_multi_project_02(self): self.assertTrue(wizard.entry_field_ids) report = self._create_report_from_wizard(wizard) self.assertEqual(len(report.group_ids), 2) - self.assertEqual(report.total_unit_amount, 3) + self.assertEqual(report.total_unit_amount, 10) # 8 + 2