feat: Automatically adjust negative cash differences during POS session validation and remove the custom _post_statement_difference override.

This commit is contained in:
Suherdy Yacob 2026-02-23 09:18:45 +07:00
parent 78e49cdeb1
commit 296ce1329a
2 changed files with 18 additions and 22 deletions

View File

@ -6,14 +6,15 @@
**License:** LGPL-3 **License:** LGPL-3
## Summary ## Summary
Prevent opening cash journal entries and exclude opening float from closing totals while keeping reconciliation data. Prevents unwanted journal entries by handling zero-amount payments and automatically adjusting negative cash differences during POS session closing.
## Features ## Features
- **Opening Cash Adjustment:** Modifies how opening cash is handled to prevent unwanted journal entries. - **Negative Cash Closing Adjustment:** Automatically overrides the cashier's inputted cash amount to match the expected closing balance if a cash shortage (negative difference) is detected. This silently prevents Odoo from generating a Cash Difference Loss journal entry, and logs the auto-adjustment in the session's chatter instead.
- **Closing Totals:** Excludes opening float from closing totals calculation. - **Zero-Amount Payment Cleanup:** Automatically removes `pos.payment` lines with `0.00` amount during session verification. This prevents the creation of "Difference at closing PoS session" journal items triggered by empty payments (e.g., from 100% discount or external payment edge cases).
- **Zero-Amount Payment Cleanup:** Automatically removes `pos.payment` lines with `0.00` amount during session verification. This prevents the creation of "Difference at closing PoS session" journal items triggered by empty payments (e.g. from 100% discount or external payment edge cases). - **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).
- **Negative Cash Closing Adjustment:** Automatically overrides the cashier's input to match the expected closing balance if a negative difference is detected, logging the action in the chatter and preventing a loss journal entry.
## Technical Details ## Technical Details
### Zero-Amount Payment Fix ### Validation Override
The module overrides `_validate_session` in `pos.session`. Before the standard validation process begins, it iterates through all orders in the session and unlinks any payment lines where the amount is considered zero by the session's currency. The module overrides `_validate_session` in `pos.session`:
1. **Auto-Adjustment:** Detects if `cash_register_balance_end_real` is less than `cash_register_balance_end`. If so, it overrides the real balance to match the expected balance *before* standard accounting lines are generated, avoiding the creation of loss lines.
2. **Zero-Amount Fix:** Iterates through all orders in the session and unlinks any payment lines where the amount is considered zero by the session's currency.

View File

@ -72,21 +72,7 @@ class PosSession(models.Model):
opening_amount = self.opening_cash_expected opening_amount = self.opening_cash_expected
return opening_amount or 0.0 return opening_amount or 0.0
def _post_statement_difference(self, amount, is_opening):
for session in self:
session_amount = amount
if not is_opening and session.config_id.cash_control:
opening_float = session._get_opening_float_amount()
if opening_float:
if session.currency_id.is_zero(session_amount + opening_float):
continue
if session.currency_id.compare_amounts(session.cash_register_balance_end_real or 0.0, opening_float) <= 0:
session_amount += opening_float
if session.currency_id.is_zero(session_amount):
continue
elif session.currency_id.is_zero(session_amount):
continue
super(PosSession, session)._post_statement_difference(session_amount, is_opening)
@api.depends("payment_method_ids", "order_ids", "cash_register_balance_start", "cash_real_transaction", "statement_line_ids") @api.depends("payment_method_ids", "order_ids", "cash_register_balance_start", "cash_real_transaction", "statement_line_ids")
def _compute_cash_balance(self): def _compute_cash_balance(self):
@ -136,6 +122,15 @@ class PosSession(models.Model):
def _validate_session(self, balancing_account=False, amount_to_balance=0, bank_payment_method_diffs=None): def _validate_session(self, balancing_account=False, amount_to_balance=0, bank_payment_method_diffs=None):
for session in self: 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 negative difference of %s." % (
session.currency_id.format(session.cash_register_balance_end_real),
session.currency_id.format(session.cash_register_balance_end),
session.currency_id.format(difference)
))
session.write({'cash_register_balance_end_real': session.cash_register_balance_end})
for order in session.order_ids: for order in session.order_ids:
for payment in order.payment_ids: for payment in order.payment_ids: