From e1c2c2cc29f89ce6e9d8d5e8996c0dfca810034f Mon Sep 17 00:00:00 2001
From: aichatou <aichatou.coulibaly@etu.univ-amu.fr>
Date: Mon, 24 Mar 2025 12:26:34 +0100
Subject: [PATCH] Facture

---
 .../controllers/AdminController.java          | 18 +++++++
 .../controllers/DoctorController.java         | 28 ++++++++--
 .../projetIndu/entities/Appointment.java      |  3 ++
 .../projet/projetIndu/entities/Doctor.java    |  2 -
 .../projet/projetIndu/entities/Invoice.java   | 54 +++++++++++++++++++
 .../projetIndu/entities/MedicalDocument.java  |  7 +++
 .../projetIndu/entities/PaymentStatus.java    |  5 +-
 .../com/projet/projetIndu/entities/User.java  |  6 ++-
 .../repositories/InvoiceRepository.java       | 10 +++-
 .../services/AppointmentService.java          | 17 +++++-
 .../projetIndu/services/DoctorService.java    | 16 +++++-
 .../projetIndu/services/InvoiceService.java   | 34 ++++++++++--
 .../projetIndu/services/PatientService.java   | 15 +++++-
 src/main/resources/application.properties     |  2 +-
 .../resources/templates/admin-dashboard.html  | 11 +++-
 .../resources/templates/doctor-dashboard.html | 14 +++--
 .../resources/templates/doctor-invoices.html  | 51 ++++++++++++++++--
 src/main/resources/templates/invoices.html    | 53 +++++++++++++++---
 18 files changed, 310 insertions(+), 36 deletions(-)

diff --git a/src/main/java/com/projet/projetIndu/controllers/AdminController.java b/src/main/java/com/projet/projetIndu/controllers/AdminController.java
index 7b5cfa3..b3fc248 100644
--- a/src/main/java/com/projet/projetIndu/controllers/AdminController.java
+++ b/src/main/java/com/projet/projetIndu/controllers/AdminController.java
@@ -3,10 +3,12 @@ package com.projet.projetIndu.controllers;
 import com.projet.projetIndu.entities.Doctor;
 import com.projet.projetIndu.services.DoctorService;
 import com.projet.projetIndu.services.PatientService;
+import com.projet.projetIndu.services.InvoiceService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 
@@ -19,6 +21,9 @@ public class AdminController {
     @Autowired
     private PatientService patientService;
 
+    @Autowired
+    private InvoiceService invoiceService;
+
     @GetMapping("/dashboard")
     public String adminDashboard() {
         return "admin-dashboard";
@@ -47,4 +52,17 @@ public class AdminController {
         model.addAttribute("doctors", doctorService.getAllDoctors());
         return "doctors";
     }
+    @GetMapping("/invoices")
+    public String invoices(Model model) {
+        model.addAttribute("invoices", invoiceService.getAllInvoices());
+        return "invoices"; // Page HTML pour afficher les factures
+    }
+
+    @PostMapping("/invoices/{id}/pay")
+    public String markInvoiceAsPaid(@PathVariable Long id) {
+        invoiceService.markAsPaid(id);
+        return "redirect:/admin/invoices";
+    }
+
+
 }
diff --git a/src/main/java/com/projet/projetIndu/controllers/DoctorController.java b/src/main/java/com/projet/projetIndu/controllers/DoctorController.java
index d365e24..7518b4c 100644
--- a/src/main/java/com/projet/projetIndu/controllers/DoctorController.java
+++ b/src/main/java/com/projet/projetIndu/controllers/DoctorController.java
@@ -1,15 +1,17 @@
 package com.projet.projetIndu.controllers;
 
 import com.projet.projetIndu.entities.Doctor;
+import com.projet.projetIndu.entities.Invoice;
 import com.projet.projetIndu.entities.Patient;
 import com.projet.projetIndu.services.DoctorService;
+import com.projet.projetIndu.services.InvoiceService;
 import com.projet.projetIndu.services.PatientService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.*;
 
+import java.security.Principal;
 import java.util.List;
 
 @RequestMapping("/doctors")
@@ -18,6 +20,9 @@ public class DoctorController {
     private final DoctorService doctorService;
     private final PatientService patientService;
 
+    @Autowired
+    private InvoiceService invoiceService;
+
 
     public DoctorController(DoctorService doctorService, PatientService patientService) {
         this.doctorService = doctorService;
@@ -49,4 +54,21 @@ public class DoctorController {
         model.addAttribute("patients", patients);
         return "patients";
     }
+    /*@GetMapping("/invoices")
+    public String viewDoctorInvoices(Model model, Principal principal) {
+        // Récupérer le nom d'utilisateur du médecin connecté (supposons qu'il soit stocké dans `principal`)
+        String doctorUsername = principal.getName();
+
+        // Récupérer les factures des patients du médecin connecté
+        List<Invoice> doctorInvoices = invoiceService.getInvoicesByDoctorUsername(doctorUsername);
+
+        model.addAttribute("invoices", doctorInvoices);
+        return "doctor-invoices"; // Page HTML pour afficher les factures
+    }
+
+    @PostMapping("/invoices/{id}/pay")
+    public String markInvoiceAsPaid(@PathVariable Long id) {
+        invoiceService.markAsPaid(id);
+        return "redirect:/doctor/invoices";
+    }*/
 }
diff --git a/src/main/java/com/projet/projetIndu/entities/Appointment.java b/src/main/java/com/projet/projetIndu/entities/Appointment.java
index 5af4c61..db9c1d3 100644
--- a/src/main/java/com/projet/projetIndu/entities/Appointment.java
+++ b/src/main/java/com/projet/projetIndu/entities/Appointment.java
@@ -57,4 +57,7 @@ public class Appointment {
     }
 
 
+    public void setStatus(AppointmentStatus appointmentStatus) {
+        this.status= appointmentStatus;
+    }
 }
diff --git a/src/main/java/com/projet/projetIndu/entities/Doctor.java b/src/main/java/com/projet/projetIndu/entities/Doctor.java
index cc524e6..c372550 100644
--- a/src/main/java/com/projet/projetIndu/entities/Doctor.java
+++ b/src/main/java/com/projet/projetIndu/entities/Doctor.java
@@ -27,6 +27,4 @@ public class Doctor extends User {
         this.role = Role.DOCTOR;
         this.speciality = speciality;
     }
-
-
 }
