From ecf660e4cfcac4fecf79615b2502e238c00e19f7 Mon Sep 17 00:00:00 2001 From: Suphonchai Phoonsawat Date: Fri, 15 May 2026 11:41:59 +0700 Subject: [PATCH] send noti process-checkin --- BMA.EHR.Leave/Controllers/LeaveController.cs | 22 ++++++- BMA.EHR.Leave/Services/NotificationService.cs | 58 +++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 BMA.EHR.Leave/Services/NotificationService.cs diff --git a/BMA.EHR.Leave/Controllers/LeaveController.cs b/BMA.EHR.Leave/Controllers/LeaveController.cs index 7e6befad..bba075e0 100644 --- a/BMA.EHR.Leave/Controllers/LeaveController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveController.cs @@ -33,6 +33,7 @@ using System.Diagnostics; using System.Security.Claims; using System.Text; using System.Threading.Tasks; +using BMA.EHR.Leave.Services; using SearchProfileResultDto = BMA.EHR.Leave.Service.DTOs.ChangeRound.SearchProfileResultDto; namespace BMA.EHR.Leave.Service.Controllers @@ -63,6 +64,7 @@ namespace BMA.EHR.Leave.Service.Controllers private readonly UserCalendarRepository _userCalendarRepository; private readonly PermissionRepository _permission; private readonly CheckInJobStatusRepository _checkInJobStatusRepository; + private readonly NotificationService _notificationService; private readonly CommandRepository _commandRepository; @@ -102,7 +104,8 @@ namespace BMA.EHR.Leave.Service.Controllers CheckInJobStatusRepository checkInJobStatusRepository, HttpClient httpClient, ApplicationDBContext appDbContext, - LeaveProcessJobStatusRepository leaveProcessJobStatusRepository) + LeaveProcessJobStatusRepository leaveProcessJobStatusRepository, + NotificationService notificationService) { _dutyTimeRepository = dutyTimeRepository; _context = context; @@ -122,6 +125,7 @@ namespace BMA.EHR.Leave.Service.Controllers _notificationRepository = notificationRepository; _checkInJobStatusRepository = checkInJobStatusRepository; _leaveProcessJobStatusRepository = leaveProcessJobStatusRepository; + _notificationService = notificationService; _objectPool = objectPool; _permission = permission; @@ -943,7 +947,9 @@ namespace BMA.EHR.Leave.Service.Controllers if (profile == null) { - await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, "ไม่พบข้อมูลผู้ใช้"); + await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, "เกิดข้อผิดพลาดจากการเรียก API [GetProfileByKeycloakIdNew2Async] : ไม่พบข้อมูลผู้ใช้"); + await _notificationService.SendNotificationAsync(data.Token, true, + "เกิดข้อผิดพลาดจากการเรียก API [GetProfileByKeycloakIdNew2Async] : ไม่พบข้อมูลผู้ใช้"); //var staffList = await _userProfileRepository.GetOCStaffAsync(profile) return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); } @@ -954,6 +960,7 @@ namespace BMA.EHR.Leave.Service.Controllers { //throw new Exception(GlobalMessages.NoFileToUpload); await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, GlobalMessages.NoFileToUpload); + await _notificationService.SendNotificationAsync(data.Token, true, $"ประมวลผลการลงเวลาวันที่ {currentDate.ToString("dd-MM-yyyy")} ไม่สำเร็จ \r\nเนื่องจาก {GlobalMessages.NoFileToUpload}"); // send notification to user var noti1 = new Notification @@ -991,6 +998,7 @@ namespace BMA.EHR.Leave.Service.Controllers catch (Exception ex) { await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, $"ไม่สามารถอัปโหลดรูปภาพได้: {ex.Message}"); + await _notificationService.SendNotificationAsync(data.Token, true, $"ประมวลผลการลงเวลาวันที่ {currentDate.ToString("dd-MM-yyyy")} ไม่สำเร็จ \r\nเนื่องจากไม่สามารถอัปโหลดรูปภาพได้ {ex.Message}"); // send notification to user var noti1 = new Notification @@ -1025,6 +1033,7 @@ namespace BMA.EHR.Leave.Service.Controllers catch (Exception ex) { await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, $"ไม่สามารถอัปโหลดรูปภาพได้: {ex.Message}"); + await _notificationService.SendNotificationAsync(data.Token, true, $"ประมวลผลการลงเวลาวันที่ {currentDate.ToString("dd-MM-yyyy")} ไม่สำเร็จ \r\nเนื่องจากไม่สามารถอัปโหลดรูปภาพได้ {ex.Message}"); // send notification to user var noti1 = new Notification @@ -1049,6 +1058,8 @@ namespace BMA.EHR.Leave.Service.Controllers if (defaultRound == null) { await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, "ไม่พบรอบการลงเวลาทำงาน Default"); + await _notificationService.SendNotificationAsync(data.Token, true, + $"ประมวลผลการลงเวลาวันที่ {currentDate.ToString("dd-MM-yyyy")} ไม่สำเร็จ \r\nเนื่องจากไม่พบรอบการลงเวลาทำงาน Default"); // send notification to user var noti1 = new Notification { @@ -1202,6 +1213,7 @@ namespace BMA.EHR.Leave.Service.Controllers if (currentCheckIn != null) { await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, "ไม่สามารถลงเวลาได้ เนื่องจากมีการลงเวลาในวันนี้แล้ว"); + await _notificationService.SendNotificationAsync(data.Token, true,$"ประมวลผลการลงเวลาวันที่ {currentDate.ToString("dd-MM-yyyy")} ไม่สำเร็จ \r\nเนื่องจากมีการลงเวลาในวันนี้แล้ว"); // send notification to user var noti1 = new Notification @@ -1359,6 +1371,7 @@ namespace BMA.EHR.Leave.Service.Controllers if (checkout == null) { await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, "ไม่พบข้อมูลการลงเวลาทำงาน"); + await _notificationService.SendNotificationAsync(data.Token,true, $"ประมวลผลการลงเวลาวันที่ {currentDate.ToString("dd-MM-yyyy")} ไม่สำเร็จ \r\nเนื่องจากไม่พบข้อมูลการลงเวลาทำงาน"); // send notification to user var noti1 = new Notification @@ -1379,6 +1392,7 @@ namespace BMA.EHR.Leave.Service.Controllers if (currentCheckInProcess == null) { await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, "ไม่พบข้อมูลการประมวลผลเวลาทำงาน (CheckIn)"); + await _notificationService.SendNotificationAsync(data.Token, true, $"ประมวลผลการลงเวลาวันที่ {currentDate.ToString("dd-MM-yyyy")} ไม่สำเร็จ \r\nเนื่องจากไม่พบข้อมูลการประมวลผลเวลาทำงาน (CheckIn)"); // send notification to user var noti1 = new Notification @@ -1556,6 +1570,7 @@ namespace BMA.EHR.Leave.Service.Controllers else { await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, "ไม่พบข้อมูลการประมวลผลเวลาทำงาน"); + await _notificationService.SendNotificationAsync(data.Token,true, $"ประมวลผลการลงเวลาวันที่ {currentDate.ToString("dd-MM-yyyy")} ไม่สำเร็จ \r\nเนื่องจากไม่พบข้อมูลการประมวลผลเวลาทำงาน"); // send notification to user var noti1 = new Notification { @@ -1579,6 +1594,8 @@ namespace BMA.EHR.Leave.Service.Controllers ProcessedDate = currentDate }); await _checkInJobStatusRepository.UpdateToCompletedAsync(taskId, additionalData); + await _notificationService.SendNotificationAsync(data.Token, false, + $"ประมวลผลการลงเวลาวันที่ {currentDate.ToString("dd-MM-yyyy")} สำเร็จ"); } var checkInType = data.CheckInId == null ? "check-in" : "check-out"; @@ -1590,6 +1607,7 @@ namespace BMA.EHR.Leave.Service.Controllers if (taskId != Guid.Empty) { await _checkInJobStatusRepository.UpdateToFailedAsync(taskId, ex.Message); + await _notificationService.SendNotificationAsync(data.Token, true, ex.Message); } return Error(ex); } diff --git a/BMA.EHR.Leave/Services/NotificationService.cs b/BMA.EHR.Leave/Services/NotificationService.cs new file mode 100644 index 00000000..3ada008e --- /dev/null +++ b/BMA.EHR.Leave/Services/NotificationService.cs @@ -0,0 +1,58 @@ +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using System.Net.Http.Headers; +using System.Text; + +namespace BMA.EHR.Leave.Services; + +public class NotificationService +{ + private readonly IHttpClientFactory _httpClientFactory; + private readonly ILogger _logger; + private readonly IConfiguration _configuration; + + private const string NotifyEndpoint = "https://hrmsbkk.case-collection.com/api/v1/org/through-socket/notify-from-token"; + + public NotificationService(IHttpClientFactory httpClientFactory, ILogger logger, IConfiguration configuration) + { + _httpClientFactory = httpClientFactory; + _logger = logger; + _configuration = configuration; + } + + public async Task SendNotificationAsync(string? token, bool error, string message) + { + if (string.IsNullOrEmpty(token)) + { + _logger.LogWarning("Cannot send import notification: token is null or empty."); + return; + } + + try + { + var client = _httpClientFactory.CreateClient("default"); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", "")); + + var payload = new + { + error, + message + }; + + var json = JsonConvert.SerializeObject(payload); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = await client.PostAsync(NotifyEndpoint, content); + + if (!response.IsSuccessStatusCode) + { + var responseBody = await response.Content.ReadAsStringAsync(); + _logger.LogWarning("Import notification failed with status {StatusCode}: {Body}", response.StatusCode, responseBody); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to send import notification: {Message}", ex.Message); + } + } +}