hrms-api-backend/BMA.EHR.Leave/Controllers/LeaveRequestController.cs
Suphonchai Phoonsawat 3e3bfff7ba
All checks were successful
Build & Deploy Leave Service / build (push) Successful in 1m51s
Refactor leave date overlap check in LeaveRequestController for improved readability and performance
2026-03-26 14:10:37 +07:00

2866 lines
No EOL
138 KiB
C#

using BMA.EHR.Application.Repositories;
using BMA.EHR.Application.Repositories.Commands;
using BMA.EHR.Application.Repositories.Leaves.LeaveRequests;
using BMA.EHR.Application.Repositories.Leaves.TimeAttendants;
using BMA.EHR.Application.Repositories.MetaData;
using BMA.EHR.Application.Responses.Profiles;
using BMA.EHR.Domain.Common;
using BMA.EHR.Domain.Extensions;
using BMA.EHR.Domain.Models.Leave.Commons;
using BMA.EHR.Domain.Models.Leave.Requests;
using BMA.EHR.Domain.Models.Notifications;
using BMA.EHR.Domain.Shared;
using BMA.EHR.Infrastructure.Persistence;
using BMA.EHR.Leave.Service.DTOs.LeaveRequest;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NodaTime;
using Org.BouncyCastle.Asn1.Pkcs;
using Sentry;
using Swashbuckle.AspNetCore.Annotations;
using System.Net.Http.Headers;
using System.Security.Claims;
namespace BMA.EHR.Leave.Service.Controllers
{
[Route("api/v{version:apiVersion}/leave")]
[ApiVersion("1.0")]
[ApiController]
[Produces("application/json")]
[Authorize]
[SwaggerTag("API ระบบลงเวลาและการลา (การลา)")]
public class LeaveRequestController : BaseController
{
#region " Fields "
private readonly LeaveDbContext _context;
private readonly ApplicationDBContext _appDbContext;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IWebHostEnvironment _hostingEnvironment;
private readonly IConfiguration _configuration;
private readonly UserProfileRepository _userProfileRepository;
private readonly LeaveTypeRepository _leaveTypeRepository;
private readonly LeaveRequestRepository _leaveRequestRepository;
private readonly MinIOLeaveService _minIOService;
private readonly HolidayRepository _holidayRepository;
private readonly CommandRepository _commandRepository;
private readonly UserCalendarRepository _userCalendarRepository;
private readonly PermissionRepository _permission;
private readonly LeaveBeginningRepository _leaveBeginningRepository;
private const string APPROVE_STEP_CREATE = "st1";
private const string APPROVE_STEP_OFFICER_APPROVE = "st2";
private const string APPROVE_STEP_COMMANDER_APPROVE = "st3";
private const string APPROVE_STEP_APPROVE = "st4";
private const string APPROVE_STEP_REJECT = "st5";
private readonly string URL = string.Empty;
#endregion
#region " Constuctor and Destructor "
public LeaveRequestController(LeaveDbContext context,
IHttpContextAccessor httpContextAccessor,
IWebHostEnvironment hostingEnvironment,
IConfiguration configuration,
UserProfileRepository userProfileRepository,
LeaveTypeRepository leaveTypeRepository,
LeaveRequestRepository leaveRequestRepository,
MinIOLeaveService minIOService,
HolidayRepository holidayRepository,
CommandRepository commandRepository,
UserCalendarRepository userCalendarRepository,
PermissionRepository permission,
LeaveBeginningRepository leaveBeginningRepository,
ApplicationDBContext appDbContext)
{
_context = context;
_httpContextAccessor = httpContextAccessor;
_hostingEnvironment = hostingEnvironment;
_configuration = configuration;
_userProfileRepository = userProfileRepository;
_leaveTypeRepository = leaveTypeRepository;
_leaveRequestRepository = leaveRequestRepository;
_minIOService = minIOService;
_holidayRepository = holidayRepository;
_commandRepository = commandRepository;
_userCalendarRepository = userCalendarRepository;
_permission = permission;
_leaveBeginningRepository = leaveBeginningRepository;
_appDbContext = appDbContext;
URL = (_configuration["VITE_URL_MGT"]).Replace("/api/v1", "");
}
#endregion
#region " Properties "
private string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
private string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value;
private bool? PlacementAdmin => _httpContextAccessor?.HttpContext?.User?.IsInRole("placement1");
protected string? AccessToken => _httpContextAccessor?.HttpContext?.Request.Headers["Authorization"];
private Guid OcId
{
get
{
if (UserId != null || UserId != "")
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
else
return Guid.Empty;
}
}
#endregion
#region " Methods "
/// <summary>
/// เพิ่มรายชิื่อผู้อนุมัติ หรือ ผู้บังคับบัญชา
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost("officer/add-approver/{type}/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> AddApprover(string type, Guid id, [FromBody] List<LeaveRequestApproverDto> req)
{
try
{
var leaveReq = await _leaveRequestRepository.GetByIdAsync(id);
if (leaveReq == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
await _leaveRequestRepository.RemoveApproversAsync(id, type);
//var delete = leaveReq.Approvers.RemoveAll(x => x.ApproveType.ToUpper() == type.Trim().ToUpper());
//await _leaveRequestRepository.UpdateAsync(leaveReq);
var addList = new List<LeaveRequestApprover>();
foreach (var r in req)
{
addList.Add(new LeaveRequestApprover
{
Seq = r.Seq,
Prefix = r.Prefix,
FirstName = r.FirstName,
LastName = r.LastName,
PositionName = r.PositionName,
PositionSign = r.PositionSign,
PosExecutiveName = r.PosExecutiveName,
PositionLevelName = r.PositionLeaveName,
OrganizationName = r.OrganizationName,
ProfileId = r.ProfileId,
KeycloakId = r.KeycloakId,
ApproveStatus = "PENDING",
ApproveType = type.Trim().ToUpper(),
CreatedFullName = FullName ?? "",
CreatedUserId = UserId!,
CreatedAt = DateTime.Now,
LastUpdateFullName = FullName ?? "",
LastUpdateUserId = UserId!,
LastUpdatedAt = DateTime.Now,
});
}
await _leaveRequestRepository.AddApproversAsync(id, addList);
return Success();
}
catch (Exception ex)
{
return Error(ex);
}
}
/// <summary>
/// LV2_001 - สร้างคำขอการลา (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost("user")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> CreateLeaveRequestAsync([FromForm] CreateLeaveRequestDto req)
{
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
// var isDuplicate = await _leaveRequestRepository.CheckDuplicateLeave(userId, req.LeaveStartDate.Date, req.LeaveEndDate.Date);
// if (isDuplicate)
// {
// return Error("ไม่สามารถขอลาในช่วงเวลาเดียวกันได้ เนื่องจากมีการขอลาในช่วงเวลาดังกล่าวแล้ว");
// }
var thisYear = DateTime.Now.Year;
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
var profile = await _userProfileRepository.GetProfileByKeycloakIdNewAsync(userId, AccessToken);
if (profile == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
//var userCalendar = await _userCalendarRepository.GetExist(profile.Id);
//var category = userCalendar == null ? "NORMAL" : userCalendar.Calendar;
var leaveType = await _leaveTypeRepository.GetByIdAsync(req.Type);
if (leaveType == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
//var sumLeave = req.LeaveStartDate.DiffDay(req.LeaveEndDate);
//var sumHoliday = await _holidayRepository.GetHolidayCountAsync(req.LeaveStartDate, req.LeaveEndDate, category);
//var sumWeekend = _holidayRepository.GetWeekEndCount(req.LeaveStartDate, req.LeaveEndDate, category);
// var leaveTotal = 0.0;
// if (req.LeaveRange != "ALL")
// leaveTotal = 0.5;
// else
// {
// switch (leaveType.Code.ToUpper().Trim())
// {
// case "LV-001":
// }
// leaveTotal = sumLeave - sumHoliday - sumWeekend;
// }
var leaveRequest = new LeaveRequest
{
Type = leaveType,
LeaveSubTypeName = req.LeaveSubTypeName,
LeaveRange = req.LeaveRange,
LeaveRangeEnd = req.LeaveRangeEnd,
LeaveStartDate = req.LeaveStartDate,
LeaveEndDate = req.LeaveEndDate,
LeaveWrote = req.LeaveWrote ?? "",
LeaveDetail = req.LeaveDetail ?? "",
LeaveAddress = req.LeaveAddress ?? "",
LeaveNumber = req.LeaveNumber ?? "",
//LeaveTotal = req.LeaveStartDate.DiffDay(req.LeaveEndDate),
LeaveTotal = req.LeaveTotal, // แก้ไขให้รับค่ามาจาก request แทน
LeaveSalaryText = req.LeaveSalaryText ?? "",
LeaveStatus = "DRAFT",
KeycloakUserId = userId,
ApproveStep = APPROVE_STEP_CREATE,
Prefix = profile.Prefix,
FirstName = profile.FirstName,
LastName = profile.LastName,
CitizenId = profile.CitizenId,
Root = profile.Root,
Child1 = profile.Child1,
Child2 = profile.Child2,
Child3 = profile.Child3,
Child4 = profile.Child4,
RootId = profile.RootId,
Child1Id = profile.Child1Id,
Child2Id = profile.Child2Id,
Child3Id = profile.Child3Id,
Child4Id = profile.Child4Id,
Gender = profile.Gender,
ProfileId = profile.Id,
ProfileType = profile.ProfileType,
Amount = profile.Amount,
BirthDate = profile.BirthDate,
DateAppoint = profile.DateAppoint,
RootDnaId = profile.RootDnaId,
Child1DnaId = profile.Child1DnaId,
Child2DnaId = profile.Child2DnaId,
Child3DnaId = profile.Child3DnaId,
Child4DnaId = profile.Child4DnaId,
};
// get leave last
leaveRequest.LeaveLast = await _leaveRequestRepository.GetLeaveLastByTypeForUserAsync(userId, req.Type);
// upload document
if (req.LeaveDocument != null)
{
foreach (var d in req.LeaveDocument)
{
var doc = await _minIOService.UploadFileAsync(d);
if (doc != null)
{
leaveRequest.LeaveDocument.Add(new LeaveDocument { Document = doc });
var a = leaveRequest.LeaveDocument.Last();
_context.Entry(a).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
}
}
}
// upload draft document
if (req.LeaveDraftDocument != null)
{
var doc = await _minIOService.UploadFileAsync(req.LeaveDraftDocument);
if (doc != null)
{
leaveRequest.LeaveDraftDocument = doc;
_context.Entry(leaveRequest.LeaveDraftDocument).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
}
}
// switch from leave type
switch (leaveType.Code.Trim().ToUpper())
{
case "LV-004":
{
leaveRequest.WifeDayName = req.WifeDayName ?? "";
leaveRequest.WifeDayDateBorn = req.WifeDayDateBorn ?? "";
}
break;
case "LV-005":
{
leaveRequest.RestDayOldTotal =
await _leaveRequestRepository.GetRestDayTotalByYearForUserAsync(userId, thisYear - 1);
leaveRequest.RestDayCurrentTotal =
await _leaveRequestRepository.GetRestDayTotalByYearForUserAsync(userId, thisYear);
}
break;
case "LV-006":
{
leaveRequest.OrdainDayStatus = req.OrdainDayStatus ?? false;
leaveRequest.OrdainDayLocationName = req.OrdainDayLocationName ?? "";
leaveRequest.OrdainDayLocationAddress = req.OrdainDayLocationAddress ?? "";
leaveRequest.OrdainDayLocationNumber = req.OrdainDayLocationNumber ?? "";
if (req.OrdainDayOrdination != null)
leaveRequest.OrdainDayOrdination = req.OrdainDayOrdination.Value;
leaveRequest.OrdainDayBuddhistLentName = req.OrdainDayBuddhistLentName ?? "";
leaveRequest.OrdainDayBuddhistLentAddress = req.OrdainDayBuddhistLentAddress ?? "";
leaveRequest.LeaveBirthDate = profile.BirthDate;
leaveRequest.LeaveGovernmentDate = profile.DateStart;
leaveRequest.HajjDayStatus = req.HajjDayStatus ?? false;
}
break;
case "LV-007":
{
leaveRequest.AbsentDayLocation = req.AbsentDayLocation ?? "";
leaveRequest.AbsentDaySummon = req.AbsentDaySummon ?? "";
if (req.AbsentDayRegistorDate != null)
leaveRequest.AbsentDayRegistorDate = req.AbsentDayRegistorDate.Value;
leaveRequest.AbsentDayGetIn = req.AbsentDayGetIn ?? "";
leaveRequest.AbsentDayAt = req.AbsentDayAt ?? "";
}
break;
case "LV-008":
{
// var lastSalary = profile.ProfileSalary;
// var lastSalaryAmount = lastSalary == null ? 0 : lastSalary.Amount == null ? 0 : lastSalary.Amount;
// var lastSalaryAmountText = lastSalary == null ? "" : lastSalary.Amount == null ? "" : ((int)lastSalary.Amount).ToThaiBahtText(false);
// leaveRequest.LeaveSalary = (int)lastSalaryAmount;
// leaveRequest.LeaveSalaryText = lastSalaryAmountText;
leaveRequest.LeaveSalary = profile.Amount.HasValue && profile.Amount > 0
? (int)profile.Amount : 0;
leaveRequest.LeaveSalaryText = profile.Amount.HasValue && profile.Amount > 0
? ((int)profile.Amount).ToThaiBahtText(false) : "";
//leaveRequest.LeaveSalary = lastSalary == null ? 0 : (int)lastSalary.Amount.Value;
//leaveRequest.LeaveSalaryText =
// lastSalary == null ? "" : ((int)lastSalary.Amount.Value).ToThaiBahtText(false);
leaveRequest.LeaveBirthDate = profile.BirthDate;
leaveRequest.LeaveGovernmentDate = profile.DateStart;
leaveRequest.StudyDaySubject = req.StudyDaySubject ?? "";
leaveRequest.StudyDayDegreeLevel = req.StudyDayDegreeLevel ?? "";
leaveRequest.StudyDayUniversityName = req.StudyDayUniversityName ?? "";
leaveRequest.StudyDayCountry = req.StudyDayCountry ?? "";
leaveRequest.StudyDayScholarship = req.StudyDayScholarship ?? "";
leaveRequest.StudyDayTrainingSubject = req.StudyDayTrainingSubject ?? "";
leaveRequest.StudyDayTrainingName = req.StudyDayTrainingName ?? "";
}
break;
case "LV-010":
{
// var lastSalary = profile.ProfileSalary;
// var lastSalaryAmount = lastSalary == null ? 0 : lastSalary.Amount == null ? 0 : lastSalary.Amount;
// var lastSalaryAmountText = lastSalary == null ? "" : lastSalary.Amount == null ? "" : ((int)lastSalary.Amount).ToThaiBahtText(false);
// leaveRequest.LeaveSalary = (int)lastSalaryAmount;
// leaveRequest.LeaveSalaryText = lastSalaryAmountText;
leaveRequest.LeaveSalary = profile.Amount.HasValue && profile.Amount > 0
? (int)profile.Amount : 0;
leaveRequest.LeaveSalaryText = profile.Amount.HasValue && profile.Amount > 0
? ((int)profile.Amount).ToThaiBahtText(false) : "";
//leaveRequest.LeaveSalary = lastSalary == null ? 0 : (int)lastSalary.Amount.Value;
//leaveRequest.LeaveSalaryText =
// lastSalary == null ? "" : ((int)lastSalary.Amount.Value).ToThaiBahtText(false);
leaveRequest.CoupleDayName = req.CoupleDayName ?? "";
leaveRequest.CoupleDayPosition = req.CoupleDayPosition ?? "";
leaveRequest.CoupleDayLevel = req.CoupleDayLevel ?? "";
leaveRequest.CoupleDayLevelCountry = req.CoupleDayLevelCountry ?? "";
leaveRequest.CoupleDayCountryHistory = req.CoupleDayCountryHistory ?? "";
leaveRequest.CoupleDayTotalHistory = req.CoupleDayTotalHistory ?? "";
if (req.CoupleDayStartDateHistory != null)
leaveRequest.CoupleDayStartDateHistory = req.CoupleDayStartDateHistory.Value;
if (req.CoupleDayEndDateHistory != null)
leaveRequest.CoupleDayEndDateHistory = req.CoupleDayEndDateHistory.Value;
leaveRequest.CoupleDaySumTotalHistory = req.CoupleDaySumTotalHistory ?? "";
}
break;
}
// add dear and oc_data
//var rootOc = _userProfileRepository.GetRootOcId(profile.OcId ?? Guid.Empty, AccessToken);
// var approver = profile.Commander ?? "";
var userOc = profile.Root ?? "";
//if (rootOc != null)
//{
// var list = await _commandRepository.GetOrgApproverAsync(rootOc ?? Guid.Empty);
// if (list.Count > 0)
// approver = list.First().Name;
//}
leaveRequest.LeaveTypeCode = leaveType.Code;
leaveRequest.Dear = req.Dear ?? "";
leaveRequest.CommanderPosition = req.CommanderPosition ?? "";
// เพิ่มตำแหน่ง
//leaveRequest.CommanderPosition = req.CommanderPosition ?? "";
leaveRequest.PositionName = profile.Position == null ? "" : profile.Position;
leaveRequest.PositionLevelName = profile.PosLevel == null ? "" : profile.PosLevel;
leaveRequest.OrganizationName = userOc;
//if (req.Approvers != null && req.Approvers != "")
//{
// //var jsonString = System.Text.Json.JsonSerializer.Deserialize<string>(req.Approvers ?? "");
// //var fixedJson = req.Approvers.Replace("\\\"", "\"");
// var approvers = JsonConvert.DeserializeObject<List<LeaveRequestApproverDto>>(req.Approvers);
// if (approver != null)
// {
// foreach (var r in approvers!)
// {
// leaveRequest.Approvers.Add(new LeaveRequestApprover
// {
// Seq = r.Seq,
// Prefix = r.Prefix,
// FirstName = r.FirstName,
// LastName = r.LastName,
// PositionName = r.PositionName,
// ProfileId = r.ProfileId,
// KeycloakId = r.KeycloakId,
// ApproveStatus = "PENDING",
// });
// }
// }
//}
// save to database
await _leaveRequestRepository.AddAsync(leaveRequest);
return Success(new { id = leaveRequest.Id });
}
[HttpGet("update-leave-root")]
[AllowAnonymous]
public async Task<IActionResult> UpdateRootForLeaveRequestAsync()
{
var leaves = await _context.Set<LeaveRequest>().ToListAsync();
foreach (var leave in leaves)
{
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(leave.KeycloakUserId, AccessToken);
var profile = await _userProfileRepository.GetProfileByKeycloakIdNewAsync(leave.KeycloakUserId, AccessToken);
if (profile != null)
{
leave.Prefix = profile.Prefix;
leave.FirstName = profile.FirstName;
leave.LastName = profile.LastName;
leave.CitizenId = profile.CitizenId;
leave.PositionName = profile.Position == null ? "" : profile.Position;
leave.PositionLevelName = profile.PosLevel == null ? "" : profile.PosLevel;
leave.OrganizationName = profile.Root ?? "";
leave.Root = profile.Root ?? "";
leave.Child1 = profile.Child1 ?? "";
leave.Child2 = profile.Child2 ?? "";
leave.Child3 = profile.Child3 ?? "";
leave.Child4 = profile.Child4 ?? "";
}
}
await _context.SaveChangesAsync();
return Ok("update success");
}
/// <summary>
/// LV2_020 - แก้ไขคำขอการลา
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPut("user/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> EditLeaveRequestAsync(Guid id, [FromForm] CreateLeaveRequestDto req)
{
try
{
var oldData = await _leaveRequestRepository.GetByIdAsync(id);
if (oldData == null)
{
return Error(GlobalMessages.DataNotFound);
}
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
var thisYear = DateTime.Now.Year;
// var isDuplicate = await _leaveRequestRepository.CheckDuplicateLeave(userId, req.LeaveStartDate.Date, req.LeaveEndDate.Date);
// if (isDuplicate)
// {
// return Error("ไม่สามารถขอลาในช่วงเวลาเดียวกันได้");
// }
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
var profile = await _userProfileRepository.GetProfileByKeycloakIdNewAsync(userId, AccessToken);
if (profile == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
var userCalendar = await _userCalendarRepository.GetExist(profile.Id);
var category = userCalendar == null ? "NORMAL" : userCalendar.Calendar;
var leaveType = await _context.Set<LeaveType>().AsNoTracking().FirstOrDefaultAsync(x => x.Id == req.Type); // _leaveTypeRepository.GetByIdAsync(req.Type);
if (leaveType == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
var sumLeave = req.LeaveStartDate.DiffDay(req.LeaveEndDate);
var sumHoliday = await _holidayRepository.GetHolidayCountAsync(req.LeaveStartDate, req.LeaveEndDate, category);
var sumWeekend = _holidayRepository.GetWeekEndCount(req.LeaveStartDate, req.LeaveEndDate, category);
// var leaveTotal = 0.0;
// if (req.LeaveRange != "ALL")
// leaveTotal = 0.5;
// else
// leaveTotal = sumLeave - sumHoliday - sumWeekend;
// ลองใช้ oldData
oldData.LeaveRange = req.LeaveRange;
oldData.LeaveRangeEnd = req.LeaveRangeEnd;
oldData.LeaveStartDate = req.LeaveStartDate;
oldData.LeaveEndDate = req.LeaveEndDate;
oldData.LeaveWrote = req.LeaveWrote ?? "";
oldData.LeaveDetail = req.LeaveDetail ?? "";
oldData.LeaveAddress = req.LeaveAddress ?? "";
oldData.LeaveNumber = req.LeaveNumber ?? "";
oldData.LeaveTotal = req.LeaveTotal;
oldData.LeaveSalaryText = req.LeaveSalaryText ?? "";
//oldData.CommanderPosition = req.CommanderPosition ?? "";
/*** remove old code
var leaveRequest = new LeaveRequest
{
Id = id,
Type = leaveType,
LeaveRange = req.LeaveRange,
LeaveStartDate = req.LeaveStartDate,
LeaveEndDate = req.LeaveEndDate,
LeaveWrote = req.LeaveWrote ?? "",
LeaveDetail = req.LeaveDetail ?? "",
LeaveAddress = req.LeaveAddress ?? "",
LeaveNumber = req.LeaveNumber ?? "",
//LeaveTotal = req.LeaveStartDate.DiffDay(req.LeaveEndDate),
LeaveTotal = req.LeaveTotal, // change to get value from request
LeaveSalaryText = req.LeaveSalaryText ?? "",
LeaveStatus = oldData.LeaveStatus,
KeycloakUserId = userId,
ApproveStep = oldData.ApproveStep
};
// assign old upload documents to new request
leaveRequest.LeaveDraftDocument = oldData.LeaveDraftDocument;
leaveRequest.LeaveDocument.AddRange(oldData.LeaveDocument);
leaveRequest.LeaveCancelDocument = oldData.LeaveCancelDocument;
// get leave last
leaveRequest.LeaveLast = await _leaveRequestRepository.GetLeaveLastByTypeForUserAsync(userId, req.Type);
**/
// switch from leave type
switch (leaveType.Code.Trim().ToUpper())
{
case "LV-004":
{
oldData.WifeDayName = req.WifeDayName ?? "";
oldData.WifeDayDateBorn = req.WifeDayDateBorn ?? "";
}
break;
case "LV-005":
{
oldData.RestDayOldTotal =
await _leaveRequestRepository.GetRestDayTotalByYearForUserAsync(userId, thisYear - 1);
oldData.RestDayCurrentTotal =
await _leaveRequestRepository.GetRestDayTotalByYearForUserAsync(userId, thisYear);
}
break;
case "LV-006":
{
oldData.OrdainDayStatus = req.OrdainDayStatus ?? false;
oldData.OrdainDayLocationName = req.OrdainDayLocationName ?? "";
oldData.OrdainDayLocationAddress = req.OrdainDayLocationAddress ?? "";
oldData.OrdainDayLocationNumber = req.OrdainDayLocationNumber ?? "";
if (req.OrdainDayOrdination != null)
oldData.OrdainDayOrdination = req.OrdainDayOrdination.Value;
oldData.OrdainDayBuddhistLentName = req.OrdainDayBuddhistLentName ?? "";
oldData.OrdainDayBuddhistLentAddress = req.OrdainDayBuddhistLentAddress ?? "";
oldData.LeaveBirthDate = profile.BirthDate;
oldData.LeaveGovernmentDate = profile.DateStart;
oldData.HajjDayStatus = req.HajjDayStatus ?? false;
}
break;
case "LV-007":
{
oldData.AbsentDayLocation = req.AbsentDayLocation ?? "";
oldData.AbsentDaySummon = req.AbsentDaySummon ?? "";
if (req.AbsentDayRegistorDate != null)
oldData.AbsentDayRegistorDate = req.AbsentDayRegistorDate.Value;
oldData.AbsentDayGetIn = req.AbsentDayGetIn ?? "";
oldData.AbsentDayAt = req.AbsentDayAt ?? "";
}
break;
case "LV-008":
{
// var lastSalary = profile.ProfileSalary;
// oldData.LeaveSalary = lastSalary == null ? 0 : (int)lastSalary.Amount.Value;
// oldData.LeaveSalaryText =
// lastSalary == null ? "" : ((int)lastSalary.Amount.Value).ToThaiBahtText(false);
oldData.LeaveSalary = profile.Amount.HasValue && profile.Amount > 0
? (int)profile.Amount : 0;
oldData.LeaveSalaryText = profile.Amount.HasValue && profile.Amount > 0
? ((int)profile.Amount).ToThaiBahtText(false) : "";
oldData.LeaveBirthDate = profile.BirthDate;
oldData.LeaveGovernmentDate = profile.DateStart;
oldData.StudyDaySubject = req.StudyDaySubject ?? "";
oldData.StudyDayDegreeLevel = req.StudyDayDegreeLevel ?? "";
oldData.StudyDayUniversityName = req.StudyDayUniversityName ?? "";
oldData.StudyDayCountry = req.StudyDayCountry ?? "";
oldData.StudyDayScholarship = req.StudyDayScholarship ?? "";
oldData.StudyDayTrainingSubject = req.StudyDayTrainingSubject ?? "";
oldData.StudyDayTrainingName = req.StudyDayTrainingName ?? "";
}
break;
case "LV-010":
{
// var lastSalary = profile.ProfileSalary;
// oldData.LeaveSalary = lastSalary == null ? 0 : (int)lastSalary.Amount.Value;
// oldData.LeaveSalaryText =
// lastSalary == null ? "" : ((int)lastSalary.Amount.Value).ToThaiBahtText(false);
oldData.LeaveSalary = profile.Amount.HasValue && profile.Amount > 0
? (int)profile.Amount : 0;
oldData.LeaveSalaryText = profile.Amount.HasValue && profile.Amount > 0
? ((int)profile.Amount).ToThaiBahtText(false) : "";
oldData.CoupleDayName = req.CoupleDayName ?? "";
oldData.CoupleDayPosition = req.CoupleDayPosition ?? "";
oldData.CoupleDayLevel = req.CoupleDayLevel ?? "";
oldData.CoupleDayLevelCountry = req.CoupleDayLevelCountry ?? "";
oldData.CoupleDayCountryHistory = req.CoupleDayCountryHistory ?? "";
oldData.CoupleDayTotalHistory = req.CoupleDayTotalHistory ?? "";
if (req.CoupleDayStartDateHistory != null)
oldData.CoupleDayStartDateHistory = req.CoupleDayStartDateHistory.Value;
if (req.CoupleDayEndDateHistory != null)
oldData.CoupleDayEndDateHistory = req.CoupleDayEndDateHistory.Value;
oldData.CoupleDaySumTotalHistory = req.CoupleDaySumTotalHistory ?? "";
}
break;
}
// add dear and oc_data
//var rootOc = _userProfileRepository.GetRootOcId(profile.OcId ?? Guid.Empty, AccessToken);
//var approver = string.Empty;
//if (rootOc != null)
//{
// var list = await _commandRepository.GetOrgApproverAsync(rootOc ?? Guid.Empty);
// if (list.Count > 0)
// approver = list.First().Name;
//}
oldData.LeaveTypeCode = leaveType.Code;
oldData.Dear = req.Dear ?? "";
oldData.CommanderPosition = req.CommanderPosition ?? "";
oldData.PositionName = profile.Position == null ? "" : profile.Position;
oldData.PositionLevelName = profile.PosLevel == null ? "" : profile.PosLevel;
oldData.OrganizationName = profile.Oc ?? "";
_context.Entry(oldData.Type).State = Microsoft.EntityFrameworkCore.EntityState.Detached;
//_context.Entry(leaveRequest.Type).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
// delete old
//await _leaveRequestRepository.DeleteAsync(oldData);
// save to database
await _leaveRequestRepository.UpdateAsync(oldData);
// upload document
if (req.LeaveDocument != null)
{
foreach (var d in req.LeaveDocument)
{
var doc = await _minIOService.UploadFileAsync(d);
if (doc != null)
{
// add new record
await _leaveRequestRepository.AddLeaveDocumentAsync(id, new LeaveDocument { Document = doc });
//oldData.LeaveDocument.Add(new LeaveDocument { Document = doc });
//var a = oldData.LeaveDocument.Last();
//_context.Entry(a).State = Microsoft.EntityFrameworkCore.EntityState.Added;
}
}
}
// upload draft document
if (req.LeaveDraftDocument != null)
{
var doc = await _minIOService.UploadFileAsync(req.LeaveDraftDocument);
if (doc != null)
{
oldData.LeaveDraftDocument = doc;
_context.Entry(oldData.LeaveDraftDocument).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
}
// save to database
await _leaveRequestRepository.UpdateAsync(oldData);
}
return Success(new { id = oldData.Id });
}
catch (Exception ex)
{
return Error(ex);
}
}
/// <summary>
/// LV2_038 - ลบรายการการลา (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpDelete("user/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> DeleteLeaveRequestAsync(Guid id)
{
var deleted = await _leaveRequestRepository.GetByIdAsync(id);
if (deleted == null)
return Error(GlobalMessages.DataNotFound);
if (deleted.LeaveStatus != "DRAFT")
{
return Error("ไม่สามารถลบคำร้องขอลาที่นำส่งแล้วได้");
}
await _leaveRequestRepository.DeleteAsync(deleted);
return Success();
}
/// <summary>
/// LV2_002 - ข้อมูลที่ user ขอยื่นลา (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost("user/profile")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetUserLeaveProfileAsync([FromBody] GetUserLeaveProfileDto req)
{
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
var thisYear = DateTime.Now.Year;
var toDay = DateTime.Now.Date;
var startFiscalDate = new DateTime(DateTime.Now.Year, 10, 1);
var endFiscalDate = new DateTime(DateTime.Now.Year + 1, 9, 30);
if (toDay >= startFiscalDate && toDay <= endFiscalDate)
thisYear = thisYear + 1;
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
if (profile == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
var govAge = (profile?.DateStart?.Date ?? DateTime.Now.Date).DiffDay(DateTime.Now.Date);
var leaveType = await _leaveTypeRepository.GetByIdAsync(req.Type);
if (leaveType == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
var leaveLimit = 0.0;
var orgName = "";
if (profile.Child4 != null && profile.Child4 != "")
orgName += $" {profile.Child4}";
if (profile.Child3 != null && profile.Child3 != "")
orgName += $" {profile.Child3}";
if (profile.Child2 != null && profile.Child2 != "")
orgName += $" {profile.Child2}";
if (profile.Child1 != null && profile.Child1 != "")
orgName += $" {profile.Child1}";
if (profile.Root != null && profile.Root != "")
orgName += $" {profile.Root}";
var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUserAsync(thisYear, req.Type, userId);
if (leaveType.Code.Trim().ToUpper() == "LV-005")
{
// if (profile.IsProbation! == true)
// leaveLimit = 0;
// else
{
leaveLimit = leaveData == null ?
10
: leaveData.LeaveDays;
}
}
else
leaveLimit = leaveType.Limit;
var restOldDay = leaveData == null ? 0 : leaveData.LeaveDays - 10;
var restCurrentDay = 10.0;
// if (profile.IsProbation! == true)
// {
// restOldDay = 0;
// restCurrentDay = 0;
// }
if(restOldDay < 0)
restOldDay = 0;
var sumLeave = leaveData == null ? 0 : leaveData.LeaveDaysUsed;
// var lastSalary = profile.ProfileSalary;
var leaveLast = await _leaveRequestRepository.GetLeaveLastByTypeForUserAsync(userId, req.Type);
var result = new GetUserLeaveProfileResultDto
{
DateSendLeave = DateTime.Now.Date,
LeaveTypeName = leaveType.Name,
FullName = $"{profile.Prefix}{profile.FirstName} {profile.LastName}",
Dear = profile.Commander ?? "",
CommanderPosition = profile.CommanderPositionName ?? "",
PositionName = profile.Position == null ? "" : profile.Position,
PositionLevelName = profile.PosLevel == null ? "" : profile.PosLevel,
OrganizationName = orgName, //profile.Oc ?? "",
LeaveLimit = leaveLimit, // จำนวนวันลาทั้งหมดในปีนั้นๆที่ลาได้ โดยรวมยอดที่เหลือจากปีก่อนมา (เอาค่ามาจากตาราง Beginning เลย)
LeaveTotal = sumLeave, // จำนวนวันลาที่ลาไปแล้วในปีนั้นๆ โดยเมื่อมีการอนุมัติลา จะมาบวกค่านี้ไปเรื่อยๆ (เอาค่ามาจากตาราง Beginning เลย)
LeaveRemain = leaveLimit - sumLeave,
RestDayTotalOld = restOldDay, // เอา leaveLimit มาลบ 10 (LV-005)
RestDayTotalCurrent = restCurrentDay,// 10 วันเสมอ (LV-005)
BirthDate = profile.BirthDate.Date,
DateAppoint = profile.DateAppoint == null ? null : profile.DateAppoint.Value.Date,
// Salary = lastSalary == null ? 0 : lastSalary.Amount == null ? 0 : (int)lastSalary.Amount.Value,
// SalaryText = lastSalary == null ? "" : lastSalary.Amount == null ? "" : ((int)lastSalary.Amount.Value).ToThaiBahtText(false),
Salary = profile.Amount.HasValue && profile.Amount > 0
? (int)profile.Amount : 0,
SalaryText = profile.Amount.HasValue && profile.Amount > 0
? ((int)profile.Amount).ToThaiBahtText(false) : "",
LeaveLast = leaveLast == null ? null : leaveLast,
TelephoneNumber = profile.TelephoneNumber ?? "",
CurrentAddress = profile.CurrentAddress ?? "",
CurrentSubDistrict = profile.CurrentSubDistrict ?? "",
CurrentDistrict = profile.CurrentDistrict ?? "",
CurrentProvince = profile.CurrentProvince ?? "",
CurrentZipCode = profile.CurrentZipCode ?? "",
GovAge = govAge
};
return Success(result);
}
[HttpGet("time-check")]
[AllowAnonymous]
public async Task<ActionResult<ResponseObject>> TimeCheckAsync()
{
var startDate = new DateTime(2017, 1, 6);
var govAge = (startDate).DiffDay(DateTime.Now.Date);
var date1Raw = startDate;
var date1 = new LocalDate(date1Raw.Year, date1Raw.Month, date1Raw.Day);
var date2 = new LocalDate(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
var (govAgeYear, govAgeMonth, govAgeDay) = startDate.GetDifference(DateTime.Now.Date);
var isLeave = false;
var message = string.Empty;
if (govAgeYear >= 1 || (govAgeYear == 0 && govAgeMonth >= 6))
{
isLeave = true;
if (!isLeave) message = "จำนวนวันลาเกินที่กำหนด";
}
else
{
isLeave = false;
if (!isLeave) message = "อายุราชการน้อยกว่า 6 เดือนหรือ 180 วัน";
}
return Success(new
{
GovAge = govAge,
GovAgeDay = govAgeDay,
GovAgeMonth = govAgeMonth,
GovAgeYear = govAgeYear,
IsLeave = isLeave,
Message = message
});
}
/// <summary>
/// LV2_003 - เช็คการยืนขอลา (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost("user/check")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> CheckUserLeaveAsync([FromBody] GetLeaveCheckDto req)
{
var totalDay = (double)req.StartLeaveDate.DiffDay(req.EndLeaveDate.Date);
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
var profile = await _userProfileRepository.GetProfileByKeycloakIdNewAsync(userId, AccessToken);
var govAge = (profile?.DateStart?.Date ?? DateTime.Now.Date).DiffDay(DateTime.Now.Date);
var startDate = profile?.DateStart?.Date ?? DateTime.Now.Date;
// var date1Raw = profile?.DateStart?.Date ?? DateTime.Now.Date;
// var date1 = new LocalDate(date1Raw.Year, date1Raw.Month, date1Raw.Day);
// var date2 = new LocalDate(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
// Period period = Period.Between(date1, date2);
// var govAgeMonth = period.Months;
// var govAgeYear = period.Years;
var (govAgeYear, govAgeMonth, govAgeDay) = startDate.GetDifference(DateTime.Now.Date);
var thisYear = DateTime.Now.Year;
var message = string.Empty;
if (profile == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
var leaveType = await _leaveTypeRepository.GetByIdAsync(req.Type);
if (leaveType == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
var userCalendar = await _userCalendarRepository.GetExist(profile.Id);
var category = userCalendar == null ? "NORMAL" : userCalendar.Calendar;
var sumLeave =
await _leaveRequestRepository.GetSumLeaveByTypeForUserAsync(userId, req.Type, req.StartLeaveDate.Year);
var sumWorkDay = await _holidayRepository.GetHolidayCountAsync(req.StartLeaveDate.Date, req.EndLeaveDate.Date, category);
var sumWeekend = _holidayRepository.GetWeekEndCount(req.StartLeaveDate.Date, req.EndLeaveDate.Date, category);
var sumApproveLeave = await _leaveRequestRepository.GetSumApproveLeaveByTypeForUserAsync(userId, req.Type, req.StartLeaveDate.Year);
// อ่านค่าจากตาราง beginning ทั้ง limit และ usage
var fiscalYear = req.StartLeaveDate.Year;
if (req.StartLeaveDate.Date >= new DateTime(DateTime.Now.Year, 10, 1) && req.EndLeaveDate.Date <= new DateTime(DateTime.Now.Year, 12, 31))
fiscalYear = req.StartLeaveDate.Year + 1;
var sumLeaveDay = await _leaveBeginningRepository.GetByYearAndTypeIdForUserAsync(fiscalYear, req.Type, userId);
var isBetween = false;
var existingLeaves = await _context.Set<LeaveRequest>()
.Where(x => x.Type.Id == req.Type &&
(x.LeaveStatus == "PENDING" || x.LeaveStatus == "APPROVE") &&
x.KeycloakUserId == userId)
.ToListAsync();
isBetween = existingLeaves.Any(leave =>
req.StartLeaveDate.Date <= leave.LeaveEndDate.Date &&
req.EndLeaveDate.Date >= leave.LeaveStartDate.Date);
// var minLeave = (await _context.Set<LeaveRequest>().Where(x => x.Type.Id == req.Type &&
// (x.LeaveStatus == "PENDING" || x.LeaveStatus == "APPROVE") &&
// x.KeycloakUserId == userId)
// .OrderBy(x => x.LeaveStartDate)
// .FirstOrDefaultAsync());
// var maxLeave = (await _context.Set<LeaveRequest>().Where(x => x.Type.Id == req.Type &&
// (x.LeaveStatus == "PENDING" || x.LeaveStatus == "APPROVE") &&
// x.KeycloakUserId == userId)
// .OrderByDescending(x => x.LeaveEndDate)
// .FirstOrDefaultAsync());
// var isBetween = false;
// if (minLeave != null && maxLeave != null)
// {
// // isBetween = (req.StartLeaveDate.Date >= minLeave.LeaveStartDate.Date && req.StartLeaveDate.Date <= maxLeave.LeaveEndDate.Date) ||
// // (req.EndLeaveDate.Date >= minLeave.LeaveStartDate.Date && req.EndLeaveDate.Date <= maxLeave.LeaveEndDate.Date);
// isBetween = req.StartLeaveDate.Date <= maxLeave.LeaveEndDate.Date &&
// req.EndLeaveDate.Date >= minLeave.LeaveStartDate.Date;
// }
var isLeave = false;
var approveDay = sumLeaveDay == null ? 0.0 : sumLeaveDay.LeaveDaysUsed;
var limitDay = sumLeaveDay == null ? 0.0 : sumLeaveDay.LeaveDays;
switch (leaveType.Code.ToUpper().Trim())
{
case "LV-001":
// fix issue : ระบบลา (ขรก.) >> ลาป่วย (กรณียื่นขอลาเกิน 120 วัน/ปี) #828
isLeave = (totalDay - (sumWorkDay + sumWeekend) + approveDay) <= 120;
if (!isLeave) message = "จำนวนวันลาเกินที่กำหนด";
//isLeave = true;
break;
case "LV-002":
// fix issue : ระบบลา (ขรก.) >> ลากิจส่วนตัว (กรณียื่นขอลาเกิน 45 วัน/ปี) #829
// fix issue : ระบบลา (ขรก.) >> ลากิจส่วนตัว (กรณีผู้เข้ารับราชการไม่เกิน 1 ปี ยื่นขอลาเกิน 15 วัน/ปี) #831
if (govAgeYear <= 1)
{
isLeave = (totalDay - (sumWorkDay + sumWeekend) + approveDay) <= 15;
if (!isLeave) message = "จำนวนวันลาเกินที่กำหนด";
}
else
{
isLeave = (totalDay - (sumWorkDay + sumWeekend) + approveDay) <= 45;
if (!isLeave) message = "จำนวนวันลาเกินที่กำหนด";
}
//isLeave = true;
break;
case "LV-007":
isLeave = true;
break;
case "LV-003":
isLeave = totalDay <= 90;
if (!isLeave) message = "จำนวนวันลาเกินที่กำหนด";
break;
case "LV-004":
isLeave = (totalDay - (sumWorkDay + sumWeekend) + approveDay) <= 15;
if (!isLeave) message = "จำนวนวันลาเกินที่กำหนด";
break;
case "LV-005":
// fix issue : ระบบลา (ขรก.) >> ลาพักผ่อน (กรณีรับราชการไม่ถึง 6 เดือน) #838
if (govAgeYear >= 1 || (govAgeYear == 0 && govAgeMonth >= 6))
{
isLeave = (totalDay - (sumWorkDay + sumWeekend) + approveDay) <= (limitDay);
if (!isLeave) message = "จำนวนวันลาเกินที่กำหนด";
}
else
{
isLeave = false;
if (!isLeave) message = "อายุราชการน้อยกว่า 6 เดือนหรือ 180 วัน";
}
break;
case "LV-006":
// fix issue : ระบบลา(ขรก.) >> ลาอุปสมบทหรือการลาประกอบพิธีฮัจย์ฯ(กรณีรับราชการน้อยกว่า 1 ปี) #840
if (govAgeYear < 1)
{
isLeave = false;
if (!isLeave) message = "อายุราชการน้อยกว่า 1 ปีหรือ 365 วัน";
}
else
{
// fix issue : ระบบลา (ขรก.) >> ลาอุปสมบทหรือการลาประกอบพิธีฮัจย์ฯ (ยื่นขอลาได้มากกว่า 1 ครั้ง) #841
var prevLeave = _context.Set<LeaveRequest>().Where(x => x.LeaveTypeCode == "LV-006" && x.KeycloakUserId == userId).Where(x => x.LeaveStatus == "APPROVE").Count();
if (prevLeave > 0)
{
isLeave = false;
if (!isLeave) message = "ไม่สามารถขอลาได้ เนื่องจากเคยยื่นขอลาไปแล้ว";
}
else
{
isLeave = totalDay <= 120;
if (!isLeave) message = "จำนวนวันลาเกินที่กำหนด";
}
}
break;
case "LV-008":
case "LV-009":
isLeave = govAgeYear >= 1;
if (!isLeave) message = "อายุราชการน้อยกว่า 1 ปีหรือ 365 วัน";
break;
case "LV-010":
int yy, mm, dd;
yy = req.StartLeaveDate.Year + 2;
if (req.StartLeaveDate.Day == 1)
{
if (req.StartLeaveDate.Month == 1)
{
mm = 12;
dd = 31;
}
else
{
mm = req.StartLeaveDate.Month - 1;
switch (mm)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
{
dd = 31;
break;
}
case 2:
{
if (DateTime.IsLeapYear(yy))
{
dd = 29;
}
else
dd = 28;
break;
}
case 4:
case 6:
case 9:
case 11:
{
dd = 30;
break;
}
default:
dd = 1;
break;
}
}
}
else
{
mm = req.StartLeaveDate.Month;
dd = req.StartLeaveDate.Day - 1;
}
var maxEnd = new DateTime(yy, mm, dd);
isLeave = req.EndLeaveDate.Date <= maxEnd;
if (!isLeave) message = "จำนวนวันลาเกินที่กำหนด";
break;
case "LV-011":
//isLeave = totalDay <= 360;
isLeave = totalDay <= 365; // fix issue : 847 เปลี่ยนเป็นเช็คว่าเกิน 365 วันหรีอไม่
if (!isLeave) message = "จำนวนวันลาเกินที่กำหนด";
break;
}
if (totalDay > 1)
{
if (req.LeaveRange == "MORNING" || req.LeaveRangeEnd == "AFTERNOON")
{
isLeave = false;
message = "ช่วงวันลาที่ระบุไม่ถูกต้อง";
}
if (req.LeaveRange != "ALL")
totalDay -= 0.5;
if (req.LeaveRangeEnd != "ALL")
totalDay -= 0.5;
}
else if (totalDay == 1)
{
if (req.LeaveRange != req.LeaveRangeEnd)
{
isLeave = false;
message = "ช่วงวันลาที่ระบุไม่ถูกต้อง";
}
if (req.LeaveRange != "ALL")
totalDay -= 0.5;
}
//var isLeave = sumLeave + (totalDay - sumWorkDay - sumWeekend) <= leaveType.Limit;
var result = new GetLeaveCheckResultDto
{
IsLeave = !isBetween ? isLeave : false,
SumDateWork = sumWorkDay,
TotalDate = totalDay,
SumDateHoliday = sumWeekend,
Message = !isBetween ? message : "ไม่สามารถทำการลาได้ เนื่องจากมีวันลาในช่วงที่เคยทำการขอลาไปแล้ว",
};
return Success(result);
}
/// <summary>
/// LV2_004 - รายการลา Calendar (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost("user/calendar")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetLeaveRequestCalendarAsync(
[FromBody] GetLeaveRequestCalendarDto req)
{
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
var data = await _leaveRequestRepository.GetLeaveRequestByYearAsync(req.Year, userId);
var resultData = (from d in data
//join p in profileList on d.KeycloakUserId equals p.Keycloak
select new GetLeaveRequestCalendarResultDto
{
Id = d.Id,
LeaveTypeId = d.Type.Id,
LeaveTypeName = d.Type.Name,
DateSendLeave = d.CreatedAt.Date,
Status = d.LeaveStatus,
FullName = $"{d.Prefix}{d.FirstName} {d.LastName}",
LeaveEndDate = d.LeaveEndDate,
LeaveStartDate = d.LeaveStartDate,
KeycloakId = d.KeycloakUserId
})
.ToList();
return Success(resultData);
}
/// <summary>
/// LV2_004 - รายการลา Calendar (ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost("admin/calendar")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetLeaveRequestCalendarAdminAsync(
[FromBody] GetLeaveRequestCalendarDto req)
{
var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
string role = jsonData["result"]?.ToString();
var nodeId = string.Empty;
var profileAdmin = new GetUserOCAllDto();
profileAdmin = await _userProfileRepository.GetUserOCAll(Guid.Parse(UserId!), AccessToken);
if (role == "NORMAL" || role == "CHILD")
{
nodeId = profileAdmin?.Node == 4
? profileAdmin?.Child4DnaId
: profileAdmin?.Node == 3
? profileAdmin?.Child3DnaId
: profileAdmin?.Node == 2
? profileAdmin?.Child2DnaId
: profileAdmin?.Node == 1
? profileAdmin?.Child1DnaId
: profileAdmin?.Node == 0
? profileAdmin?.RootDnaId
: "";
}
else if (role == "BROTHER")
{
nodeId = profileAdmin?.Node == 4
? profileAdmin?.Child3DnaId
: profileAdmin?.Node == 3
? profileAdmin?.Child2DnaId
: profileAdmin?.Node == 2
? profileAdmin?.Child1DnaId
: profileAdmin?.Node == 1 || profileAdmin?.Node == 0
? profileAdmin?.RootDnaId
: "";
}
else if (role == "ROOT" /*|| role == "PARENT"*/)
{
nodeId = profileAdmin?.RootDnaId;
}
var data = await _leaveRequestRepository.GetLeaveRequestByYearForAdminAsync(req.Year, role, nodeId, profileAdmin.Node);
var resultData = (from d in data
//join p in profileList on d.KeycloakUserId equals p.Keycloak
select new GetLeaveRequestCalendarResultDto
{
Id = d.Id,
LeaveTypeId = d.Type.Id,
LeaveTypeName = d.Type.Name,
DateSendLeave = d.CreatedAt.Date,
Status = d.LeaveStatus,
FullName = $"{d.Prefix}{d.FirstName} {d.LastName}",
LeaveEndDate = d.LeaveEndDate,
LeaveStartDate = d.LeaveStartDate,
KeycloakId = d.KeycloakUserId,
LeaveTotal = d.LeaveTotal
})
.ToList();
return Success(resultData);
}
/// <summary>
/// LV2_005 - รายการลา Table (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost("user/table")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetLeaveRequestTableAsync(
[FromBody] GetLeaveRequestTableDto req)
{
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
// if (profile == null)
// {
// return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
// }
var rawData =
await _leaveRequestRepository.GetLeaveRequestByUserIdAsync(userId, req.Year, req.Type, req.Status);
var result = new List<GetLeaveRequestTableResultDto>();
foreach (var item in rawData)
{
var res = new GetLeaveRequestTableResultDto
{
Id = item.Id,
LeaveTypeId = item.Type.Id,
LeaveTypeName = item.Type.Name,
LeaveSubTypeName = item.LeaveSubTypeName ?? "",
FullName = $"{item.Prefix}{item.FirstName} {item.LastName}",
DateSendLeave = item.CreatedAt,
IsDelete = item.LeaveStatus == "DELETE",
Status = item.LeaveStatus,
LeaveStartDate = item.LeaveStartDate,
LeaveEndDate = item.LeaveEndDate,
HajjDayStatus = item.HajjDayStatus,
LeaveRange = item.LeaveRange,
LeaveRangeEnd = item.LeaveRangeEnd,
};
result.Add(res);
}
if (req.Keyword != "")
result = result.Where(x => x.FullName.Contains(req.Keyword)).ToList();
if (!string.IsNullOrEmpty(req.SortBy))
{
var sort = req.SortBy;
if (sort == "leaveTypeName")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.LeaveTypeName).ToList()
: result.OrderBy(x => x.LeaveTypeName).ToList();
}
else if (sort == "leaveSubTypeName")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.LeaveSubTypeName).ToList()
: result.OrderBy(x => x.LeaveSubTypeName).ToList();
}
else if (sort == "fullName")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.FullName).ToList()
: result.OrderBy(x => x.FullName).ToList();
}
else if (sort == "dateSendLeave")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.DateSendLeave).ToList()
: result.OrderBy(x => x.DateSendLeave).ToList();
}
else if (sort == "isDelete")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.IsDelete).ToList()
: result.OrderBy(x => x.IsDelete).ToList();
}
else if (sort == "status")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.Status).ToList()
: result.OrderBy(x => x.Status).ToList();
}
else if (sort == "leaveStartDate")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.LeaveStartDate).ToList()
: result.OrderBy(x => x.LeaveStartDate).ToList();
}
else if (sort == "leaveEndDate")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.LeaveEndDate).ToList()
: result.OrderBy(x => x.LeaveEndDate).ToList();
}
else if (sort == "hajjDayStatus")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.HajjDayStatus).ToList()
: result.OrderBy(x => x.HajjDayStatus).ToList();
}
else if (sort == "leaveRange")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.LeaveRange).ToList()
: result.OrderBy(x => x.LeaveRange).ToList();
}
else if (sort == "leaveRangeEnd")
{
result = req.Descending.GetValueOrDefault()
? result.OrderByDescending(x => x.LeaveRangeEnd).ToList()
: result.OrderBy(x => x.LeaveRangeEnd).ToList();
}
else
{
// default กรณีส่ง sortBy มาไม่ตรง
result = result.OrderByDescending(x => x.DateSendLeave).ToList();
}
}
var pageResult = result.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList();
return Success(new { data = pageResult, total = result.Count });
}
/// <summary>
/// LV2_007 - รายละเอียดการลา (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpGet("user/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetLeaveRequestByIdAsync(Guid id)
{
var rawData = await _leaveRequestRepository.GetByIdAsync(id);
var thisYear = DateTime.Now.Year;
if (rawData == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
var profile = await _userProfileRepository.GetProfileByKeycloakIdNewAsync(rawData.KeycloakUserId, AccessToken);
if (profile == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
var govAge = (profile?.DateStart?.Date ?? DateTime.Now.Date).DiffDay(DateTime.Now.Date);
var userCalendar = await _userCalendarRepository.GetExist(profile.Id);
var category = userCalendar == null ? "NORMAL" : userCalendar.Calendar;
// var lastSalary = profile.ProfileSalary;
// var lastSalaryAmount = lastSalary == null ? 0 : lastSalary.Amount ?? 0;
var lastLeaveRequest =
await _leaveRequestRepository.GetLastLeaveRequestByTypeForUserAsync(rawData.KeycloakUserId,
rawData.Type.Id, rawData.LeaveStartDate.Date);
var sumLeave = rawData.LeaveStartDate.DiffDay(rawData.LeaveEndDate);
var sumHoliday = await _holidayRepository.GetHolidayCountAsync(rawData.LeaveStartDate, rawData.LeaveEndDate, category);
var sumWeekend = _holidayRepository.GetWeekEndCount(rawData.LeaveStartDate, rawData.LeaveEndDate, category);
var orgName = "";
if (rawData.Child4 != null && rawData.Child4 != "")
orgName += $" {rawData.Child4}";
if (rawData.Child3 != null && rawData.Child3 != "")
orgName += $" {rawData.Child3}";
if (rawData.Child2 != null && rawData.Child2 != "")
orgName += $" {rawData.Child2}";
if (rawData.Child1 != null && rawData.Child1 != "")
orgName += $" {rawData.Child1}";
if (rawData.Root != null && rawData.Root != "")
orgName += $" {rawData.Root}";
var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUserAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId);
var restDayOld = govAge < 180 ? 0 : leaveData == null ? 0 : (leaveData.LeaveDays + leaveData.BeginningLeaveDays - 10);
if (restDayOld < 0) restDayOld = 0;
var restDayCurrent = govAge < 180 ? 0 : 10;
var result = new GetLeaveRequestByIdDto
{
Id = rawData.Id,
LeaveRange = rawData.LeaveRange ?? "ALL",
LeaveRangeEnd = rawData.LeaveRangeEnd ?? "ALL",
LeaveTypeName = rawData.Type.Name,
LeaveSubTypeName = rawData.LeaveSubTypeName,
LeaveTypeId = rawData.Type.Id,
FullName = $"{rawData.Prefix}{rawData.FirstName} {rawData.LastName}",
DateSendLeave = rawData.CreatedAt,
Status = rawData.LeaveStatus,
LeaveStartDate = rawData.LeaveStartDate,
LeaveEndDate = rawData.LeaveEndDate,
LeaveWrote = rawData.LeaveWrote,
LeaveAddress = rawData.LeaveAddress,
LeaveNumber = rawData.LeaveNumber,
LeaveDetail = rawData.LeaveDetail,
LeaveDocument = new(),
LeaveLast = rawData.LeaveLast,
//LeaveDocument = rawData.LeaveDocument == null ? null : await _minIOService.ImagesPath(rawData.LeaveDocument.Id),
LeaveDraftDocument = rawData.LeaveDraftDocument == null ? "" : await _minIOService.ImagesPath(rawData.LeaveDraftDocument.Id),
LeaveLastStart = lastLeaveRequest == null ? null : lastLeaveRequest.LeaveStartDate,
LeaveLastEnd = lastLeaveRequest == null ? null : lastLeaveRequest.LeaveEndDate,
//LeaveTotal = rawData.LeaveStartDate.DiffDay(rawData.LeaveEndDate),
LeaveTotal = rawData.LeaveTotal,
LeaveBirthDate = profile.BirthDate,
LeaveGovernmentDate = profile.DateAppoint == null ? null : profile.DateAppoint.Value,
// LeaveSalary = lastSalary == null ? 0 : lastSalaryAmount,
// LeaveSalaryText = lastSalary == null ? "" : ((int)lastSalaryAmount).ToThaiBahtText(false),
LeaveSalary = profile.Amount.HasValue && profile.Amount > 0
? (int)profile.Amount : 0,
LeaveSalaryText = profile.Amount.HasValue && profile.Amount > 0
? ((int)profile.Amount).ToThaiBahtText(false) : "",
WifeDayName = rawData.WifeDayName,
WifeDayDateBorn = rawData.WifeDayDateBorn,
RestDayOldTotal = restDayOld,
RestDayCurrentTotal = restDayCurrent,
//RestDayOldTotal = rawData.RestDayOldTotal,
//RestDayCurrentTotal = rawData.RestDayCurrentTotal,
OrdainDayStatus = rawData.OrdainDayStatus,
OrdainDayLocationName = rawData.OrdainDayLocationName,
OrdainDayLocationAddress = rawData.OrdainDayLocationAddress,
OrdainDayLocationNumber = rawData.OrdainDayLocationNumber,
OrdainDayOrdination = rawData.OrdainDayOrdination,
OrdainDayBuddhistLentName = rawData.OrdainDayBuddhistLentName,
OrdainDayBuddhistLentAddress = rawData.OrdainDayBuddhistLentAddress,
HajjDayStatus = rawData.HajjDayStatus,
AbsentDaySummon = rawData.AbsentDaySummon,
AbsentDayLocation = rawData.AbsentDayLocation,
AbsentDayRegistorDate = rawData.AbsentDayRegistorDate,
AbsentDayGetIn = rawData.AbsentDayGetIn,
AbsentDayAt = rawData.AbsentDayAt,
StudyDaySubject = rawData.StudyDaySubject,
StudyDayDegreeLevel = rawData.StudyDayDegreeLevel,
StudyDayUniversityName = rawData.StudyDayUniversityName,
StudyDayTrainingSubject = rawData.StudyDayTrainingSubject,
StudyDayTrainingName = rawData.StudyDayTrainingName,
StudyDayCountry = rawData.StudyDayCountry,
StudyDayScholarship = rawData.StudyDayScholarship,
CoupleDayName = rawData.CoupleDayName,
CoupleDayPosition = rawData.CoupleDayPosition,
CoupleDayLevel = rawData.CoupleDayLevel,
CoupleDayLevelCountry = rawData.CoupleDayLevelCountry,
CoupleDayCountryHistory = rawData.CoupleDayCountryHistory,
CoupleDayTotalHistory = rawData.CoupleDayTotalHistory,
CoupleDayStartDateHistory = rawData.CoupleDayStartDateHistory,
CoupleDayEndDateHistory = rawData.CoupleDayEndDateHistory,
CoupleDaySumTotalHistory = rawData.CoupleDaySumTotalHistory,
Dear = rawData.Dear ?? "",
CommanderPosition = rawData.CommanderPosition ?? "",
PositionName = rawData.PositionName ?? "",
PositionLevelName = rawData.PositionLevelName ?? "",
OrganizationName = orgName,
//OrganizationName = rawData.OrganizationName ?? "",
// fix issue : SIT ระบบบันทึกการลา>>รายการลา (ข้อมูลผู้สังกัดและเรียนไม่แสดง) #971
LeaveTypeCode = rawData.LeaveTypeCode ?? ""
};
if (rawData.LeaveDocument != null && rawData.LeaveDocument.Count > 0)
{
foreach (var d in rawData.LeaveDocument)
{
var file = await _minIOService.ImagesPath(d.Document.Id);
result.LeaveDocument.Add(new LeaveDocumentDto
{
DocId = d.Document.Id,
Path = file
});
}
}
return Success(result);
}
/// <summary>
/// LV2_010 - รายการลา (ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost("admin")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetLeaveRequestForAdminAsync(
[FromBody] GetLeaveRequestForAdminDto req)
{
var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
string role = jsonData["result"]?.ToString();
var nodeId = string.Empty;
var profileAdmin = new GetUserOCAllDto();
profileAdmin = await _userProfileRepository.GetUserOCAll(Guid.Parse(UserId!), AccessToken);
if (role == "NORMAL" || role == "CHILD")
{
nodeId = profileAdmin?.Node == 4
? profileAdmin?.Child4DnaId
: profileAdmin?.Node == 3
? profileAdmin?.Child3DnaId
: profileAdmin?.Node == 2
? profileAdmin?.Child2DnaId
: profileAdmin?.Node == 1
? profileAdmin?.Child1DnaId
: profileAdmin?.Node == 0
? profileAdmin?.RootDnaId
: "";
}
else if (role == "BROTHER")
{
nodeId = profileAdmin?.Node == 4
? profileAdmin?.Child3DnaId
: profileAdmin?.Node == 3
? profileAdmin?.Child2DnaId
: profileAdmin?.Node == 2
? profileAdmin?.Child1DnaId
: profileAdmin?.Node == 1 || profileAdmin?.Node == 0
? profileAdmin?.RootDnaId
: "";
}
else if (role == "ROOT" /*|| role == "PARENT"*/)
{
nodeId = profileAdmin?.RootDnaId;
}
var rawData = await _leaveRequestRepository.GetListLeaveRequestForAdminAsync(req.Year, req.Type, req.Status, req.StartDate, req.EndDate, role, nodeId, profileAdmin?.Node);
var result = new List<GetLeaveRequestForAdminResultDto>();
foreach (var item in rawData)
{
//var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(item.KeycloakUserId, AccessToken);
//var userOc = _userProfileRepository.GetUserOC(item.KeycloakUserId, AccessToken);
// Get Organization
//var org = await _userProfileRepository.GetOrganizationById(profile.OcId ?? Guid.Empty);
//var agency_id = org == null ? Guid.Empty : org.OrganizationAgencyId ?? Guid.Empty;
//var gov_agency_id = org == null ? Guid.Empty : org.OrganizationGovernmentAgencyId ?? Guid.Empty;
//var agency = await _userProfileRepository.GetOrgAgencyById(agency_id);
//var gov_agency = await _userProfileRepository.GetOrgGovAgencyById(gov_agency_id);
var agency_name = string.Concat((item.Child1 != string.Empty && item.Child1 != null) ? item.Child1 : "",
(item.Child2 != string.Empty && item.Child2 != null) ? "/" + item.Child2 : "",
(item.Child3 != string.Empty && item.Child3 != null) ? "/" + item.Child3 : "",
(item.Child4 != string.Empty && item.Child4 != null) ? "/" + item.Child4 : "")
.Trim();
var res = new GetLeaveRequestForAdminResultDto
{
Id = item.Id,
LeaveTypeId = item.Type.Id,
LeaveTypeName = item.Type.Name,
LeaveSubTypeName = item.LeaveSubTypeName,
FullName = $"{item.Prefix}{item.FirstName} {item.LastName}",
ProfileType = item.ProfileType ?? "-",
DateSendLeave = item.CreatedAt,
Status = item.LeaveStatus,
CitizenId = item.CitizenId ?? "",
LeaveStartDate = item.LeaveStartDate,
LeaveEndDate = item.LeaveEndDate,
Position = item.PositionName ?? "-",
Level = item.PositionLevelName ?? "-",
Agency = agency_name,//agency == null ? "" : agency.Name,
Org = item.Root ?? "",//userOc == null ? "-" : userOc.Root,
LeaveRange = item.LeaveRange ?? "ALL",
LeaveRangeEnd = item.LeaveRangeEnd ?? "ALL",
HajjDayStatus = item.HajjDayStatus,
LeaveTotal = item.LeaveTotal
};
result.Add(res);
}
if (req.Keyword != "")
result = result.Where(x => x.FullName.Contains(req.Keyword)).ToList();
if (!string.IsNullOrEmpty(req.ProfileType) && req.ProfileType.ToUpper() != "ALL")
result = result.Where(x => x.ProfileType.ToUpper().Contains(req.ProfileType.ToUpper())).ToList();
var pageResult = result.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList();
return Success(new { data = pageResult, total = result.Count });
}
/// <summary>
/// LV2_008 - ขอยกเลิกการลา (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost("user/delete/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> CancelLeaveRequestAsync([FromForm] CancelLeaveRequestDto req,
Guid id)
{
var data = await _leaveRequestRepository.GetByIdWithTrackingAsync(id);
if (data == null)
{
//return Success(new List<object>());
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
// change status to delete
// แก้จาก DELETE เป็น DELETING ไว้ก่อน รอ approve ค่อยเปลี่ยนเป็น DELETE
// data.LeaveStatus = "DELETE";
data.LeaveStatus = "DELETING";
data.CancelLeaveWrote = req.LeaveWrote ?? "";
// ถ้าผู้มีอำนาจอนุมัติแล้ว ต้องมีการรอ
if (data.ApproveStep == "st4")
{
// add cancel status to new
data.LeaveCancelStatus = "NEW";
data.LeaveCancelComment = req.Reason ?? "";
}
else
{
data = await _leaveRequestRepository.ApproveCancelLeaveRequestAsync(data, "อนุมัติการขอยกเลิกการลา โดยระบบ", req.Reason ?? "");
}
// upload leave cancel document
if (req.Doc != null)
{
var doc = await _minIOService.UploadFileAsync(req.Doc);
if (doc != null)
{
data.LeaveCancelDocument = doc;
}
}
// save to database
await _leaveRequestRepository.UpdateWithTrackingAsync(data);
// TODO: Send notification to all users who need to approve the cancel leave request
var approvers = data.Approvers
.Where(x => x.ApproveStatus!.ToUpper() == "PENDING")
.OrderBy(x => x.Seq)
.ToList();
foreach (var approver in approvers)
{
// Send Notification
var noti1 = new Notification
{
Body = $"คำร้องขอยกเลิกการลาของคุณ {data.FirstName} {data.LastName} รอรับการอนุมัติจากคุณ",
ReceiverUserId = approver!.ProfileId,
Type = "",
Payload = $"{URL}/leave/detail/{id}",
};
_appDbContext.Set<Notification>().Add(noti1);
}
return Success();
}
/// <summary>
/// LV2_014 - รายการขอยกเลิกการลา (ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost("admin/delete")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetCancelLeaveRequestForAdminAsync(
[FromBody] GetLeaveRequestForAdminDto req)
{
var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
string role = jsonData["result"]?.ToString();
var nodeId = string.Empty;
var profileAdmin = new GetUserOCAllDto();
profileAdmin = await _userProfileRepository.GetUserOCAll(Guid.Parse(UserId!), AccessToken);
if (role == "NORMAL" || role == "CHILD")
{
nodeId = profileAdmin?.Node == 4
? profileAdmin?.Child4DnaId
: profileAdmin?.Node == 3
? profileAdmin?.Child3DnaId
: profileAdmin?.Node == 2
? profileAdmin?.Child2DnaId
: profileAdmin?.Node == 1
? profileAdmin?.Child1DnaId
: profileAdmin?.Node == 0
? profileAdmin?.RootDnaId
: "";
}
else if (role == "BROTHER")
{
nodeId = profileAdmin?.Node == 4
? profileAdmin?.Child3DnaId
: profileAdmin?.Node == 3
? profileAdmin?.Child2DnaId
: profileAdmin?.Node == 2
? profileAdmin?.Child1DnaId
: profileAdmin?.Node == 1 || profileAdmin?.Node == 0
? profileAdmin?.RootDnaId
: "";
}
else if (role == "ROOT" /*|| role == "PARENT"*/)
{
nodeId = profileAdmin?.RootDnaId;
}
var rawData =
await _leaveRequestRepository.GetCancelLeaveRequestForAdminAsync(req.Year, req.Type, req.Status, role, nodeId, profileAdmin?.Node);
var recCount = rawData.Count;
if (req.Keyword != "")
rawData = rawData.Where(x => ($"{x.Prefix}{x.FirstName} {x.LastName}").Contains(req.Keyword)).ToList();
if (!string.IsNullOrEmpty(req.ProfileType) && req.ProfileType.ToUpper() != "ALL")
rawData = rawData.Where(x => x.ProfileType.ToUpper().Contains(req.ProfileType.ToUpper())).ToList();
rawData = rawData.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList();
var result = new List<GetLeaveCancelRequestResultDto>();
foreach (var item in rawData)
{
//var profile = await _userProfileRepository.GetProfileByKeycloakIdNewAsync(item.KeycloakUserId, AccessToken);
var res = new GetLeaveCancelRequestResultDto
{
Id = item.Id,
LeaveTypeId = item.Type.Id,
LeaveTypeName = item.Type.Name,
LeaveSubTypeName = item.LeaveSubTypeName,
ProfileType = item.ProfileType ?? "-",
FullName = $"{item.Prefix}{item.FirstName} {item.LastName}",
DateSendLeave = item.CreatedAt.Date,
Status = item.LeaveCancelStatus ?? ""
};
result.Add(res);
}
// if (req.Keyword != "")
// result = result.Where(x => x.FullName.Contains(req.Keyword)).ToList();
// if (!string.IsNullOrEmpty(req.ProfileType) && req.ProfileType.ToUpper() != "ALL")
// result = result.Where(x => x.ProfileType.ToUpper().Contains(req.ProfileType.ToUpper())).ToList();
// var pageResult = result.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList();
return Success(new { data = result, total = recCount });
}
/// <summary>
/// LV2_006 - รายละเอียดการยกเลิกการลา (USER/ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpGet("user/delete/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetCancelLeaveRequestByIdAsync(Guid id)
{
var rawData = await _leaveRequestRepository.GetByIdAsync(id);
var thisYear = DateTime.Now.Year;
if (rawData == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
// if (profile == null)
// {
// return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
// }
var result = new GetCancelLeaveRequestByIdDto
{
Id = rawData.Id,
LeaveTypeName = rawData.Type.Name,
LeaveSubTypeName = rawData.LeaveSubTypeName,
FullName = $"{rawData.Prefix}{rawData.FirstName} {rawData.LastName}",
Status = rawData.LeaveCancelStatus ?? "",
LeaveStartDate = rawData.LeaveStartDate,
LeaveEndDate = rawData.LeaveEndDate,
LeaveWrote = rawData.CancelLeaveWrote ?? rawData.LeaveWrote,
LeaveAddress = rawData.LeaveAddress,
LeaveNumber = rawData.LeaveNumber,
LeaveDetail = rawData.LeaveDetail,
LeaveDocDelete = rawData.LeaveCancelDocument == null
? ""
: await _minIOService.ImagesPath(rawData.LeaveCancelDocument.Id),
LeaveReasonDelete = rawData.LeaveCancelComment ?? "",
LeaveTotal = rawData.LeaveTotal,
LeaveDirectorComment = rawData.LeaveDirectorComment,
LeaveRange = rawData.LeaveRange,
LeaveRangeEnd = rawData.LeaveRangeEnd,
};
return Success(result);
}
/// <summary>
/// เพิ่มชื่อผู้ส่งไปพิจารณา (ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPut("admin/sender/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> SenderLeaveRequestAsync(Guid id)
{
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(Guid.Parse(UserId!), AccessToken);
var profile = await _userProfileRepository.GetProfileByKeycloakIdNewAsync(Guid.Parse(UserId!), AccessToken);
if (profile == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
var rawData = await _leaveRequestRepository.GetByIdAsync(id);
if (rawData == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
var sender = rawData.Approvers
.Where(x => x.ApproveType!.ToUpper() == "SENDER")
.FirstOrDefault();
if (sender == null)
{
await _leaveRequestRepository.AddApproversAsync(id, new List<LeaveRequestApprover>
{
new LeaveRequestApprover
{
Prefix = profile.Prefix ?? "",
FirstName = profile.FirstName ?? "",
LastName = profile.LastName ?? "",
PositionName = $"{profile.Position ?? ""}",
ProfileId = profile.Id,
KeycloakId = Guid.Parse(UserId!),
ApproveType = "SENDER",
PositionLevelName = profile.PositionLeaveName ?? "",
PosExecutiveName = profile.PosExecutiveName ?? "",
OrganizationName = profile.Oc ?? "",
CreatedFullName = FullName ?? "",
CreatedUserId = UserId!,
CreatedAt = DateTime.Now,
LastUpdateFullName = FullName ?? "",
LastUpdateUserId = UserId!,
LastUpdatedAt = DateTime.Now,
}
});
}
return Success();
}
/// <summary>
/// LV2_018 - ผู้มีอำนาจอนุมัติขอยกเลิกการลา(ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPut("admin/delete/approve/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> ApproveCancelLeaveRequestAsync(Guid id,
[FromBody] CancelLeaveRequestApproveDto req)
{
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
await _leaveRequestRepository.ApproveCancelLeaveRequestAsync(id, req.Reason ?? "");
return Success();
}
/// <summary>
/// LV2_019 - ผู้มีอำนาจไม่อนุมัติขอยกเลิกการลา(ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPut("admin/delete/reject/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> RejectCancelLeaveRequestAsync(Guid id,
[FromBody] CancelLeaveRequestApproveDto req)
{
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
await _leaveRequestRepository.RejectCancelLeaveRequestAsync(id, req.Reason ?? "");
return Success();
}
/// <summary>
/// LV2_013 - เจ้าหน้าที่อนุมัติการลา (ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpGet("admin/approve/officer/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> OfficerApproveLeaveRequestAsync(Guid id)
{
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
await _leaveRequestRepository.OfficerApproveLeaveRequest(id);
return Success();
}
/// <summary>
/// LV2_015 - ผู้บังคับบัญชาอนุมัติการลา(ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPut("admin/approve/comander/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> CommanderApproveLeaveRequestAsync(Guid id,
[FromBody] LeaveRequestApproveDto req)
{
try
{
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
await _leaveRequestRepository.CommanderApproveLeaveRequest(id, req.Reason ?? "");
return Success();
}
catch (Exception ex)
{
return Error(ex);
}
}
/// <summary>
/// ผู้บังคับบัญชาไม่อนุมัติการลา(ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPut("admin/reject/comander/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> CommanderRejectLeaveRequestAsync(Guid id,
[FromBody] LeaveRequestApproveDto req)
{
try
{
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
await _leaveRequestRepository.CommanderRejectLeaveRequest(id, req.Reason ?? "");
return Success();
}
catch (Exception ex)
{
return Error(ex);
}
}
/// <summary>
/// LV2_016 - ผู้มีอำนาจอนุมัติการลา (ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPut("admin/approve/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> ApproveLeaveRequestAsync(Guid id,
[FromBody] LeaveRequestApproveDto req)
{
try
{
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
await _leaveRequestRepository.ApproveLeaveRequest(id, req.Reason ?? "");
return Success();
}
catch (Exception ex)
{
return Error(ex);
}
}
/// <summary>
/// LV2_021 - ส่งคำขอลา
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPut("user/send/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> SendLeaveRequestAsync(Guid id,
[FromBody] LeaveRequestApproveDto req)
{
try
{
await _leaveRequestRepository.SendToOfficerAsync(id);
// Remove Workflow Integration
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
if (profile == null)
{
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
}
// Get Officer List
var officers = await _userProfileRepository.GetOCStaffAsync(profile.Id, AccessToken);
if(officers != null && officers.Count > 0)
{
foreach (var officer in officers)
{
// Send Notification
var noti = new Notification
{
Body = $"มีคำร้องขอลาจาก {profile.Prefix}{profile.FirstName} {profile.LastName} รอรับการอนุมัติจากคุณ",
ReceiverUserId = officer.ProfileId,
Type = "",
Payload = $"{URL}/leave/detail/{id}",
};
_appDbContext.Set<Notification>().Add(noti);
}
await _appDbContext.SaveChangesAsync();
}
// var baseAPIOrg = _configuration["API"];
// var apiUrlOrg = $"{baseAPIOrg}/org/workflow/add-workflow";
// if (profile.ProfileType == "OFFICER")
// {
// using (var client = new HttpClient())
// {
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
// {
// refId = id,
// sysName = "SYS_LEAVE_LIST",
// posLevelName = profile.PosLevel ?? "",
// posTypeName = profile.PosType ?? "",
// fullName = $"{profile.Prefix}{profile.FirstName} {profile.LastName}"
// });
// }
// }
// else
// {
// using (var client = new HttpClient())
// {
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
// {
// refId = id,
// sysName = "SYS_LEAVE_LIST_EMP",
// posLevelName = profile.PosLevel ?? "",
// posTypeName = profile.PosType ?? "",
// fullName = $"{profile.Prefix}{profile.FirstName} {profile.LastName}"
// });
// }
// }
return Success();
}
catch (Exception ex)
{
return Error(ex);
}
}
/// <summary>
/// LV2_017 - ผู้มีอำนาจไม่อนุมัติการลา (ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPut("admin/reject/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> RejectLeaveRequestAsync(Guid id,
[FromBody] LeaveRequestApproveDto req)
{
try
{
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
await _leaveRequestRepository.RejectLeaveRequest(id, req.Reason ?? "");
return Success();
}
catch (Exception ex)
{
return Error(ex);
}
}
/// <summary>
/// LV2_012 - รายละเอียดการลา (ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpGet("admin/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetLeaveRequestForAdminByIdAsync(Guid id)
{
var rawData = await _leaveRequestRepository.GetByIdAsync(id);
if (rawData == null)
return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
if (rawData.ProfileType == "OFFICER")
{
var getWorkflow = await _permission.GetPermissionAPIWorkflowAsync(id.ToString(), "SYS_LEAVE_LIST");
if (getWorkflow == false)
{
var getPermission = await _permission.GetPermissionAPIAsync("GET", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
}
}
else
{
var getWorkflow = await _permission.GetPermissionAPIWorkflowAsync(id.ToString(), "SYS_LEAVE_LIST_EMP");
if (getWorkflow == false)
{
var getPermission = await _permission.GetPermissionAPIAsync("GET", "SYS_LEAVE_LIST");
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
if (jsonData["status"]?.ToString() != "200")
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
}
}
var thisYear = rawData.LeaveStartDate.Year;
var toDay = rawData.LeaveStartDate.Date;
// var thisYear = DateTime.Now.Year;
// var toDay = DateTime.Now.Date;
if (toDay >= new DateTime(toDay.Year, 10, 1) && toDay <= new DateTime(toDay.Year, 12, 31))
thisYear = thisYear + 1;
//var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
//if (profile == null)
//{
// return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound);
//}
//var userCalendar = await _userCalendarRepository.GetExist(Guid.Parse(rawData.ProfileId));
//var category = userCalendar == null ? "NORMAL" : userCalendar.Calendar;
//var lastSalary = profile.ProfileSalary;
//var lastSalaryAmount = lastSalary == null ? 0 : lastSalary.Amount ?? 0;
var lastLeaveRequest =
await _leaveRequestRepository.GetLastLeaveRequestByTypeForUserAsync2(rawData.KeycloakUserId,
rawData.Type.Id, rawData.CreatedAt);
//var rootOc = _userProfileRepository.GetRootOcId(profile.OcId ?? Guid.Empty, AccessToken);
//var approver = string.Empty;
//if (rootOc != null)
//{
//var list = await _commandRepository.GetOrgApproverAsync(rootOc ?? Guid.Empty);
//if (list.Count > 0)
//approver = list.First().Name;
//}
//var sumLeave = rawData.LeaveStartDate.DiffDay(rawData.LeaveEndDate);
//var sumHoliday = await _holidayRepository.GetHolidayCountAsync(rawData.LeaveStartDate, rawData.LeaveEndDate, category);
//var sumWeekend = _holidayRepository.GetWeekEndCount(rawData.LeaveStartDate, rawData.LeaveEndDate, category);
// fix issue : ระบบการลา>>สังกัด ฝ่าย (เอา / ออก เปลี่ยนเป็นว่าง) #1131
var orgName = "";
if (rawData.Child4 != null && rawData.Child4 != "")
orgName += $" {rawData.Child4}";
if (rawData.Child3 != null && rawData.Child3 != "")
orgName += $" {rawData.Child3}";
if (rawData.Child2 != null && rawData.Child2 != "")
orgName += $" {rawData.Child2}";
if (rawData.Child1 != null && rawData.Child1 != "")
orgName += $" {rawData.Child1}";
if (rawData.Root != null && rawData.Root != "")
orgName += $" {rawData.Root}";
var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUser2Async(thisYear, rawData.Type.Id, rawData.KeycloakUserId);
var startFiscalYear = new DateTime(rawData.LeaveStartDate.Year - 1, 10, 1);
var endFiscalYear = rawData.CreatedAt;
var leaveSummary = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUser2(rawData.KeycloakUserId, rawData.Type.Id, startFiscalYear, endFiscalYear);
//var leaveSummary = leaveData == null ? 0.0 : leaveData.LeaveDaysUsed;
if (leaveData != null)
leaveSummary += leaveData.BeginningLeaveDays;
var extendLeave = 0.0;
var leaveLimit = (double)rawData.Type.Limit;
if (rawData.Type.Code == "LV-005")
{
leaveLimit = leaveData == null ? 0.0 : leaveData.LeaveDays;
extendLeave = leaveLimit <= 0 ? 0 : leaveLimit - 10;
}
var result = new GetLeaveRequestForAdminByIdDto
{
Id = rawData.Id,
ReasonCommander = rawData.LeaveComment ?? "",
ReasonOligarch = rawData.LeaveDirectorComment ?? "",
ProfileType = rawData.ProfileType,
LeaveTypeName = rawData.Type.Name,
LeaveSubTypeName = rawData.LeaveSubTypeName,
LeaveTypeId = rawData.Type.Id,
FullName = $"{rawData.Prefix}{rawData.FirstName} {rawData.LastName}",
DateSendLeave = rawData.CreatedAt,
Status = rawData.LeaveStatus,
LeaveStartDate = rawData.LeaveStartDate,
LeaveEndDate = rawData.LeaveEndDate,
LeaveWrote = rawData.LeaveWrote,
LeaveAddress = rawData.LeaveAddress,
LeaveNumber = rawData.LeaveNumber,
LeaveDetail = rawData.LeaveDetail,
LeaveRange = rawData.LeaveRange ?? "ALL",
LeaveRangeEnd = rawData.LeaveRangeEnd ?? "ALL",
LeaveDocument = new(),
//LeaveDocument = rawData.LeaveDocument == null ? "" : await _minIOService.ImagesPath(rawData.LeaveDocument.Id),
LeaveDraftDocument = rawData.LeaveDraftDocument == null ? "" : await _minIOService.ImagesPath(rawData.LeaveDraftDocument.Id),
LeaveLastStart = lastLeaveRequest == null ? null : lastLeaveRequest.LeaveStartDate,
LeaveLastEnd = lastLeaveRequest == null ? null : lastLeaveRequest.LeaveEndDate,
//LeaveTotal = rawData.LeaveStartDate.DiffDay(rawData.LeaveEndDate),
LeaveTotal = rawData.LeaveTotal,
LeaveBirthDate = rawData.BirthDate == null ? null : rawData.BirthDate.Value,
LeaveGovernmentDate = rawData.DateAppoint == null ? null : rawData.DateAppoint.Value,
LeaveSalary = (double)(rawData.Amount == null ? 0 : rawData.Amount),
LeaveSalaryText = rawData.Amount == null ? "" : ((int)rawData.Amount).ToThaiBahtText(false),
WifeDayName = rawData.WifeDayName,
WifeDayDateBorn = rawData.WifeDayDateBorn,
RestDayOldTotal = extendLeave,
RestDayCurrentTotal = rawData.Type.Limit,
// #1134
//RestDayOldTotal = rawData.RestDayOldTotal,
//RestDayCurrentTotal = rawData.RestDayCurrentTotal,
OrdainDayStatus = rawData.OrdainDayStatus,
OrdainDayLocationName = rawData.OrdainDayLocationName,
OrdainDayLocationAddress = rawData.OrdainDayLocationAddress,
OrdainDayLocationNumber = rawData.OrdainDayLocationNumber,
OrdainDayOrdination = rawData.OrdainDayOrdination,
OrdainDayBuddhistLentName = rawData.OrdainDayBuddhistLentName,
OrdainDayBuddhistLentAddress = rawData.OrdainDayBuddhistLentAddress,
HajjDayStatus = rawData.HajjDayStatus,
AbsentDaySummon = rawData.AbsentDaySummon,
AbsentDayLocation = rawData.AbsentDayLocation,
AbsentDayRegistorDate = rawData.AbsentDayRegistorDate,
AbsentDayGetIn = rawData.AbsentDayGetIn,
AbsentDayAt = rawData.AbsentDayAt,
StudyDaySubject = rawData.StudyDaySubject,
StudyDayDegreeLevel = rawData.StudyDayDegreeLevel,
StudyDayUniversityName = rawData.StudyDayUniversityName,
StudyDayTrainingSubject = rawData.StudyDayTrainingSubject,
StudyDayTrainingName = rawData.StudyDayTrainingName,
StudyDayCountry = rawData.StudyDayCountry,
StudyDayScholarship = rawData.StudyDayScholarship,
CoupleDayName = rawData.CoupleDayName,
CoupleDayPosition = rawData.CoupleDayPosition,
CoupleDayLevel = rawData.CoupleDayLevel,
CoupleDayLevelCountry = rawData.CoupleDayLevelCountry,
CoupleDayCountryHistory = rawData.CoupleDayCountryHistory,
CoupleDayTotalHistory = rawData.CoupleDayTotalHistory,
CoupleDayStartDateHistory = rawData.CoupleDayStartDateHistory,
CoupleDayEndDateHistory = rawData.CoupleDayEndDateHistory,
CoupleDaySumTotalHistory = rawData.CoupleDaySumTotalHistory,
KeycloakUserId = rawData.KeycloakUserId,
// Dear = approver,
// PositionName = profile.Position == null ? "" : profile.Position.Name,
// PositionLevelName = profile.PositionLevel == null ? "" : profile.PositionLevel.Name,
// OrganizationName = profile.Oc ?? "",
// เปลี่ยนมาอ่านจากฐานข้อมูลแทน read_db
Dear = rawData.Dear ?? "",
CommanderPosition = rawData.CommanderPosition ?? "",
PositionName = rawData.PositionName ?? "",
PositionLevelName = rawData.PositionLevelName ?? "",
OrganizationName = orgName,
//OrganizationName = rawData.OrganizationName ?? "",
// fix SIT ระบบบันทึกการลา>>รายการลา (ข้อมูลผู้สังกัดและเรียนไม่แสดง) #971
ApproveStep = rawData.ApproveStep ?? "-",
LeaveLimit = rawData.Type.Limit + extendLeave,
LeaveSummary = leaveSummary,
LeaveRemain = (rawData.Type.Limit + extendLeave) - leaveSummary
};
if (rawData.LeaveDocument != null && rawData.LeaveDocument.Count > 0)
{
foreach (var d in rawData.LeaveDocument)
{
var file = await _minIOService.ImagesPath(d.Document.Id);
result.LeaveDocument.Add(new LeaveDocumentDto
{
DocId = d.Document.Id,
Path = file
});
}
}
var commanders = rawData.Approvers.Where(x => x.ApproveType.ToUpper() == "COMMANDER")
.Select(x => new GetLeaveApproverDto
{
Seq = x.Seq,
Prefix = x.Prefix,
FirstName = x.FirstName,
LastName = x.LastName,
PositionName = x.PositionName,
PositionSign = x.PositionSign,
ApproveStatus = x.ApproveStatus,
Comment = x.Comment,
ProfileId = x.ProfileId,
KeycloakId = x.KeycloakId
}).ToList();
var approvers = rawData.Approvers.Where(x => x.ApproveType.ToUpper() == "APPROVER")
.Select(x => new GetLeaveApproverDto
{
Seq = x.Seq,
Prefix = x.Prefix,
FirstName = x.FirstName,
LastName = x.LastName,
PositionName = x.PositionName,
PositionSign = x.PositionSign,
ApproveStatus = x.ApproveStatus,
Comment = x.Comment,
ProfileId = x.ProfileId,
KeycloakId = x.KeycloakId
}).ToList();
result.Approvers.AddRange(approvers);
result.Commanders.AddRange(commanders);
return Success(result);
}
/// <summary>
/// LV2_009 - รายการตารางสถิติการลา (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpGet("user/summary")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetUserLeaveSummaryAsync()
{
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
var thisYear = DateTime.Now.Year;
var toDay = DateTime.Now.Date;
if (toDay >= new DateTime(toDay.Year, 10, 1) && toDay <= new DateTime(toDay.Year, 12, 31))
thisYear = thisYear + 1;
// Execute repository calls sequentially to avoid DbContext threading issues
var leaveTypes = await _leaveTypeRepository.GetAllAsync();
var sendList = await _leaveRequestRepository.GetSumSendLeaveAsync(thisYear);
var rejectList = await _leaveRequestRepository.GetSumRejectLeaveAsync(thisYear);
var deleteList = await _leaveRequestRepository.GetSumDeleteLeaveAsync(thisYear);
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
var pf = await _userProfileRepository.GetProfileByKeycloakIdNewAsync(userId, AccessToken);
if (pf == null)
{
throw new Exception(GlobalMessages.DataNotFound);
}
// Create dictionaries for fast lookup instead of FirstOrDefault searches
var sendDict = sendList.Where(x => x.KeycloakUserId == userId)
.ToDictionary(x => x.LeaveTypeId, x => x.SumLeaveDay);
var rejectDict = rejectList.Where(x => x.KeycloakUserId == userId)
.ToDictionary(x => x.LeaveTypeId, x => x.SumLeaveDay);
var deleteDict = deleteList.Where(x => x.KeycloakUserId == userId)
.ToDictionary(x => x.LeaveTypeId, x => x.SumLeaveDay);
// Pre-load all leave beginning data sequentially to avoid DbContext threading issues
var leaveBeginningDict = new Dictionary<Guid, LeaveBeginning?>();
foreach (var leaveType in leaveTypes)
{
var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUser(thisYear, leaveType.Id, pf);
leaveBeginningDict[leaveType.Id] = leaveData;
}
var result = new List<dynamic>();
foreach (var leaveType in leaveTypes)
{
// Use dictionary lookups for better performance
var send = sendDict.GetValueOrDefault(leaveType.Id, 0);
var reject = rejectDict.GetValueOrDefault(leaveType.Id, 0);
var delete = deleteDict.GetValueOrDefault(leaveType.Id, 0);
leaveBeginningDict.TryGetValue(leaveType.Id, out var leaveData);
var approve = leaveData?.LeaveDaysUsed ?? 0;
// fix issue : SIT ระบบบันทึกการลา>> สิทธิ์การลา(โอนสิทธิ์การลา) #974
var extendLeave = 0.0;
var leaveLimit = (double)leaveType.Limit;
if (leaveType.Code == "LV-005")
{
leaveLimit = leaveData?.LeaveDays ?? 0.0;
extendLeave = leaveLimit <= 0 ? 0 : leaveLimit - 10;
}
var data = new
{
Id = leaveType.Id,
LeaveTypeName = leaveType.Name,
LeaveLimit = leaveLimit,
LeaveExtend = extendLeave,
leavePercent = Math.Round((approve * 100.0) / leaveType.Limit, 2),
LeaveCountSend = send,
LeaveCountApprove = approve,
LeaveCountReject = reject,
LeaveCountDelete = delete,
};
result.Add(data);
}
return Success(result);
}
/// <summary>
/// LV2_037 - ลบเอกสารประกอบรายละเอียดการลา (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpDelete("user/file/document/{id:guid}/{docId:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> DeleteLeaveDocumentByIdAsync(Guid id, Guid docId)
{
var leaveReq = await _leaveRequestRepository.GetByIdAsync(id);
if (leaveReq == null)
return Error(GlobalMessages.DataNotFound);
var doc = leaveReq.LeaveDocument.Where(x => x.Document.Id == docId).FirstOrDefault();
if (doc != null)
{
await _minIOService.DeleteFileAsync(doc.Document.Id);
await _leaveRequestRepository.DeleteLeaveDocumentAsync(doc.Id);
return Success();
}
else
return Error("Document not found");
}
// [HttpGet("holiday/test")]
// public async Task<ActionResult<ResponseObject>> GetHolidayTestAsync()
// {
// var start = new DateTime(2024, 1, 1);
// var end = new DateTime(2024, 1, 3);
// var count = await _holidayRepository.GetHolidayCountAsync(start, end);
// return Success(new { holiday = count });
// }
#endregion
}
}