| Hello, | -
| You are invited for %(company)s Event. | -
| Below are the details of event. Hours and dates expressed in %(timezone)s time. | -
- %(name)s- |
- |||||||||||||||||||||
-
|
- |||||||||||||||||||||
| From: | -
| %(user)s | -
| -------------------------- | -
| %(sign)s | -
-Event: %s -Event Date: %s -Description: %s - -From: - %s - ----- -%s --""" % (alarm.name, alarm.trigger_date, alarm.description, \ - alarm.user_id.name, alarm.user_id.signature) - mail_to = alarm.user_id.email - for att in alarm.attendee_ids: - mail_to = mail_to + " " + att.user_id.email - if mail_to: - vals = { - 'state': 'outgoing', - 'subject': sub, - 'body_html': body, - 'email_to': mail_to, - 'email_from': tools.config.get('email_from', mail_to), - } - self.pool.get('mail.mail').create(cr, uid, vals, context=context) - if next_trigger_date: - update_vals.update({'trigger_date': next_trigger_date}) - else: - update_vals.update({'state': 'done'}) - self.write(cr, uid, [alarm.id], update_vals) - return True - - - -class calendar_event(osv.osv): - _name = "calendar.event" - _description = "Calendar Event" - __attribute__ = {} - - def _tz_get(self, cr, uid, context=None): - return [(x.lower(), x) for x in pytz.all_timezones] - - def onchange_dates(self, cr, uid, ids, start_date, duration=False, end_date=False, allday=False, context=None): - """Returns duration and/or end date based on values passed - @param self: The object pointer - @param cr: the current row, from the database cursor, - @param uid: the current user's ID for security checks, - @param ids: List of calendar event's IDs. - @param start_date: Starting date - @param duration: Duration between start date and end date - @param end_date: Ending Datee - @param context: A standard dictionary for contextual values - """ - if context is None: - context = {} - - value = {} - if not start_date: - return value - if not end_date and not duration: - duration = 1.00 - value['duration'] = duration - - start = datetime.strptime(start_date, "%Y-%m-%d %H:%M:%S") - if allday: # For all day event - duration = 24.0 - value['duration'] = duration - # change start_date's time to 00:00:00 in the user's timezone - user = self.pool.get('res.users').browse(cr, uid, uid) - tz = pytz.timezone(user.tz) if user.tz else pytz.utc - start = pytz.utc.localize(start).astimezone(tz) # convert start in user's timezone - start = start.replace(hour=0, minute=0, second=0) # change start's time to 00:00:00 - start = start.astimezone(pytz.utc) # convert start back to utc - start_date = start.strftime("%Y-%m-%d %H:%M:%S") - value['date'] = start_date - - if end_date and not duration: - end = datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S") - diff = end - start - duration = float(diff.days)* 24 + (float(diff.seconds) / 3600) - value['duration'] = round(duration, 2) - elif not end_date: - end = start + timedelta(hours=duration) - value['date_deadline'] = end.strftime("%Y-%m-%d %H:%M:%S") - elif end_date and duration and not allday: - # we have both, keep them synchronized: - # set duration based on end_date (arbitrary decision: this avoid - # getting dates like 06:31:48 instead of 06:32:00) - end = datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S") - diff = end - start - duration = float(diff.days)* 24 + (float(diff.seconds) / 3600) - value['duration'] = round(duration, 2) - - return {'value': value} - - def unlink_events(self, cr, uid, ids, context=None): - """ - This function deletes event which are linked with the event with recurrent_id - (Removes the events which refers to the same UID value) - """ - if context is None: - context = {} - for event_id in ids: - cr.execute("select id from %s where recurrent_id=%%s" % (self._table), (event_id,)) - r_ids = map(lambda x: x[0], cr.fetchall()) - self.unlink(cr, uid, r_ids, context=context) - return True - - def _get_rulestring(self, cr, uid, ids, name, arg, context=None): - """ - Gets Recurrence rule string according to value type RECUR of iCalendar from the values given. - @param self: The object pointer - @param cr: the current row, from the database cursor, - @param id: List of calendar event's ids. - @param context: A standard dictionary for contextual values - @return: dictionary of rrule value. - """ - - result = {} - 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.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: - result[event] = "" - return result - - def _rrule_write(self, obj, cr, uid, ids, field_name, field_value, args, context=None): - data = self._get_empty_rrule_data() - if field_value: - data['recurrency'] = True - for event in self.browse(cr, uid, ids, context=context): - rdate = rule_date or event.date - update_data = self._parse_rrule(field_value, dict(data), rdate) - data.update(update_data) - super(calendar_event, obj).write(cr, uid, ids, data, context=context) - return True - - _columns = { - 'id': fields.integer('ID', readonly=True), - 'sequence': fields.integer('Sequence'), - 'name': fields.char('Description', size=64, required=False, states={'done': [('readonly', True)]}), - 'date': fields.datetime('Date', states={'done': [('readonly', True)]}, required=True,), - 'date_deadline': fields.datetime('End Date', states={'done': [('readonly', True)]}, required=True,), - 'create_date': fields.datetime('Created', readonly=True), - 'duration': fields.float('Duration', states={'done': [('readonly', True)]}), - 'description': fields.text('Description', states={'done': [('readonly', True)]}), - 'class': fields.selection([('public', 'Public'), ('private', 'Private'), \ - ('confidential', 'Public for Employees')], 'Privacy', states={'done': [('readonly', True)]}), - 'location': fields.char('Location', size=264, help="Location of Event", states={'done': [('readonly', True)]}), - 'show_as': fields.selection([('free', 'Free'), ('busy', 'Busy')], \ - 'Show Time as', states={'done': [('readonly', True)]}), - 'base_calendar_url': fields.char('Caldav URL', size=264), - 'state': fields.selection([ - ('tentative', 'Uncertain'), - ('cancelled', 'Cancelled'), - ('confirmed', 'Confirmed'), - ], 'Status', readonly=True), - 'exdate': fields.text('Exception Date/Times', help="This property \ -defines the list of date/time exceptions for a recurring calendar component."), - 'exrule': fields.char('Exception Rule', size=352, help="Defines a \ -rule or repeating pattern of time to exclude from the recurring rule."), - 'rrule': fields.function(_get_rulestring, type='char', size=124, \ - fnct_inv=_rrule_write, store=True, string='Recurrent Rule'), - 'rrule_type': fields.selection([ - ('daily', 'Day(s)'), - ('weekly', 'Week(s)'), - ('monthly', 'Month(s)'), - ('yearly', 'Year(s)') - ], 'Recurrency', states={'done': [('readonly', True)]}, - help="Let the event automatically repeat at that interval"), - 'alarm_id': fields.many2one('res.alarm', 'Reminder', states={'done': [('readonly', True)]}, - help="Set an alarm at this time, before the event occurs" ), - 'base_calendar_alarm_id': fields.many2one('calendar.alarm', 'Alarm'), - 'recurrent_id': fields.integer('Recurrent ID'), - 'recurrent_id_date': fields.datetime('Recurrent ID date'), - 'vtimezone': fields.selection(_tz_get, size=64, string='Timezone'), - 'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}), - 'organizer': fields.char("Organizer (deprecated)", size=256, states={'done': [('readonly', True)]}, - deprecated='Will be removed with OpenERP v8; use organizer_id field instead'), # Map with organizer attribute of VEvent. - 'organizer_id': fields.many2one('res.users', 'Organizer', states={'done': [('readonly', True)]}), - 'end_type' : fields.selection([('count', 'Number of repetitions'), ('end_date','End date')], 'Recurrence Termination'), - 'interval': fields.integer('Repeat Every', help="Repeat every (Days/Week/Month/Year)"), - 'count': fields.integer('Repeat', help="Repeat x times"), - 'mo': fields.boolean('Mon'), - 'tu': fields.boolean('Tue'), - 'we': fields.boolean('Wed'), - 'th': fields.boolean('Thu'), - 'fr': fields.boolean('Fri'), - 'sa': fields.boolean('Sat'), - 'su': fields.boolean('Sun'), - 'select1': fields.selection([('date', 'Date of month'), - ('day', 'Day of month')], 'Option'), - 'day': fields.integer('Date of month'), - 'week_list': fields.selection([ - ('MO', 'Monday'), - ('TU', 'Tuesday'), - ('WE', 'Wednesday'), - ('TH', 'Thursday'), - ('FR', 'Friday'), - ('SA', 'Saturday'), - ('SU', 'Sunday')], 'Weekday'), - 'byday': fields.selection([ - ('1', 'First'), - ('2', 'Second'), - ('3', 'Third'), - ('4', 'Fourth'), - ('5', 'Fifth'), - ('-1', 'Last')], 'By day'), - 'month_list': fields.selection(months.items(), 'Month'), - 'end_date': fields.date('Repeat Until'), - 'attendee_ids': fields.many2many('calendar.attendee', 'event_attendee_rel', \ - 'event_id', 'attendee_id', 'Attendees'), - 'allday': fields.boolean('All Day', states={'done': [('readonly', True)]}), - 'active': fields.boolean('Active', help="If the active field is set to \ - true, it will allow you to hide the event alarm information without removing it."), - 'recurrency': fields.boolean('Recurrent', help="Recurrent Meeting"), - 'partner_ids': fields.many2many('res.partner', string='Attendees', states={'done': [('readonly', True)]}), - } - - def create_attendees(self, cr, uid, ids, context): - att_obj = self.pool.get('calendar.attendee') - user_obj = self.pool.get('res.users') - current_user = user_obj.browse(cr, uid, uid, context=context) - for event in self.browse(cr, uid, ids, context): - attendees = {} - for att in event.attendee_ids: - attendees[att.partner_id.id] = True - new_attendees = [] - mail_to = "" - for partner in event.partner_ids: - if partner.id in attendees: - continue - local_context = context.copy() - local_context.pop('default_state', None) - att_id = self.pool.get('calendar.attendee').create(cr, uid, { - 'partner_id': partner.id, - 'user_id': partner.user_ids and partner.user_ids[0].id or False, - 'ref': self._name+','+str(event.id), - 'email': partner.email - }, context=local_context) - if partner.email: - mail_to = mail_to + " " + partner.email - self.write(cr, uid, [event.id], { - 'attendee_ids': [(4, att_id)] - }, context=context) - new_attendees.append(att_id) - - if mail_to and current_user.email: - att_obj._send_mail(cr, uid, new_attendees, mail_to, - email_from = current_user.email, context=context) - return True - - def default_organizer(self, cr, uid, context=None): - """ - .. deprecated:: 8.0 - Use organizer_id field and its default value instead. - """ - user_pool = self.pool.get('res.users') - user = user_pool.browse(cr, uid, uid, context=context) - res = user.name - if user.email: - res += " <%s>" %(user.email) - return res - - _defaults = { - 'end_type': 'count', - 'count': 1, - 'rrule_type': False, - 'state': 'tentative', - 'class': 'public', - 'show_as': 'busy', - 'select1': 'date', - 'interval': 1, - 'active': 1, - 'user_id': lambda self, cr, uid, ctx: uid, - } - - def _check_closing_date(self, cr, uid, ids, context=None): - for event in self.browse(cr, uid, ids, context=context): - if event.date_deadline < event.date: - return False - return True - - _constraints = [ - (_check_closing_date, 'Error ! End date cannot be set before start date.', ['date_deadline']), - ] - - def get_recurrent_ids(self, cr, uid, select, domain, limit=100, context=None): - """Gives virtual event ids for recurring events based on value of Recurrence Rule - This method gives ids of dates that comes between start date and end date of calendar views - @param self: The object pointer - @param cr: the current row, from the database cursor, - @param uid: the current user's ID for security checks, - @param limit: The Number of Results to Return """ - if not context: - context = {} - - result = [] - for data in super(calendar_event, self).read(cr, uid, select, ['rrule', 'recurrency', 'exdate', 'exrule', 'date'], context=context): - if not data['recurrency'] or not data['rrule']: - result.append(data['id']) - continue - event_date = datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S") - - # TOCHECK: the start date should be replaced by event date; the event date will be changed by that of calendar code - - if not data['rrule']: - continue - - exdate = data['exdate'] and data['exdate'].split(',') or [] - rrule_str = data['rrule'] - new_rrule_str = [] - rrule_until_date = False - is_until = False - for rule in rrule_str.split(';'): - name, value = rule.split('=') - if name == "UNTIL": - is_until = True - value = parser.parse(value) - rrule_until_date = parser.parse(value.strftime("%Y-%m-%d %H:%M:%S")) - value = value.strftime("%Y%m%d%H%M%S") - new_rule = '%s=%s' % (name, value) - new_rrule_str.append(new_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: - # 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 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')
- Click to schedule a new meeting. -
- The calendar is shared between employees and fully integrated with - other applications such as the employee holidays or the business - opportunities. -
-+ Once installed, you can configure your API credentials for "Google calendar" +
+${object.event_id.user_id.partner_id.name} invited you for the ${object.event_id.name} meeting of ${object.event_id.user_id.company_id.name}.
+|
+ ${object.event_id.get_interval(object.event_id.date, 'dayname')}
+
+ ${object.event_id.get_interval(object.event_id.date,'day')}
+
+ ${object.event_id.get_interval(object.event_id.date, 'month')}
+ ${object.event_id.get_interval(object.event_id.date, 'time')}
+ |
+
+
|
+ ||||||||||||||