using ComplianceDAL.DTO.GSTEWayBill; using ComplianceDAL.Query.GSTEWayBill; using GB5Shared.DTO.Framework.Login; using GB5Shared.QueryExecutor; using Microsoft.Extensions.Logging; namespace ComplianceDAL.CustomCode.GSTEWayBill; // Faithful port of GB4's EWayDAL.EwayBillOffline (header/detail build + mainHsnCode resolution), // minus the ClearTax-specific branch, per explicit instruction. Independent of the E-Invoice // canonical builder — CanonicalBuilderDAL/QB are neither referenced nor modified here. public class EWayBillPayloadBuilderDAL : IEWayBillPayloadBuilderDAL { private readonly IQueryExecutor _queryExecutor; private readonly ILogger _logger; public EWayBillPayloadBuilderDAL(IQueryExecutor queryExecutor, ILogger logger) { _queryExecutor = queryExecutor; _logger = logger; } public async Task BuildEwayBillOffLineAsync(int documentId, LoginDTO login, CancellationToken ct) { try { var billList = await _queryExecutor.QuerySingleAsync( login, EWayBillPayloadQB.GET_EWAY_HEADER, new { DocumentId = documentId, ClientId = login.ClientId }, cancellationToken: ct).ConfigureAwait(false); if (billList is null) return null; billList.actualFromStateCode = billList.fromStateCode; billList.actualToStateCode = billList.toStateCode; billList.vehicleType = "R"; var itemList = await _queryExecutor.QueryAsync( login, EWayBillPayloadQB.GET_EWAY_DETAIL, new { DocumentId = documentId }, cancellationToken: ct).ConfigureAwait(false); billList.itemList = itemList.OrderBy(i => i.itemNo).ToList(); if (billList.itemList.Count > 0) { if (billList.subSupplyType == 4) { await ResolveMainHsnCodeForJobWorkAsync(documentId, billList, login, ct).ConfigureAwait(false); } else { billList.mainHsnCode = billList.itemList[^1].hsnCode; } } return new EwayBillOffLineDTO { billLists = [billList] }; } catch (Exception ex) { _logger.LogError(ex, "E-Way Bill payload DAL: BuildEwayBillOffLineAsync failed for DocumentId {DocumentId}", documentId); throw; } } // subSupplyType == 4 (Job Work) resolves mainHsnCode from the linked MDUTYTARIFF process record // instead of the last line's HSN — matches GB4's SacResult / GET_BIZ_CLASS_FOR_DOC fallback exactly. private async Task ResolveMainHsnCodeForJobWorkAsync(int documentId, EwayBillList billList, LoginDTO login, CancellationToken ct) { var sacCodes = await _queryExecutor.QueryAsync( login, EWayBillPayloadQB.GET_EWAY_SAC_CODE, new { DocumentId = documentId }, cancellationToken: ct).ConfigureAwait(false); var sacCode = sacCodes.FirstOrDefault(); if (string.IsNullOrEmpty(sacCode)) { var bizClassCount = await _queryExecutor.ExecuteScalarAsync( login, EWayBillPayloadQB.GET_BIZ_CLASS_FOR_DOC, new { DocumentId = documentId }, cancellationToken: ct).ConfigureAwait(false); if (bizClassCount != 1) throw new InvalidOperationException("No MMdetailProcess is linked.."); // Miscellaneous Delivery Challan — process not needed, mainHsnCode stays 0 (matches GB4). } else { if (!int.TryParse(sacCode, out var parsedHsn)) throw new InvalidOperationException("Pl check HSN code linked to MMdetailProcess ,ProcessId"); billList.mainHsnCode = parsedHsn; } } }