Skip to content

Commit cc52a23

Browse files
committed
[ADD] pos_receipt: allow custom receipt layout with preview
Before this commit: POS receipts had only one fixed layout. Logo, header, and footer fields were not in one place. After this commit: Users can choose from 3 receipt layouts: light, lined, and boxes. Header, footer, and logo can be updated from POS settings. A live preview shows how the receipt will look. Impact: Easier receipt setup for users. Helps businesses match their branding. Reduces errors by showing preview before saving.
1 parent fbf9ee9 commit cc52a23

15 files changed

+738
-0
lines changed

pos_receipt/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
2+
3+
from . import models
4+
from . import wizard

pos_receipt/__manifest__.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
'name': 'POS receipt',
3+
'version': '1.0',
4+
'author': 'niyp',
5+
'depends': ['point_of_sale'],
6+
'data': [
7+
'security/ir.model.access.csv',
8+
'wizard/pos_receipt_wizard_views.xml',
9+
'views/res_config_settings_view.xml',
10+
'views/boxes_receipt.xml',
11+
'views/lined_receipt.xml',
12+
'views/light_receipt.xml',
13+
],
14+
'assets': {
15+
'point_of_sale._assets_pos': [
16+
'pos_receipt/static/src/**/*',
17+
],
18+
},
19+
'installable': True,
20+
'license': 'LGPL-3',
21+
}

pos_receipt/models/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
2+
3+
from . import pos_config
4+
from . import res_config_settings

