From 3bbbf773f42f8ef50230abb693052a8fb756fb7e Mon Sep 17 00:00:00 2001 From: Nessar Date: Sun, 19 Jul 2026 01:51:25 +0200 Subject: [PATCH] feat: enhance date formatting in rental documents and receipts --- .../pdf/ThymeleafRentalDocumentRenderer.java | 28 +++++++++++++++++-- .../resources/templates/rental/lease.html | 2 +- .../templates/rental/payment-receipt.html | 8 +++--- .../templates/rental/rent-receipt.html | 4 +-- .../ThymeleafRentalDocumentRendererTest.java | 19 +++++++++---- 5 files changed, 46 insertions(+), 15 deletions(-) diff --git a/backend/src/main/java/fr/nessar/lmnporganizer/rental/adapter/out/pdf/ThymeleafRentalDocumentRenderer.java b/backend/src/main/java/fr/nessar/lmnporganizer/rental/adapter/out/pdf/ThymeleafRentalDocumentRenderer.java index ffaf540..76592dc 100644 --- a/backend/src/main/java/fr/nessar/lmnporganizer/rental/adapter/out/pdf/ThymeleafRentalDocumentRenderer.java +++ b/backend/src/main/java/fr/nessar/lmnporganizer/rental/adapter/out/pdf/ThymeleafRentalDocumentRenderer.java @@ -8,13 +8,17 @@ import org.thymeleaf.context.Context; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.time.format.DateTimeFormatter; +import java.time.LocalDate; +import java.time.Month; +import java.time.YearMonth; +import java.time.format.TextStyle; +import java.time.temporal.TemporalAccessor; import java.util.List; import java.util.Locale; @Component public class ThymeleafRentalDocumentRenderer implements RentalDocumentRenderer { - private static final DateTimeFormatter MONTH = DateTimeFormatter.ofPattern("MMMM yyyy", Locale.FRANCE); + private static final FrenchDates DATES = new FrenchDates(); private final TemplateEngine templates; @@ -45,13 +49,13 @@ public class ThymeleafRentalDocumentRenderer implements RentalDocumentRenderer { Context context = context(document); context.setVariable("tenantNames", names(document.contract().tenants().stream() .map(tenant -> tenant.firstName() + " " + tenant.lastName()).toList())); - context.setVariable("receiptMonth", document.month().format(MONTH)); return render("rental/rent-receipt", context); } private Context context(Object document) { Context context = new Context(Locale.FRANCE); context.setVariable("document", document); + context.setVariable("dates", DATES); return context; } @@ -68,4 +72,22 @@ public class ThymeleafRentalDocumentRenderer implements RentalDocumentRenderer { private static String names(List names) { return names.isEmpty() ? "Aucun" : String.join(", ", names); } + + public static final class FrenchDates { + private FrenchDates() { + } + + public String date(LocalDate date) { + return date.getDayOfMonth() + " " + monthName(date) + " " + date.getYear(); + } + + public String month(YearMonth month) { + return monthName(month) + " " + month.getYear(); + } + + private static String monthName(TemporalAccessor date) { + String month = Month.from(date).getDisplayName(TextStyle.FULL, Locale.FRANCE); + return Character.toUpperCase(month.charAt(0)) + month.substring(1); + } + } } diff --git a/backend/src/main/resources/templates/rental/lease.html b/backend/src/main/resources/templates/rental/lease.html index 78c642f..7706504 100644 --- a/backend/src/main/resources/templates/rental/lease.html +++ b/backend/src/main/resources/templates/rental/lease.html @@ -24,7 +24,7 @@ Téléphone du bailleur+33612345678 Adresse du bailleur1 rue de Paris Locataire(s)Camille Martin - Période2026-09-01 au 2027-08-31 + Période1 Septembre 2026 au 31 Août 2027 Loyer mensuel850.00 EUR Charges mensuelles50.00 EUR Dépôt de garantie850.00 EUR diff --git a/backend/src/main/resources/templates/rental/payment-receipt.html b/backend/src/main/resources/templates/rental/payment-receipt.html index 0f75c05..34910ad 100644 --- a/backend/src/main/resources/templates/rental/payment-receipt.html +++ b/backend/src/main/resources/templates/rental/payment-receipt.html @@ -18,7 +18,7 @@ BailleurLéa Dubois Logement12 rue de la République Locataire(s)Camille Martin - Reçu le2026-07-05 + Reçu le5 Juillet 2026 Montant reçu1200.00 EUR Montant remboursé0.00 EUR Solde non affecté300.00 EUR @@ -28,9 +28,9 @@ MoisMontantDate - 2026-07 + Juillet 2026 900.00 EUR - 2026-07-05 + 5 Juillet 2026 Aucune affectation @@ -42,7 +42,7 @@ refund-1 100.00 EUR - 2026-07-06 + 6 Juillet 2026 Aucun remboursement diff --git a/backend/src/main/resources/templates/rental/rent-receipt.html b/backend/src/main/resources/templates/rental/rent-receipt.html index cc483c9..a3b1881 100644 --- a/backend/src/main/resources/templates/rental/rent-receipt.html +++ b/backend/src/main/resources/templates/rental/rent-receipt.html @@ -21,11 +21,11 @@ LogementStudio République Adresse12 rue de la République Locataire(s)Camille Martin - Périodejuillet 2026 + PériodeJuillet 2026 Loyer850.00 EUR Charges50.00 EUR Total réglé900.00 EUR -
Quittance générée le 2026-07-18. Le surplus non affecté n'est pas inclus.
+ diff --git a/backend/src/test/java/fr/nessar/lmnporganizer/rental/adapter/out/pdf/ThymeleafRentalDocumentRendererTest.java b/backend/src/test/java/fr/nessar/lmnporganizer/rental/adapter/out/pdf/ThymeleafRentalDocumentRendererTest.java index 2b2ba82..639e077 100644 --- a/backend/src/test/java/fr/nessar/lmnporganizer/rental/adapter/out/pdf/ThymeleafRentalDocumentRendererTest.java +++ b/backend/src/test/java/fr/nessar/lmnporganizer/rental/adapter/out/pdf/ThymeleafRentalDocumentRendererTest.java @@ -48,8 +48,8 @@ class ThymeleafRentalDocumentRendererTest { ThymeleafRentalDocumentRenderer renderer = new ThymeleafRentalDocumentRenderer(templateEngine()); LeaseContractVersion contract = contract(); ReceiptAllocation allocation = new ReceiptAllocation(new PaymentAllocationId("allocation-1"), - new RentDueId("due-1"), YearMonth.of(2026, 7), new BigDecimal("950.00"), - LocalDate.of(2026, 7, 5)); + new RentDueId("due-1"), YearMonth.of(2026, 6), new BigDecimal("950.00"), + LocalDate.of(2026, 8, 6)); byte[] lease = renderer.renderLease(new LeaseDocument(new LeaseId("lease-1"), contract.landlord(), contract.apartment(), contract.tenants(), contract.guarantors(), contract.period(), contract.terms())); @@ -57,18 +57,27 @@ class ThymeleafRentalDocumentRendererTest { LocalDate.of(2026, 7, 5), LocalDate.of(2026, 7, 6), new BigDecimal("1200.00"), new BigDecimal("50.00"), new BigDecimal("200.00"), contract, List.of(allocation), List.of(new ReceiptRefund(new RentPaymentRefundId("refund-1"), new BigDecimal("50.00"), - LocalDate.of(2026, 7, 6))))); + LocalDate.of(2026, 9, 7))))); byte[] rentReceipt = renderer.renderRentReceipt(new RentReceipt(new RentDueId("due-1"), - YearMonth.of(2026, 7), new BigDecimal("900.00"), new BigDecimal("50.00"), - new BigDecimal("950.00"), LocalDate.of(2026, 7, 18), contract)); + YearMonth.of(2026, 10), new BigDecimal("900.00"), new BigDecimal("50.00"), + new BigDecimal("950.00"), LocalDate.of(2026, 7, 19), contract)); assertAll(() -> assertPdf(lease), () -> assertPdf(paymentReceipt), () -> assertPdf(rentReceipt)); + String leaseText = pdfText(lease); + assertTrue(leaseText.contains("1 Janvier 2026")); + assertTrue(leaseText.contains("31 Décembre 2026")); String paymentText = pdfText(paymentReceipt); + assertTrue(paymentText.contains("5 Juillet 2026")); + assertTrue(paymentText.contains("Juin 2026")); + assertTrue(paymentText.contains("6 Août 2026")); + assertTrue(paymentText.contains("7 Septembre 2026")); assertTrue(paymentText.contains("1200.00")); assertTrue(paymentText.contains("950.00")); assertTrue(paymentText.contains("200.00")); assertTrue(paymentText.contains("refund-1")); String rentText = pdfText(rentReceipt); + assertTrue(rentText.contains("Octobre 2026")); + assertTrue(rentText.contains("19 Juillet 2026")); assertTrue(rentText.contains("900.00")); assertTrue(rentText.contains("50.00")); assertFalse(rentText.contains("1200.00"));