Skip to content

fix: shift closing total reflects money collected, not invoiced#312

Open
NotAbdelrahmanelsayed wants to merge 2 commits into
BrainWise-DEV:developfrom
NotAbdelrahmanelsayed:fix/credit-sale-closing-total
Open

fix: shift closing total reflects money collected, not invoiced#312
NotAbdelrahmanelsayed wants to merge 2 commits into
BrainWise-DEV:developfrom
NotAbdelrahmanelsayed:fix/credit-sale-closing-total

Conversation

@NotAbdelrahmanelsayed

Copy link
Copy Markdown
Contributor

Problem

When closing a POS shift, the closing total counts the full grand total of every invoice linked to the shift — even pure Pay-on-Account credit sales where no money was received. The cash Payment Reconciliation is built only from real payment rows, so it is already correct — but Net Sales (grand_total) disagrees with it within a single shift:

Event Cash reconciliation Net Sales (grand_total)
Credit sale created (no money) +0 (correct) +full amount (bug)
Old due collected today +amount (correct) +0

Root cause: pos_closing_shift.py › _process_invoice() added base_grand_total (the full invoice value) into grand_total/net_total/sales_total and the per-row amount, ignoring how much was actually paid.

Fix

For non-return invoices, the money summaries and the per-row grand_total now use the amount actually collected (base_paid_amount):

  • pure credit sale → contributes 0
  • partial sale → contributes only its down-payment
  • net_total scaled by paid_ratio = base_paid / base_grand_total

The full invoice value is preserved in transaction_amount; display-only invoice_total and outstanding_amount are added for the dialog and stripped before the child-table set (Sales Invoice Reference has no such columns). Quantities, tax accrual and the returns branch are unchanged. With this change Net Sales == sum of per-invoice collected == reconciliation cash delta.

The Close Shift dialog shows an On Account / Partially Paid badge and an Unpaid: {amount} sub-line on rows collected for less than their invoice value (desktop + mobile).

Edge case: if a credit sale is created and its due is collected within the same shift, the down-payment shows in Net Sales and the later dues Payment Entry shows in reconciliation — both are real takings, reported in their respective sections.

Tests

Adds unit tests for _process_invoice covering fully-paid, pure-credit, partial and credit-return cases, asserting the summary equals only the collected portions and per-row amounts sum to the header total. Adds the Arabic translation for the new Unpaid: {0} string.

🤖 Generated with Claude Code

NotAbdelrahmanelsayed and others added 2 commits June 12, 2026 21:09
Credit (Pay-on-Account) sales inflated the POS shift closing total.
`_process_invoice()` added the full `base_grand_total` of every invoice to
the sales summary (`grand_total`/`net_total`/`sales_total`) and the per-row
amount, regardless of how much was actually paid. The cash Payment
Reconciliation, however, is built only from real payment rows — so a pure
credit sale pushed Net Sales up by the full amount while contributing 0 to
the drawer, leaving the two figures inconsistent within a single shift.

For non-return invoices the money summaries and the per-row `grand_total`
now use the amount actually collected (`base_paid_amount`): a pure credit
sale contributes 0, a partial sale contributes only its down-payment, and
`net_total` is scaled by the paid ratio. The full invoice value is preserved
in `transaction_amount`; display-only `invoice_total` and
`outstanding_amount` are added for the dialog badge and stripped before the
child-table set. Returns, quantities and tax accrual are unchanged.

The Close Shift dialog now shows an "On Account" / "Partially Paid" badge and
an "Unpaid: {amount}" sub-line on rows collected for less than their invoice
value. Adds unit tests for the collected-money totals and an Arabic string.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…closing-total

# Conflicts:
#	POS/src/components/ShiftClosingDialog.vue
#	pos_next/pos_next/doctype/pos_closing_shift/pos_closing_shift.py
#	pos_next/pos_next/doctype/pos_closing_shift/test_pos_closing_shift.py
#	pos_next/translations/ar.csv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant