diff --git a/ldap-cesi/Configurations/Conf.cs b/ldap-cesi/Configurations/Conf.cs index 32e91c3..fa10ddd 100644 --- a/ldap-cesi/Configurations/Conf.cs +++ b/ldap-cesi/Configurations/Conf.cs @@ -1,6 +1,8 @@ using System.Reflection; using System.Security.Cryptography; using System.Text; +using FluentValidation; +using FluentValidation.AspNetCore; using ldap_cesi.Context; using ldap_cesi.Repository; using ldap_cesi.Repository.Services; @@ -42,12 +44,14 @@ public static class Conf public static void AddServices(this WebApplicationBuilder builder) { builder.Services.AddScoped(); - // builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddSingleton(); + builder.Services.AddValidatorsFromAssemblyContaining(); + builder.Services.AddFluentValidationAutoValidation(); } public static void AddEFCoreConfiguration(this WebApplicationBuilder builder) { diff --git a/ldap-cesi/Controllers/RoleController.cs b/ldap-cesi/Controllers/RoleController.cs new file mode 100644 index 0000000..d865d03 --- /dev/null +++ b/ldap-cesi/Controllers/RoleController.cs @@ -0,0 +1,88 @@ +using Microsoft.AspNetCore.Mvc; +using ldap_cesi.DTOs.Inputs.Role; +using ldap_cesi.Services.Interfaces; +using Microsoft.AspNetCore.Authorization; + +namespace ldap_cesi.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class RoleController : ControllerBase + { + private readonly IRoleService _roleService; + + public RoleController(IRoleService roleService) + { + _roleService = roleService; + } + + // GET: api/Role + /// + /// Endpoint qui retourne tous les rôles + /// + /// Un tableau de rôle + [HttpGet] + [Authorize(Roles = "admin")] + public async Task GetAllRoles() + { + var result = await _roleService.GetAll(); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); + } + + // GET: api/Role/{id} + /// + /// Endpoint qui retourne le role + /// + /// L'id du rôle. + /// Le role update + [HttpGet("{id}")] + [Authorize(Roles = "admin")] + public async Task GetRoleById(int id) + { + var result = await _roleService.GetById(id); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); + } + + // POST: api/Role + /// + /// Endpoint créer le Role + /// + /// Le nom du rôle. + /// Response. + [HttpPost] + [Authorize(Roles = "admin")] + public async Task CreateRole([FromBody] RoleCreateDto roleDto) + { + var result = await _roleService.Create(roleDto); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); + } + + // PUT: api/Role + /// + /// Endpoint qui met à jour un role. + /// + /// Les informations du role à mettre à jour. Id, nom + /// Le role mis à jour. + [HttpPut] + [Authorize(Roles = "admin")] + public async Task UpdateRole([FromBody] RoleUpdateDto roleDto) + { + var result = await _roleService.Update(roleDto); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); + } + + // DELETE: api/Role/{id} + /// + /// Endpoint qui supprime un rôle. + /// + /// L'ID du rôle à supprimer. + /// Un message de confirmation de suppression. + [HttpDelete("{id}")] + [Authorize(Roles = "admin")] + public async Task DeleteRole(int id) + { + var result = await _roleService.Delete(id); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); + } + } +} diff --git a/ldap-cesi/Controllers/SalarieController.cs b/ldap-cesi/Controllers/SalarieController.cs index 63d9120..6873f7c 100644 --- a/ldap-cesi/Controllers/SalarieController.cs +++ b/ldap-cesi/Controllers/SalarieController.cs @@ -16,7 +16,7 @@ public class SalarieController : ControllerBase _salarieService = salarieService; } - /// + /// /// Endpoint qui retourne tous les salariés. /// /// Une liste de salariés. @@ -25,6 +25,17 @@ public class SalarieController : ControllerBase { var result = await _salarieService.GetAll(); return result.Success ? Ok(result.Data) : BadRequest(result.Message); + } + + /// + /// Endpoint qui retourne tous les salariés. + /// + /// Une liste de salariés. + [HttpGet("/complete")] + public async Task GetAllSalariesComplet() + { + var result = await _salarieService.GetAllWithoutIService(); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); } /// @@ -33,7 +44,7 @@ public class SalarieController : ControllerBase /// L'ID du salarié. /// Le salarié correspondant à l'ID. [HttpGet("{id}")] - public async Task GetSalarieById(int id) + public async Task GetById(int id) { var result = await _salarieService.GetById(id); return result.Success ? Ok(result.Data) : BadRequest(result.Message); @@ -49,6 +60,17 @@ public class SalarieController : ControllerBase { var result = await _salarieService.GetCompletById(id); return result.Success ? Ok(result.Data) : BadRequest(result.Message); + } + + /// + /// Endpoint qui retourne tout les salariés et les relations qu'il détient + /// + /// Tous les salariés avec leurs relations + [HttpGet("all")] + public async Task GetAllSariesWithRelations() + { + var result = await _salarieService.GetAllWithRelationsAsync(s => s.IdServiceNavigation, s => s.IdSiteNavigation); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); } /// diff --git a/ldap-cesi/Controllers/ServicesController.cs b/ldap-cesi/Controllers/ServicesController.cs index d9c3c84..8f2ec66 100644 --- a/ldap-cesi/Controllers/ServicesController.cs +++ b/ldap-cesi/Controllers/ServicesController.cs @@ -21,7 +21,6 @@ public class ServicesController : ControllerBase /// /// Retourne tous les services. [HttpGet] - [Authorize(Roles = "admin")] public async Task GetServices() { var result = await _serviceService.GetAll(); @@ -34,7 +33,6 @@ public class ServicesController : ControllerBase /// L'ID du service. /// Le service correspondant à l'ID. [HttpGet("{id}")] - [Authorize(Roles = "admin")] public async Task GetServiceById(int id) { var result = await _serviceService.GetById(id); @@ -50,7 +48,7 @@ public class ServicesController : ControllerBase [Authorize(Roles = "admin")] public async Task CreateService([FromBody] ServiceCreateDto serviceInputDto) { - var result = await _serviceService.CreateService(serviceInputDto); + var result = await _serviceService.Create(serviceInputDto); return result.Success ? Ok(result.Data) : BadRequest(result.Message); } @@ -63,7 +61,7 @@ public class ServicesController : ControllerBase [Authorize(Roles = "admin")] public async Task UpdateService([FromBody] ServiceUpdateDto serviceUpdateDto) { - var result = await _serviceService.UpdateService(serviceUpdateDto); + var result = await _serviceService.Update(serviceUpdateDto); return result.Success ? Ok(result.Data) : BadRequest(result.Message); } @@ -76,7 +74,7 @@ public class ServicesController : ControllerBase [Authorize(Roles = "admin")] public async Task DeleteService(int id) { - var result = await _serviceService.DeleteService(id); + var result = await _serviceService.Delete(id); return result.Success ? Ok(result.Message) : BadRequest(result.Message); } } \ No newline at end of file diff --git a/ldap-cesi/DTOs/Generic/RoleDto.cs b/ldap-cesi/DTOs/Generic/RoleDto.cs new file mode 100644 index 0000000..3465bd6 --- /dev/null +++ b/ldap-cesi/DTOs/Generic/RoleDto.cs @@ -0,0 +1,8 @@ +namespace ldap_cesi.DTOs; + +public class RoleDto +{ + public int Id { get; set; } + + public string Nom { get; set; } +} \ No newline at end of file diff --git a/ldap-cesi/DTOs/Generic/SalarieDto.cs b/ldap-cesi/DTOs/Generic/SalarieDto.cs new file mode 100644 index 0000000..542bd7c --- /dev/null +++ b/ldap-cesi/DTOs/Generic/SalarieDto.cs @@ -0,0 +1,19 @@ +namespace ldap_cesi.DTOs; + +public class SalarieDto +{ + public int Id { get; set; } + + public string Nom { get; set; } = null!; + + public string Prenom { get; set; } = null!; + + public string TelephoneFixe { get; set; } = null!; + + public string TelephonePortable { get; set; } = null!; + + public string Email { get; set; } = null!; + + public ServiceDto Service { get; set; } + public SiteDto Site { get; set; } +} \ No newline at end of file diff --git a/ldap-cesi/DTOs/Inputs/Role/RoleCreateDto.cs b/ldap-cesi/DTOs/Inputs/Role/RoleCreateDto.cs new file mode 100644 index 0000000..e11af07 --- /dev/null +++ b/ldap-cesi/DTOs/Inputs/Role/RoleCreateDto.cs @@ -0,0 +1,7 @@ + +namespace ldap_cesi.DTOs.Inputs.Role; + +public class RoleCreateDto +{ + public string Nom { get; set; } +} \ No newline at end of file diff --git a/ldap-cesi/DTOs/Inputs/Role/RoleUpdateDto.cs b/ldap-cesi/DTOs/Inputs/Role/RoleUpdateDto.cs new file mode 100644 index 0000000..c7b5b00 --- /dev/null +++ b/ldap-cesi/DTOs/Inputs/Role/RoleUpdateDto.cs @@ -0,0 +1,7 @@ +namespace ldap_cesi.DTOs.Inputs.Role; + +public class RoleUpdateDto +{ + public int Id { get; set; } + public string Nom { get; set; } +} \ No newline at end of file diff --git a/ldap-cesi/Mapper/AutoMapperProfile.cs b/ldap-cesi/Mapper/AutoMapperProfile.cs index 8d3924e..9d159bf 100644 --- a/ldap-cesi/Mapper/AutoMapperProfile.cs +++ b/ldap-cesi/Mapper/AutoMapperProfile.cs @@ -1,5 +1,6 @@ using AutoMapper; using ldap_cesi.DTOs; +using ldap_cesi.DTOs.Inputs.Role; using ldap_cesi.DTOs.Inputs.Salarie; using ldap_cesi.DTOs.Inputs.Service; using ldap_cesi.DTOs.Inputs.Site; @@ -17,6 +18,7 @@ public class AutoMapperProfile : Profile CreateMap(); CreateMap(); CreateMap(); + CreateMap(); CreateMap(); CreateMap() .ForMember(dest => dest.TelephoneFixe, opt => opt.MapFrom(src => src.TelephoneFix)) @@ -29,14 +31,14 @@ public class AutoMapperProfile : Profile //OUTPUTS MAPPER CreateMap() .ForMember(dest => dest.RoleNom, opt => opt.MapFrom(src => src.IdRoleNavigation.Nom)); - CreateMap() + CreateMap() .ForMember(dest => dest.Service, opt => opt.MapFrom(src => src.IdServiceNavigation)) .ForMember(dest => dest.Site, opt => opt.MapFrom(src => src.IdSiteNavigation)); + CreateMap(); + CreateMap(); + CreateMap(); CreateMap() .ForMember(dest => dest.Service, opt => opt.MapFrom(src => src.IdServiceNavigation.Nom)) .ForMember(dest => dest.Site, opt => opt.MapFrom(src => src.IdSiteNavigation.Ville)); - CreateMap(); - CreateMap(); - CreateMap(); } } \ No newline at end of file diff --git a/ldap-cesi/Repositories/Interfaces/IRepositoryBase.cs b/ldap-cesi/Repositories/Interfaces/IRepositoryBase.cs index 1daf9fb..223565b 100644 --- a/ldap-cesi/Repositories/Interfaces/IRepositoryBase.cs +++ b/ldap-cesi/Repositories/Interfaces/IRepositoryBase.cs @@ -10,6 +10,8 @@ public interface IRepositoryBase where TEntity : class Task> GetAllAsync(CancellationToken cancellationToken = default); Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default); Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default); + Task GetWithRelationsAsync(int id, params Expression>[] relationsAInclude); + Task> GetAllWithRelationsAsync(params Expression>[] relationsAInclude); Task FirstOrDefaultAsync(Expression> predicate, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/ldap-cesi/Repositories/RepositoryBase.cs b/ldap-cesi/Repositories/RepositoryBase.cs index 3253321..d7fc138 100644 --- a/ldap-cesi/Repositories/RepositoryBase.cs +++ b/ldap-cesi/Repositories/RepositoryBase.cs @@ -9,10 +9,11 @@ namespace ldap_cesi.Repository; public class RepositoryBase : IRepositoryBase where TEntity : class { protected readonly PgContext _context; - + protected readonly DbSet _dbSet; public RepositoryBase(PgContext context) { _context = context ?? throw new ArgumentNullException(nameof(context)); + _dbSet = context.Set(); } public virtual async Task AddAsync(TEntity entity, CancellationToken cancellationToken = default) { @@ -113,5 +114,28 @@ public class RepositoryBase : IRepositoryBase where TEntity : throw new Exception("Erreur qui concerne le listing des entités", ex); } } + public virtual async Task> GetAllWithRelationsAsync(params Expression>[] relationInclues) + { + IQueryable query = _dbSet; + + foreach (var relationInclue in relationInclues) + { + query = query.Include(relationInclue); + } + + return await query.ToListAsync(); + } + + public virtual async Task GetWithRelationsAsync(int id, params Expression>[] relationInclues) + { + IQueryable query = _dbSet; + + foreach (var relationInclue in relationInclues) + { + query = query.Include(relationInclue); + } + + return await query.FirstOrDefaultAsync(e => EF.Property(e, "Id") == id); + } } \ No newline at end of file diff --git a/ldap-cesi/Services/Interfaces/IRoleService.cs b/ldap-cesi/Services/Interfaces/IRoleService.cs index b558e3b..41e1c2a 100644 --- a/ldap-cesi/Services/Interfaces/IRoleService.cs +++ b/ldap-cesi/Services/Interfaces/IRoleService.cs @@ -1,6 +1,10 @@ -namespace ldap_cesi.Services.Interfaces; +using ldap_cesi.Entities; +using ldap_cesi.DTOs; +using ldap_cesi.DTOs.Inputs.Role; -public interface IRoleService +namespace ldap_cesi.Services.Interfaces { - + public interface IRoleService : IServiceBase + { + } } \ No newline at end of file diff --git a/ldap-cesi/Services/Interfaces/ISalarieService.cs b/ldap-cesi/Services/Interfaces/ISalarieService.cs index 5318fa7..af59cd0 100644 --- a/ldap-cesi/Services/Interfaces/ISalarieService.cs +++ b/ldap-cesi/Services/Interfaces/ISalarieService.cs @@ -1,3 +1,4 @@ +using ldap_cesi.DTOs; using ldap_cesi.DTOs.Inputs.Salarie; using ldap_cesi.DTOs.Inputs.Service; using ldap_cesi.DTOs.Outputs.Salarie; @@ -6,14 +7,10 @@ using ldap_cesi.Models; namespace ldap_cesi.Services.Interfaces; -public interface ISalarieService +public interface ISalarieService : IServiceBase { - Task>> GetAll(); - Task> GetById(int id); + Task>> GetAllWithoutIService(); Task>> GetSalariesBySite(int siteId); Task>> GetSalariesByService(int serviceId); - Task> Create(SalarieCreateDto salarieInput); - Task> Update(SalarieUpdateDto salarieInput); - Task> Delete(int id); - Task> GetCompletById(int id); + Task> GetCompletById(int id); } \ No newline at end of file diff --git a/ldap-cesi/Services/Interfaces/IServiceBase.cs b/ldap-cesi/Services/Interfaces/IServiceBase.cs new file mode 100644 index 0000000..a28d769 --- /dev/null +++ b/ldap-cesi/Services/Interfaces/IServiceBase.cs @@ -0,0 +1,19 @@ +using System.Linq.Expressions; +using ldap_cesi.Models; + +namespace ldap_cesi.Services.Interfaces; + +public interface IServiceBase + where T : class + where TDto : class + where TCreateDto : class + where TUpdateDto : class +{ + Task>> GetAll(); + Task> GetById(int id); + Task> GetByIdWithRelations(int id, params Expression>[] relationsAInclures); // préciser avec une ou des fonctions lambda les relations à inclure dans la réponse + Task>> GetAllWithRelationsAsync(params Expression>[] relationsAInclure); + Task> Create(TCreateDto dto); + Task> Update(TUpdateDto dto); + Task> Delete(int id); +} \ No newline at end of file diff --git a/ldap-cesi/Services/Interfaces/IServiceService.cs b/ldap-cesi/Services/Interfaces/IServiceService.cs index 4247928..4cd3a7c 100644 --- a/ldap-cesi/Services/Interfaces/IServiceService.cs +++ b/ldap-cesi/Services/Interfaces/IServiceService.cs @@ -1,14 +1,11 @@ using ldap_cesi.DTOs.Inputs.Service; +using ldap_cesi.DTOs; using ldap_cesi.Entities; using ldap_cesi.Models; -namespace ldap_cesi.Services.Interfaces; - -public interface IServiceService +namespace ldap_cesi.Services.Interfaces { - Task>> GetAll(); - Task> GetById(int id); - Task> CreateService(ServiceCreateDto serviceCreateDto); - Task> UpdateService(ServiceUpdateDto serviceUpdateDto); - Task> DeleteService(int id); -} \ No newline at end of file + public interface IServiceService : IServiceBase + { + } +} diff --git a/ldap-cesi/Services/JwtService.cs b/ldap-cesi/Services/JwtService.cs index 085d41e..8ef0ec2 100644 --- a/ldap-cesi/Services/JwtService.cs +++ b/ldap-cesi/Services/JwtService.cs @@ -60,7 +60,7 @@ public class JwtService : IJwtService } catch (Exception ex) { - _logger.LogError(ex, "An error occurred while generating the JWT token."); + _logger.LogError(ex, "Une erreur s'est produitel lors de la génération du token."); throw; } } @@ -74,7 +74,7 @@ public class JwtService : IJwtService } catch (Exception ex) { - _logger.LogError(ex, "An error occurred while retrieving the public key."); + _logger.LogError(ex, "Une erreur s'est produite pendant la récupération de la clé."); throw; } } @@ -100,14 +100,14 @@ public class JwtService : IJwtService var nameIdClaim = principal.FindFirst(ClaimTypes.NameIdentifier); if (nameIdClaim == null || !int.TryParse(nameIdClaim.Value, out var tokenUserId) || tokenUserId != userId) { - _logger.LogWarning("Token validation failed: Invalid user ID."); + _logger.LogWarning("Erreur de validation : Id utilisateur invalide."); return false; } var utilisateur = await _context.Utilisateurs.FindAsync(userId); if (utilisateur == null) { - _logger.LogWarning("Token validation failed: User not found."); + _logger.LogWarning("Erreur de validation : Utilisateur non trouvé."); return false; } @@ -119,7 +119,7 @@ public class JwtService : IJwtService } catch (Exception ex) { - _logger.LogError(ex, "An error occurred while validating the JWT token."); + _logger.LogError(ex, "Une erreur s'est produite lors pendant la validation du token JWT."); return false; } } diff --git a/ldap-cesi/Services/RoleService.cs b/ldap-cesi/Services/RoleService.cs index b388bae..c6e44df 100644 --- a/ldap-cesi/Services/RoleService.cs +++ b/ldap-cesi/Services/RoleService.cs @@ -1,15 +1,17 @@ using ldap_cesi.Repository.Services; using ldap_cesi.Services.Interfaces; +using ldap_cesi.Entities; +using ldap_cesi.DTOs; +using ldap_cesi.DTOs.Inputs.Role; +using AutoMapper; +using ldap_cesi.Validator.Role; namespace ldap_cesi.Services; -public class RoleService : IRoleService +public class RoleService : ServiceBase,IRoleService { - private IRepositoryRole _repositoryRole; - - public RoleService(IRepositoryRole repositoryRole) + public RoleService(IRepositoryRole repositoryRole, IMapper mapper, ILogger logger, RoleCreateValidator roleCreateValidator, RoleUpdateValidator roleUpdateValidator) + : base(repositoryRole, mapper, logger, roleCreateValidator, roleUpdateValidator) { - _repositoryRole = repositoryRole; } - } \ No newline at end of file diff --git a/ldap-cesi/Services/SalarieService.cs b/ldap-cesi/Services/SalarieService.cs index 69c8108..40a28b7 100644 --- a/ldap-cesi/Services/SalarieService.cs +++ b/ldap-cesi/Services/SalarieService.cs @@ -1,4 +1,5 @@ using AutoMapper; +using ldap_cesi.DTOs; using ldap_cesi.DTOs.Inputs.Salarie; using ldap_cesi.DTOs.Inputs.Service; using ldap_cesi.DTOs.Outputs.Salarie; @@ -10,14 +11,16 @@ using ldap_cesi.Validator.Salarie; namespace ldap_cesi.Services; -public class SalarieService : ISalarieService +public class SalarieService : ServiceBase, ISalarieService { private IRepositorySalarie _repositorySalarie; private readonly IRepositorySite _repositorySite; private readonly IRepositoryService _repositoryService; private readonly IMapper _mapper; - public SalarieService(IRepositorySalarie repositorySalarie, IMapper mapper, IRepositorySite repositorySite, IRepositoryService repositoryService) + public SalarieService(IRepositorySalarie repositorySalarie, IMapper mapper, IRepositorySite repositorySite, IRepositoryService repositoryService, + ILogger logger, SalarieCreateValidator salarieCreateValidator, SalarieUpdateValidator salarieUpdateValidator) + : base(repositorySalarie, mapper, logger, salarieCreateValidator, salarieUpdateValidator) { _repositorySalarie = repositorySalarie; _repositorySite = repositorySite; @@ -25,7 +28,7 @@ public class SalarieService : ISalarieService _mapper = mapper; } - public async Task>> GetAll() + public async Task>> GetAllWithoutIService() { var salaries = await _repositorySalarie.GetAllAsync(); return new ResponseDataModel> @@ -36,22 +39,22 @@ public class SalarieService : ISalarieService }; } - public async Task> GetById(int id) - { - var salarie = await _repositorySalarie.GetSalarieWithRelationsAsync(id); - return new ResponseDataModel - { - Success = true, - Data = salarie, - StatusCode = 200, - }; - } + // public async Task> GetById(int id) + // { + // var salarie = await _repositorySalarie.GetSalarieWithRelationsAsync(id); + // return new ResponseDataModel + // { + // Success = true, + // Data = salarie, + // StatusCode = 200, + // }; + // } - public async Task> GetCompletById(int id) + public async Task> GetCompletById(int id) { var salarie = await _repositorySalarie.GetSalarieWithRelationsAsync(id); - var salarieOutput = _mapper.Map(salarie); - return new ResponseDataModel + var salarieOutput = _mapper.Map(salarie); + return new ResponseDataModel { Success = true, Data = salarieOutput, @@ -131,109 +134,109 @@ public class SalarieService : ISalarieService }; } - public async Task> Create(SalarieCreateDto salarieInput) - { - var validation = new SalarieCreateValidator(); - var result = validation.Validate(salarieInput); - if (!result.IsValid) - { - return new ResponseDataModel - { - StatusCode = 400, - Success = false, - Message = "Données salariées invalides: " + string.Join(", ", result.Errors) - }; - } - var service = _mapper.Map(salarieInput); - var response = await _repositorySalarie.AddAsync(service); - return new ResponseDataModel - { - StatusCode = 201, - Success = true, - Data = response.Id.ToString(), - }; - } + // public async Task> Create(SalarieCreateDto salarieInput) + // { + // var validation = new SalarieCreateValidator(); + // var result = validation.Validate(salarieInput); + // if (!result.IsValid) + // { + // return new ResponseDataModel + // { + // StatusCode = 400, + // Success = false, + // Message = "Données salariées invalides: " + string.Join(", ", result.Errors) + // }; + // } + // var service = _mapper.Map(salarieInput); + // var response = await _repositorySalarie.AddAsync(service); + // return new ResponseDataModel + // { + // StatusCode = 201, + // Success = true, + // Data = response.Id.ToString(), + // }; + // } - public async Task> Update(SalarieUpdateDto salarieInput) - { - var validation = new SalarieUpdateValidator(); - var result = validation.Validate(salarieInput); - if (!result.IsValid) - { - return new ResponseDataModel - { - StatusCode = 400, - Success = false, - Message = "Données salariées invalides: " + string.Join(", ", result.Errors) - }; - } + // public async Task> Update(SalarieUpdateDto salarieInput) + // { + // var validation = new SalarieUpdateValidator(); + // var result = validation.Validate(salarieInput); + // if (!result.IsValid) + // { + // return new ResponseDataModel + // { + // StatusCode = 400, + // Success = false, + // Message = "Données salariées invalides: " + string.Join(", ", result.Errors) + // }; + // } - var salarieFind = await _repositorySalarie.GetByIdAsync(salarieInput.Id); - if (salarieFind == null) - { - return new ResponseDataModel - { - Success = false, - Message = "Salarié introuvable.", - StatusCode = 404 - }; - } + // var salarieFind = await _repositorySalarie.GetByIdAsync(salarieInput.Id); + // if (salarieFind == null) + // { + // return new ResponseDataModel + // { + // Success = false, + // Message = "Salarié introuvable.", + // StatusCode = 404 + // }; + // } - var salarie = _mapper.Map(salarieInput, salarieFind); - var response = await _repositorySalarie.UpdateAsync(salarie); - if (!response) - { - return new ResponseDataModel - { - StatusCode = 500, - Success = false, - Message = "Erreur lors de la mise à jour du salarié : " + string.Join(", ", result.Errors) - }; - } - return new ResponseDataModel - { - StatusCode = 200, - Success = true, - Data = salarie, - }; - } + // var salarie = _mapper.Map(salarieInput, salarieFind); + // var response = await _repositorySalarie.UpdateAsync(salarie); + // if (!response) + // { + // return new ResponseDataModel + // { + // StatusCode = 500, + // Success = false, + // Message = "Erreur lors de la mise à jour du salarié : " + string.Join(", ", result.Errors) + // }; + // } + // return new ResponseDataModel + // { + // StatusCode = 200, + // Success = true, + // Data = salarie, + // }; + // } - public async Task> Delete(int id) - { - if (id == null) - { - return new ResponseDataModel - { - StatusCode = 400, - Success = false, - Message = "Id manquant" - }; - } - var salarie = await _repositorySalarie.GetByIdAsync(id); - if (salarie == null) - { - return new ResponseDataModel - { - Success = false, - Message = "Salarié introuvable.", - StatusCode = 404 - }; - } - var response = await _repositorySalarie.DeleteAsync(salarie); - if (!response) - { - return new ResponseDataModel - { - StatusCode = 500, - Success = false, - Message = "Erreur durant la suppression du service" - }; - } - return new ResponseDataModel - { - StatusCode = 200, - Success = true, - Data = salarie.Id.ToString(), - }; - } + // public async Task> Delete(int id) + // { + // if (id == null) + // { + // return new ResponseDataModel + // { + // StatusCode = 400, + // Success = false, + // Message = "Id manquant" + // }; + // } + // var salarie = await _repositorySalarie.GetByIdAsync(id); + // if (salarie == null) + // { + // return new ResponseDataModel + // { + // Success = false, + // Message = "Salarié introuvable.", + // StatusCode = 404 + // }; + // } + // var response = await _repositorySalarie.DeleteAsync(salarie); + // if (!response) + // { + // return new ResponseDataModel + // { + // StatusCode = 500, + // Success = false, + // Message = "Erreur durant la suppression du service" + // }; + // } + // return new ResponseDataModel + // { + // StatusCode = 200, + // Success = true, + // Data = salarie.Id.ToString(), + // }; + // } } \ No newline at end of file diff --git a/ldap-cesi/Services/ServiceBase.cs b/ldap-cesi/Services/ServiceBase.cs new file mode 100644 index 0000000..c8e444a --- /dev/null +++ b/ldap-cesi/Services/ServiceBase.cs @@ -0,0 +1,266 @@ +using AutoMapper; +using ldap_cesi.DTOs.Inputs.Site; +using ldap_cesi.Entities; +using ldap_cesi.Models; +using ldap_cesi.Repository.Services; +using ldap_cesi.Services.Interfaces; +using ldap_cesi.Validator.Site; +using Microsoft.Extensions.Logging; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Threading.Tasks; +using FluentValidation; + +namespace ldap_cesi.Services; + +public class ServiceBase : IServiceBase + where T : class + where TDto : class + where TCreateDto : class + where TUpdateDto : class +{ + protected readonly IRepositoryBase _repository; + protected readonly IMapper _mapper; + protected readonly ILogger> _logger; + protected readonly IValidator _createDtoValidator; + protected readonly IValidator _updateDtoValidator; + + public ServiceBase(IRepositoryBase repository, IMapper mapper, ILogger> logger, IValidator createDtoValidator, IValidator updateDtoValidator) + { + _repository = repository; + _mapper = mapper; + _logger = logger; + _createDtoValidator = createDtoValidator; + _updateDtoValidator = updateDtoValidator; + } + + public virtual async Task>> GetAll() + { + try + { + var entities = await _repository.GetAllAsync(); + return new ResponseDataModel> + { + Success = true, + Data = entities, + StatusCode = 200, + Message = "Liste des entités récupérée avec succès." + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Une erreur s'est produite lors de la récupération des entités."); + return new ResponseDataModel> + { + Success = false, + Message = "Une erreur s'est produite lors de la récupération des entités.", + StatusCode = 500 + }; + } + } + + public virtual async Task> GetById(int id) + { + try + { + var entity = await _repository.GetByIdAsync(id); + if (entity == null) + { + return new ResponseDataModel + { + Success = false, + Message = $"Aucune entité trouvée avec l'identifiant {id}.", + StatusCode = 404 + }; + } + + return new ResponseDataModel + { + Success = true, + Data = entity, + StatusCode = 200, + Message = "Entité récupérée avec succès." + }; + } + catch (Exception ex) + { + _logger.LogError(ex, $"Une erreur s'est produite lors de la récupération de l'entité avec l'identifiant {id}."); + return new ResponseDataModel + { + Success = false, + Message = "Une erreur s'est produite lors de la récupération de l'entité.", + StatusCode = 500 + }; + } + } + + public virtual async Task>> GetAllWithRelationsAsync(params Expression>[] relationsAInclure) + { + try + { + var entities = await _repository.GetAllWithRelationsAsync(relationsAInclure); + var dtos = _mapper.Map>(entities); + return new ResponseDataModel> + { + Success = true, + Data = dtos, + StatusCode = 200, + Message = "Liste des entités récupérée avec succès." + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Une erreur s'est produite lors de la récupération des entités."); + return new ResponseDataModel> + { + Success = false, + Message = "Une erreur s'est produite lors de la récupération des entités.", + StatusCode = 500 + }; + } + } + + public virtual async Task> GetByIdWithRelations(int id, params Expression>[] relationsAInclure) + { + try + { + var entity = await _repository.GetWithRelationsAsync(id, relationsAInclure); + if (entity == null) + { + return new ResponseDataModel + { + Success = false, + Message = $"Aucune entité trouvée avec l'identifiant {id}.", + StatusCode = 404 + }; + } + + var dto = _mapper.Map(entity); + return new ResponseDataModel + { + Success = true, + Data = dto, + StatusCode = 200, + Message = "Entité avec relations récupérée avec succès." + }; + } + catch (Exception ex) + { + _logger.LogError(ex, $"Une erreur s'est produite lors de la récupération de l'entité avec l'identifiant {id}."); + return new ResponseDataModel + { + Success = false, + Message = "Une erreur s'est produite lors de la récupération de l'entité avec relations.", + StatusCode = 500 + }; + } + } + + public virtual async Task> Create(TCreateDto dto) + { + try + { + var validationResult = _createDtoValidator.Validate(dto); + if (!validationResult.IsValid) + { + return new ResponseDataModel + { + Success = false, + Message = string.Join("; ", validationResult.Errors.Select(e => e.ErrorMessage)), + StatusCode = 400 + }; + } + var entity = _mapper.Map(dto); + var createdEntity = await _repository.AddAsync(entity); + return new ResponseDataModel + { + Success = createdEntity != null, + Data = createdEntity, + StatusCode = createdEntity != null ? 201 : 500, + Message = createdEntity != null ? "Entité créée avec succès." : "Échec de la création de l'entité." + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Une erreur s'est produite lors de la création de l'entité."); + return new ResponseDataModel + { + Success = false, + Message = "Une erreur s'est produite lors de la création de l'entité.", + StatusCode = 500 + }; + } + } + + public virtual async Task> Update(TUpdateDto dto) + { + try + { + var validationResult = _updateDtoValidator.Validate(dto); + if (!validationResult.IsValid) + { + return new ResponseDataModel + { + Success = false, + Message = string.Join("; ", validationResult.Errors.Select(e => e.ErrorMessage)), + StatusCode = 400 + }; + } + var entity = _mapper.Map(dto); + bool isUpdated = await _repository.UpdateAsync(entity); + return new ResponseDataModel + { + Success = isUpdated, + Data = isUpdated ? entity : default, + StatusCode = isUpdated ? 200 : 500, + Message = isUpdated ? "Entité mise à jour avec succès." : "Échec de la mise à jour de l'entité." + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Une erreur s'est produite lors de la mise à jour de l'entité."); + return new ResponseDataModel + { + Success = false, + Message = "Une erreur s'est produite lors de la mise à jour de l'entité.", + StatusCode = 500 + }; + } + } + + public virtual async Task> Delete(int id) + { + try + { + var entity = await _repository.GetByIdAsync(id); + if (entity == null) + { + return new ResponseDataModel + { + Success = false, + Message = $"Aucune entité trouvée avec l'identifiant {id}.", + StatusCode = 404 + }; + } + + var isDeleted = await _repository.DeleteAsync(entity); + return new ResponseDataModel + { + Success = isDeleted, + Data = isDeleted ? id.ToString() : null, + StatusCode = isDeleted ? 200 : 500, + Message = isDeleted ? "Entité supprimée avec succès." : "Échec de la suppression de l'entité." + }; + } + catch (Exception ex) + { + _logger.LogError(ex, $"Une erreur s'est produite lors de la suppression de l'entité avec l'identifiant {id}."); + return new ResponseDataModel + { + Success = false, + Message = "Une erreur s'est produite lors de la suppression de l'entité.", + StatusCode = 500 + }; + } + } +} \ No newline at end of file diff --git a/ldap-cesi/Services/ServiceService.cs b/ldap-cesi/Services/ServiceService.cs index 608496f..193fe2c 100644 --- a/ldap-cesi/Services/ServiceService.cs +++ b/ldap-cesi/Services/ServiceService.cs @@ -5,146 +5,145 @@ using ldap_cesi.Models; using ldap_cesi.Repository.Services; using ldap_cesi.Services.Interfaces; using ldap_cesi.Validator.Service; +using ldap_cesi.DTOs; +using ldap_cesi.DTOs.Inputs.Service; namespace ldap_cesi.Services; -public class ServiceService : IServiceService +public class ServiceService : ServiceBase, IServiceService { - private readonly IRepositoryService _repositoryService; - private readonly IMapper _mapper; - public ServiceService(IRepositoryService repositoryService, IMapper mapper) + public ServiceService(IRepositoryService repositoryService, IMapper mapper, ILogger logger, ServiceCreateValidator serviceCreateValidator, ServiceUpdateValidator serviceUpdateValidator) + : base(repositoryService, mapper, logger, serviceCreateValidator, serviceUpdateValidator) { - _repositoryService = repositoryService; - _mapper = mapper; } - public async Task>> GetAll() - { - var services = await _repositoryService.GetAllAsync(); - return new ResponseDataModel> - { - Success = true, - Data = services, - StatusCode = 200, - }; - } + // public async Task>> GetAll() + // { + // var services = await _repositoryService.GetAllAsync(); + // return new ResponseDataModel> + // { + // Success = true, + // Data = services, + // StatusCode = 200, + // }; + // } - public async Task> GetById(int id) - { - var service = await _repositoryService.GetByIdAsync(id); - return new ResponseDataModel - { - Success = true, - Data = service, - StatusCode = 200, - }; - } + // public async Task> GetById(int id) + // { + // var service = await _repositoryService.GetByIdAsync(id); + // return new ResponseDataModel + // { + // Success = true, + // Data = service, + // StatusCode = 200, + // }; + // } - public async Task> CreateService(ServiceCreateDto serviceCreateDto) - { - var validation = new ServiceCreateValidator(); - var result = validation.Validate(serviceCreateDto); - if (!result.IsValid) - { - return new ResponseDataModel - { - StatusCode = 400, - Success = false, - Message = "Données du service invalides: " + string.Join(", ", result.Errors) - }; - } - var service = _mapper.Map(serviceCreateDto); - var response = await _repositoryService.AddAsync(service); - return new ResponseDataModel - { - StatusCode = 201, - Success = true, - Data = response.Id.ToString(), - }; - } + // public async Task> CreateService(ServiceCreateDto serviceCreateDto) + // { + // var validation = new ServiceCreateValidator(); + // var result = validation.Validate(serviceCreateDto); + // if (!result.IsValid) + // { + // return new ResponseDataModel + // { + // StatusCode = 400, + // Success = false, + // Message = "Données du service invalides: " + string.Join(", ", result.Errors) + // }; + // } + // var service = _mapper.Map(serviceCreateDto); + // var response = await _repositoryService.AddAsync(service); + // return new ResponseDataModel + // { + // StatusCode = 201, + // Success = true, + // Data = response.Id.ToString(), + // }; + // } - public async Task> UpdateService(ServiceUpdateDto serviceUpdateDto) - { - var validation = new ServiceUpdateValidator(); - var result = validation.Validate(serviceUpdateDto); - if (!result.IsValid) - { - return new ResponseDataModel - { - StatusCode = 400, - Success = false, - Message = "Données du service invalides: " + string.Join(", ", result.Errors) - }; - } - var serviceFind = await _repositoryService.GetByIdAsync(serviceUpdateDto.Id); - if (serviceFind is null) - { - return new ResponseDataModel - { - Success = false, - Message = "Service introuvable.", - StatusCode = 404 - }; - } + // public async Task> UpdateService(ServiceUpdateDto serviceUpdateDto) + // { + // var validation = new ServiceUpdateValidator(); + // var result = validation.Validate(serviceUpdateDto); + // if (!result.IsValid) + // { + // return new ResponseDataModel + // { + // StatusCode = 400, + // Success = false, + // Message = "Données du service invalides: " + string.Join(", ", result.Errors) + // }; + // } + // var serviceFind = await _repositoryService.GetByIdAsync(serviceUpdateDto.Id); + // if (serviceFind is null) + // { + // return new ResponseDataModel + // { + // Success = false, + // Message = "Service introuvable.", + // StatusCode = 404 + // }; + // } - var service = _mapper.Map(serviceUpdateDto, serviceFind); - var response = await _repositoryService.UpdateAsync(service); - if (!response) - { - return new ResponseDataModel - { - StatusCode = 500, - Success = false, - Message = "Erreur lors de la mise à jour du service : " + string.Join(", ", result.Errors) - }; - } - return new ResponseDataModel - { - StatusCode = 200, - Success = true, - Data = service, - }; - } + // var service = _mapper.Map(serviceUpdateDto, serviceFind); + // var response = await _repositoryService.UpdateAsync(service); + // if (!response) + // { + // return new ResponseDataModel + // { + // StatusCode = 500, + // Success = false, + // Message = "Erreur lors de la mise à jour du service : " + string.Join(", ", result.Errors) + // }; + // } + // return new ResponseDataModel + // { + // StatusCode = 200, + // Success = true, + // Data = service, + // }; + // } - public async Task> DeleteService(int idService) - { - if (idService == null) - { - return new ResponseDataModel - { - StatusCode = 400, - Success = false, - Message = "Id manquant" - }; - } + // public async Task> DeleteService(int idService) + // { + // if (idService == null) + // { + // return new ResponseDataModel + // { + // StatusCode = 400, + // Success = false, + // Message = "Id manquant" + // }; + // } - var service = await _repositoryService.GetByIdAsync(idService); - if (service == null) - { - return new ResponseDataModel - { - Success = false, - Message = "Service introuvable.", - StatusCode = 404 - }; - } - var response = await _repositoryService.DeleteAsync(service); - if (!response) - { - return new ResponseDataModel - { - StatusCode = 500, - Success = false, - Message = "Erreur durant la suppression du service" - }; - } - return new ResponseDataModel - { - StatusCode = 200, - Success = true, - Data = service.Id.ToString(), - }; - } + // var service = await _repositoryService.GetByIdAsync(idService); + // if (service == null) + // { + // return new ResponseDataModel + // { + // Success = false, + // Message = "Service introuvable.", + // StatusCode = 404 + // }; + // } + // var response = await _repositoryService.DeleteAsync(service); + // if (!response) + // { + // return new ResponseDataModel + // { + // StatusCode = 500, + // Success = false, + // Message = "Erreur durant la suppression du service" + // }; + // } + // return new ResponseDataModel + // { + // StatusCode = 200, + // Success = true, + // Data = service.Id.ToString(), + // }; + // } } \ No newline at end of file diff --git a/ldap-cesi/Services/UtilisateurService.cs b/ldap-cesi/Services/UtilisateurService.cs index b908c5a..3abf032 100644 --- a/ldap-cesi/Services/UtilisateurService.cs +++ b/ldap-cesi/Services/UtilisateurService.cs @@ -47,7 +47,7 @@ public class UtilisateurService : IUtilisateurService public async Task> Login(UtilisateurLoginDto utilisateurInput) { - var validation = new UtilisateurCreateValidator(); + var validation = new UtilisateurLoginValidator(); var result = validation.Validate(utilisateurInput); if (!result.IsValid) { diff --git a/ldap-cesi/Validator/Role/RoleCreateValidator.cs b/ldap-cesi/Validator/Role/RoleCreateValidator.cs new file mode 100644 index 0000000..ff2e572 --- /dev/null +++ b/ldap-cesi/Validator/Role/RoleCreateValidator.cs @@ -0,0 +1,14 @@ +using FluentValidation; +using ldap_cesi.DTOs.Inputs.Role; + +namespace ldap_cesi.Validator.Role; + +public class RoleCreateValidator : AbstractValidator +{ + public RoleCreateValidator() + { + RuleFor(x => x.Nom) + .NotEmpty().WithMessage("Le nom est requis.") + .MaximumLength(50).WithMessage("Le nom ne doit pas dépasser 50 caractères."); + } +} \ No newline at end of file diff --git a/ldap-cesi/Validator/Role/RoleUpdateValidator.cs b/ldap-cesi/Validator/Role/RoleUpdateValidator.cs new file mode 100644 index 0000000..1bdec9d --- /dev/null +++ b/ldap-cesi/Validator/Role/RoleUpdateValidator.cs @@ -0,0 +1,16 @@ +using FluentValidation; +using ldap_cesi.DTOs.Inputs.Role; + +namespace ldap_cesi.Validator.Role; + +public class RoleUpdateValidator : AbstractValidator +{ + public RoleUpdateValidator() + { + RuleFor(x => x.Nom) + .NotEmpty().WithMessage("Le nom est requis.") + .MaximumLength(50).WithMessage("Le nom ne doit pas dépasser 50 caractères."); + RuleFor(x => x.Id) + .NotEmpty().WithMessage("L'identifiant du Rôle est requis."); + } +} \ No newline at end of file diff --git a/ldap-cesi/Validator/Salarie/SalarieCreateValidator.cs b/ldap-cesi/Validator/Salarie/SalarieCreateValidator.cs index a53fc1c..c23c02a 100644 --- a/ldap-cesi/Validator/Salarie/SalarieCreateValidator.cs +++ b/ldap-cesi/Validator/Salarie/SalarieCreateValidator.cs @@ -16,11 +16,15 @@ public class SalarieCreateValidator : AbstractValidator .MaximumLength(50).WithMessage("Le prénom ne doit pas dépasser 50 caractères."); RuleFor(x => x.TelephoneFix) - .NotEmpty().WithMessage("Le téléphone fixe est requis.") + .NotEmpty().WithMessage("Le téléphone fixe est requis.") + .Matches(@"^(\+33|0)[1-9](\d{2}){4}$") + .WithMessage("Le numéro de téléphone fixe n'est pas valide. Format attendu : +33XXXXXXXXX ou 0XXXXXXXXX.") .MaximumLength(15).WithMessage("Le téléphone fixe ne doit pas dépasser 15 caractères."); RuleFor(x => x.TelephonePortable) .NotEmpty().WithMessage("Le téléphone portable est requis.") + .Matches(@"^(\+33|0)[6-7](\d{2}){4}$") + .WithMessage("Le numéro de téléphone portable n'est pas valide. Format attendu : +33XXXXXXXXX ou 0XXXXXXXXX.") .MaximumLength(15).WithMessage("Le téléphone portable ne doit pas dépasser 15 caractères."); RuleFor(x => x.Email) diff --git a/ldap-cesi/Validator/Salarie/SalarieUpdateValidator.cs b/ldap-cesi/Validator/Salarie/SalarieUpdateValidator.cs index a755c82..d364149 100644 --- a/ldap-cesi/Validator/Salarie/SalarieUpdateValidator.cs +++ b/ldap-cesi/Validator/Salarie/SalarieUpdateValidator.cs @@ -18,11 +18,15 @@ public class SalarieUpdateValidator : AbstractValidator .MaximumLength(50).WithMessage("Le prénom ne doit pas dépasser 50 caractères."); RuleFor(x => x.TelephoneFixe) - .NotEmpty().WithMessage("Le téléphone fixe est requis.") + .NotEmpty().WithMessage("Le téléphone fixe est requis.") + .Matches(@"^(\+33|0)[1-9](\d{2}){4}$") + .WithMessage("Le numéro de téléphone fixe n'est pas valide. Format attendu : +33XXXXXXXXX ou 0XXXXXXXXX.") .MaximumLength(15).WithMessage("Le téléphone fixe ne doit pas dépasser 15 caractères."); RuleFor(x => x.TelephonePortable) .NotEmpty().WithMessage("Le téléphone portable est requis.") + .Matches(@"^(\+33|0)[6-7](\d{2}){4}$") + .WithMessage("Le numéro de téléphone portable n'est pas valide. Format attendu : +33XXXXXXXXX ou 0XXXXXXXXX.") .MaximumLength(15).WithMessage("Le téléphone portable ne doit pas dépasser 15 caractères."); RuleFor(x => x.Email) diff --git a/ldap-cesi/Validator/Utilisateur/UtilisateurCreateValidator.cs b/ldap-cesi/Validator/Utilisateur/UtilisateurLoginValidator.cs similarity index 54% rename from ldap-cesi/Validator/Utilisateur/UtilisateurCreateValidator.cs rename to ldap-cesi/Validator/Utilisateur/UtilisateurLoginValidator.cs index 154b071..aa2e28f 100644 --- a/ldap-cesi/Validator/Utilisateur/UtilisateurCreateValidator.cs +++ b/ldap-cesi/Validator/Utilisateur/UtilisateurLoginValidator.cs @@ -3,16 +3,18 @@ using ldap_cesi.DTOs.Inputs; namespace ldap_cesi.Validator.Utilisateur; -public class UtilisateurCreateValidator : AbstractValidator +public class UtilisateurLoginValidator : AbstractValidator { - public UtilisateurCreateValidator() + public UtilisateurLoginValidator() { RuleFor(x => x.Email) .NotEmpty().WithMessage("L'email est requis.") - .EmailAddress().WithMessage("L'email n'est pas valide."); + .EmailAddress().WithMessage("L'email n'est pas valide.") + .MaximumLength(50).WithMessage("L'email ne doit pas dépasser 50 caractères."); RuleFor(x => x.MotDePasse) .NotEmpty().WithMessage("Le mot de passe est requis.") - .MinimumLength(6).WithMessage("Le mot de passe doit contenir au moins 6 caractères."); + .MinimumLength(6).WithMessage("Le mot de passe doit contenir au moins 6 caractères.") + .MaximumLength(20).WithMessage("Le mot de passe ne doit pas dépasser 20 caractères."); } } \ No newline at end of file diff --git a/ldap-cesi/ldap-cesi.csproj b/ldap-cesi/ldap-cesi.csproj index 5070353..9ef0878 100644 --- a/ldap-cesi/ldap-cesi.csproj +++ b/ldap-cesi/ldap-cesi.csproj @@ -5,6 +5,7 @@ enable enable ldap_cesi + CS0472,CS1591,CS1587 true