Projet-location / src / Main.java
Main.java
Raw
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.time.LocalDate;
import java.time.format.DateTimeParseException;

void main() {
    AgenceLocation agence = new AgenceLocation();
    Scanner scanner = new Scanner(System.in);
    int choix;

    do {
        System.out.println("\n╔══════════════════════════════════════╗");
        System.out.println("║   SYSTÈME DE LOCATION DE VOITURES    ║");
        System.out.println("╠══════════════════════════════════════╣");
        System.out.println("║  1. Gestion des clients              ║");
        System.out.println("║  2. Gestion des véhicules            ║");
        System.out.println("║  3. Gestion des locations            ║");
        System.out.println("║  4. Statistiques                     ║");
        System.out.println("║  0. Quitter                          ║");
        System.out.println("╚══════════════════════════════════════╝");
        System.out.print("Votre choix : ");

        choix = lireEntier(scanner);

        switch (choix) {
            case 1 -> menuClients(scanner, agence);
            case 2 -> menuVehicules(scanner, agence);
            case 3 -> menuLocations(scanner, agence);
            case 4 -> agence.getStatistiques().afficher();
            case 0 -> System.out.println("Au revoir !");
            default -> System.out.println("⚠ Choix invalide, veuillez réessayer.");
        }
    } while (choix != 0);

    scanner.close();
}

// ════════════════════════════════════════════════════════
//  SOUS-MENU CLIENTS
// ════════════════════════════════════════════════════════

void menuClients(Scanner scanner, AgenceLocation agence) {
    int choix;
    do {
        System.out.println("\n╔══════════════════════════════════════╗");
        System.out.println("║         GESTION DES CLIENTS          ║");
        System.out.println("╠══════════════════════════════════════╣");
        System.out.println("║  1. Ajouter un client                ║");
        System.out.println("║  2. Afficher tous les clients        ║");
        System.out.println("║  3. Rechercher un client             ║");
        System.out.println("║  4. Modifier un client               ║");
        System.out.println("║  5. Supprimer un client              ║");
        System.out.println("║  0. Retour                           ║");
        System.out.println("╚══════════════════════════════════════╝");
        System.out.print("Votre choix : ");
        choix = lireEntier(scanner);

        switch (choix) {
            case 1 -> ajouterClient(scanner, agence);
            case 2 -> afficherClients(agence);
            case 3 -> rechercherClient(scanner, agence);
            case 4 -> modifierClient(scanner, agence);
            case 5 -> supprimerClient(scanner, agence);
            case 0 -> System.out.println("Retour au menu principal.");
            default -> System.out.println("⚠ Choix invalide.");
        }
    } while (choix != 0);
}

void ajouterClient(Scanner scanner, AgenceLocation agence) {
    System.out.println("\n── Ajout d'un nouveau client ──");
    System.out.print("Nom       : ");
    String nom = scanner.nextLine();
    System.out.print("Prénom    : ");
    String prenom = scanner.nextLine();
    System.out.print("Téléphone : ");
    String telephone = scanner.nextLine();
    System.out.print("Email     : ");
    String email = scanner.nextLine();
    System.out.print("N° Permis : ");
    String permis = scanner.nextLine();

    Client client = new Client(nom, prenom, telephone, email, permis);
    agence.ajouterClient(client);
    System.out.println("✔ Client ajouté avec succès (ID: " + client.getId() + ")");
}

void afficherClients(AgenceLocation agence) {
    if (agence.ListeClients.isEmpty()) {
        System.out.println("\nAucun client enregistré.");
        return;
    }
    System.out.println("\n── Liste des clients ──");
    for (Client c : agence.ListeClients) {
        c.afficherDetails();
    }
}

void rechercherClient(Scanner scanner, AgenceLocation agence) {
    System.out.println("\n── Recherche d'un client ──");
    System.out.println("1. Par ID   2. Par nom");
    System.out.print("Votre choix : ");
    int choix = lireEntier(scanner);

    if (choix == 1) {
        System.out.print("ID du client : ");
        int id = lireEntier(scanner);
        Client c = agence.RechercherClient(id);
        if (c != null) c.afficherDetails();
        else System.out.println("⚠ Aucun client trouvé avec l'ID " + id);
    } else if (choix == 2) {
        System.out.print("Nom du client : ");
        String nom = scanner.nextLine();
        boolean trouve = false;
        for (Client c : agence.ListeClients) {
            if (c.getNom().equalsIgnoreCase(nom)) {
                c.afficherDetails();
                trouve = true;
            }
        }
        if (!trouve) System.out.println("⚠ Aucun client trouvé avec le nom \"" + nom + "\"");
    } else {
        System.out.println("⚠ Choix invalide.");
    }
}

