From d0599aedea9d0fa84e989579e42ab5b371c98577 Mon Sep 17 00:00:00 2001 From: harid Date: Fri, 3 Oct 2025 11:04:39 +0700 Subject: [PATCH 01/13] =?UTF-8?q?comment=20=E0=B9=80=E0=B8=9E=E0=B8=A3?= =?UTF-8?q?=E0=B8=B2=E0=B8=B0=E0=B9=84=E0=B8=A1=E0=B9=88=E0=B9=84=E0=B8=94?= =?UTF-8?q?=E0=B9=89=E0=B9=83=E0=B8=8A=E0=B9=89=E0=B9=81=E0=B8=A5=E0=B9=89?= =?UTF-8?q?=E0=B8=A7=20#1831?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/InsigniaRequestProcessService.cs | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/BMA.EHR.Insignia/Services/InsigniaRequestProcessService.cs b/BMA.EHR.Insignia/Services/InsigniaRequestProcessService.cs index abaa5093..910c525c 100644 --- a/BMA.EHR.Insignia/Services/InsigniaRequestProcessService.cs +++ b/BMA.EHR.Insignia/Services/InsigniaRequestProcessService.cs @@ -33,25 +33,25 @@ public class InsigniaRequestProcessService : BackgroundService #endregion - public override async Task StartAsync(CancellationToken cancellationToken) - { - var client = new SocketIO("https://bma-ehr.frappet.synology.me/api/v1/org-socket", - new SocketIOOptions - { - // เพิ่ม token ใน handshake.auth - Auth = new { token = AccessToken ?? "" } - }); + //public override async Task StartAsync(CancellationToken cancellationToken) + //{ + //var client = new SocketIO("https://bma-ehr.frappet.synology.me/api/v1/org-socket", + // new SocketIOOptions + // { + // // เพิ่ม token ใน handshake.auth + // Auth = new { token = AccessToken ?? "" } + // }); - client.OnConnected += async (sender, e) => - { - Console.WriteLine("Connected to Socket.IO server"); - await client.EmitAsync("eventName", "Hello from .NET client"); - }; + //client.OnConnected += async (sender, e) => + //{ + // Console.WriteLine("Connected to Socket.IO server"); + // await client.EmitAsync("eventName", "Hello from .NET client"); + //}; - await client.ConnectAsync(); + //await client.ConnectAsync(); - await base.StartAsync(cancellationToken); - } + //await base.StartAsync(cancellationToken); + //} From 97dd104429ff98d514197f533ff815036b451678 Mon Sep 17 00:00:00 2001 From: Suphonchai Phoonsawat Date: Fri, 3 Oct 2025 20:28:49 +0700 Subject: [PATCH 02/13] fix #24 --- .../Leaves/TimeAttendants/ProcessUserTimeStampRepository.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/ProcessUserTimeStampRepository.cs b/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/ProcessUserTimeStampRepository.cs index 3117a8b1..3847b9f7 100644 --- a/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/ProcessUserTimeStampRepository.cs +++ b/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/ProcessUserTimeStampRepository.cs @@ -222,9 +222,12 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants public async Task> GetTimeStampHistoryAsync(Guid keycloakId, int year, int page = 1, int pageSize = 10, string keyword = "") { + var fiscalDateStart = new DateTime(year - 1, 10, 1); + var fiscalDateEnd = new DateTime(year, 9, 30); + var data = await _dbContext.Set() .Where(u => u.KeycloakUserId == keycloakId) - .Where(u => u.CheckIn.Year == year) + .Where(u => u.CheckIn.Date >= fiscalDateStart && u.CheckIn.Date <= fiscalDateEnd) .OrderByDescending(u => u.CheckIn.Date) .Skip((page - 1) * pageSize) .Take(pageSize) From 8529c3d8013bdbde795a0b6ac4db2c03db48b527 Mon Sep 17 00:00:00 2001 From: Suphonchai Phoonsawat Date: Mon, 6 Oct 2025 11:30:06 +0700 Subject: [PATCH 03/13] fix #1835 --- BMA.EHR.Leave/Controllers/LeaveRequestController.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BMA.EHR.Leave/Controllers/LeaveRequestController.cs b/BMA.EHR.Leave/Controllers/LeaveRequestController.cs index 8113ba9f..27457ceb 100644 --- a/BMA.EHR.Leave/Controllers/LeaveRequestController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveRequestController.cs @@ -2308,6 +2308,9 @@ namespace BMA.EHR.Leave.Service.Controllers } } var thisYear = DateTime.Now.Year; + var toDay = DateTime.Now.Date; + if(toDay >= new DateTime(toDay.Year, 10, 1) && toDay <= new DateTime(toDay.Year, 12, 31)) + thisYear = thisYear + 1; //var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken); From 946721ffb2e7a0bbad05ae09c9fcaa4ff41432c3 Mon Sep 17 00:00:00 2001 From: Suphonchai Phoonsawat Date: Mon, 6 Oct 2025 12:30:48 +0700 Subject: [PATCH 04/13] fix report --- BMA.EHR.Leave/Controllers/LeaveReportController.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/BMA.EHR.Leave/Controllers/LeaveReportController.cs b/BMA.EHR.Leave/Controllers/LeaveReportController.cs index 2913be5c..01bd6820 100644 --- a/BMA.EHR.Leave/Controllers/LeaveReportController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveReportController.cs @@ -283,7 +283,12 @@ namespace BMA.EHR.Leave.Service.Controllers var startFiscalYear = new DateTime(data.LeaveStartDate.Year - 1, 10, 1); var endFiscalYear = data.LeaveStartDate.Date.AddDays(-1); // นับจากวันที่ยื่นลา - var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUserAsync(data.LeaveStartDate.Year, data.Type.Id, data.KeycloakUserId); + var thisYear = data.LeaveStartDate.Year; + var toDay = data.LeaveStartDate.Date; + if(toDay >= new DateTime(toDay.Year, 10, 1) && toDay <= new DateTime(toDay.Year, 12, 31)) + thisYear = thisYear + 1; + + var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUserAsync(thisYear, data.Type.Id, data.KeycloakUserId); //var sumLeave = leaveData == null ? 0 : leaveData.LeaveDaysUsed; var sumLeave = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUser(data.KeycloakUserId, data.Type.Id, startFiscalYear, endFiscalYear); From 5efb1c99c60dced7804dbca5109425c8d45ec298 Mon Sep 17 00:00:00 2001 From: harid Date: Mon, 6 Oct 2025 15:12:40 +0700 Subject: [PATCH 05/13] sortBy #1814 --- .../Controllers/LeaveBeginningController.cs | 44 ++- BMA.EHR.Leave/Controllers/LeaveController.cs | 354 ++++++++++++++++-- .../GetAdditionalCheckRequestDto.cs | 3 + .../DTOs/ChangeRound/SearchProfileDto.cs | 4 + .../ChangeRound/SearchProfileResultDto.cs | 6 +- .../DTOs/CheckIn/CheckInHistoryForAdminDto.cs | 3 + .../CheckInProcessHistoryForAdminDto.cs | 3 + .../LeaveBeginnings/GetLeaveBeginningDto.cs | 4 + 8 files changed, 398 insertions(+), 23 deletions(-) diff --git a/BMA.EHR.Leave/Controllers/LeaveBeginningController.cs b/BMA.EHR.Leave/Controllers/LeaveBeginningController.cs index e37ab06a..e72c0c4f 100644 --- a/BMA.EHR.Leave/Controllers/LeaveBeginningController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveBeginningController.cs @@ -136,7 +136,49 @@ namespace BMA.EHR.Leave.Service.Controllers if (req.Keyword != "") result = result.Where(x => x.FullName!.Contains(req.Keyword)).ToList(); - + if (!string.IsNullOrWhiteSpace(req.sortBy)) + { + switch (req.sortBy.ToUpper()) + { + case "FULLNAME": + if (req.descending == true) + result = result.OrderByDescending(x => x.Prefix) + .ThenByDescending(x => x.FirstName) + .ThenByDescending(x => x.LastName) + .ToList(); + else + result = result.OrderBy(x => x.Prefix) + .ThenBy(x => x.FirstName) + .ThenBy(x => x.LastName) + .ToList(); + break; + case "LEAVETYPE": + if (req.descending == true) + result = result.OrderByDescending(x => x.LeaveType).ToList(); + else + result = result.OrderBy(x => x.LeaveType).ToList(); + break; + case "LEAVEYEAR": + if (req.descending == true) + result = result.OrderByDescending(x => x.LeaveYear).ToList(); + else + result = result.OrderBy(x => x.LeaveYear).ToList(); + break; + case "LEAVEDAYS": + if (req.descending == true) + result = result.OrderByDescending(x => x.LeaveDays).ToList(); + else + result = result.OrderBy(x => x.LeaveDays).ToList(); + break; + case "LEAVEDAYSUSED": + if (req.descending == true) + result = result.OrderByDescending(x => x.LeaveDaysUsed).ToList(); + else + result = result.OrderBy(x => x.LeaveDaysUsed).ToList(); + break; + default: break; + } + } var pageResult = result.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList(); return Success(new { data = pageResult, total = result.Count }); diff --git a/BMA.EHR.Leave/Controllers/LeaveController.cs b/BMA.EHR.Leave/Controllers/LeaveController.cs index 43972a06..08ec712b 100644 --- a/BMA.EHR.Leave/Controllers/LeaveController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveController.cs @@ -14,10 +14,12 @@ using BMA.EHR.Leave.Service.DTOs.ChangeRound; using BMA.EHR.Leave.Service.DTOs.CheckIn; using BMA.EHR.Leave.Service.DTOs.DutyTime; using BMA.EHR.Leave.Service.DTOs.LeaveRequest; +using iTextSharp.text; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.ObjectPool; +using Nest; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using RabbitMQ.Client; @@ -1257,7 +1259,7 @@ namespace BMA.EHR.Leave.Service.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> LogRecordAsync([Required] DateTime startDate, [Required] DateTime endDate, int page = 1, int pageSize = 10, string keyword = "", string profileType = "ALL") + public async Task> LogRecordAsync([Required] DateTime startDate, [Required] DateTime endDate, int page = 1, int pageSize = 10, string keyword = "", string profileType = "ALL", string? sortBy = "", bool? descending = false) { var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_CHECKIN"); var jsonData = JsonConvert.DeserializeObject(getPermission); @@ -1305,6 +1307,9 @@ namespace BMA.EHR.Leave.Service.Controllers Id = d.Id, //FullName = _userProfileRepository.GetUserFullName(d.KeycloakUserId, AccessToken), FullName = $"{d.Prefix ?? ""}{d.FirstName ?? ""} {d.LastName ?? ""}", + Prefix = d.Prefix ?? "", + FirstName = d.FirstName ?? "", + LastName = d.LastName ?? "", ProfileType = d.ProfileType ?? "", CheckInDate = d.CheckIn.Date, @@ -1339,6 +1344,61 @@ namespace BMA.EHR.Leave.Service.Controllers if (profileType.Trim().ToUpper() != "ALL") data = data.Where(x => x.ProfileType == profileType.Trim().ToUpper()).ToList(); + if (!string.IsNullOrWhiteSpace(sortBy)) + { + switch (sortBy.ToUpper()) + { + case "FULLNAME": + if (descending == true) + data = data.OrderByDescending(x => x.Prefix) + .ThenByDescending(x => x.FirstName) + .ThenByDescending(x => x.LastName) + .ToList(); + else + data = data.OrderBy(x => x.Prefix) + .ThenBy(x => x.FirstName) + .ThenBy(x => x.LastName) + .ToList(); + break; + case "CHECKINTIME": + if (descending == true) + data = data.OrderByDescending(x => x.CheckInTime).ToList(); + else + data = data.OrderBy(x => x.CheckInTime).ToList(); + break; + case "CHECKINLOCATION": + if (descending == true) + data = data.OrderByDescending(x => x.CheckInLocation) + .ThenByDescending(x => x.CheckInLat) + .ThenByDescending(x => x.CheckInLon) + .ToList(); + else + data = data.OrderBy(x => x.CheckInLocation) + .ThenBy(x => x.CheckInLat) + .ThenBy(x => x.CheckInLon) + .ToList(); + break; + case "CHECKOUTTIME": + if (descending == true) + data = data.OrderByDescending(x => x.CheckOutTime).ToList(); + else + data = data.OrderBy(x => x.CheckOutTime).ToList(); + break; + case "CHECKOUTLOCATION": + if (descending == true) + data = data.OrderByDescending(x => x.CheckOutLocation) + .ThenByDescending(x => x.CheckOutLat) + .ThenByDescending(x => x.CheckOutLon) + .ToList(); + else + data = data.OrderBy(x => x.CheckOutLocation) + .ThenBy(x => x.CheckOutLat) + .ThenBy(x => x.CheckOutLon) + .ToList(); + break; + default: break; + } + } var pageData = data .Skip((page - 1) * pageSize) .Take(pageSize) @@ -1470,7 +1530,7 @@ namespace BMA.EHR.Leave.Service.Controllers [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] [AllowAnonymous] - public async Task> GetTimeRecordAsync([Required] DateTime startDate, [Required] DateTime endDate, int page = 1, int pageSize = 10, string status = "NORMAL", string keyword = "", string profileType = "ALL") + public async Task> GetTimeRecordAsync([Required] DateTime startDate, [Required] DateTime endDate, int page = 1, int pageSize = 10, string status = "NORMAL", string keyword = "", string profileType = "ALL", string? sortBy = "", bool? descending = false) { var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_CHECKIN"); var jsonData = JsonConvert.DeserializeObject(getPermission); @@ -1557,6 +1617,9 @@ namespace BMA.EHR.Leave.Service.Controllers { Id = d.Id, FullName = $"{d.Prefix ?? ""}{d.FirstName ?? ""} {d.LastName ?? ""}", + Prefix = d.Prefix ?? "", + FirstName = d.FirstName ?? "", + LastName = d.LastName ?? "", ProfileType = d.ProfileType ?? "", CheckInDate = d.CheckIn.Date, @@ -1656,6 +1719,61 @@ namespace BMA.EHR.Leave.Service.Controllers if (profileType.Trim().ToUpper() != "ALL") data = data.Where(x => x.ProfileType == profileType.Trim().ToUpper()).ToList(); + if (!string.IsNullOrWhiteSpace(sortBy)) + { + switch (sortBy.ToUpper()) + { + case "FULLNAME": + if (descending == true) + data = data.OrderByDescending(x => x.Prefix) + .ThenByDescending(x => x.FirstName) + .ThenByDescending(x => x.LastName) + .ToList(); + else + data = data.OrderBy(x => x.Prefix) + .ThenBy(x => x.FirstName) + .ThenBy(x => x.LastName) + .ToList(); + break; + case "CHECKINTIME": + if (descending == true) + data = data.OrderByDescending(x => x.CheckInTime).ToList(); + else + data = data.OrderBy(x => x.CheckInTime).ToList(); + break; + case "CHECKINLOCATION": + if (descending == true) + data = data.OrderByDescending(x => x.CheckInLocation) + .ThenByDescending(x => x.CheckInLat) + .ThenByDescending(x => x.CheckInLon) + .ToList(); + else + data = data.OrderBy(x => x.CheckInLocation) + .ThenBy(x => x.CheckInLat) + .ThenBy(x => x.CheckInLon) + .ToList(); + break; + case "CHECKOUTTIME": + if (descending == true) + data = data.OrderByDescending(x => x.CheckOutTime).ToList(); + else + data = data.OrderBy(x => x.CheckOutTime).ToList(); + break; + case "CHECKOUTLOCATION": + if (descending == true) + data = data.OrderByDescending(x => x.CheckOutLocation) + .ThenByDescending(x => x.CheckOutLat) + .ThenByDescending(x => x.CheckOutLon) + .ToList(); + else + data = data.OrderBy(x => x.CheckOutLocation) + .ThenBy(x => x.CheckOutLat) + .ThenBy(x => x.CheckOutLon) + .ToList(); + break; + default: break; + } + } var pageData = data .Skip((page - 1) * pageSize) .Take(pageSize) @@ -1712,13 +1830,13 @@ namespace BMA.EHR.Leave.Service.Controllers } var profile = await _userProfileRepository.SearchProfile(req.CitizenId, req.FirstName, req.LastName, AccessToken ?? "", role, nodeId, profileAdmin?.Node); - var pagedProfile = profile.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList(); + //var pagedProfile = profile.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList(); var getDefaultRound = await _dutyTimeRepository.GetDefaultAsync(); var resultSet = new List(); - foreach (var p in pagedProfile) + foreach (var p in profile) { var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(p.Id); @@ -1738,8 +1856,46 @@ namespace BMA.EHR.Leave.Service.Controllers }; resultSet.Add(res); } + if (!string.IsNullOrWhiteSpace(req.sortBy)) + { + switch (req.sortBy.ToUpper()) + { + case "CITIZENID": + if (req.descending == true) + profile = profile.OrderByDescending(x => x.CitizenId).ToList(); + else + profile = profile.OrderBy(x => x.CitizenId).ToList(); + break; + case "FULLNAME": + if (req.descending == true) + profile = profile.OrderByDescending(x => x.Prefix) + .ThenByDescending(x => x.FirstName) + .ThenByDescending(x => x.LastName) + .ToList(); + else + profile = profile.OrderBy(x => x.Prefix) + .ThenBy(x => x.FirstName) + .ThenBy(x => x.LastName) + .ToList(); + break; + case "STARTTIMEMORNING": + if (req.descending == true) + resultSet = resultSet.OrderByDescending(x => x.StartTimeMorning).ToList(); + else + resultSet = resultSet.OrderBy(x => x.StartTimeMorning).ToList(); + break; + case "EFFECTIVEDATE": + if (req.descending == true) + resultSet = resultSet.OrderByDescending(x => x.EffectiveDate).ToList(); + else + resultSet = resultSet.OrderBy(x => x.EffectiveDate).ToList(); + break; + default: break; + } + } + var pageResult = resultSet.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList(); - return Success(new { data = resultSet, total = profile.Count }); + return Success(new { data = pageResult, total = profile.Count }); } /// @@ -1813,7 +1969,7 @@ namespace BMA.EHR.Leave.Service.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> GetChangeRoundHistoryByProfileIdAsync(Guid id, int page = 1, int pageSize = 10, string keyword = "") + public async Task> GetChangeRoundHistoryByProfileIdAsync(Guid id, int page = 1, int pageSize = 10, string keyword = "", string? sortBy = "", bool? descending = false) { var getWorkflow = await _permission.GetPermissionAPIWorkflowAsync(id.ToString(), "SYS_WORK_ROUND_EDIT"); if (getWorkflow == false) @@ -1834,7 +1990,7 @@ namespace BMA.EHR.Leave.Service.Controllers resultSet = data .GroupBy(item => item.ProfileId) .SelectMany(group => group - .OrderBy(item => item.EffectiveDate) // เรียงลำดับตาม property ที่คุณต้องการ + //.OrderBy(item => item.EffectiveDate) // เรียงลำดับตาม property ที่คุณต้องการ .Select((item, index) => new ChangeRoundHistoryDto { Round = index + 1, @@ -1843,10 +1999,44 @@ namespace BMA.EHR.Leave.Service.Controllers EffectiveDate = item.EffectiveDate.Value, Remark = item.Remark })) - .Skip((page - 1) * pageSize) - .Take(pageSize) + //.Skip((page - 1) * pageSize) + //.Take(pageSize) .ToList(); - + if (!string.IsNullOrWhiteSpace(sortBy)) + { + switch (sortBy.ToUpper()) + { + case "ROUNT": + if (descending == true) + resultSet = resultSet.OrderByDescending(x => x.Round).ToList(); + else + resultSet = resultSet.OrderBy(x => x.Round).ToList(); + break; + case "STARTTIMEMORNIONG": + if (descending == true) + resultSet = resultSet.OrderByDescending(x => x.StartTimeMorning).ToList(); + else + resultSet = resultSet.OrderBy(x => x.StartTimeMorning).ToList(); + break; + case "EFFECTIVEDATE": + if (descending == true) + resultSet = resultSet.OrderByDescending(x => x.EffectiveDate).ToList(); + else + resultSet = resultSet.OrderBy(x => x.EffectiveDate).ToList(); + break; + case "REMARK": + if (descending == true) + resultSet = resultSet.OrderByDescending(x => x.Remark).ToList(); + else + resultSet = resultSet.OrderBy(x => x.Remark).ToList(); + break; + default: break; + } + } + resultSet = resultSet + .Skip((page - 1) * pageSize) + .Take(pageSize) + .ToList(); } return Success(new { data = resultSet, total = data.Count }); @@ -1901,13 +2091,13 @@ namespace BMA.EHR.Leave.Service.Controllers } var profile = await _userProfileRepository.SearchProfileEmployee(req.CitizenId, req.FirstName, req.LastName, AccessToken ?? "", role, nodeId, profileAdmin?.Node); - var pagedProfile = profile.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList(); + //var pagedProfile = profile.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList(); var getDefaultRound = await _dutyTimeRepository.GetDefaultAsync(); var resultSet = new List(); - foreach (var p in pagedProfile) + foreach (var p in profile) { var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(p.Id); @@ -1927,8 +2117,45 @@ namespace BMA.EHR.Leave.Service.Controllers }; resultSet.Add(res); } - - return Success(new { data = resultSet, total = profile.Count }); + if (!string.IsNullOrWhiteSpace(req.sortBy)) + { + switch (req.sortBy.ToUpper()) + { + case "CITIZENID": + if (req.descending == true) + resultSet = resultSet.OrderByDescending(x => x.CitizenId).ToList(); + else + resultSet = resultSet.OrderBy(x => x.CitizenId).ToList(); + break; + case "FULLNAME": + if (req.descending == true) + resultSet = resultSet.OrderByDescending(x => x.Prefix) + .ThenByDescending(x => x.FirstName) + .ThenByDescending(x => x.LastName) + .ToList(); + else + resultSet = resultSet.OrderBy(x => x.Prefix) + .ThenBy(x => x.FirstName) + .ThenBy(x => x.LastName) + .ToList(); + break; + case "STARTTIMEMORNING": + if (req.descending == true) + resultSet = resultSet.OrderByDescending(x => x.StartTimeMorning).ToList(); + else + resultSet = resultSet.OrderBy(x => x.StartTimeMorning).ToList(); + break; + case "EFFECTIVEDATE": + if (req.descending == true) + resultSet = resultSet.OrderByDescending(x => x.EffectiveDate).ToList(); + else + resultSet = resultSet.OrderBy(x => x.EffectiveDate).ToList(); + break; + default: break; + } + } + var pageResult = resultSet.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).ToList(); + return Success(new { data = pageResult, total = profile.Count }); } /// @@ -2001,7 +2228,7 @@ namespace BMA.EHR.Leave.Service.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> GetChangeEmpRoundHistoryByProfileIdAsync(Guid id, int page = 1, int pageSize = 10, string keyword = "") + public async Task> GetChangeEmpRoundHistoryByProfileIdAsync(Guid id, int page = 1, int pageSize = 10, string keyword = "", string? sortBy = "", bool? descending = false) { var getWorkflow = await _permission.GetPermissionAPIWorkflowAsync(id.ToString(), "SYS_WORK_ROUND_EDIT"); if (getWorkflow == false) @@ -2022,7 +2249,7 @@ namespace BMA.EHR.Leave.Service.Controllers resultSet = data .GroupBy(item => item.ProfileId) .SelectMany(group => group - .OrderBy(item => item.EffectiveDate) // เรียงลำดับตาม property ที่คุณต้องการ + //.OrderBy(item => item.EffectiveDate) // เรียงลำดับตาม property ที่คุณต้องการ .Select((item, index) => new ChangeRoundHistoryDto { Round = index + 1, @@ -2031,10 +2258,44 @@ namespace BMA.EHR.Leave.Service.Controllers EffectiveDate = item.EffectiveDate.Value, Remark = item.Remark })) - .Skip((page - 1) * pageSize) - .Take(pageSize) + //.Skip((page - 1) * pageSize) + //.Take(pageSize) .ToList(); - + if (!string.IsNullOrWhiteSpace(sortBy)) + { + switch (sortBy.ToUpper()) + { + case "ROUNT": + if (descending == true) + resultSet = resultSet.OrderByDescending(x => x.Round).ToList(); + else + resultSet = resultSet.OrderBy(x => x.Round).ToList(); + break; + case "STARTTIMEMORNIONG": + if (descending == true) + resultSet = resultSet.OrderByDescending(x => x.StartTimeMorning).ToList(); + else + resultSet = resultSet.OrderBy(x => x.StartTimeMorning).ToList(); + break; + case "EFFECTIVEDATE": + if (descending == true) + resultSet = resultSet.OrderByDescending(x => x.EffectiveDate).ToList(); + else + resultSet = resultSet.OrderBy(x => x.EffectiveDate).ToList(); + break; + case "REMARK": + if (descending == true) + resultSet = resultSet.OrderByDescending(x => x.Remark).ToList(); + else + resultSet = resultSet.OrderBy(x => x.Remark).ToList(); + break; + default: break; + } + } + resultSet = resultSet + .Skip((page - 1) * pageSize) + .Take(pageSize) + .ToList(); } return Success(new { data = resultSet, total = data.Count }); @@ -2175,7 +2436,7 @@ namespace BMA.EHR.Leave.Service.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> GetAdditionalCheckRequestAsync([Required] int year, [Required] int month, [Required] int page = 1, [Required] int pageSize = 10, string keyword = "") + public async Task> GetAdditionalCheckRequestAsync([Required] int year, [Required] int month, [Required] int page = 1, [Required] int pageSize = 10, string keyword = "", string? sortBy = "", bool? descending = false) { var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_CHECKIN_SPECIAL"); var jsonData = JsonConvert.DeserializeObject(getPermission); @@ -2240,6 +2501,9 @@ namespace BMA.EHR.Leave.Service.Controllers { Id = data.Id, FullName = $"{data.Prefix}{data.FirstName} {data.LastName}", + Prefix = data.Prefix ?? "", + FirstName = data.FirstName ?? "", + LastName = data.LastName ?? "", //FullName = $"{profile.Prefix}{profile.FirstName} {profile.LastName}", CreatedAt = data.CreatedAt, CheckDate = data.CheckDate, @@ -2296,7 +2560,55 @@ namespace BMA.EHR.Leave.Service.Controllers { result = result.Where(x => x.FullName.Contains(keyword)).ToList(); } - + if (!string.IsNullOrWhiteSpace(sortBy)) + { + switch (sortBy.ToUpper()) + { + case "FULLNAME": + if (descending == true) + result = result.OrderByDescending(x => x.Prefix) + .ThenByDescending(x => x.FirstName) + .ThenByDescending(x => x.LastName) + .ToList(); + else + result = result.OrderBy(x => x.Prefix) + .ThenBy(x => x.FirstName) + .ThenBy(x => x.LastName) + .ToList(); + break; + case "CREATEDAT": + if (descending == true) + result = result.OrderByDescending(x => x.CreatedAt).ToList(); + else + result = result.OrderBy(x => x.CreatedAt).ToList(); + break; + case "CHECKDATE": + if (descending == true) + result = result.OrderByDescending(x => x.CheckDate).ToList(); + else + result = result.OrderBy(x => x.CheckDate).ToList(); + break; + case "STARTTIMEMORNING": + if (descending == true) + result = result.OrderByDescending(x => x.StartTimeMorning).ToList(); + else + result = result.OrderBy(x => x.StartTimeMorning).ToList(); + break; + case "STARTTIMEAFTERNOON": + if (descending == true) + result = result.OrderByDescending(x => x.StartTimeAfternoon).ToList(); + else + result = result.OrderBy(x => x.StartTimeAfternoon).ToList(); + break; + case "DESCRIPTION": + if (descending == true) + result = result.OrderByDescending(x => x.Description).ToList(); + else + result = result.OrderBy(x => x.Description).ToList(); + break; + default: break; + } + } var pageResult = result.Skip((page - 1) * pageSize).Take(pageSize) .OrderBy(x => x.StatusSort) .ToList(); diff --git a/BMA.EHR.Leave/DTOs/AdditionalCheck/GetAdditionalCheckRequestDto.cs b/BMA.EHR.Leave/DTOs/AdditionalCheck/GetAdditionalCheckRequestDto.cs index 8c04223d..b315b1b5 100644 --- a/BMA.EHR.Leave/DTOs/AdditionalCheck/GetAdditionalCheckRequestDto.cs +++ b/BMA.EHR.Leave/DTOs/AdditionalCheck/GetAdditionalCheckRequestDto.cs @@ -5,6 +5,9 @@ public Guid Id { get; set; } public string FullName { get; set; } + public string? Prefix { get; set; } = string.Empty; + public string? FirstName { get; set; } = string.Empty; + public string? LastName { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } diff --git a/BMA.EHR.Leave/DTOs/ChangeRound/SearchProfileDto.cs b/BMA.EHR.Leave/DTOs/ChangeRound/SearchProfileDto.cs index 52bb769c..3b05ad29 100644 --- a/BMA.EHR.Leave/DTOs/ChangeRound/SearchProfileDto.cs +++ b/BMA.EHR.Leave/DTOs/ChangeRound/SearchProfileDto.cs @@ -13,5 +13,9 @@ public int PageSize { get; set; } = 10; public string? Keyword { get; set; } + + public string? sortBy { get; set; } + + public bool? descending { get; set; } } } diff --git a/BMA.EHR.Leave/DTOs/ChangeRound/SearchProfileResultDto.cs b/BMA.EHR.Leave/DTOs/ChangeRound/SearchProfileResultDto.cs index 6c5bf334..83b4d7b9 100644 --- a/BMA.EHR.Leave/DTOs/ChangeRound/SearchProfileResultDto.cs +++ b/BMA.EHR.Leave/DTOs/ChangeRound/SearchProfileResultDto.cs @@ -6,7 +6,11 @@ public string CitizenId { get; set; } - public string FullName { get; set; } + public string FullName { get; set; } + + public string? Prefix { get; set; } + public string? FirstName { get; set; } + public string? LastName { get; set; } public string StartTimeMorning { get; set; } diff --git a/BMA.EHR.Leave/DTOs/CheckIn/CheckInHistoryForAdminDto.cs b/BMA.EHR.Leave/DTOs/CheckIn/CheckInHistoryForAdminDto.cs index ac4e0e9b..c6e13b54 100644 --- a/BMA.EHR.Leave/DTOs/CheckIn/CheckInHistoryForAdminDto.cs +++ b/BMA.EHR.Leave/DTOs/CheckIn/CheckInHistoryForAdminDto.cs @@ -5,6 +5,9 @@ public Guid Id { get; set; } = Guid.Empty; public string FullName { get; set; } = string.Empty; + public string? Prefix { get; set; } = string.Empty; + public string? FirstName { get; set; } = string.Empty; + public string? LastName { get; set; } = string.Empty; public DateTime? CheckInDate { get; set; } = DateTime.MinValue; diff --git a/BMA.EHR.Leave/DTOs/CheckIn/CheckInProcessHistoryForAdminDto.cs b/BMA.EHR.Leave/DTOs/CheckIn/CheckInProcessHistoryForAdminDto.cs index be150bdc..9ec96c35 100644 --- a/BMA.EHR.Leave/DTOs/CheckIn/CheckInProcessHistoryForAdminDto.cs +++ b/BMA.EHR.Leave/DTOs/CheckIn/CheckInProcessHistoryForAdminDto.cs @@ -5,6 +5,9 @@ public Guid Id { get; set; } = Guid.Empty; public string FullName { get; set; } = string.Empty; + public string? Prefix { get; set; } = string.Empty; + public string? FirstName { get; set; } = string.Empty; + public string? LastName { get; set; } = string.Empty; public DateTime? CheckInDate { get; set; } = DateTime.MinValue; diff --git a/BMA.EHR.Leave/DTOs/LeaveBeginnings/GetLeaveBeginningDto.cs b/BMA.EHR.Leave/DTOs/LeaveBeginnings/GetLeaveBeginningDto.cs index 3c3fe77d..587b99b3 100644 --- a/BMA.EHR.Leave/DTOs/LeaveBeginnings/GetLeaveBeginningDto.cs +++ b/BMA.EHR.Leave/DTOs/LeaveBeginnings/GetLeaveBeginningDto.cs @@ -16,5 +16,9 @@ namespace BMA.EHR.Leave.Service.DTOs.LeaveBeginnings public int PageSize { get; set; } = 10; public string Keyword { get; set; } = string.Empty; + + public string? sortBy { get; set; } + + public bool? descending { get; set; } } } From f9d1dd9f38be1676706b2c2b1f490d63527165ee Mon Sep 17 00:00:00 2001 From: Suphonchai Phoonsawat Date: Mon, 6 Oct 2025 15:37:13 +0700 Subject: [PATCH 06/13] #1838 --- .../LeaveRequests/LeaveRequestRepository.cs | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs b/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs index 18641ec8..bcd650ef 100644 --- a/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs +++ b/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs @@ -555,7 +555,14 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests // TODO : Update ไปตาราง beginning if (data.ApproveStep == "st4") // ถ้ามีการอนุมัติจากผู้มีอำนาจแล้ว { - await _leaveBeginningRepository.UpdateLeaveUsageAsync(data.LeaveStartDate.Year, data.Type.Id, data.KeycloakUserId, -1 * data.LeaveTotal); + + var toDay = data.LeaveStartDate.Date; + var thisYear = data.LeaveStartDate.Year; + if(toDay >= new DateTime(thisYear,10,1) && toDay <= new DateTime(thisYear,12,31)) + { + thisYear = thisYear + 1; + } + await _leaveBeginningRepository.UpdateLeaveUsageAsync(thisYear, data.Type.Id, data.KeycloakUserId, -1 * data.LeaveTotal); var _baseAPI = _configuration["API"]; var apiUrlSalary = $"{_baseAPI}/org/profile/leave/cancel/{data.Id}"; @@ -620,7 +627,15 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests // TODO : Update ไปตาราง beginning if (rawData.ApproveStep == "st4") // ถ้ามีการอนุมัติจากผู้มีอำนาจแล้ว { - await _leaveBeginningRepository.UpdateLeaveUsageAsync(rawData.LeaveStartDate.Year, rawData.Type.Id, rawData.KeycloakUserId, -1 * rawData.LeaveTotal); + + var toDay = rawData.LeaveStartDate.Date; + var thisYear = rawData.LeaveStartDate.Year; + if(toDay >= new DateTime(thisYear,10,1) && toDay <= new DateTime(thisYear,12,31)) + { + thisYear = thisYear + 1; + } + + await _leaveBeginningRepository.UpdateLeaveUsageAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId, -1 * rawData.LeaveTotal); var _baseAPI = _configuration["API"]; var apiUrlSalary = $"{_baseAPI}/org/profile/leave/cancel/{rawData.Id}"; @@ -1079,8 +1094,15 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests await UpdateWithTrackingAsync(rawData); + var toDay = rawData.LeaveStartDate.Date; + var thisYear = rawData.LeaveStartDate.Year; + if(toDay >= new DateTime(thisYear,10,1) && toDay <= new DateTime(thisYear,12,31)) + { + thisYear = thisYear + 1; + } + // TODO : Update ไปตาราง beginning - await _leaveBeginningRepository.UpdateLeaveUsageAsync(rawData.LeaveStartDate.Year, rawData.Type.Id, rawData.KeycloakUserId, rawData.LeaveTotal); + await _leaveBeginningRepository.UpdateLeaveUsageAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId, rawData.LeaveTotal); var _baseAPI = _configuration["API"]; From 12c8bc50147c27a0bc1f501529a1fea95b458789 Mon Sep 17 00:00:00 2001 From: Adisak Date: Mon, 6 Oct 2025 16:28:16 +0700 Subject: [PATCH 07/13] sort Discipline --- .../DisciplineComplaintController.cs | 86 ++++++++++++++++--- .../DisciplineComplaint_AppealController.cs | 74 ++++++++++++++-- .../DisciplineDirectorController.cs | 65 +++++++++++++- .../DisciplineDisciplinaryController.cs | 70 ++++++++++++++- .../DisciplineInvestigateController.cs | 71 ++++++++++++++- .../Controllers/DisciplineResultController.cs | 85 +++++++++++++++++- .../DisciplineSuspendController.cs | 78 +++++++++++++++-- .../Requests/DisciplineComplaintRequest.cs | 2 + .../Requests/DisciplineDisciplinaryRequest.cs | 2 + .../Requests/DisciplineInvestigateRequest.cs | 2 + .../Requests/DisciplineResultRequest.cs | 2 + 11 files changed, 503 insertions(+), 34 deletions(-) diff --git a/BMA.EHR.Discipline.Service/Controllers/DisciplineComplaintController.cs b/BMA.EHR.Discipline.Service/Controllers/DisciplineComplaintController.cs index 0a5b75c5..dca76d4b 100644 --- a/BMA.EHR.Discipline.Service/Controllers/DisciplineComplaintController.cs +++ b/BMA.EHR.Discipline.Service/Controllers/DisciplineComplaintController.cs @@ -8,14 +8,15 @@ using BMA.EHR.Infrastructure.Persistence; // using BMA.EHR.Placement.Service.Requests; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.EntityFrameworkCore; -using Swashbuckle.AspNetCore.Annotations; -using System.Runtime.Serialization; -using System.Security.Claims; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Microsoft.AspNetCore.Mvc.RazorPages; +using Swashbuckle.AspNetCore.Annotations; +using System.Linq; using System.Net.Http.Headers; +using System.Runtime.Serialization; +using System.Security.Claims; namespace BMA.EHR.DisciplineComplaint.Service.Controllers { @@ -133,6 +134,7 @@ namespace BMA.EHR.DisciplineComplaint.Service.Controllers where x.Title.Contains(keyword) || (x.Appellant == null ? false : x.Appellant.Contains(keyword)) select x).ToList(); + if (status.Trim().ToUpper() != "ALL") data_search = data_search.Where(x => x.Status.Contains(status.Trim().ToUpper())).ToList(); @@ -165,7 +167,7 @@ namespace BMA.EHR.DisciplineComplaint.Service.Controllers .ToList(); } - var data = data_search + var query = data_search .Select(x => new { Id = x.Id,//id ข้อมูลเรื่องร้องเรียน @@ -179,11 +181,75 @@ namespace BMA.EHR.DisciplineComplaint.Service.Controllers DateReceived = x.DateReceived,//วันที่รับเรื่อง Status = x.Status,//สถานะเรื่องร้องเรียน มีดังนี้ ใหม่ (NEW), ยุติเรื่อง (STOP), มีมูลส่งไปสืบสวนแล้ว (SEND_INVESTIGATE) Result = x.Result, - }) - .OrderByDescending(x => x.DateConsideration) - .Skip((page - 1) * pageSize) - .Take(pageSize) - .ToList(); + }); + + bool desc = req.descending ?? false; + if (!string.IsNullOrEmpty(req.sortBy)) + { + switch (req.sortBy) + { + case "title": + query = desc ? query.OrderByDescending(x => x.Title) + : query.OrderBy(x => x.Title); + break; + + case "respondentType": + query = desc ? query.OrderByDescending(x => x.RespondentType) + : query.OrderBy(x => x.RespondentType); + break; + + case "appellant": + query = desc ? query.OrderByDescending(x => x.Appellant) + : query.OrderBy(x => x.Appellant); + break; + + case "offenseDetails": + query = desc ? query.OrderByDescending(x => x.OffenseDetails) + : query.OrderBy(x => x.OffenseDetails); + break; + + case "createdAt": + query = desc ? query.OrderByDescending(x => x.CreatedAt) + : query.OrderBy(x => x.CreatedAt); + break; + + case "levelConsideration": + query = desc ? query.OrderByDescending(x => x.LevelConsideration) + : query.OrderBy(x => x.LevelConsideration); + break; + + case "dateConsideration": + query = desc ? query.OrderByDescending(x => x.DateConsideration) + : query.OrderBy(x => x.DateConsideration); + break; + + case "dateReceived": + query = desc ? query.OrderByDescending(x => x.DateReceived) + : query.OrderBy(x => x.DateReceived); + break; + + case "status": + query = desc ? query.OrderByDescending(x => x.Status) + : query.OrderBy(x => x.Status); + break; + + case "result": + query = desc ? query.OrderByDescending(x => x.Result) + : query.OrderBy(x => x.Result); + break; + + default: + query = query.OrderByDescending(x => x.DateConsideration); + break; + } + + } + + var data = query + .Skip((page - 1) * pageSize) + .Take(pageSize) + .ToList(); + return Success(new { data, total = data_search.Count() }); } diff --git a/BMA.EHR.Discipline.Service/Controllers/DisciplineComplaint_AppealController.cs b/BMA.EHR.Discipline.Service/Controllers/DisciplineComplaint_AppealController.cs index a8b62e23..e485e60d 100644 --- a/BMA.EHR.Discipline.Service/Controllers/DisciplineComplaint_AppealController.cs +++ b/BMA.EHR.Discipline.Service/Controllers/DisciplineComplaint_AppealController.cs @@ -746,7 +746,7 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet("admin")] - public async Task> GetDisciplineAdmin(string status = "ALL", string type = "ALL", int year = 0, int page = 1, int pageSize = 25, string keyword = "") + public async Task> GetDisciplineAdmin(string status = "ALL", string type = "ALL", int year = 0, int page = 1, int pageSize = 25, string keyword = "", string? sortBy = "", bool? descending = false) { var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_DISCIPLINE_APPEAL"); var jsonData = JsonConvert.DeserializeObject(getPermission); @@ -812,7 +812,7 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers data_search = data_search .Where(x => node == 0 ? x.child1DnaId == null : (node == 1 ? x.child2DnaId == null : (node == 2 ? x.child3DnaId == null : (node == 3 ? x.child4DnaId == null : true)))).ToList(); } - var data = data_search + var query = data_search .Select(x => new { Id = x.Id, @@ -828,12 +828,76 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers ProfileId = x.ProfileId, LastUpdatedAt = x.LastUpdatedAt, profileType = x.profileType - }) - .OrderByDescending(x => x.profileType) - .ThenByDescending(x => x.LastUpdatedAt) + }); + bool desc = descending ?? false; + if (!string.IsNullOrEmpty(sortBy)) + { + switch (sortBy) + { + case "title": + query = desc ? query.OrderByDescending(x => x.Title) + : query.OrderBy(x => x.Title); + break; + + case "description": + query = desc ? query.OrderByDescending(x => x.Description) + : query.OrderBy(x => x.Description); + break; + + case "status": + query = desc ? query.OrderByDescending(x => x.Status) + : query.OrderBy(x => x.Status); + break; + + case "type": + query = desc ? query.OrderByDescending(x => x.Type) + : query.OrderBy(x => x.Type); + break; + + case "year": + query = desc ? query.OrderByDescending(x => x.Year) + : query.OrderBy(x => x.Year); + break; + + case "caseType": + query = desc ? query.OrderByDescending(x => x.CaseType) + : query.OrderBy(x => x.CaseType); + break; + + case "caseNumber": + query = desc ? query.OrderByDescending(x => x.CaseNumber) + : query.OrderBy(x => x.CaseNumber); + break; + + case "fullname": + query = desc ? query.OrderByDescending(x => x.Fullname) + : query.OrderBy(x => x.Fullname); + break; + + case "lastUpdatedAt": + query = desc ? query.OrderByDescending(x => x.LastUpdatedAt) + : query.OrderBy(x => x.LastUpdatedAt); + break; + + case "profileType": + query = desc ? query.OrderByDescending(x => x.profileType) + : query.OrderBy(x => x.profileType); + break; + + default: + query = query + .OrderByDescending(x => x.profileType) + .ThenByDescending(x => x.LastUpdatedAt); + break; + } + + } + + var data = query .Skip((page - 1) * pageSize) .Take(pageSize) .ToList(); + return Success(new { data, total = data_search.Count() }); } diff --git a/BMA.EHR.Discipline.Service/Controllers/DisciplineDirectorController.cs b/BMA.EHR.Discipline.Service/Controllers/DisciplineDirectorController.cs index 4cbc8f5c..202eaa44 100644 --- a/BMA.EHR.Discipline.Service/Controllers/DisciplineDirectorController.cs +++ b/BMA.EHR.Discipline.Service/Controllers/DisciplineDirectorController.cs @@ -63,7 +63,7 @@ namespace BMA.EHR.DisciplineDirector.Service.Controllers /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet("{path}")] - public async Task> GetDiscipline(string path, int page = 1, int pageSize = 25, string keyword = "") + public async Task> GetDiscipline(string path, int page = 1, int pageSize = 25, string keyword = "", string? sortBy = "", bool? descending = false) { // สิทธิ์การเข้าถึง path = path.Trim().ToUpper(); @@ -105,7 +105,7 @@ namespace BMA.EHR.DisciplineDirector.Service.Controllers x.Qualification.Contains(keyword)) && (_permiss != "OWNER" && x.RootDnaId == profile.RootDnaId || _permiss == "OWNER" && true) select x).ToList(); - var data = data_search + var query = data_search .Select(x => new { Id = x.Id, @@ -118,7 +118,66 @@ namespace BMA.EHR.DisciplineDirector.Service.Controllers Qualification = x.Qualification, TotalInvestigate = x.DisciplineInvestigate_Directors.Count(), TotalDisciplinary = x.DisciplineDisciplinary_DirectorInvestigates.Count(), - }) + }); + + bool desc = descending ?? false; + if (!string.IsNullOrEmpty(sortBy)) + { + if (sortBy == "position") + { + query = desc ? query.OrderByDescending(x => x.Position) + : query.OrderBy(x => x.Position); + } + else if (sortBy == "prefix" || sortBy == "firstName" || sortBy == "lastName") + { + query = desc ? + query + //.OrderByDescending(x => x.Prefix) + .OrderByDescending(x => x.FirstName) + .ThenByDescending(x => x.LastName) : + query + //.OrderBy(x => x.Prefix) + .OrderBy(x => x.FirstName) + .ThenBy(x => x.LastName); + } + else if (sortBy == "email") + { + { + query = desc ? query.OrderByDescending(x => x.Email) + : query.OrderBy(x => x.Email); + } + } + else if (sortBy == "phone") + { + { + query = desc ? query.OrderByDescending(x => x.Phone) + : query.OrderBy(x => x.Phone); + } + } + else if (sortBy == "qualification") + { + { + query = desc ? query.OrderByDescending(x => x.Qualification) + : query.OrderBy(x => x.Qualification); + } + } + else if (sortBy == "totalInvestigate") + { + { + query = desc ? query.OrderByDescending(x => x.TotalInvestigate) + : query.OrderBy(x => x.TotalInvestigate); + } + } + else if (sortBy == "totalDisciplinary") + { + { + query = desc ? query.OrderByDescending(x => x.TotalDisciplinary) + : query.OrderBy(x => x.TotalDisciplinary); + } + } + } + + var data = query .Skip((page - 1) * pageSize) .Take(pageSize) .ToList(); diff --git a/BMA.EHR.Discipline.Service/Controllers/DisciplineDisciplinaryController.cs b/BMA.EHR.Discipline.Service/Controllers/DisciplineDisciplinaryController.cs index af802ff8..b3de6c5b 100644 --- a/BMA.EHR.Discipline.Service/Controllers/DisciplineDisciplinaryController.cs +++ b/BMA.EHR.Discipline.Service/Controllers/DisciplineDisciplinaryController.cs @@ -165,7 +165,7 @@ namespace BMA.EHR.DisciplineDisciplinary.Service.Controllers .ToList(); } - var data = data_search + var query = data_search .Select(x => new { Id = x.Id,//id ข้อมูลเรื่องสอบสวน @@ -179,11 +179,75 @@ namespace BMA.EHR.DisciplineDisciplinary.Service.Controllers CreatedAt = x.CreatedAt,//วันที่สร้างเรื่องสอบสวน DisciplinaryDateStart = x.DisciplinaryDateStart, //วันที่เริ่มการสอบสวน DisciplinaryDateEnd = x.DisciplinaryDateEnd, //วันที่สิ้นสุดการสอบสวน - }) - .OrderByDescending(x => x.DisciplinaryDateStart) + }); + + bool desc = req.descending ?? false; + if (!string.IsNullOrEmpty(req.sortBy)) + { + switch (req.sortBy) + { + case "title": + query = desc ? query.OrderByDescending(x => x.Title) + : query.OrderBy(x => x.Title); + break; + + case "respondentType": + query = desc ? query.OrderByDescending(x => x.RespondentType) + : query.OrderBy(x => x.RespondentType); + break; + + case "offenseDetails": + query = desc ? query.OrderByDescending(x => x.OffenseDetails) + : query.OrderBy(x => x.OffenseDetails); + break; + + case "disciplinaryFaultLevel": + query = desc ? query.OrderByDescending(x => x.DisciplinaryFaultLevel) + : query.OrderBy(x => x.DisciplinaryFaultLevel); + break; + + case "disciplinaryCaseFault": + query = desc ? query.OrderByDescending(x => x.DisciplinaryCaseFault) + : query.OrderBy(x => x.DisciplinaryCaseFault); + break; + + case "status": + query = desc ? query.OrderByDescending(x => x.Status) + : query.OrderBy(x => x.Status); + break; + + case "dateReceived": + query = desc ? query.OrderByDescending(x => x.DateReceived) + : query.OrderBy(x => x.DateReceived); + break; + + case "createdAt": + query = desc ? query.OrderByDescending(x => x.CreatedAt) + : query.OrderBy(x => x.CreatedAt); + break; + + case "disciplinaryDateStart": + query = desc ? query.OrderByDescending(x => x.DisciplinaryDateStart) + : query.OrderBy(x => x.DisciplinaryDateStart); + break; + + case "disciplinaryDateEnd": + query = desc ? query.OrderByDescending(x => x.DisciplinaryDateEnd) + : query.OrderBy(x => x.DisciplinaryDateEnd); + break; + + default: + query = query.OrderByDescending(x => x.DisciplinaryDateStart); + break; + } + + } + + var data = query .Skip((page - 1) * pageSize) .Take(pageSize) .ToList(); + return Success(new { data, total = data_search.Count() }); } diff --git a/BMA.EHR.Discipline.Service/Controllers/DisciplineInvestigateController.cs b/BMA.EHR.Discipline.Service/Controllers/DisciplineInvestigateController.cs index fcee819d..114717b6 100644 --- a/BMA.EHR.Discipline.Service/Controllers/DisciplineInvestigateController.cs +++ b/BMA.EHR.Discipline.Service/Controllers/DisciplineInvestigateController.cs @@ -160,7 +160,7 @@ namespace BMA.EHR.DisciplineInvestigate.Service.Controllers .ToList(); } - var data = data_search + var query = data_search .Select(x => new { Id = x.Id,//id ข้อมูลเรื่องสืบสวน @@ -174,11 +174,76 @@ namespace BMA.EHR.DisciplineInvestigate.Service.Controllers CreatedAt = x.CreatedAt,//วันที่สร้างเรื่องสืบสวน InvestigationDetail = x.InvestigationDetail, InvestigationStatusResult = x.InvestigationStatusResult, - }) - .OrderByDescending(x => x.InvestigationDateStart) + }); + + bool desc = req.descending ?? false; + if (!string.IsNullOrEmpty(req.sortBy)) + { + switch (req.sortBy) + { + case "title": + query = desc ? query.OrderByDescending(x => x.Title) + : query.OrderBy(x => x.Title); + break; + + case "respondentType": + query = desc ? query.OrderByDescending(x => x.RespondentType) + : query.OrderBy(x => x.RespondentType); + break; + + case "offenseDetails": + query = desc ? query.OrderByDescending(x => x.OffenseDetails) + : query.OrderBy(x => x.OffenseDetails); + break; + + case "status": + query = desc ? query.OrderByDescending(x => x.Status) + : query.OrderBy(x => x.Status); + break; + + case "investigationDateStart": + query = desc ? query.OrderByDescending(x => x.InvestigationDateStart) + : query.OrderBy(x => x.InvestigationDateStart); + break; + + case "investigationDateEnd": + query = desc ? query.OrderByDescending(x => x.InvestigationDateEnd) + : query.OrderBy(x => x.InvestigationDateEnd); + break; + + case "dateReceived": + query = desc ? query.OrderByDescending(x => x.DateReceived) + : query.OrderBy(x => x.DateReceived); + break; + + case "createdAt": + query = desc ? query.OrderByDescending(x => x.CreatedAt) + : query.OrderBy(x => x.CreatedAt); + break; + + case "investigationDetail": + query = desc ? query.OrderByDescending(x => x.InvestigationDetail) + : query.OrderBy(x => x.InvestigationDetail); + break; + + case "investigationStatusResult": + query = desc ? query.OrderByDescending(x => x.InvestigationStatusResult) + : query.OrderBy(x => x.InvestigationStatusResult); + break; + + default: + query = query.OrderByDescending(x => x.InvestigationDateStart); + + break; + } + + } + + var data = query .Skip((page - 1) * pageSize) .Take(pageSize) .ToList(); + return Success(new { data, total = data_search.Count() }); } diff --git a/BMA.EHR.Discipline.Service/Controllers/DisciplineResultController.cs b/BMA.EHR.Discipline.Service/Controllers/DisciplineResultController.cs index dde2cb9e..15fc50f0 100644 --- a/BMA.EHR.Discipline.Service/Controllers/DisciplineResultController.cs +++ b/BMA.EHR.Discipline.Service/Controllers/DisciplineResultController.cs @@ -192,7 +192,7 @@ namespace BMA.EHR.DisciplineResult.Service.Controllers .ToList(); } - var data = data_search + var query = data_search .Select(x => new { Id = x.Id,//id ข้อมูลเรื่องสอบสวน @@ -209,11 +209,90 @@ namespace BMA.EHR.DisciplineResult.Service.Controllers ResultDisciplineType = x.ResultDisciplineType,//หน่วยงาย/ส่วนราชการ ResultTitleType = x.ResultTitleType,//ประเภทของเรื่อง ResultYear = x.ResultYear,//ปีงบประมาณ - }) - .OrderByDescending(x => x.CreatedAt) + }); + + bool desc = req.descending ?? false; + if (!string.IsNullOrEmpty(req.sortBy)) + { + switch (req.sortBy) + { + case "title": + query = desc ? query.OrderByDescending(x => x.Title) + : query.OrderBy(x => x.Title); + break; + + case "respondentType": + query = desc ? query.OrderByDescending(x => x.RespondentType) + : query.OrderBy(x => x.RespondentType); + break; + + case "offenseDetails": + query = desc ? query.OrderByDescending(x => x.OffenseDetails) + : query.OrderBy(x => x.OffenseDetails); + break; + + case "disciplinaryFaultLevel": + query = desc ? query.OrderByDescending(x => x.DisciplinaryFaultLevel) + : query.OrderBy(x => x.DisciplinaryFaultLevel); + break; + + case "disciplinaryCaseFault": + query = desc ? query.OrderByDescending(x => x.DisciplinaryCaseFault) + : query.OrderBy(x => x.DisciplinaryCaseFault); + break; + + case "status": + query = desc ? query.OrderByDescending(x => x.Status) + : query.OrderBy(x => x.Status); + break; + + case "createdAt": + query = desc ? query.OrderByDescending(x => x.CreatedAt) + : query.OrderBy(x => x.CreatedAt); + break; + + case "disciplinaryDateStart": + query = desc ? query.OrderByDescending(x => x.DisciplinaryDateStart) + : query.OrderBy(x => x.DisciplinaryDateStart); + break; + + case "disciplinaryDateEnd": + query = desc ? query.OrderByDescending(x => x.DisciplinaryDateEnd) + : query.OrderBy(x => x.DisciplinaryDateEnd); + break; + + case "resultOc": + query = desc ? query.OrderByDescending(x => x.ResultOc) + : query.OrderBy(x => x.ResultOc); + break; + + case "resultDisciplineType": + query = desc ? query.OrderByDescending(x => x.ResultDisciplineType) + : query.OrderBy(x => x.ResultDisciplineType); + break; + + case "resultTitleType": + query = desc ? query.OrderByDescending(x => x.ResultTitleType) + : query.OrderBy(x => x.ResultTitleType); + break; + + case "resultYear": + query = desc ? query.OrderByDescending(x => x.ResultYear) + : query.OrderBy(x => x.ResultYear); + break; + + default: + query = query.OrderByDescending(x => x.CreatedAt); + break; + } + + } + + var data = query .Skip((page - 1) * pageSize) .Take(pageSize) .ToList(); + return Success(new { data, total = data_search.Count() }); } diff --git a/BMA.EHR.Discipline.Service/Controllers/DisciplineSuspendController.cs b/BMA.EHR.Discipline.Service/Controllers/DisciplineSuspendController.cs index 25603274..de2c7ab2 100644 --- a/BMA.EHR.Discipline.Service/Controllers/DisciplineSuspendController.cs +++ b/BMA.EHR.Discipline.Service/Controllers/DisciplineSuspendController.cs @@ -9,9 +9,10 @@ using BMA.EHR.Infrastructure.Persistence; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -using Newtonsoft.Json.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Swashbuckle.AspNetCore.Annotations; +using System.Linq; using System.Security.Claims; namespace BMA.EHR.DisciplineSuspend.Service.Controllers @@ -58,7 +59,7 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers /// ไม่ได้ Login เข้าระบบ /// เมื่อเกิดข้อผิดพลาดในการทำงาน [HttpGet()] - public async Task> GetDisciplineSuspend(DateTime? startDate, DateTime? endDate, int page = 1, int pageSize = 25, string keyword = "", string profileType = "") + public async Task> GetDisciplineSuspend(DateTime? startDate, DateTime? endDate, int page = 1, int pageSize = 25, string keyword = "", string profileType = "", string? sortBy = "", bool? descending = false) { var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_DISCIPLINE_SUSPENDED"); var jsonData = JsonConvert.DeserializeObject(getPermission); @@ -94,7 +95,7 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers (profileType.ToUpper() == "EMPLOYEE" && x.profileType == "EMPLOYEE") ) select x).ToList(); - var data = data_search + var query = data_search .Select(x => new { Id = x.Id, @@ -145,13 +146,76 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers DisciplinaryCaseFault = x.DisciplineDisciplinary.DisciplinaryCaseFault,//กรณีความผิด profileType = x.profileType, CreatedAt = x.CreatedAt, - }) - .OrderByDescending(x => x.profileType) - .ThenByDescending(x => x.CreatedAt) - .ThenByDescending(x => x.CitizenId) + }); + + bool desc = descending ?? false; + if (!string.IsNullOrEmpty(sortBy)) + { + if (sortBy == "title") + { + query = desc ? query.OrderByDescending(x => x.Title) + : query.OrderBy(x => x.Title); + } + else if (sortBy == "prefix" || sortBy == "firstName" || sortBy == "lastName") + { + query = desc ? + query + //.OrderByDescending(x => x.Prefix) + .OrderByDescending(x => x.FirstName) + .ThenByDescending(x => x.LastName) : + query + //.OrderBy(x => x.Prefix) + .OrderBy(x => x.FirstName) + .ThenBy(x => x.LastName); + } + else if (sortBy == "position") + { + query = desc ? query.OrderByDescending(x => x.Position) + : query.OrderBy(x => x.Position); + } + else if (sortBy == "positionType" || sortBy == "positionLevel") + { + query = desc ? + query + .OrderByDescending(x => x.PositionType) + .ThenByDescending(x => x.PositionLevel) : + query + .OrderBy(x => x.PositionType) + .ThenBy(x => x.PositionLevel); + } + else if (sortBy == "organization") + { + query = desc ? query.OrderByDescending(x => x.Organization) + : query.OrderBy(x => x.Organization); + } + else if (sortBy == "startDateSuspend") + { + query = desc ? query.OrderByDescending(x => x.StartDateSuspend) + : query.OrderBy(x => x.StartDateSuspend); + } + else if (sortBy == "endDateSuspend") + { + query = desc ? query.OrderByDescending(x => x.EndDateSuspend) + : query.OrderBy(x => x.EndDateSuspend); + } + else if (sortBy == "descriptionSuspend") + { + query = desc ? query.OrderByDescending(x => x.DescriptionSuspend) + : query.OrderBy(x => x.DescriptionSuspend); + } + else + { + query = query.OrderByDescending(x => x.profileType) + .ThenByDescending(x => x.CreatedAt) + .ThenByDescending(x => x.CitizenId); + } + } + + var data = query .Skip((page - 1) * pageSize) .Take(pageSize) .ToList(); + return Success(new { data, total = data_search.Count() }); } diff --git a/BMA.EHR.Discipline.Service/Requests/DisciplineComplaintRequest.cs b/BMA.EHR.Discipline.Service/Requests/DisciplineComplaintRequest.cs index b9871b89..b05ad34d 100644 --- a/BMA.EHR.Discipline.Service/Requests/DisciplineComplaintRequest.cs +++ b/BMA.EHR.Discipline.Service/Requests/DisciplineComplaintRequest.cs @@ -76,6 +76,8 @@ namespace BMA.EHR.Discipline.Service.Requests public string? levelConsideration { get; set; } // ระดับการพิจารณา public DateTime? dateConsiderationStart { get; set; } // วันที่เริ่มต้นการพิจารณา public DateTime? dateConsiderationEnd { get; set; } // วันที่สิ้นสุดการพิจารณา + public string? sortBy { get; set; } + public bool? descending { get; set; } } } diff --git a/BMA.EHR.Discipline.Service/Requests/DisciplineDisciplinaryRequest.cs b/BMA.EHR.Discipline.Service/Requests/DisciplineDisciplinaryRequest.cs index 21761a4c..c23d236a 100644 --- a/BMA.EHR.Discipline.Service/Requests/DisciplineDisciplinaryRequest.cs +++ b/BMA.EHR.Discipline.Service/Requests/DisciplineDisciplinaryRequest.cs @@ -48,6 +48,8 @@ namespace BMA.EHR.Discipline.Service.Requests public DateTime? disciplinaryDateEnd { get; set; } // วันที่สิ้นสุดสอบสวน public DateTime? dateReceivedStart { get; set; } // วันที่เริ่มต้นรับเรื่อง public DateTime? dateReceivedEnd { get; set; } // วันที่สิ้นสุดรับเรื่อง + public string? sortBy { get; set; } + public bool? descending { get; set; } } } diff --git a/BMA.EHR.Discipline.Service/Requests/DisciplineInvestigateRequest.cs b/BMA.EHR.Discipline.Service/Requests/DisciplineInvestigateRequest.cs index 2f99b010..fc27a490 100644 --- a/BMA.EHR.Discipline.Service/Requests/DisciplineInvestigateRequest.cs +++ b/BMA.EHR.Discipline.Service/Requests/DisciplineInvestigateRequest.cs @@ -36,6 +36,8 @@ namespace BMA.EHR.Discipline.Service.Requests public DateTime? dateReceivedStart { get; set; } // วันที่เริ่มต้นรับเรื่อง public DateTime? dateReceivedEnd { get; set; } // วันที่สิ้นสุดรับเรื่อง public string? investigationStatusResult { get; set; } // ผลการสืบสวน + public string? sortBy { get; set; } + public bool? descending { get; set; } } } diff --git a/BMA.EHR.Discipline.Service/Requests/DisciplineResultRequest.cs b/BMA.EHR.Discipline.Service/Requests/DisciplineResultRequest.cs index a08dae9c..7481c76a 100644 --- a/BMA.EHR.Discipline.Service/Requests/DisciplineResultRequest.cs +++ b/BMA.EHR.Discipline.Service/Requests/DisciplineResultRequest.cs @@ -27,6 +27,8 @@ namespace BMA.EHR.Discipline.Service.Requests public string? resultTitleType { get; set; } // ประเภทของเรื่อง public string? resultOc { get; set; } // หน่วยงาน/ส่วนราชการ public int? resultYear { get; set; } // ปีงบประมาณ + public string? sortBy { get; set; } + public bool? descending { get; set; } } From 7ddc1debfc913de19076226db7f3c6176707b347 Mon Sep 17 00:00:00 2001 From: Harid Promsri <52228846+Harid-999@users.noreply.github.com> Date: Tue, 7 Oct 2025 13:17:58 +0700 Subject: [PATCH 08/13] fix timestamp report #1843 (#1844) Co-authored-by: harid --- .../Controllers/LeaveReportController.cs | 75 +++++++++--------- BMA.EHR.Leave/Reports/TimeStampRecords.xlsx | Bin 18348 -> 18272 bytes 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/BMA.EHR.Leave/Controllers/LeaveReportController.cs b/BMA.EHR.Leave/Controllers/LeaveReportController.cs index 01bd6820..f897e075 100644 --- a/BMA.EHR.Leave/Controllers/LeaveReportController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveReportController.cs @@ -2168,12 +2168,15 @@ namespace BMA.EHR.Leave.Service.Controllers var templatePath = Path.Combine(_hostingEnvironment.ContentRootPath, "Reports", "TimeStampRecords.xlsx"); byte[] templateBytes = System.IO.File.ReadAllBytes(templatePath); - //using (var package = new ExcelPackage(fileInfo)) + using (var stream = new MemoryStream(templateBytes)) using (var package = new ExcelPackage(stream)) { - //var worksheet = package.Workbook.Worksheets.Add("Sheet1"); + var worksheet = package.Workbook.Worksheets["Sheet1"] ?? package.Workbook.Worksheets[0]; + // กำหนดให้ใช้ฟอนต์ TH SarabunPSK ซึ่งเป็นฟอนต์มาตรฐานราชการไทย + // **ข้อควรระวัง:** หากเครื่องผู้ใช้ไม่มีฟอนต์นี้ติดตั้งอยู่ การจัดหน้าเอกสารจะเพี้ยน + worksheet.Cells.Style.Font.Name = "TH SarabunPSK"; worksheet.Cells["A1:J1"].Merge = true; worksheet.Cells["A2:J2"].Merge = true; @@ -2185,56 +2188,50 @@ namespace BMA.EHR.Leave.Service.Controllers range.Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center; range.Style.Font.Bold = true; } - //worksheet.Cells[1, 1].Value = "แบบการลงเวลาปฏิบัติราชการ"; + worksheet.Cells[2, 1].Value = organizationName; worksheet.Cells[3, 1].Value = dateTimeStamp; - using (var range = worksheet.Cells[4, 1, 4, 10]) - { - range.Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; - range.Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; - range.Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; - range.Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; - range.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center; - range.Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center; - range.Style.Font.Bold = true; - } - //worksheet.Cells[4, 1].Value = "ลำดับที่"; - //worksheet.Cells[4, 2].Value = "ชื่อ - สกุล"; - //worksheet.Cells[4, 3].Value = "รอบ"; - //worksheet.Cells[4, 4].Value = "วันที่เข้างาน"; - //worksheet.Cells[4, 5].Value = "พิกัด"; - //worksheet.Cells[4, 6].Value = "เวลามา"; - //worksheet.Cells[4, 7].Value = "วันที่ออกงาน"; - //worksheet.Cells[4, 8].Value = "พิกัด"; - //worksheet.Cells[4, 9].Value = "เวลากลับ"; - //worksheet.Cells[4, 10].Value = "หมายเหตุ"; int startRow = 5; - foreach (var emp in employees) + int colCount = 10; + int totalRows = employees.Count; + + // เตรียม List สำหรับใช้กับ LoadFromArrays + var data = new List(totalRows); + for (int i = 0; i < totalRows; i++) { - worksheet.Cells[startRow, 1].Value = emp.no; - worksheet.Cells[startRow, 2].Value = emp.fullName; - worksheet.Cells[startRow, 3].Value = emp.dutyTimeName; - worksheet.Cells[startRow, 4].Value = emp.checkInDate; - worksheet.Cells[startRow, 5].Value = emp.checkInLocation; - worksheet.Cells[startRow, 6].Value = emp.checkInTime; - worksheet.Cells[startRow, 7].Value = emp.checkedOutDate; - worksheet.Cells[startRow, 8].Value = emp.checkOutLocation; - worksheet.Cells[startRow, 9].Value = emp.checkOutTime; - worksheet.Cells[startRow, 10].Value = emp.remark; - startRow++; + var emp = employees[i]; + data.Add(new object[] + { + emp.no, + emp.fullName, + emp.dutyTimeName, + emp.checkInDate, + emp.checkInLocation, + emp.checkInTime, + emp.checkedOutDate, + emp.checkOutLocation, + emp.checkOutTime, + emp.remark + }); } - // ใส่กรอบให้ตาราง - using (var range = worksheet.Cells[5, 1, startRow - 1, 10]) + // เขียนข้อมูลลง Excel ครั้งเดียว + worksheet.Cells[startRow, 1].LoadFromArrays(data); + + // กำหนดสไตล์ตัวบาง + ขอบ + using (var range = worksheet.Cells[startRow, 1, startRow + totalRows - 1, colCount]) { + range.Style.Font.Bold = false; range.Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; range.Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; range.Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; range.Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; } - int lastRow = startRow + 2; + // ส่วนสรุปท้ายตาราง + int lastRow = startRow + totalRows + 2; + worksheet.Cells[lastRow, 2].Value = type.Trim().ToUpper() == "OFFICER" ? "ข้าราชการทั้งหมด" : "ลูกจ้างประจำทั้งหมด"; worksheet.Cells[lastRow, 5].Value = profile?.Count; worksheet.Cells[lastRow, 6].Value = "คน"; @@ -2260,6 +2257,8 @@ namespace BMA.EHR.Leave.Service.Controllers worksheet.Cells[lastRow + 6, 2].Value = "เรียน"; worksheet.Cells[lastRow + 7, 2].Value = "เพื่อโปรดทราบ"; worksheet.Cells[lastRow + 7, 9].Value = "ทราบ"; + worksheet.Cells[lastRow + 7, 9].Style.Font.Bold = true; + worksheet.Cells[lastRow + 7, 9].Style.Font.Size = 22; worksheet.Cells[lastRow + 8, 2].Value = "................................"; worksheet.Cells[lastRow + 8, 9].Value = "................................"; worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns(); diff --git a/BMA.EHR.Leave/Reports/TimeStampRecords.xlsx b/BMA.EHR.Leave/Reports/TimeStampRecords.xlsx index ee4527d547ab7b7aa1ad89bad6738cccc9e7a6f0..d5fe12be63a9954d81c089e2e359eb7ef9edce6a 100644 GIT binary patch delta 4711 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 U6)_xpxqpLX6)2u7;-AF-12WCNSpWb4 delta 4827 zcmZ8lbyU>d(_a>rj-_EiK)NKP%cVg|q@=rBq(Q#qA|SbdbV*1`_tKpbg0Rx~pfpGc z03&bjB#XJ+oKCty@1V$_o009`F!3?`T$kRJ{RL;?bV{9XC| zJiJ`2Jv?0a{M}ru^w&JHB`HF>XYX+A4?bf^$%45v!K}t5?iKZ`2PHb+LUpUa|G?&o zD=xZ^XygH2eiXWBVCc!lPrs>OQzuKq3i`&ErcLq-q|D?vMx9f(e7k7e+n}bQSGG-A zpCxzzyGfR_9+R_|Cx`hBC_O(Dt|MO12Q)6Fu~?y7i%~Dnf|hN+OYMGfMFygzy$P-S zGQ9<|)6VU-E8b-$`20P_Lp_h)q>kJXf9{5w%_as}3jR#&Yqy74zKWIgEj{`gD?UV1 zwx2-*2C4G!vx1R|`s3ft>9KC=o;R}6dj;#jUVoyvz^4;dfn0k17>!Yb!!xXcgRrxh z`++*V0Lt)wC&E?4_HyhR0kWUNVC-Jg;Ep`~o=`aluFS$zZO-!$>qu;-lf#|j(Ufn| z_8RsN<0_}F+A-S-MT1de)L7I%0g?8#sX=$n3O<@&W5}w6nY-x(Vn2j`i~YIT8uO58BwQyYwY1^kh-(kVSvcZTwO@$z?A;y$lq z%@&O|Gp0B%((}k!ZAC~H_88aSp7v|hYf%qx(|yNnOZq`R=ip28XaG+t89wLloxte& zj|F1pqF>x~`Kws(6sbeb17Ivo2vDaF5cbqA8K_k~WP*8wC zJv04E)sw01ft{V@CRQ31X8d5&O3$jQf4X42WVY4CLD#`DNVl8)e1ee_8DlG zNc9nEGa}H1aABTSeJdS%Y;dtd0|a|^Lj$HJOTwx8PmbWc@T5DNMCN-Mh8uiRgP#HI5@h_!7b6_Q3x0Wy1&OniVBf5B;y-{ z@$--*Hk5xzX!!tnPRIn9c`OT1AdWZ=;EG+*U!JPsG3$L(&lcAI?AYS6MN^wKkm-i+ zx(uwt>WsWu)BFC>MMLP@Hd3enGrqqCnaM)GlLRSq%S>`Kl zFL;mm1p&939y#_d8N#$0YfE>u8N#ng^jx|O`*e}+`45Cat-2>fKM`HgZ~Gj>n#;?I zm^ijGoT#ftz5M&*==Mw2q6sw571l9Pwt)MsezCj&Ta#%fU(&7Q&f+(YkWJl%6!S%Z z6rtF)`K*s&9S@)k=4G38G3v#m3V~9!2%z~yzQpn>0pSenTQ3v6Q?hNp#*{w)+D1D) z^gudu$e&?~y+Po2oU%e0Qc45{YtI=m<$hNEjw@?gkYS5K`OeXBM#RGNr}he$2ipXy zGXkPrxAN2EUL#b`HAs5!1y}pS2z0H3#Y>Oh(BQIsnIHh_-ur5bFxnOGG(_Eqm!^rC z>ET*ltyATqyYRDk$Gxurlh$I!&As3ST*+RPORb$X!IS<>yW!I8u* z(5V+ztqM41UvtaUs!r=b^92<73W9FMUg6<9E$V>|21K}F`muQJ≠JeuG**!#nE- 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 Date: Tue, 7 Oct 2025 14:52:59 +0700 Subject: [PATCH 09/13] fix #1841, #1842 --- .../Leaves/LeaveRequests/LeaveRequestRepository.cs | 7 ++++++- BMA.EHR.Leave/Controllers/LeaveRequestController.cs | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs b/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs index bcd650ef..84b0d84e 100644 --- a/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs +++ b/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs @@ -280,7 +280,12 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests .Where(x => x.KeycloakUserId == keycloakUserId); if (year != 0) - rawData = rawData.Where(x => x.LeaveStartDate.Year == year); + { + var startFiscalDate = new DateTime(year - 1, 10, 1); + var endFiscalDate = new DateTime(year, 9, 30); + rawData = rawData.Where(x => x.LeaveStartDate.Date >= startFiscalDate && x.LeaveStartDate.Date <= endFiscalDate); + } + //rawData = rawData.Where(x => x.LeaveStartDate.Year == year); if (type != Guid.Empty) rawData = rawData.Where(x => x.Type.Id == type); diff --git a/BMA.EHR.Leave/Controllers/LeaveRequestController.cs b/BMA.EHR.Leave/Controllers/LeaveRequestController.cs index 27457ceb..489dccae 100644 --- a/BMA.EHR.Leave/Controllers/LeaveRequestController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveRequestController.cs @@ -1349,6 +1349,8 @@ namespace BMA.EHR.Leave.Service.Controllers // return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); // } + + var rawData = await _leaveRequestRepository.GetLeaveRequestByUserIdAsync(userId, req.Year, req.Type, req.Status); From 0dcabaa25dde835d7babf4683843c22360bef22c Mon Sep 17 00:00:00 2001 From: Harid Promsri <52228846+Harid-999@users.noreply.github.com> Date: Tue, 7 Oct 2025 17:15:32 +0700 Subject: [PATCH 10/13] =?UTF-8?q?=E0=B8=88=E0=B8=B1=E0=B8=94=20Align=20(#1?= =?UTF-8?q?846)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: harid --- .../Controllers/LeaveReportController.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/BMA.EHR.Leave/Controllers/LeaveReportController.cs b/BMA.EHR.Leave/Controllers/LeaveReportController.cs index f897e075..2ef225dc 100644 --- a/BMA.EHR.Leave/Controllers/LeaveReportController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveReportController.cs @@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Routing.Template; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OfficeOpenXml; +using OfficeOpenXml.Style; using Swashbuckle.AspNetCore.Annotations; using System.Globalization; using System.Security.Claims; @@ -2227,6 +2228,21 @@ namespace BMA.EHR.Leave.Service.Controllers range.Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; range.Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; range.Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; + range.Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Top; + + // Center Align: คอลัมน์ 1 (A), 3 (C), 4 (D), 6 (F), 7 (G), 9 (I) + var centerColumns = new[] { 1, 3, 4, 6, 7, 9 }; + foreach (var col in centerColumns) + { + worksheet.Cells[startRow, col, startRow + totalRows - 1, col].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; + } + + // Left Align: คอลัมน์ 2 (B), 5 (E), 8 (H), 10 (J) + var leftColumns = new[] { 2, 5, 8, 10 }; + foreach (var col in leftColumns) + { + worksheet.Cells[startRow, col, startRow + totalRows - 1, col].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left; + } } // ส่วนสรุปท้ายตาราง From f784205412c346167d75b589accd8e2fba3520ca Mon Sep 17 00:00:00 2001 From: AdisakKanthawilang <153157069+AdisakKanthawilang@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:01:57 +0700 Subject: [PATCH 11/13] fix sort /api/v1/leave/admin/edit (#1848) --- BMA.EHR.Leave/Controllers/LeaveController.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/BMA.EHR.Leave/Controllers/LeaveController.cs b/BMA.EHR.Leave/Controllers/LeaveController.cs index 08ec712b..27d00e35 100644 --- a/BMA.EHR.Leave/Controllers/LeaveController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveController.cs @@ -2560,6 +2560,10 @@ namespace BMA.EHR.Leave.Service.Controllers { result = result.Where(x => x.FullName.Contains(keyword)).ToList(); } + if (string.IsNullOrWhiteSpace(sortBy)) + { + sortBy = "default"; + } if (!string.IsNullOrWhiteSpace(sortBy)) { switch (sortBy.ToUpper()) @@ -2606,11 +2610,12 @@ namespace BMA.EHR.Leave.Service.Controllers else result = result.OrderBy(x => x.Description).ToList(); break; - default: break; + default: + result = result.OrderBy(x => x.StatusSort).ToList(); + break; } } - var pageResult = result.Skip((page - 1) * pageSize).Take(pageSize) - .OrderBy(x => x.StatusSort) + var pageResult = result.Skip((page - 1) * pageSize).Take(pageSize) .ToList(); return Success(new { data = pageResult, total = result.Count }); From fe4a174bf7a1950f91e050a3879e16150bf2527e Mon Sep 17 00:00:00 2001 From: AdisakKanthawilang <153157069+AdisakKanthawilang@users.noreply.github.com> Date: Wed, 8 Oct 2025 17:23:10 +0700 Subject: [PATCH 12/13] fix sort api/v1/leave/search (#1852) --- BMA.EHR.Leave/Controllers/LeaveController.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/BMA.EHR.Leave/Controllers/LeaveController.cs b/BMA.EHR.Leave/Controllers/LeaveController.cs index 27d00e35..8ef2c54d 100644 --- a/BMA.EHR.Leave/Controllers/LeaveController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveController.cs @@ -26,6 +26,7 @@ using RabbitMQ.Client; using RabbitMQ.Client.Events; using Swashbuckle.AspNetCore.Annotations; using System.ComponentModel.DataAnnotations; +using System.Diagnostics; using System.Security.Claims; using System.Text; using System.Threading.Tasks; @@ -1862,21 +1863,15 @@ namespace BMA.EHR.Leave.Service.Controllers { case "CITIZENID": if (req.descending == true) - profile = profile.OrderByDescending(x => x.CitizenId).ToList(); + resultSet = resultSet.OrderByDescending(x => x.CitizenId).ToList(); else - profile = profile.OrderBy(x => x.CitizenId).ToList(); + resultSet = resultSet.OrderBy(x => x.CitizenId).ToList(); break; case "FULLNAME": if (req.descending == true) - profile = profile.OrderByDescending(x => x.Prefix) - .ThenByDescending(x => x.FirstName) - .ThenByDescending(x => x.LastName) - .ToList(); + resultSet = resultSet.OrderByDescending(x => x.FullName).ToList(); else - profile = profile.OrderBy(x => x.Prefix) - .ThenBy(x => x.FirstName) - .ThenBy(x => x.LastName) - .ToList(); + resultSet = resultSet.OrderBy(x => x.FullName).ToList(); break; case "STARTTIMEMORNING": if (req.descending == true) From 5f0a0b1a46e53f0e9e2f45ea0956f747ba5326e0 Mon Sep 17 00:00:00 2001 From: Harid Promsri <52228846+Harid-999@users.noreply.github.com> Date: Thu, 9 Oct 2025 16:49:10 +0700 Subject: [PATCH 13/13] =?UTF-8?q?=E0=B8=9B=E0=B8=A3=E0=B8=B1=E0=B8=9A?= =?UTF-8?q?=E0=B9=83=E0=B8=AB=E0=B9=89=E0=B8=88=E0=B8=B1=E0=B8=94=20group?= =?UTF-8?q?=20=E0=B8=95=E0=B8=B2=E0=B8=A1=E0=B8=97=E0=B8=B5=E0=B9=88?= =?UTF-8?q?=E0=B8=81=E0=B8=A3=E0=B8=AD=E0=B8=87=20(#1858)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: harid --- .../LeaveRequests/LeaveRequestRepository.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs b/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs index 84b0d84e..c6d9bdc7 100644 --- a/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs +++ b/BMA.EHR.Application/Repositories/Leaves/LeaveRequests/LeaveRequestRepository.cs @@ -1563,10 +1563,21 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests var organizationName = $"{org.Root ?? ""}{(!string.IsNullOrEmpty(org.Child1) ? "/" + org.Child1 : "")}{(!string.IsNullOrEmpty(org.Child2) ? "/" + org.Child2 : "")}{(!string.IsNullOrEmpty(org.Child3) ? "/" + org.Child3 : "")}{(!string.IsNullOrEmpty(org.Child4) ? "/" + org.Child4 : "")}"; if (data.Count > 0) { - var res = (from d in data + var grouped = data.GroupBy(d => nodeByReq switch + { + 0 => d.Root, + 1 => d.Child1, + 2 => d.Child2, + 3 => d.Child3, + 4 => d.Child4, + _ => d.Root + }); + var res = (/*from d in data group d by new { d.Root, d.Child1, d.Child2, d.Child3, d.Child4 } into grp - orderby grp.Key.Root, grp.Key.Child1, grp.Key.Child2, grp.Key.Child3, grp.Key.Child4 - select new GetSumApproveLeaveByRootDto + orderby grp.Key.Root, grp.Key.Child1, grp.Key.Child2, grp.Key.Child3, grp.Key.Child4*/ + from grp in grouped + orderby grp.Key + select new GetSumApproveLeaveByRootDto { //Root = $"{grp.Key.Root}{(!string.IsNullOrEmpty(grp.Key.Child1) ? "/" + grp.Key.Child1 : "")}{(!string.IsNullOrEmpty(grp.Key.Child2) ? "/" + grp.Key.Child2 : "")}{(!string.IsNullOrEmpty(grp.Key.Child3) ? "/" + grp.Key.Child3 : "")}{(!string.IsNullOrEmpty(grp.Key.Child4) ? "/" + grp.Key.Child4 : "")}", Root = organizationName,