Skip to content

Odoo18 Dashboard OWL

Odoo18 Dashboard OWL

Build a Sales Dashboard from Scratch

Odoo18 Dashboard OWL drives modern interface design. In this tutorial, we cover how to use Odoo18 Dashboard OWL to build a full-featured sales dashboard step by step. First, we set up the XML templates. Then, we integrate OWL components with JavaScript to fetch and render real data. Finally, we customize charts and interactivity for a seamless user experience. By the end, you will master Odoo18 Dashboard OWL for any reporting need.

source code : https://github.com/afjol77/odoo_sales_dashboard


Why Use Odoo18 Dashboard OWL?

First, Odoo18 Dashboard OWL leverages the lightweight OWL framework for reactive UI. Moreover, it integrates seamlessly with Odoo’s ORM and services. As a result, you get:

  • Reactive components that update on data change.
  • Modular templates in XML for clear separation of view logic.
  • Chart.js integration to visualize metrics.
  • Action services for navigation on user clicks.

Therefore, Odoo18 Dashboard OWL helps you build dashboards faster and maintain them easily.


Project Structure Overview

Next, let’s inspect the key files under odoo_sales_dashboard/static/src:

odoo_sales_dashboard/
├─ static/
│  ├─ src/
│  │  ├─ css/
│  │  │  └─ sales_dashboard.css
│  │  ├─ js/
│  │  │  └─ sales_dashboard.js
│  │  └─ xml/
│  │     └─ sales_dashboard_view.xml
  • XML templates define the markup and CSS links.
  • JavaScript implements the OWL component logic.
  • CSS file styles cards, charts, and layout.

Defining the XML View Templates

In sales_dashboard_view.xml, we declare OWL templates:

<?xml version="1.0" encoding="UTF-8" ?>
<templates id="sales_dashboard_template" xml:space="preserve">
    <t t-name="sales_dashboard" owl="1">
        <div class="parent-div" style="height:100% !important; overflow-y:scroll !important; font-family:roboto; background-color: #F7F7F7;">
            <link rel="stylesheet" type="text/css" href="odoo_sales_dashboard/static/src/css/sales_dashboard.css"/>
            <t t-call="sales-section"/>
        </div>
    </t>
    ...
</templates>

Parent Wrapper and Styles

First, the <t t-name="sales_dashboard"> template wraps all content. It links the CSS file and calls the main sales-section.

Sales Cards Section

Within <t t-name="sales-section"> we include:

<section id="sales_section" class="dashboard-container">
    <h2 class="text-center fw-bold mb-4" style="font-size: 24px;">Sales Dashboard</h2>
    <t t-call="sales_cards"/>
    <t t-call="sales_charts"/>
    <t t-call="top_sales_reps_section"/>
</section>

sales_cards

This template renders KPI cards:

<t t-name="sales_cards">
  <div class="row mb-3">
    <!-- Total Sales Card -->
    <div class="col-lg-6 col-md-6 mb-3">
      <div class="card sales-card light-blue">
        <h3>Total Sales</h3>
        <div class="card-data"><p><t t-esc="currency_symbol"/> <t t-esc="total_sales_amount"/></p></div>
      </div>
    </div>
    <!-- More cards… -->
  </div>
</t>
  • We bind OWL expressions via <t t-esc="..."/>.
  • We include click handlers with t-on-click.

Sales Charts Section

Under <t t-name="sales_charts"> we define four chart containers:

<div class="row mb-3">
  <div class="col-lg-6"><canvas t-ref="canvasMonthlySales"></canvas></div>
  <div class="col-lg-6"><canvas t-ref="canvasTopSellingProducts"></canvas></div>
  <!-- Additional charts... -->
</div>
  • Each <canvas> has a t-ref for OWL to reference in JS.

Top Sales Reps Table

Finally, <t t-name="top_sales_reps_section"> shows a table:

<table class="table">
  <thead>…</thead>
  <tbody>
    <t t-foreach="top_sales_reps" t-as="rep">
      <tr><td><t t-esc="rep.sales_rep_name"/></td><td><t t-esc="rep.sales_volume"/></td></tr>
    </t>
  </tbody>
</table>

Implementing the OWL Component (JavaScript)

Now, let’s inspect sales_dashboard.js:

/** @odoo-module **/
import { registry } from "@web/core/registry";
import { Component } from "@odoo/owl";
import { useService } from "@web/core/utils/hooks";
import { onWillStart, onMounted, useRef } from "@odoo/owl";

export class SalesDashboard extends Component {
  setup() {
    this.orm = useService("orm");
    this.canvasMonthlySales = useRef('canvasMonthlySales');
    // … other canvas refs …

    onWillStart(async () => {
      await loadBundle("web.chartjs_lib");
      const data = await this.orm.call('sale.order','get_sales_dashboard_data');
      Object.assign(this, data);
    });

    onMounted(() => {
      this.renderMonthlySales();
      // … other render calls …
    });
  }
  // … click handlers …

