mirror of
https://github.com/whekin/household-bot.git
synced 2026-04-01 07:14:02 +00:00
Support rebalance and validate purchase splits
Add ParticipantShare type and client-side rebalance/validation helpers for purchase splits (rebalancePurchaseSplit, recalculatePercentages, calculateRemainingToAllocate, validatePurchaseDraft). Integrate rebalancing and validation into the miniapp ledger UI (auto-adjust shares, percentage<>amount syncing, remaining/error display, prefill participants on new purchase, disable save when invalid). On the backend, tighten input validation in finance-command-service for custom_amounts (require explicit shares and sum match) and make settlement-engine more lenient when reading legacy/malformed custom splits (ignore missing shares, accept explicit subset). Also add a test ensuring dashboard generation doesn't 500 on legacy malformed purchases.
This commit is contained in:
@@ -15,6 +15,8 @@ import type {
|
||||
import {
|
||||
BillingCycleId,
|
||||
BillingPeriod,
|
||||
DomainError,
|
||||
DOMAIN_ERROR_CODE,
|
||||
MemberId,
|
||||
Money,
|
||||
PurchaseEntryId,
|
||||
@@ -867,6 +869,27 @@ export function createFinanceCommandService(
|
||||
)
|
||||
const currency = parseCurrency(currencyArg, settings.settlementCurrency)
|
||||
const amount = Money.fromMajor(amountArg, currency)
|
||||
|
||||
if (split?.mode === 'custom_amounts') {
|
||||
if (split.participants.some((p) => p.shareAmountMajor === undefined)) {
|
||||
throw new DomainError(
|
||||
DOMAIN_ERROR_CODE.INVALID_SETTLEMENT_INPUT,
|
||||
'Purchase custom split must include explicit share amounts for every participant'
|
||||
)
|
||||
}
|
||||
|
||||
const totalMinor = split.participants.reduce(
|
||||
(sum, p) => sum + Money.fromMajor(p.shareAmountMajor!, currency).amountMinor,
|
||||
0n
|
||||
)
|
||||
if (totalMinor !== amount.amountMinor) {
|
||||
throw new DomainError(
|
||||
DOMAIN_ERROR_CODE.INVALID_SETTLEMENT_INPUT,
|
||||
'Purchase custom split must add up to the full amount'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const updated = await repository.updateParsedPurchase({
|
||||
purchaseId,
|
||||
amountMinor: amount.amountMinor,
|
||||
|
||||
Reference in New Issue
Block a user