diff --git a/hr_timesheet_overtime/README.rst b/hr_timesheet_overtime/README.rst index 72b1faf..1bc6c3e 100644 --- a/hr_timesheet_overtime/README.rst +++ b/hr_timesheet_overtime/README.rst @@ -29,32 +29,6 @@ Computes overtime hours according to employee's contracts. .. contents:: :local: -Known issues / Roadmap -====================== - -There is a problem with the way this module handles rates for overtime. If the -rate ever changes, things will start to break. - -At time of writing (2024-06-28), the way a rate is computed for a date is by -looking _exclusively_ at the corresponding day of the week. This should be more -robust. - -Furthermore, when inserting hours worked, the actual hours worked get lost. You -(try to) write a value to ``unit_amount``, but an augmented value gets written -to the field instead. This is rather ugly. - -We can improve this by relying on the computation of ``unit_amount`` in Odoo -≥16: create a new field ``hours_worked``, which contains the actual hours worked -sans rate. Then, compute ``unit_amount`` from ``hours_worked`` (in a more robust -fashion than is presently the case). In the interface, show ``hours_worked`` -more prominently than ``unit_amount`` as the main editable field. - -To make this module subsequently compatible with ``hr_timesheet_begin_end``, -``hours_worked`` must be computed from ``time_stop`` and ``time_start``, and -``unit_amount`` must use this module's computation method instead of -``hr_timesheet_begin_end``'s. The compatibility layer should go into its own -module. - Bug Tracker =========== diff --git a/hr_timesheet_overtime/__manifest__.py b/hr_timesheet_overtime/__manifest__.py index 90e0318..80fef81 100644 --- a/hr_timesheet_overtime/__manifest__.py +++ b/hr_timesheet_overtime/__manifest__.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { "name": "Timesheet/Contract - Overtime", - "version": "16.0.2.1.0", + "version": "16.0.3.0.0", "category": "Human Resources", "summary": "Overtime Calculation", "author": "Coop IT Easy SC, Odoo Community Association (OCA)", @@ -15,9 +15,7 @@ "resource_work_time_from_contracts", ], "data": [ - "security/ir.model.access.csv", "views/hr_employee_view.xml", - "views/resource_view.xml", "views/hr_timesheet_sheet_view.xml", ], "demo": [ diff --git a/hr_timesheet_overtime/models/__init__.py b/hr_timesheet_overtime/models/__init__.py index c01dbe6..88ae19e 100644 --- a/hr_timesheet_overtime/models/__init__.py +++ b/hr_timesheet_overtime/models/__init__.py @@ -1,5 +1,2 @@ -from . import account_analytic_line from . import hr_employee from . import hr_timesheet_sheet -from . import resource_overtime -from . import resource_overtime_rate diff --git a/hr_timesheet_overtime/models/account_analytic_line.py b/hr_timesheet_overtime/models/account_analytic_line.py deleted file mode 100644 index 47b82d8..0000000 --- a/hr_timesheet_overtime/models/account_analytic_line.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2020 Coop IT Easy SC -# - Vincent Van Rossem -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import logging - -from odoo import api, fields, models - -_logger = logging.getLogger(__name__) - - -class AnalyticLine(models.Model): - """ - Apply on account analytic lines the rate defined in resource.overtime.rate - """ - - _inherit = "account.analytic.line" - - @api.model_create_multi - def create(self, vals_list): - for vals in vals_list: - self._update_values(vals) - return super().create(vals_list) - - def write(self, values): - if not self.env.context.get("create"): # sale module - self._update_values(values) - return super().write(values) - - def _update_values(self, values): - """ - Update values if date or unit_amount fields have changed - """ - if "date" in values or "unit_amount" in values: - # TODO: self.date and self.unit_amount do not exist when called from - # create(). - date = values.get("date", self.date) - unit_amount = values.get("unit_amount", self.unit_amount) - values["unit_amount"] = unit_amount * self.rate_for_date(date) - - @api.model - def rate_for_date(self, date): - # n.b. from_string also works on date objects, returning itself. - weekday = fields.Date.from_string(date).weekday() - return ( - self.env["resource.overtime.rate"] - .search([("dayofweek", "=", weekday)], limit=1) - .rate - or 1.0 - ) diff --git a/hr_timesheet_overtime/readme/ROADMAP.rst b/hr_timesheet_overtime/readme/ROADMAP.rst deleted file mode 100644 index 08e5a7f..0000000 --- a/hr_timesheet_overtime/readme/ROADMAP.rst +++ /dev/null @@ -1,22 +0,0 @@ -There is a problem with the way this module handles rates for overtime. If the -rate ever changes, things will start to break. - -At time of writing (2024-06-28), the way a rate is computed for a date is by -looking _exclusively_ at the corresponding day of the week. This should be more -robust. - -Furthermore, when inserting hours worked, the actual hours worked get lost. You -(try to) write a value to ``unit_amount``, but an augmented value gets written -to the field instead. This is rather ugly. - -We can improve this by relying on the computation of ``unit_amount`` in Odoo -≥16: create a new field ``hours_worked``, which contains the actual hours worked -sans rate. Then, compute ``unit_amount`` from ``hours_worked`` (in a more robust -fashion than is presently the case). In the interface, show ``hours_worked`` -more prominently than ``unit_amount`` as the main editable field. - -To make this module subsequently compatible with ``hr_timesheet_begin_end``, -``hours_worked`` must be computed from ``time_stop`` and ``time_start``, and -``unit_amount`` must use this module's computation method instead of -``hr_timesheet_begin_end``'s. The compatibility layer should go into its own -module. diff --git a/hr_timesheet_overtime/static/description/index.html b/hr_timesheet_overtime/static/description/index.html index b0b4321..0987ab3 100644 --- a/hr_timesheet_overtime/static/description/index.html +++ b/hr_timesheet_overtime/static/description/index.html @@ -366,47 +366,25 @@

