From 37a3ef575ebafbca919076421f5abe8160698dbc Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Wed, 12 Dec 2012 15:31:38 +0100 Subject: [PATCH 1/6] [FIX] base_calendar: virtual ids and misc fixes bzr revid: qdp-launchpad@openerp.com-20121212143138-r400ibtajigk0lns --- addons/base_calendar/base_calendar.py | 48 +++++++------------ .../security/ir.model.access.csv | 2 + 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index 9cf07a4b73e..28264bea759 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -30,6 +30,7 @@ import pytz import re import time import tools +from openerp import SUPERUSER_ID months = { 1: "January", 2: "February", 3: "March", 4: "April", \ @@ -1001,12 +1002,15 @@ class calendar_event(osv.osv): if not isinstance(ids, list): ids = [ids] - for data in self.read(cr, uid, ids, ['id','byday','recurrency', 'month_list','end_date', 'rrule_type', 'select1', 'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'exrule', 'day', 'week_list' ], context=context): - event = data['id'] + for id in ids: + #read these fields as SUPERUSER because if the record is private a normal search could return False and raise an error + data = self.read(cr, SUPERUSER_ID, id, ['interval', 'count'], context=context) if data.get('interval', 0) < 0: raise osv.except_osv(_('Warning!'), _('Interval cannot be negative.')) if data.get('count', 0) <= 0: raise osv.except_osv(_('Warning!'), _('Count cannot be negative or 0.')) + data = self.read(cr, uid, id, ['id','byday','recurrency', 'month_list','end_date', 'rrule_type', 'select1', 'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'exrule', 'day', 'week_list' ], context=context) + event = data['id'] if data['recurrency']: result[event] = self.compute_rule_string(data) else: @@ -1339,40 +1343,24 @@ rule or repeating pattern of time to exclude from the recurring rule."), return data def search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False): - context = context or {} - args_without_date = [] - filter_date = [] + if context is None: + context = {} + new_args = [] for arg in args: - if arg[0] == "id": - new_id = self.remove_virtual_id(arg[2]) + new_arg = arg + if arg[0] in ('date', unicode('date'), 'date_deadline', unicode('date_deadline')): + if context.get('virtual_id', True): + new_args += ['|','&',('recurrency','=',1),('recurrent_id_date', arg[1], arg[2])] + elif arg[0] == "id": + new_id = get_real_ids(arg[2]) new_arg = (arg[0], arg[1], new_id) - args_without_date.append(new_arg) - elif arg[0] not in ('date', unicode('date'), 'date_deadline', unicode('date_deadline')): - args_without_date.append(arg) - else: - if context.get('virtual_id', True): - args_without_date.append('|') - args_without_date.append(arg) - if context.get('virtual_id', True): - args_without_date.append(('recurrency','=',1)) - filter_date.append(arg) + new_args.append(new_arg) - res = super(calendar_event, self).search(cr, uid, args_without_date, \ - 0, 0, order, context, count=False) - if context.get('virtual_id', True): - res = self.get_recurrent_ids(cr, uid, res, args, limit, context=context) - - if count: - return len(res) - elif limit: - return res[offset:offset+limit] - else: - return res + return super(calendar_event, self).search(cr, uid, new_args, offset=offset, limit=limit, order=order, context=context, count=count) def _get_data(self, cr, uid, id, context=None): - res = self.read(cr, uid, [id],['date', 'date_deadline']) - return res[0] + return self.read(cr, uid, id,['date', 'date_deadline']) def need_to_update(self, event_id, vals): split_id = str(event_id).split("-") diff --git a/addons/base_calendar/security/ir.model.access.csv b/addons/base_calendar/security/ir.model.access.csv index 54ab0590aca..7db870d9053 100644 --- a/addons/base_calendar/security/ir.model.access.csv +++ b/addons/base_calendar/security/ir.model.access.csv @@ -10,4 +10,6 @@ access_crm_meeting,crm.meeting,model_crm_meeting,base.group_sale_salesman,1,1,1, access_crm_meeting_all,crm.meeting_allll,model_crm_meeting,base.group_user,1,0,0,0 access_crm_meeting_partner_manager,crm.meeting.partner.manager,model_crm_meeting,base.group_partner_manager,1,1,1,1 access_crm_meeting_type_sale_manager,crm.meeting.type.manager,model_crm_meeting_type,base.group_sale_manager,1,1,1,0 +access_crm_meeting_type_sale_user,crm.meeting.type.user,model_crm_meeting_type,base.group_user,1,0,0,0 +access_crm_meeting_type_sale_user,crm.meeting.type.salesman,model_crm_meeting_type,base.group_sale_salesman,1,0,0,0 access_crm_meeting_type_manager,crm.meeting.type.manager,model_crm_meeting_type,base.group_system,1,1,1,1 From 92750eadc01c7c458c16a79e49e1f5d2985a9f54 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Wed, 12 Dec 2012 15:31:38 +0100 Subject: [PATCH 2/6] [FIX] base_calendar: virtual ids and misc fixes bzr revid: qdp-launchpad@openerp.com-20121212143138-bugp0y3aib9ip6y6 --- addons/base_calendar/base_calendar.py | 48 +++++++------------ .../security/ir.model.access.csv | 2 + 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index 9cf07a4b73e..28264bea759 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -30,6 +30,7 @@ import pytz import re import time import tools +from openerp import SUPERUSER_ID months = { 1: "January", 2: "February", 3: "March", 4: "April", \ @@ -1001,12 +1002,15 @@ class calendar_event(osv.osv): if not isinstance(ids, list): ids = [ids] - for data in self.read(cr, uid, ids, ['id','byday','recurrency', 'month_list','end_date', 'rrule_type', 'select1', 'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'exrule', 'day', 'week_list' ], context=context): - event = data['id'] + for id in ids: + #read these fields as SUPERUSER because if the record is private a normal search could return False and raise an error + data = self.read(cr, SUPERUSER_ID, id, ['interval', 'count'], context=context) if data.get('interval', 0) < 0: raise osv.except_osv(_('Warning!'), _('Interval cannot be negative.')) if data.get('count', 0) <= 0: raise osv.except_osv(_('Warning!'), _('Count cannot be negative or 0.')) + data = self.read(cr, uid, id, ['id','byday','recurrency', 'month_list','end_date', 'rrule_type', 'select1', 'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'exrule', 'day', 'week_list' ], context=context) + event = data['id'] if data['recurrency']: result[event] = self.compute_rule_string(data) else: @@ -1339,40 +1343,24 @@ rule or repeating pattern of time to exclude from the recurring rule."), return data def search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False): - context = context or {} - args_without_date = [] - filter_date = [] + if context is None: + context = {} + new_args = [] for arg in args: - if arg[0] == "id": - new_id = self.remove_virtual_id(arg[2]) + new_arg = arg + if arg[0] in ('date', unicode('date'), 'date_deadline', unicode('date_deadline')): + if context.get('virtual_id', True): + new_args += ['|','&',('recurrency','=',1),('recurrent_id_date', arg[1], arg[2])] + elif arg[0] == "id": + new_id = get_real_ids(arg[2]) new_arg = (arg[0], arg[1], new_id) - args_without_date.append(new_arg) - elif arg[0] not in ('date', unicode('date'), 'date_deadline', unicode('date_deadline')): - args_without_date.append(arg) - else: - if context.get('virtual_id', True): - args_without_date.append('|') - args_without_date.append(arg) - if context.get('virtual_id', True): - args_without_date.append(('recurrency','=',1)) - filter_date.append(arg) + new_args.append(new_arg) - res = super(calendar_event, self).search(cr, uid, args_without_date, \ - 0, 0, order, context, count=False) - if context.get('virtual_id', True): - res = self.get_recurrent_ids(cr, uid, res, args, limit, context=context) - - if count: - return len(res) - elif limit: - return res[offset:offset+limit] - else: - return res + return super(calendar_event, self).search(cr, uid, new_args, offset=offset, limit=limit, order=order, context=context, count=count) def _get_data(self, cr, uid, id, context=None): - res = self.read(cr, uid, [id],['date', 'date_deadline']) - return res[0] + return self.read(cr, uid, id,['date', 'date_deadline']) def need_to_update(self, event_id, vals): split_id = str(event_id).split("-") diff --git a/addons/base_calendar/security/ir.model.access.csv b/addons/base_calendar/security/ir.model.access.csv index 54ab0590aca..7db870d9053 100644 --- a/addons/base_calendar/security/ir.model.access.csv +++ b/addons/base_calendar/security/ir.model.access.csv @@ -10,4 +10,6 @@ access_crm_meeting,crm.meeting,model_crm_meeting,base.group_sale_salesman,1,1,1, access_crm_meeting_all,crm.meeting_allll,model_crm_meeting,base.group_user,1,0,0,0 access_crm_meeting_partner_manager,crm.meeting.partner.manager,model_crm_meeting,base.group_partner_manager,1,1,1,1 access_crm_meeting_type_sale_manager,crm.meeting.type.manager,model_crm_meeting_type,base.group_sale_manager,1,1,1,0 +access_crm_meeting_type_sale_user,crm.meeting.type.user,model_crm_meeting_type,base.group_user,1,0,0,0 +access_crm_meeting_type_sale_user,crm.meeting.type.salesman,model_crm_meeting_type,base.group_sale_salesman,1,0,0,0 access_crm_meeting_type_manager,crm.meeting.type.manager,model_crm_meeting_type,base.group_system,1,1,1,1 From cf863ebd182e84ef0c41093c488e935e6d02c813 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Wed, 12 Dec 2012 18:42:15 +0100 Subject: [PATCH 3/6] [IMP] base_calendar: improved yaml test to help debug bzr revid: qdp-launchpad@openerp.com-20121212174215-kclquypqib680zju --- addons/base_calendar/test/base_calendar_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/base_calendar/test/base_calendar_test.yml b/addons/base_calendar/test/base_calendar_test.yml index c84f3ce36c3..7afd2e49551 100644 --- a/addons/base_calendar/test/base_calendar_test.yml +++ b/addons/base_calendar/test/base_calendar_test.yml @@ -26,7 +26,7 @@ - !python {model: calendar.event}: | ids = self.search(cr, uid, [('date', '>=', '2011-04-30 16:00:00'), ('date', '<=', '2011-05-31 00:00:00')], context={'virtual_id': True} ) - assert len(ids) == 9 + assert len(ids) == 9, 'Wrong number of events found' - Now I will make All day event and test it - From 85c90838a860cdf4eab329a85688ee1eef5736e3 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Wed, 12 Dec 2012 18:43:23 +0100 Subject: [PATCH 4/6] [REF] mail: splitted the search() function in smaller part in order to ease the inheritance (because some code needs to be overriden for virtual ids, for example) bzr revid: qdp-launchpad@openerp.com-20121212174323-3kw9vrzacfm3wvm7 --- addons/mail/mail_message.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 069e0118ec4..d0a73385f7f 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -550,6 +550,20 @@ class mail_message(osv.Model): if not cr.fetchone(): cr.execute("""CREATE INDEX mail_message_model_res_id_idx ON mail_message (model, res_id)""") + def _find_allowed_model_wise(self, cr, uid, doc_model, doc_dict, context=None): + doc_ids = doc_dict.keys() + allowed_doc_ids = self.pool.get(doc_model).search(cr, uid, [('id', 'in', doc_ids)], context=context) + return set([message_id for allowed_doc_id in allowed_doc_ids for message_id in doc_dict[allowed_doc_id]]) + + def _find_allowed_doc_ids(self, cr, uid, model_ids, context=None): + model_access_obj = self.pool.get('ir.model.access') + allowed_ids = set() + for doc_model, doc_dict in model_ids.iteritems(): + if not model_access_obj.check(cr, uid, doc_model, 'read', False): + continue + allowed_ids |= self._find_allowed_model_wise(cr, uid, doc_model, doc_dict, context=context) + return allowed_ids + def _search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None): """ Override that adds specific access rights of mail.message, to remove @@ -587,13 +601,7 @@ class mail_message(osv.Model): elif message.get('model') and message.get('res_id'): model_ids.setdefault(message.get('model'), {}).setdefault(message.get('res_id'), set()).add(message.get('id')) - model_access_obj = self.pool.get('ir.model.access') - for doc_model, doc_dict in model_ids.iteritems(): - if not model_access_obj.check(cr, uid, doc_model, 'read', False): - continue - doc_ids = doc_dict.keys() - allowed_doc_ids = self.pool.get(doc_model).search(cr, uid, [('id', 'in', doc_ids)], context=context) - allowed_ids |= set([message_id for allowed_doc_id in allowed_doc_ids for message_id in doc_dict[allowed_doc_id]]) + allowed_ids = self._find_allowed_doc_ids(cr, uid, model_ids, context=context) final_ids = author_ids | partner_ids | allowed_ids if count: From 7ef99890d82d3a51859b01867483b95c0f1721f1 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Wed, 12 Dec 2012 18:44:15 +0100 Subject: [PATCH 5/6] [REV] base_calendar: reverted to a previous code because it broke one test bzr revid: qdp-launchpad@openerp.com-20121212174415-pllm4f5g7k6uyn3o --- addons/base_calendar/base_calendar.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index 28264bea759..69baf57c1a9 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -1357,7 +1357,15 @@ rule or repeating pattern of time to exclude from the recurring rule."), new_arg = (arg[0], arg[1], new_id) new_args.append(new_arg) - return super(calendar_event, self).search(cr, uid, new_args, offset=offset, limit=limit, order=order, context=context, count=count) + #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) + if count: + return len(res) + elif limit: + return res[offset:offset+limit] + return res def _get_data(self, cr, uid, id, context=None): return self.read(cr, uid, id,['date', 'date_deadline']) From 7b206d300458dd6c1b77f75e4af89e8ae593fb63 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Wed, 12 Dec 2012 18:45:02 +0100 Subject: [PATCH 6/6] [FIX] base_calendar: opening a virtual event with the non-admin user was crashing bzr revid: qdp-launchpad@openerp.com-20121212174502-qj74lmso3a2yjpbx --- addons/base_calendar/crm_meeting.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addons/base_calendar/crm_meeting.py b/addons/base_calendar/crm_meeting.py index 4745d6c5896..e9fe70f19ff 100644 --- a/addons/base_calendar/crm_meeting.py +++ b/addons/base_calendar/crm_meeting.py @@ -142,6 +142,12 @@ class mail_message(osv.osv): args[index][2] = get_real_ids(args[index][2]) return super(mail_message, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count) + def _find_allowed_model_wise(self, cr, uid, doc_model, doc_dict, context=None): + if doc_model == 'crm.meeting': + for virtual_id in self.pool.get(doc_model).get_recurrent_ids(cr, uid, doc_dict.keys(), [], context=context): + doc_dict.setdefault(virtual_id, doc_dict[get_real_ids(virtual_id)]) + return super(mail_message, self)._find_allowed_model_wise(cr, uid, doc_model, doc_dict, context=context) + class ir_attachment(osv.osv): _inherit = "ir.attachment"