fix(25-4-c2): un règlement partiel marque la facture, et l'acceptation rejoue un interblocage (closes #480) - #485
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… l'orchestrateur (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… arbitrages en attente (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… en partie (refs #420) Le filtre des candidates, le score, le re-score à l'acceptation et le montant affiché portent sur le reste dû (TTC − avoir − règlements), par la forme jointe ; le TTC ne suit qu'en mention quand les deux diffèrent. Manuel et brochure réécrits sur le score réel ; #481 ouverte pour le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ues, Playwright départagé (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le rejeu sur interblocage (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n rejoue un interblocage (refs #480) Le règlement manuel incrémente invoices.version à chaque règlement, partiel compris : le verrou optimiste de l'acceptation refuse désormais celle qui arrive après un règlement concurrent. Un interblocage absorbé dans une proposition (ROLLBACK TO SAVEPOINT en 1305) remonte en TransactionAborted et la route rejoue le lot par retry_with. Trois tests de course sans sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…INT, verrou de test détaché (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…(refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
guycorbaz
added a commit
that referenced
this pull request
Sep 30, 2026
…s paramètres (refs #476) (#487) * docs(25-4-c): story créée — le résiduel au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): arbitrages Q1–Q3 retenus par défaut, rebase sur la b2 (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P1 — 3 HIGH, 2 MED, 1 LOW remédiés (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P2 — 0 finding sans preuve, 2 MED repris par l'orchestrateur (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): références de lignes du verrou recontrôlées (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P3 consignée — 1 CRIT / 3 HIGH, découpage et arbitrages en attente (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): découpée — verrou en 25-4-c2 (#480), arrondi en 25-4-c3 (#476) ; périmètre réduit au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P4 — 1 MED, 1 LOW remédiés (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P5 ciblée — close, 0 > LOW (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): le rapprochement reconnaît le solde d'une facture réglée en partie (refs #420) Le filtre des candidates, le score, le re-score à l'acceptation et le montant affiché portent sur le reste dû (TTC − avoir − règlements), par la forme jointe ; le TTC ne suit qu'en mention quand les deux diffèrent. Manuel et brochure réécrits sur le score réel ; #481 ouverte pour le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): revue de code P1 — CHANGELOG replacé, traductions univoques, Playwright départagé (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): revue de code P2 — close, 0 > LOW ; story done (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): story créée — l'invariant de version au règlement, et le rejeu sur interblocage (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P1 — 1 HIGH, 2 MED, 2 LOW remédiés (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P2 — close, 0 > LOW (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): un règlement partiel marque la facture, et l'acceptation rejoue un interblocage (refs #480) Le règlement manuel incrémente invoices.version à chaque règlement, partiel compris : le verrou optimiste de l'acceptation refuse désormais celle qui arrive après un règlement concurrent. Un interblocage absorbé dans une proposition (ROLLBACK TO SAVEPOINT en 1305) remonte en TransactionAborted et la route rejoue le lot par retry_with. Trois tests de course sans sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): revue de code P1 — gardes rows_affected, RELEASE SAVEPOINT, verrou de test détaché (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(25-4-c3): arbitrage de Guy — l'écart d'arrondi passe en écriture ; PR #485 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3): découpée en a1 / a2 / b ; story c3-a1 créée — le réglage du compte d'arrondi (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P1 — 2 MED remédiés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P2 ciblée — close, 0 > LOW (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a1): désigner le compte de différences d'arrondi dans les paramètres (refs #476) Nouvelle colonne company_invoice_settings.default_rounding_account_id (DDL seul, non breaking), validée charge ou produit, actif, imputable ; absente d'un PUT elle est préservée, à null effacée. Section Différences d'arrondi dans Paramètres > Facturation ; export ; import d'une sauvegarde antérieure prouvé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a1): revue de code P1 — compte d'arrondi validé seulement s'il change, Playwright nettoyé en finally (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
guycorbaz
added a commit
that referenced
this pull request
Oct 1, 2026
… livrés, désigné d'office (refs #476) (#489) * docs(25-4-c): story créée — le résiduel au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): arbitrages Q1–Q3 retenus par défaut, rebase sur la b2 (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P1 — 3 HIGH, 2 MED, 1 LOW remédiés (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P2 — 0 finding sans preuve, 2 MED repris par l'orchestrateur (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): références de lignes du verrou recontrôlées (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P3 consignée — 1 CRIT / 3 HIGH, découpage et arbitrages en attente (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): découpée — verrou en 25-4-c2 (#480), arrondi en 25-4-c3 (#476) ; périmètre réduit au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P4 — 1 MED, 1 LOW remédiés (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P5 ciblée — close, 0 > LOW (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): le rapprochement reconnaît le solde d'une facture réglée en partie (refs #420) Le filtre des candidates, le score, le re-score à l'acceptation et le montant affiché portent sur le reste dû (TTC − avoir − règlements), par la forme jointe ; le TTC ne suit qu'en mention quand les deux diffèrent. Manuel et brochure réécrits sur le score réel ; #481 ouverte pour le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): revue de code P1 — CHANGELOG replacé, traductions univoques, Playwright départagé (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): revue de code P2 — close, 0 > LOW ; story done (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): story créée — l'invariant de version au règlement, et le rejeu sur interblocage (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P1 — 1 HIGH, 2 MED, 2 LOW remédiés (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P2 — close, 0 > LOW (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): un règlement partiel marque la facture, et l'acceptation rejoue un interblocage (refs #480) Le règlement manuel incrémente invoices.version à chaque règlement, partiel compris : le verrou optimiste de l'acceptation refuse désormais celle qui arrive après un règlement concurrent. Un interblocage absorbé dans une proposition (ROLLBACK TO SAVEPOINT en 1305) remonte en TransactionAborted et la route rejoue le lot par retry_with. Trois tests de course sans sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): revue de code P1 — gardes rows_affected, RELEASE SAVEPOINT, verrou de test détaché (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(25-4-c3): arbitrage de Guy — l'écart d'arrondi passe en écriture ; PR #485 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3): découpée en a1 / a2 / b ; story c3-a1 créée — le réglage du compte d'arrondi (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P1 — 2 MED remédiés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P2 ciblée — close, 0 > LOW (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a1): désigner le compte de différences d'arrondi dans les paramètres (refs #476) Nouvelle colonne company_invoice_settings.default_rounding_account_id (DDL seul, non breaking), validée charge ou produit, actif, imputable ; absente d'un PUT elle est préservée, à null effacée. Section Différences d'arrondi dans Paramètres > Facturation ; export ; import d'une sauvegarde antérieure prouvé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a1): revue de code P1 — compte d'arrondi validé seulement s'il change, Playwright nettoyé en finally (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): story créée — le compte de différences d'arrondi dans les plans livrés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P1 — 3 MED, 2 LOW remédiés ; #488 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P2 ciblée — close, 0 > LOW ; dev démarré (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a2): le compte 6940 Différences d'arrondi dans les plans livrés, désigné d'office (refs #476) Marqueur de plan roundingDifference (pas de rôle, pas de numéro dans le code), validé au chargement ; les deux insert_with_defaults* désignent le compte marqué du plan de la société (FOR UPDATE), NULL sans erreur s'il manque. Rien chez les sociétés existantes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a2): revue de code P1 — marqueur sans rôle, erreur de plan tracée, types liés par l'enum (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): revue de code P2 ciblée — close, 0 finding ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
guycorbaz
added a commit
that referenced
this pull request
Oct 5, 2026
…gne (closes #476) (#493) * docs(25-4-c): story créée — le résiduel au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): arbitrages Q1–Q3 retenus par défaut, rebase sur la b2 (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P1 — 3 HIGH, 2 MED, 1 LOW remédiés (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P2 — 0 finding sans preuve, 2 MED repris par l'orchestrateur (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): références de lignes du verrou recontrôlées (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P3 consignée — 1 CRIT / 3 HIGH, découpage et arbitrages en attente (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): découpée — verrou en 25-4-c2 (#480), arrondi en 25-4-c3 (#476) ; périmètre réduit au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P4 — 1 MED, 1 LOW remédiés (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P5 ciblée — close, 0 > LOW (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): le rapprochement reconnaît le solde d'une facture réglée en partie (refs #420) Le filtre des candidates, le score, le re-score à l'acceptation et le montant affiché portent sur le reste dû (TTC − avoir − règlements), par la forme jointe ; le TTC ne suit qu'en mention quand les deux diffèrent. Manuel et brochure réécrits sur le score réel ; #481 ouverte pour le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): revue de code P1 — CHANGELOG replacé, traductions univoques, Playwright départagé (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): revue de code P2 — close, 0 > LOW ; story done (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): story créée — l'invariant de version au règlement, et le rejeu sur interblocage (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P1 — 1 HIGH, 2 MED, 2 LOW remédiés (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P2 — close, 0 > LOW (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): un règlement partiel marque la facture, et l'acceptation rejoue un interblocage (refs #480) Le règlement manuel incrémente invoices.version à chaque règlement, partiel compris : le verrou optimiste de l'acceptation refuse désormais celle qui arrive après un règlement concurrent. Un interblocage absorbé dans une proposition (ROLLBACK TO SAVEPOINT en 1305) remonte en TransactionAborted et la route rejoue le lot par retry_with. Trois tests de course sans sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): revue de code P1 — gardes rows_affected, RELEASE SAVEPOINT, verrou de test détaché (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(25-4-c3): arbitrage de Guy — l'écart d'arrondi passe en écriture ; PR #485 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3): découpée en a1 / a2 / b ; story c3-a1 créée — le réglage du compte d'arrondi (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P1 — 2 MED remédiés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P2 ciblée — close, 0 > LOW (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a1): désigner le compte de différences d'arrondi dans les paramètres (refs #476) Nouvelle colonne company_invoice_settings.default_rounding_account_id (DDL seul, non breaking), validée charge ou produit, actif, imputable ; absente d'un PUT elle est préservée, à null effacée. Section Différences d'arrondi dans Paramètres > Facturation ; export ; import d'une sauvegarde antérieure prouvé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a1): revue de code P1 — compte d'arrondi validé seulement s'il change, Playwright nettoyé en finally (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): story créée — le compte de différences d'arrondi dans les plans livrés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P1 — 3 MED, 2 LOW remédiés ; #488 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P2 ciblée — close, 0 > LOW ; dev démarré (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a2): le compte 6940 Différences d'arrondi dans les plans livrés, désigné d'office (refs #476) Marqueur de plan roundingDifference (pas de rôle, pas de numéro dans le code), validé au chargement ; les deux insert_with_defaults* désignent le compte marqué du plan de la société (FOR UPDATE), NULL sans erreur s'il manque. Rien chez les sociétés existantes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a2): revue de code P1 — marqueur sans rôle, erreur de plan tracée, types liés par l'enum (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): revue de code P2 ciblée — close, 0 finding ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): story créée — l'arrondi au centime et l'écart en écriture (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P1 — double borne brut/arrondi, échelle du règlement manuel, sites triés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P2 — échelle normalisée, contrôle client des décimales, reste sous le demi-centime tracé (#490) (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P3 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P3 ciblée — montant reçu tel quel, décimales sur la forme big.js, test d'échelle discriminant, #490 reformulée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P4 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P4 ciblée — 0 finding, boucle close (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-b): solder au centime, l'écart d'arrondi en troisième ligne (refs #476) Le reste dû peut porter quatre décimales (10.0050) ; QR, rappels et dialogue réclament 10.01, que le rapprochement ne proposait pas et que le règlement manuel refusait en trop-perçu. Toute comparaison se fait au centime (amount_due_to_centime) ; un paiement égal au reste arrondi solde la facture, réglée au reste brut, l'écart passant sur le compte de différences d'arrondi (double borne : entre brut et arrondi, trop-perçu). Sans compte utilisable, refus dédié ROUNDING_ACCOUNT_NOT_CONFIGURED, rien d'écrit. Règlement manuel à plus de deux décimales refusé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P1 (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-b): revue de code P1 — invariant tracé au rapprochement, compte d'arrondi produit testé (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P2 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): revue de code P2 ciblée — close, aucune correction de production ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
guycorbaz
added a commit
that referenced
this pull request
Oct 5, 2026
…loses #494) (#507) * docs(25-4-c): story créée — le résiduel au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): arbitrages Q1–Q3 retenus par défaut, rebase sur la b2 (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P1 — 3 HIGH, 2 MED, 1 LOW remédiés (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P2 — 0 finding sans preuve, 2 MED repris par l'orchestrateur (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): références de lignes du verrou recontrôlées (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P3 consignée — 1 CRIT / 3 HIGH, découpage et arbitrages en attente (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): découpée — verrou en 25-4-c2 (#480), arrondi en 25-4-c3 (#476) ; périmètre réduit au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P4 — 1 MED, 1 LOW remédiés (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P5 ciblée — close, 0 > LOW (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): le rapprochement reconnaît le solde d'une facture réglée en partie (refs #420) Le filtre des candidates, le score, le re-score à l'acceptation et le montant affiché portent sur le reste dû (TTC − avoir − règlements), par la forme jointe ; le TTC ne suit qu'en mention quand les deux diffèrent. Manuel et brochure réécrits sur le score réel ; #481 ouverte pour le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): revue de code P1 — CHANGELOG replacé, traductions univoques, Playwright départagé (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): revue de code P2 — close, 0 > LOW ; story done (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): story créée — l'invariant de version au règlement, et le rejeu sur interblocage (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P1 — 1 HIGH, 2 MED, 2 LOW remédiés (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P2 — close, 0 > LOW (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): un règlement partiel marque la facture, et l'acceptation rejoue un interblocage (refs #480) Le règlement manuel incrémente invoices.version à chaque règlement, partiel compris : le verrou optimiste de l'acceptation refuse désormais celle qui arrive après un règlement concurrent. Un interblocage absorbé dans une proposition (ROLLBACK TO SAVEPOINT en 1305) remonte en TransactionAborted et la route rejoue le lot par retry_with. Trois tests de course sans sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): revue de code P1 — gardes rows_affected, RELEASE SAVEPOINT, verrou de test détaché (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(25-4-c3): arbitrage de Guy — l'écart d'arrondi passe en écriture ; PR #485 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3): découpée en a1 / a2 / b ; story c3-a1 créée — le réglage du compte d'arrondi (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P1 — 2 MED remédiés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P2 ciblée — close, 0 > LOW (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a1): désigner le compte de différences d'arrondi dans les paramètres (refs #476) Nouvelle colonne company_invoice_settings.default_rounding_account_id (DDL seul, non breaking), validée charge ou produit, actif, imputable ; absente d'un PUT elle est préservée, à null effacée. Section Différences d'arrondi dans Paramètres > Facturation ; export ; import d'une sauvegarde antérieure prouvé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a1): revue de code P1 — compte d'arrondi validé seulement s'il change, Playwright nettoyé en finally (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): story créée — le compte de différences d'arrondi dans les plans livrés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P1 — 3 MED, 2 LOW remédiés ; #488 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P2 ciblée — close, 0 > LOW ; dev démarré (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a2): le compte 6940 Différences d'arrondi dans les plans livrés, désigné d'office (refs #476) Marqueur de plan roundingDifference (pas de rôle, pas de numéro dans le code), validé au chargement ; les deux insert_with_defaults* désignent le compte marqué du plan de la société (FOR UPDATE), NULL sans erreur s'il manque. Rien chez les sociétés existantes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a2): revue de code P1 — marqueur sans rôle, erreur de plan tracée, types liés par l'enum (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): revue de code P2 ciblée — close, 0 finding ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): story créée — l'arrondi au centime et l'écart en écriture (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P1 — double borne brut/arrondi, échelle du règlement manuel, sites triés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P2 — échelle normalisée, contrôle client des décimales, reste sous le demi-centime tracé (#490) (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P3 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P3 ciblée — montant reçu tel quel, décimales sur la forme big.js, test d'échelle discriminant, #490 reformulée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P4 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P4 ciblée — 0 finding, boucle close (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-b): solder au centime, l'écart d'arrondi en troisième ligne (refs #476) Le reste dû peut porter quatre décimales (10.0050) ; QR, rappels et dialogue réclament 10.01, que le rapprochement ne proposait pas et que le règlement manuel refusait en trop-perçu. Toute comparaison se fait au centime (amount_due_to_centime) ; un paiement égal au reste arrondi solde la facture, réglée au reste brut, l'écart passant sur le compte de différences d'arrondi (double borne : entre brut et arrondi, trop-perçu). Sans compte utilisable, refus dédié ROUNDING_ACCOUNT_NOT_CONFIGURED, rien d'écrit. Règlement manuel à plus de deux décimales refusé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P1 (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-b): revue de code P1 — invariant tracé au rapprochement, compte d'arrondi produit testé (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P2 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): revue de code P2 ciblée — close, aucune correction de production ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): story créée — l'arrondi à 5 centimes figé à la validation (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P1 — refus contextualisé, ordre des refus, références corrigées (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P2 — sites de la variante et emplacement du refus écrits (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P3 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P3 ciblée — l'avoir à arrondi nul n'exige aucun compte (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P4 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P4 ciblée — 0 finding, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-a): arrondir à 5 centimes le total des pièces émises, figé à la validation (refs #494) Le total TTC d'une facture validée est arrondi au multiple de 0.05 (123.44 → 123.45, 234.52 → 234.50) ; l'écart, sans TVA, est figé sur la facture (invoices.rounding_amount) et écrit en dernière ligne de l'écriture de vente sur le compte de différences d'arrondi. Toutes les formes du TTC l'intègrent (reste dû, listes, rapprochement, QR, PDF, e-mail). L'avoir le recopie et l'annule en miroir. Réglage par société, actif par défaut. Refus à contexte : le message d'émission ne parle plus de paiement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-a): revue de code P1 — forme jointe du crédit symétrique, manuel admin rectifié, avoir et sauvegarde testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): revue de code P2 ciblée — 0 finding, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): story créée — l'arrondi à 5 centimes, visible et réglable (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P1 — aperçu sur toute réponse brouillon, récapitulatif traduit, doc-comment rectifié (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P2 — type résolu clarifié, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-b): l'arrondi à 5 centimes visible et réglable (refs #494) Ligne « Arrondi » signée au PDF de la facture, de l'avoir et du rappel, et sur la fiche (aperçu « estimé » pour un brouillon, calculé par le serveur et porté par toute réponse qui rend un brouillon, dévalidation comprise). Le réglage roundTo5Centimes est exposé (GET/PUT, préservé s'il est absent) et se règle dans Paramètres → Facturation ; les factures émises gardent leur total. Récapitulatif de la fiche traduit, manuels et CHANGELOG à jour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-b): revue de code P1 — réglage lu sans écriture, arrondi décidé au centime, manuel rectifié, avoir et rappel testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): revue de code P2 ciblée — 0 réel, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4): fixture du test de la fiche (25-6-b) complétée de l'arrondi (refs #494) La fusion de main apporte invoice-pdf-page.test.ts, dont la fixture InvoiceResponse ignorait roundingAmount / roundingIsPreview ajoutés par la c4 : npm run check rougissait (1 erreur), tests et build passaient. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
guycorbaz
added a commit
that referenced
this pull request
Oct 5, 2026
…ise (closes #495) (#508) * docs(25-4-c): story créée — le résiduel au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): arbitrages Q1–Q3 retenus par défaut, rebase sur la b2 (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P1 — 3 HIGH, 2 MED, 1 LOW remédiés (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P2 — 0 finding sans preuve, 2 MED repris par l'orchestrateur (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): références de lignes du verrou recontrôlées (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P3 consignée — 1 CRIT / 3 HIGH, découpage et arbitrages en attente (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): découpée — verrou en 25-4-c2 (#480), arrondi en 25-4-c3 (#476) ; périmètre réduit au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P4 — 1 MED, 1 LOW remédiés (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P5 ciblée — close, 0 > LOW (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): le rapprochement reconnaît le solde d'une facture réglée en partie (refs #420) Le filtre des candidates, le score, le re-score à l'acceptation et le montant affiché portent sur le reste dû (TTC − avoir − règlements), par la forme jointe ; le TTC ne suit qu'en mention quand les deux diffèrent. Manuel et brochure réécrits sur le score réel ; #481 ouverte pour le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): revue de code P1 — CHANGELOG replacé, traductions univoques, Playwright départagé (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): revue de code P2 — close, 0 > LOW ; story done (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): story créée — l'invariant de version au règlement, et le rejeu sur interblocage (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P1 — 1 HIGH, 2 MED, 2 LOW remédiés (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P2 — close, 0 > LOW (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): un règlement partiel marque la facture, et l'acceptation rejoue un interblocage (refs #480) Le règlement manuel incrémente invoices.version à chaque règlement, partiel compris : le verrou optimiste de l'acceptation refuse désormais celle qui arrive après un règlement concurrent. Un interblocage absorbé dans une proposition (ROLLBACK TO SAVEPOINT en 1305) remonte en TransactionAborted et la route rejoue le lot par retry_with. Trois tests de course sans sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): revue de code P1 — gardes rows_affected, RELEASE SAVEPOINT, verrou de test détaché (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(25-4-c3): arbitrage de Guy — l'écart d'arrondi passe en écriture ; PR #485 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3): découpée en a1 / a2 / b ; story c3-a1 créée — le réglage du compte d'arrondi (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P1 — 2 MED remédiés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P2 ciblée — close, 0 > LOW (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a1): désigner le compte de différences d'arrondi dans les paramètres (refs #476) Nouvelle colonne company_invoice_settings.default_rounding_account_id (DDL seul, non breaking), validée charge ou produit, actif, imputable ; absente d'un PUT elle est préservée, à null effacée. Section Différences d'arrondi dans Paramètres > Facturation ; export ; import d'une sauvegarde antérieure prouvé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a1): revue de code P1 — compte d'arrondi validé seulement s'il change, Playwright nettoyé en finally (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): story créée — le compte de différences d'arrondi dans les plans livrés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P1 — 3 MED, 2 LOW remédiés ; #488 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P2 ciblée — close, 0 > LOW ; dev démarré (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a2): le compte 6940 Différences d'arrondi dans les plans livrés, désigné d'office (refs #476) Marqueur de plan roundingDifference (pas de rôle, pas de numéro dans le code), validé au chargement ; les deux insert_with_defaults* désignent le compte marqué du plan de la société (FOR UPDATE), NULL sans erreur s'il manque. Rien chez les sociétés existantes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a2): revue de code P1 — marqueur sans rôle, erreur de plan tracée, types liés par l'enum (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): revue de code P2 ciblée — close, 0 finding ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): story créée — l'arrondi au centime et l'écart en écriture (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P1 — double borne brut/arrondi, échelle du règlement manuel, sites triés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P2 — échelle normalisée, contrôle client des décimales, reste sous le demi-centime tracé (#490) (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P3 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P3 ciblée — montant reçu tel quel, décimales sur la forme big.js, test d'échelle discriminant, #490 reformulée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P4 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P4 ciblée — 0 finding, boucle close (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-b): solder au centime, l'écart d'arrondi en troisième ligne (refs #476) Le reste dû peut porter quatre décimales (10.0050) ; QR, rappels et dialogue réclament 10.01, que le rapprochement ne proposait pas et que le règlement manuel refusait en trop-perçu. Toute comparaison se fait au centime (amount_due_to_centime) ; un paiement égal au reste arrondi solde la facture, réglée au reste brut, l'écart passant sur le compte de différences d'arrondi (double borne : entre brut et arrondi, trop-perçu). Sans compte utilisable, refus dédié ROUNDING_ACCOUNT_NOT_CONFIGURED, rien d'écrit. Règlement manuel à plus de deux décimales refusé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P1 (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-b): revue de code P1 — invariant tracé au rapprochement, compte d'arrondi produit testé (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P2 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): revue de code P2 ciblée — close, aucune correction de production ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): story créée — l'arrondi à 5 centimes figé à la validation (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P1 — refus contextualisé, ordre des refus, références corrigées (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P2 — sites de la variante et emplacement du refus écrits (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P3 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P3 ciblée — l'avoir à arrondi nul n'exige aucun compte (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P4 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P4 ciblée — 0 finding, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-a): arrondir à 5 centimes le total des pièces émises, figé à la validation (refs #494) Le total TTC d'une facture validée est arrondi au multiple de 0.05 (123.44 → 123.45, 234.52 → 234.50) ; l'écart, sans TVA, est figé sur la facture (invoices.rounding_amount) et écrit en dernière ligne de l'écriture de vente sur le compte de différences d'arrondi. Toutes les formes du TTC l'intègrent (reste dû, listes, rapprochement, QR, PDF, e-mail). L'avoir le recopie et l'annule en miroir. Réglage par société, actif par défaut. Refus à contexte : le message d'émission ne parle plus de paiement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-a): revue de code P1 — forme jointe du crédit symétrique, manuel admin rectifié, avoir et sauvegarde testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): revue de code P2 ciblée — 0 finding, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): story créée — l'arrondi à 5 centimes, visible et réglable (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P1 — aperçu sur toute réponse brouillon, récapitulatif traduit, doc-comment rectifié (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P2 — type résolu clarifié, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-b): l'arrondi à 5 centimes visible et réglable (refs #494) Ligne « Arrondi » signée au PDF de la facture, de l'avoir et du rappel, et sur la fiche (aperçu « estimé » pour un brouillon, calculé par le serveur et porté par toute réponse qui rend un brouillon, dévalidation comprise). Le réglage roundTo5Centimes est exposé (GET/PUT, préservé s'il est absent) et se règle dans Paramètres → Facturation ; les factures émises gardent leur total. Récapitulatif de la fiche traduit, manuels et CHANGELOG à jour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-b): revue de code P1 — réglage lu sans écriture, arrondi décidé au centime, manuel rectifié, avoir et rappel testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): revue de code P2 ciblée — 0 réel, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): story créée — un montant minimum configurable sous lequel une facture n'est pas émise (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): validation P1 — sites qui énumèrent les colonnes nommés ; prompt P2 (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): validation P2 ciblée — sites hors dépôt explicités, boucle close (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-e): un montant minimum configurable sous lequel une facture n'est pas émise (refs #495) Réglage company_invoice_settings.minimum_invoice_amount (NULL = aucun seuil, le défaut) ; la validation refuse une facture dont le total arrondi est inférieur (INVOICE_BELOW_MINIMUM, message à deux montants). Avoirs exemptés. API qui préserve l'absent, section Montant minimum dans Paramètres → Facturation, manuels et CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): prompt de la revue de code P1 (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-e): revue de code P1 — seuil comparé au centime, plafond, helper d'export réellement appelé (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): prompt de la revue de code P2 ciblée (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): revue de code P2 ciblée — 0 au-dessus de LOW, boucle close ; story done (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4): fixture du test de la fiche (25-6-b) complétée de l'arrondi (refs #494) La fusion de main apporte invoice-pdf-page.test.ts, dont la fixture InvoiceResponse ignorait roundingAmount / roundingIsPreview ajoutés par la c4 : npm run check rougissait (1 erreur), tests et build passaient. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
guycorbaz
added a commit
that referenced
this pull request
Oct 5, 2026
…e sur débiteur (refs #384) (#509) * docs(25-4-c): story créée — le résiduel au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): arbitrages Q1–Q3 retenus par défaut, rebase sur la b2 (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P1 — 3 HIGH, 2 MED, 1 LOW remédiés (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P2 — 0 finding sans preuve, 2 MED repris par l'orchestrateur (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): références de lignes du verrou recontrôlées (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P3 consignée — 1 CRIT / 3 HIGH, découpage et arbitrages en attente (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): découpée — verrou en 25-4-c2 (#480), arrondi en 25-4-c3 (#476) ; périmètre réduit au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P4 — 1 MED, 1 LOW remédiés (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P5 ciblée — close, 0 > LOW (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): le rapprochement reconnaît le solde d'une facture réglée en partie (refs #420) Le filtre des candidates, le score, le re-score à l'acceptation et le montant affiché portent sur le reste dû (TTC − avoir − règlements), par la forme jointe ; le TTC ne suit qu'en mention quand les deux diffèrent. Manuel et brochure réécrits sur le score réel ; #481 ouverte pour le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): revue de code P1 — CHANGELOG replacé, traductions univoques, Playwright départagé (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): revue de code P2 — close, 0 > LOW ; story done (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): story créée — l'invariant de version au règlement, et le rejeu sur interblocage (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P1 — 1 HIGH, 2 MED, 2 LOW remédiés (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P2 — close, 0 > LOW (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): un règlement partiel marque la facture, et l'acceptation rejoue un interblocage (refs #480) Le règlement manuel incrémente invoices.version à chaque règlement, partiel compris : le verrou optimiste de l'acceptation refuse désormais celle qui arrive après un règlement concurrent. Un interblocage absorbé dans une proposition (ROLLBACK TO SAVEPOINT en 1305) remonte en TransactionAborted et la route rejoue le lot par retry_with. Trois tests de course sans sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): revue de code P1 — gardes rows_affected, RELEASE SAVEPOINT, verrou de test détaché (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(25-4-c3): arbitrage de Guy — l'écart d'arrondi passe en écriture ; PR #485 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3): découpée en a1 / a2 / b ; story c3-a1 créée — le réglage du compte d'arrondi (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P1 — 2 MED remédiés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P2 ciblée — close, 0 > LOW (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a1): désigner le compte de différences d'arrondi dans les paramètres (refs #476) Nouvelle colonne company_invoice_settings.default_rounding_account_id (DDL seul, non breaking), validée charge ou produit, actif, imputable ; absente d'un PUT elle est préservée, à null effacée. Section Différences d'arrondi dans Paramètres > Facturation ; export ; import d'une sauvegarde antérieure prouvé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a1): revue de code P1 — compte d'arrondi validé seulement s'il change, Playwright nettoyé en finally (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): story créée — le compte de différences d'arrondi dans les plans livrés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P1 — 3 MED, 2 LOW remédiés ; #488 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P2 ciblée — close, 0 > LOW ; dev démarré (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a2): le compte 6940 Différences d'arrondi dans les plans livrés, désigné d'office (refs #476) Marqueur de plan roundingDifference (pas de rôle, pas de numéro dans le code), validé au chargement ; les deux insert_with_defaults* désignent le compte marqué du plan de la société (FOR UPDATE), NULL sans erreur s'il manque. Rien chez les sociétés existantes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a2): revue de code P1 — marqueur sans rôle, erreur de plan tracée, types liés par l'enum (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): revue de code P2 ciblée — close, 0 finding ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): story créée — l'arrondi au centime et l'écart en écriture (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P1 — double borne brut/arrondi, échelle du règlement manuel, sites triés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P2 — échelle normalisée, contrôle client des décimales, reste sous le demi-centime tracé (#490) (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P3 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P3 ciblée — montant reçu tel quel, décimales sur la forme big.js, test d'échelle discriminant, #490 reformulée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P4 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P4 ciblée — 0 finding, boucle close (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-b): solder au centime, l'écart d'arrondi en troisième ligne (refs #476) Le reste dû peut porter quatre décimales (10.0050) ; QR, rappels et dialogue réclament 10.01, que le rapprochement ne proposait pas et que le règlement manuel refusait en trop-perçu. Toute comparaison se fait au centime (amount_due_to_centime) ; un paiement égal au reste arrondi solde la facture, réglée au reste brut, l'écart passant sur le compte de différences d'arrondi (double borne : entre brut et arrondi, trop-perçu). Sans compte utilisable, refus dédié ROUNDING_ACCOUNT_NOT_CONFIGURED, rien d'écrit. Règlement manuel à plus de deux décimales refusé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P1 (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-b): revue de code P1 — invariant tracé au rapprochement, compte d'arrondi produit testé (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P2 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): revue de code P2 ciblée — close, aucune correction de production ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): story créée — l'arrondi à 5 centimes figé à la validation (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P1 — refus contextualisé, ordre des refus, références corrigées (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P2 — sites de la variante et emplacement du refus écrits (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P3 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P3 ciblée — l'avoir à arrondi nul n'exige aucun compte (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P4 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P4 ciblée — 0 finding, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-a): arrondir à 5 centimes le total des pièces émises, figé à la validation (refs #494) Le total TTC d'une facture validée est arrondi au multiple de 0.05 (123.44 → 123.45, 234.52 → 234.50) ; l'écart, sans TVA, est figé sur la facture (invoices.rounding_amount) et écrit en dernière ligne de l'écriture de vente sur le compte de différences d'arrondi. Toutes les formes du TTC l'intègrent (reste dû, listes, rapprochement, QR, PDF, e-mail). L'avoir le recopie et l'annule en miroir. Réglage par société, actif par défaut. Refus à contexte : le message d'émission ne parle plus de paiement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-a): revue de code P1 — forme jointe du crédit symétrique, manuel admin rectifié, avoir et sauvegarde testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): revue de code P2 ciblée — 0 finding, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): story créée — l'arrondi à 5 centimes, visible et réglable (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P1 — aperçu sur toute réponse brouillon, récapitulatif traduit, doc-comment rectifié (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P2 — type résolu clarifié, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-b): l'arrondi à 5 centimes visible et réglable (refs #494) Ligne « Arrondi » signée au PDF de la facture, de l'avoir et du rappel, et sur la fiche (aperçu « estimé » pour un brouillon, calculé par le serveur et porté par toute réponse qui rend un brouillon, dévalidation comprise). Le réglage roundTo5Centimes est exposé (GET/PUT, préservé s'il est absent) et se règle dans Paramètres → Facturation ; les factures émises gardent leur total. Récapitulatif de la fiche traduit, manuels et CHANGELOG à jour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-b): revue de code P1 — réglage lu sans écriture, arrondi décidé au centime, manuel rectifié, avoir et rappel testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): revue de code P2 ciblée — 0 réel, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): story créée — un montant minimum configurable sous lequel une facture n'est pas émise (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): validation P1 — sites qui énumèrent les colonnes nommés ; prompt P2 (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): validation P2 ciblée — sites hors dépôt explicités, boucle close (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-e): un montant minimum configurable sous lequel une facture n'est pas émise (refs #495) Réglage company_invoice_settings.minimum_invoice_amount (NULL = aucun seuil, le défaut) ; la validation refuse une facture dont le total arrondi est inférieur (INVOICE_BELOW_MINIMUM, message à deux montants). Avoirs exemptés. API qui préserve l'absent, section Montant minimum dans Paramètres → Facturation, manuels et CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): prompt de la revue de code P1 (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-e): revue de code P1 — seuil comparé au centime, plafond, helper d'export réellement appelé (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): prompt de la revue de code P2 ciblée (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): revue de code P2 ciblée — 0 au-dessus de LOW, boucle close ; story done (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): story créée — les comptes de solde (escompte, frais bancaires, perte sur débiteur) ; 25-4-d découpée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): validation P1 — test de comptage à créer, double marqueur interdit, messages préservés ; prompt P2 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): validation P2 ciblée — boucle close (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-d1): les comptes de solde — escompte, frais bancaires, perte sur débiteur (refs #384) Marqueur de plan writeOffNature (discount, bankFees, badDebt), validé par le même helper que le compte d'arrondi (messages de l'arrondi inchangés), double marqueur refusé. Plans livrés : 3805 Pertes sur créances ajouté aux trois, 6900 marqué frais bancaires, 3800 marqué escompte (PME, indépendant). Migration 20261001000003 : trois comptes désignés dans company_invoice_settings (BIGINT NULL, FK RESTRICT), désignés d'office à la création d'une société par un helper commun avec l'arrondi. API (absent préservé, null effacé, validé s'il change), section « Solde du reste » dans Paramètres → Facturation, quatre locales, manuel admin, CHANGELOG. Le solde lui-même (écriture, bouton) suit en 25-4-d2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): prompt de la revue de code P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d1): revue P1 — double marqueur nommé avant le type ; manuel admin précisé (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): prompt de la revue de code P2 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): revue de code P2 ciblée — 0 finding, boucle close ; story done (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4): fixture du test de la fiche (25-6-b) complétée de l'arrondi (refs #494) La fusion de main apporte invoice-pdf-page.test.ts, dont la fixture InvoiceResponse ignorait roundingAmount / roundingIsPreview ajoutés par la c4 : npm run check rougissait (1 erreur), tests et build passaient. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
guycorbaz
added a commit
that referenced
this pull request
Oct 5, 2026
…384, refs #490) (#510) * docs(25-4-c): story créée — le résiduel au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): arbitrages Q1–Q3 retenus par défaut, rebase sur la b2 (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P1 — 3 HIGH, 2 MED, 1 LOW remédiés (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P2 — 0 finding sans preuve, 2 MED repris par l'orchestrateur (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): références de lignes du verrou recontrôlées (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P3 consignée — 1 CRIT / 3 HIGH, découpage et arbitrages en attente (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): découpée — verrou en 25-4-c2 (#480), arrondi en 25-4-c3 (#476) ; périmètre réduit au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P4 — 1 MED, 1 LOW remédiés (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P5 ciblée — close, 0 > LOW (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): le rapprochement reconnaît le solde d'une facture réglée en partie (refs #420) Le filtre des candidates, le score, le re-score à l'acceptation et le montant affiché portent sur le reste dû (TTC − avoir − règlements), par la forme jointe ; le TTC ne suit qu'en mention quand les deux diffèrent. Manuel et brochure réécrits sur le score réel ; #481 ouverte pour le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): revue de code P1 — CHANGELOG replacé, traductions univoques, Playwright départagé (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): revue de code P2 — close, 0 > LOW ; story done (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): story créée — l'invariant de version au règlement, et le rejeu sur interblocage (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P1 — 1 HIGH, 2 MED, 2 LOW remédiés (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P2 — close, 0 > LOW (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): un règlement partiel marque la facture, et l'acceptation rejoue un interblocage (refs #480) Le règlement manuel incrémente invoices.version à chaque règlement, partiel compris : le verrou optimiste de l'acceptation refuse désormais celle qui arrive après un règlement concurrent. Un interblocage absorbé dans une proposition (ROLLBACK TO SAVEPOINT en 1305) remonte en TransactionAborted et la route rejoue le lot par retry_with. Trois tests de course sans sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): revue de code P1 — gardes rows_affected, RELEASE SAVEPOINT, verrou de test détaché (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(25-4-c3): arbitrage de Guy — l'écart d'arrondi passe en écriture ; PR #485 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3): découpée en a1 / a2 / b ; story c3-a1 créée — le réglage du compte d'arrondi (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P1 — 2 MED remédiés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P2 ciblée — close, 0 > LOW (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a1): désigner le compte de différences d'arrondi dans les paramètres (refs #476) Nouvelle colonne company_invoice_settings.default_rounding_account_id (DDL seul, non breaking), validée charge ou produit, actif, imputable ; absente d'un PUT elle est préservée, à null effacée. Section Différences d'arrondi dans Paramètres > Facturation ; export ; import d'une sauvegarde antérieure prouvé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a1): revue de code P1 — compte d'arrondi validé seulement s'il change, Playwright nettoyé en finally (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): story créée — le compte de différences d'arrondi dans les plans livrés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P1 — 3 MED, 2 LOW remédiés ; #488 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P2 ciblée — close, 0 > LOW ; dev démarré (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a2): le compte 6940 Différences d'arrondi dans les plans livrés, désigné d'office (refs #476) Marqueur de plan roundingDifference (pas de rôle, pas de numéro dans le code), validé au chargement ; les deux insert_with_defaults* désignent le compte marqué du plan de la société (FOR UPDATE), NULL sans erreur s'il manque. Rien chez les sociétés existantes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a2): revue de code P1 — marqueur sans rôle, erreur de plan tracée, types liés par l'enum (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): revue de code P2 ciblée — close, 0 finding ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): story créée — l'arrondi au centime et l'écart en écriture (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P1 — double borne brut/arrondi, échelle du règlement manuel, sites triés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P2 — échelle normalisée, contrôle client des décimales, reste sous le demi-centime tracé (#490) (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P3 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P3 ciblée — montant reçu tel quel, décimales sur la forme big.js, test d'échelle discriminant, #490 reformulée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P4 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P4 ciblée — 0 finding, boucle close (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-b): solder au centime, l'écart d'arrondi en troisième ligne (refs #476) Le reste dû peut porter quatre décimales (10.0050) ; QR, rappels et dialogue réclament 10.01, que le rapprochement ne proposait pas et que le règlement manuel refusait en trop-perçu. Toute comparaison se fait au centime (amount_due_to_centime) ; un paiement égal au reste arrondi solde la facture, réglée au reste brut, l'écart passant sur le compte de différences d'arrondi (double borne : entre brut et arrondi, trop-perçu). Sans compte utilisable, refus dédié ROUNDING_ACCOUNT_NOT_CONFIGURED, rien d'écrit. Règlement manuel à plus de deux décimales refusé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P1 (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-b): revue de code P1 — invariant tracé au rapprochement, compte d'arrondi produit testé (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P2 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): revue de code P2 ciblée — close, aucune correction de production ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): story créée — l'arrondi à 5 centimes figé à la validation (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P1 — refus contextualisé, ordre des refus, références corrigées (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P2 — sites de la variante et emplacement du refus écrits (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P3 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P3 ciblée — l'avoir à arrondi nul n'exige aucun compte (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P4 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P4 ciblée — 0 finding, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-a): arrondir à 5 centimes le total des pièces émises, figé à la validation (refs #494) Le total TTC d'une facture validée est arrondi au multiple de 0.05 (123.44 → 123.45, 234.52 → 234.50) ; l'écart, sans TVA, est figé sur la facture (invoices.rounding_amount) et écrit en dernière ligne de l'écriture de vente sur le compte de différences d'arrondi. Toutes les formes du TTC l'intègrent (reste dû, listes, rapprochement, QR, PDF, e-mail). L'avoir le recopie et l'annule en miroir. Réglage par société, actif par défaut. Refus à contexte : le message d'émission ne parle plus de paiement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-a): revue de code P1 — forme jointe du crédit symétrique, manuel admin rectifié, avoir et sauvegarde testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): revue de code P2 ciblée — 0 finding, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): story créée — l'arrondi à 5 centimes, visible et réglable (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P1 — aperçu sur toute réponse brouillon, récapitulatif traduit, doc-comment rectifié (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P2 — type résolu clarifié, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-b): l'arrondi à 5 centimes visible et réglable (refs #494) Ligne « Arrondi » signée au PDF de la facture, de l'avoir et du rappel, et sur la fiche (aperçu « estimé » pour un brouillon, calculé par le serveur et porté par toute réponse qui rend un brouillon, dévalidation comprise). Le réglage roundTo5Centimes est exposé (GET/PUT, préservé s'il est absent) et se règle dans Paramètres → Facturation ; les factures émises gardent leur total. Récapitulatif de la fiche traduit, manuels et CHANGELOG à jour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-b): revue de code P1 — réglage lu sans écriture, arrondi décidé au centime, manuel rectifié, avoir et rappel testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): revue de code P2 ciblée — 0 réel, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): story créée — un montant minimum configurable sous lequel une facture n'est pas émise (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): validation P1 — sites qui énumèrent les colonnes nommés ; prompt P2 (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): validation P2 ciblée — sites hors dépôt explicités, boucle close (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-e): un montant minimum configurable sous lequel une facture n'est pas émise (refs #495) Réglage company_invoice_settings.minimum_invoice_amount (NULL = aucun seuil, le défaut) ; la validation refuse une facture dont le total arrondi est inférieur (INVOICE_BELOW_MINIMUM, message à deux montants). Avoirs exemptés. API qui préserve l'absent, section Montant minimum dans Paramètres → Facturation, manuels et CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): prompt de la revue de code P1 (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-e): revue de code P1 — seuil comparé au centime, plafond, helper d'export réellement appelé (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): prompt de la revue de code P2 ciblée (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): revue de code P2 ciblée — 0 au-dessus de LOW, boucle close ; story done (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): story créée — les comptes de solde (escompte, frais bancaires, perte sur débiteur) ; 25-4-d découpée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): validation P1 — test de comptage à créer, double marqueur interdit, messages préservés ; prompt P2 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): validation P2 ciblée — boucle close (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-d1): les comptes de solde — escompte, frais bancaires, perte sur débiteur (refs #384) Marqueur de plan writeOffNature (discount, bankFees, badDebt), validé par le même helper que le compte d'arrondi (messages de l'arrondi inchangés), double marqueur refusé. Plans livrés : 3805 Pertes sur créances ajouté aux trois, 6900 marqué frais bancaires, 3800 marqué escompte (PME, indépendant). Migration 20261001000003 : trois comptes désignés dans company_invoice_settings (BIGINT NULL, FK RESTRICT), désignés d'office à la création d'une société par un helper commun avec l'arrondi. API (absent préservé, null effacé, validé s'il change), section « Solde du reste » dans Paramètres → Facturation, quatre locales, manuel admin, CHANGELOG. Le solde lui-même (écriture, bouton) suit en 25-4-d2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): prompt de la revue de code P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d1): revue P1 — double marqueur nommé avant le type ; manuel admin précisé (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): prompt de la revue de code P2 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): revue de code P2 ciblée — 0 finding, boucle close ; story done (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): story créée — l'écriture de solde et son annulation ; 25-4-d2 découpée (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P1 — rejeu sur interblocage, CHECK distincts, garde de TVA, invariant du solde total (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P2 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P2 — annulation bloquée par un solde, version exigée, facture payée sans ligne refusée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P3 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P3 — motif d'annulation traduit à l'écran, son rang, test du sens inverse (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P4 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P4 ciblée — boucle close (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-d2a): solder le reste d'une facture — l'écriture et son annulation (refs #384, refs #490) POST /api/v1/invoices/{id}/write-off { nature, settledOn, version } éteint tout le reste dû d'une facture validée, imputé au compte de sa nature (escompte, frais bancaires, perte sur débiteur, reste d'arrondi). Écriture OD ; escompte et perte corrigent la TVA due au prorata des taux de la facture, ventilation figée sur la ligne (write_off_vat). Migration 20261001000004 : type write_off dans invoice_settlements, nature, ventilation JSON, CHECK recréés. Compte de la nature relu au moment d'écrire (cœur commun avec le compte d'arrondi). Un règlement ne s'annule pas tant qu'un solde existe (INVOICE_WRITTEN_OFF, rang 1 bis), dé-rapprochement compris. Route rejouée sur interblocage, sûre par la version. Un reste inférieur au demi-centime se solde en nature rounding (#490). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de la revue de code P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2a): revue P1 — fraction de centime au compte d'arrondi, compte de TVA relu, tests du dé-rapprochement et des taux mêlés (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de la revue de code P2 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2a): revue P2 — un reste sous le demi-centime va au compte d'arrondi quelle que soit la nature ; ordre des verrous rétabli (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de la revue de code P3 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): revue de code P3 ciblée — boucle close ; story done (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4): fixture du test de la fiche (25-6-b) complétée de l'arrondi (refs #494) La fusion de main apporte invoice-pdf-page.test.ts, dont la fixture InvoiceResponse ignorait roundingAmount / roundingIsPreview ajoutés par la c4 : npm run check rougissait (1 erreur), tests et build passaient. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
guycorbaz
added a commit
that referenced
this pull request
Oct 5, 2026
…loses #505) (#511) * docs(25-4-c): story créée — le résiduel au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): arbitrages Q1–Q3 retenus par défaut, rebase sur la b2 (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P1 — 3 HIGH, 2 MED, 1 LOW remédiés (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P2 — 0 finding sans preuve, 2 MED repris par l'orchestrateur (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): références de lignes du verrou recontrôlées (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P3 consignée — 1 CRIT / 3 HIGH, découpage et arbitrages en attente (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): découpée — verrou en 25-4-c2 (#480), arrondi en 25-4-c3 (#476) ; périmètre réduit au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P4 — 1 MED, 1 LOW remédiés (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P5 ciblée — close, 0 > LOW (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): le rapprochement reconnaît le solde d'une facture réglée en partie (refs #420) Le filtre des candidates, le score, le re-score à l'acceptation et le montant affiché portent sur le reste dû (TTC − avoir − règlements), par la forme jointe ; le TTC ne suit qu'en mention quand les deux diffèrent. Manuel et brochure réécrits sur le score réel ; #481 ouverte pour le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): revue de code P1 — CHANGELOG replacé, traductions univoques, Playwright départagé (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): revue de code P2 — close, 0 > LOW ; story done (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): story créée — l'invariant de version au règlement, et le rejeu sur interblocage (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P1 — 1 HIGH, 2 MED, 2 LOW remédiés (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P2 — close, 0 > LOW (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): un règlement partiel marque la facture, et l'acceptation rejoue un interblocage (refs #480) Le règlement manuel incrémente invoices.version à chaque règlement, partiel compris : le verrou optimiste de l'acceptation refuse désormais celle qui arrive après un règlement concurrent. Un interblocage absorbé dans une proposition (ROLLBACK TO SAVEPOINT en 1305) remonte en TransactionAborted et la route rejoue le lot par retry_with. Trois tests de course sans sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): revue de code P1 — gardes rows_affected, RELEASE SAVEPOINT, verrou de test détaché (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(25-4-c3): arbitrage de Guy — l'écart d'arrondi passe en écriture ; PR #485 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3): découpée en a1 / a2 / b ; story c3-a1 créée — le réglage du compte d'arrondi (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P1 — 2 MED remédiés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P2 ciblée — close, 0 > LOW (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a1): désigner le compte de différences d'arrondi dans les paramètres (refs #476) Nouvelle colonne company_invoice_settings.default_rounding_account_id (DDL seul, non breaking), validée charge ou produit, actif, imputable ; absente d'un PUT elle est préservée, à null effacée. Section Différences d'arrondi dans Paramètres > Facturation ; export ; import d'une sauvegarde antérieure prouvé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a1): revue de code P1 — compte d'arrondi validé seulement s'il change, Playwright nettoyé en finally (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): story créée — le compte de différences d'arrondi dans les plans livrés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P1 — 3 MED, 2 LOW remédiés ; #488 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P2 ciblée — close, 0 > LOW ; dev démarré (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a2): le compte 6940 Différences d'arrondi dans les plans livrés, désigné d'office (refs #476) Marqueur de plan roundingDifference (pas de rôle, pas de numéro dans le code), validé au chargement ; les deux insert_with_defaults* désignent le compte marqué du plan de la société (FOR UPDATE), NULL sans erreur s'il manque. Rien chez les sociétés existantes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a2): revue de code P1 — marqueur sans rôle, erreur de plan tracée, types liés par l'enum (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): revue de code P2 ciblée — close, 0 finding ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): story créée — l'arrondi au centime et l'écart en écriture (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P1 — double borne brut/arrondi, échelle du règlement manuel, sites triés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P2 — échelle normalisée, contrôle client des décimales, reste sous le demi-centime tracé (#490) (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P3 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P3 ciblée — montant reçu tel quel, décimales sur la forme big.js, test d'échelle discriminant, #490 reformulée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P4 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P4 ciblée — 0 finding, boucle close (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-b): solder au centime, l'écart d'arrondi en troisième ligne (refs #476) Le reste dû peut porter quatre décimales (10.0050) ; QR, rappels et dialogue réclament 10.01, que le rapprochement ne proposait pas et que le règlement manuel refusait en trop-perçu. Toute comparaison se fait au centime (amount_due_to_centime) ; un paiement égal au reste arrondi solde la facture, réglée au reste brut, l'écart passant sur le compte de différences d'arrondi (double borne : entre brut et arrondi, trop-perçu). Sans compte utilisable, refus dédié ROUNDING_ACCOUNT_NOT_CONFIGURED, rien d'écrit. Règlement manuel à plus de deux décimales refusé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P1 (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-b): revue de code P1 — invariant tracé au rapprochement, compte d'arrondi produit testé (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P2 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): revue de code P2 ciblée — close, aucune correction de production ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): story créée — l'arrondi à 5 centimes figé à la validation (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P1 — refus contextualisé, ordre des refus, références corrigées (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P2 — sites de la variante et emplacement du refus écrits (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P3 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P3 ciblée — l'avoir à arrondi nul n'exige aucun compte (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P4 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P4 ciblée — 0 finding, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-a): arrondir à 5 centimes le total des pièces émises, figé à la validation (refs #494) Le total TTC d'une facture validée est arrondi au multiple de 0.05 (123.44 → 123.45, 234.52 → 234.50) ; l'écart, sans TVA, est figé sur la facture (invoices.rounding_amount) et écrit en dernière ligne de l'écriture de vente sur le compte de différences d'arrondi. Toutes les formes du TTC l'intègrent (reste dû, listes, rapprochement, QR, PDF, e-mail). L'avoir le recopie et l'annule en miroir. Réglage par société, actif par défaut. Refus à contexte : le message d'émission ne parle plus de paiement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-a): revue de code P1 — forme jointe du crédit symétrique, manuel admin rectifié, avoir et sauvegarde testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): revue de code P2 ciblée — 0 finding, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): story créée — l'arrondi à 5 centimes, visible et réglable (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P1 — aperçu sur toute réponse brouillon, récapitulatif traduit, doc-comment rectifié (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P2 — type résolu clarifié, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-b): l'arrondi à 5 centimes visible et réglable (refs #494) Ligne « Arrondi » signée au PDF de la facture, de l'avoir et du rappel, et sur la fiche (aperçu « estimé » pour un brouillon, calculé par le serveur et porté par toute réponse qui rend un brouillon, dévalidation comprise). Le réglage roundTo5Centimes est exposé (GET/PUT, préservé s'il est absent) et se règle dans Paramètres → Facturation ; les factures émises gardent leur total. Récapitulatif de la fiche traduit, manuels et CHANGELOG à jour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-b): revue de code P1 — réglage lu sans écriture, arrondi décidé au centime, manuel rectifié, avoir et rappel testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): revue de code P2 ciblée — 0 réel, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): story créée — un montant minimum configurable sous lequel une facture n'est pas émise (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): validation P1 — sites qui énumèrent les colonnes nommés ; prompt P2 (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): validation P2 ciblée — sites hors dépôt explicités, boucle close (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-e): un montant minimum configurable sous lequel une facture n'est pas émise (refs #495) Réglage company_invoice_settings.minimum_invoice_amount (NULL = aucun seuil, le défaut) ; la validation refuse une facture dont le total arrondi est inférieur (INVOICE_BELOW_MINIMUM, message à deux montants). Avoirs exemptés. API qui préserve l'absent, section Montant minimum dans Paramètres → Facturation, manuels et CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): prompt de la revue de code P1 (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-e): revue de code P1 — seuil comparé au centime, plafond, helper d'export réellement appelé (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): prompt de la revue de code P2 ciblée (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): revue de code P2 ciblée — 0 au-dessus de LOW, boucle close ; story done (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): story créée — les comptes de solde (escompte, frais bancaires, perte sur débiteur) ; 25-4-d découpée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): validation P1 — test de comptage à créer, double marqueur interdit, messages préservés ; prompt P2 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): validation P2 ciblée — boucle close (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-d1): les comptes de solde — escompte, frais bancaires, perte sur débiteur (refs #384) Marqueur de plan writeOffNature (discount, bankFees, badDebt), validé par le même helper que le compte d'arrondi (messages de l'arrondi inchangés), double marqueur refusé. Plans livrés : 3805 Pertes sur créances ajouté aux trois, 6900 marqué frais bancaires, 3800 marqué escompte (PME, indépendant). Migration 20261001000003 : trois comptes désignés dans company_invoice_settings (BIGINT NULL, FK RESTRICT), désignés d'office à la création d'une société par un helper commun avec l'arrondi. API (absent préservé, null effacé, validé s'il change), section « Solde du reste » dans Paramètres → Facturation, quatre locales, manuel admin, CHANGELOG. Le solde lui-même (écriture, bouton) suit en 25-4-d2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): prompt de la revue de code P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d1): revue P1 — double marqueur nommé avant le type ; manuel admin précisé (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): prompt de la revue de code P2 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): revue de code P2 ciblée — 0 finding, boucle close ; story done (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): story créée — l'écriture de solde et son annulation ; 25-4-d2 découpée (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P1 — rejeu sur interblocage, CHECK distincts, garde de TVA, invariant du solde total (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P2 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P2 — annulation bloquée par un solde, version exigée, facture payée sans ligne refusée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P3 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P3 — motif d'annulation traduit à l'écran, son rang, test du sens inverse (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P4 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P4 ciblée — boucle close (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-d2a): solder le reste d'une facture — l'écriture et son annulation (refs #384, refs #490) POST /api/v1/invoices/{id}/write-off { nature, settledOn, version } éteint tout le reste dû d'une facture validée, imputé au compte de sa nature (escompte, frais bancaires, perte sur débiteur, reste d'arrondi). Écriture OD ; escompte et perte corrigent la TVA due au prorata des taux de la facture, ventilation figée sur la ligne (write_off_vat). Migration 20261001000004 : type write_off dans invoice_settlements, nature, ventilation JSON, CHECK recréés. Compte de la nature relu au moment d'écrire (cœur commun avec le compte d'arrondi). Un règlement ne s'annule pas tant qu'un solde existe (INVOICE_WRITTEN_OFF, rang 1 bis), dé-rapprochement compris. Route rejouée sur interblocage, sûre par la version. Un reste inférieur au demi-centime se solde en nature rounding (#490). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de la revue de code P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2a): revue P1 — fraction de centime au compte d'arrondi, compte de TVA relu, tests du dé-rapprochement et des taux mêlés (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de la revue de code P2 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2a): revue P2 — un reste sous le demi-centime va au compte d'arrondi quelle que soit la nature ; ordre des verrous rétabli (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de la revue de code P3 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): revue de code P3 ciblée — boucle close ; story done (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): story créée — le bouton, le dialogue et la liste du solde (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de validation P1 (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): les deux limites assumées tracées en CR (#496, #497) (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): validation P1 — compte d'arrondi pour toute nature, annulation dite « solde », récapitulatif sans liste, version relue (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de validation P2 (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): validation P2 — 409 distingués par code, comparaisons en big.js, reste aux quatre décimales, sites du symptôme ; #496 corrigée (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de validation P3 ciblée (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): validation P3 — fermeture du dialogue et cas complémentaire reliés ; montage E2E par le formulaire (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de validation P4 ciblée (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): validation P4 ciblée — boucle close (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-d2b): solder le reste depuis la fiche — bouton, dialogue, liste (refs #384, refs #490) Bouton « Solder le reste » (Comptable+) et dialogue : nature au choix, montant non saisi (le reste dû, aux quatre décimales s'il porte une fraction de centime), compte manquant signalé avant l'envoi — y compris le compte d'arrondi pour toute nature sur une fraction de centime. Version de la facture affichée envoyée ; refus distingués par code (409 de version : dialogue ouvert et version relue ; facture dévalidée ou payée : fermeture). Liste : « Solde — nature », « Annuler le solde » ; récapitulatif « Déjà réglé » / « Soldé », réduit au reste dû sans liste fiable. Manuels utilisateur et admin, CHANGELOG (#496, #497 cités). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de la revue de code P1 (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2b): revue P1 — fermeture bloquée pendant l'envoi, dialogue toujours monté, reste exact à l'échéancier (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de la revue de code P2 ciblée (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2b): revue P2 — garde du parent retirée, reste inconnu expliqué, relecture après validation, échéancier au format exact (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de la revue de code P3 ciblée (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): revue de code P3 ciblée — boucle close ; story done (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4): fixture du test de la fiche (25-6-b) complétée de l'arrondi (refs #494) La fusion de main apporte invoice-pdf-page.test.ts, dont la fixture InvoiceResponse ignorait roundingAmount / roundingIsPreview ajoutés par la c4 : npm run check rougissait (1 erreur), tests et build passaient. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2b): fixture du test de solde complétée du PDF figé (refs #490) La fusion de main apporte pdfFrozenAt / pdfLanguage (25-6-b) dans InvoiceResponse ; la fixture d'invoice-write-off-page.test.ts les ignorait : npm run check rougissait (1 erreur), tests et E2E passaient. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
guycorbaz
added a commit
that referenced
this pull request
Oct 5, 2026
…) (#512) * docs(25-4-c): story créée — le résiduel au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): arbitrages Q1–Q3 retenus par défaut, rebase sur la b2 (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P1 — 3 HIGH, 2 MED, 1 LOW remédiés (refs #420, refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P2 — 0 finding sans preuve, 2 MED repris par l'orchestrateur (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): références de lignes du verrou recontrôlées (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P3 consignée — 1 CRIT / 3 HIGH, découpage et arbitrages en attente (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): découpée — verrou en 25-4-c2 (#480), arrondi en 25-4-c3 (#476) ; périmètre réduit au rapprochement (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P4 — 1 MED, 1 LOW remédiés (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): validation P5 ciblée — close, 0 > LOW (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): le rapprochement reconnaît le solde d'une facture réglée en partie (refs #420) Le filtre des candidates, le score, le re-score à l'acceptation et le montant affiché portent sur le reste dû (TTC − avoir − règlements), par la forme jointe ; le TTC ne suit qu'en mention quand les deux diffèrent. Manuel et brochure réécrits sur le score réel ; #481 ouverte pour le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c): revue de code P1 — CHANGELOG replacé, traductions univoques, Playwright départagé (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c): revue de code P2 — close, 0 > LOW ; story done (refs #420) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): story créée — l'invariant de version au règlement, et le rejeu sur interblocage (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P1 — 1 HIGH, 2 MED, 2 LOW remédiés (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): validation P2 — close, 0 > LOW (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): un règlement partiel marque la facture, et l'acceptation rejoue un interblocage (refs #480) Le règlement manuel incrémente invoices.version à chaque règlement, partiel compris : le verrou optimiste de l'acceptation refuse désormais celle qui arrive après un règlement concurrent. Un interblocage absorbé dans une proposition (ROLLBACK TO SAVEPOINT en 1305) remonte en TransactionAborted et la route rejoue le lot par retry_with. Trois tests de course sans sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c2): revue de code P1 — gardes rows_affected, RELEASE SAVEPOINT, verrou de test détaché (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c2): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #480) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(25-4-c3): arbitrage de Guy — l'écart d'arrondi passe en écriture ; PR #485 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3): découpée en a1 / a2 / b ; story c3-a1 créée — le réglage du compte d'arrondi (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P1 — 2 MED remédiés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): validation P2 ciblée — close, 0 > LOW (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a1): désigner le compte de différences d'arrondi dans les paramètres (refs #476) Nouvelle colonne company_invoice_settings.default_rounding_account_id (DDL seul, non breaking), validée charge ou produit, actif, imputable ; absente d'un PUT elle est préservée, à null effacée. Section Différences d'arrondi dans Paramètres > Facturation ; export ; import d'une sauvegarde antérieure prouvé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a1): revue de code P1 — compte d'arrondi validé seulement s'il change, Playwright nettoyé en finally (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a1): revue de code P2 ciblée — close, 0 > LOW ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): story créée — le compte de différences d'arrondi dans les plans livrés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P1 — 3 MED, 2 LOW remédiés ; #488 ouverte (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): validation P2 ciblée — close, 0 > LOW ; dev démarré (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-a2): le compte 6940 Différences d'arrondi dans les plans livrés, désigné d'office (refs #476) Marqueur de plan roundingDifference (pas de rôle, pas de numéro dans le code), validé au chargement ; les deux insert_with_defaults* désignent le compte marqué du plan de la société (FOR UPDATE), NULL sans erreur s'il manque. Rien chez les sociétés existantes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-a2): revue de code P1 — marqueur sans rôle, erreur de plan tracée, types liés par l'enum (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-a2): revue de code P2 ciblée — close, 0 finding ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): story créée — l'arrondi au centime et l'écart en écriture (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P1 — double borne brut/arrondi, échelle du règlement manuel, sites triés (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P2 — échelle normalisée, contrôle client des décimales, reste sous le demi-centime tracé (#490) (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P3 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P3 ciblée — montant reçu tel quel, décimales sur la forme big.js, test d'échelle discriminant, #490 reformulée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la validation P4 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): validation P4 ciblée — 0 finding, boucle close (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c3-b): solder au centime, l'écart d'arrondi en troisième ligne (refs #476) Le reste dû peut porter quatre décimales (10.0050) ; QR, rappels et dialogue réclament 10.01, que le rapprochement ne proposait pas et que le règlement manuel refusait en trop-perçu. Toute comparaison se fait au centime (amount_due_to_centime) ; un paiement égal au reste arrondi solde la facture, réglée au reste brut, l'écart passant sur le compte de différences d'arrondi (double borne : entre brut et arrondi, trop-perçu). Sans compte utilisable, refus dédié ROUNDING_ACCOUNT_NOT_CONFIGURED, rien d'écrit. Règlement manuel à plus de deux décimales refusé. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P1 (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c3-b): revue de code P1 — invariant tracé au rapprochement, compte d'arrondi produit testé (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): prompt de la revue de code P2 ciblée (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c3-b): revue de code P2 ciblée — close, aucune correction de production ; story done (refs #476) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): story créée — l'arrondi à 5 centimes figé à la validation (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P1 — refus contextualisé, ordre des refus, références corrigées (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P2 — sites de la variante et emplacement du refus écrits (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P3 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P3 ciblée — l'avoir à arrondi nul n'exige aucun compte (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la validation P4 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): validation P4 ciblée — 0 finding, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-a): arrondir à 5 centimes le total des pièces émises, figé à la validation (refs #494) Le total TTC d'une facture validée est arrondi au multiple de 0.05 (123.44 → 123.45, 234.52 → 234.50) ; l'écart, sans TVA, est figé sur la facture (invoices.rounding_amount) et écrit en dernière ligne de l'écriture de vente sur le compte de différences d'arrondi. Toutes les formes du TTC l'intègrent (reste dû, listes, rapprochement, QR, PDF, e-mail). L'avoir le recopie et l'annule en miroir. Réglage par société, actif par défaut. Refus à contexte : le message d'émission ne parle plus de paiement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-a): revue de code P1 — forme jointe du crédit symétrique, manuel admin rectifié, avoir et sauvegarde testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-a): revue de code P2 ciblée — 0 finding, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): story créée — l'arrondi à 5 centimes, visible et réglable (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P1 — aperçu sur toute réponse brouillon, récapitulatif traduit, doc-comment rectifié (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la validation P2 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): validation P2 — type résolu clarifié, boucle close (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-c4-b): l'arrondi à 5 centimes visible et réglable (refs #494) Ligne « Arrondi » signée au PDF de la facture, de l'avoir et du rappel, et sur la fiche (aperçu « estimé » pour un brouillon, calculé par le serveur et porté par toute réponse qui rend un brouillon, dévalidation comprise). Le réglage roundTo5Centimes est exposé (GET/PUT, préservé s'il est absent) et se règle dans Paramètres → Facturation ; les factures émises gardent leur total. Récapitulatif de la fiche traduit, manuels et CHANGELOG à jour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P1 (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4-b): revue de code P1 — réglage lu sans écriture, arrondi décidé au centime, manuel rectifié, avoir et rappel testés (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): prompt de la revue de code P2 ciblée (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-c4-b): revue de code P2 ciblée — 0 réel, boucle close ; story done (refs #494) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): story créée — un montant minimum configurable sous lequel une facture n'est pas émise (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): validation P1 — sites qui énumèrent les colonnes nommés ; prompt P2 (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): validation P2 ciblée — sites hors dépôt explicités, boucle close (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-e): un montant minimum configurable sous lequel une facture n'est pas émise (refs #495) Réglage company_invoice_settings.minimum_invoice_amount (NULL = aucun seuil, le défaut) ; la validation refuse une facture dont le total arrondi est inférieur (INVOICE_BELOW_MINIMUM, message à deux montants). Avoirs exemptés. API qui préserve l'absent, section Montant minimum dans Paramètres → Facturation, manuels et CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): prompt de la revue de code P1 (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-e): revue de code P1 — seuil comparé au centime, plafond, helper d'export réellement appelé (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): prompt de la revue de code P2 ciblée (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-e): revue de code P2 ciblée — 0 au-dessus de LOW, boucle close ; story done (refs #495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): story créée — les comptes de solde (escompte, frais bancaires, perte sur débiteur) ; 25-4-d découpée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): validation P1 — test de comptage à créer, double marqueur interdit, messages préservés ; prompt P2 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): validation P2 ciblée — boucle close (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-d1): les comptes de solde — escompte, frais bancaires, perte sur débiteur (refs #384) Marqueur de plan writeOffNature (discount, bankFees, badDebt), validé par le même helper que le compte d'arrondi (messages de l'arrondi inchangés), double marqueur refusé. Plans livrés : 3805 Pertes sur créances ajouté aux trois, 6900 marqué frais bancaires, 3800 marqué escompte (PME, indépendant). Migration 20261001000003 : trois comptes désignés dans company_invoice_settings (BIGINT NULL, FK RESTRICT), désignés d'office à la création d'une société par un helper commun avec l'arrondi. API (absent préservé, null effacé, validé s'il change), section « Solde du reste » dans Paramètres → Facturation, quatre locales, manuel admin, CHANGELOG. Le solde lui-même (écriture, bouton) suit en 25-4-d2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): prompt de la revue de code P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d1): revue P1 — double marqueur nommé avant le type ; manuel admin précisé (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): prompt de la revue de code P2 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d1): revue de code P2 ciblée — 0 finding, boucle close ; story done (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): story créée — l'écriture de solde et son annulation ; 25-4-d2 découpée (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P1 — rejeu sur interblocage, CHECK distincts, garde de TVA, invariant du solde total (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P2 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P2 — annulation bloquée par un solde, version exigée, facture payée sans ligne refusée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P3 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P3 — motif d'annulation traduit à l'écran, son rang, test du sens inverse (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de validation P4 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): validation P4 ciblée — boucle close (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-d2a): solder le reste d'une facture — l'écriture et son annulation (refs #384, refs #490) POST /api/v1/invoices/{id}/write-off { nature, settledOn, version } éteint tout le reste dû d'une facture validée, imputé au compte de sa nature (escompte, frais bancaires, perte sur débiteur, reste d'arrondi). Écriture OD ; escompte et perte corrigent la TVA due au prorata des taux de la facture, ventilation figée sur la ligne (write_off_vat). Migration 20261001000004 : type write_off dans invoice_settlements, nature, ventilation JSON, CHECK recréés. Compte de la nature relu au moment d'écrire (cœur commun avec le compte d'arrondi). Un règlement ne s'annule pas tant qu'un solde existe (INVOICE_WRITTEN_OFF, rang 1 bis), dé-rapprochement compris. Route rejouée sur interblocage, sûre par la version. Un reste inférieur au demi-centime se solde en nature rounding (#490). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de la revue de code P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2a): revue P1 — fraction de centime au compte d'arrondi, compte de TVA relu, tests du dé-rapprochement et des taux mêlés (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de la revue de code P2 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2a): revue P2 — un reste sous le demi-centime va au compte d'arrondi quelle que soit la nature ; ordre des verrous rétabli (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): prompt de la revue de code P3 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2a): revue de code P3 ciblée — boucle close ; story done (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): story créée — le bouton, le dialogue et la liste du solde (refs #384, refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de validation P1 (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): les deux limites assumées tracées en CR (#496, #497) (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): validation P1 — compte d'arrondi pour toute nature, annulation dite « solde », récapitulatif sans liste, version relue (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de validation P2 (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): validation P2 — 409 distingués par code, comparaisons en big.js, reste aux quatre décimales, sites du symptôme ; #496 corrigée (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de validation P3 ciblée (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): validation P3 — fermeture du dialogue et cas complémentaire reliés ; montage E2E par le formulaire (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de validation P4 ciblée (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): validation P4 ciblée — boucle close (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-d2b): solder le reste depuis la fiche — bouton, dialogue, liste (refs #384, refs #490) Bouton « Solder le reste » (Comptable+) et dialogue : nature au choix, montant non saisi (le reste dû, aux quatre décimales s'il porte une fraction de centime), compte manquant signalé avant l'envoi — y compris le compte d'arrondi pour toute nature sur une fraction de centime. Version de la facture affichée envoyée ; refus distingués par code (409 de version : dialogue ouvert et version relue ; facture dévalidée ou payée : fermeture). Liste : « Solde — nature », « Annuler le solde » ; récapitulatif « Déjà réglé » / « Soldé », réduit au reste dû sans liste fiable. Manuels utilisateur et admin, CHANGELOG (#496, #497 cités). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de la revue de code P1 (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2b): revue P1 — fermeture bloquée pendant l'envoi, dialogue toujours monté, reste exact à l'échéancier (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de la revue de code P2 ciblée (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2b): revue P2 — garde du parent retirée, reste inconnu expliqué, relecture après validation, échéancier au format exact (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): prompt de la revue de code P3 ciblée (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2b): revue de code P3 ciblée — boucle close ; story done (refs #490) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): story créée — le rapport TVA retranche la TVA des soldes (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): prompt de validation P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): validation P1 — garde « vide » de l'écran, signe du delta, fixtures (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): prompt de validation P2 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): validation P2 — E2E reports ancré, limite fiscale du solde annulé, erreur CorruptData, sites du manuel (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): prompt de validation P3 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): validation P3 — E2E avant l'annulation, gardes Rust testés, rendus conditionnels ; découpage reposé à Guy (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): prompt de validation P4 ciblée (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): arbitrage de Guy — pas de découpage (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): validation P4 ciblée — boucle close (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(25-4-d2c): le rapport TVA retranche la TVA des soldes (refs #384) Diminutions de contre-prestation par taux (escompte, perte sur débiteur) datées dans la période, TVA due nette, solde AFC sur le net ; delta de réconciliation net contre grand livre net. Rendus CSV, PDF, écran conditionnels ; JSON de ventilation corrompu → 500. Manuel et CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(25-4-d2c): prompt de revue de code P1 (refs #384) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2c): revue de code P1 — 0 > LOW, boucle close (refs #384) Test de l'agrégation de deux soldes au même taux, limite du compte d'arrondi écrite, ligne vide du CHANGELOG. Story done. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-c4): fixture du test de la fiche (25-6-b) complétée de l'arrondi (refs #494) La fusion de main apporte invoice-pdf-page.test.ts, dont la fixture InvoiceResponse ignorait roundingAmount / roundingIsPreview ajoutés par la c4 : npm run check rougissait (1 erreur), tests et build passaient. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(25-4-d2b): fixture du test de solde complétée du PDF figé (refs #490) La fusion de main apporte pdfFrozenAt / pdfLanguage (25-6-b) dans InvoiceResponse ; la fixture d'invoice-write-off-page.test.ts les ignorait : npm run check rougissait (1 erreur), tests et E2E passaient. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #480.
Le défaut
Une acceptation de rapprochement lit le reste dû d'une facture sur l'instantané de sa transaction (REPEATABLE READ, MariaDB 10.11), puis se protège par un verrou optimiste :
UPDATE invoices … WHERE version = ?. Ce verrou ne vaut que si tout écrit qui change le reste dû incrémenteversion. Un seul écrivain y manquait : le règlement manuel partiel. Une acceptation en cours pouvait donc encaisser une seconde fois une facture qui venait d'être réglée en partie — 1 000.— réglée 1 400.—, compte clients créditeur, sans erreur. Reproduit par test avant correctif.Ce qui change
settle_invoiceincrémenteversionà chaque règlement, partiel compris ; garderows_affectedsur cette ligne et sur l'annulation d'un règlement. Doc-comments qui nomment l'invariant et l'inventaire clos de ses écrivains.FOR UPDATEà l'acceptation : il liraitversionà jour et le reste dû périmé, et désarmerait le verrou au lieu de le renforcer (écrit dans le code).ROLLBACK TO SAVEPOINTsuivant qui échoue (1305) :accept_batchle remonte enReconciliationError::TransactionAborted, etPOST /reconciliation/acceptrejoue le lot parretry_with(patron de l'annulation). Prédicat local ;is_deadlock_errorinchangé.docs/api-external.mddocumente enfinPOST /reconciliation/accept; CHANGELOG[0.12.1]. Issue Manuel : la numérotation des factures ne se fait pas dans une transaction SERIALIZABLE #484 ouverte (une affirmation fausse du manuel trouvée en chemin).Tests
Trois tests de course sans
sleep: règlement manuel partiel pendant l'acceptation (verrou de métadonnéesLOCK TABLES contacts WRITE— le verrou d'exercice ne permet pas de montage, la recherche d'exercice verrouillant toutes les lignes examinées), deux acceptations depuis deux comptes, interblocage dont l'acceptation est la victime. Mutations : incrément conditionnel rétabli, rejeu neutralisé, reconnaissance du 1305 neutralisée,version = ?relâché — chacune tuée.Validation et revue
Validation de spec en 2 passes (Sonnet 1 HIGH / 2 MEDIUM → Haiku 0 > LOW). Revue de code en 2 passes (Sonnet ×3 : 1 HIGH / 4 MEDIUM corrigés → Haiku ciblée : 0 > LOW).
Gates locaux, au dernier commit, base remise à zéro
check,lint-i18n-ownership, 836/836, build (inchangé par cette PR).🤖 Generated with Claude Code