diff --git a/src/main/java/com/projet/projetIndu/entities/Invoice.java b/src/main/java/com/projet/projetIndu/entities/Invoice.java
index 7cef425..5e394bf 100644
--- a/src/main/java/com/projet/projetIndu/entities/Invoice.java
+++ b/src/main/java/com/projet/projetIndu/entities/Invoice.java
@@ -1,4 +1,58 @@
 package com.projet.projetIndu.entities;
 
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "invoices")
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
 public class Invoice {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @OneToOne(mappedBy = "invoice")
+    private Appointment appointment;
+
+    @Column(nullable = false)
+    private Double amount;
+
+    @Enumerated(EnumType.STRING)
+    private PaymentStatus status;
+
+    @Column(nullable = false, updatable = false)
+    private LocalDateTime issueDate = LocalDateTime.now();
+
+
+    @ManyToOne
+    @JoinColumn(name = "doctor_id")
+    private Doctor doctor; //
+
+    public Invoice(Appointment appointment, Double amount) {
+        this.appointment = appointment;
+        this.amount = amount;
+        this.status = PaymentStatus.PENDING;
+        this.issueDate = LocalDateTime.now();
+    }
+
+    public void setStatus(PaymentStatus status) {
+        this.status = status;
+    }
+
+    public PaymentStatus getStatus() {
+        return status;
+    }
+    public Doctor getDoctor() {
+        return doctor;
+    }
+
+    public void setDoctor(Doctor doctor) {
+        this.doctor = doctor;
+    }
 }
diff --git a/src/main/java/com/projet/projetIndu/entities/MedicalDocument.java b/src/main/java/com/projet/projetIndu/entities/MedicalDocument.java
index fab8f16..b8e88e6 100644
--- a/src/main/java/com/projet/projetIndu/entities/MedicalDocument.java
+++ b/src/main/java/com/projet/projetIndu/entities/MedicalDocument.java
@@ -24,4 +24,11 @@ public class MedicalDocument {
     @JoinColumn(name = "medical_file_id", nullable = true)
     private MedicalFile medicalFile;
 
+    public String getFileName() {
+        return fileName;
+    }
+
+    public byte[] getFileData() {
+        return fileData;
+    }
 }
