You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Digitalisation_EPA_Serveur/EPAServeur/Services/FormationService.cs

550 lines
25 KiB

using EPAServeur.Context;
using EPAServeur.Exceptions;
using EPAServeur.IServices;
using EPAServeur.Models.EP;
using EPAServeur.Models.Formation;
using IO.Swagger.DTO;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace EPAServeur.Services
{
public class FormationService : IFormationService
{
#region Variables
/// <summary>
/// Accès et gestion de la base de données
/// </summary>
private readonly EpContext epContext;
/// <summary>
/// Accès et service collaborateur
/// </summary>
private readonly ICollaborateurService collaborateurService;
/// <summary>
/// Accès au service permettant de transformer un modèle en dto
/// </summary>
private readonly ITransformDTO transformDTO;
/// <summary>
/// Nombre d'éléments min à afficher par page
/// </summary>
private readonly int minParPage = 5;
/// <summary>
/// Nom d'éléments max à affichar par page
/// </summary>
private readonly int maxParPage = 100;
/// <summary>
/// Nombre d'éléments à afficher par défaut par page
/// </summary>
private readonly int defaultParPage = 15;
/// <summary>
/// Numéro de page min à afficher par défaut
/// </summary>
private readonly int defaultNumPage = 1;
/// <summary>
/// Ordonnancement par défaut
/// </summary>
private readonly bool defaultAsc = true;
#endregion
#region Contructeurs
/// <summary>
/// Constructeur de la classe FormationService
/// </summary>
/// <param name="_epContext"></param>
public FormationService(EpContext _epContext, ICollaborateurService _collaborateurService, ITransformDTO _transformDTO)
{
epContext = _epContext;
collaborateurService = _collaborateurService;
transformDTO = _transformDTO;
}
#endregion
#region Méthodes Service
/// <summary>
/// Récupérer une formation par son id de manière asynchrone
/// </summary>
/// <param name="idFormation"></param>
/// <returns></returns>
public async Task<FormationDTO> GetFormationByIdAsync(long idFormation)
{
Formation formation = await epContext.Formation.Include(formation => formation.Statut)
.Include(formation => formation.ModeFormation)
.Include(formation => formation.Origine)
.Include(formation => formation.TypeFormation)
.Include(formation => formation.ParticipationsFormation)
.ThenInclude(participation => participation.DemandeFormation)
.ThenInclude(demande => demande.Ep)
.FirstOrDefaultAsync(formation => formation.IdFormation == idFormation);
if (formation == null)
throw new FormationNotFoundException(string.Format("Aucune formation trouvée avec l'id suivant: {0}.", idFormation));
if (formation.ParticipationsFormation.Count > 0)
{
IEnumerable<CollaborateurDTO> collaborateurDTOs = await collaborateurService.GetCollaborateurDTOsAsync(formation.ParticipationsFormation);
return transformDTO.GetFormationDTO(formation, collaborateurDTOs);
}
else
{
return transformDTO.GetFormationDTOWhitoutParticipationFormation(formation);
}
}
/// <summary>
/// Récupérer la liste des formations de manière asynchrone
/// </summary>
/// <param name="asc">Préciser si les données sont dans l&#x27;ordre (true) ou dans l&#x27;ordre inverse (false)</param>
/// <param name="numPage">Numéro de la page du tableau qui affiche les données</param>
/// <param name="parPage">Nombre d&#x27;éléments affiché sur chaque page du tableau</param>
/// <param name="idAgence">id de l&#x27;agence à laquelle sont rattachées les données à récupérer</param>
/// <param name="texte">Texte permettant d&#x27;identifier l&#x27;objet rechercher</param>
/// <param name="tri">Colonne du tableau sur lequel le tri s&#x27;effectue</param>
/// <returns></returns>
public async Task<IEnumerable<FormationDetailsDTO>> GetFormationsAsync(long? idAgence, List<int?> idStatuts, bool? asc, int? numPage, int? parPage, string texte, string tri, DateTime? dateDebut, DateTime? dateFin)
{
IQueryable<Formation> query;
IEnumerable<Formation> formations;
IEnumerable<FormationDetailsDTO> formationDTOs;
query = epContext.Formation
.Include(formation => formation.Statut)
.Include(formation => formation.ModeFormation)
.Include(formation => formation.Origine)
.Include(formation => formation.TypeFormation)
.Include(formation => formation.ParticipationsFormation);
query = IdStatutsFilter(query, idStatuts);
query = IdAgenceFilter(query, idAgence);
query = IntituleFilter(query, texte);
query = DateFilter(query, dateDebut, dateFin);
query = OrderByColumn(query, asc, tri);
query = SkipAndTake(query, parPage, numPage);
formations = await query.ToListAsync();
formationDTOs = formations.Select(formation => transformDTO.GetFormationDetailsDTO(formation));
return formationDTOs;
}
/// <summary>
/// Récupérer le nombre total de formations de manière asynchrone
/// </summary>
/// <param name="numPage">Numéro de la page du tableau qui affiche les données</param>
/// <param name="parPage">Nombre d&#x27;éléments affiché sur chaque page du tableau</param>
/// <param name="idAgence">id de l&#x27;agence à laquelle sont rattachées les données à récupérer</param>
/// <param name="texte">Texte permettant d&#x27;identifier l&#x27;objet rechercher</param>
/// <returns></returns>
public async Task<long> GetFormationsCountAsync(long? idAgence, List<int?> idStatuts, string texte, DateTime? dateDebut, DateTime? dateFin)
{
IQueryable<Formation> query;
long count;
query = epContext.Formation
.Include(formation => formation.Statut)
.Include(formation => formation.ModeFormation)
.Include(formation => formation.Origine)
.Include(formation => formation.TypeFormation)
.Include(formation => formation.ParticipationsFormation);
query = IntituleFilter(query, texte);
query = IdStatutsFilter(query, idStatuts);
query = IdAgenceFilter(query, idAgence);
query = DateFilter(query, dateDebut, dateFin);
count = await query.CountAsync();
return count;
}
/// <summary>
/// Récupérer les modes de formation de manière asynchrone
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<ModeFormationDTO>> GetModesFormationAsync()
{
IEnumerable<ModeFormation> modeFormations;
IEnumerable<ModeFormationDTO> modeFormationDTOs;
modeFormations = await epContext.ModeFormation.ToListAsync();
modeFormationDTOs = modeFormations.Select(modeFormation => transformDTO.GetModeFormationDTO(modeFormation));
return modeFormationDTOs;
}
/// <summary>
/// Récupérer les origines de formation de manière asynchrone
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<OrigineFormationDTO>> GetOriginesFormationAsync()
{
IEnumerable<OrigineFormation> origineFormations;
IEnumerable<OrigineFormationDTO> origineFormationDTOs;
origineFormations = await epContext.OrigineFormation.ToListAsync();
origineFormationDTOs = origineFormations.Select(origineFormation => transformDTO.GetOrigineFormationDTO(origineFormation));
return origineFormationDTOs;
}
/// <summary>
/// Récupérer les statuts de formation de manière asynchrone
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<StatutFormationDTO>> GetStatutsFormationAsync()
{
IEnumerable<StatutFormation> statutFormations;
IEnumerable<StatutFormationDTO> statutFormationDTOs;
statutFormations = await epContext.StatutFormation.ToListAsync();
statutFormationDTOs = statutFormations.Select(statutFormation => transformDTO.GetStatutFormationDTO(statutFormation));
return statutFormationDTOs;
}
/// <summary>
/// Récupérer les types de formation de manière asynchrone
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<TypeFormationDTO>> GetTypesFormationAsync()
{
IEnumerable<TypeFormation> typeFormations;
IEnumerable<TypeFormationDTO> typeFormationDTOs;
typeFormations = await epContext.TypeFormation.ToListAsync();
typeFormationDTOs = typeFormations.Select(typeFormation => transformDTO.GetTypeFormationDTO(typeFormation));
return typeFormationDTOs;
}
/// <summary>
/// Ajouter une formation de manière asynchrone
/// </summary>
/// <param name="formationDTO"></param>
/// <returns></returns>
public async Task<FormationDTO> AddFormationAsync(FormationDTO formationDTO)
{
IsFormationValide(formationDTO);
Formation formation = new Formation();
formation = transformDTO.SetFormation(formation, formationDTO);
epContext.StatutFormation.Attach(formation.Statut);
epContext.OrigineFormation.Attach(formation.Origine);
epContext.ModeFormation.Attach(formation.ModeFormation);
epContext.TypeFormation.Attach(formation.TypeFormation);
epContext.Add(formation);
await epContext.SaveChangesAsync();
return transformDTO.GetFormationDTOWhitoutParticipationFormation(formation);
}
/// <summary>
/// Modifier une formation de manière asynchrone
/// </summary>
/// <param name="idFormation"></param>
/// <param name="formationDTO"></param>
/// <returns></returns>
public async Task<FormationDTO> UpdateFormationAsync(long idFormation, FormationDTO formationDTO)
{
IsFormationValide(formationDTO);
if (!formationDTO.Id.HasValue || formationDTO.Id.Value != idFormation)
throw new FormationIncompatibleIdException("L'id de la formation a mettre à jour et la formation a mettre à jour sont incompatble.");
Formation formation = await epContext.Formation.Include(formation => formation.Statut)
.Include(formation => formation.ModeFormation)
.Include(formation => formation.Origine)
.Include(formation => formation.TypeFormation)
.Include(formation => formation.ParticipationsFormation)
.ThenInclude(participation => participation.DemandeFormation)
.ThenInclude(demande => demande.Ep)
.FirstOrDefaultAsync(formation => formation.IdFormation == idFormation);
if (formation == null)
throw new FormationNotFoundException(string.Format("Aucune formation trouvée avec l'id suivant: {0}.", idFormation));
formation = transformDTO.SetFormation(formation, formationDTO);
await epContext.SaveChangesAsync();
return transformDTO.GetFormationDTOWhitoutParticipationFormation(formation);
}
/// <summary>
/// Supprimer une formation de manière asynchrone
/// </summary>
/// <param name="idFormation"></param>
/// <returns></returns>
public async Task<FormationDTO> DeleteFormationByIdAsync(long idFormation)
{
Formation formation = await epContext.Formation.Include(formation => formation.Statut)
.Include(formation => formation.ModeFormation)
.Include(formation => formation.Origine)
.Include(formation => formation.TypeFormation)
.Include(formation => formation.ParticipationsFormation)
.ThenInclude(participation => participation.DemandeFormation)
.ThenInclude(demande => demande.Ep)
.FirstOrDefaultAsync(formation => formation.IdFormation == idFormation);
if (formation == null)
throw new FormationNotFoundException(string.Format("Aucune formation trouvée avec l'id suivant: {0}.", idFormation));
epContext.Remove(formation);
await epContext.SaveChangesAsync();
return transformDTO.GetFormationDTOWhitoutParticipationFormation(formation);
}
#endregion
#region Méthodes Privée
/// <summary>
/// Vérifier si un objet FormationDTO est valide pour ajout ou mise à jour
/// </summary>
/// <remarks> Un objet FormationDTO est valide si aucune de ses propriétés n'est à null,si la date de début de la formation est inférieur à la date de fin et si le statut, l'origine,le mode et le type sont présents dans la base de données</remarks>
/// <param name="formation"></param>
/// <returns>true si l'objet est valide, false sinon</returns>
private void IsFormationValide(FormationDTO formation)
{
// Vérifier que la formation n'est pas null
if (formation == null)
throw new FormationInvalidException("Aucune formation n'a été reçue");
// Vérfier que la formation a bien un statut de formation
if (formation.Statut == null || !formation.Statut.Id.HasValue)
throw new FormationInvalidException("Impossible d'enregistrer une formation sans statut de formation.");
// Vérfier que la formation a bien un mode de formation
if (formation.Mode == null || !formation.Mode.Id.HasValue)
throw new FormationInvalidException("Impossible d'enregistrer une formation sans mode de formation.");
// Vérfier que la formation a bien une origine de formation
if (formation.Origine == null || !formation.Origine.Id.HasValue)
throw new FormationInvalidException("Impossible d'enregistrer une formation sans origine de formation.");
// Vérfier que la formation a bien un type de formation
if (formation.Type == null || !formation.Type.Id.HasValue)
throw new FormationInvalidException("Impossible d'enregistrer une formation sans type de formation.");
// Vérfier que la formation a bien une agence
if (!formation.IdAgence.HasValue || formation.IdAgence == 0)
throw new FormationInvalidException("Impossible d'enregistrer une formation sans mode de formation.");
// Vérifier que la formation a bien un intitulé
if (string.IsNullOrWhiteSpace(formation.Intitule))
throw new FormationInvalidException("L'intitulé de la formation doit contenir au moins 1 caractère.");
// Vérifier que la formation a bien un organisme
if (string.IsNullOrWhiteSpace(formation.Organisme))
throw new FormationInvalidException("L'organisme de la formation doit contenir au moins 1 caractère.");
// Vérifier que la formation a bien une date de début
if (!formation.DateDebut.HasValue)
throw new FormationInvalidException("Impossible d'enregistrer une formation sans date de début de formation.");
// Vérifier que la formation a bien une date de fin
if (!formation.DateFin.HasValue)
throw new FormationInvalidException("Impossible d'enregistrer une formation sans date de fin de formation.");
// Vérifier que la formation a bien une date de début inférieure à la date de fin
if (formation.DateDebut.Value > formation.DateFin.Value)
throw new FormationInvalidException("La date de début de la formation est supérieure à la date de fin.");
// Vérfier que le statut de la formation est présent dans la BDD
if (!epContext.StatutFormation.Any(statut => statut.IdStatutFormation == formation.Statut.Id.Value && statut.Libelle == formation.Statut.Libelle))
throw new FormationInvalidException("Le statut de la formation n'existe pas.");
// Vérfier que le mode de la formation est présent dans la BDD
if (!epContext.ModeFormation.Any(mode => mode.IdModeFormation == formation.Mode.Id.Value && mode.Libelle == formation.Mode.Libelle))
throw new FormationInvalidException("Le mode de la formation n'existe pas.");
// Vérfier que l'orgine de la formation est présente dans la BDD
if (!epContext.OrigineFormation.Any(origine => origine.IdOrigineFormation == formation.Origine.Id.Value && origine.Libelle == formation.Origine.Libelle))
throw new FormationInvalidException("L'origine de la formation n'existe pas.");
// Vérfier que le type de la formation est présent dans la BDD
if (!epContext.TypeFormation.Any(type => type.IdTypeFormation == formation.Type.Id.Value && type.Libelle == formation.Type.Libelle))
throw new FormationInvalidException("Le type de la formation n'existe pas.");
}
/// <summary>
/// Ajouter un ordonnancement croissant ou décroissant sur colonne
/// </summary>
/// <param name="query"></param>
/// <param name="idStatuts"></param>
/// <returns></returns>
private IQueryable<Formation> OrderByColumn(IQueryable<Formation> query, bool? asc, string columnName)
{
if (!asc.HasValue)
asc = defaultAsc;
if (string.IsNullOrWhiteSpace(columnName))
{
if (asc.Value)
return query.OrderBy(p => p.Intitule);
else
return query.OrderByDescending(p => p.Intitule);
}
switch (columnName.ToLower())
{
case "intitule":
if (asc.Value)
return query.OrderBy(p => p.Intitule);
else
return query.OrderByDescending(p => p.Intitule);
case "statut":
if (asc.Value)
return query.OrderBy(p => p.Statut.Libelle);
else
return query.OrderByDescending(p => p.Statut.Libelle);
case "origine":
if (asc.Value)
return query.OrderBy(p => p.Origine.Libelle);
else
return query.OrderByDescending(p => p.Origine.Libelle);
case "date":
if (asc.Value)
return query.OrderBy(p => p.DateDebut);
else
return query.OrderByDescending(p => p.DateDebut);
case "certification":
if (asc.Value)
return query.OrderBy(p => p.EstCertifiee);
else
return query.OrderByDescending(p => p.EstCertifiee);
case "participants":
if (asc.Value)
return query.OrderBy(p => p.ParticipationsFormation.Count);
else
return query.OrderByDescending(p => p.ParticipationsFormation.Count);
default:
if (asc.Value)
return query.OrderBy(p => p.Intitule);
else
return query.OrderByDescending(p => p.Intitule);
}
}
/// <summary>
/// Ajouter un filtre pour récupérer les formations en fonction de plusieurs identifiants de statut de formation
/// </summary>
/// <param name="query"></param>
/// <param name="idStatuts"></param>
/// <returns></returns>
private IQueryable<Formation> IdStatutsFilter(IQueryable<Formation> query, List<int?> idStatuts)
{
if (idStatuts != null && idStatuts.Count > 0 && idStatuts.First().HasValue)
return query.Where(formation => idStatuts.Contains(formation.Statut.IdStatutFormation));
else
return query;
}
/// <summary>
/// Ajouter un filtre pour récupérer les formations en fonction de l'identifiant d'une agence
/// </summary>
/// <param name="query"></param>
/// <param name="idAgence"></param>
/// <returns></returns>
private IQueryable<Formation> IdAgenceFilter(IQueryable<Formation> query, long? idAgence)
{
if (idAgence != null)
return query.Where(formation => formation.IdAgence == idAgence);
else
return query;
}
/// <summary>
/// Ajouter un filtre pour récupérer les formations en fonction d'un intitulé
/// </summary>
/// <param name="query"></param>
/// <param name="intitule"></param>
/// <returns></returns>
private IQueryable<Formation> IntituleFilter(IQueryable<Formation> query, string intitule)
{
if (!string.IsNullOrWhiteSpace(intitule))
return query.Where(formation => formation.Intitule.ToLower().Contains(intitule.ToLower()));
else
return query;
}
/// <summary>
/// Ajouter un filtre pour récupérer les formations en fonction d'un intervalle de date
/// </summary>
/// <param name="query"></param>
/// <param name="dateDebut"></param>
/// <param name="dateFin"></param>
/// <returns></returns>
private IQueryable<Formation> DateFilter(IQueryable<Formation> query, DateTime? dateDebut, DateTime? dateFin)
{
if (dateDebut.HasValue && dateFin.HasValue)
return query.Where(formation => formation.DateDebut >= dateDebut.Value && formation.DateFin <= dateFin.Value.AddDays(1));
else if (!dateDebut.HasValue && dateFin.HasValue)
return query.Where(formation => formation.DateFin <= dateFin.Value.AddDays(1));
else if (dateDebut.HasValue && !dateFin.HasValue)
return query.Where(formation => formation.DateDebut >= dateDebut.Value);
else
return query;
}
/// <summary>
/// Ajouter une pagination
/// </summary>
/// <param name="query"></param>
/// <param name="parPage"></param>
/// <param name="numPage"></param>
/// <returns></returns>
private IQueryable<Formation> SkipAndTake(IQueryable<Formation> query, int? parPage, int? numPage)
{
int skip, take;
if (!parPage.HasValue || parPage.Value < minParPage || parPage.Value > maxParPage)
parPage = defaultParPage;
if (!numPage.HasValue || numPage.Value <= 0)
numPage = defaultNumPage;
skip = (numPage.Value - 1) * parPage.Value;
take = parPage.Value;
return query.Skip(skip).Take(take);
}
#endregion
}
}