Arnaud Pineux (OpenERP) has proposed merging lp:~openerp-dev/openobject-addons/7.0-base_calendar-api into lp:openobject-addons/7.0.
Requested reviews: qdp (OpenERP) (qdp) For more details, see: https://code.launchpad.net/~openerp-dev/openobject-addons/7.0-base_calendar-api/+merge/142456 This branch repairs few things: - The recurrent meetings are well shown on the calendar view. - By default, when someone create a meeting, he is added to the attendee list. - New constraint: To create a meeting or save information, the meeting needs at least one attendee (partner). - When a meeting is created: - A copy of this meeting are created and the user_id of those meetings are the attendees that have a user. - Each meeting share the same calendar_attendee. - An invitation email is sent to every attendee. - When we remove an attendee from a meeting: - The attendee is removed from every meeting but also the copy of meeting that belongs to this attendee will be deleted. - When we add an attendee to a meeting: - Each copy of that meeting are updated with the new attendee. - A new copy of meeting is created if the attendee has a user. - An invitation email is sent to the "new" attendee. - Changes made on a meeting are also made on every copy of that meeting. - Demo and test for meeting have been updated to correspond to the new constraint. - hr_holiday has also been updated as it inherit from meeting. -- https://code.launchpad.net/~openerp-dev/openobject-addons/7.0-base_calendar-api/+merge/142456 Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-addons/7.0-base_calendar-api.
=== modified file 'base_calendar/base_calendar.py' --- base_calendar/base_calendar.py 2012-12-28 11:18:53 +0000 +++ base_calendar/base_calendar.py 2013-01-09 08:54:22 +0000 @@ -23,7 +23,7 @@ from dateutil import parser from dateutil import rrule from dateutil.relativedelta import relativedelta -from openerp.osv import fields, osv +from openerp.osv import fields, osv, orm from openerp.service import web_services from openerp.tools.translate import _ import pytz @@ -1364,7 +1364,7 @@ #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, super(calendar_event, self).search(cr, uid, [('recurrency','=',1)], offset=0, limit=0, order=order, context=context, count=False), new_args, limit, context=context) if count: return len(res) elif limit: @@ -1442,14 +1442,59 @@ if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'): vals['vtimezone'] = vals['vtimezone'][40:] - res = super(calendar_event, self).write(cr, uid, ids, vals, context=context) - if vals.get('partner_ids', False): - self.create_attendees(cr, uid, ids, context) - if ('alarm_id' in vals or 'base_calendar_alarm_id' in vals)\ or ('date' in vals or 'duration' in vals or 'date_deadline' in vals): alarm_obj = self.pool.get('res.alarm') alarm_obj.do_alarm_create(cr, uid, ids, self._name, 'date', context=context) + + if 'partner_ids' in vals and vals['partner_ids']: + #If partner_ids belongs to vals, it means that we added or removed at least one "partner" from the event + linked_event_ids = [] + for event in self.browse(cr, uid, ids, context=context): + #Get every event linked to the current event. (Every copy of that event) + linked_event_ids = [base_calendar_id2real_id(id) for id in self.search(cr, uid, [('attendee_ids', 'like', [attendee.id for attendee in event['attendee_ids']])], context=context)] + #We collect the list of partners from the Event and from the vals to look if we remove a partner or add one to the event. + partners_event = set([attendee.partner_id.id for attendee in event['attendee_ids']]) + partners_vals = set(vals['partner_ids'][0][2]) + #We collect a dictionnary of partner.id : attendee for later + partner_to_attendee = {attendee.partner_id.id : attendee for attendee in event['attendee_ids']} + #We change the partners on every linked_event + res = super(calendar_event, self).write(cr, uid, linked_event_ids, vals, context=context) + #if we add a new partner, it means that partners_vals contains more elements than partners_event + if partners_vals - partners_event: + #We create the new attendee(s) + self.create_attendees(cr, uid, [event.id], context=context) + #We create a new meeting with the new attendee as user_id if he is a user + for id in partners_vals - partners_event: + for user_id in self.pool.get("res.partner").browse(cr, uid, id, context=context)['user_ids']: + new = self.copy(cr, uid, event.id, context={'copy':True}) + super(calendar_event, self).write(cr, uid, new, {'user_id': user_id.id, 'organizer_id': user_id.id}, context=context) + linked_event_ids.append(new) + #We add the new attendees to linked_events + attendee_ids = self.browse(cr, uid, event.id, context=context)['attendee_ids'] + for linked_event in self.browse(cr, uid, list(set(linked_event_ids)-set([event.id])), context=context): + for attendee in attendee_ids: + if not attendee.id in linked_event['attendee_ids']: + linked_event.write({'attendee_ids': [(4, attendee.id)]}, context=context) + #if we remove a partner, it means that partners_event contains more elements than partners_vals + if partners_event - partners_vals: + partner_ids_to_remove = partners_event - partners_vals + for partner_to_remove in partner_ids_to_remove: + #We get the attendee to remove + attendee_to_remove = partner_to_attendee[partner_to_remove] + #We remove the meeting where the attendee to remove is the responsible so the user_id + for linked_event in self.browse(cr, uid, linked_event_ids, context=context): + if linked_event['user_id'] in attendee_to_remove.partner_id.user_ids: + super(calendar_event, self).write(cr, uid, [linked_event.id], {'active':False}, context=context) + linked_event_ids = list(set(linked_event_ids) - set([linked_event.id])) + #We finaly remove the attendee + attendee_to_remove.unlink(context=context) + return linked_event_ids or True + else: + res = super(calendar_event, self).write(cr, uid, ids, vals, context=context) + for event in self.browse(cr, uid, ids, context=context): + linked_event_ids = [base_calendar_id2real_id(id) for id in self.search(cr, uid, [('attendee_ids', 'like', [attendee.id for attendee in event['attendee_ids']])], context=context)] + super(calendar_event, self).write(cr, uid, linked_event_ids, vals, context=context) return res or True and False def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False): @@ -1530,6 +1575,9 @@ if context is None: context = {} + if 'copy' in context and context['copy']: + return super(calendar_event, self).copy(cr, uid, base_calendar_id2real_id(id), default=default, context=context) + res = super(calendar_event, self).copy(cr, uid, base_calendar_id2real_id(id), default, context) alarm_obj = self.pool.get('res.alarm') alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context) @@ -1565,14 +1613,42 @@ if context is None: context = {} + if 'copy' in context and context['copy']: + return super(calendar_event, self).create(cr, uid, vals, context) + if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'): vals['vtimezone'] = vals['vtimezone'][40:] - 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) - return res + if 'partner_ids' in vals and vals['partner_ids']: + meeting_copy_number = 0 + result = -1 + partner_pool = self.pool.get('res.partner') + alarm_pool = self.pool.get('res.alarm') + for elmt in vals['partner_ids']: + for partner_id in elmt[2]: + partner = partner_pool.browse(cr, uid, partner_id, context=context) + if 'user_ids' in partner and partner['user_ids']: + for user in partner['user_ids']: + vals['user_id'] = user.id + vals['organizer_id'] = user.id + if meeting_copy_number == 0: + result = super(calendar_event, self).create(cr, uid, vals, context) + alarm_pool.do_alarm_create(cr, uid, [result], self._name, 'date', context=context) + self.create_attendees(cr, uid, [result], context) + meeting_copy_number += 1 + else: + attendee_ids = self.browse(cr, uid, result, context=context)['attendee_ids'] + result = super(calendar_event, self).create(cr, uid, vals, context) + for attendee in attendee_ids: + self.write(cr, uid, [result], {'attendee_ids': [(4, attendee.id)]}, context=context) + if meeting_copy_number == 0: + raise orm.except_orm(_('Error!'), + _('You must select at least one user as attendee')) + else: + return result + else: + raise orm.except_orm(_('Error!'), + _('You must select at least one Attendee')) def do_tentative(self, cr, uid, ids, context=None, *args): """ Makes event invitation as Tentative === modified file 'base_calendar/crm_meeting.py' --- base_calendar/crm_meeting.py 2012-12-20 12:49:27 +0000 +++ base_calendar/crm_meeting.py 2013-01-09 08:54:22 +0000 @@ -64,6 +64,7 @@ } _defaults = { 'state': 'open', + 'partner_ids' : lambda self,cr,uid,c: [self.pool.get('res.users').browse(cr, uid, uid, c).partner_id.id], } def message_get_subscription_data(self, cr, uid, ids, context=None): === modified file 'base_calendar/crm_meeting_demo.xml' --- base_calendar/crm_meeting_demo.xml 2012-11-29 22:26:45 +0000 +++ base_calendar/crm_meeting_demo.xml 2013-01-09 08:54:22 +0000 @@ -15,6 +15,7 @@ <field name="categ_ids" eval="[(6,0,[ref('categ_meet1')])]"/> <field eval="time.strftime('%Y-%m-03 16:30:00')" name="date_deadline"/> <field eval="6.3" name="duration"/> + <field name="partner_ids" eval="[(6,0,[ref('base.partner_root')])]"/> <field name="state">open</field> </record> @@ -27,6 +28,7 @@ <field eval="time.strftime('%Y-%m-05 12:00:00')" name="date"/> <field eval="time.strftime('%Y-%m-05 19:00:00')" name="date_deadline"/> <field eval="7.0" name="duration"/> + <field name="partner_ids" eval="[(6,0,[ref('base.partner_root')])]"/> <field name="state">open</field> </record> @@ -39,6 +41,7 @@ <field eval="time.strftime('%Y-%m-12 15:55:05')" name="date"/> <field eval="time.strftime('%Y-%m-12 18:55:05')" name="date_deadline"/> <field eval="3.0" name="duration"/> + <field name="partner_ids" eval="[(6,0,[ref('base.partner_root')])]"/> <field name="state">open</field> </record> @@ -50,6 +53,7 @@ <field eval="time.strftime('%Y-%m-20 8:00:00')" name="date"/> <field eval="time.strftime('%Y-%m-20 10:30:00')" name="date_deadline"/> <field eval="2.5" name="duration"/> + <field name="partner_ids" eval="[(6,0,[ref('base.partner_demo')])]"/> <field name="state">open</field> </record> @@ -60,6 +64,7 @@ <field name="categ_ids" eval="[(6,0,[ref('categ_meet1')])]"/> <field eval="time.strftime('%Y-%m-22 11:05:00')" name="date"/> <field eval="time.strftime('%Y-%m-22 16:05:00')" name="date_deadline"/> + <field name="partner_ids" eval="[(6,0,[ref('base.partner_demo')])]"/> <field eval="5" name="duration"/> <field name="state">open</field> </record> @@ -72,6 +77,7 @@ <field eval="time.strftime('%Y-%m-18 2:00:00')" name="date"/> <field eval="time.strftime('%Y-%m-18 10:30:00')" name="date_deadline"/> <field eval="8.5" name="duration"/> + <field name="partner_ids" eval="[(6,0,[ref('base.partner_root')])]"/> <field name="state">open</field> </record> </data> === modified file 'base_calendar/test/base_calendar_test.yml' --- base_calendar/test/base_calendar_test.yml 2012-12-12 17:42:15 +0000 +++ base_calendar/test/base_calendar_test.yml 2013-01-09 08:54:22 +0000 @@ -10,6 +10,7 @@ duration: 2.5 location: OpenERP S.A. name: Technical Presentation + partner_ids: [base.partner_root] - Now I will set recurrence for this event to occur monday and friday of week - @@ -26,7 +27,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, 'Wrong number of events found' + assert len(ids) == 10, 'Wrong number of events found' - Now I will make All day event and test it - @@ -38,6 +39,7 @@ description: 'All day technical test ' location: School name: All day test event + partner_ids: [base.partner_root] - In order to check reminder I will first create reminder - === modified file 'hr_holidays/hr_holidays.py' --- hr_holidays/hr_holidays.py 2013-01-04 14:50:30 +0000 +++ hr_holidays/hr_holidays.py 2013-01-09 08:54:22 +0000 @@ -345,6 +345,7 @@ 'duration': record.number_of_days_temp * 8, 'description': record.notes, 'user_id': record.user_id.id, + 'partner_ids' : [(6,0,[self.pool.get('res.users').browse(cr, uid, record.user_id.id, context=context).partner_id.id])], 'date': record.date_from, 'end_date': record.date_to, 'date_deadline': record.date_to,
_______________________________________________ Mailing list: https://launchpad.net/~openerp-dev-gtk Post to : openerp-dev-gtk@lists.launchpad.net Unsubscribe : https://launchpad.net/~openerp-dev-gtk More help : https://help.launchpad.net/ListHelp