From cba02a4f6e75ea4fa791d03aee3a06df8068eadf Mon Sep 17 00:00:00 2001 From: harid Date: Fri, 1 May 2026 14:22:07 +0700 Subject: [PATCH 1/2] =?UTF-8?q?api=20=E0=B8=A3=E0=B8=B2=E0=B8=A2=E0=B8=87?= =?UTF-8?q?=E0=B8=B2=E0=B8=99=E0=B8=A3=E0=B8=B2=E0=B8=A2=E0=B8=8A=E0=B8=B7?= =?UTF-8?q?=E0=B9=88=E0=B8=AD=E0=B8=9C=E0=B8=B9=E0=B9=89=E0=B8=A1=E0=B8=B5?= =?UTF-8?q?=E0=B8=AA=E0=B8=B4=E0=B8=97=E0=B8=98=E0=B8=B4=E0=B9=8C=E0=B8=AA?= =?UTF-8?q?=E0=B8=AD=E0=B8=9A,=20=E0=B8=A3=E0=B8=B2=E0=B8=A2=E0=B8=8A?= =?UTF-8?q?=E0=B8=B7=E0=B9=88=E0=B8=AD=E0=B8=9C=E0=B8=B9=E0=B9=89=E0=B8=AA?= =?UTF-8?q?=E0=B8=AD=E0=B8=9A=E0=B8=84=E0=B8=B1=E0=B8=94=E0=B9=80=E0=B8=A5?= =?UTF-8?q?=E0=B8=B7=E0=B8=AD=E0=B8=81=E0=B9=84=E0=B8=94=E0=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Controllers/PeriodExamController.cs | 50 +++++++++++++++ Services/PeriodExamService.cs | 95 +++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) diff --git a/Controllers/PeriodExamController.cs b/Controllers/PeriodExamController.cs index b52b0f6..84ea0d9 100644 --- a/Controllers/PeriodExamController.cs +++ b/Controllers/PeriodExamController.cs @@ -749,6 +749,56 @@ namespace BMA.EHR.Recurit.Exam.Service.Controllers } } + /// + /// ดาวน์โหลดรายชื่อผู้มีสิทธิ์สอบ + /// + /// รหัสรอบสมัคร + /// + /// เมื่อทำการอ่านโหลดผู้สมัครสอบสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("download/candidate-exam/{examId:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> DownloadCandidateExamAsync(string examId) + { + try + { + var data = await _periodExamService.DownloadCandidateExamAsync(examId); + return Success(data); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// ดาวน์โหลดรายชื่อผู้สอบคัดเลือกได้ + /// + /// รหัสรอบสมัคร + /// + /// เมื่อทำการอ่านโหลดผู้สมัครสอบสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("download/pass-exam/{examId:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> DownloadPassExamAsync(string examId) + { + try + { + var data = await _periodExamService.DownloadPassExamAsync(examId); + return Success(data); + } + catch (Exception ex) + { + return Error(ex, "เกิดข้อผิดพลาดในการแสดงรายงาน"); + } + } + /// /// โหลดผู้สมัครสอบ /// diff --git a/Services/PeriodExamService.cs b/Services/PeriodExamService.cs index aeefa24..c967bca 100644 --- a/Services/PeriodExamService.cs +++ b/Services/PeriodExamService.cs @@ -1625,6 +1625,101 @@ namespace BMA.EHR.Recurit.Exam.Service.Services }; } + public async Task DownloadCandidateExamAsync(string examId) + { + var periodExam = await _context.PeriodExams.AsQueryable() + .Where(x => x.CheckDisability == false) + .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); + + if (periodExam == null) + throw new Exception(GlobalMessages.ExamNotFound); + + var data = await _context.Candidates.AsQueryable() + .Include(x => x.PeriodExam) + .Where(x => x.PeriodExam == periodExam) + .Where(x => x.Status != "register") + .Where(x => x.ExamIdenNumber != null && x.ExamIdenNumber != "") + .OrderBy(x => x.ExamIdenNumber) + .Select(p => new + { + ExamId = p.ExamIdenNumber == null ? null : (p.ExamIdenNumber.ToThaiNumber()), + FullName = $"{p.PrefixName}{p.FirstName} {p.LastName}", + PositionName = "", + ExamName = + ($"{p.PeriodExam.Name} ครั้งที่ {p.PeriodExam.Round}/{p.PeriodExam.Year.Value.ToThaiYear()}").ToThaiNumber(), + }).ToListAsync(); + + if (data.Count == 0) + throw new Exception("ไม่พบข้อมูลในระบบ"); + + var examName = data[0].ExamName; + return new + { + template = "rptCandidateList", + reportName = $"รายชื่อผู้มีสิทธิ์สอบ_{data.First().ExamName}", + data = new + { + examName = examName, + data = data + } + }; + } + + public async Task DownloadPassExamAsync(string examId) + { + var periodExam = await _context.PeriodExams.AsQueryable() + .Where(x => x.CheckDisability == false) + .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); + + if (periodExam == null) + throw new Exception(GlobalMessages.ExamNotFound); + + var candidates = await _context.Candidates.AsQueryable() + .Include(x => x.PeriodExam) + .ThenInclude(x => x.ScoreImport) + .Where(x => x.PeriodExam == periodExam) + .Where(x => x.Status != "register") + .ToListAsync(); + + var data = candidates.Select((p, idx) => new + { + SeatNumber = p.SeatNumber == null ? "-" : (p.SeatNumber.ToThaiNumber()), + CitizenId = p.CitizenId == null ? "-" : (p.CitizenId.ToThaiNumber()), + FullName = $"{p.PrefixName}{p.FirstName} {p.LastName}", + DateOfBirth = p.DateOfBirth == null ? "-" : (p.DateOfBirth.Value.ToThaiShortDate()), + ExamName = ($"{p.PeriodExam.Name} ครั้งที่ {p.PeriodExam.Round}/{p.PeriodExam.Year.Value.ToThaiYear()}").ToThaiNumber(), + Number = p.Number == null ? (idx + 1).ToString().ToThaiNumber() : p.Number.ToThaiNumber(), + FullA = "๐", + SumA = "๐", + FullB = p.PointTotalB == null ? "-" : p.PointTotalB.ToString(), + SumB = p.PointB == null ? "-" : p.PointB.ToString(), + FullC = p.PointTotalC == null ? "-" : p.PointTotalC.ToString(), + SumC = p.PointC == null ? "-" : p.PointC.ToString(), + SumScore = ((Convert.ToInt32(p.PointB ?? "0") + Convert.ToInt32(p.PointC ?? "0")).ToString()).ToThaiNumber(), + ExamResult = p.Pass, + ExamThaiId = p.ExamIdenNumber == null ? "-" : p.ExamIdenNumber.ToThaiNumber(), + ExamId = p.ExamIdenNumber, + }) + .OrderBy(x => x.ExamId) + .Where(x => x.ExamResult?.Trim() == "ได้") + .ToList(); + + if (data.Count == 0) + throw new Exception("ไม่พบข้อมูลในระบบ"); + + var examName = data[0].ExamName; + return new + { + template = "rptPassExamList", + reportName = $"รายชื่อผู้สอบแข่งขันได้_{periodExam.Name} ครั้งที่ {periodExam.Round}/{periodExam.Year.Value.ToThaiYear()}", + data = new + { + examName = examName, + data = data + } + }; + } + public async Task GetsPaymentExamAsync(string examId) { var periodExam = await _context.PeriodExams.AsQueryable() From 081c00b869aee9dc11983679b2de4dfde1176924 Mon Sep 17 00:00:00 2001 From: harid Date: Tue, 12 May 2026 16:24:39 +0700 Subject: [PATCH 2/2] =?UTF-8?q?fix=20=E0=B9=80=E0=B8=A1=E0=B8=B7=E0=B9=88?= =?UTF-8?q?=E0=B8=AD=E0=B8=9E=E0=B9=89=E0=B8=99=E0=B8=81=E0=B8=B2=E0=B8=A3?= =?UTF-8?q?=E0=B8=AA=E0=B8=AD=E0=B8=9A=2015=20=E0=B8=A7=E0=B8=B1=E0=B8=99?= =?UTF-8?q?=20=E0=B9=84=E0=B8=A1=E0=B9=88=E0=B9=83=E0=B8=AB=E0=B9=89?= =?UTF-8?q?=E0=B8=84=E0=B8=A5=E0=B8=B4=E0=B8=81=E0=B8=94=E0=B8=B9=E0=B8=82?= =?UTF-8?q?=E0=B9=89=E0=B8=AD=E0=B8=A1=E0=B8=B9=E0=B8=A5=E0=B9=84=E0=B8=94?= =?UTF-8?q?=E0=B9=89=20#2485?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Response/CandidateStatusResponse.cs | 3 +++ Services/CandidateService.cs | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Response/CandidateStatusResponse.cs b/Response/CandidateStatusResponse.cs index e36d0a7..ac6b699 100644 --- a/Response/CandidateStatusResponse.cs +++ b/Response/CandidateStatusResponse.cs @@ -9,5 +9,8 @@ namespace BMA.EHR.Recurit.Exam.Service.Response public string? RejectDetail { get; set; } public bool? IsShowExamInfo { get; set; } + + public bool? IsShowResult { get; set; } + } } diff --git a/Services/CandidateService.cs b/Services/CandidateService.cs index fc1ba9f..64c57a6 100644 --- a/Services/CandidateService.cs +++ b/Services/CandidateService.cs @@ -1978,7 +1978,19 @@ namespace BMA.EHR.Recurit.Exam.Service.Services if (candidate == null) throw new Exception(GlobalMessages.CandidateNotFound); - return new CandidateStatusResponse { Status = candidate.Status, RejectDetail = candidate.RejectDetail, IsShowExamInfo = candidate.IsShowExamInfo }; + bool IsShowResult = true; + if (exam.AnnouncementDate != null) + { + var showResultEndDate = exam.AnnouncementDate.Value.Date.AddDays(15); + IsShowResult = DateTime.Now.Date <= showResultEndDate; + } + + return new CandidateStatusResponse { + Status = candidate.Status, + RejectDetail = candidate.RejectDetail, + IsShowExamInfo = candidate.IsShowExamInfo, + IsShowResult = IsShowResult, + }; } public async Task UserCheckCandidateService(string examId, string positionId, string status)