diff --git a/Controllers/ExamReportController.cs b/Controllers/ExamReportController.cs
index 91fde03..aee878d 100644
--- a/Controllers/ExamReportController.cs
+++ b/Controllers/ExamReportController.cs
@@ -666,7 +666,7 @@ namespace BMA.EHR.Report.Service.Controllers
}
///
- /// รายชื่อผู้มีสิทธิ์สอบ แสดงรายชื่อแบ่งตามตำแหน่ง (สอบคัดเลือกผู้พิการ)
+ /// รายชื่อผู้มีสิทธิ์สอบ แสดงรายชื่อแบ่งตามตำแหน่ง (สอบคัดเลือกอื่นๆ)
///
/// รหัสรอบการสอบ
///
@@ -796,7 +796,7 @@ namespace BMA.EHR.Report.Service.Controllers
}
///
- /// รายชื่อผู้สอบแข่งขันได้ แสดงรายชื่อแบ่งตามตำแหน่ง (สอบคัดเลือกผู้พิการ)
+ /// รายชื่อผู้สอบคัดเลือกได้ แสดงรายชื่อแบ่งตามตำแหน่ง (สอบคัดเลือกอื่นๆ)
///
/// รหัสรอบการสอบ
///
@@ -871,7 +871,7 @@ namespace BMA.EHR.Report.Service.Controllers
document.SetFont(font).SetFontSize(16);
document.SetMargins(30, 15, 20, 15);
- var title = new Paragraph($"รายชื่อผู้สอบแข่งขันได้\n{examName}")
+ var title = new Paragraph($"รายชื่อผู้สอบคัดเลือกได้\n{examName}")
.SetBold()
.SetMultipliedLeading(1.0f)
.SetTextAlignment(TextAlignment.CENTER);
@@ -924,6 +924,282 @@ namespace BMA.EHR.Report.Service.Controllers
}
}
+ ///
+ /// รายชื่อผู้มีสิทธิ์สอบ แสดงรายชื่อแบ่งตามตำแหน่ง (สอบคัดเลือก)
+ ///
+ /// รหัสรอบการสอบ
+ ///
+ /// เมื่อแสดงรายงานสำเร็จ
+ /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง
+ /// ไม่ได้ Login เข้าระบบ
+ /// เมื่อเกิดข้อผิดพลาดในการทำงาน
+ [HttpGet("candidate/candidate-new/{id:length(36)}")]
+ [AllowAnonymous]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(StatusCodes.Status500InternalServerError)]
+ public async Task> GetListCandidateNewReportAsync(Guid id)
+ {
+ try
+ {
+ var periodExam = await _context.PeriodExams.AsQueryable()
+ .Where(x => x.CheckDisability == false)
+ .FirstOrDefaultAsync(x => x.Id == id);
+
+ if (periodExam == null)
+ return Error("ไม่พบข้อมูลการรับสมัครสอบ");
+
+ var data = await _context.Candidates.AsQueryable()
+ .Include(x => x.PeriodExam)
+ .ThenInclude(x => x.PositionExam)
+ .Where(x => x.PeriodExam!.Id == periodExam.Id)
+ .OrderBy(x => x.ExamIdenNumber)
+ .ThenBy(x => x.PositionExam!.CreatedAt)
+ .Select(p => new
+ {
+ FullName = $"{p.PrefixName ?? ""}{p.FirstName ?? ""} {p.LastName ?? ""}",
+ PositionName = p.PositionExam!.PositionName,
+ Remark = !string.IsNullOrEmpty(p.ExamReason) ? p.ExamReason.ToThaiNumber() : "",
+ ExamId = !string.IsNullOrEmpty(p.ExamIdenNumber) ? p.ExamIdenNumber.ToThaiNumber() : "",
+ ExamName =
+ ($"{p.PeriodExam!.Name} ครั้งที่ {p.PeriodExam.Round}/{p.PeriodExam.Year.Value.ToThaiYear()}").ToThaiNumber(),
+ }).ToListAsync();
+
+ if (data.Count == 0)
+ return Error("ไม่พบข้อมูลในระบบ");
+
+ var examName = data.First().ExamName;
+
+ var groupData = data
+ .GroupBy(x => x.PositionName)
+ .Select(g => new
+ {
+ PositionName = $"ตำแหน่ง {g.Key}",
+ Total = $"จำนวน {g.Count().ToString().ToThaiNumber()} ราย",
+ Persons = g.Select((x, index) => new
+ {
+ No = (index + 1).ToString().ToThaiNumber(),
+ ExamId = x.ExamId,
+ FullName = x.FullName,
+ Remark = x.Remark
+ }).ToList()
+ })
+ .ToList();
+
+ // เตรียม MemoryStream
+ using (var stream = new MemoryStream())
+ {
+ // สร้าง PDF document
+ using (var writer = new PdfWriter(stream))
+ using (var pdf = new PdfDocument(writer))
+ using (var document = new Document(pdf, iText.Kernel.Geom.PageSize.A4))
+ {
+ // กำหนดฟ้อนต์ TH-Sarabun
+ var fontPath = System.IO.Path.Combine(Environment.CurrentDirectory, "Fonts", "THSarabun.ttf");
+ var font = PdfFontFactory.CreateFont(fontPath, "Identity-H");
+ document.SetFont(font).SetFontSize(16);
+
+ // ตั้งค่าระยะขอบ top, right, bottom, left
+ document.SetMargins(30, 15, 20, 15);
+
+ // Title
+ var title = new Paragraph($"รายชื่อผู้มีสิทธิ์สอบ\n{examName ?? ""}")
+ .SetBold()
+ .SetMultipliedLeading(1.0f)
+ .SetTextAlignment(TextAlignment.CENTER);
+
+ document.Add(title);
+ float[] columnWidths = { 10f, 20f, 45f, 25f };
+ // Loop Groups
+ foreach (var group in groupData)
+ {
+ // Group Header (ตำแหน่ง)
+ Paragraph positionHeader = new Paragraph($"{group.PositionName} {group.Total}")
+ .SetBold()
+ .SetMultipliedLeading(1.0f)
+ .SetTextAlignment(TextAlignment.CENTER)
+ .SetMarginBottom(5);
+
+ document.Add(positionHeader);
+
+ var table = new iText.Layout.Element.Table(UnitValue.CreatePercentArray(columnWidths)).UseAllAvailableWidth();
+
+ // Table Header
+ string[] headers = { "ลำดับที่", "เลขประจำตัวสอบ", "ชื่อ-สกุล", "หมายเหตุ" };
+ foreach (var h in headers)
+ {
+ table.AddHeaderCell(new Cell()
+ .Add(new Paragraph(h).SetMultipliedLeading(1.0f))
+ .SetBold()
+ .SetTextAlignment(TextAlignment.CENTER));
+ }
+
+ // Table Details
+ foreach (var x in group.Persons)
+ {
+ table.AddCell(new Cell().Add(new Paragraph(x.No ?? "").SetMultipliedLeading(1.0f))
+ .SetTextAlignment(TextAlignment.CENTER));
+
+ table.AddCell(new Cell().Add(new Paragraph(x.ExamId ?? "").SetMultipliedLeading(1.0f))
+ .SetTextAlignment(TextAlignment.CENTER));
+
+ table.AddCell(new Cell().Add(new Paragraph(x.FullName ?? "").SetMultipliedLeading(1.0f))
+ .SetTextAlignment(TextAlignment.LEFT));
+
+ table.AddCell(new Cell().Add(new Paragraph(x.Remark ?? "").SetMultipliedLeading(1.0f))
+ .SetTextAlignment(TextAlignment.CENTER));
+ }
+ document.Add(table);
+ document.Add(new Paragraph("").SetMarginBottom(15));
+ }
+ }
+ return File(stream.ToArray(), "application/pdf", $"รายชื่อผู้มีสิทธิ์สอบ_{examName}");
+ }
+ }
+ catch (Exception ex)
+ {
+ return Error(ex);
+ }
+ }
+
+ ///
+ /// รายชื่อผู้สอบคัดเลือกได้ แสดงรายชื่อแบ่งตามตำแหน่ง (สอบคัดเลือก)
+ ///
+ /// รหัสรอบการสอบ
+ ///
+ /// เมื่อแสดงรายงานสำเร็จ
+ /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง
+ /// ไม่ได้ Login เข้าระบบ
+ /// เมื่อเกิดข้อผิดพลาดในการทำงาน
+ [HttpGet("candidate/pass-new/{id:length(36)}")]
+ [AllowAnonymous]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(StatusCodes.Status500InternalServerError)]
+ public async Task> GetCandidatePassExamListNewReportAsync(Guid id)
+ {
+ try
+ {
+ var periodExam = await _context.PeriodExams.AsQueryable()
+ .Where(x => x.CheckDisability == false)
+ .FirstOrDefaultAsync(x => x.Id == id);
+
+ if (periodExam == null)
+ return Error("ไม่พบข้อมูลการรับสมัครสอบ");
+
+ var candidates = await _context.Candidates.AsQueryable()
+ .Include(x => x.PeriodExam)
+ .ThenInclude(x => x.PositionExam)
+ .Where(x => x.PeriodExam!.Id == periodExam.Id)
+ .Where(x => x.Status != "register")
+ .OrderBy(x => x.PositionExam!.CreatedAt)
+ .ToListAsync();
+
+ var data = candidates.Select((p, idx) => new
+ {
+ PositionName = p.PositionExam!.PositionName,
+ FullName = $"{p.PrefixName ?? ""}{p.FirstName ?? ""} {p.LastName ?? ""}".Trim(),
+ ExamResult = p.Pass,
+ ExamName = $"{p.PeriodExam!.Name} ครั้งที่ {p.PeriodExam.Round}/{p.PeriodExam!.Year.Value.ToThaiYear()}".ToThaiNumber(),
+ Number = string.IsNullOrEmpty(p.Number) ? (idx + 1) : Convert.ToInt32(p.Number),
+ SumScore = (Convert.ToInt32(p.PointB ?? "0") + Convert.ToInt32(p.PointC ?? "0")) .ToString().ToThaiNumber(),
+ SeatNumber = string.IsNullOrEmpty(p.SeatNumber) ? "" : p.SeatNumber.ToThaiNumber(),
+ })
+ .OrderBy(x => x.Number)
+ .Where(x => x.ExamResult?.Trim() == "ได้")
+ .ToList();
+
+ if (data.Count == 0)
+ return Error("ไม่พบข้อมูลในระบบ");
+
+ var examName = data.First().ExamName;
+
+ // Group by PositionName
+ var groupData = data
+ .GroupBy(g => g.PositionName)
+ .Select(g => new
+ {
+ PositionName = $"ตำแหน่ง {g.Key}",
+ Total = $"จำนวน {g.Count().ToString().ToThaiNumber()} ราย",
+ Persons = g.Select((x) => new
+ {
+ Number = x.Number > 0 ? x.Number.ToString().ToThaiNumber() : "",
+ FullName = x.FullName,
+ SumScore = x.SumScore,
+ SeatNumber = x.SeatNumber
+ }).ToList()
+ })
+ .ToList();
+
+ using (var stream = new MemoryStream())
+ {
+ using (var writer = new PdfWriter(stream))
+ using (var pdf = new PdfDocument(writer))
+ using (var document = new Document(pdf, iText.Kernel.Geom.PageSize.A4))
+ {
+ var fontPath = System.IO.Path.Combine(Environment.CurrentDirectory, "Fonts", "THSarabun.ttf");
+ var font = PdfFontFactory.CreateFont(fontPath, "Identity-H");
+
+ document.SetFont(font).SetFontSize(16);
+ document.SetMargins(30, 15, 20, 15);
+
+ var title = new Paragraph($"รายชื่อผู้สอบคัดเลือกได้\n{examName}")
+ .SetBold()
+ .SetMultipliedLeading(1.0f)
+ .SetTextAlignment(TextAlignment.CENTER);
+
+ document.Add(title);
+ // float[] columnWidths = { 10f, 20f, 45f, 25f };
+ float[] columnWidths = { 10f, 25f, 25f, 25f };
+ foreach (var g in groupData)
+ {
+ // Header per group
+ Paragraph positionHeader = new Paragraph($"{g.PositionName} {g.Total}")
+ .SetBold()
+ .SetMultipliedLeading(1.0f)
+ .SetTextAlignment(TextAlignment.CENTER)
+ .SetMarginBottom(5);
+
+
+ document.Add(positionHeader);
+
+ var table = new iText.Layout.Element.Table(UnitValue.CreatePercentArray(columnWidths)).UseAllAvailableWidth();
+
+ string[] headers = { "ลำดับที่", "สนามสอบ", "ชื่อ - นามสกุล", "คะแนนสอบ" };
+ foreach (var h in headers)
+ {
+ table.AddHeaderCell(new Cell().Add(new Paragraph(h).SetMultipliedLeading(1.0f))
+ .SetTextAlignment(TextAlignment.CENTER)
+ .SetBold());
+ }
+
+ foreach (var p in g.Persons) //SeatNumber
+ {
+ table.AddCell(new Cell().Add(new Paragraph(p.Number ?? "").SetMultipliedLeading(1.0f))
+ .SetTextAlignment(TextAlignment.CENTER));
+ table.AddCell(new Cell().Add(new Paragraph(p.SeatNumber).SetMultipliedLeading(1.0f))
+ .SetTextAlignment(TextAlignment.LEFT));
+ table.AddCell(new Cell().Add(new Paragraph(p.FullName ?? "").SetMultipliedLeading(1.0f))
+ .SetTextAlignment(TextAlignment.LEFT));
+ table.AddCell(new Cell().Add(new Paragraph(p.SumScore ?? "").SetMultipliedLeading(1.0f))
+ .SetTextAlignment(TextAlignment.CENTER));
+ }
+
+ document.Add(table);
+ document.Add(new Paragraph("").SetMarginBottom(15));
+ }
+ }
+ return File(stream.ToArray(), "application/pdf", $"รายชื่อผู้สอบแข่งขันได้_{examName}");
+ }
+ }
+ catch (Exception ex)
+ {
+ return Error(ex, "เกิดข้อผิดพลาดในการแสดงรายงาน");
+ }
+ }
+
#endregion
}
}