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; /// /// Accès au service permettant de transformer un modèle en dto /// 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 /// /// 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); List guids = new List(); guids.AddRange(new Guid?[]{nouvelleNote.IdAuteur, nouvelleNote.Collaborateur.Id}); IEnumerable 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; } /// /// Supprimer une note en fonction de son Id de manière async /// /// Id de la note à supprimer public async Task 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; } /// /// 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("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)); } /// /// 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"); IEnumerable notes = context.Note.Where(n => n.IdAuteur == idAuteur); List guids = notes.Select(n => (Guid?)n.IdCollaborateur).ToList(); IEnumerable collaborateurs = await collaborateurApi.ChercherCollabAsync(guids); IEnumerable 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); } /// /// 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); List guids = notes.Select(n => (Guid?)n.IdCollaborateur).ToList(); IEnumerable collaborateurs = await collaborateurApi.ChercherCollabAsync(guids); IEnumerable 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(); } /// /// Mettre à jour une note /// /// Id de la note à modifier /// Note avec les informations à jour /// La note mise à jour public async Task 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 /// /// 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"); } private IEnumerable Tri(IEnumerable 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, }; } /// /// 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 notes pour un collaborateur qui a quitté l'entreprise"); } #endregion } }