namespace OpenNest.Data.MaterialLedger; /// /// The body of MaterialLedger's GET /api/stock/opennest: the /api/stock shape plus /// , false when ML has no approved mapping for the OpenNest material. /// public sealed record LedgerStockResponse( bool Mapped, IReadOnlyList? Specs, IReadOnlyList? Items); /// /// Mirrors ML StockApi.OpenNestStockSpecDto. is the spec's place in ML's /// acceptance rule (0 an exact mapping, 1 preferred, higher a substitute); an older ledger sends /// neither it nor the catalog names, so they stay null and the spec counts as rank 1. /// public sealed record LedgerStockSpec(long MaterialSpecId, string DisplayName, decimal ThicknessIn, string? GaugeLabel) { public int? Rank { get; init; } public string? MaterialFamily { get; init; } public string? Grade { get; init; } public string? Finish { get; init; } } /// /// Mirrors ML StockApi.StockItemDto. Sizes are inches with the short /// side; is free after active holds. and /// stay strings so a new ML enum value still deserializes. /// is its spec's rank, null from an older ledger. /// public sealed record LedgerStockItem( string ItemCode, long MaterialSpecId, string Kind, decimal WidthIn, decimal LengthIn, int Quantity, string Shape, string LocationCode, string LocationName, string? ParentLocationCode, decimal? CostPerUnit, DateTime LastObservedAtUtc) { public int? Rank { get; init; } } /// ML InventoryItemKind names. public static class LedgerItemKinds { public const string FullSheetBundle = "FullSheetBundle"; public const string FullSheet = "FullSheet"; public const string Drop = "Drop"; } /// ML ShapeClassification names. public static class LedgerItemShapes { public const string Rectangular = "Rectangular"; public const string IrregularConservativeRectangle = "IrregularConservativeRectangle"; public const string Unknown = "Unknown"; } /// What a ledger stock request came to. Expected failures are results, never exceptions. public abstract record LedgerStockResult { private LedgerStockResult() { } /// No ledger URL is set on this PC. public sealed record NotConfigured : LedgerStockResult; /// The ledger did not answer usefully: network error, timeout, bad status or body. public sealed record Unreachable(string Reason) : LedgerStockResult; /// The ledger rejected the API key (401/403). public sealed record Unauthorized : LedgerStockResult; /// The ledger has no approved mapping for this material, grade and thickness. public sealed record Unmapped : LedgerStockResult; public sealed record Ok(IReadOnlyList Specs, IReadOnlyList Items) : LedgerStockResult; }