commit 989865e434f35b30033ec2daed53b8033c716a28 Author: Abdul Aziz Amrullah Date: Wed Apr 8 11:28:38 2026 +0700 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cbbb8d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +venv/ +__pycache__/ +*.pyc +.env \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/__manifest__.py b/__manifest__.py new file mode 100644 index 0000000..f19f641 --- /dev/null +++ b/__manifest__.py @@ -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', +} diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..2b92809 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,2 @@ +from . import pos_config +from . import res_config_settings diff --git a/models/pos_config.py b/models/pos_config.py new file mode 100644 index 0000000..2979b77 --- /dev/null +++ b/models/pos_config.py @@ -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") diff --git a/models/res_config_settings.py b/models/res_config_settings.py new file mode 100644 index 0000000..1c70cf9 --- /dev/null +++ b/models/res_config_settings.py @@ -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) diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..5c56d19 --- /dev/null +++ b/readme.md @@ -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. diff --git a/static/src/app/close_pos_popup_inherit.xml b/static/src/app/close_pos_popup_inherit.xml new file mode 100644 index 0000000..948d712 --- /dev/null +++ b/static/src/app/close_pos_popup_inherit.xml @@ -0,0 +1,44 @@ + + + + + + + pos.config.custom_hide_payment_details ? 'd-none' : '' + + + pos.config.module_pos_hr and !pos.config.custom_hide_payment_details + + + + + _showDiff and !pos.config.custom_hide_non_cash_inputs + + + + + pos.showCashMoveButton and !pos.config.custom_hide_cash_in_out + + + + + !pos.config.custom_hide_summary_data + + + + + + !pos.config.custom_hide_copy_btn + + + + !pos.config.custom_hide_copy_btn + + + + + !pos.config.custom_hide_daily_sale_btn + + + + diff --git a/static/src/app/close_pos_popup_patch.js b/static/src/app/close_pos_popup_patch.js new file mode 100644 index 0000000..7fb042b --- /dev/null +++ b/static/src/app/close_pos_popup_patch.js @@ -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) + ), + }); + } +}); diff --git a/views/res_config_settings_views.xml b/views/res_config_settings_views.xml new file mode 100644 index 0000000..588abdc --- /dev/null +++ b/views/res_config_settings_views.xml @@ -0,0 +1,32 @@ + + + + res.config.settings.view.form.inherit.pos.custom.closing + res.config.settings + + + + + + + + + + + + + + + + + + + + + + + + + + +