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,5 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import microsoft_calendar
from . import microsoft_event
from . import event_id_storage

View file

@ -1,10 +0,0 @@
IDS_SEPARATOR = ':'
def combine_ids(ms_id, ms_uid):
if not ms_id:
return False
return ms_id + IDS_SEPARATOR + (ms_uid if ms_uid else '')
def split_ids(value):
ids = value.split(IDS_SEPARATOR)
return tuple(ids) if len(ids) > 1 and ids[1] else (ids[0], False)

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import requests
@ -207,7 +206,13 @@ class MicrosoftCalendarService():
return 'offline_access openid Calendars.ReadWrite'
def _microsoft_authentication_url(self, from_url='http://www.odoo.com'):
return self.microsoft_service._get_authorize_uri(from_url, service='calendar', scope=self._get_calendar_scope())
redirect_uri = self.microsoft_service.get_base_url() + '/microsoft_account/authentication'
return self.microsoft_service._get_authorize_uri(
from_url,
service='calendar',
scope=self._get_calendar_scope(),
redirect_uri=redirect_uri
)
def _can_authorize_microsoft(self, user):
return user.has_group('base.group_erp_manager')

View file

@ -1,12 +1,11 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
from odoo.api import model
from typing import Iterator, Mapping
from collections import abc
from odoo.tools import ReadonlyDict, email_normalize
from odoo.addons.microsoft_calendar.utils.event_id_storage import combine_ids
from typing import Iterator, Mapping
from odoo.tools import email_normalize
from odoo.tools.misc import ReadonlyDict
class MicrosoftEvent(abc.Set):
@ -107,25 +106,11 @@ class MicrosoftEvent(abc.Set):
# Query events OR recurrences, get organizer_id and universal_id values by splitting microsoft_id.
model_env = force_model if force_model is not None else self._get_model(env)
organiser_ids = tuple(str(v) for v in unmapped_events.ids if v) or ('NULL',)
universal_ids = tuple(str(v) for v in unmapped_events.uids if v) or ('NULL',)
model_env.flush_model(['microsoft_id'])
env.cr.execute(
"""
SELECT id, organizer_id, universal_id
FROM (
SELECT id,
split_part(microsoft_id, ':', 1) AS organizer_id,
split_part(microsoft_id, ':', 2) AS universal_id
FROM %s
WHERE microsoft_id IS NOT NULL) AS splitter
WHERE organizer_id IN %%s
OR universal_id IN %%s
""" % model_env._table, (organiser_ids, universal_ids))
res = env.cr.fetchall()
odoo_events_ids = [val[0] for val in res]
odoo_events = model_env.browse(odoo_events_ids)
odoo_events = model_env.with_context(active_test=False).search([
'|',
('ms_universal_event_id', "in", unmapped_events.uids),
('microsoft_id', "in", unmapped_events.ids)
]).with_env(env)
# 1. try to match unmapped events with Odoo events using their iCalUId
unmapped_events_with_uids = unmapped_events.filter(lambda e: e.iCalUId)
@ -140,7 +125,7 @@ class MicrosoftEvent(abc.Set):
# 2. try to match unmapped events with Odoo events using their id
unmapped_events = self.filter(lambda e: e.id not in mapped_events)
mapping = {e.ms_organizer_event_id: e for e in odoo_events}
mapping = {e.microsoft_id: e for e in odoo_events}
for ms_event in unmapped_events:
odoo_event = mapping.get(ms_event.id)
@ -151,7 +136,8 @@ class MicrosoftEvent(abc.Set):
# don't forget to also set the global event ID on the Odoo event to ease
# and improve reliability of future mappings
odoo_event.write({
'microsoft_id': combine_ids(ms_event.id, ms_event.iCalUId),
'microsoft_id': ms_event.id,
'ms_universal_event_id': ms_event.iCalUId,
'need_sync_m': False,
})
@ -218,8 +204,6 @@ class MicrosoftEvent(abc.Set):
}
rrule_type = type_dict.get(pattern['type'], pattern['type'])
interval = pattern['interval']
if rrule_type == 'yearly':
interval *= 12
result = {
'rrule_type': rrule_type,
'end_type': end_type_dict.get(range['type'], False),