[MERGE] forward port of branch saas-5 up to 9363bc9
[odoo/odoo.git] / addons / calendar / calendar.py
index f25e530..efec387 100644 (file)
@@ -11,6 +11,7 @@ from datetime import datetime, timedelta
 from dateutil import parser
 from dateutil import rrule
 from dateutil.relativedelta import relativedelta
+from openerp import api
 from openerp import tools, SUPERUSER_ID
 from openerp.osv import fields, osv
 from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
@@ -162,7 +163,7 @@ class calendar_attendee(osv.Model):
                 elif interval == 'minutes':
                     delta = timedelta(minutes=duration)
                 trigger.value = delta
-                valarm.add('DESCRIPTION').value = alarm.name or 'OpenERP'
+                valarm.add('DESCRIPTION').value = alarm.name or 'Odoo'
         for attendee in event_obj.attendee_ids:
             attendee_add = event.add('attendee')
             attendee_add.value = 'MAILTO:' + (attendee.email or '')
@@ -297,7 +298,7 @@ class res_partner(osv.Model):
         Used by web_calendar.js : Many2ManyAttendee
         """
         datas = []
-        meeting = False
+        meeting = None
         if meeting_id:
             meeting = self.pool['calendar.event'].browse(cr, uid, get_real_ids(meeting_id), context=context)
         for partner in self.browse(cr, uid, ids, context=context):
@@ -309,7 +310,7 @@ class res_partner(osv.Model):
             datas.append(data)
         return datas
 
-    def calendar_last_notif_ack(self, cr, uid, context=None):
+    def _set_calendar_last_notif_ack(self, cr, uid, context=None):
         partner = self.pool['res.users'].browse(cr, uid, uid, context=context).partner_id
         self.write(cr, uid, partner.id, {'calendar_last_notif_ack': datetime.now()}, context=context)
         return
@@ -741,6 +742,7 @@ class calendar_event(osv.Model):
         return (format_date, format_time)
 
     def get_display_time_tz(self, cr, uid, ids, tz=False, context=None):
+        context = dict(context or {})
         if tz:
             context["tz"] = tz
         ev = self.browse(cr, uid, ids, context=context)[0]
@@ -753,8 +755,7 @@ class calendar_event(osv.Model):
             1) if user add duration for 2 hours, return : August-23-2013 at (04-30 To 06-30) (Europe/Brussels)
             2) if event all day ,return : AllDay, July-31-2013
         """
-        if context is None:
-            context = {}
+        context = dict(context or {})
 
         tz = context.get('tz', False)
         if not tz:  # tz can have a value False, so dont do it in the default value of get !
@@ -778,24 +779,25 @@ class calendar_event(osv.Model):
 
     def _compute(self, cr, uid, ids, fields, arg, context=None):
         res = {}
-        for meeting_id in ids:
-            res[meeting_id] = {}
-            attendee = self._find_my_attendee(cr, uid, [meeting_id], context)
-            meeting = self.browse(cr, uid, [meeting_id], context=context)[0]
+        if not isinstance(fields, list):
+            fields = [fields]
+        for meeting in self.browse(cr, uid, ids, context=context):
+            meeting_data = {}
+            res[meeting.id] = meeting_data
+            attendee = self._find_my_attendee(cr, uid, [meeting.id], context)
             for field in fields:
                 if field == 'is_attendee':
-                    res[meeting_id][field] = True if attendee else False
+                    meeting_data[field] = bool(attendee)
                 elif field == 'attendee_status':
-                    res[meeting_id][field] = attendee.state if attendee else 'needsAction'
+                    meeting_data[field] = attendee.state if attendee else 'needsAction'
                 elif field == 'display_time':
-                    res[meeting_id][field] = self._get_display_time(cr, uid, meeting.start, meeting.stop, meeting.duration, meeting.allday, context=context)
+                    meeting_data[field] = self._get_display_time(cr, uid, meeting.start, meeting.stop, meeting.duration, meeting.allday, context=context)
                 elif field == "display_start":
-                    res[meeting_id][field] = meeting.start_date if meeting.allday else meeting.start_datetime
+                    meeting_data[field] = meeting.start_date if meeting.allday else meeting.start_datetime
                 elif field == 'start':
