From efb22a9d73db2180e710d031b5ce6dc3f7578f0e Mon Sep 17 00:00:00 2001 From: harid Date: Tue, 18 Nov 2025 17:29:49 +0700 Subject: [PATCH] =?UTF-8?q?=E0=B8=9B=E0=B8=A3=E0=B8=B1=E0=B8=9A=E0=B8=A3?= =?UTF-8?q?=E0=B8=B0=E0=B8=9A=E0=B8=9A=E0=B8=AA=E0=B8=A3=E0=B8=A3=E0=B8=AB?= =?UTF-8?q?=E0=B8=B2=E0=B8=AA=E0=B8=AD=E0=B8=9A=E0=B8=84=E0=B8=B1=E0=B8=94?= =?UTF-8?q?=E0=B9=80=E0=B8=A5=E0=B8=B7=E0=B8=AD=E0=B8=81=20(3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Controllers/CandidateController.cs | 27 ++++ Request/RequestStatusExam.cs | 1 + Response/CandidateResponseItem.cs | 2 +- Services/CandidateService.cs | 213 ++++++++++++++++++++--------- Services/PeriodExamService.cs | 1 + 5 files changed, 182 insertions(+), 62 deletions(-) diff --git a/Controllers/CandidateController.cs b/Controllers/CandidateController.cs index a3c7fbb..65017c5 100644 --- a/Controllers/CandidateController.cs +++ b/Controllers/CandidateController.cs @@ -847,6 +847,33 @@ namespace BMA.EHR.Recurit.Exam.Service.Controllers } } + /// + /// ผู้สมัครทำการสมัครสอบ + /// + /// รหัสรอบสมัคร + /// Id ตำแหน่งสมัครสอบ + /// + /// เมื่อทำการผู้สมัครทำการสมัครสอบ สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost("register-confirm/{examId:length(36)}/{positionId:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> RegisterCheckSeatService(string examId, string positionId) + { + try + { + await _candidateService.UserConfirmCheckSeatService(examId, positionId); + + return Success(); + } + catch (Exception ex) + { + return Error(ex); + } + } + /// /// เจ้าหน้าที่ย้อนสถานะเป็นตรวจสอบข้อมูล /// diff --git a/Request/RequestStatusExam.cs b/Request/RequestStatusExam.cs index ed4af29..25dc2e8 100644 --- a/Request/RequestStatusExam.cs +++ b/Request/RequestStatusExam.cs @@ -10,5 +10,6 @@ namespace BMA.EHR.Recurit.Exam.Service.Request public int? Year { get; set; } public bool Status { get; set; } public bool SetSeat { get; set; } + public float? Fee { get; set;} } } diff --git a/Response/CandidateResponseItem.cs b/Response/CandidateResponseItem.cs index 93bb705..bb14cd9 100644 --- a/Response/CandidateResponseItem.cs +++ b/Response/CandidateResponseItem.cs @@ -5,7 +5,7 @@ namespace BMA.EHR.Recurit.Exam.Service.Response { // public Models.Prefix? Prefix { get; set; } public string? PrefixId { get; set; } - public string? Prefix { get; set; } + public string? PrefixName { get; set; } public string? FirstName { get; set; } = string.Empty; public string? LastName { get; set; } = string.Empty; public string? Nationality { get; set; } = string.Empty; diff --git a/Services/CandidateService.cs b/Services/CandidateService.cs index 0e1a46f..229d2e4 100644 --- a/Services/CandidateService.cs +++ b/Services/CandidateService.cs @@ -741,49 +741,49 @@ namespace BMA.EHR.Recurit.Exam.Service.Services if (candidate == null) throw new Exception(GlobalMessages.ExamNotFound); - if (updated.PrefixId != null) - { - var prefix = await _contextOrg.prefixe.AsQueryable() - .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.PrefixId)); + //if (updated.PrefixId != null) + //{ + // var prefix = await _contextOrg.prefixe.AsQueryable() + // .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.PrefixId)); - if (prefix == null) - throw new Exception(GlobalMessages.PrefixNotFound); + // if (prefix == null) + // throw new Exception(GlobalMessages.PrefixNotFound); - candidate.PrefixId = prefix.Id; - candidate.PrefixName = prefix.name; - } - if (!string.IsNullOrEmpty(updated.Prefix)) + // candidate.PrefixId = prefix.Id; + // candidate.PrefixName = prefix.name; + //} + if (!string.IsNullOrEmpty(updated.PrefixName)) { - candidate.PrefixName = updated.Prefix; + candidate.PrefixName = updated.PrefixName; } - if (updated.ContactPrefixId != null) - { - var prefix = await _contextOrg.prefixe.AsQueryable() - .FirstOrDefaultAsync(x => x.Id == updated.ContactPrefixId); + //if (updated.ContactPrefixId != null) + //{ + // var prefix = await _contextOrg.prefixe.AsQueryable() + // .FirstOrDefaultAsync(x => x.Id == updated.ContactPrefixId); - if (prefix == null) - throw new Exception(GlobalMessages.PrefixNotFound); + // if (prefix == null) + // throw new Exception(GlobalMessages.PrefixNotFound); - candidate.ContactPrefixId = prefix.Id; - candidate.ContactPrefixName = prefix.name; - } + // candidate.ContactPrefixId = prefix.Id; + // candidate.ContactPrefixName = prefix.name; + //} if (!string.IsNullOrEmpty(updated.ContactPrefixName)) { candidate.ContactPrefixName = updated.ContactPrefixName; } - if (updated.ReligionId != null) - { - var religion = await _contextOrg.religion.AsQueryable() - .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.ReligionId)); + //if (updated.ReligionId != null) + //{ + // var religion = await _contextOrg.religion.AsQueryable() + // .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.ReligionId)); - if (religion == null) - throw new Exception(GlobalMessages.ReligionNotFound); + // if (religion == null) + // throw new Exception(GlobalMessages.ReligionNotFound); - candidate.ReligionId = religion.Id; - candidate.ReligionName = religion.name; - } + // candidate.ReligionId = religion.Id; + // candidate.ReligionName = religion.name; + //} if (!string.IsNullOrEmpty(updated.ReligionName)) { candidate.ReligionName = updated.ReligionName; @@ -977,49 +977,49 @@ namespace BMA.EHR.Recurit.Exam.Service.Services if (candidate == null) throw new Exception(GlobalMessages.ExamNotFound); - if (updated.PrefixId != null) - { - var prefix = await _contextOrg.prefixe.AsQueryable() - .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.PrefixId)); + //if (updated.PrefixId != null) + //{ + // var prefix = await _contextOrg.prefixe.AsQueryable() + // .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.PrefixId)); - if (prefix == null) - throw new Exception(GlobalMessages.PrefixNotFound); + // if (prefix == null) + // throw new Exception(GlobalMessages.PrefixNotFound); - candidate.PrefixId = prefix.Id; - candidate.PrefixName = prefix.name; - } - if (!string.IsNullOrEmpty(updated.Prefix)) + // candidate.PrefixId = prefix.Id; + // candidate.PrefixName = prefix.name; + //} + if (!string.IsNullOrEmpty(updated.PrefixName)) { - candidate.PrefixName = updated.Prefix; + candidate.PrefixName = updated.PrefixName; } - if (updated.ContactPrefixId != null) - { - var prefix = await _contextOrg.prefixe.AsQueryable() - .FirstOrDefaultAsync(x => x.Id == updated.ContactPrefixId); + //if (updated.ContactPrefixId != null) + //{ + // var prefix = await _contextOrg.prefixe.AsQueryable() + // .FirstOrDefaultAsync(x => x.Id == updated.ContactPrefixId); - if (prefix == null) - throw new Exception(GlobalMessages.PrefixNotFound); + // if (prefix == null) + // throw new Exception(GlobalMessages.PrefixNotFound); - candidate.ContactPrefixId = prefix.Id; - candidate.ContactPrefixName = prefix.name; - } + // candidate.ContactPrefixId = prefix.Id; + // candidate.ContactPrefixName = prefix.name; + //} if (!string.IsNullOrEmpty(updated.ContactPrefixName)) { candidate.ContactPrefixName = updated.ContactPrefixName; } - if (updated.ReligionId != null) - { - var religion = await _contextOrg.religion.AsQueryable() - .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.ReligionId)); + //if (updated.ReligionId != null) + //{ + // var religion = await _contextOrg.religion.AsQueryable() + // .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.ReligionId)); - if (religion == null) - throw new Exception(GlobalMessages.ReligionNotFound); + // if (religion == null) + // throw new Exception(GlobalMessages.ReligionNotFound); - candidate.ReligionId = religion.Id; - candidate.ReligionName = religion.name; - } + // candidate.ReligionId = religion.Id; + // candidate.ReligionName = religion.name; + //} if (!string.IsNullOrEmpty(updated.ReligionName)) { candidate.ReligionName = updated.ReligionName; @@ -2048,6 +2048,99 @@ namespace BMA.EHR.Recurit.Exam.Service.Services await _context.SaveChangesAsync(); } + public async Task UserConfirmCheckSeatService(string examId, string positionId) + { + var examGuid = Guid.Parse(examId); + var positionGuid = Guid.Parse(positionId); + + // 1) โหลดข้อมูลรอบสอบ + var exam = await _context.PeriodExams + .Where(p => !p.CheckDisability && p.Id == examGuid) + .Include(x => x.PositionExam) + .FirstOrDefaultAsync(); + + if (exam == null) + throw new Exception(GlobalMessages.ExamNotFound); + + // 2) โหลด Candidate เดิม (ดึงครั้งเดียวพอ) + var candidate = await _context.Candidates + .Include(x => x.PositionExam) + .Include(x => x.PeriodExam) + .FirstOrDefaultAsync(x => x.PeriodExam.Id == exam.Id && x.UserId == UserId); + + if (positionGuid != Guid.Empty) + { + // 3) ตรวจสอบตำแหน่ง + var position = await _context.PositionExams + .FirstOrDefaultAsync(x => x.Id == positionGuid && x.PeriodExam.Id == exam.Id); + + if (position == null) + throw new Exception(GlobalMessages.PositionExamNotFound); + + // 4) ลบข้อมูลตำแหน่งอื่นในรอบนี้ + var deleteOther = await _context.Candidates + .Where(x => x.PeriodExam.Id == exam.Id + && x.UserId == UserId + && x.PositionExam.Id != position.Id) + .ToListAsync(); + + _context.Candidates.RemoveRange(deleteOther); + + // 5) โหลด candidate ใหม่เฉพาะตำแหน่งที่เลือก + candidate = await _context.Candidates + .FirstOrDefaultAsync(x => x.PeriodExam.Id == exam.Id + && x.UserId == UserId + && x.PositionExam.Id == position.Id); + } + + if (candidate == null) + throw new Exception(GlobalMessages.CandidateNotFound); + + // ต้องอยู่ในสถานะ CHECKREGISTER เท่านั้น + if (candidate.Status.Trim().ToUpper() != "CHECKREGISTER") + throw new Exception(GlobalMessages.CannotInsertToDatabase); + + // 6) ไม่เสียค่าสมัคร → ต้องออกเลขประจำตัวสอบด้วย + if (candidate.PeriodExam.Fee == 0) + { + candidate.Status = "checkSeat"; + + // ❗ออกเลขประจำตัวสอบ (กันซ้ำ 100%) + if (string.IsNullOrEmpty(candidate.ExamIdenNumber)) + { + using var transaction = await _context.Database.BeginTransactionAsync(); + + // อ่านเลขล่าสุด (Lock ภายใน Transaction) + var lastNumber = await _context.Candidates + .Where(x => x.PeriodExam.Id == exam.Id) + .OrderByDescending(x => x.ExamIdenNumber) + .Select(x => x.ExamIdenNumber) + .FirstOrDefaultAsync(); + + // Convert → หาเลขลำดับต่อไป + int next = 1; + if (!string.IsNullOrEmpty(lastNumber)) + { + // ถ้าเลขมี prefix เช่น P01xxxx → ต้องเอาเฉพาะตัวเลข + string numeric = new string(lastNumber.Where(char.IsDigit).ToArray()); + next = int.Parse(numeric) + 1; + } + + // สร้างเลขตามตำแหน่งสอบ + candidate.ExamIdenNumber = + candidate.PositionExam == null + ? next.ToString("D5") + : candidate.PositionExam.Code + next.ToString("D5"); + + await _context.SaveChangesAsync(); + await transaction.CommitAsync(); + } + } + + await _context.SaveChangesAsync(); + } + + public async Task AdminCheckCandidateService(string candidateId, string status, RequestApprove item) { var candidate = await _context.Candidates.AsQueryable() @@ -2180,7 +2273,6 @@ namespace BMA.EHR.Recurit.Exam.Service.Services } public async Task AdminCheckShowExamInfoService(string[] candidateId) { - //var _num = 0; foreach (var _candidateId in candidateId) { var candidate = await _context.Candidates.AsQueryable() @@ -2190,7 +2282,7 @@ namespace BMA.EHR.Recurit.Exam.Service.Services if (candidate == null) throw new Exception(GlobalMessages.CandidateNotFound); - if (candidate.Status.Trim().ToUpper() != "CHECKREGISTER") + if (candidate.Status.Trim().ToUpper() != "CHECKSEAT") continue; if (candidate.PeriodExam == null) @@ -2208,7 +2300,6 @@ namespace BMA.EHR.Recurit.Exam.Service.Services throw new Exception(GlobalMessages.ExamNotFound); candidate.IsShowExamInfo = true; - //++_num; } await _context.SaveChangesAsync(); diff --git a/Services/PeriodExamService.cs b/Services/PeriodExamService.cs index 6c4db2a..32b79f7 100644 --- a/Services/PeriodExamService.cs +++ b/Services/PeriodExamService.cs @@ -291,6 +291,7 @@ namespace BMA.EHR.Recurit.Exam.Service.Services Year = periodExam.Year, Status = periodExam.PaymentEndDate == null ? true : DateTime.Now > periodExam.PaymentEndDate, SetSeat = periodExam.SetSeat, + Fee = periodExam.Fee, }; }