diff --git a/src/main/java/com/projet/projetIndu/entities/PaymentStatus.java b/src/main/java/com/projet/projetIndu/entities/PaymentStatus.java
index 65cc0e5..d719826 100644
--- a/src/main/java/com/projet/projetIndu/entities/PaymentStatus.java
+++ b/src/main/java/com/projet/projetIndu/entities/PaymentStatus.java
@@ -1,4 +1,7 @@
 package com.projet.projetIndu.entities;
 
-public class PaymentStatus {
+public enum PaymentStatus {
+    PENDING, // En attente
+    PAID,    // Payé
+    CANCELLED // Annulé
 }
diff --git a/src/main/java/com/projet/projetIndu/entities/User.java b/src/main/java/com/projet/projetIndu/entities/User.java
index bfc67a3..9cee911 100644
--- a/src/main/java/com/projet/projetIndu/entities/User.java
+++ b/src/main/java/com/projet/projetIndu/entities/User.java
@@ -61,8 +61,10 @@ public abstract class User {
         this.email = email;
         this.password = password;
     }
-
-
     public void setId(Long id) {
     }
+
+    public long getId() {
+        return id;
+    }
 }
diff --git a/src/main/java/com/projet/projetIndu/repositories/InvoiceRepository.java b/src/main/java/com/projet/projetIndu/repositories/InvoiceRepository.java
index 38e7759..a5a03a9 100644
--- a/src/main/java/com/projet/projetIndu/repositories/InvoiceRepository.java
+++ b/src/main/java/com/projet/projetIndu/repositories/InvoiceRepository.java
@@ -2,7 +2,15 @@ package com.projet.projetIndu.repositories;
 
 import com.projet.projetIndu.entities.Invoice;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
 
