whisper-money/app
Víctor Falcón 9e2a9cadfe
fix(cashflow): only count sign-matching transactions in Sankey category breakdown (#232)
## Problem

When an income category contained both incoming and outgoing
transactions (e.g. an \"Income from Rents\" category that also holds
property-related expense payments), the Sankey endpoint was summing
**all** amounts together and applying `abs()` to the net result.

Real example reported:

| Date | Description | Amount |
|------|-------------|--------|
| Mar 13 | BIZUM sent — Lavadora | -€124.03 |
| Mar 10 | BIZUM received — luz febrero | +€38.04 |
| Mar 9 | Endesa energy payment | -€38.04 |
| Mar 4 | BIZUM received — agua Febrero | +€41.34 |
| Mar 2 | Comunidad de Propietarios | -€105.92 |

- Net: **-€188.61** → `abs()` → **€188.61 shown as income** 
- Correct: sum of positive flows only → **€79.38** 

## Fix

Added a sign filter to `getCategoryBreakdown()` before the `GROUP BY`
aggregation:
- Income categories: `WHERE transactions.amount > 0`
- Expense categories: `WHERE transactions.amount < 0`

This ensures the Sankey shows the **actual gross flow** on each side
rather than a misleading abs-of-net.

## Test

Added a regression test in `CashflowAnalyticsTest` that reproduces the
exact five transactions from the reported scenario and asserts the
Sankey returns `7938` cents (€79.38) instead of the buggy `18861`
(€188.61).
2026-03-17 09:29:36 +00:00
..
Actions feat(categories): add Self-Employment Income income category (#164) 2026-02-28 18:04:21 +00:00
Console/Commands fix(banking): correct backfill-ibans endpoint and handle expired sessions gracefully (#222) 2026-03-12 11:57:54 +00:00
Contracts feat(banking): add banking:backfill-ibans command to populate missing IBANs (#221) 2026-03-12 10:58:55 +00:00
Enums Add chart color scheme setting (#101) 2026-02-28 12:58:21 +01:00
Events Add Budgeting Feature to Track and Manage Spending (#36) 2026-01-21 15:25:50 +01:00
Http fix(cashflow): only count sign-matching transactions in Sankey category breakdown (#232) 2026-03-17 09:29:36 +00:00
Jobs fix(banking): treat 429 rate limit as transient, skip error status on sync (#224) 2026-03-16 10:59:46 +00:00
Listeners feat(emails): co-founder language, welcome rewrite, and Spanish translations (#208) 2026-03-05 15:22:07 +01:00
Mail Add weekly bank logo audit command (#211) 2026-03-06 11:05:13 +00:00
Models fix(banking): update external_account_id on reconnect and store IBAN (#220) 2026-03-12 10:28:23 +00:00
Notifications feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
Policies Add Budgeting Feature to Track and Manage Spending (#36) 2026-01-21 15:25:50 +01:00
Providers fix(static-analysis): clear phpstan-baseline by fixing all suppressed errors (#183) 2026-03-02 12:22:30 +00:00
Services fix(banking): correct backfill-ibans endpoint and handle expired sessions gracefully (#222) 2026-03-12 11:57:54 +00:00