void modifierClient(Scanner scanner, AgenceLocation agence) {
    System.out.print("\nID du client à modifier : ");
    int id = lireEntier(scanner);
    Client c = agence.RechercherClient(id);

    if (c == null) {
        System.out.println("⚠ Client introuvable.");
        return;
    }

    c.afficherDetails();
    System.out.println("Laissez vide pour garder la valeur actuelle.");

    System.out.print("Nouveau nom       [" + c.getNom() + "] : ");
    String nom = scanner.nextLine();
    if (!nom.isBlank()) c.setNom(nom);

    System.out.print("Nouveau prénom    [" + c.getPrenom() + "] : ");
    String prenom = scanner.nextLine();
    if (!prenom.isBlank()) c.setPrenom(prenom);

    System.out.print("Nouveau téléphone [" + c.getTelephone() + "] : ");
    String tel = scanner.nextLine();
    if (!tel.isBlank()) c.setTelephone(tel);

    System.out.print("Nouveau email     [" + c.getEmail() + "] : ");
    String email = scanner.nextLine();
    if (!email.isBlank()) c.setEmail(email);

    System.out.print("Nouveau n° permis [" + c.getNumeroPermis() + "] : ");
    String permis = scanner.nextLine();
    if (!permis.isBlank()) c.setNumeroPermis(permis);

    System.out.println("✔ Client modifié avec succès.");
}

void supprimerClient(Scanner scanner, AgenceLocation agence) {
    System.out.print("\nID du client à supprimer : ");
    int id = lireEntier(scanner);
    Client c = agence.RechercherClient(id);

    if (c == null) {
        System.out.println("⚠ Client introuvable.");
        return;
    }

    c.afficherDetails();
    System.out.print("Confirmer la suppression ? (oui/non) : ");
    if (scanner.nextLine().equalsIgnoreCase("oui")) {
        agence.SuprimerClient(id);
        System.out.println("✔ Client supprimé.");
    } else {
        System.out.println("Suppression annulée.");
    }
}

// ════════════════════════════════════════════════════════
//  SOUS-MENU VÉHICULES
// ════════════════════════════════════════════════════════

void menuVehicules(Scanner scanner, AgenceLocation agence) {
    int choix;
    do {
        System.out.println("\n╔══════════════════════════════════════╗");
        System.out.println("║        GESTION DES VÉHICULES         ║");
        System.out.println("╠══════════════════════════════════════╣");
        System.out.println("║  1. Ajouter un véhicule              ║");
        System.out.println("║  2. Afficher tous les véhicules      ║");
        System.out.println("║  3. Véhicules disponibles            ║");
        System.out.println("║  4. Rechercher par ID                ║");
        System.out.println("║  5. Rechercher par marque            ║");
        System.out.println("║  6. Trier les véhicules              ║");
        System.out.println("║  7. Supprimer un véhicule            ║");
        System.out.println("║  0. Retour                           ║");
        System.out.println("╚══════════════════════════════════════╝");
        System.out.print("Votre choix : ");
        choix = lireEntier(scanner);

        switch (choix) {
            case 1 -> ajouterVehicule(scanner, agence);
            case 2 -> afficherVehicules(agence);
            case 3 -> afficherVehiculesDisponibles(agence);
            case 4 -> rechercherVehiculeParId(scanner, agence);
            case 5 -> rechercherVehiculeParMarque(scanner, agence);
            case 6 -> trierVehicules(scanner, agence);
            case 7 -> supprimerVehicule(scanner, agence);
            case 0 -> System.out.println("Retour au menu principal.");
            default -> System.out.println("⚠ Choix invalide.");
        }
    } while (choix != 0);
}

