From 8fa171aa0d8de89b01cb6a9f030bae99d29c2d68 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 17 Jul 2013 16:23:25 +0200 Subject: [PATCH 1/3] [FIX] crm_meeting: fix domain evaluation for calendar recursive. (see openerp-web/7.0/revision/3989). Todo: fix recursive when the begin date it's before the domain search date bzr revid: chm@openerp.com-20130717142325-8lo9el6gk9kgos3d --- addons/base_calendar/base_calendar.py | 50 ++++++++++++++++++++------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index e6b01e45cdf..4fef3720e57 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -1217,20 +1217,44 @@ rule or repeating pattern of time to exclude from the recurring rule."), new_rrule_str = ';'.join(new_rrule_str) rdates = get_recurrent_dates(str(new_rrule_str), exdate, event_date, data['exrule']) for r_date in rdates: - ok = True + # fix domain evaluation + # step 1: check date and replace expression by True or False, replace other expressions by True + # step 2: evaluation of & and | + # check if there are one False + pile = [] for arg in domain: - if arg[0] in ('date', 'date_deadline'): - if (arg[1]=='='): - ok = ok and r_date.strftime('%Y-%m-%d')==arg[2] - if (arg[1]=='>'): - ok = ok and r_date.strftime('%Y-%m-%d')>arg[2] - if (arg[1]=='<'): - ok = ok and r_date.strftime('%Y-%m-%d')='): - ok = ok and r_date.strftime('%Y-%m-%d')>=arg[2] - if (arg[1]=='<='): - ok = ok and r_date.strftime('%Y-%m-%d')<=arg[2] - if not ok: + if str(arg[0]) in (str('date'), str('date_deadline')): + if (arg[1] == '='): + ok = r_date.strftime('%Y-%m-%d')==arg[2] + if (arg[1] == '>'): + ok = r_date.strftime('%Y-%m-%d')>arg[2] + if (arg[1] == '<'): + ok = r_date.strftime('%Y-%m-%d')='): + ok = r_date.strftime('%Y-%m-%d')>=arg[2] + if (arg[1] == '<='): + ok = r_date.strftime('%Y-%m-%d')<=arg[2] + pile.append(ok) + elif str(arg) == str('&') or str(arg) == str('|'): + pile.append(arg) + else: + pile.append(True) + pile.reverse() + new_pile = [] + for item in pile: + if not isinstance(item, basestring): + res = item + elif str(item) == str('&'): + first = new_pile.pop() + second = new_pile.pop() + res = first and second + elif str(item) == str('|'): + first = new_pile.pop() + second = new_pile.pop() + res = first or second + new_pile.append(res) + + if [True for item in new_pile if not item]: continue idval = real_id2base_calendar_id(data['id'], r_date.strftime("%Y-%m-%d %H:%M:%S")) result.append(idval) From bad1a58eba0bd0673d7079ce5223a9eeaa4eac45 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 20 Aug 2013 14:32:24 +0200 Subject: [PATCH 2/3] [FIX] base_calendar: change write, create and search method display recurrency date, and recurrency date with number of repetitions bzr revid: chm@openerp.com-20130820123224-33bwr2gt9tp7x9qg --- addons/base_calendar/base_calendar.py | 34 +++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index 4fef3720e57..b8768e59c3a 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -1379,18 +1379,17 @@ rule or repeating pattern of time to exclude from the recurring rule."), for arg in args: new_arg = arg - if arg[0] in ('date', unicode('date'), 'date_deadline', unicode('date_deadline')): + if arg[0] in ('date_deadline', unicode('date_deadline')): if context.get('virtual_id', True): - new_args += ['|','&',('recurrency','=',1),('recurrent_id_date', arg[1], arg[2])] + new_args += ['|','&',('recurrency','=',1),('end_date', arg[1], arg[2])] elif arg[0] == "id": new_id = get_real_ids(arg[2]) new_arg = (arg[0], arg[1], new_id) new_args.append(new_arg) - #offset, limit and count must be treated separately as we may need to deal with virtual ids res = super(calendar_event, self).search(cr, uid, new_args, offset=0, limit=0, order=order, context=context, count=False) if context.get('virtual_id', True): - res = self.get_recurrent_ids(cr, uid, res, new_args, limit, context=context) + res = self.get_recurrent_ids(cr, uid, res, args, limit, context=context) if count: return len(res) elif limit: @@ -1469,6 +1468,14 @@ rule or repeating pattern of time to exclude from the recurring rule."), vals['vtimezone'] = vals['vtimezone'][40:] res = super(calendar_event, self).write(cr, uid, ids, vals, context=context) + + # set end_date for calendar searching + if vals.get('recurrency', True) and vals.get('end_type', 'count') in ('count', unicode('count')) and \ + (vals.get('rrule_type') or vals.get('count') or vals.get('date') or vals.get('date_deadline')): + for data in self.read(cr, uid, ids, ['date', 'date_deadline', 'recurrency', 'rrule_type', 'count', 'end_type'], context=context): + end_date = self._set_recurrency_end_date(data, context=context) + super(calendar_event, self).write(cr, uid, [data['id']], {'end_date': end_date}, context=context) + if vals.get('partner_ids', False): self.create_attendees(cr, uid, ids, context) @@ -1587,6 +1594,23 @@ rule or repeating pattern of time to exclude from the recurring rule."), self.unlink_events(cr, uid, ids, context=context) return res + def _set_recurrency_end_date(self, data, context=None): + end_date = data.get('end_date') + if data.get('recurrency') and data.get('end_type') in ('count', unicode('count')): + data_date_deadline = datetime.strptime(data.get('date_deadline'), '%Y-%m-%d %H:%M:%S') + if data.get('rrule_type') in ('daily', unicode('count')): + rel_date = relativedelta(day=data.get('count')) + elif data.get('rrule_type') in ('weekly', unicode('weekly')): + rel_date = relativedelta(days=data.get('count')*7) + elif data.get('rrule_type') in ('monthly', unicode('monthly')): + rel_date = relativedelta(month=data.get('count')) + elif data.get('rrule_type') in ('yearly', unicode('yearly')): + rel_date = relativedelta(year=data.get('count')) + end_date = data_date_deadline + rel_date + # have all virtual date, weekly condition, monthly condition + end_date += relativedelta(month=1) + return end_date + def create(self, cr, uid, vals, context=None): if context is None: context = {} @@ -1594,7 +1618,9 @@ rule or repeating pattern of time to exclude from the recurring rule."), if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'): vals['vtimezone'] = vals['vtimezone'][40:] + vals['end_date'] = self._set_recurrency_end_date(vals, context=context) res = super(calendar_event, self).create(cr, uid, vals, context) + alarm_obj = self.pool.get('res.alarm') alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context) self.create_attendees(cr, uid, [res], context) From 1f7f826a90b8fabcd09bfdc0ff0233719daf5a6a Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 10 Sep 2013 11:25:01 +0200 Subject: [PATCH 3/3] [FIX] base_calendar: add s after day, month, year into relativedelta bzr revid: chm@openerp.com-20130910092501-gl9pmd3vk26q32tv --- addons/base_calendar/base_calendar.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index b8768e59c3a..c5a16931323 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -1599,16 +1599,14 @@ rule or repeating pattern of time to exclude from the recurring rule."), if data.get('recurrency') and data.get('end_type') in ('count', unicode('count')): data_date_deadline = datetime.strptime(data.get('date_deadline'), '%Y-%m-%d %H:%M:%S') if data.get('rrule_type') in ('daily', unicode('count')): - rel_date = relativedelta(day=data.get('count')) + rel_date = relativedelta(days=data.get('count')+1) elif data.get('rrule_type') in ('weekly', unicode('weekly')): - rel_date = relativedelta(days=data.get('count')*7) + rel_date = relativedelta(days=(data.get('count')+1)*7) elif data.get('rrule_type') in ('monthly', unicode('monthly')): - rel_date = relativedelta(month=data.get('count')) + rel_date = relativedelta(months=data.get('count')+1) elif data.get('rrule_type') in ('yearly', unicode('yearly')): - rel_date = relativedelta(year=data.get('count')) + rel_date = relativedelta(years=data.get('count')+1) end_date = data_date_deadline + rel_date - # have all virtual date, weekly condition, monthly condition - end_date += relativedelta(month=1) return end_date def create(self, cr, uid, vals, context=None):