Skip to content

fix: submit customer credit redemption payload from POS#218

Merged
engahmed1190 merged 2 commits intoBrainWise-DEV:developfrom
my-dev-jour:fix/210-customer-credit-payload
Apr 1, 2026
Merged

fix: submit customer credit redemption payload from POS#218
engahmed1190 merged 2 commits intoBrainWise-DEV:developfrom
my-dev-jour:fix/210-customer-credit-payload

Conversation

@my-dev-jour
Copy link
Copy Markdown
Contributor

Summary

Fix customer-credit POS sales so the frontend submits the redemption payload the backend already expects.

Before this change:

  • the payment dialog created Customer Credit entries with is_customer_credit and credit_details
  • POSSale.vue stripped that metadata before submit
  • submit_invoice() never received customer_credit_dict / redeemed_customer_credit
  • pure customer-credit sales could not redeem credit correctly

This patch:

  • preserves customer-credit metadata through the POS submit flow
  • builds customer_credit_dict and redeemed_customer_credit in useInvoice.js
  • excludes synthetic Customer Credit rows from normal invoice payments
  • allows pure customer-credit POS sales to pass core POS payment-row validation only when POSNext has explicitly marked the invoice for redemption

Validation

  • reproduced the bug on staging (frappe 16.12.0, erpnext 16.11.0, pos_next 1.15.0)
  • applied the fix on staging and reran the same bench-console sale flow
  • confirmed the invoice submitted successfully
  • confirmed customer-credit redemption created a linked Journal Entry
  • confirmed the saved invoice finished with outstanding_amount = 0

Issue

Closes #210

Copy link
Copy Markdown
Contributor

@engahmed1190 engahmed1190 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review — APPROVE (with suggestions) ✅

Summary

Enables pure customer-credit POS sales by preserving credit metadata through the submit flow and adding a scoped validate_pos_paid_amount override.

Test Results

No test file included. Validated on staging per PR description.

Correctness

Frontend (buildCustomerCreditPayload):

  • Well-structured: separates credit payments from regular payments, deduplicates credit sources via Map, allocates FIFO with tolerance check (0.01)
  • Edge case handled: if credit_details is missing on an is_customer_credit payment, the allocation throws — correct, better to fail than silently lose credit
  • serializeInvoicePayments correctly filters out is_customer_credit payments from the normal payment array

Backend (validate_pos_paid_amount):

  • Correctly scoped: only activates when pos_next_redeemed_customer_credit flag is set AND zero payments AND POS invoice with positive grand total
  • Falls through to super().validate_pos_paid_amount() for all other cases
  • The flag is on invoice_doc.flags (transient Python attribute, not a DocField) — cannot be injected via Frappe's API or JSON payload

POSSale.vue (...p spread):

  • Correctly preserves is_customer_credit and credit_details metadata that was previously stripped

Security

The flags pattern is idiomatic Frappe and safe. The only code path that sets pos_next_redeemed_customer_credit is through submit_invoice() which is behind @frappe.whitelist().

Suggestions (non-blocking)

  1. Add a backend guard: if redeemed_customer_credit > 0 but customer_credit_dict is empty/falsy, don't set the flag. Currently, a crafted API call with redeemed_customer_credit=100 and no customer_credit_dict would submit a zero-payment invoice that stays fully outstanding
  2. Add tests for the validate_pos_paid_amount override — verify it bypasses with the flag and does NOT bypass without it
  3. Consider filtering the ...p spread in POSSale.vue to only known properties, to prevent unexpected properties leaking into the cart store

Conflict Note

This PR modifies submit_invoice in invoices.py and adds validate_pos_paid_amount to sales_invoice.py. No conflict with the current fix/payment-amount-wiped-by-erpnext branch (which modifies update_invoice).

Verdict

Well-scoped fix. The flags pattern is the right approach for a temporary validation bypass. Good to merge.

Copy link
Copy Markdown
Contributor

@engahmed1190 engahmed1190 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirming approval — customer credit payload fix is correct, validate_pos_paid_amount override is properly scoped via flags pattern. Safe to merge.

@engahmed1190 engahmed1190 merged commit 73868ed into BrainWise-DEV:develop Apr 1, 2026
1 of 3 checks passed
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.

[Bug]: Customer Credit UI counts payment as settled but submit flow does not send redemption payload

2 participants