initial commit
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
using Indotalent.ConfigBackEnd.Exceptions;
|
||||
using Indotalent.ConfigBackEnd.Extensions;
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class CreateEmployeeDeductionRequest
|
||||
{
|
||||
public string? EmployeeId { get; set; }
|
||||
public string? DeductionId { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
|
||||
public class CreateEmployeeDeductionResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
}
|
||||
|
||||
public record CreateEmployeeDeductionCommand(CreateEmployeeDeductionRequest Data) : IRequest<CreateEmployeeDeductionResponse>;
|
||||
|
||||
public class CreateEmployeeDeductionHandler : IRequestHandler<CreateEmployeeDeductionCommand, CreateEmployeeDeductionResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public CreateEmployeeDeductionHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<CreateEmployeeDeductionResponse> Handle(CreateEmployeeDeductionCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entityName = nameof(Data.Entities.EmployeeDeduction);
|
||||
var autoNo = await _context.GenerateAutoNumberAsync(
|
||||
entityName: entityName,
|
||||
prefixTemplate: $"EDED/{{Year}}/",
|
||||
ct: cancellationToken
|
||||
);
|
||||
|
||||
var entity = new Data.Entities.EmployeeDeduction
|
||||
{
|
||||
AutoNumber = autoNo,
|
||||
EmployeeId = request.Data.EmployeeId,
|
||||
DeductionId = request.Data.DeductionId,
|
||||
Amount = request.Data.Amount,
|
||||
Description = request.Data.Description,
|
||||
IsActive = request.Data.IsActive
|
||||
};
|
||||
|
||||
_context.EmployeeDeduction.Add(entity);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new CreateEmployeeDeductionResponse { Id = entity.Id };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using FluentValidation;
|
||||
using Indotalent.Shared.Consts;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class CreateEmployeeDeductionValidator : AbstractValidator<CreateEmployeeDeductionRequest>
|
||||
{
|
||||
public CreateEmployeeDeductionValidator()
|
||||
{
|
||||
RuleFor(x => x.EmployeeId).NotEmpty().WithMessage("Employee is required");
|
||||
RuleFor(x => x.DeductionId).NotEmpty().WithMessage("Deduction component is required");
|
||||
RuleFor(x => x.Amount).GreaterThanOrEqualTo(0).WithMessage("Amount must be 0 or greater");
|
||||
RuleFor(x => x.Description).MaximumLength(GlobalConsts.StringLengthShort);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using Indotalent.ConfigBackEnd.Exceptions;
|
||||
using Indotalent.ConfigBackEnd.Extensions;
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class CreateEmployeeRequest
|
||||
{
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
public string MiddleName { get; set; } = string.Empty;
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
public string JobDescription { get; set; } = string.Empty;
|
||||
public string GradeId { get; set; } = string.Empty;
|
||||
public decimal BasicSalary { get; set; }
|
||||
public string SalaryBankName { get; set; } = string.Empty;
|
||||
public string SalaryBankAccountName { get; set; } = string.Empty;
|
||||
public string SalaryBankAccountNumber { get; set; } = string.Empty;
|
||||
public string PlaceOfBirth { get; set; } = string.Empty;
|
||||
public DateTime? DateOfBirth { get; set; }
|
||||
public string Gender { get; set; } = string.Empty;
|
||||
public string MaritalStatus { get; set; } = string.Empty;
|
||||
public string Religion { get; set; } = string.Empty;
|
||||
public string BloodType { get; set; } = string.Empty;
|
||||
public string IdentityNumber { get; set; } = string.Empty;
|
||||
public string TaxNumber { get; set; } = string.Empty;
|
||||
public string LastEducation { get; set; } = string.Empty;
|
||||
public DateTime? JoinedDate { get; set; }
|
||||
public DateTime? ResignedDate { get; set; }
|
||||
public string EmployeeStatus { get; set; } = string.Empty;
|
||||
public string EmploymentType { get; set; } = string.Empty;
|
||||
public string StreetAddress { get; set; } = string.Empty;
|
||||
public string City { get; set; } = string.Empty;
|
||||
public string StateProvince { get; set; } = string.Empty;
|
||||
public string ZipCode { get; set; } = string.Empty;
|
||||
public string Phone { get; set; } = string.Empty;
|
||||
public string Email { get; set; } = string.Empty;
|
||||
public string BranchId { get; set; } = string.Empty;
|
||||
public string DepartmentId { get; set; } = string.Empty;
|
||||
public string DesignationId { get; set; } = string.Empty;
|
||||
public string SocialMediaLinkedIn { get; set; } = string.Empty;
|
||||
public string SocialMediaX { get; set; } = string.Empty;
|
||||
public string SocialMediaFacebook { get; set; } = string.Empty;
|
||||
public string SocialMediaInstagram { get; set; } = string.Empty;
|
||||
public string SocialMediaTikTok { get; set; } = string.Empty;
|
||||
public string OtherInformation1 { get; set; } = string.Empty;
|
||||
public string OtherInformation2 { get; set; } = string.Empty;
|
||||
public string OtherInformation3 { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class CreateEmployeeResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? Code { get; set; }
|
||||
}
|
||||
|
||||
public record CreateEmployeeCommand(CreateEmployeeRequest Data) : IRequest<CreateEmployeeResponse>;
|
||||
|
||||
public class CreateEmployeeHandler : IRequestHandler<CreateEmployeeCommand, CreateEmployeeResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public CreateEmployeeHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<CreateEmployeeResponse> Handle(CreateEmployeeCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var isExists = await _context.Employee.AnyAsync(x => x.Code == request.Data.Code, cancellationToken);
|
||||
if (isExists) throw new AlreadyExistsException("Employee", request.Data.Code);
|
||||
|
||||
var entityName = nameof(Data.Entities.Employee);
|
||||
var autoNo = await _context.GenerateAutoNumberAsync(
|
||||
entityName: entityName,
|
||||
prefixTemplate: $"EMP/{{Year}}/",
|
||||
ct: cancellationToken
|
||||
);
|
||||
|
||||
var entity = new Data.Entities.Employee
|
||||
{
|
||||
AutoNumber = autoNo,
|
||||
Code = request.Data.Code,
|
||||
FirstName = request.Data.FirstName,
|
||||
MiddleName = request.Data.MiddleName,
|
||||
LastName = request.Data.LastName,
|
||||
JobDescription = request.Data.JobDescription,
|
||||
GradeId = request.Data.GradeId,
|
||||
BasicSalary = request.Data.BasicSalary,
|
||||
SalaryBankName = request.Data.SalaryBankName,
|
||||
SalaryBankAccountName = request.Data.SalaryBankAccountName,
|
||||
SalaryBankAccountNumber = request.Data.SalaryBankAccountNumber,
|
||||
PlaceOfBirth = request.Data.PlaceOfBirth,
|
||||
DateOfBirth = request.Data.DateOfBirth,
|
||||
Gender = request.Data.Gender,
|
||||
MaritalStatus = request.Data.MaritalStatus,
|
||||
Religion = request.Data.Religion,
|
||||
BloodType = request.Data.BloodType,
|
||||
IdentityNumber = request.Data.IdentityNumber,
|
||||
TaxNumber = request.Data.TaxNumber,
|
||||
LastEducation = request.Data.LastEducation,
|
||||
JoinedDate = request.Data.JoinedDate,
|
||||
ResignedDate = request.Data.ResignedDate,
|
||||
EmployeeStatus = request.Data.EmployeeStatus,
|
||||
EmploymentType = request.Data.EmploymentType,
|
||||
StreetAddress = request.Data.StreetAddress,
|
||||
City = request.Data.City,
|
||||
StateProvince = request.Data.StateProvince,
|
||||
ZipCode = request.Data.ZipCode,
|
||||
Phone = request.Data.Phone,
|
||||
Email = request.Data.Email,
|
||||
BranchId = request.Data.BranchId,
|
||||
DepartmentId = request.Data.DepartmentId,
|
||||
DesignationId = request.Data.DesignationId,
|
||||
SocialMediaLinkedIn = request.Data.SocialMediaLinkedIn,
|
||||
SocialMediaX = request.Data.SocialMediaX,
|
||||
SocialMediaFacebook = request.Data.SocialMediaFacebook,
|
||||
SocialMediaInstagram = request.Data.SocialMediaInstagram,
|
||||
SocialMediaTikTok = request.Data.SocialMediaTikTok,
|
||||
OtherInformation1 = request.Data.OtherInformation1,
|
||||
OtherInformation2 = request.Data.OtherInformation2,
|
||||
OtherInformation3 = request.Data.OtherInformation3
|
||||
};
|
||||
|
||||
_context.Employee.Add(entity);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new CreateEmployeeResponse { Id = entity.Id, Code = entity.Code };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using Indotalent.ConfigBackEnd.Exceptions;
|
||||
using Indotalent.ConfigBackEnd.Extensions;
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class CreateEmployeeIncomeRequest
|
||||
{
|
||||
public string? EmployeeId { get; set; }
|
||||
public string? IncomeId { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
|
||||
public class CreateEmployeeIncomeResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
}
|
||||
|
||||
public record CreateEmployeeIncomeCommand(CreateEmployeeIncomeRequest Data) : IRequest<CreateEmployeeIncomeResponse>;
|
||||
|
||||
public class CreateEmployeeIncomeHandler : IRequestHandler<CreateEmployeeIncomeCommand, CreateEmployeeIncomeResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public CreateEmployeeIncomeHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<CreateEmployeeIncomeResponse> Handle(CreateEmployeeIncomeCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entityName = nameof(Data.Entities.EmployeeIncome);
|
||||
var autoNo = await _context.GenerateAutoNumberAsync(
|
||||
entityName: entityName,
|
||||
prefixTemplate: $"EINC/{{Year}}/",
|
||||
ct: cancellationToken
|
||||
);
|
||||
|
||||
var entity = new Data.Entities.EmployeeIncome
|
||||
{
|
||||
AutoNumber = autoNo,
|
||||
EmployeeId = request.Data.EmployeeId,
|
||||
IncomeId = request.Data.IncomeId,
|
||||
Amount = request.Data.Amount,
|
||||
Description = request.Data.Description,
|
||||
IsActive = request.Data.IsActive
|
||||
};
|
||||
|
||||
_context.EmployeeIncome.Add(entity);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new CreateEmployeeIncomeResponse { Id = entity.Id };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using FluentValidation;
|
||||
using Indotalent.Shared.Consts;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class CreateEmployeeIncomeValidator : AbstractValidator<CreateEmployeeIncomeRequest>
|
||||
{
|
||||
public CreateEmployeeIncomeValidator()
|
||||
{
|
||||
RuleFor(x => x.EmployeeId).NotEmpty().WithMessage("Employee is required");
|
||||
RuleFor(x => x.IncomeId).NotEmpty().WithMessage("Income component is required");
|
||||
RuleFor(x => x.Amount).GreaterThanOrEqualTo(0).WithMessage("Amount must be 0 or greater");
|
||||
RuleFor(x => x.Description).MaximumLength(GlobalConsts.StringLengthShort);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using FluentValidation;
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using Indotalent.Shared.Consts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class CreateEmployeeValidator : AbstractValidator<CreateEmployeeRequest>
|
||||
{
|
||||
public CreateEmployeeValidator()
|
||||
{
|
||||
|
||||
RuleFor(x => x.Code)
|
||||
.NotEmpty().WithMessage("Employee Code is required")
|
||||
.MaximumLength(GlobalConsts.StringLengthShort).WithMessage($"Code cannot exceed {GlobalConsts.StringLengthShort} characters");
|
||||
|
||||
RuleFor(x => x.FirstName)
|
||||
.NotEmpty().WithMessage("First Name is required")
|
||||
.MaximumLength(GlobalConsts.StringLengthShort).WithMessage($"First Name cannot exceed {GlobalConsts.StringLengthShort} characters");
|
||||
|
||||
RuleFor(x => x.LastName)
|
||||
.NotEmpty().WithMessage("Last Name is required")
|
||||
.MaximumLength(GlobalConsts.StringLengthShort).WithMessage($"Last Name cannot exceed {GlobalConsts.StringLengthShort} characters");
|
||||
|
||||
RuleFor(x => x.Email)
|
||||
.NotEmpty().WithMessage("Email is required")
|
||||
.EmailAddress().WithMessage("Invalid email format");
|
||||
|
||||
RuleFor(x => x.IdentityNumber)
|
||||
.NotEmpty().WithMessage("Identity Number is required");
|
||||
|
||||
RuleFor(x => x.JoinedDate)
|
||||
.NotEmpty().WithMessage("Joined Date is required");
|
||||
|
||||
RuleFor(x => x.BranchId)
|
||||
.NotEmpty().WithMessage("Please select a Branch");
|
||||
|
||||
RuleFor(x => x.DepartmentId)
|
||||
.NotEmpty().WithMessage("Please select a Department");
|
||||
|
||||
RuleFor(x => x.DesignationId)
|
||||
.NotEmpty().WithMessage("Please select a Designation");
|
||||
|
||||
RuleFor(x => x.GradeId)
|
||||
.NotEmpty().WithMessage("Please select a Salary Grade");
|
||||
|
||||
RuleFor(x => x.Gender)
|
||||
.NotEmpty().WithMessage("Gender is required");
|
||||
|
||||
RuleFor(x => x.Phone)
|
||||
.NotEmpty().WithMessage("Phone number is required");
|
||||
|
||||
RuleFor(x => x.BasicSalary)
|
||||
.GreaterThan(0).WithMessage("Basic Salary must be greater than 0.");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public record DeleteEmployeeByIdRequest(string Id);
|
||||
|
||||
public record DeleteEmployeeByIdCommand(DeleteEmployeeByIdRequest Data) : IRequest<bool>;
|
||||
|
||||
public class DeleteEmployeeByIdHandler : IRequestHandler<DeleteEmployeeByIdCommand, bool>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public DeleteEmployeeByIdHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<bool> Handle(DeleteEmployeeByIdCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _context.Employee
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Data.Id, cancellationToken);
|
||||
|
||||
if (entity == null) return false;
|
||||
|
||||
_context.Employee.Remove(entity);
|
||||
return await _context.SaveChangesAsync(cancellationToken) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public record DeleteEmployeeDeductionByIdRequest(string Id);
|
||||
|
||||
public record DeleteEmployeeDeductionByIdCommand(DeleteEmployeeDeductionByIdRequest Data) : IRequest<bool>;
|
||||
|
||||
public class DeleteEmployeeDeductionByIdHandler : IRequestHandler<DeleteEmployeeDeductionByIdCommand, bool>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public DeleteEmployeeDeductionByIdHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<bool> Handle(DeleteEmployeeDeductionByIdCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _context.EmployeeDeduction
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Data.Id, cancellationToken);
|
||||
|
||||
if (entity == null) return false;
|
||||
|
||||
_context.EmployeeDeduction.Remove(entity);
|
||||
return await _context.SaveChangesAsync(cancellationToken) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public record DeleteEmployeeIncomeByIdRequest(string Id);
|
||||
|
||||
public record DeleteEmployeeIncomeByIdCommand(DeleteEmployeeIncomeByIdRequest Data) : IRequest<bool>;
|
||||
|
||||
public class DeleteEmployeeIncomeByIdHandler : IRequestHandler<DeleteEmployeeIncomeByIdCommand, bool>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public DeleteEmployeeIncomeByIdHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<bool> Handle(DeleteEmployeeIncomeByIdCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _context.EmployeeIncome
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Data.Id, cancellationToken);
|
||||
|
||||
if (entity == null) return false;
|
||||
|
||||
_context.EmployeeIncome.Remove(entity);
|
||||
return await _context.SaveChangesAsync(cancellationToken) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class GetEmployeeByIdResponse
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string? AutoNumber { get; set; }
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
public string MiddleName { get; set; } = string.Empty;
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
public string JobDescription { get; set; } = string.Empty;
|
||||
public string? GradeId { get; set; }
|
||||
public decimal BasicSalary { get; set; }
|
||||
public string SalaryBankName { get; set; } = string.Empty;
|
||||
public string SalaryBankAccountName { get; set; } = string.Empty;
|
||||
public string SalaryBankAccountNumber { get; set; } = string.Empty;
|
||||
public string PlaceOfBirth { get; set; } = string.Empty;
|
||||
public DateTime? DateOfBirth { get; set; }
|
||||
public string Gender { get; set; } = string.Empty;
|
||||
public string MaritalStatus { get; set; } = string.Empty;
|
||||
public string Religion { get; set; } = string.Empty;
|
||||
public string BloodType { get; set; } = string.Empty;
|
||||
public string IdentityNumber { get; set; } = string.Empty;
|
||||
public string TaxNumber { get; set; } = string.Empty;
|
||||
public string LastEducation { get; set; } = string.Empty;
|
||||
public DateTime? JoinedDate { get; set; }
|
||||
public DateTime? ResignedDate { get; set; }
|
||||
public string EmployeeStatus { get; set; } = string.Empty;
|
||||
public string EmploymentType { get; set; } = string.Empty;
|
||||
public string StreetAddress { get; set; } = string.Empty;
|
||||
public string City { get; set; } = string.Empty;
|
||||
public string StateProvince { get; set; } = string.Empty;
|
||||
public string ZipCode { get; set; } = string.Empty;
|
||||
public string Phone { get; set; } = string.Empty;
|
||||
public string Email { get; set; } = string.Empty;
|
||||
public string BranchId { get; set; } = string.Empty;
|
||||
public string DepartmentId { get; set; } = string.Empty;
|
||||
public string DesignationId { get; set; } = string.Empty;
|
||||
public string SocialMediaLinkedIn { get; set; } = string.Empty;
|
||||
public string SocialMediaX { get; set; } = string.Empty;
|
||||
public string SocialMediaFacebook { get; set; } = string.Empty;
|
||||
public string SocialMediaInstagram { get; set; } = string.Empty;
|
||||
public string SocialMediaTikTok { get; set; } = string.Empty;
|
||||
public string OtherInformation1 { get; set; } = string.Empty;
|
||||
public string OtherInformation2 { get; set; } = string.Empty;
|
||||
public string OtherInformation3 { get; set; } = string.Empty;
|
||||
public DateTimeOffset? CreatedAt { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
public DateTimeOffset? UpdatedAt { get; set; }
|
||||
public string? UpdatedBy { get; set; }
|
||||
}
|
||||
|
||||
public record GetEmployeeByIdQuery(string Id) : IRequest<GetEmployeeByIdResponse?>;
|
||||
|
||||
public class GetEmployeeByIdHandler : IRequestHandler<GetEmployeeByIdQuery, GetEmployeeByIdResponse?>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public GetEmployeeByIdHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<GetEmployeeByIdResponse?> Handle(GetEmployeeByIdQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _context.Employee
|
||||
.AsNoTracking()
|
||||
.Where(x => x.Id == request.Id)
|
||||
.Select(x => new GetEmployeeByIdResponse
|
||||
{
|
||||
Id = x.Id,
|
||||
AutoNumber = x.AutoNumber,
|
||||
Code = x.Code,
|
||||
FirstName = x.FirstName,
|
||||
MiddleName = x.MiddleName,
|
||||
LastName = x.LastName,
|
||||
JobDescription = x.JobDescription,
|
||||
GradeId = x.GradeId,
|
||||
BasicSalary = x.BasicSalary,
|
||||
SalaryBankName = x.SalaryBankName,
|
||||
SalaryBankAccountName = x.SalaryBankAccountName,
|
||||
SalaryBankAccountNumber = x.SalaryBankAccountNumber,
|
||||
PlaceOfBirth = x.PlaceOfBirth,
|
||||
DateOfBirth = x.DateOfBirth,
|
||||
Gender = x.Gender,
|
||||
MaritalStatus = x.MaritalStatus,
|
||||
Religion = x.Religion,
|
||||
BloodType = x.BloodType,
|
||||
IdentityNumber = x.IdentityNumber,
|
||||
TaxNumber = x.TaxNumber,
|
||||
LastEducation = x.LastEducation,
|
||||
JoinedDate = x.JoinedDate,
|
||||
ResignedDate = x.ResignedDate,
|
||||
EmployeeStatus = x.EmployeeStatus,
|
||||
EmploymentType = x.EmploymentType,
|
||||
StreetAddress = x.StreetAddress,
|
||||
City = x.City,
|
||||
StateProvince = x.StateProvince,
|
||||
ZipCode = x.ZipCode,
|
||||
Phone = x.Phone,
|
||||
Email = x.Email,
|
||||
BranchId = x.BranchId,
|
||||
DepartmentId = x.DepartmentId,
|
||||
DesignationId = x.DesignationId,
|
||||
SocialMediaLinkedIn = x.SocialMediaLinkedIn,
|
||||
SocialMediaX = x.SocialMediaX,
|
||||
SocialMediaFacebook = x.SocialMediaFacebook,
|
||||
SocialMediaInstagram = x.SocialMediaInstagram,
|
||||
SocialMediaTikTok = x.SocialMediaTikTok,
|
||||
OtherInformation1 = x.OtherInformation1,
|
||||
OtherInformation2 = x.OtherInformation2,
|
||||
OtherInformation3 = x.OtherInformation3,
|
||||
CreatedAt = x.CreatedAt,
|
||||
CreatedBy = x.CreatedBy,
|
||||
UpdatedAt = x.UpdatedAt,
|
||||
UpdatedBy = x.UpdatedBy
|
||||
})
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class GetEmployeeDeductionByIdResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? DeductionId { get; set; }
|
||||
public string? DeductionName { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public record GetEmployeeDeductionByIdQuery(string Id) : IRequest<GetEmployeeDeductionByIdResponse>;
|
||||
|
||||
public class GetEmployeeDeductionByIdHandler : IRequestHandler<GetEmployeeDeductionByIdQuery, GetEmployeeDeductionByIdResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public GetEmployeeDeductionByIdHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<GetEmployeeDeductionByIdResponse> Handle(GetEmployeeDeductionByIdQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var data = await _context.EmployeeDeduction
|
||||
.Where(x => x.Id == request.Id)
|
||||
.Select(x => new GetEmployeeDeductionByIdResponse
|
||||
{
|
||||
Id = x.Id,
|
||||
DeductionId = x.DeductionId,
|
||||
DeductionName = x.Deduction != null ? x.Deduction.Name : string.Empty,
|
||||
Amount = x.Amount,
|
||||
Description = x.Description,
|
||||
IsActive = x.IsActive
|
||||
})
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
return data!;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class GetEmployeeDeductionListResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? DeductionId { get; set; }
|
||||
public string? EmployeeCode { get; set; }
|
||||
public string? DeductionName { get; set; }
|
||||
public string? DeductionCategory { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public record GetEmployeeDeductionListByEmployeeIdQuery(string EmployeeId) : IRequest<List<GetEmployeeDeductionListResponse>>;
|
||||
|
||||
public class GetEmployeeDeductionListByEmployeeIdHandler : IRequestHandler<GetEmployeeDeductionListByEmployeeIdQuery, List<GetEmployeeDeductionListResponse>>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public GetEmployeeDeductionListByEmployeeIdHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<List<GetEmployeeDeductionListResponse>> Handle(GetEmployeeDeductionListByEmployeeIdQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var data = await _context.EmployeeDeduction
|
||||
.Where(x => x.EmployeeId == request.EmployeeId)
|
||||
.Select(x => new GetEmployeeDeductionListResponse
|
||||
{
|
||||
Id = x.Id,
|
||||
DeductionId = x.DeductionId,
|
||||
EmployeeCode = x.Employee != null ? x.Employee.Code : string.Empty,
|
||||
DeductionName = x.Deduction != null ? x.Deduction.Name : string.Empty,
|
||||
DeductionCategory = x.Deduction != null ? x.Deduction.Category : string.Empty,
|
||||
Amount = x.Amount,
|
||||
Description = x.Description,
|
||||
IsActive = x.IsActive
|
||||
})
|
||||
.OrderBy(x => x.DeductionName)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class GetEmployeeIncomeByIdResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? IncomeId { get; set; }
|
||||
public string? IncomeName { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public record GetEmployeeIncomeByIdQuery(string Id) : IRequest<GetEmployeeIncomeByIdResponse>;
|
||||
|
||||
public class GetEmployeeIncomeByIdHandler : IRequestHandler<GetEmployeeIncomeByIdQuery, GetEmployeeIncomeByIdResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public GetEmployeeIncomeByIdHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<GetEmployeeIncomeByIdResponse> Handle(GetEmployeeIncomeByIdQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var data = await _context.EmployeeIncome
|
||||
.Where(x => x.Id == request.Id)
|
||||
.Select(x => new GetEmployeeIncomeByIdResponse
|
||||
{
|
||||
Id = x.Id,
|
||||
IncomeId = x.IncomeId,
|
||||
IncomeName = x.Income != null ? x.Income.Name : string.Empty,
|
||||
Amount = x.Amount,
|
||||
Description = x.Description,
|
||||
IsActive = x.IsActive
|
||||
})
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
return data!;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class GetEmployeeIncomeListResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? IncomeId { get; set; }
|
||||
public string? EmployeeCode { get; set; }
|
||||
public string? IncomeName { get; set; }
|
||||
public string? IncomeType { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public record GetEmployeeIncomeListByEmployeeIdQuery(string EmployeeId) : IRequest<List<GetEmployeeIncomeListResponse>>;
|
||||
|
||||
public class GetEmployeeIncomeListByEmployeeIdHandler : IRequestHandler<GetEmployeeIncomeListByEmployeeIdQuery, List<GetEmployeeIncomeListResponse>>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public GetEmployeeIncomeListByEmployeeIdHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<List<GetEmployeeIncomeListResponse>> Handle(GetEmployeeIncomeListByEmployeeIdQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var data = await _context.EmployeeIncome
|
||||
.Where(x => x.EmployeeId == request.EmployeeId)
|
||||
.Select(x => new GetEmployeeIncomeListResponse
|
||||
{
|
||||
Id = x.Id,
|
||||
IncomeId = x.IncomeId,
|
||||
EmployeeCode = x.Employee != null ? x.Employee.Code : string.Empty,
|
||||
IncomeName = x.Income != null ? x.Income.Name : string.Empty,
|
||||
IncomeType = x.Income != null ? x.Income.Type : string.Empty,
|
||||
Amount = x.Amount,
|
||||
Description = x.Description,
|
||||
IsActive = x.IsActive
|
||||
})
|
||||
.OrderBy(x => x.IncomeName)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using Indotalent.ConfigBackEnd.Extensions;
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class GetEmployeeListResponse
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string? AutoNumber { get; set; }
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string FullName { get; set; } = string.Empty;
|
||||
public string DesignationName { get; set; } = string.Empty;
|
||||
public string DepartmentName { get; set; } = string.Empty;
|
||||
public string BranchName { get; set; } = string.Empty;
|
||||
public string EmployeeStatus { get; set; } = string.Empty;
|
||||
public string? GradeName { get; set; }
|
||||
public decimal? BasicSalary { get; set; }
|
||||
}
|
||||
|
||||
public record GetEmployeeListQuery() : IRequest<List<GetEmployeeListResponse>>;
|
||||
|
||||
public class GetEmployeeListHandler : IRequestHandler<GetEmployeeListQuery, List<GetEmployeeListResponse>>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public GetEmployeeListHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<List<GetEmployeeListResponse>> Handle(GetEmployeeListQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var data = await _context.Employee
|
||||
.Include(x => x.Grade)
|
||||
.Include(x => x.Branch)
|
||||
.Include(x => x.Department)
|
||||
.Include(x => x.Designation)
|
||||
.AsNoTracking()
|
||||
.Select(x => new GetEmployeeListResponse
|
||||
{
|
||||
Id = x.Id,
|
||||
Code = x.Code,
|
||||
FullName = $"{x.FirstName} {x.MiddleName} {x.LastName}".Replace(" ", " "),
|
||||
DesignationName = x.Designation!.Name,
|
||||
DepartmentName = x.Department!.Name,
|
||||
BranchName = x.Branch!.Name,
|
||||
GradeName = x.Grade != null ? x.Grade.Name : string.Empty,
|
||||
BasicSalary = x.BasicSalary
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class LookupResponse
|
||||
{
|
||||
public List<LookupItem> Branches { get; set; } = new();
|
||||
public List<LookupItem> Departments { get; set; } = new();
|
||||
public List<LookupItem> Designations { get; set; } = new();
|
||||
public List<LookupItem> Grades { get; set; } = new();
|
||||
public List<LookupItem> Incomes { get; set; } = new();
|
||||
public List<LookupItem> Deductions { get; set; } = new();
|
||||
}
|
||||
|
||||
public class LookupItem
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Code { get; set; }
|
||||
public decimal SalaryFrom { get; set; }
|
||||
public decimal SalaryTo { get; set; }
|
||||
}
|
||||
|
||||
public record LookupQuery() : IRequest<LookupResponse>;
|
||||
|
||||
public class LookupHandler : IRequestHandler<LookupQuery, LookupResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public LookupHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<LookupResponse> Handle(LookupQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var response = new LookupResponse();
|
||||
|
||||
response.Branches = await _context.Branch
|
||||
.AsNoTracking()
|
||||
.Select(x => new LookupItem { Id = x.Id, Name = x.Name, Code = x.Code })
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
response.Departments = await _context.Department
|
||||
.AsNoTracking()
|
||||
.Select(x => new LookupItem { Id = x.Id, Name = x.Name, Code = x.CostCenter })
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
response.Designations = await _context.Designation
|
||||
.AsNoTracking()
|
||||
.Select(x => new LookupItem { Id = x.Id, Name = x.Name, Code = x.Code })
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
response.Grades = await _context.Grade
|
||||
.AsNoTracking()
|
||||
.Select(x => new LookupItem
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
Code = x.Code,
|
||||
SalaryFrom = x.SalaryFrom,
|
||||
SalaryTo = x.SalaryTo
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
response.Incomes = await _context.Income
|
||||
.AsNoTracking()
|
||||
.Where(x => x.Status == "Active")
|
||||
.Select(x => new LookupItem { Id = x.Id, Name = x.Name, Code = x.Code })
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
response.Deductions = await _context.Deduction
|
||||
.AsNoTracking()
|
||||
.Where(x => x.Status == "Active")
|
||||
.Select(x => new LookupItem { Id = x.Id, Name = x.Name, Code = x.Code })
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Indotalent.ConfigBackEnd.Exceptions;
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class UpdateEmployeeDeductionRequest
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? DeductionId { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateEmployeeDeductionResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
}
|
||||
|
||||
public record UpdateEmployeeDeductionCommand(UpdateEmployeeDeductionRequest Data) : IRequest<UpdateEmployeeDeductionResponse>;
|
||||
|
||||
public class UpdateEmployeeDeductionHandler : IRequestHandler<UpdateEmployeeDeductionCommand, UpdateEmployeeDeductionResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public UpdateEmployeeDeductionHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<UpdateEmployeeDeductionResponse> Handle(UpdateEmployeeDeductionCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _context.EmployeeDeduction
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Data.Id, cancellationToken);
|
||||
|
||||
if (entity == null) throw new NotFoundException("EmployeeDeduction", request.Data.Id ?? string.Empty);
|
||||
|
||||
entity.DeductionId = request.Data.DeductionId;
|
||||
entity.Amount = request.Data.Amount;
|
||||
entity.Description = request.Data.Description;
|
||||
entity.IsActive = request.Data.IsActive;
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new UpdateEmployeeDeductionResponse { Id = entity.Id };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using FluentValidation;
|
||||
using Indotalent.Shared.Consts;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class UpdateEmployeeDeductionValidator : AbstractValidator<UpdateEmployeeDeductionRequest>
|
||||
{
|
||||
public UpdateEmployeeDeductionValidator()
|
||||
{
|
||||
RuleFor(x => x.Id).NotEmpty().WithMessage("ID is required");
|
||||
RuleFor(x => x.DeductionId).NotEmpty().WithMessage("Deduction component is required");
|
||||
RuleFor(x => x.Amount).GreaterThanOrEqualTo(0).WithMessage("Amount must be 0 or greater");
|
||||
RuleFor(x => x.Description).MaximumLength(GlobalConsts.StringLengthShort);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using Indotalent.ConfigBackEnd.Exceptions;
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class UpdateEmployeeRequest : CreateEmployeeRequest
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public DateTimeOffset? CreatedAt { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
public DateTimeOffset? UpdatedAt { get; set; }
|
||||
public string? UpdatedBy { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateEmployeeResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public bool Success { get; set; }
|
||||
}
|
||||
|
||||
public record UpdateEmployeeCommand(UpdateEmployeeRequest Data) : IRequest<UpdateEmployeeResponse>;
|
||||
|
||||
public class UpdateEmployeeHandler : IRequestHandler<UpdateEmployeeCommand, UpdateEmployeeResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public UpdateEmployeeHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<UpdateEmployeeResponse> Handle(UpdateEmployeeCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _context.Employee.FirstOrDefaultAsync(x => x.Id == request.Data.Id, cancellationToken);
|
||||
if (entity == null) return new UpdateEmployeeResponse { Id = request.Data.Id, Success = false };
|
||||
|
||||
var isExists = await _context.Employee.AnyAsync(x => x.Code == request.Data.Code && x.Id != request.Data.Id, cancellationToken);
|
||||
if (isExists) throw new AlreadyExistsException("Employee", request.Data.Code);
|
||||
|
||||
entity.Code = request.Data.Code;
|
||||
entity.FirstName = request.Data.FirstName;
|
||||
entity.MiddleName = request.Data.MiddleName;
|
||||
entity.LastName = request.Data.LastName;
|
||||
entity.JobDescription = request.Data.JobDescription;
|
||||
entity.GradeId = request.Data.GradeId;
|
||||
entity.BasicSalary = request.Data.BasicSalary;
|
||||
entity.SalaryBankName = request.Data.SalaryBankName;
|
||||
entity.SalaryBankAccountName = request.Data.SalaryBankAccountName;
|
||||
entity.SalaryBankAccountNumber = request.Data.SalaryBankAccountNumber;
|
||||
entity.PlaceOfBirth = request.Data.PlaceOfBirth;
|
||||
entity.DateOfBirth = request.Data.DateOfBirth;
|
||||
entity.Gender = request.Data.Gender;
|
||||
entity.MaritalStatus = request.Data.MaritalStatus;
|
||||
entity.Religion = request.Data.Religion;
|
||||
entity.BloodType = request.Data.BloodType;
|
||||
entity.IdentityNumber = request.Data.IdentityNumber;
|
||||
entity.TaxNumber = request.Data.TaxNumber;
|
||||
entity.LastEducation = request.Data.LastEducation;
|
||||
entity.JoinedDate = request.Data.JoinedDate;
|
||||
entity.ResignedDate = request.Data.ResignedDate;
|
||||
entity.EmployeeStatus = request.Data.EmployeeStatus;
|
||||
entity.EmploymentType = request.Data.EmploymentType;
|
||||
entity.StreetAddress = request.Data.StreetAddress;
|
||||
entity.City = request.Data.City;
|
||||
entity.StateProvince = request.Data.StateProvince;
|
||||
entity.ZipCode = request.Data.ZipCode;
|
||||
entity.Phone = request.Data.Phone;
|
||||
entity.Email = request.Data.Email;
|
||||
entity.BranchId = request.Data.BranchId;
|
||||
entity.DepartmentId = request.Data.DepartmentId;
|
||||
entity.DesignationId = request.Data.DesignationId;
|
||||
entity.SocialMediaLinkedIn = request.Data.SocialMediaLinkedIn;
|
||||
entity.SocialMediaX = request.Data.SocialMediaX;
|
||||
entity.SocialMediaFacebook = request.Data.SocialMediaFacebook;
|
||||
entity.SocialMediaInstagram = request.Data.SocialMediaInstagram;
|
||||
entity.SocialMediaTikTok = request.Data.SocialMediaTikTok;
|
||||
entity.OtherInformation1 = request.Data.OtherInformation1;
|
||||
entity.OtherInformation2 = request.Data.OtherInformation2;
|
||||
entity.OtherInformation3 = request.Data.OtherInformation3;
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
return new UpdateEmployeeResponse { Id = entity.Id, Success = true };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Indotalent.ConfigBackEnd.Exceptions;
|
||||
using Indotalent.Infrastructure.Database;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class UpdateEmployeeIncomeRequest
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? IncomeId { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateEmployeeIncomeResponse
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
}
|
||||
|
||||
public record UpdateEmployeeIncomeCommand(UpdateEmployeeIncomeRequest Data) : IRequest<UpdateEmployeeIncomeResponse>;
|
||||
|
||||
public class UpdateEmployeeIncomeHandler : IRequestHandler<UpdateEmployeeIncomeCommand, UpdateEmployeeIncomeResponse>
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
public UpdateEmployeeIncomeHandler(AppDbContext context) => _context = context;
|
||||
|
||||
public async Task<UpdateEmployeeIncomeResponse> Handle(UpdateEmployeeIncomeCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _context.EmployeeIncome
|
||||
.FirstOrDefaultAsync(x => x.Id == request.Data.Id, cancellationToken);
|
||||
|
||||
if (entity == null) throw new NotFoundException("EmployeeIncome", request.Data.Id ?? string.Empty);
|
||||
|
||||
entity.IncomeId = request.Data.IncomeId;
|
||||
entity.Amount = request.Data.Amount;
|
||||
entity.Description = request.Data.Description;
|
||||
entity.IsActive = request.Data.IsActive;
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new UpdateEmployeeIncomeResponse { Id = entity.Id };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using FluentValidation;
|
||||
using Indotalent.Shared.Consts;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class UpdateEmployeeIncomeValidator : AbstractValidator<UpdateEmployeeIncomeRequest>
|
||||
{
|
||||
public UpdateEmployeeIncomeValidator()
|
||||
{
|
||||
RuleFor(x => x.Id).NotEmpty().WithMessage("ID is required");
|
||||
RuleFor(x => x.IncomeId).NotEmpty().WithMessage("Income component is required");
|
||||
RuleFor(x => x.Amount).GreaterThanOrEqualTo(0).WithMessage("Amount must be 0 or greater");
|
||||
RuleFor(x => x.Description).MaximumLength(GlobalConsts.StringLengthShort);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using FluentValidation;
|
||||
using Indotalent.Shared.Consts;
|
||||
|
||||
namespace Indotalent.Features.Organization.Employee.Cqrs;
|
||||
|
||||
public class UpdateEmployeeValidator : AbstractValidator<UpdateEmployeeRequest>
|
||||
{
|
||||
public UpdateEmployeeValidator()
|
||||
{
|
||||
RuleFor(x => x.Id)
|
||||
.NotEmpty().WithMessage("Employee ID is required for update");
|
||||
|
||||
RuleFor(x => x.Code)
|
||||
.NotEmpty().WithMessage("Employee Code is required")
|
||||
.MaximumLength(GlobalConsts.StringLengthShort).WithMessage($"Code cannot exceed {GlobalConsts.StringLengthShort} characters");
|
||||
|
||||
RuleFor(x => x.FirstName)
|
||||
.NotEmpty().WithMessage("First Name is required")
|
||||
.MaximumLength(GlobalConsts.StringLengthShort).WithMessage($"First Name cannot exceed {GlobalConsts.StringLengthShort} characters");
|
||||
|
||||
RuleFor(x => x.LastName)
|
||||
.NotEmpty().WithMessage("Last Name is required")
|
||||
.MaximumLength(GlobalConsts.StringLengthShort).WithMessage($"Last Name cannot exceed {GlobalConsts.StringLengthShort} characters");
|
||||
|
||||
RuleFor(x => x.Email)
|
||||
.NotEmpty().WithMessage("Email is required")
|
||||
.EmailAddress().WithMessage("Invalid email format");
|
||||
|
||||
RuleFor(x => x.BranchId)
|
||||
.NotEmpty().WithMessage("Please select a Branch");
|
||||
|
||||
RuleFor(x => x.DepartmentId)
|
||||
.NotEmpty().WithMessage("Please select a Department");
|
||||
|
||||
RuleFor(x => x.DesignationId)
|
||||
.NotEmpty().WithMessage("Please select a Designation");
|
||||
|
||||
RuleFor(x => x.GradeId)
|
||||
.NotEmpty().WithMessage("Please select a Salary Grade");
|
||||
|
||||
RuleFor(x => x.BasicSalary)
|
||||
.GreaterThan(0).WithMessage("Basic Salary must be greater than 0");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user