Timesheet/Contract - Overtime

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:f303e3ad17e5d88c4ddf2a1baf816f420994d594a04db998c4fd2c1e9f1b2131 +!! source digest: sha256:bde6f189b3da65ae6a23a4337c16402e0a29f4ebbb8dd39431f53c37a66249ef !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 coopiteasy/cie-timesheet

Computes overtime hours according to employee’s contracts.

Table of contents

-
-

Known issues / Roadmap

-

There is a problem with the way this module handles rates for overtime. If the -rate ever changes, things will start to break.

-

At time of writing (2024-06-28), the way a rate is computed for a date is by -looking _exclusively_ at the corresponding day of the week. This should be more -robust.

-

Furthermore, when inserting hours worked, the actual hours worked get lost. You -(try to) write a value to unit_amount, but an augmented value gets written -to the field instead. This is rather ugly.

-

We can improve this by relying on the computation of unit_amount in Odoo -≥16: create a new field hours_worked, which contains the actual hours worked -sans rate. Then, compute unit_amount from hours_worked (in a more robust -fashion than is presently the case). In the interface, show hours_worked -more prominently than unit_amount as the main editable field.

-

To make this module subsequently compatible with hr_timesheet_begin_end, -hours_worked must be computed from time_stop and time_start, and -unit_amount must use this module’s computation method instead of -hr_timesheet_begin_end’s. The compatibility layer should go into its own -module.

-
-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -414,15 +392,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Coop IT Easy SC
-

Contributors

+

Contributors

-

Other credits

+

Other credits

The development of this module has been paid for by Pro Velo.

-

Maintainers

+

Maintainers

This module is part of the coopiteasy/cie-timesheet project on GitHub.

You are welcome to contribute.

