Compare commits

...

4 commits
v1.0.25 ... dev

Author SHA1 Message Date
harid
67253337a9 fix แสดงจำนวนผู้ที่สอบผ่าน
All checks were successful
Build & Deploy on Dev / build (push) Successful in 57s
2026-07-02 13:30:12 +07:00
harid
b5567b5459 migrate add ScoreExpireDate
All checks were successful
Build & Deploy on Dev / build (push) Successful in 48s
2026-07-01 18:07:57 +07:00
harid
853b5c59f6 Migrate + ปรับการแสดงผลจัดการรอบสอบแข่งขัน #11
All checks were successful
Build & Deploy on Dev / build (push) Successful in 48s
2026-06-10 15:29:22 +07:00
harid
5752f35712 lookup province, district, subDistrict IDs with parent filtering
All checks were successful
Build & Deploy on Dev / build (push) Successful in 44s
2026-06-09 10:49:00 +07:00
12 changed files with 3385 additions and 17 deletions

View file

@ -96,6 +96,9 @@ namespace BMA.EHR.Recruit.Controllers
private string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
private string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value;
private string? RootDnaId => _httpContextAccessor?.HttpContext?.User?.FindFirst("orgRootDnaId")?.Value;
private string? token => _httpContextAccessor.HttpContext.Request.Headers["Authorization"];
#endregion
@ -477,16 +480,21 @@ namespace BMA.EHR.Recruit.Controllers
PaymentEndDate = req.PaymentEndDate,
Note = req.Note,
AnnouncementDate = req.AnnouncementDate,
ScoreExpireDate = req.ScoreExpireDate,
OrganizationId = req.rootDnaId,
CreatedAt = DateTime.Now,
CreatedUserId = UserId ?? "",
CreatedFullName = FullName ?? "System Administrator",
LastUpdatedAt = DateTime.Now,
LastUpdateUserId = UserId ?? "",
LastUpdateFullName = FullName ?? "System Administrator",
};
var apiUrl = $"{_configuration["API"]}/org/find/head/officer";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
var _res = await client.SendAsync(_req);
var _result = await _res.Content.ReadAsStringAsync();
@ -554,6 +562,11 @@ namespace BMA.EHR.Recruit.Controllers
data.ExamDate = req.ExamDate;
data.Note = req.Note;
data.AnnouncementDate = req.AnnouncementDate;
if (req.ScoreExpireDate.HasValue)
data.ScoreExpireDate = req.ScoreExpireDate;
data.LastUpdatedAt = DateTime.Now;
data.LastUpdateUserId = UserId ?? "";
data.LastUpdateFullName = FullName ?? "System Administrator";
await _context.SaveChangesAsync();
@ -644,7 +657,14 @@ namespace BMA.EHR.Recruit.Controllers
{
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
}
string role = jsonData["result"]?.ToString() ?? string.Empty;
string rootDnaId = string.Empty;
if (role != "OWNER")
{
rootDnaId = RootDnaId?.ToString() ?? "";
}
var data = await _context.RecruitImports.AsQueryable()
.Where(x => string.IsNullOrEmpty(rootDnaId) || x.OrganizationId == Guid.Parse(rootDnaId))
.Include(x => x.ImportFile)
.Include(x => x.Recruits)
.Include(x => x.ScoreImport)
@ -669,7 +689,7 @@ namespace BMA.EHR.Recruit.Controllers
ImportYear = x.ScoreImport.Year,
ImportDate = x.CreatedAt.Date.ToThaiShortDate(),
ScoreCount = x.ScoreImport.Scores.Count(),
ResultCount = x.ScoreImport.Scores.Count(x => !string.IsNullOrEmpty(x.Number))
ResultCount = x.ScoreImport.Scores.Count(x => x.ExamStatus == "ผ่าน" && !string.IsNullOrEmpty(x.Number))
},
x.CreatedUserId,
})
@ -1520,6 +1540,9 @@ namespace BMA.EHR.Recruit.Controllers
case "notpass":
queryWithScores = queryWithScores.Where(x => x.score != null && x.score.ExamStatus == "ไม่ผ่าน");
break;
case "other":
queryWithScores = queryWithScores.Where(x => x.score != null && !new[] { "ขส.", "ผ่าน", "ไม่ผ่าน" }.Contains(x.score.ExamStatus));
break;
}
}
@ -1803,11 +1826,15 @@ namespace BMA.EHR.Recruit.Controllers
Score = score == null ? 0.0 : score.TotalScore,
Number = score == null ? "" : score.Number,
ExamCount = _recruitService.GetExamCount(recruit.CitizenId),
ScoreExpire = recruit.RecruitImport.AnnouncementDate == null
// เดิมคำนวณวันหมดอายุจาก AnnouncementDate + 2 ปี (เก็บไว้สำหรับอ้างอิงข้อมูลเก่า)
//ScoreExpire = recruit.RecruitImport.AnnouncementDate == null
// ? ""
// : recruit.RecruitImport.AnnouncementDate != DateTime.MinValue
// ? recruit.RecruitImport.AnnouncementDate.Value.AddYears(2).ToThaiShortDate()
// : "",
ScoreExpire = recruit.RecruitImport.ScoreExpireDate == null
? ""
: recruit.RecruitImport.AnnouncementDate != DateTime.MinValue
? recruit.RecruitImport.AnnouncementDate.Value.AddYears(2).ToThaiShortDate()
: "",
: recruit.RecruitImport.ScoreExpireDate.Value.ToThaiShortDate(),
typeTest = recruit.typeTest,
ScoreResult = score == null ? null : new
{
@ -2634,11 +2661,15 @@ namespace BMA.EHR.Recruit.Controllers
T = score != null && score.TotalScore != null ? score.TotalScore.ToString().ToThaiNumber() : "",
Result = score == null ? "" : score.ExamStatus,
Number = score != null && score.Number != null ? score.Number.ToString().ToThaiNumber() : "",
Expire = recruit.RecruitImport.AnnouncementDate == null
// เดิมคำนวณวันหมดอายุจาก AnnouncementDate + 2 ปี (เก็บไว้สำหรับอ้างอิงข้อมูลเก่า)
//Expire = recruit.RecruitImport.AnnouncementDate == null
// ? ""
// : recruit.RecruitImport.AnnouncementDate != DateTime.MinValue
// ? recruit.RecruitImport.AnnouncementDate.Value.AddYears(2).ToThaiShortDate().ToString().ToThaiNumber()
// : "",
Expire = recruit.RecruitImport.ScoreExpireDate == null
? ""
: recruit.RecruitImport.AnnouncementDate != DateTime.MinValue
? recruit.RecruitImport.AnnouncementDate.Value.AddYears(2).ToThaiShortDate().ToString().ToThaiNumber()
: "",
: recruit.RecruitImport.ScoreExpireDate.Value.ToThaiShortDate().ToString().ToThaiNumber(),
};
var result = new

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BMA.EHR.Recruit.Migrations
{
/// <inheritdoc />
public partial class update_RecruitImport_add_OrganizationId : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "OrganizationId",
table: "RecruitImports",
type: "char(36)",
nullable: true,
comment: "DnaId หน่วยงาน",
collation: "ascii_general_ci");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "OrganizationId",
table: "RecruitImports");
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BMA.EHR.Recruit.Migrations
{
/// <inheritdoc />
public partial class update_RecruitImport_add_ScoreExpireDate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "ScoreExpireDate",
table: "RecruitImports",
type: "datetime(6)",
nullable: true,
comment: "วันหมดอายุบัญชี")
.Annotation("Relational:ColumnOrder", 15);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ScoreExpireDate",
table: "RecruitImports");
}
}
}

