Enable Dark Mode!
how-to-create-pivot-report-using-query-in-odoo-18.jpg
By: Sonu S

How to Create Pivot Report Using Query in Odoo 18

Functional Odoo 18

Odoo 18 is a robust and versatile open-source ERP system designed to streamline business operations across various domains, including Accounting, Sales, Inventory, and HR. This latest version enhances user experience with a modern interface, improved performance, and automation, making it an adaptable solution for businesses of all sizes. One of its standout features is its ability to generate real-time reports and analytics, enabling businesses to make well-informed decisions based on accurate data.

Odoo 18 offers an enhanced Pivot View, allowing users to efficiently analyze and summarize large volumes of data. Pivot reports help transform raw information into actionable insights by enabling users to group, filter, and aggregate data in a structured format. While Odoo provides built-in pivot views for many standard modules, advanced users can create custom reports using SQL queries. This approach is particularly beneficial for generating complex reports, such as financial summaries, sales performance tracking, or vendor bill analysis. By integrating Odoo’s ORM with PostgreSQL views, businesses can build powerful, dynamic reports that are easily accessible within the system. 

For example, we will create a Vendor Bill Report that will analyze vendor bills based on key financial metrics. The report will include: Invoice Name, Bill Month, Vendor Name, Purchase Order Name, Total Bills, Total Billed Amount, Total Paid Amount, Total Unpaid Amount, Company, Salesperson, Journal, and Invoice Date.

Creating the Model

Since we are using an SQL view instead of a regular Odoo model, we need to define our model in a way that does not create a database table. We do this by setting _auto = False in the model definition.

Python:

from odoo import models, fields
class VendorBillReport(models.Model):
    _name = 'vendor.bill.report'
    _description = 'Vendor Bill Report'
    _auto = False  # No table creation, uses SQL view
    invoice_name = fields.Char(string="Invoice Name")
    bill_month = fields.Char(string="Bill Month")
    vendor_name = fields.Char(string="Vendor Name")
    purchase_order_name = fields.Char(string="Purchase Order")
    total_bills = fields.Integer(string="Total Bills")
    total_billed = fields.Float(string="Total Billed Amount")
    total_paid = fields.Float(string="Total Paid")
    total_unpaid = fields.Float(string="Total Unpaid")
    company_id = fields.Many2one('res.company', string="Company")
    sale_person_id = fields.Many2one('res.users', string="Salesperson")
    journal_id = fields.Many2one('account.journal', string="Journal")
    invoice_date = fields.Date(string="Invoice Date")

Creating the SQL View

Odoo allows us to define an SQL view using the init() method. This method executes raw SQL to create a view that retrieves the required data.

Python:

   def init(self):
        """
        Creates or replaces the SQL view for the Vendor Bill Report Pivot table.
        This view aggregates data from account moves to provide a summary of
        vendor bills based on bill month, vendor, purchase orders, and payment status.
        """
        self.env.cr.execute("""
            CREATE OR REPLACE VIEW vendor_bill_report AS (
                SELECT 
                    row_number() OVER() AS id,
                    am.name AS invoice_name,
                    TO_CHAR(am.invoice_date, 'YYYY-MM') AS bill_month,
                    rp.name AS vendor_name,
                    COALESCE(po.name, 'No Purchase Order') AS purchase_order_name,
                    COUNT(DISTINCT am.id) AS total_bills,
                    SUM(am.amount_total) AS total_billed,
                    SUM(CASE WHEN am.payment_state = 'paid' THEN am.amount_total ELSE 0 END) AS total_paid,
                    SUM(CASE WHEN am.payment_state = 'not_paid' THEN am.amount_total ELSE 0 END) AS total_unpaid,
                    am.company_id,
                    am.invoice_user_id AS sale_person_id,
                    am.journal_id,
                    am.invoice_date
                FROM 
                    account_move am
                JOIN 
                    res_partner rp ON am.partner_id = rp.id
                LEFT JOIN 
                    account_move_line aml ON aml.move_id = am.id
                LEFT JOIN 
                    purchase_order_line pol ON aml.purchase_line_id = pol.id
                LEFT JOIN 
                    purchase_order po ON pol.order_id = po.id
                WHERE 
                    am.move_type = 'in_invoice'  -- Only vendor bills
                    AND am.state = 'posted'      -- Only posted invoices
                GROUP BY 
                    am.name, bill_month, rp.name, po.name, 
                    am.company_id, am.invoice_user_id, am.journal_id, am.invoice_date
                ORDER BY 
                    bill_month DESC, total_billed DESC
            );
        """)

