Skip to content

Commit 3f0c4ab

Browse files
committed
[ADD] pos_receipt: configure receipt layout
-Now users can configure their receipt format for each POS configuration. -Users can choose receipt type - Receipt Logo: Logo is also customizable in receipts now - Header and Footer: receipt with personalized header & footer content
1 parent fbf9ee9 commit 3f0c4ab

File tree

10 files changed

+170
-0
lines changed

10 files changed

+170
-0
lines changed

pos_reciept_customize/__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_reciept_customize/__manifest__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "POS Receipt Customization",
3+
"summary": "Customizable POS receipt with layouts and HTML header/footer",
4+
"depends": ["point_of_sale"],
5+
"category": "Point of Sale",
6+
"author": "Rohit",
7+
"installable": True,
8+
"license": "LGPL-3",
9+
"data": [
10+
"security/ir.model.access.csv",
11+
"views/res_config_settings_views.xml",
12+
"wizard/reciepts_layout_view.xml",
13+
],
14+
}
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
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
2+
3+
from odoo import models, fields
4+
5+
6+
class PosConfig(models.Model):
7+
_inherit = "pos.config"
8+
9+
receipt_layout = fields.Selection([
10+
("light", "Light"),
11+
("boxes", "Boxes"),
12+
("lined", "Lined")],
13+
string="Receipt Layout",
14+
default="light",
15+
)
16+
receipt_logo = fields.Binary(string="Receipt Logo", default=lambda self: self.env.company.logo)
17+
receipt_header_html = fields.Html(string="Header", default="", help="Custom HTML header for receipts")
18+
receipt_footer_html = fields.Html(string="Footer", default="", help="Custom HTML footer for receipts")
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+
pos_receipt_layout = fields.Selection(related="pos_config_id.receipt_layout", readonly=False)
10+
11+
def action_view_receipt_layout(self):
12+
return {
13+
"type": "ir.actions.act_window",
14+
"name": ("Configure your pos receipt"),
15+
"res_model": "receipts.layout",
16+
"view_mode": "form",
17+
"target": "main",
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_reciept_customize.access_receipts_layout,access_receipts_layout,pos_reciept_customize.model_receipts_layout,base.group_user,1,1,1,0
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<odoo>
3+
<record id="pos_config_form_view_inherit_receipt_layout" model="ir.ui.view">
4+
<field name="name">pos.config.form.inherit.receipt.layout</field>
5+
<field name="model">res.config.settings</field>
6+
<field name="inherit_id" ref="point_of_sale.res_config_settings_view_form"/>
7+
<field name="arch" type="xml">
8+
<xpath expr="//block[@id='pos_bills_and_receipts_section']/setting" position="replace">
9+
<setting help="Choose layout of your reciept">
10+
<field name="pos_receipt_layout"/>
11+
<div class="content-group mt16">
12+
<button name="action_view_receipt_layout"
13+
string="Configure Receipts"
14+
type="object"
15+
class="oe_link"
16+
icon="oi-arrow-right"/>
17+
</div>
18+
</setting>
19+
</xpath>
20+
</field>
21+
</record>
22+
</odoo>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
2+
3+
from . import reciepts_layout
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
2+
3+
from odoo import api, fields, models
4+
5+
6+
class ReceiptsLayout(models.TransientModel):
7+
_name = "receipts.layout"
8+
_description = "Custom Reciept Template"
9+
10+
pos_config_id = fields.Many2one(
11+
"pos.config",
12+
string="Point of Sale",
13+
default=lambda self: self.env["pos.config"].browse(
14+
self.env.context.get("active_pos_config_id")
15+
),
16+
required=True,
17+
)
18+
receipt_layout = fields.Selection(related="pos_config_id.receipt_layout", required=True)
19+
receipt_logo = fields.Binary(related="pos_config_id.receipt_logo")
20+
receipt_header = fields.Html(related="pos_config_id.receipt_header_html")
21+
receipt_footer = fields.Html(related="pos_config_id.receipt_footer_html")
22+
preview = fields.Html("_compute_receipt_preview")
23+
24+
def receipt_layout_save(self):
25+
return {"type": "ir.actions.act_window_close"}
26+
27+
@api.depends("receipt_layout", "receipt_header", "receipt_footer", "receipt_logo")
28+
def _compute_receipt_preview(self):
29+
for wizard in self:
30+
if wizard.pos_config_id:
31+
wizard.preview = wizard.env["ir.ui.view"]._render_template(
32+
wizard._get_template(),
33+
{
34+
"receipt_header": wizard.receipt_header,
35+
"receipt_footer": wizard.receipt_footer,
36+
"receipt_logo": wizard.receipt_logo,
37+
},
38+
)
39+
else:
40+
wizard.preview = False
41+
42+
def _get_template(self):
43+
is_restaurant = self.pos_config_id.module_pos_restaurant
44+
if is_restaurant:
45+
base_module = "pos_receipt.report_restaurant_preview"
46+
else:
47+
base_module = "pos_receipt.report_receipts_wizard_preview"
48+
49+
layout_templates = {
50+
"light": f"{base_module}_light",
51+
"boxes": f"{base_module}_boxes",
52+
"lined": f"{base_module}_lined",
53+
}
54+
55+
return layout_templates.get(self.receipt_layout, layout_templates["light"])
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
<data>
4+
<record id="view_receipt_layout" model="ir.ui.view">
5+
<field name="name">Receipt Layout</field>
6+
<field name="model">receipts.layout</field>
7+
<field name="arch" type="xml">
8+
<form class="o_document_layout">
9+
<group>
10+
<group class="o_document_layout_company">
11+
<field name="pos_config_id" invisible="1"/>
12+
<field name="receipt_layout" widget="selection_badge" options="{'size': 'sm'}"/>
13+
<field name="receipt_logo" string="Logo" widget="image" options="{'size': [0, 50]}"/>
14+
<field name="receipt_header" string="Header" placeholder="e.g. Shop Name, Location" />
15+
<field name="receipt_footer" string="Footer" placeholder="Thanks, visit again ..." />
16+
</group>
17+
<div class="o_preview">
18+
<field name="preview"/>
19+
</div>
20+
</group>
21+
<footer>
22+
<button string="Continue" class="btn-primary" type="object" name="receipt_layout_save"/>
23+
<button special="cancel" string="Discard" />
24+
</footer>
25+
</form>
26+
</field>
27+
</record>
28+
</data>
29+
</odoo>

0 commit comments

Comments
 (0)