View file

@ -704,6 +704,10 @@ namespace BMA.EHR.Recruit.Migrations
.HasColumnOrder(3)
.HasComment("ครั้งที่");
b.Property<Guid?>("OrganizationId")
.HasColumnType("char(36)")
.HasComment("DnaId หน่วยงาน");
b.Property<DateTime?>("PaymentEndDate")
.HasColumnType("datetime(6)")
.HasColumnOrder(9)
@ -724,6 +728,11 @@ namespace BMA.EHR.Recruit.Migrations
.HasColumnOrder(10)
.HasComment("วันเริ่มสมัครสอบ");
b.Property<DateTime?>("ScoreExpireDate")
.HasColumnType("datetime(6)")
.HasColumnOrder(15)
.HasComment("วันหมดอายุบัญชี");
b.Property<int>("Year")
.HasColumnType("int")
.HasColumnOrder(1)

View file

@ -11,6 +11,9 @@ namespace BMA.EHR.MetaData.Service.Models
[Required, MaxLength(150), Column(Order = 1), Comment("เขต/อำเภอ")]
public string name { get; set; } = string.Empty;
[Column(Order = 2), Comment("รหัสอ้างอิงจังหวัด")]
public Guid? provinceId { get; set; } = null;
// [Column(Order = 2), Comment("สถานะการใช้งาน")]
// public bool IsActive { get; set; } = true;

View file

@ -14,6 +14,9 @@ namespace BMA.EHR.MetaData.Service.Models
[MaxLength(10), Column(Order = 2), Comment("รหัสไปรษณีย์")]
public string? zipCode { get; set; } = null;
[Column(Order = 3), Comment("รหัสอ้างอิงอำเภอ")]
public Guid? districtId { get; set; } = null;
// [Column(Order = 3), Comment("สถานะการใช้งาน")]
// public bool IsActive { get; set; } = true;

View file

@ -49,6 +49,9 @@ namespace BMA.EHR.Recruit.Models.Recruits
[Column(Order = 14), Comment("วันที่ประกาศผลสอบ")]
public DateTime? AnnouncementDate { get; set; }
[Column(Order = 15), Comment("วันหมดอายุบัญชี")]
public DateTime? ScoreExpireDate { get; set; }
public Document ImportFile { get; set; } = new Document();
public List<Recruit> Recruits { get; set; } = new List<Recruit>();
@ -57,6 +60,9 @@ namespace BMA.EHR.Recruit.Models.Recruits
public string? AuthName { get; set; }
public string? AuthPosition { get; set; }
[Comment("DnaId หน่วยงาน")]
public Guid? OrganizationId { get; set; }
public List<RecruitImportHistory> ImportHostories { get; set; } = new List<RecruitImportHistory>();
[Comment("รูป")]

