9.5 KiB
9.5 KiB
🚀 Exemple d'Implémentation : Lazy Loading pour Factures
📋 Objectif
Transformer la liste des factures pour utiliser le lazy loading avec pagination côté serveur.
📁 Fichiers à Créer/Modifier
1. Créer FactureLazyDataModel.java
Chemin : src/main/java/dev/lions/btpxpress/view/model/FactureLazyDataModel.java
package dev.lions.btpxpress.view.model;
import dev.lions.btpxpress.service.FactureService;
import dev.lions.btpxpress.view.FactureView.Facture;
import org.primefaces.model.FilterMeta;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortMeta;
import org.primefaces.model.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.*;
public class FactureLazyDataModel extends LazyDataModel<Facture> implements Serializable {
private static final Logger LOG = LoggerFactory.getLogger(FactureLazyDataModel.class);
private final FactureService factureService;
public FactureLazyDataModel(FactureService factureService) {
this.factureService = factureService;
}
@Override
public int count(Map<String, FilterMeta> filterBy) {
try {
Map<String, Object> filterParams = buildFilterParams(filterBy);
int count = factureService.countFactures(filterParams);
LOG.debug("Count factures with filters: {}", count);
return count;
} catch (Exception e) {
LOG.error("Erreur lors du comptage des factures", e);
return 0;
}
}
@Override
public List<Facture> load(int first, int pageSize,
Map<String, SortMeta> sortBy,
Map<String, FilterMeta> filterBy) {
try {
Map<String, Object> params = new HashMap<>();
params.put("offset", first);
params.put("limit", pageSize);
// Ajouter les paramètres de tri
if (sortBy != null && !sortBy.isEmpty()) {
SortMeta sortMeta = sortBy.values().iterator().next();
params.put("sortField", sortMeta.getField());
params.put("sortOrder", sortMeta.getOrder() == SortOrder.ASCENDING ? "ASC" : "DESC");
}
// Ajouter les paramètres de filtrage
params.putAll(buildFilterParams(filterBy));
LOG.debug("Loading factures with params: {}", params);
List<Facture> factures = factureService.getFacturesLazy(params);
LOG.debug("Loaded {} factures", factures.size());
return factures;
} catch (Exception e) {
LOG.error("Erreur lors du chargement des factures", e);
return Collections.emptyList();
}
}
@Override
public String getRowKey(Facture facture) {
return facture.getId() != null ? facture.getId().toString() : null;
}
@Override
public Facture getRowData(String rowKey) {
// Cette méthode est appelée pour récupérer une facture par son ID
// Pour l'instant, on retourne null car on ne garde pas de cache local
return null;
}
private Map<String, Object> buildFilterParams(Map<String, FilterMeta> filterBy) {
Map<String, Object> params = new HashMap<>();
if (filterBy != null) {
filterBy.forEach((field, filterMeta) -> {
Object filterValue = filterMeta.getFilterValue();
if (filterValue != null && !filterValue.toString().trim().isEmpty()) {
params.put("filter_" + field, filterValue);
}
});
}
return params;
}
}
2. Modifier FactureService.java
Ajouter les méthodes pour le lazy loading :
package dev.lions.btpxpress.service;
import dev.lions.btpxpress.view.FactureView.Facture;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
@ApplicationScoped
public class FactureService {
private static final Logger LOG = LoggerFactory.getLogger(FactureService.class);
@Inject
@RestClient
BtpXpressApiClient apiClient;
/**
* Récupère les factures avec pagination et filtres
*/
public List<Facture> getFacturesLazy(Map<String, Object> params) {
try {
int offset = (int) params.getOrDefault("offset", 0);
int limit = (int) params.getOrDefault("limit", 10);
String sortField = (String) params.get("sortField");
String sortOrder = (String) params.get("sortOrder");
// Extraire les filtres
String filtreNumero = (String) params.get("filter_numero");
String filtreClient = (String) params.get("filter_client");
String filtreStatut = (String) params.get("filter_statut");
// Appel API (à adapter selon votre backend)
List<Map<String, Object>> facturesData = apiClient.getFacturesLazy(
offset, limit, sortField, sortOrder,
filtreNumero, filtreClient, filtreStatut
);
// Mapper vers les objets Facture
return facturesData.stream()
.map(this::mapToFacture)
.collect(Collectors.toList());
} catch (Exception e) {
LOG.error("Erreur lors de la récupération lazy des factures", e);
return Collections.emptyList();
}
}
/**
* Compte le nombre total de factures avec filtres
*/
public int countFactures(Map<String, Object> params) {
try {
String filtreNumero = (String) params.get("filter_numero");
String filtreClient = (String) params.get("filter_client");
String filtreStatut = (String) params.get("filter_statut");
return apiClient.countFactures(filtreNumero, filtreClient, filtreStatut);
} catch (Exception e) {
LOG.error("Erreur lors du comptage des factures", e);
return 0;
}
}
private Facture mapToFacture(Map<String, Object> data) {
Facture f = new Facture();
f.setId(data.get("id") != null ? Long.valueOf(data.get("id").toString()) : null);
f.setNumero((String) data.get("numero"));
f.setObjet((String) data.get("objet"));
// Mapping du client
Object clientObj = data.get("client");
if (clientObj instanceof Map) {
Map<String, Object> clientData = (Map<String, Object>) clientObj;
String entreprise = (String) clientData.get("entreprise");
String nom = (String) clientData.get("nom");
String prenom = (String) clientData.get("prenom");
f.setClient(entreprise != null && !entreprise.trim().isEmpty() ?
entreprise : (prenom != null ? prenom + " " : "") + (nom != null ? nom : ""));
} else if (clientObj instanceof String) {
f.setClient((String) clientObj);
}
// Mapping des dates
if (data.get("dateEmission") != null) {
f.setDateEmission(LocalDate.parse(data.get("dateEmission").toString()));
}
if (data.get("dateEcheance") != null) {
f.setDateEcheance(LocalDate.parse(data.get("dateEcheance").toString()));
}
// Mapping des montants
f.setStatut((String) data.get("statut"));
f.setMontantHT(data.get("montantHT") != null ? Double.valueOf(data.get("montantHT").toString()) : 0.0);
f.setMontantTTC(data.get("montantTTC") != null ? Double.valueOf(data.get("montantTTC").toString()) : 0.0);
f.setMontantPaye(data.get("montantPaye") != null ? Double.valueOf(data.get("montantPaye").toString()) : 0.0);
return f;
}
}
3. Modifier BtpXpressApiClient.java
Ajouter les endpoints pour le lazy loading :
package dev.lions.btpxpress.service;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import java.util.List;
import java.util.Map;
@Path("/api")
@RegisterRestClient(configKey = "btpxpress-api")
public interface BtpXpressApiClient {
// ... méthodes existantes ...
@GET
@Path("/factures/lazy")
@Produces(MediaType.APPLICATION_JSON)
List<Map<String, Object>> getFacturesLazy(
@QueryParam("offset") int offset,
@QueryParam("limit") int limit,
@QueryParam("sortField") String sortField,
@QueryParam("sortOrder") String sortOrder,
@QueryParam("filter_numero") String filtreNumero,
@QueryParam("filter_client") String filtreClient,
@QueryParam("filter_statut") String filtreStatut
);
@GET
@Path("/factures/count")
@Produces(MediaType.APPLICATION_JSON)
int countFactures(
@QueryParam("filter_numero") String filtreNumero,
@QueryParam("filter_client") String filtreClient,
@QueryParam("filter_statut") String filtreStatut
);
}
✅ Prochaines Étapes
- Créer les fichiers ci-dessus
- Tester avec des données de test
- Vérifier les logs pour le debugging
- Adapter le backend si nécessaire
- Répliquer pour les autres modules (Devis, Clients, etc.)