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.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.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 Swashbuckle.AspNetCore.Annotations; 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 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 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"; #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) { _context = context; _httpContextAccessor = httpContextAccessor; _hostingEnvironment = hostingEnvironment; _configuration = configuration; _userProfileRepository = userProfileRepository; _leaveTypeRepository = leaveTypeRepository; _leaveRequestRepository = leaveRequestRepository; _minIOService = minIOService; _holidayRepository = holidayRepository; _commandRepository = commandRepository; _userCalendarRepository = userCalendarRepository; } #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 " /// /// 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); 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, 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, // แก้ไขให้รับค่ามาจาก request แทน LeaveSalaryText = req.LeaveSalaryText ?? "", LeaveStatus = "DRAFT", KeycloakUserId = userId, ApproveStep = APPROVE_STEP_CREATE, Prefix = profile.Prefix, FirstName = profile.FirstName, LastName = profile.LastName, CitizenId = profile.CitizenId, }; // 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; 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; 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 = string.Empty; 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 = approver; leaveRequest.PositionName = profile.Position == null ? "" : profile.Position; leaveRequest.PositionLevelName = profile.PosLevel == null ? "" : profile.PosLevel.PosLevelName; leaveRequest.OrganizationName = profile.Oc ?? ""; // save to database await _leaveRequestRepository.AddAsync(leaveRequest); return Success(new { id = leaveRequest.Id }); } /// /// 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) { 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); 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; 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); // 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; 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; 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 = string.Empty; 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 = approver; leaveRequest.PositionName = profile.Position == null ? "" : profile.Position; leaveRequest.PositionLevelName = profile.PosLevel == null ? "" : profile.PosLevel.PosLevelName; leaveRequest.OrganizationName = profile.Oc ?? ""; _context.Entry(leaveRequest.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(leaveRequest); return Success(new { id = leaveRequest.Id }); } /// /// 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 profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken); 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 sumLeave = await _leaveRequestRepository.GetSumLeaveByTypeForUserAsync(userId, req.Type, thisYear); var restOldDay = await _leaveRequestRepository.GetRestDayTotalByYearForUserAsync(userId, thisYear - 1); var lastSalary = profile.ProfileSalary; 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 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 = approver, PositionName = profile.Position == null ? "" : profile.Position, PositionLevelName = profile.PosLevel == null ? "" : profile.PosLevel.PosLevelName, OrganizationName = profile.Oc ?? "", LeaveLimit = leaveType.Limit, LeaveTotal = sumLeave, LeaveRemain = leaveType.Limit - sumLeave, RestDayTotalOld = restOldDay, BirthDate = profile.BirthDate.Date, DateAppoint = profile.DateAppoint == null ? null : profile.DateAppoint.Value.Date, Salary = lastSalary == null ? 0 : (int)lastSalary.Amount.Value, SalaryText = lastSalary == null ? "" : ((int)lastSalary.Amount.Value).ToThaiBahtText(false), LeaveLast = leaveLast == null ? null : leaveLast }; return Success(result); } /// /// LV2_003 - เช็คการยืนขอลา (USER) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("user/check")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> CheckUserLeaveAsync([FromBody] GetLeaveCheckDto req) { var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId); var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken); var govAge = profile!.DateStart!.Value.Date.DiffDay(DateTime.Now.Date); 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 totalDay = req.StartLeaveDate.DiffDay(req.EndLeaveDate.Date); var sumWeekend = _holidayRepository.GetWeekEndCount(req.StartLeaveDate.Date, req.EndLeaveDate.Date, category); var isLeave = false; switch (leaveType.Code.ToUpper().Trim()) { case "LV-001": case "LV-002": case "LV-007": isLeave = true; break; case "LV-003": isLeave = totalDay <= 90; break; case "LV-004": isLeave = (totalDay - sumWorkDay - sumWeekend) <= 15; break; case "LV-005": isLeave = (totalDay - sumWorkDay - sumWeekend) <= 10; break; case "LV-006": isLeave = totalDay <= 120; break; case "LV-008": case "LV-009": isLeave = govAge >= 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; break; case "LV-011": isLeave = totalDay <= 360; break; } //var isLeave = sumLeave + (totalDay - sumWorkDay - sumWeekend) <= leaveType.Limit; var result = new GetLeaveCheckResultDto { IsLeave = isLeave, SumDateWork = sumWorkDay, TotalDate = totalDay, SumDateHoliday = sumWeekend }; return Success(result); } /// /// LV2_004 - รายการลา Calendar (USER/ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("user/calendar")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> GetLeaveRequestCalendarAsync( [FromBody] GetLeaveRequestCalendarDto req) { //var thisYear = DateTime.Now.Year; var data = await _leaveRequestRepository.GetLeaveRequestByYearAsync(req.Year); // var profileList = await _userProfileRepository.GetProfileWithKeycloak(AccessToken); 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); //var personList = new List(); //var result = new List(); //foreach (var item in data) //{ // var profile = personList.FirstOrDefault(x => x.Keycloak == item.KeycloakUserId); // if (profile == null) // { // profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(item.KeycloakUserId, AccessToken); // personList.Add(profile); // } // //var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(item.KeycloakUserId, AccessToken); // var resData = new GetLeaveRequestCalendarResultDto // { // Id = item.Id, // LeaveTypeName = item.Type.Name, // LeaveTypeId = item.Type.Id, // DateSendLeave = item.CreatedAt.Date, // Status = item.LeaveStatus, // FullName = $"{profile.Prefix}{profile.FirstName} {profile.LastName}", // LeaveStartDate = item.LeaveStartDate, // LeaveEndDate = item.LeaveEndDate, // KeycloakId = item.KeycloakUserId // }; // result.Add(resData); //} //return Success(result); } /// /// 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, FullName = $"{item.Prefix}{item.FirstName} {item.LastName}", DateSendLeave = item.CreatedAt.Date, IsDelete = item.LeaveStatus == "DELETE", Status = item.LeaveStatus, LeaveStartDate = item.LeaveStartDate, LeaveEndDate = item.LeaveEndDate }; result.Add(res); } if (req.Keyword != "") result = result.Where(x => x.FullName.Contains(req.Keyword)).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); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } 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); 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 result = new GetLeaveRequestByIdDto { Id = rawData.Id, LeaveRange = rawData.LeaveRange ?? "", LeaveTypeName = rawData.Type.Name, 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(), //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), WifeDayName = rawData.WifeDayName, WifeDayDateBorn = rawData.WifeDayDateBorn, 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 ?? "", PositionName = rawData.PositionName ?? "", PositionLevelName = rawData.PositionLevelName ?? "", OrganizationName = rawData.OrganizationName ?? "", 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 rawData = await _leaveRequestRepository.GetLeaveRequestForAdminAsync(req.Year, req.Type, req.Status, req.StartDate, req.EndDate); var result = new List(); foreach (var item in rawData) { //var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(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 res = new GetLeaveRequestForAdminResultDto { Id = item.Id, LeaveTypeId = item.Type.Id, LeaveTypeName = item.Type.Name, FullName = $"{item.Prefix}{item.FirstName} {item.LastName}", DateSendLeave = item.CreatedAt.Date, Status = item.LeaveStatus, CitizenId = item.CitizenId ?? "", LeaveStartDate = item.LeaveStartDate, LeaveEndDate = item.LeaveEndDate, Position = item.PositionName ?? "-", Level = item.PositionLevelName ?? "-", Agency = "-", //agency == null ? "" : agency.Name, Org = "-", //gov_agency == null ? "" : gov_agency.Name, LeaveRange = item.LeaveRange ?? "ALL" }; result.Add(res); } if (req.Keyword != "") result = result.Where(x => x.FullName.Contains(req.Keyword)).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.GetByIdAsync(id); if (data == null) { //return Success(new List()); return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } // change status to delete data.LeaveStatus = "DELETE"; data.CancelLeaveWrote = req.LeaveWrote ?? ""; // ถ้าผู้มีอำนาจอนุมัติแล้ว ต้องมีการรอ if (data.ApproveStep == "st4") { // add cancel status to new data.LeaveCancelStatus = "NEW"; data.LeaveCancelComment = req.Reason ?? ""; } else { await _leaveRequestRepository.ApproveCancelLeaveRequestAsync(data.Id, "อนุมัติการขอยกเลิกการลา โดยระบบ"); } // 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.UpdateAsync(data); 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 rawData = await _leaveRequestRepository.GetCancelLeaveRequestForAdminAsync(req.Year, req.Type, req.Status); var result = new List(); foreach (var item in rawData) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(item.KeycloakUserId, AccessToken); var res = new GetLeaveCancelRequestResultDto { Id = item.Id, LeaveTypeId = item.Type.Id, LeaveTypeName = item.Type.Name, 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(); var pageResult = result.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList(); return Success(new { data = pageResult, total = result.Count }); } /// /// 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, 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, }; return Success(result); } /// /// 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) { 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) { 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) { 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) { await _leaveRequestRepository.CommanderApproveLeaveRequest(id, req.Reason ?? ""); return Success(); } /// /// 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) { await _leaveRequestRepository.ApproveLeaveRequest(id, req.Reason ?? ""); return Success(); } /// /// 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) { await _leaveRequestRepository.SendToOfficerAsync(id); return Success(); } /// /// 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) { await _leaveRequestRepository.RejectLeaveRequest(id, req.Reason ?? ""); return Success(); } /// /// LV2_012 - รายละเอียดการลา (ADMIN) /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet("admin/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> GetLeaveRequestForAdminByIdAsync(Guid id) { var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId); 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 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); 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 leaveSummary = await _leaveRequestRepository.GetSumApproveLeaveByTypeForUserAsync(userId, rawData.Type.Id, thisYear); 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 result = new GetLeaveRequestForAdminByIdDto { Id = rawData.Id, ReasonCommander = rawData.LeaveComment ?? "", ReasonOligarch = rawData.LeaveDirectorComment ?? "", LeaveTypeName = rawData.Type.Name, 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", 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 = profile.BirthDate, LeaveGovernmentDate = profile.DateAppoint == null ? null : profile.DateAppoint.Value, LeaveSalary = lastSalary == null ? 0 : lastSalaryAmount, LeaveSalaryText = lastSalary == null ? "" : ((int)lastSalaryAmount).ToThaiBahtText(false), WifeDayName = rawData.WifeDayName, WifeDayDateBorn = rawData.WifeDayDateBorn, 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 = approver, // PositionName = profile.Position == null ? "" : profile.Position.Name, // PositionLevelName = profile.PositionLevel == null ? "" : profile.PositionLevel.Name, // OrganizationName = profile.Oc ?? "", // เปลี่ยนมาอ่านจากฐานข้อมูลแทน read_db Dear = rawData.Dear ?? "", PositionName = rawData.PositionName ?? "", PositionLevelName = rawData.PositionLevelName ?? "", OrganizationName = rawData.OrganizationName ?? "", ApproveStep = rawData.ApproveStep ?? "-", LeaveLimit = rawData.Type.Limit, LeaveSummary = leaveSummary, LeaveRemain = rawData.Type.Limit - 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 }); } } 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 leaveTypes = await _leaveTypeRepository.GetAllAsync(); var thisYear = DateTime.Now.Year; var sendList = await _leaveRequestRepository.GetSumSendLeaveAsync(thisYear); var approveList = await _leaveRequestRepository.GetSumApproveLeaveAsync(thisYear); var rejectList = await _leaveRequestRepository.GetSumRejectLeaveAsync(thisYear); var deleteList = await _leaveRequestRepository.GetSumDeleteLeaveAsync(thisYear); var result = new List(); foreach (var leaveType in leaveTypes) { var sendData = sendList.FirstOrDefault(x => x.KeycloakUserId == userId && x.LeaveTypeId == leaveType.Id); var send = sendData == null ? 0 : sendData.SumLeaveDay; var approveData = approveList.FirstOrDefault(x => x.KeycloakUserId == userId && x.LeaveTypeId == leaveType.Id); var approve = approveData == null ? 0 : approveData.SumLeaveDay; var rejectData = rejectList.FirstOrDefault(x => x.KeycloakUserId == userId && x.LeaveTypeId == leaveType.Id); var reject = rejectData == null ? 0 : rejectData.SumLeaveDay; var deleteData = deleteList.FirstOrDefault(x => x.KeycloakUserId == userId && x.LeaveTypeId == leaveType.Id); var delete = deleteData == null ? 0 : deleteData.SumLeaveDay; var data = new { Id = leaveType.Id, LeaveTypeName = leaveType.Name, LeaveLimit = leaveType.Limit, LeaveExtend = 0, 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 } }