| @@ -0,0 +1,8 @@ | |||
| namespace BlackRock.Reporting.API.Controllers.Dto | |||
| { | |||
| public class UserDto | |||
| { | |||
| public string? Name { get; set; } | |||
| public string? Email { get; set; } | |||
| } | |||
| } | |||
| @@ -1,9 +1,7 @@ | |||
| using BlackRock.Reporting.API.Mediator; | |||
| using BlackRock.Reporting.API.Models; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| using MediatR; | |||
| using Microsoft.AspNetCore.Authorization; | |||
| using Microsoft.AspNetCore.Mvc; | |||
| using Microsoft.AspNetCore.Mvc.ModelBinding; | |||
| namespace BlackRock.Reporting.API.Controllers | |||
| { | |||
| @@ -20,7 +18,7 @@ namespace BlackRock.Reporting.API.Controllers | |||
| // GET: api/users/1 | |||
| [HttpGet] | |||
| [Route("api/users/{id}")] | |||
| public async Task<IActionResult> Get(Guid id) | |||
| public async Task<IActionResult> GetUser(int id) | |||
| { | |||
| var result = await mediator.Send(new GetUsersQuery(id)); | |||
| if (!result.IsSuccess) | |||
| @@ -34,9 +32,9 @@ namespace BlackRock.Reporting.API.Controllers | |||
| // GET: api/users?Page=2&PageSize=25 | |||
| [HttpGet] | |||
| [Route("api/users")] | |||
| public async Task<IActionResult> GetAll(UserQuery filter) | |||
| public async Task<IActionResult> GetAllUsers(GetAllUsersQuery query) | |||
| { | |||
| var result = await mediator.Send(new GetAllUsersQuery(filter)); | |||
| var result = await mediator.Send(query); | |||
| if (!result.IsSuccess) | |||
| return BadRequest(result.Error); | |||
| @@ -44,17 +42,18 @@ namespace BlackRock.Reporting.API.Controllers | |||
| if (result.Data == null) | |||
| return NotFound("Id is not valid"); | |||
| return Ok(result.Data); | |||
| } | |||
| // POST: api/users | |||
| [HttpPost] | |||
| [Route("api/users")] | |||
| public async Task<IActionResult> Post([FromBody] UserForm form) | |||
| public async Task<IActionResult> CreateUser([FromBody] CreateUsersCommand user) | |||
| { | |||
| if (!ModelState.IsValid) | |||
| return BadRequest(ModelState); | |||
| var result = await mediator.Send(new CreateUsersCommand(form)); | |||
| var result = await mediator.Send(user); | |||
| if (!result.IsSuccess) | |||
| return BadRequest(result.Error); | |||
| @@ -65,12 +64,12 @@ namespace BlackRock.Reporting.API.Controllers | |||
| // PUT: api/users/1 | |||
| [HttpPut] | |||
| [Route("api/users/{id}")] | |||
| public async Task<IActionResult> Put(Guid id, [FromBody] UserForm form) | |||
| public async Task<IActionResult> UpdateAllUser(int id, [FromBody] UserCommand user) | |||
| { | |||
| if (!ModelState.IsValid) | |||
| return BadRequest(ErrorResponse.Validation(ModelState)); | |||
| var result = await mediator.Send(new UpdateAllUsersCommand(id, form)); | |||
| var result = await mediator.Send(new UpdateAllUsersCommand(id,user)); | |||
| if (!result.IsSuccess) | |||
| return BadRequest(result.Error); | |||
| @@ -79,12 +78,12 @@ namespace BlackRock.Reporting.API.Controllers | |||
| // PATCH: api/users/1/email | |||
| [HttpPatch] | |||
| [Route("api/users/{id}/email")] | |||
| public async Task<IActionResult> UpdateEmail(Guid id, [FromBody] UserForm form) | |||
| public async Task<IActionResult> UpdateUserEmail(int id, [FromBody] UserCommand user) | |||
| { | |||
| if (!ModelState.IsValid) | |||
| return BadRequest(ErrorResponse.Validation(ModelState)); | |||
| var result = await mediator.Send(new UpdateEmailUsersCommand(id, form)); | |||
| var result = await mediator.Send(new UpdateEmailUsersCommand(id, user)); | |||
| if (!result.IsSuccess) | |||
| return BadRequest(result.Error); | |||
| @@ -93,7 +92,7 @@ namespace BlackRock.Reporting.API.Controllers | |||
| // DELETE: api/users/1 | |||
| [HttpDelete] | |||
| [Route("api/users/{id}")] | |||
| public async Task<IActionResult> Delete(Guid id) | |||
| public async Task<IActionResult> DeleteUser(int id) | |||
| { | |||
| if (!ModelState.IsValid) | |||
| return BadRequest(ErrorResponse.Validation(ModelState)); | |||
| @@ -106,21 +105,6 @@ namespace BlackRock.Reporting.API.Controllers | |||
| } | |||
| } | |||
| public class ErrorResponse | |||
| { | |||
| public IEnumerable<string> Errors { get; set; } | |||
| public Enum StatusCode { get; set; } | |||
| public ModelStateDictionary Validations { get; set; } | |||
| public static ErrorResponse Validation(ModelStateDictionary validations) | |||
| { | |||
| return new ErrorResponse | |||
| { | |||
| Validations = validations | |||
| }; | |||
| } | |||
| } | |||
| // I/O | |||
| // Output: DTO : Entity wraper, Agregations | |||
| // Input: Query / Form | |||
| @@ -1,15 +1,18 @@ | |||
| using System.Linq.Expressions; | |||
| using BlackRock.Reporting.API.Core.Models; | |||
| using BlackRock.Reporting.API.Models; | |||
| using BlackRock.Reporting.API.Persistence; | |||
| namespace BlackRock.Reporting.API.Core | |||
| { | |||
| public interface IRepository<TEntity> where TEntity : class | |||
| public interface IRepository<TEntity> where TEntity : class, IBaseEntity | |||
| { | |||
| Task<TEntity> GetByIdAsync(Guid id); | |||
| Task<IQueryable<TEntity>> GetAllAsync(); | |||
| Task<TEntity> GetByIdAsync(int id); | |||
| Task<IEnumerable<TEntity>> GetAllAsync(); | |||
| Task AddAsync(TEntity entity); | |||
| Task AddRangeAsync(IEnumerable<TEntity> entities); | |||
| void Update(TEntity entity); | |||
| void UpdateRange(IEnumerable<TEntity> entities); | |||
| void Remove(TEntity entity); | |||
| void RemoveRange(IEnumerable<TEntity> entities); | |||
| } | |||
| @@ -2,6 +2,7 @@ namespace BlackRock.Reporting.API.Core | |||
| { | |||
| public interface IUnitOfWork | |||
| { | |||
| IUsersRepository UsersRepository{get;set;} | |||
| Task SaveChangesAsync(); | |||
| } | |||
| } | |||
| @@ -1,9 +1,12 @@ | |||
| using BlackRock.Reporting.API.Mediator; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| using BlackRock.Reporting.API.Models; | |||
| namespace BlackRock.Reporting.API.Core | |||
| { | |||
| public interface IUsersRepository : IRepository<User> | |||
| { | |||
| void UpdateEmail(User user,string email); | |||
| Task<PaggingCollection<User>> GetAllByFilter(PaggingAndFiltering queryObj); | |||
| } | |||
| } | |||
| @@ -0,0 +1,33 @@ | |||
| using System.Linq.Expressions; | |||
| using BlackRock.Reporting.API.Mediator; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| namespace BlackRock.Reporting.API.Extensions | |||
| { | |||
| public static class IQueryableExtensions | |||
| { | |||
| public static IQueryable<T> ApplyOrdering<T>(this IQueryable<T> query, | |||
| IPaggingAndFiltering queryObj, Dictionary<string, Expression<Func<T, object>>> columnsMap) | |||
| { | |||
| if (string.IsNullOrWhiteSpace(queryObj.SortBy) || | |||
| !columnsMap.ContainsKey(queryObj.SortBy)) | |||
| return query; | |||
| if (queryObj.IsSortAscending) | |||
| return query.OrderBy(columnsMap[queryObj.SortBy]); | |||
| return query.OrderByDescending(columnsMap[queryObj.SortBy]); | |||
| } | |||
| public static IQueryable<T> ApplyPagging<T>(this IQueryable<T> query, | |||
| IPaggingAndFiltering queryObj) | |||
| { | |||
| if (queryObj.Page <= 0) | |||
| queryObj.Page = 1; | |||
| if (queryObj.PageSize <= 0) | |||
| queryObj.PageSize = 10; | |||
| return query.Skip((queryObj.Page - 1) * queryObj.PageSize) | |||
| .Take(queryObj.PageSize); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,51 +1,48 @@ | |||
| using AutoMapper; | |||
| using BlackRock.Reporting.API.Core; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| using BlackRock.Reporting.API.Models; | |||
| using MediatR; | |||
| namespace BlackRock.Reporting.API.Mediator | |||
| { | |||
| public class CreateUsersCommand : IRequest<Result<Guid>> | |||
| public class CreateUsersCommand : UserCommand, IRequest<Result<int>> | |||
| { | |||
| public UserForm User { get; } | |||
| public CreateUsersCommand(UserForm user) | |||
| public CreateUsersCommand(string Name, string Email) : base(Name, Email) | |||
| { | |||
| this.User = user; | |||
| } | |||
| } | |||
| public class CreateUsersCommandHandlers : IRequestHandler<CreateUsersCommand, Result<Guid>> | |||
| public class CreateUsersCommandHandlers : IRequestHandler<CreateUsersCommand, Result<int>> | |||
| { | |||
| private readonly ILogger<CreateUsersCommandHandlers> logger; | |||
| private readonly IMapper mapper; | |||
| private readonly IUsersRepository repository; | |||
| private readonly IUnitOfWork unitOfWork; | |||
| public CreateUsersCommandHandlers(ILogger<CreateUsersCommandHandlers> logger, IMapper mapper, IUsersRepository repository, IUnitOfWork unitOfWork) | |||
| public CreateUsersCommandHandlers(ILogger<CreateUsersCommandHandlers> logger, IMapper mapper, IUnitOfWork unitOfWork) | |||
| { | |||
| this.unitOfWork = unitOfWork; | |||
| this.repository = repository; | |||
| this.mapper = mapper; | |||
| this.logger = logger; | |||
| } | |||
| public async Task<Result<Guid>> Handle(CreateUsersCommand command, CancellationToken cancellationToken) | |||
| public async Task<Result<int>> Handle(CreateUsersCommand command, CancellationToken cancellationToken) | |||
| { | |||
| if (command.User == null) | |||
| throw new ArgumentException($"Parameter {nameof(command.User)} must not be null"); | |||
| if (command is null) | |||
| throw new ArgumentException($"Parameter {nameof(command)} must not be null"); | |||
| try | |||
| { | |||
| logger.LogInformation("Creating new user ..."); | |||
| var user = mapper.Map<UserForm, User>(command.User); | |||
| user.Id = Guid.NewGuid(); | |||
| await repository.AddAsync(user); | |||
| var user = mapper.Map<UserCommand, User>(command); | |||
| await unitOfWork.UsersRepository.AddAsync(user); | |||
| await unitOfWork.SaveChangesAsync(); | |||
| logger.LogInformation($"User with id {user.Id} has been created successfully"); | |||
| return new Result<Guid> { Data = user.Id }; | |||
| return new Result<int> { Data = user.Id}; | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| return new Result<Guid> { IsSuccess = false, Error = "Faild to add data to DB." }; | |||
| logger.LogError(ex,"Faild to add data to DB."); | |||
| return new Result<int> { IsSuccess = false, Error = "Faild to add data to DB." }; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,48 +1,45 @@ | |||
| using AutoMapper; | |||
| using BlackRock.Reporting.API.Core; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| using BlackRock.Reporting.API.Models; | |||
| using MediatR; | |||
| namespace BlackRock.Reporting.API.Mediator | |||
| { | |||
| public class DeleteUsersCommand : IRequest<Result<Guid>> | |||
| public class DeleteUsersCommand : UserQuery, IRequest<Result<int>> | |||
| { | |||
| public Guid Id { get; } | |||
| public DeleteUsersCommand(Guid id) | |||
| public DeleteUsersCommand(int id) : base(id) | |||
| { | |||
| this.Id = id; | |||
| } | |||
| } | |||
| public class DeleteUsersCommandHandlers : IRequestHandler<DeleteUsersCommand, Result<Guid>> | |||
| public class DeleteUsersCommandHandlers : IRequestHandler<DeleteUsersCommand, Result<int>> | |||
| { | |||
| private readonly ILogger<DeleteUsersCommandHandlers> logger; | |||
| private readonly IMapper mapper; | |||
| private readonly IUsersRepository repository; | |||
| private readonly IUnitOfWork unitOfWork; | |||
| public DeleteUsersCommandHandlers(ILogger<DeleteUsersCommandHandlers> logger, IMapper mapper, IUsersRepository repository, IUnitOfWork unitOfWork) | |||
| public DeleteUsersCommandHandlers(ILogger<DeleteUsersCommandHandlers> logger, IMapper mapper, IUnitOfWork unitOfWork) | |||
| { | |||
| this.unitOfWork = unitOfWork; | |||
| this.repository = repository; | |||
| this.mapper = mapper; | |||
| this.logger = logger; | |||
| } | |||
| public async Task<Result<Guid>> Handle(DeleteUsersCommand command, CancellationToken cancellationToken) | |||
| public async Task<Result<int>> Handle(DeleteUsersCommand command, CancellationToken cancellationToken) | |||
| { | |||
| if (command.Id == Guid.Empty) | |||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be null or empty"); | |||
| if (command.Id <= 0) | |||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be grater than 0"); | |||
| logger.LogInformation("Deleting user ..."); | |||
| try | |||
| { | |||
| var user = await repository.GetByIdAsync(command.Id); | |||
| repository.Remove(user); | |||
| var user = await unitOfWork.UsersRepository.GetByIdAsync(command.Id); | |||
| unitOfWork.UsersRepository.Remove(user); | |||
| await unitOfWork.SaveChangesAsync(); | |||
| logger.LogInformation($"User with id {user.Id} has been deleted successfully"); | |||
| return new Result<Guid> { Data = command.Id }; | |||
| return new Result<int> { Data = command.Id }; | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| return new Result<Guid> { IsSuccess = false, Error = "Faild to delete data from DB." }; | |||
| return new Result<int> { IsSuccess = false, Error = "Faild to delete data from DB." }; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,62 +1,42 @@ | |||
| using AutoMapper; | |||
| using BlackRock.Reporting.API.Controllers.Dto; | |||
| using BlackRock.Reporting.API.Core; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| using BlackRock.Reporting.API.Models; | |||
| using MediatR; | |||
| namespace BlackRock.Reporting.API.Mediator | |||
| { | |||
| public class QueryResults<T> | |||
| public class GetAllUsersQuery : PaggingAndFiltering, IRequest<Result<PaggingCollection<UserDto>>> | |||
| { | |||
| public int TotalItems { get; set; } | |||
| public IEnumerable<T> Items { get; set; } | |||
| } | |||
| public class UserQuery | |||
| { | |||
| public string SortBy { get; set; } | |||
| public bool IsSortAscending { get; set; } | |||
| public int Page { get; set; } | |||
| public int PageSize { get; set; } | |||
| } | |||
| public class GetAllUsersQuery : IRequest<Result<QueryResults<UserDto>>> | |||
| { | |||
| public UserQuery Filter { get; } | |||
| public GetAllUsersQuery(UserQuery filter) | |||
| { | |||
| this.Filter = filter; | |||
| } | |||
| } | |||
| public class GetAllUsersQueryHandlers : IRequestHandler<GetAllUsersQuery, Result<QueryResults<UserDto>>> | |||
| public class GetAllUsersQueryHandlers : IRequestHandler<GetAllUsersQuery, Result<PaggingCollection<UserDto>>> | |||
| { | |||
| private readonly ILogger<GetAllUsersQueryHandlers> logger; | |||
| private readonly IMapper mapper; | |||
| private readonly IUnitOfWork unitOfWork; | |||
| private readonly IUsersRepository repository; | |||
| public GetAllUsersQueryHandlers(ILogger<GetAllUsersQueryHandlers> logger, IMapper mapper, IUsersRepository repository, IUnitOfWork unitOfWork) | |||
| public GetAllUsersQueryHandlers(ILogger<GetAllUsersQueryHandlers> logger, IMapper mapper, IUnitOfWork unitOfWork) | |||
| { | |||
| this.repository = repository; | |||
| this.unitOfWork = unitOfWork; | |||
| this.mapper = mapper; | |||
| this.logger = logger; | |||
| } | |||
| public async Task<Result<QueryResults<UserDto>>> Handle(GetAllUsersQuery command, CancellationToken cancellationToken) | |||
| public async Task<Result<PaggingCollection<UserDto>>> Handle(GetAllUsersQuery command, CancellationToken cancellationToken) | |||
| { | |||
| if (command.Filter == null) | |||
| throw new ArgumentNullException($"Parameter {nameof(command.Filter)} must not be null"); | |||
| if (command == null) | |||
| throw new ArgumentNullException($"Parameter {nameof(command)} must not be null"); | |||
| logger.LogInformation("Getting users ..."); | |||
| try | |||
| { | |||
| var users = await repository.GetAllAsync(); | |||
| var usersDto = mapper.Map<IEnumerable<User>, IEnumerable<UserDto>>(users); | |||
| var data = new QueryResults<UserDto> { Items = usersDto, TotalItems = usersDto.Count() }; | |||
| var users = await unitOfWork.UsersRepository.GetAllByFilter(command); | |||
| var usersDto = mapper.Map<PaggingCollection<User>, PaggingCollection<UserDto>>(users); | |||
| logger.LogInformation($"The Users has been founded successfully"); | |||
| return new Result<QueryResults<UserDto>> { Data = data }; | |||
| return new Result<PaggingCollection<UserDto>> { Data = usersDto }; | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| return new Result<QueryResults<UserDto>> { IsSuccess = false, Error = "Faild to fetch data from DB." }; | |||
| return new Result<PaggingCollection<UserDto>> { IsSuccess = false, Error = "Faild to fetch data from DB." }; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,16 +1,16 @@ | |||
| using AutoMapper; | |||
| using BlackRock.Reporting.API.Controllers.Dto; | |||
| using BlackRock.Reporting.API.Core; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| using BlackRock.Reporting.API.Models; | |||
| using MediatR; | |||
| namespace BlackRock.Reporting.API.Mediator | |||
| { | |||
| public class GetUsersQuery : IRequest<Result<UserDto>> | |||
| public class GetUsersQuery : UserQuery, IRequest<Result<UserDto>> | |||
| { | |||
| public Guid Id { get; } | |||
| public GetUsersQuery(Guid id) | |||
| public GetUsersQuery(int id) : base(id) | |||
| { | |||
| this.Id = id; | |||
| } | |||
| } | |||
| @@ -29,8 +29,8 @@ namespace BlackRock.Reporting.API.Mediator | |||
| } | |||
| public async Task<Result<UserDto>> Handle(GetUsersQuery command, CancellationToken cancellationToken) | |||
| { | |||
| if (command.Id == Guid.Empty) | |||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be null or empty"); | |||
| if (command.Id <= 0) | |||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be grater than 0"); | |||
| logger.LogInformation("Getting user ..."); | |||
| try | |||
| { | |||
| @@ -0,0 +1,23 @@ | |||
| using Microsoft.AspNetCore.Mvc.ModelBinding; | |||
| namespace BlackRock.Reporting.API.Mediator.Model | |||
| { | |||
| public class ErrorResponse | |||
| { | |||
| public IEnumerable<string> Errors { get; set; } | |||
| public Enum StatusCode { get; set; } | |||
| public ModelStateDictionary Validations { get; set; } | |||
| public static ErrorResponse Validation(ModelStateDictionary validations) | |||
| { | |||
| return new ErrorResponse | |||
| { | |||
| Validations = validations | |||
| }; | |||
| } | |||
| } | |||
| // I/O | |||
| // Output: DTO : Entity wraper, Agregations | |||
| // Input: Query / Form | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| namespace BlackRock.Reporting.API.Mediator.Model | |||
| { | |||
| public interface IPaggingAndFiltering | |||
| { | |||
| string EmailDomain {get;set;} | |||
| string SortBy { get; set; } | |||
| bool IsSortAscending { get; set; } | |||
| int Page { get; set; } | |||
| int PageSize { get; set; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| namespace BlackRock.Reporting.API.Mediator.Model | |||
| { | |||
| public class PaggingAndFiltering : IPaggingAndFiltering | |||
| { | |||
| public string EmailDomain { get; set; } | |||
| public string SortBy {get;set;} | |||
| public bool IsSortAscending {get;set;} | |||
| public int Page {get;set;} | |||
| public int PageSize {get;set;} | |||
| } | |||
| } | |||
| @@ -0,0 +1,13 @@ | |||
| using System.Collections.ObjectModel; | |||
| namespace BlackRock.Reporting.API.Mediator.Model | |||
| { | |||
| public class PaggingCollection<T> : Collection<T>, IPaggingAndFiltering where T : class | |||
| { | |||
| public string SortBy {set;get;} | |||
| public bool IsSortAscending {set;get;} | |||
| public int Page {set;get;} | |||
| public int PageSize {set;get;} | |||
| public string EmailDomain {get;set;} | |||
| } | |||
| } | |||
| @@ -0,0 +1,17 @@ | |||
| using System.ComponentModel.DataAnnotations; | |||
| namespace BlackRock.Reporting.API.Mediator.Model | |||
| { | |||
| public class UserCommand | |||
| { | |||
| [Required] | |||
| public string Name { get; } | |||
| [Required] | |||
| public string Email { get; } | |||
| public UserCommand(string Name,string Email) | |||
| { | |||
| this.Name = Name; | |||
| this.Email = Email; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,14 @@ | |||
| using System.ComponentModel.DataAnnotations; | |||
| namespace BlackRock.Reporting.API.Mediator.Model | |||
| { | |||
| public class UserQuery | |||
| { | |||
| [Required] | |||
| public int Id { get; } | |||
| public UserQuery(int id) | |||
| { | |||
| Id = id; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,5 +1,7 @@ | |||
| using AutoMapper; | |||
| using BlackRock.Reporting.API.Controllers.Dto; | |||
| using BlackRock.Reporting.API.Core; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| using BlackRock.Reporting.API.Models; | |||
| using MediatR; | |||
| @@ -7,9 +9,9 @@ namespace BlackRock.Reporting.API.Mediator | |||
| { | |||
| public class UpdateAllUsersCommand : IRequest<Result<UserDto>> | |||
| { | |||
| public UserForm User { get; } | |||
| public Guid Id { get; } | |||
| public UpdateAllUsersCommand(Guid id, UserForm user) | |||
| public UserCommand User { get; } | |||
| public int Id { get; } | |||
| public UpdateAllUsersCommand(int id, UserCommand user) | |||
| { | |||
| this.Id = id; | |||
| this.User = user; | |||
| @@ -20,24 +22,23 @@ namespace BlackRock.Reporting.API.Mediator | |||
| { | |||
| private readonly ILogger<UpdateAllUsersCommandHandlers> logger; | |||
| private readonly IMapper mapper; | |||
| private readonly IUsersRepository repository; | |||
| private readonly IUnitOfWork unitOfWork; | |||
| public UpdateAllUsersCommandHandlers(ILogger<UpdateAllUsersCommandHandlers> logger, IMapper mapper, IUsersRepository repository, IUnitOfWork unitOfWork) | |||
| public UpdateAllUsersCommandHandlers(ILogger<UpdateAllUsersCommandHandlers> logger, IMapper mapper, IUnitOfWork unitOfWork) | |||
| { | |||
| this.unitOfWork = unitOfWork; | |||
| this.repository = repository; | |||
| this.mapper = mapper; | |||
| this.logger = logger; | |||
| } | |||
| public async Task<Result<UserDto>> Handle(UpdateAllUsersCommand command, CancellationToken cancellationToken) | |||
| { | |||
| if (command.Id == Guid.Empty) | |||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be null or empty"); | |||
| if (command.Id <= 0) | |||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be grater than 0"); | |||
| logger.LogInformation("Updating user ..."); | |||
| try | |||
| { | |||
| var user = await repository.GetByIdAsync(command.Id); | |||
| mapper.Map<UserForm, User>(command.User, user); | |||
| var user = await unitOfWork.UsersRepository.GetByIdAsync(command.Id); | |||
| mapper.Map<UserCommand, User>(command.User, user); | |||
| unitOfWork.UsersRepository.Update(user); | |||
| await unitOfWork.SaveChangesAsync(); | |||
| var updatedUser = mapper.Map<User, UserDto>(user); | |||
| logger.LogInformation($"User with id {user.Id} has been updated successfully"); | |||
| @@ -1,5 +1,7 @@ | |||
| using AutoMapper; | |||
| using BlackRock.Reporting.API.Controllers.Dto; | |||
| using BlackRock.Reporting.API.Core; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| using BlackRock.Reporting.API.Models; | |||
| using MediatR; | |||
| @@ -7,9 +9,9 @@ namespace BlackRock.Reporting.API.Mediator | |||
| { | |||
| public class UpdateEmailUsersCommand : IRequest<Result<UserDto>> | |||
| { | |||
| public UserForm User { get; } | |||
| public Guid Id { get; } | |||
| public UpdateEmailUsersCommand(Guid id, UserForm user) | |||
| public UserCommand User { get; } | |||
| public int Id { get; } | |||
| public UpdateEmailUsersCommand(int id, UserCommand user) | |||
| { | |||
| this.Id = id; | |||
| this.User = user; | |||
| @@ -20,24 +22,22 @@ namespace BlackRock.Reporting.API.Mediator | |||
| { | |||
| private readonly ILogger<UpdateEmailUsersCommandHandlers> logger; | |||
| private readonly IMapper mapper; | |||
| private readonly IUsersRepository repository; | |||
| private readonly IUnitOfWork unitOfWork; | |||
| public UpdateEmailUsersCommandHandlers(ILogger<UpdateEmailUsersCommandHandlers> logger, IMapper mapper, IUsersRepository repository, IUnitOfWork unitOfWork) | |||
| public UpdateEmailUsersCommandHandlers(ILogger<UpdateEmailUsersCommandHandlers> logger, IMapper mapper, IUnitOfWork unitOfWork) | |||
| { | |||
| this.unitOfWork = unitOfWork; | |||
| this.repository = repository; | |||
| this.mapper = mapper; | |||
| this.logger = logger; | |||
| } | |||
| public async Task<Result<UserDto>> Handle(UpdateEmailUsersCommand command, CancellationToken cancellationToken) | |||
| { | |||
| if (command.Id == Guid.Empty) | |||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be null or empty"); | |||
| if (command.Id <= 0) | |||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be grater than 0"); | |||
| logger.LogInformation("Updating user email ..."); | |||
| try | |||
| { | |||
| var user = await repository.GetByIdAsync(command.Id); | |||
| user.Email = command.User.Email; | |||
| var user = await unitOfWork.UsersRepository.GetByIdAsync(command.Id); | |||
| unitOfWork.UsersRepository.UpdateEmail(user,command.User.Email); | |||
| await unitOfWork.SaveChangesAsync(); | |||
| var updatedUser = mapper.Map<User, UserDto>(user); | |||
| logger.LogInformation($"Email of the user with id {user.Id} has been updated successfully"); | |||
| @@ -0,0 +1,40 @@ | |||
| // <auto-generated /> | |||
| using BlackRock.Reporting.API.Persistence; | |||
| using Microsoft.EntityFrameworkCore; | |||
| using Microsoft.EntityFrameworkCore.Infrastructure; | |||
| using Microsoft.EntityFrameworkCore.Migrations; | |||
| using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | |||
| #nullable disable | |||
| namespace BlackRock.Reporting.API.Migrations | |||
| { | |||
| [DbContext(typeof(BRDbContext))] | |||
| [Migration("20211123150542_ChangedIdFromGuidToInt")] | |||
| partial class ChangedIdFromGuidToInt | |||
| { | |||
| protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||
| { | |||
| #pragma warning disable 612, 618 | |||
| modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); | |||
| modelBuilder.Entity("BlackRock.Reporting.API.Models.User", b => | |||
| { | |||
| b.Property<int>("Id") | |||
| .ValueGeneratedOnAdd() | |||
| .HasColumnType("INTEGER"); | |||
| b.Property<string>("Email") | |||
| .HasColumnType("TEXT"); | |||
| b.Property<string>("Name") | |||
| .HasColumnType("TEXT"); | |||
| b.HasKey("Id"); | |||
| b.ToTable("Users"); | |||
| }); | |||
| #pragma warning restore 612, 618 | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,34 @@ | |||
| using System; | |||
| using Microsoft.EntityFrameworkCore.Migrations; | |||
| #nullable disable | |||
| namespace BlackRock.Reporting.API.Migrations | |||
| { | |||
| public partial class ChangedIdFromGuidToInt : Migration | |||
| { | |||
| protected override void Up(MigrationBuilder migrationBuilder) | |||
| { | |||
| migrationBuilder.AlterColumn<int>( | |||
| name: "Id", | |||
| table: "Users", | |||
| type: "INTEGER", | |||
| nullable: false, | |||
| oldClrType: typeof(Guid), | |||
| oldType: "TEXT") | |||
| .Annotation("Sqlite:Autoincrement", true); | |||
| } | |||
| protected override void Down(MigrationBuilder migrationBuilder) | |||
| { | |||
| migrationBuilder.AlterColumn<Guid>( | |||
| name: "Id", | |||
| table: "Users", | |||
| type: "TEXT", | |||
| nullable: false, | |||
| oldClrType: typeof(int), | |||
| oldType: "INTEGER") | |||
| .OldAnnotation("Sqlite:Autoincrement", true); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,5 +1,4 @@ | |||
| // <auto-generated /> | |||
| using System; | |||
| using BlackRock.Reporting.API.Persistence; | |||
| using Microsoft.EntityFrameworkCore; | |||
| using Microsoft.EntityFrameworkCore.Infrastructure; | |||
| @@ -19,9 +18,9 @@ namespace BlackRock.Reporting.API.Migrations | |||
| modelBuilder.Entity("BlackRock.Reporting.API.Models.User", b => | |||
| { | |||
| b.Property<Guid>("Id") | |||
| b.Property<int>("Id") | |||
| .ValueGeneratedOnAdd() | |||
| .HasColumnType("TEXT"); | |||
| .HasColumnType("INTEGER"); | |||
| b.Property<string>("Email") | |||
| .HasColumnType("TEXT"); | |||
| @@ -0,0 +1,7 @@ | |||
| namespace BlackRock.Reporting.API.Models | |||
| { | |||
| public interface IBaseEntity | |||
| { | |||
| public int Id { get; set; } | |||
| } | |||
| } | |||
| @@ -2,14 +2,9 @@ | |||
| namespace BlackRock.Reporting.API.Models | |||
| { | |||
| public class User | |||
| { | |||
| public Guid Id { get; set; } | |||
| public string? Name { get; set; } | |||
| public string? Email { get; set; } | |||
| } | |||
| public class UserDto | |||
| public class User : IBaseEntity | |||
| { | |||
| public int Id { get; set; } | |||
| public string? Name { get; set; } | |||
| public string? Email { get; set; } | |||
| } | |||
| @@ -1,12 +0,0 @@ | |||
| using System.ComponentModel.DataAnnotations; | |||
| namespace BlackRock.Reporting.API.Models | |||
| { | |||
| public class UserForm | |||
| { | |||
| [Required] | |||
| public string? Name { get; set; } | |||
| [Required] | |||
| public string? Email { get; set; } | |||
| } | |||
| } | |||
| @@ -9,7 +9,6 @@ namespace BlackRock.Reporting.API.Persistence | |||
| { | |||
| } | |||
| public DbSet<User> Users { get; set; } | |||
| } | |||
| } | |||
| @@ -1,24 +1,23 @@ | |||
| using System.Linq.Expressions; | |||
| using BlackRock.Reporting.API.Core; | |||
| using BlackRock.Reporting.API.Core.Models; | |||
| using BlackRock.Reporting.API.Models; | |||
| using Microsoft.EntityFrameworkCore; | |||
| namespace BlackRock.Reporting.API.Persistence | |||
| { | |||
| // Q: Da li da dozvolimo promene van klase ili da zabranimo pomocu AsNoTracking(); | |||
| public class Repository<TEntity> : IRepository<TEntity> where TEntity : class | |||
| public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IBaseEntity | |||
| { | |||
| private readonly BRDbContext context; | |||
| public Repository(BRDbContext context) | |||
| { | |||
| this.context = context; | |||
| } | |||
| public async Task<IQueryable<TEntity>> GetAllAsync() | |||
| public async Task<IEnumerable<TEntity>> GetAllAsync() | |||
| { | |||
| var result = await context.Set<TEntity>().ToListAsync(); | |||
| return result.AsQueryable(); | |||
| return await context.Set<TEntity>().ToListAsync(); | |||
| } | |||
| public async Task<TEntity> GetByIdAsync(Guid id) | |||
| public async Task<TEntity> GetByIdAsync(int id) | |||
| { | |||
| return await context.Set<TEntity>() | |||
| .FindAsync(id); | |||
| @@ -27,6 +26,14 @@ namespace BlackRock.Reporting.API.Persistence | |||
| { | |||
| await context.Set<TEntity>().AddAsync(entity); | |||
| } | |||
| public void Update(TEntity entity) | |||
| { | |||
| context.Set<TEntity>().Update(entity); | |||
| } | |||
| public void UpdateRange(IEnumerable<TEntity> entities) | |||
| { | |||
| context.Set<TEntity>().UpdateRange(entities); | |||
| } | |||
| public async Task AddRangeAsync(IEnumerable<TEntity> entities) | |||
| { | |||
| await context.Set<TEntity>().AddRangeAsync(entities); | |||
| @@ -5,8 +5,10 @@ namespace BlackRock.Reporting.API.Persistence | |||
| public class UnitOfWork : IUnitOfWork | |||
| { | |||
| private readonly BRDbContext context; | |||
| public UnitOfWork(BRDbContext context) | |||
| public IUsersRepository UsersRepository { get; set; } | |||
| public UnitOfWork(BRDbContext context, IUsersRepository usersRepository) | |||
| { | |||
| this.UsersRepository = usersRepository; | |||
| this.context = context; | |||
| } | |||
| @@ -1,5 +1,10 @@ | |||
| using System.Linq.Expressions; | |||
| using BlackRock.Reporting.API.Core; | |||
| using BlackRock.Reporting.API.Extensions; | |||
| using BlackRock.Reporting.API.Mediator; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| using BlackRock.Reporting.API.Models; | |||
| using Microsoft.EntityFrameworkCore; | |||
| namespace BlackRock.Reporting.API.Persistence | |||
| { | |||
| @@ -10,5 +15,39 @@ namespace BlackRock.Reporting.API.Persistence | |||
| { | |||
| this.context = context; | |||
| } | |||
| public async Task<PaggingCollection<User>> GetAllByFilter(PaggingAndFiltering queryObj) | |||
| { | |||
| var result = new PaggingCollection<User>(); | |||
| var queryResult = await context.Users.ToListAsync(); | |||
| var query = queryResult.AsQueryable(); | |||
| // filtering | |||
| if (!string.IsNullOrWhiteSpace(queryObj.EmailDomain)) | |||
| query = query.Where(q => q.Email.EndsWith(queryObj.EmailDomain.ToLower())); | |||
| // sorting | |||
| var columnsMap = new Dictionary<string, Expression<Func<User, object>>>() | |||
| { | |||
| ["name"] = u => u.Name, | |||
| ["email"] = u => u.Email | |||
| }; | |||
| query = query.ApplyOrdering(queryObj, columnsMap); | |||
| query = query.ApplyPagging(queryObj); | |||
| foreach (var item in query) | |||
| { | |||
| result.Add(item); | |||
| } | |||
| return result; | |||
| // pagging | |||
| } | |||
| public void UpdateEmail(User user, string email) | |||
| { | |||
| user.Email = email; | |||
| this.Update(user); | |||
| } | |||
| } | |||
| } | |||
| @@ -2,6 +2,8 @@ using AutoMapper; | |||
| using PuppeteerSharp; | |||
| using BlackRock.Reporting.API.Core.Models; | |||
| using BlackRock.Reporting.API.Models; | |||
| using BlackRock.Reporting.API.Mediator.Model; | |||
| using BlackRock.Reporting.API.Controllers.Dto; | |||
| namespace BlackRock.Reporting.API.Profiles | |||
| { | |||
| @@ -12,7 +14,7 @@ namespace BlackRock.Reporting.API.Profiles | |||
| { | |||
| CreateMap<OptionsForPdf, PdfOptions>().ConvertUsing<OptionsForPdfConverter>(); | |||
| CreateMap<User, UserDto>().ReverseMap(); | |||
| CreateMap<User, UserForm>().ReverseMap(); | |||
| CreateMap<User, UserCommand>().ReverseMap(); | |||
| } | |||
| } | |||
| @@ -29,3 +29,19 @@ | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||
| 2.0 | |||