diff --git a/hr_timesheet_overtime/views/hr_timesheet_sheet_view.xml b/hr_timesheet_overtime/views/hr_timesheet_sheet_view.xml index 10c7965..eb30eb0 100644 --- a/hr_timesheet_overtime/views/hr_timesheet_sheet_view.xml +++ b/hr_timesheet_overtime/views/hr_timesheet_sheet_view.xml @@ -58,7 +58,6 @@ decoration-info="total_overtime >= 0" /> - @@ -96,20 +95,4 @@ - - - - diff --git a/hr_timesheet_overtime_rate/README.rst b/hr_timesheet_overtime_rate/README.rst new file mode 100644 index 0000000..ccb27d5 --- /dev/null +++ b/hr_timesheet_overtime_rate/README.rst @@ -0,0 +1,84 @@ +============= +Overtime Rate +============= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:36d3b7bc33750523cfa2cc468002678f8db599e083759ba12ede988ee84d6431 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-coopiteasy%2Fcie--timesheet-lightgray.png?logo=github + :target: https://github.com/coopiteasy/cie-timesheet/tree/16.0/hr_timesheet_overtime_rate + :alt: coopiteasy/cie-timesheet + +|badge1| |badge2| |badge3| + +Define an extra rate for working certain days. + +**Table of contents** + +.. contents:: + :local: + +Known issues / Roadmap +====================== + +There is a problem with the way this module handles rates for overtime. If the +rate ever changes, things will start to break. + +At time of writing (2024-06-28), the way a rate is computed for a date is by +looking _exclusively_ at the corresponding day of the week. This should be more +robust. + +Furthermore, the summary view of timesheet sheets are set read-only in this +module. Because of programming complexities, it is not easy to change this view +to use ``hours_worked`` instead of ``unit_amount``. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Coop IT Easy SC + +Contributors +~~~~~~~~~~~~ + +* `Coop IT Easy SC `_: + + * Carmen Bianca BAKKER + +Maintainers +~~~~~~~~~~~ + +.. |maintainer-carmenbianca| image:: https://github.com/carmenbianca.png?size=40px + :target: https://github.com/carmenbianca + :alt: carmenbianca + +Current maintainer: + +|maintainer-carmenbianca| + +This module is part of the `coopiteasy/cie-timesheet `_ project on GitHub. + +You are welcome to contribute. diff --git a/hr_timesheet_overtime_rate/__init__.py b/hr_timesheet_overtime_rate/__init__.py new file mode 100644 index 0000000..3eb7887 --- /dev/null +++ b/hr_timesheet_overtime_rate/__init__.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import models diff --git a/hr_timesheet_overtime_rate/__manifest__.py b/hr_timesheet_overtime_rate/__manifest__.py new file mode 100644 index 0000000..d8df1ff --- /dev/null +++ b/hr_timesheet_overtime_rate/__manifest__.py @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +{ + "name": "Overtime Rate", + "summary": "Define an extra rate for working certain days.", + "version": "16.0.1.0.0", + "category": "Human Resources", + "website": "https://github.com/coopiteasy/cie-timesheet", + "author": "Coop IT Easy SC", + "maintainers": ["carmenbianca"], + "license": "AGPL-3", + "depends": [ + "hr_timesheet_sheet", + ], + "data": [ + "security/ir.model.access.csv", + "data/data.xml", + "views/resource_views.xml", + "views/account_analytic_line_views.xml", + "views/hr_timesheet_sheet_views.xml", + "views/project_task_views.xml", + ], +} diff --git a/hr_timesheet_overtime_rate/data/data.xml b/hr_timesheet_overtime_rate/data/data.xml new file mode 100644 index 0000000..202225e --- /dev/null +++ b/hr_timesheet_overtime_rate/data/data.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/hr_timesheet_overtime_rate/models/__init__.py b/hr_timesheet_overtime_rate/models/__init__.py new file mode 100644 index 0000000..0aa99e9 --- /dev/null +++ b/hr_timesheet_overtime_rate/models/__init__.py @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import account_analytic_line +from . import resource_overtime +from . import resource_overtime_rate diff --git a/hr_timesheet_overtime_rate/models/account_analytic_line.py b/hr_timesheet_overtime_rate/models/account_analytic_line.py new file mode 100644 index 0000000..46b7ab1 --- /dev/null +++ b/hr_timesheet_overtime_rate/models/account_analytic_line.py @@ -0,0 +1,70 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from odoo import api, fields, models + + +class AnalyticLine(models.Model): + """ + Apply on account analytic lines the rate defined in resource.overtime.rate + """ + + _inherit = "account.analytic.line" + + hours_worked = fields.Float( + default=0.0, + ) + # Override to be a computed field. + unit_amount = fields.Float( + # We use a kind of custom name here because `hr_timesheet_begin_end` + # also overrides this, and the two compute methods are not necessarily + # compatible. + compute="_compute_unit_amount_from_hours", + store=True, + readonly=False, + # This triggers computation on creation. default=False and default=0 do + # not trigger computation. + default=None, + ) + + # TODO: should this also depend on resource.overtime.rate, somehow? + @api.depends("hours_worked", "date") + def _compute_unit_amount_from_hours(self): + # Do not compute/adjust the unit_amount of non-timesheets. + lines = self.filtered(lambda line: line.project_id) + for line in lines: + line.unit_amount = line.hours_worked * line.get_overtime_rate() + + def get_overtime_rate(self): + self.ensure_one() + weekday = self.date.weekday() + return ( + self.env["resource.overtime.rate"] + .search([("dayofweek", "=", weekday)], limit=1) + .rate + or 1.0 + ) + + def _init_hours_worked(self): + """Upon module installation (or manually any other time, if you really + want), this method is called to populate hours_worked with something + sensible, derived from unit_amount and the rate for that day. + """ + # We use an SQL query because we do not want to trigger computation upon + # writing to hours_worked. + query = """ + UPDATE account_analytic_line + SET hours_worked=CASE + """ + params = [] + + for line in self.filtered(lambda item: item.project_id): + rate = line.get_overtime_rate() + hours_worked = line.unit_amount / rate + query += "WHEN id=%s THEN %s " + params.extend([line.id, hours_worked]) + query += "END WHERE id IN %s" + + if params: + self.env.cr.execute(query, (*params, tuple(line.id for line in self))) diff --git a/hr_timesheet_overtime/models/resource_overtime.py b/hr_timesheet_overtime_rate/models/resource_overtime.py similarity index 100% rename from hr_timesheet_overtime/models/resource_overtime.py rename to hr_timesheet_overtime_rate/models/resource_overtime.py diff --git a/hr_timesheet_overtime/models/resource_overtime_rate.py b/hr_timesheet_overtime_rate/models/resource_overtime_rate.py similarity index 100% rename from hr_timesheet_overtime/models/resource_overtime_rate.py rename to hr_timesheet_overtime_rate/models/resource_overtime_rate.py diff --git a/hr_timesheet_overtime_rate/readme/CONTRIBUTORS.rst b/hr_timesheet_overtime_rate/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..f1ac675 --- /dev/null +++ b/hr_timesheet_overtime_rate/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Coop IT Easy SC `_: + + * Carmen Bianca BAKKER diff --git a/hr_timesheet_overtime_rate/readme/DESCRIPTION.rst b/hr_timesheet_overtime_rate/readme/DESCRIPTION.rst new file mode 100644 index 0000000..2f57b00 --- /dev/null +++ b/hr_timesheet_overtime_rate/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Define an extra rate for working certain days. diff --git a/hr_timesheet_overtime_rate/readme/ROADMAP.rst b/hr_timesheet_overtime_rate/readme/ROADMAP.rst new file mode 100644 index 0000000..d84795b --- /dev/null +++ b/hr_timesheet_overtime_rate/readme/ROADMAP.rst @@ -0,0 +1,10 @@ +There is a problem with the way this module handles rates for overtime. If the +rate ever changes, things will start to break. + +At time of writing (2024-06-28), the way a rate is computed for a date is by +looking _exclusively_ at the corresponding day of the week. This should be more +robust. + +Furthermore, the summary view of timesheet sheets are set read-only in this +module. Because of programming complexities, it is not easy to change this view +to use ``hours_worked`` instead of ``unit_amount``. diff --git a/hr_timesheet_overtime/security/ir.model.access.csv b/hr_timesheet_overtime_rate/security/ir.model.access.csv similarity index 100% rename from hr_timesheet_overtime/security/ir.model.access.csv rename to hr_timesheet_overtime_rate/security/ir.model.access.csv diff --git a/hr_timesheet_overtime_rate/static/description/index.html b/hr_timesheet_overtime_rate/static/description/index.html new file mode 100644 index 0000000..31b5bbd --- /dev/null +++ b/hr_timesheet_overtime_rate/static/description/index.html @@ -0,0 +1,432 @@ + + + + + +Overtime Rate + + + +
+

