In the world of business, first impressions matter. From your marketing materials to your official documents, every touchpoint reflects your brand’s professionalism and attention to detail. For businesses utilizing Odoo, one such critical document is the invoice receipt. While Odoo provides robust default templates, there often comes a need to tailor these to specific branding, legal requirements, or operational preferences. This is where the power of Odoo QWEB Invoice Receipt customization truly shines.
Imagine presenting a perfectly branded receipt that not only confirms payment but also reinforces your company’s identity. This guide will walk you through the essential steps to customize your Odoo QWEB Invoice Receipt, transforming a standard document into a powerful brand asset. We’ll delve into the practicalities of Odoo’s QWEB templating engine, showing you how to dynamically pull data and craft a receipt that meets your exact needs.
Why Customizing Your Odoo Invoice Receipt Is Essential
Before we dive into the “how,” let’s explore the “why.” A customized invoice receipt offers numerous benefits:
- Brand Reinforcement: Every document leaving your company is an opportunity for branding. A custom receipt allows you to integrate your logo, brand colors, and specific messaging, creating a consistent and professional image.
- Clarity and Readability: Tailor the layout to highlight crucial information like amount, date, and invoice number, making it easier for your customers to understand their transactions.
- Legal and Compliance Requirements: Different regions or industries may have specific requirements for what must appear on a receipt. Customization ensures you meet these obligations without hassle.
- Improved User Experience: A well-designed, clear receipt enhances the customer experience, fostering trust and reducing inquiries related to payment details.
- Operational Efficiency: Automating the generation of detailed, customized receipts frees up valuable time for your team.
Leveraging Odoo’s QWEB templating engine allows you to achieve all this and more.
Understanding Odoo QWEB: The Backbone of Your Reports
QWEB (Odoo’s templating engine) is a powerful, XML-based templating system used for generating dynamic HTML content, primarily for reports, web pages, and email templates within Odoo. It combines XML structures with special directives (like t-esc, t-if, t-foreach) to render data from your Odoo database into user-friendly formats. When customizing your Odoo QWEB Invoice Receipt, you’ll be working directly with these QWEB elements to define how your data is displayed.
Think of QWEB as the bridge between your Odoo database and the beautiful documents you present to your clients. It allows you to:
- Display dynamic data (e.g., customer names, amounts, dates).
- Apply conditional logic (e.g., show a field only if it has a value).
- Iterate over lists (e.g., displaying invoice lines).
- Include custom styling with CSS.
Prerequisites for Customizing Your Odoo QWEB Invoice Receipt
To follow this tutorial, a basic understanding of HTML and Odoo’s module development concepts will be beneficial. You’ll need access to an Odoo development environment and a custom module where you can safely make your modifications without affecting core Odoo files. If you’re new to Odoo module development, consider checking out resources like the Odoo Documentation for Developers.
Step-by-Step Tutorial: Building a Basic Odoo QWEB Invoice Receipt
This tutorial will guide you through creating a simple receipt layout within an Odoo QWEB report, fetching data dynamically from an invoice object. Our goal is to create a clean, functional receipt based on your existing invoice report.
Step 1: Identifying and Duplicating the Base Report
First, you need to locate the existing invoice report that you wish to modify. In Odoo, reports are typically defined in XML files within a module. For invoices, you’d usually look for templates related to report_invoice or similar. It’s always best practice to inherit and extend an existing report rather than modifying the core one directly.
Once you’ve identified the report, you’ll create a new XML file in your custom module (e.g., my_module/views/report_receipt_template.xml) and inherit the original invoice report. This allows you to add or override elements without touching Odoo’s core.
Step 2: Laying the Basic HTML Structure for Your Odoo QWEB Invoice Receipt
Within your inherited QWEB template, you’ll define the basic HTML structure for your receipt. This includes elements like paragraphs (<p>) and spans (<span>) which will serve as placeholders for your dynamic data. This is your skeleton for the receipt.
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_invoice_document_receipt" inherit_id="account.report_invoice_document">
<xpath expr="//div[@class='page']" position="replace">
<div class="page">
<p><strong>Invoice Payment Receipt</strong></p>
<p>Received from: <span></span></p>
<p>Amount of: <span></span></p>
<p>For payment of invoice number: <span></span></p>
<p>Date: <span></span></p>
<p>Received by: <span>[Receiver Name]</span></p>
<br/>
<p>Thank you for your business!</p>
</div>
</xpath>
</template>
</odoo>
In this initial structure:
<strong>Invoice Payment Receipt</strong>: Serves as the clear title for your Odoo QWEB Invoice Receipt.Received from: This line will hold the customer’s name (the partner).Amount of: Will display the total amount paid.For payment of invoice number: Will show the unique invoice number.Date: The date of the payment or receipt generation.Received by: A placeholder for the name of the person who received the payment.
Step 3: Unleashing Dynamic Data with Odoo QWEB for Your Invoice Receipt
Now, let’s make your receipt dynamic by fetching data directly from the invoice object (referred to as doc in QWEB). The doc variable is automatically available and represents the record (in this case, an invoice) for which the report is being generated. We’ll use QWEB’s t-esc directive to print the value of fields, and t-attf-class for adding CSS classes for styling.
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_invoice_document_receipt" inherit_id="account.report_invoice_document">
<xpath expr="//div[@class='page']" position="replace">
<div class="page">
<h2><strong>Odoo QWEB Invoice Receipt</strong></h2>
<p>Received from: <span t-attf-class="pay-field customer-name" t-esc="doc.partner_id.name"/></p>
<p>Amount of: <span t-attf-class="pay-field amount-total" t-esc="doc.amount_total" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/></p>
<p>For payment of invoice number: <span t-attf-class="pay-field invoice-number" t-esc="doc.name"/></p>
<p>Date: <span t-attf-class="pay-field receipt-date" t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d')"/></p>
<p>Received by: <span t-attf-class="pay-field receiver-name">[Your Company Representative Name]</span></p>
<br/>
<p>Thank you for your business!</p>
<p>For more details, please visit our website: <a href="https://yourcompany.com" target="_blank" class="text-primary">www.yourcompany.com</a></p>
</div>
</xpath>
</template>
</odoo>
Let’s break down the new directives:
t-attf-class="pay-field customer-name": This adds CSS classes (pay-fieldandcustomer-name) to the<span>element. These classes can later be used in a CSS file to style the text.t-esc="doc.partner_id.name": This is a core QWEB directive that securely escapes and prints the value ofdoc.partner_id.name.doc: The current invoice object.partner_id: A many-to-one field on the invoice, linking to the customer (partner) record.name: The name field of that customer record.
t-esc="doc.amount_total" t-options='{"widget": "monetary", "display_currency": doc.currency_id}': This prints the total amount from the invoice. Thet-optionspart is crucial for formatting the amount as currency, automatically including the correct symbol and decimal places based ondoc.currency_id. This makes your Odoo QWEB Invoice Receipt much clearer.t-esc="doc.name": Prints the internal name or reference number of the invoice.t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d')": This dynamically retrieves the current date and time from the server, converts it to the user’s timezone (context_timestamp), and then formats it into a ‘YYYY-MM-DD’ string. This ensures the date on your Odoo QWEB Invoice Receipt is always accurate.<span>[Your Company Representative Name]</span>: For now, this is static. You could make this dynamic by linking it to the user who printed the report or a field on the invoice itself.<a>tag: An example of adding an external DoFollow link.
Step 4: Updating Your Module and Testing
After saving your XML file, you need to update your Odoo module.
- Add the XML file to your
__manifest__.pyfile: Ensure your new XML file is listed under thedatakey in your module’s manifest.
'data': [
'views/report_receipt_template.xml',
# ... other XML files
],
- Upgrade your module: In Odoo, go to Apps -> Update Apps List (if needed) -> find your module -> click “Upgrade.”
- Print an Invoice: Navigate to an invoice, click “Print,” and then select the appropriate report (which should now reflect your changes).
You should now see your customized Odoo QWEB Invoice Receipt with dynamic data populated from the invoice!
Beyond the Basics: Advanced Customizations for Your Odoo QWEB Invoice Receipt
A basic receipt is a great start, but Odoo QWEB allows for much more sophisticated customization.
1. Styling with CSS
The t-attf-class attributes we added are perfect for applying custom styling. In your custom module, you can create a CSS file (e.g., my_module/static/src/css/report_receipt.css) and link it to your report template.
<template id="report_invoice_document_receipt" inherit_id="account.report_invoice_document">
<xpath expr="//t[1]" position="before">
<link href="/my_module/static/src/css/report_receipt.css" rel="stylesheet"/>
</xpath>
<!-- ... rest of your template -->
</template>
Then, in report_receipt.css:
.page {
font-family: Arial, sans-serif;
padding: 15mm;
border: 1px solid #ccc;
background-color: #f9f9f9;
}
h2 {
color: #007bff;
text-align: center;
margin-bottom: 20px;
}
.pay-field {
font-weight: bold;
color: #333;
}
.customer-name {
text-transform: uppercase;
}
.amount-total {
font-size: 1.2em;
color: #28a745; /* Green for amount */
}
This is a small example, but illustrates how you can dramatically change the look and feel of your Odoo QWEB Invoice Receipt.
2. Handling Paper Size and Layout
The original context hinted at adjusting paper size. Odoo reports often default to A4. For a receipt, you might prefer a smaller format, like A5 or even a custom size. This is managed via report.paperformat records.
You can define a new ir.actions.report record in your XML and specify a paperformat_id that points to a custom paper format. Alternatively, you can modify the existing account.report_invoice_document record in your custom module to use a different paper format.
For instance, to create a custom paper format:
<odoo>
<record id="paperformat_invoice_receipt" model="report.paperformat">
<field name="name">Invoice Receipt Paper Format</field>
<field name="default">True</field>
<field name="format">custom</field>
<field name="page_height">148</field> <!-- A5 height in mm -->
<field name="page_width">210</field> <!-- A5 width in mm -->
<field name="orientation">Portrait</field>
<field name="margin_top">10</field>
<field name="margin_bottom">10</field>
<field name="margin_left">10</field>
<field name="margin_right">10</field>
<field name="header_line">False</field>
<field name="header_spacing">5</field>
<field name="dpi">90</field>
</record>
<record id="account.report_invoice_document" model="ir.actions.report">
<field name="paperformat_id" ref="my_module.paperformat_invoice_receipt"/>
</record>
</odoo>
Remember to add this XML to your module’s data list and upgrade your module.
3. Conditional Logic (t-if, t-else)
You might want certain elements to appear only under specific conditions. For example, a “Paid in Full” stamp:
<p t-if="doc.payment_state == 'paid'" class="text-success">Status: PAID IN FULL</p>
<p t-elif="doc.payment_state == 'partial'" class="text-warning">Status: Partially Paid</p>
<p t-else="" class="text-danger">Status: Unpaid</p>
This adds intelligent detail to your Odoo QWEB Invoice Receipt.
4. Displaying Invoice Lines (for detailed receipts)
While a simple receipt might not need all invoice lines, if you want a more detailed payment confirmation, you can iterate over doc.invoice_line_ids:
<h3>Items Paid:</h3>
<ul>
<li t-foreach="doc.invoice_line_ids" t-as="line">
<span t-esc="line.name"/> - <span t-esc="line.quantity"/> x <span t-esc="line.price_unit" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/> = <span t-esc="line.price_subtotal" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/>
</li>
</ul>
This is a more advanced customization, allowing your Odoo QWEB Invoice Receipt to be as granular as needed.
Best Practices for Odoo QWEB Report Development
- Keep it Modular: Always work within a custom module. This ensures your changes are upgradable and don’t interfere with Odoo’s core.
- Test Thoroughly: After every significant change, upgrade your module and print various invoices to ensure everything renders correctly, especially edge cases (e.g., invoices with no lines, different currencies).
- Use Version Control: Store your custom module in a version control system (like Git) to track changes and collaborate effectively.
- Consult Odoo Documentation: The official Odoo QWEB Documentation is an invaluable resource for advanced directives and troubleshooting.
- Internal Linking: When creating comprehensive documentation for your team or clients, always link to relevant internal resources, such as a guide on “Designing Odoo Reports with QWEB Basics” or “Managing Odoo Paper Formats.” This helps maintain a cohesive knowledge base.
Conclusion
Customizing your Odoo QWEB Invoice Receipt is a powerful way to enhance your business’s professionalism, clarity, and brand consistency. By understanding the basics of QWEB, you can transform standard documents into tailored assets that resonate with your clients and streamline your operations. The step-by-step process outlined here provides a solid foundation, and with a little exploration, the possibilities for customization are virtually limitless.
Start today and unlock the full potential of your Odoo reports. Your clients, and your brand, will thank you for it!
Discover more from teguhteja.id
Subscribe to get the latest posts sent to your email.

