[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 collections
from datetime import datetime, timedelta
from datetime import datetime, timedelta, MAXYEAR
from dateutil import parser
from dateutil import rrule
from dateutil.relativedelta import relativedelta
@ -608,7 +608,8 @@ class Meeting(models.Model):
if not event_date:
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)
else:
# 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={})
recurring_meetings = self.search([('recurrent_id', '=', self.id), '|', ('active', '=', False), ('active', '=', True)])
for meeting in recurring_meetings:
rset1._exdate.append(todate(meeting.recurrent_id_date))
return [d.astimezone(pytz.UTC) if d.tzinfo else d for d in rset1]
# We handle a maximum of 50,000 meetings at a time, and clear the cache at each step to
# control the memory usage.
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
def _get_recurrency_end_date(self):
@ -642,7 +655,13 @@ class Meeting(models.Model):
}[data['rrule_type']]
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
@api.multi
@ -883,8 +902,8 @@ class Meeting(models.Model):
startdate = startdate.astimezone(pytz.utc) # Convert to UTC
meeting.start = fields.Datetime.to_string(startdate)
else:
meeting.start = meeting.start_datetime
meeting.stop = meeting.stop_datetime
meeting.write({'start': meeting.start_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')
def _compute_rrule(self):
@ -910,9 +929,13 @@ class Meeting(models.Model):
def _check_closing_date(self):
for meeting in self:
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:
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')
def _onchange_duration(self):
@ -1141,9 +1164,15 @@ class Meeting(models.Model):
for key in (order or self._order).split(',')
))
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)
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
)
# 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):
day_list = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
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:
data['rrule_type'] = rrule_type[rule._freq]

View File

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