Initial Commit

This commit is contained in:
Abdul Aziz Amrullah 2026-04-08 11:28:38 +07:00
commit 989865e434
10 changed files with 191 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
venv/
__pycache__/
*.pyc
.env

1
__init__.py Normal file
View File

@ -0,0 +1 @@
from . import models

21
__manifest__.py Normal file
View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
{
'name': 'POS Custom Closing',
'version': '1.0',
'category': 'Sales/Point of Sale',
'summary': 'Customize Point of sale Closing Register modal',
'author': 'Aziz',
'depends': ['point_of_sale', 'pos_hr'],
'data': [
'views/res_config_settings_views.xml',
],
'assets': {
'point_of_sale._assets_pos': [
'pos_custom_closing/static/src/app/close_pos_popup_inherit.xml',
'pos_custom_closing/static/src/app/close_pos_popup_patch.js',
],
},
'installable': True,
'application': False,
'license': 'LGPL-3',
}

2
models/__init__.py Normal file
View File

@ -0,0 +1,2 @@
from . import pos_config
from . import res_config_settings

11
models/pos_config.py Normal file
View File

@ -0,0 +1,11 @@
from odoo import fields, models
class PosConfig(models.Model):
_inherit = 'pos.config'
custom_hide_payment_details = fields.Boolean("Hide Payment Details")
custom_hide_non_cash_inputs = fields.Boolean("Hide Non-Cash Payment Inputs")
custom_hide_cash_in_out = fields.Boolean("Hide Cash In/Out Button")
custom_hide_summary_data = fields.Boolean("Hide Summary Data")
custom_hide_copy_btn = fields.Boolean("Hide Copy Buttons")
custom_hide_daily_sale_btn = fields.Boolean("Hide Daily Sale Button")

View File

@ -0,0 +1,11 @@
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
pos_custom_hide_payment_details = fields.Boolean(related='pos_config_id.custom_hide_payment_details', readonly=False)
pos_custom_hide_non_cash_inputs = fields.Boolean(related='pos_config_id.custom_hide_non_cash_inputs', readonly=False)
pos_custom_hide_cash_in_out = fields.Boolean(related='pos_config_id.custom_hide_cash_in_out', readonly=False)
pos_custom_hide_summary_data = fields.Boolean(related='pos_config_id.custom_hide_summary_data', readonly=False)
pos_custom_hide_copy_btn = fields.Boolean(related='pos_config_id.custom_hide_copy_btn', readonly=False)
pos_custom_hide_daily_sale_btn = fields.Boolean(related='pos_config_id.custom_hide_daily_sale_btn', readonly=False)

35
readme.md Normal file
View File

