[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
This commit is contained in:
ajay javiya (OpenERP) 2013-10-08 12:58:41 +05:30
parent b8fd401199
commit c30200fc9b
7 changed files with 84 additions and 79 deletions

View File

@ -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

View File

@ -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('<script type="text/javascript" src="%s"></script>' % i for i in webmain.manifest_list('js', db=db))
css = "\n ".join('<link rel="stylesheet" href="%s">' % 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),
}

View File

@ -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')

View File

@ -115,11 +115,11 @@
</table>
</div>
<div style="height: 50px;width:300px; margin:0 auto;">
<a style="padding: 8px 30px 8px 30px;border-radius: 6px;border: 1px solid #CCCCCC;background:#8A89BA;margin : 0 15px 0 0;text-decoration: none;color:#FFFFFF;" href="${ctx['base_url']}/meeting/meeting_invitation?db=${ctx['dbname']}&token=${ctx['att_obj'].id}&action=${ctx['action_id']}&id=${object.id}&view_type=form&status=accepted">Accept</a>
<a style="padding: 8px 30px 8px 30px;border-radius: 6px;border: 1px solid #CCCCCC;background:#8A89BA;text-decoration: none;color:#FFFFFF;" href="${ctx['base_url']}/meeting/meeting_invitation?db=${ctx['dbname']}&token=${ctx['att_obj'].id}&action=${ctx['action_id']}&id=${object.id}&view_type=form&status=declined">Decline</a>
<a style="padding: 8px 30px 8px 30px;border-radius: 6px;border: 1px solid #CCCCCC;background:#8A89BA;margin : 0 15px 0 0;text-decoration: none;color:#FFFFFF;" href="${ctx['base_url']}/meeting_invitation/accept?db=${ctx['dbname']}&token=${ctx['att_obj'].access_token}&action=${ctx['action_id']}&id=${object.id}">Accept</a>
<a style="padding: 8px 30px 8px 30px;border-radius: 6px;border: 1px solid #CCCCCC;background:#808080;text-decoration: none;color:#FFFFFF;" href="${ctx['base_url']}/meeting_invitation/decline?db=${ctx['dbname']}&token=${ctx['att_obj'].access_token}&action=${ctx['action_id']}&id=${object.id}">Decline</a>
</div>
<div>
-- </br> Sent by ${object.user_id.name} from ${object.user_id.company_id.name}. View this meeting detail <a href="${ctx['base_url']}/meeting/meeting_invitation?db=${ctx['dbname']}&token=${ctx['att_obj'].id}&action=${ctx['action_id']}&id=${object.id}&view_type=calendar&status=">directly in OpenERP.</a>
-- </br> Sent by ${object.user_id.name} from ${object.user_id.company_id.name}. View this meeting detail <a href="${ctx['base_url']}/meeting_invitation/view?db=${ctx['dbname']}&token=${ctx['att_obj'].access_token}&id=${object.id}">directly in OpenERP.</a>
</div>
</div>
</body>

View File

@ -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'));
});
}
};

View File

@ -10,4 +10,7 @@
<t t-set="i" t-value="i + 1"/>
</t>
</t>
<t t-name="invitation_view">
Testttt
</t>
</template>

View File

@ -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

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_meeting meeting portal_meeting base_calendar.model_crm_meeting portal.group_portal 1 0 0 0
3 access_anonymous_meeting meeting anonymous_meeting base_calendar.model_crm_meeting portal.group_anonymous 1 0 0 0
4 access_anonymous_attendee anonymous_attendee base_calendar.model_calendar_attendee portal.group_anonymous 1 0 0 0
5 access_anonymous_event anonymous_event base_calendar.model_calendar_event portal.group_anonymous 1 0 0 0