Exports PDF : total mensuel à fin de mois et mise en avant de la régularisation

Report mensuel :
- « Total parcouru sur l'année » devient « Total annuel (à fin de mois) »
  et affiche le cumul jusqu'au mois de restitution inclus
  (Total_Annuel_Partiel, via ITotauxService)
- la tranche de barème (coefficient, base, TOTAL IK du mois) est
  déterminée sur ce même cumul, cohérent avec le Panneau_Totaux du site
  et stable même si le PDF est édité plus tard

Report annuel :
- ligne « Formule réelle » centrée (comme la régularisation)
- ligne « Régularisation (réel − payé) » agrandie (14 pt, gras) pour la
  mettre en avant comme action finale

Test d'intégration PDF mis à jour (injection d'ITotauxService). Specs
requirements/design-requirements/design synchronisées (Exigence 7).
This commit is contained in:
2026-10-13 07:08:12 +02:00
parent df259258a0
commit 0e14a8f806
5 changed files with 28 additions and 14 deletions
@@ -110,7 +110,8 @@ Le document est organisé **en miroir** des exigences de `requirements.md` : cha
4. WHEN le Backend compose la colonne "A/R" de la table des Trajets d'un Export_PDF mensuel, THE Backend SHALL afficher le marqueur « X » (et non une coche Unicode, non rendue par la police par défaut Lato) pour un Trajet Aller_Retour. 4. WHEN le Backend compose la colonne "A/R" de la table des Trajets d'un Export_PDF mensuel, THE Backend SHALL afficher le marqueur « X » (et non une coche Unicode, non rendue par la police par défaut Lato) pour un Trajet Aller_Retour.
5. WHEN le Backend définit les largeurs de colonnes de la table des Trajets d'un Export_PDF mensuel, THE Backend SHALL dimensionner la colonne "A/R" à sa largeur minimale, la colonne "Kms" pour afficher jusqu'à « 9 999 » (avec séparateur de milliers), et la colonne des adresses de façon maximisée pour que l'adresse de départ et l'adresse d'arrivée tiennent majoritairement sur deux lignes. 5. WHEN le Backend définit les largeurs de colonnes de la table des Trajets d'un Export_PDF mensuel, THE Backend SHALL dimensionner la colonne "A/R" à sa largeur minimale, la colonne "Kms" pour afficher jusqu'à « 9 999 » (avec séparateur de milliers), et la colonne des adresses de façon maximisée pour que l'adresse de départ et l'adresse d'arrivée tiennent majoritairement sur deux lignes.
6. WHEN le Backend compose le bloc d'infos de l'en-tête d'un Export_PDF annuel, THE Backend SHALL insérer un espace après la ligne « Véhicule » et présenter « Barème applicable » et « Total kilométrique de l'année » sur deux colonnes côte à côte. 6. WHEN le Backend compose le bloc d'infos de l'en-tête d'un Export_PDF annuel, THE Backend SHALL insérer un espace après la ligne « Véhicule » et présenter « Barème applicable » et « Total kilométrique de l'année » sur deux colonnes côte à côte.
7. WHEN le Backend compose la fin d'un Export_PDF annuel, THE Backend SHALL conserver la ligne « Formule réelle » alignée à gauche, insérer un espace, puis centrer la ligne « Régularisation (réel − payé) » sur la largeur de la page. 7. WHEN le Backend compose la fin d'un Export_PDF annuel, THE Backend SHALL centrer la ligne « Formule réelle » sur la largeur de la page, insérer un espace, puis centrer la ligne « Régularisation (réel − payé) » également sur la largeur de la page, cette dernière étant rendue en police de 14 pt et en gras pour la mettre en avant.
8. WHEN le Backend compose l'en-tête d'un Export_PDF mensuel, THE Backend SHALL obtenir le total annuel « à fin de mois » via `ITotauxService.GetTotauxAsync` (champ `TotalAnnuelPartiel`, cumul jusqu'au mois de restitution inclus), l'afficher sous le libellé « Total annuel (à fin de mois) », et SHALL déterminer la tranche de barème (coefficient, base, TOTAL IK du mois) en appliquant `IBaremeService.CalculerMontantAsync` à ce même cumul, et non au total des douze mois.
--- ---
+5 -5
View File
@@ -1554,7 +1554,7 @@ QuestPDF est une bibliothèque .NET open-source (licence MIT pour usage communau
│ │ │ Domicile : 29 route des Cascades, 23400 Saint-Pardoux-Morter. │ │ │ │ Domicile : 29 route des Cascades, 23400 Saint-Pardoux-Morter. │
│ └───────┘ Véhicule : GOLF (ES-036-YF) — 6 CV (Coef. : 0,447 / Base : 0) │ │ └───────┘ Véhicule : GOLF (ES-036-YF) — 6 CV (Coef. : 0,447 / Base : 0) │
│ Total parcouru sur le mois : 931 Kms TOTAL IK du mois : 416 € │ │ Total parcouru sur le mois : 931 Kms TOTAL IK du mois : 416 € │
│ Total parcouru sur l'année : 931 Kms Réglé : 500,00 € │ │ Total annuel (à fin de mois) : 931 Kms Réglé : 500,00 € │
├──────────────────────────────────────────────────────────────────────────── (trait pleine largeur) ├──────────────────────────────────────────────────────────────────────────── (trait pleine largeur)
├────────────┬────────────────┬───────────────────────────────┬─────┬────────┤ ├────────────┬────────────────┬───────────────────────────────┬─────┬────────┤
│ Date │ Motifs │ Départ → Arrivée │ A/R │ Kms │ │ Date │ Motifs │ Départ → Arrivée │ A/R │ Kms │
@@ -1568,7 +1568,7 @@ QuestPDF est une bibliothèque .NET open-source (licence MIT pour usage communau
(pied de page : Mention_Legale 5 pt justifiée, puis « Page X / Y ») (pied de page : Mention_Legale 5 pt justifiée, puis « Page X / Y »)
``` ```
> Le titre « RAPPORT DE TRAJETS » est désormais en majuscules. L'en-tête est disposé sur une rangée : logo carré agrandi (120 pt) aligné en haut à gauche ; à droite du logo, un bloc titre (titre + sous-titre « Feuille d'indemnité kilométrique {MOIS} {ANNEE} ») centré sur l'espace restant ; sous le bloc titre, le bloc d'infos (Utilisateur/Matricule, Domicile, Véhicule, totaux). Un trait séparateur horizontal est tracé sur toute la largeur de la page sous l'en-tête. Le libellé « Adresse de départ » devient « Domicile », positionné juste après la ligne Utilisateur/Matricule. Dans la table des Trajets, l'adresse d'arrivée passe à la ligne sous l'adresse de départ, précédée de « → » ; une colonne dédiée **« A/R »** (juste avant « Kms ») affiche un marqueur « X » pour un Aller_Retour (le suffixe « (A/R) » dans la cellule itinéraire est supprimé). Le « TOTAL IK du mois » = kilomètres du mois × coefficient de la tranche annuelle applicable. Le « Réglé » = Montant_Regle saisi pour le mois. Le motif affiché est le commentaire du Trajet. Les kilomètres (mois, année, table des trajets) sont formatés selon Precision_Distance. > Le titre « RAPPORT DE TRAJETS » est désormais en majuscules. L'en-tête est disposé sur une rangée : logo carré agrandi (120 pt) aligné en haut à gauche ; à droite du logo, un bloc titre (titre + sous-titre « Feuille d'indemnité kilométrique {MOIS} {ANNEE} ») centré sur l'espace restant ; sous le bloc titre, le bloc d'infos (Utilisateur/Matricule, Domicile, Véhicule, totaux). Un trait séparateur horizontal est tracé sur toute la largeur de la page sous l'en-tête. Le libellé « Adresse de départ » devient « Domicile », positionné juste après la ligne Utilisateur/Matricule. Dans la table des Trajets, l'adresse d'arrivée passe à la ligne sous l'adresse de départ, précédée de « → » ; une colonne dédiée **« A/R »** (juste avant « Kms ») affiche un marqueur « X » pour un Aller_Retour (le suffixe « (A/R) » dans la cellule itinéraire est supprimé). Le total annuel affiché porte le libellé « Total annuel (à fin de mois) » : c'est le cumul de l'année jusqu'au mois de restitution inclus (Total_Annuel_Partiel), obtenu via `ITotauxService`, et non le total des douze mois. La tranche de barème applicable (coefficient, base) et donc le « TOTAL IK du mois » (kilomètres du mois × coefficient de la tranche) sont déterminés sur ce même cumul « à fin de mois », pour rester cohérents avec le Panneau_Totaux du site et avec la situation à la date du mois même si le PDF est édité plus tard. Le « Réglé » = Montant_Regle saisi pour le mois. Le motif affiché est le commentaire du Trajet. Les kilomètres (mois, année, table des trajets) sont formatés selon Precision_Distance.
#### PDF Annuel (`AAAA_Trajets_MATRICULE_PLAQUE.pdf`) #### PDF Annuel (`AAAA_Trajets_MATRICULE_PLAQUE.pdf`)
@@ -1598,14 +1598,14 @@ QuestPDF est une bibliothèque .NET open-source (licence MIT pour usage communau
├────────────┼───────────────┼───────────────────┼────────────────────────────┤ ├────────────┼───────────────┼───────────────────┼────────────────────────────┤
│ TOTAL │ 12 241 │ 6 000,00 € │ 6 035,13 € │ │ TOTAL │ 12 241 │ 6 000,00 € │ 6 035,13 € │
├────────────┴───────────────┴───────────────────┴────────────────────────────┤ ├────────────┴───────────────┴───────────────────┴────────────────────────────┤
│ Formule réelle : 12241 km × 0,374 + 1457 = 6 035,13 € (tranche 5001–20000, 6 CV) │ │ Formule réelle : 12241 km × 0,374 + 1457 = 6 035,13 € (tranche 5001–20000) │ (centrée)
│ │ │ │
│ Régularisation (réel − payé) : 35,13 € (ligne centrée) │ │ Régularisation (réel − payé) : 35,13 € (centrée, 14 pt gras) │
└──────────────────────────────────────────────────────────────────────────────┘ └──────────────────────────────────────────────────────────────────────────────┘
(pied de page : Mention_Legale 5 pt justifiée, puis « Page X / Y ») (pied de page : Mention_Legale 5 pt justifiée, puis « Page X / Y »)
``` ```
> Le titre « RAPPORT DE TRAJETS » est en majuscules et son bloc titre (titre + sous-titre « Synthèse {Année} d'indemnité kilométrique ») est centré à droite du logo 120 pt ; le bloc d'infos est placé dessous. La ligne « Année : AAAA » reste retirée (redondante avec le titre). Un espace est ajouté après la ligne « Véhicule », puis « Barème applicable » et « Total kilométrique de l'année » sont présentés sur **deux colonnes côte à côte** (même agencement que le bloc totaux du rapport mensuel). Le titre du tableau barème rappelle le mode de calcul en toutes lettres : « Barème applicable pour l'année (N CV) — Kms parcourus × Coef + Base » (les valeurs coef/base effectivement appliquées apparaissent, elles, dans la « Formule réelle » en fin de document). En fin de document, un espace sépare la ligne « Formule réelle » (alignée à gauche) de la ligne « Régularisation (réel − payé) », désormais **centrée** sur la largeur de la page. Le « Frais réel » mensuel = kilomètres du mois × coefficient de la tranche annuelle. Le « Frais payé » = Montant_Regle saisi. La minoration 80% n'apparaît pas dans la synthèse : elle sert uniquement d'indication de versement en cours d'année. Les kilomètres (total annuel, table des mois, formule réelle) sont formatés selon Precision_Distance. > Le titre « RAPPORT DE TRAJETS » est en majuscules et son bloc titre (titre + sous-titre « Synthèse {Année} d'indemnité kilométrique ») est centré à droite du logo 120 pt ; le bloc d'infos est placé dessous. La ligne « Année : AAAA » reste retirée (redondante avec le titre). Un espace est ajouté après la ligne « Véhicule », puis « Barème applicable » et « Total kilométrique de l'année » sont présentés sur **deux colonnes côte à côte** (même agencement que le bloc totaux du rapport mensuel). Le titre du tableau barème rappelle le mode de calcul en toutes lettres : « Barème applicable pour l'année (N CV) — Kms parcourus × Coef + Base » (les valeurs coef/base effectivement appliquées apparaissent, elles, dans la « Formule réelle » en fin de document). En fin de document, la ligne « Formule réelle » est désormais **centrée** sur la largeur de la page (comme la régularisation) ; un espace la sépare de la ligne « Régularisation (réel − payé) », elle aussi **centrée** et rendue en **taille agrandie (14 pt, gras)** pour la mettre en avant en tant qu'action comptable finale. Le « Frais réel » mensuel = kilomètres du mois × coefficient de la tranche annuelle. Le « Frais payé » = Montant_Regle saisi. La minoration 80% n'apparaît pas dans la synthèse : elle sert uniquement d'indication de versement en cours d'année. Les kilomètres (total annuel, table des mois, formule réelle) sont formatés selon Precision_Distance.
> **Rapports distincts par véhicule** : si la période demandée (mois ou année) contient des Trajets associés à plusieurs Véhicules, le backend génère un fichier PDF distinct par Véhicule. Chaque PDF ne contient que les Trajets et montants du Véhicule concerné. > **Rapports distincts par véhicule** : si la période demandée (mois ou année) contient des Trajets associés à plusieurs Véhicules, le backend génère un fichier PDF distinct par Véhicule. Chaque PDF ne contient que les Trajets et montants du Véhicule concerné.
@@ -215,7 +215,7 @@ L'application permet de gérer un profil (identité, matricule, adresse de domic
6. WHEN l'utilisateur demande un export PDF (mensuel ou annuel), THE Backend SHALL n'inclure que les Trajets associés au Véhicule sélectionné et SHALL indiquer dans l'en-tête du PDF la plaque d'immatriculation et la Puissance_Fiscale du Véhicule concerné. 6. WHEN l'utilisateur demande un export PDF (mensuel ou annuel), THE Backend SHALL n'inclure que les Trajets associés au Véhicule sélectionné et SHALL indiquer dans l'en-tête du PDF la plaque d'immatriculation et la Puissance_Fiscale du Véhicule concerné.
7. WHEN le Backend génère un Export_PDF (mensuel ou annuel), THE Backend SHALL inclure dans l'en-tête du document : le nom, le prénom, le matricule de l'utilisateur, ainsi que la plaque d'immatriculation et la Puissance_Fiscale du Véhicule concerné. 7. WHEN le Backend génère un Export_PDF (mensuel ou annuel), THE Backend SHALL inclure dans l'en-tête du document : le nom, le prénom, le matricule de l'utilisateur, ainsi que la plaque d'immatriculation et la Puissance_Fiscale du Véhicule concerné.
8. IF des Trajets de plusieurs Véhicules existent pour la période (mois ou année) demandée, THEN THE Backend SHALL générer un rapport PDF distinct par Véhicule. 8. IF des Trajets de plusieurs Véhicules existent pour la période (mois ou année) demandée, THEN THE Backend SHALL générer un rapport PDF distinct par Véhicule.
9. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL faire figurer dans l'en-tête, à la suite de la ligne Utilisateur/Matricule : le Véhicule (plaque, puissance fiscale, coefficient et base de la tranche applicable), l'Adresse_Domicile du Profil sous le libellé "Domicile", le total kilométrique du mois, le total kilométrique annuel cumulé, le TOTAL IK du mois (kilomètres du mois × coefficient de la tranche annuelle) et le Montant_Regle du mois ; le titre du document SHALL intégrer le mois et l'année de la période couverte (ex. "Feuille d'indemnité kilométrique Janvier 2025") au lieu d'un titre fixe, et l'en-tête SHALL ne pas comporter de ligne distincte "Période". 9. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL faire figurer dans l'en-tête, à la suite de la ligne Utilisateur/Matricule : le Véhicule (plaque, puissance fiscale, coefficient et base de la tranche applicable), l'Adresse_Domicile du Profil sous le libellé "Domicile", le total kilométrique du mois, le total kilométrique annuel cumulé jusqu'au mois de restitution inclus (Total_Annuel_Partiel) sous le libellé "Total annuel (à fin de mois)", le TOTAL IK du mois (kilomètres du mois × coefficient de la tranche applicable) et le Montant_Regle du mois ; la tranche de barème applicable (donc son coefficient, sa base et le TOTAL IK du mois) SHALL être déterminée par ce total annuel cumulé jusqu'au mois de restitution inclus (et non par le total des douze mois), afin de rester cohérente avec le Panneau_Totaux du site et avec la situation à la date du mois même si le document est édité ultérieurement ; le titre du document SHALL intégrer le mois et l'année de la période couverte (ex. "Feuille d'indemnité kilométrique Janvier 2025") au lieu d'un titre fixe, et l'en-tête SHALL ne pas comporter de ligne distincte "Période".
10. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL faire figurer la liste des Trajets du mois avec, pour chaque Trajet : la date, le motif (commentaire), l'adresse de départ, l'adresse d'arrivée et la distance en kilomètres. 10. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL faire figurer la liste des Trajets du mois avec, pour chaque Trajet : la date, le motif (commentaire), l'adresse de départ, l'adresse d'arrivée et la distance en kilomètres.
11. WHEN le Backend génère un Export_PDF annuel (synthèse), THE Backend SHALL faire figurer : le nom et le prénom de l'utilisateur, l'adresse de domicile, le Bareme_Kilometrique applicable pour l'année, le Véhicule et sa puissance fiscale, la tranche applicable ; puis pour chacun des douze mois : les kilomètres parcourus, le Montant_Regle (frais payé) et le Frais_Reel_Mensuel (frais réel) ; et enfin les totaux : total kilométrique annuel, total réglé, Montant_Reel, et Regularisation (Montant_Reel − total réglé) ; le titre du document SHALL indiquer l'année couverte (ex. "Synthèse 2025 d'indemnité kilométrique"), et l'en-tête SHALL ne pas comporter de ligne distincte "Année" dès lors que l'année figure déjà dans ce titre. 11. WHEN le Backend génère un Export_PDF annuel (synthèse), THE Backend SHALL faire figurer : le nom et le prénom de l'utilisateur, l'adresse de domicile, le Bareme_Kilometrique applicable pour l'année, le Véhicule et sa puissance fiscale, la tranche applicable ; puis pour chacun des douze mois : les kilomètres parcourus, le Montant_Regle (frais payé) et le Frais_Reel_Mensuel (frais réel) ; et enfin les totaux : total kilométrique annuel, total réglé, Montant_Reel, et Regularisation (Montant_Reel − total réglé) ; le titre du document SHALL indiquer l'année couverte (ex. "Synthèse 2025 d'indemnité kilométrique"), et l'en-tête SHALL ne pas comporter de ligne distincte "Année" dès lors que l'année figure déjà dans ce titre.
12. WHEN le Backend génère un Export_PDF (mensuel ou annuel), THE Backend SHALL exprimer tous les kilomètres affichés dans le document (totaux d'en-tête, table des Trajets, table de synthèse annuelle, formule réelle) avec le nombre de décimales défini par Precision_Distance (voir spec `precision-distances-km`, Requirements 1, 3, 4, 5), au lieu d'une précision fixe à deux décimales. 12. WHEN le Backend génère un Export_PDF (mensuel ou annuel), THE Backend SHALL exprimer tous les kilomètres affichés dans le document (totaux d'en-tête, table des Trajets, table de synthèse annuelle, formule réelle) avec le nombre de décimales défini par Precision_Distance (voir spec `precision-distances-km`, Requirements 1, 3, 4, 5), au lieu d'une précision fixe à deux décimales.
@@ -223,6 +223,7 @@ L'application permet de gérer un profil (identité, matricule, adresse de domic
14. WHEN le Backend génère un Export_PDF (mensuel ou annuel), THE Backend SHALL faire figurer en pied de page la Mention_Legale suivante : « Les kilomètres restitués dans le présent document sont déclarés par l'utilisateur sur l'honneur et sous sa seule responsabilité. Le calcul de l'indemnité kilométrique est fourni à titre purement indicatif, sur la base du barème kilométrique officiel en vigueur. SchotzIAD ne saurait être tenue responsable d'une quelconque erreur ou omission dans les données saisies ni du montant résultant du calcul. Le présent document ne constitue pas un justificatif opposable aux administrations. » 14. WHEN le Backend génère un Export_PDF (mensuel ou annuel), THE Backend SHALL faire figurer en pied de page la Mention_Legale suivante : « Les kilomètres restitués dans le présent document sont déclarés par l'utilisateur sur l'honneur et sous sa seule responsabilité. Le calcul de l'indemnité kilométrique est fourni à titre purement indicatif, sur la base du barème kilométrique officiel en vigueur. SchotzIAD ne saurait être tenue responsable d'une quelconque erreur ou omission dans les données saisies ni du montant résultant du calcul. Le présent document ne constitue pas un justificatif opposable aux administrations. »
15. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL faire figurer dans la liste des Trajets une colonne dédiée "A/R" affichant un marqueur lorsque le Trajet est un Aller_Retour et restant vide sinon, l'indicateur Aller_Retour n'étant plus signalé dans la cellule de l'itinéraire. 15. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL faire figurer dans la liste des Trajets une colonne dédiée "A/R" affichant un marqueur lorsque le Trajet est un Aller_Retour et restant vide sinon, l'indicateur Aller_Retour n'étant plus signalé dans la cellule de l'itinéraire.
16. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL présenter, pour chaque Trajet de la liste, l'adresse d'arrivée sur une ligne distincte sous l'adresse de départ, précédée du symbole "→". 16. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL présenter, pour chaque Trajet de la liste, l'adresse d'arrivée sur une ligne distincte sous l'adresse de départ, précédée du symbole "→".
17. WHEN le Backend génère un Export_PDF annuel (synthèse), THE Backend SHALL présenter, en fin de document, la ligne « Formule réelle » et la ligne « Régularisation (réel − payé) » centrées sur la largeur de la page, la ligne « Régularisation » étant affichée dans une taille de police supérieure à celle du reste du document pour la mettre en avant en tant qu'action finale à entreprendre.
--- ---
@@ -30,6 +30,7 @@ public class PdfService : IPdfService
private readonly IMontantRegleService _montantRegleService; private readonly IMontantRegleService _montantRegleService;
private readonly IRemboursementService _remboursementService; private readonly IRemboursementService _remboursementService;
private readonly IPrecisionDistanceService _precisionDistanceService; private readonly IPrecisionDistanceService _precisionDistanceService;
private readonly ITotauxService _totauxService;
private readonly AppDbContext _context; private readonly AppDbContext _context;
/// <summary>Logo carré, chargé une seule fois depuis la ressource embarquée (Assets/logo-carre.png).</summary> /// <summary>Logo carré, chargé une seule fois depuis la ressource embarquée (Assets/logo-carre.png).</summary>
@@ -43,6 +44,7 @@ public class PdfService : IPdfService
IMontantRegleService montantRegleService, IMontantRegleService montantRegleService,
IRemboursementService remboursementService, IRemboursementService remboursementService,
IPrecisionDistanceService precisionDistanceService, IPrecisionDistanceService precisionDistanceService,
ITotauxService totauxService,
AppDbContext context) AppDbContext context)
{ {
_resumeService = resumeService; _resumeService = resumeService;
@@ -52,6 +54,7 @@ public class PdfService : IPdfService
_montantRegleService = montantRegleService; _montantRegleService = montantRegleService;
_remboursementService = remboursementService; _remboursementService = remboursementService;
_precisionDistanceService = precisionDistanceService; _precisionDistanceService = precisionDistanceService;
_totauxService = totauxService;
_context = context; _context = context;
} }
@@ -228,11 +231,15 @@ public class PdfService : IPdfService
// Résumé mensuel filtré sur le véhicule (trajets triés + total km du mois). // Résumé mensuel filtré sur le véhicule (trajets triés + total km du mois).
var resumeMensuel = await _resumeService.GetResumeMensuelAsync(annee, mois, vehiculeId, cancellationToken); var resumeMensuel = await _resumeService.GetResumeMensuelAsync(annee, mois, vehiculeId, cancellationToken);
// Total kilométrique annuel cumulé (tous mois de l'année, même véhicule). // Total annuel « à fin de mois » : cumul de l'année jusqu'au mois de restitution INCLUS
var resumeAnnuel = await _resumeService.GetResumeAnnuelAsync(annee, vehiculeId, cancellationToken); // (Total_Annuel_Partiel), cohérent avec le Panneau_Totaux du site et avec la situation à la
var totalKmAnnuel = resumeAnnuel.TotalKm; // date du mois — y compris si le PDF est édité plusieurs mois plus tard. Les distances
// sommées sont déjà arrondies selon Precision_Distance et tiennent compte des allers/retours.
var totaux = await _totauxService.GetTotauxAsync(new DateOnly(annee, mois, 1), vehiculeId, cancellationToken);
var totalKmAnnuel = totaux.TotalAnnuelPartiel;
// Coefficient et base de la tranche ANNUELLE applicable (déterminée par le total annuel). // Coefficient et base de la tranche applicable, déterminée par ce même cumul « à fin de mois »
// (et non par le total des 12 mois), pour rester cohérent avec l'affichage du site.
var bareme = await _baremeService.CalculerMontantAsync( var bareme = await _baremeService.CalculerMontantAsync(
annee, vehicule.PuissanceFiscale, totalKmAnnuel, cancellationToken); annee, vehicule.PuissanceFiscale, totalKmAnnuel, cancellationToken);
@@ -420,7 +427,7 @@ public class PdfService : IPdfService
}); });
c.Item().Text(txt => c.Item().Text(txt =>
{ {
txt.Span("Total parcouru sur l'année : ").SemiBold(); txt.Span("Total annuel (à fin de mois) : ").SemiBold();
txt.Span($"{FormatKm(modele.TotalKmAnnuel, precision)} km"); txt.Span($"{FormatKm(modele.TotalKmAnnuel, precision)} km");
}); });
}); });
@@ -765,14 +772,17 @@ public class PdfService : IPdfService
container.Column(col => container.Column(col =>
{ {
col.Spacing(3); col.Spacing(3);
col.Item().Text(txt => // Formule réelle centrée (comme la régularisation).
col.Item().AlignCenter().Text(txt =>
{ {
txt.Span("Formule réelle : ").SemiBold(); txt.Span("Formule réelle : ").SemiBold();
txt.Span(formule); txt.Span(formule);
}); });
// Espace entre la formule réelle et la régularisation, puis régularisation centrée. // Espace puis régularisation centrée, mise en avant (14 pt) car c'est l'action
// comptable finale à entreprendre (régulariser les frais).
col.Item().PaddingTop(8).AlignCenter().Text(txt => col.Item().PaddingTop(8).AlignCenter().Text(txt =>
{ {
txt.DefaultTextStyle(x => x.FontSize(14));
txt.Span("Régularisation (réel − payé) : ").SemiBold(); txt.Span("Régularisation (réel − payé) : ").SemiBold();
txt.Span($"{FormatMontant(reg.Regularisation)} €"); txt.Span($"{FormatMontant(reg.Regularisation)} €");
}); });
@@ -50,6 +50,7 @@ public class PdfServiceIntegrationTests : IDisposable
var vehiculeRepository = new VehiculeRepository(_context); var vehiculeRepository = new VehiculeRepository(_context);
var vehiculeService = new VehiculeService(vehiculeRepository, _context); var vehiculeService = new VehiculeService(vehiculeRepository, _context);
var totauxService = new TotauxService(_context, vehiculeService, precisionDistanceService);
var adresseCacheRepository = new AdresseCacheRepository(_context); var adresseCacheRepository = new AdresseCacheRepository(_context);
var adresseCacheService = new AdresseCacheService(adresseCacheRepository, _context); var adresseCacheService = new AdresseCacheService(adresseCacheRepository, _context);
@@ -65,6 +66,7 @@ public class PdfServiceIntegrationTests : IDisposable
montantRegleService, montantRegleService,
remboursementService, remboursementService,
precisionDistanceService, precisionDistanceService,
totauxService,
_context); _context);
} }