[FIX] calendar, google_calendar: multiple fixes with timezones, filters, google sync and dashboards
bzr revid: odo@openerp.com-20140218171508-6li402027u57ltrx
This commit is contained in:
parent
3226a16b99
commit
629daccd56
|
@ -37,6 +37,8 @@ from openerp.tools.translate import _
|
||||||
from openerp.http import request
|
from openerp.http import request
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
|
from werkzeug.exceptions import BadRequest
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -775,7 +777,7 @@ class calendar_event(osv.Model):
|
||||||
else:
|
else:
|
||||||
result[event] = ""
|
result[event] = ""
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _rrule_write(self, 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):
|
if not isinstance(ids, list):
|
||||||
ids = [ids]
|
ids = [ids]
|
||||||
|
@ -788,7 +790,7 @@ class calendar_event(osv.Model):
|
||||||
data.update(update_data)
|
data.update(update_data)
|
||||||
self.write(cr, uid, ids, data, context=context)
|
self.write(cr, uid, ids, data, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _tz_get(self, cr, uid, context=None):
|
def _tz_get(self, cr, uid, context=None):
|
||||||
return [(x.lower(), x) for x in pytz.all_timezones]
|
return [(x.lower(), x) for x in pytz.all_timezones]
|
||||||
|
|
||||||
|
@ -801,7 +803,7 @@ class calendar_event(osv.Model):
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_columns = {
|
_columns = {
|
||||||
'id': fields.integer('ID', readonly=True),
|
'id': fields.integer('ID', readonly=True),
|
||||||
'state': fields.selection([('draft', 'Unconfirmed'), ('open', 'Confirmed')], string='Status', readonly=True, track_visibility='onchange'),
|
'state': fields.selection([('draft', 'Unconfirmed'), ('open', 'Confirmed')], string='Status', readonly=True, track_visibility='onchange'),
|
||||||
'name': fields.char('Meeting Subject', required=True, states={'done': [('readonly', True)]}),
|
'name': fields.char('Meeting Subject', required=True, states={'done': [('readonly', True)]}),
|
||||||
'is_attendee': fields.function(_compute, string='Attendee', type="boolean", multi='attendee'),
|
'is_attendee': fields.function(_compute, string='Attendee', type="boolean", multi='attendee'),
|
||||||
|
@ -843,6 +845,7 @@ class calendar_event(osv.Model):
|
||||||
'attendee_ids': fields.one2many('calendar.attendee', 'event_id', 'Attendees', ondelete='cascade'),
|
'attendee_ids': fields.one2many('calendar.attendee', 'event_id', 'Attendees', ondelete='cascade'),
|
||||||
'partner_ids': fields.many2many('res.partner', string='Attendees', states={'done': [('readonly', True)]}),
|
'partner_ids': fields.many2many('res.partner', string='Attendees', states={'done': [('readonly', True)]}),
|
||||||
'alarm_ids': fields.many2many('calendar.alarm', string='Reminders', ondelete="restrict"),
|
'alarm_ids': fields.many2many('calendar.alarm', string='Reminders', ondelete="restrict"),
|
||||||
|
|
||||||
}
|
}
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'end_type': 'count',
|
'end_type': 'count',
|
||||||
|
@ -872,9 +875,6 @@ class calendar_event(osv.Model):
|
||||||
|
|
||||||
"""Returns duration and/or end date based on values passed
|
"""Returns duration and/or end date based on values passed
|
||||||
@param ids: List of calendar event's IDs.
|
@param ids: List of calendar event's IDs.
|
||||||
@param start_date: Starting date
|
|
||||||
@param duration: Duration between start date and end date
|
|
||||||
@param end_date: Ending Datee
|
|
||||||
"""
|
"""
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
@ -1353,15 +1353,55 @@ class calendar_event(osv.Model):
|
||||||
res = super(calendar_event, self).copy(cr, uid, calendar_id2real_id(id), default, context)
|
res = super(calendar_event, self).copy(cr, uid, calendar_id2real_id(id), default, context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def _detach_one_event(self, cr, uid, id, values=dict(), context=None):
|
||||||
|
real_event_id = calendar_id2real_id(id)
|
||||||
|
data = self.read(cr, uid, id, ['date', 'date_deadline', 'rrule', 'duration'])
|
||||||
|
|
||||||
|
if data.get('rrule'):
|
||||||
|
data.update(
|
||||||
|
values,
|
||||||
|
recurrent_id=real_event_id,
|
||||||
|
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'])
|
||||||
|
new_id = self.copy(cr, uid, real_event_id, default=data, context=context)
|
||||||
|
return new_id
|
||||||
|
|
||||||
|
def open_after_detach_event(self, cr, uid, ids, context=None):
|
||||||
|
if context is None:
|
||||||
|
context = {}
|
||||||
|
|
||||||
|
new_id = self._detach_one_event(cr, uid, ids[0], context=context)
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_model': 'calendar.event',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'res_id': new_id,
|
||||||
|
'target': 'current',
|
||||||
|
'flags': {'form': {'action_buttons': True, 'options' : { 'mode' : 'edit' } } }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def write(self, cr, uid, ids, values, context=None):
|
def write(self, cr, uid, ids, values, context=None):
|
||||||
def _only_changes_to_apply_on_real_ids(field_names):
|
def _only_changes_to_apply_on_real_ids(field_names):
|
||||||
''' return True if changes are only to be made on the real ids'''
|
''' return True if changes are only to be made on the real ids'''
|
||||||
for field in field_names:
|
for field in field_names:
|
||||||
if field not in ['name', 'message_follower_ids','oe_update_date']:
|
if field in ['date','active']:
|
||||||
return False
|
return True
|
||||||
return True
|
return False
|
||||||
|
|
||||||
context = context or {}
|
context = context or {}
|
||||||
|
|
||||||
|
|
||||||
if isinstance(ids, (str,int, long)):
|
if isinstance(ids, (str,int, long)):
|
||||||
if len(str(ids).split('-')) == 1:
|
if len(str(ids).split('-')) == 1:
|
||||||
|
@ -1383,31 +1423,14 @@ class calendar_event(osv.Model):
|
||||||
# if we are setting the recurrency flag to False or if we are only changing fields that
|
# if we are setting the recurrency flag to False or if we are only changing fields that
|
||||||
# should be only updated on the real ID and not on the virtual (like message_follower_ids):
|
# should be only updated on the real ID and not on the virtual (like message_follower_ids):
|
||||||
# then set real ids to be updated.
|
# then set real ids to be updated.
|
||||||
if not values.get('recurrency', True) or _only_changes_to_apply_on_real_ids(values.keys()):
|
if not values.get('recurrency', True) or not _only_changes_to_apply_on_real_ids(values.keys()):
|
||||||
ids.append(real_event_id)
|
ids.append(real_event_id)
|
||||||
continue
|
continue
|
||||||
|
else:
|
||||||
#if edit one instance of a reccurrent id
|
data = self.read(cr, uid, event_id, ['date', 'date_deadline', 'rrule', 'duration'])
|
||||||
data = self.read(cr, uid, event_id, ['date', 'date_deadline', 'rrule', 'duration'])
|
if data.get('rrule'):
|
||||||
if data.get('rrule'):
|
new_id = self._detach_one_event(cr, uid, event_id, values, context=None)
|
||||||
data.update(
|
|
||||||
values,
|
|
||||||
recurrent_id=real_event_id,
|
|
||||||
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'])
|
|
||||||
new_id = self.copy(cr, uid, real_event_id, default=data, context=context)
|
|
||||||
context.update({'active_id': new_id, 'active_ids': [new_id]})
|
|
||||||
continue
|
|
||||||
|
|
||||||
res = super(calendar_event, self).write(cr, uid, ids, values, context=context)
|
res = super(calendar_event, self).write(cr, uid, ids, values, context=context)
|
||||||
|
|
||||||
# set end_date for calendar searching
|
# set end_date for calendar searching
|
||||||
|
@ -1473,7 +1496,6 @@ class calendar_event(osv.Model):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
fields2 = fields and fields[:] or None
|
fields2 = fields and fields[:] or None
|
||||||
|
|
||||||
EXTRAFIELDS = ('class', 'user_id', 'duration', 'date', 'rrule', 'vtimezone')
|
EXTRAFIELDS = ('class', 'user_id', 'duration', 'date', 'rrule', 'vtimezone')
|
||||||
for f in EXTRAFIELDS:
|
for f in EXTRAFIELDS:
|
||||||
if fields and (f not in fields):
|
if fields and (f not in fields):
|
||||||
|
@ -1518,6 +1540,7 @@ class calendar_event(osv.Model):
|
||||||
for k in EXTRAFIELDS:
|
for k in EXTRAFIELDS:
|
||||||
if (k in r) and (fields and (k not in fields)):
|
if (k in r) and (fields and (k not in fields)):
|
||||||
del r[k]
|
del r[k]
|
||||||
|
|
||||||
if isinstance(ids, (str, int, long)):
|
if isinstance(ids, (str, int, long)):
|
||||||
return result and result[0] or False
|
return result and result[0] or False
|
||||||
return result
|
return result
|
||||||
|
@ -1531,7 +1554,7 @@ class calendar_event(osv.Model):
|
||||||
ids_to_unlink = []
|
ids_to_unlink = []
|
||||||
|
|
||||||
# One time moved to google_Calendar, we can specify, if not in google, and not rec or get_inst = 0, we delete it
|
# One time moved to google_Calendar, we can specify, if not in google, and not rec or get_inst = 0, we delete it
|
||||||
for event_id in ids:
|
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:
|
if self.browse(cr, uid, event_id).recurrent_id:
|
||||||
ids_to_exclure.append(event_id)
|
ids_to_exclure.append(event_id)
|
||||||
|
|
|
@ -51,6 +51,11 @@
|
||||||
</div>
|
</div>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="Meeting Details">
|
<page string="Meeting Details">
|
||||||
|
<group attrs="{'invisible': [('recurrency','==',False)]}" class="oe_edit_only ">
|
||||||
|
<p class='alert alert-warning'> This event is linked to a recurrence...<br/>
|
||||||
|
<button type="object" name="open_after_detach_event" string="Update only this instance" help="Click here to update only this instance and not all recurrences. " class="oe_link"/>
|
||||||
|
</p>
|
||||||
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="date" string="Starting at" on_change="onchange_dates(date, duration, False, allday)"/>
|
<field name="date" string="Starting at" on_change="onchange_dates(date, duration, False, allday)"/>
|
||||||
|
@ -124,7 +129,7 @@
|
||||||
<group>
|
<group>
|
||||||
<field name="class"/>
|
<field name="class"/>
|
||||||
<field name="show_as"/>
|
<field name="show_as"/>
|
||||||
<field name="rrule" invisible="1" readonly="0" />
|
<field name="rrule" invisible="1" readonly="0" />
|
||||||
<field name="recurrent_id" invisible="1" />
|
<field name="recurrent_id" invisible="1" />
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
|
|
|
@ -77,7 +77,6 @@ openerp.calendar = function(instance) {
|
||||||
if(instance.session.session_is_valid(self.db) && instance.session.username != "anonymous") {
|
if(instance.session.session_is_valid(self.db) && instance.session.username != "anonymous") {
|
||||||
self.redirect_meeting_view(self.db,self.action,self.id,self.view);
|
self.redirect_meeting_view(self.db,self.action,self.id,self.view);
|
||||||
} else {
|
} else {
|
||||||
alert('in anonymous or null ');
|
|
||||||
self.open_invitation_form(self.attendee_data);
|
self.open_invitation_form(self.attendee_data);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -94,7 +93,6 @@ openerp.calendar = function(instance) {
|
||||||
return location.replace(action_url);
|
return location.replace(action_url);
|
||||||
};
|
};
|
||||||
reload_page();
|
reload_page();
|
||||||
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,14 @@
|
||||||
!python {model: calendar.event}: |
|
!python {model: calendar.event}: |
|
||||||
ids = self.search(cr, uid, [('date', '>=', '2011-04-30 16:00:00'), ('date', '<=', '2011-05-31 00:00:00')], context={'virtual_id': True} )
|
ids = self.search(cr, uid, [('date', '>=', '2011-04-30 16:00:00'), ('date', '<=', '2011-05-31 00:00:00')], context={'virtual_id': True} )
|
||||||
before = self.search(cr, uid, [('date', '>=', '2011-04-30 16:00:00'), ('date', '<=', '2011-05-31 00:00:00')], context={'virtual_id': False})
|
before = self.search(cr, uid, [('date', '>=', '2011-04-30 16:00:00'), ('date', '<=', '2011-05-31 00:00:00')], context={'virtual_id': False})
|
||||||
self.write(cr, uid,[ids[1]], {'name':'New Name','recurrency' : True}, context={'virtual_id': True})
|
# We start by detach the event
|
||||||
|
newid = self._detach_one_event(cr, uid,ids[1])
|
||||||
|
self.write(cr, uid,[newid], {'name':'New Name','recurrency' : True}, context={'virtual_id': True})
|
||||||
after = self.search(cr, uid, [('date', '>=', '2011-04-30 16:00:00'), ('date', '<=', '2011-05-31 00:00:00')], context={'virtual_id': False})
|
after = self.search(cr, uid, [('date', '>=', '2011-04-30 16:00:00'), ('date', '<=', '2011-05-31 00:00:00')], context={'virtual_id': False})
|
||||||
assert len(after) == len(before)+1, 'Wrong number of events found, after to have moved a virtual event'
|
assert len(after) == len(before)+1, 'Wrong number of events found, after to have moved a virtual event'
|
||||||
new_id = list(set(after)-set(before))[0]
|
new_id = list(set(after)-set(before))[0]
|
||||||
new_event = self.browse(cr,uid,new_id,context=context)
|
new_event = self.browse(cr,uid,new_id,context=context)
|
||||||
assert new_event.recurrent_id == before[0], 'Recurrent_id not correctly passed to the new event'
|
assert new_event.recurrent_id == before[0], 'Recurrent_id not correctly passed to the new event'
|
||||||
-
|
-
|
||||||
Now I will make All day event and test it
|
Now I will make All day event and test it
|
||||||
-
|
-
|
||||||
|
@ -58,7 +60,6 @@
|
||||||
duration: 1
|
duration: 1
|
||||||
interval: days
|
interval: days
|
||||||
type: notification
|
type: notification
|
||||||
|
|
||||||
-
|
-
|
||||||
Now I will assign this reminder to all day event
|
Now I will assign this reminder to all day event
|
||||||
-
|
-
|
||||||
|
|
|
@ -84,9 +84,12 @@
|
||||||
idval = '%d-%s' % (ref('calendar_event_sprintreview0'), '20110425124700')
|
idval = '%d-%s' % (ref('calendar_event_sprintreview0'), '20110425124700')
|
||||||
self.write(cr, uid, [idval], {'description': 'Review code of the module: sync_google_calendar.'})
|
self.write(cr, uid, [idval], {'description': 'Review code of the module: sync_google_calendar.'})
|
||||||
-
|
-
|
||||||
I check whether the record is edited perfectly or not.
|
I check whether that all the records of this recurrence has been edited.
|
||||||
-
|
-
|
||||||
!python {model: calendar.event}: |
|
!python {model: calendar.event}: |
|
||||||
meeting_ids = self.search(cr, uid, [('recurrent_id', '=', ref('calendar_event_sprintreview0')), ('recurrent_id_date','=','2011-04-25 12:47:00')], context)
|
meeting_ids = self.search(cr, uid, [('recurrent_id', '=', ref('calendar_event_sprintreview0'))], context)
|
||||||
assert meeting_ids, 'Meeting is not edited !'
|
meetings = self.browse(cr, uid, meeting_ids, context)
|
||||||
|
for meeting in meetings:
|
||||||
|
assert meeting.description == 'Review code of the module: sync_google_calendar.', 'Description not changed for id: %s' %meeting.id
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
# it under the terms of the GNU Affero General Public License as
|
# it under the terms of the GNU Affero General Public License as
|
||||||
# published by the Free Software Foundation, either version 3 of the
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
# License, or (at your option) any later version.
|
# License, or (at your option) any later version.
|
||||||
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
@ -36,21 +37,185 @@ from dateutil import parser
|
||||||
import pytz
|
import pytz
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
from openerp.osv import osv
|
from openerp.osv import osv
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
import logging
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Meta(type):
|
||||||
|
""" This Meta class allow to define class as a structure, and so instancied variable
|
||||||
|
in __init__ to avoid to have side effect alike 'static' variable """
|
||||||
|
def __new__(typ, name, parents, attrs):
|
||||||
|
methods = dict((k, v) for k, v in attrs.iteritems()
|
||||||
|
if callable(v))
|
||||||
|
attrs = dict((k, v) for k, v in attrs.iteritems()
|
||||||
|
if not callable(v))
|
||||||
|
|
||||||
|
def init(self, **kw):
|
||||||
|
for k, v in attrs.iteritems():
|
||||||
|
setattr(self, k, v)
|
||||||
|
for k, v in kw.iteritems():
|
||||||
|
assert k in attrs
|
||||||
|
setattr(self, k, v)
|
||||||
|
|
||||||
|
methods['__init__'] = init
|
||||||
|
methods['__getitem__'] = getattr
|
||||||
|
return type.__new__(typ, name, parents, methods)
|
||||||
|
|
||||||
|
class Struct(object):
|
||||||
|
__metaclass__ = Meta
|
||||||
|
|
||||||
|
class OpenerpEvent(Struct):
|
||||||
|
event = False
|
||||||
|
found = False
|
||||||
|
event_id = False
|
||||||
|
isRecurrence = False
|
||||||
|
isInstance = False
|
||||||
|
update = False
|
||||||
|
status = False
|
||||||
|
attendee_id = False
|
||||||
|
synchro = False
|
||||||
|
|
||||||
|
class GmailEvent(Struct):
|
||||||
|
event = False
|
||||||
|
found = False
|
||||||
|
isRecurrence = False
|
||||||
|
isInstance = False
|
||||||
|
update = False
|
||||||
|
status = False
|
||||||
|
|
||||||
|
class SyncEvent(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.OE = OpenerpEvent()
|
||||||
|
self.GG = GmailEvent()
|
||||||
|
self.OP = None
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return getattr(self,key)
|
||||||
|
|
||||||
|
def compute_OP(self):
|
||||||
|
#If event are already in Gmail and in OpenERP
|
||||||
|
if self.OE.found and self.GG.found:
|
||||||
|
#If the event has been deleted from one side, we delete on other side !
|
||||||
|
if self.OE.status != self.GG.status:
|
||||||
|
self.OP = Delete((self.OE.status and "OE") or (self.GG.status and "GG"),
|
||||||
|
'The event has been deleted from one side, we delete on other side !' )
|
||||||
|
#If event is not deleted !
|
||||||
|
elif self.OE.status and self.GG.status:
|
||||||
|
if self.OE.update.split('.')[0] != self.GG.update.split('.')[0]:
|
||||||
|
if self.OE.update < self.GG.update:
|
||||||
|
tmpSrc = 'GG'
|
||||||
|
elif self.OE.update > self.GG.update:
|
||||||
|
tmpSrc = 'OE'
|
||||||
|
assert tmpSrc in ['GG','OE']
|
||||||
|
|
||||||
|
|
||||||
|
#if self.OP.action == None:
|
||||||
|
if self[tmpSrc].isRecurrence:
|
||||||
|
if self[tmpSrc].status:
|
||||||
|
self.OP = Update(tmpSrc, 'Only need to update, because i\'m active')
|
||||||
|
else:
|
||||||
|
self.OP = Exclude(tmpSrc, 'Need to Exclude (Me = First event from recurrence) from recurrence')
|
||||||
|
|
||||||
|
elif self[tmpSrc].isInstance:
|
||||||
|
self.OP= Update(tmpSrc, 'Only need to update, because already an exclu');
|
||||||
|
else:
|
||||||
|
self.OP = Update(tmpSrc, 'Simply Update... I\'m a single event');
|
||||||
|
#end-if self.OP.action == None:
|
||||||
|
|
||||||
|
else:
|
||||||
|
if not self.OE.synchro or self.OE.synchro.split('.')[0] < self.OE.update.split('.')[0]:
|
||||||
|
self.OP = Update('OE','Event already updated by another user, but not synchro with my google calendar')
|
||||||
|
#import ipdb; ipdb.set_trace();
|
||||||
|
else:
|
||||||
|
self.OP = NothingToDo("",'Not update needed')
|
||||||
|
else:
|
||||||
|
self.OP = NothingToDo("", "Both are already deleted");
|
||||||
|
|
||||||
|
# New in openERP... Create on create_events of synchronize function
|
||||||
|
elif self.OE.found and not self.GG.found:
|
||||||
|
#Has been deleted from gmail
|
||||||
|
if self.OE.status:
|
||||||
|
self.OP = Delete('OE', 'Removed from GOOGLE')
|
||||||
|
else:
|
||||||
|
self.OP = NothingToDo("","Already Deleted in gmail and unlinked in OpenERP")
|
||||||
|
elif self.GG.found and not self.OE.found:
|
||||||
|
tmpSrc = 'GG'
|
||||||
|
if not self.GG.status and not self.GG.isInstance:
|
||||||
|
# don't need to make something... because event has been created and deleted before the synchronization
|
||||||
|
self.OP = NothingToDo("", 'Nothing to do... Create and Delete directly')
|
||||||
|
else:
|
||||||
|
if self.GG.isInstance:
|
||||||
|
if self[tmpSrc].status:
|
||||||
|
self.OP = Exclude(tmpSrc, 'Need to create the new exclu')
|
||||||
|
else:
|
||||||
|
self.OP = Exclude(tmpSrc, 'Need to copy and Exclude')
|
||||||
|
else:
|
||||||
|
self.OP = Create(tmpSrc, 'New EVENT CREATE from GMAIL')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.__repr__()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
myPrint = "---- A SYNC EVENT ---"
|
||||||
|
myPrint += "\n ID OE: %s " % (self.OE.event and self.OE.event.id)
|
||||||
|
myPrint += "\n ID GG: %s " % (self.GG.event and self.GG.event.get('id', False))
|
||||||
|
myPrint += "\n Name OE: %s " % (self.OE.event and self.OE.event.name)
|
||||||
|
myPrint += "\n Name GG: %s " % (self.GG.event and self.GG.event.get('summary', False))
|
||||||
|
myPrint += "\n Found OE:%5s vs GG: %5s" % (self.OE.found, self.GG.found)
|
||||||
|
myPrint += "\n Recurrence OE:%5s vs GG: %5s" % (self.OE.isRecurrence, self.GG.isRecurrence)
|
||||||
|
myPrint += "\n Instance OE:%5s vs GG: %5s" % (self.OE.isInstance, self.GG.isInstance)
|
||||||
|
myPrint += "\n Synchro OE: %10s " % (self.OE.synchro)
|
||||||
|
myPrint += "\n Update OE: %10s " % (self.OE.update)
|
||||||
|
myPrint += "\n Update GG: %10s " % (self.GG.update)
|
||||||
|
myPrint += "\n Status OE:%5s vs GG: %5s" % (self.OE.status, self.GG.status)
|
||||||
|
if (self.OP is None):
|
||||||
|
myPrint += "\n Action %s" % "---!!!---NONE---!!!---"
|
||||||
|
else:
|
||||||
|
myPrint += "\n Action %s" % type(self.OP).__name__
|
||||||
|
myPrint += "\n Source %s" % (self.OP.src)
|
||||||
|
myPrint += "\n comment %s" % (self.OP.info)
|
||||||
|
return myPrint
|
||||||
|
|
||||||
|
|
||||||
|
class SyncOperation(object):
|
||||||
|
def __init__(self, src,info, **kw):
|
||||||
|
self.src = src
|
||||||
|
self.info = info
|
||||||
|
for k,v in kw.items():
|
||||||
|
setattr(self,k,v)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return 'in__STR__'
|
||||||
|
|
||||||
|
class Create(SyncOperation):
|
||||||
|
pass
|
||||||
|
class Update(SyncOperation):
|
||||||
|
pass
|
||||||
|
class Delete(SyncOperation):
|
||||||
|
pass
|
||||||
|
class NothingToDo(SyncOperation):
|
||||||
|
pass
|
||||||
|
class Exclude(SyncOperation):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class google_calendar(osv.AbstractModel):
|
class google_calendar(osv.AbstractModel):
|
||||||
STR_SERVICE = 'calendar'
|
STR_SERVICE = 'calendar'
|
||||||
_name = 'google.%s' % STR_SERVICE
|
_name = 'google.%s' % STR_SERVICE
|
||||||
|
|
||||||
def generate_data(self, cr, uid, event, context=None):
|
def generate_data(self, cr, uid, event, context=None):
|
||||||
if event.allday:
|
if event.allday:
|
||||||
start_date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(event.date, tools.DEFAULT_SERVER_DATETIME_FORMAT) , 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]
|
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'
|
type = 'date'
|
||||||
|
vstype = 'dateTime'
|
||||||
else:
|
else:
|
||||||
start_date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(event.date, tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context).isoformat('T')
|
start_date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(event.date, tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context).isoformat('T')
|
||||||
end_date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(event.date_deadline, tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context).isoformat('T')
|
end_date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(event.date_deadline, tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context).isoformat('T')
|
||||||
type = 'dateTime'
|
type = 'dateTime'
|
||||||
|
vstype = 'date'
|
||||||
attendee_list = []
|
attendee_list = []
|
||||||
|
|
||||||
for attendee in event.attendee_ids:
|
for attendee in event.attendee_ids:
|
||||||
|
@ -64,10 +229,12 @@ class google_calendar(osv.AbstractModel):
|
||||||
"description": event.description or '',
|
"description": event.description or '',
|
||||||
"start":{
|
"start":{
|
||||||
type:start_date,
|
type:start_date,
|
||||||
|
vstype:None,
|
||||||
'timeZone':'UTC'
|
'timeZone':'UTC'
|
||||||
},
|
},
|
||||||
"end":{
|
"end":{
|
||||||
type:end_date,
|
type:end_date,
|
||||||
|
vstype:None,
|
||||||
'timeZone':'UTC'
|
'timeZone':'UTC'
|
||||||
},
|
},
|
||||||
"attendees":attendee_list,
|
"attendees":attendee_list,
|
||||||
|
@ -80,10 +247,13 @@ class google_calendar(osv.AbstractModel):
|
||||||
if not event.active:
|
if not event.active:
|
||||||
data["state"] = "cancelled"
|
data["state"] = "cancelled"
|
||||||
|
|
||||||
|
if not self.get_need_synchro_attendee(cr,uid,context=context):
|
||||||
|
data.pop("attendees")
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def create_an_event(self, cr, uid,event, context=None):
|
def create_an_event(self, cr, uid,event, context=None):
|
||||||
gs_pool = self.pool.get('google.service')
|
gs_pool = self.pool['google.service']
|
||||||
|
|
||||||
data = self.generate_data(cr, uid,event, context=context)
|
data = self.generate_data(cr, uid,event, context=context)
|
||||||
|
|
||||||
|
@ -94,7 +264,7 @@ class google_calendar(osv.AbstractModel):
|
||||||
return gs_pool._do_request(cr, uid, url, data_json, headers, type='POST', context=context)
|
return gs_pool._do_request(cr, uid, url, data_json, headers, type='POST', context=context)
|
||||||
|
|
||||||
def delete_an_event(self, cr, uid,event_id, context=None):
|
def delete_an_event(self, cr, uid,event_id, context=None):
|
||||||
gs_pool = self.pool.get('google.service')
|
gs_pool = self.pool['google.service']
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
'access_token' : self.get_token(cr,uid,context)
|
'access_token' : self.get_token(cr,uid,context)
|
||||||
|
@ -108,12 +278,14 @@ class google_calendar(osv.AbstractModel):
|
||||||
if not token:
|
if not token:
|
||||||
token = self.get_token(cr,uid,context)
|
token = self.get_token(cr,uid,context)
|
||||||
|
|
||||||
gs_pool = self.pool.get('google.service')
|
gs_pool = self.pool['google.service']
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
'fields': 'items,nextPageToken',
|
'fields': 'items,nextPageToken',
|
||||||
'access_token' : token,
|
'access_token' : token,
|
||||||
'maxResults':1000
|
'maxResults':1000,
|
||||||
|
'timeMin': self.get_start_time_to_synchro(cr,uid,context=context).strftime("%Y-%m-%dT%H:%M:%S.%fz"),
|
||||||
|
|
||||||
}
|
}
|
||||||
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
|
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
|
||||||
|
|
||||||
|
@ -134,7 +306,7 @@ class google_calendar(osv.AbstractModel):
|
||||||
|
|
||||||
def update_to_google(self, cr, uid, oe_event, google_event, context):
|
def update_to_google(self, cr, uid, oe_event, google_event, context):
|
||||||
calendar_event = self.pool['calendar.event']
|
calendar_event = self.pool['calendar.event']
|
||||||
gs_pool = self.pool.get('google.service')
|
gs_pool = self.pool['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))
|
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'}
|
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
|
||||||
|
@ -148,10 +320,10 @@ class google_calendar(osv.AbstractModel):
|
||||||
calendar_event.write(cr, uid, [oe_event.id], {'oe_update_date':update_date})
|
calendar_event.write(cr, uid, [oe_event.id], {'oe_update_date':update_date})
|
||||||
|
|
||||||
if context['curr_attendee']:
|
if context['curr_attendee']:
|
||||||
self.pool.get('calendar.attendee').write(cr,uid,[context['curr_attendee']], {'oe_synchro_date':update_date},context)
|
self.pool['calendar.attendee'].write(cr,uid,[context['curr_attendee']], {'oe_synchro_date':update_date},context)
|
||||||
|
|
||||||
def update_an_event(self, cr, uid,event, context=None):
|
def update_an_event(self, cr, uid,event, context=None):
|
||||||
gs_pool = self.pool.get('google.service')
|
gs_pool = self.pool['google.service']
|
||||||
|
|
||||||
data = self.generate_data(cr, uid,event, context=context)
|
data = self.generate_data(cr, uid,event, context=context)
|
||||||
|
|
||||||
|
@ -164,7 +336,7 @@ class google_calendar(osv.AbstractModel):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def update_recurrent_event_exclu(self, cr, uid,instance_id,event_ori_google_id,event_new, context=None):
|
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')
|
gs_pool = self.pool['google.service']
|
||||||
|
|
||||||
data = self.generate_data(cr, uid,event_new, context=context)
|
data = self.generate_data(cr, uid,event_new, context=context)
|
||||||
|
|
||||||
|
@ -186,7 +358,7 @@ class google_calendar(osv.AbstractModel):
|
||||||
calendar_event = self.pool['calendar.event']
|
calendar_event = self.pool['calendar.event']
|
||||||
res_partner_obj = self.pool['res.partner']
|
res_partner_obj = self.pool['res.partner']
|
||||||
calendar_attendee_obj = self.pool['calendar.attendee']
|
calendar_attendee_obj = self.pool['calendar.attendee']
|
||||||
user_obj = self.pool.get('res.users')
|
user_obj = self.pool['res.users']
|
||||||
myPartnerID = user_obj.browse(cr,uid,uid,context).partner_id.id
|
myPartnerID = user_obj.browse(cr,uid,uid,context).partner_id.id
|
||||||
attendee_record = []
|
attendee_record = []
|
||||||
partner_record = [(4,myPartnerID)]
|
partner_record = [(4,myPartnerID)]
|
||||||
|
@ -203,14 +375,16 @@ class google_calendar(osv.AbstractModel):
|
||||||
|
|
||||||
if google_attendee.get('found',False):
|
if google_attendee.get('found',False):
|
||||||
continue
|
continue
|
||||||
attendee_id = res_partner_obj.search(cr, uid,[('email', '=', google_attendee['email'])], context=context)
|
if self.get_need_synchro_attendee(cr,uid,context=context):
|
||||||
if not attendee_id:
|
attendee_id = res_partner_obj.search(cr, uid,[('email', '=', google_attendee['email'])], context=context)
|
||||||
attendee_id = [res_partner_obj.create(cr, uid,{'email': google_attendee['email'],'Customer': False, 'name': google_attendee.get("displayName",False) or google_attendee['email'] }, context=context)]
|
if not attendee_id:
|
||||||
attendee = res_partner_obj.read(cr, uid, attendee_id[0], ['email'], context=context)
|
attendee_id = [res_partner_obj.create(cr, uid,{'email': google_attendee['email'],'customer': False, 'name': google_attendee.get("displayName",False) or google_attendee['email'] }, context=context)]
|
||||||
partner_record.append((4, attendee.get('id')))
|
attendee = res_partner_obj.read(cr, uid, attendee_id[0], ['email'], context=context)
|
||||||
attendee['partner_id'] = attendee.pop('id')
|
partner_record.append((4, attendee.get('id')))
|
||||||
attendee['state'] = google_attendee['responseStatus']
|
attendee['partner_id'] = attendee.pop('id')
|
||||||
attendee_record.append((0, 0, attendee))
|
attendee['state'] = google_attendee['responseStatus']
|
||||||
|
attendee_record.append((0, 0, attendee))
|
||||||
|
|
||||||
UTC = pytz.timezone('UTC')
|
UTC = pytz.timezone('UTC')
|
||||||
if single_event_dict.get('start') and single_event_dict.get('end'): # If not cancelled
|
if single_event_dict.get('start') and single_event_dict.get('end'): # If not cancelled
|
||||||
if single_event_dict['start'].get('dateTime',False) and single_event_dict['end'].get('dateTime',False):
|
if single_event_dict['start'].get('dateTime',False) and single_event_dict['end'].get('dateTime',False):
|
||||||
|
@ -244,7 +418,7 @@ class google_calendar(osv.AbstractModel):
|
||||||
'location':single_event_dict.get('location',False),
|
'location':single_event_dict.get('location',False),
|
||||||
'class':single_event_dict.get('visibility','public'),
|
'class':single_event_dict.get('visibility','public'),
|
||||||
'oe_update_date':update_date,
|
'oe_update_date':update_date,
|
||||||
# 'google_internal_event_id': single_event_dict.get('id',False),
|
# 'google_internal_event_id': single_event_dict.get('id',False),
|
||||||
})
|
})
|
||||||
|
|
||||||
if single_event_dict.get("recurrence",False):
|
if single_event_dict.get("recurrence",False):
|
||||||
|
@ -261,16 +435,17 @@ class google_calendar(osv.AbstractModel):
|
||||||
res = calendar_event.create(cr, uid, result, context=context)
|
res = calendar_event.create(cr, uid, result, context=context)
|
||||||
|
|
||||||
if context['curr_attendee']:
|
if context['curr_attendee']:
|
||||||
self.pool.get('calendar.attendee').write(cr,uid,[context['curr_attendee']], {'oe_synchro_date':update_date,'google_internal_event_id': single_event_dict.get('id',False)},context)
|
self.pool['calendar.attendee'].write(cr,uid,[context['curr_attendee']], {'oe_synchro_date':update_date,'google_internal_event_id': single_event_dict.get('id',False)},context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def synchronize_events(self, cr, uid, ids, context=None):
|
def synchronize_events(self, cr, uid, ids, context=None):
|
||||||
gc_obj = self.pool.get('google.calendar')
|
gc_obj = self.pool['google.calendar']
|
||||||
|
|
||||||
|
# Create all new events from OpenERP into Gmail, if that is not recurrent event
|
||||||
self.create_new_events(cr, uid, context=context)
|
self.create_new_events(cr, uid, context=context)
|
||||||
|
|
||||||
self.bind_recurring_events_to_google(cr, uid, context)
|
self.bind_recurring_events_to_google(cr, uid, context)
|
||||||
cr.commit()
|
|
||||||
|
|
||||||
res = self.update_events(cr, uid, context)
|
res = self.update_events(cr, uid, context)
|
||||||
|
|
||||||
|
@ -279,10 +454,9 @@ class google_calendar(osv.AbstractModel):
|
||||||
"url" : ''
|
"url" : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
def create_new_events(self, cr, uid, context):
|
def create_new_events(self, cr, uid, context=None):
|
||||||
gc_pool = self.pool.get('google.calendar')
|
gc_pool = self.pool['google.calendar']
|
||||||
|
ev_obj = self.pool['calendar.event']
|
||||||
calendar_event = self.pool['calendar.event']
|
|
||||||
att_obj = self.pool['calendar.attendee']
|
att_obj = self.pool['calendar.attendee']
|
||||||
user_obj = self.pool['res.users']
|
user_obj = self.pool['res.users']
|
||||||
myPartnerID = user_obj.browse(cr,uid,uid,context=context).partner_id.id
|
myPartnerID = user_obj.browse(cr,uid,uid,context=context).partner_id.id
|
||||||
|
@ -290,75 +464,73 @@ class google_calendar(osv.AbstractModel):
|
||||||
context_norecurrent = context.copy()
|
context_norecurrent = context.copy()
|
||||||
context_norecurrent['virtual_id'] = False
|
context_norecurrent['virtual_id'] = False
|
||||||
|
|
||||||
my_att_ids = att_obj.search(cr, uid,[('partner_id', '=', myPartnerID),('google_internal_event_id', '=', False)], context=context_norecurrent)
|
my_att_ids = att_obj.search(cr, uid,[ ('partner_id', '=', myPartnerID),
|
||||||
|
('google_internal_event_id', '=', False),
|
||||||
|
'|',
|
||||||
|
('event_id.date_deadline','>',self.get_start_time_to_synchro(cr,uid,context).strftime("%Y-%m-%d %H:%M:%S")),
|
||||||
|
('event_id.end_date','>',self.get_start_time_to_synchro(cr,uid,context).strftime("%Y-%m-%d %H:%M:%S")),
|
||||||
|
], context=context_norecurrent)
|
||||||
|
|
||||||
for att in att_obj.browse(cr,uid,my_att_ids,context=context):
|
for att in att_obj.browse(cr,uid,my_att_ids,context=context):
|
||||||
if not att.event_id.recurrent_id or att.event_id.recurrent_id == 0:
|
if not att.event_id.recurrent_id or att.event_id.recurrent_id == 0:
|
||||||
response = self.create_an_event(cr,uid,att.event_id,context=context)
|
response = self.create_an_event(cr,uid,att.event_id,context=context)
|
||||||
update_date = datetime.strptime(response['updated'],"%Y-%m-%dT%H:%M:%S.%fz")
|
update_date = datetime.strptime(response['updated'],"%Y-%m-%dT%H:%M:%S.%fz")
|
||||||
calendar_event.write(cr, uid, att.event_id.id, {'oe_update_date':update_date})
|
ev_obj.write(cr, uid, att.event_id.id, {'oe_update_date':update_date})
|
||||||
att_obj.write(cr, uid, [att.id], {'google_internal_event_id': response['id'], 'oe_synchro_date':update_date})
|
att_obj.write(cr, uid, [att.id], {'google_internal_event_id': response['id'], 'oe_synchro_date':update_date})
|
||||||
cr.commit()
|
cr.commit()
|
||||||
return True
|
|
||||||
|
|
||||||
def get_empty_synchro_summarize(self) :
|
def bind_recurring_events_to_google(self, cr, uid, context):
|
||||||
return {
|
ev_obj = self.pool['calendar.event']
|
||||||
#OPENERP
|
att_obj = self.pool['calendar.attendee']
|
||||||
'OE_event' : False,
|
user_obj = self.pool['res.users']
|
||||||
'OE_found' : False,
|
myPartnerID = user_obj.browse(cr,uid,uid,context=context).partner_id.id
|
||||||
'OE_event_id' : False,
|
|
||||||
'OE_isRecurrence':False,
|
|
||||||
'OE_isInstance':False,
|
|
||||||
'OE_update':False,
|
|
||||||
'OE_status':False,
|
|
||||||
'OE_attendee_id': False,
|
|
||||||
'OE_synchro':False,
|
|
||||||
|
|
||||||
#GOOGLE
|
context_norecurrent = context.copy()
|
||||||
'GG_event' : False,
|
context_norecurrent['virtual_id'] = False
|
||||||
'GG_found' : False,
|
context_norecurrent['active_test'] = False
|
||||||
'GG_isRecurrence':False,
|
|
||||||
'GG_isInstance':False,
|
|
||||||
'GG_update':False,
|
|
||||||
'GG_status':False,
|
|
||||||
|
|
||||||
#TO_DO_IN_GOOGLE
|
my_att_ids = att_obj.search(cr, uid,[('partner_id', '=', myPartnerID),('google_internal_event_id', '=', False)], context=context_norecurrent)
|
||||||
'td_action':'', # create, update, delete, None
|
|
||||||
#If 'td_action' in (create , update),
|
for att in att_obj.browse(cr,uid,my_att_ids,context=context):
|
||||||
# If td_source == OE
|
if att.event_id.recurrent_id and att.event_id.recurrent_id > 0:
|
||||||
# We create in google the event based on OpenERP
|
new_google_internal_event_id = False
|
||||||
# If td_source == GG
|
source_event_record = ev_obj.browse(cr, uid, att.event_id.recurrent_id, context)
|
||||||
# We create in OpenERP the event based on Gmail
|
source_attendee_record_id = att_obj.search(cr, uid, [('partner_id','=', myPartnerID), ('event_id','=',source_event_record.id)], context=context)
|
||||||
#
|
source_attendee_record = att_obj.browse(cr, uid, source_attendee_record_id, context)[0]
|
||||||
#If 'td_action' in (delete),
|
|
||||||
# If td_source == OE
|
if att.event_id.recurrent_id_date and source_event_record.allday and source_attendee_record.google_internal_event_id:
|
||||||
# We delete in OpenERP the event
|
new_google_internal_event_id = source_attendee_record.google_internal_event_id +'_'+ att.event_id.recurrent_id_date.split(' ')[0].replace('-','')
|
||||||
# If td_source == GG
|
elif att.event_id.recurrent_id_date and source_attendee_record.google_internal_event_id:
|
||||||
# We delete in Gmail the event
|
new_google_internal_event_id = source_attendee_record.google_internal_event_id +'_'+ att.event_id.recurrent_id_date.replace('-','').replace(' ','T').replace(':','') + 'Z'
|
||||||
# If td_source == ALL
|
|
||||||
# We delete in openERP AND in Gmail the event
|
|
||||||
'td_source': '', # OE, GG, ALL
|
|
||||||
'td_comment':''
|
|
||||||
|
|
||||||
}
|
if new_google_internal_event_id:
|
||||||
|
#TODO WARNING, NEED TO CHECK THAT EVENT and ALL instance NOT DELETE IN GMAIL BEFORE !
|
||||||
|
res = self.update_recurrent_event_exclu(cr, uid,new_google_internal_event_id, source_attendee_record.google_internal_event_id,att.event_id, context=context)
|
||||||
|
att_obj.write(cr, uid, [att.id], {'google_internal_event_id': new_google_internal_event_id}, context=context)
|
||||||
|
cr.commit()
|
||||||
|
|
||||||
def update_events(self, cr, uid, context):
|
def update_events(self, cr, uid, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
|
||||||
calendar_event = self.pool['calendar.event']
|
calendar_event = self.pool['calendar.event']
|
||||||
user_obj = self.pool['res.users']
|
user_obj = self.pool['res.users']
|
||||||
att_obj = self.pool['calendar.attendee']
|
att_obj = self.pool['calendar.attendee']
|
||||||
myPartnerID = user_obj.browse(cr,uid,uid,context=context).partner_id.id
|
myPartnerID = user_obj.browse(cr, uid, uid, context=context).partner_id.id
|
||||||
|
|
||||||
context_novirtual = context.copy()
|
context_novirtual = context.copy()
|
||||||
context_novirtual['virtual_id'] = False
|
context_novirtual['virtual_id'] = False
|
||||||
context_novirtual['active_test'] = False
|
context_novirtual['active_test'] = False
|
||||||
|
|
||||||
all_event_from_google = self.get_event_dict(cr,uid,context=context)
|
all_event_from_google = self.get_event_dict(cr, uid, context=context)
|
||||||
all_new_event_from_google = all_event_from_google.copy()
|
|
||||||
|
|
||||||
# Select all events from OpenERP which have been already synchronized in gmail
|
# Select all events from OpenERP which have been already synchronized in gmail
|
||||||
my_att_ids = att_obj.search(cr, uid,[('partner_id', '=', myPartnerID),('google_internal_event_id', '!=', False)], context=context_novirtual)
|
my_att_ids = att_obj.search(cr, uid,[ ('partner_id', '=', myPartnerID),
|
||||||
|
('google_internal_event_id', '!=', False),
|
||||||
|
'|',
|
||||||
|
('event_id.date_deadline','>',self.get_start_time_to_synchro(cr,uid,context).strftime("%Y-%m-%d %H:%M:%S")),
|
||||||
|
('event_id.end_date','>',self.get_start_time_to_synchro(cr,uid,context).strftime("%Y-%m-%d %H:%M:%S")),
|
||||||
|
], context=context_novirtual)
|
||||||
event_to_synchronize = {}
|
event_to_synchronize = {}
|
||||||
for att in att_obj.browse(cr,uid,my_att_ids,context=context):
|
for att in att_obj.browse(cr,uid,my_att_ids,context=context):
|
||||||
event = att.event_id
|
event = att.event_id
|
||||||
|
@ -369,18 +541,19 @@ class google_calendar(osv.AbstractModel):
|
||||||
event_to_synchronize[base_event_id] = {}
|
event_to_synchronize[base_event_id] = {}
|
||||||
|
|
||||||
if att.google_internal_event_id not in event_to_synchronize[base_event_id]:
|
if att.google_internal_event_id not in event_to_synchronize[base_event_id]:
|
||||||
event_to_synchronize[base_event_id][att.google_internal_event_id] = self.get_empty_synchro_summarize()
|
event_to_synchronize[base_event_id][att.google_internal_event_id] = SyncEvent()
|
||||||
|
|
||||||
event_to_synchronize[base_event_id][att.google_internal_event_id]['OE_attendee_id'] = att.id
|
|
||||||
event_to_synchronize[base_event_id][att.google_internal_event_id]['OE_event'] = event
|
|
||||||
event_to_synchronize[base_event_id][att.google_internal_event_id]['OE_found'] = True
|
|
||||||
event_to_synchronize[base_event_id][att.google_internal_event_id]['OE_event_id'] = event.id
|
|
||||||
event_to_synchronize[base_event_id][att.google_internal_event_id]['OE_isRecurrence'] = event.recurrency
|
|
||||||
event_to_synchronize[base_event_id][att.google_internal_event_id]['OE_isInstance'] = bool(event.recurrent_id and event.recurrent_id > 0)
|
|
||||||
event_to_synchronize[base_event_id][att.google_internal_event_id]['OE_update'] = event.oe_update_date
|
|
||||||
event_to_synchronize[base_event_id][att.google_internal_event_id]['OE_status'] = event.active
|
|
||||||
event_to_synchronize[base_event_id][att.google_internal_event_id]['OE_synchro'] = att.oe_synchro_date
|
|
||||||
|
|
||||||
|
ev_to_sync = event_to_synchronize[base_event_id][att.google_internal_event_id]
|
||||||
|
|
||||||
|
ev_to_sync.OE.attendee_id = att.id
|
||||||
|
ev_to_sync.OE.event = event
|
||||||
|
ev_to_sync.OE.found = True
|
||||||
|
ev_to_sync.OE.event_id = event.id
|
||||||
|
ev_to_sync.OE.isRecurrence = event.recurrency
|
||||||
|
ev_to_sync.OE.isInstance = bool(event.recurrent_id and event.recurrent_id > 0)
|
||||||
|
ev_to_sync.OE.update = event.oe_update_date
|
||||||
|
ev_to_sync.OE.status = event.active
|
||||||
|
ev_to_sync.OE.synchro = att.oe_synchro_date
|
||||||
|
|
||||||
for event in all_event_from_google.values():
|
for event in all_event_from_google.values():
|
||||||
event_id = event.get('id')
|
event_id = event.get('id')
|
||||||
|
@ -390,98 +563,28 @@ class google_calendar(osv.AbstractModel):
|
||||||
event_to_synchronize[base_event_id] = {}
|
event_to_synchronize[base_event_id] = {}
|
||||||
|
|
||||||
if event_id not in event_to_synchronize[base_event_id]:
|
if event_id not in event_to_synchronize[base_event_id]:
|
||||||
event_to_synchronize[base_event_id][event_id] = self.get_empty_synchro_summarize()
|
event_to_synchronize[base_event_id][event_id] = SyncEvent()
|
||||||
|
|
||||||
event_to_synchronize[base_event_id][event_id]['GG_event'] = event
|
|
||||||
event_to_synchronize[base_event_id][event_id]['GG_found'] = True
|
|
||||||
event_to_synchronize[base_event_id][event_id]['GG_isRecurrence'] = bool(event.get('recurrence',''))
|
|
||||||
event_to_synchronize[base_event_id][event_id]['GG_isInstance'] = bool(event.get('recurringEventId',0))
|
|
||||||
event_to_synchronize[base_event_id][event_id]['GG_update'] = event.get('updated',None) # if deleted, no date without browse event
|
|
||||||
if event_to_synchronize[base_event_id][event_id]['GG_update']:
|
|
||||||
event_to_synchronize[base_event_id][event_id]['GG_update'] =event_to_synchronize[base_event_id][event_id]['GG_update'].replace('T',' ').replace('Z','')
|
|
||||||
event_to_synchronize[base_event_id][event_id]['GG_status'] = (event.get('status') != 'cancelled')
|
|
||||||
|
|
||||||
|
|
||||||
|
ev_to_sync = event_to_synchronize[base_event_id][event_id]
|
||||||
|
|
||||||
|
ev_to_sync.GG.event = event
|
||||||
|
ev_to_sync.GG.found = True
|
||||||
|
ev_to_sync.GG.isRecurrence = bool(event.get('recurrence',''))
|
||||||
|
ev_to_sync.GG.isInstance = bool(event.get('recurringEventId',0))
|
||||||
|
ev_to_sync.GG.update = event.get('updated',None) # if deleted, no date without browse event
|
||||||
|
if ev_to_sync.GG.update:
|
||||||
|
ev_to_sync.GG.update = ev_to_sync.GG.update.replace('T',' ').replace('Z','')
|
||||||
|
ev_to_sync.GG.status = (event.get('status') != 'cancelled')
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# PRE-PROCESSING #
|
# PRE-PROCESSING #
|
||||||
######################
|
######################
|
||||||
|
|
||||||
for base_event in event_to_synchronize:
|
for base_event in event_to_synchronize:
|
||||||
for current_event in event_to_synchronize[base_event]:
|
for current_event in event_to_synchronize[base_event]:
|
||||||
event = event_to_synchronize[base_event][current_event]
|
event_to_synchronize[base_event][current_event].compute_OP()
|
||||||
|
#print event_to_synchronize[base_event]
|
||||||
#If event are already in Gmail and in OpenERP
|
#print "========================================================"
|
||||||
if event['OE_found'] and event['GG_found']:
|
|
||||||
#If the event has been deleted from one side, we delete on other side !
|
|
||||||
if event['OE_status'] != event['GG_status']:
|
|
||||||
event['td_action'] = "DELETE"
|
|
||||||
event['td_source'] = (event['OE_status'] and "OE") or (event['GG_status'] and "GG")
|
|
||||||
#If event is not deleted !
|
|
||||||
elif event['OE_status'] and event['GG_status']:
|
|
||||||
if event['OE_update'].split('.')[0] != event['GG_update'].split('.')[0]:
|
|
||||||
if event['OE_update'] < event['GG_update']:
|
|
||||||
event['td_source'] = 'GG'
|
|
||||||
elif event['OE_update'] > event['GG_update']:
|
|
||||||
event['td_source'] = 'OE'
|
|
||||||
|
|
||||||
|
|
||||||
if event['td_action'] != "None":
|
|
||||||
if event['%s_isRecurrence' % event['td_source']]:
|
|
||||||
if event['%s_status' % event['td_source']]:
|
|
||||||
event['td_action'] = "UPDATE"
|
|
||||||
event['td_comment'] = 'Only need to update, because i\'m active'
|
|
||||||
else:
|
|
||||||
event['td_action'] = "EXCLUDE"
|
|
||||||
event['td_comment'] = 'Need to Exclude (Me = First event from recurrence) from recurrence'
|
|
||||||
|
|
||||||
elif event['%s_isInstance' % event['td_source']]:
|
|
||||||
event['td_action'] = "UPDATE"
|
|
||||||
event['td_comment'] = 'Only need to update, because already an exclu'
|
|
||||||
else:
|
|
||||||
event['td_action'] = "UPDATE"
|
|
||||||
event['td_comment'] = 'Simply Update... I\'m a single event'
|
|
||||||
|
|
||||||
else:
|
|
||||||
if not event['OE_synchro'] or event['OE_synchro'].split('.')[0] < event['OE_update'].split('.')[0]:
|
|
||||||
event['td_source'] = 'OE'
|
|
||||||
event['td_action'] = "UPDATE"
|
|
||||||
event['td_comment'] = 'Event already updated by another user, but not synchro with my google calendar'
|
|
||||||
|
|
||||||
else:
|
|
||||||
event['td_action'] = "None"
|
|
||||||
event['td_comment'] = 'Not update needed'
|
|
||||||
else:
|
|
||||||
event['td_action'] = "None"
|
|
||||||
event['td_comment'] = "Both are already deleted"
|
|
||||||
# New in openERP... Create on create_events of synchronize function
|
|
||||||
elif event['OE_found'] and not event['GG_found']:
|
|
||||||
#Has been deleted from gmail
|
|
||||||
if event['OE_status']:
|
|
||||||
event['td_source'] = 'OE'
|
|
||||||
event['td_action'] = 'DELETE'
|
|
||||||
event['td_comment'] = 'Removed from GOOGLE ?'
|
|
||||||
else:
|
|
||||||
event['td_action'] = "None"
|
|
||||||
event['td_comment'] = "Already Deleted in gmail and unlinked in OpenERP"
|
|
||||||
elif event['GG_found'] and not event['OE_found']:
|
|
||||||
event['td_source'] = 'GG'
|
|
||||||
if not event['GG_status'] and not event['GG_isInstance']:
|
|
||||||
# don't need to make something... because event has been created and deleted before the synchronization
|
|
||||||
event['td_action'] = 'None'
|
|
||||||
event['td_comment'] = 'Nothing to do... Create and Delete directly'
|
|
||||||
|
|
||||||
else:
|
|
||||||
if event['GG_isInstance']:
|
|
||||||
if event['%s_status' % event['td_source']]:
|
|
||||||
event['td_action'] = "EXCLUDE"
|
|
||||||
event['td_comment'] = 'Need to create the new exclu'
|
|
||||||
else:
|
|
||||||
event['td_action'] = "EXCLUDE"
|
|
||||||
event['td_comment'] = 'Need to copy and Exclude'
|
|
||||||
else:
|
|
||||||
event['td_action'] = "CREATE"
|
|
||||||
event['td_comment'] = 'New EVENT CREATE from GMAIL'
|
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# DO ACTION #
|
# DO ACTION #
|
||||||
######################
|
######################
|
||||||
|
@ -489,105 +592,62 @@ class google_calendar(osv.AbstractModel):
|
||||||
event_to_synchronize[base_event] = sorted(event_to_synchronize[base_event].iteritems(),key=operator.itemgetter(0))
|
event_to_synchronize[base_event] = sorted(event_to_synchronize[base_event].iteritems(),key=operator.itemgetter(0))
|
||||||
for current_event in event_to_synchronize[base_event]:
|
for current_event in event_to_synchronize[base_event]:
|
||||||
cr.commit()
|
cr.commit()
|
||||||
event = current_event[1]
|
event = current_event[1] # event is an Sync Event !
|
||||||
#############
|
|
||||||
### DEBUG ###
|
actToDo = event.OP
|
||||||
#############
|
actSrc = event.OP.src
|
||||||
# if event['td_action'] and event['td_action'] != 'None':
|
|
||||||
# print " Real Event %s (%s)" % (current_event[0],event['OE_event_id'])
|
|
||||||
# print " Found OE:%5s vs GG: %5s" % (event['OE_found'],event['GG_found'])
|
|
||||||
# print " Recurrence OE:%5s vs GG: %5s" % (event['OE_isRecurrence'],event['GG_isRecurrence'])
|
|
||||||
# print " Instance OE:%5s vs GG: %5s" % (event['OE_isInstance'],event['GG_isInstance'])
|
|
||||||
# print " Synchro OE: %10s " % (event['OE_synchro'])
|
|
||||||
# print " Update OE: %10s " % (event['OE_update'])
|
|
||||||
# print " Update GG: %10s " % (event['GG_update'])
|
|
||||||
# print " Status OE:%5s vs GG: %5s" % (event['OE_status'],event['GG_status'])
|
|
||||||
# print " Action %s" % (event['td_action'])
|
|
||||||
# print " Source %s" % (event['td_source'])
|
|
||||||
# print " comment %s" % (event['td_comment'])
|
|
||||||
|
|
||||||
context['curr_attendee'] = event.get('OE_attendee_id',False)
|
# if not isinstance(actToDo, NothingToDo):
|
||||||
|
# print event
|
||||||
|
|
||||||
|
context['curr_attendee'] = event.OE.attendee_id
|
||||||
|
|
||||||
actToDo = event['td_action']
|
if isinstance(actToDo, NothingToDo):
|
||||||
actSrc = event['td_source']
|
continue
|
||||||
if not actToDo:
|
elif isinstance(actToDo, Create):
|
||||||
raise ("#!? WHAT I NEED TO DO ????")
|
context_tmp = context.copy()
|
||||||
else:
|
context_tmp['NewMeeting'] = True
|
||||||
if actToDo == 'None':
|
if actSrc == 'GG':
|
||||||
continue
|
res = self.update_from_google(cr, uid, False, event.GG.event, "create", context=context_tmp)
|
||||||
elif actToDo == 'CREATE':
|
event.OE.event_id = res
|
||||||
context_tmp = context.copy()
|
meeting = calendar_event.browse(cr,uid,res,context=context)
|
||||||
context_tmp['NewMeeting'] = True
|
attendee_record_id = att_obj.search(cr, uid, [('partner_id','=', myPartnerID), ('event_id','=',res)], context=context)
|
||||||
if actSrc == 'GG':
|
self.pool['calendar.attendee'].write(cr, uid, attendee_record_id, {'oe_synchro_date':meeting.oe_update_date, 'google_internal_event_id':event.GG.event['id']}, context=context_tmp)
|
||||||
res = self.update_from_google(cr, uid, False, event['GG_event'], "create", context=context_tmp)
|
elif actSrc == 'OE':
|
||||||
event['OE_event_id'] = res
|
raise "Should be never here, creation for OE is done before update !"
|
||||||
meeting = calendar_event.browse(cr,uid,res,context=context)
|
#TODO Add to batch
|
||||||
attendee_record_id = att_obj.search(cr, uid, [('partner_id','=', myPartnerID), ('event_id','=',res)], context=context)
|
elif isinstance(actToDo, Update):
|
||||||
self.pool.get('calendar.attendee').write(cr,uid,attendee_record_id, {'oe_synchro_date':meeting.oe_update_date,'google_internal_event_id': event['GG_event']['id']},context=context_tmp)
|
if actSrc == 'GG':
|
||||||
elif actSrc == 'OE':
|
self.update_from_google(cr, uid, event.OE.event, event.GG.event, 'write', context)
|
||||||
raise "Should be never here, creation for OE is done before update !"
|
elif actSrc == 'OE':
|
||||||
#TODO Add to batch
|
self.update_to_google(cr, uid, event.OE.event, event.GG.event, context)
|
||||||
elif actToDo == 'UPDATE':
|
elif isinstance(actToDo, Exclude):
|
||||||
if actSrc == 'GG':
|
if actSrc == 'OE':
|
||||||
self.update_from_google(cr, uid, event['OE_event'], event['GG_event'], 'write', context)
|
self.delete_an_event(cr,uid,current_event[0],context=context)
|
||||||
elif actSrc == 'OE':
|
elif actSrc == 'GG':
|
||||||
self.update_to_google(cr, uid, event['OE_event'], event['GG_event'], context)
|
new_google_event_id = event.GG.event['id'].split('_')[1]
|
||||||
elif actToDo == 'EXCLUDE' :
|
if 'T' in new_google_event_id:
|
||||||
if actSrc == 'OE':
|
new_google_event_id = new_google_event_id.replace('T','')[:-1]
|
||||||
self.delete_an_event(cr,uid,current_event[0],context=context)
|
else:
|
||||||
elif actSrc == 'GG':
|
new_google_event_id = new_google_event_id + "000000"
|
||||||
new_google_event_id = event['GG_event']['id'].split('_')[1]
|
|
||||||
if 'T' in new_google_event_id:
|
if event.GG.status:
|
||||||
new_google_event_id = new_google_event_id.replace('T','')[:-1]
|
parent_event = {}
|
||||||
|
parent_event['id'] = "%s-%s" % (event_to_synchronize[base_event][0][1].OE.event_id , new_google_event_id)
|
||||||
|
res = self.update_from_google(cr, uid, parent_event, event.GG.event, "copy", context)
|
||||||
else:
|
else:
|
||||||
new_google_event_id = new_google_event_id + "000000"
|
if event_to_synchronize[base_event][0][1].OE.event_id:
|
||||||
|
parent_oe_id = event_to_synchronize[base_event][0][1].OE.event_id
|
||||||
if event['GG_status']:
|
calendar_event.unlink(cr,uid,"%s-%s" % (parent_oe_id,new_google_event_id),unlink_level=1,context=context)
|
||||||
parent_event = {}
|
|
||||||
parent_event['id'] = "%s-%s" % (event_to_synchronize[base_event][0][1].get('OE_event_id') , new_google_event_id)
|
|
||||||
res = self.update_from_google(cr, uid, parent_event, event['GG_event'], "copy", context)
|
|
||||||
else:
|
|
||||||
if event_to_synchronize[base_event][0][1].get('OE_event_id'):
|
|
||||||
parent_oe_id = event_to_synchronize[base_event][0][1].get('OE_event_id')
|
|
||||||
calendar_event.unlink(cr,uid,"%s-%s" % (parent_oe_id,new_google_event_id),unlink_level=1,context=context)
|
|
||||||
|
|
||||||
elif actToDo == 'DELETE':
|
elif isinstance(actToDo, Delete):
|
||||||
if actSrc == 'GG':
|
if actSrc == 'GG':
|
||||||
self.delete_an_event(cr,uid,current_event[0],context=context)
|
self.delete_an_event(cr,uid,current_event[0],context=context)
|
||||||
elif actSrc == 'OE':
|
elif actSrc == 'OE':
|
||||||
calendar_event.unlink(cr,uid,event['OE_event_id'],unlink_level=0,context=context)
|
calendar_event.unlink(cr,uid,event.OE.event_id,unlink_level=0,context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def bind_recurring_events_to_google(self, cr, uid, context):
|
|
||||||
calendar_event = self.pool['calendar.event']
|
|
||||||
att_obj = self.pool.get('calendar.attendee')
|
|
||||||
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
|
|
||||||
context_norecurrent['active_test'] = False
|
|
||||||
|
|
||||||
my_att_ids = att_obj.search(cr, uid,[('partner_id', '=', myPartnerID),('google_internal_event_id', '=', False)], context=context_norecurrent)
|
|
||||||
for att in att_obj.browse(cr,uid,my_att_ids,context=context):
|
|
||||||
if att.event_id.recurrent_id and att.event_id.recurrent_id > 0:
|
|
||||||
new_google_internal_event_id = False
|
|
||||||
source_event_record = calendar_event.browse(cr, uid, att.event_id.recurrent_id, context)
|
|
||||||
source_attendee_record_id = att_obj.search(cr, uid, [('partner_id','=', myPartnerID), ('event_id','=',source_event_record.id)], context=context)
|
|
||||||
source_attendee_record = att_obj.browse(cr, uid, source_attendee_record_id, context)
|
|
||||||
if source_attendee_record:
|
|
||||||
source_attendee_record = source_attendee_record[0]
|
|
||||||
|
|
||||||
if att.event_id.recurrent_id_date and source_event_record.allday and source_attendee_record.google_internal_event_id:
|
|
||||||
new_google_internal_event_id = source_attendee_record.google_internal_event_id +'_'+ att.event_id.recurrent_id_date.split(' ')[0].replace('-','')
|
|
||||||
elif event.recurrent_id_date and source_attendee_record.google_internal_event_id:
|
|
||||||
new_google_internal_event_id = source_attendee_record.google_internal_event_id +'_'+ att.event_id.recurrent_id_date.replace('-','').replace(' ','T').replace(':','') + 'Z'
|
|
||||||
|
|
||||||
if new_google_internal_event_id:
|
|
||||||
#TODO WARNING, NEED TO CHECK THAT EVENT and ALL instance NOT DELETE IN GMAIL BEFORE !
|
|
||||||
res = self.update_recurrent_event_exclu(cr,uid,new_google_internal_event_id,source_attendee_record.google_internal_event_id,att.event_id,context=context)
|
|
||||||
att_obj.write(cr, uid, [att.id], {'google_internal_event_id': new_google_internal_event_id})
|
|
||||||
|
|
||||||
def check_and_sync(self, cr, uid, oe_event, google_event, 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"):
|
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)
|
self.update_to_google(cr, uid, oe_event, google_event, context)
|
||||||
|
@ -595,7 +655,7 @@ class google_calendar(osv.AbstractModel):
|
||||||
self.update_from_google(cr, uid, oe_event, google_event, 'write', context)
|
self.update_from_google(cr, uid, oe_event, google_event, 'write', context)
|
||||||
|
|
||||||
def get_sequence(self,cr,uid,instance_id,context=None):
|
def get_sequence(self,cr,uid,instance_id,context=None):
|
||||||
gs_pool = self.pool.get('google.service')
|
gs_pool = self.pool['google.service']
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
'fields': 'sequence',
|
'fields': 'sequence',
|
||||||
|
@ -613,7 +673,7 @@ class google_calendar(osv.AbstractModel):
|
||||||
#################################
|
#################################
|
||||||
|
|
||||||
def get_token(self,cr,uid,context=None):
|
def get_token(self,cr,uid,context=None):
|
||||||
current_user = self.pool.get('res.users').browse(cr,uid,uid,context=context)
|
current_user = self.pool['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=1)):
|
if datetime.strptime(current_user.google_calendar_token_validity.split('.')[0], "%Y-%m-%d %H:%M:%S") < (datetime.now() + timedelta(minutes=1)):
|
||||||
self.do_refresh_token(cr,uid,context=context)
|
self.do_refresh_token(cr,uid,context=context)
|
||||||
|
@ -622,20 +682,20 @@ class google_calendar(osv.AbstractModel):
|
||||||
return current_user.google_calendar_token
|
return current_user.google_calendar_token
|
||||||
|
|
||||||
def do_refresh_token(self,cr,uid,context=None):
|
def do_refresh_token(self,cr,uid,context=None):
|
||||||
current_user = self.pool.get('res.users').browse(cr,uid,uid,context=context)
|
current_user = self.pool['res.users'].browse(cr,uid,uid,context=context)
|
||||||
gs_pool = self.pool.get('google.service')
|
gs_pool = self.pool['google.service']
|
||||||
|
|
||||||
refresh = current_user.google_calendar_rtoken
|
refresh = current_user.google_calendar_rtoken
|
||||||
all_token = gs_pool._refresh_google_token_json(cr, uid, current_user.google_calendar_rtoken,self.STR_SERVICE,context=context)
|
all_token = gs_pool._refresh_google_token_json(cr, uid, current_user.google_calendar_rtoken, self.STR_SERVICE, context=context)
|
||||||
|
|
||||||
vals = {}
|
vals = {}
|
||||||
vals['google_%s_token_validity' % self.STR_SERVICE] = datetime.now() + timedelta(seconds=all_token.get('expires_in'))
|
vals['google_%s_token_validity' % self.STR_SERVICE] = datetime.now() + timedelta(seconds=all_token.get('expires_in'))
|
||||||
vals['google_%s_token' % self.STR_SERVICE] = all_token.get('access_token')
|
vals['google_%s_token' % self.STR_SERVICE] = all_token.get('access_token')
|
||||||
|
|
||||||
self.pool.get('res.users').write(cr,SUPERUSER_ID,uid,vals,context=context)
|
self.pool['res.users'].write(cr,SUPERUSER_ID,uid,vals,context=context)
|
||||||
|
|
||||||
def need_authorize(self,cr,uid,context=None):
|
def need_authorize(self,cr,uid,context=None):
|
||||||
current_user = self.pool.get('res.users').browse(cr,uid,uid,context=context)
|
current_user = self.pool['res.users'].browse(cr,uid,uid,context=context)
|
||||||
return current_user.google_calendar_rtoken == False
|
return current_user.google_calendar_rtoken == False
|
||||||
|
|
||||||
def get_calendar_scope(self,RO=False):
|
def get_calendar_scope(self,RO=False):
|
||||||
|
@ -643,22 +703,30 @@ class google_calendar(osv.AbstractModel):
|
||||||
return 'https://www.googleapis.com/auth/calendar%s' % (readonly)
|
return 'https://www.googleapis.com/auth/calendar%s' % (readonly)
|
||||||
|
|
||||||
def authorize_google_uri(self,cr,uid,from_url='http://www.openerp.com',context=None):
|
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)
|
url = self.pool['google.service']._get_authorize_uri(cr,uid,from_url,self.STR_SERVICE,scope=self.get_calendar_scope(),context=context)
|
||||||
return url
|
return url
|
||||||
|
|
||||||
def can_authorize_google(self,cr,uid,context=None):
|
def can_authorize_google(self,cr,uid,context=None):
|
||||||
return self.pool['res.users'].has_group(cr, uid, 'base.group_erp_manager')
|
return self.pool['res.users'].has_group(cr, uid, 'base.group_erp_manager')
|
||||||
|
|
||||||
def set_all_tokens(self,cr,uid,authorization_code,context=None):
|
def set_all_tokens(self,cr,uid,authorization_code,context=None):
|
||||||
gs_pool = self.pool.get('google.service')
|
gs_pool = self.pool['google.service']
|
||||||
all_token = gs_pool._get_google_token_json(cr, uid, authorization_code,self.STR_SERVICE,context=context)
|
all_token = gs_pool._get_google_token_json(cr, uid, authorization_code,self.STR_SERVICE,context=context)
|
||||||
|
|
||||||
vals = {}
|
vals = {}
|
||||||
vals['google_%s_rtoken' % self.STR_SERVICE] = all_token.get('refresh_token')
|
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'))
|
vals['google_%s_token_validity' % self.STR_SERVICE] = datetime.now() + timedelta(seconds=all_token.get('expires_in'))
|
||||||
vals['google_%s_token' % self.STR_SERVICE] = all_token.get('access_token')
|
vals['google_%s_token' % self.STR_SERVICE] = all_token.get('access_token')
|
||||||
self.pool.get('res.users').write(cr,SUPERUSER_ID,uid,vals,context=context)
|
self.pool['res.users'].write(cr,SUPERUSER_ID,uid,vals,context=context)
|
||||||
|
|
||||||
|
def get_start_time_to_synchro(self, cr, uid, context=None) :
|
||||||
|
# WILL BE AN IR CONFIG PARAMETER - beginning from SAAS4
|
||||||
|
number_of_week = 13
|
||||||
|
return datetime.now()-timedelta(weeks=number_of_week)
|
||||||
|
|
||||||
|
def get_need_synchro_attendee(self, cr, uid, context=None):
|
||||||
|
# WILL BE AN IR CONFIG PARAMETER - beginning from SAAS4
|
||||||
|
return True
|
||||||
|
|
||||||
class res_users(osv.Model):
|
class res_users(osv.Model):
|
||||||
_inherit = 'res.users'
|
_inherit = 'res.users'
|
||||||
|
@ -718,7 +786,6 @@ class calendar_attendee(osv.Model):
|
||||||
# If attendees are updated, we need to specify that next synchro need an action
|
# If attendees are updated, we need to specify that next synchro need an action
|
||||||
# Except if it come from an update_from_google
|
# Except if it come from an update_from_google
|
||||||
if not context.get('curr_attendee', False) and not context.get('NewMeeting', False):
|
if not context.get('curr_attendee', False) and not context.get('NewMeeting', False):
|
||||||
self.pool.get('calendar.event').write(cr, uid, ref, {'oe_update_date':datetime.now()},context)
|
self.pool['calendar.event'].write(cr, uid, ref, {'oe_update_date':datetime.now()},context)
|
||||||
|
|
||||||
return super(calendar_attendee, self).write(cr, uid, ids, vals, context=context)
|
|
||||||
|
|
||||||
|
return super(calendar_attendee, self).write(cr, uid, ids, vals, context=context)
|
Loading…
Reference in New Issue