using BMA.EHR.Application.Common.Interfaces; using BMA.EHR.Domain.Models.Placement; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System.Net.Http.Headers; using Newtonsoft.Json; namespace BMA.EHR.Application.Repositories { public class PlacementRepository : GenericRepository { #region " Fields " private readonly IApplicationDBContext _dbContext; private readonly IHttpContextAccessor _httpContextAccessor; private readonly IConfiguration _configuration; #endregion #region " Constructor and Destructor " public PlacementRepository(IApplicationDBContext dbContext, IHttpContextAccessor httpContextAccessor, IConfiguration configuration) : base(dbContext, httpContextAccessor) { _dbContext = dbContext; _httpContextAccessor = httpContextAccessor; _configuration = configuration; } #endregion #region " Methods " public async Task> GetCompetitivePlacementAsync() { try { var data = await _dbContext.Set() .Include(p => p.PlacementType) .Where(p => p.PlacementType.Name == "สอบแข่งขัน") .ToListAsync(); return data; } catch { throw; } } public async Task> GetAllPlacementAsync() { try { var data = await _dbContext.Set() .Include(p => p.PlacementType) .ToListAsync(); return data; } catch { throw; } } public async Task> GetQualifyingPlacementAsync() { var data = await _dbContext.Set() .Include(p => p.PlacementType) .Where(p => p.PlacementType.Name != "สอบแข่งขัน") .ToListAsync(); return data; } public async Task> FindByNameAsync(string name) { var data = await _dbContext.Set().Where(x => x.Name == name).ToListAsync(); return data; } /// /// Job อัพเดทสถานะผู้สอบผ่านที่ลาออกไปแล้วแต่ยังไม่ส่งไปออกคำสั่ง /// ทำงานทุกวันเวลา 05:00 น. /// public async Task UpdateStatusPlacementProfiles() { Console.WriteLine("[Job:UpdateStatusPlacementProfiles] === STARTED ==="); var officerProfileIds = await _dbContext.Set() .Where(p => !string.IsNullOrEmpty(p.profileId) && p.IsOfficer == true && p.PlacementStatus != "DONE" // && p.Id == Guid.Parse("08deb7de-3030-4d1b-8519-8148584949fc") ) .Select(p => p.profileId) .ToListAsync(); if (!officerProfileIds.Any()) { Console.WriteLine("[Job:UpdateStatusPlacementProfiles] No profiles to process"); return; } Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] พบข้าราชการที่สอบผ่านทั้งหมด {officerProfileIds.Count} คน ที่ยังไม่ส่งไปออกคำสั่ง"); var apiUrl = $"{_configuration["API"]}/org/dotnet/check-isLeave"; List leaveProfileIds = new(); using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]); var payload = new { profileIds = officerProfileIds.Distinct().ToList() }; var jsonPayload = JsonConvert.SerializeObject(payload); var content = new StringContent(jsonPayload, System.Text.Encoding.UTF8, "application/json"); try { var response = await client.PostAsync(apiUrl, content); var result = await response.Content.ReadAsStringAsync(); var responseObj = JsonConvert.DeserializeAnonymousType(result, new { status = 0, message = "", result = new List() }); leaveProfileIds = responseObj.result ?? new(); Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] พบ {leaveProfileIds.Count} รายการที่ลาออก"); } catch (Exception ex) { Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] Call API failed: {ex.Message}"); return; } } if (leaveProfileIds.Any()) { var batchSize = 500; var totalUpdated = 0; var totalBatches = (int)Math.Ceiling((double)leaveProfileIds.Count / batchSize); for (int i = 0; i < totalBatches; i++) { var batch = leaveProfileIds.Skip(i * batchSize).Take(batchSize).ToList(); var profilesToUpdate = await _dbContext.Set() .Where(p => !string.IsNullOrEmpty(p.profileId) && batch.Contains(p.profileId)) .ToListAsync(); foreach (var profile in profilesToUpdate) { profile.IsOfficer = false; } await _dbContext.SaveChangesAsync(); totalUpdated += profilesToUpdate.Count; Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] Batch {i + 1}/{totalBatches} → อัปเดต {profilesToUpdate.Count} รายการ"); } Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] อัปเดตรวมทั้งหมด {totalUpdated} รายการ → IsOfficer = false"); } Console.WriteLine("[Job:UpdateStatusPlacementProfiles] === COMPLETED ==="); } #endregion } }