feat(po): manager sets advance payment on approval (#92) #99

Merged
shad0w merged 3 commits from feat/manager-advance-payment into master 2026-06-23 20:26:28 +00:00
Owner

Closes #92.

Summary

The approving Manager decides how much of the PO is paid first — a 0–100% slider on the approval card (default 100% = full). Per the issue's answered open questions, the slider is convenience only: the absolute amount is what gets stored, it prefills the first Accounts payment, the balance runs the normal partial loop, it's locked at approval, and it is not on the export.

Data

  • PurchaseOrder.suggestedAdvancePayment Decimal(12,2), nullable + migration. Null (legacy / no explicit advance) ⇒ full payment, so existing POs are unaffected.

Flow

  • Approve (approval-actions.tsx → approvePo): whole-percent slider resolves to ₹amount (100% = exact total, partials rounded to whole rupees); the action clamps to [0, totalAmount], persists it, and records it on the APPROVED audit row. Set once — nothing else writes the field, so it's effectively locked.
  • Accounts (payments queue + po-detail): the requested advance is surfaced, and it prefills the first payment's amount (only when nothing is paid yet and it's a true partial). The remaining balance then follows the existing PARTIALLY_PAID loop — markPaid is unchanged.
  • Export: po-export-layout.ts untouched.

Tests

  • approval-actions.test.ts: persists the advance + audit metadata, defaults to null without an advance, and clamps an over-total amount down to the total.
  • Full integration suite green (245), tsc --noEmit clean.

Notes

  • "Whole numbers only" → the slider steps in whole percent; the stored amount keeps Decimal(12,2) (exact total at 100%, whole rupees for partials).
  • The migration must be applied on deploy (prisma migrate deploy).

🤖 Generated with Claude Code

Closes #92. ## Summary The approving **Manager decides how much of the PO is paid first** — a 0–100% slider on the approval card (default **100% = full**). Per the issue's answered open questions, the slider is convenience only: the **absolute amount** is what gets stored, it **prefills the first Accounts payment**, the balance runs the normal partial loop, it's **locked at approval**, and it is **not** on the export. ## Data - `PurchaseOrder.suggestedAdvancePayment` `Decimal(12,2)`, nullable + migration. Null (legacy / no explicit advance) ⇒ full payment, so existing POs are unaffected. ## Flow - **Approve** (`approval-actions.tsx` → `approvePo`): whole-percent slider resolves to ₹amount (`100% = exact total`, partials rounded to whole rupees); the action clamps to `[0, totalAmount]`, persists it, and records it on the `APPROVED` audit row. Set once — nothing else writes the field, so it's effectively locked. - **Accounts** (`payments` queue + `po-detail`): the requested advance is surfaced, and it **prefills the first payment's amount** (only when nothing is paid yet and it's a true partial). The remaining balance then follows the existing `PARTIALLY_PAID` loop — `markPaid` is unchanged. - **Export**: `po-export-layout.ts` untouched. ## Tests - `approval-actions.test.ts`: persists the advance + audit metadata, defaults to null without an advance, and clamps an over-total amount down to the total. - Full integration suite green (245), `tsc --noEmit` clean. ## Notes - "Whole numbers only" → the slider steps in whole percent; the stored amount keeps `Decimal(12,2)` (exact total at 100%, whole rupees for partials). - The migration must be applied on deploy (`prisma migrate deploy`). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
shad0w added 1 commit 2026-06-23 20:10:43 +00:00
feat(po): manager sets advance payment on approval (issue #92)
All checks were successful
PR checks / checks (pull_request) Successful in 43s
PR checks / integration (pull_request) Successful in 30s
99c928213b
The approving Manager decides how much of the PO is paid first, via a
0–100% slider on the approval card (default 100% = full). The slider is
convenience only — the resolved ABSOLUTE amount is stored on
PurchaseOrder.suggestedAdvancePayment (Decimal(12,2), nullable).

- schema + migration: add suggestedAdvancePayment (null = no explicit
  advance ⇒ full payment, preserves legacy behaviour).
- approvePo(): accepts the amount, clamps to [0, totalAmount], persists
  it, records it on the APPROVED audit row. Set once at approval; never
  edited afterwards.
- approval-actions.tsx: whole-percent slider showing the resolved ₹
  amount + remaining balance; value sent with Approve / Approve-with-Remarks.
- Accounts surface: payment queue + PO detail show the advance; it
  prefills the FIRST payment amount (only when nothing is paid yet and
  it is a true partial). Balance runs the normal PARTIALLY_PAID loop.
- Not shown on the exported PO/invoice (po-export-layout untouched).
- Tests: persist + audit metadata + clamp-to-total.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
shad0w added 1 commit 2026-06-23 20:15:59 +00:00
docs(schema): note suggestedAdvancePayment is the reuse point for issue #91
All checks were successful
PR checks / checks (pull_request) Successful in 43s
PR checks / integration (pull_request) Successful in 32s
455d268925
The structured payment-request lane (#91) should extend this column for the
ADVANCE/PART 'exact sum due', not add a parallel field.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
shad0w added 1 commit 2026-06-23 20:26:12 +00:00
Merge branch 'master' into feat/manager-advance-payment
All checks were successful
PR checks / checks (pull_request) Successful in 44s
PR checks / integration (pull_request) Successful in 30s
0e0e377718
shad0w merged commit 8a2c592f6f into master 2026-06-23 20:26:28 +00:00
Sign in to join this conversation.
No description provided.