namespace OpenNest.Data.MaterialLedger; /// The body of MaterialLedger's GET /api/stock/holds?openNestNestId=. public sealed record LedgerHoldsResponse(Guid OpenNestNestId, IReadOnlyList? Holds); /// /// One ML MaterialReservation for a sheet of the nest. Sizes are inches with /// the short side. stays a string so a new ML /// ReservationStatus value still deserializes. /// public sealed record LedgerHold( long MaterialReservationId, string ItemCode, decimal WidthIn, decimal LengthIn, string Status, string? LocationCode, DateTime CreatedAtUtc); /// ML ReservationStatus names. public static class LedgerHoldStatuses { public const string Proposed = "Proposed"; public const string Approved = "Approved"; public const string Released = "Released"; public const string AwaitingCloseout = "AwaitingCloseout"; public const string ClosedConsumed = "ClosedConsumed"; public const string ClosedReturned = "ClosedReturned"; public const string Canceled = "Cancelled"; public const string Exception = "Exception"; /// /// True for holds that still keep a sheet for the nest and need closing out: the statuses ML /// counts against free stock. Released means the hold was let go, not sent to cutting, so it /// is not open; nor are closed, canceled, exception and unknown statuses. /// public static bool IsOpen(string? status) => string.Equals(status, Proposed, StringComparison.OrdinalIgnoreCase) || string.Equals(status, Approved, StringComparison.OrdinalIgnoreCase) || string.Equals(status, AwaitingCloseout, StringComparison.OrdinalIgnoreCase); } /// What a ledger hold request came to. Expected failures are results, never exceptions. public abstract record LedgerHoldsResult { private LedgerHoldsResult() { } /// No ledger URL is set on this PC. public sealed record NotConfigured : LedgerHoldsResult; /// The ledger did not answer usefully: network error, timeout, bad status or body. public sealed record Unreachable(string Reason) : LedgerHoldsResult; /// The ledger rejected the API key (401/403). public sealed record Unauthorized : LedgerHoldsResult; /// The nest's holds in every status; empty when ML has none for it. public sealed record Ok(IReadOnlyList Holds) : LedgerHoldsResult; }