using EPAServeur.Context; using EPAServeur.Exceptions; using EPAServeur.IServices; using EPAServeur.Models.EP; using EPAServeur.Models.Formation; using IO.Swagger.ApiCollaborateur; using IO.Swagger.DTO; using IO.Swagger.ModelCollaborateur; using Microsoft.EntityFrameworkCore.ChangeTracking; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices.ComTypes; using System.Threading.Tasks; namespace EPAServeur.Services { /// /// Service permettant de récupérer les informations collaborateurs. /// public class CollaborateurService : ICollaborateurService { #region Variables /// /// API pour accéder aux données collaborateur en passant par le service collaborateur /// private readonly ICollaborateurApi collaborateurApi; /// /// Accès au service permettant de transformer un modèle en dto /// private readonly ITransformDTO transformDTO; /// /// Nombre d'éléments min à afficher par page /// private readonly int minParPage = 5; /// /// Nom d'éléments max à affichar par page /// private readonly int maxParPage = 100; /// /// Nombre d'éléments à afficher par défaut par page /// private readonly int defaultParPage = 15; /// /// Accès et gestion de la base de données /// private readonly EpContext context; #endregion #region Constructeurs public CollaborateurService(ICollaborateurApi _collaborateurApi, EpContext _contexte, ITransformDTO _transformDTO) { collaborateurApi = _collaborateurApi; context = _contexte; transformDTO = _transformDTO; } #endregion #region Services Async /// /// Récupérer un collaborateur en fonction d'un id de manière asynchrone /// /// Identifiant du collaborateur à renvoyer /// Le collaborateur corresponant à l'id en paramètre public async Task GetCollaborateurByIdAsync(Guid? id) { Collaborateur collaborateur = await collaborateurApi.ChercherCollabIdAsync(id); if (collaborateur == null) throw new CollaborateurNotFoundException("Le collaborateur recherché n'a pas été trouvé"); return await GetCollaborateurDTOAsync(collaborateur, true); } /// /// Récupérer un collaborateur en fonction d'un mail de manière asynchrone /// /// Mail du collaborateur à renvoyer /// Le collaborateur correspondant au mail en paramètre public async Task GetCollaborateurByMailAsync(string mail) { Collaborateur collaborateur = await collaborateurApi.ChercherCollabMailAsync(mail); if (collaborateur == null) throw new CollaborateurNotFoundException("Le collaborateur recherché n'a pas été trouvé"); return await GetCollaborateurDTOAsync(collaborateur, true); } /// /// Récupérer la liste de tous les collaborateurs de manière asynchrone /// /// /// Liste des rôles auxquels les collaborateurs à récupérer appartiennent /// Liste des business units auxquelles sont rattachés les collaborateurs à récupérer /// Précise si la liste est trié dans l'ordre croissant ou décroissant /// Numéro de la page qui est affiché du côté front /// Nombre de collaborateurs à renvoyer /// id de l'agence à laquelle appartient les collaborateurs à récupérer /// /// permet de récupérer les collaborateurs dont le nom + prénom ou le prénom + nom contient le texte /// Choisir l'attribut par lequel est trié la liste /// Date à partir de laquelle les collaborateurs sont arrivés /// Date jusqu'à laquelle les collaborateurs sont arrivés /// Renvoie la liste des collaborateurs en fonction des paramètres public async Task> GetCollaborateursAsync(List roles, List idBUs, bool? asc, int? numPage, int? parPage, string texte, string tri, DateTime? dateDebut, DateTime? dateFin) { IEnumerable collaborateurs; IEnumerable collaborateursDTO; collaborateurs = await collaborateurApi.ChercherCollabAsync(ancienCollaborateur: false, roles: roles, buIds: idBUs); /*collaborateursDTO = (from c in collaborateurs select GetCollaborateurDTO(c, false));*/ var task = collaborateurs.Select(c => GetCollaborateurDTOAsync(c, true)); collaborateursDTO = await Task.WhenAll(task); if (!parPage.HasValue || parPage.Value < minParPage || parPage.Value > maxParPage) parPage = defaultParPage; if (!numPage.HasValue ||numPage.Value <= 0) numPage = 1; int skip = (numPage.Value - 1) * parPage.Value; int take = parPage.Value; if (texte != null) collaborateursDTO = TriTexte(collaborateursDTO, texte.ToLower()); collaborateursDTO = TriDates(collaborateursDTO, dateDebut, dateFin); if (tri != null) collaborateursDTO = TriAttribut(collaborateursDTO, tri); if (asc.HasValue && !asc.Value) collaborateursDTO = collaborateursDTO.Reverse(); return collaborateursDTO.Skip(skip).Take(take); } /// /// Récupérer le nombre de collaborateurs correspondant aux paramètres de la requête de manière asynchrone /// /// /// Liste des rôles auxquels les collaborateurs à récupérer appartiennent /// Liste des business units auxquelles sont rattachés les collaborateurs à récupérer /// permet de récupérer les collaborateurs dont le nom + prénom ou le prénom + nom contient le texte /// Date à partir de laquelle les collaborateurs sont arrivés /// Date jusqu'à laquelle les collaborateurs sont arrivés /// Renvoie la liste des collaborateurs en fonction des paramètres /// Le nombre de collaborateur public async Task GetCollaborateursCountAsync(List roles, List idBUs, string texte, DateTime? dateDebut, DateTime? dateFin) { IEnumerable collaborateurs; IEnumerable collaborateursDTO; collaborateurs = await collaborateurApi.ChercherCollabAsync(ancienCollaborateur: false, roles: roles, buIds: idBUs); var tasks = collaborateurs.Select(c => GetCollaborateurDTOAsync(c, false)); collaborateursDTO = await Task.WhenAll(tasks); if (texte != null) collaborateursDTO = TriTexte(collaborateursDTO, texte.ToLower()); collaborateursDTO = TriDates(collaborateursDTO, dateDebut, dateFin); return collaborateursDTO.Count(); } /// /// Récupérer les collaborateurs d'un référent de manière asynchrone /// /// id du référent des collaborateurs à récupérer /// Précise si la liste est trié dans l'ordre croissant ou décroissant /// Numéro de la page qui est affiché du côté front /// Nombre de collaborateurs à renvoyer /// permet de récupérer les collaborateurs dont le nom + prénom ou le prénom + nom contient le texte /// Choisir l'attribut par lequel est trié la liste /// Renvoyer les collaborateurs du référent en paramètre public async Task> GetCollaborateursByReferentAsync(Guid? idReferent, bool? asc, int? numPage, int? parPage, string texte, string tri) { Collaborateur referent = await collaborateurApi.ChercherCollabIdAsync(idReferent); if (referent == null) throw new ReferentNotFoundException("Le référent recherché n'a pas été trouvé"); List collaborateursIds = (from r in context.ReferentEP where r.IdReferent.Value.Equals(idReferent) select (Guid?) r.IdCollaborateur).ToList(); if (collaborateursIds.Count == 0) return new List(); IEnumerable collaborateurs = await collaborateurApi.ChercherCollabAsync(collabsId: collaborateursIds); if (!parPage.HasValue || parPage.Value < minParPage || parPage.Value > maxParPage) parPage = maxParPage; if (!numPage.HasValue || numPage.Value <= 0) numPage = 1; int skip = (numPage.Value - 1) * parPage.Value; int take = parPage.Value; var tasks = collaborateurs.Select(c => GetCollaborateurDTOAsync(c, false)); IEnumerable collaborateursDTO = await Task.WhenAll(tasks); if (texte != null && texte != "") collaborateursDTO = TriTexte(collaborateursDTO, texte.ToLower()); if (tri != null) collaborateursDTO = TriAttribut(collaborateursDTO, tri); if(asc != null && asc == false) collaborateursDTO = collaborateursDTO.Reverse(); return collaborateursDTO.Skip(skip).Take(take); } /// /// Récupérer le nombre de collaborateurs d'un référent en fonction des paramètres de manière asynchrone /// /// id du référent des collaborateurs à récupérer /// permet de récupérer les collaborateurs dont le nom + prénom ou le prénom + nom contient le texte /// Renvoyer le nombre collaborateurs du référent en fonction des paramètres public async Task GetCollaborateursCountByReferentAsync(Guid? idReferent, string texte) { Collaborateur referent = await collaborateurApi.ChercherCollabIdAsync(idReferent); if (referent == null) throw new ReferentNotFoundException("Le référent recherché n'a pas été trouvé"); List collaborateursIds = (from r in context.ReferentEP where r.IdReferent.Value.Equals(idReferent) select (Guid?)r.IdCollaborateur).ToList(); if (collaborateursIds.Count == 0) return 0; IEnumerable collaborateurs = await collaborateurApi.ChercherCollabAsync(collabsId: collaborateursIds); var tasks = collaborateurs.Select(c => GetCollaborateurDTOAsync(c, false)); IEnumerable collaborateursDTO = await Task.WhenAll(tasks); if (texte != null) collaborateursDTO = TriTexte(collaborateursDTO, texte.ToLower()); return collaborateursDTO.Count(); } /// /// Récupérer la liste référents ayant fait passer des EP au collaborateur /// /// id du collaborateur concerné /// Liste des référents public Task> GetReferentsPrecedentsEPAsync(Guid? idCollaborateur) { throw new NotImplementedException(); } public async Task> GetCollaborateurDTOsAsync(List guids) { IEnumerable collaborateurs = await collaborateurApi.ChercherCollabAsync(collabsId: guids); var tasks = collaborateurs.Select(c => GetCollaborateurDTOAsync(c, false)); IEnumerable collaborateursDTO = await Task.WhenAll(tasks); return collaborateursDTO; } /// /// Transformer un collaborateur en collaborateurDTO de manière asynchrone. /// /// Collaborateur à transformer en collaborateurDTO /// Indiquer si le référent du collaborateur doit être récupéré ou non /// Renvoie la transformation DTO du collaborateur public async Task GetCollaborateurDTOAsync(Collaborateur collaborateur, bool chercherReferent) { CollaborateurDTO collaborateurDTO = new CollaborateurDTO() { Id = collaborateur.Id, Prenom = collaborateur.Prenom, Nom = collaborateur.Nom, MailApside = collaborateur.MailApside, DateArrivee = collaborateur.DateArrivee, }; collaborateurDTO.BusinessUnit = transformDTO.GetBusinessUnitDTO(collaborateur.BusinessUnit); //Si le référent du collaborateur doit être récupérer en même temps if (chercherReferent) collaborateurDTO.Referent = await GetReferentAsync(collaborateurDTO); return collaborateurDTO; } /// /// Récupérer une liste de CollaborateurDTO contenant les collaborateurs et les référents. /// /// /// public async Task> GetCollaborateurDTOsAsync(List participationsFormation) { if (participationsFormation == null || participationsFormation.Count == 0) return null; List guids = participationsFormation.SelectMany(participationFormation => new[] { (Guid?)participationFormation.DemandeFormation.Ep.IdCollaborateur, participationFormation.DemandeFormation.Ep.IdReferent }).ToList(); return await GetCollaborateurDTOsAsync(guids); } /// /// Récupérer une liste de CollaborateurDTO contenant les collaborateurs et les référents. /// /// /// public async Task> GetCollaborateurDTOsAsync(IEnumerable participationsFormation) { if (participationsFormation == null || !participationsFormation.Any()) return null; List guids = participationsFormation.SelectMany(participationFormation => new[] { (Guid?)participationFormation.DemandeFormation.Ep.IdCollaborateur, participationFormation.DemandeFormation.Ep.IdReferent }).ToList(); return await GetCollaborateurDTOsAsync(guids); } /// /// Récupérer le collaborateur et le référent qui sont présent dans l'EP qui est lié à l'engagement. /// /// /// public async Task> GetCollaborateurDTOsAsync(Engagement engagement) { if (engagement == null) return null; List guids = new List(); guids.Add((Guid?)engagement.Ep.IdCollaborateur); guids.Add(engagement.Ep.IdReferent); return await GetCollaborateurDTOsAsync(guids); } /// /// Récupérer les collaborateurs et les référents qui sont présent dans les EP qui sont liés aux engagements. /// /// /// public async Task> GetCollaborateurDTOsAsync(IEnumerable engagements) { if (engagements == null || !engagements.Any()) return null; List guids = engagements.SelectMany(engagement => new[] { (Guid?)engagement.Ep.IdCollaborateur, engagement.Ep.IdReferent }).ToList(); return await GetCollaborateurDTOsAsync(guids); } /// /// Récupérer le collaborateur et le référent qui sont présent dans les EP. /// /// /// public async Task> GetCollaborateurDTOsAsync(IEnumerable eps) { if (eps == null || !eps.Any()) return null; List guids = eps.SelectMany(ep => new Guid?[] { ep.IdReferent, ep.IdCollaborateur }).Distinct().ToList(); return await GetCollaborateurDTOsAsync(guids); } /// /// Récupérer le référent EP d'un collaborateur de manière asynchrone s'il existe. /// /// Le collaborateur dont on cherche le référent EP /// Le référent EP du collaborateur public async Task GetReferentAsync(CollaborateurDTO collaborateur) { ReferentEP referentEP = await context.ReferentEP.FindAsync(collaborateur.Id); //vérifier que le collaorateur a un référent EP if (referentEP == null || referentEP.IdReferent == null || !referentEP.IdReferent.HasValue || referentEP.IdReferent.Value == null) return null; Collaborateur referent = await collaborateurApi.ChercherCollabIdAsync(referentEP.IdReferent); if (referent == null) return null; return await GetCollaborateurDTOAsync(referent, false); } #endregion #region Methode de tri /// /// Permettre de récupéer les collaborateurs en fonction de leur nom et/ou prénom /// /// Liste des collaborateurs à trier /// Texte permettant de trier par rapport aux noms et prénoms /// Une liste de collaborateurs private IEnumerable TriTexte(IEnumerable collaborateurs, string texte) { return (from c in collaborateurs where (c.Nom + " " + c.Prenom).ToLower().Contains(texte) || (c.Prenom + " " + c.Nom).ToLower().Contains(texte) select c); } /// /// Permettre de trier les données collaborateurs en fonction d'un attribut /// /// La liste des collaborateurs à trier /// L'attribut sur lequel les données sont triées /// Indique si les données sont rangées dans l'ordre croissant ou non /// Une liste de collaborateur private IEnumerable TriAttribut(IEnumerable collaborateurs, string tri) { switch(tri) { case "datearrivee": collaborateurs = collaborateurs.OrderBy(c => c.DateArrivee); break; case "businessunit": collaborateurs = collaborateurs.OrderBy(c => c.BusinessUnit.Nom); break; case "referent": collaborateurs = collaborateurs.OrderBy(c => c.Referent.Nom ); break; default: collaborateurs = collaborateurs.OrderBy(c => c.Nom); break; } return collaborateurs; } /// /// Cette fonction va permettre de récupérer les collaborteurs dont la date d'arrivée se situe dans un intervalle de dates /// /// La liste des collaborateurs à trier /// La date à partir de laquelle les dates d'arrivées sont récupérées /// La data limite d'arrivée du collaborateur /// Une liste de collaborateurs private IEnumerable TriDates(IEnumerable collaborateurs, DateTime? dateDebut, DateTime? dateFin) { if(dateDebut.HasValue && dateFin.HasValue) { DateTime dateFinValue = dateFin.Value.AddDays(1); return (from c in collaborateurs where c.DateArrivee >= dateDebut.Value && c.DateArrivee < dateFinValue select c); } if(dateDebut.HasValue) { return (from c in collaborateurs where c.DateArrivee >= dateDebut.Value select c); } if(dateFin.HasValue) { DateTime dateFinValue = dateFin.Value.AddDays(1); return (from c in collaborateurs where c.DateArrivee < dateFinValue select c); } return collaborateurs; } #endregion } }