@ -0,0 +1,41 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
POS Receipt Design |
||||
|
================== |
||||
|
Option to select the customised Receipts for each POS |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
Developer: (V14) Syamili K, |
||||
|
(V15) Sajna Sherin T, |
||||
|
(V16 & V17) Sadique Kottekkat |
||||
|
(V18) Sreerag PM |
||||
|
Contact: odoo@cybrosys.com |
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
----------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Sreerag PM (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################ |
||||
|
from . import models |
@ -0,0 +1,54 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Sreerag PM (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################ |
||||
|
{ |
||||
|
'name': 'POS Receipt Design', |
||||
|
'version': '18.0.1.0.0', |
||||
|
'category': 'Point of Sale', |
||||
|
'summary': "Customize POS receipts with unique templates for each POS in " |
||||
|
"Odoo 18", |
||||
|
'description': "Option to select the customised Receipts for each POS. So, " |
||||
|
"we can easily updated the Receipt Design for better styles", |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': 'https://www.cybrosys.com', |
||||
|
'depends': ['base', 'point_of_sale'], |
||||
|
'data': [ |
||||
|
'security/ir.model.access.csv', |
||||
|
'data/pos_receipt_design1_data.xml', |
||||
|
'data/pos_receipt_design2_data.xml', |
||||
|
'views/pos_receipt_views.xml', |
||||
|
'views/pos_config_views.xml' |
||||
|
], |
||||
|
'assets': { |
||||
|
'point_of_sale._assets_pos': [ |
||||
|
'custom_receipts_for_pos/static/src/js/receipt_design.js', |
||||
|
'custom_receipts_for_pos/static/src/xml/order_receipt.xml', |
||||
|
], |
||||
|
}, |
||||
|
'images': ['static/description/banner.png'], |
||||
|
'license': 'AGPL-3', |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'application': False |
||||
|
} |
@ -0,0 +1,154 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Examples for receipt design: which can be used or modified --> |
||||
|
<record id="pos_receipt_design1" model="pos.receipt"> |
||||
|
<field name="name">Design 1</field> |
||||
|
<field name="design_receipt"><![CDATA[ |
||||
|
<div class="pos-receipt"> |
||||
|
<t t-if="env.services.pos.config.logo"> |
||||
|
<img t-att-src="'data:image/png;base64,' + env.services.pos.config.logo" |
||||
|
alt="Logo" class="pos-receipt-logo"/> |
||||
|
<br /> |
||||
|
</t> |
||||
|
<div class="pos-receipt-contact"> |
||||
|
<t t-if="env.services.pos.company.name"> |
||||
|
<div><t t-esc="env.services.pos.company.name" /></div> |
||||
|
</t> |
||||
|
<t t-if="env.services.pos.company.phone"> |
||||
|
<div>Tel:<t t-esc="env.services.pos.company.phone" /></div> |
||||
|
</t> |
||||
|
<t t-if="env.services.pos.company.vat"> |
||||
|
<div><t t-esc="env.services.pos.company.vat_label"/>:<t t-esc="env.services.pos.company.vat" /></div> |
||||
|
</t> |
||||
|
<t t-if="env.services.pos.company.email"> |
||||
|
<div><t t-esc="env.services.pos.company.email" /></div> |
||||
|
</t> |
||||
|
<t t-if="env.services.pos.company.website"> |
||||
|
<div><t t-esc="env.services.pos.company.website" /></div> |
||||
|
</t> |
||||
|
<t t-if="props.receipt.headerData.header"> |
||||
|
<t t-out="props.receipt.headerData.header" /> |
||||
|
</t> |
||||
|
<t t-if="props.receipt.headerData.cashier"> |
||||
|
<div class="cashier"> |
||||
|
<div>--------------------------------</div> |
||||
|
<div>Served by <t t-esc="props.receipt.headerData.cashier" /></div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</div> |
||||
|
<br/> |
||||
|
<t t-if="props.receipt.headerData.header"> |
||||
|
<div style='text-align:center; font-size:13px'> |
||||
|
<t t-esc="props.receipt.headerData.header" /> |
||||
|
</div> |
||||
|
<br /> |
||||
|
</t> |
||||
|
<div> |
||||
|
<table class='receipt-orderlines' style="font-size:15px; border-style:double; border-left:none; border-right:none; border-bottom:none; width:100%;"> |
||||
|
<colgroup> |
||||
|
<col width='40%' /> |
||||
|
<col width='30%' /> |
||||
|
<col width='30%' /> |
||||
|
</colgroup> |
||||
|
<tr style="border-bottom:1px dashed black;"> |
||||
|
<th style="text-align:left;">Product</th> |
||||
|
<th style="text-align:right;">Qty</th> |
||||
|
<th style="text-align:right;">Amount</th> |
||||
|
</tr> |
||||
|
<t t-if="props.order and props.order.length and props.order and props.order.pos and props.order.pos.mainScreen and props.order.pos.mainScreen.props and props.order.pos.mainScreen.props.order and props.order.pos.mainScreen.props.order.orderlines and props.order.pos.mainScreen.props.order.orderlines.length"> |
||||
|
<t t-if="props.order.pos.mainScreen.props"> |
||||
|
<tr t-foreach="props.order.pos.mainScreen.props.order.orderlines" t-as="orderline" t-key="index_orderlines"> |
||||
|
<td style="padding-top:1%; padding-bottom:1%; text-align:left;"> |
||||
|
<t t-esc="orderline.get_product().display_name"/> |
||||
|
<t t-if="orderline.get_discount() > 0"> |
||||
|
<div style="font-size:12px; font-style:italic; color:#808080;"> |
||||
|
<t t-esc="orderline.get_discount()"/>% discount |
||||
|
</div> |
||||
|
</t> |
||||
|
<t t-if="orderline.customerNote"> |
||||
|
<div style="font-size:14px;" t-esc="orderline.customerNote"/> |
||||
|
</t> |
||||
|
</td> |
||||
|
<td style="text-align:right; font-size:14px;"> |
||||
|
<t t-esc="orderline.get_quantity_str_with_unit()"/> |
||||
|
</td> |
||||
|
<td style="text-align:right; font-size:14px;"> |
||||
|
<t t-esc="env.utils.formatCurrency(orderline.get_display_price())"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
</t> |
||||
|
<t t-else=""> |
||||
|
<t t-if="props.orderlines and props.orderlines.length"> |
||||
|
<tr t-foreach="props.orderlines" t-as="orderline" t-key="orderline.id"> |
||||
|
<td style="padding-top:1%; padding-bottom:1%; text-align:left;"> |
||||
|
<t t-esc="orderline.get_product().display_name"/> |
||||
|
<t t-if="orderline.get_discount() > 0"> |
||||
|
<div style="font-size:12px; font-style:italic; color:#808080;"> |
||||
|
<t t-esc="orderline.get_discount()"/>% discount |
||||
|
</div> |
||||
|
</t> |
||||
|
<t t-if="orderline.customerNote"> |
||||
|
<div style="font-size:14px;" t-esc="orderline.customerNote"/> |
||||
|
</t> |
||||
|
</td> |
||||
|
<td style="text-align:right; font-size:14px;"> |
||||
|
<t t-esc="orderline.get_quantity_str_with_unit()"/> |
||||
|
</td> |
||||
|
<td style="text-align:right; font-size:14px;"> |
||||
|
<t t-esc="env.utils.formatCurrency(orderline.get_display_price())"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
</table> |
||||
|
</div> |
||||
|
<br /> |
||||
|
<div style="padding-top:6px;"> |
||||
|
<t t-set='taxincluded' t-value='Math.abs(props.receipt.amount_total - props.receipt.total_with_tax) <= 0.000001' /> |
||||
|
<t t-if='!taxincluded'> |
||||
|
<br/> |
||||
|
<div style="font-weight:700; font-size:14px; border-top:1px dashed;"> |
||||
|
<span style="margin-left:40%;">Subtotal : </span> |
||||
|
<span t-esc='env.utils.formatCurrency(props.data.total_without_tax)' |
||||
|
class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
<t t-log='props'/> |
||||
|
<t t-foreach='props.data.tax_details' t-as='tax' t-key="index_tax_details"> |
||||
|
<div style="font-weight:700; font-size:14px;"> |
||||
|
<span style="margin-left:40%;"><t t-esc='tax.name' /></span> |
||||
|
<span t-esc='env.utils.formatCurrency(tax.amount)' |
||||
|
class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
<!-- Total --> |
||||
|
<br/> |
||||
|
<div style="font-weight:700; font-size:14px;"> |
||||
|
<span style="margin-left:40%;">TOTAL : </span> |
||||
|
<span t-esc='env.utils.formatCurrency(props.data.amount_total)' class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
<br/><br/> |
||||
|
</div> |
||||
|
<div class='before-footer' /> |
||||
|
<br/><br/> |
||||
|
<!-- Footer --> |
||||
|
<div class="pos-receipt-order-data"> |
||||
|
<div><t t-esc="props.receipt.name" /> |
||||
|
</div> |
||||
|
<t t-if="props.receipt.date"> |
||||
|
<div><t t-esc="props.receipt.date" /></div> |
||||
|
</t> |
||||
|
<t t-else=""> |
||||
|
<div><t t-esc="props.receipt.date" /></div> |
||||
|
</t> |
||||
|
</div> |
||||
|
<br/><br/> |
||||
|
<div style="font-size:14px; text-align:center;"> |
||||
|
Thank You... Please Visit Again ... |
||||
|
</div> |
||||
|
</div>]]></field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,188 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Examples for receipt design: which can be used or modified --> |
||||
|
<record id="pos_receipt_design2_demo" model="pos.receipt"> |
||||
|
<field name="name">Design 2</field> |
||||
|
<field name="design_receipt"><![CDATA[ |
||||
|
<div class="pos-receipt"> |
||||
|
<t t-if="env.services.pos.config.logo"> |
||||
|
<img t-att-src="'data:image/png;base64,' + env.services.pos.config.logo" |
||||
|
alt="Logo" class="pos-receipt-logo"/> |
||||
|
<br /> |
||||
|
</t> |
||||
|
<div style="font-size:13px; text-align:center;"> |
||||
|
<t t-esc="env.services.pos.company.name"/><br /> |
||||
|
Phone:<t t-esc="env.services.pos.company.phone || ''"/><br /> |
||||
|
</div> |
||||
|
<br/> |
||||
|
<div style="font-size:13px; text-align:center;"> |
||||
|
Date : |
||||
|
<t t-if="props.receipt.date"> |
||||
|
<t t-esc="props.receipt.date"/> |
||||
|
</t> |
||||
|
<t t-else=""> |
||||
|
<t t-esc="props.order.validation_date"/> |
||||
|
</t> |
||||
|
<br /> |
||||
|
Order : <t t-esc="props.order.name"/><br /> |
||||
|
</div> |
||||
|
<br /> |
||||
|
<div style="font-size:13px; text-align:center;"> |
||||
|
Cashier : <t t-esc='props.receipt.headerData.cashier' /><br /> |
||||
|
<t t-if="props.order.partner_id"> |
||||
|
Customer : <t t-esc='props.order.partner_id.name' style="font-style:bold" /> |
||||
|
</t> |
||||
|
<br /> |
||||
|
</div> |
||||
|
<br/> |
||||
|
<t t-if="props.receipt.headerData.header"> |
||||
|
<div style='text-align:center; font-size:13px'> |
||||
|
<t t-esc="props.receipt.headerData.header" /> |
||||
|
</div> |
||||
|
<br /> |
||||
|
</t> |
||||
|
<div> |
||||
|
<table class='receipt-orderlines' style="font-size:15px; border-style:double; |
||||
|
border-left:none; border-right:none; border-bottom:none; width:100%;"> |
||||
|
<colgroup> |
||||
|
<col width='40%' /> |
||||
|
<col width='30%' /> |
||||
|
<col width='30%' /> |
||||
|
</colgroup> |
||||
|
<tr style="border-bottom:1px dashed black;"> |
||||
|
<th style="text-align:left;">Product</th> |
||||
|
<th style="text-align:right;">Qty</th> |
||||
|
<th style="text-align:right;">Amount</th> |
||||
|
</tr> |
||||
|
<t t-if="props.order and props.order.length and props.order and props.order.pos and props.order.pos.mainScreen and props.order.pos.mainScreen.props and props.order.pos.mainScreen.props.order and props.order.pos.mainScreen.props.order.orderlines and props.order.pos.mainScreen.props.order.orderlines.length"> |
||||
|
<t t-if="props.order.pos.mainScreen.props"> |
||||
|
<tr t-foreach="props.order.pos.mainScreen.props.order.orderlines" t-as="orderline" t-key="index_orderlines"> |
||||
|
<td style="padding-top:1%; padding-bottom:1%; text-align:left;"> |
||||
|
<t t-esc="orderline.get_product().display_name"/> |
||||
|
<t t-if="orderline.get_discount() > 0"> |
||||
|
<div style="font-size:12px; font-style:italic; color:#808080;"> |
||||
|
<t t-esc="orderline.get_discount()"/>% discount |
||||
|
</div> |
||||
|
</t> |
||||
|
<t t-if="orderline.customerNote"> |
||||
|
<div style="font-size:14px;" t-esc="orderline.customerNote"/> |
||||
|
</t> |
||||
|
</td> |
||||
|
<td style="text-align:right; font-size:14px;"> |
||||
|
<t t-esc="orderline.get_quantity_str_with_unit()"/> |
||||
|
</td> |
||||
|
<td style="text-align:right; font-size:14px;"> |
||||
|
<t t-esc="env.utils.formatCurrency(orderline.get_display_price())"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
</t> |
||||
|
<t t-else=""> |
||||
|
<t t-if="props.orderlines and props.orderlines.length"> |
||||
|
<tr t-foreach="props.orderlines" t-as="orderline" t-key="orderline.id"> |
||||
|
<td style="padding-top:1%; padding-bottom:1%; text-align:left;"> |
||||
|
<t t-esc="orderline.get_product().display_name"/> |
||||
|
<t t-if="orderline.get_discount() > 0"> |
||||
|
<div style="font-size:12px; font-style:italic; color:#808080;"> |
||||
|
<t t-esc="orderline.get_discount()"/>% discount |
||||
|
</div> |
||||
|
</t> |
||||
|
<t t-if="orderline.customerNote"> |
||||
|
<div style="font-size:14px;" t-esc="orderline.customerNote"/> |
||||
|
</t> |
||||
|
</td> |
||||
|
<td style="text-align:right; font-size:14px;"> |
||||
|
<t t-esc="orderline.get_quantity_str_with_unit()"/> |
||||
|
</td> |
||||
|
<td style="text-align:right; font-size:14px;"> |
||||
|
<t t-esc="env.utils.formatCurrency(orderline.get_display_price())"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
</t> |
||||
|
</table> |
||||
|
</div> |
||||
|
<br /> |
||||
|
<div style="padding-top:6px;"> |
||||
|
<t t-set='taxincluded' t-value='Math.abs(props.receipt.amount_total - props.receipt.total_with_tax) <= 0.000001' /> |
||||
|
<t t-if='!taxincluded'> |
||||
|
<br/> |
||||
|
<div style="font-weight:700; font-size:14px; border-top:1px dashed;"><span style="margin-left:40%;">Subtotal : </span><span t-esc='env.utils.formatCurrency(props.data.total_without_tax)' class="pos-receipt-right-align"/></div> |
||||
|
<t t-if="props.data.tax_details"> |
||||
|
<t t-foreach='props.data.tax_details' t-as='tax' t-key="index_tax_details"> |
||||
|
<div style="font-weight:700; font-size:14px;"> |
||||
|
<span style="margin-left:40%;"><t t-esc='tax.name' /></span> |
||||
|
<span t-esc='env.utils.formatCurrency(tax.amount)' class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
</t> |
||||
|
<!-- Total --> |
||||
|
<br/> |
||||
|
<div style="font-weight:700; font-size:14px;"> |
||||
|
<span style="margin-left:40%;">TOTAL : </span> |
||||
|
<span t-esc='env.utils.formatCurrency(props.data.amount_total)' class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
<br/><br/> |
||||
|
</div> |
||||
|
<!-- Payment Lines --> |
||||
|
<t t-foreach='props.paymentlines' t-as='line' t-key="index_paymentlines"> |
||||
|
<div style="font-size:14px; border-top:1px dashed; padding-top:5px;"> |
||||
|
<span style="margin-left:40%;"><t t-esc='line.name' /></span> |
||||
|
<span t-esc='env.utils.formatCurrency(line.amount)' class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
<br/> |
||||
|
<div class="receipt-change" style="font-size:14px;"> |
||||
|
<span style="margin-left:40%;">CHANGE : </span> |
||||
|
<span t-esc='env.utils.formatCurrency(props.receipt.change)' class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
<br/> |
||||
|
<!-- Extra Payment Info --> |
||||
|
<t t-if='props.receipt.total_discount'> |
||||
|
<div style="font-size:14px; border-top:1px dashed; padding-top:5px;"> |
||||
|
<span style="margin-left:40%;">Discounts : </span> |
||||
|
<span t-esc='env.utils.formatCurrency(props.receipt.total_discount)' class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
<t t-if='taxincluded'> |
||||
|
<t t-if="props.receipt.tax_details"> |
||||
|
<t t-foreach='props.receipt.tax_details' t-as='tax' t-key="index_receipt_tax_details"> |
||||
|
<div style="font-size:14px;"> |
||||
|
<span style="margin-left:40%;"><t t-esc='tax.name' /></span> |
||||
|
<span t-esc='env.utils.formatCurrency(tax.amount)' class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
<div style="font-size:14px;"> |
||||
|
<span style="margin-left:40%;">Total Taxes : </span> |
||||
|
<span t-esc='env.utils.formatCurrency(props.receipt.total_tax)' class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
<div class='before-footer' /> |
||||
|
<!-- Footer --> |
||||
|
<div t-if='props.receipt.footer_html' style="text-align:center; font-size:14px;"> |
||||
|
<t t-raw='props.receipt.footer_html'/> |
||||
|
</div> |
||||
|
<div t-if='!props.receipt.footer_html and props.receipt.footer' style="text-align:center; font-size:14px;"> |
||||
|
<br/> |
||||
|
<t t-esc='props.receipt.footer'/> |
||||
|
<br/><br/> |
||||
|
</div> |
||||
|
<div class='after-footer' style="font-size:14px;"> |
||||
|
<t t-foreach='props.paymentlines' t-as='line' t-key="index_payment"> |
||||
|
<t t-if='line.ticket'> |
||||
|
<br /> |
||||
|
<div class="pos-payment-terminal-receipt"> |
||||
|
<t t-raw='line.ticket'/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
</div> |
||||
|
<br/><br/> |
||||
|
<div style="font-size:14px; text-align:center;"> |
||||
|
Thank You... Please Visit Again ... |
||||
|
</div> |
||||
|
</div>]]></field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,6 @@ |
|||||
|
## Module <custom_receipts_for_pos> |
||||
|
|
||||
|
#### 30.10.2024 |
||||
|
#### Version 18.0.1.0.0 |
||||
|
##### ADD |
||||
|
- Initial Commit for POS Receipt Design |
@ -0,0 +1,25 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Sreerag PM (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################ |
||||
|
from .import pos_receipt |
||||
|
from .import pos_config |
||||
|
from .import pos_session |
@ -0,0 +1,41 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Sreerag PM (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################ |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class PosConfig(models.Model): |
||||
|
""" |
||||
|
This is an Odoo model for Point of Sale (POS). |
||||
|
It inherits the 'pos.config' model to add new fields. |
||||
|
""" |
||||
|
_inherit = 'pos.config' |
||||
|
|
||||
|
receipt_design_id = fields.Many2one('pos.receipt', string='Receipt Design', |
||||
|
help='Choose any receipt design') |
||||
|
design_receipt = fields.Text(related='receipt_design_id.design_receipt', |
||||
|
string='Receipt XML') |
||||
|
logo = fields.Binary(related='company_id.logo', string='Logo', |
||||
|
readonly=False) |
||||
|
is_custom_receipt = fields.Boolean(string='Is Custom Receipt', |
||||
|
help='Indicates the receipt design is ' |
||||
|
'custom or not') |
@ -0,0 +1,37 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Sreerag PM (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################ |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class PosReceipt(models.Model): |
||||
|
""" |
||||
|
This is an Odoo model for Point of Sale (POS). |
||||
|
It creates a new model of pos.receipt for providing different types of |
||||
|
receipt design. |
||||
|
""" |
||||
|
_name = 'pos.receipt' |
||||
|
_description = 'POS Receipts' |
||||
|
|
||||
|
name = fields.Char(string='Name', help='Name of the pos receipt') |
||||
|
design_receipt = fields.Text(string='Receipt XML', |
||||
|
help='Add your customised receipts for pos') |
@ -0,0 +1,52 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Sreerag PM (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################ |
||||
|
from odoo import models |
||||
|
|
||||
|
|
||||
|
class PosSession(models.Model): |
||||
|
""" |
||||
|
This is an Odoo model for Point of Sale (POS) sessions. |
||||
|
It inherits from the 'pos.session' model and extends its functionality. |
||||
|
|
||||
|
Methods: _loader_params_product_product(): Adds the 'qty_available' |
||||
|
field to the search parameters for the product loader. |
||||
|
""" |
||||
|
_inherit = 'pos.session' |
||||
|
|
||||
|
def _loader_params_product_product(self): |
||||
|
"""Function to load the product field to the product params""" |
||||
|
result = super()._loader_params_product_product() |
||||
|
result['search_params']['fields'].append('qty_available') |
||||
|
return result |
||||
|
|
||||
|
def _loader_params_pos_receipt(self): |
||||
|
"""Function that returns the product field pos Receipt""" |
||||
|
return { |
||||
|
'search_params': { |
||||
|
'fields': ['design_receipt', 'name'], |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
def _get_pos_ui_pos_receipt(self, params): |
||||
|
"""Used to Return the params value to the pos Receipts""" |
||||
|
return self.env['pos.receipt'].search_read(**params['search_params']) |
|
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 628 KiB |
After Width: | Height: | Size: 190 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 210 KiB |
After Width: | Height: | Size: 209 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 495 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 738 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 800 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 189 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 912 KiB |
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 167 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 880 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,44 @@ |
|||||
|
/** @odoo-module */ |
||||
|
import { OrderReceipt } from "@point_of_sale/app/screens/receipt_screen/receipt/order_receipt"; |
||||
|
import { patch } from "@web/core/utils/patch"; |
||||
|
import { useState, Component, xml } from "@odoo/owl"; |
||||
|
import { useService } from "@web/core/utils/hooks"; |
||||
|
|
||||
|
patch(OrderReceipt.prototype, { |
||||
|
setup(){ |
||||
|
super.setup(); |
||||
|
this.state = useState({ |
||||
|
template: true, |
||||
|
}) |
||||
|
this.pos = useState(useService("pos")); |
||||
|
const templateProps = { |
||||
|
data: this.props.data, |
||||
|
order: this.pos.get_order(), |
||||
|
receipt: this.pos.get_order().export_for_printing(), |
||||
|
orderlines: this.pos.get_order().get_orderlines(), |
||||
|
paymentlines: this.pos.get_order().export_for_printing().paymentlines |
||||
|
}; |
||||
|
}, |
||||
|
get templateProps() { |
||||
|
return { |
||||
|
data: this.props.data, |
||||
|
order: this.pos.get_order(), |
||||
|
receipt: this.pos.get_order().export_for_printing(), |
||||
|
orderlines: this.pos.get_order().get_orderlines(), |
||||
|
paymentlines: this.pos.get_order().export_for_printing().paymentlines |
||||
|
}; |
||||
|
}, |
||||
|
get templateComponent() { |
||||
|
var mainRef = this; |
||||
|
return class extends Component { |
||||
|
setup() {} |
||||
|
static template = xml`${mainRef.pos.config.design_receipt}` |
||||
|
}; |
||||
|
}, |
||||
|
get isTrue() { |
||||
|
if (this.env.services.pos.config.is_custom_receipt == false) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
}); |
@ -0,0 +1,168 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!--Inherit point_of_sale.OrderReceipt for getting our custom receipt design--> |
||||
|
<templates id="template" xml:space="preserve"> |
||||
|
<t t-inherit="point_of_sale.OrderReceipt" t-inherit-mode="extension"> |
||||
|
<xpath expr="//div[hasclass('pos-receipt')]" position="replace"> |
||||
|
<div class="pos-receipt"> |
||||
|
<t t-if="isTrue"> |
||||
|
<ReceiptHeader data="props.data.headerData"/> |
||||
|
<OrderWidget lines="props.data.orderlines" t-slot-scope="scope"> |
||||
|
<t t-set="line" t-value="scope.line"/> |
||||
|
<Orderline line="omit(scope.line, 'customerNote')" |
||||
|
class="{ 'pe-none': true }"> |
||||
|
<li t-if="line.customerNote" |
||||
|
class="customer-note w-100 p-2 my-1 rounded text-break"> |
||||
|
<i class="fa fa-sticky-note me-1" role="img" |
||||
|
aria-label="Customer Note" title="Customer Note"/> |
||||
|
<t t-esc="line.customerNote"/> |
||||
|
</li> |
||||
|
<ul t-if="line.pack_lot_lines"> |
||||
|
<li t-foreach="line.pack_lot_lines" t-as="lot" |
||||
|
t-key="lot.cid"> |
||||
|
<t t-if="lot.order_line.product.tracking == 'lot'"> |
||||
|
Lot Number <t t-esc="lot.lot_name"/> |
||||
|
</t> |
||||
|
<t t-else=""> |
||||
|
SN <t t-esc="lot.lot_name"/> |
||||
|
</t> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</Orderline> |
||||
|
</OrderWidget> |
||||
|
|
||||
|
<!-- Total --> |
||||
|
<div class="pos-receipt-right-align">--------</div> |
||||
|
<br/> |
||||
|
<div class="pos-receipt-amount"> |
||||
|
TOTAL |
||||
|
<span t-esc="props.formatCurrency(props.data.amount_total)" |
||||
|
class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
<t t-if="props.data.rounding_applied"> |
||||
|
<div class="pos-receipt-amount"> |
||||
|
Rounding |
||||
|
<span t-esc='props.formatCurrency(props.data.rounding_applied)' |
||||
|
class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
<div class="pos-receipt-amount">To Pay |
||||
|
<span t-esc='props.formatCurrency(props.data.amount_total + props.data.rounding_applied)' |
||||
|
class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
|
||||
|
<!-- Payment Lines --> |
||||
|
|
||||
|
<div class="paymentlines" t-foreach="props.data.paymentlines" |
||||
|
t-as="line" t-key="line_index"> |
||||
|
<t t-esc="line.name"/> |
||||
|
<span t-esc="props.formatCurrency(line.amount, false)" |
||||
|
class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
<div class="pos-receipt-amount receipt-change mt-2"> |
||||
|
CHANGE |
||||
|
<span t-esc="props.formatCurrency(props.data.change)" |
||||
|
class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Extra Payment Info --> |
||||
|
|
||||
|
<t t-if="props.data.total_discount"> |
||||
|
<div> |
||||
|
Discounts |
||||
|
<span t-esc="props.formatCurrency(props.data.total_discount)" |
||||
|
class="pos-receipt-right-align"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
<div t-if="props.data.tax_details.length > 0" |
||||
|
class="pos-receipt-taxes"> |
||||
|
<span/> |
||||
|
<span>TAX%</span> |
||||
|
<span>Tax</span> |
||||
|
<span>Base</span> |
||||
|
<span>Total</span> |
||||
|
<t t-foreach="props.data.tax_details" t-as="tax" |
||||
|
t-key="tax.tax.id"> |
||||
|
<span t-esc="tax.tax.letter || ''"/> |
||||
|
<span><t t-esc="tax.tax.amount"/> |
||||
|
%</span> |
||||
|
<span t-esc="props.formatCurrency(tax.amount, false)"/> |
||||
|
<span t-esc="props.formatCurrency(tax.base, false)"/> |
||||
|
<span t-esc="props.formatCurrency(tax.amount + tax.base, false)"/> |
||||
|
</t> |
||||
|
<t t-if="props.data.tax_details.length > 1"> |
||||
|
<span/> |
||||
|
<span/> |
||||
|
<span t-esc="props.formatCurrency(props.data.amount_tax, false)"/> |
||||
|
<span t-esc="props.formatCurrency(props.data.total_without_tax, false)"/> |
||||
|
<span t-esc="props.formatCurrency(props.data.amount_total, false)"/> |
||||
|
</t> |
||||
|
</div> |
||||
|
|
||||
|
<div class="before-footer"/> |
||||
|
|
||||
|
<div t-if="props.data.pos_qr_code"> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<div class="pos-receipt-order-data mb-2"> |
||||
|
Scan me to request an invoice for your purchase. |
||||
|
</div> |
||||
|
<img id="posqrcode" t-att-src="props.data.pos_qr_code" |
||||
|
class="pos-receipt-logo"/> |
||||
|
</div> |
||||
|
<div t-if="props.data.ticket_code"> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<div class="pos-receipt-order-data"> |
||||
|
You can go to <t t-out="props.data.base_url"/>/pos/ticket |
||||
|
and use the code below to request an invoice online |
||||
|
</div> |
||||
|
<div class="pos-receipt-order-data"> |
||||
|
Unique Code: <t t-out="props.data.ticket_code"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Footer --> |
||||
|
<div t-if="props.data.footer" class="pos-receipt-center-align" |
||||
|
style="white-space:pre-line"> |
||||
|
<br/> |
||||
|
<t t-esc="props.data.footer"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
</div> |
||||
|
|
||||
|
<div class="after-footer"> |
||||
|
<t t-foreach="props.data.paymentlines" t-as="line" |
||||
|
t-key="line_index"> |
||||
|
<t t-if="line.ticket"> |
||||
|
<br/> |
||||
|
<div class="pos-payment-terminal-receipt"> |
||||
|
<pre t-esc="line.ticket"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
</div> |
||||
|
|
||||
|
<br/> |
||||
|
<t t-if="props.shippingDate"> |
||||
|
<div class="pos-receipt-order-data"> |
||||
|
Expected delivery: |
||||
|
<div><t t-esc="props.shippingDate" /></div> |
||||
|
</div> |
||||
|
</t> |
||||
|
|
||||
|
<br/> |
||||
|
<div class="pos-receipt-order-data"> |
||||
|
<p>Odoo Point of Sale</p> |
||||
|
<div t-esc="props.data.name"/> |
||||
|
<div t-esc="props.data.date"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
<t t-else=""> |
||||
|
<t t-component="templateComponent" t-props="templateProps"/> |
||||
|
</t> |
||||
|
</div> |
||||
|
</xpath> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,22 @@ |
|||||
|
<?xml version='1.0' encoding='utf-8'?> |
||||
|
<odoo> |
||||
|
<!-- Inherits `pos.config` form view to add the new fields for the configuration for custom receipt design --> |
||||
|
<record id="pos_config_view_form" model="ir.ui.view"> |
||||
|
<field name="name">pos.config.view.form.inherit.custom.receipts.for.pos</field> |
||||
|
<field name="model">pos.config</field> |
||||
|
<field name="inherit_id" ref="point_of_sale.pos_config_view_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//setting[@id='other_devices']" position="after"> |
||||
|
<setting title="Customize the POS receipts" string="Custom Receipt" help="Use custom receipt designs"> |
||||
|
<field name="is_custom_receipt"/> |
||||
|
<div class="content-group mt16"> |
||||
|
<field name="receipt_design_id" invisible="not is_custom_receipt" required="True"/> |
||||
|
</div> |
||||
|
<div class="content-group mt16"> |
||||
|
<field name="design_receipt" invisible="1"/> |
||||
|
</div> |
||||
|
</setting> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |