using ComplianceBLL.CanonicalBuilder; using ComplianceDAL.CustomCode.ComplianceArtifact; using ComplianceDAL.DTO.CanonicalInvoice; using ComplianceDAL.DTO.ComplianceArtifact; using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using Microsoft.Extensions.Logging; using Newtonsoft.Json; namespace ComplianceBLL.ComplianceArtifact; public class ComplianceArtifactBLL : IComplianceArtifactBLL { private readonly IComplianceArtifactDAL _dal; private readonly ICanonicalBuilderBLL _canonicalBuilder; private readonly AutoNumber _autoNumber; private readonly ILogger _logger; public ComplianceArtifactBLL( IComplianceArtifactDAL dal, ICanonicalBuilderBLL canonicalBuilder, AutoNumber autoNumber, ILogger logger) { _dal = dal; _canonicalBuilder = canonicalBuilder; _autoNumber = autoNumber; _logger = logger; } public async Task CreateArtifactFromInvoiceAsync(InvoicePostedEvent evt, LoginDTO login, CancellationToken ct) { try { var existing = await _dal.GetArtifactBySource("Invoice", evt.DocumentId, "EInvoice", login, ct).ConfigureAwait(false); if (existing is not null) { _logger.LogInformation("Artifact already exists for DocumentId {DocumentId}, skipping", evt.DocumentId); return existing.ArtifactId; } var canonical = await _canonicalBuilder.BuildAsync(evt.DocumentId, login, ct).ConfigureAwait(false); if (canonical is null) { _logger.LogWarning("No ERP data found for DocumentId {DocumentId}", evt.DocumentId); return 0; } var autoNum = await _autoNumber.GetNumberAsync(1, "COMPLIANCEARTIFACT", login).ConfigureAwait(false); var artifactId = autoNum.StartNumber; var artifact = new ComplianceArtifactDTO { ArtifactId = artifactId, ArtifactType = "EInvoice", Framework = evt.Framework, SourceEntityType = "Invoice", SourceEntityId = evt.DocumentId, GSTIN = canonical.Supplier.GSTIN, ReturnPeriod = $"{canonical.DocumentDate:MMyyyy}", Status = "DRAFT", AttemptCount = 0, CreatedById = login.UserId, ModifiedById = login.UserId }; await _dal.SaveArtifact(artifact, login, ct).ConfigureAwait(false); var payloadAutoNum = await _autoNumber.GetNumberAsync(1, "COMPLIANCEPAYLOAD", login).ConfigureAwait(false); var payload = new CompliancePayloadDTO { PayloadId = payloadAutoNum.StartNumber, ArtifactId = artifactId, PayloadType = "Canonical", PayloadFormat = "JSON", Payload = JsonConvert.SerializeObject(canonical), AttemptNumber = 1 }; await _dal.SavePayload(payload, login, ct).ConfigureAwait(false); await _dal.SaveAudit(new ComplianceAuditDTO { ArtifactId = artifactId, Action = "STATE_CHANGE", PreviousState = "", NewState = "DRAFT", UserId = login.UserId, AttemptNumber = 1 }, login, ct).ConfigureAwait(false); _logger.LogInformation("Compliance artifact {ArtifactId} created for DocumentId {DocumentId}", artifactId, evt.DocumentId); return artifactId; } catch (Exception ex) { _logger.LogError(ex, "CreateArtifactFromInvoice failed for DocumentId {DocumentId}", evt.DocumentId); throw; } } public async Task UpdateArtifactStatus(int artifactId, string status, LoginDTO login, CancellationToken ct) { var existing = await _dal.GetArtifact(artifactId, login, ct).ConfigureAwait(false); if (existing is null) return; await _dal.UpdateArtifactStatus(artifactId, status, existing.AttemptCount + 1, login.UserId, login, ct).ConfigureAwait(false); await _dal.SaveAudit(new ComplianceAuditDTO { ArtifactId = artifactId, Action = "STATE_CHANGE", PreviousState = existing.Status, NewState = status, UserId = login.UserId, AttemptNumber = existing.AttemptCount + 1 }, login, ct).ConfigureAwait(false); } public async Task GetAuditLog(int artifactId, int page, int pageSize, LoginDTO login, CancellationToken ct) => await _dal.GetAuditLog(artifactId, page, pageSize, login, ct).ConfigureAwait(false); }