  renderMonthlySales() {
    const ctx = this.canvasMonthlySales.el.getContext('2d');
    new Chart(ctx, {/*… options …*/});
  }
  // … other render methods …
}
SalesDashboard.template = 'sales_dashboard';
registry.category("actions").add("sales_dashboard", SalesDashboard);

Setup and Data Fetching

  • We use useService("orm") to call sale.order.get_sales_dashboard_data on the server.
  • We assign the returned metrics directly onto this.

Interactivity: Click Handlers

We define methods like _onClickLeads() that call:

this.env.services.action.doAction({
  name: _t("Leads"),
  type: 'ir.actions.act_window',
  res_model: 'crm.lead',
  view_mode: 'tree',
  domain: [['type','=','lead']],
});

This opens the standard Odoo list view.

Rendering Monthly Sales Chart

Inside renderMonthlySales():

const ctx = this.canvasMonthlySales.el.getContext('2d');
const gradient = ctx.createLinearGradient(0,0,0,400);
gradient.addColorStop(0,'rgba(89,50,234,0.7)');
gradient.addColorStop(1,'rgba(89,50,234,0.1)');
new Chart(ctx, {
  type: 'line',
  data: { labels: monthNames, datasets: [{ data: salesAmounts, backgroundColor: gradient, /*...*/ }] },
  options: { responsive:true, plugins:{ legend:{position:'bottom'}}, scales:{ y:{ title:{text:`Sales (${this.currency_symbol})`} }} }
});
  • We create a gradient fill for the line chart.
  • We format tooltips to show currency.

Rendering Top Selling Products Chart

The renderTopSellingProducts() method sorts products, slices top 5, and displays a bar chart:

new Chart(this.canvasTopSellingProducts.el, {
  type: 'bar',
  data: { labels: productNames, datasets:[{ label:`Revenue (${this.currency_symbol})`, data:productRevenues }]},
  options: { plugins:{ tooltip:{ callbacks:{ title: ctx=> this.top_selling_products[ctx[0].dataIndex].product_name }}}}
});

We use callbacks to show full product names in tooltips.

Rendering Fulfillment Efficiency Pie

In renderFulfillmentEfficiency():

new Chart(this.canvasFulfillmentEfficiency.el, {
  type: 'pie',
  data: { labels:['On-time','Delayed'], datasets:[{ data:[onTimeCount,delayedCount], backgroundColor:['#4CAF50','#FF6F61'] }]},
  options: { plugins:{ title:{ text:`Efficiency: ${efficiencyPercentage.toFixed(1)}%` }}}
});

This pie chart displays shipment performance.

Rendering Sales by Customer Bar

Finally, renderSalesByCustomer() shows a horizontal bar chart of sales volume by customer:

new Chart(this.canvasSalesByCustomer.el, {
  type: 'bar',
  data: { labels: customers, datasets:[{ data:salesVolumes }]},
  options: { indexAxis:'y', scales:{ x:{ beginAtZero:true, title:{ text:`Volume (${this.currency_symbol})`} } }}
});

Styling the Dashboard

In sales_dashboard.css, apply card colors and layout:

.sales-card { padding: 1rem; border-radius: 8px; transition: transform .2s; }
.sales-card.light-blue { background: #E0F2FF; }
.sales-card:hover { transform: scale(1.02); cursor: pointer; }
.dashboard-container { padding: 2rem; }

You can adjust fonts, spacing, and responsive breakpoints as needed.


Putting It All Together

  1. Enable the action in your module’s __manifest__.py under ir.actions.client to register the dashboard.
  2. Restart Odoo and update your module: ./odoo-bin -u odoo_sales_dashboard -d your_db
  3. Access the dashboard via a menu item that references the sales_dashboard action.

You now have a dynamic Odoo18 Dashboard OWL that displays KPIs, charts, and detailed tables.


Next Steps & Advanced Tips

  • Add Filtering Controls: Use OWL state hooks to filter data by date or salesperson.
  • Cache Data: Implement server-side caching for heavy queries.
  • Export to PDF: Integrate wkhtmltopdf to allow users to export dashboard snapshots.
  • Mobile Optimizations: Adjust CSS grid and canvas sizes for small screens.

Resources & Further Reading

With this guide, you can confidently build, customize, and extend Odoo18 Dashboard OWL components to fit any reporting requirement. Happy coding!


Discover more from teguhteja.id

Subscribe to get the latest posts sent to your email.

Leave a Reply

WP Twitter Auto Publish Powered By : XYZScripts.com