Commit 2e4f641f authored by hasan khaddour's avatar hasan khaddour

CQRS for steps and financial spends

parent 7fd9449c
......@@ -2,6 +2,7 @@
using PSManagement.Application.Customers.Common;
using PSManagement.Application.Employees.Common;
using PSManagement.Application.FinancialSpends.Common;
using PSManagement.Application.FinancialSpends.UseCases.Commands.CreateFinancialSpendItem;
using PSManagement.Application.Projects.Common;
using PSManagement.Application.Tracks.Common;
using PSManagement.Domain.Customers.Entities;
......@@ -9,7 +10,9 @@ using PSManagement.Domain.Customers.ValueObjects;
using PSManagement.Domain.Employees.Entities;
using PSManagement.Domain.FinancialSpends.Entities;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.ValueObjects;
using PSManagement.Domain.Tracking;
using PSManagement.Domain.Tracking.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
......@@ -29,20 +32,42 @@ namespace PSManagement.Application.Mappers
CreateMap<Employee, EmployeeDTO>()
.ForMember(e => e.DepartmentName, op => op.MapFrom(e => e.Department.Name));
CreateMap<EmployeeParticipateDTO, EmployeeParticipate>()
.ForMember(d=>d.Project ,op =>op.Ignore())
;
CreateMap< EmployeeParticipate, EmployeeParticipateDTO>()
.ForMember(d => d.ProjectInfo, op => op.MapFrom(e => e.Project.ProjectInfo));
.ForMember(d => d.ProjectInfo, opt => opt.MapFrom(s => s.Project.ProjectInfo))
.ForMember(d => d.Employee, op => op.MapFrom(e => e.Employee))
CreateMap<EmployeeParticipate, EmployeeParticipateDTO>()
.ForMember(d => d.ProjectInfo, op => op.MapFrom(e=>e.Project.ProjectInfo));
;
CreateMap<Project, ProjectInfo>()
.ConvertUsing(project => project.ProjectInfo);
CreateMap<TrackDTO, Track>().ReverseMap();
CreateMap<StepTrack, StepTrackDTO>()
.ForMember(d => d.TrackDate, op=> op.MapFrom( src => src.Track.TrackDate));
CreateMap<FinancialSpendingDTO, FinancialSpending>().ReverseMap();
CreateMap<Project, ProjectDTO>().ReverseMap();
CreateMap <CreateFinancialSpendItemCommand,FinancialSpending> ()
.ForMember(d=>d.Id, op => op.Ignore())
.ForMember(d=> d.Events, op => op.Ignore())
.ConstructUsing(src => new FinancialSpending(
src.ProjectId,
src.LocalPurchase,
src.ExternalPurchase,
src.CostType,
src.Description,
src.ExpectedSpendingDate
))
;
}
}
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.Logging;
using System.Threading;
using PSManagement.SharedKernel.CQRS.Command;
namespace PSManagement.Application.Behaviors.LoggingBehavior
{
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : ILoggableCommand<TResponse>
{
private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;
public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger)
{
_logger = logger;
}
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var requestName = typeof(TRequest).Name;
_logger.LogInformation("Starting request: {RequestName} at {DateTime}", requestName, DateTime.UtcNow);
try
{
var response = await next();
_logger.LogInformation("Completed request: {RequestName} at {DateTime}", requestName, DateTime.UtcNow);
return response;
}
catch (Exception ex)
{
_logger.LogError(ex, "Request {RequestName} failed at {DateTime}", requestName, DateTime.UtcNow);
throw;
}
}
}
}
......@@ -7,6 +7,8 @@ using AutoMapper;
using PSManagement.Application.Mappers;
using FluentValidation;
using PSManagement.Application.Behaviors.ValidationBehavior;
using PSManagement.Application.Behaviors.LoggingBehavior;
using MapperConfiguration = PSManagement.Application.Mappers.MapperConfiguration;
namespace PSManagement.Application.DI
{
......@@ -18,15 +20,16 @@ namespace PSManagement.Application.DI
services.AddMediatR(typeof(DependencyInjection).Assembly);
// Register the pipeline behaviors explicitly
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
// Register FluentValidation validators
services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
services.AddAutoMapper(typeof(Mappers.MapperConfiguration));
services.AddAutoMapper(cfg => {
cfg.AddProfile<MapperConfiguration>();
});
return services;
}
......
......@@ -21,7 +21,10 @@ namespace PSManagement.Application.Employees.UseCases.Commands.UpdateEmployeeWor
public async Task<Result> Handle(UpdateEmployeeWorkHoursCommand request, CancellationToken cancellationToken)
{
Employee employee =await _employeesRepository.GetByIdAsync(request.EmployeeId);
if (request.WorkingHour < _workHourLimit)
if (employee is null) {
return Result.Invalid(EmployeesErrors.EmployeeUnExist);
}
if (request.WorkingHour < _workHourLimit && request.WorkingHour > 0)
{
employee.Availability = new(request.WorkingHour, employee.Availability.IsAvailable);
......
......@@ -35,10 +35,13 @@ namespace PSManagement.Application.Employees.UseCases.Queries.GetEmployeeById
_specification.ApplyPaging((pageNumber - 1) * pageSize, pageSize);
_specification.AddInclude(e => e.Project);
_specification.AddInclude("Employee.Department");
_specification.AddInclude(e => e.Employee);
IEnumerable<EmployeeParticipate> response = await _employeesParticipateRepository.ListAsync(_specification);
response =response.Where(e => e.EmployeeId == request.EmployeeId);
response =response.Where(e => e.EmployeeId == request.EmployeeId).ToList();
return Result.Success(_mapper.Map<IEnumerable<EmployeeParticipateDTO>>(response));
}
......
using Ardalis.Result;
using PSManagement.SharedKernel.CQRS.Command;
using PSManagement.SharedKernel.ValueObjects;
using System;
namespace PSManagement.Application.FinancialSpends.UseCases.Commands.CreateFinancialSpendItem
{
public record CreateFinancialSpendItemCommand(
int ProjectId,
Money ExternalPurchase,
int LocalPurchase,
string CostType,
string Description,
DateTime ExpectedSpendingDate
) : ICommand<Result<int>>;
}
using Ardalis.Result;
using AutoMapper;
using PSManagement.Domain.FinancialSpends.Entities;
using PSManagement.Domain.FinincialSpending.Repositories;
using PSManagement.Domain.Projects.DomainErrors;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Command;
using PSManagement.SharedKernel.Interfaces;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.FinancialSpends.UseCases.Commands.CreateFinancialSpendItem
{
public class CreateFinancialSpendItemCommandHandler : ICommandHandler<CreateFinancialSpendItemCommand, Result<int>>
{
private readonly IProjectsRepository _projectsRepository;
private readonly IFinancialSpendingRepository _spendRepository;
private readonly IUnitOfWork _unitOfWork;
private readonly IMapper _mapper;
public CreateFinancialSpendItemCommandHandler(
IFinancialSpendingRepository spendRepository,
IProjectsRepository projectsRepository,
IUnitOfWork unitOfWork,
IMapper mapper)
{
_spendRepository = spendRepository;
_projectsRepository = projectsRepository;
_unitOfWork = unitOfWork;
_mapper = mapper;
}
public async Task<Result<int>> Handle(CreateFinancialSpendItemCommand request, CancellationToken cancellationToken)
{
Project project = await _projectsRepository.GetByIdAsync(request.ProjectId);
if (project is null)
{
return Result.Invalid(ProjectsErrors.InvalidEntryError);
}
else
{
FinancialSpending spending = await _spendRepository.AddAsync(new (request.ProjectId,request.LocalPurchase,request.ExternalPurchase,request.CostType,request.Description,request.ExpectedSpendingDate));
await _unitOfWork.SaveChangesAsync();
return Result.Success(spending.Id);
}
}
}
}
using Ardalis.Result;
using PSManagement.SharedKernel.CQRS.Command;
namespace PSManagement.Application.FinancialSpends.UseCases.Commands.RemoveFinancialSpendingItem
{
public record RemoveFinancialSpendItemCommand(
int ProjectId,
int Id
) : ICommand<Result>;
}
using Ardalis.Result;
using AutoMapper;
using PSManagement.Domain.FinancialSpends.Entities;
using PSManagement.Domain.FinincialSpending.Repositories;
using PSManagement.Domain.Projects.DomainErrors;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Command;
using PSManagement.SharedKernel.Interfaces;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.FinancialSpends.UseCases.Commands.RemoveFinancialSpendingItem
{
public class RemoveFinancialSpendItemCommandHandler : ICommandHandler<RemoveFinancialSpendItemCommand, Result>
{
private readonly IProjectsRepository _projectsRepository;
private readonly IFinancialSpendingRepository _spendRepository;
private readonly IUnitOfWork _unitOfWork;
public RemoveFinancialSpendItemCommandHandler(
IFinancialSpendingRepository spendRepository,
IProjectsRepository projectsRepository,
IUnitOfWork unitOfWork)
{
_spendRepository = spendRepository;
_projectsRepository = projectsRepository;
_unitOfWork = unitOfWork;
}
public async Task<Result> Handle(RemoveFinancialSpendItemCommand request, CancellationToken cancellationToken)
{
Project project = await _projectsRepository.GetByIdAsync(request.ProjectId);
if (project is null)
{
return Result.Invalid(ProjectsErrors.InvalidEntryError);
}
else
{
FinancialSpending spending = await _spendRepository.GetByIdAsync(request.Id);
if (spending is null) {
return Result.NotFound();
}
await _spendRepository.DeleteAsync(spending);
await _unitOfWork.SaveChangesAsync();
return Result.Success();
}
}
}
}
using Ardalis.Result;
using PSManagement.SharedKernel.CQRS.Command;
using PSManagement.SharedKernel.ValueObjects;
using System;
namespace PSManagement.Application.FinancialSpends.UseCases.Commands.UpateFinancialSpendingItem
{
public record UpdateFinancialSpendItemCommand(
int ProjectId,
int Id,
Money ExternalPurchase,
int LocalPurchase,
string CostType,
string Description,
DateTime ExpectedSpendingDate
) : ICommand<Result>;
}
using Ardalis.Result;
using AutoMapper;
using PSManagement.Domain.FinancialSpends.Entities;
using PSManagement.Domain.FinincialSpending.Repositories;
using PSManagement.Domain.Projects.DomainErrors;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Command;
using PSManagement.SharedKernel.Interfaces;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.FinancialSpends.UseCases.Commands.UpateFinancialSpendingItem
{
public class UpdateFinancialSpendItemCommandHandler : ICommandHandler<UpdateFinancialSpendItemCommand, Result>
{
private readonly IProjectsRepository _projectsRepository;
private readonly IFinancialSpendingRepository _spendRepository;
private readonly IUnitOfWork _unitOfWork;
private readonly IMapper _mapper;
public UpdateFinancialSpendItemCommandHandler(
IFinancialSpendingRepository spendRepository,
IProjectsRepository projectsRepository,
IUnitOfWork unitOfWork,
IMapper mapper)
{
_spendRepository = spendRepository;
_projectsRepository = projectsRepository;
_unitOfWork = unitOfWork;
_mapper = mapper;
}
public async Task<Result> Handle(UpdateFinancialSpendItemCommand request, CancellationToken cancellationToken)
{
Project project = await _projectsRepository.GetByIdAsync(request.ProjectId);
if (project is null)
{
return Result.Invalid(ProjectsErrors.InvalidEntryError);
}
else
{
FinancialSpending spending = await _spendRepository.GetByIdAsync(request.Id);
if (spending is null)
{
return Result.NotFound();
}
await _spendRepository.UpdateAsync(_mapper.Map<FinancialSpending>(request));
await _unitOfWork.SaveChangesAsync();
return Result.Success();
}
}
}
}
using Ardalis.Result;
using PSManagement.Application.FinancialSpends.Common;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Command;
using PSManagement.SharedKernel.CQRS.Query;
using PSManagement.SharedKernel.ValueObjects;
using System;
namespace PSManagement.Application.FinancialSpends.UseCases.Queries.GetFinancialSpendingById
{
public record GetFinancialSpendItemByIdQuery(
int Id) : IQuery<Result<FinancialSpendingDTO>>;
}
using Ardalis.Result;
using AutoMapper;
using PSManagement.Application.FinancialSpends.Common;
using PSManagement.Domain.FinancialSpends.Entities;
using PSManagement.Domain.FinincialSpending.Repositories;
using PSManagement.SharedKernel.CQRS.Query;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.FinancialSpends.UseCases.Queries.GetFinancialSpendingById
{
public class GetFinancialSpendItemByIdQueryHandler : IQueryHandler<GetFinancialSpendItemByIdQuery, Result<FinancialSpendingDTO>>
{
private readonly IFinancialSpendingRepository _spendRepository;
private readonly IMapper _mapper;
public GetFinancialSpendItemByIdQueryHandler(
IMapper mapper,
IFinancialSpendingRepository spendRepository
)
{
_mapper = mapper;
_spendRepository = spendRepository;
}
public async Task<Result<FinancialSpendingDTO>> Handle(GetFinancialSpendItemByIdQuery request, CancellationToken cancellationToken)
{
FinancialSpending spending = await _spendRepository.GetByIdAsync(request.Id);
if (spending is null) {
return Result.NotFound("Not Found");
}
return Result.Success(_mapper.Map<FinancialSpendingDTO>(spending));
}
}
}
using Ardalis.Result;
using PSManagement.Application.FinancialSpends.Common;
using PSManagement.Domain.Projects.Entities;
using PSManagement.SharedKernel.CQRS.Query;
using System.Collections.Generic;
namespace PSManagement.Application.FinancialSpends.UseCases.Queries.GetFinancialSpendingByProject
{
public record GetFinancialSpendItemByProjectQuery(
int ProjectId,
int? PageNumber,
int? PageSize) : IQuery<Result<IEnumerable<FinancialSpendingDTO>>>;
}
using Ardalis.Result;
using AutoMapper;
using PSManagement.Application.FinancialSpends.Common;
using PSManagement.Domain.FinancialSpends.Entities;
using PSManagement.Domain.FinancialSpends.Specification;
using PSManagement.Domain.FinincialSpending.Repositories;
using PSManagement.SharedKernel.CQRS.Query;
using PSManagement.SharedKernel.Specification;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.FinancialSpends.UseCases.Queries.GetFinancialSpendingByProject
{
public class GetFinancialSpendItemByProjectQueryHandler : IQueryHandler<GetFinancialSpendItemByProjectQuery, Result<IEnumerable<FinancialSpendingDTO>>>
{
private readonly IFinancialSpendingRepository _spendRepository;
private readonly IMapper _mapper;
private readonly BaseSpecification<FinancialSpending> _specification;
public GetFinancialSpendItemByProjectQueryHandler(
IMapper mapper,
IFinancialSpendingRepository spendRepository)
{
_mapper = mapper;
_spendRepository = spendRepository;
_specification = new FinancialSpendingSpecification();
}
public async Task<Result<IEnumerable<FinancialSpendingDTO>>> Handle(GetFinancialSpendItemByProjectQuery request, CancellationToken cancellationToken)
{
_specification.Criteria = p => p.ProjectId == request.ProjectId;
int pageNumber = request.PageNumber.HasValue && request.PageNumber.Value > 0 ? request.PageNumber.Value : 1;
int pageSize = request.PageSize.HasValue && request.PageSize.Value > 0 && request.PageSize.Value <= 30 ? request.PageSize.Value : 30;
_specification.ApplyPaging((pageNumber - 1) * pageSize, pageSize);
IEnumerable<FinancialSpending> spending = await _spendRepository.ListAsync(_specification);
if (spending is null)
{
return Result.NotFound("Not Found");
}
return Result.Success(_mapper.Map<IEnumerable<FinancialSpendingDTO>>(spending));
}
}
}
......@@ -7,26 +7,15 @@
<ItemGroup>
<Folder Include="Behaviors\AuthorizationBehavior\" />
<Folder Include="Behaviors\LoggingBehavior\" />
<Folder Include="FinancialSpends\UseCases\Commands\CreateFinancialSpendingItem\" />
<Folder Include="FinancialSpends\UseCases\Commands\RemoveFinancialSpendingItem\" />
<Folder Include="FinancialSpends\UseCases\Commands\UpateFinancialSpendingItem\" />
<Folder Include="FinancialSpends\UseCases\Queries\GetFinancialSpendingByProject\" />
<Folder Include="FinancialSpends\UseCases\Queries\GetFinancialSpendingById\" />
<Folder Include="Projects\UseCases\Queries\GetProjectPlan\" />
<Folder Include="Steps\UseCases\Queries\GetStepsByProject\" />
<Folder Include="Employees\UseCases\Commands\InreesEmployeeWorkHours\" />
<Folder Include="Projects\UseCases\Queries\GetProjectAttachments\" />
<Folder Include="XReports\UseCases\" />
<Folder Include="XReports\UseCases\Queries\" />
<Folder Include="Steps\UseCases\Commands\ChangeStepWeight\" />
<Folder Include="Steps\UseCases\Commands\UpdateCompletionRatio\" />
<Folder Include="Steps\UseCases\Commands\RemoveStep\" />
<Folder Include="Steps\UseCases\Queries\GetStep\" />
<Folder Include="Steps\UseCases\Queries\GetStepHistory\" />
<Folder Include="Tracks\UseCaes\Commands\CreateTrack\" />
<Folder Include="Tracks\UseCaes\Commands\AddStepsTrack\" />
<Folder Include="Tracks\UseCaes\Commands\AddEmployeesTrack\" />
<Folder Include="Tracks\UseCaes\Commands\RemoveTrack\" />
<Folder Include="Tracks\UseCaes\Commands\SaveTrack\" />
<Folder Include="Tracks\UseCaes\Commands\CompleteTrack\" />
<Folder Include="Tracks\UseCaes\Commands\UpdateEmployeeTrack\" />
<Folder Include="Tracks\UseCaes\Commands\UpdateStepTrack\" />
<Folder Include="Tracks\UseCaes\Commands\UpdateTrack\" />
......@@ -49,6 +38,7 @@
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
......
......@@ -4,7 +4,6 @@ using PSManagement.Domain.Customers.Entities;
using PSManagement.Domain.Employees.Entities;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.ValueObjects;
using PSManagement.Domain.ProjectsStatus.Entites;
using System;
using System.Collections.Generic;
......
......@@ -8,10 +8,10 @@ using System.Text;
namespace PSManagement.Application.Projects.UseCases.Commands.AddParticipant
{
public record AddParticipantCommand(
public record AddParticipantCommand(
int ProjectId,
int ParticipantId,
int PartialTimeRatio,
String Role
):ICommand<Result>;
String Role
) : ICommand<Result>;
}
......@@ -18,5 +18,5 @@ namespace PSManagement.Application.Projects.UseCases.Commands.CreateProject
int ProjectManagerId,
int ProposerId,
int ExecuterId
) : ICommand<Result<CreateProjectResult>>;
) : ILoggableCommand<Result<CreateProjectResult>>;
}
using Ardalis.Result;
using AutoMapper;
using PSManagement.Application.Projects.Common;
using PSManagement.Domain.Projects;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Query;
using PSManagement.SharedKernel.Specification;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
......@@ -14,6 +17,7 @@ namespace PSManagement.Application.Projects.UseCases.Queries.GetParticipants
{
private readonly IProjectsRepository _projectRepository;
private readonly IMapper _mapper;
private readonly BaseSpecification<Project> _specification;
public GetProjectParticipantsQueryHandler(
IProjectsRepository projectRepository,
......@@ -21,6 +25,7 @@ namespace PSManagement.Application.Projects.UseCases.Queries.GetParticipants
{
_projectRepository = projectRepository;
_mapper = mapper;
_specification = new ProjectSpecification();
}
public async Task<Result<IEnumerable<EmployeeParticipateDTO>>> Handle(GetProjectParticipantsQuery request, CancellationToken cancellationToken)
......@@ -30,8 +35,11 @@ namespace PSManagement.Application.Projects.UseCases.Queries.GetParticipants
{
return Result.NotFound("Project not found");
}
_specification.AddInclude(p => p.EmployeeParticipates);
_specification.AddInclude("EmployeeParticipates.Employee");
_specification.AddInclude("EmployeeParticipates.Project");
IEnumerable<EmployeeParticipateDTO> result = _mapper.Map<IEnumerable<EmployeeParticipateDTO>>(_projectRepository.GetProjectParticipants(request.ProjectId));
IEnumerable<EmployeeParticipateDTO> result = _mapper.Map<IEnumerable<EmployeeParticipateDTO>>(_projectRepository.GetProjectParticipants(request.ProjectId,_specification));
if (result is null)
{
result = new List<EmployeeParticipateDTO>();
......
using Ardalis.Result;
using PSManagement.SharedKernel.CQRS.Command;
using PSManagement.SharedKernel.Interfaces;
namespace PSManagement.Application.Steps.UseCases.Commands.ChangeStepWeight
{
public record ChangeStepWeightCommand(
int StepId,
int Weight
) : ICommand<Result>;
}
using Ardalis.Result;
using PSManagement.Domain.Projects.DomainErrors;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Command;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.Steps.UseCases.Commands.ChangeStepWeight
{
public class ChangeStepWeightCommandHandler : ICommandHandler<ChangeStepWeightCommand, Result>
{
private readonly IStepsRepository _stepsRepository;
public ChangeStepWeightCommandHandler(IStepsRepository stepsRepository)
{
_stepsRepository = stepsRepository;
}
public async Task<Result> Handle(ChangeStepWeightCommand request, CancellationToken cancellationToken)
{
Step step = await _stepsRepository.GetByIdAsync(request.StepId);
if (step is null)
{
return Result.Invalid(StepsErrors.InvalidEntryError);
}
else
{
if (request.Weight < 0) {
return Result.Invalid(StepsErrors.InvalidWeightError);
}
step.Weight = request.Weight;
await _stepsRepository.UpdateAsync(step);
return Result.Success();
}
}
}
}
using Ardalis.Result;
using PSManagement.SharedKernel.CQRS.Command;
namespace PSManagement.Application.Steps.UseCases.Commands.RemoveStep
{
public record RemoveStepCommand(
int StepId
) : ICommand<Result>;
}
using Ardalis.Result;
using PSManagement.Domain.Projects.DomainErrors;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Command;
using PSManagement.SharedKernel.Interfaces;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.Steps.UseCases.Commands.RemoveStep
{
public class RemoveStepCommandHandler : ICommandHandler<RemoveStepCommand, Result>
{
private readonly IStepsRepository _stepsRepository;
private readonly IUnitOfWork _unitOfWork;
public RemoveStepCommandHandler(IStepsRepository stepsRepository, IUnitOfWork unitOfWork)
{
_stepsRepository = stepsRepository;
_unitOfWork = unitOfWork;
}
public async Task<Result> Handle(
RemoveStepCommand request,
CancellationToken cancellationToken
)
{
Step step = await _stepsRepository.GetByIdAsync(request.StepId);
if (step is null)
{
return Result.Invalid(StepsErrors.InvalidEntryError);
}
else
{
await _stepsRepository.DeleteAsync(step);
await _unitOfWork.SaveChangesAsync();
return Result.Success();
}
}
}
}
using Ardalis.Result;
using PSManagement.SharedKernel.CQRS.Command;
namespace PSManagement.Application.Steps.UseCases.Commands.UpdateCompletionRatio
{
public record UpdateCompletionRatioCommand(
int StepId,
int CompletionRatio
) : ICommand<Result>;
}
using Ardalis.Result;
using PSManagement.Domain.Projects.DomainErrors;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Command;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.Steps.UseCases.Commands.UpdateCompletionRatio
{
public class UpdateCompleteionRatioCommandHandler : ICommandHandler<UpdateCompletionRatioCommand, Result>
{
private readonly IStepsRepository _stepsRepository;
public UpdateCompleteionRatioCommandHandler(IStepsRepository stepsRepository)
{
_stepsRepository = stepsRepository;
}
public async Task<Result> Handle(UpdateCompletionRatioCommand request, CancellationToken cancellationToken)
{
Step step = await _stepsRepository.GetByIdAsync(request.StepId);
if (step is null)
{
return Result.Invalid(StepsErrors.InvalidEntryError);
}
else
{
if (request.CompletionRatio < step.CurrentCompletionRatio)
{
return Result.Invalid(StepsErrors.InvalidCompletionRatioError);
}
step.CurrentCompletionRatio = request.CompletionRatio;
await _stepsRepository.UpdateAsync(step);
return Result.Success();
}
}
}
}
using Ardalis.Result;
using PSManagement.Application.Projects.Common;
using PSManagement.SharedKernel.CQRS.Query;
namespace PSManagement.Application.Steps.UseCases.Queries.GetStepById
{
public record GetStepByIdQuery(
int StepId
) : IQuery<Result<StepDTO>>;
}
using Ardalis.Result;
using AutoMapper;
using PSManagement.Application.Projects.Common;
using PSManagement.Domain.Projects.DomainErrors;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Query;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.Steps.UseCases.Queries.GetStepById
{
public class GetStepByIdQueryHandler : IQueryHandler<GetStepByIdQuery, Result<StepDTO>>
{
private readonly IStepsRepository _stepsRepository;
private readonly IMapper _mapper;
public GetStepByIdQueryHandler(
IStepsRepository stepsRepository,
IMapper mapper)
{
_stepsRepository = stepsRepository;
_mapper = mapper;
}
public async Task<Result<StepDTO>> Handle(GetStepByIdQuery request, CancellationToken cancellationToken)
{
Step step = await _stepsRepository.GetByIdAsync(request.StepId);
if (step is null)
{
return Result.Invalid(StepsErrors.InvalidEntryError);
}
else
{
return Result.Success(_mapper.Map<StepDTO>(step));
}
}
}
}
using Ardalis.Result;
using PSManagement.Application.Tracks.Common;
using PSManagement.SharedKernel.CQRS.Query;
using System.Collections.Generic;
namespace PSManagement.Application.Steps.UseCases.Queries.GetStepTrackHistory
{
public record GetStepTrackHistoryQuery(
int StepId,
int? PageNumber,
int ? PageSize
) : IQuery<Result<IEnumerable<StepTrackDTO>>>;
}
using Ardalis.Result;
using AutoMapper;
using PSManagement.Application.Tracks.Common;
using PSManagement.Domain.Projects;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Query;
using PSManagement.SharedKernel.Specification;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
namespace PSManagement.Application.Steps.UseCases.Queries.GetStepTrackHistory
{
public class GetStepTrackHistoryQueryHandler : IQueryHandler<GetStepTrackHistoryQuery, Result<IEnumerable<StepTrackDTO>>>
{
private readonly IStepsRepository _stepsRepository;
private readonly BaseSpecification<Step> _specification;
private readonly IMapper _mapper;
public GetStepTrackHistoryQueryHandler(
IStepsRepository stepsRepository,
IMapper mapper)
{
_stepsRepository = stepsRepository;
_specification = new StepSpecification();
_mapper = mapper;
}
public async Task<Result<IEnumerable<StepTrackDTO>>> Handle(GetStepTrackHistoryQuery request, CancellationToken cancellationToken)
{
int pageNumber = request.PageNumber.HasValue && request.PageNumber.Value > 0 ? request.PageNumber.Value : 1;
int pageSize = request.PageSize.HasValue && request.PageSize.Value > 0 && request.PageSize.Value <= 30 ? request.PageSize.Value : 30;
_specification.AddInclude(e => e.StepTracks);
_specification.AddInclude("StepTracks.Track");
_specification.ApplyPaging((pageNumber - 1) * pageSize, pageSize);
var steps = await _stepsRepository.GetByIdAsync(request.StepId,_specification);
return Result.Success(_mapper.Map<IEnumerable<StepTrackDTO>>(steps.StepTracks.AsEnumerable()));
}
}
}
using Ardalis.Result;
using PSManagement.Application.Projects.Common;
using PSManagement.SharedKernel.CQRS.Query;
using System.Collections.Generic;
namespace PSManagement.Application.Steps.UseCases.Queries.GetStepsByProject
{
public record GetStepsByProjectQuery(
int ProjectId,
int? PageSize,
int? PageNumber
) : IQuery<Result<IEnumerable<StepDTO>>>;
}
using Ardalis.Result;
using AutoMapper;
using PSManagement.Application.Projects.Common;
using PSManagement.Domain.Projects;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Query;
using PSManagement.SharedKernel.Specification;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.Steps.UseCases.Queries.GetStepsByProject
{
public class GetStepsByProjectQueryHandler : IQueryHandler<GetStepsByProjectQuery, Result<IEnumerable<StepDTO>>>
{
private readonly IStepsRepository _stepsRepository;
private readonly BaseSpecification<Step> _specification;
private readonly IMapper _mapper;
public GetStepsByProjectQueryHandler(
IMapper mapper,
IStepsRepository projectsRepository)
{
_mapper = mapper;
_stepsRepository = projectsRepository;
_specification = new StepSpecification();
}
public async Task<Result<IEnumerable<StepDTO>>> Handle(GetStepsByProjectQuery request, CancellationToken cancellationToken)
{
int pageNumber = request.PageNumber.HasValue && request.PageNumber.Value > 0 ? request.PageNumber.Value : 1;
int pageSize = request.PageSize.HasValue && request.PageSize.Value > 0 && request.PageSize.Value <= 30 ? request.PageSize.Value : 30;
_specification.ApplyPaging((pageNumber - 1) * pageSize, pageSize);
var steps = await _stepsRepository.ListAsync(_specification);
return Result.Success(_mapper.Map<IEnumerable<StepDTO>>(steps));
}
}
}
namespace PSManagement.Application.Tracks.Common
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.ValueObjects;
using System;
namespace PSManagement.Application.Tracks.Common
{
public class StepTrackDTO
{
public int StepId { get; set; }
public int TrackId { get; set; }
public String ExecutionState { get; set; }
public DateTime TrackDate { get; set; }
public int ExecutionRatio { get; set; }
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment