From 8091755747eb48cddeeeed9f0910e15725d39c10 Mon Sep 17 00:00:00 2001 From: Simone Rubino Date: Tue, 10 Feb 2026 09:47:34 +0100 Subject: [PATCH 1/4] [IMP] hr_payroll_document: Thread safe If multiple wizards are sending payrolls at the same time, every wizard acts in their own folder. Also add display name. --- .../wizard/payroll_management_wizard.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/hr_payroll_document/wizard/payroll_management_wizard.py b/hr_payroll_document/wizard/payroll_management_wizard.py index bb3c96fc..dc003668 100644 --- a/hr_payroll_document/wizard/payroll_management_wizard.py +++ b/hr_payroll_document/wizard/payroll_management_wizard.py @@ -1,4 +1,5 @@ import base64 +import pathlib from base64 import b64decode from pypdf import PdfReader, PdfWriter @@ -10,6 +11,7 @@ class PayrollManagamentWizard(models.TransientModel): _name = "payroll.management.wizard" _description = "Payroll Management" + _rec_name = "subject" subject = fields.Char( help="Enter the title of the payroll whether it is the month, week, day, etc.", @@ -19,10 +21,16 @@ class PayrollManagamentWizard(models.TransientModel): "ir.attachment", "payrol_rel", "doc_id", "attach_id3", copy=False, required=True ) + def _get_temp_path(self): + self.ensure_one() + path = f"/tmp/{self._table}_{self.id}/" + pathlib.Path(path).mkdir(exist_ok=True) + return path + def send_payrolls(self): not_found = set() self.merge_pdfs() - reader = PdfReader("/tmp/merged-pdf.pdf") + reader = PdfReader(f"{self._get_temp_path()}merged-pdf.pdf") employees = set() # Validate if company have country @@ -48,7 +56,9 @@ def send_payrolls(self): # Save pdf with payrolls of employee pdfWriter.add_page(page) - path = "/tmp/" + self.env._("Payroll ") + employee.name + ".pdf" + path = ( + self._get_temp_path() + self.env._("Payroll ") + employee.name + ".pdf" + ) if not employee.no_payroll_encryption: # Encrypt the payroll file @@ -96,13 +106,14 @@ def send_payrolls(self): def merge_pdfs(self): # Merge the pdfs together + temp_path = self._get_temp_path() pdfs = [] for file in self.payrolls: b64 = file.datas btes = b64decode(b64, validate=True) if btes[0:4] != b"%PDF": raise ValidationError(self.env._("Missing pdf file signature")) - f = open("/tmp/" + file.name, "wb") + f = open(self._get_temp_path() + file.name, "wb") f.write(btes) f.close() pdfs.append(f.name) @@ -112,7 +123,7 @@ def merge_pdfs(self): for pdf in pdfs: merger.append(pdf) - merger.write("/tmp/merged-pdf.pdf") + merger.write(f"{temp_path}merged-pdf.pdf") merger.close() def send_mail(self, employee, path): From b2367da2796dbec1c811f1a85d82b4c179f93a6d Mon Sep 17 00:00:00 2001 From: Simone Rubino Date: Mon, 9 Feb 2026 11:55:21 +0100 Subject: [PATCH 2/4] [ADD] hr_payroll_document_queue --- hr_payroll_document_queue/README.rst | 90 ++++ hr_payroll_document_queue/__init__.py | 3 + hr_payroll_document_queue/__manifest__.py | 22 + .../readme/CONTRIBUTORS.rst | 3 + .../readme/DESCRIPTION.rst | 5 + .../static/description/index.html | 430 ++++++++++++++++++ hr_payroll_document_queue/tests/__init__.py | 3 + .../tests/test_payroll_management.py | 71 +++ hr_payroll_document_queue/wizards/__init__.py | 3 + .../wizards/payroll_management_wizard.py | 89 ++++ .../payroll_management_wizard_views.xml | 59 +++ .../odoo/addons/hr_payroll_document_queue | 1 + setup/hr_payroll_document_queue/setup.py | 6 + 13 files changed, 785 insertions(+) create mode 100644 hr_payroll_document_queue/README.rst create mode 100644 hr_payroll_document_queue/__init__.py create mode 100644 hr_payroll_document_queue/__manifest__.py create mode 100644 hr_payroll_document_queue/readme/CONTRIBUTORS.rst create mode 100644 hr_payroll_document_queue/readme/DESCRIPTION.rst create mode 100644 hr_payroll_document_queue/static/description/index.html create mode 100644 hr_payroll_document_queue/tests/__init__.py create mode 100644 hr_payroll_document_queue/tests/test_payroll_management.py create mode 100644 hr_payroll_document_queue/wizards/__init__.py create mode 100644 hr_payroll_document_queue/wizards/payroll_management_wizard.py create mode 100644 hr_payroll_document_queue/wizards/payroll_management_wizard_views.xml create mode 120000 setup/hr_payroll_document_queue/odoo/addons/hr_payroll_document_queue create mode 100644 setup/hr_payroll_document_queue/setup.py diff --git a/hr_payroll_document_queue/README.rst b/hr_payroll_document_queue/README.rst new file mode 100644 index 00000000..341f7924 --- /dev/null +++ b/hr_payroll_document_queue/README.rst @@ -0,0 +1,90 @@ +============================= +HR - Payroll Document - Queue +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:9b97fc250e9f7c34ba848cdc7ac246d98c29cdd4d8f16c1d6ed18fcf14fbc4f8 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-OCA%2Fpayroll-lightgray.png?logo=github + :target: https://github.com/OCA/payroll/tree/16.0/hr_payroll_document_queue + :alt: OCA/payroll +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/payroll-16-0/payroll-16-0-hr_payroll_document_queue + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/payroll&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Allow to process the payslips asynchronously. + +If a payroll is being processed asynchronously, attempting to process it again will show a warning and prevent it from being processed. + +When the payroll has been processed, the user is notified according to their Notification preference. + +**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 +~~~~~~~ + +* PyTech + +Contributors +~~~~~~~~~~~~ + +* `PyTech `_: + + * Simone Rubino + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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. + +.. |maintainer-SirPyTech| image:: https://github.com/SirPyTech.png?size=40px + :target: https://github.com/SirPyTech + :alt: SirPyTech + +Current `maintainer `__: + +|maintainer-SirPyTech| + +This module is part of the `OCA/payroll `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_payroll_document_queue/__init__.py b/hr_payroll_document_queue/__init__.py new file mode 100644 index 00000000..74d71de4 --- /dev/null +++ b/hr_payroll_document_queue/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import wizards diff --git a/hr_payroll_document_queue/__manifest__.py b/hr_payroll_document_queue/__manifest__.py new file mode 100644 index 00000000..20c3ffa1 --- /dev/null +++ b/hr_payroll_document_queue/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2026 Simone Rubino - PyTech +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "HR - Payroll Document - Queue", + "summary": "Process a PDF payslip aynchronously.", + "author": "PyTech, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/payroll", + "license": "AGPL-3", + "category": "Payrolls", + "version": "16.0.1.0.0", + "maintainers": [ + "SirPyTech", + ], + "depends": [ + "hr_payroll_document", + "queue_job", + ], + "data": [ + "wizards/payroll_management_wizard_views.xml", + ], +} diff --git a/hr_payroll_document_queue/readme/CONTRIBUTORS.rst b/hr_payroll_document_queue/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..3e2b1040 --- /dev/null +++ b/hr_payroll_document_queue/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `PyTech `_: + + * Simone Rubino diff --git a/hr_payroll_document_queue/readme/DESCRIPTION.rst b/hr_payroll_document_queue/readme/DESCRIPTION.rst new file mode 100644 index 00000000..b1e36f7b --- /dev/null +++ b/hr_payroll_document_queue/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +Allow to process the payslips asynchronously. + +If a payroll is being processed asynchronously, attempting to process it again will show a warning and prevent it from being processed. + +When the payroll has been processed, the user is notified according to their Notification preference. diff --git a/hr_payroll_document_queue/static/description/index.html b/hr_payroll_document_queue/static/description/index.html new file mode 100644 index 00000000..659c27ba --- /dev/null +++ b/hr_payroll_document_queue/static/description/index.html @@ -0,0 +1,430 @@ + + + + + +HR - Payroll Document - Queue + + + +
+

