chore(docker): add root Dockerfile pinning ubi8/openjdk-21:1.21 + UID 1001 for lionsctl pipeline
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 4m2s

This commit is contained in:
2026-04-24 16:19:25 +00:00
parent fb3a32817b
commit a72ab54abd
461 changed files with 51042 additions and 73486 deletions

View File

@@ -1,194 +1,194 @@
package dev.lions.unionflow.server.entity;
import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* Entité Cotisation avec UUID Représente une cotisation d'un membre à son
* organisation
*
* @author UnionFlow Team
* @version 2.0
* @since 2025-01-16
*/
@Entity
@Table(name = "cotisations", indexes = {
@Index(name = "idx_cotisation_membre", columnList = "membre_id"),
@Index(name = "idx_cotisation_reference", columnList = "numero_reference", unique = true),
@Index(name = "idx_cotisation_statut", columnList = "statut"),
@Index(name = "idx_cotisation_echeance", columnList = "date_echeance"),
@Index(name = "idx_cotisation_type", columnList = "type_cotisation"),
@Index(name = "idx_cotisation_annee_mois", columnList = "annee, mois")
})
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
public class Cotisation extends BaseEntity {
@NotBlank
@Column(name = "numero_reference", unique = true, nullable = false, length = 50)
private String numeroReference;
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "membre_id", nullable = false)
private Membre membre;
/** Organisation pour laquelle la cotisation est due */
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "organisation_id", nullable = false)
private Organisation organisation;
/** Intention de paiement Wave associée (null si cotisation en attente) */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "intention_paiement_id")
private IntentionPaiement intentionPaiement;
@NotBlank
@Column(name = "type_cotisation", nullable = false, length = 50)
private String typeCotisation;
@NotBlank
@Column(name = "libelle", nullable = false, length = 100)
private String libelle;
@NotNull
@DecimalMin(value = "0.0", message = "Le montant dû doit être positif")
@Digits(integer = 10, fraction = 2)
@Column(name = "montant_du", nullable = false, precision = 12, scale = 2)
private BigDecimal montantDu;
@Builder.Default
@DecimalMin(value = "0.0", message = "Le montant payé doit être positif")
@Digits(integer = 10, fraction = 2)
@Column(name = "montant_paye", nullable = false, precision = 12, scale = 2)
private BigDecimal montantPaye = BigDecimal.ZERO;
@NotBlank
@Pattern(regexp = "^[A-Z]{3}$", message = "Le code devise doit être un code ISO à 3 lettres")
@Column(name = "code_devise", nullable = false, length = 3)
private String codeDevise;
@NotBlank
@Pattern(regexp = "^(EN_ATTENTE|PAYEE|EN_RETARD|PARTIELLEMENT_PAYEE|ANNULEE)$")
@Column(name = "statut", nullable = false, length = 30)
private String statut;
@NotNull
@Column(name = "date_echeance", nullable = false)
private LocalDate dateEcheance;
@Column(name = "date_paiement")
private LocalDateTime datePaiement;
@Size(max = 500)
@Column(name = "description", length = 500)
private String description;
@Size(max = 20)
@Column(name = "periode", length = 20)
private String periode;
@NotNull
@Min(value = 2020, message = "L'année doit être supérieure à 2020")
@Max(value = 2100, message = "L'année doit être inférieure à 2100")
@Column(name = "annee", nullable = false)
private Integer annee;
@Min(value = 1, message = "Le mois doit être entre 1 et 12")
@Max(value = 12, message = "Le mois doit être entre 1 et 12")
@Column(name = "mois")
private Integer mois;
@Size(max = 1000)
@Column(name = "observations", length = 1000)
private String observations;
@Builder.Default
@Column(name = "recurrente", nullable = false)
private Boolean recurrente = false;
@Builder.Default
@Min(value = 0, message = "Le nombre de rappels doit être positif")
@Column(name = "nombre_rappels", nullable = false)
private Integer nombreRappels = 0;
@Column(name = "date_dernier_rappel")
private LocalDateTime dateDernierRappel;
@Column(name = "valide_par_id")
private UUID valideParId;
@Size(max = 100)
@Column(name = "nom_validateur", length = 100)
private String nomValidateur;
@Column(name = "date_validation")
private LocalDateTime dateValidation;
/** Méthode métier pour calculer le montant restant à payer */
public BigDecimal getMontantRestant() {
if (montantDu == null || montantPaye == null) {
return BigDecimal.ZERO;
}
return montantDu.subtract(montantPaye);
}
/** Méthode métier pour vérifier si la cotisation est entièrement payée */
public boolean isEntierementPayee() {
return getMontantRestant().compareTo(BigDecimal.ZERO) <= 0;
}
/** Méthode métier pour vérifier si la cotisation est en retard */
public boolean isEnRetard() {
return dateEcheance != null && dateEcheance.isBefore(LocalDate.now()) && !isEntierementPayee();
}
private static final AtomicLong REFERENCE_COUNTER =
new AtomicLong(System.currentTimeMillis() % 100000000L);
/** Méthode métier pour générer un numéro de référence unique */
public static String genererNumeroReference() {
return "COT-"
+ LocalDate.now().getYear()
+ "-"
+ String.format("%08d", REFERENCE_COUNTER.incrementAndGet() % 100000000L);
}
/** Callback JPA avant la persistance */
@PrePersist
protected void onCreate() {
super.onCreate(); // Appelle le onCreate de BaseEntity
if (numeroReference == null || numeroReference.isEmpty()) {
numeroReference = genererNumeroReference();
}
if (codeDevise == null) {
codeDevise = "XOF";
}
if (statut == null) {
statut = "EN_ATTENTE";
}
if (montantPaye == null) {
montantPaye = BigDecimal.ZERO;
}
if (nombreRappels == null) {
nombreRappels = 0;
}
if (recurrente == null) {
recurrente = false;
}
}
}
package dev.lions.unionflow.server.entity;
import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* Entité Cotisation avec UUID Représente une cotisation d'un membre à son
* organisation
*
* @author UnionFlow Team
* @version 2.0
* @since 2025-01-16
*/
@Entity
@Table(name = "cotisations", indexes = {
@Index(name = "idx_cotisation_membre", columnList = "membre_id"),
@Index(name = "idx_cotisation_reference", columnList = "numero_reference", unique = true),
@Index(name = "idx_cotisation_statut", columnList = "statut"),
@Index(name = "idx_cotisation_echeance", columnList = "date_echeance"),
@Index(name = "idx_cotisation_type", columnList = "type_cotisation"),
@Index(name = "idx_cotisation_annee_mois", columnList = "annee, mois")
})
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
public class Cotisation extends BaseEntity {
@NotBlank
@Column(name = "numero_reference", unique = true, nullable = false, length = 50)
private String numeroReference;
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "membre_id", nullable = false)
private Membre membre;
/** Organisation pour laquelle la cotisation est due */
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "organisation_id", nullable = false)
private Organisation organisation;
/** Intention de paiement Wave associée (null si cotisation en attente) */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "intention_paiement_id")
private IntentionPaiement intentionPaiement;
@NotBlank
@Column(name = "type_cotisation", nullable = false, length = 50)
private String typeCotisation;
@NotBlank
@Column(name = "libelle", nullable = false, length = 100)
private String libelle;
@NotNull
@DecimalMin(value = "0.0", message = "Le montant dû doit être positif")
@Digits(integer = 10, fraction = 2)
@Column(name = "montant_du", nullable = false, precision = 12, scale = 2)
private BigDecimal montantDu;
@Builder.Default
@DecimalMin(value = "0.0", message = "Le montant payé doit être positif")
@Digits(integer = 10, fraction = 2)
@Column(name = "montant_paye", nullable = false, precision = 12, scale = 2)
private BigDecimal montantPaye = BigDecimal.ZERO;
@NotBlank
@Pattern(regexp = "^[A-Z]{3}$", message = "Le code devise doit être un code ISO à 3 lettres")
@Column(name = "code_devise", nullable = false, length = 3)
private String codeDevise;
@NotBlank
@Pattern(regexp = "^(EN_ATTENTE|PAYEE|EN_RETARD|PARTIELLEMENT_PAYEE|ANNULEE)$")
@Column(name = "statut", nullable = false, length = 30)
private String statut;
@NotNull
@Column(name = "date_echeance", nullable = false)
private LocalDate dateEcheance;
@Column(name = "date_paiement")
private LocalDateTime datePaiement;
@Size(max = 500)
@Column(name = "description", length = 500)
private String description;
@Size(max = 20)
@Column(name = "periode", length = 20)
private String periode;
@NotNull
@Min(value = 2020, message = "L'année doit être supérieure à 2020")
@Max(value = 2100, message = "L'année doit être inférieure à 2100")
@Column(name = "annee", nullable = false)
private Integer annee;
@Min(value = 1, message = "Le mois doit être entre 1 et 12")
@Max(value = 12, message = "Le mois doit être entre 1 et 12")
@Column(name = "mois")
private Integer mois;
@Size(max = 1000)
@Column(name = "observations", length = 1000)
private String observations;
@Builder.Default
@Column(name = "recurrente", nullable = false)
private Boolean recurrente = false;
@Builder.Default
@Min(value = 0, message = "Le nombre de rappels doit être positif")
@Column(name = "nombre_rappels", nullable = false)
private Integer nombreRappels = 0;
@Column(name = "date_dernier_rappel")
private LocalDateTime dateDernierRappel;
@Column(name = "valide_par_id")
private UUID valideParId;
@Size(max = 100)
@Column(name = "nom_validateur", length = 100)
private String nomValidateur;
@Column(name = "date_validation")
private LocalDateTime dateValidation;
/** Méthode métier pour calculer le montant restant à payer */
public BigDecimal getMontantRestant() {
if (montantDu == null || montantPaye == null) {
return BigDecimal.ZERO;
}
return montantDu.subtract(montantPaye);
}
/** Méthode métier pour vérifier si la cotisation est entièrement payée */
public boolean isEntierementPayee() {
return getMontantRestant().compareTo(BigDecimal.ZERO) <= 0;
}
/** Méthode métier pour vérifier si la cotisation est en retard */
public boolean isEnRetard() {
return dateEcheance != null && dateEcheance.isBefore(LocalDate.now()) && !isEntierementPayee();
}
private static final AtomicLong REFERENCE_COUNTER =
new AtomicLong(System.currentTimeMillis() % 100000000L);
/** Méthode métier pour générer un numéro de référence unique */
public static String genererNumeroReference() {
return "COT-"
+ LocalDate.now().getYear()
+ "-"
+ String.format("%08d", REFERENCE_COUNTER.incrementAndGet() % 100000000L);
}
/** Callback JPA avant la persistance */
@PrePersist
protected void onCreate() {
super.onCreate(); // Appelle le onCreate de BaseEntity
if (numeroReference == null || numeroReference.isEmpty()) {
numeroReference = genererNumeroReference();
}
if (codeDevise == null) {
codeDevise = "XOF";
}
if (statut == null) {
statut = "EN_ATTENTE";
}
if (montantPaye == null) {
montantPaye = BigDecimal.ZERO;
}
if (nombreRappels == null) {
nombreRappels = 0;
}
if (recurrente == null) {
recurrente = false;
}
}
}