Projet-location / src / Location.java
Location.java
Raw
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class Location {

    // ── Attributs privés ──
    private int id;
    private Vehicule voiture;
    private Client client;
    private LocalDate dateDebut;
    private LocalDate dateFin;       // date de fin prévue
    private LocalDate dateRetour;    // date réelle de retour (null si pas encore rendu)
    private double prixTotal;
    private StatutLocation statut;

    // ── Compteur statique pour les IDs ──
    private static int compteur = 0;

    // ── Constructeur ──
    public Location(Vehicule voiture, Client client, LocalDate dateDebut, LocalDate dateFin) {
        this.id = ++compteur;
        this.voiture = voiture;
        this.client = client;
        this.dateDebut = dateDebut;
        this.dateFin = dateFin;
        this.dateRetour = null;
        this.statut = StatutLocation.EN_COURS;
        this.prixTotal = calculerPrix();
        voiture.louer();
    }

    // ── Méthodes métier ──

    // Retourne le nombre de jours prévus (dateDebut -> dateFin)
    public long getDuree() {
        return ChronoUnit.DAYS.between(dateDebut, dateFin);
    }

    // Calcule le prix total : durée × prix par jour du véhicule
    public double calculerPrix() {
        return getDuree() * voiture.getPrixJour();
    }

    // Vérifie si la location est en retard
    public boolean isEnRetard() {
        if (dateRetour != null) {
            return dateRetour.isAfter(dateFin);
        }
        return LocalDate.now().isAfter(dateFin);
    }

    // Retourne la pénalité de retard : jours de retard × prixJour × 1.5
    public double getPenaliteRetard() {
        if (!isEnRetard()) return 0;

        LocalDate reference = (dateRetour != null) ? dateRetour : LocalDate.now();
        long joursRetard = ChronoUnit.DAYS.between(dateFin, reference);
        return joursRetard * voiture.getPrixJour() * 1.5;
    }

    // Termine la location : enregistre la date de retour réelle et met à jour le statut
    public void terminerLocation() {
        this.dateRetour = LocalDate.now();
        voiture.retourner();
        if (isEnRetard()) {
            this.statut = StatutLocation.EN_RETARD;
        } else {
            this.statut = StatutLocation.TERMINEE;
        }
        this.prixTotal = calculerPrix() + getPenaliteRetard();
    }

    // Annule la location (si elle est encore en cours)
    public void annulerLocation() {
        if (this.statut == StatutLocation.EN_COURS) {
            this.statut = StatutLocation.ANNULEE;
            voiture.retourner();
        }
    }

    // Affichage formaté
    public void afficherLocation() {
        System.out.println("──────────────────────────────────");
        System.out.println("  Location N°     : " + id);
        System.out.println("  Client          : " + client.getPrenom() + " " + client.getNom());
        System.out.println("  Date début      : " + dateDebut);
        System.out.println("  Date fin prévue : " + dateFin);
        System.out.println("  Date retour     : " + (dateRetour != null ? dateRetour : "En cours"));
        System.out.println("  Durée prévue    : " + getDuree() + " jour(s)");
        System.out.println("  Prix total      : " + prixTotal + " €");
        if (isEnRetard()) {
            System.out.println("  Pénalité retard : " + getPenaliteRetard() + " €");
        }
        System.out.println("  Statut          : " + statut);
        System.out.println("──────────────────────────────────");
    }

    // ── Getters ──
    public int getId()                   { return id; }
    public Vehicule getVoiture()         { return voiture; }
    public Client getClient()            { return client; }
    public LocalDate getDateDebut()      { return dateDebut; }
    public LocalDate getDateFin()        { return dateFin; }
    public LocalDate getDateRetour()     { return dateRetour; }
    public double getPrixTotal()         { return prixTotal; }
    public StatutLocation getStatut()    { return statut; }

    // ── Setter statut (utile pour forcer un état depuis AgenceLocation) ──
    public void setStatut(StatutLocation statut) { this.statut = statut; }

    // ── toString ──
    @Override
    public String toString() {
        return "Location #" + id + " | " + client.getNom() + " | " + voiture.toString()
                + " | " + dateDebut + " → " + dateFin + " | " + statut;
    }
}