From c30200fc9b921de9c1021e07657e761928e86078 Mon Sep 17 00:00:00 2001 From: "ajay javiya (OpenERP)" Date: Tue, 8 Oct 2013 12:58:41 +0530 Subject: [PATCH] [IMP]: Handle accept,decline and view calendar url from controller and add new qweb template to allow a user to view and accept/decline without login bzr revid: aja@tinyerp.com-20131008072841-ob47desoiwqzagoa --- addons/base_calendar/base_calendar.py | 15 ++- addons/base_calendar/controllers/main.py | 35 +++++-- addons/base_calendar/crm_meeting.py | 7 ++ addons/base_calendar/crm_meeting_data.xml | 6 +- .../static/src/js/base_calendar.js | 91 ++++++------------- .../static/src/xml/base_calender.xml | 3 + .../security/ir.model.access.csv | 6 +- 7 files changed, 84 insertions(+), 79 deletions(-) diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index 06d151ee1d4..74351f87940 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -28,7 +28,7 @@ from openerp.tools.translate import _ import pytz import re import time - +import hashlib from openerp import tools, SUPERUSER_ID import openerp.service.report months = { @@ -235,6 +235,7 @@ class calendar_attendee(osv.osv): ('declined', 'Declined'), ('accepted', 'Accepted'), ('delegated', 'Delegated')], 'Status', readonly=True, \ + write= ['portal.group_anonymous'] , help="Status of the attendee's participation"), 'rsvp': fields.boolean('Required Reply?', help="Indicats whether the favor of a reply is requested"), @@ -271,6 +272,7 @@ property or property parameter."), multi='event_end_date'), 'ref': fields.reference('Event Ref', selection=openerp.addons.base.res.res_request.referencable_models, size=128), 'availability': fields.selection([('free', 'Free'), ('busy', 'Busy')], 'Free/Busy', readonly="True"), + 'access_token':fields.char('Invitation Token', size=256), } _defaults = { @@ -926,7 +928,7 @@ class calendar_event(osv.osv): ('tentative', 'Uncertain'), ('cancelled', 'Cancelled'), ('confirmed', 'Confirmed'), - ], 'Status', readonly=True), + ],'Status', readonly=True), 'exdate': fields.text('Exception Date/Times', help="This property \ defines the list of date/time exceptions for a recurring calendar component."), 'exrule': fields.char('Exception Rule', size=352, help="Defines a \ @@ -988,6 +990,11 @@ rule or repeating pattern of time to exclude from the recurring rule."), 'partner_ids': fields.many2many('res.partner', string='Attendees', states={'done': [('readonly', True)]}), } + def new_invitation_token(self, cr, uid, record, partner_id): + db_uuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid') + 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): att_obj = self.pool.get('calendar.attendee') user_obj = self.pool.get('res.users') @@ -1003,11 +1010,13 @@ rule or repeating pattern of time to exclude from the recurring rule."), continue local_context = context.copy() local_context.pop('default_state', None) + access_token = self.new_invitation_token(cr, uid, event, partner.id) att_id = self.pool.get('calendar.attendee').create(cr, uid, { 'partner_id': partner.id, 'user_id': partner.user_ids and partner.user_ids[0].id or False, 'ref': self._name+','+str(event.id), - 'email': partner.email + 'access_token': access_token, + 'email': partner.email, }, context=local_context) if partner.email: mail_to = mail_to + " " + partner.email diff --git a/addons/base_calendar/controllers/main.py b/addons/base_calendar/controllers/main.py index 7e9828e5729..3ee025be849 100644 --- a/addons/base_calendar/controllers/main.py +++ b/addons/base_calendar/controllers/main.py @@ -1,21 +1,44 @@ import simplejson import urllib +import openerp import openerp.addons.web.http as http from openerp.addons.web.http import request import openerp.addons.web.controllers.main as webmain +SUPERUSER_ID = 1 -class crm_meetting_importstatus(http.Controller): - - @http.route('/meeting/meeting_invitation', type='http', auth="none") - def meeting_invitation(self, db, token, action, view_type, id, status): +class meetting_invitation(http.Controller): + + @http.route('/meeting_invitation/accept', type='http', auth="none") + def accept(self, db, token, action, id): + # http://hostname:8069/meeting_invitation/accept/id=1&token=&db= + registry = openerp.modules.registry.RegistryManager.get(db) + attendee_pool = registry.get('calendar.attendee') + with registry.cursor() as cr: + attendee_ids = attendee_pool.search(cr, SUPERUSER_ID, [('access_token','=',token)]) + attendee_pool.do_accept(cr, SUPERUSER_ID, attendee_ids) + return self.view(db, token, action, id, view='form') + + + @http.route('/meeting_invitation/decline', type='http', auth="none") + def declined(self, db, token, id): + # http://hostname:8069/meeting_invitation/accept/id=1&token=&db= + registry = openerp.modules.registry.RegistryManager.get(db) + attendee_pool = registry.get('calendar.attendee') + with registry.cursor() as cr: + attendee_ids = attendee_pool.search(cr, SUPERUSER_ID, [('access_token','=',token)]) + attendee_pool.do_decline(cr, SUPERUSER_ID, attendee_ids) + return self.view(db, token, action, id, view='form') + + @http.route('/meeting_invitation/view', type='http', auth="none") + def view(self, db, token, action, id, view='calendar'): + # http://hostname:8069/meeting_invitation/view/id=1&token=&db=&view= js = "\n ".join('' % i for i in webmain.manifest_list('js', db=db)) css = "\n ".join('' % i for i in webmain.manifest_list('css',db=db)) - return webmain.html_template % { 'js': js, 'css': css, 'modules': simplejson.dumps(webmain.module_boot(db)), - 'init': 's.base_calendar.event("%s", "%s", "%s", "%s", "%s", "%s");'% (db, token, action, view_type, id, status), + 'init': 's.base_calendar.event("%s", "%s", "%s", "%s");' % (db, action, id, view), } diff --git a/addons/base_calendar/crm_meeting.py b/addons/base_calendar/crm_meeting.py index ae89d86d4f0..d04e6fc5cbe 100644 --- a/addons/base_calendar/crm_meeting.py +++ b/addons/base_calendar/crm_meeting.py @@ -212,6 +212,13 @@ class crm_meeting(osv.Model): attendee_pool.write(cr, uid, attendee.id, {'state': 'accepted'}, context) return True + def get_attendee(self, cr, uid, meeting_id, context=None): + att = [] + attendee_pool = self.pool.get('calendar.attendee') + for attendee in self.browse(cr,uid,int(meeting_id),context).attendee_ids: + att.append({'name':attendee.cn,'status': attendee.state}) + return att + def get_day(self, cr, uid, ids, time= None, context=None): rec = self.browse(cr, uid, ids,context=context)[0] date = datetime.strptime(rec.date,'%Y-%m-%d %H:%M:%S') diff --git a/addons/base_calendar/crm_meeting_data.xml b/addons/base_calendar/crm_meeting_data.xml index 615c9e281e4..3e0c79ca701 100644 --- a/addons/base_calendar/crm_meeting_data.xml +++ b/addons/base_calendar/crm_meeting_data.xml @@ -115,11 +115,11 @@
- Accept - Decline + Accept + Decline
- --
Sent by ${object.user_id.name} from ${object.user_id.company_id.name}. View this meeting detail directly in OpenERP. + --
Sent by ${object.user_id.name} from ${object.user_id.company_id.name}. View this meeting detail directly in OpenERP.
diff --git a/addons/base_calendar/static/src/js/base_calendar.js b/addons/base_calendar/static/src/js/base_calendar.js index 4d62b27a1ce..4f499da08fd 100644 --- a/addons/base_calendar/static/src/js/base_calendar.js +++ b/addons/base_calendar/static/src/js/base_calendar.js @@ -3,83 +3,43 @@ var _t = instance.web._t; var QWeb = instance.web.qweb; instance.base_calendar = {} - instance.base_calendar.invite = instance.web.Widget.extend({ + instance.base_calendar.invitation = instance.web.Widget.extend({ - init: function(parent,db,token,action,view_type,id,status) { + init: function(parent, db, action, id, view) { this._super(); - this.db = db; - this.token = token; - this.status = status; - this.action = action; - this.view_type = view_type; + this.db = db; + this.action = action; this.id = id; + this.view = view; }, start: function() { var self = this; - if (instance.session.session_is_valid(self.db) && (this.view_type == 'calendar' || this.view_type == 'form' && this.session.username != 'anonymous')) { - self.show_meeting(); - }else { - self.show_login(); + if(!instance.session.session_is_valid(self.db)) { + self.redirect_meeting_view(self.db,self.action,self.id,self.view); + } else { + new instance.web.Model("crm.meeting").call('get_attendee',[self.id]).then(function(res){ + self.open_invitation_form(res); + }); } }, - show_login: function(action) { - var self = this; - this.destroy_content(); - this.login = new instance.web.Login_extended(this,self.action); - this.login.appendTo(this.$el); - this.login.on('db_loaded',self,function(db,login){ - if (instance.session.session_is_valid(db)) { - (self.show_meeting()).done(function(){ - self.login.off('db_loaded'); - }); - } - else{ - self.show_login(); - } - }) + open_invitation_form : function(invitation){ + this.$el.html(QWeb.render('invitation_view', {'widget': invitation})); }, - destroy_content: function() { - _.each(_.clone(this.getChildren()), function(el) { - el.destroy(); - }); - this.$el.children().remove(); - }, - show_meeting : function(){ - var db = this.db; - var att_status = false; + redirect_meeting_view : function(db, action, meeting_id, view){ var self = this; + 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); + } 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(){ - if(self.view_type === 'form'){ - return location.replace(_.str.sprintf('/?db=%s#id=%s&view_type=%s&model=crm.meeting',self.db,self.id,self.view_type)); - } - else{ - return location.replace(_.str.sprintf('/?db=%s#view_type=%s&model=crm.meeting&action=%s',self.db,self.view_type,self.action)); - } + return location.replace(action_url); } - if(self.status === 'accepted'){ - att_status = "do_accept"; - } - else if(self.status === 'declined'){ - att_status === "do_decline"; - } - var calender_attendee = new instance.web.Model('calendar.attendee') - - return calender_attendee.get_func("search_read")([["id", "=", parseInt(this.token)]],['state']).done(function(res){ - if(res[0] && res[0]['state'] === "needs-action" && att_status){ - return calender_attendee.call(att_status,[[parseInt(self.token)]]).done(reload_page); - } - reload_page(); - }); + reload_page(); }, }); - instance.web.Login_extended = instance.web.Login.extend({ - do_login: function (db, login, password) { - var self = this; - (this._super.apply(this,arguments)).done(function(){ - self.trigger('db_loaded',db,login) - }); - } - }); + instance.web.form.Many2Many_invite = instance.web.form.FieldMany2ManyTags.extend({ initialize_content: function() { var self = this; @@ -214,9 +174,10 @@ instance.base_calendar = {} instance.web.form.widgets = instance.web.form.widgets.extend({ 'Many2Many_invite' : 'instance.web.form.Many2Many_invite', }); - instance.base_calendar.event = function (db, token, action, view_type, id, status) { + + instance.base_calendar.event = function (db, action, id, view) { instance.session.session_bind(instance.session.origin).done(function () { - new instance.base_calendar.invite(null,db,token,action,view_type,id,status).appendTo($("body").addClass('openerp')); + new instance.base_calendar.invitation(null,db,action,id,view).appendTo($("body").addClass('openerp')); }); } }; diff --git a/addons/base_calendar/static/src/xml/base_calender.xml b/addons/base_calendar/static/src/xml/base_calender.xml index 48c470c423a..6d1ebd1811e 100644 --- a/addons/base_calendar/static/src/xml/base_calender.xml +++ b/addons/base_calendar/static/src/xml/base_calender.xml @@ -10,4 +10,7 @@ + + Testttt + diff --git a/addons/portal_calendar/security/ir.model.access.csv b/addons/portal_calendar/security/ir.model.access.csv index 8031b83d1a7..9e3852aa9cf 100644 --- a/addons/portal_calendar/security/ir.model.access.csv +++ b/addons/portal_calendar/security/ir.model.access.csv @@ -1,3 +1,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_meeting,meeting,base_calendar.model_crm_meeting,portal.group_portal,1,0,0,0 -access_anonymous_meeting,meeting,base_calendar.model_crm_meeting,portal.group_anonymous,1,0,0,0 +access_meeting,portal_meeting,base_calendar.model_crm_meeting,portal.group_portal,1,0,0,0 +access_anonymous_meeting,anonymous_meeting,base_calendar.model_crm_meeting,portal.group_anonymous,1,0,0,0 +access_anonymous_attendee,anonymous_attendee,base_calendar.model_calendar_attendee,portal.group_anonymous,1,0,0,0 +access_anonymous_event,anonymous_event,base_calendar.model_calendar_event,portal.group_anonymous,1,0,0,0