From 03b463733210980b23d7b1b582b53d61ede204b6 Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Tue, 9 Jun 2026 09:41:44 +0700 Subject: [PATCH] feat: add closing cash tracking fields and update session validation logic to suppress shortages instead of surpluses --- README.md | 6 ++++-- models/pos_session.py | 38 ++++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 44e3009..5966872 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,9 @@ This module provides adjustments for the POS opening cash mechanism in Odoo 19. - Overrides `_set_opening_control_data` to properly initialize and track `opening_cash_expected` and `opening_cash_counted` while utilizing Odoo's native functionality. - Tracks opening cash correctly so that the system correctly calculates differences. - Leverages standard Odoo 19 journal handling for robust accounting integration. -- Suppresses positive cash differences automatically via standard backend validations, adjusting the `cash_register_balance_end_real` to match the expected balance when there is a surplus. +- **Phantom Difference Prevention:** Relies on standard Odoo mechanisms to ensure no journal items are created when the expected cash mathematically matches the inputted cash (e.g. opening with 150k and closing with 150k, or opening with 200k, selling 100k, and closing with 300k). +- **Shortage Suppression:** Automatically adjusts the real balance to match the expected balance when a shortage is detected, avoiding loss/expense journal entries. +- **Surplus Recording:** Allows standard Odoo behavior to record a surplus as a profit journal entry. ## Technical Details This module modifies the `pos.session` object, tracking: @@ -14,7 +16,7 @@ This module modifies the `pos.session` object, tracking: - **`opening_cash_counted`**: The actual cash counted by the cashier. - **`opening_cash_difference`**: Computed difference between counted and expected opening cash. -It modifies the standard `_validate_session` process strictly for suppressing positive discrepancies (where the ending cash register is higher than expected), logging the event into the chatter. +It modifies the standard `_validate_session` process strictly for suppressing negative discrepancies (shortages where the ending cash register is lower than expected), logging the event into the chatter. ## Author Suherdy Yacob diff --git a/models/pos_session.py b/models/pos_session.py index 7b74e60..86c20ff 100755 --- a/models/pos_session.py +++ b/models/pos_session.py @@ -25,6 +25,25 @@ class PosSession(models.Model): help="Difference between the expected and the counted cash at session opening.", ) + closing_cash_expected = fields.Monetary( + string="Expected Closing Cash", + currency_field="currency_id", + readonly=True, + help="Expected cash amount in the drawer when the session is closed.", + ) + closing_cash_counted = fields.Monetary( + string="Counted Closing Cash", + currency_field="currency_id", + readonly=True, + help="Actual cash amount counted by the cashier when the session is closed.", + ) + closing_cash_difference = fields.Monetary( + string="Closing Cash Difference", + currency_field="currency_id", + readonly=True, + help="Difference between expected and counted cash at session closing.", + ) + @api.depends("opening_cash_expected", "opening_cash_counted") def _compute_opening_cash_difference(self): for session in self: @@ -83,14 +102,21 @@ class PosSession(models.Model): def _validate_session(self, balancing_account=False, amount_to_balance=0, bank_payment_method_diffs=None): for session in self: if session.config_id.cash_control: - difference = session.cash_register_balance_end_real - session.cash_register_balance_end - if session.currency_id.compare_amounts(difference, 0.0) > 0: - session.message_post(body="Auto-adjustment: Cashier input %s overridden to expected %s to suppress positive difference of %s." % ( - session.currency_id.format(session.cash_register_balance_end_real), - session.currency_id.format(session.cash_register_balance_end), + expected = session.cash_register_balance_end + counted = session.cash_register_balance_end_real + difference = counted - expected + session.write({ + 'closing_cash_expected': expected, + 'closing_cash_counted': counted, + 'closing_cash_difference': difference, + }) + if session.currency_id.compare_amounts(difference, 0.0) < 0: + session.message_post(body="Auto-adjustment: Cashier input %s overridden to expected %s to suppress shortage difference of %s." % ( + session.currency_id.format(counted), + session.currency_id.format(expected), session.currency_id.format(difference) )) - session.write({'cash_register_balance_end_real': session.cash_register_balance_end}) + session.write({'cash_register_balance_end_real': expected}) for order in session.order_ids: for payment in order.payment_ids: