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/EngagementService.cs

335 lines
14 KiB

using EPAServeur.Context;
using EPAServeur.Exceptions;
using EPAServeur.IServices;
using EPAServeur.Models.EP;
using IO.Swagger.DTO;
using IO.Swagger.Enum;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace EPAServeur.Services
{
public class EngagementService : IEngagementService
{
#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 EngagementService
/// </summary>
/// <param name="_epContext"></param>
public EngagementService(EpContext _epContext, ICollaborateurService _collaborateurService, ITransformDTO _transformDTO)
{
epContext = _epContext;
collaborateurService = _collaborateurService;
transformDTO = _transformDTO;
}
#endregion
#region Méthodes Service
/// <summary>
/// Récupérer la liste des engagements de manière asynchrone
/// </summary>
/// <param name="etatsEngagement"></param>
/// <param name="idBUs"></param>
/// <param name="asc"></param>
/// <param name="numPage"></param>
/// <param name="parPage"></param>
/// <param name="texte"></param>
/// <param name="tri"></param>
/// <returns></returns>
public async Task<IEnumerable<EngagementDTO>> GetEngagementsAsync(List<long> idBUs, List<EtatEngagement> etatsEngagement, bool? asc, int? numPage, int? parPage, string texte, string tri)
{
IQueryable<Engagement> query;
IEnumerable<Engagement> engagements;
IEnumerable<EngagementDTO> engagementDTOs;
IEnumerable<CollaborateurDTO> collaborateurDTOs;
query = epContext.Engagement.Include(engagement => engagement.Ep);
query = IdBUsFilter(query, idBUs);
query = EtatsEngagementFilter(query, etatsEngagement);
query = OrderByColumn(query, asc, tri);
query = SkipAndTake(query, parPage, numPage);
engagements = await query.ToListAsync();
collaborateurDTOs = await collaborateurService.GetCollaborateurDTOsAsync(engagements);
engagementDTOs = engagements.Select(engagement => transformDTO.GetEngagementDTO(engagement, collaborateurDTOs));
engagementDTOs = CollaborateurFilter(engagementDTOs, texte);
return engagementDTOs;
}
public async Task<long> GetEngagementsCountAsync(List<long> idBUs, List<EtatEngagement> etatsEngagement, string texte)
{
IQueryable<Engagement> query;
IEnumerable<Engagement> engagements;
IEnumerable<EngagementDTO> engagementDTOs;
IEnumerable<CollaborateurDTO> collaborateurDTOs;
long count;
query = epContext.Engagement.Include(engagement => engagement.Ep);
query = IdBUsFilter(query, idBUs);
query = EtatsEngagementFilter(query, etatsEngagement);
engagements = await query.ToListAsync();
collaborateurDTOs = await collaborateurService.GetCollaborateurDTOsAsync(engagements);
engagementDTOs = engagements.Select(engagement => transformDTO.GetEngagementDTO(engagement, collaborateurDTOs));
engagementDTOs = CollaborateurFilter(engagementDTOs, texte);
count = engagementDTOs.Count();
return count;
}
/// <summary>
/// Donner une réponse à un engagement de manière asynchrone
/// </summary>
/// <param name="engagementDTO"></param>
/// <param name="idEngagement"></param>
/// <returns></returns>
public async Task<EngagementDTO> RepondreEngagementAsync(EngagementDTO engagementDTO, long idEngagement)
{
IEnumerable<CollaborateurDTO> collaborateurDTOs;
Engagement engagement;
IsEngagementValide(engagementDTO);
if (!engagementDTO.Id.HasValue || engagementDTO.Id.Value != idEngagement)
throw new EngagementIncompatibleIdException("L'id de l'engagement à mettre à jour et l'engagement à mettre à jour sont incompatible.");
engagement = await epContext.Engagement.Include(engagement => engagement.Ep).FirstOrDefaultAsync(engagement => engagement.IdEngagement == idEngagement);
if (engagement == null)
throw new EngagementNotFoundException();
collaborateurDTOs = await collaborateurService.GetCollaborateurDTOsAsync(engagement);
engagement = transformDTO.SetReponseEngagement(engagement, engagementDTO);
await epContext.SaveChangesAsync();
return transformDTO.GetEngagementDTO(engagement, collaborateurDTOs);
}
#endregion
#region Méthodes Privée
/// <summary>
/// Vérifier si un objet EngagementDTO est valide pour ajout ou mise à jour
/// </summary>
/// <remarks> Un objet EngagementDTO est valide si l'action, le dispositif, la modalité et la date limite n'est pas null, si l'EP est signé, et si l'EP est présent dans la base de données.</remarks>
/// <param name="formation"></param>
/// <exception cref="EPAServeur.Exceptions.EngagementInvalidException"></exception>
private void IsEngagementValide(EngagementDTO engagementDTO)
{
// Vérifier que l'engagement n'est pas null
if (engagementDTO == null)
throw new EngagementInvalidException("Aucun engagement n'a été reçu.");
// Vérfier que l'engagement a bien un EP
if (engagementDTO.Ep == null || !engagementDTO.Ep.Id.HasValue)
throw new EngagementInvalidException("Impossible de répondre à un engagement sans EP.");
// Vérfier que l'ep a bien été signé par le collaborateur
if (engagementDTO.Ep.Statut != StatutEp.Signe)
throw new EngagementInvalidException("Impossible de répondre à un engagement d'un EP qui n'est pas en cours et qui n'a pas été signé par le collaborateur.");
// Vérifier que l'engagement a bien une action
if (string.IsNullOrWhiteSpace(engagementDTO.Action))
throw new EngagementInvalidException("L'action de l'engagement doit contenir au moins 1 caractère.");
// Vérifier que l'engagement a bien un dispositif
if (string.IsNullOrWhiteSpace(engagementDTO.Dispositif))
throw new EngagementInvalidException("Le dispostif de l'engagement doit contenir au moins 1 caractère.");
// Vérifier que l'engagement a bien une modalité
if (string.IsNullOrWhiteSpace(engagementDTO.Modalite))
throw new EngagementInvalidException("La modalité de l'engagement doit contenir au moins 1 caractère.");
// Vérifier que l'engagement a bien une date limite
if (!engagementDTO.DateLimite.HasValue)
throw new EngagementInvalidException("Impossible de répondre à l'engagement sans date limite.");
// Vérifier que l'engagement a bien raison expliquant pourquoi l'engagement n'est pas réalisable lorsque l'état de l'engagement n'est pas réalisable
if (engagementDTO.EtatEngagement == EtatEngagement.NonRealisable && string.IsNullOrWhiteSpace(engagementDTO.RaisonNonRealisable))
throw new EngagementInvalidException("Impossible de répondre à l'engagement, une raison doit être rensignée lorsqu'un engagement n'est pas réalisé.");
// Vérfier que l'EP lié à l'engagement est présent dans la BDD
if (!epContext.Ep.Any(ep => ep.IdEP == engagementDTO.Ep.Id.Value))
throw new EngagementInvalidException("L'EP 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<Engagement> OrderByColumn(IQueryable<Engagement> query, bool? asc, string columnName)
{
if (!asc.HasValue)
asc = defaultAsc;
if (string.IsNullOrWhiteSpace(columnName))
{
if (asc.Value)
return query.OrderBy(p => p.Action);
return query.OrderByDescending(p => p.Action);
}
switch (columnName.ToLower())
{
case "action":
if (asc.Value)
return query.OrderBy(p => p.Action);
return query.OrderByDescending(p => p.Action);
case "dispositif":
if (asc.Value)
return query.OrderBy(p => p.Dispositif);
return query.OrderByDescending(p => p.Dispositif);
case "modalite":
if (asc.Value)
return query.OrderBy(p => p.Modalite);
return query.OrderByDescending(p => p.Modalite);
case "date":
if (asc.Value)
return query.OrderBy(p => p.DateLimite);
return query.OrderByDescending(p => p.DateLimite);
default:
if (asc.Value)
return query.OrderBy(p => p.Action);
return query.OrderByDescending(p => p.Action);
}
}
/// <summary>
/// Ajouter un filtre pour récupérer les engagements en fonction de plusieurs identifiants de Business Unit
/// </summary>
/// <param name="query"></param>
/// <param name="idBUs"></param>
/// <returns></returns>
/// <exception cref="EPAServeur.Exceptions.EngagementInvalidException"></exception>
private IQueryable<Engagement> IdBUsFilter(IQueryable<Engagement> query, List<long> idBUs)
{
if (idBUs == null || idBUs.Count == 0)
throw new EngagementInvalidException("Aucune Business Unit n'a été reçu.");
return query.Where(engagement => idBUs.Contains(engagement.Ep.IdBu));
}
/// <summary>
/// Ajouter un filtre pour récupérer les engagements en fonction de plusieurs états d'engagement
/// </summary>
/// <param name="query"></param>
/// <param name="idBUs"></param>
/// <returns></returns>
private IQueryable<Engagement> EtatsEngagementFilter(IQueryable<Engagement> query, List<EtatEngagement> etatsEngagement)
{
if (etatsEngagement == null || etatsEngagement.Count <= 0)
return query;
return query.Where(engagement => etatsEngagement.Contains(engagement.EtatEngagement));
}
/// <summary>
/// Ajouter un filtre pour récupérer les engagements en fonction du nom et du prénom du collaborateur
/// </summary>
/// <param name="engagementDTOs"></param>
/// <param name="intitule"></param>
/// <returns></returns>
private IEnumerable<EngagementDTO> CollaborateurFilter(IEnumerable<EngagementDTO> engagementDTOs, string texte)
{
if (string.IsNullOrWhiteSpace(texte))
return engagementDTOs;
return engagementDTOs.Where(engagement => (engagement.Ep.Collaborateur.Nom + " " + engagement.Ep.Collaborateur.Prenom).ToLower().Contains(texte.ToLower()) ||
(engagement.Ep.Collaborateur.Prenom + " " + engagement.Ep.Collaborateur.Nom).ToLower().Contains(texte.ToLower()) );
}
/// <summary>
/// Ajouter une pagination
/// </summary>
/// <param name="query"></param>
/// <param name="parPage"></param>
/// <param name="numPage"></param>
/// <returns></returns>
private IQueryable<Engagement> SkipAndTake(IQueryable<Engagement> 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
}
}