fix: show actual transactions in budget previous year column (#34) #35

Merged
maximus merged 4 commits from fix/simpl-resultat-34-budget-previous-year-actual into main 2026-03-11 16:16:19 +00:00
Collaborator

Summary

  • The budget table's "Previous Year" column now displays actual transaction totals instead of the planned budget amounts from the previous year
  • Added getActualTotalsForYear() helper in budgetService.ts to fetch yearly transaction totals by category
  • Updated useBudget.ts to use actuals instead of budget entries for previous year data

Fixes #34

Changes

  • src/services/budgetService.ts — new getActualTotalsForYear(year) export
  • src/hooks/useBudget.ts — replaced getBudgetEntriesForYear(year-1) with getActualTotalsForYear(year-1)
  • src/shared/types/index.ts — updated comment on previousYearTotal field
  • CHANGELOG.md / CHANGELOG.fr.md — documented the change

🤖 Generated with Claude Code

## Summary - The budget table's "Previous Year" column now displays **actual transaction totals** instead of the planned budget amounts from the previous year - Added `getActualTotalsForYear()` helper in `budgetService.ts` to fetch yearly transaction totals by category - Updated `useBudget.ts` to use actuals instead of budget entries for previous year data Fixes #34 ## Changes - `src/services/budgetService.ts` — new `getActualTotalsForYear(year)` export - `src/hooks/useBudget.ts` — replaced `getBudgetEntriesForYear(year-1)` with `getActualTotalsForYear(year-1)` - `src/shared/types/index.ts` — updated comment on `previousYearTotal` field - `CHANGELOG.md` / `CHANGELOG.fr.md` — documented the change 🤖 Generated with [Claude Code](https://claude.com/claude-code)
medic-bot added 1 commit 2026-03-11 03:03:39 +00:00
Replace planned budget data with actual transaction totals for the
previous year column in the budget table. Add getActualTotalsForYear
helper to budgetService.

Ref #34

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Collaborator

Reviewer automatique — needs-fix

Bug de signe : les montants réels (transactions) des dépenses sont négatifs dans la BD, mais le budget planning grid les affiche via * sign (expense → -1). Cela cause une double négation : négatif × -1 = positif, inversant le signe affiché pour la colonne année précédente des dépenses. Aucun test ajouté.

Problèmes détectés

  • src/hooks/useBudget.ts:94 [high] Bug de signe. getActualsByCategoryRange retourne SUM(amount) brut des transactions. Les dépenses sont stockées avec des montants négatifs. Or, dans BudgetTable.tsx, previousYearTotal est multiplié par signFor(type) (-1 pour expenses) pour l'affichage. Résultat : négatif × -1 = positif → les dépenses de l'année précédente s'affichent avec le mauvais signe (positif au lieu de négatif). L'ancien code utilisait les entrées budget (toujours positives), donc positif × -1 = négatif fonctionnait correctement. Fix suggéré : stocker la valeur absolue (Math.abs(a.actual)) dans prevYearTotalMap, ou appliquer le même sign que dans getBudgetVsActualData pour normaliser les actuals en positif avant de les passer au grid.
  • src/hooks/useBudget.ts:94 [medium] Aucun test unitaire n'est ajouté pour valider que les actuals de l'année précédente sont correctement récupérés et affichés, notamment avec des dépenses (montants négatifs) et des revenus (montants positifs). Un test devrait vérifier que prevYearTotalMap contient des valeurs avec le bon signe pour les deux types de catégories.
## Reviewer automatique — needs-fix Bug de signe : les montants réels (transactions) des dépenses sont négatifs dans la BD, mais le budget planning grid les affiche via `* sign` (expense → -1). Cela cause une double négation : négatif × -1 = positif, inversant le signe affiché pour la colonne année précédente des dépenses. Aucun test ajouté. ### Problèmes détectés - **src/hooks/useBudget.ts:94** [high] Bug de signe. `getActualsByCategoryRange` retourne `SUM(amount)` brut des transactions. Les dépenses sont stockées avec des montants négatifs. Or, dans `BudgetTable.tsx`, `previousYearTotal` est multiplié par `signFor(type)` (-1 pour expenses) pour l'affichage. Résultat : négatif × -1 = positif → les dépenses de l'année précédente s'affichent avec le mauvais signe (positif au lieu de négatif). L'ancien code utilisait les entrées budget (toujours positives), donc `positif × -1 = négatif` fonctionnait correctement. Fix suggéré : stocker la valeur absolue (`Math.abs(a.actual)`) dans `prevYearTotalMap`, ou appliquer le même `sign` que dans `getBudgetVsActualData` pour normaliser les actuals en positif avant de les passer au grid. - **src/hooks/useBudget.ts:94** [medium] Aucun test unitaire n'est ajouté pour valider que les actuals de l'année précédente sont correctement récupérés et affichés, notamment avec des dépenses (montants négatifs) et des revenus (montants positifs). Un test devrait vérifier que `prevYearTotalMap` contient des valeurs avec le bon signe pour les deux types de catégories.
maximus added 2 commits 2026-03-11 12:05:40 +00:00
Fix sign bug in previous year actuals column: transaction amounts are
stored with sign in the DB (expenses negative) but budget entries are
always positive. Apply Math.abs() when building the previousYearTotal
map so the display-time sign multiplier works correctly.

Add unit tests for the normalization logic verifying that both expense
(negative in DB) and income (positive in DB) amounts are correctly
handled.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Collaborator

Reviewer automatique — needs-simplify

Le fix est correct : il remplace bien le budget planifié par les transactions réelles pour la colonne année précédente. La logique Math.abs et la nouvelle fonction de service sont saines. Cependant, le fichier de test ne teste pas le vrai code — il réimplémente la logique localement, ce qui le rend fragile et peu utile.

Suggestions de simplification

  • src/hooks/useBudget.test.ts : Le test réimplémente buildPrevYearTotalMap au lieu d'importer et tester le vrai code de useBudget.ts. Si la logique dans le hook change, ces tests passeront toujours — ils ne protègent contre aucune régression réelle. Soit extraire la fonction de normalisation dans un module utilitaire et tester celui-ci, soit supprimer ce fichier et couvrir le comportement via un test d'intégration du hook (avec mock de getActualTotalsForYear). En l'état, c'est 62 lignes qui testent essentiellement Math.abs().
## Reviewer automatique — needs-simplify Le fix est correct : il remplace bien le budget planifié par les transactions réelles pour la colonne année précédente. La logique Math.abs et la nouvelle fonction de service sont saines. Cependant, le fichier de test ne teste pas le vrai code — il réimplémente la logique localement, ce qui le rend fragile et peu utile. ### Suggestions de simplification - **src/hooks/useBudget.test.ts** : Le test réimplémente `buildPrevYearTotalMap` au lieu d'importer et tester le vrai code de `useBudget.ts`. Si la logique dans le hook change, ces tests passeront toujours — ils ne protègent contre aucune régression réelle. Soit extraire la fonction de normalisation dans un module utilitaire et tester celui-ci, soit supprimer ce fichier et couvrir le comportement via un test d'intégration du hook (avec mock de `getActualTotalsForYear`). En l'état, c'est 62 lignes qui testent essentiellement `Math.abs()`.
maximus added 1 commit 2026-03-11 16:03:03 +00:00
Transaction amounts are already signed in the DB (expenses negative,
income positive). Remove Math.abs() normalization and stop multiplying
by sign at display time to avoid double negation.

Extract buildPrevYearTotalMap as a testable exported function and
rewrite tests to import the real function instead of reimplementing it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Collaborator

Reviewer automatique — approved

Le fix est correct. Il remplace les entrées budget de l'année précédente par les transactions réelles (actuals), conformément à l'issue #34. La suppression de * sign est justifiée car les montants de transactions sont déjà signés en DB (dépenses négatives, revenus positifs), ce qui est cohérent avec le pattern existant dans getBudgetVsActualData() de budgetService.ts. Les CHANGELOGs, types et tests sont à jour.

Suggestions de simplification

  • src/hooks/useBudget.test.ts : buildPrevYearTotalMap est une fonction triviale (3 lignes de logique). Les 50 lignes de tests pour une boucle avec un filtre null sont disproportionnées. Un seul test couvrant le cas multi-catégories avec un null suffirait à valider le contrat. Pas bloquant, mais à considérer.
  • src/hooks/useBudget.ts : buildPrevYearTotalMap est exportée uniquement pour le testing. Vu sa simplicité (3 lignes), elle pourrait rester inline dans useBudget() et être testée indirectement via un test d'intégration du hook. Mais l'approche actuelle est acceptable.
## Reviewer automatique — approved Le fix est correct. Il remplace les entrées budget de l'année précédente par les transactions réelles (actuals), conformément à l'issue #34. La suppression de `* sign` est justifiée car les montants de transactions sont déjà signés en DB (dépenses négatives, revenus positifs), ce qui est cohérent avec le pattern existant dans `getBudgetVsActualData()` de budgetService.ts. Les CHANGELOGs, types et tests sont à jour. ### Suggestions de simplification - **src/hooks/useBudget.test.ts** : buildPrevYearTotalMap est une fonction triviale (3 lignes de logique). Les 50 lignes de tests pour une boucle avec un filtre null sont disproportionnées. Un seul test couvrant le cas multi-catégories avec un null suffirait à valider le contrat. Pas bloquant, mais à considérer. - **src/hooks/useBudget.ts** : buildPrevYearTotalMap est exportée uniquement pour le testing. Vu sa simplicité (3 lignes), elle pourrait rester inline dans useBudget() et être testée indirectement via un test d'intégration du hook. Mais l'approche actuelle est acceptable.
maximus merged commit ecbcf44f86 into main 2026-03-11 16:16:19 +00:00
maximus deleted branch fix/simpl-resultat-34-budget-previous-year-actual 2026-03-11 16:16:20 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#35
No description provided.