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

Reply via email to