HR - Payroll Document - Queue

+ + +

Beta License: AGPL-3 OCA/payroll Translate me on Weblate Try me on Runboat

+

Allow to process the payslips asynchronously.

+

If a payroll is being processed asynchronously, attempting to process it again will show a warning and prevent it from being processed.

+

When the payroll has been processed, the user is notified according to their Notification preference.

+

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

+
    +
  • PyTech
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +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.

+

Current maintainer:

+

SirPyTech

+

This module is part of the OCA/payroll project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/hr_payroll_document_queue/tests/__init__.py b/hr_payroll_document_queue/tests/__init__.py new file mode 100644 index 00000000..cbc8cf7e --- /dev/null +++ b/hr_payroll_document_queue/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_payroll_management diff --git a/hr_payroll_document_queue/tests/test_payroll_management.py b/hr_payroll_document_queue/tests/test_payroll_management.py new file mode 100644 index 00000000..0466ce01 --- /dev/null +++ b/hr_payroll_document_queue/tests/test_payroll_management.py @@ -0,0 +1,71 @@ +# Copyright 2026 Simone Rubino - PyTech +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import exceptions + +from odoo.addons.hr_payroll_document.tests.common import TestHrPayrollDocument +from odoo.addons.mail.tests.common import MailCase +from odoo.addons.queue_job.tests.common import trap_jobs + + +class TestPayrollManagement(MailCase, TestHrPayrollDocument): + def test_job_creation(self): + """The job is created.""" + # Arrange + self.fill_company_id() + employee = self.employee_emp + employee.identification_id = "51000278D" + + # Act + with trap_jobs() as trap: + self.wizard.send_payrolls_async() + + # Assert + trap.assert_jobs_count(1) + + def test_process_same_payroll(self): + """The same payroll cannot be processed if it is already being processed.""" + # Arrange + self.fill_company_id() + self.employee_emp.identification_id = "51000278D" + self.wizard.send_payrolls_async() + other_wizard = self.wizard.copy() + other_wizard.payrolls = self.wizard.payrolls + + # Act + with self.assertRaises(exceptions.UserError) as ue: + other_wizard.send_payrolls() + + # Assert + exc_message = ue.exception.args[0] + self.assertIn("cannot be processed", exc_message) + self.assertTrue(other_wizard.is_payroll_being_processed) + self.assertFalse(other_wizard.is_send_visible) + + def test_email_notification(self): + """ + If the user has "email" notification preference, + when the payrolls are processed the user is notified. + """ + # Arrange + self.fill_company_id() + employee = self.employee_emp + employee.identification_id = "51000278D" + author_partner = self.env.ref("base.partner_root") + payman_user = self.user_admin + payman_user.notification_type = "email" + wizard = self.wizard + + # Act + with trap_jobs() as trap, self.mock_mail_gateway(): + wizard.with_user(payman_user).send_payrolls_async() + trap.perform_enqueued_jobs() + + # Assert + email = self.assertMailMail( + payman_user.partner_id, + "sent", + author=author_partner, + ) + self.assertEqual(email.model, wizard._name) + self.assertEqual(email.res_id, wizard.id) diff --git a/hr_payroll_document_queue/wizards/__init__.py b/hr_payroll_document_queue/wizards/__init__.py new file mode 100644 index 00000000..723401a2 --- /dev/null +++ b/hr_payroll_document_queue/wizards/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import payroll_management_wizard diff --git a/hr_payroll_document_queue/wizards/payroll_management_wizard.py b/hr_payroll_document_queue/wizards/payroll_management_wizard.py new file mode 100644 index 00000000..368fe04b --- /dev/null +++ b/hr_payroll_document_queue/wizards/payroll_management_wizard.py @@ -0,0 +1,89 @@ +# Copyright 2026 Simone Rubino - PyTech +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + + +from odoo import _, api, exceptions, fields, models +from odoo.tools.misc import flatten + +from odoo.addons.queue_job.job import CANCELLED, DONE, FAILED + + +class PayrollManagamentWizard(models.TransientModel): + _inherit = "payroll.management.wizard" + + is_payroll_being_processed = fields.Boolean( + string="Is being processed", + help="One of the selected payrolls is being processed.", + compute="_compute_is_payroll_being_processed", + compute_sudo=True, + ) + is_send_visible = fields.Boolean( + string="Send button is visible", + compute="_compute_is_send_visible", + ) + + def _notify_async_processed(self, send_result): + """Notify the result to the user that processed the payrolls.""" + self.ensure_one() + odoobot = self.env.ref("base.partner_root") + user = self.env.user + return self.env["mail.thread"].message_notify( + author_id=odoobot.id, + partner_ids=user.partner_id.ids, + subject=send_result["params"]["title"], + body=send_result["params"]["message"], + model=self._name, + res_id=self.id, + ) + + def send_payrolls(self): + if not self.is_send_visible: + # We are already hiding the buttons in the UI, + # but this public method can still be executed. + raise exceptions.UserError(_("The selected payrolls cannot be processed.")) + + result = super().send_payrolls() + + if self.env.context.get("job_uuid"): + self._notify_async_processed(result) + return result + + def send_payrolls_async(self): + return self.with_delay().send_payrolls() + + def _get_payrolls_being_processed(self): + jobs = self.env["queue.job"].search( + [ + ("model_name", "=", self._name), + ("method_name", "=", "send_payrolls"), + ("state", "not in", [CANCELLED, DONE, FAILED]), + ] + ) + jobs_records_ids = [ + wizard_id + for wizard_id in flatten(jobs.mapped("record_ids")) + if wizard_id not in self.ids + ] + jobs_records = self.browse(jobs_records_ids).exists() + return jobs_records.payrolls + + @api.depends( + "payrolls", + ) + def _compute_is_payroll_being_processed(self): + jobs_payrolls_checksums = set( + self._get_payrolls_being_processed().mapped("checksum") + ) + + for wizard in self: + wizard.is_payroll_being_processed = any( + payroll.checksum in jobs_payrolls_checksums + for payroll in wizard.payrolls + ) + + @api.depends( + "is_payroll_being_processed", + ) + def _compute_is_send_visible(self): + for wizard in self: + wizard.is_send_visible = not wizard.is_payroll_being_processed diff --git a/hr_payroll_document_queue/wizards/payroll_management_wizard_views.xml b/hr_payroll_document_queue/wizards/payroll_management_wizard_views.xml new file mode 100644 index 00000000..d43b4770 --- /dev/null +++ b/hr_payroll_document_queue/wizards/payroll_management_wizard_views.xml @@ -0,0 +1,59 @@ + + + + + Add Async buttons and fields Payroll Management form view + payroll.management.wizard + + + + + + + + + + + + diff --git a/setup/hr_payroll_document_queue/odoo/addons/hr_payroll_document_queue b/setup/hr_payroll_document_queue/odoo/addons/hr_payroll_document_queue new file mode 120000 index 00000000..1fe87fe7 --- /dev/null +++ b/setup/hr_payroll_document_queue/odoo/addons/hr_payroll_document_queue @@ -0,0 +1 @@ +../../../../hr_payroll_document_queue \ No newline at end of file diff --git a/setup/hr_payroll_document_queue/setup.py b/setup/hr_payroll_document_queue/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/hr_payroll_document_queue/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 2827e699f7f1e506571f225b4362f9d119a3e482 Mon Sep 17 00:00:00 2001 From: Simone Rubino Date: Thu, 27 Aug 2026 14:46:28 +0200 Subject: [PATCH 3/4] [IMP] hr_payroll_document_queue: pre-commit execution --- hr_payroll_document_queue/README.rst | 26 ++++++++++--------- hr_payroll_document_queue/pyproject.toml | 3 +++ .../readme/CONTRIBUTORS.md | 2 ++ .../readme/CONTRIBUTORS.rst | 3 --- .../{DESCRIPTION.rst => DESCRIPTION.md} | 6 +++-- .../static/description/index.html | 12 +++++---- 6 files changed, 30 insertions(+), 22 deletions(-) create mode 100644 hr_payroll_document_queue/pyproject.toml create mode 100644 hr_payroll_document_queue/readme/CONTRIBUTORS.md delete mode 100644 hr_payroll_document_queue/readme/CONTRIBUTORS.rst rename hr_payroll_document_queue/readme/{DESCRIPTION.rst => DESCRIPTION.md} (61%) diff --git a/hr_payroll_document_queue/README.rst b/hr_payroll_document_queue/README.rst index 341f7924..380203c7 100644 --- a/hr_payroll_document_queue/README.rst +++ b/hr_payroll_document_queue/README.rst @@ -17,22 +17,24 @@ HR - Payroll Document - Queue :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpayroll-lightgray.png?logo=github - :target: https://github.com/OCA/payroll/tree/16.0/hr_payroll_document_queue + :target: https://github.com/OCA/payroll/tree/18.0/hr_payroll_document_queue :alt: OCA/payroll .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/payroll-16-0/payroll-16-0-hr_payroll_document_queue + :target: https://translation.odoo-community.org/projects/payroll-18-0/payroll-18-0-hr_payroll_document_queue :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/payroll&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/payroll&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| Allow to process the payslips asynchronously. -If a payroll is being processed asynchronously, attempting to process it again will show a warning and prevent it from being processed. +If a payroll is being processed asynchronously, attempting to process it +again will show a warning and prevent it from being processed. -When the payroll has been processed, the user is notified according to their Notification preference. +When the payroll has been processed, the user is notified according to +their Notification preference. **Table of contents** @@ -45,7 +47,7 @@ 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 `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -53,19 +55,19 @@ Credits ======= Authors -~~~~~~~ +------- * PyTech Contributors -~~~~~~~~~~~~ +------------ -* `PyTech `_: +- `PyTech `__: - * Simone Rubino + - Simone Rubino Maintainers -~~~~~~~~~~~ +----------- This module is maintained by the OCA. @@ -85,6 +87,6 @@ Current `maintainer `__: |maintainer-SirPyTech| -This module is part of the `OCA/payroll `_ project on GitHub. +This module is part of the `OCA/payroll `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_payroll_document_queue/pyproject.toml b/hr_payroll_document_queue/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/hr_payroll_document_queue/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/hr_payroll_document_queue/readme/CONTRIBUTORS.md b/hr_payroll_document_queue/readme/CONTRIBUTORS.md new file mode 100644 index 00000000..f5175108 --- /dev/null +++ b/hr_payroll_document_queue/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- [PyTech](https://www.pytech.it): + - Simone Rubino \ diff --git a/hr_payroll_document_queue/readme/CONTRIBUTORS.rst b/hr_payroll_document_queue/readme/CONTRIBUTORS.rst deleted file mode 100644 index 3e2b1040..00000000 --- a/hr_payroll_document_queue/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,3 +0,0 @@ -* `PyTech `_: - - * Simone Rubino diff --git a/hr_payroll_document_queue/readme/DESCRIPTION.rst b/hr_payroll_document_queue/readme/DESCRIPTION.md similarity index 61% rename from hr_payroll_document_queue/readme/DESCRIPTION.rst rename to hr_payroll_document_queue/readme/DESCRIPTION.md index b1e36f7b..7c0e6cad 100644 --- a/hr_payroll_document_queue/readme/DESCRIPTION.rst +++ b/hr_payroll_document_queue/readme/DESCRIPTION.md @@ -1,5 +1,7 @@ Allow to process the payslips asynchronously. -If a payroll is being processed asynchronously, attempting to process it again will show a warning and prevent it from being processed. +If a payroll is being processed asynchronously, attempting to process it +again will show a warning and prevent it from being processed. -When the payroll has been processed, the user is notified according to their Notification preference. +When the payroll has been processed, the user is notified according to +their Notification preference. diff --git a/hr_payroll_document_queue/static/description/index.html b/hr_payroll_document_queue/static/description/index.html index 659c27ba..28966391 100644 --- a/hr_payroll_document_queue/static/description/index.html +++ b/hr_payroll_document_queue/static/description/index.html @@ -369,10 +369,12 @@

