# Pagga.Remuneration - Approbation des EVP ## Nouveaux droits #### Doit déclarer des propositions d'evp - Specifique métier : Liste de natures - Scope : `SupportedScopes.RelativeCollaborators` `Must_Submit_Variable_Remuneration_Item_Proposal = 14` #### Peut saisir des propositions d'evp - Specifique métier : Liste de natures - Scope : `SupportedScopes.RelativeDepartments` `Can_Submit_Variable_Remuneration_Item_Proposal = 15` #### Déclarer des EVPs à la place de ... - Specifique métier : N/A - Scope : `SupportedScopes.AllNew | SupportedScopes.RelativeCollaborators` `Submit_Variable_Remuneration_Item_Proposal_Instead_Of = 16` #### Monitorer les déclarants - Specifique métier : N/A - Scope : `SupportedScopes.None` `Manage_Submitters = 17` --- ## Paramétrage saisie des propositions d’evp #### Diagramme de classes ```plantuml VariableRemunerationNatureList *-- VariableRemunerationNature VariableRemunerationNatureList *-- Role class VariableRemunerationNatureList { int Id; string Name; VariableRemunerationNature[] Natures; Role[] Roles; // si aucun droit sur admin des roles, cette liste reste vide int RoleCount; } class VariableRemunerationNature { int Id, string Name, RemunerationNatureType Type VariableRemunerationNatureCategory Category Establishment[] Establishments } class Role { int Id, string Name } ``` Si l'utilisateur connecté n'a pas accès à l'admin des rôles, la propriété `RoleNames` sera laissée vide. La propriété `RoleNames` est uniquement présente dans la classe `VariableRemunerationNatureList` dans la couche Domain. Il n'y a pas de lien entre la table `dbo.Roles` existante et la future table `Remuneration.VariableRemunerationNatureList`. #### API ##### Récupération des rôles On utilise l'API V3 des permissions pour connaitre les différents rôles utilisant les opérations suivantes : - Must_Submit_Variable_Remuneration_Item_Proposal - Can_Submit_Variable_Remuneration_Item_Proposal Le retour de cet appel d'API permet de remplir la propriété `RoleNames` décrite plus haut. ``` .../api/v3/permissions?fields=Id,role[id,name]&appinstanceid=16&operationid=14,15 ``` Pagga Remuneration utilisera un token de webservice lui donnant accès à cette API. ##### Responsable de saisie Nous devons connaitre tous les responsable de saisie pour remplir le UserPicker permettant de filtrer les listes. -> TODO : requete de récupération des rôles pour chaque manager ##### Listes de natures Les APIs suivantes permettent de créer, récupérer, modifier ou supprimer une liste de nature. ##### GET - /remuneration/api/VariableRemunerationNatureLists - Response : VariableRemunerationNatureList[] (pagination) ##### GET - /remuneration/api/VariableRemunerationNatureLists/**{id}** - QueryParams : id = Id de VariableRemunerationNatureLists - Response : VariableRemunerationNatureList ##### POST - /remuneration/api/VariableRemunerationNatureLists - Payload ```json= { name: "liste1", naturesId : [1, 2, 3, 4] } ``` - Response - Code : 201 ##### PUT - /remuneration/api/VariableRemunerationNatureLists/**{id}** - QueryParams : id = Id de VariableRemunerationNatureLists - Payload ```json= { name: "liste2", naturesId : [4, 5, 6] } ``` - Response - Code : 202 ##### DELETE - /remuneration/api/VariableRemunerationNatureLists/**{id}** - QueryParams : id = Id de VariableRemunerationNatureLists - Response : - code : - 202 - 409 : conflict si la liste est liée à au moins un rôle --- ## Saisie des propositions d'evp ### Jalons Aucune modification à apporter pour le moment. Les ajouts potentiels à faire seront spécifiés dans le lot 3. Avec notamment une sortie hors-monolithe de ce module. #### APIs de service des "Jalons" On a besoin d'une API de service pour les Jalon pour permettre au front de faire son regroupement soit par date de collecte (et éventuellement date de paie ensuite) soit par soummissions déjà réalisées sur la période. ```plantuml class MilestoneSubmissionState { Submission? Submission // renvoyer un dto light (owner / author / date) int EstablishmentId DateTime EndItemsCollectionDate } ``` ##### GET - /api/milestoneSubmissionStates?period={period}&ownerId={ownerId} - query params: - period (required) DateTime - ownerId int? - Response : - MilestoneSubmissionState[] Cette APIs doit retourner les MilestoneSubmissionStates correspondant aux établissements des utilisateurs pour lesquelles il DOIT faire une déclaration. Il faut donc appeler le service des scope. ### Liste des périodes de paie On a besoin d'une API pour determiner les périodes sur lesquelles on a une action à faire (Déclarer, suivre les proposition, suivre les déclarants). ```plantuml class PayPeriodRange { PayPeriod Start, PayPeriod Current } ``` > Sur l'écran de déclaration: > - Start: Dernière période déclarée > - Current: Période en cours (mois courant) ou dernière periode non déclarée dans le passé ##### GET - /api/SubmissionPayPeriodRange - Response : - PayPeriodRange > Sur l'écran de suivie des propositions : > - Start: Première période où il y eu une déclaration > - Current: Période la plus ancienne sur laquelle il y a des propositions en attente ##### GET - /api/ProposalPayPeriodRange - Response : - PayPeriodRange ### Déclaration des EVPs #### Liste des responsable de saisie Permet de connaitre la liste des utilisateurs pour lesquels l'utilisateur courant peut déclarer la grille des EVPs. Correspond à l'opération *Déclarer à la place de ...*. ####i GET - /api/v3/users/scope?appInstanceId={appInstanceId}&operations={operationId}&userId={userId} periodra - QueryParams : - operationId -> Operations "déclarer à la place de ..." - appInstanceId -> appInstanceId de PaggaRem - userId -> currentUser - Response : User[] ### Scope/Authorized #### Enums ```csharp= // Type de proposition d'EVP à saisir. => doit et/ou peut enum PropositionType { Recurring, Ponctual } // Types d'erreur rendant une "cellule" disabled dans la grille de saisie enum BlockingType { InsufficientPermission, OverlapItem } ``` #### Diagramme de classes Le regroupement Scope/Authorized concerne le domaine métier permettant de connaitre les droits et les possibilités sur les natures pour un utilisateur donné. Ce modèle nous permet de facilement construire les headers de la grille de saisie mensuelle mais aussi la liste des natures/utilisateurs pour lesquelles le manager PEUT saisir des EVPs. ```plantuml package "Core" #DDDDDD { class WorkContract {} class VariableRemunerationNature {} } package "Scope/Authorized" #F0FFF0 { RemunerationItemProposalScope *-- WorkContract RemunerationItemProposalScope *-- RemunerationNaturePropositionType RemunerationNaturePropositionType *-- VariableRemunerationNature RemunerationNaturePropositionType *-- BlockingReason BlockingReason <|-- InsufficientPermissionBlockingReason BlockingReason <|-- OverlapItemBlockingReason } class RemunerationItemProposalScope { WorkContract WorkContract; RemunerationNaturePropositionType[] NaturePropositionTypes; } class RemunerationNaturePropositionType { VariableRemunerationNature Nature; PropositionType[] Types; BlockingReason BlockingReason; } abstract class BlockingReason { (abstract) BlockingType Type } class InsufficientPermissionBlockingReason {} class OverlapItemBlockingReason { // EVP / SubmittedProposal / DraftProposal } ``` #### APIs Api permettant de renvoyer tout les headers de la matrices ou on peut/doit saisir une proposition ##### GET - /remuneration/api/VariableRemunerationItemProposal/scope - QueryString possible : - submitterId -> si non spécifié : currentUser - establishmentId[] - propositionType[] - userClue - responses : - Hors pagination - RemunerationNaturePropositionType[] - Count - Pagination - RemunerationItemProposalScope[] > exemple : /remuneration/api/VariableRemunerationItemProposal/scope?establishmentId=1,2,3&propositionType=0&userClue=jourda ### Submissions & Proposals La submission concerne la soumission par le manager d'une liste d'evp. Nous avons identifié 4 types de soumission possibles : - **Period** -> Déclaration de la grille sur la période - **EmployeeSettlement** -> Déclaration d'un solde tout compte *(Hors MVP mais on le note par anticipation pour ne pas se fermer cette porte).* - **Ponctual** -> Déclaration d'une saisie hors-grille - **FromDenied** -> Déclaration d'une nouvelle proposition issue d'une précédente proposition refusée Ce typage va nous permettre de définir des règles métiers fortes par type (exemple : une seule submission de type Period par mois pour un déclarant). Les proposals correspondent aux propositions d'EVP. Il en existe deux types : - Draft - Submitted Toutes les opérations (Get/Put/Post/Delete) sont possible sur un draft alors que sur le submitted seul le Get est disponible. Les objets Draft et Submitted héritent d'un classe abstraite commune et on beaucoup de propiétés communes. Le submitted se distingue par son statut et liaison indirecte à une BR (la BR porte le summitedProposal): `VariableRemunerationItemRequest`. Les drafts sont soumis par les Apis des Submissions. Une fois soumis chaque Draft devient Submitted et devient immutable. Seul sa BR peut la modifer en mettant sa propriété `Status` à jour. ### Enums ```csharp= // Statut liéé à l'état de la BR enum VariableRemunerationItemProposalStatus { Pending, Denied, Approved, ... } // Différentes façon de soumettre un lot d'EVP enum SubmissionType { Period, EmployeeSettlement, Ponctual, FromDenied } ``` #### Diagramme de classes ```plantuml RemunerationItemProposalSubmission -- VariableRemunerationItemProposal RemunerationItemProposalSubmission <|-- RemunerationItemProposalPeriodSubmission RemunerationItemProposalSubmission <|-- RemunerationItemProposalEmployeeSettlementSubmission RemunerationItemProposalSubmission <|-- RemunerationItemProposalPonctualSubmission RemunerationItemProposalSubmission <|-- RemunerationItemProposalFromDeniedSubmission abstract class RemunerationItemProposalSubmission { Id int; (abstract) SubmissionType Type; DateTime Date; User Author; User Owner; VariableRemunerationItemProposal[] Proposals; Period Period; } class RemunerationItemProposalPeriodSubmission { } class RemunerationItemProposalEmployeeSettlementSubmission { WorkContract WorkContract; } class RemunerationItemProposalPonctualSubmission { } class RemunerationItemProposalFromDeniedSubmission { RemunerationItemProposal DeniedProposal; } abstract class VariableRemunerationItemProposal { WorkContract WorkContract; VariableRemunerationNature Nature; decimal Amount; Period Period; User CreatedBy; DateTime CreatedAt; string? comment; } ``` ```plantuml package "Core" #DDDDDD { class WorkContract {} class VariableRemunerationNature {} } package "Submissions" #DFF2FF { RemunerationItemProposalPeriodSubmission -- VariableRemunerationItemDraftProposal RemunerationItemProposalEmployeeSettlementSubmission -- VariableRemunerationItemDraftProposal RemunerationItemProposalPonctualSubmission -- VariableRemunerationItemDraftProposal RemunerationItemProposalFromDeniedSubmission -- VariableRemunerationItemDraftProposal RemunerationItemProposalSubmission <|-- RemunerationItemProposalPeriodSubmission RemunerationItemProposalSubmission <|-- RemunerationItemProposalEmployeeSettlementSubmission RemunerationItemProposalSubmission <|-- RemunerationItemProposalPonctualSubmission RemunerationItemProposalSubmission <|-- RemunerationItemProposalFromDeniedSubmission VariableRemunerationItemDraftProposal -- VariableRemunerationNature VariableRemunerationItemDraftProposal -- WorkContract VariableRemunerationItemProposal <|-- VariableRemunerationItemDraftProposal VariableRemunerationItemProposal <|-- VariableRemunerationItemSubmittedProposal } abstract class RemunerationItemProposalSubmission { Id int; (abstract) SubmissionType Type; DateTime Date; User Author; User Owner; RemunerationItemProposal[] Proposals; Period Period; } class RemunerationItemProposalPeriodSubmission { } class RemunerationItemProposalEmployeeSettlementSubmission { WorkContract WorkContract; } class RemunerationItemProposalPonctualSubmission { } class RemunerationItemProposalFromDeniedSubmission { RemunerationItemProposal DeniedProposal; } abstract class VariableRemunerationItemProposal { WorkContract WorkContract; VariableRemunerationNature Nature; decimal Amount; Period Period; User CreatedBy; DateTime CreatedAt; string? comment; PropositionType Type; } class VariableRemunerationItemSubmittedProposal { RemunerationItemProposalSubmission Submission; VariableRemunerationItem? Item; VariableRemunerationItemProposalStatus Status; } class VariableRemunerationItemDraftProposal { DateTime LastModifiedAt; User LastModifiedBy; DateTime? DeletedAt; User? DeletedBy; } ``` ```plantuml VariableRemunerationItemProposal <|-- VariableRemunerationItemDraftProposal VariableRemunerationItemProposal <|-- VariableRemunerationItemSubmittedProposal abstract class VariableRemunerationItemProposal { WorkContract WorkContract; VariableRemunerationNature Nature; decimal Amount; Period Period; User CreatedBy; DateTime CreatedAt; string? comment; PropositionType Type; } class VariableRemunerationItemSubmittedProposal { RemunerationItemProposalSubmission Submission; VariableRemunerationItem? Item; VariableRemunerationItemProposalStatus Status; } class VariableRemunerationItemDraftProposal { DateTime LastModifiedAt; User LastModifiedBy; DateTime? DeletedAt; User? DeletedBy; } ``` ```csharp abstract class RemunerationItemProposalSubmission { Id int; (abstract) SubmissionType Type; DateTime Date; User Author; User Owner; (abstract) VariableRemunerationItemProposal[] GetProposals(); Period Period; } class RemunerationItemProposalPeriodSubmission : RemunerationItemProposalSubmission { EstablishmentProposals[] EstablishmentProposals; } class RemunerationItemProposalEmployeeSettlementSubmission: RemunerationItemProposalSubmission { WorkContract WorkContract; VariableRemunerationItemProposal[] Proposals; } class RemunerationItemProposalPonctualSubmission : RemunerationItemProposalSubmission{ VariableRemunerationItemProposal[] Proposals; } class RemunerationItemProposalFromDeniedSubmission : RemunerationItemProposalSubmission{ RemunerationItemProposal DeniedProposal; VariableRemunerationItemProposal NewProposal; } class EstablishmentProposals { Establishment Estalishment; VariableRemunerationItemProposal[] Proposals; } ``` #### APIs des Submissions ##### GET - /remuneration/api/RemunerationItemProposalSubmissions - responses : - RemunerationItemProposalSubmission[] ##### GET - /remuneration/api/RemunerationItemProposalPeriodSubmissions - responses : - RemunerationItemProposalPeriodSubmission[] ##### POST - /remuneration/api/RemunerationItemProposalPeriodSubmissions - payload : ```json= { ownerId: 12, // Nullable - correspond au responsable de saisie devant faire la déclaration period: 2022-06, establishmentId: 1 // un seul et unique } ``` - responses : - Code : 201 ##### POST - /remuneration/api/RemunerationItemProposalPeriodSubmissions/ - payload : ```json= { [ { ownerId: 12, // Nullable - correspond au responsable de saisie devant faire la déclaration period: 2022-06, establishmentIds: 1 }, { ownerId: 12, // Nullable - correspond au responsable de saisie devant faire la déclaration period: 2022-06, establishmentIds: 2 } ] } ``` - responses : - Code : 201 *Note : PUT & DELETE - **interdit*** ##### GET - /remuneration/api/RemunerationItemProposalFromDeniedSubmissions - responses : - RemunerationItemProposalFromDeniedSubmission[] ##### POST - /remuneration/api/RemunerationItemProposalFromDeniedSubmissions - payload : ```json= { deniedProposalId: 56, draft: { workContractId: 12, natureId: 1, amount: 55.56, period: 2022/05/10, propositionType: 0, // Recurring or Ponctual, comments: "bla bla bla" // nullable } } ``` - responses : - Code : 201 *Note : PUT & DELETE - **interdit*** ##### GET - /remuneration/api/RemunerationItemProposalPonctualSubmissions - responses : - RemunerationItemProposalPonctualSubmission[] ##### POST - /remuneration/api/RemunerationItemProposalPonctualSubmissions - payload : ```json= { ownerId: 12, proposalIds: [1, 2, 3] } ``` - responses : - Code : 201 *Note : PUT & DELETE - **interdit*** #### APIs des Proposals ##### GET - /remuneration/api/VariableRemunerationItemProposals - response : - VariableRemunerationItemProposal[] ##### GET - /remuneration/api/VariableRemunerationItemDraftProposals - QueryString possible : - workContractIds[] - period - response : - VariableRemunerationItemDraftProposal[] ##### POST - /remuneration/api/VariableRemunerationItemDraftProposals - payload : ```json= { workContractId: 12, natureId: 1, amount: 55.56, period: 2022/05/10, propositionType: 0, // Recurring or Ponctual, comments: "bla bla bla" // nullable } ``` - Response : - VariableRemunerationItemDraftProposal - code : - 200 - 409 : conflit par concurrence : un élément existe déjà pour cet utilisateur sur cette période, pour cette nature. ##### PUT - /remuneration/api/VariableRemunerationItemDraftProposals/{id} - QueryParams : id = Id du draft - payload : ```json= { amount: 55.56, comments: "bla bla bla" // nullable } ``` - Response : - VariableRemunerationItemDraftProposal - code : - 200 ##### DELETE - /remuneration/api/VariableRemunerationItemDraftProposals/{id} - QueryParams : id = Id du draft - Response : - code : - 202 ##### GET - /remuneration/api/VariableRemunerationItemSubmittedProposals - response : - VariableRemunerationItemSubmittedProposal[] *Note : POST & PUT & DELETE - **interdit*** --- ## Suivis de la déclaration des EVPs La soummision d'un Draft le transforme en Submitted. Cette action engendre la création d'une Buisness Request `VariableRemunerationItemRequests` liée à `VariableRemunerationItemSubmittedProposal`. Le suivi de déclaration consiste principalement à suivre l'avancement des BR dans le workflow. Le statut du Submitted est mis à jours par la BR et est persisté en base. ```plantuml class VariableRemunerationItemSubmittedProposal { RemunerationItemProposalSubmission Submission; VariableRemunerationItem? Item; VariableRemunerationItemProposalStatus Status; } abstract class VariableRemunerationItemProposal { WorkContract WorkContract; VariableRemunerationNature Nature; decimal Amount; Period Period; } class VariableRemunerationItem { [...] // Aucun changement } VariableRemunerationItemProposal <|-- VariableRemunerationItemSubmittedProposal VariableRemunerationItemRequest *-- VariableRemunerationItemSubmittedProposal VariableRemunerationItemSubmittedProposal *-- VariableRemunerationItem class VariableRemunerationItemRequest { VariableRemunerationItemSubmittedProposal Proposal [...] int NextApproverId; int PreviousApproverId; WorkflowTemplate WorkflowTemplate; WorkflowAction[] WorkflowActions; WorkflowApprovalState ApprovalState; [...] } ``` Les propriétés liées au workflow de la buisness request `VariableRemunerationItemRequest` sont définies plus bas dans *Approbation / Refus / Transfert - Action du workflow* L'API des `VariableRemunerationItemRequests` et son filtrage par statut nous permet de remonter toutes les informations nécessaires au suivi des propositions d'EVP. Note : La classe `VariableRemunerationItem` correspond à celle déjà présente dans Pagga Remuneration actuellement et ne subira aucune modification. ##### GET - remuneration/api/VariableRemunerationItemRequests - response : - Hors pagination - deniedCount - pendingCount - approvedCount - Count - Pagination - VariableRemunerationItemRequest[] - queryString possible : - Status *Note : tri par défaut sur le statut (Dans l'ordre : Denied -> Pending -> Approved)* ## Paramétrage de l'approbation - Workflow Les concepts et termes utilisés par la suite sont ceux définit par la norme [Lucca.Workflow](https://luccasoftware.atlassian.net/wiki/spaces/ProductDirection/pages/2824175690/Lucca.Workflow) ### Manifest Le manifest correspond à la déclaration du workflow, figé dans le code. Il faudra qu'il soit déclarer dans l'injection de dépendance au moment de l'injection de la librairie back Lucca.Workflow. Pour notre besoin : ```csharp= new WorkflowTemplateManifest SupportedApproverTypes = new List<ApproverTypeDefinition> { ApproverTypeDefinitions.Manager, ApproverTypeDefinitions.ManagerOfManager, ApproverTypeDefinitions.HeadOfDepartment, ApproverTypeDefinitions.SpecificUser }, NextApproverFailBehavior = NextApproverFailBehavior.PerStep, FinalMailRecipientTypes = new List<MailRecipientTypeDefinition>{}, } ``` #### Diagramme de classes ```plantuml class WorkflowRegistration { string WorkflowId; // ex : "VariableRemunerationItemProposal" WorkflowTemplateManifest Manifest; } WorkflowRegistration *-- WorkflowTemplateManifest ``` #### API Cette APIs sera nécessaire pour le paramétrage du workflow pour définir les possibilités de paramétrage. ##### GET - remuneration/api/workflow/{id} - QueryParams : id = Id du workflow déclaré dans le back - response : WorkflowTemplateManifest ### Template Le template correspond, pour un manifest donné, à la configuration faites pas l'administrateur dans l'écran de paramétrage de l'approbation. Comme décrit dans la norme Lucca.Workflow, un template est immuable : > Un Workflow Template est immuable. À chaque enregistrement, un nouveau WorkflowTemplate est créé. > > La mise à jour d’un WorkflowTemplate n’impacte pas les demandes en cours de traitement. Elle s’appliquera uniquement sur les demandes à venir. #### Diagramme de classes ```plantuml class WorkflowTemplate { int id; string WorkflowId; WorkflowTemplateStep[] Steps; WorkflowMailRecipientConfiguration[] FinalRecipients; ConditionDefinition[] Conditions; int AuthorId; DateTime CreatedAt; } WorkflowTemplate *-- WorkflowTemplateStep WorkflowTemplate *-- WorkflowMailRecipientConfiguration WorkflowTemplate *-- ConditionDefinition ``` `WorkflowTemplateStep`, `WorkflowMailRecipientConfiguration`, et `ConditionDefinition` sont des classes définis par la librairie des workflows #### API ##### GET - remuneration/api/workflow/{id}/templates - QueryParams : id = Id du workflow déclaré dans le back - response : WorkflowTemplate - Retourne un seul et unique WorkflowTemplate. Le dernier créé pour un workflowId donné. ##### POST - remuneration/api/workflow/{id}/templates - QueryParams : id = Id du workflow déclaré dans le back - Payload : ```json= { workflowId : "VariableRemunerationItemProposal", steps: [ ... ], finalRecipients: [ ... ], conditions: [ ... ] } ``` - Response : - code : - 201 *Note : PUT & DELETE - **interdit : Template immuable*** ## Approbation / Refus / Transfert - Action du workflow #### Enums issue de la norme workflow ```csharp= enum WorkflowActionType { Approval, Denial, Transfer, Delegation, SkippedApproval, } enum WorkflowActionSource { Desktop = 0, API, Mobile, Mail, Migration } enum WorkflowApprovalMode { Manual = 0, Auto } ``` #### Diagramme de classes La classe `BuisnessRequest` est une classe abstraite fournis par la library Lucca.Workflow. Cette librairie nous fournis également une interface pour `WorkflowAction` que nous utiliserons. ```plantuml BuisnessRequest <|-- VariableRemunerationItemRequest VariableRemunerationItemRequest *-- VariableRemunerationItemSubmittedProposal VariableRemunerationItemRequest *-- WorkflowTemplate VariableRemunerationItemRequest *-- WorkflowAction WorkflowAction <|-- WorkflowActionApproval WorkflowAction <|-- WorkflowActionTransfer WorkflowAction <|-- WorkflowActionDenial WorkflowAction <|-- WorkflowActionDelegation WorkflowAction <|-- WorkflowSkippedApproval abstract class BuisnessRequest { int NextApproverId; int PreviousApproverId; WorkflowTemplate WorkflowTemplate; WorkflowAction[] WorkflowActions; WorkflowApprovalState ApprovalState; [...] } class VariableRemunerationItemRequest { int Id; VariableRemunerationItemSubmittedProposal Proposal } abstract class WorkflowAction { int Id; int CreatedById; DateTime CreatedAt; int StepNumber; string Comment; WorkflowActionSource Source; (abstract) WorkflowActionType Type; } class WorkflowActionDenial { int ApproverId; string ApproverTypeDefinitions; } class WorkflowActionApproval { int ApproverId; string ApproverTypeDefinitions; WorkflowApprovalMode WorkflowApprovalMode; } class WorkflowActionTransfer { int OldApproverId; int NewApproverId; } class WorkflowActionDelegation { int OldApproverId; int NewApproverId; } class WorkflowSkippedApproval { } ``` #### APIs Les apis suivantes permettent d'effectuer les actions sur la BR. Nous avons besoin de gérer les actions (approbation/refus/transfer) multiples pour des besoin fonctionnels. Plutôt que de forcer le front à faire n appel à l'API unitaire nous fournissons une APIs pour chaque action prenant en payload une liste de request sur lesquels appliquer l'action. ##### POST - remuneration/api/VariableRemunerationItemRequests/{id}/approvals - QueryParams : id = Id de la request à approuver - Response : - code : - 201 ##### POST - remuneration/api/VariableRemunerationItemRequests/approvals - Payload : ```json= { [ { variableRemunerationItemRequestId: 23, // Id de la request à approuver }, { variableRemunerationItemRequestId: 21, // Id de la request à approuver }, { variableRemunerationItemRequestId: 14, // Id de la request à approuver } ] } ``` - Response : - code : - 201 ##### POST - remuneration/api/VariableRemunerationItemRequests/{id}/denials - QueryParams : id = Id de la request à refuser - Payload : ```json= { variableRemunerationItemRequestId: 23, // Id de la request à approuver comment: "un commentaire pour justifier le refus" } ``` - Response : - code : - 201 ##### POST - remuneration/api/VariableRemunerationItemRequests/denials - Payload : ```json= { [ { variableRemunerationItemRequestId: 23, // Id de la request à approuver comment: "un commentaire pour justifier le refus" }, { variableRemunerationItemRequestId: 21, // Id de la request à approuver comment: "un autre commentaire pour justifier le refus" } ] } ``` - Response : - code : - 201 ##### POST - remuneration/api/VariableRemunerationItemRequests/{id}/transfers - QueryParams : id = Id de la request à transférer - Payload : ```json= { variableRemunerationItemRequestId: 23, // Id de la request à approuver nextApproverId: 2, comment: "un commentaire pour justifier le transfert" } ``` - Response : - code : - 201 ##### POST - remuneration/api/VariableRemunerationItemRequests/transfers - Payload : ```json= { [ { variableRemunerationItemRequestId: 23, // Id de la request à approuver nextApproverId: 2, comment: "un commentaire pour justifier le transfert" }, { variableRemunerationItemRequestId: 21, // Id de la request à approuver nextApproverId: 2, comment: "un autre commentaire pour justifier le transfert" } ] } ``` - Response : - code : - 201 ## Suivis des déclarants Est ce qu'il reste des managers qui n'ont pas fait leur déclaration ? Pour répondre à ce problème nous avons une API de service renvoyant des `PeriodSubmissionState`. Cette information est également accessible par le front en faisant les appels suivants décrits plus haut : - Un appel à l'api V3 des permissions pour connaitre les différents utilisateurs ayant l'opération `Must_Submit_Variable_Remuneration_Item_Proposal` - Pour chaque utilisateur, un appel à l'API des Submission sur la période souhaitée nous donne l'état des déclarations. Cette enchainement d'appels étant plus complexe et plus couteux, nous préviligions donc une API de service. ```csharp= enum SubmissionState { Empty, Draft, Submitted } ``` ```plantuml class PeriodSubmissionState { Period Period; User user; SubmissionState State; } ``` ##### GET - remuneration/service/PeriodSubmissionStates?period={period}&userclue={clue} - QueryString : - period = Date représentant la période pour laquelle on souhaite avoir l'avancement des déclarations. Paramètre obligatoire. - userclue = filtrage sur un user. Facultatif. - response : - code : - 200 - 400 -> On retourne une erreur 400 si le paramètre period n'est pas remplis. - PeriodSubmissionState[] (pagination) ## Warning sur l'export paie On souhaite répondre à une question pour ajouter des warnings lors de la génération des exports. Est ce qu'il reste des VariableRemunerationItemRequest en pending ? L'APIs des `VariableRemunerationItemRequest` décrite plus haut nous fournit cette information. ##### GET - remuneration/api/VariableRemunerationItemRequests ```csharp= class VariableRemunerationItemRequestPage { int DeniedCount { get; set; } int PendingCount { get; set; } int ApprovedCount { get; set; } int Count { get; set; } List<VariableRemunerationItemRequest> Items { get; set; } // prev & next } class UserxxxxxPage { int Count { get; set; } int ToApproveCount { get; set; } List<UserVariableRemunerationItemRequest> Items { get; set; } // prev & next } ``` Relance : Utiliser le morning ping du monolithe. --- ## Base de données https://lucid.app/lucidchart/35ced00c-b046-4ee0-93b5-605d89eaf129/edit?from_internal=true ![](https://i.imgur.com/SAejWB7.png)