Odoo how to send email on button click


Create mail template

<?xml version="1.0" ?>
<odoo>
    <data noupdate="0">
        <!--Email template -->
        <record id="email_template_employee_peer_feedback" model="mail.template">
            <field name="name">Employee Peer Feedback</field>
            <field name="model_id" ref="employee_peer_feedback.model_employee_peer_feedback"/>
            <field name="subject">Employee Peer Feedback</field>
            <field name="email_from">${('&lt;%s&gt;' % (object.env.user.company_id.email or user.email)) | safe}</field>
            <field name="recipient_ids">${object.recipient_ids|safe}</field>
            <field name="use_default_to" eval="True"/>
            <field name="body_html" type="html">
                <div>${object.body_html}</div>                
            </field>
            <field name="auto_delete" eval="True"/>
            <field name="user_signature" eval="True"/>
        </record>

    </data>
</odoo>

Add button on xml view

<button name="action_submit" type="object"
                            string="Submit 2"                            
                            groups="hr.group_hr_manager,hr.group_hr_user"/>

Add python function to send mail

@api.multi
    def action_submit(self):
        self.ensure_one()
        
        template_obj = self.env['mail.template'].sudo().search([('name','=','Employee Peer Feedback')], limit=1)
        base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
        
        for peers in self.peer_employee_ids:
            _url = ''+ base_url +'/peer_feedback/'+ str(self.id) +'/'
            if peers.user_id.partner_id.id:
                body_html = '<p>Dear '+ peers.name +',<br />\
                    We request your feedback for the employee '+ self.employee_id.name +' as part \
                    of the Performance Review. Click on the link below to submit your \
                    comments.</p><br /><p><a href=%s class="btn btn-danger">Employee Peer Feedback</a><br></p>' % _url

                if template_obj:
                    mail_values = {                        
                        'body_html': body_html,
                        'recipient_ids': [(4, peers.user_id.partner_id.id)]
                    }
                    create_and_send_email = self.env['mail.mail'].create(mail_values).send() 

Error when compiling AST TypeError: required field “posonlyargs” missing from arguments


Edit doo/addons/base/models/qweb.py

@@ -109,6 +109,7 @@ def visit_Lambda(self, node):
                # handle that cross-version
                kwonlyargs=[],
                kw_defaults=[],(LINE 111) 
                posonlyargs=[], ----ADD NEW LINE
            ),
            body=Contextifier(self._safe_names + tuple(names)).visit(node.body)
        ), node)
@@ -554,7 +555,7 @@ def _create_def(self, options, body, prefix='fn', lineno=None):
                arg(arg='values', annotation=None),
                arg(arg='options', annotation=None),
                arg(arg='log', annotation=None),
            ], defaults=[], vararg=None, kwarg=None, posonlyargs=[], kwonlyargs=[], kw_defaults=[]), -- UPDATE THIS LINE (LINE 557) 
            body=body or [ast.Return()],
            decorator_list=[])
        if lineno is not None:

Default Values For One2many Fields in Odoo


    @api.model
    def default_get(self, fields):
        vals = super(LibraryManagement, self).default_get(fields)
        vals['note'] = "Test Data"
        library_management_lines = [(5,0,0)]
        books_rec = self.env['library.books'].search([])
        for rec in books_rec:
            line = (0,0,{
                'library_management_id' : self.id,
                'book_id': rec.id,
                'issue_date': date.today(),
            })
            library_management_lines.append(line)
        vals['library_management_line_ids'] = library_management_lines
        return vals

ModuleNotFoundError: No module named ‘psycopg2’


1 Install Psycopg2

To install Psycopg2 on Ubuntu, make sure you have installed libpq-dev package:

$ sudo apt-get install libpq-dev

Then there are two ways to install Psycopg2 for Python3 on Ubuntu: by apt or by pip.

1.1 Install Psycopg2 by apt

$ sudo apt-get install python3-Psycopg2

Make sure add 3 suffix to python, otherwise you will install Psycopg2 for Python2 by default.

1.2 Install Psycopg2 by Python pip

First of all you need Python3 version pip:

$ sudo apt-get install python3-pip

This will install the Python3 version of pip command: pip3. Then you can install Psycopg2 using pip3:

$ sudo pip3 install Psycopg2

Programmatically create a sale order using Python


# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models


