I need to approve a record through email. So I send details and Approve button for approve. If I click this approve button, the record should be approve and the record should be open in application. So in the email template, I call the controller and I pass the database, token, action_id and id.
Here the problem is action_id not passed to controller. Its null. So the url page is opened with Not found error.
in the Send for Approval action:
class Application(models.Model):
_name = 'application'
@api.multi
def action_sent_for_approval(self):
for record in self:
record.state = 'send_for_approval'
self._send_mail_to_manager('module.template_approval_mail')
@api.multi
def _send_mail_to_manager(self, template_xmlid, force_send=False):
res = False
form_view = self.env.ref('module.view_form_application')
approve_template = self.env.ref(template_xmlid)
colors = {
'needsAction': 'grey',
'approved': 'green',
'tentative': '#FFFF00',
}
rendering_context = dict(self._context)
rendering_context.update({
'color': colors,
'action_id': self.env['ir.actions.act_window'].search([('view_id', '=', form_view.id)], limit=1).id,
'dbname': self._cr.dbname,
'base_url': self.env['ir.config_parameter'].get_param('web.base.url', default='http://localhost:8069')
})
approve_template = approve_template.with_context(rendering_context)
mails_to_send = self.env['mail.mail']
for record in self:
if record.employee_id.parent_id.work_email:
mail_id = approve_template.send_mail(record.id)
vals = {}
vals['model'] = None
vals['res_id'] = False
current_mail = self.env['mail.mail'].browse(mail_id)
current_mail.mail_message_id.write(vals)
mails_to_send |= current_mail
if force_send and mails_to_send:
res = mails_to_send.send()
return res
In template_approval_mail email template,
<field name="body_html"><![CDATA[
<div summary="o_mail_template" style="padding:0px;width:600px;margin:auto;background: #FFFFFF repeat top /100%;color:#777777">
% set colors = {'needsAction': 'grey', 'approved': 'green', 'tentative': '#FFFF00'}
<table cellspacing="0" cellpadding="0" style="width:600px;border-collapse:collapse;background:inherit;color:inherit">
<tbody><tr>
<td valign="center" width="200" style="padding:10px 10px 10px 5px;font-size: 12px">
<img src="/logo.png" style="padding: 0px; margin: 0px; height: auto; width: 80px;" alt="${user.company_id.name}">
</td>
<td valign="center" align="right" width="340" style="padding:10px 10px 10px 5px; font-size: 12px;">
<p>
<a href="/accept?db=${'dbname' in ctx and ctx['dbname'] or ''}&token=${object.access_token}&action=${'action_id' in ctx and ctx['action_id'] or ''}"&id=${object.id}" style="padding: 5px 10px; font-size: 12px; line-height: 18px; color: #FFFFFF; border-color:#875A7B; text-decoration: none; display: inline-block; margin-bottom: 0px; font-weight: 400; text-align: center; vertical-align: middle; cursor: pointer; white-space: nowrap; background-image: none; background-color: #875A7B; border: 1px solid #875A7B; border-radius:3px">Approve</a>
</p>
</td>
</tr></tbody>
</table>
----- Details -----
</div>]]></field>
</record>
In Controller,
@http.route('/accept', type='http', auth="none")
def accept(self, db, token, action, id, **kwargs):
registry = registry_get(db)
with registry.cursor() as cr:
env = Environment(cr, SUPERUSER_ID, {})
record = env['application'].search([('access_token', '=', token), ('state', '=', 'send_for_approval')])
if record:
record.action_approval()
return self.view(db, token, action, id, view='form')
@http.route('/view', type='http', auth="none")
def view(self, db, token, action, id, view='form'):
registry = registry_get(db)
with registry.cursor() as cr:
# Since we are in auth=none, create an env with SUPERUSER_ID
env = Environment(cr, SUPERUSER_ID, {})
if request.session.uid:
return werkzeug.utils.redirect('http://localhost:8069' % (db, id))
I referred this method in calendar invitation mail in Calendar module in Odoo 10.
I have using Odoo 10.