Creating the Pivot View XML

Now, we need to define the pivot view in an XML file. The pivot view will structure the report dynamically, allowing users to analyze data in different dimensions.

xml:

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    
    <record id="vendor_bill_report_pivot_view" model="ir.ui.view">
        <field name="name">vendor.bill.report.pivot</field>
        <field name="model">vendor.bill.report</field>
        <field name="arch" type="xml">
            <pivot string="Vendor Bills Analysis">
                <field name="invoice_name" type="row"/>
                <field name="vendor_name" type="col"/>
                <field name="total_billed" type="measure"/>
                <field name="total_paid" type="measure"/>
                <field name="total_unpaid" type="measure"/>
            </pivot>
        </field>
    </record>
    
    <record id="vendor_bill_report_action" model="ir.actions.act_window">
        <field name="name">Vendor Bills Report</field>
        <field name="res_model">vendor.bill.report</field>
        <field name="view_mode">pivot</field>
    </record>
    <menuitem id="menu_vendor_bill_report"
              name="Vendor Bills Report"
              parent="account.account_reports_management_menu"
              action="vendor_bill_report_action"/>
    
</odoo>

* type=”row”

<field name="invoice_name" type="row"/>

This means that each row in the pivot table represents a unique invoice.

* type=”col”

<field name="vendor_name" type="col"/>

This means that each column represents a different vendor.

* type=”measure”

<field name="total_billed" type="measure"/>
<field name="total_paid" type="measure"/>
<field name="total_unpaid" type="measure"/>

These are the values aggregated in the pivot table and that are displayed on the measure.

After including these files in the custom module and successfully installing it, a new menu item will appear under Invoicing > Reporting > Vendor Bills Report. Clicking on this menu item will open the pivot report view, where users can analyze vendor bills using dynamic filtering, grouping, and aggregation tools, as shown in the figure.

How to Create Pivot Report Using Query in Odoo 18-cybrosys

In Odoo's Pivot View, the plus button allows users to dynamically modify and customize the way data is displayed in the pivot table. When users interact with the pivot table, they can add multiple fields as rows or columns, enabling them to perform a more granular analysis of their data as shown below.

How to Create Pivot Report Using Query in Odoo 18-cybrosys

Taking the company as an example, the vendor pivot report based on the company is displayed in the figure.

How to Create Pivot Report Using Query in Odoo 18-cybrosys

By clicking the inner plus button on companies, we can select the desired options as shown in the figure below.

How to Create Pivot Report Using Query in Odoo 18-cybrosys

The data will be retrieved by choosing the invoice name, as shown below.

How to Create Pivot Report Using Query in Odoo 18-cybrosys

We can also customize the measures by using the "Measure" button and selecting the desired measure according to our requirements, as shown in the figure below.

How to Create Pivot Report Using Query in Odoo 18-cybrosys

In conclusion, creating pivot reports using SQL queries in Odoo 18 offers a powerful way to analyze complex data with flexibility. By defining SQL views and integrating them with Odoo's ORM, users can generate reports that provide meaningful insights, tailored to business needs. This approach is particularly beneficial for those needing specific reports, such as financial summaries or vendor performance. Additionally, Odoo’s core functionality enables easy export of these reports to XLSX format, allowing businesses to share and analyze data beyond the system. Combining SQL query power with Odoo’s intuitive pivot interface and export features enables more informed, data-driven decision-making.

To read more about. How to Inherit Existing Pivot View Report in Odoo 17, refer to our blog How to Inherit Existing Pivot View Report in Odoo 17.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message