-public interface InvoiceRepository extends JpaRepository<Invoice, Long> {
+import java.time.LocalDate;
+import java.util.List;
 
+@Repository
+public interface InvoiceRepository extends JpaRepository<Invoice, Long> {
+    List<Invoice> findInvoicesByIssueDateBetween(LocalDate startDate, LocalDate endDate);
 }
+
diff --git a/src/main/java/com/projet/projetIndu/services/AppointmentService.java b/src/main/java/com/projet/projetIndu/services/AppointmentService.java
index 5f41a66..6a464d2 100644
--- a/src/main/java/com/projet/projetIndu/services/AppointmentService.java
+++ b/src/main/java/com/projet/projetIndu/services/AppointmentService.java
@@ -13,10 +13,12 @@ import java.util.Optional;
 @Service
 public class AppointmentService {
     private final AppointmentRepository appointmentRepository;
+    private final InvoiceService invoiceService;  // Ajoutez cette ligne pour l'injection du service InvoiceService
 
     @Autowired
-    public AppointmentService(AppointmentRepository appointmentRepository) {
+    public AppointmentService(AppointmentRepository appointmentRepository, InvoiceService invoiceService) {
         this.appointmentRepository = appointmentRepository;
+        this.invoiceService = invoiceService;  // Initialisez invoiceService dans le constructeur
     }
 
     public List<Appointment> getAllAppointments() {
@@ -43,7 +45,7 @@ public class AppointmentService {
         Optional<Appointment> optionalAppointment = appointmentRepository.findById(id);
         if (optionalAppointment.isPresent()) {
             Appointment appointment = optionalAppointment.get();
-            appointment.setStatus(AppointmentStatus.valueOf("CANCELLED"));
+            appointment.setStatus(AppointmentStatus.CANCELLED);
             appointmentRepository.save(appointment);
         }
     }
@@ -62,8 +64,19 @@ public class AppointmentService {
             Appointment appointment = optionalAppointment.get();
             appointment.setStatus(AppointmentStatus.CONFIRMED);
             appointmentRepository.save(appointment);
+
+            // Création automatique d'une facture
+            double amount = calculateAmount(appointment); // Méthode à définir pour calculer le montant
+            invoiceService.createInvoice(appointment, amount); // Création de la facture
         } else {
             throw new RuntimeException("Rendez-vous introuvable.");
         }
     }
+
+    private double calculateAmount(Appointment appointment) {
+        // Calculer le montant en fonction du type de médecin, de la durée, etc.
+        // Exemple avec un montant fixe
+        return 50.0;
+    }
+
 }
diff --git a/src/main/java/com/projet/projetIndu/services/DoctorService.java b/src/main/java/com/projet/projetIndu/services/DoctorService.java
index 3b69c9f..7f3486a 100644
--- a/src/main/java/com/projet/projetIndu/services/DoctorService.java
+++ b/src/main/java/com/projet/projetIndu/services/DoctorService.java
@@ -45,13 +45,27 @@ public class DoctorService {
         doctorRepository.deleteById(id);
     }
 
-    public Long getAuthenticatedDoctorId() {
+    /*public Long getAuthenticatedDoctorId() {
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
         String email = authentication.getName();
         return doctorRepository.findByEmail(email)
                 .map(Doctor::getId)
                 .orElseThrow(() -> new RuntimeException("Médecin non trouvé"));
+    }*/
+    public Long getAuthenticatedDoctorId() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        String email = authentication.getName();
+
+        Optional<Doctor> doctorOpt = doctorRepository.findByEmail(email);
+
+        if (doctorOpt.isPresent()) {
+            return (Long) doctorOpt.get().getId(); // Cast en Long
+        } else {
+            throw new RuntimeException("Médecin non trouvé");
+        }
     }
+
+
 }
 
 
diff --git a/src/main/java/com/projet/projetIndu/services/InvoiceService.java b/src/main/java/com/projet/projetIndu/services/InvoiceService.java
index 8342019..ade97d9 100644
--- a/src/main/java/com/projet/projetIndu/services/InvoiceService.java
+++ b/src/main/java/com/projet/projetIndu/services/InvoiceService.java
@@ -1,15 +1,19 @@
 package com.projet.projetIndu.services;
 
+import com.projet.projetIndu.entities.Appointment;
 import com.projet.projetIndu.entities.Invoice;
+import com.projet.projetIndu.entities.PaymentStatus;
 import com.projet.projetIndu.repositories.InvoiceRepository;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDate;
 import java.util.List;
 import java.util.Optional;
 
 @Service
 public class InvoiceService {
+
     private final InvoiceRepository invoiceRepository;
 
     @Autowired
@@ -25,11 +29,33 @@ public class InvoiceService {
         return invoiceRepository.findById(id);
     }
 
-    public void deleteInvoiceById(Long id) {
-        invoiceRepository.deleteById(id);
+    public Invoice createInvoice(Appointment appointment, Double amount) {
+        Invoice invoice = new Invoice(appointment, amount);
+        return invoiceRepository.save(invoice);
     }
 
-    public Invoice saveInvoice(Invoice invoice) {
-        return invoiceRepository.save(invoice);
+    public void markAsPaid(Long invoiceId) {
+        Optional<Invoice> optionalInvoice = invoiceRepository.findById(invoiceId);
+        if (optionalInvoice.isPresent()) {
+            Invoice invoice = optionalInvoice.get();
+            invoice.setStatus(PaymentStatus.PAID); // Changer le statut de paiement
+            invoiceRepository.save(invoice); // Sauvegarder la facture mise à jour
+        } else {
+            throw new RuntimeException("Facture non trouvée");
+        }
+    }
+    public List<Invoice> getInvoicesByPeriod(LocalDate startDate, LocalDate endDate) {
+        return invoiceRepository.findInvoicesByIssueDateBetween(startDate, endDate); // Implémenter la méthode dans le repository
+    }
+
+    public double calculateMonthlyRevenue(LocalDate month) {
+        LocalDate startDate = month.withDayOfMonth(1);
+        LocalDate endDate = startDate.plusMonths(1).minusDays(1);
+
+        List<Invoice> invoices = getInvoicesByPeriod(startDate, endDate);
+        return invoices.stream().mapToDouble(Invoice::getAmount).sum(); // Somme des montants des factures
     }
+
+
+
 }
diff --git a/src/main/java/com/projet/projetIndu/services/PatientService.java b/src/main/java/com/projet/projetIndu/services/PatientService.java
index b234e8d..2d99d54 100644
--- a/src/main/java/com/projet/projetIndu/services/PatientService.java
+++ b/src/main/java/com/projet/projetIndu/services/PatientService.java
@@ -43,15 +43,28 @@ public class PatientService {
     }
 
 
-    public Long getAuthenticatedPatientId() {
+    /*public Long getAuthenticatedPatientId() {
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
         String email = authentication.getName();
 
         return patientRepository.findByEmail(email)
                 .map(Patient::getId)
                 .orElseThrow(() -> new RuntimeException("Patient non trouvé"));
+    }*/
+    public Long getAuthenticatedPatientId() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        String email = authentication.getName();
+
+        Optional<Patient> patientOpt = patientRepository.findByEmail(email);
+
+        if (patientOpt.isPresent()) {
+            return (Long) patientOpt.get().getId(); // Cast explicite
+        } else {
+            throw new RuntimeException("Patient non trouvé");
+        }
     }
 
+
     @Transactional
     public Patient mettreAJourPatient(Long id, Patient patient) {
         if (patientRepository.existsById(id)) {
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index fb7cb50..8d19862 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,7 +1,7 @@
 spring.application.name=projetIndu
 spring.datasource.url=jdbc:mysql://localhost:3307/projet
 spring.datasource.username=root
-spring.datasource.password=241001
+spring.datasource.password=mypassword
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
 spring.jpa.hibernate.ddl-auto=create
diff --git a/src/main/resources/templates/admin-dashboard.html b/src/main/resources/templates/admin-dashboard.html
index 7e5b297..c49ae5e 100644
--- a/src/main/resources/templates/admin-dashboard.html
+++ b/src/main/resources/templates/admin-dashboard.html
@@ -22,8 +22,9 @@
 <main class="mt-12">
     <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
         <h2 class="text-3xl font-bold text-gray-800 text-center">Bienvenue sur votre tableau de bord</h2>
-        <p class="mt-4 text-lg text-gray-600 text-center">Gérez les médecins, les dossiers médicaux, les rendez-vous et
-            les patients.</p>
+        <p class="mt-4 text-lg text-gray-600 text-center">
+            Gérez les médecins, les dossiers médicaux, les rendez-vous, les patients et les factures.
+        </p>
 
         <div class="mt-8 grid grid-cols-1 md:grid-cols-2 gap-6">
             <a href="/admin/createDoctor" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
@@ -53,6 +54,12 @@
                 <h3 class="text-xl font-semibold text-gray-800">Médecins</h3>
                 <p class="mt-2 text-gray-600">Consulter la liste de tous les médecins.</p>
             </a>
+
+            <!-- Nouvelle tuile pour les factures -->
+            <a href="/admin/invoices" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
+                <h3 class="text-xl font-semibold text-gray-800">Factures</h3>
+                <p class="mt-2 text-gray-600">Consulter et gérer les factures des consultations.</p>
+            </a>
         </div>
     </div>
 </main>
diff --git a/src/main/resources/templates/doctor-dashboard.html b/src/main/resources/templates/doctor-dashboard.html
index 09666ef..8f03fc9 100644
--- a/src/main/resources/templates/doctor-dashboard.html
+++ b/src/main/resources/templates/doctor-dashboard.html
@@ -22,8 +22,9 @@
 <main class="mt-12">
     <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
         <h2 class="text-3xl font-bold text-gray-800 text-center">Bienvenue sur votre tableau de bord</h2>
-        <p class="mt-4 text-lg text-gray-600 text-center">Consultez vos dossiers médicaux et gérez vos patients
-            efficacement.</p>
+        <p class="mt-4 text-lg text-gray-600 text-center">
+            Consultez vos dossiers médicaux et gérez vos patients efficacement.
+        </p>
 
         <div class="mt-8 grid grid-cols-1 md:grid-cols-2 gap-6">
             <a href="/doctors/patients" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
@@ -31,8 +32,7 @@
                 <p class="mt-2 text-gray-600">Consulter et gérer la liste de vos patients.</p>
             </a>
 
-            <a href="/doctors/medical-files-doctor"
-               class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
+            <a href="/doctors/medical-files-doctor" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
                 <h3 class="text-xl font-semibold text-gray-800">Dossiers Médicaux</h3>
                 <p class="mt-2 text-gray-600">Accéder aux dossiers médicaux de vos patients.</p>
             </a>
@@ -45,7 +45,11 @@
                 </div>
             </a>
 
-
+            <!-- Nouvelle tuile pour les factures -->
+            <a href="/doctor/invoices" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
+                <h3 class="text-xl font-semibold text-gray-800">Mes Factures</h3>
+                <p class="mt-2 text-gray-600">Consulter vos factures de consultations.</p>
+            </a>
         </div>
     </div>
 </main>
diff --git a/src/main/resources/templates/doctor-invoices.html b/src/main/resources/templates/doctor-invoices.html
index 4bdcfcb..1913290 100644
--- a/src/main/resources/templates/doctor-invoices.html
+++ b/src/main/resources/templates/doctor-invoices.html
@@ -1,10 +1,51 @@
 <!DOCTYPE html>
-<html lang="en">
+<html lang="fr" xmlns:th="http://www.w3.org/1999/xhtml">
 <head>
   <meta charset="UTF-8">
-  <title>$Title$</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Factures</title>
+  <script src="https://cdn.tailwindcss.com"></script>
 </head>
-<body>
-$END$
+<body class="bg-gray-100 font-sans leading-normal tracking-normal">
+
+<header class="bg-white shadow-md">
+  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
+    <div class="flex justify-between items-center py-6">
+      <h1 class="text-2xl font-semibold text-gray-900">Mes Factures</h1>
+      <a href="/doctor/dashboard" class="text-blue-500 hover:text-blue-700">Retour au tableau de bord</a>
+    </div>
+  </div>
+</header>
+
+<main class="mt-12">
+  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
+    <h2 class="text-3xl font-bold text-gray-800 text-center">Liste des factures</h2>
+    <table class="mt-8 w-full border-collapse bg-white shadow-md rounded-lg">
+      <thead>
+      <tr class="bg-gray-200">
+        <th class="p-4 border">ID</th>
+        <th class="p-4 border">Patient</th>
+        <th class="p-4 border">Montant</th>
+        <th class="p-4 border">Statut</th>
+        <th class="p-4 border">Actions</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr th:each="invoice : ${invoices}">
+        <td class="p-4 border" th:text="${invoice.id}"></td>
+        <td class="p-4 border" th:text="${invoice.appointment.patient.firstName} + ' ' + ${invoice.appointment.patient.lastName}"></td>
+        <td class="p-4 border" th:text="${invoice.amount} + ' €'"></td>
+        <td class="p-4 border" th:text="${invoice.status}"></td>
+        <td class="p-4 border">
+          <form th:action="@{/doctor/invoices/{id}/pay(id=${invoice.id})}" method="post">
+            <button class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-700" type="submit">Marquer comme payé</button>
+          </form>
+        </td>
+      </tr>
+      </tbody>
+    </table>
+  </div>
+</main>
+
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/src/main/resources/templates/invoices.html b/src/main/resources/templates/invoices.html
index 4bdcfcb..b4f53cb 100644
--- a/src/main/resources/templates/invoices.html
+++ b/src/main/resources/templates/invoices.html
@@ -1,10 +1,51 @@
 <!DOCTYPE html>
-<html lang="en">
+<html lang="fr" xmlns:th="http://www.w3.org/1999/xhtml">
 <head>
-  <meta charset="UTF-8">
-  <title>$Title$</title>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Factures</title>
+    <script src="https://cdn.tailwindcss.com"></script>
 </head>
-<body>
-$END$
+<body class="bg-gray-100 font-sans leading-normal tracking-normal">
+
+<header class="bg-white shadow-md">
+    <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
+        <div class="flex justify-between items-center py-6">
+            <h1 class="text-2xl font-semibold text-gray-900">Factures</h1>
+            <a href="/admin/dashboard" class="text-blue-500 hover:text-blue-700">Retour au tableau de bord</a>
+        </div>
+    </div>
+</header>
+
+<main class="mt-12">
+    <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
+        <h2 class="text-3xl font-bold text-gray-800 text-center">Liste des factures</h2>
+        <table class="mt-8 w-full border-collapse bg-white shadow-md rounded-lg">
+            <thead>
+            <tr class="bg-gray-200">
+                <th class="p-4 border">ID</th>
+                <th class="p-4 border">Patient</th>
+                <th class="p-4 border">Montant</th>
+                <th class="p-4 border">Statut</th>
+                <th class="p-4 border">Actions</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr th:each="invoice : ${invoices}">
+                <td class="p-4 border" th:text="${invoice.id}"></td>
+                <td th:text="${(invoice.appointment != null and invoice.appointment.patient != null) ? invoice.appointment.patient.firstName : 'N/A'}"></td>
+                <td class="p-4 border" th:text="${invoice.amount} + ' €'"></td>
+                <td class="p-4 border" th:text="${invoice.status}"></td>
+                <td class="p-4 border">
+                    <form th:action="@{/admin/invoices/{id}/pay(id=${invoice.id})}" method="post">
+                        <button class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-700" type="submit">Marquer comme payé</button>
+                    </form>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</main>
+
 </body>
-</html>
\ No newline at end of file
+</html>
-- 
GitLab