pos_receipt/models/pos_config.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
2+
3+
from odoo import fields, models
4+
5+
6+
class POSConfig(models.Model):
7+
_inherit = 'pos.config'
8+
9+
receipt_layout = fields.Selection([
10+
('light', 'Light'),
11+
('lined', 'Lined'),
12+
('boxes', 'Boxes'),
13+
], string="Receipt Layout", default='light')
14+
15+
receipt_logo = fields.Binary(string='Receipt Logo', related='company_id.logo', readonly=False)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
2+
3+
from odoo import _, fields, models
4+
5+
6+
class ResConfigSettings(models.TransientModel):
7+
_inherit = 'res.config.settings'
8+
9+
receipt_layout = fields.Selection(related='pos_config_id.receipt_layout', readonly=False)
10+
11+
def action_pos_receipt_layout(self):
12+
return {
13+
'type': 'ir.actions.act_window',
14+
'name': _('Configure your pos receipt'),
15+
'res_model': 'pos.receipt.wizard',
16+
'view_mode': 'form',
17+
'target': 'new',
18+
'context': {'active_pos_config_id': self.pos_config_id.id, 'dialog_size': 'extra-large'},
19+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2+
pos_receipt.access_receipt_layout,access_receipt_layout,pos_receipt.model_pos_receipt_wizard,base.group_user,1,1,1,1
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { OrderReceipt } from "@point_of_sale/app/screens/receipt_screen/receipt/order_receipt";
2+
import { patch } from "@web/core/utils/patch";
3+
import { usePos } from "@point_of_sale/app/store/pos_hook";
4+
5+
patch(OrderReceipt, {
6+
template: "pos_receipt.order_receipt_inherited"
7+
});
8+
9+
patch(OrderReceipt.prototype, {
10+
setup(){
11+
super.setup();
12+
this.pos = usePos();
13+
},
14+
15+
get orderQuantity() {
16+
return this.props.data.orderlines.reduce((acc, line) => acc + parseFloat(line.qty), 0);
17+
},
18+
19+
get order() {
20+
return this.pos.get_order()
21+
}
22+
});

pos_receipt/static/src/order_receipt_inherit.xml

Lines changed: 329 additions & 0 deletions
Large diffs are not rendered by default.

pos_receipt/views/boxes_receipt.xml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
<template id="custom_pos_receipt_boxes">
4+
<div style="text-align: center; width: 300px; margin: auto; border: 1px solid black; padding: 10px;">
5+
<img t-if="logo" t-att-src="image_data_uri(logo)" alt="Logo" style="height: 70px; " />
6+
<p style="margin: 5px 0;">Odoo India Pvt Ltd<br />Infocity Gandhinagar<br />Tax Id:
7+
233300990223</p>
8+
<t t-esc="header" />
9+
<h2 style="margin: 5px 0;">701</h2>
10+
<t t-if="is_restaurant"> Served by MOG <br /> Table 5 Guest 3 </t>
11+
<table style="width: 100%; border-collapse: collapse; text-align: left;">
12+
<tr>
13+
<th style="border: 1px solid black;">No</th>
14+
<th style="border: 1px solid black;">Item</th>
15+
<th style="border: 1px solid black;">Amount</th>
16+
</tr>
17+
<tr>
18+
<td style="border: 1px solid black;">1</td>
19+
<td style="border: 1px solid black;">Margarita Pizza<br />3 X 200<br />HSN:
20+
2300976</td>
21+
<td style="border: 1px solid black;">$600</td>
22+
</tr>
23+
<tr>
24+
<td style="border: 1px solid black;">2</td>
25+
<td style="border: 1px solid black;">Bacon Burger<br />5 X 150</td>
26+
<td style="border: 1px solid black;">$750</td>
27+
</tr>
28+
<tr>
29+
<td style="border: 1px solid black;">3</td>
30+
<td style="border: 1px solid black;">Apple Pie<br />3 X 80<br />HSN: 2300976</td>
31+
<td style="border: 1px solid black;">$240</td>
32+
</tr>
33+
<tr>
34+
<td style="border: 1px solid black;">4</td>
35+
<td style="border: 1px solid black;">Cheese Burger<br />5 X 150<br />HSN:
36+
2300976</td>
37+
<td style="border: 1px solid black;">$750</td>
38+
</tr>
39+
</table>
40+
<div class="border-bottom border-dark py-1 mb-2" style="font-size: 12px;">
41+
<div class="d-flex justify-content-between small">
42+
<span>Total Qty 12</span>
43+
<span>Sub Total $1625</span>
44+
</div>
45+
</div>
46+
<div class="text-end mb-2 fw-bold small border-bottom border-dark"
47+
style="font-size: 12px;">
48+
Cash $1625
49+
</div>
50+
<table style="width: 100%; border-collapse: collapse; text-align: left;">
51+
<tr>
52+
<th>Tax</th>
53+
<th>Amount</th>
54+
<th>Base</th>
55+
<th>Total</th>
56+
</tr>
57+
<tr>
58+
<td>SGST 2.5%</td>
59+
<td>40.2</td>
60+
<td>1584.8</td>
61+
<td>1625</td>
62+
</tr>
63+
<tr>
64+
<td>CGST 2.5%</td>
65+
<td>40.2</td>
66+
<td>1584.8</td>
67+
<td>1625</td>
68+
</tr>
69+
</table>
70+
<t t-esc="footer" />
71+
<p style="margin: 5px 0;">Odoo Point of Sale</p>
72+
<p style="margin: 5px 0;">Order 0001-003-0004</p>
73+
<p style="margin: 5px 0;">04/06/2024 08:30:24</p>
74+
</div>
75+
</template>
76+
</odoo>

pos_receipt/views/light_receipt.xml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
<template id="custom_receipt_static_light" t-name="custom_receipt_static">
4+
<div style="font-family: Arial, sans-serif; width: 350px; margin: auto; text-align: center; border: 1px solid #ddd; padding: 10px;">
5+
<img t-if="logo" t-att-src="image_data_uri(logo)" alt="Logo" style="height: 70px; "/>
6+
<p style="margin: 5px 0; font-size: 12px;">
7+
Tel: +1 555-555-5556<br/>
8+
9+
http://www.example.com
10+
</p>
11+
<t t-esc="header"/>
12+
<h1 style="margin: 10px 0;">301</h1>
13+
<t t-if="is_restaurant">
14+
Served by MOG <br/>
15+
Table 5 Guest 3
16+
</t>
17+
<table style="width: 100%; text-align: left; font-size: 14px;">
18+
<tr><td><b>Margarita Pizza</b></td><td style="text-align: right;">$ 140.00</td></tr>
19+
<tr><td><span style="border: 1px solid #000; padding: 2px 5px;">1.00</span> x $140.00 / Units</td></tr>
20+
21+
<tr><td><b>Bacon Burger</b></td><td style="text-align: right;">$ 33.00</td></tr>
22+
<tr><td><span style="border: 1px solid #000; padding: 2px 5px;">1.00</span> x $33.00 / Units</td></tr>
23+
24+
<tr><td><b>Apple Pie</b></td><td style="text-align: right;">$ 85.00</td></tr>
25+
<tr><td><span style="border: 1px solid #000; padding: 2px 5px;">1.00</span> x $85.00 / Units</td></tr>
26+
</table>
27+
<hr/>
28+
<table style="width: 100%; text-align: left; font-size: 14px;">
29+
<tr><td>TOTAL</td><td style="text-align: right;">$ 258.00</td></tr>
30+
<tr><td>Cash</td><td style="text-align: right;">$ 258.00</td></tr>
31+
</table>
32+
<t t-esc="footer"/>
33+
<p style="margin-top: 10px; font-size: 12px;">Powered by Odoo</p>
34+
<p style="font-size: 12px;">Order 00003-001-0001<br/>03/19/2025 17:55:58</p>
35+
</div>
36+
</template>
37+
</odoo>

0 commit comments

Comments
 (0)