fix(reports): net transfer-type categories in real-vs-real compare (#243) #248
No reviewers
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/Simpl-Resultat#248
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-243-netting-transferts"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Real-vs-real Compare summed only outflows (SUM(ABS(amount)) filtered on amount < 0), so a
transfercategory like "Paiement CC" always showed the sum of its debits instead of netting to ~0. This netstransfer-type categories via a signed SUM(t.amount) while keeping the expense behavior (ABS + amount < 0) for every other type, and broadens the WHERE so transfer credits survive the expense filter. Both MoM and YoY share one COMPARE_DELTA_SQL constant; real-vs-budget already nets and is unchanged.Resolves #243
Generated autonomously by /autopilot run of 2026-07-04
Revue /pr-review — PR #248 (issue #243)
Verdict : APPROVE
Résumé
Le correctif implémente correctement l'intention : les catégories de type
transfers'annulent via unSUM(t.amount)signé, pendant que le comportement des autres types reste strictement identique (WHEREamount < 0+ABS). Changelog bilingue, tests et lien d'issue présents. Quelques finitions non-bloquantes subsistent pour le cas rare d'un transfert déséquilibré sur la période.Points validés
Correctness du SQL
transfer: le WHERE restet.amount < 0et la somme resteABS(t.amount)→ totaux bit-à-bit identiques à l'ancien comportement. Vérifié.transfer: WHERE élargi (OR COALESCE(c.type,'expense')='transfer') pour que les crédits survivent au filtre de dépense, puisSUM(t.amount)signé → une paire débit/crédit équilibrée s'annule à ~0. Correct.c.typeNULL via LEFT JOIN) →COALESCE= 'expense' → comportement ABS. Correct.rowsToDeltasrenvoiedeltaPct = nullquandprevious === 0(transfert netté) → rendu « — », pas de NaN/Infinity.$1..$8), aucune injection.Refactor
COMPARE_DELTA_SQLest sûre et supprime la duplication. L'ordre des paramètres est préservé dans les deux appels.Schéma & données
categories.typeexiste (NOT NULL DEFAULT 'expense', valeursexpense/income/transfer) ;transferest posé via l'UI (CategoryForm) et le seed (id 71 « Paiement CC »). Aucune migration touchée.Claim « real-vs-budget nète déjà »
getActualsByCategoryRange(budgetService) utilise déjàSUM(amount)signé sansABSni filtre de signe → les transferts s'y annulent nativement. Fichier non modifié.Process
[Unreleased]dans les deux langues. Aucune chaîne UI ajoutée → pas de sujet i18n.type:bug: les assertions structurelles échoueraient sur l'ancien SQL (absence duCASEtransfert) → garde de régression effective au niveau chaîne, acceptable vu l'absence de SQLite runnable en tests unitaires.Suggestions (non-bloquantes)
Toutes concernent l'arrivée de valeurs signées/négatives de transfert dans du code de rendu conçu pour des magnitudes positives. Le cas courant — transfert équilibré sur la même période (ex. « Paiement CC » avec les deux comptes importés) — nète à ~0 et s'affiche proprement ; ces points ne touchent que le transfert déséquilibré / à une seule jambe.
ComparePeriodTable(l.66-76) — le total additionnecurrentAmount/deltaAbssur toutes les lignes, mélangeant désormais des magnitudes de dépense positives et des nets de transfert signés. Équilibré → contribue ~0 (améliore même le total, qui n'est plus gonflé par les débits de transfert) ; déséquilibré → décale le total du montant net. Envisager d'exclure les lignestransferdu total, ou de les présenter à part.ComparePeriodChart+variationColor— convention « dépense » (positif = rouge/mauvais, barres vers la droite). Un net de transfert négatif dessine une barre vers la gauche avec le rayon d'angle du mauvais côté, et un delta de transfert positif est peint en rouge. Cosmétique.rowsToDeltasdeltaPct (l.400) — divise par lepreviousAmountsigné (pasMath.abs). Un transfert dont la période précédente nète négatif produit un signe de % inversé vsdeltaAbs(ligne verte affichant+50 %). Le chemin des totaux utilise déjàMath.abs(previous)(l.78) — aligner le calcul par ligne.getCartesSnapshotsignificantMovers (l.952-954) — le filtrepreviousAmount > 0 || currentAmount > 0écarte maintenant du top-movers Cartes les transferts qui nètent négatif sur les deux périodes. Probablement souhaitable (un transfert n'est pas un mouvement de dépense), simple note de changement de comportement.COMPARE_DELTA_SQL), plus une fonction de sémantique de référence ; ils n'exécutent pas le SQL. Compromis raisonnable vu la contrainte « pas de SQLite dans les tests unitaires », à garder en tête.Revue adversariale générée par
/pr-review. Cas heureux (transfert équilibré) correct et amélioré ; suggestions = polissage de suivi pour les valeurs signées, non-bloquant.Merged into
mainlocally as part of the milestone stack (merge commita6fa89e). Closing manually — the merge was done outside Forgejo's API, so it can't flag this PR as merged. The change is onmain.Pull request closed