initial commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
using Indotalent.ConfigBackEnd.Extensions;
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
|
||||
namespace Indotalent.Features.Leave.LeaveRequest.Cqrs;
|
||||
|
||||
public class CreateLeaveRequestRequest
|
||||
{
|
||||
public string EmployeeId { get; set; } = string.Empty;
|
||||
public string LeaveCategoryId { get; set; } = string.Empty;
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public double Days { get; set; }
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
public string Status { get; set; } = "Pending";
|
||||
public string? AttachmentPath { get; set; }
|
||||
}
|
||||
|
||||
public class CreateLeaveRequestResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? AutoNumber { get; set; }
|
||||
}
|
||||
|
||||
public record CreateLeaveRequestCommand(CreateLeaveRequestRequest Data) : IRequest<CreateLeaveRequestResponse>;
|
||||
|
||||
public class CreateLeaveRequestHandler : IRequestHandler<CreateLeaveRequestCommand, CreateLeaveRequestResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public CreateLeaveRequestHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<CreateLeaveRequestResponse> Handle(CreateLeaveRequestCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entityName = nameof(Data.Entities.LeaveRequest);
|
||||
|
||||
var autoNo = await _context.GenerateAutoNumberAsync(
|
||||
entityName: entityName,
|
||||
prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/",
|
||||
ct: cancellationToken
|
||||
);
|
||||
|
||||
var entity = new Data.Entities.LeaveRequest
|
||||
{
|
||||
AutoNumber = autoNo,
|
||||
EmployeeId = request.Data.EmployeeId,
|
||||
LeaveCategoryId = request.Data.LeaveCategoryId,
|
||||
StartDate = request.Data.StartDate,
|
||||
EndDate = request.Data.EndDate,
|
||||
Days = request.Data.Days,
|
||||
Reason = request.Data.Reason,
|
||||
Status = request.Data.Status,
|
||||
AttachmentPath = request.Data.AttachmentPath
|
||||
};
|
||||
|
||||
_context.LeaveRequest.Add(entity);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new CreateLeaveRequestResponse
|
||||
{
|
||||
Id = entity.Id,
|
||||
AutoNumber = entity.AutoNumber
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace Indotalent.Features.Leave.LeaveRequest.Cqrs;
|
||||
|
||||
public class CreateLeaveRequestValidator : AbstractValidator<CreateLeaveRequestRequest>
|
||||
{
|
||||
public CreateLeaveRequestValidator()
|
||||
{
|
||||
RuleFor(x => x.EmployeeId).NotEmpty().WithMessage("Employee is required");
|
||||
RuleFor(x => x.LeaveCategoryId).NotEmpty().WithMessage("Leave Type is required");
|
||||
RuleFor(x => x.StartDate).NotEmpty();
|
||||
RuleFor(x => x.EndDate).NotEmpty().GreaterThanOrEqualTo(x => x.StartDate).WithMessage("End Date cannot be before Start Date");
|
||||
RuleFor(x => x.Reason).NotEmpty().WithMessage("Reason is required");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Leave.LeaveRequest.Cqrs;
|
||||
|
||||
public record DeleteLeaveRequestByIdRequest(string Id);
|
||||
|
||||
public record DeleteLeaveRequestByIdCommand(DeleteLeaveRequestByIdRequest Data) : IRequest<bool>;
|
||||
|
||||
public class DeleteLeaveRequestByIdHandler : IRequestHandler<DeleteLeaveRequestByIdCommand, bool>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public DeleteLeaveRequestByIdHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<bool> Handle(DeleteLeaveRequestByIdCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _context.LeaveRequest
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Data.Id, cancellationToken);
|
||||
|
||||
if (entity == null) return false;
|
||||
|
||||
_context.LeaveRequest.Remove(entity);
|
||||
return await _context.SaveChangesAsync(cancellationToken) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Leave.LeaveRequest.Cqrs;
|
||||
|
||||
public class EmployeeLeaveReferenceResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? Code { get; set; }
|
||||
public string? FullName { get; set; }
|
||||
}
|
||||
|
||||
public record GetEmployeeLeaveReferenceQuery() : IRequest<List<EmployeeLeaveReferenceResponse>>;
|
||||
|
||||
public class GetEmployeeLeaveReferenceHandler : IRequestHandler<GetEmployeeLeaveReferenceQuery, List<EmployeeLeaveReferenceResponse>>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public GetEmployeeLeaveReferenceHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<List<EmployeeLeaveReferenceResponse>> Handle(GetEmployeeLeaveReferenceQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _context.Employee
|
||||
.AsNoTracking()
|
||||
.Where(x => x.EmployeeStatus == "Active")
|
||||
.Select(x => new EmployeeLeaveReferenceResponse
|
||||
{
|
||||
Id = x.Id,
|
||||
Code = x.Code,
|
||||
FullName = $"{x.FirstName} {x.LastName}"
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Leave.LeaveRequest.Cqrs;
|
||||
|
||||
public class GetLeaveRequestByIdResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? AutoNumber { get; set; }
|
||||
public string? EmployeeId { get; set; }
|
||||
public string? EmployeeName { get; set; }
|
||||
public string? LeaveCategoryId { get; set; }
|
||||
public string? LeaveType { get; set; }
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public double Days { get; set; }
|
||||
public string? Reason { get; set; }
|
||||
public string? Status { get; set; }
|
||||
public string? AttachmentPath { get; set; }
|
||||
public string? ApproverId { get; set; }
|
||||
public DateTime? ActionDate { get; set; }
|
||||
public string? RejectReason { get; set; }
|
||||
public DateTimeOffset? CreatedAt { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
public DateTimeOffset? UpdatedAt { get; set; }
|
||||
public string? UpdatedBy { get; set; }
|
||||
}
|
||||
|
||||
public record GetLeaveRequestByIdQuery(string Id) : IRequest<GetLeaveRequestByIdResponse?>;
|
||||
|
||||
public class GetLeaveRequestByIdHandler : IRequestHandler<GetLeaveRequestByIdQuery, GetLeaveRequestByIdResponse?>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public GetLeaveRequestByIdHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<GetLeaveRequestByIdResponse?> Handle(GetLeaveRequestByIdQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _context.LeaveRequest
|
||||
.AsNoTracking()
|
||||
.Include(x => x.Employee)
|
||||
.Include(x => x.LeaveCategory)
|
||||
.Where(x => x.Id == request.Id)
|
||||
.Select(x => new GetLeaveRequestByIdResponse
|
||||
{
|
||||
Id = x.Id,
|
||||
AutoNumber = x.AutoNumber,
|
||||
EmployeeId = x.EmployeeId,
|
||||
EmployeeName = x.Employee != null ? $"{x.Employee.FirstName} {x.Employee.LastName}" : string.Empty,
|
||||
LeaveCategoryId = x.LeaveCategoryId,
|
||||
LeaveType = x.LeaveCategory != null ? x.LeaveCategory.Name : string.Empty,
|
||||
StartDate = x.StartDate,
|
||||
EndDate = x.EndDate,
|
||||
Days = x.Days,
|
||||
Reason = x.Reason,
|
||||
Status = x.Status,
|
||||
AttachmentPath = x.AttachmentPath,
|
||||
ApproverId = x.ApproverId,
|
||||
ActionDate = x.ActionDate,
|
||||
RejectReason = x.RejectReason,
|
||||
CreatedAt = x.CreatedAt,
|
||||
CreatedBy = x.CreatedBy,
|
||||
UpdatedAt = x.UpdatedAt,
|
||||
UpdatedBy = x.UpdatedBy
|
||||
})
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using Indotalent.ConfigBackEnd.Extensions;
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Leave.LeaveRequest.Cqrs;
|
||||
|
||||
public class GetLeaveRequestListResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? AutoNumber { get; set; }
|
||||
public string? EmployeeId { get; set; }
|
||||
public string? EmployeeName { get; set; }
|
||||
public string? LeaveType { get; set; }
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public double Days { get; set; }
|
||||
public string? Reason { get; set; }
|
||||
public string? Status { get; set; }
|
||||
}
|
||||
|
||||
public record GetLeaveRequestListQuery() : IRequest<List<GetLeaveRequestListResponse>>;
|
||||
|
||||
public class GetLeaveRequestListHandler : IRequestHandler<GetLeaveRequestListQuery, List<GetLeaveRequestListResponse>>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public GetLeaveRequestListHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<List<GetLeaveRequestListResponse>> Handle(GetLeaveRequestListQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _context.LeaveRequest
|
||||
.AsNoTracking()
|
||||
.NotDeletedOnly()
|
||||
.Include(x => x.Employee)
|
||||
.Include(x => x.LeaveCategory)
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.Select(x => new GetLeaveRequestListResponse
|
||||
{
|
||||
Id = x.Id,
|
||||
AutoNumber = x.AutoNumber,
|
||||
EmployeeId = x.Employee != null ? x.Employee.Code : string.Empty,
|
||||
EmployeeName = x.Employee != null ? $"{x.Employee.FirstName} {x.Employee.LastName}" : string.Empty,
|
||||
LeaveType = x.LeaveCategory != null ? x.LeaveCategory.Name : string.Empty,
|
||||
StartDate = x.StartDate,
|
||||
EndDate = x.EndDate,
|
||||
Days = x.Days,
|
||||
Reason = x.Reason,
|
||||
Status = x.Status
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Leave.LeaveRequest.Cqrs;
|
||||
|
||||
public class UpdateLeaveRequestRequest : CreateLeaveRequestRequest
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? EmployeeName { get; set; }
|
||||
public string? LeaveType { get; set; }
|
||||
public DateTimeOffset? CreatedAt { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
public DateTimeOffset? UpdatedAt { get; set; }
|
||||
public string? UpdatedBy { get; set; }
|
||||
public string? RejectReason { get; set; }
|
||||
public string? ApproverId { get; set; }
|
||||
public DateTime? ActionDate { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateLeaveRequestResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public bool Success { get; set; }
|
||||
}
|
||||
|
||||
public record UpdateLeaveRequestCommand(UpdateLeaveRequestRequest Data) : IRequest<UpdateLeaveRequestResponse>;
|
||||
|
||||
public class UpdateLeaveRequestHandler : IRequestHandler<UpdateLeaveRequestCommand, UpdateLeaveRequestResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public UpdateLeaveRequestHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<UpdateLeaveRequestResponse> Handle(UpdateLeaveRequestCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _context.LeaveRequest
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Data.Id, cancellationToken);
|
||||
|
||||
if (entity == null)
|
||||
{
|
||||
return new UpdateLeaveRequestResponse { Id = request.Data.Id, Success = false };
|
||||
}
|
||||
|
||||
entity.EmployeeId = request.Data.EmployeeId;
|
||||
entity.LeaveCategoryId = request.Data.LeaveCategoryId;
|
||||
entity.StartDate = request.Data.StartDate;
|
||||
entity.EndDate = request.Data.EndDate;
|
||||
entity.Days = request.Data.Days;
|
||||
entity.Reason = request.Data.Reason;
|
||||
entity.Status = request.Data.Status;
|
||||
entity.AttachmentPath = request.Data.AttachmentPath;
|
||||
entity.RejectReason = request.Data.RejectReason;
|
||||
entity.ApproverId = request.Data.ApproverId;
|
||||
entity.ActionDate = request.Data.ActionDate;
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new UpdateLeaveRequestResponse
|
||||
{
|
||||
Id = entity.Id,
|
||||
Success = true
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace Indotalent.Features.Leave.LeaveRequest.Cqrs;
|
||||
|
||||
public class UpdateLeaveRequestValidator : AbstractValidator<UpdateLeaveRequestRequest>
|
||||
{
|
||||
public UpdateLeaveRequestValidator()
|
||||
{
|
||||
RuleFor(x => x.Id)
|
||||
.NotEmpty().WithMessage("ID is required for update");
|
||||
|
||||
RuleFor(x => x.EmployeeId)
|
||||
.NotEmpty().WithMessage("Employee is required");
|
||||
|
||||
RuleFor(x => x.LeaveCategoryId)
|
||||
.NotEmpty().WithMessage("Leave Type is required");
|
||||
|
||||
RuleFor(x => x.StartDate)
|
||||
.NotEmpty().WithMessage("Start Date is required");
|
||||
|
||||
RuleFor(x => x.EndDate)
|
||||
.NotEmpty()
|
||||
.GreaterThanOrEqualTo(x => x.StartDate).WithMessage("End Date cannot be before Start Date");
|
||||
|
||||
RuleFor(x => x.Reason)
|
||||
.NotEmpty().WithMessage("Reason is required");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user