package dev.lions.btpxpress.view; import dev.lions.btpxpress.service.ChantierService; import jakarta.annotation.PostConstruct; import jakarta.faces.view.ViewScoped; import jakarta.inject.Inject; import jakarta.inject.Named; import lombok.Getter; import lombok.Setter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Predicate; @Named("chantiersView") @ViewScoped @Getter @Setter public class ChantiersView extends BaseListView implements Serializable { private static final Logger LOG = LoggerFactory.getLogger(ChantiersView.class); @Inject ChantierService chantierService; private String filtreNom; private String filtreClient; private String filtreStatut; private Long chantierId; @PostConstruct public void init() { if (filtreStatut == null) { filtreStatut = "TOUS"; } loadItems(); } /** * Définit le filtre de statut (utilisé depuis les pages filtrées). */ public void setFiltreStatut(String statut) { this.filtreStatut = statut; } @Override public void loadItems() { loading = true; try { items = new ArrayList<>(); // Récupération depuis l'API backend List> chantiersData = chantierService.getAllChantiers(); for (Map data : chantiersData) { Chantier c = new Chantier(); // Mapping des données de l'API vers l'objet Chantier c.setId(data.get("id") != null ? Long.valueOf(data.get("id").toString().hashCode()) : null); c.setNom((String) data.get("nom")); // Le client peut être un objet ou une chaîne Object clientObj = data.get("client"); if (clientObj instanceof Map) { Map clientData = (Map) clientObj; c.setClient((String) clientData.get("raisonSociale")); } else if (clientObj instanceof String) { c.setClient((String) clientObj); } else { c.setClient("N/A"); } c.setAdresse((String) data.get("adresse")); // Conversion des dates if (data.get("dateDebut") != null) { c.setDateDebut(LocalDate.parse(data.get("dateDebut").toString())); } if (data.get("dateFinPrevue") != null) { c.setDateFinPrevue(LocalDate.parse(data.get("dateFinPrevue").toString())); } c.setStatut((String) data.get("statut")); // Avancement en pourcentage Object avancementObj = data.get("avancement"); if (avancementObj != null) { c.setAvancement(avancementObj instanceof Integer ? (Integer) avancementObj : Integer.parseInt(avancementObj.toString())); } else { c.setAvancement(0); } // Budget et coût réel Object montantObj = data.get("montant"); if (montantObj != null) { c.setBudget(montantObj instanceof Number ? ((Number) montantObj).doubleValue() : Double.parseDouble(montantObj.toString())); } else { c.setBudget(0.0); } Object coutReelObj = data.get("coutReel"); if (coutReelObj != null) { c.setCoutReel(coutReelObj instanceof Number ? ((Number) coutReelObj).doubleValue() : Double.parseDouble(coutReelObj.toString())); } else { c.setCoutReel(0.0); } items.add(c); } LOG.info("Chantiers chargés depuis l'API : {} élément(s)", items.size()); applyFilters(items, buildFilters()); } catch (Exception e) { LOG.error("Erreur chargement chantiers depuis l'API", e); // En cas d'erreur, on garde une liste vide items = new ArrayList<>(); } finally { loading = false; } } private List> buildFilters() { List> filters = new ArrayList<>(); if (filtreNom != null && !filtreNom.trim().isEmpty()) { filters.add(c -> c.getNom().toLowerCase().contains(filtreNom.toLowerCase())); } if (filtreClient != null && !filtreClient.trim().isEmpty()) { filters.add(c -> c.getClient().toLowerCase().contains(filtreClient.toLowerCase())); } if (filtreStatut != null && !filtreStatut.trim().isEmpty() && !"TOUS".equals(filtreStatut)) { filters.add(c -> c.getStatut().equals(filtreStatut)); } return filters; } @Override protected void resetFilterFields() { filtreNom = null; filtreClient = null; filtreStatut = "TOUS"; } @Override protected String getDetailsPath() { return "/chantiers/"; } @Override protected String getCreatePath() { return "/chantiers/nouveau"; } @Override protected void performDelete() { LOG.info("Suppression chantier : {}", selectedItem.getId()); // TODO: Appeler chantierService.delete(selectedItem.getId()) } @Override protected Chantier createNewEntity() { Chantier c = new Chantier(); c.setStatut("PLANIFIE"); c.setAvancement(0); c.setDateDebut(LocalDate.now()); c.setDateCreation(LocalDateTime.now()); return c; } @Override protected void performCreate() { entity.setId(System.currentTimeMillis()); // Simulation ID entity.setDateCreation(LocalDateTime.now()); entity.setDateModification(LocalDateTime.now()); items.add(entity); LOG.info("Nouveau chantier créé : {}", entity.getNom()); // TODO: Appeler chantierService.create(entity) } @Override protected void performUpdate() { entity.setDateModification(LocalDateTime.now()); LOG.info("Chantier modifié : {}", entity.getNom()); // TODO: Appeler chantierService.update(entity) } @Override protected Long getEntityId(Chantier chantier) { return chantier.getId(); } /** * Initialise un nouveau chantier pour la création. */ @Override public String createNew() { prepareNew(); return getCreatePath() + "?faces-redirect=true"; } /** * Sauvegarde un nouveau chantier. */ public String saveNew() { if (selectedItem == null) { selectedItem = new Chantier(); } selectedItem.setId(System.currentTimeMillis()); // Simulation ID selectedItem.setDateCreation(LocalDateTime.now()); selectedItem.setDateModification(LocalDateTime.now()); items.add(selectedItem); LOG.info("Nouveau chantier créé : {}", selectedItem.getNom()); return "/chantiers?faces-redirect=true"; } /** * Charge un chantier par son ID depuis les paramètres de la requête. */ public void loadChantierById() { if (chantierId != null) { loadItems(); // S'assurer que les items sont chargés selectedItem = items.stream() .filter(c -> c.getId().equals(chantierId)) .findFirst() .orElse(null); if (selectedItem == null) { LOG.warn("Chantier avec ID {} non trouvé", chantierId); } } } /** * Affiche les détails d'un chantier. */ public String viewDetails(Long id) { selectedItem = items.stream() .filter(c -> c.getId().equals(id)) .findFirst() .orElse(null); if (selectedItem != null) { return getDetailsPath() + "details?id=" + id + "&faces-redirect=true"; } return "/chantiers?faces-redirect=true"; } @lombok.Getter @lombok.Setter public static class Chantier { private Long id; private String nom; private String client; private String adresse; private LocalDate dateDebut; private LocalDate dateFinPrevue; private String statut; private int avancement; private double budget; private double coutReel; private LocalDateTime dateCreation; private LocalDateTime dateModification; } }