From 82c31a0f576d9260253e87bbc14832d744ff7838 Mon Sep 17 00:00:00 2001 From: Suphonchai Phoonsawat Date: Tue, 31 Mar 2026 10:18:06 +0700 Subject: [PATCH] Refactor GenericRepository and GenericLeaveRepository to expose PostExternalAPIAsync method and enhance LeaveProcessJobStatusRepository with API integration for processing employee records --- .../Repositories/GenericRepository.cs | 2 +- .../Leaves/GenericLeaveRepository.cs | 35 ++++++++++++ .../LeaveProcessJobStatusRepository.cs | 54 ++++++++++++------- 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/BMA.EHR.Application/Repositories/GenericRepository.cs b/BMA.EHR.Application/Repositories/GenericRepository.cs index 805b88ba..d825ccaf 100644 --- a/BMA.EHR.Application/Repositories/GenericRepository.cs +++ b/BMA.EHR.Application/Repositories/GenericRepository.cs @@ -115,7 +115,7 @@ namespace BMA.EHR.Application.Repositories } - protected async Task PostExternalAPIAsync(string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default) + public async Task PostExternalAPIAsync(string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default) { try { diff --git a/BMA.EHR.Application/Repositories/Leaves/GenericLeaveRepository.cs b/BMA.EHR.Application/Repositories/Leaves/GenericLeaveRepository.cs index 93ae9cec..2e550d71 100644 --- a/BMA.EHR.Application/Repositories/Leaves/GenericLeaveRepository.cs +++ b/BMA.EHR.Application/Repositories/Leaves/GenericLeaveRepository.cs @@ -2,8 +2,11 @@ using BMA.EHR.Domain.Models.Base; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; +using Newtonsoft.Json; using System.IO.Pipes; +using System.Net.Http.Headers; using System.Security.Claims; +using System.Text; namespace BMA.EHR.Application.Repositories.Leaves { @@ -43,6 +46,38 @@ namespace BMA.EHR.Application.Repositories.Leaves #region " Methods " + public async Task PostExternalAPIAsync(string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default) + { + try + { + // กำหนด timeout เป็น 30 นาที + using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30)); + using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token); + var json = JsonConvert.SerializeObject(body); + var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); + //stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + + using (var client = new HttpClient()) + { + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", "")); + client.DefaultRequestHeaders.Add("api-key", apiKey); + var _res = await client.PostAsync(apiPath, stringContent, combinedCts.Token); + if (_res.IsSuccessStatusCode) + { + var _result = await _res.Content.ReadAsStringAsync(); + + return _result; + } + return string.Empty; + } + } + catch + { + throw; + } + } + + public virtual async Task> GetAllAsync() { return await _dbSet.ToListAsync(); diff --git a/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/LeaveProcessJobStatusRepository.cs b/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/LeaveProcessJobStatusRepository.cs index ded9e370..4eba7b2a 100644 --- a/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/LeaveProcessJobStatusRepository.cs +++ b/BMA.EHR.Application/Repositories/Leaves/TimeAttendants/LeaveProcessJobStatusRepository.cs @@ -12,6 +12,7 @@ using BMA.EHR.Domain.Extensions; using BMA.EHR.Domain.Models.Leave.TimeAttendants; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants { @@ -27,6 +28,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants private readonly UserDutyTimeRepository _userDutyTimeRepository; private readonly ProcessUserTimeStampRepository _processUserTimeStampRepository; private readonly LeaveRequestRepository _leaveRequestRepository; + private readonly IConfiguration _configuration; #endregion @@ -39,12 +41,14 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants DutyTimeRepository dutyTimeRepository, UserDutyTimeRepository userDutyTimeRepository, ProcessUserTimeStampRepository processUserTimeStampRepository, - LeaveRequestRepository leaveRequestRepository) : base(dbContext, httpContextAccessor) + LeaveRequestRepository leaveRequestRepository, + IConfiguration configuration) : base(dbContext, httpContextAccessor) { _dbContext = dbContext; _httpContextAccessor = httpContextAccessor; _userProfileRepository = userProfileRepository; _holidayRepository = holidayRepository; + _configuration = configuration; _leaveRequestRepository = leaveRequestRepository; _dutyTimeRepository = dutyTimeRepository; _userDutyTimeRepository = userDutyTimeRepository; @@ -364,38 +368,50 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants stampAmount = stampAmount, remark = remarkStr, status = status - }; employees.Add(emp); count++; } - // Write employees to JSON file - var fileName = $"employees_{DateTime.Now:yyyyMMdd_HHmmss}.txt"; - var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Exports", fileName); + // // Write employees to JSON file + // var fileName = $"employees_{DateTime.Now:yyyyMMdd_HHmmss}.txt"; + // var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Exports", fileName); - // Ensure directory exists - var directory = Path.GetDirectoryName(filePath); - if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) - { - Directory.CreateDirectory(directory); - } + // // Ensure directory exists + // var directory = Path.GetDirectoryName(filePath); + // if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) + // { + // Directory.CreateDirectory(directory); + // } - var jsonOptions = new JsonSerializerOptions - { - WriteIndented = true, - Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping - }; + // var jsonOptions = new JsonSerializerOptions + // { + // WriteIndented = true, + // Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping + // }; - var jsonContent = JsonSerializer.Serialize(employees, jsonOptions); - await File.WriteAllTextAsync(filePath, jsonContent); + // var jsonContent = JsonSerializer.Serialize(employees, jsonOptions); + // await File.WriteAllTextAsync(filePath, jsonContent); } + + //call api + var apiPath = $"{_configuration["API"]}/org/profile/absent-late/batch"; + var apiKey = _configuration["API_KEY"]; + var body = new + { + records = employees + }; + + var apiResult = await PostExternalAPIAsync(apiPath, AccessToken ?? "", body, apiKey); + if(apiResult == "") + { + throw new Exception($"เรียก API {apiPath} ไม่สำเร็จ"); + } } public async Task ProcessPendingJobsAsync() { - var pendingJobs = await GetPendingJobsAsync(); Console.WriteLine($"พบงานที่ค้างอยู่ในสถานะ PENDING จำนวน {pendingJobs.Count} งาน");