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
{
///
/// Service permettant de gérer les notes (ajout, récupération, mise à jour, suppression)
///
public class NoteService : INoteService
{
#region Variables
private readonly ICollaborateurApi collaborateurApi;
///
/// Contexte pour interagir avec la base de données MySQL du serveur EP
///
private readonly EpContext context;
///
/// Service collaborateur pour récupérer les données collaborateurs au format DTO
///
private readonly ICollaborateurService collaborateurService;
#endregion
#region Constructeurs
public NoteService(ICollaborateurApi _collaborateurApi, ICollaborateurService _collaborateurService, EpContext _context)
{
collaborateurService = _collaborateurService;
collaborateurApi = _collaborateurApi;
context = _context;
}
#endregion
#region Services Sync
///
/// Ajouter une nouvelle note dans la base de données
///
/// La nouvelle note a ajouté en base
/// La nouvelle note ajouté
public DetailsNoteDTO AjouterNote(DetailsNoteDTO nouvelleNote)
{
//vérifier qu'il n'y a aucune valeur null
CheckNoteValide(nouvelleNote);
//vérifier que le référent existe
Collaborateur auteur = collaborateurApi.ChercherCollabId(nouvelleNote.IdAuteur);
CheckReferent(auteur);
//vérifier que le collaborateur existe
Collaborateur collaborateur = collaborateurApi.ChercherCollabId(nouvelleNote.Collaborateur.Id);
CheckCollaborateur(collaborateur);
//transformer la note DTO en Note
Note note = DetailsNoteDTOToNouvelleNote(nouvelleNote);
//ajouter la note et sauvegarder
context.Note.Add(note);
context.SaveChanges();
nouvelleNote.Id = note.IdNote;
return nouvelleNote;
}
//
/// Supprimer une note en fonction de son Id de manière async
///
/// Id de la note à supprimer
public void SupprimerNote(long? idNote)
{
Note note = context.Note.Find(idNote);
if (note != null)
{
context.Remove(note);
context.SaveChanges();
}
}
///
/// Récupérer une note en fonction de son id
///
/// Id de la note à récupérer
/// L'objet DTO de la note correspondant à l'id passé en paramètre
public DetailsNoteDTO GetNoteById(long? idNote)
{
Note note = context.Note.Find(idNote);
//vérifier l'existance de la note
if (note == null)
throw new NoteNotFoundException();
//vérifier l'existence de l'auteur
Collaborateur auteur = collaborateurApi.ChercherCollabId(note.IdAuteur);
if (auteur == null)
throw new ReferentNotFoundException("L'auteur de la note n'existe pas");
return NoteToDetailSDTO(note);
}
///
/// Récupérer la liste des notes qu'un auteur a écrit sur un collaborateur
///
/// Id de l'auteur des notes à 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 notes à renvoyer
/// permet de récupérer les notes les informations du collaborateur ou le titre de la note contient le texte
/// Choisir l'attribut par lequel est trié la liste
/// Retour la liste des notes à afficher
public IEnumerable GetNotesByAuteur(Guid? idAuteur, bool? asc, int? numPage, int? parPage, string texte, string tri)
{
Collaborateur auteur = collaborateurApi.ChercherCollabId(idAuteur);
if (auteur == null)
throw new ReferentNotFoundException("L'auteur de la note n'existe pas");
int skip = (numPage.Value - 1) * parPage.Value;
int take = parPage.Value;
//Stopwatch stopwatch = new Stopwatch();
//stopwatch.Start();
/*
* IEnumerable AffichageNoteDTO = (from n in context.Note
where n.IdAuteur == idAuteur
select NoteToAffichageDTO(n));
*/
IEnumerable notes = (from n in context.Note
where n.IdAuteur == idAuteur
select n);
IEnumerable AffichageNoteDTO = (from n in notes
select NoteToAffichageDTO(n));
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.Skip(skip).Take(take);
}
///
/// Récupérer le nombre de notes qu'un auteur a écrit
///
/// Id de l'auteur des notes à récupérer
/// permet de récupérer les notes les informations du collaborateur ou le titre de la note contient le texte
/// Le nombre de notes
public int GetNotesByAuteurCount(Guid? idAuteur, string texte)
{
Collaborateur auteur = collaborateurApi.ChercherCollabId(idAuteur);
if (auteur == null)
throw new ReferentNotFoundException("L'auteur de la note n'existe pas");
IEnumerable notes = (from n in context.Note
where n.IdAuteur == idAuteur
select n);
IEnumerable AffichageNoteDTO = (from n in notes
select NoteToAffichageDTO(n));
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();
}
#endregion
#region Services Async
///
/// Ajouter une nouvelle note dans la base de données de manière async
///
/// La nouvelle note a ajouté en base
/// La nouvelle note ajouté
public async Task AjouterNoteAsync(DetailsNoteDTO nouvelleNote)
{
//vérifier qu'il n'y a aucune valeur null
CheckNoteValide(nouvelleNote);
//vérifier que le référent existe
Collaborateur auteur = await collaborateurApi.ChercherCollabIdAsync((Guid?)nouvelleNote.IdAuteur);
CheckReferent(auteur);
//vérifier que le collaborateur existe
Collaborateur collaborateur = await collaborateurApi.ChercherCollabIdAsync(nouvelleNote.Collaborateur.Id);
CheckCollaborateur(collaborateur);
//transformer la note DTO en Note
Note note = DetailsNoteDTOToNouvelleNote(nouvelleNote);
//ajouter la note et sauvegarder
await context.Note.AddAsync(note);
await context.SaveChangesAsync();
nouvelleNote.Id = note.IdNote;
return nouvelleNote;
}
///
/// Supprimer une note en fonction de son Id de manière async
///
/// Id de la note à supprimer
public async void SupprimerNoteAsync(long? idNote)
{
Note note = await context.Note.FindAsync(idNote);
if (note != null)
{
context.Remove(note);
await context.SaveChangesAsync();
}
}
///
/// Récupérer une note en fonction de son id de manière async
///
/// Id de la note à récupérer
/// L'objet DTO de la note correspondant à l'id passé en paramètre
public async Task GetNoteByIdAsync(long? idNote)
{
Note note = await context.Note.FindAsync(idNote);
//vérifier l'existance de la note
if (note == null)
throw new NoteNotFoundException();
//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 await NoteToDetailSDTOAsync(note);
}
///
/// Récupérer la liste des notes qu'un auteur a écrit sur un collaborateur
///
/// Id de l'auteur des notes à 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 notes à renvoyer
/// permet de récupérer les notes les informations du collaborateur ou le titre de la note contient le texte
/// Choisir l'attribut par lequel est trié la liste
/// Retour la liste des notes à afficher
public async Task> 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");
int skip = (numPage.Value - 1) * parPage.Value;
int take = parPage.Value;
IEnumerable notes = context.Note.Where(n => n.IdAuteur == idAuteur);
var task = notes.Select(n => NoteToAffichageDTOAsync(n));
IEnumerable AffichageNoteDTO = await Task.WhenAll(task);
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.Skip(skip).Take(take);
}
///
/// Récupérer le nombre de notes qu'un auteur a écrit
///
/// Id de l'auteur des notes à récupérer
/// permet de récupérer les notes les informations du collaborateur ou le titre de la note contient le texte
/// Le nombre de notes
public async Task 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 notes = context.Note.Where(n => n.IdAuteur == idAuteur);
var task = notes.Select(n => NoteToAffichageDTOAsync(n));
IEnumerable AffichageNoteDTO = await Task.WhenAll(task);
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();
}
#endregion
/*
#region Services
///
/// Récupérer la liste des notes qu'un auteur a écrit sur un collaborateur
///
/// Id de l'auteur des notes à récupérer
/// Id du collaborateur pour lesquelles les notes ont été écrites
/// 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 notes à renvoyer
/// permet de récupérer les notes les informations du collaborateur ou le titre de la note contient le texte
/// Choisir l'attribut par lequel est trié la liste
/// Retour la liste des notes à afficher
public IEnumerable GetNotesByCollaborateur(Guid? idAuteur, Guid? idCollaborateur, bool? asc, int? numPage, int? parPage, string texte, string tri)
{
//Stopwatch stopwatch = new Stopwatch();
//stopwatch.Start();
if (collaborateurService.GetCollaborateurById(idAuteur) == null)
throw new ReferentNotFoundException();
//stopwatch.Stop();
//Console.WriteLine("Durée d'exécution GetProfil 1: {0}", stopwatch.Elapsed.TotalSeconds);
//stopwatch.Restart();
if (collaborateurService.GetCollaborateurById(idAuteur) == null || collaborateurService.GetCollaborateurById(idCollaborateur) == null)
throw new CollaborateurNotFoundException();
//stopwatch.Stop();
//Console.WriteLine("Durée d'exécution GetProfil 2: {0}", stopwatch.Elapsed.TotalSeconds);
if (texte == null)
texte = "";
else
texte = texte.ToLower();
int skip = (numPage.Value - 1) * parPage.Value;
int take = parPage.Value;
IEnumerable AffichageNoteDTO = (from n in context.Note
where n.IdAuteur == idAuteur && n.IdCollaborateur == idCollaborateur
select NoteToAffichageDTO(n, collaborateurService));
AffichageNoteDTO = (from a in AffichageNoteDTO
where a.Titre.ToLower().Contains(texte)
select a).Skip(skip).Take(take);
return AffichageNoteDTO;
}
///
/// Récupérer une note en fonction de son id
///
/// Id de la note à récupérer
/// L'objet DTO de la note correspondant à l'id passé en paramètre
public DetailsNoteDTO GetNoteById(long? idNote)
{
Note note = context.Note.Find(idNote);
if (note == null)
throw new NoteNotFoundException();
return NoteToDetailSDTO(note);
}
public IEnumerable GetNotes(bool? asc, int? numPage, int? parPage, string texte, string tri)
{
throw new NotImplementedException();
}
///
/// Récupérer la liste des notes qu'un auteur a écrit sur un collaborateur
///
/// Id de l'auteur des notes à 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 notes à renvoyer
/// permet de récupérer les notes les informations du collaborateur ou le titre de la note contient le texte
/// Choisir l'attribut par lequel est trié la liste
/// Retour la liste des notes à afficher
public IEnumerable GetNotesByAuteur(Guid? idAuteur, bool? asc, int? numPage, int? parPage, string texte, string tri)
{
if (collaborateurService.GetCollaborateurById(idAuteur) == null)
throw new CollaborateurNotFoundException();
if (texte == null)
texte = "";
else
texte = texte.ToLower();
int skip = (numPage.Value - 1) * parPage.Value;
int take = parPage.Value;
//Stopwatch stopwatch = new Stopwatch();
//stopwatch.Start();
IEnumerable AffichageNoteDTO = (from n in context.Note
where n.IdAuteur == idAuteur
select NoteToAffichageDTO(n, collaborateurService));
//stopwatch.Stop();
//Console.WriteLine("Durée d'exécution numéro 1: {0}", stopwatch.Elapsed.TotalSeconds);
//stopwatch.Restart();
AffichageNoteDTO = (from a in AffichageNoteDTO
where a.Collaborateur.ToLower().Contains(texte) || a.Titre.ToLower().Contains(texte)
select a).Skip(skip).Take(take);
//stopwatch.Stop();
//Console.WriteLine("Durée d'exécution numéro 2: {0}", stopwatch.Elapsed.TotalSeconds);
return AffichageNoteDTO;
}
///
/// Supprimer une note en fonction de son Id
///
/// Id de la note à supprimer
/// Si oui ou non la notea bien été supprimé
public void SupprimerNote(long? idNote)
{
Note note = context.Note.Find(idNote);
if (note == null)
throw new NoteNotFoundException();
context.Remove(note);
context.SaveChanges();
}
///
/// Mettre à jour une note
///
/// Id de la note à modifier
///
///
public DetailsNoteDTO UpdateNote(long? idNote, DetailsNoteDTO note)
{
if (idNote != note.Id)
throw new NoteIdImcompatibleException();
if (!CheckNoteValide(note))
throw new NoteInvalideException();
Note noteToUpdate = context.Note.Find(idNote);
noteToUpdate.Titre = note.Titre;
noteToUpdate.Texte = note.Texte;
noteToUpdate.DateMiseAJour = DateTime.Now;
context.SaveChanges();
return NoteToDetailSDTO(noteToUpdate);
}
///
/// Vérifier si un objet DetailsNoteDTO possède est valide pour ajout ou mise à jour
///
/// Un objet DetailsNoteDTO est valide si aucune de ses propriétés n'est à null
///
/// true si l'objet est valide, false sinon
private bool CheckNoteValide(DetailsNoteDTO note)
{
return !(note == null || note.IdAuteur == null || note.Collaborateur == null || note.Collaborateur.Id == null || note.Titre == null || note.Texte == null) ;
}
#endregion
*/
#region fonctions privees
///
/// Vérfier si la note est valide
///
/// La note a vérifié
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");
}
///
/// Vérifier que l'auteur de la note existe et est toujours présent dans l'entreprise
///
/// L'auteur de la note
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");
}
///
/// Vérifier que le collaborateur concerné par la note existe et est toujorus présent dans l'entreprise
///
/// Le collaborateur concerné
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 note si vous avez quitté l'entreprise");
}
#endregion
#region ObjectToDTO
///
/// Transformer un objet note en objet pour afficher un note dans dans un tableau
///
/// Note à transformer
/// Service collaborateur pour récupérer les informations des collaborateurs
/// La note transformée pour être affichée
private AffichageNoteDTO NoteToAffichageDTO(Note note)
{
/*
string infoCollab = "Aucun collaborateur lié";
Collaborateur collaborateur = collaborateurApi.ChercherCollabId((Guid?)note.IdCollaborateur);
if (collaborateur != null)
infoCollab = collaborateur.Prenom + collaborateur.Nom;
*/
AffichageNoteDTO affichage = new AffichageNoteDTO()
{
Id = note.IdNote,
IdCollaborateur = note.IdCollaborateur,
Collaborateur = "ui",
Titre = note.Titre,
DateMiseAJour = note.DateMiseAJour
};
return affichage;
}
///
/// Transformer un objet note en objet pour afficher un note dans dans un tableau
///
/// Note à transformer
/// Service collaborateur pour récupérer les informations des collaborateurs
/// La note transformée pour être affichée
private async Task NoteToAffichageDTOAsync(Note note)
{
string infoCollab = "Aucun collaborateur lié";
Collaborateur collaborateur = await collaborateurApi.ChercherCollabIdAsync((Guid?)note.IdCollaborateur);
if (collaborateur != null)
infoCollab = collaborateur.Prenom + " " + collaborateur.Nom;
AffichageNoteDTO affichage = new AffichageNoteDTO()
{
Id = note.IdNote,
IdCollaborateur = note.IdCollaborateur,
Collaborateur = infoCollab,
Titre = note.Titre,
DateMiseAJour = note.DateMiseAJour
};
return affichage;
}
///
/// Transformatino d'une note en DetailsNoteDTO
///
/// Note à transformer
/// Note transformer en DetailsNoteDTO
private DetailsNoteDTO NoteToDetailSDTO(Note note)
{
CollaborateurDTO collaborateur = collaborateurService.GetCollaborateurById(note.IdCollaborateur);
if (collaborateur == null)
throw new CollaborateurNotFoundException("Il est impossible de récupérer une note dont le collaborateur n'existe plus");
DetailsNoteDTO details = new DetailsNoteDTO()
{
Id = note.IdNote,
DateCreation = note.DateCreation,
DateMiseAjour = note.DateMiseAJour,
Titre = note.Titre,
Texte = note.Texte,
IdAuteur = note.IdAuteur,
Collaborateur = collaborateur,
};
return details;
}
///
/// Transformatino d'une note en DetailsNoteDTO de manière asynchrone
///
/// Note à transformer
/// Note transformer en DetailsNoteDTO
private async Task NoteToDetailSDTOAsync(Note note)
{
CollaborateurDTO collaborateur = await collaborateurService.GetCollaborateurByIdAsync(note.IdCollaborateur);
if (collaborateur == null)
throw new CollaborateurNotFoundException("Il est impossible de récupérer une note donc le collaborateur n'existe plus");
DetailsNoteDTO details = new DetailsNoteDTO()
{
Id = note.IdNote,
DateCreation = note.DateCreation,
DateMiseAjour = note.DateMiseAJour,
Titre = note.Titre,
Texte = note.Texte,
IdAuteur = note.IdAuteur,
Collaborateur = collaborateur,
};
return details;
}
#endregion
#region DTOToObject
///
/// Transformer l'objet DTO d'une note en note
///
/// En général, de base, cette méthode est prévue pour être utilisée qu'à la création d'une nouvelle note, dateCreation et dateUpdate sont donc initialisée à ce moment là
/// Objet DTO à transformer en note
/// L'objet DTO transformé en note
private Note DetailsNoteDTOToNouvelleNote(DetailsNoteDTO detailsNoteDTO)
{
Note note = new Note()
{
IdAuteur = detailsNoteDTO.IdAuteur.Value,
IdCollaborateur = detailsNoteDTO.Collaborateur.Id.Value,
Texte = detailsNoteDTO.Texte,
Titre = detailsNoteDTO.Titre,
DateCreation = DateTime.Now,
DateMiseAJour = DateTime.Now
};
return note;
}
#endregion
}
}