# Pagga.Remuneration - Présentation - Rapports F/H
# Périmètre fonctionnel
https://www.notion.so/Sp-carts-de-r-mun-rations-4fe564d3ee634e14938c2e0c1d5d8cff


# Contrat d'API
Services dédié pour les rapports d'égalité H/F
Note importante : on prend l'établissement de la personne à la date de fin de période
## Filtres & modèle de rapport
#### Dto
```csharp
abstract class ReportTemplate {
int Id;
string Name;
abstract ReportType ReportType;
}
class ReportTemplateTop : ReportTemplate {
List<Establishment> Establishments; // Simplified Establishments
List<Department> Departments; // Simplified Dept
List<OccupationCategory> Occu;
List<VariableRemunerationNature> VariableRemunerationNatures;
List<FixedRemunerationNature> FixedRemunerationNatures;
List<WorkContractType> WorkContractTypes;
}
class ReportTemplateGenderGap : ReportTemplate{
OccupationCategoryGroups OccupationCategoryGroups;
List<Establishment> Establishments; // Simplified Establishments
List<Department> Departments; // Simplified Dept
List<VariableRemunerationNature> VariableRemunerationNatures;
List<FixedRemunerationNature> FixedRemunerationNatures;
List<WorkContractType> WorkContractTypes
}
class OccupationCategoryGroups {
List<Group<OccupationCategories>> OccupationCategoryGroups;
}
class Group<T> { // Si trop complexe avec le swagger, on passe sur une classe par groupe
int Id,
string Name,
T[] Items
}
enum ReportType {
Top,
GenderGap
}
```
### Apis
#### GET - /remuneration/api/report-templates/top
- Response : ReportTemplateTop[]
#### GET - /remuneration/api/report-templates/top/{id}
- Response : ReportTemplateTop
#### GET - /remuneration/api/report-templates/gender-gap
- Response : ReportTemplateGenderGap[]
#### GET - /remuneration/api/report-templates/gender-gap/{id}
- Response : ReportTemplateGenderGap
#### POST - /remuneration/api/report-templates/gender-gap
- Payload
```json=
{
name: "nom du modèle",
establishmentIds: [1, 2, 3],
departmentIds: [1, 2],
...
}
```
#### PUT - /remuneration/api/report-templates/gender-gap/{id}
- Payload
```json=
{
id : 1,
name: "nom du modèle",
establishmentIds: [1, 2, 3],
departmentIds: [1, 2],
...
}
```
#### POST - /remuneration/api/report-templates/top
- Payload
```json=
{
name: "nom du modèle",
establishmentIds: [1, 2, 3],
departmentIds: [1, 2],
occupationCategoryGroups: [ // A revoir ce point là -> l'interface de gestion des groupes serait interessante, notament pour les Apis
{
name : "groupe 1",
ids : [1, 2, 3]
}
],
...
}
```
#### PUT - /remuneration/api/report-templates/top/{id}
- Payload : idem Post
#### DELETE - /remuneration/api/report-templates/{id}
### Notes pour le front
#### APIs a utiliser
- modèles de contrat :
https://demoprem1.ilucca.net/directory/api/work-contract-types
- établissements : https://demoprem1.ilucca.net/organization/structure/api/establishments
- departements : https://demoprem1.ilucca.net/api/v3/departments/tree?fields=id,name,code,head[id,name,dtContractEnd],isActive,currentUsersCount&isActive=true
- CSP : https://demoprem1.ilucca.net/organization/structure/api/occupation-categories
- natures EFP : https://demoprem1.ilucca.net/api/v3/fixedRemunerationNatures
- natures EVP : https://demoprem1.ilucca.net/api/v3/variableRemunerationNatures?typeId=1
Todo :
- Voir le picker du departement de Poplee-Engagement @f2x
- Faire un establishmentPicker custom Bu-Pay pour prendre en compte les LU et les devises
## Générer un rapport - Top
**⚠️Pas de pagination sur cette API⚠️**

### Apis
#### POST - /remuneration/api/reports/top
- payload
```json=
{
endDate : "2023-01-03",
template :
{
name: "nom du modèle",
establishmentIds: [1, 2, 3],
departmentIds: [1, 2],
...
}
}
```
- response : TopReport
### Dto
```csharp
class TopReport {
DateOnly StartDate;
DateOnly EndDate;
List<TopRankedRemuneration> TopRankedRemunerations;
}
class TopRankedRemuneration {
User User;
Establishment Establishment;
int Rank;
RemunerationAmount RemunerationAmount;
}
class RemunerationAmount {
decimal Amount;
Currency Currency
}
```
## Générer un rapport - Gender Gap
**⚠️Pas de pagination sur cette API⚠️**

