282 lines
9.5 KiB
Markdown
282 lines
9.5 KiB
Markdown
# 🚀 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`
|
|
|
|
```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** :
|
|
|
|
```java
|
|
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** :
|
|
|
|
```java
|
|
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
|
|
|
|
1. Créer les fichiers ci-dessus
|
|
2. Tester avec des données de test
|
|
3. Vérifier les logs pour le debugging
|
|
4. Adapter le backend si nécessaire
|
|
5. Répliquer pour les autres modules (Devis, Clients, etc.)
|
|
|