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 " /// /// เพิ่มรายชิื่อผู้อนุมัติ หรือ ผู้บังคับบัญชา /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("officer/add-approver/{type}/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> AddApprover(string type, Guid id, [FromBody] List 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(); 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); } } /// /// LV2_001 - สร้างคำขอการลา (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("user")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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(req.Approvers ?? ""); // //var fixedJson = req.Approvers.Replace("\\\"", "\""); // var approvers = JsonConvert.DeserializeObject>(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 UpdateRootForLeaveRequestAsync() { var leaves = await _context.Set().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"); } /// /// LV2_020 - แก้ไขคำขอการลา /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPut("user/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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().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); } } /// /// LV2_038 - ลบรายการการลา (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpDelete("user/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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(); } /// /// LV2_002 - ข้อมูลที่ user ขอยื่นลา (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("user/profile")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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> 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 }); } /// /// LV2_003 - เช็คการยืนขอลา (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("user/check")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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 minLeave = (await _context.Set().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().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); } 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().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); } /// /// LV2_004 - รายการลา Calendar (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("user/calendar")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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); } /// /// LV2_004 - รายการลา Calendar (ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("admin/calendar")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> GetLeaveRequestCalendarAdminAsync( [FromBody] GetLeaveRequestCalendarDto req) { var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(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); } /// /// LV2_005 - รายการลา Table (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("user/table")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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(); 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 }); } /// /// LV2_007 - รายละเอียดการลา (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet("user/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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); } /// /// LV2_010 - รายการลา (ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("admin")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> GetLeaveRequestForAdminAsync( [FromBody] GetLeaveRequestForAdminDto req) { var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(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(); 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 }); } /// /// LV2_008 - ขอยกเลิกการลา (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("user/delete/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> CancelLeaveRequestAsync([FromForm] CancelLeaveRequestDto req, Guid id) { var data = await _leaveRequestRepository.GetByIdWithTrackingAsync(id); if (data == null) { //return Success(new List()); 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().Add(noti1); } return Success(); } /// /// LV2_014 - รายการขอยกเลิกการลา (ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("admin/delete")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> GetCancelLeaveRequestForAdminAsync( [FromBody] GetLeaveRequestForAdminDto req) { var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(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(); 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 }); } /// /// LV2_006 - รายละเอียดการยกเลิกการลา (USER/ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet("user/delete/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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); } /// /// เพิ่มชื่อผู้ส่งไปพิจารณา (ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPut("admin/sender/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> SenderLeaveRequestAsync(Guid id) { var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(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 { 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(); } /// /// LV2_018 - ผู้มีอำนาจอนุมัติขอยกเลิกการลา(ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPut("admin/delete/approve/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> ApproveCancelLeaveRequestAsync(Guid id, [FromBody] CancelLeaveRequestApproveDto req) { var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(getPermission); if (jsonData["status"]?.ToString() != "200") { return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden); } await _leaveRequestRepository.ApproveCancelLeaveRequestAsync(id, req.Reason ?? ""); return Success(); } /// /// LV2_019 - ผู้มีอำนาจไม่อนุมัติขอยกเลิกการลา(ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPut("admin/delete/reject/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> RejectCancelLeaveRequestAsync(Guid id, [FromBody] CancelLeaveRequestApproveDto req) { var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(getPermission); if (jsonData["status"]?.ToString() != "200") { return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden); } await _leaveRequestRepository.RejectCancelLeaveRequestAsync(id, req.Reason ?? ""); return Success(); } /// /// LV2_013 - เจ้าหน้าที่อนุมัติการลา (ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet("admin/approve/officer/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> OfficerApproveLeaveRequestAsync(Guid id) { var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(getPermission); if (jsonData["status"]?.ToString() != "200") { return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden); } await _leaveRequestRepository.OfficerApproveLeaveRequest(id); return Success(); } /// /// LV2_015 - ผู้บังคับบัญชาอนุมัติการลา(ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPut("admin/approve/comander/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> CommanderApproveLeaveRequestAsync(Guid id, [FromBody] LeaveRequestApproveDto req) { try { var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(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); } } /// /// ผู้บังคับบัญชาไม่อนุมัติการลา(ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPut("admin/reject/comander/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> CommanderRejectLeaveRequestAsync(Guid id, [FromBody] LeaveRequestApproveDto req) { try { var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(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); } } /// /// LV2_016 - ผู้มีอำนาจอนุมัติการลา (ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPut("admin/approve/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> ApproveLeaveRequestAsync(Guid id, [FromBody] LeaveRequestApproveDto req) { try { var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(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); } } /// /// LV2_021 - ส่งคำขอลา /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPut("user/send/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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().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); } } /// /// LV2_017 - ผู้มีอำนาจไม่อนุมัติการลา (ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPut("admin/reject/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> RejectLeaveRequestAsync(Guid id, [FromBody] LeaveRequestApproveDto req) { try { var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_LIST"); var jsonData = JsonConvert.DeserializeObject(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); } } /// /// LV2_012 - รายละเอียดการลา (ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet("admin/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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(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(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); } /// /// LV2_009 - รายการตารางสถิติการลา (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet("user/summary")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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(); foreach (var leaveType in leaveTypes) { var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUser(thisYear, leaveType.Id, pf); leaveBeginningDict[leaveType.Id] = leaveData; } var result = new List(); 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); } /// /// LV2_037 - ลบเอกสารประกอบรายละเอียดการลา (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpDelete("user/file/document/{id:guid}/{docId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> 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> 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 } }