HR - Payroll Document - Queue

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:9b97fc250e9f7c34ba848cdc7ac246d98c29cdd4d8f16c1d6ed18fcf14fbc4f8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/payroll Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/payroll Translate me on Weblate Try me on Runboat

Allow to process the payslips asynchronously.

-

If a payroll is being processed asynchronously, attempting to process it again will show a warning and prevent it from being processed.

-

When the payroll has been processed, the user is notified according to their Notification preference.

+

If a payroll is being processed asynchronously, attempting to process it +again will show a warning and prevent it from being processed.

+

When the payroll has been processed, the user is notified according to +their Notification preference.

Table of contents

    @@ -390,7 +392,7 @@

    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.

    +feedback.

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

@@ -421,7 +423,7 @@

Maintainers

promote its widespread use.

Current maintainer:

SirPyTech

-

This module is part of the OCA/payroll project on GitHub.

+

This module is part of the OCA/payroll project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

From b02300972be2ff7f9e7cd076fbb1fd75105ad2c8 Mon Sep 17 00:00:00 2001 From: Simone Rubino Date: Thu, 27 Aug 2026 14:46:35 +0200 Subject: [PATCH 4/4] [MIG] hr_payroll_document_queue: Migration to 18.0 --- hr_payroll_document_queue/__manifest__.py | 2 +- .../tests/test_payroll_management.py | 6 +++-- .../wizards/payroll_management_wizard.py | 27 ++++++++++--------- .../payroll_management_wizard_views.xml | 18 +++---------- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/hr_payroll_document_queue/__manifest__.py b/hr_payroll_document_queue/__manifest__.py index 20c3ffa1..6dd2dcc2 100644 --- a/hr_payroll_document_queue/__manifest__.py +++ b/hr_payroll_document_queue/__manifest__.py @@ -8,7 +8,7 @@ "website": "https://github.com/OCA/payroll", "license": "AGPL-3", "category": "Payrolls", - "version": "16.0.1.0.0", + "version": "18.0.1.0.0", "maintainers": [ "SirPyTech", ], diff --git a/hr_payroll_document_queue/tests/test_payroll_management.py b/hr_payroll_document_queue/tests/test_payroll_management.py index 0466ce01..be634575 100644 --- a/hr_payroll_document_queue/tests/test_payroll_management.py +++ b/hr_payroll_document_queue/tests/test_payroll_management.py @@ -3,12 +3,14 @@ from odoo import exceptions -from odoo.addons.hr_payroll_document.tests.common import TestHrPayrollDocument +from odoo.addons.hr_payroll_document.tests.test_hr_payroll_document import ( + TestHRPayrollDocument, +) from odoo.addons.mail.tests.common import MailCase from odoo.addons.queue_job.tests.common import trap_jobs -class TestPayrollManagement(MailCase, TestHrPayrollDocument): +class TestPayrollManagement(MailCase, TestHRPayrollDocument): def test_job_creation(self): """The job is created.""" # Arrange diff --git a/hr_payroll_document_queue/wizards/payroll_management_wizard.py b/hr_payroll_document_queue/wizards/payroll_management_wizard.py index 368fe04b..ccaca879 100644 --- a/hr_payroll_document_queue/wizards/payroll_management_wizard.py +++ b/hr_payroll_document_queue/wizards/payroll_management_wizard.py @@ -1,9 +1,9 @@ # Copyright 2026 Simone Rubino - PyTech # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from itertools import chain from odoo import _, api, exceptions, fields, models -from odoo.tools.misc import flatten from odoo.addons.queue_job.job import CANCELLED, DONE, FAILED @@ -25,15 +25,18 @@ class PayrollManagamentWizard(models.TransientModel): def _notify_async_processed(self, send_result): """Notify the result to the user that processed the payrolls.""" self.ensure_one() - odoobot = self.env.ref("base.partner_root") + odoobot = self.env.ref("base.user_root") user = self.env.user - return self.env["mail.thread"].message_notify( - author_id=odoobot.id, - partner_ids=user.partner_id.ids, - subject=send_result["params"]["title"], - body=send_result["params"]["message"], - model=self._name, - res_id=self.id, + return ( + self.env["mail.thread"] + .with_user(odoobot) + .message_notify( + partner_ids=user.partner_id.ids, + subject=send_result["params"]["title"], + body=send_result["params"]["message"], + model=self._name, + res_id=self.id, + ) ) def send_payrolls(self): @@ -60,9 +63,9 @@ def _get_payrolls_being_processed(self): ] ) jobs_records_ids = [ - wizard_id - for wizard_id in flatten(jobs.mapped("record_ids")) - if wizard_id not in self.ids + wizard.id + for wizard in chain.from_iterable(jobs.mapped("records")) + if wizard not in self ] jobs_records = self.browse(jobs_records_ids).exists() return jobs_records.payrolls diff --git a/hr_payroll_document_queue/wizards/payroll_management_wizard_views.xml b/hr_payroll_document_queue/wizards/payroll_management_wizard_views.xml index d43b4770..be3e63bc 100644 --- a/hr_payroll_document_queue/wizards/payroll_management_wizard_views.xml +++ b/hr_payroll_document_queue/wizards/payroll_management_wizard_views.xml @@ -19,11 +19,7 @@