Add credit card purchase tracking, statement management, and Ledger/Balance integration #200

Merged
Copilot merged 3 commits from copilot/add-payment-section-credit-card into main 2026-04-05 20:22:35 +00:00
Copilot commented 2026-04-05 19:30:20 +00:00 (Migrated from github.com)

Description

Three gaps in the Credits system: credit cards lacked purchase/statement tracking, credits didn't appear in the Ledger accordion, and credits were missing from Balance calculations.

Credit Card Enhancements

  • Purchases: credit_card_purchases table — recording purchases auto-updates used_credit; deletion reverses it; interest-free date auto-calculated from configurable interest_free_days
  • Statements: credit_card_statements table — monthly billing cycle tracking with expected/actual payments, interest charged, overdue detection, mark-as-paid flow
  • New credit card fields on credits: credit_limit (enables utilization %), planned_monthly_payment (payoff projections), billing_cycle_day, interest_free_days
  • Payoff projection: CreditService::calculatePayoffProjection() — months to payoff, total interest, handles impossible-payoff detection

Ledger Integration

  • FinanceService now aggregates CreditCardStatement events alongside CreditPayment events
  • LedgerService processes statements into a dedicated credit_card_statements accordion section with per-card breakdown
  • LedgerApiController returns credit_card_statements data to frontend
  • All totals (cash flow, budget balance, expected/actual out) include both credit payment types

Balance Integration

  • BalanceService year/month calculations include CreditCardStatement::getTotalExpectedForDateRange / getTotalActualForDateRange
  • Unpaid statements counted in remaining/unpaid tracking
  • getDetailedMonthlyBalance() pushes credit and statement payments as individual expense line items

Frontend

  • CreditCardStatements.vue — statement history table, summary cards (balance/paid/interest/utilization), add/mark-paid dialogs
  • CreditCardPurchases.vue — purchase recording, interest-free period display, available credit
  • CreditDialog.vue — 4 new fields for credit card configuration
  • CreditTable.vue — statement and purchase action buttons
  • Ledger store extended with creditCardStatementsByMonth state

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (code change that neither fixes a bug nor adds a feature)
  • Performance improvement
  • Test coverage improvement

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have tested this manually (if applicable)

17 new tests across 4 files:

  • CreditCardStatementTest (4) — relationships, mark paid, overdue detection, date range totals
  • CreditCardPurchaseTest (3) — relationships, interest-free status, date range totals
  • CreditServiceTest (6) — statement CRUD, purchase with balance updates, payoff projection
  • CreditControllerTest (4) — statement store/mark/delete, purchase store/delete endpoints

Code Quality

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings or errors

CI/CD Checks

  • All automated tests pass
  • Code formatting (Pint) passes
  • JavaScript/TypeScript linting passes
  • Build process completes successfully

Additional Notes

3 additive migrations (post-v1.0 compatible). All existing credit tests continue to pass unchanged. CodeQL security scan clean.

## Description Three gaps in the Credits system: credit cards lacked purchase/statement tracking, credits didn't appear in the Ledger accordion, and credits were missing from Balance calculations. ### Credit Card Enhancements - **Purchases**: `credit_card_purchases` table — recording purchases auto-updates `used_credit`; deletion reverses it; interest-free date auto-calculated from configurable `interest_free_days` - **Statements**: `credit_card_statements` table — monthly billing cycle tracking with expected/actual payments, interest charged, overdue detection, mark-as-paid flow - **New credit card fields** on `credits`: `credit_limit` (enables utilization %), `planned_monthly_payment` (payoff projections), `billing_cycle_day`, `interest_free_days` - **Payoff projection**: `CreditService::calculatePayoffProjection()` — months to payoff, total interest, handles impossible-payoff detection ### Ledger Integration - `FinanceService` now aggregates `CreditCardStatement` events alongside `CreditPayment` events - `LedgerService` processes statements into a dedicated `credit_card_statements` accordion section with per-card breakdown - `LedgerApiController` returns `credit_card_statements` data to frontend - All totals (cash flow, budget balance, expected/actual out) include both credit payment types ### Balance Integration - `BalanceService` year/month calculations include `CreditCardStatement::getTotalExpectedForDateRange` / `getTotalActualForDateRange` - Unpaid statements counted in remaining/unpaid tracking - `getDetailedMonthlyBalance()` pushes credit and statement payments as individual expense line items ### Frontend - `CreditCardStatements.vue` — statement history table, summary cards (balance/paid/interest/utilization), add/mark-paid dialogs - `CreditCardPurchases.vue` — purchase recording, interest-free period display, available credit - `CreditDialog.vue` — 4 new fields for credit card configuration - `CreditTable.vue` — statement and purchase action buttons - Ledger store extended with `creditCardStatementsByMonth` state ## Type of Change - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Documentation update - [ ] Refactoring (code change that neither fixes a bug nor adds a feature) - [ ] Performance improvement - [ ] Test coverage improvement ## Testing - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] I have tested this manually (if applicable) 17 new tests across 4 files: - `CreditCardStatementTest` (4) — relationships, mark paid, overdue detection, date range totals - `CreditCardPurchaseTest` (3) — relationships, interest-free status, date range totals - `CreditServiceTest` (6) — statement CRUD, purchase with balance updates, payoff projection - `CreditControllerTest` (4) — statement store/mark/delete, purchase store/delete endpoints ## Code Quality - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] My changes generate no new warnings or errors ## CI/CD Checks - [x] All automated tests pass - [x] Code formatting (Pint) passes - [x] JavaScript/TypeScript linting passes - [x] Build process completes successfully ## Additional Notes 3 additive migrations (post-v1.0 compatible). All existing credit tests continue to pass unchanged. CodeQL security scan clean.
coderabbitai[bot] commented 2026-04-05 19:33:10 +00:00 (Migrated from github.com)

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Free

Run ID: e7d99598-7390-4ae8-99cb-4d781d0efdad

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands and usage tips.

<!-- This is an auto-generated comment: summarize by coderabbit.ai --> <!-- This is an auto-generated comment: skip review by coderabbit.ai --> > [!IMPORTANT] > ## Review skipped > > Bot user detected. > > To trigger a single review, invoke the `@coderabbitai review` command. > > <details> > <summary>⚙️ Run configuration</summary> > > **Configuration used**: defaults > > **Review profile**: CHILL > > **Plan**: Free > > **Run ID**: `e7d99598-7390-4ae8-99cb-4d781d0efdad` > > </details> > > You can disable this status message by setting the `reviews.review_status` to `false` in the CodeRabbit configuration file. > > Use the checkbox below for a quick retry: > - [ ] <!-- {"checkboxId": "e9bb8d72-00e8-4f67-9cb2-caf3b22574fe"} --> 🔍 Trigger review <!-- end of auto-generated comment: skip review by coderabbit.ai --> <!-- tips_start --> --- <sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub> <!-- tips_end -->
Sign in to join this conversation.
No description provided.