19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:32:28 +01:00
parent 20ddc1b4a3
commit c0efcc53f5
1162 changed files with 125577 additions and 105287 deletions

View file

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import google_calendar
from . import google_event

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from uuid import uuid4
@ -29,8 +28,10 @@ class GoogleCalendarService():
self.google_service = google_service
@requires_auth_token
def get_events(self, sync_token=None, token=None, timeout=TIMEOUT):
def get_events(self, sync_token=None, token=None, event_id=None, timeout=TIMEOUT):
url = "/calendar/v3/calendars/primary/events"
if event_id:
url += f"/{event_id}"
headers = {'Content-type': 'application/json'}
params = {'access_token': token}
if sync_token:
@ -51,6 +52,11 @@ class GoogleCalendarService():
raise InvalidSyncToken("Invalid sync token. Full sync required")
raise e
if event_id:
next_sync_token = None
default_reminders = ()
return GoogleEvent([data]), next_sync_token, default_reminders
events = data.get('items', [])
next_page_token = data.get('nextPageToken')
while next_page_token:
@ -65,18 +71,19 @@ class GoogleCalendarService():
return GoogleEvent(events), next_sync_token, default_reminders
@requires_auth_token
def insert(self, values, token=None, timeout=TIMEOUT):
send_updates = self.google_service._context.get('send_updates', True)
url = "/calendar/v3/calendars/primary/events?conferenceDataVersion=1&sendUpdates=%s" % ("all" if send_updates else "none")
def insert(self, values, token=None, timeout=TIMEOUT, need_video_call=True):
send_updates = self.google_service.env.context.get('send_updates', True)
url = "/calendar/v3/calendars/primary/events?conferenceDataVersion=%d&sendUpdates=%s" % (1 if need_video_call else 0, "all" if send_updates else "none")
headers = {'Content-type': 'application/json', 'Authorization': 'Bearer %s' % token}
if not values.get('id'):
values['id'] = uuid4().hex
self.google_service._do_request(url, json.dumps(values), headers, method='POST', timeout=timeout)
return values['id']
_dummy, google_values, _dummy = self.google_service._do_request(url, json.dumps(values), headers, method='POST', timeout=timeout)
return google_values
@requires_auth_token
def patch(self, event_id, values, token=None, timeout=TIMEOUT):
url = "/calendar/v3/calendars/primary/events/%s?sendUpdates=all" % event_id
send_updates = self.google_service.env.context.get('send_updates', True)
url = "/calendar/v3/calendars/primary/events/%s?sendUpdates=%s&conferenceDataVersion=1" % (event_id, "all" if send_updates else "none")
headers = {'Content-type': 'application/json', 'Authorization': 'Bearer %s' % token}
self.google_service._do_request(url, json.dumps(values), headers, method='PATCH', timeout=timeout)
@ -88,7 +95,7 @@ class GoogleCalendarService():
# Delete all events from recurrence in a single request to Google and triggering a single mail.
# The 'singleEvents' parameter is a trick that tells Google API to delete all recurrent events individually,
# making the deletion be handled entirely on their side, and then we archive the events in Odoo.
is_recurrence = self.google_service._context.get('is_recurrence', True)
is_recurrence = self.google_service.env.context.get('is_recurrence', True)
if is_recurrence:
params['singleEvents'] = 'true'
try:
@ -116,9 +123,10 @@ class GoogleCalendarService():
state = {
'd': self.google_service.env.cr.dbname,
's': 'calendar',
'f': from_url
'f': from_url,
'u': self.google_service.env['ir.config_parameter'].sudo().get_param('database.uuid'),
}
base_url = self.google_service._context.get('base_url') or self.google_service.get_base_url()
base_url = self.google_service.env.context.get('base_url') or self.google_service.get_base_url()
return self.google_service._get_authorize_uri(
'calendar',
self._get_calendar_scope(),

View file

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
from odoo.tools import email_normalize, ReadonlyDict
import logging
from typing import Iterator, Mapping
from collections import abc
import re
from collections import abc
from typing import Iterator, Mapping
from odoo.tools import email_normalize
from odoo.tools.misc import ReadonlyDict
_logger = logging.getLogger(__name__)
@ -196,9 +196,17 @@ class GoogleEvent(abc.Set):
recurringEventId_value = re.match(r'(\w+_)', self.recurringEventId)
if not id_value or not recurringEventId_value or id_value.group(1) != recurringEventId_value.group(1):
return None
ID_RANGE = re.search(r'\w+_R\d+T\d+', self.recurringEventId).group()
TIMESTAMP = re.search(r'\d+T\d+Z', self.id).group()
return f"{ID_RANGE}_{TIMESTAMP}"
rec_pattern = re.search(r'(\w+_R\d+(?:T\d+)?(?:Z)?)', self.recurringEventId)
if not rec_pattern:
return None
id_range = rec_pattern.group()
ts_pattern = re.search(r'(\d{8}(?:T\d+Z?)?)$', self.id)
if not ts_pattern:
return None
timestamp = ts_pattern.group()
return f"{id_range}_{timestamp}"
def cancelled(self):
return self.filter(lambda e: e.status == 'cancelled')