mirror of
https://github.com/bringout/oca-ocb-technical.git
synced 2026-04-25 05:31:59 +02:00
19.0 vanilla
This commit is contained in:
parent
5faf7397c5
commit
2696f14ed7
721 changed files with 220375 additions and 91221 deletions
|
|
@ -1,17 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools import plaintext2html
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
from odoo.tools.sql import SQL
|
||||
|
||||
|
||||
class AlarmManager(models.AbstractModel):
|
||||
class CalendarAlarm_Manager(models.AbstractModel):
|
||||
_name = 'calendar.alarm_manager'
|
||||
_description = 'Event Alarm Manager'
|
||||
|
||||
|
|
@ -23,7 +19,9 @@ class AlarmManager(models.AbstractModel):
|
|||
result = {}
|
||||
delta_request = """
|
||||
SELECT
|
||||
rel.calendar_event_id, max(alarm.duration_minutes) AS max_delta,min(alarm.duration_minutes) AS min_delta
|
||||
rel.calendar_event_id,
|
||||
max(alarm.duration_minutes) AS max_delta,
|
||||
min(alarm.duration_minutes) AS min_delta
|
||||
FROM
|
||||
calendar_alarm_calendar_event_rel AS rel
|
||||
LEFT JOIN calendar_alarm AS alarm ON alarm.id = rel.calendar_alarm_id
|
||||
|
|
@ -31,30 +29,24 @@ class AlarmManager(models.AbstractModel):
|
|||
GROUP BY rel.calendar_event_id
|
||||
"""
|
||||
base_request = """
|
||||
SELECT
|
||||
cal.id,
|
||||
cal.start - interval '1' minute * calcul_delta.max_delta AS first_alarm,
|
||||
CASE
|
||||
WHEN cal.recurrency THEN rrule.until - interval '1' minute * calcul_delta.min_delta
|
||||
ELSE cal.stop - interval '1' minute * calcul_delta.min_delta
|
||||
END as last_alarm,
|
||||
cal.start as first_event_date,
|
||||
CASE
|
||||
WHEN cal.recurrency THEN rrule.until
|
||||
ELSE cal.stop
|
||||
END as last_event_date,
|
||||
calcul_delta.min_delta,
|
||||
calcul_delta.max_delta,
|
||||
rrule.rrule AS rule
|
||||
FROM
|
||||
calendar_event AS cal
|
||||
RIGHT JOIN calcul_delta ON calcul_delta.calendar_event_id = cal.id
|
||||
LEFT JOIN calendar_recurrence as rrule ON rrule.id = cal.recurrence_id
|
||||
"""
|
||||
|
||||
SELECT
|
||||
cal.id,
|
||||
cal.start - interval '1' minute * calcul_delta.max_delta AS first_alarm,
|
||||
cal.stop - interval '1' minute * calcul_delta.min_delta AS last_alarm,
|
||||
cal.start AS first_meeting,
|
||||
cal.stop AS last_meeting,
|
||||
calcul_delta.min_delta,
|
||||
calcul_delta.max_delta
|
||||
FROM
|
||||
calendar_event AS cal
|
||||
INNER JOIN calcul_delta ON calcul_delta.calendar_event_id = cal.id
|
||||
WHERE cal.active = True
|
||||
"""
|
||||
filter_user = """
|
||||
RIGHT JOIN calendar_event_res_partner_rel AS part_rel ON part_rel.calendar_event_id = cal.id
|
||||
AND part_rel.res_partner_id IN %s
|
||||
INNER JOIN calendar_event_res_partner_rel AS part_rel
|
||||
ON part_rel.calendar_event_id = cal.id
|
||||
AND part_rel.res_partner_id IN %s
|
||||
WHERE cal.active = True
|
||||
"""
|
||||
|
||||
# Add filter on alarm type
|
||||
|
|
@ -62,7 +54,7 @@ class AlarmManager(models.AbstractModel):
|
|||
|
||||
# Add filter on partner_id
|
||||
if partners:
|
||||
base_request += filter_user
|
||||
base_request = base_request.replace("WHERE cal.active = True", filter_user)
|
||||
tuple_params += (tuple(partners.ids), )
|
||||
|
||||
# Upper bound on first_alarm of requested events
|
||||
|
|
@ -81,15 +73,15 @@ class AlarmManager(models.AbstractModel):
|
|||
tuple_params += (seconds,)
|
||||
|
||||
self.env.flush_all()
|
||||
self._cr.execute("""
|
||||
self.env.cr.execute("""
|
||||
WITH calcul_delta AS (%s)
|
||||
SELECT *
|
||||
FROM ( %s WHERE cal.active = True ) AS ALL_EVENTS
|
||||
WHERE ALL_EVENTS.first_alarm < %s
|
||||
AND ALL_EVENTS.last_event_date > (now() at time zone 'utc')
|
||||
FROM ( %s ) AS ALL_EVENTS
|
||||
WHERE ALL_EVENTS.first_alarm < %s
|
||||
AND ALL_EVENTS.last_alarm > (now() at time zone 'utc')
|
||||
""" % (delta_request, base_request, first_alarm_max_value), tuple_params)
|
||||
|
||||
for event_id, first_alarm, last_alarm, first_meeting, last_meeting, min_duration, max_duration, rule in self._cr.fetchall():
|
||||
for event_id, first_alarm, last_alarm, first_meeting, last_meeting, min_duration, max_duration in self.env.cr.fetchall():
|
||||
result[event_id] = {
|
||||
'event_id': event_id,
|
||||
'first_alarm': first_alarm,
|
||||
|
|
@ -98,14 +90,13 @@ class AlarmManager(models.AbstractModel):
|
|||
'last_meeting': last_meeting,
|
||||
'min_duration': min_duration,
|
||||
'max_duration': max_duration,
|
||||
'rrule': rule
|
||||
}
|
||||
|
||||
# determine accessible events
|
||||
events = self.env['calendar.event'].browse(result)
|
||||
result = {
|
||||
key: result[key]
|
||||
for key in set(events._filter_access_rules('read').ids)
|
||||
for key in events._filtered_access('read').ids
|
||||
}
|
||||
return result
|
||||
|
||||
|
|
@ -147,7 +138,7 @@ class AlarmManager(models.AbstractModel):
|
|||
To be overriden on inherited modules
|
||||
adding extra conditions to extract only the unsynced events
|
||||
"""
|
||||
return ""
|
||||
return SQL("")
|
||||
|
||||
def _get_events_by_alarm_to_notify(self, alarm_type):
|
||||
"""
|
||||
|
|
@ -159,21 +150,28 @@ class AlarmManager(models.AbstractModel):
|
|||
design. The attendees receive an invitation for any new event
|
||||
already.
|
||||
"""
|
||||
lastcall = self.env.context.get('lastcall', False) or fields.date.today() - relativedelta(weeks=1)
|
||||
self.env.cr.execute('''
|
||||
SELECT "alarm"."id", "event"."id"
|
||||
FROM "calendar_event" AS "event"
|
||||
JOIN "calendar_alarm_calendar_event_rel" AS "event_alarm_rel"
|
||||
ON "event"."id" = "event_alarm_rel"."calendar_event_id"
|
||||
JOIN "calendar_alarm" AS "alarm"
|
||||
ON "event_alarm_rel"."calendar_alarm_id" = "alarm"."id"
|
||||
WHERE
|
||||
"alarm"."alarm_type" = %s
|
||||
AND "event"."active"
|
||||
AND "event"."start" - CAST("alarm"."duration" || ' ' || "alarm"."interval" AS Interval) >= %s
|
||||
AND "event"."start" - CAST("alarm"."duration" || ' ' || "alarm"."interval" AS Interval) < now() at time zone 'utc'
|
||||
AND "event"."stop" > now() at time zone 'utc'
|
||||
''' + self._get_notify_alert_extra_conditions(), [alarm_type, lastcall])
|
||||
lastcall = self.env.context.get('lastcall', False) or fields.Date.today() - timedelta(weeks=1)
|
||||
# TODO MASTER: remove context and add a proper parameter
|
||||
extra_conditions = self.with_context(alarm_type=alarm_type)._get_notify_alert_extra_conditions()
|
||||
now = fields.Datetime.now()
|
||||
self.env.cr.execute(SQL("""
|
||||
SELECT alarm.id, event.id
|
||||
FROM calendar_event AS event
|
||||
JOIN calendar_alarm_calendar_event_rel AS event_alarm_rel
|
||||
ON event.id = event_alarm_rel.calendar_event_id
|
||||
JOIN calendar_alarm AS alarm
|
||||
ON event_alarm_rel.calendar_alarm_id = alarm.id
|
||||
WHERE alarm.alarm_type = %s
|
||||
AND event.active
|
||||
AND event.start - CAST(alarm.duration || ' ' || alarm.interval AS Interval) >= %s
|
||||
AND event.start - CAST(alarm.duration || ' ' || alarm.interval AS Interval) < %s
|
||||
%s
|
||||
""",
|
||||
alarm_type,
|
||||
lastcall,
|
||||
now,
|
||||
extra_conditions,
|
||||
))
|
||||
|
||||
events_by_alarm = {}
|
||||
for alarm_id, event_id in self.env.cr.fetchall():
|
||||
|
|
@ -187,21 +185,24 @@ class AlarmManager(models.AbstractModel):
|
|||
if not events_by_alarm:
|
||||
return
|
||||
|
||||
# force_send limit should apply to the total nb of attendees, not per alarm
|
||||
force_send_limit = int(self.env['ir.config_parameter'].sudo().get_param('mail.mail_force_send_limit', 100))
|
||||
|
||||
event_ids = list(set(event_id for event_ids in events_by_alarm.values() for event_id in event_ids))
|
||||
events = self.env['calendar.event'].browse(event_ids)
|
||||
attendees = events.attendee_ids.filtered(lambda a: a.state != 'declined')
|
||||
now = fields.Datetime.now()
|
||||
attendees = events.filtered(lambda e: e.stop > now).attendee_ids.filtered(lambda a: a.state != 'declined')
|
||||
alarms = self.env['calendar.alarm'].browse(events_by_alarm.keys())
|
||||
for alarm in alarms:
|
||||
alarm_attendees = attendees.filtered(lambda attendee: attendee.event_id.id in events_by_alarm[alarm.id])
|
||||
alarm_attendees.with_context(
|
||||
mail_notify_force_send=True,
|
||||
calendar_template_ignore_recurrence=True,
|
||||
mail_notify_author=True
|
||||
)._send_mail_to_attendees(
|
||||
alarm_attendees.with_context(calendar_template_ignore_recurrence=True)._notify_attendees(
|
||||
alarm.mail_template_id,
|
||||
force_send=True
|
||||
force_send=len(attendees) <= force_send_limit,
|
||||
notify_author=True,
|
||||
)
|
||||
|
||||
events._setup_event_recurrent_alarms(events_by_alarm)
|
||||
|
||||
@api.model
|
||||
def get_next_notif(self):
|
||||
partner = self.env.user.partner_id
|
||||
|
|
@ -245,13 +246,10 @@ class AlarmManager(models.AbstractModel):
|
|||
|
||||
def _notify_next_alarm(self, partner_ids):
|
||||
""" Sends through the bus the next alarm of given partners """
|
||||
notifications = []
|
||||
users = self.env['res.users'].search([
|
||||
('partner_id', 'in', tuple(partner_ids)),
|
||||
('groups_id', 'in', self.env.ref('base.group_user').ids),
|
||||
('group_ids', 'in', self.env.ref('base.group_user').ids),
|
||||
])
|
||||
for user in users:
|
||||
notif = self.with_user(user).with_context(allowed_company_ids=user.company_ids.ids).get_next_notif()
|
||||
notifications.append([user.partner_id, 'calendar.alarm', notif])
|
||||
if len(notifications) > 0:
|
||||
self.env['bus.bus']._sendmany(notifications)
|
||||
user._bus_send("calendar.alarm", notif)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue