feat(loans): principal/interest split so repayments stop distorting spend
ci / lint-test (push) Successful in 41s
ci / lint-test (push) Successful in 41s
A loan repayment is not an expense. A $3,000 mortgage repayment is roughly $1,200 of principal (equity — a balance-sheet move) and $1,800 of interest (the only part that is genuinely spend). Migration 0014: - transactions.principal_amount / interest_amount, populated only when the lender itemises the split on the repayment row - statements.interest_rate, scheduled_repayment, repayment_frequency, redraw_available, loan_term_months - normalize_repayment_frequency() + trigger, so "Fortnightly", "Bi-Weekly" and "Every 2 weeks" all land on 'fortnightly' Two statement shapes are handled. Where the loan statement lists repayments and "Interest Charged" as separate rows (the common Australian case), transaction_type already does the work. Where a lender itemises the split on the repayment row, that row is typed 'payment' and would be skipped entirely — losing the interest. New SPEND_ROWS / SPEND_BASE fragments in analytics-sql.ts count such rows at interest_amount instead of amount. Adds the loan_interest category (+ colour, and the missing fees colour). Verified against the live DB with a synthetic ANZ home loan statement: a $3,000 itemised repayment plus a $10 service fee moved April spend by exactly $1,810, with the $1,200 principal excluded and still retained on the row. Test data removed and the figure confirmed back at its original value.
This commit is contained in:
@@ -151,6 +151,11 @@ model statements {
|
||||
account_holder_name String?
|
||||
exchange_rate_to_aud Decimal? @db.Decimal(10, 6)
|
||||
paperless_doc_id Int? @unique
|
||||
interest_rate Decimal? @db.Decimal(6, 3)
|
||||
scheduled_repayment Decimal? @db.Decimal(12, 2)
|
||||
repayment_frequency String?
|
||||
redraw_available Decimal? @db.Decimal(12, 2)
|
||||
loan_term_months Int?
|
||||
transactions transactions[]
|
||||
}
|
||||
|
||||
@@ -172,6 +177,8 @@ model transactions {
|
||||
amount_aud Decimal? @db.Decimal(12, 2)
|
||||
owner_id Int?
|
||||
reconciled_with_id Int?
|
||||
principal_amount Decimal? @db.Decimal(12, 2)
|
||||
interest_amount Decimal? @db.Decimal(12, 2)
|
||||
statement statements? @relation(fields: [statement_id], references: [id], onDelete: Cascade)
|
||||
reconciled_with transactions? @relation("reconciled", fields: [reconciled_with_id], references: [id], onDelete: SetNull)
|
||||
reconciled_by transactions[] @relation("reconciled")
|
||||
|
||||
Reference in New Issue
Block a user