Compare commits
10 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f8effe7e4 | ||
|
|
081c00b869 | ||
|
|
f1fc324828 | ||
|
|
cba02a4f6e | ||
|
|
208ad63abf | ||
|
|
d2f21a9181 | ||
|
|
c4a6b6d1df | ||
|
|
16015cf3ef | ||
|
|
06b62df43a | ||
|
|
022b68b496 |
10 changed files with 3449 additions and 32 deletions
|
|
@ -1365,7 +1365,7 @@ namespace BMA.EHR.Recurit.Exam.Service.Controllers
|
|||
District = workSheet?.Cells[row, 54]?.GetValue<string>() ?? "",
|
||||
Amphur = workSheet?.Cells[row, 55]?.GetValue<string>() ?? "",
|
||||
Province = workSheet?.Cells[row, 56]?.GetValue<string>() ?? "",
|
||||
ZipCode = workSheet?.Cells[row, 57]?.GetValue<string>() ?? "",
|
||||
ZipCode = (workSheet?.Cells[row, 57]?.GetValue<string>() ?? "").Trim(),
|
||||
Telephone = workSheet?.Cells[row, 58]?.GetValue<string>() ?? "",
|
||||
Mobile = "",
|
||||
Address1 = $"{(workSheet?.Cells[row, 61]?.GetValue<string>() ?? "")} {(workSheet?.Cells[row, 62]?.GetValue<string>() ?? "")}",
|
||||
|
|
@ -1375,7 +1375,7 @@ namespace BMA.EHR.Recurit.Exam.Service.Controllers
|
|||
District1 = workSheet?.Cells[row, 66]?.GetValue<string>() ?? "",
|
||||
Amphur1 = workSheet?.Cells[row, 67]?.GetValue<string>() ?? "",
|
||||
Province1 = workSheet?.Cells[row, 68]?.GetValue<string>() ?? "",
|
||||
ZipCode1 = workSheet?.Cells[row, 69]?.GetValue<string>() ?? "",
|
||||
ZipCode1 = (workSheet?.Cells[row, 69]?.GetValue<string>() ?? "").Trim(),
|
||||
CreatedAt = DateTime.Now,
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
|
|
@ -1399,7 +1399,7 @@ namespace BMA.EHR.Recurit.Exam.Service.Controllers
|
|||
TermBranch = workSheet?.Cells[row, 113]?.GetValue<string>() ?? "",
|
||||
TellerId = workSheet?.Cells[row, 114]?.GetValue<string>() ?? "",
|
||||
CreditDebit = workSheet?.Cells[row, 115]?.GetValue<string>() ?? "",
|
||||
PaymentType = workSheet?.Cells[row, 116]?.GetValue<string>(),
|
||||
PaymentType = workSheet?.Cells[row, 116]?.GetValue<string>() ?? "",
|
||||
ChequeNo = workSheet?.Cells[row, 117]?.GetValue<string>() ?? "",
|
||||
Amount = (decimal)workSheet?.Cells[row, 118]?.GetValue<decimal>(),
|
||||
ChqueBankCode = workSheet?.Cells[row, 119]?.GetValue<string>() ?? "",
|
||||
|
|
@ -2187,8 +2187,8 @@ namespace BMA.EHR.Recurit.Exam.Service.Controllers
|
|||
.Where(x => x.ExamId == examId)
|
||||
.Join(_context.DisableScores.AsQueryable()
|
||||
.Include(x => x.ScoreImport),
|
||||
rc => new { /*rc.PeriodExam.Year,*/ rc.ExamId },
|
||||
sc => new { /*sc.ScoreImport.Year,*/ sc.ExamId },
|
||||
rc => new { PeriodExamId = rc.PeriodExam.Id, rc.ExamId },
|
||||
sc => new { PeriodExamId = sc.ScoreImport.PeriodExamId, sc.ExamId },
|
||||
(p, sr) => new
|
||||
{
|
||||
ExamID = p.ExamId,
|
||||
|
|
|
|||
|
|
@ -749,6 +749,56 @@ namespace BMA.EHR.Recurit.Exam.Service.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดาวน์โหลดรายชื่อผู้มีสิทธิ์สอบ
|
||||
/// </summary>
|
||||
/// <param name="examId">รหัสรอบสมัคร</param>
|
||||
/// <returns></returns>
|
||||
/// <response code="200">เมื่อทำการอ่านโหลดผู้สมัครสอบสำเร็จ</response>
|
||||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpGet("download/candidate-exam/{examId:length(36)}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public async Task<ActionResult<ResponseObject>> DownloadCandidateExamAsync(string examId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _periodExamService.DownloadCandidateExamAsync(examId);
|
||||
return Success(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดาวน์โหลดรายชื่อผู้สอบคัดเลือกได้
|
||||
/// </summary>
|
||||
/// <param name="examId">รหัสรอบสมัคร</param>
|
||||
/// <returns></returns>
|
||||
/// <response code="200">เมื่อทำการอ่านโหลดผู้สมัครสอบสำเร็จ</response>
|
||||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpGet("download/pass-exam/{examId:length(36)}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public async Task<ActionResult<ResponseObject>> DownloadPassExamAsync(string examId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _periodExamService.DownloadPassExamAsync(examId);
|
||||
return Success(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Error(ex, "เกิดข้อผิดพลาดในการแสดงรายงาน");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// โหลดผู้สมัครสอบ
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Nest;
|
||||
using System.Diagnostics;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
|
|
@ -29,6 +30,49 @@ namespace BMA.EHR.Recurit.Exam.Service.Core
|
|||
SystemName = "recruiting";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// แกะ JWT token เพื่อดึง claims ต่างๆ
|
||||
/// </summary>
|
||||
private JwtSecurityToken? ParseToken(string token)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var jwtToken = tokenHandler.ReadJwtToken(token.Replace("Bearer ", ""));
|
||||
return jwtToken;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดึงค่า claim จาก token โดยลองชื่อหลายแบบ
|
||||
/// </summary>
|
||||
private string? GetClaimValue(JwtSecurityToken? token, params string[] claimNames)
|
||||
{
|
||||
if (token == null) return null;
|
||||
|
||||
foreach (var name in claimNames)
|
||||
{
|
||||
var claim = token.Claims.FirstOrDefault(c => c.Type == name);
|
||||
if (claim != null)
|
||||
return claim.Value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดึงค่า Guid claim จาก token
|
||||
/// </summary>
|
||||
private Guid? GetGuidClaim(JwtSecurityToken? token, params string[] claimNames)
|
||||
{
|
||||
var value = GetClaimValue(token, claimNames);
|
||||
if (Guid.TryParse(value, out var guid))
|
||||
return guid;
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
|
|
@ -92,28 +136,22 @@ namespace BMA.EHR.Recurit.Exam.Service.Core
|
|||
// เปลี่ยน stream ของ Response เพื่อให้สามารถอ่านได้
|
||||
context.Response.Body = memoryStream;
|
||||
|
||||
|
||||
|
||||
// Extract all required data from JWT token claims
|
||||
var keycloakId = context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? Guid.Empty.ToString("D");
|
||||
var tokenHeader = context.Request.Headers["Authorization"].ToString();
|
||||
|
||||
var prefix = context.User?.FindFirst("prefix")?.Value;
|
||||
var firstName = context.User?.FindFirst("given_name")?.Value;
|
||||
var lastName = context.User?.FindFirst("family_name")?.Value;
|
||||
var preferredUsername = context.User?.FindFirst("preferred_username")?.Value;
|
||||
// แกะ JWT token เพื่อดึง claims ต่างๆ
|
||||
var jwtToken = ParseToken(tokenHeader);
|
||||
|
||||
var orgRootDnaId = context.User?.FindFirst("orgRootDnaId")?.Value;
|
||||
var orgChild1DnaId = context.User?.FindFirst("orgChild1DnaId")?.Value;
|
||||
var orgChild2DnaId = context.User?.FindFirst("orgChild2DnaId")?.Value;
|
||||
var orgChild3DnaId = context.User?.FindFirst("orgChild3DnaId")?.Value;
|
||||
var orgChild4DnaId = context.User?.FindFirst("orgChild4DnaId")?.Value;
|
||||
|
||||
// Parse Guid values safely
|
||||
Guid? rootDnaId = Guid.TryParse(orgRootDnaId, out var rid) ? rid : null;
|
||||
Guid? child1DnaId = Guid.TryParse(orgChild1DnaId, out var c1) ? c1 : null;
|
||||
Guid? child2DnaId = Guid.TryParse(orgChild2DnaId, out var c2) ? c2 : null;
|
||||
Guid? child3DnaId = Guid.TryParse(orgChild3DnaId, out var c3) ? c3 : null;
|
||||
Guid? child4DnaId = Guid.TryParse(orgChild4DnaId, out var c4) ? c4 : null;
|
||||
// ดึงข้อมูลจาก claims โดยลองชื่อหลายแบบ (camelCase, snake_case, ฯลฯ)
|
||||
var prefix = GetClaimValue(jwtToken, "prefix", "Prefix", "PREFIX");
|
||||
var firstName = GetClaimValue(jwtToken, "given_name", "firstname", "firstName", "FirstName", "FIRSTNAME");
|
||||
var lastName = GetClaimValue(jwtToken, "family_name", "lastname", "lastName", "LastName", "LASTNAME");
|
||||
var preferredUsername = GetClaimValue(jwtToken, "preferred_username", "preferred_username", "PreferredUsername");
|
||||
var orgRootDnaId = GetGuidClaim(jwtToken, "orgRootDnaId", "org_root_dna_id", "OrgRootDnaId", "rootDnaId");
|
||||
var orgChild1DnaId = GetGuidClaim(jwtToken, "orgChild1DnaId", "org_child1_dna", "OrgChild1Dna", "child1DnaId");
|
||||
var orgChild2DnaId = GetGuidClaim(jwtToken, "orgChild2DnaId", "org_child2_dna", "OrgChild2Dna", "child2DnaId");
|
||||
var orgChild3DnaId = GetGuidClaim(jwtToken, "orgChild3DnaId", "org_child3_dna", "OrgChild3Dna", "child3DnaId");
|
||||
var orgChild4DnaId = GetGuidClaim(jwtToken, "orgChild4DnaId", "org_child4_dna", "OrgChild4Dna", "child4DnaId");
|
||||
|
||||
await _next(context); // ดำเนินการต่อไปยัง Middleware อื่น ๆ
|
||||
|
||||
|
|
@ -200,7 +238,7 @@ namespace BMA.EHR.Recurit.Exam.Service.Core
|
|||
{
|
||||
logType = logType,
|
||||
ip = context.Connection.RemoteIpAddress?.ToString(),
|
||||
rootId = rootDnaId,
|
||||
rootId = orgRootDnaId?.ToString("D"),
|
||||
systemName = SystemName,
|
||||
startTimeStamp = startTime.ToString("o"),
|
||||
endTimeStamp = endTime.ToString("o"),
|
||||
|
|
|
|||
|
|
@ -1296,13 +1296,13 @@ namespace BMA.EHR.Recurit.Exam.Service.Data.Migrations
|
|||
|
||||
b.Property<string>("ZipCode")
|
||||
.IsRequired()
|
||||
.HasMaxLength(5)
|
||||
.HasColumnType("varchar(5)");
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("varchar(10)");
|
||||
|
||||
b.Property<string>("ZipCode1")
|
||||
.IsRequired()
|
||||
.HasMaxLength(5)
|
||||
.HasColumnType("varchar(5)");
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("varchar(10)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
|
|
|
|||
3153
Migrations/20260324084215_update_DisableAddress.Designer.cs
generated
Normal file
3153
Migrations/20260324084215_update_DisableAddress.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
66
Migrations/20260324084215_update_DisableAddress.cs
Normal file
66
Migrations/20260324084215_update_DisableAddress.cs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BMA.EHR.Recurit.Exam.Service.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class update_DisableAddress : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ZipCode1",
|
||||
table: "DisableAddresses",
|
||||
type: "varchar(10)",
|
||||
maxLength: 10,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(5)",
|
||||
oldMaxLength: 5)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ZipCode",
|
||||
table: "DisableAddresses",
|
||||
type: "varchar(10)",
|
||||
maxLength: 10,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(5)",
|
||||
oldMaxLength: 5)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ZipCode1",
|
||||
table: "DisableAddresses",
|
||||
type: "varchar(5)",
|
||||
maxLength: 5,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(10)",
|
||||
oldMaxLength: 10)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ZipCode",
|
||||
table: "DisableAddresses",
|
||||
type: "varchar(5)",
|
||||
maxLength: 5,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(10)",
|
||||
oldMaxLength: 10)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ namespace BMA.EHR.Recurit.Exam.Service.Models.Disables
|
|||
[MaxLength(200)]
|
||||
public string Province { get; set; }//
|
||||
|
||||
[MaxLength(5)]
|
||||
[MaxLength(10)]
|
||||
public string ZipCode { get; set; }//
|
||||
|
||||
[MaxLength(200)]
|
||||
|
|
@ -55,7 +55,7 @@ namespace BMA.EHR.Recurit.Exam.Service.Models.Disables
|
|||
[MaxLength(200)]
|
||||
public string Province1 { get; set; }//
|
||||
|
||||
[MaxLength(5)]
|
||||
[MaxLength(10)]
|
||||
public string ZipCode1 { get; set; }//
|
||||
|
||||
public Disable Disable { get; set; }
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1625,6 +1625,101 @@ namespace BMA.EHR.Recurit.Exam.Service.Services
|
|||
};
|
||||
}
|
||||
|
||||
public async Task<dynamic> 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<dynamic> 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<PeriodExam> GetsPaymentExamAsync(string examId)
|
||||
{
|
||||
var periodExam = await _context.PeriodExams.AsQueryable()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue