[ADD]: Added Upstream Patch for calendar.

This commit is contained in:
Kunjal 2018-07-06 17:19:55 +05:30
parent 804235226e
commit 7cf60bc315
2 changed files with 46 additions and 13 deletions

View File

@ -4,7 +4,7 @@ import base64
import babel.dates import babel.dates
import collections import collections
from datetime import datetime, timedelta from datetime import datetime, timedelta, MAXYEAR
from dateutil import parser from dateutil import parser
from dateutil import rrule from dateutil import rrule
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
@ -608,7 +608,8 @@ class Meeting(models.Model):
if not event_date: if not event_date:
event_date = datetime.now() event_date = datetime.now()
if self.allday and self.rrule and 'UNTIL' in self.rrule and 'Z' not in self.rrule: use_naive_datetime = self.allday and self.rrule and 'UNTIL' in self.rrule and 'Z' not in self.rrule
if use_naive_datetime:
rset1 = rrule.rrulestr(str(self.rrule), dtstart=event_date.replace(tzinfo=None), forceset=True, ignoretz=True) rset1 = rrule.rrulestr(str(self.rrule), dtstart=event_date.replace(tzinfo=None), forceset=True, ignoretz=True)
else: else:
# Convert the event date to saved timezone (or context tz) as it'll # Convert the event date to saved timezone (or context tz) as it'll
@ -617,9 +618,21 @@ class Meeting(models.Model):
rset1 = rrule.rrulestr(str(self.rrule), dtstart=event_date, forceset=True, tzinfos={}) rset1 = rrule.rrulestr(str(self.rrule), dtstart=event_date, forceset=True, tzinfos={})
recurring_meetings = self.search([('recurrent_id', '=', self.id), '|', ('active', '=', False), ('active', '=', True)]) recurring_meetings = self.search([('recurrent_id', '=', self.id), '|', ('active', '=', False), ('active', '=', True)])
for meeting in recurring_meetings: # We handle a maximum of 50,000 meetings at a time, and clear the cache at each step to
rset1._exdate.append(todate(meeting.recurrent_id_date)) # control the memory usage.
return [d.astimezone(pytz.UTC) if d.tzinfo else d for d in rset1] invalidate = False
for meetings in self.env.cr.split_for_in_conditions(recurring_meetings, size=50000):
if invalidate:
self.invalidate_cache()
for meeting in meetings:
recurring_date = fields.Datetime.from_string(meeting.recurrent_id_date)
if use_naive_datetime:
recurring_date = recurring_date.replace(tzinfo=None)
else:
recurring_date = todate(meeting.recurrent_id_date)
rset1.exdate(recurring_date)
invalidate = True
return [d.astimezone(pytz.UTC) if d.tzinfo else d for d in rset1 if d.year < MAXYEAR]
@api.multi @api.multi
def _get_recurrency_end_date(self): def _get_recurrency_end_date(self):
@ -642,7 +655,13 @@ class Meeting(models.Model):
}[data['rrule_type']] }[data['rrule_type']]
deadline = fields.Datetime.from_string(data['stop']) deadline = fields.Datetime.from_string(data['stop'])
return deadline + relativedelta(**{delay: count * mult}) computed_final_date = False
while not computed_final_date and count > 0:
try: # may crash if year > 9999 (in case of recurring events)
computed_final_date = deadline + relativedelta(**{delay: count * mult})
except ValueError:
count -= data['interval']
return computed_final_date or deadline
return final_date return final_date
@api.multi @api.multi
@ -883,8 +902,8 @@ class Meeting(models.Model):
startdate = startdate.astimezone(pytz.utc) # Convert to UTC startdate = startdate.astimezone(pytz.utc) # Convert to UTC
meeting.start = fields.Datetime.to_string(startdate) meeting.start = fields.Datetime.to_string(startdate)
else: else:
meeting.start = meeting.start_datetime meeting.write({'start': meeting.start_datetime,
meeting.stop = meeting.stop_datetime 'stop': meeting.stop_datetime})
@api.depends('byday', 'recurrency', 'final_date', 'rrule_type', 'month_by', 'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'day', 'week_list') @api.depends('byday', 'recurrency', 'final_date', 'rrule_type', 'month_by', 'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'day', 'week_list')
def _compute_rrule(self): def _compute_rrule(self):
@ -910,9 +929,13 @@ class Meeting(models.Model):
def _check_closing_date(self): def _check_closing_date(self):
for meeting in self: for meeting in self:
if meeting.start_datetime and meeting.stop_datetime and meeting.stop_datetime < meeting.start_datetime: if meeting.start_datetime and meeting.stop_datetime and meeting.stop_datetime < meeting.start_datetime:
raise ValidationError(_('Ending datetime cannot be set before starting datetime.')) raise ValidationError(_('Ending datetime cannot be set before starting datetime.') + "\n" +
_("Meeting '%s' starts '%s' and ends '%s'") % (meeting.name, meeting.start_datetime, meeting.stop_datetime)
)
if meeting.start_date and meeting.stop_date and meeting.stop_date < meeting.start_date: if meeting.start_date and meeting.stop_date and meeting.stop_date < meeting.start_date:
raise ValidationError(_('Ending date cannot be set before starting date.')) raise ValidationError(_('Ending date cannot be set before starting date.') + "\n" +
_("Meeting '%s' starts '%s' and ends '%s'") % (meeting.name, meeting.start_date, meeting.stop_date)
)
@api.onchange('start_datetime', 'duration') @api.onchange('start_datetime', 'duration')
def _onchange_duration(self): def _onchange_duration(self):
@ -1141,9 +1164,15 @@ class Meeting(models.Model):
for key in (order or self._order).split(',') for key in (order or self._order).split(',')
)) ))
def key(record): def key(record):
# we need to deal with undefined fields, as sorted requires an homogeneous iterable
def boolean_product(x):
x = False if (isinstance(x, models.Model) and not x) else x
if isinstance(x, bool):
return (x, x)
return (True, x)
# first extract the values for each key column (ids need special treatment) # first extract the values for each key column (ids need special treatment)
vals_spec = ( vals_spec = (
(any_id2key(record[name]) if name == 'id' else record[name], desc) (any_id2key(record[name]) if name == 'id' else boolean_product(record[name]), desc)
for name, desc in sort_spec for name, desc in sort_spec
) )
# then Reverse if the value matches a "desc" column # then Reverse if the value matches a "desc" column
@ -1218,7 +1247,12 @@ class Meeting(models.Model):
def _rrule_parse(self, rule_str, data, date_start): def _rrule_parse(self, rule_str, data, date_start):
day_list = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su'] day_list = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
rrule_type = ['yearly', 'monthly', 'weekly', 'daily'] rrule_type = ['yearly', 'monthly', 'weekly', 'daily']
rule = rrule.rrulestr(rule_str, dtstart=fields.Datetime.from_string(date_start)) ddate = fields.Datetime.from_string(date_start)
if 'Z' in rule_str and not ddate.tzinfo:
ddate = ddate.replace(tzinfo=pytz.timezone('UTC'))
rule = rrule.rrulestr(rule_str, dtstart=ddate)
else:
rule = rrule.rrulestr(rule_str, dtstart=ddate)
if rule._freq > 0 and rule._freq < 4: if rule._freq > 0 and rule._freq < 4:
data['rrule_type'] = rrule_type[rule._freq] data['rrule_type'] = rrule_type[rule._freq]

View File

@ -194,7 +194,6 @@
<group> <group>
<field name="privacy"/> <field name="privacy"/>
<field name="show_as"/> <field name="show_as"/>
<field name="rrule" invisible="1" readonly="0" />
<field name="recurrent_id" invisible="1" /> <field name="recurrent_id" invisible="1" />
</group> </group>
</group> </group>