-                    res[meeting_id][field] = meeting.start_date if meeting.allday else meeting.start_datetime
+                    meeting_data[field] = meeting.start_date if meeting.allday else meeting.start_datetime
                 elif field == 'stop':
-                    res[meeting_id][field] = meeting.stop_date if meeting.allday else meeting.stop_datetime
-
+                    meeting_data[field] = meeting.stop_date if meeting.allday else meeting.stop_datetime
         return res
 
     def _get_rulestring(self, cr, uid, ids, name, arg, context=None):
@@ -807,21 +809,17 @@ class calendar_event(osv.Model):
         if not isinstance(ids, list):
             ids = [ids]
 
-        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.browse(cr, SUPERUSER_ID, id, context=context)
-
-            if data.interval and data.interval < 0:
-                raise osv.except_osv(_('Warning!'), _('Interval cannot be negative.'))
-            if data.count and data.count <= 0:
-                raise osv.except_osv(_('Warning!'), _('Count cannot be negative or 0.'))
-
-            data = self.read(cr, uid, id, ['id', 'byday', 'recurrency', 'month_list', 'final_date', 'rrule_type', 'month_by', 'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'day', 'week_list'], context=context)
-            event = data['id']
-            if data['recurrency']:
-                result[event] = self.compute_rule_string(data)
+        #read these fields as SUPERUSER because if the record is private a normal search could raise an error
+        events = self.read(cr, SUPERUSER_ID, ids,
+                           ['id', 'byday', 'recurrency', 'final_date', 'rrule_type', 'month_by',
+                            'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa',
+                            'su', 'day', 'week_list'], context=context)
+        for event in events:
+            if event['recurrency']:
+                result[event['id']] = self.compute_rule_string(event)
             else:
-                result[event] = ""
+                result[event['id']] = ''
+
         return result
 
     # retro compatibility function
@@ -892,10 +890,10 @@ class calendar_event(osv.Model):
         'is_attendee': fields.function(_compute, string='Attendee', type="boolean", multi='attendee'),
         'attendee_status': fields.function(_compute, string='Attendee Status', type="selection", selection=calendar_attendee.STATE_SELECTION, multi='attendee'),
         'display_time': fields.function(_compute, string='Event Time', type="char", multi='attendee'),
-        'display_start': fields.function(_compute, string='Date', type="char", multi='display_start', store=True),
+        'display_start': fields.function(_compute, string='Date', type="char", multi='attendee', store=True),
         'allday': fields.boolean('All Day', states={'done': [('readonly', True)]}),
-        'start': fields.function(_compute, string='Calculated start', type="datetime", multi='start', store=True, required=True),
-        'stop': fields.function(_compute, string='Calculated stop', type="datetime", multi='stop', store=True, required=True),
+        'start': fields.function(_compute, string='Calculated start', type="datetime", multi='attendee', store=True, required=True),
+        'stop': fields.function(_compute, string='Calculated stop', type="datetime", multi='attendee', store=True, required=True),
         'start_date': fields.date('Start Date', states={'done': [('readonly', True)]}, track_visibility='onchange'),
         'start_datetime': fields.datetime('Start DateTime', states={'done': [('readonly', True)]}, track_visibility='onchange'),
         'stop_date': fields.date('End Date', states={'done': [('readonly', True)]}, track_visibility='onchange'),
@@ -934,7 +932,7 @@ class calendar_event(osv.Model):
         'categ_ids': fields.many2many('calendar.event.type', 'meeting_category_rel', 'event_id', 'type_id', 'Tags'),
         'attendee_ids': fields.one2many('calendar.attendee', 'event_id', 'Attendees', ondelete='cascade'),
         'partner_ids': fields.many2many('res.partner', 'calendar_event_res_partner_rel', string='Attendees', states={'done': [('readonly', True)]}),
-        'alarm_ids': fields.many2many('calendar.alarm', 'calendar_alarm_calendar_event_rel', string='Reminders', ondelete="restrict"),
+        'alarm_ids': fields.many2many('calendar.alarm', 'calendar_alarm_calendar_event_rel', string='Reminders', ondelete="restrict", copy=False),
     }
 
     def _get_default_partners(self, cr, uid, ctx=None):
@@ -1023,22 +1021,22 @@ class calendar_event(osv.Model):
         value['allday'] = checkallday  # Force to be rewrited
 
         if allday:
-            if fromtype == 'start':
+            if fromtype == 'start' and start:
                 start = datetime.strptime(start, DEFAULT_SERVER_DATE_FORMAT)
                 value['start_datetime'] = datetime.strftime(start, DEFAULT_SERVER_DATETIME_FORMAT)
                 value['start'] = datetime.strftime(start, DEFAULT_SERVER_DATETIME_FORMAT)
 
-            if fromtype == 'stop':
+            if fromtype == 'stop' and end:
                 end = datetime.strptime(end, DEFAULT_SERVER_DATE_FORMAT)
                 value['stop_datetime'] = datetime.strftime(end, DEFAULT_SERVER_DATETIME_FORMAT)
                 value['stop'] = datetime.strftime(end, DEFAULT_SERVER_DATETIME_FORMAT)
 
         else:
-            if fromtype == 'start':
+            if fromtype == 'start' and start:
                 start = datetime.strptime(start, DEFAULT_SERVER_DATETIME_FORMAT)
                 value['start_date'] = datetime.strftime(start, DEFAULT_SERVER_DATE_FORMAT)
                 value['start'] = datetime.strftime(start, DEFAULT_SERVER_DATETIME_FORMAT)
-            if fromtype == 'stop':
+            if fromtype == 'stop' and end:
                 end = datetime.strptime(end, DEFAULT_SERVER_DATETIME_FORMAT)
                 value['stop_date'] = datetime.strftime(end, DEFAULT_SERVER_DATE_FORMAT)
                 value['stop'] = datetime.strftime(end, DEFAULT_SERVER_DATETIME_FORMAT)
@@ -1220,6 +1218,11 @@ class calendar_event(osv.Model):
         @param data: dictionary of freq and interval value
         @return: string containing recurring rule (empty if no rule)
         """
+        if data['interval'] and data['interval'] < 0:
+            raise osv.except_osv(_('warning!'), _('interval cannot be negative.'))
+        if data['count'] and data['count'] <= 0:
+            raise osv.except_osv(_('warning!'), _('count cannot be negative or 0.'))
+
         def get_week_string(freq, data):
             weekdays = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
             if freq == 'weekly':
@@ -1364,6 +1367,7 @@ class calendar_event(osv.Model):
             ('user_id', '=', uid),
         ]
 
+    @api.cr_uid_ids_context
     def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification', subtype=None, parent_id=False, attachments=None, context=None, **kwargs):
         if isinstance(thread_id, str):
             thread_id = get_real_ids(thread_id)
@@ -1447,16 +1451,9 @@ class calendar_event(osv.Model):
         return res
 
     def copy(self, cr, uid, id, default=None, context=None):
-        if context is None:
-            context = {}
-
         default = default or {}
-
         self._set_date(cr, uid, default, id=default.get('id'), context=context)
-        default['attendee_ids'] = False
-
-        res = super(calendar_event, self).copy(cr, uid, calendar_id2real_id(id), default, context)
-        return res
+        return super(calendar_event, self).copy(cr, uid, calendar_id2real_id(id), default, context)
 
     def _detach_one_event(self, cr, uid, id, values=dict(), context=None):
         real_event_id = calendar_id2real_id(id)
@@ -1590,8 +1587,7 @@ class calendar_event(osv.Model):
         return res
 
     def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False, lazy=True):
-        if not context:
-            context = {}
+        context = dict(context or {})
 
         if 'date' in groupby:
             raise osv.except_osv(_('Warning!'), _('Group by date is not supported, use the calendar view instead.'))
@@ -1637,7 +1633,8 @@ class calendar_event(osv.Model):
                     res['start_datetime'] = ls[1]
                     res['stop_datetime'] = ls[2]
 
-                res['display_time'] = self._get_display_time(cr, uid, ls[1], ls[2], res['duration'], res['allday'], context=context)
+                if 'display_time' in fields:
+                    res['display_time'] = self._get_display_time(cr, uid, ls[1], ls[2], res['duration'], res['allday'], context=context)
 
             res['id'] = calendar_id
             result.append(res)