void ajouterVehicule(Scanner scanner, AgenceLocation agence) {
    System.out.println("\n── Ajout d'un véhicule ──");
    System.out.println("Type : 1. Voiture   2. Moto   3. Utilitaire");
    System.out.print("Votre choix : ");
    int type = lireEntier(scanner);

    System.out.print("Marque          : ");
    String marque = scanner.nextLine();
    System.out.print("Modèle          : ");
    String modele = scanner.nextLine();
    System.out.print("Immatriculation : ");
    String immat = scanner.nextLine();
    System.out.print("Année           : ");
    int annee = lireEntier(scanner);
    System.out.print("Prix / jour (€) : ");
    double prix = lireDouble(scanner);

    int id = agence.ListeVehicule.size() + 1;

    switch (type) {
        case 1 -> {
            System.out.print("Nb portes       : ");
            int portes = lireEntier(scanner);
            System.out.print("Carburant       : ");
            String carburant = scanner.nextLine();
            agence.AjouterVehicule(new Voiture(id, marque, modele, immat, annee, prix, true, portes, carburant));
        }
        case 2 -> {
            System.out.print("Cylindrée (cc)  : ");
            int cylindre = lireEntier(scanner);
            System.out.print("Type moto       : ");
            String typeMoto = scanner.nextLine();
            agence.AjouterVehicule(new moto(id, marque, modele, immat, annee, prix, true, cylindre, typeMoto));
        }
        case 3 -> {
            System.out.print("Charge max (kg) : ");
            double charge = lireDouble(scanner);
            System.out.print("Volume cargo (m³) : ");
            double volume = lireDouble(scanner);
            agence.AjouterVehicule(new Utilitaire(id, marque, modele, immat, annee, prix, true, charge, volume));
        }
        default -> { System.out.println("⚠ Type invalide."); return; }
    }
    System.out.println("✔ Véhicule ajouté (ID: " + id + ")");
}

void afficherVehicules(AgenceLocation agence) {
    if (agence.ListeVehicule.isEmpty()) {
        System.out.println("\nAucun véhicule enregistré.");
        return;
    }
    System.out.println("\n── Liste des véhicules ──");
    for (Vehicule v : agence.ListeVehicule) {
        v.afficher();
    }
}

void afficherVehiculesDisponibles(AgenceLocation agence) {
    List<Vehicule> dispo = agence.GetVehiculesDisponible();
    if (dispo.isEmpty()) {
        System.out.println("\nAucun véhicule disponible.");
        return;
    }
    System.out.println("\n── Véhicules disponibles ──");
    for (Vehicule v : dispo) {
        v.afficher();
    }
}

void rechercherVehiculeParId(Scanner scanner, AgenceLocation agence) {
    System.out.print("ID du véhicule : ");
    int id = lireEntier(scanner);
    Vehicule v = agence.RechercherVehicule(id);
    if (v != null) v.afficher();
    else System.out.println("⚠ Aucun véhicule avec l'ID " + id);
}

void rechercherVehiculeParMarque(Scanner scanner, AgenceLocation agence) {
    System.out.print("Marque : ");
    String marque = scanner.nextLine();
    List<Vehicule> resultats = agence.RechercheParMarque(marque);
    if (resultats.isEmpty()) System.out.println("⚠ Aucun véhicule trouvé pour \"" + marque + "\"");
    else resultats.forEach(Vehicule::afficher);
}

void trierVehicules(Scanner scanner, AgenceLocation agence) {
    System.out.println("Trier par : 1. Prix   2. Marque   3. Année");
    System.out.print("Votre choix : ");
    int choix = lireEntier(scanner);
    String critere = switch (choix) {
        case 1 -> "prix";
        case 2 -> "marque";
        case 3 -> "annee";
        default -> "";
    };
    if (critere.isEmpty()) { System.out.println("⚠ Choix invalide."); return; }
    System.out.println("\n── Véhicules triés par " + critere + " ──");
    agence.trierVehicules(critere).forEach(Vehicule::afficher);
}

void supprimerVehicule(Scanner scanner, AgenceLocation agence) {
    System.out.print("ID du véhicule à supprimer : ");
    int id = lireEntier(scanner);
    Vehicule v = agence.RechercherVehicule(id);
    if (v == null) { System.out.println("⚠ Véhicule introuvable."); return; }
    v.afficher();
    System.out.print("Confirmer ? (oui/non) : ");
    if (scanner.nextLine().equalsIgnoreCase("oui")) {
        agence.SupprimerVehicule(v);
        System.out.println("✔ Véhicule supprimé.");
    } else {
        System.out.println("Suppression annulée.");
    }
}