### Apis
#### POST - /remuneration/api/reports/gender-gap
- payload
```json=
{
endDate : "2023-01-03",
template :
{
name: "nom du modèle",
establishmentIds: [1, 2, 3],
departmentIds: [1, 2],
occupationCategoryGroups: [ // A revoir ce point là -> l'interface de gestion des groupes serait interessante, notament pour les Apis
{
name : "groupe 1",
ids : [1, 2, 3]
}
],
...
}
}
```
#### GET - /remuneration/api/reports/gender-gap/details?OccupationCategoryIds=1,2,3,4&ageMin=18&ageMax=55
- RequiredField : OccupationCategoryIds & ageMin
- response : UserRemunerationPage
### Dto
```csharp
class GenderGapReport {
DateOnly StartDate;
DateOnly EndDate;
List<GenderGapReportItem> Items;
GenderGapReportMetrics Total
}
class GenderGapReportItem {
OccupationCategoryCriteria OccupationCategory;
AgeRangeCriterion AgeRange;
GenderGapReportMetrics Metrics;
}
class GenderGapReportMetrics {
GenderMetrics MaleMetrics;
GenderMetrics FemaleMetrics;
decimal PercentageGap
}
class AgeRangeCriterion {
int Min,
int? Max
}
class OccupationCategoryCriteria {
string Name;
List<OccupationCategory> OccupationCategories; // liste simplifiée de OccupationCategory
}
class GenderMetrics {
RemunerationAmount AverageAmount,
int Count
}
class RemunerationAmount {
decimal Amount;
Currency Currency
}
class UserRemuneration {
User User;
RemunerationAmount Amount;
}
```
### APIS des warnings
#### POST - /remuneration/api/reports/gender-gap/warnings
- payload
```json=
{
endDate : "2023-01-03",
template :
{
name: "nom du modèle",
establishmentIds: [1, 2, 3],
departmentIds: [1, 2],
occupationCategoryGroups: [ // A revoir ce point là -> l'interface de gestion des groupes serait interessante, notament pour les Apis
{
name : "groupe 1",
ids : [1, 2, 3]
}
],
...
}
}
```
- response : GenderGapWarningPage
#### Dto
```csharp
class GenderGapWarningPage : Page<GenderGapWarning> {
int MissingOccupationCategoryCount;
int UndefinedGenderCount;
}
class GenderGapWarning {
User User;
GenderGapWarningType WarningType;
}
enum GenderGapWarningType {
MissingOccupationCategory,
UndefinedGender
}
```
# Architecture technique
[](https://i.imgur.com/Ysk1q7X.jpg)
## Découpage des services
- Service propre au rapport (un pour chaque rapport)
- Service de filtrage de population
- Service d'extraction des données nécessaires au moteur
- Service de calcul des rémunerations (moteur de calcul)
### Filtrage de Population
#### Entrées
On donne les filtres correspondant au rapport en question.
Uniquement les données associées aux workcontracts :
- Establishments
- Departments
- OccupationCategories
- WorkContractTypes
- Qualification (pas MVP)
- Période sur laquelle les contrats sont éligibles (Date de début/date de fin)
- Collaborateurs présent sur la fin de la période (true/false)
- Temps de présence sur la période demandée
#### Sortie possible
- Liste de workcontracts (pas nécessaire pour notre cas ?)
- Liste de workcontracts paginée (pas nécessaire pour notre cas ?)
- Expression/Prédicat permettant de récupérer cette liste des workcontracts
### Récupération des données de rémunérations
On va utiliser une fonction SQL pour récupérer les données de rémunération (EVP/EFP) qui sont nécessaires au moteur de calcul. Cette fonction nous permet de récupérer les données de manière "propre".
POC de cette fonction
**Entrée**
- Date de début
- Date de fin
**Sortie**
Periode (mois)
Nombre de jours calendaires de la période
Contrat sur la période
Nombre de jours calendaires d'intersection du contrat
Element de rémuneration de la période (fixe ou variable)
Nombre de jour calendaires d'intersection de l'élement de rémunération
ETP à fin de période ou fin de contrat
### Moteur de calcul
**Entrée du moteur :**
- liste de ligne permettant le calcul
- liste de règles chainables optionnelles
- une règle d'aggrégation
- une liste de règles de transformations optionnelles
**Process d'éxecution du moteur :**
Pour chaque ligne, on applique toute les règles chainables.
Une fois le chainage terminé, on applique la règle d'aggrégation.
Pour terminer on applique les règles de transformations.
*3 types de règles :*
- Item Transformation
- Aggregation
- Aggregate transformation
Règles *Item Transformation*
- Entrée : Une ligne (ComputedRemunerationItem)
- `ComputedRemunerationItem`
- Sortie : La même ligne (ComputedRemunerationItem) avec le montant calculé mis à jour
- `ComputedRemunerationItem`
```csharp
class ComputedRemunerationItem {
decimal ComputedAmount; // montant utilisé par les règles
PeriodRemunerationItem SourceItem;
}
```
- Exemples de rêgles :
* Proratisation par ETP
* Proratisation calendaire
* Multiplication par le nombre de périodes
Règles *Aggregation*
- Entrée : Une liste de lignes (ComputedRemunerationItem)
- `ComputedRemunerationItem`
- Sortie : Un (AggregatedRemunerationItem) qui renvoie le montant aggrégé et pondéré
- `AggregatedRemunerationItem`
```csharp
class AggregatedRemunerationItem {
int Weight; // A rediscuter au moment de l'implem
decimal Sum;
}
```
- Exemples de rêgles :
* Somme
* Moyenne
* Reconsitution annuelle
Règles *Aggregate transformation*
- Entrée : Un (AggregatedRemunerationItem)
- `AggregatedRemunerationItem`
- Sortie : Un (AggregatedRemunerationItem) modifié
- `AggregatedRemunerationItem`
- Exemples de rêgles :
* Pondération via user dates
* Arrondi
* ....
#### Modèle de donnée
```csharp
interface IItemTransformationRule {
ComputedRemunerationItem Apply(ComputedRemunerationItem item);
}
interface IAggregateRule {
AggregatedRemunerationItem Apply(ComputedRemunerationItem item);
}
interface IAggregateTransformationRule {
AggregatedRemunerationItem Apply(AggregatedRemunerationItem aggregatedItem);
}
```