| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Point of Sale (point_of_sale)
• Discuss (mail) • Inventory (stock) • Invoicing (account) |
| Lines of code | 2526 |
| Technical Name |
cml_pos_ticket_editor |
| License | LGPL-3 |
| Website | https://kaypi.pe |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Point of Sale (point_of_sale)
• Discuss (mail) • Inventory (stock) • Invoicing (account) |
| Lines of code | 2526 |
| Technical Name |
cml_pos_ticket_editor |
| License | LGPL-3 |
| Website | https://kaypi.pe |
POS Ticket Editor lets you create fully custom receipt layouts using Odoo's native OWL template engine. Design your tickets with a live code editor inside the POS, preview them with real order data, and print them on any supported printer — including ESC/POS thermal printers, IoT-connected printers, and browser print.
- ✅ Real Printing — Replaces the default receipt on thermal printers, screen display & reprint
- ✅ Live OWL Editor — Ace code editor with Monokai theme and XML syntax highlighting
- ✅ Smart Autocomplete — Ctrl+Space suggestions built from live order data
- ✅ Real-Time Preview — Side-by-side custom vs native receipt comparison
- ✅ Template Validation — XML & OWL rendering checks before saving
- ✅ Unsaved Changes Guard — Confirmation popup prevents accidental data loss
- ✅ Multiple Formats — Create unlimited templates, activate per POS config
- ✅ Security Group — Only authorized users can access the editor and modify templates
- ✅ Dynamic Variables — Full introspection of order, company, config, partner & inherited helpers
- ✅ Safe Fallback — If a custom template fails, the native Odoo receipt prints automatically
- ✔ Community
-
✔
Enterprise
On-premises - ✔ Odoo.sh
- ✘ Online
The editor running inside the POS — split view with live preview
🔒 1. Security & Access Control
The module includes a dedicated "POS Ticket Editor" security group. Only users in this group (or POS Managers) can create, edit, save, activate or deactivate ticket formats. The editor screen is hidden from unauthorized users. Regular POS users print the active format transparently.
Grant the "POS Ticket Editor" group to users who need to design receipts
Access Matrix:
- POS User — Read only (needed for receipt rendering at print time)
- POS Ticket Editor — Full CRUD (create, read, update, delete formats)
✏ 2. Backend Template Management
Create and manage ticket formats from the backend. Go to Point of Sale > Ticket Formats. Each format record contains a name, sequence, optional notes, and the OWL/XML template body that defines the receipt layout.
Ticket Formats list view in the backend — create, duplicate or archive formats
Step-by-step:
- Go to Point of Sale > Ticket Formats
- Click New to create a format, or edit an existing one
- Write your OWL/XML template in the HTML Template field
- Optionally add Notes to document the template purpose
- Save the record — it is now available in the POS
⚙ 3. POS Configuration
Assign a default ticket format to each POS configuration from the backend settings. You can also change the active format live from the POS editor using the Activate / Deactivate buttons.
POS Settings > Custom Ticket Format — select which template this POS will use
Step-by-step:
- Go to Point of Sale > Configuration > Settings
- Select your POS configuration
- In the Custom Ticket Format section, pick a format from the dropdown
- Save — all future receipts from this POS will use the selected template
💻 4. POS Ticket Editor Screen
Open the editor directly from the POS hamburger menu. The screen features a split view with the Ace code editor on the left and a live receipt preview on the right. Select any paid order to see your template rendered with real data.
The editor screen inside the POS — write OWL templates and see the result instantly
✅ Editor Features
- Ace editor with Monokai theme & XML mode
- Ctrl+Space autocomplete with live order variables
- Unsaved changes detection with confirmation popup
- XML syntax + OWL rendering validation before save
- Variables reference dialog with full introspection
🔄 Preview Modes
- Custom — Shows only your custom template
- Native — Shows the default Odoo receipt
- Split — Side-by-side comparison of both
The preview updates automatically as you type (400ms debounce). Undefined variables are highlighted with warnings.
👁 5. Live Preview with Real Orders
Select any paid order from the dropdown to see your template rendered with real data — product lines, taxes, payments, customer info, and more. Rendering errors are shown inline with descriptive messages.
Live preview with a real paid order — exactly what will be printed
🔒 7. Security & Access Control
The module includes a dedicated "POS Ticket Editor" security group. Only users in this group (or POS Managers) can create, edit, save, activate or deactivate ticket formats. The editor screen is hidden from unauthorized users. Regular POS users print the active format transparently.
Grant the "POS Ticket Editor" group to users who need to design receipts
Access Matrix:
- POS User — Read only (needed for receipt rendering at print time)
- POS Ticket Editor — Full CRUD (create, read, update, delete formats)
📋 6. Available Variables Reference
All these variables are available in your OWL templates via
t-esc,
t-if, t-foreach, etc. They are built dynamically
from the
OrderReceipt prototype chain, so any module that patches
OrderReceipt
automatically adds its getters/methods to the context. The popup lists each
variable with its type and the live value coming from the currently selected
order,
so you always know what you can print.
Screenshot of the Reference > Variables dialog inside the POS editor. It highlights the Core Objects, Pre-computed Values, inherited getters, and helper functions you can use directly in your OWL templates.
OrderReceipt
(e.g. pos_restaurant, pos_loyalty, localization
modules)
automatically adds its getters and methods to the template context.
Use the Reference dialog inside the POS editor to see all
available
variables for your specific installation.
✂ 7. Code Snippets Reference
The Snippets tab inside the Reference popup lets you browse ready-to-use blocks and insert them into your template with a single click.
This dialog groups snippets by section (Basic Structure, Order Lines, Totals, Payments, etc.), offers search-as-you-type, and provides Copy + Insert actions for every block so you can scaffold layouts faster.
Highlights:
- Use categories to focus on specific areas like totals, payments, taxes, or footer.
- Preview code with syntax highlighting before inserting it into the editor.
- Keyboard shortcut reminder (Ctrl + Space) is shown for Ace autocomplete.
💳 8. Result After Payment
After completing a sale and processing payment, the Receipt Screen automatically displays your custom template instead of the native Odoo receipt. The customer and cashier see your branded design immediately.
Receipt Screen after payment — your custom template is displayed and ready to print
What happens:
- Customer pays for the order
- POS navigates to the Receipt Screen
- Module detects active custom format
- Your template renders with real order data
- Receipt is displayed on screen and sent to printer
Technical flow:
ReceiptScreenchecksuseCustomReceipt- If active format exists, renders
CmlCustomReceipt PosStore.printReceipt()sends custom HTML to printergenerateTicketImage()creates JPEG from custom template
🔄 9. Reprint Result
When reprinting a past order, the module uses the same custom
template
that was active at print time. The reprint flow goes through
printReceipt() in PosStore, which checks for the active format
and renders your custom template with the historical order data.
Receipt Screen after reprint — your custom template is displayed and ready to print
Reprint Flow:
- Open the Orders screen in POS
- Select a past order and click Print Receipt
- Module intercepts
printReceipt() - Custom template renders with the order data
- Receipt is sent to the printer or displayed on screen
JPEG Generation:
generateTicketImage()is overridden- Creates a JPEG from
CmlCustomReceipt - Used for email attachments and order history
- Falls back to native if custom template fails
🎨 10. Demo Templates
The module ships with 5 ready-to-use demo templates. Each one demonstrates a different layout style. Use them as-is or as starting points for your own designs.
Simple Receipt
Clean minimal layout for quick-service environments.
Table Layout
Structured table format with clear product and totals columns.
Detailed Receipt
Full detail including customer, taxes and payment breakdown.
Compact Receipt
Condensed print-optimized format for narrow thermal paper.
Modern Receipt
Branded modern structure with grouped sections and footer message.
Installation
This module requires only the standard Point of Sale module. No external Python libraries or system packages are needed.
point_of_sale— Odoo Point of Sale (core module)
Pure JavaScript frontend module. No pip packages required.
📥 Install Steps
- Place the
cml_pos_ticket_editorfolder in your addons path - Restart Odoo and Update Apps List
- Search for "POS Ticket Editor" and click Install
- Go to Settings > Users and grant the POS Ticket Editor group to designers
✅ What You Get After Install
- A Ticket Editor screen accessible from the POS hamburger menu
- A Ticket Formats menu under POS > Configuration
- A Custom Ticket Format field in POS Settings
- A ready-to-use default template with all common receipt sections
- A new POS Ticket Editor security group
❓ What template syntax does the editor use?
The editor uses OWL XML templates — the same syntax used
by Odoo's
native receipt components. All OWL directives are supported: t-esc,
t-out, t-if, t-foreach,
t-att-*,
t-set, etc. You can also use standard HTML and Bootstrap classes.
❓ Does this actually print on thermal printers (ESC/POS)?
Yes. The module overrides the printReceipt()
method in PosStore,
which is the same method Odoo uses to send receipts to ESC/POS thermal printers
via IoT Box,
USB, Bluetooth, or browser print. Your custom template is rendered as HTML and
sent through
the exact same pipeline as the native receipt. If your printer works with
standard Odoo POS,
it will work with custom templates.
❓ What about reprinting? Does it use my custom template too?
Yes. The module also overrides
generateTicketImage() in the
Receipt Screen, so reprints and JPEG exports use your custom template. The
receipt shown
on screen after payment is also your custom design.
❓ What happens if my template has an error during a real sale?
The module has a safe fallback mechanism. If your custom template throws a runtime error during printing, the module catches the exception and automatically falls back to the native Odoo receipt. No sales are lost, no blank tickets are printed.
❓ Can I use variables from other installed modules?
Yes. The editor dynamically introspects the OrderReceipt prototype
chain,
so getters and methods added by modules like pos_restaurant,
pos_loyalty, l10n_de_pos_cert, or any localization
module are
automatically available in your templates and in the autocomplete suggestions.
❓ What happens if my template has errors in the editor?
The editor validates XML syntax and OWL rendering before saving. If there are XML syntax errors, saving is blocked entirely. If there are rendering errors (e.g. undefined variable), you get a confirmation dialog asking whether to save anyway or fix the issue first.
❓ Will I lose changes if I switch templates?
No. If you have unsaved changes, a confirmation popup appears asking whether to discard your changes or stay on the current template.
❓ Can different POS terminals use different templates?
Yes. Each POS configuration has its own Custom Ticket Format field. You can assign a different template to each terminal. You can also leave it empty to use the standard Odoo receipt on specific terminals.
❓ What Odoo versions are supported?
Odoo 19 — Community and Enterprise on-premises, Odoo.sh. Not compatible with Odoo Online (SaaS) as it requires custom module installation.
Need Help?
Contact us for technical support, bug reports, feature requests, or help designing your custom receipt templates.
Contact Support⏰ Response time: 24–48 business hours
⭐ If you find this module useful, please leave a review on Odoo Apps ⭐
Please log in to comment on this module