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;
}