From 95304f65dae26d00e9ab630c24bfd3715bb5a7f8 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 2 Oct 2026 17:38:50 +0000 Subject: [PATCH 1/3] Added translation using Weblate (Spanish) (cherry picked from commit 1dd74a892747e90e3ccf104687bc42d1abae2f7e) --- hr_holidays_google_calendar/i18n/es.po | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 hr_holidays_google_calendar/i18n/es.po diff --git a/hr_holidays_google_calendar/i18n/es.po b/hr_holidays_google_calendar/i18n/es.po new file mode 100644 index 00000000..c8395807 --- /dev/null +++ b/hr_holidays_google_calendar/i18n/es.po @@ -0,0 +1,32 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_holidays_google_calendar +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-06-17 15:20+0000\n" +"PO-Revision-Date: 2026-06-17 15:20+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: hr_holidays_google_calendar +#: model:ir.model,name:hr_holidays_google_calendar.model_calendar_event +msgid "Calendar Event" +msgstr "" + +#. module: hr_holidays_google_calendar +#: model:ir.model.fields,field_description:hr_holidays_google_calendar.field_calendar_event__display_name +msgid "Display Name" +msgstr "" + +#. module: hr_holidays_google_calendar +#: model:ir.model.fields,field_description:hr_holidays_google_calendar.field_calendar_event__id +msgid "ID" +msgstr "" From 4acab074afe1113c6b1315b92dca3a928d612b3b Mon Sep 17 00:00:00 2001 From: mav-adhoc Date: Fri, 23 Oct 2026 15:09:16 -0300 Subject: [PATCH 2/3] [MIG] hr_holidays_google_calendar: Migration to 20.0 - google.calendar.sync is split into google.sync and google.event.sync: _google_insert takes the target calendar as a new argument, so the override follows the 20.0 signature. - TIMEOUT is no longer exported by google_calendar.models.google_sync: import it from google_account.models.google_service. - Regenerate i18n and translate the module name and summary. --- hr_holidays_google_calendar/__manifest__.py | 4 ++-- hr_holidays_google_calendar/i18n/es.po | 18 ++++++++++++++---- .../i18n/hr_holidays_google_calendar.pot | 16 +++++++++++++--- .../models/calendar_event.py | 6 +++--- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/hr_holidays_google_calendar/__manifest__.py b/hr_holidays_google_calendar/__manifest__.py index 5eb32b99..14e3558f 100644 --- a/hr_holidays_google_calendar/__manifest__.py +++ b/hr_holidays_google_calendar/__manifest__.py @@ -19,7 +19,7 @@ ############################################################################## { "name": "Holidays Google Calendar", - "version": "19.0.1.0.0", + "version": "20.0.1.0.0", "category": "Human Resources", "summary": "Suppress Google Calendar invitations when approving time off", "author": "ADHOC SA", @@ -31,7 +31,7 @@ ], "data": [], "demo": [], - "installable": False, + "installable": True, "auto_install": True, "application": False, } diff --git a/hr_holidays_google_calendar/i18n/es.po b/hr_holidays_google_calendar/i18n/es.po index c8395807..817fff14 100644 --- a/hr_holidays_google_calendar/i18n/es.po +++ b/hr_holidays_google_calendar/i18n/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 19.0+e\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-17 15:20+0000\n" -"PO-Revision-Date: 2026-06-17 15:20+0000\n" +"POT-Creation-Date: 2026-10-23 18:13+0000\n" +"PO-Revision-Date: 2026-10-23 18:13+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: es\n" @@ -19,14 +19,24 @@ msgstr "" #. module: hr_holidays_google_calendar #: model:ir.model,name:hr_holidays_google_calendar.model_calendar_event msgid "Calendar Event" -msgstr "" +msgstr "Evento del calendario" #. module: hr_holidays_google_calendar #: model:ir.model.fields,field_description:hr_holidays_google_calendar.field_calendar_event__display_name msgid "Display Name" -msgstr "" +msgstr "Nombre en pantalla" + +#. module: hr_holidays_google_calendar +#: model:ir.module.module,shortdesc:base.module_hr_holidays_google_calendar +msgid "Holidays Google Calendar" +msgstr "Ausencias Google Calendar" #. module: hr_holidays_google_calendar #: model:ir.model.fields,field_description:hr_holidays_google_calendar.field_calendar_event__id msgid "ID" msgstr "" + +#. module: hr_holidays_google_calendar +#: model:ir.module.module,summary:base.module_hr_holidays_google_calendar +msgid "Suppress Google Calendar invitations when approving time off" +msgstr "Suprime las invitaciones de Google Calendar al aprobar ausencias" diff --git a/hr_holidays_google_calendar/i18n/hr_holidays_google_calendar.pot b/hr_holidays_google_calendar/i18n/hr_holidays_google_calendar.pot index 42593702..ea73783d 100644 --- a/hr_holidays_google_calendar/i18n/hr_holidays_google_calendar.pot +++ b/hr_holidays_google_calendar/i18n/hr_holidays_google_calendar.pot @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 19.0+e\n" +"Project-Id-Version: Odoo Server 20.0+e\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-17 15:20+0000\n" -"PO-Revision-Date: 2026-06-17 15:20+0000\n" +"POT-Creation-Date: 2026-10-23 18:13+0000\n" +"PO-Revision-Date: 2026-10-23 18:13+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -25,7 +25,17 @@ msgstr "" msgid "Display Name" msgstr "" +#. module: hr_holidays_google_calendar +#: model:ir.module.module,shortdesc:base.module_hr_holidays_google_calendar +msgid "Holidays Google Calendar" +msgstr "" + #. module: hr_holidays_google_calendar #: model:ir.model.fields,field_description:hr_holidays_google_calendar.field_calendar_event__id msgid "ID" msgstr "" + +#. module: hr_holidays_google_calendar +#: model:ir.module.module,summary:base.module_hr_holidays_google_calendar +msgid "Suppress Google Calendar invitations when approving time off" +msgstr "" diff --git a/hr_holidays_google_calendar/models/calendar_event.py b/hr_holidays_google_calendar/models/calendar_event.py index 8c446856..5d055691 100644 --- a/hr_holidays_google_calendar/models/calendar_event.py +++ b/hr_holidays_google_calendar/models/calendar_event.py @@ -1,14 +1,14 @@ from odoo import models -from odoo.addons.google_calendar.models.google_sync import TIMEOUT +from odoo.addons.google_account.models.google_service import TIMEOUT class CalendarEvent(models.Model): _inherit = "calendar.event" - def _google_insert(self, google_service, values, timeout=TIMEOUT): + def _google_insert(self, google_service, calendar, values, timeout=TIMEOUT): # When hr_holidays creates a leave event it sets no_mail_to_attendees=True, # meaning Odoo itself must not notify attendees. Honour that restriction in # Google Calendar too by suppressing the sendUpdates notification. if self.env.context.get("no_mail_to_attendees"): self = self.with_context(send_updates=False) - return super()._google_insert(google_service, values, timeout=timeout) + return super()._google_insert(google_service, calendar, values, timeout=timeout) From daa0c55f48ec372ce6a47ef9962208fa11885267 Mon Sep 17 00:00:00 2001 From: mav-adhoc Date: Fri, 30 Oct 2026 10:47:17 -0300 Subject: [PATCH 3/3] [FIX] hr_holidays_google_calendar: accept both _google_insert call shapes Odoo 20 calls _google_insert with two signatures: google_event_sync.py:68 still omits `calendar`, while lines 129 and 174 pass it. Upstream wraps the method in @after_commit, which takes any arguments and defers the call, so without this module the mismatch only ends as a post-commit warning. The override ran first and raised TypeError inside the transaction, so confirming a draft event failed. It now forwards whatever it gets. Also add the first test of the module: it covers both call shapes and the send_updates=False suppression, and fails with the previous signature. Change note: en Odoo 20, confirmar un evento de calendario en borrador fallaba con error en las bases que tienen instalado este modulo (se instala solo). Ahora confirma bien, y se mantiene que una ausencia aprobada no le mande la invitacion de Google a los asistentes. --- .../models/calendar_event.py | 7 ++- hr_holidays_google_calendar/tests/__init__.py | 1 + .../tests/test_calendar_event.py | 59 +++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 hr_holidays_google_calendar/tests/__init__.py create mode 100644 hr_holidays_google_calendar/tests/test_calendar_event.py diff --git a/hr_holidays_google_calendar/models/calendar_event.py b/hr_holidays_google_calendar/models/calendar_event.py index 5d055691..67b94c97 100644 --- a/hr_holidays_google_calendar/models/calendar_event.py +++ b/hr_holidays_google_calendar/models/calendar_event.py @@ -1,14 +1,15 @@ from odoo import models -from odoo.addons.google_account.models.google_service import TIMEOUT class CalendarEvent(models.Model): _inherit = "calendar.event" - def _google_insert(self, google_service, calendar, values, timeout=TIMEOUT): + # Odoo 20 still calls this with the old signature in google_event_sync.py:68 + # (no `calendar`), so the override forwards whatever it gets instead of binding it. + def _google_insert(self, *args, **kwargs): # When hr_holidays creates a leave event it sets no_mail_to_attendees=True, # meaning Odoo itself must not notify attendees. Honour that restriction in # Google Calendar too by suppressing the sendUpdates notification. if self.env.context.get("no_mail_to_attendees"): self = self.with_context(send_updates=False) - return super()._google_insert(google_service, calendar, values, timeout=timeout) + return super()._google_insert(*args, **kwargs) diff --git a/hr_holidays_google_calendar/tests/__init__.py b/hr_holidays_google_calendar/tests/__init__.py new file mode 100644 index 00000000..1d2a24b0 --- /dev/null +++ b/hr_holidays_google_calendar/tests/__init__.py @@ -0,0 +1 @@ +from . import test_calendar_event diff --git a/hr_holidays_google_calendar/tests/test_calendar_event.py b/hr_holidays_google_calendar/tests/test_calendar_event.py new file mode 100644 index 00000000..2b1cb42d --- /dev/null +++ b/hr_holidays_google_calendar/tests/test_calendar_event.py @@ -0,0 +1,59 @@ +from datetime import timedelta +from unittest.mock import patch + +from odoo import fields +from odoo.addons.google_calendar.models.google_event_sync import GoogleEventSync +from odoo.tests.common import TransactionCase + + +class TestCalendarEventGoogleInsert(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + now = fields.Datetime.now() + cls.event = cls.env["calendar.event"].create( + { + "name": "Time off", + "start": now, + "stop": now + timedelta(hours=1), + } + ) + + def _forward(self, context, *args, **kwargs): + """Call the override with the parent replaced, and return what the parent got.""" + seen = [] + + def _parent(records, *parent_args, **parent_kwargs): + seen.append((records.env.context, parent_args, parent_kwargs)) + + # Not autospec: after_commit wraps the parent, so autospec would enforce + # its signature and reject the very call shape this test covers. + with patch.object(GoogleEventSync, "_google_insert", _parent): + self.event.with_context(**context)._google_insert(*args, **kwargs) + self.assertEqual(len(seen), 1, "the override must call its parent exactly once") + return seen[0] + + def test_google_insert_forwards_every_call_shape(self): + """The override forwards each call Odoo 20 makes, and suppresses the Google + notification only when hr_holidays asked not to notify the attendees. + """ + service = self.env["google.service"] + values = {"summary": "Time off"} + + with self.subTest("confirming a draft event does not break"): + # google_calendar/models/google_event_sync.py:68 still calls without `calendar` + context, args, kwargs = self._forward({}, service, values, timeout=3) + self.assertEqual(args, (service, values)) + self.assertEqual(kwargs, {"timeout": 3}) + self.assertNotIn("send_updates", context) + + with self.subTest("the call with a calendar reaches the parent untouched"): + context, args, kwargs = self._forward({}, service, "primary", values, timeout=3) + self.assertEqual(args, (service, "primary", values)) + self.assertEqual(kwargs, {"timeout": 3}) + self.assertNotIn("send_updates", context) + + with self.subTest("an approved time off does not notify attendees on Google"): + context, args, kwargs = self._forward({"no_mail_to_attendees": True}, service, "primary", values) + self.assertFalse(context["send_updates"]) + self.assertEqual(args, (service, "primary", values))