using EPAServeur.Context;
using EPAServeur.Exceptions;
using EPAServeur.IServices;
using EPAServeur.Models.EP;
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;
///
/// 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)
{
collaborateurApi = _collaborateurApi;
context = _contexte;
}
#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.Value < minParPage || parPage.Value > maxParPage)
parPage = defaultParPage;
if (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);
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;
}
#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
#region DTO To Object
///
/// Transformer une agence en agenceDTO
///
/// agence à transformer en agenceDTO
/// Retourne la transformation DTO de l'agence
private AgenceDTO GetAgenceDTO(Agence agence)
{
if (agence == null)
return null;
AgenceDTO agenceDTO = new AgenceDTO()
{
Id = agence.Id,
Nom = agence.Nom,
Bu = new List()
};
agenceDTO.Bu = agence.Bus.Select(bu => new BusinessUnitDTO()
{
Id = bu.Id,
Nom = bu.Nom
}).ToList();
return agenceDTO;
}
///
/// Transforme une businessUnit en businessUnitDTO
///
/// businessUnit à transformer en businessUnitDTO
/// Retourne la transformation DTO de la businessUnit
private BusinessUnitDTO GetBusinessUnitDTO(BU businessUnit)
{
if (businessUnit == null)
return null;
BusinessUnitDTO businessUnitDTO = new BusinessUnitDTO()
{
Id = businessUnit.Id,
Nom = businessUnit.Nom,
Agence = GetAgenceDTO(businessUnit.Agence)
};
return businessUnitDTO;
}
///
/// Transforme 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
private 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 = 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 le référent EP d'un collaborateur de manière asynchrone si il existe
///
/// Le collaborateur dont on cherche le référent EP
/// Le référent EP du collaborateur
private 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
}
}