This commit is contained in:
kittapath 2025-10-11 18:56:47 +07:00
parent fb726ca789
commit 2b0151fd67
2 changed files with 57 additions and 26 deletions

View file

@ -0,0 +1,16 @@
namespace BMA.EHR.Recruit.Service.Requests.Recruits
{
public class RecruitPosRequest
{
public RecruitPosTypeRequest result { get; set; } = new();
}
public class RecruitPosTypeRequest
{
public string posTypeName { get; set; }
public List<RecruitPosLevelRequest> posLevels { get; set; } = new();
}
public class RecruitPosLevelRequest
{
public string posLevelName { get; set; }
}
}

View file

@ -13,6 +13,7 @@ using System.Security.Claims;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Globalization;
using BMA.EHR.Recruit.Service.Requests.Recruits;
namespace BMA.EHR.Recruit.Service.Services
{
@ -179,6 +180,14 @@ namespace BMA.EHR.Recruit.Service.Services
{
try
{
// 🚀 Prepare HTTP client once
var httpClient1 = new HttpClient();
httpClient1.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token?.Replace("Bearer ", ""));
httpClient1.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
var apiUrl1 = $"{_configuration["API"]}/api/v1/org/pos/type";
var response1 = await httpClient1.GetStringAsync(apiUrl1);
var posType = JsonConvert.DeserializeObject<RecruitPosTypeRequest>(response1);
var recruitImport = await _context.RecruitImports.AsQueryable()
.FirstOrDefaultAsync(x => x.Id == examId);
@ -232,7 +241,9 @@ namespace BMA.EHR.Recruit.Service.Services
.Where(x => x.ScoreImport == scoreImport && x.ExamStatus == "ผ่าน")
.ToListAsync();
var recruitScoresDict = recruitScores.ToDictionary(x => x.ExamId, x => x);
var recruitScoresDict = recruitScores
.Where(x => !string.IsNullOrWhiteSpace(x.ExamId))
.ToDictionary(x => x.ExamId, x => x);
// 🚀 Prepare HTTP client once
var httpClient = new HttpClient();
@ -242,20 +253,23 @@ namespace BMA.EHR.Recruit.Service.Services
// 🚀 Batch HTTP requests
var orgTasks = candidates.Select(async candidate =>
{
if (string.IsNullOrWhiteSpace(candidate.CitizenId))
return new { CitizenId = candidate.CitizenId ?? "", org = (dynamic?)null };
var apiUrl = $"{_configuration["API"]}/org/profile/citizenid/position/{candidate.CitizenId}";
try
{
var response = await httpClient.GetStringAsync(apiUrl);
return new { candidate.CitizenId, org = JsonConvert.DeserializeObject<dynamic>(response) };
return new { CitizenId = candidate.CitizenId, org = JsonConvert.DeserializeObject<dynamic>(response) };
}
catch
{
return new { candidate.CitizenId, org = (dynamic?)null };
return new { CitizenId = candidate.CitizenId ?? "", org = (dynamic?)null };
}
}).ToList();
var orgResults = await Task.WhenAll(orgTasks);
var orgDict = orgResults.ToDictionary(x => x.CitizenId, x => x.org);
var orgDict = orgResults.ToDictionary(x => x.CitizenId ?? "", x => x.org);
// 🚀 Prepare batch inserts
var placementProfiles = new List<PlacementProfile>();
@ -264,10 +278,11 @@ namespace BMA.EHR.Recruit.Service.Services
foreach (var candidate in candidates)
{
if (!recruitScoresDict.TryGetValue(candidate.ExamId, out var recruitScore))
if (string.IsNullOrWhiteSpace(candidate.ExamId) ||
!recruitScoresDict.TryGetValue(candidate.ExamId, out var recruitScore))
continue;
var org = orgDict.GetValueOrDefault(candidate.CitizenId);
var org = orgDict.TryGetValue(candidate.CitizenId ?? "", out var orgValue) ? orgValue : null;
var isOfficer = org?.result != null;
// 🚀 Cache repeated calculations
@ -282,19 +297,19 @@ namespace BMA.EHR.Recruit.Service.Services
var placementProfile = new PlacementProfile
{
Placement = placement,
PositionCandidate = candidate.PositionName,
PositionType = candidate.PositionType,
PositionLevel = candidate.PositionLevel,
Prefix = candidate.Prefix,
Firstname = candidate.FirstName,
Lastname = candidate.LastName,
Gender = candidate.Gendor,
Nationality = candidate.National,
Race = candidate.Race,
Religion = candidate.Religion,
PositionCandidate = candidate.PositionName ?? "",
PositionType = candidate.PositionType ?? "",
PositionLevel = candidate.PositionLevel ?? "",
Prefix = candidate.Prefix ?? "",
Firstname = candidate.FirstName ?? "",
Lastname = candidate.LastName ?? "",
Gender = candidate.Gendor ?? "",
Nationality = candidate.National ?? "",
Race = candidate.Race ?? "",
Religion = candidate.Religion ?? "",
DateOfBirth = candidate.DateOfBirth,
Relationship = candidate.Marry,
CitizenId = candidate.CitizenId,
Relationship = candidate.Marry ?? "",
CitizenId = candidate.CitizenId ?? "",
CitizenProvinceId = provincesCache.FirstOrDefault(x => x.name == candidate.CitizenCardIssuer)?.Id,
CitizenDate = candidate.CitizenCardExpireDate,
Telephone = firstAddress?.Telephone,
@ -314,17 +329,17 @@ namespace BMA.EHR.Recruit.Service.Services
OccupationPositionType = "other",
OccupationTelephone = firstOccupation?.Telephone,
OccupationPosition = firstOccupation?.Position,
PointTotalA = Convert.ToDouble(recruitScore.FullA),
PointA = Convert.ToDouble(recruitScore.SumA),
PointTotalB = Convert.ToDouble(recruitScore.FullB),
PointB = Convert.ToDouble(recruitScore.SumB),
PointTotalC = Convert.ToDouble(recruitScore.FullC),
PointC = Convert.ToDouble(recruitScore.SumC),
ExamNumber = int.TryParse(recruitScore.Number, out int n) ? n : null,
PointTotalA = recruitScore.FullA, // non-nullable int
PointA = recruitScore.SumA, // non-nullable double
PointTotalB = recruitScore.FullB ?? 0, // nullable int?
PointB = recruitScore.SumB ?? 0, // nullable double?
PointTotalC = recruitScore.FullC, // non-nullable int
PointC = recruitScore.SumC, // non-nullable double
ExamNumber = !string.IsNullOrWhiteSpace(recruitScore.Number) && int.TryParse(recruitScore.Number, out int n) ? n : null,
ExamRound = null,
IsRelief = false,
PlacementStatus = "UN-CONTAIN",
Pass = recruitScore.ExamStatus,
Pass = recruitScore.ExamStatus ?? "",
RemarkHorizontal = "โดยมีเงื่อนไขว่าต้องปฏิบัติงานให้กรุงเทพมหานครเป็นระยะเวลาไม่น้อยกว่า ๕ ปี นับแต่วันที่ได้รับการบรรจุและแต่งตั้ง โดยห้ามโอนไปหน่วยงานหรือส่วนราชการอื่น เว้นเเต่ลาออกจากราชการ",
Amount = org?.result?.amount,
PositionSalaryAmount = org?.result?.positionSalaryAmount,