using System.Data.Common; using System.Globalization; using System.IO.Pipelines; using System.Security.Claims; 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.Requests; using BMA.EHR.Domain.Models.Leave.TimeAttendants; using BMA.EHR.Domain.Shared; using BMA.EHR.Infrastructure.Persistence; using BMA.EHR.Leave.Service.DTOs.Reports; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Org.BouncyCastle.Utilities; using Swashbuckle.AspNetCore.Annotations; namespace BMA.EHR.Leave.Service.Controllers { [Route("api/v{version:apiVersion}/leave/report")] [ApiVersion("1.0")] [ApiController] [Produces("application/json")] [Authorize] [SwaggerTag("API ระบบลงเวลาและการลา (ดึงข้อมูลสำหรับนำไปออกรายงาน)")] public class LeaveReportController : BaseController { #region " Fields " private static CultureInfo _culture = new CultureInfo("th-TH"); private readonly LeaveRequestRepository _leaveRequestRepository; private readonly UserProfileRepository _userProfileRepository; private readonly CommandRepository _commandRepository; private readonly LeaveTypeRepository _leaveTypeRepository; private readonly ProcessUserTimeStampRepository _processUserTimeStampRepository; private readonly DutyTimeRepository _dutyTimeRepository; private readonly UserDutyTimeRepository _userDutyTimeRepository; private readonly HolidayRepository _holidayRepository; private readonly UserCalendarRepository _userCalendarRepository; private readonly IHttpContextAccessor _httpContextAccessor; #endregion #region " Constructor and Destructor " public LeaveReportController(LeaveRequestRepository leaveRequestRepository, UserProfileRepository userProfileRepository, CommandRepository commandRepository, LeaveTypeRepository leaveTypeRepository, ProcessUserTimeStampRepository processUserTimeStampRepository, DutyTimeRepository dutyTimeRepository, UserDutyTimeRepository userDutyTimeRepository, HolidayRepository holidayRepository, UserCalendarRepository userCalendarRepository, IHttpContextAccessor httpContextAccessor) { _leaveRequestRepository = leaveRequestRepository; _userProfileRepository = userProfileRepository; _commandRepository = commandRepository; _leaveTypeRepository = leaveTypeRepository; _processUserTimeStampRepository = processUserTimeStampRepository; _dutyTimeRepository = dutyTimeRepository; _userDutyTimeRepository = userDutyTimeRepository; _holidayRepository = holidayRepository; _userCalendarRepository = userCalendarRepository; _httpContextAccessor = httpContextAccessor; } #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 string? AccessToken => _httpContextAccessor?.HttpContext?.Request.Headers["Authorization"]; private Guid OcId { get { if (UserId != null || UserId != "") return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!)); else return Guid.Empty; } } #endregion #region " Methods " #region " Private Methods " private async Task GetReport01(LeaveRequest data) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}"; var lastLeaveRequest = await _leaveRequestRepository.GetLastLeaveRequestByTypeForUserAsync(data.KeycloakUserId, data.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 sumLeave = await _leaveRequestRepository.GetSumApproveLeaveByTypeForUserAsync(data.KeycloakUserId, data.Type.Id, data.LeaveStartDate.Year); return new { template = "leave9", reportName = $"leave_form", data = new { leaveWrote = data.LeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, dear = approver, fullname = fullName, positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", leaveDetail = data.LeaveDetail, leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), LeaveTotal = data.LeaveStartDate.DiffDay(data.LeaveEndDate), leaveAddress = data.LeaveAddress, leaveNumber = data.LeaveNumber, LeaveLastStart = lastLeaveRequest == null ? "" : lastLeaveRequest.LeaveStartDate.Date.ToThaiShortDate(), LeaveLastEnd = lastLeaveRequest == null ? "" : lastLeaveRequest.LeaveEndDate.Date.ToThaiShortDate(), LeaveSummary = sumLeave, LeaveRemain = data.Type.Limit - sumLeave, } }; } private async Task GetReport02(LeaveRequest data) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}"; 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; } return new { template = "leave10", reportName = $"leave_form", data = new { leaveWrote = data.LeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, dear = approver, fullname = fullName, positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", wifeDayName = data.WifeDayName ?? "", wifeDayDateBorn = data.WifeDayDateBorn ?? "", leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), LeaveTotal = data.LeaveStartDate.DiffDay(data.LeaveEndDate), leaveAddress = data.LeaveAddress, leaveNumber = data.LeaveNumber, } }; } private async Task GetReport03(LeaveRequest data) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}"; 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 sumLeave = await _leaveRequestRepository.GetSumApproveLeaveByTypeForUserAsync(data.KeycloakUserId, data.Type.Id, data.LeaveStartDate.Year); return new { template = "leave11", reportName = $"leave_form", data = new { leaveWrote = data.LeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, dear = approver, fullname = fullName, positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", restDayOldTotal = data.RestDayOldTotal, restDayCurrentTotal = data.RestDayCurrentTotal, leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), LeaveTotal = data.LeaveStartDate.DiffDay(data.LeaveEndDate), leaveAddress = data.LeaveAddress, leaveNumber = data.LeaveNumber, LeaveSummary = sumLeave, LeaveRemain = data.Type.Limit - sumLeave, } }; } private async Task GetReport04(LeaveRequest data, bool isHajj = false) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}"; 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; } if (isHajj) { return new { template = "leave13", reportName = $"leave_form", data = new { leaveWrote = data.LeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, dear = approver, fullname = fullName, positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", leavegovernmentDate = data.LeaveGovernmentDate == null ? "" : data.LeaveGovernmentDate.Value.Date.ToThaiShortDate(), hajjDayStatus = data.HajjDayStatus, leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), LeaveTotal = data.LeaveStartDate.DiffDay(data.LeaveEndDate), } }; } else { return new { template = "leave12", reportName = $"leave_form", data = new { leaveWrote = data.LeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, dear = approver, fullname = fullName, positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", leavebirthDate = data.LeaveBirthDate == null ? "" : data.LeaveBirthDate.Value.Date.ToThaiShortDate(), leavegovernmentDate = data.LeaveGovernmentDate == null ? "" : data.LeaveGovernmentDate.Value.Date.ToThaiShortDate(), ordainDayStatus = data.OrdainDayStatus, ordainDayLocationName = data.OrdainDayLocationName, ordainDayLocationAddress = data.OrdainDayLocationAddress, ordainDayLocationNumber = data.OrdainDayLocationNumber, ordainDayOrdination = data.OrdainDayOrdination, ordainDayBuddhistLentName = data.OrdainDayBuddhistLentName, ordainDayBuddhistLentAddress = data.OrdainDayBuddhistLentAddress, leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), LeaveTotal = data.LeaveStartDate.DiffDay(data.LeaveEndDate), } }; } } private async Task GetReport05(LeaveRequest data) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}"; 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; } return new { template = "leave14", reportName = $"leave_form", data = new { leaveWrote = data.LeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, dear = approver, fullname = fullName, positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", absentDaySummon = data.AbsentDaySummon, absentDayLocation = data.AbsentDayLocation, absentDayRegistorDate = data.AbsentDayRegistorDate.Date.ToThaiShortDate(), absentDayGetIn = data.AbsentDayGetIn, absentDayAt = data.AbsentDayAt, leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), LeaveTotal = data.LeaveStartDate.DiffDay(data.LeaveEndDate), } }; } private async Task GetReport06(LeaveRequest data) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}"; 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; } return new { template = "leave15", reportName = $"leave_form", data = new { leaveWrote = data.LeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, dear = approver, fullname = fullName, positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", leavebirthDate = data.LeaveBirthDate == null ? "" : data.LeaveBirthDate.Value.Date.ToThaiShortDate(), leavegovernmentDate = data.LeaveGovernmentDate == null ? "" : data.LeaveGovernmentDate.Value.Date.ToThaiShortDate(), leaveSalary = data.LeaveSalary, leaveSalaryText = data.LeaveSalaryText, studyDaySubject = data.StudyDaySubject ?? "", studyDayDegreeLevel = data.StudyDayDegreeLevel ?? "", studyDayUniversityName = data.StudyDayUniversityName ?? "", studyDayCountry = data.StudyDayCountry ?? "", studyDayScholarship = data.StudyDayScholarship ?? "", studyDayTrainingSubject = data.StudyDayTrainingSubject ?? "", studyDayTrainingName = data.StudyDayTrainingName ?? "", leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), LeaveTotal = data.LeaveStartDate.DiffDay(data.LeaveEndDate), leaveAddress = data.LeaveAddress, leaveNumber = data.LeaveNumber, } }; } private async Task GetReport07(LeaveRequest data) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}"; 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; } return new { template = "leave16", reportName = $"leave_form", data = new { leaveWrote = data.LeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, dear = approver, fullname = fullName, fullnameEng = "", positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), } }; } private async Task GetReport08(LeaveRequest data) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}"; 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; } return new { template = "leave17", reportName = $"leave_form", data = new { leaveWrote = data.LeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, dear = approver, fullname = fullName, positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", leaveSalary = data.LeaveSalary, leaveSalaryText = data.LeaveSalaryText, coupleDayName = data.CoupleDayName, coupleDayLevel = data.CoupleDayLevel, coupleDayPosition = data.CoupleDayPosition, coupleDayOrganizationName = "-", coupleDayLevelCountry = data.CoupleDayLevelCountry, coupleDayCountryHistory = data.CoupleDayCountryHistory, coupleDayTotalHistory = data.CoupleDayTotalHistory, coupleDayStartDateHistory = data.CoupleDayStartDateHistory.Date.ToThaiShortDate(), coupleDayEndDateHistory = data.CoupleDayEndDateHistory.Date.ToThaiShortDate(), coupleDaySumTotalHistory = data.CoupleDaySumTotalHistory, leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), LeaveTotal = data.LeaveStartDate.DiffDay(data.LeaveEndDate), } }; } private async Task GetReport09(LeaveRequest data) { var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}"; 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; } return new { template = "leave18", reportName = $"leave_form", data = new { leaveWrote = data.LeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, dear = approver, fullname = fullName, positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), } }; } #endregion /// /// LV2_033 - รายงานการลา /// /// รหัสของรายการขอลา /// เป็นการแสดงรายงานการขอลาไปพิธีอัจย์หรือไม่? /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet("{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> GetReport(Guid id, [FromQuery] bool hajj = false) { try { var data = await _leaveRequestRepository.GetByIdAsync(id); if (data == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } dynamic result = new { }; switch (data.Type.Code.Trim().ToUpper()) { case "LV-001": case "LV-002": case "LV-003": { result = await GetReport01(data); break; } case "LV-004": { result = await GetReport02(data); break; } case "LV-005": { result = await GetReport03(data); break; } case "LV-006": { result = await GetReport04(data, hajj); break; } case "LV-007": { result = await GetReport05(data); break; } case "LV-008": { result = await GetReport06(data); break; } case "LV-009": { result = await GetReport07(data); break; } case "LV-010": { result = await GetReport08(data); break; } case "LV-011": { result = await GetReport09(data); break; } } return Success(result); } catch (Exception ex) { return Error(ex); } } /// /// LV2_034 - รายงานการยกเลิกการลา /// /// รหัสของรายการขอลา /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet("reject/{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> GetCancelReport(Guid id) { try { var data = await _leaveRequestRepository.GetByIdAsync(id); if (data == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken); if (profile == null) { return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}"; 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 result = new { template = "แบบใบขอยกเลิกวันลา", reportName = $"leave_cancel_form", data = new { leaveWrote = data.CancelLeaveWrote ?? "", dateSendLeave = data.CreatedAt.Date.ToThaiShortDate(), leaveTypeName = data.Type.Name, fullname = fullName, positionName = profile!.Position == null ? "-" : profile!.Position, positionLeaveName = profile!.Position == null ? "-" : profile!.Position, organizationName = profile!.Oc ?? "", leaveDateStart = data.LeaveStartDate.Date.ToThaiShortDate(), leaveDateEnd = data.LeaveEndDate.Date.ToThaiShortDate(), dear = approver, leaveTotal = data.LeaveTotal } }; return Success(result); } catch (Exception ex) { return Error(ex); } } /// /// LV2_035 - รายงานบัญชีแสดงวันลา ขรก /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("leaveday/officer")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> GetOfficerLeaveDayReport([FromBody] GetLeaveReportDto req) { try { //var profile = await _userProfileRepository.SearchProfile(null, null, null); var profile = await _userProfileRepository.GetProfileWithKeycloak(); var count = 1; var employees = new List(); foreach (var p in profile) { var sickType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-001"); if (sickType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var sickDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, sickType.Id, req.StartDate, req.EndDate); var personalType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-002"); if (personalType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var personalDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, personalType.Id, req.StartDate, req.EndDate); var maternityType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-003"); if (maternityType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var maternityDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, maternityType.Id, req.StartDate, req.EndDate); var wifeType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-004"); if (wifeType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var wifeDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, wifeType.Id, req.StartDate, req.EndDate); var restType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-005"); if (restType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var restDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, restType.Id, req.StartDate, req.EndDate); var ordainType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-006"); if (ordainType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var ordainDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, ordainType.Id, req.StartDate, req.EndDate); var absentType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-007"); if (absentType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var absentDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, absentType.Id, req.StartDate, req.EndDate); var studyType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-008"); if (studyType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var studyDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, studyType.Id, req.StartDate, req.EndDate); var agencyType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-009"); if (agencyType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var agencyDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, agencyType.Id, req.StartDate, req.EndDate); var coupleType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-010"); if (coupleType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var coupleDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, coupleType.Id, req.StartDate, req.EndDate); var therapyType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-011"); if (therapyType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var therapyDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, therapyType.Id, req.StartDate, req.EndDate); var timeStamps = await _processUserTimeStampRepository.GetTimeStampHistoryByRangeForUserAsync(p.KeycloakId ?? Guid.Empty, req.StartDate, req.EndDate); var defaultRound = await _dutyTimeRepository.GetDefaultAsync(); if (defaultRound == null) { return Error("ไม่พบรอบการลงเวลา Default", StatusCodes.Status404NotFound); } //var userRound = await _dutyTimeRepository.GetByIdAsync(profile.DutyTimeId ?? Guid.Empty); var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(p.Id); var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty; var userRound = await _dutyTimeRepository.GetByIdAsync(roundId); var duty = userRound ?? defaultRound; var processTimeStamps = timeStamps .Select(d => new { d.Id, CheckInStatus = DateTime.Parse(d.CheckIn.ToString("yyyy-MM-dd HH:mm")) > DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.StartTimeMorning}") ? "LATE" : "NORMAL", CheckOutStatus = d.CheckOut == null ? "" : DateTime.Parse(d.CheckOut.Value.ToString("yyyy-MM-dd HH:mm")) < DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.EndTimeAfternoon}") ? "LATE" : DateTime.Parse(d.CheckOut.Value.ToString("yyyy-MM-dd HH:mm")) < DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.EndTimeMorning}") ? "ABSENT" : "NORMAL", }); var absentCount = processTimeStamps.Count(x => x.CheckOutStatus == "ABSENT"); var lateCount = processTimeStamps.Count(x => x.CheckInStatus == "LATE"); var emp = new { no = count, fullName = _userProfileRepository.GetUserFullName(p.KeycloakId ?? Guid.Empty), position = p.Position == null ? "" : p.Position.Name, positionLevel = p.PositionLevel == null ? "" : p.PositionLevel.Name, posNo = p.PosNo == null ? "" : p.PosNo.Name, reason = "", sickDayCount = sickDayCount, maternityDayCount = maternityDayCount, wifeDayCount = wifeDayCount, personalDayCount = personalDayCount, restDayCount = restDayCount, ordainDayCount = ordainDayCount, absentDayCount = absentDayCount, studyDayCount = studyDayCount, agencyDayCount = agencyDayCount, coupleDayCount = coupleDayCount, therapyDayCount = therapyDayCount, absentTotal = absentCount, lateTotal = lateCount, leaveTotal = sickDayCount + maternityDayCount + wifeDayCount + personalDayCount + restDayCount + ordainDayCount + absentDayCount + studyDayCount + agencyDayCount + coupleDayCount + therapyDayCount }; employees.Add(emp); count++; } var result = new { template = "LeaveHalfYear-ขรก", reportName = "LeaveHalfYear-Officer", data = new { leaveDateStart = req.StartDate.Date.ToThaiShortDate().ToThaiNumber(), leaveDateEnd = req.EndDate.Date.ToThaiShortDate().ToThaiNumber(), organizationName = profile.First().Oc ?? "", leaveTitleType = req.Type == "FULL" ? "หนึ่งปี" : "ครึ่งปี", employees = employees } }; return Success(result); } catch (Exception ex) { return Error(ex); } } /// /// LV2_036 - รายงานบัญชีแสดงวันลา ลูกจ้าง /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("leaveday/employee")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> GetEmployeeLeaveDayReport([FromBody] GetLeaveReportDto req) { try { var profile = await _userProfileRepository.SearchProfileEmployee(null, null, null); var count = 1; var employees = new List(); foreach (var p in profile) { var sickType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-001"); if (sickType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var sickDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, sickType.Id, req.StartDate, req.EndDate); var sickCount = await _leaveRequestRepository.GetCountApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, sickType.Id, req.StartDate, req.EndDate); var personalType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-002"); if (personalType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var personalDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, personalType.Id, req.StartDate, req.EndDate); var personalCount = await _leaveRequestRepository.GetCountApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, personalType.Id, req.StartDate, req.EndDate); var maternityType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-003"); if (maternityType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var maternityDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, maternityType.Id, req.StartDate, req.EndDate); var wifeType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-004"); if (wifeType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var wifeDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, wifeType.Id, req.StartDate, req.EndDate); var restType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-005"); if (restType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var restDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, restType.Id, req.StartDate, req.EndDate); var ordainType = await _leaveTypeRepository.GetLeaveTypeByCodeAsync("LV-006"); if (ordainType == null) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); var ordainDayCount = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRangeForUser(p.KeycloakId ?? Guid.Empty, ordainType.Id, req.StartDate, req.EndDate); var timeStamps = await _processUserTimeStampRepository.GetTimeStampHistoryByRangeForUserAsync(p.KeycloakId ?? Guid.Empty, req.StartDate, req.EndDate); var defaultRound = await _dutyTimeRepository.GetDefaultAsync(); if (defaultRound == null) { return Error("ไม่พบรอบการลงเวลา Default", StatusCodes.Status404NotFound); } //var userRound = await _dutyTimeRepository.GetByIdAsync(profile.DutyTimeId ?? Guid.Empty); var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(p.Id); var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty; var userRound = await _dutyTimeRepository.GetByIdAsync(roundId); var duty = userRound ?? defaultRound; var processTimeStamps = timeStamps .Select(d => new { d.Id, CheckInStatus = DateTime.Parse(d.CheckIn.ToString("yyyy-MM-dd HH:mm")) > DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.StartTimeMorning}") ? "LATE" : "NORMAL", CheckOutStatus = d.CheckOut == null ? "" : DateTime.Parse(d.CheckOut.Value.ToString("yyyy-MM-dd HH:mm")) < DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.EndTimeAfternoon}") ? "LATE" : DateTime.Parse(d.CheckOut.Value.ToString("yyyy-MM-dd HH:mm")) < DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.EndTimeMorning}") ? "ABSENT" : "NORMAL", }); var absentCount = processTimeStamps.Count(x => x.CheckOutStatus == "ABSENT"); var lateCount = processTimeStamps.Count(x => x.CheckInStatus == "LATE"); var emp = new { no = count, fullName = _userProfileRepository.GetUserFullName(p.KeycloakId ?? Guid.Empty), posNo = p.PosNoEmployee ?? "", reason = "", sickDay = sickDayCount, sickDayCount = sickCount, personalDay = personalDayCount, personalDayCount = personalCount, leaveDay = sickDayCount + personalDayCount, leaveTotal = sickCount + personalCount, //*รวมจำนวนครั้งลาป่วยและลากิจ(13) maternityDay = maternityDayCount, wifeDay = wifeDayCount, ordainDay = ordainDayCount, absentTotal = absentCount, lateTotal = lateCount, leaveTotalText = $"{sickDayCount + personalDayCount}/{sickCount + personalCount}" }; employees.Add(emp); count++; } var result = new { template = "LeaveHalfYear-ลูกจ้าง", reportName = "LeaveHalfYear-Employee", data = new { leaveDateStart = req.StartDate.Date.ToThaiShortDate().ToThaiNumber(), leaveDateEnd = req.EndDate.Date.ToThaiShortDate().ToThaiNumber(), organizationName = profile.First().Oc ?? "", leaveTitleType = req.Type == "FULL" ? "หนึ่งปี" : "ครึ่งปี", employees = employees } }; return Success(result); } catch (Exception ex) { return Error(ex); } } /// /// LV2_037 - รายงานการลงเวลาประจำวัน /// /// /// /// เมื่อทำรายการสำเร็จ /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpPost("time-records/officer")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> GetTimeRecordsOfficerReport([FromBody] GetLeaveDetailReportDto req) { try { //var profile = await _userProfileRepository.SearchProfile(null, null, null); var profile = await _userProfileRepository.GetProfileWithKeycloak(); var date = req.StartDate.Date; var holidays = await _holidayRepository.GetHolidayAsync(req.StartDate.Date, req.EndDate.Date); var weekend = _holidayRepository.GetWeekEnd(req.StartDate.Date, req.EndDate.Date); var excludeDates = holidays.Union(weekend).ToList(); var dateList = new List(); for (DateTime i = req.StartDate.Date; i <= req.EndDate.Date; i = i.AddDays(1)) { if (!excludeDates.Contains(i)) dateList.Add(i); } var employees = new List(); var count = 1; var restTotal = 0; var sickTotal = 0; var lateTotal = 0; var wfhTotal = 0; var studyTotal = 0; var workTotal = 0; foreach (var dd in dateList) { foreach (var p in profile) { var keycloakUserId = p.KeycloakId ?? Guid.Empty; var timeStamps = await _processUserTimeStampRepository.GetTimestampByDateAsync(keycloakUserId, dd); var fullName = _userProfileRepository.GetUserFullName(keycloakUserId); var defaultRound = await _dutyTimeRepository.GetDefaultAsync(); if (defaultRound == null) { return Error("ไม่พบรอบการลงเวลา Default", StatusCodes.Status404NotFound); } //var userRound = await _dutyTimeRepository.GetByIdAsync(profile.DutyTimeId ?? Guid.Empty); var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(p.Id); var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty; var userRound = await _dutyTimeRepository.GetByIdAsync(roundId); var duty = userRound ?? defaultRound; // check วันลาของแต่ละคน var leaveReq = await _leaveRequestRepository.GetLeavePeriodAsync(keycloakUserId, dd); var remarkStr = string.Empty; if (leaveReq != null) { switch (leaveReq.Type.Code.ToUpper()) { case "LV-001": case "LV-002": case "LV-005": remarkStr += leaveReq.Type.Name; var leaveRange = leaveReq.LeaveRange == null ? "" : leaveReq.LeaveRange.ToUpper(); if (leaveRange == "MORNING") remarkStr += "ครึ่งวันเช้า"; else if (leaveRange == "AFTERNOON") remarkStr += "ครึ่งวันบ่าย"; break; default: remarkStr += leaveReq.Type.Name; break; } } else { if (timeStamps == null) { if (dd <= DateTime.Now.Date) remarkStr = "ขาดราชการ"; else remarkStr = ""; } else { // check status ของการลงเวลา if (timeStamps.CheckOut != null) { if (timeStamps.CheckOutStatus == "ABSENT") remarkStr = "ขาดราชการ"; else if (timeStamps.CheckInStatus == "ABSENT") remarkStr = "ขาดราชการ"; else if (timeStamps.CheckInStatus == "LATE") { remarkStr = "สาย"; lateTotal += 1; } else remarkStr = ""; } else { if (timeStamps.CheckInStatus == "ABSENT") remarkStr = "ขาดราชการ"; else if (timeStamps.CheckInStatus == "LATE") { remarkStr = "สาย"; lateTotal += 1; } else remarkStr = ""; } } } var emp = new { no = count, fullName = fullName, dutyTimeName = $"{duty.StartTimeMorning} - {duty.EndTimeAfternoon} น.", checkInLocation = timeStamps == null ? "" : timeStamps.CheckInPOI, checkInTime = timeStamps == null ? "" : $"{timeStamps.CheckIn.ToString("HH:mm")} น.", checkOutLocation = timeStamps == null ? "" : timeStamps.CheckOutPOI ?? "", checkOutTime = timeStamps == null ? "" : timeStamps.CheckOut != null ? $"{timeStamps.CheckOut.Value.ToString("HH:mm")} น." : "", //remark = timeStamps == null ? "ขาดราชการ" : "", remark = remarkStr, checkInDate = timeStamps == null ? dd.Date.ToThaiFullDate2().ToThaiNumber() : timeStamps.CheckIn.Date.ToThaiFullDate2().ToThaiNumber(), checkedOutDate = timeStamps == null ? dd.Date.ToThaiFullDate2().ToThaiNumber() : timeStamps.CheckOut != null ? timeStamps.CheckOut.Value.ToThaiFullDate2().ToThaiNumber() : "", }; if (timeStamps != null) { workTotal += 1; if (!timeStamps.IsLocationCheckIn) wfhTotal += 1; } if (leaveReq != null) { switch (leaveReq.Type.Code.ToUpper()) { case "LV-001": case "LV-002": sickTotal += 1; break; case "LV-005": restTotal += 1; break; case "LV-008": studyTotal += 1; break; } } employees.Add(emp); count++; } } var dateStamp = ""; var reportName = ""; switch (req.Type.ToUpper()) { case "MONTH": { var dd = req.StartDate.Date; reportName = "TimeStamp-Month"; dateStamp = $"เดือน {dd.ToString("MMMM", _culture.DateTimeFormat)} พ.ศ. {dd.Year.ToThaiYear()}".ToThaiNumber(); break; } default: dateStamp = req.StartDate.Date.ToThaiFullDate().ToThaiNumber(); reportName = "TimeStamp-Day"; break; } var item = new { DateTimeStamp = dateStamp, officerTotal = profile.Count, workTotal = workTotal, restTotal = restTotal, sickTotal = sickTotal, lateTotal = lateTotal, wfhTotal = wfhTotal, studyTotal = studyTotal, employees = employees }; var result = new { template = reportName, reportName = reportName, data = item }; return Success(result); } catch (Exception ex) { return Error(ex); } } #endregion } }