Files
Core_Be/Services/OverdueLockRunner.cs
T
Dhananjaya99 bffc9b1686 first commit
2026-09-28 11:44:26 +05:30

70 lines
3.4 KiB
C#

using Fitness_core_BE.Infra.Tenancy;
using Fitness_core_BE.Infra.UoW;
using Fitness_core_BE.Models;
using Fitness_core_BE.Repos;
namespace Fitness_core_BE.Services
{
// The per-client overdue-lock algorithm, extracted verbatim from OverdueLockJob so the
// admin "trigger now" endpoint (AdminBackgroundJobsController) can call the exact same code
// path instead of duplicating it. Pure extraction -- no change to the locking logic itself.
// Mirrors the SubscriptionRenewalRunner/SubscriptionRenewalJob split.
public class OverdueLockRunner(ILogger<OverdueLockRunner> logger)
{
private readonly ILogger<OverdueLockRunner> _logger = logger;
public async Task RunForClientAsync(Client client, DateTime now, TenantSchemaIterator iterator, CancellationToken ct)
{
await using var schemaCtx = await iterator.OpenSchemaForClientAsync(client.ClientId, ct);
if (schemaCtx == null)
{
_logger.LogWarning(
"OverdueLockJob: client {ClientId} has a lock policy but no provisioned tenant schema; skipping.",
client.ClientId);
return;
}
var repository = new OverdueLockRepository(schemaCtx.Tenant, schemaCtx.Central);
var accessDeviceService = new AccessDeviceService(
new EFUnitOfWork(schemaCtx.Central, schemaCtx.Tenant),
new AccessDeviceRepo(schemaCtx.Tenant, schemaCtx.Central),
new AttendanceRepository(schemaCtx.Tenant),
new DeviceCommandRepo(schemaCtx.Tenant),
new PairingCodeRepo(schemaCtx.Central));
var effectiveDays = client.LockAfterDaysOverdue ?? Client.DefaultLockAfterDaysOverdue;
var thresholdDate = now.AddDays(-effectiveDays);
var overdueCustomerIds = await repository.GetOverdueCustomerIdsAsync(
client.ClientId, thresholdDate, ct);
foreach (var customerId in overdueCustomerIds)
{
var customer = await repository.GetCustomerByIdAsync(customerId, ct);
if (customer == null)
continue;
var alreadyLocked = await repository.IsCustomerAccessDisabledAsync(
client.ClientId, customer.FKUserId, ct);
if (alreadyLocked)
continue;
await accessDeviceService.SetCustomerAccessAsync(
client.ClientId, customerId, enabled: false, reason: "Overdue");
_logger.LogInformation("Auto-locked customer {CustomerId} for client {ClientId} (overdue).", customerId, client.ClientId);
}
// Auto-unlock members who were locked for being overdue but are no longer
// (paid, or their overdue invoice fell out of scope) — never touches manual locks.
var lockedOverdueCustomerIds =
await repository.GetCustomersLockedForOverdueAsync(client.ClientId, ct);
foreach (var customerId in lockedOverdueCustomerIds.Except(overdueCustomerIds))
{
await accessDeviceService.SetCustomerAccessAsync(
client.ClientId, customerId, enabled: true, reason: null);
_logger.LogInformation("Auto-unlocked customer {CustomerId} for client {ClientId} (no longer overdue).", customerId, client.ClientId);
}
}
}
}