class SaleOrder(models.Model):
    _inherit = 'sale.order'

    @api.multi
    def create_action(self):
        order_line = [
                (0, 0, {
                        'product_id': 23,
                        'product_uom_qty': 1.00,
                }),
                (0, 0, {
                        'product_id': 15,
                        'product_uom_qty': 2.00,
                })
            ]

        sale_order = self.env['sale.order'].create({
            'partner_id': 14,
            'partner_invoice_id': 14,
            'partner_shipping_id': 14,
            'order_line': order_line,
            'pricelist_id': 1,
            'picking_policy': 'direct',
        })
so = self.env['sale.order'].create({
            'partner_id': self.partner_customer_usd.id,
            'partner_invoice_id': self.partner_customer_usd.id,
            'partner_shipping_id': self.partner_customer_usd.id,
            'order_line': [(0, 0, {'name': prod_gap.name, 'product_id': prod_gap.id, 'product_uom_qty': 2, 'product_uom': prod_gap.uom_id.id, 'price_unit': prod_gap.list_price})],
            'pricelist_id': self.pricelist_usd.id,
        })
        so.action_confirm()
        so._create_analytic_account()

Send mail on Submit – odoo

@api.multi
    def action_submit(self):
        base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
        for peers in self.peer_employee_ids:
            _url = ''+ base_url +'/peer_feedback/'+ str(self.id) +'/'
            button_name = str("Employee Peer Feedback")
            if peers.user_id.partner_id.id:
                subject = 'Employee Peer Feedback Form for %s' % peers.name                        
                body_html = '<p>Dear '+ peers.name +',<br />\
                            We request your feedback for the employee '+ self.employee_id.name +' as part \
                            of the Performance Review. Click on the link below to submit your \
                            comments.</p><br /><p><a href=%s class="btn btn-danger">Employee Peer Feedback</a><br></p>' % _url                
                mail = self.env['mail.mail'].create({
                    'subject': subject,
                    'body_html': body_html,
                    'notification': True,
                    'state': 'outgoing',
                    'recipient_ids': [(4, peers.user_id.partner_id.id)]
                })
        self.state = 'submitted'

add button on List View -odoo 12


__manifest__.py

{
    "name": "Leaves Summary Create Leave Button",
    "summary": "Leaves Summary Create Leave Button",
    "version": "12.0.1",
    "description": """Leaves Summary Create Leave Button""",
    "version" :  "1.0.0",
    "author": "Ananthu Krishna",
    "maintainer": "Ananthu Krishna",
    "website": "http://www.codersfort.com",
    "license" :  "Other proprietary",
    "category": "HR",
    "depends": [
        "web",
        "hr",
    ],
    "data": [
        "views/assets.xml",        
    ],
    "qweb": ["static/src/xml/qweb.xml"],
    "installable": True,
    "application": True,
}

assets.xml

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <template id="assets_backend_inherit_ninebox" inherit_id="web.assets_backend" name="Employees Asset">        
        <xpath expr="script[last()]" position="after">            
            <script type="text/javascript" src="/leaves_summary_create_leave_button/static/src/js/listview_button.js"></script>
            <link href="/leaves_summary_create_leave_button/static/src/css/style.css" rel="stylesheet" type="text/css"/>           
        </xpath>
    </template>
</odoo>

qweb.xml

<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">

    <t t-extend="ListView.buttons">
        <t t-jquery="div.o_list_buttons" t-operation="append">            
            <t t-if = "widget.modelName == 'hr.leave.report'">               
                <button type="button" class="btn btn-primary o_crete_leave_from_summary">
                    Apply Leave
                </button>      
            </t>      
        </t>
    </t>

</templates>

listview_button.js

odoo.define('leaves_summary_create_leave_button.listview_button', function (require) {
    "use strict";

    var core = require('web.core');
    var ListView = require('web.ListView');
    var ListController = require("web.ListController");

    var IncludeListView = {

        renderButtons: function() {
            this._super.apply(this, arguments);
            if (this.modelName === "hr.leave.report") {
                var summary_apply_leave_btn = this.$buttons.find('button.o_crete_leave_from_summary');              
                summary_apply_leave_btn.on('click', this.proxy('crete_leave_from_summary'))
            }
        },
        crete_leave_from_summary: function(){
            var self = this;
            var action = {
                type: "ir.actions.act_window",
                name: "Leave",
                res_model: "hr.leave",
                views: [[false,'form']],
                target: 'new',
                views: [[false, 'form']], 
                view_type : 'form',
                view_mode : 'form',
                flags: {'form': {'action_buttons': true, 'options': {'mode': 'edit'}}}
            };
            return this.do_action(action);
        },

    };
    ListController.include(IncludeListView);
});