Overtime Rate

+ + +

Beta License: AGPL-3 coopiteasy/cie-timesheet

+

Define an extra rate for working certain days.

+

Table of contents

+ +
+

Known issues / Roadmap

+

There is a problem with the way this module handles rates for overtime. If the +rate ever changes, things will start to break.

+

At time of writing (2024-06-28), the way a rate is computed for a date is by +looking _exclusively_ at the corresponding day of the week. This should be more +robust.

+

Furthermore, the summary view of timesheet sheets are set read-only in this +module. Because of programming complexities, it is not easy to change this view +to use hours_worked instead of unit_amount.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Coop IT Easy SC
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

Current maintainer:

+

carmenbianca

+

This module is part of the coopiteasy/cie-timesheet project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/hr_timesheet_overtime_rate/tests/__init__.py b/hr_timesheet_overtime_rate/tests/__init__.py new file mode 100644 index 0000000..f143b69 --- /dev/null +++ b/hr_timesheet_overtime_rate/tests/__init__.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import test_overtime diff --git a/hr_timesheet_overtime_rate/tests/test_overtime.py b/hr_timesheet_overtime_rate/tests/test_overtime.py new file mode 100644 index 0000000..ab23cfe --- /dev/null +++ b/hr_timesheet_overtime_rate/tests/test_overtime.py @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from datetime import date + +from odoo.tests.common import TransactionCase + + +class TestOvertime(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # users + user1_dict = {"name": "User 1", "login": "user1", "password": "user1"} + cls.user1 = cls.env["res.users"].create(user1_dict) + # employees + employee1_dict = { + "name": "Employee 1", + "user_id": cls.user1.id, + "address_id": cls.user1.partner_id.id, + } + cls.employee1 = cls.env["hr.employee"].create(employee1_dict) + # projects + cls.project_01 = cls.env["project.project"].create({"name": "Project 01"}) + + def test_write_multiple_lines(self): + """When writing multiple analytic lines, overtime rates are applied + separately to each record. + """ + overtime = self.env["resource.overtime"].create({"name": "test"}) + self.env["resource.overtime.rate"].create( + { + "name": "test", + "dayofweek": "0", # Monday + "rate": 2.0, + "overtime_id": overtime.id, + } + ) + + lines = self.env["account.analytic.line"].browse() + # monday and tuesday + for day in range(9, 11): + lines += self.env["account.analytic.line"].create( + { + "project_id": self.project_01.id, + "amount": 0.0, + "date": date(2019, 12, day), + "name": "-", + "employee_id": self.employee1.id, + } + ) + lines.write({"hours_worked": 1}) + + self.assertEqual(lines[0].unit_amount, 2) + self.assertEqual(lines[0].hours_worked, 1) + self.assertEqual(lines[1].unit_amount, 1) + self.assertEqual(lines[1].hours_worked, 1) diff --git a/hr_timesheet_overtime_rate/views/account_analytic_line_views.xml b/hr_timesheet_overtime_rate/views/account_analytic_line_views.xml new file mode 100644 index 0000000..7366bbd --- /dev/null +++ b/hr_timesheet_overtime_rate/views/account_analytic_line_views.xml @@ -0,0 +1,96 @@ + + + + + account.analytic.line.tree.hr_timesheet + account.analytic.line + + + + + + + + + + + account.analytic.line.pivot + account.analytic.line + + + + + + + + + + + account.analytic.line.graph + account.analytic.line + + + + + + + + + + + account.analytic.line.graph + account.analytic.line + + + + + + + + + + + account.analytic.line.graph + account.analytic.line + + + + + + + + + + + account.analytic.line.form + account.analytic.line + + + + + + + + + + + account.analytic.line.kanban + account.analytic.line + + + + + + + + + + diff --git a/hr_timesheet_overtime_rate/views/hr_timesheet_sheet_views.xml b/hr_timesheet_overtime_rate/views/hr_timesheet_sheet_views.xml new file mode 100644 index 0000000..cea373d --- /dev/null +++ b/hr_timesheet_overtime_rate/views/hr_timesheet_sheet_views.xml @@ -0,0 +1,53 @@ + + + + hr.timesheet.sheet.form + hr_timesheet.sheet + + + + + + 1 + + + + + + + + + + + + + + + + + diff --git a/hr_timesheet_overtime_rate/views/project_task_views.xml b/hr_timesheet_overtime_rate/views/project_task_views.xml new file mode 100644 index 0000000..74e2403 --- /dev/null +++ b/hr_timesheet_overtime_rate/views/project_task_views.xml @@ -0,0 +1,30 @@ + + + + + project.task.form.inherited (in hr_timesheet_overtime_rate) + project.task + + + + + + + + + + + + diff --git a/hr_timesheet_overtime/views/resource_view.xml b/hr_timesheet_overtime_rate/views/resource_views.xml similarity index 100% rename from hr_timesheet_overtime/views/resource_view.xml rename to hr_timesheet_overtime_rate/views/resource_views.xml diff --git a/hr_timesheet_overtime_rate_begin_end/README.rst b/hr_timesheet_overtime_rate_begin_end/README.rst new file mode 100644 index 0000000..286154b --- /dev/null +++ b/hr_timesheet_overtime_rate_begin_end/README.rst @@ -0,0 +1,70 @@ +=========================================================== +Timesheet - Overtime rate and begin/end hours compatibility +=========================================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:5ab790e671629b45c0297eceb50037e97ab4827da3d637687db534dd0dd0dde0 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-coopiteasy%2Fcie--timesheet-lightgray.png?logo=github + :target: https://github.com/coopiteasy/cie-timesheet/tree/16.0/hr_timesheet_overtime_rate_begin_end + :alt: coopiteasy/cie-timesheet + +|badge1| |badge2| |badge3| + +Make ``hr_timesheet_overtime_rate`` and ``hr_timesheet_begin_end`` compatible. + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Coop IT Easy SC + +Contributors +~~~~~~~~~~~~ + +* `Coop IT Easy SC `_: + + * Carmen Bianca BAKKER + +Maintainers +~~~~~~~~~~~ + +.. |maintainer-carmenbianca| image:: https://github.com/carmenbianca.png?size=40px + :target: https://github.com/carmenbianca + :alt: carmenbianca + +Current maintainer: + +|maintainer-carmenbianca| + +This module is part of the `coopiteasy/cie-timesheet `_ project on GitHub. + +You are welcome to contribute. diff --git a/hr_timesheet_overtime_rate_begin_end/__init__.py b/hr_timesheet_overtime_rate_begin_end/__init__.py new file mode 100644 index 0000000..3eb7887 --- /dev/null +++ b/hr_timesheet_overtime_rate_begin_end/__init__.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import models diff --git a/hr_timesheet_overtime_rate_begin_end/__manifest__.py b/hr_timesheet_overtime_rate_begin_end/__manifest__.py new file mode 100644 index 0000000..5d67310 --- /dev/null +++ b/hr_timesheet_overtime_rate_begin_end/__manifest__.py @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +{ + "name": "Timesheet - Overtime rate and begin/end hours compatibility", + "summary": "Make ``hr_timesheet_overtime_rate`` and ``hr_timesheet_begin_end`` compatible.", + "version": "16.0.1.0.0", + "category": "Human Resources", + "website": "https://github.com/coopiteasy/cie-timesheet", + "author": "Coop IT Easy SC", + "maintainers": ["carmenbianca"], + "license": "AGPL-3", + "application": False, + "depends": [ + "hr_timesheet_overtime_rate", + "hr_timesheet_begin_end", + ], + "auto_install": True, +} diff --git a/hr_timesheet_overtime_rate_begin_end/models/__init__.py b/hr_timesheet_overtime_rate_begin_end/models/__init__.py new file mode 100644 index 0000000..84f4adc --- /dev/null +++ b/hr_timesheet_overtime_rate_begin_end/models/__init__.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import account_analytic_line diff --git a/hr_timesheet_overtime_rate_begin_end/models/account_analytic_line.py b/hr_timesheet_overtime_rate_begin_end/models/account_analytic_line.py new file mode 100644 index 0000000..67d2b96 --- /dev/null +++ b/hr_timesheet_overtime_rate_begin_end/models/account_analytic_line.py @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from odoo import api, fields, models + + +class AnalyticLine(models.Model): + _inherit = "account.analytic.line" + + hours_worked = fields.Float( + store=True, + readonly=True, + compute="_compute_hours_worked", + ) + unit_amount = fields.Float( + # Make sure unit_amount is computed from hours worked, NOT directly from + # time_start and time_stop. + compute="_compute_unit_amount_from_hours", + ) + + @api.depends("time_start", "time_stop") + def _compute_hours_worked(self): + for line in self: + line.hours_worked = self._hours_from_start_stop( + line.time_start, line.time_stop + ) + + # Add date to constrains. + @api.constrains("time_start", "time_stop", "unit_amount", "date") + def _check_time_start_stop(self): + return super()._check_time_start_stop() + + def unit_amount_from_start_stop(self): + result = super().unit_amount_from_start_stop() + result *= self.get_overtime_rate() + return result diff --git a/hr_timesheet_overtime_rate_begin_end/readme/CONTRIBUTORS.rst b/hr_timesheet_overtime_rate_begin_end/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..f1ac675 --- /dev/null +++ b/hr_timesheet_overtime_rate_begin_end/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Coop IT Easy SC `_: + + * Carmen Bianca BAKKER diff --git a/hr_timesheet_overtime_rate_begin_end/readme/DESCRIPTION.rst b/hr_timesheet_overtime_rate_begin_end/readme/DESCRIPTION.rst new file mode 100644 index 0000000..3ae044d --- /dev/null +++ b/hr_timesheet_overtime_rate_begin_end/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Make ``hr_timesheet_overtime_rate`` and ``hr_timesheet_begin_end`` compatible. diff --git a/hr_timesheet_overtime_rate_begin_end/static/description/index.html b/hr_timesheet_overtime_rate_begin_end/static/description/index.html new file mode 100644 index 0000000..e5fc9bb --- /dev/null +++ b/hr_timesheet_overtime_rate_begin_end/static/description/index.html @@ -0,0 +1,420 @@ + + + + + +Timesheet - Overtime rate and begin/end hours compatibility + + + +
+

Timesheet - Overtime rate and begin/end hours compatibility

+ + +

Beta License: AGPL-3 coopiteasy/cie-timesheet

+

Make hr_timesheet_overtime_rate and hr_timesheet_begin_end compatible.

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Coop IT Easy SC
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

Current maintainer:

+

carmenbianca

+

This module is part of the coopiteasy/cie-timesheet project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/hr_timesheet_overtime_rate_begin_end/tests/__init__.py b/hr_timesheet_overtime_rate_begin_end/tests/__init__.py new file mode 100644 index 0000000..926bcd5 --- /dev/null +++ b/hr_timesheet_overtime_rate_begin_end/tests/__init__.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from . import test_analytic_line diff --git a/hr_timesheet_overtime_rate_begin_end/tests/test_analytic_line.py b/hr_timesheet_overtime_rate_begin_end/tests/test_analytic_line.py new file mode 100644 index 0000000..a736509 --- /dev/null +++ b/hr_timesheet_overtime_rate_begin_end/tests/test_analytic_line.py @@ -0,0 +1,78 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from odoo.tests.common import TransactionCase + + +class TestAnalyticLine(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.project = cls.env.ref("project.project_project_1") + cls.employee = cls.env.ref("hr.employee_qdp") + # I'm not sure what this record does in this context. + cls.overtime = cls.env["resource.overtime"].create({"name": "test"}) + cls.rate = cls.env["resource.overtime.rate"].create( + { + "name": "test", + "dayofweek": "0", # Monday + "rate": 2.0, + "overtime_id": cls.overtime.id, + } + ) + + def base_line(self): + return { + "name": "test", + "date": "2024-01-01", # Monday + "time_start": 10.0, + "time_stop": 12.0, + "project_id": self.project.id, + "employee_id": self.employee.id, + } + + def test_rate_applied(self): + line = self.base_line() + line_record = self.env["account.analytic.line"].create(line) + self.assertEqual(line_record.unit_amount, 4.0) + + def test_rate_applied_after_edit(self): + line = self.base_line() + del line["time_start"] + del line["time_stop"] + line_record = self.env["account.analytic.line"].create(line) + line_record.write({"time_start": 10.0, "time_stop": 12.0}) + self.assertEqual(line_record.unit_amount, 4.0) + + def test_rate_not_double_applied(self): + line = self.base_line() + del line["time_start"] + del line["time_stop"] + + # Emulating a transient record before it is actually created. + line_new = self.env["account.analytic.line"].new(line) + line_new.time_start = 10.0 + line_new.time_stop = 12.0 + self.assertEqual(line_new.unit_amount, 4.0) + + # Prepare the transient data for writing to a new record. + # + # Annoyingly, the value for unit_amount is not in _cache, so we have to + # add it here. + # + # Ideally I would emulate this with a Form(), but the necessary fields + # are not available in a form. This is the closest emulation. + vals = line_new._convert_to_write(line_new._cache) + vals.setdefault("unit_amount", line_new.unit_amount) + line_record = self.env["account.analytic.line"].create(vals) + + # The rate was already applied on the transient record. Don't also apply + # it on creation. + self.assertEqual(line_record.unit_amount, 4.0) + + def test_rate_changes_on_date(self): + line = self.base_line() + line_record = self.env["account.analytic.line"].create(line) + line_record.date = "2024-01-02" + self.assertEqual(line_record.unit_amount, line_record.hours_worked) diff --git a/setup/hr_timesheet_overtime_rate/odoo/addons/hr_timesheet_overtime_rate b/setup/hr_timesheet_overtime_rate/odoo/addons/hr_timesheet_overtime_rate new file mode 120000 index 0000000..cb4c829 --- /dev/null +++ b/setup/hr_timesheet_overtime_rate/odoo/addons/hr_timesheet_overtime_rate @@ -0,0 +1 @@ +../../../../hr_timesheet_overtime_rate \ No newline at end of file diff --git a/setup/hr_timesheet_overtime_rate/setup.py b/setup/hr_timesheet_overtime_rate/setup.py new file mode 100644 index 0000000..28c57bb --- /dev/null +++ b/setup/hr_timesheet_overtime_rate/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/setup/hr_timesheet_overtime_rate_begin_end/odoo/addons/hr_timesheet_overtime_begin_end b/setup/hr_timesheet_overtime_rate_begin_end/odoo/addons/hr_timesheet_overtime_begin_end new file mode 120000 index 0000000..58ec292 --- /dev/null +++ b/setup/hr_timesheet_overtime_rate_begin_end/odoo/addons/hr_timesheet_overtime_begin_end @@ -0,0 +1 @@ +../../../../hr_timesheet_overtime_begin_end \ No newline at end of file diff --git a/setup/hr_timesheet_overtime_rate_begin_end/odoo/addons/hr_timesheet_overtime_rate_begin_end b/setup/hr_timesheet_overtime_rate_begin_end/odoo/addons/hr_timesheet_overtime_rate_begin_end new file mode 120000 index 0000000..348076d --- /dev/null +++ b/setup/hr_timesheet_overtime_rate_begin_end/odoo/addons/hr_timesheet_overtime_rate_begin_end @@ -0,0 +1 @@ +../../../../hr_timesheet_overtime_rate_begin_end \ No newline at end of file diff --git a/setup/hr_timesheet_overtime_rate_begin_end/setup.py b/setup/hr_timesheet_overtime_rate_begin_end/setup.py new file mode 100644 index 0000000..28c57bb --- /dev/null +++ b/setup/hr_timesheet_overtime_rate_begin_end/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)