feat(web-admin): add last-period due amount calc helpers

Pure functions for fq auto-fill of the final installment amount
with override/lock gates, covered by unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-10-13 14:48:43 +08:00
1 parent 13ac45d10d
commit 5fd5550e0d
2 files changed
+73 -1

No files matched your search

@@ -15,7 +15,9 @@ import {
applyConsolidateRemainingToPayment,
applyExpandRemainingToInstallment,
availableSamplePayModes,
samplePaymentHasConfirmedTransfer
samplePaymentHasConfirmedTransfer,
calcLastPeriodDueAmount,
shouldAutoFillLastPeriodDue
} from './protocol-sample-payment'
describe('parsePreferentialPrice', () => {
@@ -331,3 +333,42 @@ describe('samplePaymentHasConfirmedTransfer', () => {
)
})
})
describe('calcLastPeriodDueAmount', () => {
it('last = contract − sum(priors), cents remainder on last', () => {
assert.equal(calcLastPeriodDueAmount(100, [33.33, 33.33]), 33.34)
assert.equal(calcLastPeriodDueAmount(20000, [10000, 5000]), 5000)
})
it('returns null when contract invalid', () => {
assert.equal(calcLastPeriodDueAmount(null, [1000]), null)
assert.equal(calcLastPeriodDueAmount(NaN, [1000]), null)
})
it('returns null when all priors empty', () => {
assert.equal(calcLastPeriodDueAmount(20000, [null, '', undefined]), null)
})
it('treats empty slot as 0 when at least one prior filled', () => {
assert.equal(calcLastPeriodDueAmount(20000, [10000, null, '']), 10000)
})
it('clamps negative result to 0', () => {
assert.equal(calcLastPeriodDueAmount(1000, [800, 800]), 0)
})
})
describe('shouldAutoFillLastPeriodDue', () => {
it('blocks when override or locked', () => {
assert.equal(
shouldAutoFillLastPeriodDue({ lastManualOverride: true, lastLocked: false }),
false
)
assert.equal(
shouldAutoFillLastPeriodDue({ lastManualOverride: false, lastLocked: true }),
false
)
})
it('allows when neither override nor locked', () => {
assert.equal(
shouldAutoFillLastPeriodDue({ lastManualOverride: false, lastLocked: false }),
true
)
})
})