// ════════════════════════════════════════════════════════
//  SOUS-MENU LOCATIONS
// ════════════════════════════════════════════════════════

void menuLocations(Scanner scanner, AgenceLocation agence) {
    int choix;
    do {
        System.out.println("\n╔══════════════════════════════════════╗");
        System.out.println("║        GESTION DES LOCATIONS         ║");
        System.out.println("╠══════════════════════════════════════╣");
        System.out.println("║  1. Louer un véhicule                ║");
        System.out.println("║  2. Retourner un véhicule            ║");
        System.out.println("║  3. Locations en cours               ║");
        System.out.println("║  4. Historique d'un client           ║");
        System.out.println("║  5. Annuler une location             ║");
        System.out.println("║  0. Retour                           ║");
        System.out.println("╚══════════════════════════════════════╝");
        System.out.print("Votre choix : ");
        choix = lireEntier(scanner);

        switch (choix) {
            case 1 -> louerVehicule(scanner, agence);
            case 2 -> retournerVehicule(scanner, agence);
            case 3 -> agence.afficherLocationsEnCours();
            case 4 -> historiqueClient(scanner, agence);
            case 5 -> annulerLocation(scanner, agence);
            case 0 -> System.out.println("Retour au menu principal.");
            default -> System.out.println("⚠ Choix invalide.");
        }
    } while (choix != 0);
}

void louerVehicule(Scanner scanner, AgenceLocation agence) {
    System.out.println("\n── Nouvelle location ──");
    System.out.print("ID du véhicule : ");
    int idV = lireEntier(scanner);
    System.out.print("ID du client   : ");
    int idC = lireEntier(scanner);

    Client client = agence.RechercherClient(idC);
    Vehicule vehicule = agence.RechercherVehicule(idV);

    if (client == null)           { System.out.println("⚠ Client introuvable.");                    return; }
    if (vehicule == null)         { System.out.println("⚠ Véhicule introuvable.");                  return; }
    if (!vehicule.isDisponible()) { System.out.println("⚠ Ce véhicule n'est pas disponible.");      return; }

    LocalDate debut = lireDate(scanner, "Date de début (yyyy-mm-dd) : ");
    LocalDate fin   = lireDate(scanner, "Date de fin   (yyyy-mm-dd) : ");

    if (!fin.isAfter(debut)) { System.out.println("⚠ La date de fin doit être après la date de début."); return; }

    Location loc = agence.louerVehicule(idV, client, debut, fin);
    if (loc != null) {
        System.out.println("✔ Location créée !");
        loc.afficherLocation();
    } else {
        System.out.println("⚠ Impossible de créer la location.");
    }
}

void retournerVehicule(Scanner scanner, AgenceLocation agence) {
    System.out.print("ID de la location : ");
    int id = lireEntier(scanner);
    agence.retournerVehicule(id);
}

void historiqueClient(Scanner scanner, AgenceLocation agence) {
    System.out.print("ID du client : ");
    int id = lireEntier(scanner);
    List<Location> locs = agence.getLocationsClient(id);
    if (locs.isEmpty()) System.out.println("Aucune location pour ce client.");
    else locs.forEach(Location::afficherLocation);
}

void annulerLocation(Scanner scanner, AgenceLocation agence) {
    System.out.print("ID de la location à annuler : ");
    int id = lireEntier(scanner);
    agence.annulerLocation(id);
}

// ════════════════════════════════════════════════════════
//  UTILITAIRES
// ════════════════════════════════════════════════════════

int lireEntier(Scanner scanner) {
    while (!scanner.hasNextInt()) {
        System.out.print("⚠ Nombre entier attendu : ");
        scanner.next();
    }
    int val = scanner.nextInt();
    scanner.nextLine();
    return val;
}

double lireDouble(Scanner scanner) {
    while (!scanner.hasNextDouble()) {
        System.out.print("⚠ Nombre décimal attendu : ");
        scanner.next();
    }
    double val = scanner.nextDouble();
    scanner.nextLine();
    return val;
}

LocalDate lireDate(Scanner scanner, String message) {
    while (true) {
        System.out.print(message);
        String saisie = scanner.nextLine();
        try {
            return LocalDate.parse(saisie);
        } catch (DateTimeParseException e) {
            System.out.println("⚠ Format invalide. Utilisez yyyy-mm-dd (ex: 2025-06-15)");
        }
    }
}