using BMA.EHR.Application.Repositories; using BMA.EHR.Application.Repositories.Leaves.LeaveRequests; using BMA.EHR.Application.Repositories.MetaData; using BMA.EHR.Domain.Common; using BMA.EHR.Domain.Extensions; 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 Swashbuckle.AspNetCore.Annotations; using System.Security.Claims; using BMA.EHR.Application.Repositories.Commands; 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 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) { _context = context; _httpContextAccessor = httpContextAccessor; _hostingEnvironment = hostingEnvironment; _configuration = configuration; _userProfileRepository = userProfileRepository; _leaveTypeRepository = leaveTypeRepository; _leaveRequestRepository = leaveRequestRepository; _minIOService = minIOService; _holidayRepository = holidayRepository; _commandRepository = commandRepository; } #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"); private Guid OcId { get { if (UserId != null || UserId != "") return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!)); 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 thisYear = DateTime.Now.Year; var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId); 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 leaveRequest = new LeaveRequest { Type = leaveType, LeaveStartDate = req.LeaveStartDate, LeaveEndDate = req.LeaveEndDate, LeaveWrote = req.LeaveWrote ?? "", LeaveDetail = req.LeaveDetail ?? "", LeaveAddress = req.LeaveAddress ?? "", LeaveNumber = req.LeaveNumber ?? "", LeaveTotal = req.LeaveStartDate.DiffDay(req.LeaveEndDate), LeaveSalaryText = req.LeaveSalaryText ?? "", LeaveStatus = "NEW", KeycloakUserId = userId, ApproveStep = APPROVE_STEP_CREATE }; // get leave last leaveRequest.LeaveLast = await _leaveRequestRepository.GetLeaveLastByTypeForUserAsync(userId, req.Type); // upload document if (req.LeaveDocument != null) { var doc = await _minIOService.UploadFileAsync(req.LeaveDocument); if (doc != null) { leaveRequest.LeaveDocument = doc; } } // upload draft document if (req.LeaveDraftDocument != null) { var doc = await _minIOService.UploadFileAsync(req.LeaveDraftDocument); if (doc != null) { leaveRequest.LeaveDraftDocument = doc; } } // 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.Salaries.OrderByDescending(x => x.Order).FirstOrDefault(); 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.Salaries.OrderByDescending(x => x.Order).FirstOrDefault(); 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; } // save to database await _leaveRequestRepository.AddAsync(leaveRequest); 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); 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.Salaries.OrderByDescending(x => x.Order).FirstOrDefault(); var rootOc = _userProfileRepository.GetRootOcId(profile.OcId ?? Guid.Empty); 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, Dear = approver, FullName = $"{profile.Prefix.Name}{profile.FirstName} {profile.LastName}", PositionName = profile.Position == null ? "" : profile.Position.Name, PositionLevelName = profile.PositionLevel == null ? "" : profile.PositionLevel.Name, 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 leaveType = await _leaveTypeRepository.GetByIdAsync(req.Type); if (leaveType == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var sumLeave = await _leaveRequestRepository.GetSumLeaveByTypeForUserAsync(userId, req.Type, req.StartLeaveDate.Year); var sumWorkDay = await _holidayRepository.GetHolidayCountAsync(req.StartLeaveDate, req.EndLeaveDate); var totalDay = req.StartLeaveDate.DiffDay(req.EndLeaveDate); var sumWeekend = _holidayRepository.GetWeekEndCount(req.StartLeaveDate, req.EndLeaveDate); var isLeave = sumLeave + (totalDay - sumWorkDay) <= 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 result = new List(); foreach (var item in data) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(item.KeycloakUserId); 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.Name}{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); 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 = $"{profile.Prefix.Name}{profile.FirstName} {profile.LastName}", DateSendLeave = item.CreatedAt.Date, IsDelete = item.LeaveStatus == "DELETE", Status = item.LeaveStatus }; 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); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var lastSalary = profile.Salaries.OrderByDescending(x => x.Order).FirstOrDefault(); var lastSalaryAmount = lastSalary == null ? 0 : lastSalary.Amount ?? 0; var lastLeaveRequest = await _leaveRequestRepository.GetLastLeaveRequestByTypeForUserAsync(rawData.KeycloakUserId, rawData.Type.Id); var result = new GetLeaveRequestByIdDto { Id = rawData.Id, LeaveTypeName = rawData.Type.Name, LeaveTypeId = rawData.Type.Id, FullName = $"{profile.Prefix.Name}{profile.FirstName} {profile.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 = 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), 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, }; 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); var result = new List(); foreach (var item in rawData) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(item.KeycloakUserId); var res = new GetLeaveRequestForAdminResultDto { Id = item.Id, LeaveTypeId = item.Type.Id, LeaveTypeName = item.Type.Name, FullName = $"{profile.Prefix.Name}{profile.FirstName} {profile.LastName}", DateSendLeave = item.CreatedAt.Date, Status = item.LeaveStatus }; 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 ?? ""; // add cancel status to new data.LeaveCancelStatus = "NEW"; data.LeaveCancelComment = 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.UpdateAsync(data); // await _leaveRequestRepository.AddAsync(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); var res = new GetLeaveCancelRequestResultDto { Id = item.Id, LeaveTypeId = item.Type.Id, LeaveTypeName = item.Type.Name, FullName = $"{profile.Prefix.Name}{profile.FirstName} {profile.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); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var result = new GetCancelLeaveRequestByIdDto { Id = rawData.Id, LeaveTypeName = rawData.Type.Name, FullName = $"{profile.Prefix.Name}{profile.FirstName} {profile.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_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); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var lastSalary = profile.Salaries.OrderByDescending(x => x.Order).FirstOrDefault(); 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); 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 result = new GetLeaveRequestForAdminByIdDto { Id = rawData.Id, ReasonCommander = rawData.LeaveComment ?? "", ReasonOligarch = rawData.LeaveDirectorComment ?? "", PositionName = profile.Position == null ? "" : profile.Position.Name, PositionLevelName = profile.PositionLevel == null ? "" : profile.PositionLevel.Name, OrganizationName = profile.Oc ?? "", LeaveTypeName = rawData.Type.Name, LeaveTypeId = rawData.Type.Id, FullName = $"{profile.Prefix.Name}{profile.FirstName} {profile.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 = 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), 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, ApproveStep = rawData.ApproveStep ?? "-", LeaveLimit = rawData.Type.Limit, LeaveSummary = leaveSummary, LeaveRemain = rawData.Type.Limit - leaveSummary }; 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 result = new List(); foreach (var leaveType in leaveTypes) { var send = await _leaveRequestRepository.GetSumSendLeaveByTypeForUserAsync(userId, leaveType.Id, thisYear); var approve = await _leaveRequestRepository.GetSumApproveLeaveByTypeForUserAsync(userId, leaveType.Id, thisYear); var reject = await _leaveRequestRepository.GetSumRejectLeaveByTypeForUserAsync(userId, leaveType.Id, thisYear); var delete = await _leaveRequestRepository.GetSumDeleteLeaveByTypeForUserAsync(userId, leaveType.Id, thisYear); 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); } #endregion } }