[REF] Refactoring according to CHS and AL review
bzr revid: jke@openerp.com-20140113174157-ins4vf57g0p6v82u
This commit is contained in:
parent
656f8241d5
commit
c5791441c4
|
@ -1,8 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# OpenERP, Open Source Management Solution
|
# OpenERP, Open Source Business Applications
|
||||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
@ -15,10 +15,10 @@
|
||||||
# GNU Affero General Public License for more details.
|
# GNU Affero General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import models
|
from . import calendar
|
||||||
import controllers
|
import controllers
|
||||||
import contacts
|
import contacts
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# OpenERP, Open Source Management Solution
|
# OpenERP, Open Source Business Applications
|
||||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# OpenERP, Open Source Management Solution
|
# OpenERP, Open Source Business Applications
|
||||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
@ -33,9 +33,10 @@ from openerp import tools, SUPERUSER_ID
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
|
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
from openerp import http
|
||||||
|
from openerp.http import request
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -295,7 +296,7 @@ class calendar_attendee(osv.Model):
|
||||||
class res_partner(osv.Model):
|
class res_partner(osv.Model):
|
||||||
_inherit = 'res.partner'
|
_inherit = 'res.partner'
|
||||||
_columns = {
|
_columns = {
|
||||||
'cal_last_notif': fields.datetime('Last Notification from base Calendar'),
|
'calendar_last_notif': fields.datetime('Last Notification from base Calendar'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_attendee_detail(self, cr, uid, ids, meeting_id, context=None):
|
def get_attendee_detail(self, cr, uid, ids, meeting_id, context=None):
|
||||||
|
@ -312,13 +313,13 @@ class res_partner(osv.Model):
|
||||||
datas.append(data)
|
datas.append(data)
|
||||||
return datas
|
return datas
|
||||||
|
|
||||||
def update_cal_last_event(self, cr, uid, context=None):
|
def calendar_last_event(self, cr, uid, context=None):
|
||||||
partner = self.pool['res.users'].browse(cr, uid, uid, context=context).partner_id
|
partner = self.pool['res.users'].browse(cr, uid, uid, context=context).partner_id
|
||||||
self.write(cr, uid, partner.id, {'cal_last_notif': datetime.now()}, context=context)
|
self.write(cr, uid, partner.id, {'calendar_last_notif': datetime.now()}, context=context)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
class calendar_alarm_manager(osv.Model):
|
class calendar_alarm_manager(osv.AbstractModel):
|
||||||
_name = 'calendar.alarm_manager'
|
_name = 'calendar.alarm_manager'
|
||||||
|
|
||||||
def get_next_potential_limit_alarm(self, cr, uid, seconds, notif=True, mail=True, partner_id=None, context=None):
|
def get_next_potential_limit_alarm(self, cr, uid, seconds, notif=True, mail=True, partner_id=None, context=None):
|
||||||
|
@ -424,86 +425,84 @@ class calendar_alarm_manager(osv.Model):
|
||||||
res.append(alert)
|
res.append(alert)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def do_run_scheduler_mail(self, cr, uid, context=None):
|
|
||||||
self.do_run(cr, uid, type='mail', context=None)
|
|
||||||
|
|
||||||
def do_run_next_event(self, cr, uid, context=None):
|
def get_next_mail(self,cr,uid,context=None):
|
||||||
return self.do_run(cr, uid, type='notif', context=None)
|
cron = self.pool.get('ir.cron').search(cr,uid,[('model','ilike',self._name)],context=context)
|
||||||
|
if cron and len(cron) == 1:
|
||||||
def do_run(self, cr, uid, type, context=None): # Type is 'notif' or 'email'
|
cron = self.pool.get('ir.cron').browse(cr,uid,cron[0],context=context)
|
||||||
all_notif = []
|
else:
|
||||||
if (type == 'notif'):
|
raise ("Cron for " + self._name + " not identified :( !")
|
||||||
ajax_check_every_seconds = 300
|
|
||||||
partner = self.pool['res.users'].browse(cr, uid, uid, context=context).partner_id
|
|
||||||
all_events = self.get_next_potential_limit_alarm(cr, uid, ajax_check_every_seconds, partner_id=partner.id, mail=False, context=context)
|
|
||||||
elif (type == 'mail'):
|
|
||||||
cron = self.pool['ir.cron'].search(cr, uid, [('model', 'ilike', self._name)], context=context)
|
|
||||||
if cron and len(cron) == 1:
|
|
||||||
cron = self.pool['ir.cron'].browse(cr, uid, cron[0], context=context)
|
|
||||||
else:
|
|
||||||
_logger.exception("Cron for % can't be found !" % self._name)
|
|
||||||
return
|
|
||||||
|
|
||||||
if cron.interval_type == "weeks":
|
|
||||||
cron_interval = cron.interval_number * 7 * 24 * 60 * 60
|
|
||||||
elif cron.interval_type == "days":
|
|
||||||
cron_interval = cron.interval_number * 24 * 60 * 60
|
|
||||||
elif cron.interval_type == "hours":
|
|
||||||
cron_interval = cron.interval_number * 60 * 60
|
|
||||||
elif cron.interval_type == "minutes":
|
|
||||||
cron_interval = cron.interval_number * 60
|
|
||||||
elif cron.interval_type == "seconds":
|
|
||||||
cron_interval = cron.interval_number
|
|
||||||
|
|
||||||
if not cron_interval:
|
|
||||||
_logger.exception("Cron delay for % can not be calculated !" % self._name)
|
|
||||||
return
|
|
||||||
|
|
||||||
all_events = self.get_next_potential_limit_alarm(cr, uid, cron_interval, notif=False, context=context)
|
|
||||||
|
|
||||||
for event in all_events:
|
if cron.interval_type=="weeks":
|
||||||
max_delta = all_events[event]['max_duration']
|
cron_interval = cron.interval_number * 7 * 24 * 60 * 60
|
||||||
curEvent = self.pool['crm.meeting'].browse(cr, uid, event, context=context)
|
elif cron.interval_type=="days":
|
||||||
|
cron_interval = cron.interval_number * 24 * 60 * 60
|
||||||
|
elif cron.interval_type=="hours":
|
||||||
|
cron_interval = cron.interval_number * 60 * 60
|
||||||
|
elif cron.interval_type=="minutes":
|
||||||
|
cron_interval = cron.interval_number * 60
|
||||||
|
elif cron.interval_type=="seconds":
|
||||||
|
cron_interval = cron.interval_number
|
||||||
|
|
||||||
|
if not cron_interval:
|
||||||
|
raise ("Cron delay for " + self._name + " can not be calculated :( !")
|
||||||
|
|
||||||
|
all_events = self.get_next_potential_limit_alarm(cr,uid,cron_interval,notif=False,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:
|
if curEvent.recurrency:
|
||||||
bFound = False
|
bFound = False
|
||||||
LastFound = False
|
LastFound = False
|
||||||
for one_date in self.pool['crm.meeting'].get_recurrent_date_by_event(cr, uid, curEvent, 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')
|
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 (type == 'notif'):
|
|
||||||
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)
|
|
||||||
elif (type == 'mail'):
|
|
||||||
LastFound = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, cron_interval, notif=False, context=context)
|
|
||||||
|
|
||||||
if LastFound:
|
if LastFound:
|
||||||
for alert in LastFound:
|
for alert in LastFound:
|
||||||
|
self.do_mail_reminder(cr,uid,alert,context=context)
|
||||||
if (type == 'notif'):
|
|
||||||
all_notif.append(self.do_notif_reminder(cr, uid, alert, context=context))
|
|
||||||
elif (type == 'mail'):
|
|
||||||
self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, cron_interval, notif=False, context=context)
|
|
||||||
|
|
||||||
if not bFound: # if it's the first alarm for this recurrent event
|
if not bFound: # if it's the first alarm for this recurrent event
|
||||||
bFound = True
|
bFound = True
|
||||||
if bFound and not LastFound: # if the precedent event had alarm but not this one, we can stop the search for this event
|
if bFound and not LastFound: # if the precedent event had an alarm but not this one, we can stop the search for this event
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
in_date_format = datetime.strptime(curEvent.date, '%Y-%m-%d %H:%M:%S')
|
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,cron_interval,notif=False,context=context)
|
||||||
if (type == 'notif'):
|
|
||||||
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)
|
|
||||||
elif (type == 'mail'):
|
|
||||||
self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, cron_interval, notif=False, context=context)
|
|
||||||
|
|
||||||
if LastFound:
|
if LastFound:
|
||||||
for alert in LastFound:
|
for alert in LastFound:
|
||||||
if (type == 'notif'):
|
self.do_mail_reminder(cr,uid,alert,context=context)
|
||||||
all_notif.append(self.do_notif_reminder(cr, uid, alert, context=context))
|
|
||||||
elif (type == 'mail'):
|
def get_next_notif(self,cr,uid,context=None):
|
||||||
all_notif.append(self.do_mail_reminder(cr, uid, alert, context=context))
|
ajax_check_every_seconds = 300
|
||||||
return all_notif
|
partner = self.pool.get('res.users').browse(cr,uid,uid,context=context).partner_id;
|
||||||
|
all_notif = []
|
||||||
|
all_events = self.get_next_potential_limit_alarm(cr,uid,ajax_check_every_seconds,partner_id=partner.id,mail=False,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
|
||||||
|
LastFound = False
|
||||||
|
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:
|
||||||
|
for alert in LastFound:
|
||||||
|
all_notif.append(self.do_notif_reminder(cr,uid,alert,context=context))
|
||||||
|
if not bFound: #if it's the first alarm for this recurrent event
|
||||||
|
bFound = True
|
||||||
|
if bFound and not LastFound: #if the precedent 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');
|
||||||
|
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)
|
||||||
|
if LastFound:
|
||||||
|
for alert in LastFound:
|
||||||
|
all_notif.append(self.do_notif_reminder(cr,uid,alert,context=context))
|
||||||
|
return all_notif
|
||||||
|
|
||||||
def do_mail_reminder(self, cr, uid, alert, context=None):
|
def do_mail_reminder(self, cr, uid, alert, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
@ -913,10 +912,8 @@ class crm_meeting(osv.Model):
|
||||||
|
|
||||||
return {'value': value}
|
return {'value': value}
|
||||||
|
|
||||||
def new_invitation_token(self, cr, uid, record, partner_id):
|
def new_invitation_token(self, cr, uid, record, partner_id):
|
||||||
db_uuid = self.pool['ir.config_parameter'].get_param(cr, uid, 'database.uuid')
|
return uuid.uuid4().hex
|
||||||
invitation_token = hashlib.sha256('%s-%s-%s-%s-%s' % (time.time(), db_uuid, record._name, record.id, partner_id)).hexdigest()
|
|
||||||
return invitation_token
|
|
||||||
|
|
||||||
def create_attendees(self, cr, uid, ids, context):
|
def create_attendees(self, cr, uid, ids, context):
|
||||||
user_obj = self.pool['res.users']
|
user_obj = self.pool['res.users']
|
||||||
|
@ -1223,15 +1220,15 @@ class crm_meeting(osv.Model):
|
||||||
|
|
||||||
def get_attendee(self, cr, uid, meeting_id, context=None):
|
def get_attendee(self, cr, uid, meeting_id, context=None):
|
||||||
# Used for view in controller
|
# Used for view in controller
|
||||||
invitation = {'meeting': {}, 'attendee': [], 'logo': ''}
|
invitation = {'meeting': {}, 'attendee': []}
|
||||||
company_logo = self.pool['res.users'].browse(cr, uid, uid, context=context).company_id.logo
|
|
||||||
meeting = self.browse(cr, uid, int(meeting_id), context)
|
meeting = self.browse(cr, uid, int(meeting_id), context)
|
||||||
invitation['meeting'] = {
|
invitation['meeting'] = {
|
||||||
'event': meeting.name,
|
'event': meeting.name,
|
||||||
'where': meeting.location,
|
'where': meeting.location,
|
||||||
'when': meeting.display_time
|
'when': meeting.display_time
|
||||||
}
|
}
|
||||||
invitation['logo'] = company_logo.replace('\n', '\\n') if company_logo else ''
|
|
||||||
for attendee in meeting.attendee_ids:
|
for attendee in meeting.attendee_ids:
|
||||||
invitation['attendee'].append({'name': attendee.cn, 'status': attendee.state})
|
invitation['attendee'].append({'name': attendee.cn, 'status': attendee.state})
|
||||||
return invitation
|
return invitation
|
||||||
|
@ -1454,30 +1451,6 @@ class crm_meeting(osv.Model):
|
||||||
return result and result[0] or False
|
return result and result[0] or False
|
||||||
return result
|
return result
|
||||||
|
|
||||||
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)
|
|
||||||
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 unlink(self, cr, uid, ids, unlink_level=0, context=None):
|
def unlink(self, cr, uid, ids, unlink_level=0, context=None):
|
||||||
if not isinstance(ids, list):
|
if not isinstance(ids, list):
|
||||||
ids = [ids]
|
ids = [ids]
|
||||||
|
@ -1544,8 +1517,33 @@ class ir_attachment(osv.Model):
|
||||||
if isinstance(vals.get('res_id'), str):
|
if isinstance(vals.get('res_id'), str):
|
||||||
vals['res_id'] = get_real_ids(vals.get('res_id'))
|
vals['res_id'] = get_real_ids(vals.get('res_id'))
|
||||||
return super(ir_attachment, self).write(cr, uid, ids, vals, context=context)
|
return super(ir_attachment, self).write(cr, uid, ids, vals, context=context)
|
||||||
|
|
||||||
|
|
||||||
|
class ir_http(osv.AbstractModel):
|
||||||
|
_inherit = 'ir.http'
|
||||||
|
|
||||||
|
def _auth_method_calendar(self):
|
||||||
|
token = request.params['token']
|
||||||
|
db = request.params['db']
|
||||||
|
|
||||||
|
registry = openerp.modules.registry.RegistryManager.get(db)
|
||||||
|
attendee_pool = registry.get('calendar.attendee')
|
||||||
|
error_message = False
|
||||||
|
with registry.cursor() as cr:
|
||||||
|
attendee_id = attendee_pool.search(cr, openerp.SUPERUSER_ID, [('access_token','=',token)])
|
||||||
|
if not attendee_id:
|
||||||
|
error_message = """Invalid Invitation Token."""
|
||||||
|
elif request.session.uid and request.session.login != 'anonymous':
|
||||||
|
# if valid session but user is not match
|
||||||
|
attendee = attendee_pool.browse(cr, openerp.SUPERUSER_ID, attendee_id[0])
|
||||||
|
user = registry.get('res.users').browse(cr, openerp.SUPERUSER_ID, request.session.uid)
|
||||||
|
if attendee.partner_id.id != user.partner_id.id:
|
||||||
|
error_message = """Invitation cannot be forwarded via email. This event/meeting belongs to %s and you are logged in as %s. Please ask organizer to add you.""" % (attendee.email, user.email)
|
||||||
|
|
||||||
|
if error_message:
|
||||||
|
raise BadRequest(error_message)
|
||||||
|
return True
|
||||||
|
|
||||||
class invite_wizard(osv.osv_memory):
|
class invite_wizard(osv.osv_memory):
|
||||||
_inherit = 'mail.wizard.invite'
|
_inherit = 'mail.wizard.invite'
|
||||||
|
|
|
@ -9,12 +9,6 @@
|
||||||
<field name="description">Warning, a mandatory field has been modified since the creation of this event</field>
|
<field name="description">Warning, a mandatory field has been modified since the creation of this event</field>
|
||||||
<field name="default" eval="False"/>
|
<field name="default" eval="False"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="res.request.link" id="request_link_event">
|
|
||||||
<field name="name">Event</field>
|
|
||||||
<field name="object">calendar.event</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record model="calendar.alarm" id="alarm_notif_1">
|
<record model="calendar.alarm" id="alarm_notif_1">
|
||||||
<field name="name">15 min notif</field>
|
<field name="name">15 min notif</field>
|
||||||
<field name="duration" eval="15" />
|
<field name="duration" eval="15" />
|
||||||
|
@ -89,7 +83,7 @@
|
||||||
<field name="numbercall">-1</field>
|
<field name="numbercall">-1</field>
|
||||||
<field eval="False" name="doall" />
|
<field eval="False" name="doall" />
|
||||||
<field eval="'calendar.alarm_manager'" name="model" />
|
<field eval="'calendar.alarm_manager'" name="model" />
|
||||||
<field eval="'do_run_scheduler_mail'" name="function" />
|
<field eval="'get_next_mail'" name="function" />
|
||||||
<!--<field eval="'(False,)'" name="args" />-->
|
<!--<field eval="'(False,)'" name="args" />-->
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
@ -113,11 +107,6 @@
|
||||||
<field name="name">Feedback Meeting</field>
|
<field name="name">Feedback Meeting</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="res.request.link" id="request_link_meeting">
|
|
||||||
<field name="name">Meeting</field>
|
|
||||||
<field name="object">crm.meeting</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="calendar_template_meeting_invitation" model="email.template">
|
<record id="calendar_template_meeting_invitation" model="email.template">
|
||||||
<field name="name">Meeting Invitation</field>
|
<field name="name">Meeting Invitation</field>
|
||||||
<field name="email_from">${object.event_id.user_id.email or ''}</field>
|
<field name="email_from">${object.event_id.user_id.email or ''}</field>
|
||||||
|
@ -484,6 +473,5 @@
|
||||||
]]>
|
]]>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
|
@ -1,3 +1,24 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Business Applications
|
||||||
|
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
|
|
||||||
class calendar_contacts(osv.osv):
|
class calendar_contacts(osv.osv):
|
||||||
|
|
|
@ -10,28 +10,8 @@ from werkzeug.exceptions import BadRequest
|
||||||
|
|
||||||
class meeting_invitation(http.Controller):
|
class meeting_invitation(http.Controller):
|
||||||
|
|
||||||
def check_security(self, db, token):
|
@http.route('/calendar/meeting/accept', type='http', auth="calendar")
|
||||||
registry = openerp.modules.registry.RegistryManager.get(db)
|
def accept(self, db, token, action, id,**kwargs):
|
||||||
attendee_pool = registry.get('calendar.attendee')
|
|
||||||
error_message = False
|
|
||||||
with registry.cursor() as cr:
|
|
||||||
attendee_id = attendee_pool.search(cr, openerp.SUPERUSER_ID, [('access_token','=',token)])
|
|
||||||
if not attendee_id:
|
|
||||||
error_message = """Invalid Invitation Token."""
|
|
||||||
elif request.session.uid and request.session.login != 'anonymous':
|
|
||||||
# if valid session but user is not match
|
|
||||||
attendee = attendee_pool.browse(cr, openerp.SUPERUSER_ID, attendee_id[0])
|
|
||||||
user = registry.get('res.users').browse(cr, openerp.SUPERUSER_ID, request.session.uid)
|
|
||||||
if attendee.partner_id.user_id.id != user.id:
|
|
||||||
error_message = """Invitation cannot be forwarded via email. This event/meeting belongs to %s and you are logged in as %s. Please ask organizer to add you.""" % (attendee.email, user.email)
|
|
||||||
|
|
||||||
if error_message:
|
|
||||||
raise BadRequest(error_message)
|
|
||||||
return True
|
|
||||||
|
|
||||||
@http.route('/calendar/meeting/accept', type='http', auth="none")
|
|
||||||
def accept(self, db, token, action, id):
|
|
||||||
self.check_security(db, token)
|
|
||||||
registry = openerp.modules.registry.RegistryManager.get(db)
|
registry = openerp.modules.registry.RegistryManager.get(db)
|
||||||
attendee_pool = registry.get('calendar.attendee')
|
attendee_pool = registry.get('calendar.attendee')
|
||||||
with registry.cursor() as cr:
|
with registry.cursor() as cr:
|
||||||
|
@ -40,9 +20,8 @@ class meeting_invitation(http.Controller):
|
||||||
attendee_pool.do_accept(cr, openerp.SUPERUSER_ID, attendee_id)
|
attendee_pool.do_accept(cr, openerp.SUPERUSER_ID, attendee_id)
|
||||||
return self.view(db, token, action, id, view='form')
|
return self.view(db, token, action, id, view='form')
|
||||||
|
|
||||||
@http.route('/calendar/meeting/decline', type='http', auth="none")
|
@http.route('/calendar/meeting/decline', type='http', auth="calendar")
|
||||||
def declined(self, db, token, action, id):
|
def declined(self, db, token, action, id):
|
||||||
self.check_security(db, token)
|
|
||||||
registry = openerp.modules.registry.RegistryManager.get(db)
|
registry = openerp.modules.registry.RegistryManager.get(db)
|
||||||
attendee_pool = registry.get('calendar.attendee')
|
attendee_pool = registry.get('calendar.attendee')
|
||||||
with registry.cursor() as cr:
|
with registry.cursor() as cr:
|
||||||
|
@ -51,9 +30,8 @@ class meeting_invitation(http.Controller):
|
||||||
attendee_pool.do_decline(cr, openerp.SUPERUSER_ID, attendee_id)
|
attendee_pool.do_decline(cr, openerp.SUPERUSER_ID, attendee_id)
|
||||||
return self.view(db, token, action, id, view='form')
|
return self.view(db, token, action, id, view='form')
|
||||||
|
|
||||||
@http.route('/calendar/meeting/view', type='http', auth="none")
|
@http.route('/calendar/meeting/view', type='http', auth="calendar")
|
||||||
def view(self, db, token, action, id, view='calendar'):
|
def view(self, db, token, action, id, view='calendar'):
|
||||||
self.check_security(db, token)
|
|
||||||
registry = openerp.modules.registry.RegistryManager.get(db)
|
registry = openerp.modules.registry.RegistryManager.get(db)
|
||||||
meeting_pool = registry.get('crm.meeting')
|
meeting_pool = registry.get('crm.meeting')
|
||||||
attendee_pool = registry.get('calendar.attendee')
|
attendee_pool = registry.get('calendar.attendee')
|
||||||
|
@ -89,6 +67,6 @@ class meeting_invitation(http.Controller):
|
||||||
uid = request.session.uid
|
uid = request.session.uid
|
||||||
context = request.session.context
|
context = request.session.context
|
||||||
with registry.cursor() as cr:
|
with registry.cursor() as cr:
|
||||||
res = registry.get("res.partner").update_cal_last_event(cr,uid,context=context)
|
res = registry.get("res.partner").calendar_last_event(cr,uid,context=context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,11 @@ openerp.calendar = function(instance) {
|
||||||
get_notif_box: function(me) {
|
get_notif_box: function(me) {
|
||||||
return $(me).closest(".ui-notify-message-style");
|
return $(me).closest(".ui-notify-message-style");
|
||||||
},
|
},
|
||||||
get_next_event: function() {
|
get_next_notif: function() {
|
||||||
var self= this;
|
var self= this;
|
||||||
this.rpc("/calendar/notify")
|
this.rpc("/calendar/notify")
|
||||||
.then(
|
.then(
|
||||||
function(result) {
|
function(result) {
|
||||||
console.log(result);
|
|
||||||
_.each(result, function(res) {
|
_.each(result, function(res) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
//If notification not already displayed, we add button and action on it
|
//If notification not already displayed, we add button and action on it
|
||||||
|
@ -49,9 +48,9 @@ openerp.calendar = function(instance) {
|
||||||
},
|
},
|
||||||
check_notifications: function() {
|
check_notifications: function() {
|
||||||
var self= this;
|
var self= this;
|
||||||
self.get_next_event();
|
self.get_next_notif();
|
||||||
setInterval(function(){
|
setInterval(function(){
|
||||||
self.get_next_event();
|
self.get_next_notif();
|
||||||
}, 5 * 60 * 1000 );
|
}, 5 * 60 * 1000 );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -78,6 +77,7 @@ 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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -87,15 +87,14 @@ openerp.calendar = function(instance) {
|
||||||
redirect_meeting_view : function(db, action, meeting_id, view){
|
redirect_meeting_view : function(db, action, meeting_id, view){
|
||||||
var self = this;
|
var self = this;
|
||||||
var action_url = '';
|
var action_url = '';
|
||||||
if(view == "form") {
|
|
||||||
action_url = _.str.sprintf('/?db=%s#id=%s&view_type=%s&model=crm.meeting', db, meeting_id, view, meeting_id);
|
action_url = _.str.sprintf('/?db=%s#id=%s&view_type=form&model=crm.meeting', db, meeting_id);
|
||||||
} else {
|
|
||||||
action_url = _.str.sprintf('/?db=%s#view_type=%s&model=crm.meeting&action=%s',self.db,self.view,self.action);
|
|
||||||
}
|
|
||||||
var reload_page = function(){
|
var reload_page = function(){
|
||||||
return location.replace(action_url);
|
return location.replace(action_url);
|
||||||
}
|
}
|
||||||
reload_page();
|
reload_page();
|
||||||
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -32,32 +32,45 @@
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
<t t-name="invitation_view">
|
<t t-name="invitation_view">
|
||||||
<div class="oe_right"><b><t t-esc="invitation['current_attendee'].cn"/> (<t t-esc="invitation['current_attendee'].email"/>)</b></div>
|
<div class='invitation_block well' style='width:50%; margin:auto; margin-top : 30px;'>
|
||||||
<div class="oe_left"><img class="cal_inline cal_image" t-attf-src="data:image/png;base64,#{invitation['logo']}"/><p class="cal_tag cal_inline">Calendar</p></div>
|
<div class="oe_right"><b><t t-esc="invitation['current_attendee'].cn"/> (<t t-esc="invitation['current_attendee'].email"/>)</b></div>
|
||||||
<div class="invitation_block">
|
<div class="oe_left">
|
||||||
<t t-if="invitation['current_attendee'].state != 'needsAction'">
|
<img class="cal_inline cal_image" src='/web/binary/company_logo' />
|
||||||
<div class="event_status"><a t-attf-class="attendee_#{invitation['current_attendee'].state}"><b t-if="invitation['current_attendee'].state == 'accepted'">Yes I'm going.</b><b t-if="invitation['current_attendee'].state == 'declined'">No I'm not going.</b></a></div>
|
</div>
|
||||||
</t>
|
<div>
|
||||||
<div class="cal_meeting"><t t-esc="invitation['meeting'].event"/></div>
|
<div class="invitation_block cal_meeting">
|
||||||
<table calss="invitation_block">
|
<h2 class="cal_inline">Calendar Invitation</h2>
|
||||||
<tr>
|
<t t-if="invitation['current_attendee'].state != 'needsAction'">
|
||||||
<td class="cal_lable">When</td>
|
<a t-attf-class="attendee_#{invitation['current_attendee'].state}">
|
||||||
<td>: <t t-esc="invitation['meeting'].when"/></td>
|
<b t-if="invitation['current_attendee'].state == 'accepted'">Yes I'm going.</b>
|
||||||
</tr>
|
<b t-if="invitation['current_attendee'].state == 'declined'">No I'm not going.</b>
|
||||||
<tr>
|
</a>
|
||||||
<td class="cal_lable">Where</td>
|
</t>
|
||||||
<td>: <t t-esc="invitation['meeting'].where or '-'"/></td>
|
<br/><br/>
|
||||||
</tr>
|
<div class="cal_meeting"><t t-esc="invitation['meeting'].event"/></div>
|
||||||
<tr>
|
<br/>
|
||||||
<td class="cal_lable">Who</td>
|
<table class="">
|
||||||
<td>
|
<tr>
|
||||||
<t t-foreach="invitation['attendee']" t-as="att">
|
<td class="cal_lable">When</td>
|
||||||
<br/>
|
<td> <t t-esc="invitation['meeting'].when"/></td>
|
||||||
<span class="cal_status"><a t-attf-class="oe_invitation #{att.status}"/><t t-esc="att.name"/></span>
|
</tr>
|
||||||
</t>
|
<tr>
|
||||||
</td>
|
<td class="cal_lable">Where</td>
|
||||||
</tr>
|
<td> <t t-esc="invitation['meeting'].where or '-'"/></td>
|
||||||
</table>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="cal_lable">Who</td>
|
||||||
|
<td>
|
||||||
|
<t t-foreach="invitation['attendee']" t-as="att">
|
||||||
|
<br/>
|
||||||
|
<span class="cal_status"><a t-attf-class="oe_invitation #{att.status}"/><t t-esc="att.name"/></span>
|
||||||
|
</t>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -17,18 +17,16 @@ class google_auth(http.Controller):
|
||||||
state = simplejson.loads(kw['state'])
|
state = simplejson.loads(kw['state'])
|
||||||
dbname = state.get('d')
|
dbname = state.get('d')
|
||||||
service = state.get('s')
|
service = state.get('s')
|
||||||
url_return = state.get('from')
|
url_return = state.get('f')
|
||||||
|
|
||||||
registry = openerp.modules.registry.RegistryManager.get(dbname)
|
registry = openerp.modules.registry.RegistryManager.get(dbname)
|
||||||
with registry.cursor() as cr:
|
with registry.cursor() as cr:
|
||||||
if kw.get('code',False):
|
if kw.get('code',False):
|
||||||
registry.get('google.%s' % service).set_all_tokens(cr,request.session.uid,kw['code'])
|
registry.get('google.%s' % service).set_all_tokens(cr,request.session.uid,kw['code'])
|
||||||
return werkzeug.utils.redirect(url_return)
|
return werkzeug.utils.redirect(url_return)
|
||||||
|
|
||||||
#TODO - Display error at customer if url contains ?Error=
|
|
||||||
elif kw.get('error'):
|
elif kw.get('error'):
|
||||||
return werkzeug.utils.redirect("%s%s%s" % (url_return ,"?Error=" , kw.get('error')))
|
return werkzeug.utils.redirect("%s%s%s" % (url_return ,"?error=" , kw.get('error')))
|
||||||
else:
|
else:
|
||||||
return werkzeug.utils.redirect("%s%s%s" % (url_return ,"?Error=Unknown_error"))
|
return werkzeug.utils.redirect("%s%s%s" % (url_return ,"?error=Unknown_error"))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ import urllib
|
||||||
import urllib2
|
import urllib2
|
||||||
import simplejson
|
import simplejson
|
||||||
|
|
||||||
|
import logging
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class google_service(osv.osv_memory):
|
class google_service(osv.osv_memory):
|
||||||
_name = 'google.service'
|
_name = 'google.service'
|
||||||
|
@ -68,10 +70,7 @@ class google_service(osv.osv_memory):
|
||||||
|
|
||||||
def _get_authorize_uri(self, cr, uid, from_url, service, scope = False, context=None):
|
def _get_authorize_uri(self, cr, uid, from_url, service, scope = False, context=None):
|
||||||
""" This method return the url needed to allow this instance of OpenErp to access to the scope of gmail specified as parameters """
|
""" This method return the url needed to allow this instance of OpenErp to access to the scope of gmail specified as parameters """
|
||||||
state_obj = {}
|
state_obj = dict(d=cr.dbname, s=service, f=from_url)
|
||||||
state_obj['d'] = cr.dbname
|
|
||||||
state_obj['s'] = service
|
|
||||||
state_obj['from'] = from_url
|
|
||||||
|
|
||||||
base_url = self.get_base_url(cr, uid, context)
|
base_url = self.get_base_url(cr, uid, context)
|
||||||
client_id = self.get_client_id(cr, uid, service, context)
|
client_id = self.get_client_id(cr, uid, service, context)
|
||||||
|
@ -110,10 +109,8 @@ class google_service(osv.osv_memory):
|
||||||
req = urllib2.Request(self.get_uri_oauth(a='token'), data, headers)
|
req = urllib2.Request(self.get_uri_oauth(a='token'), data, headers)
|
||||||
|
|
||||||
content = urllib2.urlopen(req).read()
|
content = urllib2.urlopen(req).read()
|
||||||
res = simplejson.loads(content)
|
res = simplejson.loads(content)
|
||||||
|
|
||||||
except urllib2.HTTPError,e:
|
except urllib2.HTTPError,e:
|
||||||
print e
|
|
||||||
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during your token generation. Maybe your Authorization Code is invalid"), context=context)
|
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during your token generation. Maybe your Authorization Code is invalid"), context=context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@ -143,19 +140,8 @@ class google_service(osv.osv_memory):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _do_request(self,cr,uid,uri,params={},headers={},type='POST', context=None):
|
def _do_request(self,cr,uid,uri,params={},headers={},type='POST', context=None):
|
||||||
|
_logger.debug("Uri: %s - Type : %s - Headers: %s - Params : %s !" % (uri,type,headers,urllib.urlencode(params) if type =='GET' else params))
|
||||||
res = False
|
res = False
|
||||||
######################
|
|
||||||
### FOR DEBUG ###
|
|
||||||
######################
|
|
||||||
# print "#########################################"
|
|
||||||
# print "### URI : %s ###" % (uri)
|
|
||||||
# print "### HEADERS : %s ###" % (headers)
|
|
||||||
# print "### METHOD : %s ###" % (type)
|
|
||||||
# if type=='GET':
|
|
||||||
# print "### PARAMS : %s ###" % urllib.urlencode(params)
|
|
||||||
# else:
|
|
||||||
# print "### PARAMS : %s ###" % (params)
|
|
||||||
# print "#########################################"
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if type.upper() == 'GET' or type.upper() == 'DELETE':
|
if type.upper() == 'GET' or type.upper() == 'DELETE':
|
||||||
|
@ -164,7 +150,7 @@ class google_service(osv.osv_memory):
|
||||||
elif type.upper() == 'POST' or type.upper() == 'PATCH' or type.upper() == 'PUT':
|
elif type.upper() == 'POST' or type.upper() == 'PATCH' or type.upper() == 'PUT':
|
||||||
req = urllib2.Request(self.get_uri_api() + uri, params, headers)
|
req = urllib2.Request(self.get_uri_api() + uri, params, headers)
|
||||||
else:
|
else:
|
||||||
raise ('Method not supported [%s] not in [GET, POST, PUT or PATCH]!' % (type))
|
raise ('Method not supported [%s] not in [GET, POST, PUT, PATCH or DELETE]!' % (type))
|
||||||
req.get_method = lambda: type.upper()
|
req.get_method = lambda: type.upper()
|
||||||
|
|
||||||
request = urllib2.urlopen(req)
|
request = urllib2.urlopen(req)
|
||||||
|
@ -176,11 +162,9 @@ class google_service(osv.osv_memory):
|
||||||
else:
|
else:
|
||||||
content=request.read()
|
content=request.read()
|
||||||
res = simplejson.loads(content)
|
res = simplejson.loads(content)
|
||||||
print "="
|
|
||||||
except urllib2.HTTPError,e:
|
except urllib2.HTTPError,e:
|
||||||
print "ERROR CATCHED : ",e.read()
|
_logger.exception("Bad google request : %s !" % e.read())
|
||||||
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong with your request to google"), context=context)
|
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong with your request to google"), context=context)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_base_url(self, cr, uid, context=None):
|
def get_base_url(self, cr, uid, context=None):
|
||||||
|
|
|
@ -14,18 +14,16 @@ class google_calendar_controller(http.Controller):
|
||||||
def sync_data(self, arch, fields, model,**kw):
|
def sync_data(self, arch, fields, model,**kw):
|
||||||
"""
|
"""
|
||||||
This route/function is called when we want to synchronize openERP calendar with Google Calendar
|
This route/function is called when we want to synchronize openERP calendar with Google Calendar
|
||||||
|
Function return a dictionary with the status : need_config_from_admin, need_auth, need_refresh, success if not crm_meeting
|
||||||
Function return a dictionary with the status : NeedConfigFromAdmin, NeedAuth, NeedRefresh, NoNewEventFromGoogle, SUCCESS if not crm meeting
|
|
||||||
The dictionary may contains an url, to allow OpenERP Client to redirect user on this URL for authorization for example
|
The dictionary may contains an url, to allow OpenERP Client to redirect user on this URL for authorization for example
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if model == 'crm.meeting':
|
if model == 'crm.meeting':
|
||||||
gs_obj = request.registry.get('google.service')
|
gs_obj = request.registry['google.service']
|
||||||
gc_obj = request.registry.get('google.calendar')
|
gc_obj = request.registry['google.calendar']
|
||||||
|
|
||||||
# Checking that admin have already configured Google API for google synchronization !
|
# Checking that admin have already configured Google API for google synchronization !
|
||||||
client_id = gs_obj.get_client_id(request.cr, request.uid,'calendar',context=kw.get('LocalContext'))
|
client_id = gs_obj.get_client_id(request.cr, request.uid,'calendar',context=kw.get('local_context'))
|
||||||
|
|
||||||
if not client_id or client_id == '':
|
if not client_id or client_id == '':
|
||||||
action = ''
|
action = ''
|
||||||
|
@ -33,21 +31,21 @@ class google_calendar_controller(http.Controller):
|
||||||
dummy, action = request.registry.get('ir.model.data').get_object_reference(request.cr, request.uid, 'google_calendar', 'action_config_settings_google_calendar')
|
dummy, action = request.registry.get('ir.model.data').get_object_reference(request.cr, request.uid, 'google_calendar', 'action_config_settings_google_calendar')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status" : "NeedConfigFromAdmin",
|
"status" : "need_config_from_admin",
|
||||||
"url" : '',
|
"url" : '',
|
||||||
"action" : action
|
"action" : action
|
||||||
}
|
}
|
||||||
|
|
||||||
# Checking that user have already accepted OpenERP to access his calendar !
|
# Checking that user have already accepted OpenERP to access his calendar !
|
||||||
if gc_obj.need_authorize(request.cr, request.uid,context=kw.get('LocalContext')):
|
if gc_obj.need_authorize(request.cr, request.uid,context=kw.get('local_context')):
|
||||||
url = gc_obj.authorize_google_uri(request.cr, request.uid, from_url=kw.get('fromurl'), context=kw.get('LocalContext'))
|
url = gc_obj.authorize_google_uri(request.cr, request.uid, from_url=kw.get('fromurl'), context=kw.get('local_context'))
|
||||||
return {
|
return {
|
||||||
"status" : "NeedAuth",
|
"status" : "need_auth",
|
||||||
"url" : url
|
"url" : url
|
||||||
}
|
}
|
||||||
|
|
||||||
# If App authorized, and user access accepted, We launch the synchronization
|
# If App authorized, and user access accepted, We launch the synchronization
|
||||||
return gc_obj.synchronize_events(request.cr, request.uid, [], kw.get('LocalContext'))
|
return gc_obj.synchronize_events(request.cr, request.uid, [], kw.get('local_context'))
|
||||||
|
|
||||||
return { "status" : "Success" }
|
return { "status" : "success" }
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ import operator
|
||||||
import simplejson
|
import simplejson
|
||||||
import re
|
import re
|
||||||
import urllib
|
import urllib
|
||||||
import urllib2
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from openerp import tools
|
from openerp import tools
|
||||||
|
@ -40,7 +39,7 @@ from openerp.osv import osv
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class google_calendar(osv.osv):
|
class google_calendar(osv.AbstractModel):
|
||||||
STR_SERVICE = 'calendar'
|
STR_SERVICE = 'calendar'
|
||||||
_name = 'google.%s' % STR_SERVICE
|
_name = 'google.%s' % STR_SERVICE
|
||||||
|
|
||||||
|
@ -152,7 +151,6 @@ class google_calendar(osv.osv):
|
||||||
|
|
||||||
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.get('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.get('google.service')
|
||||||
|
@ -178,7 +176,7 @@ class google_calendar(osv.osv):
|
||||||
url = "/calendar/v3/calendars/%s/events/%s?access_token=%s" % ('primary', instance_id,self.get_token(cr,uid,context))
|
url = "/calendar/v3/calendars/%s/events/%s?access_token=%s" % ('primary', instance_id,self.get_token(cr,uid,context))
|
||||||
headers = { 'Content-type': 'application/json'}
|
headers = { 'Content-type': 'application/json'}
|
||||||
|
|
||||||
data['sequence'] = self.get_sequence(cr, uid, instance_id, context)
|
|
||||||
|
|
||||||
data_json = simplejson.dumps(data)
|
data_json = simplejson.dumps(data)
|
||||||
return gs_pool._do_request(cr, uid, url, data_json, headers, type='PUT', context=context)
|
return gs_pool._do_request(cr, uid, url, data_json, headers, type='PUT', context=context)
|
||||||
|
@ -270,8 +268,7 @@ class google_calendar(osv.osv):
|
||||||
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.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)
|
||||||
|
|
||||||
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.get('google.calendar')
|
||||||
|
|
||||||
|
@ -283,7 +280,7 @@ class google_calendar(osv.osv):
|
||||||
res = self.update_events(cr, uid, context)
|
res = self.update_events(cr, uid, context)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status" : res and "NeedRefresh" or "NoNewEventFromGoogle",
|
"status" : res and "need_refresh" or "no_new_event_form_google",
|
||||||
"url" : ''
|
"url" : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,8 +304,7 @@ class google_calendar(osv.osv):
|
||||||
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
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_empty_synchro_summarize(self) :
|
def get_empty_synchro_summarize(self) :
|
||||||
return {
|
return {
|
||||||
#OPENERP
|
#OPENERP
|
||||||
|
@ -430,8 +426,6 @@ class google_calendar(osv.osv):
|
||||||
event['td_source'] = (event['OE_status'] and "OE") or (event['GG_status'] and "GG")
|
event['td_source'] = (event['OE_status'] and "OE") or (event['GG_status'] and "GG")
|
||||||
#If event is not deleted !
|
#If event is not deleted !
|
||||||
elif event['OE_status'] and event['GG_status']:
|
elif event['OE_status'] and event['GG_status']:
|
||||||
# if not event['GG_update']:
|
|
||||||
# print "### Should never be here
|
|
||||||
if event['OE_update'].split('.')[0] != event['GG_update'].split('.')[0]:
|
if event['OE_update'].split('.')[0] != event['GG_update'].split('.')[0]:
|
||||||
if event['OE_update'] < event['GG_update']:
|
if event['OE_update'] < event['GG_update']:
|
||||||
event['td_source'] = 'GG'
|
event['td_source'] = 'GG'
|
||||||
|
@ -502,7 +496,6 @@ class google_calendar(osv.osv):
|
||||||
# DO ACTION #
|
# DO ACTION #
|
||||||
######################
|
######################
|
||||||
for base_event in event_to_synchronize:
|
for base_event in event_to_synchronize:
|
||||||
#print "Base Event : %s " % base_event
|
|
||||||
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()
|
||||||
|
@ -515,13 +508,13 @@ class google_calendar(osv.osv):
|
||||||
# print " Found OE:%5s vs GG: %5s" % (event['OE_found'],event['GG_found'])
|
# 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 " 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 " Instance OE:%5s vs GG: %5s" % (event['OE_isInstance'],event['GG_isInstance'])
|
||||||
# print " Synchro OE: %10s " % (event['OE_synchro'])
|
# print " Synchro OE: %10s " % (event['OE_synchro'])
|
||||||
# print " Update OE: %10s " % (event['OE_update'])
|
# print " Update OE: %10s " % (event['OE_update'])
|
||||||
# print " Update GG: %10s " % (event['GG_update'])
|
# print " Update GG: %10s " % (event['GG_update'])
|
||||||
# print " Status OE:%5s vs GG: %5s" % (event['OE_status'],event['GG_status'])
|
# print " Status OE:%5s vs GG: %5s" % (event['OE_status'],event['GG_status'])
|
||||||
# print " Action %s" % (event['td_action'])
|
# print " Action %s" % (event['td_action'])
|
||||||
# print " Source %s" % (event['td_source'])
|
# print " Source %s" % (event['td_source'])
|
||||||
# print " comment %s" % (event['td_comment'])
|
# print " comment %s" % (event['td_comment'])
|
||||||
|
|
||||||
|
|
||||||
context['curr_attendee'] = event.get('OE_attendee_id',False)
|
context['curr_attendee'] = event.get('OE_attendee_id',False)
|
||||||
|
@ -615,21 +608,7 @@ class google_calendar(osv.osv):
|
||||||
self.update_to_google(cr, uid, oe_event, google_event, context)
|
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"):
|
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)
|
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)
|
|
||||||
|
|
||||||
#################################
|
#################################
|
||||||
## MANAGE CONNEXION TO GMAIL ##
|
## MANAGE CONNEXION TO GMAIL ##
|
||||||
|
@ -684,7 +663,7 @@ class google_calendar(osv.osv):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class res_users(osv.osv):
|
class res_users(osv.Model):
|
||||||
_inherit = 'res.users'
|
_inherit = 'res.users'
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
|
@ -694,7 +673,7 @@ class res_users(osv.osv):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class crm_meeting(osv.osv):
|
class crm_meeting(osv.Model):
|
||||||
_inherit = "crm.meeting"
|
_inherit = "crm.meeting"
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, context=None):
|
def write(self, cr, uid, ids, vals, context=None):
|
||||||
|
@ -722,7 +701,7 @@ class crm_meeting(osv.osv):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class calendar_attendee(osv.osv):
|
class calendar_attendee(osv.Model):
|
||||||
_inherit = 'calendar.attendee'
|
_inherit = 'calendar.attendee'
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
|
|
||||||
class calendar_config_settings(osv.osv_memory):
|
class calendar_config_settings(osv.TransientModel):
|
||||||
#_name = 'calendar.config.settings'
|
|
||||||
_inherit = 'base.config.settings'
|
_inherit = 'base.config.settings'
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
|
@ -11,33 +10,11 @@ class calendar_config_settings(osv.osv_memory):
|
||||||
'server_uri': fields.char('URI for tuto')
|
'server_uri': fields.char('URI for tuto')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def set_calset(self,cr,uid,ids,context=None) :
|
def set_calset(self,cr,uid,ids,context=None) :
|
||||||
params = self.pool.get('ir.config_parameter')
|
params = self.pool['ir.config_parameter']
|
||||||
me = self.browse(cr,uid,ids[0],context=context)
|
myself = self.browse(cr,uid,ids[0],context=context)
|
||||||
#new_val = dict(cal_client_id=me.cal_client_id,cal_client_secret=me.cal_client_secret)
|
params.set_param(cr, uid, 'google_calendar_client_id', myself.cal_client_id, context=None)
|
||||||
|
params.set_param(cr, uid, 'google_calendar_client_secret', myself.cal_client_secret, context=None)
|
||||||
new_val_id = {
|
|
||||||
'key' : 'google_calendar_client_id',
|
|
||||||
'value' : me.cal_client_id
|
|
||||||
}
|
|
||||||
new_val_secret = {
|
|
||||||
'key' : 'google_calendar_client_secret',
|
|
||||||
'value' : me.cal_client_secret
|
|
||||||
}
|
|
||||||
|
|
||||||
exist_id = params.search(cr,uid,[('key','=','google_calendar_client_id')],context=context)
|
|
||||||
exist_secret = params.search(cr,uid,[('key','=','google_calendar_client_secret')],context=context)
|
|
||||||
|
|
||||||
if exist_id:
|
|
||||||
params.write(cr,uid,exist_id[0],new_val_id,context=context)
|
|
||||||
else:
|
|
||||||
params.create(cr,uid,new_val_id,context=context)
|
|
||||||
|
|
||||||
if exist_secret:
|
|
||||||
params.write(cr,uid,exist_secret[0],new_val_secret,context=context)
|
|
||||||
else:
|
|
||||||
params.create(cr,uid,new_val_secret,context=context)
|
|
||||||
|
|
||||||
|
|
||||||
def get_default_all(self,cr,uid,ids,context=None):
|
def get_default_all(self,cr,uid,ids,context=None):
|
||||||
|
|
|
@ -80,10 +80,7 @@
|
||||||
<field name="view_mode">form</field>
|
<field name="view_mode">form</field>
|
||||||
<field name="target">inline</field>
|
<field name="target">inline</field>
|
||||||
</record>
|
</record>
|
||||||
<!--
|
|
||||||
<menuitem id="menu_calendar_google_main" parent="base.menu_administration" name="Google Calendar"/>
|
|
||||||
<menuitem id="menu_calendar_google_config" name="API credentials" parent="google_calendar.menu_calendar_google_main" action="action_config_settings_google_calendar"/>
|
|
||||||
-->
|
|
||||||
<menuitem id="menu_calendar_google_tech_config" name="API Credentials" parent="calendar.menu_calendar_configuration" groups="base.group_no_one" action="action_config_settings_google_calendar"/>
|
<menuitem id="menu_calendar_google_tech_config" name="API Credentials" parent="calendar.menu_calendar_configuration" groups="base.group_no_one" action="action_config_settings_google_calendar"/>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -3,11 +3,10 @@ openerp.google_calendar = function(instance) {
|
||||||
_lt = instance.web._lt;
|
_lt = instance.web._lt;
|
||||||
var QWeb = instance.web.qweb;
|
var QWeb = instance.web.qweb;
|
||||||
|
|
||||||
instance.web_calendar.FullCalendarView.include({
|
instance.web_calendar.CalendarView.include({
|
||||||
view_loading: function(r) {
|
view_loading: function(r) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.$el.on('click', 'div.oe_cal_sync_button', function() {
|
this.$el.on('click', 'div.oe_cal_sync_button', function() {
|
||||||
console.log("Launch synchro");
|
|
||||||
self.sync_calendar(r);
|
self.sync_calendar(r);
|
||||||
});
|
});
|
||||||
return this._super(r);
|
return this._super(r);
|
||||||
|
@ -23,17 +22,15 @@ openerp.google_calendar = function(instance) {
|
||||||
fields: res.fields,
|
fields: res.fields,
|
||||||
model:res.model,
|
model:res.model,
|
||||||
fromurl: window.location.href,
|
fromurl: window.location.href,
|
||||||
LocalContext:context
|
local_context:context
|
||||||
}).done(function(o) {
|
}).done(function(o) {
|
||||||
console.log(o);
|
if (o.status == "need_auth") {
|
||||||
|
|
||||||
if (o.status == "NeedAuth") {
|
|
||||||
alert(_t("You will be redirected on gmail to authorize your OpenErp to access your calendar !"));
|
alert(_t("You will be redirected on gmail to authorize your OpenErp to access your calendar !"));
|
||||||
window.location = o.url;
|
instance.web.redirect(o.url);
|
||||||
}
|
}
|
||||||
else if (o.status == "NeedConfigFromAdmin") {
|
else if (o.status == "need_config_from_admin") {
|
||||||
|
|
||||||
if (typeof o.action !== 'undefined' && parseInt(o.action)) {
|
if (!_.IsUndefined(o.action) && parseInt(o.action)) {
|
||||||
if (confirm(_t("An admin need to configure Google Synchronization before to use it, do you want to configure it now ? !"))) {
|
if (confirm(_t("An admin need to configure Google Synchronization before to use it, do you want to configure it now ? !"))) {
|
||||||
self.do_action(o.action);
|
self.do_action(o.action);
|
||||||
}
|
}
|
||||||
|
@ -41,9 +38,8 @@ openerp.google_calendar = function(instance) {
|
||||||
else {
|
else {
|
||||||
alert(_t("An admin need to configure Google Synchronization before to use it !"));
|
alert(_t("An admin need to configure Google Synchronization before to use it !"));
|
||||||
}
|
}
|
||||||
//window.location = o.url;
|
|
||||||
}
|
}
|
||||||
else if (o.status == "NeedRefresh"){
|
else if (o.status == "need_refresh"){
|
||||||
self.$calendar.fullCalendar('refetchEvents');
|
self.$calendar.fullCalendar('refetchEvents');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,13 +47,12 @@ openerp.google_calendar = function(instance) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
instance.web_calendar.FullCalendarView.include({
|
instance.web_calendar.CalendarView.include({
|
||||||
extraSideBar: function() {
|
extraSideBar: function() {
|
||||||
this._super();
|
this._super();
|
||||||
if (this.dataset.model == "crm.meeting") {
|
if (this.dataset.model == "crm.meeting") {
|
||||||
var button = QWeb.render('GoogleCalendar.buttonSynchro');
|
this.$el.find('.oe_calendar_filter').prepend(QWeb.render('GoogleCalendar.buttonSynchro'));
|
||||||
this.$el.find('.oe_calendar_filter').prepend(button);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue