diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py
index c855e5ba882..ec83ba240ee 100644
--- a/addons/base_calendar/base_calendar.py
+++ b/addons/base_calendar/base_calendar.py
@@ -37,47 +37,6 @@ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FO
from openerp.tools.translate import _
-def get_recurrent_dates(rrulestring, startdate, exdate=None, tz=None, context=None):
- """Get recurrent dates based on Rule string considering exdate and start date.
-
- All input dates and output dates are in UTC. Dates are infered
- thanks to rules in the ``tz`` timezone if given, else it'll be in
- the current local timezone as specified in the context.
-
- @param rrulestring: rulestring (ie: 'FREQ=DAILY;INTERVAL=1;COUNT=3')
- @param exdate: string of dates separated by commas (ie: '20130506220000Z,20130507220000Z')
- @param startdate: string start date for computing recurrent dates
- @param tz: pytz timezone for computing recurrent dates
- @return: list of Recurrent dates
-
- """
-
- exdate = exdate.split(',') if exdate else []
- startdate = pytz.UTC.localize(datetime.strptime(startdate, "%Y-%m-%d %H:%M:%S"))
-
- def todate(date):
- val = parser.parse(''.join((re.compile('\d')).findall(date)))
- ## Dates are localized to saved timezone if any, else current timezone.
- if not val.tzinfo:
- val = pytz.UTC.localize(val)
- return val.astimezone(timezone)
-
- timezone = pytz.timezone(tz or context.get('tz') or 'UTC')
-
- if not startdate:
- startdate = datetime.now()
-
- ## Convert the start date to saved timezone (or context tz) as it'll
- ## define the correct hour/day asked by the user to repeat for recurrence.
- startdate = startdate.astimezone(timezone)
- rset1 = rrule.rrulestr(str(rrulestring), dtstart=startdate, forceset=True)
- for date in exdate:
- datetime_obj = todate(date)
- rset1._exdate.append(datetime_obj)
-
- print "CASE 1 ", [d.astimezone(pytz.UTC) for d in rset1]
- print "CASE 2 ", [d for d in rset1]
- return [d.astimezone(pytz.UTC) for d in rset1]
def base_calendar_id2real_id(base_calendar_id=None, with_date=False):
@@ -118,15 +77,15 @@ class calendar_attendee(osv.osv):
_name = 'calendar.attendee'
_description = 'Attendee information'
- def _get_address(self, name=None, email=None):
- """
- Gives email information in ical CAL-ADDRESS type format.
- @param name: name for CAL-ADDRESS value
- @param email: email address for CAL-ADDRESS value
- """
- if name and email:
- name += ':'
- return (name or '') + (email and ('MAILTO:' + email) or '')
+# def _get_address(self, name=None, email=None):
+# """
+# Gives email information in ical CAL-ADDRESS type format.
+# @param name: name for CAL-ADDRESS value
+# @param email: email address for CAL-ADDRESS value
+# """
+# if name and email:
+# name += ':'
+# return (name or '') + (email and ('MAILTO:' + email) or '')
def _compute_data(self, cr, uid, ids, name, arg, context=None):
"""
@@ -148,17 +107,11 @@ class calendar_attendee(osv.osv):
result[id][name] = attdata.email or ''
if name == 'event_date':
- if attdata.ref:
- result[id][name] = attdata.ref.date
- else:
- result[id][name] = False
-
+ result[id][name] = attdata.event_id.date
+
if name == 'event_end_date':
- if attdata.ref:
- result[id][name] = attdata.ref.date_deadline
- else:
- result[id][name] = False
-
+ result[id][name] = attdata.event_id.date_deadline
+
return result
_columns = {
@@ -171,7 +124,7 @@ class calendar_attendee(osv.osv):
'event_end_date': fields.function(_compute_data, string='Event End Date', type="datetime", multi='event_end_date'),
'availability': fields.selection([('free', 'Free'), ('busy', 'Busy')], 'Free/Busy', readonly="True"),
'access_token':fields.char('Invitation Token', size=256),
- 'ref': fields.many2one('crm.meeting','Meeting linked'),
+ 'event_id': fields.many2one('crm.meeting','Meeting linked'),
}
_defaults = {
'state': 'needs-action',
@@ -275,39 +228,36 @@ class calendar_attendee(osv.osv):
if not isinstance(ids, (tuple, list)):
ids = [ids]
-
-
- print "IDS to send = ", ids
+
for attendee in self.browse(cr, uid, ids, context=context):
- res_obj = attendee.ref
- if res_obj:
- dummy,template_id = data_pool.get_object_reference(cr, uid, 'base_calendar', template_xmlid)
- dummy,act_id = data_pool.get_object_reference(cr, uid, 'base_calendar', "view_crm_meeting_calendar")
- body = template_pool.browse(cr, uid, template_id, context=context).body_html
+
+ dummy,template_id = data_pool.get_object_reference(cr, uid, 'base_calendar', template_xmlid)
+ dummy,act_id = data_pool.get_object_reference(cr, uid, 'base_calendar', "view_crm_meeting_calendar")
+ body = template_pool.browse(cr, uid, template_id, context=context).body_html
+
+ if attendee.email and email_from:
+ ics_file = self.get_ics_file(cr, uid, attendee.event_id, context=context)
+ local_context['att_obj'] = attendee
+ local_context['color'] = color
+ local_context['action_id'] = self.pool.get('ir.actions.act_window').search(cr, uid, [('view_id','=',act_id)], context=context)[0]
+ local_context['dbname'] = cr.dbname
+ local_context['base_url'] = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://localhost:8069', context=context)
+ vals = template_pool.generate_email(cr, uid, template_id, attendee.event_id.id, context=local_context)
- if attendee.email and email_from:
- ics_file = self.get_ics_file(cr, uid, res_obj, context=context)
- local_context['att_obj'] = attendee
- local_context['color'] = color
- local_context['action_id'] = self.pool.get('ir.actions.act_window').search(cr, uid, [('view_id','=',act_id)], context=context)[0]
- local_context['dbname'] = cr.dbname
- local_context['base_url'] = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://localhost:8069', context=context)
- vals = template_pool.generate_email(cr, uid, template_id, res_obj.id, context=local_context)
-
- if ics_file:
- vals['attachment_ids'] = [(0,0,{'name': 'invitation.ics',
- 'datas_fname': 'invitation.ics',
- 'datas': str(ics_file).encode('base64')})]
-
- vals['model'] = None #We don't want to have the mail in the tchatter while in queue!
- vals['auto_delete'] = True #We don't need mail after it has been sended !
-
- if (vals['email_to']== attendee.partner_id.email):
- vals['email_to'] = ''
- vals['recipient_ids'] = [(4,attendee.partner_id.id),]
-
- if not attendee.partner_id.opt_out:
- mail_id.append(mail_pool.create(cr, uid, vals, context=context))
+ if ics_file:
+ vals['attachment_ids'] = [(0,0,{'name': 'invitation.ics',
+ 'datas_fname': 'invitation.ics',
+ 'datas': str(ics_file).encode('base64')})]
+
+ vals['model'] = None #We don't want to have the mail in the tchatter while in queue!
+ vals['auto_delete'] = True #We don't need mail after it has been sended !
+
+ if (vals['email_to']== attendee.partner_id.email):
+ vals['email_to'] = ''
+ vals['recipient_ids'] = [(4,attendee.partner_id.id),]
+
+ if not attendee.partner_id.opt_out:
+ mail_id.append(mail_pool.create(cr, uid, vals, context=context))
if mail_id:
try:
@@ -348,7 +298,7 @@ class calendar_attendee(osv.osv):
res = self.write(cr, uid, ids, {'state': 'accepted'}, context)
for attendee in self.browse(cr, uid, ids, context=context):
if attendee.ref:
- meeting_obj.message_post(cr, uid, attendee.ref.id, body=_(("%s has accepted invitation") % (attendee.cn)),subtype="base_calendar.subtype_invitation", context=context)
+ meeting_obj.message_post(cr, uid, attendee.event_id.id, body=_(("%s has accepted invitation") % (attendee.cn)),subtype="base_calendar.subtype_invitation", context=context)
return res
@@ -362,8 +312,7 @@ class calendar_attendee(osv.osv):
meeting_obj = self.pool.get('crm.meeting')
res = self.write(cr, uid, ids, {'state': 'declined'}, context)
for attendee in self.browse(cr, uid, ids, context=context):
- if attendee.ref:
- meeting_obj.message_post(cr, uid, attendee.ref.id, body=_(("%s has declined invitation") % (attendee.cn)),subtype="base_calendar.subtype_invitation", context=context)
+ meeting_obj.message_post(cr, uid, attendee.event_id.id, body=_(("%s has declined invitation") % (attendee.cn)),subtype="base_calendar.subtype_invitation", context=context)
return res
def create(self, cr, uid, vals, context=None):
@@ -410,7 +359,6 @@ class calendar_alarm_manager(osv.osv):
def get_next_potential_limit_alarm(self,cr,uid,seconds, notif=True, mail=True, partner_id=None, context=None):
res = {}
- print "Search for partner: ", partner_id
base_request = """
SELECT
crm.id,
@@ -465,7 +413,6 @@ class calendar_alarm_manager(osv.osv):
#Add filter on hours
tuple_params += (seconds,seconds,)
- print(tuple_params)
cr.execute("""
SELECT
*
@@ -489,8 +436,7 @@ class calendar_alarm_manager(osv.osv):
res[event_id]['min_duration'] = min_duration
res[event_id]['max_duration'] = max_duration
res[event_id]['rrule'] = rrule
-
- print "All event from SQL : ",res
+
return res
def do_check_alarm_for_one_date(self,cr,uid,one_date,event, event_maxdelta,in_the_next_X_seconds,after=False,notif=True, mail=True,context=None):
@@ -525,7 +471,6 @@ class calendar_alarm_manager(osv.osv):
else:
print "Not in condition..."
- print "DATE SERVER:", datetime.now();
return res
def do_run_scheduler_mail(self,cr,uid,context=None):
@@ -548,8 +493,7 @@ class calendar_alarm_manager(osv.osv):
if not cron_interval:
raise ("Cron delay for " + self._name + " not calculated :( !")
-
- print "Cron interval = ",cron_interval
+
all_events = self.get_next_potential_limit_alarm(cr,uid,cron_interval,notif=False,context=context)
for event in all_events: #.values()
@@ -558,7 +502,7 @@ class calendar_alarm_manager(osv.osv):
if curEvent.recurrency:
bFound = False
LastFound = False
- for one_date in get_recurrent_dates(curEvent.rrule, curEvent.date, curEvent.exdate, curEvent.vtimezone, context=context) :
+ for one_date in self.pool.get('crm.meeting').get_recurrent_date_by_event(cr,uid,curEvent, context=context) :
in_date_format = datetime.strptime(one_date, '%Y-%m-%d %H:%M:%S');
LastFound = self.do_check_alarm_for_one_date(cr,uid,in_date_format,curEvent,max_delta,cron_interval,notif=False,context=context)
if LastFound:
@@ -582,8 +526,7 @@ class calendar_alarm_manager(osv.osv):
ajax_check_every_seconds = 300
partner = self.pool.get('res.users').browse(cr,uid,uid,context=context).partner_id;
- print "Last alert for partner : ",partner.cal_last_notif
-
+
all_notif = []
all_events = self.get_next_potential_limit_alarm(cr,uid,ajax_check_every_seconds,partner_id=partner.id,mail=False,context=context)
@@ -595,7 +538,7 @@ class calendar_alarm_manager(osv.osv):
if curEvent.recurrency:
bFound = False
LastFound = False
- for one_date in get_recurrent_dates(curEvent.rrule, curEvent.date, curEvent.exdate, curEvent.vtimezone, context=context) :
+ for one_date in self.pool.get("crm.meeting").get_recurrent_date_by_event(cr,uid,curEvent, context=context) :
in_date_format = datetime.strptime(one_date, '%Y-%m-%d %H:%M:%S');
LastFound = self.do_check_alarm_for_one_date(cr,uid,in_date_format,curEvent,max_delta,ajax_check_every_seconds,after=partner.cal_last_notif,mail=False,context=context)
if LastFound:
@@ -608,7 +551,6 @@ class calendar_alarm_manager(osv.osv):
else:
in_date_format = datetime.strptime(curEvent.date, '%Y-%m-%d %H:%M:%S');
LastFound = self.do_check_alarm_for_one_date(cr,uid,in_date_format,curEvent,max_delta,ajax_check_every_seconds,partner.cal_last_notif,mail=False,context=context)
- print "Lastfound = ",LastFound
if LastFound:
for alert in LastFound:
all_notif.append(self.do_notif_reminder(cr,uid,alert,context=context))
@@ -616,7 +558,6 @@ class calendar_alarm_manager(osv.osv):
return all_notif
def do_mail_reminder(self,cr,uid,alert,context=None):
- print 'in Do mail reminder'
if context is None:
context = {}
res = False
@@ -649,7 +590,7 @@ class calendar_alarm_manager(osv.osv):
local_context['action_id'] = self.pool.get('ir.actions.act_window').search(cr, uid, [('view_id','=',act_id)], context=context)[0]
local_context['dbname'] = cr.dbname
local_context['base_url'] = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://localhost:8069', context=context)
- vals = template_pool.generate_email(cr, uid, template_id, attendee.ref.id, context=local_context)
+ vals = template_pool.generate_email(cr, uid, template_id, attendee.event_id.id, context=local_context)
vals['model'] = None #We don't want to have the mail in the tchatter while in queue!
vals['auto_delete'] = True #We don't need mail after it has been sended !
@@ -660,9 +601,6 @@ class calendar_alarm_manager(osv.osv):
if not attendee.partner_id.opt_out:
mail_ids.append(mail_pool.create(cr, uid, vals, context=local_context))
- else:
- print "attendee no email or mail from not found", attendee.email
- print 'Mail ids : ',mail_ids
if mail_ids:
try:
res = mail_pool.send(cr, uid, mail_ids, context=local_context)
@@ -701,30 +639,6 @@ class calendar_alarm_manager(osv.osv):
print "SHOULD BE AN NOTIF ALARM :( FOR EVENT %s / ALARM %s" % (alert['event_id'],alert['alarm_id'])
-#
-# def do_run_stack_scheduler(self,cr,uid,context=None):
-# all_events = self.get_next_potential_limit_alarm(cr,uid,self.EVENT_ALARM_STACK_HOURS,context=context)
-# for event in all_events: #.values()
-# max_delta = all_events[event]['max_duration'];
-# curEvent = self.pool.get('crm.meeting').browse(cr,uid,event,context=context)
-# if curEvent.recurrency:
-# bFound = False
-# bLastFournd = False
-# for one_date in get_recurrent_dates(curEvent.rrule,curEvent.date) :
-# in_date_format = datetime.strptime(one_date, '%Y-%m-%d %H:%M:%S');
-# bLastFound = self.do_check_alarm_for_one_date(cr,uid,in_date_format,curEvent,max_delta,context=context)
-# if bLastFound and not bFound: #if it's the first alarm for this recurrent event
-# bFound = True
-# if bFound and not bLastFound: #if the precendent event had alarm but not this one, we can stop the search fot this event
-# break
-# else:
-# in_date_format = datetime.strptime(curEvent.date, '%Y-%m-%d %H:%M:%S');
-# self.do_check_alarm_for_one_date(cr,uid,in_date_format,curEvent,max_delta,context=context)
-#
-# #Purge all done
-
-
-
class calendar_alarm(osv.osv):
_name = 'calendar.alarm'
_description = 'Event alarm'
@@ -820,19 +734,6 @@ def exp_report(db, uid, object, ids, data=None, context=None):
openerp.service.report.exp_report = exp_report
-
-
-
-
-class ________OLD_CRM_MEETING():
- _name = 'TEMP'
-
-
-
-
-
-
-
class crm_meeting_type(osv.Model):
_name = 'crm.meeting.type'
_description = 'Meeting Type'
@@ -840,6 +741,7 @@ class crm_meeting_type(osv.Model):
'name': fields.char('Name', size=64, required=True, translate=True),
}
+
class crm_meeting(osv.Model):
""" Model for CRM meetings """
_name = 'crm.meeting'
@@ -850,6 +752,39 @@ class crm_meeting(osv.Model):
def do_run_scheduler(self,cr,uid,id,context=None):
self.pool.get('calendar.alarm_manager').do_run_scheduler(cr,uid,context=context)
+ def get_recurrent_date_by_event(self,cr,uid,event,context=None):
+ """Get recurrent dates based on Rule string and all event where recurrent_id is child
+ """
+
+ def todate(date):
+ val = parser.parse(''.join((re.compile('\d')).findall(date)))
+ ## Dates are localized to saved timezone if any, else current timezone.
+ if not val.tzinfo:
+ val = pytz.UTC.localize(val)
+ return val.astimezone(timezone)
+
+ timezone = pytz.timezone(event.vtimezone or context.get('tz') or 'UTC')
+
+ startdate = pytz.UTC.localize(datetime.strptime(event.date, "%Y-%m-%d %H:%M:%S")) #Add "+hh:mm" timezone
+ if not startdate:
+ startdate = datetime.now()
+
+ ## Convert the start date to saved timezone (or context tz) as it'll
+ ## define the correct hour/day asked by the user to repeat for recurrence.
+ startdate = startdate.astimezone(timezone) #transform "+hh:mm" timezone
+
+ rset1 = rrule.rrulestr(str(event.rrule), dtstart=startdate, forceset=True)
+
+ ids_depending = self.search(cr,uid,[('recurrent_id','=',event.id),'|',('active','=',False),('active','=',True)],context=context)
+ all_events = self.browse(cr,uid,ids_depending,context=context)
+
+ for ev in all_events:
+ rset1._exdate.append(todate(ev.recurrent_id_date))
+ #rset1.rdate(pytz.UTC.localize(datetime.strptime(ev.date, "%Y-%m-%d %H:%M:%S")))
+
+ return [d.astimezone(pytz.UTC) for d in rset1]
+
+
def _get_recurrency_end_date(self, data, context=None):
if data.get('recurrency') and data.get('end_type') in ('count', unicode('count')):
data_date_deadline = datetime.strptime(data.get('date_deadline'), '%Y-%m-%d %H:%M:%S')
@@ -946,13 +881,17 @@ class crm_meeting(osv.Model):
result[event] = ""
return result
- def _rrule_write(self, obj, cr, uid, ids, field_name, field_value, args, context=None):
+ def _rrule_write(self, cr, uid, ids, field_name, field_value, args, context=None):
+ if not isinstance(ids, list):
+ ids = [ids]
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 #TO CHECK :/
+ rdate = event.date
update_data = self._parse_rrule(field_value, dict(data), rdate)
+ print 'UPDATE_DATA = ',update_data
data.update(update_data)
self.write(cr, uid, ids, data, context=context)
return True
@@ -997,12 +936,12 @@ class crm_meeting(osv.Model):
#'state': fields.selection([('tentative', 'Uncertain'),('cancelled', 'Cancelled'),('confirmed', 'Confirmed'),],'Status', readonly=True, track_visibility='onchange'),
#FIELD FOR RECURRENCY
- 'exdate': fields.text('Exception Date/Times', help="This property defines the list of date/time exceptions for a recurring calendar component."),
+ #'exdate': fields.text('Exception Date/Times', help="This property defines the list of date/time exceptions for a recurring calendar component."),
'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"),
'recurrency': fields.boolean('Recurrent', help="Recurrent Meeting"),
'recurrent_id': fields.integer('Recurrent ID'),
- #'recurrent_id_date': fields.datetime('Recurrent ID date'),
+ 'recurrent_id_date': fields.datetime('Recurrent ID date'),
#'recurrence_end_date': fields.function(_get_recurrence_end_date, type='datetime', store=True, string='Recurrence end date',priority=30),
'vtimezone': fields.selection(_tz_get, size=64, string='Timezone'),
'end_type' : fields.selection([('count', 'Number of repetitions'), ('end_date','End date')], 'Recurrence Termination'),
@@ -1027,7 +966,8 @@ class crm_meeting(osv.Model):
'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."),
'categ_ids': fields.many2many('crm.meeting.type', 'meeting_category_rel', 'event_id', 'type_id', 'Tags'),
- 'attendee_ids': fields.many2many('calendar.attendee', 'crmmeeting_attendee_rel', 'crmmeeting_id', 'attendee_id', 'Attendees'),
+ 'attendee_ids': fields.one2many('calendar.attendee', 'event_id', 'Attendees', ondelete='cascade'),
+ #'attendee_ids': fields.many2many('calendar.attendee', 'crmmeeting_attendee_rel', 'crmmeeting_id', 'attendee_id', 'Attendees', ondelete='cascade'),
'partner_ids': fields.many2many('res.partner', string='Attendees', states={'done': [('readonly', True)]}),
'alarm_ids': fields.many2many('calendar.alarm', string='Reminders'),
}
@@ -1073,8 +1013,9 @@ class crm_meeting(osv.Model):
duration = 1.00
value['duration'] = duration
- start = datetime.strptime(start_date, "%Y-%m-%d %H:%M:%S")
+
if allday: # For all day event
+ start = datetime.strptime(start_date.split(' ')[0].split('T')[0], "%Y-%m-%d")
duration = 24.0
value['duration'] = duration
# change start_date's time to 00:00:00 in the user's timezone
@@ -1083,8 +1024,9 @@ class crm_meeting(osv.Model):
start = pytz.utc.localize(start).astimezone(tz) # convert start in user's timezone
#start = start.replace(hour=0, minute=0, second=0) # remove time
start = start.astimezone(pytz.utc) # convert start back to utc
- value['date'] = start.strftime("%Y-%m-%d %H:%M:%S")
-
+ value['date'] = start.strftime("%Y-%m-%d") + ' 00:00:00'
+ else:
+ start = datetime.strptime(start_date, "%Y-%m-%d %H:%M:%S")
if end_date and not duration:
end = datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S")
@@ -1105,17 +1047,17 @@ class crm_meeting(osv.Model):
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:
- r_ids = self.search(cr,uid,[('recurrent_id','=',event_id)],context=context)
- self.unlink(cr, uid, r_ids, context=context)
- return True
+# 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:
+# r_ids = self.search(cr,uid,[('recurrent_id','=',event_id)],context=context)
+# self.unlink(cr, uid, r_ids, context=context)
+# return True
def new_invitation_token(self, cr, uid, record, partner_id):
db_uuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
@@ -1141,7 +1083,7 @@ class crm_meeting(osv.Model):
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': event.id,
+ 'event_id': event.id,
'access_token': access_token,
'email': partner.email,
}, context=context)
@@ -1157,9 +1099,6 @@ class crm_meeting(osv.Model):
print "Send mail... from ",mail_from, " to ",att_id
if self.pool.get('calendar.attendee')._send_mail_to_attendees(cr, uid, att_id, email_from = mail_from, context=context):
self.message_post(cr, uid, event.id, body=_("An invitation email has been sent to attendee %s") % (partner.name,),subtype="base_calendar.subtype_invitation", context=context)
- else:
- print "DON'T SEND MAIL TO MYSELF !"
-
if new_attendees:
self.write(cr, uid, [event.id], {'attendee_ids': [(4, att) for att in new_attendees]},context=context)
@@ -1175,7 +1114,7 @@ class crm_meeting(osv.Model):
attendee_ids_to_remove = []
if partner_ids_to_remove:
- attendee_ids_to_remove =self.pool.get("calendar.attendee").search(cr,uid,[('partner_id.id','in',partner_ids_to_remove),('ref.id','=',event.id)],context=context)
+ attendee_ids_to_remove =self.pool.get("calendar.attendee").search(cr,uid,[('partner_id.id','in',partner_ids_to_remove),('event_id.id','=',event.id)],context=context)
if attendee_ids_to_remove:
self.pool.get("calendar.attendee").unlink(cr, uid, attendee_ids_to_remove, context)
## NEED TO UNSUBSCRIBE ?
@@ -1195,14 +1134,21 @@ class crm_meeting(osv.Model):
if not context:
context = {}
+ if isinstance(select, (str, int, long)):
+ ids_to_browse = [select] #keep select for return
+ else:
+ ids_to_browse = select
+
result = []
- for data in self.read(cr, uid, select, ['rrule', 'recurrency', 'exdate', 'date', 'vtimezone'], context=context):
- if not data['recurrency'] or not data['rrule']:
- result.append(data['id'])
+ for ev in self.browse(cr, uid, select, context=context):
+ if not ev.recurrency or not ev.rrule:
+ result.append(ev.id)
continue
# event_date = datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
# event_date = pytz.UTC.localize(event_date)
- rdates = get_recurrent_dates(data['rrule'], data['date'], data['exdate'], data['vtimezone'], context=context)
+
+ rdates = self.get_recurrent_date_by_event(cr, uid, ev, context=context)
+
for r_date in rdates:
# fix domain evaluation
# step 1: check date and replace expression by True or False, replace other expressions by True
@@ -1245,13 +1191,15 @@ class crm_meeting(osv.Model):
if [True for item in new_pile if not item]:
continue
# idval = real_id2base_calendar_id(data['id'], r_date.strftime("%Y-%m-%d %H:%M:%S"))
- idval = '%d-%s' % (data['id'], r_date.strftime("%Y%m%d%H%M%S"))
+ idval = '%d-%s' % (ev.id, r_date.strftime("%Y%m%d%H%M%S"))
result.append(idval)
+
if isinstance(select, (str, int, long)):
return ids and ids[0] or False
else:
ids = list(set(result))
+
return ids
def compute_rule_string(self, data):
@@ -1360,6 +1308,7 @@ class crm_meeting(osv.Model):
data['end_type'] = 'count'
else:
data['end_type'] = 'end_date'
+
return data
#def _get_data(self, cr, uid, id, context=None):
@@ -1497,8 +1446,7 @@ class crm_meeting(osv.Model):
new_arg = (arg[0], arg[1], new_id)
new_args.append(new_arg)
#offset, limit and count must be treated separately as we may need to deal with virtual ids
- print 'AFTER SEARCH',new_args
-
+
res = super(crm_meeting,self).search(cr, uid, new_args, offset=0, limit=0, order=order, context=context, count=False)
if context.get('virtual_id', True):
@@ -1521,6 +1469,8 @@ class crm_meeting(osv.Model):
return res
def write(self, cr, uid, ids, values, context=None):
+ print "Write : ",ids
+ print values
def _only_changes_to_apply_on_real_ids(field_names):
''' return True if changes are only to be made on the real ids'''
for field in field_names:
@@ -1535,9 +1485,10 @@ class crm_meeting(osv.Model):
new_id = False
# Special write of complex IDS
- for event_id in ids[:]:
+ for event_id in ids:
if len(str(event_id).split('-')) == 1:
continue
+
ids.remove(event_id)
real_event_id = base_calendar_id2real_id(event_id)
@@ -1550,16 +1501,18 @@ class crm_meeting(osv.Model):
#if edit one instance of a reccurrent id
data = self.read(cr, uid, event_id, ['date', 'date_deadline', \
- 'rrule', 'duration', 'exdate'])
+ 'rrule', 'duration'])#, 'exdate'])
if data.get('rrule'):
data.update(
values,
recurrent_id=real_event_id,
- #recurrent_id_date=data.get('date'),
+ recurrent_id_date=data.get('date'),
rrule_type=False,
rrule='',
recurrency=False,
+ end_date = datetime.strptime(values.get('date',False) or data.get('date'),"%Y-%m-%d %H:%M:%S") + timedelta(hours=values.get('duration',False) or data.get('duration'))
)
+
#do not copy the id
if data.get('id'):
del(data['id'])
@@ -1567,9 +1520,10 @@ class crm_meeting(osv.Model):
date_new = event_id.split('-')[1]
date_new = time.strftime("%Y%m%dT%H%M%SZ", time.strptime(date_new, "%Y%m%d%H%M%S"))
- exdate = (data['exdate'] and (data['exdate'] + ',') or '') + date_new
- res = super(crm_meeting, self).write(cr, uid, [real_event_id], {'exdate': exdate})
-
+
+ #exdate = (data['exdate'] and (data['exdate'] + ',') or '') + date_new
+ #res = super(crm_meeting, self).write(cr, uid, [real_event_id], {'exdate': exdate})
+
context.update({'active_id': new_id, 'active_ids': [new_id]})
continue
@@ -1586,19 +1540,14 @@ class crm_meeting(osv.Model):
if values.get('partner_ids', False):
attendees_create = self.create_attendees(cr, uid, ids, context)
- if values.get('date', False) and not context.get('install_mode',False): #Not send mail when install data
- print 'Id notified (ids|new_id) : ',ids,"|",new_id
+ if values.get('date', False) and not context.get('install_mode',False) and values.get('active',True): #Not send mail when install data
the_id = new_id or (ids and int(ids[0]));
- print "Date has been changed !!!! --> SEND MAIL"
if attendees_create:
attendees_create = attendees_create[the_id]
mail_to_ids = list(set(attendees_create['old_attendee_ids']) - set(attendees_create['removed_attendee_ids']))
- print 'xxxToSend to ', mail_to_ids
else:
-
mail_to_ids = [att.id for att in self.browse(cr,uid,the_id,context=context).attendee_ids]
- print 'yyyToSend to ', mail_to_ids
if mail_to_ids:
current_user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
@@ -1619,7 +1568,9 @@ class crm_meeting(osv.Model):
if vals.get('recurrency', True) and vals.get('end_type', 'count') in ('count', unicode('count')) and \
(vals.get('rrule_type') or vals.get('count') or vals.get('date') or vals.get('date_deadline')):
vals['end_date'] = self._get_recurrency_end_date(vals, context=context)
-
+
+
+ print "CREATE WITH VALUES",vals
res = super(crm_meeting, self).create(cr, uid, vals, context=context)
#res = self.write(cr, uid, id_res,vals, context)
@@ -1650,7 +1601,7 @@ class crm_meeting(osv.Model):
context = {}
fields2 = fields and fields[:] or None
- EXTRAFIELDS = ('class','user_id','duration', 'date','rrule', 'vtimezone', 'exdate')
+ EXTRAFIELDS = ('class','user_id','duration', 'date','rrule', 'vtimezone')#, 'exdate')
for f in EXTRAFIELDS:
if fields and (f not in fields):
fields2.append(f)
@@ -1674,8 +1625,7 @@ class crm_meeting(osv.Model):
res = real_data[real_id].copy()
ls = base_calendar_id2real_id(base_calendar_id, with_date=res and res.get('duration', 0) or 0)
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
- recurrent_dates = [d.strftime("%Y-%m-%d %H:%M:%S") for d in get_recurrent_dates(res['rrule'], res['date'], res['exdate'],res['vtimezone'], context=context)]
-
+ #recurrent_dates = [d.strftime("%Y-%m-%d %H:%M:%S") for d in get_recurrent_dates(res['rrule'], res['date'], res['exdate'],res['vtimezone'], context=context)]
#if not (ls[1] in recurrent_dates or ls[1] in res['exdate']): #when update a recurrent event
res['date'] = ls[1]
@@ -1706,53 +1656,78 @@ class crm_meeting(osv.Model):
return result and result[0] or False
return result
- def unlink(self, cr, uid, ids, context=None):
+
+ def count_left_instance(self,cr,uid,event_id,context=None):
+
+ event = self.browse(cr,uid,event_id,context=context)
+ if event.recurrent_id and event.recurrent_id > 0:
+ parent_event_id = event.recurrent_id
+ else:
+ parent_event_id = event.id
+ domain = ['|', ('id', '=', parent_event_id), ('recurrent_id', '=', parent_event_id)]
+
+ count = self.search(cr, uid, domain, context=context)
+ print "Count = ",count
+ return len(count)
+
+ def get_linked_ids(self,cr,uid,event_id,show_unactive=True,context=None):
+ event = self.browse(cr,uid,event_id,context=context)
+ if event.recurrent_id and event.recurrent_id > 0:
+ parent_event_id = event.recurrent_id
+ else:
+ parent_event_id = event.id
+
+ domain = ['|', ('id', '=', parent_event_id), ('recurrent_id', '=', parent_event_id)]
+
+ if show_unactive:
+ domain += ['|',('active', '=', True), ('active', '=', False)]
+
+ return super(crm_meeting, self).search(cr, uid, domain, context=context)
+
+ def delete(self,cr,uid,ids,context=None):
+ if not isinstance(ids, list):
+ ids = [ids]
+ all_ids = []
+ for id_to_unlink in ids:
+ all_ids += self.get_linked_ids(cr, uid, id_to_unlink, context=context)
+ print "in deleTe functIon === ids : %s, all_ids : %s" % (ids,all_ids)
+ all_ids = list(set(all_ids))
+ res = super(crm_meeting, self).unlink(cr, uid, all_ids, context=context)
+ return all_ids
+
+
+ def unlink(self, cr, uid, ids,unlink_level=0, context=None):
+ print "IN UNLINK !!!"
if not isinstance(ids, list):
ids = [ids]
res = False
- attendee_obj=self.pool.get('calendar.attendee')
- for event_id in ids[:]:
- if len(str(event_id).split('-')) == 1:
- continue
- real_event_id = base_calendar_id2real_id(event_id)
- data = self.read(cr, uid, real_event_id, ['exdate'], context=context)
- date_new = event_id.split('-')[1]
- date_new = time.strftime("%Y%m%dT%H%M%S", time.strptime(date_new, "%Y%m%d%H%M%S"))
- exdate = (data['exdate'] and (data['exdate'] + ',') or '') + date_new
- self.write(cr, uid, [real_event_id], {'exdate': exdate}, context=context)
- ids.remove(event_id)
- for event in self.browse(cr, uid, ids, context=context):
- if event.attendee_ids:
- attendee_obj.unlink(cr, uid, [x.id for x in event.attendee_ids], context=context)
+ ids_to_exclure = []
+ ids_to_unlink = []
+
+ #One time moved to google_Calendar, we can specify, an if not in google, and not rec or get_inst = 0, we delete it
+ for event_id in ids:
+ #if unlink_level == 1 and len(str(event_id).split('-')) == 1: ## if ID REAL
+ if unlink_level == 1 and len(str(event_id).split('-')) == 1: ## if ID REAL
+ if self.browse(cr,uid,event_id).recurrent_id:
+ print "Could not be deleted ! because instance of recursive"
+ ids_to_exclure.append(event_id)
+ else:
+ ids_to_unlink.append(event_id)
+ else:
+ print "Could not be deleted ! because instance virtual"
+ ids_to_exclure.append(event_id)
+
- res = super(crm_meeting, self).unlink(cr, uid, ids, context=context)
- self.unlink_events(cr, uid, ids, context=context)
+ if ids_to_unlink:
+ res = super(crm_meeting, self).unlink(cr, uid, ids_to_unlink, context=context)
+
+ if ids_to_exclure:
+ for id_to_exclure in ids_to_exclure:
+ res = self.write(cr, uid, id_to_exclure, {'active': False}, context=context)
+
return res
-
-
-
-# class mail_mail(osv.osv):
-# _inherit = "mail.mail"
-#
-# _columns = {
-# 'date_trigger': fields.datetime('date_trigger'),
-# }
-#
-# def process_email_queue(self, cr, uid, ids=None, context=None):
-# if context is None:
-# context = {}
-# import ipdb; ipdb.set_trace();
-# context['filters'] = (['|',('date_trigger', '=', False),('date_trigger', '>=', datetime.now().strftime("%Y-%m-%d %H:%M:%S"))]) #datetime.now().strftime("%Y-%m-%d %H:%M:%S")
-# # ids_to_send = ids;
-# # for mail in self.browse(cr,uid,ids,context=context):
-# # if mail.date_trigger and datetime.strptime(mail.date_trigger, '%Y-%m-%d %H:%M:%S') > datetime.now():
-# # ids_to_send.remove(mail.id)
-# #
-# # return super(mail_mail, self).send(cr, uid, ids_to_send, auto_commit=auto_commit, raise_exception=raise_exception, context=context)
-# return super(mail_mail, self).process_email_queue(cr, uid, ids=ids, context=context)
-
-
+
class mail_message(osv.osv):
_inherit = "mail.message"
diff --git a/addons/base_calendar/static/src/css/base_calender.css b/addons/base_calendar/static/src/css/base_calender.css
index 2e3e963fb2c..f8858d8b88a 100644
--- a/addons/base_calendar/static/src/css/base_calender.css
+++ b/addons/base_calendar/static/src/css/base_calender.css
@@ -67,3 +67,7 @@
span.no-wrap {
white-space:nowrap
}
+
+.cal_tab {
+ margin: 20 0 20 0;
+}
diff --git a/addons/google_base_account/controllers/main.py b/addons/google_base_account/controllers/main.py
index ce7909da6cf..cb729e10c79 100644
--- a/addons/google_base_account/controllers/main.py
+++ b/addons/google_base_account/controllers/main.py
@@ -16,54 +16,62 @@ class google_auth(http.Controller):
state = simplejson.loads(kw['state'])
- #action = state.get('a')
- #menu = state.get('m')
dbname = state.get('d')
- #service = state.get('s')
url_return = state.get('from')
registry = openerp.modules.registry.RegistryManager.get(dbname)
with registry.cursor() as cr:
#TODO CHECK IF REQUEST OK
registry.get('google.calendar').set_all_tokens(cr,request.session.uid,kw['code'])
- registry.get('google.calendar').set_primary_id(cr,request.session.uid)
+ #registry.get('google.calendar').set_primary_id(cr,request.session.uid)
return werkzeug.utils.redirect(url_return)
- #@openerp.addons.web.http.route('/web_calendar_sync/sync_calendar/sync_data', type='json', auth='user')
@http.route('/web_calendar_sync/sync_calendar/sync_data', type='json', auth='user')
def sync_data(self, arch, fields, model,**kw):
- calendar_info = {
- 'field_data':{},
- 'date_start':arch['attrs'].get('date_start'),
- 'date_stop':arch['attrs'].get('date_stop'),
- 'calendar_string':arch['attrs'].get('string'),
- 'model':model
- }
- for field, data in fields.items():
- calendar_info['field_data'][field] = {
- 'type': data.get('type'),
- 'string': data.get('string')
- }
+
if model == 'crm.meeting':
- model_obj = request.registry.get('crm.meeting.synchronize')
+ gs_obj = request.registry.get('google.service')
gc_obj = request.registry.get('google.calendar')
-
- #We check that user has already accepted openerp to acces his calendar !
- if not gc_obj.get_refresh_token(request.cr, request.uid,context=kw.get('LocalContext')):
+
+ #We check that admin has already configure api for google synchronization !
+ client_id = gs_obj.get_client_id(request.cr, request.uid,'calendar',context=kw.get('LocalContext'))
+
+ if not client_id or client_id == '':
+ return {
+ "status" : "NeedConfigFromAdmin",
+ "url" : ''
+ }
+
+ #We check that user has already accepted openerp to access his calendar !
+ if gc_obj.need_authorize(request.cr, request.uid,context=kw.get('LocalContext')):
url = gc_obj.authorize_google_uri(request.cr, request.uid, from_url=kw.get('fromurl'),context=kw.get('LocalContext'))
return {
"status" : "NeedAuth",
"url" : url
}
- #We lunch th synchronization
- print "ORI COONTEXT = ",kw.get('LocalContext')
- model_obj.synchronize_events(request.cr, request.uid, [], kw.get('LocalContext'))
- else:
- model_obj = request.registry.get('google.calendar')
- model_obj.synchronize_calendar(request.cr, request.uid, calendar_info, kw.get('LocalContext'))
+ #We launch the synchronization
+ result = gc_obj.synchronize_events(request.cr, request.uid, [], kw.get('LocalContext'))
+ return result
+ else:
+ calendar_info = {
+ 'field_data':{},
+ 'date_start':arch['attrs'].get('date_start'),
+ 'date_stop':arch['attrs'].get('date_stop'),
+ 'calendar_string':arch['attrs'].get('string'),
+ 'model':model
+ }
+ for field, data in fields.items():
+ calendar_info['field_data'][field] = {
+ 'type': data.get('type'),
+ 'string': data.get('string')
+ }
+
+ print "@@@@@@@@@@@@@@@@@ Is still used !!!!"
+ import ipdb; ipdb.set_trace()
+ gc_obj.synchronize_calendar(request.cr, request.uid, calendar_info, kw.get('LocalContext'))
return { "status" : "SUCCESS" }
@@ -90,6 +98,31 @@ class google_auth(http.Controller):
+
+ @http.route('/gmail/delete_all', type='http', auth='user')
+ def delete_all(self, **kw):
+ gs_obj = request.registry.get('google.service')
+ gc_obj = request.registry.get('google.calendar')
+
+ #We check that admin has already configure api for google synchronization !
+ client_id = gs_obj.get_client_id(request.cr, request.uid,'calendar',context=kw.get('LocalContext'))
+
+ if not client_id or client_id == '':
+ return {
+ "status" : "NeedConfigFromAdmin",
+ "url" : ''
+ }
+
+ #We check that user has already accepted openerp to access his calendar !
+ if gc_obj.need_authorize(request.cr, request.uid,context=kw.get('LocalContext')):
+ url = gc_obj.authorize_google_uri(request.cr, request.uid, from_url=kw.get('fromurl'),context=kw.get('LocalContext'))
+ return {
+ "status" : "NeedAuth",
+ "url" : url
+ }
+
+ #We launch the synchronization
+ gc_obj.delete_all(request.cr, request.uid, kw.get('LocalContext'))
diff --git a/addons/google_base_account/google_base_account.py b/addons/google_base_account/google_base_account.py
index e45a599be51..a895c271314 100644
--- a/addons/google_base_account/google_base_account.py
+++ b/addons/google_base_account/google_base_account.py
@@ -65,14 +65,10 @@ class google_service(osv.osv_memory):
#If no scope is passed, we use service by default to get a default scope
- def _get_authorize_uri(self, cr, uid, from_url, service, scope = False, context=None): #authorize_API
- if not service:
- print 'please specify a service (Calendar for example)!'
+ def _get_authorize_uri(self, cr, uid, from_url, service, scope = False, context=None):
state_obj = {}
state_obj['d'] = cr.dbname
- state_obj['a'] = request and request.params.get('action') or False
- state_obj['m'] = request and request.params.get('menu_id') or False
state_obj['s'] = service
state_obj['from'] = from_url
@@ -155,23 +151,32 @@ class google_service(osv.osv_memory):
if type=='GET':
print "### PARAMS : %s ###" % urllib.urlencode(params)
else:
- print "### PARAMS : %s ###" % (params)
-
+ print "### PARAMS : %s ###" % (params)
print "#########################################"
try:
- if type.upper() == 'GET':
+ if type.upper() == 'GET' or type.upper() == 'DELETE':
data = urllib.urlencode(params)
- req = urllib2.Request(self.get_uri_api() + uri + "?" + data)#,headers)
- elif type.upper() == 'POST':
- req = urllib2.Request(self.get_uri_api() + uri, params, headers)
+ req = urllib2.Request(self.get_uri_api() + uri + "?" + data)
+ elif type.upper() == 'POST' or type.upper() == 'PATCH' or type.upper() == 'PUT':
+ req = urllib2.Request(self.get_uri_api() + uri, params, headers)
else:
- raise ('Method not supported [GET or POST] not in [%s]!' % (type))
-
- content = urllib2.urlopen(req).read()
- res = simplejson.loads(content)
+ raise ('Method not supported [%s] not in [GET, POST, PUT or PATCH]!' % (type))
+ req.get_method = lambda: type.upper()
+ req.add_header('Pragma', 'no-cache')
+ request = urllib2.urlopen(req)
+
+ if request.getcode() == 204:
+ res = True
+ else:
+ content=request.read()
+ res = simplejson.loads(content)
+ print "RESPONSE"
+ print "=========="
+ print res
+ print "=========="
except urllib2.HTTPError,e:
- print e.read()
+ print "ERROR CATCHED : ",e.read()
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired"), context=context)
return res
@@ -180,10 +185,10 @@ class google_service(osv.osv_memory):
return self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url',default='http://www.openerp.com?NoBaseUrl',context=context)
def get_client_id(self, cr, uid, service, context=None):
- return self.pool.get('ir.config_parameter').get_param(cr, uid, 'google_%s_client_id' % (service,),context=context)
+ return self.pool.get('ir.config_parameter').get_param(cr, uid, 'google_%s_client_id' % (service,),context=context).strip()
def get_client_secret(self, cr, uid, service, context=None):
- return self.pool.get('ir.config_parameter').get_param(cr, uid, 'google_%s_client_secret' % (service,),context=context)
+ return self.pool.get('ir.config_parameter').get_param(cr, uid, 'google_%s_client_secret' % (service,),context=context).strip()
def get_uri_oauth(self,a=''): #a = optionnal action
return "https://accounts.google.com/o/oauth2/%s" % (a,)
diff --git a/addons/google_calendar/__init__.py b/addons/google_calendar/__init__.py
index 0b6021f1d0d..721388873ae 100644
--- a/addons/google_calendar/__init__.py
+++ b/addons/google_calendar/__init__.py
@@ -1,2 +1 @@
import google_calendar
-import wizard
\ No newline at end of file
diff --git a/addons/google_calendar/__init__.pyc b/addons/google_calendar/__init__.pyc
index 82e16f37c14..f937a51b89d 100644
Binary files a/addons/google_calendar/__init__.pyc and b/addons/google_calendar/__init__.pyc differ
diff --git a/addons/google_calendar/__openerp__.py b/addons/google_calendar/__openerp__.py
index c11cd989058..3295d86c50c 100644
--- a/addons/google_calendar/__openerp__.py
+++ b/addons/google_calendar/__openerp__.py
@@ -30,13 +30,11 @@ The module adds the possibility to synchronize Google Calendar with OpenERP
""",
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
- 'depends': ['base_calendar'],
+ 'depends': ['google_base_account','base_calendar'],
'js': ['static/src/js/*.js'],
'qweb': ['static/src/xml/*.xml'],
'data': [
- 'google_calendar_view.xml',
'google_calendar_data.xml',
- 'wizard/crm_meeting_view.xml',
],
'demo': [],
'installable': True,
diff --git a/addons/google_calendar/google_calendar.py b/addons/google_calendar/google_calendar.py
index c3d343a70db..cc25b83f9d7 100644
--- a/addons/google_calendar/google_calendar.py
+++ b/addons/google_calendar/google_calendar.py
@@ -31,7 +31,8 @@ from openerp.addons.web.http import request
import werkzeug.utils
from datetime import datetime, timedelta, date
-
+from dateutil import parser
+import pytz
from openerp.osv import fields, osv
from openerp.osv import osv
@@ -55,42 +56,14 @@ class google_calendar(osv.osv):
STR_SERVICE = 'calendar'
- def authorize_google_uri(self,cr,uid,from_url='http://www.openerp.com',context=None):
- url = self.pool.get('google.service')._get_authorize_uri(cr,uid,from_url,self.STR_SERVICE,scope=self.get_calendar_scope(),context=context)
- return url
-
- def set_all_tokens(self,cr,uid,authorization_code,context=None):
- gs_pool = self.pool.get('google.service')
- all_token = gs_pool._get_google_token_json(cr, uid, authorization_code,self.STR_SERVICE,context=context)
-
- vals = {}
- vals['google_%s_rtoken' % self.STR_SERVICE] = all_token.get('refresh_token')
- vals['google_%s_token_validity' % self.STR_SERVICE] = datetime.now() + timedelta(seconds=all_token.get('expires_in')) #NEED A CALCUL
- vals['google_%s_token' % self.STR_SERVICE] = all_token.get('access_token')
- self.pool.get('res.users').write(cr,uid,uid,vals,context=context)
-
- def set_primary_id(self,cr,uid,context=None):
- gs_pool = self.pool.get('google.service')
-
- params = {
- 'fields': 'id',
- 'access_token': self.get_token(cr, uid, context=context)
- }
-
- cal = gs_pool._do_request(cr, uid, "/calendar/v3/calendars/primary/", params, type='GET', context=context)
-
- if cal.get('id',False):
- vals = {}
- vals['google_calendar_id']= cal.get('id')
- self.pool.get('res.users').write(cr,uid,uid,vals,context=context)
- return True
- else:
- return False
+#################################
+## DISCUSS WITH GMAIL ##
+#################################
def generate_data(self, cr, uid, event, context=None):
if event.allday:
- start_date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(event.date, tools.DEFAULT_SERVER_DATETIME_FORMAT) + timedelta(hours=0), context=context).isoformat('T').split('T')[0]
- end_date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(event.date, tools.DEFAULT_SERVER_DATETIME_FORMAT) + timedelta(hours=24), context=context).isoformat('T').split('T')[0]
+ start_date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(event.date, tools.DEFAULT_SERVER_DATETIME_FORMAT) , context=context).isoformat('T').split('T')[0]
+ end_date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(event.date, tools.DEFAULT_SERVER_DATETIME_FORMAT) + timedelta(hours=event.duration), context=context).isoformat('T').split('T')[0]
type = 'date'
else:
start_date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(event.date, tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context).isoformat('T')
@@ -98,6 +71,8 @@ class google_calendar(osv.osv):
type = 'dateTime'
attendee_list = []
+ print "att for event %s : %s" % (event.id,event.attendee_ids)
+
for attendee in event.attendee_ids:
attendee_list.append({
'email':attendee.email or 'NoEmail@mail.com',
@@ -109,37 +84,29 @@ class google_calendar(osv.osv):
"description": event.description or '',
"start":{
type:start_date,
- #'timeZone':context.get('tz') or 'UTC'
+ 'timeZone':'UTC'
},
"end":{
type:end_date,
- #'timeZone':context.get('tz') or 'UTC'
+ 'timeZone':'UTC'
},
"attendees":attendee_list,
"location":event.location or '',
"visibility":event['class'] or 'public',
}
if event.recurrency and event.rrule:
- data["recurrence"]= []
- if event.exdate:
- data["recurrence"].append("EXDATE:"+event.exdate)
-
- data["recurrence"]+=["RRULE:"+event.rrule]
-
-
- #if not recurrency and event.recurrent_id and event.recurrent_id != 0: ###" IMMUTABLE
- # data["recurringEventId"] = event.recurrent_id
-
- print data
+ data["recurrence"]=["RRULE:"+event.rrule]
+
+ if not event.active:
+ data["state"] = "cancelled"
+
return data
- def create_event(self, cr, uid,event, context=None):
+ def create_an_event(self, cr, uid,event, context=None):
gs_pool = self.pool.get('google.service')
- print "CONTEXT : ",context
data = self.generate_data(cr, uid,event, context=context)
-
url = "/calendar/v3/calendars/%s/events?fields=%s&access_token=%s" % ('primary',urllib.quote('id,updated'),self.get_token(cr,uid,context))
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
data_json = simplejson.dumps(data)
@@ -149,14 +116,443 @@ class google_calendar(osv.osv):
return response
+ def delete_an_event(self, cr, uid,event_id, context=None):
+ gs_pool = self.pool.get('google.service')
+
+ params = {
+ 'access_token' : self.get_token(cr,uid,context)
+ }
+ headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
+
+ url = "/calendar/v3/calendars/%s/events/%s" % ('primary',event_id)
+
+ response = gs_pool._do_request(cr, uid, url, params, headers, type='DELETE', context=context)
+ print "@@@RESPONSE",response
+ return response
+
+
+ def get_event_dict(self,cr,uid,token=False,nextPageToken=False,context=None):
+ if not token:
+ token = self.get_token(cr,uid,context)
+
+ gs_pool = self.pool.get('google.service')
+
+ params = {
+ 'fields': 'items,nextPageToken',
+ 'access_token' : token
+ }
+ headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
+
+ url = "/calendar/v3/calendars/%s/events" % 'primary' #?fields=%s&access_token=%s" % ('primary',urllib.quote('items,nextPageToken'), token)
+ if nextPageToken:
+ params['pageToken'] = nextPageToken
+
+
+ content = gs_pool._do_request(cr, uid, url, params, headers, type='GET', context=context)
+
+ google_events_dict = {}
+
+ print content['items']
+
+
+ for google_event in content['items']:
+ google_events_dict[google_event['id']] = google_event
+ #if google_event.get('updated',False):
+# if withInstance:
+# for instance in self.get_instance_event(cr,uid,event_id,context):
+# google_events_dict[instance['id']] = instance
+# else:
+
+ if content.get('nextPageToken', False):
+ google_events_dict.update(self.get_event_dict(cr,uid,token,content['nextPageToken'],context=context))
+ return google_events_dict
+
+ def update_to_google(self, cr, uid, oe_event, google_event, context):
+ crm_meeting = self.pool['crm.meeting']
+ gs_pool = self.pool.get('google.service')
+
+
+ url = "/calendar/v3/calendars/%s/events/%s?fields=%s&access_token=%s" % ('primary', google_event['id'],'id,updated', self.get_token(cr,uid,context))
+ headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
+ data = self.generate_data(cr,uid ,oe_event, context)
+ data['sequence'] = google_event.get('sequence', 0)
+ data_json = simplejson.dumps(data)
+
+
+ content = gs_pool._do_request(cr, uid, url, data_json, headers, type='PATCH', context=context)
+
+ #except urllib2.HTTPError,e:
+ # error_message = json.loads(e.read())
+
+ update_date = datetime.strptime(content['updated'],"%Y-%m-%dT%H:%M:%S.%fz")
+ crm_meeting.write(cr, uid, [oe_event.id], {'oe_update_date':update_date})
+
+ def update_an_event(self, cr, uid,event, context=None):
+ gs_pool = self.pool.get('google.service')
+
+ data = self.generate_data(cr, uid,event, context=context)
+
+ url = "/calendar/v3/calendars/%s/events/%s" % ('primary', event.google_internal_event_id)
+ headers = {}
+ data['access_token'] = self.get_token(cr,uid,context)
+
+ response = gs_pool._do_request(cr, uid, url, data, headers, type='GET', context=context)
+
+ #TODO, il http fail, no event, do DELETE ! ?
+
+ return response
+
+ def update_recurrent_event_exclu(self, cr, uid,instance_id,event_ori_google_id,event_new, context=None):
+ gs_pool = self.pool.get('google.service')
+
+ data = self.generate_data(cr, uid,event_new, context=context)
+
+ data['recurringEventId'] = event_ori_google_id
+ data['originalStartTime'] = event_new.recurrent_id_date
+
+ url = "/calendar/v3/calendars/%s/events/%s?access_token=%s" % ('primary', instance_id,self.get_token(cr,uid,context))
+ headers = { 'Content-type': 'application/json'}
+
+ data['sequence'] = self.get_sequence(cr, uid, instance_id, context)
+
+ data_json = simplejson.dumps(data)
+ response = gs_pool._do_request(cr, uid, url, data_json, headers, type='PUT', context=context)
+
+ #TODO, il http fail, no event, do DELETE ! ?
+
+ return response
+#################################
+## MANAGE SYNCHRO TO GMAIL ##
+#################################
+
+ def update_from_google(self, cr, uid, event, single_event_dict, type, context):
+ crm_meeting = self.pool['crm.meeting']
+ res_partner_obj = self.pool['res.partner']
+ calendar_attendee_obj = self.pool['calendar.attendee']
+ attendee_record= []
+ result = {}
+
+ if single_event_dict.get('attendees',False):
+ for google_attendee in single_event_dict['attendees']:
+ if type == "write":
+ for oe_attendee in event['attendee_ids']:
+ if calendar_attendee_obj.browse(cr, uid ,oe_attendee,context=context).email == google_attendee['email']:
+ calendar_attendee_obj.write(cr, uid,[oe_attendee] ,{'state' : oe_state_mapping[google_attendee['responseStatus']]})
+ google_attendee['found'] = True
+ if google_attendee.get('found',False):
+ continue
+ attendee_id = res_partner_obj.search(cr, uid,[('email', '=', google_attendee['email'])], context=context)
+ if not attendee_id:
+ attendee_id = [res_partner_obj.create(cr, uid,{'email': google_attendee['email'], 'name': google_attendee.get("displayName",False) or google_attendee['email'] }, context=context)]
+ attendee = res_partner_obj.read(cr, uid, attendee_id[0], ['email'], context=context)
+ attendee['partner_id'] = attendee.pop('id')
+ attendee['state'] = oe_state_mapping[google_attendee['responseStatus']]
+ attendee_record.append((0, 0, attendee))
+ UTC = pytz.timezone('UTC')
+ if single_event_dict['start'].get('dateTime',False) and single_event_dict['end'].get('dateTime',False):
+ date = parser.parse(single_event_dict['start']['dateTime'])
+ date_deadline = parser.parse(single_event_dict['end']['dateTime'])
+ delta = date_deadline.astimezone(UTC) - date.astimezone(UTC)
+ date = str(date.astimezone(UTC))[:-6]
+ date_deadline = str(date_deadline.astimezone(UTC))[:-6]
+ allday = False
+ else:
+ date = (single_event_dict['start']['date'] + ' 00:00:00')
+ date_deadline = (single_event_dict['end']['date'] + ' 00:00:00')
+ d_start = datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
+ d_end = datetime.strptime(date_deadline, "%Y-%m-%d %H:%M:%S")
+ delta = (d_end - d_start)
+ allday = True
+
+ result['duration'] = (delta.seconds / 60) / 60.0 + delta.days *24
+
+ update_date = datetime.strptime(single_event_dict['updated'],"%Y-%m-%dT%H:%M:%S.%fz")
+ result.update({
+ 'attendee_ids': attendee_record,
+ 'date': date,
+ 'date_deadline': date_deadline,
+ 'allday': allday,
+ 'name': single_event_dict.get('summary','Event'),
+ 'description': single_event_dict.get('description',False),
+ 'location':single_event_dict.get('location',False),
+ 'class':single_event_dict.get('visibility','public'),
+ 'oe_update_date':update_date,
+ 'google_internal_event_id': single_event_dict.get('id',False),
+ })
+ print "Location = <%s> vs <%s>" % (single_event_dict.get('location'),result['location'])
+ #import ipdb; ipdb.set_trace()
+ if single_event_dict.get("recurrence",False):
+ rrule = [rule for rule in single_event_dict["recurrence"] if rule.startswith("RRULE:")][0][6:]
+ result['rrule']=rrule
+
+ if type == "write":
+ crm_meeting.write(cr, uid, event['id'], result, context=context)
+ elif type == "copy":
+ result['write_type'] = "copy"
+ crm_meeting.write(cr, uid, event['id'], result, context=context)
+ elif type == "create":
+ crm_meeting.create(cr, uid, result, context=context)
+
+ def synchronize_events(self, cr, uid, ids, context=None):
+ gc_obj = self.pool.get('google.calendar')
+
+ self.create_new_events(cr, uid, context=context)
+ cr.commit()
+
+ self.bind_recurring_events_to_google(cr, uid, context)
+ cr.commit()
+
+ res = self.update_events(cr, uid, context)
+
+ return {
+ "status" : res and "NeedRefresh" or "NoNewEventFromGoogle",
+ "url" : ''
+ }
+
+ def create_new_events(self, cr, uid, context):
+ gc_pool = self.pool.get('google.calendar')
+
+ crm_meeting = self.pool['crm.meeting']
+ user_obj = self.pool['res.users']
+ myPartnerID = user_obj.browse(cr,uid,uid,context=context).partner_id.id
+
+ context_norecurrent = context.copy()
+ context_norecurrent['virtual_id'] = False
+
+ new_events_ids = crm_meeting.search(cr, uid,[('partner_ids', 'in', myPartnerID),('google_internal_event_id', '=', False),'|',('recurrent_id', '=', 0),('recurrent_id', '=', False)], context=context_norecurrent)
+
+ for event in crm_meeting.browse(cr, uid, list(set(new_events_ids)), context):
+ response = self.create_an_event(cr,uid,event,context=context)
+ update_date = datetime.strptime(response['updated'],"%Y-%m-%dT%H:%M:%S.%fz")
+ crm_meeting.write(cr, uid, event.id, {'google_internal_event_id': response['id'], 'oe_update_date':update_date})
+ #Check that response OK and return according to that
+
+ return True
+
+
+ def get_empty_synchro_summarize(self) :
+ return {
+ 'oe_event_id' : False,
+ 'oe_isRecurrence':False,
+ 'oe_isInstance':False,
+ 'oe_update':False,
+ 'oe_status':False,
+
+ 'gg_isRecurrence':False,
+ 'gg_isInstance':False,
+ 'gg_update':False,
+ 'gg_status':False,
+ }
+
+
+ def bind_recurring_events_to_google(self, cr, uid, context):
+ crm_meeting = self.pool['crm.meeting']
+
+ user_obj = self.pool['res.users']
+ myPartnerID = user_obj.browse(cr,uid,uid,context=context).partner_id.id
+
+ context_norecurrent = context.copy()
+ context_norecurrent['virtual_id'] = False
+
+
+ new_events_ids = crm_meeting.search(cr, uid,[('partner_ids', 'in', myPartnerID),('google_internal_event_id', '=', False),('recurrent_id', '>', 0),'|',('active', '=', False),('active', '=', True)], context=context_norecurrent)
+ new_google_internal_event_id = False
+
+ for event in crm_meeting.browse(cr, uid, new_events_ids, context):
+ source_record = crm_meeting.browse(cr, uid ,event.recurrent_id,context)
+
+ if event.recurrent_id_date and source_record.allday and source_record.google_internal_event_id:
+ new_google_internal_event_id = source_record.google_internal_event_id +'_'+ event.recurrent_id_date.split(' ')[0].replace('-','')
+ elif event.recurrent_id_date and source_record.google_internal_event_id:
+ new_google_internal_event_id = source_record.google_internal_event_id +'_'+ event.recurrent_id_date.replace('-','').replace(' ','T').replace(':','') + 'Z'
+
+ if new_google_internal_event_id:
+ crm_meeting.write(cr, uid, [event.id], {'google_internal_event_id': new_google_internal_event_id})
+ #Create new event calendar with exlude recuureent_id on RecurringEventID
+
+ #TODO WARNING, NEED TO CHECK THAT EVENT and ALl insatance NOT DELETE IN GMAIL BEFORE !
+ self.update_recurrent_event_exclu(cr,uid,new_google_internal_event_id,source_record.google_internal_event_id,event,context=context)
+
+
+ def check_and_sync(self, cr, uid, oe_event, google_event, context):
+ if datetime.strptime(oe_event.oe_update_date,"%Y-%m-%d %H:%M:%S.%f") > datetime.strptime(google_event['updated'],"%Y-%m-%dT%H:%M:%S.%fz"):
+ self.update_to_google(cr, uid, oe_event, google_event, context)
+ elif datetime.strptime(oe_event.oe_update_date,"%Y-%m-%d %H:%M:%S.%f") < datetime.strptime(google_event['updated'],"%Y-%m-%dT%H:%M:%S.%fz"):
+ self.update_from_google(cr, uid, oe_event, google_event, 'write', context)
+
+ def get_sequence(self,cr,uid,instance_id,context=None):
+ gs_pool = self.pool.get('google.service')
+
+ params = {
+ 'fields': 'sequence',
+ 'access_token' : self.get_token(cr,uid,context)
+ }
+
+ headers = {'Content-type': 'application/json'}
+
+ url = "/calendar/v3/calendars/%s/events/%s" % ('primary',instance_id)
+
+ content = gs_pool._do_request(cr, uid, url, params, headers, type='GET', context=context)
+ return content.get('sequence',0)
+
+ def update_events(self, cr, uid, context):
+ crm_meeting = self.pool['crm.meeting']
+ user_obj = self.pool['res.users']
+ myPartnerID = user_obj.browse(cr,uid,uid,context=context).partner_id.id
+
+ context_novirtual = context.copy()
+ context_novirtual['virtual_id'] = False
+
+ all_event_from_google = self.get_event_dict(cr,uid,context=context)
+ all_new_event_from_google = all_event_from_google.copy()
+
+ events_ids = crm_meeting.search(cr, uid,[('partner_ids', 'in', myPartnerID),('google_internal_event_id', '!=', False),('oe_update_date','!=', False),'|',('active','=',False),('active','=',True)],order='google_internal_event_id',context=context_novirtual) #MORE ACTIVE = False
+
+ print " $ Event IN Google "
+ print " $-----------------"
+ for ev in all_event_from_google:
+ print ' $ %s (%s) [%s]' % (all_event_from_google[ev].get('id'), all_event_from_google[ev].get('sequence'),all_event_from_google[ev].get('status'))
+ print " $-----------------"
+ print ""
+ print " $ Event IN OPENERP "
+ print " $------------------"
+ for event in crm_meeting.browse(cr, uid, events_ids, context):
+ print ' $ %s (%s) [%s]' % (event.google_internal_event_id, event.id,event.active)
+ print " $------------------"
+
+ #For each Event in MY CALENDAR (ALL has been already create in GMAIL in the past)
+
+ # WARNING, NEED TO KEEP IDS SORTED !!!
+ # AS THAT, WE THREAT ALWAYS THE PARENT BEFORE THE RECURRENT
+
+ for event_id in events_ids:
+ event = crm_meeting.browse(cr, uid, event_id, context)
+ cr.commit()
+
+ # IF I HAVE BEEN DELETED FROM GOOGLE
+ if event.google_internal_event_id not in all_event_from_google:
+ print " __ !! OERP %s (%s) NOT IN google" % (event.google_internal_event_id,event.id)
+
+ #If m the parent, we delete all all recurrence
+ if not event.recurrent_id or event.recurrent_id == 0:
+ print " __ !! Master Event (%s) has been deleted has been delete in google" % (event.google_internal_event_id)
+ ids_deleted = crm_meeting.delete(cr,uid,event.id,context=context)
+ print "IDS DELETED : ",ids_deleted
+ for id_deleted in [x for x in ids_deleted if x in events_ids]:
+ #if id_deleted in events_ids:
+ events_ids.remove(id_deleted)
+ else: # I 'm and recurrence, removed from gmail
+ print "Unlink me simply ? Where i m passed ?"
+ raise "Unlink me simply ? Where i m passed ?"
+
+
+ else:
+ print " __ OERP %s (%s) IN google" % (event.google_internal_event_id,event.id)
+
+ if event.active == False:
+ if all_event_from_google[event.google_internal_event_id].get('status')!='cancelled':
+ print " __ !! Event (%s) has been removed from OPENERP" % (event.google_internal_event_id)
+ #if len(crm_meeting.get_linked_ids(cr,uid,event.id,show_unactive=False,context=context)) == 1: #IF I'M ALONE
+ if crm_meeting.count_left_instance(cr,uid,event.id,context=context)==0:
+ print "COUNT LEFT INTANCE==="
+ print crm_meeting.count_left_instance(cr,uid,event.id,context=context)
+ temp = crm_meeting.get_linked_ids(cr,uid,event.id,show_unactive=False,context=context)
+ print "IDS LINKEND : IM ALONE = ",temp
+ print "@1___DELETE FROM GOOGLE THE EVENT AND DELETE FROM OPENERP : ",event.id
+ print "delete event from google : ",event.google_internal_event_id.split('_')[0]
+ print "delete event from openerp : ",event.id
+
+ content = self.delete_an_event(cr,uid,event.google_internal_event_id.split('_')[0],context=context_novirtual)
+ ids_deleted = crm_meeting.delete(cr,uid,event.id,context=context_novirtual)
+ print "IDS DELETED : ",ids_deleted
+ for id_deleted in ids_deleted:
+ if id_deleted in events_ids:
+ events_ids.remove(id_deleted)
+ else :
+ print "@2___DELETE FROM GOOGLE THE EVENT AND HIDE FROM OPENERP : %s [%s]" % (event.id,event.google_internal_event_id)
+ content = self.delete_an_event(cr,uid,event.google_internal_event_id,context=context_novirtual)
+ crm_meeting.unlink(cr,uid,event.id,unlink_level=0,context=context)
+
+ elif all_event_from_google[event.google_internal_event_id].get('status')=='cancelled':
+ print "@3___HAS BEEN REMOVED IN GOOGLE, HIDE IT IN OPENERP : ",event.id
+ crm_meeting.unlink(cr,uid,event.id,unlink_level=1,context=context) #Try to delete really in db if not recurrent
+ else:
+ print "@4___NEED UPDATE : %s " % (event.id)
+ self.check_and_sync(cr, uid, event, all_event_from_google[event.google_internal_event_id], context)
+
+ if event.google_internal_event_id in all_new_event_from_google:
+ del all_new_event_from_google[event.google_internal_event_id]
+
+ #FOR EACH EVENT CREATE IN GOOGLE, WE ADD THEM IN OERP
+ print " $ New Event IN Google "
+ print " $-----------------"
+ for ev in all_new_event_from_google:
+ print ' $ %s (%s) [%s]' % (all_new_event_from_google[ev].get('id'), all_new_event_from_google[ev].get('sequence'),all_new_event_from_google[ev].get('status'))
+ print " $-----------------"
+ print ""
+
+ for new_google_event in all_new_event_from_google.values():
+ if new_google_event.get('status','') == 'cancelled':
+ continue
+# print "#### IN FOR #########"
+ elif new_google_event.get('recurringEventId',False):
+
+ reccurent_event = crm_meeting.search(cr, uid, [('google_internal_event_id', '=', new_google_event['recurringEventId'])])
+
+ new_google_event_id = new_google_event['id'].split('_')[1]
+ if 'T' in new_google_event_id:
+ new_google_event_id = new_google_event_id.replace('T','')[:-1]
+ else:
+ new_google_event_id = new_google_event_id + "000000"
+ print "#############rec_event : ",reccurent_event
+ print "Google id : %s [%s]" % (new_google_event_id,new_google_event['id'])
+ for event_id in reccurent_event:
+ print "EVENT_ID = %s (%s)" % (event_id,event_id.split('-')[1])
+
+ if isinstance(event_id, str) and len(event_id.split('-'))>1 and event_id.split('-')[1] == new_google_event_id:
+ reccurnt_event_id = int(event_id.split('-')[0].strip())
+ parent_event = crm_meeting.read(cr,uid, reccurnt_event_id, [], context)
+ parent_event['id'] = event_id
+ #recurrent update from google
+
+ if new_google_event.get('status','') == 'cancelled':
+ print 'unlink -> cancelled in google'
+ crm_meeting.unlink(cr,uid,event_id,context)
+ else:
+ print "DO COPY?"
+ self.update_from_google(cr, uid, parent_event, new_google_event, "copy", context)
+ else:
+ print "ELSE"
+ elif new_google_event.get('recurrence',False) != False: #If was origin event from recurrent:
+ print "NEED TO CHECK IF AN INSTANCE ACTIVE..."
+ if True: #if a instance exist
+ self.update_from_google(cr, uid, False, new_google_event, "create", context)
+ #
+ else:
+ self.delete_an_event(cr, uid, new_google_event, context)
+ print ''#ELSE WE DELETE THE ORIGIN EVENT
+ else :
+ print "@and not recurring event"
+ #new event from google
+ self.update_from_google(cr, uid, False, new_google_event, "create", context)
+ # del google_events_dict[new_google_event['id']]
+ return True
+
+#################################
+## MANAGE CONNEXION TO GMAIL ##
+#################################
+
def get_token(self,cr,uid,context=None):
current_user = self.pool.get('res.users').browse(cr,uid,uid,context=context)
- if datetime.strptime(current_user.google_calendar_token_validity.split('.')[0], "%Y-%m-%d %H:%M:%S") < datetime.now() - timedelta(minutes=5):
- print "NEED TO RENEW TOKEN",current_user.google_calendar_token_validity , "<", datetime.now() - timedelta(minutes=5)
+
+ if datetime.strptime(current_user.google_calendar_token_validity.split('.')[0], "%Y-%m-%d %H:%M:%S") < (datetime.now() + timedelta(minutes=1)):
+ print "@@ REFRESH TOKEN NEEDED !!!!"
self.do_refresh_token(cr,uid,context=context)
+ print "@@ REFRESH TOKEN DONE !!!!"
current_user.refresh()
else:
- print "KEEP OLD TOKEN",current_user.google_calendar_token_validity , "<", datetime.now() - timedelta(minutes=5)
+ print "TOKEN OK : ",datetime.strptime(current_user.google_calendar_token_validity.split('.')[0], "%Y-%m-%d %H:%M:%S"), " > ", (datetime.now() - timedelta(minutes=1))
+
return current_user.google_calendar_token
def do_refresh_token(self,cr,uid,context=None):
@@ -171,40 +567,44 @@ class google_calendar(osv.osv):
vals['google_%s_token' % self.STR_SERVICE] = all_token.get('access_token')
self.pool.get('res.users').write(cr,uid,uid,vals,context=context)
-
- def get_refresh_token(self,cr,uid,context=None):
- current_user = self.pool.get('res.users').browse(cr,uid,uid,context=context)
- return current_user.google_calendar_rtoken
+ def need_authorize(self,cr,uid,context=None):
+ current_user = self.pool.get('res.users').browse(cr,uid,uid,context=context)
+ return current_user.google_calendar_rtoken == False
def get_calendar_scope(self,RO=False):
readonly = RO and '.readonly' or ''
return 'https://www.googleapis.com/auth/calendar%s' % (readonly)
+ def authorize_google_uri(self,cr,uid,from_url='http://www.openerp.com',context=None):
+ url = self.pool.get('google.service')._get_authorize_uri(cr,uid,from_url,self.STR_SERVICE,scope=self.get_calendar_scope(),context=context)
+ return url
+
+ def set_all_tokens(self,cr,uid,authorization_code,context=None):
+ gs_pool = self.pool.get('google.service')
+ all_token = gs_pool._get_google_token_json(cr, uid, authorization_code,self.STR_SERVICE,context=context)
+
+ vals = {}
+ vals['google_%s_rtoken' % self.STR_SERVICE] = all_token.get('refresh_token')
+ vals['google_%s_token_validity' % self.STR_SERVICE] = datetime.now() + timedelta(seconds=all_token.get('expires_in')) #NEED A CALCUL
+ vals['google_%s_token' % self.STR_SERVICE] = all_token.get('access_token')
+ self.pool.get('res.users').write(cr,uid,uid,vals,context=context)
+
class res_users(osv.osv):
_inherit = 'res.users'
_columns = {
- 'google_calendar_id': fields.char('Primary Calendar ID'),
'google_calendar_rtoken': fields.char('Refresh Token'),
'google_calendar_token': fields.char('User token'),
'google_calendar_token_validity': fields.datetime('Token Validity'),
}
- def get_cal_token_info(self, cr, uid, partner_id=False, context=None):
- if partner_id:
- user = self.pool.get('res.partner').browse(cr,uid,partner_id,context=context).user_id
- else:
- user = self.pool.get('res.users').browse(cr,uid,uid,context=context)
-
- return dict(authcode=user.google_cal_authcode, token=user.google_cal_token, validity=user.google_cal_token_validity,)
-
- def update_cal_token(self,cr,uid,jsontoken,context=None):
- print jsontoken
- import ipdb; ipdb.set_trace();
- self.write(cr,uid,uid,{'xxx' : datetime.now() } ,context=context)
- return "OK"
-
+# def get_cal_token_info(self, cr, uid, partner_id=False, context=None):
+# if partner_id:
+# user = self.pool.get('res.partner').browse(cr,uid,partner_id,context=context).user_id
+# else:
+# user = self.pool.get('res.users').browse(cr,uid,uid,context=context)
+# return dict(authcode=user.google_cal_authcode, token=user.google_cal_token, validity=user.google_cal_token_validity,)
class crm_meeting(osv.osv):
@@ -214,6 +614,7 @@ class crm_meeting(osv.osv):
sync_fields = set(['name', 'description', 'date', 'date_closed', 'date_deadline', 'attendee_ids', 'location', 'class'])
if (set(vals.keys()) & sync_fields) and 'oe_update_date' not in vals.keys():
vals['oe_update_date'] = datetime.now()
+
return super(crm_meeting, self).write(cr, uid, ids, vals, context=context)
def copy(self, cr, uid, id, default=None, context=None):
@@ -233,18 +634,15 @@ class crm_meeting(osv.osv):
'google_internal_event_id': fields.char('Google Calendar Event Id', size=124),
'oe_update_date': fields.datetime('OpenERP Update Date'),
}
-
+ _sql_constraints = [('google_id_uniq','unique(google_internal_event_id)', 'Google ID must be unique!')]
# If attendees are updated, we need to specify that next synchro need an action
class calendar_attendee(osv.osv):
_inherit = 'calendar.attendee'
def write(self, cr, uid, ids, vals, context=None):
- if isinstance(ids, list):
- cr.execute("SELECT crmmeeting_id FROM crmmeeting_attendee_rel WHERE attendee_id = %s"%(ids[0]))
- else:
- cr.execute("SELECT crmmeeting_id FROM crmmeeting_attendee_rel WHERE attendee_id = %s"%(ids))
- event_id = cr.fetchone()[0]
- if event_id:
- self.pool.get('crm.meeting').write(cr, uid, event_id, {'oe_update_date':datetime.now()})
+ for id in ids:
+ ref = vals.get('event_id',self.browse(cr,uid,id,context=context).event_id)
+ self.pool.get('crm.meeting').write(cr, uid, ref, {'oe_update_date':datetime.now()})
+
return super(calendar_attendee, self).write(cr, uid, ids, vals, context=context)
diff --git a/addons/google_calendar/google_calendar.pyc b/addons/google_calendar/google_calendar.pyc
index 1a190173fc1..a323743f43b 100644
Binary files a/addons/google_calendar/google_calendar.pyc and b/addons/google_calendar/google_calendar.pyc differ
diff --git a/addons/google_calendar/google_calendar_data.xml b/addons/google_calendar/google_calendar_data.xml
index dadfaa915e3..85e3ce5d5d5 100644
--- a/addons/google_calendar/google_calendar_data.xml
+++ b/addons/google_calendar/google_calendar_data.xml
@@ -1,14 +1,13 @@
-
+
-
-
\ No newline at end of file
diff --git a/addons/google_calendar/google_calendar_view.xml b/addons/google_calendar/google_calendar_view.xml
deleted file mode 100644
index e99826dae52..00000000000
--- a/addons/google_calendar/google_calendar_view.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
-
- ir.attachment.google.spreadsheet.tree
- ir.attachment
-
-
-
-
-
-
-
-
-
- ir.attachment.google.spreadsheet.form
- ir.attachment
-
-
-
-
-
-
- Google Spreadsheets
- ir.attachment
- form
- tree,form
- {}
- [('url', 'like', '/spreadsheet/')]
- Google Spreadsheets
-
-
-
-
- tree
-
-
-
-
-
-
- form
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/addons/google_calendar/static/src/js/calendar_sync.js b/addons/google_calendar/static/src/js/calendar_sync.js
index 62639c6771f..76570caad4f 100644
--- a/addons/google_calendar/static/src/js/calendar_sync.js
+++ b/addons/google_calendar/static/src/js/calendar_sync.js
@@ -10,15 +10,17 @@ openerp.google_calendar = function(instance) {
instance.web_calendar.FullCalendarView.include({
view_loading: function(r) {
var self = this;
- this.$el.on('click', 'div.oe_dhx_cal_sync_button', function() {
+ this.$el.on('click', 'div.oe_cal_sync_button', function() {
+ console.log("Launch synchro");
self.sync_calendar(r);
});
return this._super(r);
},
- sync_calendar: function(res) {
+ sync_calendar: function(res,button) {
var self = this;
var context = instance.web.pyeval.eval('context');
- console.log("Model is..." + res.model);
+ //$('div.oe_cal_sync_button').hide();
+ $('div.oe_cal_sync_button').prop('disabled',true);
self.rpc('/web_calendar_sync/sync_calendar/sync_data', {
arch: res.arch,
@@ -26,13 +28,21 @@ openerp.google_calendar = function(instance) {
model:res.model,
fromurl: window.location.href,
LocalContext:context
- }).always(function(o) {
+ }).done(function(o) {
+ console.log(o);
+
if (o.status == "NeedAuth") {
alert(_t("You will be redirected on gmail to authorize your OpenErp to access your calendar !"));
window.location = o.url;
}
- console.log(o);
- //self.reload();
+ else if (o.status == "NeedConfigFromAdmin") {
+ alert(_t("Admin need to configure Google Synchronization before to use it !"));
+ window.location = o.url;
+ }
+ else if (o.status == "NeedRefresh"){
+ self.$calendar.fullCalendar('refetchEvents');
+ }
+ $('div.oe_cal_sync_button').prop('disabled',false);
});
}
});
diff --git a/addons/google_calendar/static/src/xml/web_calendar.xml b/addons/google_calendar/static/src/xml/web_calendar.xml
index 7baadaaf183..df09fac6da1 100644
--- a/addons/google_calendar/static/src/xml/web_calendar.xml
+++ b/addons/google_calendar/static/src/xml/web_calendar.xml
@@ -2,9 +2,9 @@
-