Configure Maven repository for unionflow-server-api dependency

This commit is contained in:
dahoud
2025-12-10 01:08:17 +00:00
commit 4a0c5f9d33
320 changed files with 33373 additions and 0 deletions

View File

@@ -0,0 +1,559 @@
package dev.lions.unionflow.server.service;
import dev.lions.unionflow.server.api.dto.finance.AdhesionDTO;
import dev.lions.unionflow.server.entity.Adhesion;
import dev.lions.unionflow.server.entity.Membre;
import dev.lions.unionflow.server.entity.Organisation;
import dev.lions.unionflow.server.repository.AdhesionRepository;
import dev.lions.unionflow.server.repository.MembreRepository;
import dev.lions.unionflow.server.repository.OrganisationRepository;
import io.quarkus.panache.common.Page;
import io.quarkus.panache.common.Sort;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.NotFoundException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
/**
* Service métier pour la gestion des adhésions
* Contient la logique métier et les règles de validation
*
* @author UnionFlow Team
* @version 1.0
* @since 2025-01-17
*/
@ApplicationScoped
@Slf4j
public class AdhesionService {
@Inject AdhesionRepository adhesionRepository;
@Inject MembreRepository membreRepository;
@Inject OrganisationRepository organisationRepository;
/**
* Récupère toutes les adhésions avec pagination
*
* @param page numéro de page (0-based)
* @param size taille de la page
* @return liste des adhésions converties en DTO
*/
public List<AdhesionDTO> getAllAdhesions(int page, int size) {
log.debug("Récupération des adhésions - page: {}, size: {}", page, size);
jakarta.persistence.TypedQuery<Adhesion> query =
adhesionRepository
.getEntityManager()
.createQuery(
"SELECT a FROM Adhesion a ORDER BY a.dateDemande DESC", Adhesion.class);
query.setFirstResult(page * size);
query.setMaxResults(size);
List<Adhesion> adhesions = query.getResultList();
return adhesions.stream().map(this::convertToDTO).collect(Collectors.toList());
}
/**
* Récupère une adhésion par son ID
*
* @param id identifiant UUID de l'adhésion
* @return DTO de l'adhésion
* @throws NotFoundException si l'adhésion n'existe pas
*/
public AdhesionDTO getAdhesionById(@NotNull UUID id) {
log.debug("Récupération de l'adhésion avec ID: {}", id);
Adhesion adhesion =
adhesionRepository
.findByIdOptional(id)
.orElseThrow(() -> new NotFoundException("Adhésion non trouvée avec l'ID: " + id));
return convertToDTO(adhesion);
}
/**
* Récupère une adhésion par son numéro de référence
*
* @param numeroReference numéro de référence unique
* @return DTO de l'adhésion
* @throws NotFoundException si l'adhésion n'existe pas
*/
public AdhesionDTO getAdhesionByReference(@NotNull String numeroReference) {
log.debug("Récupération de l'adhésion avec référence: {}", numeroReference);
Adhesion adhesion =
adhesionRepository
.findByNumeroReference(numeroReference)
.orElseThrow(
() ->
new NotFoundException(
"Adhésion non trouvée avec la référence: " + numeroReference));
return convertToDTO(adhesion);
}
/**
* Crée une nouvelle adhésion
*
* @param adhesionDTO données de l'adhésion à créer
* @return DTO de l'adhésion créée
*/
@Transactional
public AdhesionDTO createAdhesion(@Valid AdhesionDTO adhesionDTO) {
log.info(
"Création d'une nouvelle adhésion pour le membre: {} et l'organisation: {}",
adhesionDTO.getMembreId(),
adhesionDTO.getOrganisationId());
// Validation du membre
Membre membre =
membreRepository
.findByIdOptional(adhesionDTO.getMembreId())
.orElseThrow(
() ->
new NotFoundException(
"Membre non trouvé avec l'ID: " + adhesionDTO.getMembreId()));
// Validation de l'organisation
Organisation organisation =
organisationRepository
.findByIdOptional(adhesionDTO.getOrganisationId())
.orElseThrow(
() ->
new NotFoundException(
"Organisation non trouvée avec l'ID: " + adhesionDTO.getOrganisationId()));
// Conversion DTO vers entité
Adhesion adhesion = convertToEntity(adhesionDTO);
adhesion.setMembre(membre);
adhesion.setOrganisation(organisation);
// Génération automatique du numéro de référence si absent
if (adhesion.getNumeroReference() == null || adhesion.getNumeroReference().isEmpty()) {
adhesion.setNumeroReference(genererNumeroReference());
}
// Initialisation par défaut
if (adhesion.getDateDemande() == null) {
adhesion.setDateDemande(LocalDate.now());
}
if (adhesion.getStatut() == null || adhesion.getStatut().isEmpty()) {
adhesion.setStatut("EN_ATTENTE");
}
if (adhesion.getMontantPaye() == null) {
adhesion.setMontantPaye(BigDecimal.ZERO);
}
if (adhesion.getCodeDevise() == null || adhesion.getCodeDevise().isEmpty()) {
adhesion.setCodeDevise("XOF");
}
// Persistance
adhesionRepository.persist(adhesion);
log.info(
"Adhésion créée avec succès - ID: {}, Référence: {}",
adhesion.getId(),
adhesion.getNumeroReference());
return convertToDTO(adhesion);
}
/**
* Met à jour une adhésion existante
*
* @param id identifiant UUID de l'adhésion
* @param adhesionDTO nouvelles données
* @return DTO de l'adhésion mise à jour
*/
@Transactional
public AdhesionDTO updateAdhesion(@NotNull UUID id, @Valid AdhesionDTO adhesionDTO) {
log.info("Mise à jour de l'adhésion avec ID: {}", id);
Adhesion adhesionExistante =
adhesionRepository
.findByIdOptional(id)
.orElseThrow(() -> new NotFoundException("Adhésion non trouvée avec l'ID: " + id));
// Mise à jour des champs modifiables
updateAdhesionFields(adhesionExistante, adhesionDTO);
log.info("Adhésion mise à jour avec succès - ID: {}", id);
return convertToDTO(adhesionExistante);
}
/**
* Supprime (désactive) une adhésion
*
* @param id identifiant UUID de l'adhésion
*/
@Transactional
public void deleteAdhesion(@NotNull UUID id) {
log.info("Suppression de l'adhésion avec ID: {}", id);
Adhesion adhesion =
adhesionRepository
.findByIdOptional(id)
.orElseThrow(() -> new NotFoundException("Adhésion non trouvée avec l'ID: " + id));
// Vérification si l'adhésion peut être supprimée
if ("PAYEE".equals(adhesion.getStatut())) {
throw new IllegalStateException("Impossible de supprimer une adhésion déjà payée");
}
adhesion.setStatut("ANNULEE");
log.info("Adhésion supprimée avec succès - ID: {}", id);
}
/**
* Approuve une adhésion
*
* @param id identifiant UUID de l'adhésion
* @param approuvePar nom de l'utilisateur qui approuve
* @return DTO de l'adhésion approuvée
*/
@Transactional
public AdhesionDTO approuverAdhesion(@NotNull UUID id, String approuvePar) {
log.info("Approbation de l'adhésion avec ID: {}", id);
Adhesion adhesion =
adhesionRepository
.findByIdOptional(id)
.orElseThrow(() -> new NotFoundException("Adhésion non trouvée avec l'ID: " + id));
if (!"EN_ATTENTE".equals(adhesion.getStatut())) {
throw new IllegalStateException(
"Seules les adhésions en attente peuvent être approuvées");
}
adhesion.setStatut("APPROUVEE");
adhesion.setDateApprobation(LocalDate.now());
adhesion.setApprouvePar(approuvePar);
adhesion.setDateValidation(LocalDate.now());
log.info("Adhésion approuvée avec succès - ID: {}", id);
return convertToDTO(adhesion);
}
/**
* Rejette une adhésion
*
* @param id identifiant UUID de l'adhésion
* @param motifRejet motif du rejet
* @return DTO de l'adhésion rejetée
*/
@Transactional
public AdhesionDTO rejeterAdhesion(@NotNull UUID id, String motifRejet) {
log.info("Rejet de l'adhésion avec ID: {}", id);
Adhesion adhesion =
adhesionRepository
.findByIdOptional(id)
.orElseThrow(() -> new NotFoundException("Adhésion non trouvée avec l'ID: " + id));
if (!"EN_ATTENTE".equals(adhesion.getStatut())) {
throw new IllegalStateException("Seules les adhésions en attente peuvent être rejetées");
}
adhesion.setStatut("REJETEE");
adhesion.setMotifRejet(motifRejet);
log.info("Adhésion rejetée avec succès - ID: {}", id);
return convertToDTO(adhesion);
}
/**
* Enregistre un paiement pour une adhésion
*
* @param id identifiant UUID de l'adhésion
* @param montantPaye montant payé
* @param methodePaiement méthode de paiement
* @param referencePaiement référence du paiement
* @return DTO de l'adhésion mise à jour
*/
@Transactional
public AdhesionDTO enregistrerPaiement(
@NotNull UUID id,
BigDecimal montantPaye,
String methodePaiement,
String referencePaiement) {
log.info("Enregistrement du paiement pour l'adhésion avec ID: {}", id);
Adhesion adhesion =
adhesionRepository
.findByIdOptional(id)
.orElseThrow(() -> new NotFoundException("Adhésion non trouvée avec l'ID: " + id));
if (!"APPROUVEE".equals(adhesion.getStatut()) && !"EN_PAIEMENT".equals(adhesion.getStatut())) {
throw new IllegalStateException(
"Seules les adhésions approuvées peuvent recevoir un paiement");
}
BigDecimal nouveauMontantPaye =
adhesion.getMontantPaye() != null
? adhesion.getMontantPaye().add(montantPaye)
: montantPaye;
adhesion.setMontantPaye(nouveauMontantPaye);
adhesion.setMethodePaiement(methodePaiement);
adhesion.setReferencePaiement(referencePaiement);
adhesion.setDatePaiement(java.time.LocalDateTime.now());
// Mise à jour du statut si payée intégralement
if (adhesion.isPayeeIntegralement()) {
adhesion.setStatut("PAYEE");
} else {
adhesion.setStatut("EN_PAIEMENT");
}
log.info("Paiement enregistré avec succès pour l'adhésion - ID: {}", id);
return convertToDTO(adhesion);
}
/**
* Récupère les adhésions d'un membre
*
* @param membreId identifiant UUID du membre
* @param page numéro de page
* @param size taille de la page
* @return liste des adhésions du membre
*/
public List<AdhesionDTO> getAdhesionsByMembre(@NotNull UUID membreId, int page, int size) {
log.debug("Récupération des adhésions du membre: {}", membreId);
if (!membreRepository.findByIdOptional(membreId).isPresent()) {
throw new NotFoundException("Membre non trouvé avec l'ID: " + membreId);
}
List<Adhesion> adhesions =
adhesionRepository.findByMembreId(membreId).stream()
.skip(page * size)
.limit(size)
.collect(Collectors.toList());
return adhesions.stream().map(this::convertToDTO).collect(Collectors.toList());
}
/**
* Récupère les adhésions d'une organisation
*
* @param organisationId identifiant UUID de l'organisation
* @param page numéro de page
* @param size taille de la page
* @return liste des adhésions de l'organisation
*/
public List<AdhesionDTO> getAdhesionsByOrganisation(
@NotNull UUID organisationId, int page, int size) {
log.debug("Récupération des adhésions de l'organisation: {}", organisationId);
if (!organisationRepository.findByIdOptional(organisationId).isPresent()) {
throw new NotFoundException("Organisation non trouvée avec l'ID: " + organisationId);
}
List<Adhesion> adhesions =
adhesionRepository.findByOrganisationId(organisationId).stream()
.skip(page * size)
.limit(size)
.collect(Collectors.toList());
return adhesions.stream().map(this::convertToDTO).collect(Collectors.toList());
}
/**
* Récupère les adhésions par statut
*
* @param statut statut recherché
* @param page numéro de page
* @param size taille de la page
* @return liste des adhésions avec le statut spécifié
*/
public List<AdhesionDTO> getAdhesionsByStatut(@NotNull String statut, int page, int size) {
log.debug("Récupération des adhésions avec statut: {}", statut);
List<Adhesion> adhesions =
adhesionRepository.findByStatut(statut).stream()
.skip(page * size)
.limit(size)
.collect(Collectors.toList());
return adhesions.stream().map(this::convertToDTO).collect(Collectors.toList());
}
/**
* Récupère les adhésions en attente
*
* @param page numéro de page
* @param size taille de la page
* @return liste des adhésions en attente
*/
public List<AdhesionDTO> getAdhesionsEnAttente(int page, int size) {
log.debug("Récupération des adhésions en attente");
List<Adhesion> adhesions =
adhesionRepository.findEnAttente().stream()
.skip(page * size)
.limit(size)
.collect(Collectors.toList());
return adhesions.stream().map(this::convertToDTO).collect(Collectors.toList());
}
/**
* Récupère les statistiques des adhésions
*
* @return map contenant les statistiques
*/
public Map<String, Object> getStatistiquesAdhesions() {
log.debug("Calcul des statistiques des adhésions");
long totalAdhesions = adhesionRepository.count();
long adhesionsApprouvees = adhesionRepository.findByStatut("APPROUVEE").size();
long adhesionsEnAttente = adhesionRepository.findEnAttente().size();
long adhesionsPayees = adhesionRepository.findByStatut("PAYEE").size();
return Map.of(
"totalAdhesions", totalAdhesions,
"adhesionsApprouvees", adhesionsApprouvees,
"adhesionsEnAttente", adhesionsEnAttente,
"adhesionsPayees", adhesionsPayees,
"tauxApprobation",
totalAdhesions > 0 ? (adhesionsApprouvees * 100.0 / totalAdhesions) : 0.0,
"tauxPaiement",
adhesionsApprouvees > 0
? (adhesionsPayees * 100.0 / adhesionsApprouvees)
: 0.0);
}
/** Génère un numéro de référence unique pour une adhésion */
private String genererNumeroReference() {
return "ADH-" + System.currentTimeMillis() + "-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
}
/** Convertit une entité Adhesion en DTO */
private AdhesionDTO convertToDTO(Adhesion adhesion) {
if (adhesion == null) {
return null;
}
AdhesionDTO dto = new AdhesionDTO();
dto.setId(adhesion.getId());
dto.setNumeroReference(adhesion.getNumeroReference());
// Conversion du membre associé
if (adhesion.getMembre() != null) {
dto.setMembreId(adhesion.getMembre().getId());
dto.setNomMembre(adhesion.getMembre().getNomComplet());
dto.setNumeroMembre(adhesion.getMembre().getNumeroMembre());
dto.setEmailMembre(adhesion.getMembre().getEmail());
}
// Conversion de l'organisation
if (adhesion.getOrganisation() != null) {
dto.setOrganisationId(adhesion.getOrganisation().getId());
dto.setNomOrganisation(adhesion.getOrganisation().getNom());
}
// Propriétés de l'adhésion
dto.setDateDemande(adhesion.getDateDemande());
dto.setFraisAdhesion(adhesion.getFraisAdhesion());
dto.setMontantPaye(adhesion.getMontantPaye());
dto.setCodeDevise(adhesion.getCodeDevise());
dto.setStatut(adhesion.getStatut());
dto.setDateApprobation(adhesion.getDateApprobation());
dto.setDatePaiement(adhesion.getDatePaiement());
dto.setMethodePaiement(adhesion.getMethodePaiement());
dto.setReferencePaiement(adhesion.getReferencePaiement());
dto.setMotifRejet(adhesion.getMotifRejet());
dto.setObservations(adhesion.getObservations());
dto.setApprouvePar(adhesion.getApprouvePar());
dto.setDateValidation(adhesion.getDateValidation());
// Métadonnées de BaseEntity
dto.setDateCreation(adhesion.getDateCreation());
dto.setDateModification(adhesion.getDateModification());
dto.setCreePar(adhesion.getCreePar());
dto.setModifiePar(adhesion.getModifiePar());
dto.setActif(adhesion.getActif());
return dto;
}
/** Convertit un DTO en entité Adhesion */
private Adhesion convertToEntity(AdhesionDTO dto) {
if (dto == null) {
return null;
}
Adhesion adhesion = new Adhesion();
adhesion.setNumeroReference(dto.getNumeroReference());
adhesion.setDateDemande(dto.getDateDemande());
adhesion.setFraisAdhesion(dto.getFraisAdhesion());
adhesion.setMontantPaye(dto.getMontantPaye() != null ? dto.getMontantPaye() : BigDecimal.ZERO);
adhesion.setCodeDevise(dto.getCodeDevise());
adhesion.setStatut(dto.getStatut());
adhesion.setDateApprobation(dto.getDateApprobation());
adhesion.setDatePaiement(dto.getDatePaiement());
adhesion.setMethodePaiement(dto.getMethodePaiement());
adhesion.setReferencePaiement(dto.getReferencePaiement());
adhesion.setMotifRejet(dto.getMotifRejet());
adhesion.setObservations(dto.getObservations());
adhesion.setApprouvePar(dto.getApprouvePar());
adhesion.setDateValidation(dto.getDateValidation());
return adhesion;
}
/** Met à jour les champs modifiables d'une adhésion existante */
private void updateAdhesionFields(Adhesion adhesion, AdhesionDTO dto) {
if (dto.getFraisAdhesion() != null) {
adhesion.setFraisAdhesion(dto.getFraisAdhesion());
}
if (dto.getMontantPaye() != null) {
adhesion.setMontantPaye(dto.getMontantPaye());
}
if (dto.getStatut() != null) {
adhesion.setStatut(dto.getStatut());
}
if (dto.getDateApprobation() != null) {
adhesion.setDateApprobation(dto.getDateApprobation());
}
if (dto.getDatePaiement() != null) {
adhesion.setDatePaiement(dto.getDatePaiement());
}
if (dto.getMethodePaiement() != null) {
adhesion.setMethodePaiement(dto.getMethodePaiement());
}
if (dto.getReferencePaiement() != null) {
adhesion.setReferencePaiement(dto.getReferencePaiement());
}
if (dto.getMotifRejet() != null) {
adhesion.setMotifRejet(dto.getMotifRejet());
}
if (dto.getObservations() != null) {
adhesion.setObservations(dto.getObservations());
}
if (dto.getApprouvePar() != null) {
adhesion.setApprouvePar(dto.getApprouvePar());
}
if (dto.getDateValidation() != null) {
adhesion.setDateValidation(dto.getDateValidation());
}
}
}