199
202
to send an Email to Invited Person')
206
'type': lambda *x: 'internal'
202
209
def do_invite(self, cr, uid, ids, context={}):
203
datas = self.read(cr, uid, ids)[0]
206
if not context or not context.get('model'):
209
model = context.get('model')
210
model_field = context.get('attendee_field', False)
211
obj = self.pool.get(model)
212
res_obj = obj.browse(cr, uid, context['active_id'])
213
type = datas.get('type')
214
att_obj = self.pool.get('calendar.attendee')
217
if not model == 'calendar.attendee':
218
vals = {'ref': '%s,%s' % (model, base_calendar_id2real_id(context['active_id']))}
220
if type == 'internal':
221
user_obj = self.pool.get('res.users')
222
for user_id in datas.get('user_ids', []):
223
user = user_obj.browse(cr, uid, user_id)
224
if not user.address_id.email:
225
raise osv.except_osv(_('Error!'), \
226
("User does not have an email Address"))
227
vals.update({'user_id': user_id,
228
'email': user.address_id.email})
229
mail_to.append(user.address_id.email)
231
elif type == 'external' and datas.get('email'):
232
vals.update({'email': datas['email']})
233
mail_to.append(datas['email'])
234
elif type == 'partner':
235
add_obj = self.pool.get('res.partner.address')
236
for contact in add_obj.browse(cr, uid, datas['contact_ids']):
237
if not contact.email:
238
raise osv.except_osv(_('Error!'), \
239
("Partner does not have an email Address"))
211
datas = self.read(cr, uid, att_id)
214
if not context or not context.get('model'):
217
model = context.get('model')
218
model_field = context.get('attendee_field', False)
219
obj = self.pool.get(model)
220
res_obj = obj.browse(cr, uid, context['active_id'])
221
type = datas.get('type')
222
att_obj = self.pool.get('calendar.attendee')
225
if not model == 'calendar.attendee':
226
vals = {'ref': '%s,%s' % (model, base_calendar_id2real_id(context['active_id']))}
228
if type == 'internal':
229
user_obj = self.pool.get('res.users')
230
if not datas.get('user_ids'):
231
raise osv.except_osv(_('Error!'), ("Please select any User"))
232
for user_id in datas.get('user_ids'):
233
user = user_obj.browse(cr, uid, user_id)
234
vals.update({'user_id': user_id,
235
'email': user.address_id.email})
236
if user.address_id.email:
237
mail_to.append(user.address_id.email)
239
elif type == 'external' and datas.get('email'):
240
vals.update({'email': datas['email']})
241
mail_to.append(datas['email'])
242
elif type == 'partner':
243
add_obj = self.pool.get('res.partner.address')
244
for contact in add_obj.browse(cr, uid, datas['contact_ids']):
246
'partner_address_id': contact.id,
247
'email': contact.email})
249
mail_to.append(contact.email)
251
if model == 'calendar.attendee':
252
att = att_obj.browse(cr, uid, context['active_id'])
241
'partner_address_id': contact.id,
242
'email': contact.email})
243
mail_to.append(contact.email)
245
if model == 'calendar.attendee':
246
att = att_obj.browse(cr, uid, context['active_id'])
248
'parent_ids' : [(4, att.id)],
251
att_id = att_obj.create(cr, uid, vals)
253
obj.write(cr, uid, res_obj.id, {model_field: [(4, att_id)]})
255
if datas.get('send_mail'):
256
att_obj._send_mail(cr, uid, [att_id], mail_to, \
257
email_from=tools.config.get('email_from', False))
254
'parent_ids' : [(4, att.id)],
257
if datas.get('send_mail'):
259
name = map(lambda x: x[1], filter(lambda x: type==x[0], \
260
self._columns['type'].selection))
261
raise osv.except_osv(_('Error!'), ("%s must have an email \
262
Address to send mail") % (name[0]))
263
att_obj._send_mail(cr, uid, [att_id], mail_to, \
264
email_from=tools.config.get('email_from', False))
265
att_id = att_obj.create(cr, uid, vals)
267
obj.write(cr, uid, res_obj.id, {model_field: [(4, att_id)]})
309
314
if name == 'delegated_to':
311
316
for parent in attdata.parent_ids:
312
todata.append('MAILTO:' + parent.email)
318
todata.append('MAILTO:' + parent.email)
313
319
result[id][name] = ', '.join(todata)
314
320
if name == 'delegated_from':
316
322
for child in attdata.child_ids:
317
fromdata.append('MAILTO:' + child.email)
324
fromdata.append('MAILTO:' + child.email)
318
325
result[id][name] = ', '.join(fromdata)
319
326
if name == 'event_date':
321
model, res_id = tuple(attdata.ref.split(','))
322
model_obj = self.pool.get(model)
323
obj = model_obj.read(cr, uid, res_id, ['date'])[0]
324
result[id][name] = obj.get('date')
328
result[id][name] = attdata.ref.date
326
330
result[id][name] = False
327
331
if name == 'event_end_date':
329
model, res_id = tuple(attdata.ref.split(','))
330
model_obj = self.pool.get(model)
331
obj = model_obj.read(cr, uid, res_id, ['date_deadline'])[0]
332
result[id][name] = obj.get('date_deadline')
333
result[id][name] = attdata.ref.date_deadline
334
335
result[id][name] = False
335
336
if name == 'sent_by_uid':
337
model, res_id = tuple(attdata.ref.split(','))
338
model_obj = self.pool.get(model)
339
obj = model_obj.read(cr, uid, res_id, ['user_id'])[0]
340
result[id][name] = obj.get('user_id')
338
result[id][name] = (attdata.ref.user_id.id,attdata.ref.user_id.name)
342
340
result[id][name] = uid
343
341
if name == 'language':
394
392
'language': fields.function(_compute_data, method=True, string='Language', type="selection", selection=_lang_get, multi='language', store=True, help="To specify the language for text values in a property or property parameter."),
395
393
'user_id': fields.many2one('res.users', 'User'),
396
394
'partner_address_id': fields.many2one('res.partner.address', 'Contact'),
397
'partner_id': fields.related('partner_address_id', 'partner_id', type='many2one', relation='res.partner', string='Partner'),
398
'email': fields.char('Email', size=124, required=True, help="Email of Invited Person"),
395
'partner_id': fields.related('partner_address_id', 'partner_id', type='many2one', relation='res.partner', string='Partner', help="Partner related to contact"),
396
'email': fields.char('Email', size=124, help="Email of Invited Person"),
399
397
'event_date': fields.function(_compute_data, method=True, string='Event Date', type="datetime", multi='event_date'),
400
398
'event_end_date': fields.function(_compute_data, method=True, string='Event End Date', type="datetime", multi='event_end_date'),
401
399
'ref': fields.reference('Event Ref', selection=_links_get, size=128),
477
474
self.write(cr, uid, ids, {'state': 'tentative'}, context)
479
476
def do_accept(self, cr, uid, ids, context=None, *args):
480
self.write(cr, uid, ids, {'state': 'accepted'}, context)
478
vals = self.read(cr, uid, invite, context=context)
479
user = vals.get('user_id')
481
ref = vals.get('ref', None)
484
if event_ref.user_id.id != user[0]:
485
defaults = {'user_id': user[0]}
486
new_event = model_obj.copy(cr, uid, event, default=defaults, context=context)
487
self.write(cr, uid, invite, {'state': 'accepted'}, context)
482
490
def do_decline(self, cr, uid, ids, context=None, *args):
483
491
self.write(cr, uid, ids, {'state': 'declined'}, context)
695
703
def _tz_get(self, cr, uid, context={}):
696
704
return [(x.lower(), x) for x in pytz.all_timezones]
698
def onchange_rrule_type(self, cr, uid, ids, rtype, *args, **argv):
699
if rtype == 'none' or not rtype:
700
return {'value': {'rrule': ''}}
701
if rtype == 'custom':
707
def onchange_dates(self, cr, uid, ids, start_date, duration=False, end_date=False, context={}):
703
rrule = self.pool.get('calendar.custom.rrule')
704
rrulestr = rrule.compute_rule_string(cr, uid, {'freq': rtype.upper(), \
706
return {'value': {'rrule': rrulestr}}
708
def _get_duration(self, cr, uid, ids, name, arg, context):
710
for event in self.browse(cr, uid, ids, context=context):
711
start = datetime.strptime(event.date, "%Y-%m-%d %H:%M:%S")
713
if event.date_deadline:
714
end = datetime.strptime(event.date_deadline[:19], "%Y-%m-%d %H:%M:%S")
716
duration = float(diff.days)* 24 + (float(diff.seconds) / 3600)
717
res[event.id] = round(duration, 2)
720
def _set_duration(self, cr, uid, id, name, value, arg, context):
721
event = self.browse(cr, uid, id, context=context)
722
start = datetime.strptime(event.date, "%Y-%m-%d %H:%M:%S")
723
end = start + timedelta(hours=value)
724
cr.execute("UPDATE %s set date_deadline='%s' \
725
where id=%s"% (self._table, end.strftime("%Y-%m-%d %H:%M:%S"), id))
710
start = datetime.strptime(start_date, "%Y-%m-%d %H:%M:%S")
712
if end_date and not duration:
713
end = datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S")
715
duration = float(diff.days)* 24 + (float(diff.seconds) / 3600)
716
value['duration'] = round(duration, 2)
718
end = start + timedelta(hours=duration)
719
value['date_deadline'] = end.strftime("%Y-%m-%d %H:%M:%S")
720
return {'value': value}
722
def _get_rulestring(self, cr, uid, ids, name, arg, context=None):
725
datas = self.read(cr, uid, event)
726
if datas.get('rrule_type'):
727
if datas.get('rrule_type') == 'none':
728
result[event] = False
729
elif datas.get('rrule_type') == 'custom':
730
rrule_custom = self.compute_rule_string(cr, uid, datas)
731
result[event] = rrule_custom
733
result[event] = self.compute_rule_string(cr, uid, {'freq':\
734
datas.get('rrule_type').upper(), \
735
'interval': 1}, context=context)
729
739
'id': fields.integer('ID'),
730
740
'sequence': fields.integer('Sequence'),
754
763
'base_calendar_alarm_id': fields.many2one('calendar.alarm', 'Alarm'),
755
764
'recurrent_uid': fields.integer('Recurrent ID'),
756
765
'recurrent_id': fields.datetime('Recurrent ID date'),
757
'vtimezone': fields.selection(_tz_get, 'Timezone', size=64),
758
'user_id': fields.many2one('res.users', 'Responsible'),
766
'vtimezone': fields.related('user_id', 'context_tz', type='char', size=24, string='Timezone'),
767
'user_id': fields.many2one('res.users', 'Responsible'),
768
'freq': fields.selection([('None', 'No Repeat'), \
769
('secondly', 'Secondly'), \
770
('minutely', 'Minutely'), \
771
('hourly', 'Hourly'), \
772
('daily', 'Daily'), \
773
('weekly', 'Weekly'), \
774
('monthly', 'Monthly'), \
775
('yearly', 'Yearly')], 'Frequency'),
776
'interval': fields.integer('Interval'),
777
'count': fields.integer('Count'),
778
'mo': fields.boolean('Mon'),
779
'tu': fields.boolean('Tue'),
780
'we': fields.boolean('Wed'),
781
'th': fields.boolean('Thu'),
782
'fr': fields.boolean('Fri'),
783
'sa': fields.boolean('Sat'),
784
'su': fields.boolean('Sun'),
785
'select1': fields.selection([('date', 'Date of month'), \
786
('day', 'Day of month')], 'Option'),
787
'day': fields.integer('Date of month'),
788
'week_list': fields.selection([('MO', 'Monday'), ('TU', 'Tuesday'), \
789
('WE', 'Wednesday'), ('TH', 'Thursday'), \
790
('FR', 'Friday'), ('SA', 'Saturday'), \
791
('SU', 'Sunday')], 'Weekday'),
792
'byday': fields.selection([('1', 'First'), ('2', 'Second'), \
793
('3', 'Third'), ('4', 'Fourth'), \
794
('5', 'Fifth'), ('-1', 'Last')], 'By day'),
795
'month_list': fields.selection(months.items(), 'Month'),
796
'end_date': fields.date('Repeat Until')
762
800
'class': lambda *a: 'public',
763
801
'show_as': lambda *a: 'busy',
802
'freq': lambda *x: 'None',
803
'select1': lambda *x: 'date',
804
'interval': lambda *x: 1,
766
def onchange_user_id(self, cr, uid, ids, user_id, *args, **argv):
768
return {'value': {'vtimezone': False}}
769
value = {'vtimezone': False}
770
cr.execute('select context_tz from res_users where id=%s' % (user_id))
771
timezone = cr.fetchone()[0]
773
value.update({'vtimezone': timezone.lower()})
774
return {'value': value}
776
def modify_this(self, cr, uid, ids, defaults, context=None, *args):
777
datas = self.read(cr, uid, ids[0], context=context)
778
date = datas.get('date')
807
def modify_this(self, cr, uid, event_id, defaults, real_date, context=None, *args):
808
event_id = base_calendar_id2real_id(event_id)
809
datas = self.read(cr, uid, event_id, context=context)
779
810
defaults.update({
780
811
'recurrent_uid': base_calendar_id2real_id(datas['id']),
781
'recurrent_id': defaults.get('date'),
812
'recurrent_id': defaults.get('date') or real_date,
782
813
'rrule_type': 'none',
785
new_id = self.copy(cr, uid, ids[0], default=defaults, context=context)
816
exdate = datas['exdate'] and datas['exdate'].split(',') or []
817
if real_date and defaults.get('date'):
818
exdate.append(real_date)
819
self.write(cr, uid, event_id, {'exdate': ','.join(exdate)}, context=context)
820
new_id = self.copy(cr, uid, event_id, default=defaults, context=context)
823
def modify_all(self, cr, uid, event_id, defaults, context=None, *args):
824
event_id = base_calendar_id2real_id(event_id)
826
defaults.update({'table': self._table})
828
qry = "UPDATE %(table)s set name='%(name)s', \
829
date='%(date)s', date_deadline='%(date_deadline)s'"
830
if defaults.get('alarm_id'):
831
qry += ", alarm_id=%(alarm_id)s"
832
if defaults.get('location'):
833
qry += ", location='%(location)s'"
834
qry += "WHERE id=%s" % (event_id)
835
cr.execute(qry % (defaults))
788
838
def get_recurrent_ids(self, cr, uid, select, base_start_date, base_until_date, limit=100):
857
907
return ids and ids[0] or False
910
def compute_rule_string(self, cr, uid, datas, context=None, *args):
911
weekdays = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
915
# logic for computing rrule string
916
freq = datas.get('freq')
921
byday = map(lambda x: x.upper(), filter(lambda x: datas.get(x) and x in weekdays, datas))
923
weekstring = ';BYDAY=' + ','.join(byday)
925
elif freq == 'monthly':
926
if datas.get('select1')=='date' and (datas.get('day') < 1 or datas.get('day') > 31):
927
raise osv.except_osv(_('Error!'), ("Please select proper Day of month"))
928
if datas.get('select1')=='day':
929
monthstring = ';BYDAY=' + datas.get('byday') + datas.get('week_list')
930
elif datas.get('select1')=='date':
931
monthstring = ';BYMONTHDAY=' + str(datas.get('day'))
933
elif freq == 'yearly':
934
if datas.get('select1')=='date' and (datas.get('day') < 1 or datas.get('day') > 31):
935
raise osv.except_osv(_('Error!'), ("Please select proper Day of month"))
936
bymonth = ';BYMONTH=' + str(datas.get('month_list'))
937
if datas.get('select1')=='day':
938
bystring = ';BYDAY=' + datas.get('byday') + datas.get('week_list')
939
elif datas.get('select1')=='date':
940
bystring = ';BYMONTHDAY=' + str(datas.get('day'))
941
yearstring = bymonth + bystring
943
if datas.get('end_date'):
944
datas['end_date'] = ''.join((re.compile('\d')).findall(datas.get('end_date'))) + '235959Z'
945
enddate = (datas.get('count') and (';COUNT=' + str(datas.get('count'))) or '') +\
946
((datas.get('end_date') and (';UNTIL=' + datas.get('end_date'))) or '')
948
rrule_string = 'FREQ=' + freq.upper() + weekstring + ';INTERVAL=' + \
949
str(datas.get('interval')) + enddate + monthstring + yearstring
860
954
def search(self, cr, uid, args, offset=0, limit=100, order=None,
861
955
context=None, count=False):
862
956
args_without_date = []
887
id = base_calendar_id2real_id(id)
888
if not id in new_ids:
980
for event_id in select:
981
if len(str(event_id).split('-')) > 1:
982
data = self.read(cr, uid, event_id, ['date', 'date_deadline', \
983
'rrule', 'duration'])
984
if data.get('rrule'):
985
real_date = data.get('date')
987
new_id = self.modify_this(cr, uid, event_id, data, \
989
context.update({'active_id': new_id,'active_ids': [new_id]})
991
event_id = base_calendar_id2real_id(event_id)
992
if not event_id in new_ids:
993
new_ids.append(event_id)
890
994
res = super(calendar_event, self).write(cr, uid, new_ids, vals, context=context)
891
995
if vals.has_key('alarm_id') or vals.has_key('base_calendar_alarm_id'):
892
996
alarm_obj = self.pool.get('res.alarm')
893
997
context.update({'alarm_id': vals.get('alarm_id')})
894
alarm_obj.do_alarm_create(cr, uid, new_ids, self._name, 'date', context=context)
998
alarm_obj.do_alarm_create(cr, uid, new_ids, self._name, 'date', \
897
1002
def browse(self, cr, uid, ids, context=None, list_class=None, fields_process={}):
1072
1179
virtual_report_spool()
1074
class calendar_custom_rrule(osv.osv):
1075
_name = "calendar.custom.rrule"
1076
_description = "Custom Recurrency Rule"
1079
'freq': fields.selection([('None', 'No Repeat'), \
1080
('secondly', 'Secondly'), \
1081
('minutely', 'Minutely'), \
1082
('hourly', 'Hourly'), \
1083
('daily', 'Daily'), \
1084
('weekly', 'Weekly'), \
1085
('monthly', 'Monthly'), \
1086
('yearly', 'Yearly')], 'Frequency', required=True),
1087
'interval': fields.integer('Interval'),
1088
'count': fields.integer('Count'),
1089
'mo': fields.boolean('Mon'),
1090
'tu': fields.boolean('Tue'),
1091
'we': fields.boolean('Wed'),
1092
'th': fields.boolean('Thu'),
1093
'fr': fields.boolean('Fri'),
1094
'sa': fields.boolean('Sat'),
1095
'su': fields.boolean('Sun'),
1096
'select1': fields.selection([('date', 'Date of month'), \
1097
('day', 'Day of month')], 'Option'),
1098
'day': fields.integer('Date of month'),
1099
'week_list': fields.selection([('MO', 'Monday'), ('TU', 'Tuesday'), \
1100
('WE', 'Wednesday'), ('TH', 'Thursday'), \
1101
('FR', 'Friday'), ('SA', 'Saturday'), \
1102
('SU', 'Sunday')], 'Weekday'),
1103
'byday': fields.selection([('1', 'First'), ('2', 'Second'), \
1104
('3', 'Third'), ('4', 'Fourth'), \
1105
('5', 'Fifth'), ('-1', 'Last')], 'By day'),
1106
'month_list': fields.selection(months.items(), 'Month'),
1107
'end_date': fields.date('Repeat Until')
1111
'freq': lambda *x: 'daily',
1112
'select1': lambda *x: 'date',
1113
'interval': lambda *x: 1,
1116
def compute_rule_string(self, cr, uid, datas, context=None, *args):
1117
weekdays = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
1122
# logic for computing rrule string
1124
freq = datas.get('freq')
1126
obj.write(cr, uid, [res_obj.id], {'rrule': ''})
1129
if freq == 'weekly':
1130
byday = map(lambda x: x.upper(), filter(lambda x: datas.get(x) and x in weekdays, datas))
1132
weekstring = ';BYDAY=' + ','.join(byday)
1134
elif freq == 'monthly':
1135
if datas.get('select1')=='date' and (datas.get('day') < 1 or datas.get('day') > 31):
1136
raise osv.except_osv(_('Error!'), ("Please select proper Day of month"))
1137
if datas.get('select1')=='day':
1138
monthstring = ';BYDAY=' + datas.get('byday') + datas.get('week_list')
1139
elif datas.get('select1')=='date':
1140
monthstring = ';BYMONTHDAY=' + str(datas.get('day'))
1142
elif freq == 'yearly':
1143
if datas.get('select1')=='date' and (datas.get('day') < 1 or datas.get('day') > 31):
1144
raise osv.except_osv(_('Error!'), ("Please select proper Day of month"))
1145
bymonth = ';BYMONTH=' + str(datas.get('month_list'))
1146
if datas.get('select1')=='day':
1147
bystring = ';BYDAY=' + datas.get('byday') + datas.get('week_list')
1148
elif datas.get('select1')=='date':
1149
bystring = ';BYMONTHDAY=' + str(datas.get('day'))
1150
yearstring = bymonth + bystring
1152
if datas.get('end_date'):
1153
datas['end_date'] = ''.join((re.compile('\d')).findall(datas.get('end_date'))) + '235959Z'
1154
enddate = (datas.get('count') and (';COUNT=' + str(datas.get('count'))) or '') +\
1155
((datas.get('end_date') and (';UNTIL=' + datas.get('end_date'))) or '')
1157
rrule_string = 'FREQ=' + freq.upper() + weekstring + ';INTERVAL=' + \
1158
str(datas.get('interval')) + enddate + monthstring + yearstring
1163
def do_add(self, cr, uid, ids, context={}):
1164
datas = self.read(cr, uid, ids)[0]
1165
if datas.get('interval') <= 0:
1166
raise osv.except_osv(_('Error!'), ("Please select proper Interval"))
1169
if not context or not context.get('model'):
1172
model = context.get('model')
1173
obj = self.pool.get(model)
1174
res_obj = obj.browse(cr, uid, context['active_id'])
1176
rrule_string = self.compute_rule_string(cr, uid, datas)
1177
obj.write(cr, uid, [res_obj.id], {'rrule': rrule_string})
1180
calendar_custom_rrule()
1182
1181
class res_users(osv.osv):
1183
1182
_inherit = 'res.users'