View file

@ -44,7 +44,7 @@ namespace BMA.EHR.Recruit.Services
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
var req = await client.GetAsync(apiPath);
var res = await req.Content.ReadAsStringAsync();
return res;

View file

@ -82,5 +82,15 @@ namespace BMA.EHR.Recruit.Requests.Recruits
/// วันที่ประกาศผลสอบ
/// </summary>
public DateTime? AnnouncementDate { get; set; }
/// <summary>
/// วันหมดอายุบัญชี
/// </summary>
public DateTime? ScoreExpireDate { get; set; }
/// <summary>
/// รหัส DNA หน่วยงาน
/// </summary>
public Guid? rootDnaId { get; set; }
}
}

View file

@ -341,6 +341,27 @@ namespace BMA.EHR.Recruit.Services
{
positionNameWithoutLevel = positionNameWithoutLevel.Replace(posLevelName, "").Trim();
}
// lookup province, district, subDistrict IDs with parent filtering
var registProvinceId = provincesCache.FirstOrDefault(x => x.name == firstAddress?.Province)?.Id;
var registDistrictId = districtsCache.FirstOrDefault(x => x.name == firstAddress?.Amphur && x.provinceId == registProvinceId)?.Id;
var registSubDistrictId = subDistrictsCache.FirstOrDefault(x => x.name == firstAddress?.District && x.districtId == registDistrictId)?.Id;
var currentProvinceId = provincesCache.FirstOrDefault(x => x.name == firstAddress?.Province1)?.Id;
var currentDistrictId = districtsCache.FirstOrDefault(x => x.name == firstAddress?.Amphur1 && x.provinceId == currentProvinceId)?.Id;
var currentSubDistrictId = subDistrictsCache.FirstOrDefault(x => x.name == firstAddress?.District1 && x.districtId == currentDistrictId)?.Id;
// log warning when address lookup fails
if (registProvinceId == null && !string.IsNullOrWhiteSpace(firstAddress?.Province))
Console.WriteLine($"[WARN] Regist province not found: {firstAddress?.Province}");
if (registDistrictId == null && !string.IsNullOrWhiteSpace(firstAddress?.Amphur))
Console.WriteLine($"[WARN] Regist district not found: {firstAddress?.Amphur}, Province: {firstAddress?.Province}");
if (registSubDistrictId == null && !string.IsNullOrWhiteSpace(firstAddress?.District))
Console.WriteLine($"[WARN] Regist subdistrict not found: {firstAddress?.District}, District: {firstAddress?.Amphur}");
if (currentProvinceId == null && !string.IsNullOrWhiteSpace(firstAddress?.Province1))
Console.WriteLine($"[WARN] Current province not found: {firstAddress?.Province1}");
if (currentDistrictId == null && !string.IsNullOrWhiteSpace(firstAddress?.Amphur1))
Console.WriteLine($"[WARN] Current district not found: {firstAddress?.Amphur1}, Province: {firstAddress?.Province1}");
if (currentSubDistrictId == null && !string.IsNullOrWhiteSpace(firstAddress?.District1))
Console.WriteLine($"[WARN] Current subdistrict not found: {firstAddress?.District1}, District: {firstAddress?.Amphur1}");
var placementProfile = new PlacementProfile
{
@ -363,15 +384,15 @@ namespace BMA.EHR.Recruit.Services
Telephone = firstAddress?.Telephone ?? "",
MobilePhone = firstAddress?.Mobile ?? "",
RegistAddress = registAddress ?? "",
RegistProvinceId = provincesCache.FirstOrDefault(x => x.name == firstAddress?.Province)?.Id,
RegistDistrictId = districtsCache.FirstOrDefault(x => x.name == firstAddress?.Amphur)?.Id,
RegistSubDistrictId = subDistrictsCache.FirstOrDefault(x => x.name == firstAddress?.District)?.Id,
RegistProvinceId = registProvinceId,
RegistDistrictId = registDistrictId,
RegistSubDistrictId = registSubDistrictId,
RegistZipCode = firstAddress?.ZipCode ?? "",
RegistSame = false,
CurrentAddress = currentAddress,
CurrentProvinceId = provincesCache.FirstOrDefault(x => x.name == firstAddress?.Province1)?.Id,
CurrentDistrictId = districtsCache.FirstOrDefault(x => x.name == firstAddress?.Amphur1)?.Id,
CurrentSubDistrictId = subDistrictsCache.FirstOrDefault(x => x.name == firstAddress?.District1)?.Id,
CurrentProvinceId = currentProvinceId,
CurrentDistrictId = currentDistrictId,
CurrentSubDistrictId = currentSubDistrictId,
CurrentZipCode = firstAddress?.ZipCode1,
Marry = candidate.Marry?.Contains("สมรส") ?? false,
OccupationPositionType = "other",