Aller au contenu principal

Données maîtres (syndicats, employeurs, emplois)

Ce guide détaille la gestion des référentiels MCM : syndicats, employeurs, et emplois (liens employé-employeur). Il pose la stratégie d'identifiants externes (IdentifiantExterne) et les interactions entre ces trois entités.

Module requis : MaCarteDeMembre.

Clients SDK : ISyndicatsClient, IEmployeursClient, IEmploisClient, IObjetsConsentementClient.


1. Modèle de données

Syndicat (1) ───< Employeur (N)


Emploi (N) >─── Employe (1)

Adhesion (N) >─── Syndicat (1)
  • Syndicat — une organisation membre (union, association).
  • Employeur — une organisation employant des membres ; rattaché à un syndicat principal.
  • Emploi — un lien employé ↔ employeur (un employé peut en avoir plusieurs, simultanés ou successifs).
  • Adhésion — un lien employé ↔ syndicat avec une DateAdhesion. Distinct de l'emploi.
  • Objet de consentement — un consentement nommable (infolettre, partage d'infos, …) qu'on peut attacher aux employés.

2. Stratégie d'identifiants externes

Toutes les entités exposent un IdentifiantExterne (ou IdExterne) sous votre contrôle. C'est la clé primaire côté MCM, utilisée pour :

  • Identifier l'entité dans tous les endpoints B2B
  • Router les upserts (AddXxx vs UpdateXxx)
  • Dédupliquer les syncs

Règles

  1. Unique à l'échelle du client MCM pour chaque type d'entité.
  2. Stable — ne jamais le renommer une fois utilisé côté MCM ; cela crée un doublon, pas un rename.
  3. Opaque pour MCM mais signifiant pour vous (ex. EMP-MTL-001, PERSON-423). Préférez un slug lisible à un UUID aléatoire : la maintenance est plus simple.
  4. Pas de dépendance aux ID internes MCM (IdUnique est une Guid générée par MCM ; ne la stockez pas comme identifiant source).

Collision et rename

Si vous devez renommer un IdentifiantExterne côté source :

  1. Créez l'entité avec le nouvel identifiant (AddXxx).
  2. Mettez à jour les entités enfants pour pointer vers le nouveau parent (SyncClient.Sync ou CRUD unitaire).
  3. Supprimez l'ancienne entité seulement après validation (DeleteXxx).

Il n'existe pas d'endpoint de « rename atomique » côté API.


3. Syndicats (ISyndicatsClient)

Entité minimale : simplement un nom et un identifiant externe.

Créer

await syndicatsClient.AddSyndicat(new B2BUpdateSyndicatDto
{
IdentifiantExterne = "SYND001",
Nom = "Syndicat des travailleurs"
});

Lister / récupérer / mettre à jour / supprimer

var all = await syndicatsClient.GetAllSyndicats();
var one = await syndicatsClient.GetSyndicatById("SYND001");

await syndicatsClient.UpdateSyndicat(new B2BUpdateSyndicatDto
{
IdentifiantExterne = "SYND001",
Nom = "Nouveau nom"
});

await syndicatsClient.DeleteSyndicat("SYND001");

B2BSyndicatItem hérite aujourd'hui de B2BUpdateSyndicatDto (pas de colonnes en lecture seule additionnelles).

Suppression : bloquée si le syndicat référence des employeurs ou des adhésions actives. Supprimez ou reparentez ces dépendances avant.


4. Employeurs (IEmployeursClient)

Un employeur est porté par un syndicat dans le modèle V2 (structure imbriquée dans B2BUpdateSyndicatDtoV2.Employeurs). En V1 CRUD, le syndicat est implicite (rattachement au syndicat principal du client si non précisé).

Créer via V2 Sync (recommandé)

await syncClient.Sync(
syndicatDtos:
[
new B2BUpdateSyndicatDtoV2
{
IdentifiantExterne = "SYND001",
Nom = "Syndicat",
Employeurs =
[
new() { IdentifiantExterne = "EMP001", Nom = "Entreprise ABC" },
new() { IdentifiantExterne = "EMP002", Nom = "Entreprise XYZ" }
]
}
],
employeDtos: [],
objetConsentementDtos: []);

Créer via CRUD V1

await employeursClient.AddEmployeur(new B2BUpdateEmployeurDto
{
IdentifiantExterne = "EMP001",
Nom = "Entreprise ABC"
});

Lister

var all = await employeursClient.GetAllEmployeurs();   // IEnumerable<B2BUpdateEmployeurDto>

Le GetAllEmployeurs V1 retourne les mêmes DTO que la mise à jour (pas de champs supplémentaires). Pour des queries avancées (filtrer par syndicat, compter les emplois actifs), passez par IEmploisClient.SearchEmplois avec IdExterneEmployeur.


5. Emplois (IEmploisClient)

Un emploi = relation durable employé ↔ employeur (avec éventuellement Matricule, DateDebut, DateFin). Un même employé peut en avoir plusieurs (multi-employeurs ou changements d'emploi).

Clé composite

  • Identifiant externe de l'emploi : votre propre ID unique (IdentifiantExterne).
  • Relation : IdentifiantExterneEmploye + IdentifiantExterneEmployeur.

Créer

await emploisClient.AddEmploi(new B2BUpdateEmploiDto
{
IdentifiantExterne = "EMPLOI-001",
IdentifiantExterneEmploye = "PERSON001",
IdentifiantExterneEmployeur = "EMP001",
Matricule = "M12345",
DateDebut = new DateTime(2020, 1, 15),
DateFin = null // null = actif
});

Terminer un emploi

Mettez à jour avec DateFin :

await emploisClient.UpdateEmploi(new B2BUpdateEmploiDto
{
IdentifiantExterne = "EMPLOI-001",
IdentifiantExterneEmploye = "PERSON001",
IdentifiantExterneEmployeur = "EMP001",
Matricule = "M12345",
DateDebut = new DateTime(2020, 1, 15),
DateFin = new DateTime(2026, 3, 31)
});

Ne supprimez pas un emploi terminé — la DateFin suffit et préserve l'historique des adhésions.

Rechercher

var actifs = await emploisClient.SearchEmplois(new B2BEmploiSearchRequest
{
IdExterneEmployeur = "EMP001",
Actif = true // DateFin IS NULL
});

Filtres : IdExterneSyndicat, IdExterneEmployeur, IdExterneEmploye, Matricule, Actif.

Cas « changement d'employeur »

Deux approches :

  1. Deux emplois distincts (historique conservé) :

    EMPLOI-001 : EMP001, 2020-01-15 → 2026-03-31
    EMPLOI-002 : EMP002, 2026-04-01 → null

    Recommandé — préserve les rapports historiques.

  2. Un seul emploi muté (perd l'historique) : Mettez à jour IdentifiantExterneEmployeur. À éviter sauf si le changement est une correction d'erreur.


6. Objets de consentement (IObjetsConsentementClient)

Un objet de consentement décrit ce à quoi le membre a consenti : Titre, IdentifiantExterne, Description. L'attachement à un employé se fait via le formulaire de consentement côté MCM ou via B2BUpsertEmployeDtoV2.Adhesions + templates.

CRUD

await objetsConsentementClient.AddObjetConsentement(new B2BUpdateObjetConsentementDto
{
IdentifiantExterne = "INFOLETTRE",
Titre = "Recevoir l'infolettre mensuelle",
Description = "Communication trimestrielle du syndicat, désabonnement possible à tout moment."
});

await objetsConsentementClient.GetAllObjetsConsentement();

Pour lire les consentements donnés par les membres, utilisez IConsentementClient (lecture seule).


7. Intégrité référentielle

MCM valide les liens à l'écriture :

OpérationVérification
Créer un employeurLe syndicat parent doit exister (V2 Sync) ou utiliser le syndicat principal (V1)
Créer un emploiEmployé + employeur doivent exister
Créer une adhésion (via Sync V2)Employé + syndicat doivent exister
Supprimer un syndicatAucun employeur ni adhésion active
Supprimer un employeurAucun emploi actif
Supprimer un employéAucun emploi actif ni adhésion active (selon règles côté client)

Les erreurs retournées suivent le pattern EntiteParent.NotFound ou Entite.DependanceActive.


8. Lectures fréquentes

Inventaire des employés d'un employeur

var emplois = await emploisClient.SearchEmplois(new B2BEmploiSearchRequest
{
IdExterneEmployeur = "EMP001",
Actif = true
});

foreach (var e in emplois.Value)
Console.WriteLine($"{e.IdentifiantExterneEmploye} matricule={e.Matricule}");

Tableau de bord par syndicat

var employeurs = await employeursClient.GetAllEmployeurs();
var syndicats = await syndicatsClient.GetAllSyndicats();

// Puis filtrer les emplois par syndicat pour des métriques
foreach (var s in syndicats.Value)
{
var emplois = await emploisClient.SearchEmplois(new B2BEmploiSearchRequest
{
IdExterneSyndicat = s.IdentifiantExterne,
Actif = true
});
Console.WriteLine($"{s.Nom}: {emplois.Value.Count()} actifs");
}

Pour de gros volumes ou des calculs récurrents, préférez une synchronisation de votre côté + calcul local — moins d'allers-retours HTTP.


9. Bonnes pratiques

  • Syndicats et employeurs : créez-les avant tout sync d'employés. Idéalement en configuration statique ou dans une étape d'init séparée.
  • Emplois via Sync V2 : préférez nester les emplois dans B2BUpsertEmployeDtoV2.Emplois — une seule transaction par employé. CRUD unitaire = cas de correction ponctuelle.
  • Ne pas supprimer l'historique : DateFin > DeleteEmploi. Les adhésions et les votes historiques dépendent des emplois.
  • Matricule unique par employeur : MCM impose l'unicité (matricule, employeur) — une collision retourne une erreur validation.
  • Slugs lisibles : SYND-CSN-001, EMP-MTL-002 > 00c3e1a8-.... Les logs et traces sont plus faciles à déboguer.
  • Mocks / tests : ITestClient (interne) crée un client de test + ses référentiels — voir Tests/MCM.B2B.IntegrationTests.

Voir aussi