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

284 lines
11 KiB

using EPAServeur.Context;
using EPAServeur.Exceptions;
using EPAServeur.IServices;
using EPAServeur.Models.Notes;
using IO.Swagger.ApiCollaborateur;
using IO.Swagger.DTO;
using IO.Swagger.ModelCollaborateur;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace EPAServeur.Services
{
/// <summary>
/// Service permettant de gérer les notes (ajout, récupération, mise à jour, suppression)
/// </summary>
public class NoteService : INoteService
{
#region Variables
private readonly ICollaborateurApi collaborateurApi;
/// <summary>
/// Contexte pour interagir avec la base de données MySQL du serveur EP
/// </summary>
private readonly EpContext context;
/// <summary>
/// Service collaborateur pour récupérer les données collaborateurs au format DTO
/// </summary>
private readonly ICollaborateurService collaborateurService;
/// <summary>
/// Accès au service permettant de transformer un modèle en dto
/// </summary>
private readonly ITransformDTO transformDTO;
#endregion
#region Constructeurs
public NoteService(ICollaborateurApi _collaborateurApi, ICollaborateurService _collaborateurService, EpContext _context, ITransformDTO _transformDTO)
{
collaborateurService = _collaborateurService;
collaborateurApi = _collaborateurApi;
context = _context;
transformDTO = _transformDTO;
}
#endregion
#region Services Async
/// <summary>
/// Ajouter une nouvelle note dans la base de données de manière async
/// </summary>
/// <param name="nouvelleNote">La nouvelle note a ajouté en base</param>
/// <returns>La nouvelle note ajouté</returns>
public async Task<DetailsNoteDTO> AjouterNoteAsync(DetailsNoteDTO nouvelleNote)
{
//vérifier qu'il n'y a aucune valeur null
CheckNoteValide(nouvelleNote);
List<Guid?> guids = new List<Guid?>();
guids.AddRange(new Guid?[]{nouvelleNote.IdAuteur, nouvelleNote.Collaborateur.Id});
IEnumerable<Collaborateur> collaborateurs = await collaborateurApi.ChercherCollabAsync(guids);
//vérifier que le référent existe
CheckReferent(collaborateurs.Where(c => c.Id.Equals(nouvelleNote.IdAuteur)).FirstOrDefault());
//vérifier que le collaborateur existe
CheckCollaborateur(collaborateurs.Where(c => c.Id.Equals(nouvelleNote.Collaborateur.Id)).FirstOrDefault());
//transformer la note DTO en Note
Note note = transformDTO.DetailsNoteDTOToNouvelleNote(nouvelleNote);
//ajouter la note et sauvegarder
await context.Note.AddAsync(note);
await context.SaveChangesAsync();
nouvelleNote.Id = note.IdNote;
return nouvelleNote;
}
/// <summary>
/// Supprimer une note en fonction de son Id de manière async
/// </summary>
/// <param name="idNote">Id de la note à supprimer</param>
public async Task<bool> SupprimerNoteAsync(long? idNote)
{
Note note = await context.Note.FindAsync(idNote);
if (note == null)
{
throw new NoteNotFoundException("Impossible de supprimer la note car elle n'a pas été trouvée");
}
context.Remove(note);
await context.SaveChangesAsync();
return true;
}
/// <summary>
/// Récupérer une note en fonction de son id de manière async
/// </summary>
/// <param name="idNote">Id de la note à récupérer</param>
/// <returns>L'objet DTO de la note correspondant à l'id passé en paramètre</returns>
public async Task<DetailsNoteDTO> GetNoteByIdAsync(long? idNote)
{
Note note = await context.Note.FindAsync(idNote);
//vérifier l'existance de la note
if (note == null)
throw new NoteNotFoundException("La note cherchée n'a pas été trouvée");
//vérifier l'existence de l'auteur
Collaborateur auteur = await collaborateurApi.ChercherCollabIdAsync(note.IdAuteur);
if (auteur == null)
throw new ReferentNotFoundException("L'auteur de la note n'existe pas");
return transformDTO.NoteToDetailSDTO(note, await collaborateurService.GetCollaborateurByIdAsync(note.IdCollaborateur));
}
/// <summary>
/// Récupérer la liste des notes qu'un auteur a écrit sur un collaborateur
/// </summary>
/// <param name="idAuteur">Id de l'auteur des notes à récupérer</param>
/// <param name="asc">Précise si la liste est trié dans l'ordre croissant ou décroissant</param>
/// <param name="numPage">Numéro de la page qui est affiché du côté front</param>
/// <param name="parPage">Nombre de notes à renvoyer</param>
/// <param name="texte">permet de récupérer les notes les informations du collaborateur ou le titre de la note contient le texte</param>
/// <param name="tri">Choisir l'attribut par lequel est trié la liste</param>
/// <returns>Retour la liste des notes à afficher</returns>
public async Task<IEnumerable<AffichageNoteDTO>> GetNotesByAuteurAsync(Guid? idAuteur, bool? asc, int? numPage, int? parPage, string texte, string tri)
{
Collaborateur auteur = await collaborateurApi.ChercherCollabIdAsync(idAuteur);
if (auteur == null)
throw new ReferentNotFoundException("L'auteur de la note n'existe pas");
IEnumerable<Note> notes = context.Note.Where(n => n.IdAuteur == idAuteur);
List<Guid?> guids = notes.Select(n => (Guid?)n.IdCollaborateur).ToList();
IEnumerable<Collaborateur> collaborateurs = await collaborateurApi.ChercherCollabAsync(guids);
IEnumerable<AffichageNoteDTO> AffichageNoteDTO = notes.Select(note => transformDTO.NoteToAffichageDTO(note, collaborateurs));
int skip = (numPage.Value - 1) * parPage.Value;
int take = parPage.Value;
if (texte != null)
{
texte = texte.ToLower();
AffichageNoteDTO = (from a in AffichageNoteDTO
where a.Collaborateur.ToLower().Contains(texte) || a.Titre.ToLower().Contains(texte)
select a);
}
AffichageNoteDTO = Tri(AffichageNoteDTO, tri);
if( asc.HasValue && !asc.Value)
{
AffichageNoteDTO = AffichageNoteDTO.Reverse();
}
return AffichageNoteDTO.Skip(skip).Take(take);
}
/// <summary>
/// Récupérer le nombre de notes qu'un auteur a écrit
/// </summary>
/// <param name="idAuteur">Id de l'auteur des notes à récupérer</param>
/// <param name="texte">permet de récupérer les notes les informations du collaborateur ou le titre de la note contient le texte</param>
/// <returns>Le nombre de notes</returns>
public async Task<int> GetNotesByAuteurCountAsync(Guid? idAuteur, string texte)
{
Collaborateur auteur = await collaborateurApi.ChercherCollabIdAsync(idAuteur);
if (auteur == null)
throw new ReferentNotFoundException("L'auteur de la note n'existe pas");
IEnumerable<Note> notes = context.Note.Where(n => n.IdAuteur == idAuteur);
List<Guid?> guids = notes.Select(n => (Guid?)n.IdCollaborateur).ToList();
IEnumerable<Collaborateur> collaborateurs = await collaborateurApi.ChercherCollabAsync(guids);
IEnumerable<AffichageNoteDTO> AffichageNoteDTO = notes.Select(note => transformDTO.NoteToAffichageDTO(note, collaborateurs));
if (texte != null)
{
texte = texte.ToLower();
AffichageNoteDTO = (from a in AffichageNoteDTO
where a.Collaborateur.ToLower().Contains(texte) || a.Titre.ToLower().Contains(texte)
select a);
}
return AffichageNoteDTO.Count();
}
/// <summary>
/// Mettre à jour une note
/// </summary>
/// <param name="idNote">Id de la note à modifier</param>
/// <param name="note">Note avec les informations à jour</param>
/// <returns>La note mise à jour</returns>
public async Task<DetailsNoteDTO> UpdateNoteAsync(long? idNote, DetailsNoteDTO note)
{
if (idNote != note.Id)
throw new NoteIdImcompatibleException("L'id de la note a mettre à jour et la note a mettre à jour sont incompatble");
CheckNoteValide(note);
Note noteToUpdate = await context.Note.FindAsync(idNote);
if (!noteToUpdate.DateCreation.Equals(note.DateCreation) || note.Collaborateur.Id != noteToUpdate.IdCollaborateur || note.IdAuteur != noteToUpdate.IdAuteur)
throw new NoteIdImcompatibleException("La note a mettre à jour et la note en base de données ne correspondent pas");
noteToUpdate.Titre = note.Titre;
noteToUpdate.Texte = note.Texte;
noteToUpdate.DateMiseAJour = DateTime.Now;
note.DateMiseAjour = noteToUpdate.DateMiseAJour;
return note;
}
#endregion
#region fonctions privees
/// <summary>
/// Vérfier si la note est valide
/// </summary>
/// <param name="note">La note a vérifié</param>
private void CheckNoteValide(DetailsNoteDTO note)
{
//vérifier que la note n'est pas null
if (note == null)
throw new NoteInvalideException("Aucune note n'a été reçue");
//vérfier que la note a bien un auteur
if (note.IdAuteur == null || !note.IdAuteur.HasValue)
throw new NoteInvalideException("Il impossible d'enregistrer sans donnée sur la personne qui l'a écrite");
//vérifier que la note est bien lié à un collaboarteur identifiable sur le serveur distant (avec une id)
if (note.Collaborateur == null || note.Collaborateur.Id == null || !note.Collaborateur.Id.HasValue)
throw new NoteInvalideException("Il est impossible d'enregistrer une note qui n'est pas lié à un collaborateur");
//vérifier que le titre de la note est valide
if (note.Titre == null || note.Titre == "" || note.Titre.Length < 3)
throw new NoteInvalideException("Vous devez saisir un titre d'au moins 3 caractères");
//vérifier que le texte de la note est valide
if(note.Texte == null || note.Texte == "" || note.Texte.Length < 3)
throw new NoteInvalideException("Vous devez saisir une note d'au moins 3 caractères");
}
/// <summary>
/// Vérifier que l'auteur de la note existe et est toujours présent dans l'entreprise
/// </summary>
/// <param name="referent">L'auteur de la note</param>
private void CheckReferent(Collaborateur auteur)
{
if (auteur == null)
throw new ReferentNotFoundException("Les informations de l'auteur de la note n'ont pas été trouvé");
if (auteur.DateDepart.HasValue)
throw new CollaborateurPartiException("Vous ne pouvez pas créer ou modifier de note si vous avez quitté l'entreprise");
}
private IEnumerable<AffichageNoteDTO> Tri(IEnumerable<AffichageNoteDTO> affichageNoteDTOs, string tri)
{
return tri switch
{
"collaborateur" => affichageNoteDTOs.OrderBy(n => n.Collaborateur),
"datemiseajour" => affichageNoteDTOs.OrderBy(n => n.DateMiseAJour),
"titre" => affichageNoteDTOs.OrderBy(n => n.Titre),
_ => affichageNoteDTOs,
};
}
/// <summary>
/// Vérifier que le collaborateur concerné par la note existe et est toujorus présent dans l'entreprise
/// </summary>
/// <param name="collaborateur">Le collaborateur concerné</param>
private void CheckCollaborateur(Collaborateur collaborateur)
{
if (collaborateur == null)
throw new CollaborateurNotFoundException("Le collaborateur pour qui la note est écrite n'a pas été trouvé");
if (collaborateur.DateDepart.HasValue)
throw new CollaborateurPartiException("Vous ne pouvez pas créer ou modifier de notes pour un collaborateur qui a quitté l'entreprise");
}
#endregion
}
}