From 2f2d7fe74cfab5c9b152af226c810114454c9c09 Mon Sep 17 00:00:00 2001 From: Suphonchai Phoonsawat Date: Fri, 3 Jul 2026 10:08:34 +0700 Subject: [PATCH 1/3] =?UTF-8?q?=E0=B8=9B=E0=B8=A3=E0=B8=B1=E0=B8=9A?= =?UTF-8?q?=E0=B8=81=E0=B8=B2=E0=B8=A3=E0=B8=84=E0=B8=B3=E0=B8=99=E0=B8=A7?= =?UTF-8?q?=E0=B8=99=20=E0=B8=82=E0=B8=B2=E0=B8=94=20=E0=B8=A1=E0=B8=B2?= =?UTF-8?q?=E0=B8=AA=E0=B8=B2=E0=B8=A2=20=E0=B8=9B=E0=B8=81=E0=B8=95?= =?UTF-8?q?=E0=B8=B4=20=E0=B8=96=E0=B9=89=E0=B8=B2=E0=B8=A1=E0=B8=B5?= =?UTF-8?q?=E0=B8=81=E0=B8=B2=E0=B8=A3=E0=B8=A5=E0=B8=B2=E0=B8=84=E0=B8=A3?= =?UTF-8?q?=E0=B8=B6=E0=B9=88=E0=B8=87=E0=B8=A7=E0=B8=B1=E0=B8=99=20?= =?UTF-8?q?=E0=B9=80=E0=B8=8A=E0=B9=89=E0=B8=B2=20=E0=B8=AB=E0=B8=A3?= =?UTF-8?q?=E0=B8=B7=E0=B8=AD=20=E0=B8=9A=E0=B9=88=E0=B8=B2=E0=B8=A2=20?= =?UTF-8?q?=E0=B9=83=E0=B8=99=E0=B8=AA=E0=B9=88=E0=B8=A7=E0=B8=99=E0=B8=95?= =?UTF-8?q?=E0=B8=AD=E0=B8=99=E0=B8=81=E0=B8=B2=E0=B8=A3=E0=B8=9B=E0=B8=9C?= =?UTF-8?q?=E0=B8=A3=E0=B8=B0=E0=B8=A1=E0=B8=A7=E0=B8=A5=20=E0=B9=81?= =?UTF-8?q?=E0=B8=A5=E0=B8=B0=E0=B8=AD=E0=B8=99=E0=B8=B8=E0=B8=A1=E0=B8=B1?= =?UTF-8?q?=E0=B8=95=E0=B8=B4=E0=B8=81=E0=B8=B2=E0=B8=A3=E0=B8=A5=E0=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #2584 --- .../LeaveRequests/LeaveRequestRepository.cs | 80 ++++++++++++++++++- BMA.EHR.Leave/Controllers/LeaveController.cs | 11 ++- 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs b/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs index 6363e258..898139f5 100644 --- a/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs +++ b/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs @@ -32,6 +32,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests private readonly LeaveBeginningRepository _leaveBeginningRepository; private readonly ProcessUserTimeStampRepository _processUserTimeStampRepository; + + private readonly UserDutyTimeRepository _userDutyTimeRepository; + private readonly DutyTimeRepository _dutyTimeRepository; private readonly string URL = string.Empty; @@ -48,7 +51,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests IApplicationDBContext appDbContext, MinIOLeaveService minIOService, LeaveBeginningRepository leaveBeginningRepository, - ProcessUserTimeStampRepository processUserTimeStampRepository) : base(dbContext, httpContextAccessor) + ProcessUserTimeStampRepository processUserTimeStampRepository, + UserDutyTimeRepository userDutyTimeRepository, + DutyTimeRepository dutyTimeRepository) : base(dbContext, httpContextAccessor) { _dbContext = dbContext; _httpContextAccessor = httpContextAccessor; @@ -58,6 +63,10 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests _emailSenderService = emailSenderService; _appDbContext = appDbContext; + _userDutyTimeRepository = userDutyTimeRepository; + _dutyTimeRepository = dutyTimeRepository; + + URL = (_configuration["VITE_URL_MGT"]).Replace("/api/v1", ""); Console.WriteLine($"URL : {URL}"); _minIOService = minIOService; @@ -1331,6 +1340,20 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests await _appDbContext.SaveChangesAsync(); // ปรับสถานะการลงเวลา + var currentDate = rawData.LeaveStartDate; + var defaultRound = await _dutyTimeRepository.GetDefaultAsync(); + if (defaultRound is null) + { + throw new Exception("ไม่พบรอบการลงเวลาทำงาน Default"); + } + var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(profile.Id, currentDate); + var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty; + var userRound = await _dutyTimeRepository.GetByIdAsync(roundId); + + // TODO : รอดุึงรอบที่ผูกกับ user + var duty = userRound ?? defaultRound; + + if (rawData.LeaveStartDate.Date == rawData.LeaveEndDate.Date) { var processCheckIn = await _dbContext.Set() @@ -1341,13 +1364,39 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests if (processCheckIn is not null) { + var startTimeMorning = duty.StartTimeMorning; + var endTimeMorning = duty.EndTimeMorning; + var startTimeAfterNoon = duty.StartTimeAfternoon; + var endTimeAfterNoon = duty.EndTimeAfternoon; + + // var currentDateTime = DateTime.Parse(currentDate.ToString("yyyy-MM-dd HH:mm")); + // var dutyEndTimeAfternoon = DateTime.Parse($"{checkout.CheckIn.ToString("yyyy-MM-dd")} {endTime1}"); + // var dutyEndTimeMorning = DateTime.Parse($"{checkout.CheckIn.ToString("yyyy-MM-dd")} {endTimeMorning1}"); + switch (rawData.LeaveRange.Trim().ToUpper()) { case "MORNING": - processCheckIn.CheckInStatus = "NORMAL"; + var checkIn = DateTime.Parse(processCheckIn.CheckIn.ToString("yyyy-MM-dd HH:mm")); + var startAfternoon = DateTime.Parse($"{processCheckIn.CheckIn.ToString("yyyy-MM-dd")} {startTimeAfterNoon}"); + if (checkIn <= startAfternoon) + processCheckIn.CheckInStatus = "NORMAL"; + else + { + processCheckIn.CheckInStatus = "LATE"; + } break; case "AFTERNOON": - processCheckIn.CheckOutStatus = "NORMAL"; + if (processCheckIn.CheckOut is not null) + { + var checkOut = DateTime.Parse(processCheckIn.CheckOut.Value.ToString("yyyy-MM-dd HH:mm")); + var endMorning = DateTime.Parse($"{processCheckIn.CheckIn.ToString("yyyy-MM-dd")} {endTimeMorning}"); + if(checkOut >= endMorning) + processCheckIn.CheckOutStatus = "NORMAL"; + else + { + processCheckIn.CheckOutStatus = "ABSENT"; + } + } break; case "ALL": processCheckIn.CheckInStatus = "NORMAL"; @@ -1361,6 +1410,11 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests } else { + var startTimeMorning = duty.StartTimeMorning; + var endTimeMorning = duty.EndTimeMorning; + var startTimeAfterNoon = duty.StartTimeAfternoon; + var endTimeAfterNoon = duty.EndTimeAfternoon; + var from = rawData.LeaveStartDate.Date; var to = rawData.LeaveEndDate.Date; for (var day = from.Date; day <= to.Date; day = day.AddDays(1)) @@ -1375,10 +1429,28 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests switch (rawData.LeaveRange.Trim().ToUpper()) { case "MORNING": + var checkIn = DateTime.Parse(processCheckIn.CheckIn.ToString("yyyy-MM-dd HH:mm")); + var startAfternoon = DateTime.Parse($"{processCheckIn.CheckIn.ToString("yyyy-MM-dd")} {startTimeAfterNoon}"); + if (checkIn <= startAfternoon) + processCheckIn.CheckInStatus = "NORMAL"; + else + { + processCheckIn.CheckInStatus = "LATE"; + } processCheckIn.CheckInStatus = "NORMAL"; break; case "AFTERNOON": - processCheckIn.CheckOutStatus = "NORMAL"; + if (processCheckIn.CheckOut is not null) + { + var checkOut = DateTime.Parse(processCheckIn.CheckOut.Value.ToString("yyyy-MM-dd HH:mm")); + var endMorning = DateTime.Parse($"{processCheckIn.CheckIn.ToString("yyyy-MM-dd")} {endTimeMorning}"); + if (checkOut >= endMorning) + processCheckIn.CheckOutStatus = "NORMAL"; + else + { + processCheckIn.CheckOutStatus = "ABSENT"; + } + } break; case "ALL": processCheckIn.CheckInStatus = "NORMAL"; diff --git a/BMA.EHR.Leave/Controllers/LeaveController.cs b/BMA.EHR.Leave/Controllers/LeaveController.cs index 66d49d39..f2d8cc43 100644 --- a/BMA.EHR.Leave/Controllers/LeaveController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveController.cs @@ -1436,9 +1436,18 @@ namespace BMA.EHR.Leave.Service.Controllers var leaveReq = await _leaveRequestRepository.GetLeavePeriodAsync(userId, currentDate.Date); if (leaveReq != null) { + var startTimeAfternoon = duty.StartTimeAfternoon; + var endTimeAfterNoon = duty.EndTimeAfternoon; var leaveRange = leaveReq.LeaveRange == null ? "" : leaveReq.LeaveRange.ToUpper(); if (leaveRange == "MORNING" || leaveRange == "ALL") - checkInStatus = "NORMAL"; + if(DateTime.Parse(currentDate.ToString("yyyy-MM-dd HH:mm")) > + DateTime.Parse($"{currentDate.ToString("yyyy-MM-dd")} {startTimeAfternoon}")) + checkInStatus = "LATE"; + else if(DateTime.Parse(currentDate.ToString("yyyy-MM-dd HH:mm")) > + DateTime.Parse($"{currentDate.ToString("yyyy-MM-dd")} {endTimeAfterNoon}")) + checkInStatus = "ABSENT"; + else + checkInStatus = "NORMAL"; else { checkInStatus = DateTime.Parse(currentDate.ToString("yyyy-MM-dd HH:mm")) > From b05e7cc3abfa5426af57dca21d82d6300bec9179 Mon Sep 17 00:00:00 2001 From: Suphonchai Phoonsawat Date: Fri, 3 Jul 2026 10:53:27 +0700 Subject: [PATCH 2/3] #2585 , #2588 --- .../LeaveRequests/LeaveRequestRepository.cs | 6 ++++-- .../Controllers/LeaveRequestController.cs | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs b/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs index 898139f5..54a80a41 100644 --- a/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs +++ b/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs @@ -1437,7 +1437,6 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests { processCheckIn.CheckInStatus = "LATE"; } - processCheckIn.CheckInStatus = "NORMAL"; break; case "AFTERNOON": if (processCheckIn.CheckOut is not null) @@ -1454,7 +1453,10 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests break; case "ALL": processCheckIn.CheckInStatus = "NORMAL"; - processCheckIn.CheckOutStatus = "NORMAL"; + if (processCheckIn.CheckOut is not null) + { + processCheckIn.CheckOutStatus = "NORMAL"; + } break; default: break; diff --git a/BMA.EHR.Leave/Controllers/LeaveRequestController.cs b/BMA.EHR.Leave/Controllers/LeaveRequestController.cs index 9b1140cd..8cfd6a34 100644 --- a/BMA.EHR.Leave/Controllers/LeaveRequestController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveRequestController.cs @@ -1111,9 +1111,22 @@ namespace BMA.EHR.Leave.Service.Controllers x.KeycloakUserId == userId) .ToListAsync(); - isBetween = existingLeaves.Any(leave => - req.StartLeaveDate.Date <= leave.LeaveEndDate.Date && - req.EndLeaveDate.Date >= leave.LeaveStartDate.Date); + if (req.StartLeaveDate.Date == req.EndLeaveDate.Date) + { + isBetween = existingLeaves.Any(leave => + req.StartLeaveDate.Date == leave.LeaveEndDate.Date && + req.EndLeaveDate.Date == leave.LeaveStartDate.Date && + req.LeaveRange == leave.LeaveRange); + } + else + { + isBetween = existingLeaves.Any(leave => + req.StartLeaveDate.Date <= leave.LeaveEndDate.Date && + req.EndLeaveDate.Date >= leave.LeaveStartDate.Date); + } + + + // var minLeave = (await _context.Set().Where(x => x.Type.Id == req.Type && // (x.LeaveStatus == "PENDING" || x.LeaveStatus == "APPROVE") && From 0cb199d0ee298df6b0aa977eeaebafe26d9fbd9c Mon Sep 17 00:00:00 2001 From: Suphonchai Phoonsawat Date: Fri, 3 Jul 2026 11:17:17 +0700 Subject: [PATCH 3/3] #2587 --- BMA.EHR.Leave/Controllers/LeaveController.cs | 40 ++++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/BMA.EHR.Leave/Controllers/LeaveController.cs b/BMA.EHR.Leave/Controllers/LeaveController.cs index f2d8cc43..173f859d 100644 --- a/BMA.EHR.Leave/Controllers/LeaveController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveController.cs @@ -3308,8 +3308,6 @@ namespace BMA.EHR.Leave.Service.Controllers return Error("ไม่สามารถขอลงเวลากรณีพิเศษในวันที่มากกว่าวันที่ปัจจุบันได้", StatusCodes.Status400BadRequest); } - - var userId = UserId != null ? Guid.Parse(UserId) : Guid.Empty; var checkin = await _userTimeStampRepository.GetTimestampByDateAsync(userId, req.CheckDate.Date); @@ -3569,9 +3567,21 @@ namespace BMA.EHR.Leave.Service.Controllers var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty; var userRound = await _dutyTimeRepository.GetByIdAsync(roundId); var checkInData = await _userTimeStampRepository.GetTimestampByDateAsync(data.KeycloakUserId, data.CheckDate); + + var duty = userRound ?? getDefaultRound; + var leaveReq = await _leaveRequestRepository.GetLeavePeriodAsync(data.KeycloakUserId, data.CheckDate.Date); + + var startTimeMorning = leaveReq is null ? duty.StartTimeMorning : + leaveReq.LeaveRange == "MORNING" ? duty.StartTimeAfternoon : duty.StartTimeMorning; + var endTimeMorning = leaveReq is null ? duty.EndTimeMorning : + leaveReq.LeaveRange == "MORNING" ? duty.StartTimeAfternoon : duty.EndTimeMorning; + + var startTimeAfterNoon = duty.StartTimeAfternoon; + var endTimeAfterNoon = duty.EndTimeAfternoon; + //var duty = getDefaultRound; // create result object to return @@ -3612,10 +3622,15 @@ namespace BMA.EHR.Leave.Service.Controllers "ABSENT" : "NORMAL", - StartTimeMorning = duty.StartTimeMorning, - EndTimeMorning = duty.EndTimeMorning, - StartTimeAfternoon = duty.StartTimeAfternoon, - EndTimeAfternoon = duty.EndTimeAfternoon, + // StartTimeMorning = duty.StartTimeMorning, + // EndTimeMorning = duty.EndTimeMorning, + // StartTimeAfternoon = duty.StartTimeAfternoon, + // EndTimeAfternoon = duty.EndTimeAfternoon, + + StartTimeMorning = startTimeMorning, + EndTimeMorning = endTimeMorning, + StartTimeAfternoon = startTimeAfterNoon, + EndTimeAfternoon = endTimeAfterNoon, Reason = data.Comment ?? "", Status = data.Status, @@ -4193,11 +4208,22 @@ namespace BMA.EHR.Leave.Service.Controllers DateTime? resultCheckInDate, resultCheckOutDate, resultCheckInDateAndTime, resultCheckOutDateAndTime; string resultCheckInTime, resultCheckOutTime; string resultCheckInLocation = "", resultCheckOutLocation = ""; + + var leaveReq = await _leaveRequestRepository.GetLeavePeriodAsync(data.KeycloakUserId, data.CheckDate.Date); + + var startTimeMorning = leaveReq is null ? duty.StartTimeMorning : + leaveReq.LeaveRange == "MORNING" ? duty.StartTimeAfternoon : duty.StartTimeMorning; + var endTimeMorning = leaveReq is null ? duty.EndTimeMorning : + leaveReq.LeaveRange == "MORNING" ? duty.StartTimeAfternoon : duty.EndTimeMorning; + + var startTimeAfterNoon = duty.StartTimeAfternoon; + var endTimeAfterNoon = duty.EndTimeAfternoon; if (data.CheckInEdit) { resultCheckInDate = data.CheckDate.Date; - resultCheckInTime = duty.StartTimeMorning; + //resultCheckInTime = duty.StartTimeMorning; + resultCheckInTime = startTimeMorning; resultCheckInLocation = data.POI ?? ""; } else