feat(types-org): validation LCB-FT FINANCIER_SOLIDAIRE + code auto-normalisation
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 2m55s
Some checks failed
CI/CD Pipeline / pipeline (push) Failing after 2m55s
TypeReferenceService : - validerLbcFtSiFinancierSolidaire() : LCB_FT obligatoire BCEAO appelé avant persist et update - genererCodeDepuisLibelle() / normaliserCode() : UPPER_SNAKE_CASE sans accents - assurerUniciteCode() : suffixe _2/_3 en cas de doublon TypeReferenceServiceTest : 6 tests validerLbcFtSiFinancierSolidaire (avec/sans LCB_FT, catégorie non-financière, modification suppressionLcbFt)
This commit is contained in:
@@ -11,6 +11,7 @@ import jakarta.enterprise.context.ApplicationScoped;
|
|||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
import java.text.Normalizer;
|
import java.text.Normalizer;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -157,6 +158,9 @@ public class TypeReferenceService {
|
|||||||
.modulesRequis(request.modulesRequis())
|
.modulesRequis(request.modulesRequis())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
validerLbcFtSiFinancierSolidaire(
|
||||||
|
entity.getCategorie(), entity.getModulesRequis());
|
||||||
|
|
||||||
if (request.organisationId() != null) {
|
if (request.organisationId() != null) {
|
||||||
Organisation org = organisationRepository
|
Organisation org = organisationRepository
|
||||||
.findById(request.organisationId());
|
.findById(request.organisationId());
|
||||||
@@ -211,6 +215,8 @@ public class TypeReferenceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
appliquerMiseAJour(entity, request);
|
appliquerMiseAJour(entity, request);
|
||||||
|
validerLbcFtSiFinancierSolidaire(
|
||||||
|
entity.getCategorie(), entity.getModulesRequis());
|
||||||
entity.setModifiePar(
|
entity.setModifiePar(
|
||||||
keycloakService.getCurrentUserEmail());
|
keycloakService.getCurrentUserEmail());
|
||||||
repository.update(entity);
|
repository.update(entity);
|
||||||
@@ -353,6 +359,26 @@ public class TypeReferenceService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Réglementation BCEAO : LCB_FT obligatoire pour FINANCIER_SOLIDAIRE.
|
||||||
|
* Appelé avant persist et avant update pour couvrir les deux flux.
|
||||||
|
*/
|
||||||
|
private void validerLbcFtSiFinancierSolidaire(
|
||||||
|
String categorie, String modulesRequis) {
|
||||||
|
if (!"FINANCIER_SOLIDAIRE".equals(categorie)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean contientLbcFt = modulesRequis != null
|
||||||
|
&& Arrays.asList(modulesRequis.split(","))
|
||||||
|
.contains("LCB_FT");
|
||||||
|
if (!contientLbcFt) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Le module LCB_FT (anti-blanchiment) est obligatoire "
|
||||||
|
+ "pour les types d'organisation de catégorie "
|
||||||
|
+ "FINANCIER_SOLIDAIRE (réglementation BCEAO)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Valide l'unicité du code dans un domaine.
|
* Valide l'unicité du code dans un domaine.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -506,4 +506,128 @@ class TypeReferenceServiceTest {
|
|||||||
assertThat(updated.getOrdreAffichage()).isEqualTo(10);
|
assertThat(updated.getOrdreAffichage()).isEqualTo(10);
|
||||||
assertThat(updated.getEstDefaut()).isTrue();
|
assertThat(updated.getEstDefaut()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// validerLbcFtSiFinancierSolidaire — règle BCEAO
|
||||||
|
// ================================================================
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestTransaction
|
||||||
|
@DisplayName("creer FINANCIER_SOLIDAIRE sans LCB_FT lance IllegalArgumentException")
|
||||||
|
void creer_financierSolidaire_sansLbcFt_throws() {
|
||||||
|
String domaine = "TYPE_ORGANISATION";
|
||||||
|
CreateTypeReferenceRequest request = CreateTypeReferenceRequest.builder()
|
||||||
|
.domaine(domaine)
|
||||||
|
.code("FS_" + UUID.randomUUID().toString().substring(0, 8))
|
||||||
|
.libelle("Mutuelle test")
|
||||||
|
.categorie("FINANCIER_SOLIDAIRE")
|
||||||
|
.modulesRequis("COTISATIONS,EPARGNE,CREDIT")
|
||||||
|
.organisationId(null)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> typeReferenceService.creer(request))
|
||||||
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
|
.hasMessageContaining("LCB_FT");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestTransaction
|
||||||
|
@DisplayName("creer FINANCIER_SOLIDAIRE avec modulesRequis null lance IllegalArgumentException")
|
||||||
|
void creer_financierSolidaire_modulesNull_throws() {
|
||||||
|
CreateTypeReferenceRequest request = CreateTypeReferenceRequest.builder()
|
||||||
|
.domaine("TYPE_ORGANISATION")
|
||||||
|
.code("FS_NULL_" + UUID.randomUUID().toString().substring(0, 6))
|
||||||
|
.libelle("Mutuelle sans modules")
|
||||||
|
.categorie("FINANCIER_SOLIDAIRE")
|
||||||
|
.modulesRequis(null)
|
||||||
|
.organisationId(null)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> typeReferenceService.creer(request))
|
||||||
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
|
.hasMessageContaining("LCB_FT");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestTransaction
|
||||||
|
@DisplayName("creer FINANCIER_SOLIDAIRE avec LCB_FT réussit")
|
||||||
|
void creer_financierSolidaire_avecLbcFt_succes() {
|
||||||
|
CreateTypeReferenceRequest request = CreateTypeReferenceRequest.builder()
|
||||||
|
.domaine("TYPE_ORGANISATION")
|
||||||
|
.code("FS_OK_" + UUID.randomUUID().toString().substring(0, 6))
|
||||||
|
.libelle("Mutuelle conforme")
|
||||||
|
.categorie("FINANCIER_SOLIDAIRE")
|
||||||
|
.modulesRequis("COTISATIONS,EPARGNE,CREDIT,LCB_FT")
|
||||||
|
.organisationId(null)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
TypeReferenceResponse created = typeReferenceService.creer(request);
|
||||||
|
assertThat(created).isNotNull();
|
||||||
|
assertThat(created.getModulesRequis()).contains("LCB_FT");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestTransaction
|
||||||
|
@DisplayName("creer catégorie ASSOCIATIF sans LCB_FT réussit (pas de contrainte)")
|
||||||
|
void creer_autreCategorie_sansLbcFt_succes() {
|
||||||
|
CreateTypeReferenceRequest request = CreateTypeReferenceRequest.builder()
|
||||||
|
.domaine("TYPE_ORGANISATION")
|
||||||
|
.code("ASSOC_" + UUID.randomUUID().toString().substring(0, 6))
|
||||||
|
.libelle("Association simple")
|
||||||
|
.categorie("ASSOCIATIF")
|
||||||
|
.modulesRequis("COTISATIONS,EVENEMENTS")
|
||||||
|
.organisationId(null)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
TypeReferenceResponse created = typeReferenceService.creer(request);
|
||||||
|
assertThat(created).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestTransaction
|
||||||
|
@DisplayName("modifier FINANCIER_SOLIDAIRE en retirant LCB_FT lance IllegalArgumentException")
|
||||||
|
void modifier_financierSolidaire_suppressionLbcFt_throws() {
|
||||||
|
TypeReferenceResponse created = typeReferenceService.creer(
|
||||||
|
CreateTypeReferenceRequest.builder()
|
||||||
|
.domaine("TYPE_ORGANISATION")
|
||||||
|
.code("FS_MOD_" + UUID.randomUUID().toString().substring(0, 6))
|
||||||
|
.libelle("Mutuelle à modifier")
|
||||||
|
.categorie("FINANCIER_SOLIDAIRE")
|
||||||
|
.modulesRequis("COTISATIONS,LCB_FT")
|
||||||
|
.organisationId(null)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
UpdateTypeReferenceRequest update = new UpdateTypeReferenceRequest(
|
||||||
|
null, null, null, null, null, null, null, null, null,
|
||||||
|
null, // categorie inchangée → reste FINANCIER_SOLIDAIRE
|
||||||
|
"COTISATIONS,EPARGNE"); // LCB_FT retiré
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> typeReferenceService.modifier(created.getId(), update))
|
||||||
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
|
.hasMessageContaining("LCB_FT");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestTransaction
|
||||||
|
@DisplayName("modifier FINANCIER_SOLIDAIRE sans changer modulesRequis réussit")
|
||||||
|
void modifier_financierSolidaire_sansChangerModules_succes() {
|
||||||
|
TypeReferenceResponse created = typeReferenceService.creer(
|
||||||
|
CreateTypeReferenceRequest.builder()
|
||||||
|
.domaine("TYPE_ORGANISATION")
|
||||||
|
.code("FS_NOCHG_" + UUID.randomUUID().toString().substring(0, 5))
|
||||||
|
.libelle("Mutuelle initiale")
|
||||||
|
.categorie("FINANCIER_SOLIDAIRE")
|
||||||
|
.modulesRequis("COTISATIONS,LCB_FT")
|
||||||
|
.organisationId(null)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
UpdateTypeReferenceRequest update = new UpdateTypeReferenceRequest(
|
||||||
|
null, "Mutuelle renommée", null, null, null, null, null, null, null,
|
||||||
|
null, // categorie inchangée
|
||||||
|
null); // modulesRequis inchangé → LCB_FT conservé en entité
|
||||||
|
|
||||||
|
TypeReferenceResponse updated = typeReferenceService.modifier(created.getId(), update);
|
||||||
|
assertThat(updated.getLibelle()).isEqualTo("Mutuelle renommée");
|
||||||
|
assertThat(updated.getModulesRequis()).contains("LCB_FT");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user