Skip to content
Snippets Groups Projects
Commit e1c2c2cc authored by COULIBALY Aichatou's avatar COULIBALY Aichatou
Browse files

Facture

parent 8f4f3ca7
Branches
No related tags found
No related merge requests found
Showing
with 310 additions and 36 deletions
...@@ -3,10 +3,12 @@ package com.projet.projetIndu.controllers; ...@@ -3,10 +3,12 @@ package com.projet.projetIndu.controllers;
import com.projet.projetIndu.entities.Doctor; import com.projet.projetIndu.entities.Doctor;
import com.projet.projetIndu.services.DoctorService; import com.projet.projetIndu.services.DoctorService;
import com.projet.projetIndu.services.PatientService; import com.projet.projetIndu.services.PatientService;
import com.projet.projetIndu.services.InvoiceService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; 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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
...@@ -19,6 +21,9 @@ public class AdminController { ...@@ -19,6 +21,9 @@ public class AdminController {
@Autowired @Autowired
private PatientService patientService; private PatientService patientService;
@Autowired
private InvoiceService invoiceService;
@GetMapping("/dashboard") @GetMapping("/dashboard")
public String adminDashboard() { public String adminDashboard() {
return "admin-dashboard"; return "admin-dashboard";
...@@ -47,4 +52,17 @@ public class AdminController { ...@@ -47,4 +52,17 @@ public class AdminController {
model.addAttribute("doctors", doctorService.getAllDoctors()); model.addAttribute("doctors", doctorService.getAllDoctors());
return "doctors"; 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";
}
} }
package com.projet.projetIndu.controllers; package com.projet.projetIndu.controllers;
import com.projet.projetIndu.entities.Doctor; import com.projet.projetIndu.entities.Doctor;
import com.projet.projetIndu.entities.Invoice;
import com.projet.projetIndu.entities.Patient; import com.projet.projetIndu.entities.Patient;
import com.projet.projetIndu.services.DoctorService; import com.projet.projetIndu.services.DoctorService;
import com.projet.projetIndu.services.InvoiceService;
import com.projet.projetIndu.services.PatientService; import com.projet.projetIndu.services.PatientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.security.Principal;
import java.util.List; import java.util.List;
@RequestMapping("/doctors") @RequestMapping("/doctors")
...@@ -18,6 +20,9 @@ public class DoctorController { ...@@ -18,6 +20,9 @@ public class DoctorController {
private final DoctorService doctorService; private final DoctorService doctorService;
private final PatientService patientService; private final PatientService patientService;
@Autowired
private InvoiceService invoiceService;
public DoctorController(DoctorService doctorService, PatientService patientService) { public DoctorController(DoctorService doctorService, PatientService patientService) {
this.doctorService = doctorService; this.doctorService = doctorService;
...@@ -49,4 +54,21 @@ public class DoctorController { ...@@ -49,4 +54,21 @@ public class DoctorController {
model.addAttribute("patients", patients); model.addAttribute("patients", patients);
return "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";
}*/
} }
...@@ -57,4 +57,7 @@ public class Appointment { ...@@ -57,4 +57,7 @@ public class Appointment {
} }
public void setStatus(AppointmentStatus appointmentStatus) {
this.status= appointmentStatus;
}
} }
...@@ -27,6 +27,4 @@ public class Doctor extends User { ...@@ -27,6 +27,4 @@ public class Doctor extends User {
this.role = Role.DOCTOR; this.role = Role.DOCTOR;
this.speciality = speciality; this.speciality = speciality;
} }
} }
package com.projet.projetIndu.entities; 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 { 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;
}
} }
...@@ -24,4 +24,11 @@ public class MedicalDocument { ...@@ -24,4 +24,11 @@ public class MedicalDocument {
@JoinColumn(name = "medical_file_id", nullable = true) @JoinColumn(name = "medical_file_id", nullable = true)
private MedicalFile medicalFile; private MedicalFile medicalFile;
public String getFileName() {
return fileName;
}
public byte[] getFileData() {
return fileData;
}
} }
package com.projet.projetIndu.entities; package com.projet.projetIndu.entities;
public class PaymentStatus { public enum PaymentStatus {
PENDING, // En attente
PAID, // Payé
CANCELLED // Annulé
} }
...@@ -61,8 +61,10 @@ public abstract class User { ...@@ -61,8 +61,10 @@ public abstract class User {
this.email = email; this.email = email;
this.password = password; this.password = password;
} }
public void setId(Long id) { public void setId(Long id) {
} }
public long getId() {
return id;
}
} }
...@@ -2,7 +2,15 @@ package com.projet.projetIndu.repositories; ...@@ -2,7 +2,15 @@ package com.projet.projetIndu.repositories;
import com.projet.projetIndu.entities.Invoice; import com.projet.projetIndu.entities.Invoice;
import org.springframework.data.jpa.repository.JpaRepository; 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);
} }
...@@ -13,10 +13,12 @@ import java.util.Optional; ...@@ -13,10 +13,12 @@ import java.util.Optional;
@Service @Service
public class AppointmentService { public class AppointmentService {
private final AppointmentRepository appointmentRepository; private final AppointmentRepository appointmentRepository;
private final InvoiceService invoiceService; // Ajoutez cette ligne pour l'injection du service InvoiceService
@Autowired @Autowired
public AppointmentService(AppointmentRepository appointmentRepository) { public AppointmentService(AppointmentRepository appointmentRepository, InvoiceService invoiceService) {
this.appointmentRepository = appointmentRepository; this.appointmentRepository = appointmentRepository;
this.invoiceService = invoiceService; // Initialisez invoiceService dans le constructeur
} }
public List<Appointment> getAllAppointments() { public List<Appointment> getAllAppointments() {
...@@ -43,7 +45,7 @@ public class AppointmentService { ...@@ -43,7 +45,7 @@ public class AppointmentService {
Optional<Appointment> optionalAppointment = appointmentRepository.findById(id); Optional<Appointment> optionalAppointment = appointmentRepository.findById(id);
if (optionalAppointment.isPresent()) { if (optionalAppointment.isPresent()) {
Appointment appointment = optionalAppointment.get(); Appointment appointment = optionalAppointment.get();
appointment.setStatus(AppointmentStatus.valueOf("CANCELLED")); appointment.setStatus(AppointmentStatus.CANCELLED);
appointmentRepository.save(appointment); appointmentRepository.save(appointment);
} }
} }
...@@ -62,8 +64,19 @@ public class AppointmentService { ...@@ -62,8 +64,19 @@ public class AppointmentService {
Appointment appointment = optionalAppointment.get(); Appointment appointment = optionalAppointment.get();
appointment.setStatus(AppointmentStatus.CONFIRMED); appointment.setStatus(AppointmentStatus.CONFIRMED);
appointmentRepository.save(appointment); 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 { } else {
throw new RuntimeException("Rendez-vous introuvable."); 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;
}
} }
...@@ -45,13 +45,27 @@ public class DoctorService { ...@@ -45,13 +45,27 @@ public class DoctorService {
doctorRepository.deleteById(id); doctorRepository.deleteById(id);
} }
public Long getAuthenticatedDoctorId() { /*public Long getAuthenticatedDoctorId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String email = authentication.getName(); String email = authentication.getName();
return doctorRepository.findByEmail(email) return doctorRepository.findByEmail(email)
.map(Doctor::getId) .map(Doctor::getId)
.orElseThrow(() -> new RuntimeException("Médecin non trouvé")); .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é");
}
} }
} }
......
package com.projet.projetIndu.services; package com.projet.projetIndu.services;
import com.projet.projetIndu.entities.Appointment;
import com.projet.projetIndu.entities.Invoice; import com.projet.projetIndu.entities.Invoice;
import com.projet.projetIndu.entities.PaymentStatus;
import com.projet.projetIndu.repositories.InvoiceRepository; import com.projet.projetIndu.repositories.InvoiceRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@Service @Service
public class InvoiceService { public class InvoiceService {
private final InvoiceRepository invoiceRepository; private final InvoiceRepository invoiceRepository;
@Autowired @Autowired
...@@ -25,11 +29,33 @@ public class InvoiceService { ...@@ -25,11 +29,33 @@ public class InvoiceService {
return invoiceRepository.findById(id); return invoiceRepository.findById(id);
} }
public void deleteInvoiceById(Long id) { public Invoice createInvoice(Appointment appointment, Double amount) {
invoiceRepository.deleteById(id); Invoice invoice = new Invoice(appointment, amount);
return invoiceRepository.save(invoice);
} }
public Invoice saveInvoice(Invoice invoice) { public void markAsPaid(Long invoiceId) {
return invoiceRepository.save(invoice); 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
}
}
...@@ -43,14 +43,27 @@ public class PatientService { ...@@ -43,14 +43,27 @@ public class PatientService {
} }
public Long getAuthenticatedPatientId() { /*public Long getAuthenticatedPatientId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String email = authentication.getName(); String email = authentication.getName();
return patientRepository.findByEmail(email) return patientRepository.findByEmail(email)
.map(Patient::getId) .map(Patient::getId)
.orElseThrow(() -> new RuntimeException("Patient non trouvé")); .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 @Transactional
public Patient mettreAJourPatient(Long id, Patient patient) { public Patient mettreAJourPatient(Long id, Patient patient) {
......
spring.application.name=projetIndu spring.application.name=projetIndu
spring.datasource.url=jdbc:mysql://localhost:3307/projet spring.datasource.url=jdbc:mysql://localhost:3307/projet
spring.datasource.username=root spring.datasource.username=root
spring.datasource.password=241001 spring.datasource.password=mypassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=create spring.jpa.hibernate.ddl-auto=create
......
...@@ -22,8 +22,9 @@ ...@@ -22,8 +22,9 @@
<main class="mt-12"> <main class="mt-12">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <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> <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 <p class="mt-4 text-lg text-gray-600 text-center">
les patients.</p> 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"> <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"> <a href="/admin/createDoctor" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
...@@ -53,6 +54,12 @@ ...@@ -53,6 +54,12 @@
<h3 class="text-xl font-semibold text-gray-800">Médecins</h3> <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> <p class="mt-2 text-gray-600">Consulter la liste de tous les médecins.</p>
</a> </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>
</div> </div>
</main> </main>
......
...@@ -22,8 +22,9 @@ ...@@ -22,8 +22,9 @@
<main class="mt-12"> <main class="mt-12">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <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> <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 <p class="mt-4 text-lg text-gray-600 text-center">
efficacement.</p> 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"> <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"> <a href="/doctors/patients" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
...@@ -31,8 +32,7 @@ ...@@ -31,8 +32,7 @@
<p class="mt-2 text-gray-600">Consulter et gérer la liste de vos patients.</p> <p class="mt-2 text-gray-600">Consulter et gérer la liste de vos patients.</p>
</a> </a>
<a href="/doctors/medical-files-doctor" <a href="/doctors/medical-files-doctor" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
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> <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> <p class="mt-2 text-gray-600">Accéder aux dossiers médicaux de vos patients.</p>
</a> </a>
...@@ -45,7 +45,11 @@ ...@@ -45,7 +45,11 @@
</div> </div>
</a> </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>
</div> </div>
</main> </main>
......
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="fr" xmlns:th="http://www.w3.org/1999/xhtml">
<head> <head>
<meta charset="UTF-8"> <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> </head>
<body> <body class="bg-gray-100 font-sans leading-normal tracking-normal">
$END$
<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> </body>
</html> </html>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="fr" xmlns:th="http://www.w3.org/1999/xhtml">
<head> <head>
<meta charset="UTF-8"> <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> </head>
<body> <body class="bg-gray-100 font-sans leading-normal tracking-normal">
$END$
<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> </body>
</html> </html>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment