[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:
parent
b8fd401199
commit
c30200fc9b
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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'));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,4 +10,7 @@
|
|||
<t t-set="i" t-value="i + 1"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="invitation_view">
|
||||
Testttt
|
||||
</t>
|
||||
</template>
|
||||
|
|
|
@ -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
|
||||
|
|
|
Loading…
Reference in New Issue