@ -0,0 +1,35 @@
# POS Custom Closing
This custom module for Odoo 19 modifies the Point of Sale (POS) Closing Register modal to allow for advanced UI customizations based on the shop's preferences. It also improves workflow speed by streamlining the checkout closing process.
## Features
This module introduces a "Closing Session Customization" section within the POS settings, giving administrators the ability to conditionally display or hide specific elements on the Closing Register popup:
1. **Hide Payment Details:** Hides the breakdown of payments grouped by payment method (including the "Opening", "Payments", "Counted", and "Difference" rows).
2. **Hide Non-Cash Payment Inputs:** Hides all manual input fields for non-cash payment methods (like Bank/Card/Customer Account), leaving only the Cash Count input.
3. **Hide Cash In/Out Button:** Hides the "Cash In/Out" shortcut button from the modal footer.
4. **Hide Summary Data:** Hides the total "Orders Count" and "Orders Amount" from the top right corner of the dialog.
5. **Hide Copy Buttons:** Hides the quick copy ("clone") shortcut buttons next to the cash/payment input fields.
6. **Hide Daily Sale Button:** Hides the "Daily Sale" download report shortcut button from the modal footer.
### Streamlined Workflow (Warning Bypass)
Additionally, this module overrides the standard Odoo behavior for "Payments Difference":
- Authorized users will implicitly log differences **without seeing the warning dialog** (`"The money counted doesn't match what we expected. Want to log the difference for the books?"`).
- Simply clicking "Close Register" will finalize the process immediately, significantly speeding up the end-of-shift workflow.
## Configuration
To enable or disable any of the hiding features:
1. Ensure you have the `pos_custom_closing` module installed.
2. Navigate to **Point of Sale** -> **Configuration** -> **Settings**.
3. Scroll down to the **Closing Session Customization** section.
4. Check the desired boxes to hide those respective UI elements, and **Save**.
5. The changes will immediately apply to the next POS session you close.
## Technical Details
- **Depends:** `point_of_sale`, `pos_hr`
- **Frontend Overrides:** Conditionally injects CSS styling (`d-none`) and overrides nested elements using XPath to cleanly hide DOM elements without breaking `pos_hr`'s injected structures.
- **JavaScript Patches:** Wraps the `ClosePosPopup`'s `confirm()` method iteratively returning `this.closeSession()` to natively bypass UI dialogs.

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="pos_custom_closing.ClosePosPopup" t-inherit="point_of_sale.ClosePosPopup" t-inherit-mode="extension" owl="1">
<!-- 1. Hide Payment Details -->
<xpath expr="//div[hasclass('payment-methods-overview')]" position="attributes">
<attribute name="t-att-class">pos.config.custom_hide_payment_details ? 'd-none' : ''</attribute>
</xpath>
<xpath expr="//t[@t-if='pos.config.module_pos_hr']" position="attributes">
<attribute name="t-if">pos.config.module_pos_hr and !pos.config.custom_hide_payment_details</attribute>
</xpath>
<!-- 2. Hide Non Cash Input Fields -->
<xpath expr="//div[@t-foreach='props.non_cash_payment_methods']//t[@t-if='_showDiff']" position="attributes">
<attribute name="t-if">_showDiff and !pos.config.custom_hide_non_cash_inputs</attribute>
</xpath>
<!-- 3. Hide Cash In/Out -->
<xpath expr="//button[@t-on-click='() =&gt; this.cashMove()']" position="attributes">
<attribute name="t-if">pos.showCashMoveButton and !pos.config.custom_hide_cash_in_out</attribute>
</xpath>
<!-- 4. Hide Summary Data -->
<xpath expr="//div[hasclass('total-orders')]" position="attributes">
<attribute name="t-if">!pos.config.custom_hide_summary_data</attribute>
</xpath>
<!-- 5. Hide Copy Buttons -->
<!-- Cash count autofill -->
<xpath expr="//button[@t-on-click='autoFillCashCount']" position="attributes">
<attribute name="t-if">!pos.config.custom_hide_copy_btn</attribute>
</xpath>
<!-- PM count autofill -->
<xpath expr="//button[@t-on-click='() =&gt; this.autoFillPMCount(pm.id)']" position="attributes">
<attribute name="t-if">!pos.config.custom_hide_copy_btn</attribute>
</xpath>
<!-- 6. Hide Daily Sale Button -->
<xpath expr="//button[@t-on-click='downloadSalesReport']" position="attributes">
<attribute name="t-if">!pos.config.custom_hide_daily_sale_btn</attribute>
</xpath>
</t>
</templates>

View File

@ -0,0 +1,30 @@
/** @odoo-module **/
import { ClosePosPopup } from "@point_of_sale/app/components/popups/closing_popup/closing_popup";
import { patch } from "@web/core/utils/patch";
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
import { _t } from "@web/core/l10n/translation";
patch(ClosePosPopup.prototype, {
async confirm() {
if (!this.pos.config.cash_control || this.pos.currency.isZero(this.getMaxDifference())) {
await this.closeSession();
return;
}
// If the user is authorized to accept the difference, close the session immediately
// bypassing the "Proceed Anyway" / "Discard" dialog completely.
if (this.hasUserAuthority()) {
return this.closeSession();
}
// If the user doesn't have authority, still show the authorization required warning
this.dialog.add(ConfirmationDialog, {
title: _t("Payments Difference"),
body: _t(
"The maximum difference allowed is %s.\nPlease contact your manager to accept the closing difference.",
this.env.utils.formatCurrency(this.props.amount_authorized_diff)
),
});
}
});

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form_inherit_pos_custom_closing" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.pos.custom.closing</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="point_of_sale.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//block[@id='pos_accounting_section']" position="after">
<block title="Closing Session Customization" id="pos_custom_closing_section">
<setting id="pos_custom_hide_payment_details_setting" help="Hide payment details section in the closing modal">
<field name="pos_custom_hide_payment_details" />
</setting>
<setting id="pos_custom_hide_non_cash_inputs_setting" help="Hide non-cash input fields (like bank, customer account) and only keep cash">
<field name="pos_custom_hide_non_cash_inputs" />
</setting>
<setting id="pos_custom_hide_cash_in_out_setting" help="Hide Cash In/Out button">
<field name="pos_custom_hide_cash_in_out" />
</setting>
<setting id="pos_custom_hide_summary_data_setting" help="Hide number of orders and total summary data at top right">
<field name="pos_custom_hide_summary_data" />
</setting>
<setting id="pos_custom_hide_copy_btn_setting" help="Hide copy/auto-fill icons next to input fields">
<field name="pos_custom_hide_copy_btn" />
</setting>
<setting id="pos_custom_hide_daily_sale_btn_setting" help="Hide Daily Sale download button">
<field name="pos_custom_hide_daily_sale_btn" />
</setting>
</block>
</xpath>
</field>
</record>
</odoo>