refactor(jobs): modularize background job handlers
Some checks failed
ci / release-gate (push) Has been cancelled
Some checks failed
ci / release-gate (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Tiku.Application.Jobs;
|
||||
using Tiku.Domain.Commerce;
|
||||
using Tiku.Domain.Tenancy;
|
||||
using Tiku.Infrastructure.Jobs;
|
||||
using Tiku.Infrastructure.Persistence;
|
||||
|
||||
namespace Tiku.Infrastructure.Commerce.Reconciliation;
|
||||
|
||||
internal sealed class CommerceReconciliationJobHandler(TikuDbContext dbContext) : IBackgroundJobHandler
|
||||
{
|
||||
public string JobType => "commerce_reconciliation";
|
||||
|
||||
public async Task<BackgroundJobHandlerResult> HandleAsync(
|
||||
BackgroundJobExecutionContext context,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var provider = NormalizeProvider(BackgroundJobPayload.GetString(context.Payload, "provider"));
|
||||
var hasProviderConfig = await dbContext.TenantExternalProviders.AnyAsync(
|
||||
item =>
|
||||
item.TenantId == context.TenantId &&
|
||||
item.Capability == TenantExternalProviderCapability.Payment &&
|
||||
item.Provider == provider &&
|
||||
item.Status == TenantExternalProviderStatus.Active,
|
||||
cancellationToken);
|
||||
if (!hasProviderConfig)
|
||||
throw new InvalidOperationException(
|
||||
$"Active payment provider '{provider}' is required for commerce reconciliation job.");
|
||||
|
||||
var billDate = BackgroundJobPayload.GetDateOnly(context.Payload, "billDate") ??
|
||||
DateOnly.FromDateTime(DateTime.UtcNow.Date);
|
||||
var billType = BackgroundJobPayload.GetEnum(context.Payload, "billType", ReconciliationBillType.Combined);
|
||||
var sourceHash = $"background-job:{context.JobId:N}";
|
||||
var batch = await dbContext.CommerceReconciliationBatches.SingleOrDefaultAsync(
|
||||
item =>
|
||||
item.TenantId == context.TenantId &&
|
||||
item.Provider == provider &&
|
||||
item.Source == ReconciliationSource.ProviderDownload &&
|
||||
item.SourceHash == sourceHash,
|
||||
cancellationToken);
|
||||
if (batch is null)
|
||||
{
|
||||
batch = new CommerceReconciliationBatch
|
||||
{
|
||||
TenantId = context.TenantId,
|
||||
Provider = provider,
|
||||
BillDate = billDate,
|
||||
BillType = billType,
|
||||
Source = ReconciliationSource.ProviderDownload,
|
||||
SourceName = $"provider-bill:{provider}:{billDate:yyyyMMdd}",
|
||||
SourceHash = sourceHash,
|
||||
Status = ReconciliationBatchStatus.Pending,
|
||||
Metadata = JsonSerializer.SerializeToElement(new
|
||||
{
|
||||
jobId = context.JobId,
|
||||
note =
|
||||
"Provider bill job created the reconciliation batch; provider download/parser is handled by a dedicated provider processor."
|
||||
})
|
||||
};
|
||||
dbContext.CommerceReconciliationBatches.Add(batch);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
return new BackgroundJobHandlerResult(JsonSerializer.SerializeToElement(new
|
||||
{
|
||||
batchId = batch.Id,
|
||||
provider,
|
||||
billDate,
|
||||
billType = billType.ToString(),
|
||||
status = batch.Status.ToString()
|
||||
}));
|
||||
}
|
||||
|
||||
private static string NormalizeProvider(string? provider)
|
||||
{
|
||||
var normalized = (provider ?? string.Empty).Trim().ToLowerInvariant();
|
||||
return string.IsNullOrWhiteSpace(normalized)
|
||||
? throw new InvalidOperationException("Background job provider is required.")
|
||||
: normalized;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user