using FastEndpoints; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Framework.ResponseStandard; using GB5Shared.FastEndPoint; using QMSBLL.Matrix; using static GB5Shared.GB5Constant.Constant; namespace QMSSL.EndPoints.Matrix; public class ExplodeBOM : BaseEndpoint> { private readonly IMatrixBLL _bll; public ExplodeBOM(IMatrixBLL bll) => _bll = bll; public override void Configure() { Get("/Matrix/ExplodeBOM"); AllowAnonymous(); Description(x => x .WithTags("Matrix") .WithSummary("Explode BOM") .WithDescription("Explodes the Bill of Materials for the given production item and set range. Returns two arrays: Input (component/RM lines, BOMLEVEL != 0) with RequiredQty calculated as FINALQUANTITY × SetCount, and Output (FG production item line, BOMLEVEL = 0) with QuantityPer, RequiredQty, and SetNumber. Use these arrays to pre-populate the MatrixDTO before calling SaveMatrix. Optionally pass AllotedAllocationId to validate SetFrom/SetTo against the sets actually generated for that allocation (via GetGeneratedSets) — rejects with 400 if any set in the range wasn't generated.")); } public record Params( [property: FromHeader] string Login, [property: QueryParam] int ProductItemId, [property: QueryParam] int SetFrom, [property: QueryParam] int SetTo, [property: QueryParam] int? AllotedAllocationId = null); protected override string? GetCacheKey(Params req, LoginDTO login) => null; protected override async Task> ExecuteAsync( Params req, LoginDTO login, CancellationToken ct) { try { if (req.ProductItemId == 0) return await GB5Shared.ResponseStandard.Response .CreateExceptionError( new ArgumentException("ProductItemId is required."), CacheKeyLevel.CLIENT_LEVEL, login, "ProductItemId is required.", 400); if (req.SetFrom > req.SetTo) return await GB5Shared.ResponseStandard.Response .CreateExceptionError( new ArgumentException("SetFrom cannot be greater than SetTo."), CacheKeyLevel.CLIENT_LEVEL, login, "SetFrom cannot be greater than SetTo.", 400); string result = await _bll.ExplodeBOMAsync( req.ProductItemId, req.SetFrom, req.SetTo, login, ct, req.AllotedAllocationId); return await GB5Shared.ResponseStandard.Response .CreateSuccessResponse(result, CacheKeyLevel.CLIENT_LEVEL, login); } catch (InvalidOperationException ex) { // SetFrom/SetTo-vs-generated-sets validation and "no BOM found" both // surface here as InvalidOperationException from the BLL — these are // caller input problems, not server faults, so 400 not 500. return await GB5Shared.ResponseStandard.Response .CreateExceptionError(ex, CacheKeyLevel.CLIENT_LEVEL, login, ex.Message, 400); } catch (Exception ex) { return await GB5Shared.ResponseStandard.Response .CreateExceptionError(ex, CacheKeyLevel.CLIENT_LEVEL, login, ex.Message, 500); } } }