From 644ee7fbb5884d90e56c61c4e729e7b71fc83731 Mon Sep 17 00:00:00 2001 From: gasa-odoo Date: Tue, 5 Aug 2025 16:09:05 +0530 Subject: [PATCH 1/2] [ADD] pos_formate: add pos formate module for select and edit receipt formate In this task, Add new module pos format in which select receipt type (ex. lined, light, boxed) also add header, footer and logo and can see the preview of receipt. for this task use wizards, js file for report and add three template for preview. --- pos_formate/__init__.py | 4 + pos_formate/__manifest__.py | 24 ++ pos_formate/models/__init__.py | 4 + pos_formate/models/pos_config.py | 15 + pos_formate/models/res_config_settings.py | 30 ++ pos_formate/security/ir.model.access.csv | 2 + pos_formate/static/src/order_receipt_patch.js | 37 ++ .../static/src/order_receipt_patch.xml | 340 ++++++++++++++++++ pos_formate/tests/__init__.py | 3 + .../tests/test_pos_configure_receipt.py | 43 +++ pos_formate/views/boxed_template.xml | 92 +++++ pos_formate/views/light_template.xml | 88 +++++ pos_formate/views/lined_template.xml | 111 ++++++ .../views/res_config_settings_views.xml | 20 ++ pos_formate/wizards/__init__.py | 3 + pos_formate/wizards/pos_configure_receipt.py | 86 +++++ .../wizards/pos_configure_receipt_views.xml | 35 ++ 17 files changed, 937 insertions(+) create mode 100644 pos_formate/__init__.py create mode 100644 pos_formate/__manifest__.py create mode 100644 pos_formate/models/__init__.py create mode 100644 pos_formate/models/pos_config.py create mode 100644 pos_formate/models/res_config_settings.py create mode 100644 pos_formate/security/ir.model.access.csv create mode 100644 pos_formate/static/src/order_receipt_patch.js create mode 100644 pos_formate/static/src/order_receipt_patch.xml create mode 100644 pos_formate/tests/__init__.py create mode 100644 pos_formate/tests/test_pos_configure_receipt.py create mode 100644 pos_formate/views/boxed_template.xml create mode 100644 pos_formate/views/light_template.xml create mode 100644 pos_formate/views/lined_template.xml create mode 100644 pos_formate/views/res_config_settings_views.xml create mode 100644 pos_formate/wizards/__init__.py create mode 100644 pos_formate/wizards/pos_configure_receipt.py create mode 100644 pos_formate/wizards/pos_configure_receipt_views.xml diff --git a/pos_formate/__init__.py b/pos_formate/__init__.py new file mode 100644 index 00000000000..878f71004eb --- /dev/null +++ b/pos_formate/__init__.py @@ -0,0 +1,4 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import models +from . import wizards diff --git a/pos_formate/__manifest__.py b/pos_formate/__manifest__.py new file mode 100644 index 00000000000..f35d8301017 --- /dev/null +++ b/pos_formate/__manifest__.py @@ -0,0 +1,24 @@ +{ + 'name': "pos formate", + 'version': '1.0', + 'depends': ['point_of_sale'], + 'author': "gasa", + "license": "LGPL-3", + "sequence": 1, + 'data': [ + 'security/ir.model.access.csv', + 'wizards/pos_configure_receipt_views.xml', + 'views/res_config_settings_views.xml', + 'views/boxed_template.xml', + 'views/lined_template.xml', + 'views/light_template.xml', + ], + 'installable': True, + 'application': True, + 'assets': { + 'point_of_sale._assets_pos': [ + 'pos_formate/static/src/order_receipt_patch.js', + 'pos_formate/static/src/order_receipt_patch.xml', + ], + }, +} diff --git a/pos_formate/models/__init__.py b/pos_formate/models/__init__.py new file mode 100644 index 00000000000..342f6d0a345 --- /dev/null +++ b/pos_formate/models/__init__.py @@ -0,0 +1,4 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import res_config_settings +from . import pos_config diff --git a/pos_formate/models/pos_config.py b/pos_formate/models/pos_config.py new file mode 100644 index 00000000000..049fc6bdfaf --- /dev/null +++ b/pos_formate/models/pos_config.py @@ -0,0 +1,15 @@ +from odoo import models, fields + + +class PosConfig(models.Model): + _inherit = 'pos.config' + + receipt_layout = fields.Selection([ + ('light', 'Light'), + ('boxed', 'Boxed'), + ('lined', 'Lined'), + ], string="Receipt Layout", default='light') + + receipt_logo = fields.Binary("Receipt Logo") + receipt_header = fields.Text("Receipt Header") + receipt_footer = fields.Text("Receipt Footer") diff --git a/pos_formate/models/res_config_settings.py b/pos_formate/models/res_config_settings.py new file mode 100644 index 00000000000..83c93022fc6 --- /dev/null +++ b/pos_formate/models/res_config_settings.py @@ -0,0 +1,30 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models, fields + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + pos_receipt_layout = fields.Selection( + selection=[ + ('light', 'Light'), + ('boxed', 'Boxed'), + ('lined', 'Lined'), + ], + string="POS Receipt Layout", + default='light', + config_parameter='pos.receipt.layout' + ) + + def action_open_receipt_configuration(self): + return { + 'type': 'ir.actions.act_window', + 'name': 'Configure Receipt', + 'res_model': 'pos.configure.receipt', + 'view_mode': 'form', + 'target': 'new', + "context": { + "default_pos_config_id": self.pos_config_id.id, + }, + } diff --git a/pos_formate/security/ir.model.access.csv b/pos_formate/security/ir.model.access.csv new file mode 100644 index 00000000000..a2868d96d18 --- /dev/null +++ b/pos_formate/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_pos_configure_receipt,pos.configure.receipt,model_pos_configure_receipt,base.group_system,1,1,1,1 diff --git a/pos_formate/static/src/order_receipt_patch.js b/pos_formate/static/src/order_receipt_patch.js new file mode 100644 index 00000000000..907dcc0729b --- /dev/null +++ b/pos_formate/static/src/order_receipt_patch.js @@ -0,0 +1,37 @@ +/** @odoo-module **/ + +import { OrderReceipt } from "@point_of_sale/app/screens/receipt_screen/receipt/order_receipt"; +import { patch } from "@web/core/utils/patch"; +import { usePos } from "@point_of_sale/app/store/pos_hook"; + +patch(OrderReceipt, { + template: "pos_formate.order_receipt_inherited", +}); + +patch(OrderReceipt.prototype, { + setup() { + super.setup(); + this.pos = usePos(); + }, + + get receiptLogo() { + const logo = this.pos.config?.receipt_logo; + return logo ? `data:image/png;base64,${logo}` : false; + }, + + get receiptLayout() { + const layout = this.pos.config?.receipt_layout || "light"; + return layout; + }, + + get orderQuantity() { + return this.props.data.orderlines.reduce( + (acc, line) => acc + parseFloat(line.qty), + 0 + ); + }, + + get order() { + return this.pos.get_order(); + }, +}); diff --git a/pos_formate/static/src/order_receipt_patch.xml b/pos_formate/static/src/order_receipt_patch.xml new file mode 100644 index 00000000000..a09153cdb18 --- /dev/null +++ b/pos_formate/static/src/order_receipt_patch.xml @@ -0,0 +1,340 @@ + + + +
+ + + + + + + + + +
  • + + +
  • +
    +
    + +
    +
    --------------------------------
    +
    + + Untaxed Amount + +
    +
    + + + + + + + on + + + +
    +
    +
    --------------------------------
    +
    + TOTAL + +
    + +
    + Rounding + +
    +
    + To Pay + +
    +
    +
    + + +
    +
    + CHANGE + +
    + +
    + Discounts + +
    +
    +