diff --git a/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/UserTimeStampRepository.cs b/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/UserTimeStampRepository.cs index d2d9ae5c..769c3141 100644 --- a/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/UserTimeStampRepository.cs +++ b/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/UserTimeStampRepository.cs @@ -57,6 +57,16 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants #region " Methods " + public async Task GetTimestampByDateAsync(Guid keycloakId,DateTime date) + { + var data = await _dbContext.Set() + .Where(u => u.KeycloakUserId == keycloakId) + .Where(u => u.CheckIn.Date == date.Date) + .FirstOrDefaultAsync(); + + return data; + } + public async Task GetLastRecord(Guid keycloakId) { var data = await _dbContext.Set() diff --git a/BMA.EHR.Leave.Service/Controllers/LeaveController.cs b/BMA.EHR.Leave.Service/Controllers/LeaveController.cs index 4be53fe8..bdb74ff6 100644 --- a/BMA.EHR.Leave.Service/Controllers/LeaveController.cs +++ b/BMA.EHR.Leave.Service/Controllers/LeaveController.cs @@ -9,6 +9,7 @@ using BMA.EHR.Infrastructure.Persistence; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; +using System.ComponentModel.DataAnnotations; using System.Security.Claims; namespace BMA.EHR.Command.Service.Controllers @@ -377,6 +378,14 @@ namespace BMA.EHR.Command.Service.Controllers // create check in object if (data.CheckInId == null) { + // validate duplicate check in + var currentCheckIn = await _userTimeStampRepository.GetTimestampByDateAsync(Guid.Parse(UserId), currentDate); + if (currentCheckIn != null) + { + throw new Exception("ไม่สามารถลงเวลาได้ เนืองจากมีการลงเวลาในวันนี้แล้ว!"); + } + + var checkin = new UserTimeStamp { KeycloakUserId = UserId != null ? Guid.Parse(UserId) : Guid.Empty, @@ -436,7 +445,7 @@ namespace BMA.EHR.Command.Service.Controllers // TODO : รอดุึงรอบที่ผูกกับ user var duty = await _dutyTimeRepository.GetDefaultAsync(); - if(duty == null) + if (duty == null) { throw new Exception(GlobalMessages.DataNotFound); } @@ -452,16 +461,16 @@ namespace BMA.EHR.Command.Service.Controllers CheckInDate = d.CheckIn.Date, CheckInTime = d.CheckIn.ToString("HH:mm"), CheckInLocation = d.CheckInPOI, - CheckInStatus = DateTime.Parse(d.CheckIn.ToString("yyyy-MM-dd HH:mm")) > + CheckInStatus = DateTime.Parse(d.CheckIn.ToString("yyyy-MM-dd HH:mm")) > DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.StartTimeMorning}") ? - "LATE" : + "LATE" : "NORMAL", CheckOutDate = d.CheckOut == null ? null : d.CheckOut.Value.Date, CheckOutTime = d.CheckOut == null ? "" : d.CheckOut.Value.ToString("HH:mm"), CheckOutLocation = d.CheckOutPOI ?? "", CheckOutStatus = d.CheckOut == null ? 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.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.EndTimeAfternoon}") ? + "LATE" : "NORMAL", }) @@ -482,7 +491,7 @@ namespace BMA.EHR.Command.Service.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> LogRecordAsync(DateTime startDate, DateTime endDate, int page = 1, int pageSize = 10, string keyword = "") + public async Task> LogRecordAsync([Required] DateTime startDate, [Required] DateTime endDate, int page = 1, int pageSize = 10, string keyword = "") { var imgUrl = $"{_configuration["MinIO:Endpoint"]}{_configuration["MinIO:BucketName"]}"; var data = (await _userTimeStampRepository.GetTimeStampHistoryForAdminAsync(startDate, endDate, page, pageSize, keyword))