hrms-api-backend/BMA.EHR.CheckInConsumer/Program.cs
Suphonchai Phoonsawat 3532df32fd
All checks were successful
Build & Deploy Checkin Service / build (push) Successful in 1m20s
Refactor message consumption to start after 8:10 AM and implement time checks for operating hours
2026-01-20 05:38:42 +07:00

167 lines
No EOL
4.7 KiB
C#

using Microsoft.Extensions.Configuration;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
var basePath = Directory.GetCurrentDirectory();
var configuration = new ConfigurationBuilder()
.SetBasePath(basePath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
WriteToConsole("Consumer Start!");
var host = configuration["Rabbit:Host"] ?? "";
var user = configuration["Rabbit:User"] ?? "";
var pass = configuration["Rabbit:Password"] ?? "";
var queue = configuration["Rabbit:Queue"] ?? "basic-queue";
// create connection
var factory = new ConnectionFactory()
{
HostName = host,
UserName = user,
Password = pass
};
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.QueueDeclare(queue: queue, durable: true, exclusive: false, autoDelete: false, arguments: null);
var consumer = new EventingBasicConsumer(channel);
string? consumerTag = null;
bool isConsuming = false;
consumer.Received += async (model, ea) =>
{
var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
// Double-check time before processing (safety check)
if (!IsWithinOperatingHours())
{
WriteToConsole($"Message received outside operating hours. Requeuing message.");
channel.BasicNack(ea.DeliveryTag, false, true); // Requeue the message
return;
}
await CallRestApi(message);
WriteToConsole($"ได้รับคำขอจาก Queue: {message}");
};
// Monitor and control consumer based on time schedule
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(1));
while (await timer.WaitForNextTickAsync())
{
var shouldBeConsuming = IsWithinOperatingHours();
if (shouldBeConsuming && !isConsuming)
{
// Start consuming
consumerTag = channel.BasicConsume(queue: queue, autoAck: true, consumer: consumer);
isConsuming = true;
WriteToConsole($"✅ Started consuming messages at {GetCurrentBangkokTime():yyyy-MM-dd HH:mm:ss}");
}
else if (!shouldBeConsuming && isConsuming)
{
// Stop consuming
if (consumerTag != null)
{
channel.BasicCancel(consumerTag);
consumerTag = null;
}
isConsuming = false;
WriteToConsole($"⏸️ Stopped consuming messages at {GetCurrentBangkokTime():yyyy-MM-dd HH:mm:ss}. Will resume after 08:10 tomorrow.");
}
}
static void WriteToConsole(string message)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} : {message}");
}
async Task CallRestApi(string requestData)
{
using var client = new HttpClient();
var apiPath = $"{configuration["API"]}/leave/process-check-in";
var content = new StringContent(requestData, Encoding.UTF8, "application/json");
var response = await client.PostAsync(apiPath, content);
if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
WriteToConsole(responseContent);
}
else
{
var errorMessage = await response.Content.ReadAsStringAsync();
var res = JsonSerializer.Deserialize<ResponseObject>(errorMessage);
WriteToConsole($"Error: {res.Message}");
}
}
DateTime GetCurrentBangkokTime()
{
var bangkokTimeZone = TimeZoneInfo.FindSystemTimeZoneById("SE Asia Standard Time");
return TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, bangkokTimeZone);
}
bool IsWithinOperatingHours()
{
var currentTime = GetCurrentBangkokTime();
var startTime = new TimeSpan(8, 10, 0); // 8:10 AM
var endTime = new TimeSpan(23, 59, 59); // End of day
var currentTimeOfDay = currentTime.TimeOfDay;
// Consumer should only work from 8:10 AM to end of day
return currentTimeOfDay >= startTime && currentTimeOfDay <= endTime;
}
public class ResponseObject
{
[JsonPropertyName("status")]
public int Status { get; set; }
[JsonPropertyName("message")]
public string? Message { get; set; }
[JsonPropertyName("result")]
public object? Result { get; set; }
}
public class CheckTimeDtoRB
{
public Guid? CheckInId { get; set; }
public double Lat { get; set; } = 0;
public double Lon { get; set; } = 0;
public string POI { get; set; } = string.Empty;
public bool IsLocation { get; set; } = true;
public string? LocationName { get; set; } = string.Empty;
public string? Remark { get; set; } = string.Empty;
public Guid? UserId { get; set; }
public DateTime? CurrentDate { get; set; }
public string? CheckInFileName { get; set; }
public byte[]? CheckInFileBytes { get; set; }
}