diff --git a/OpenNest.Data/MaterialLedger/LedgerHoldSummary.cs b/OpenNest.Data/MaterialLedger/LedgerHoldSummary.cs index c77ea34b..74496c91 100644 --- a/OpenNest.Data/MaterialLedger/LedgerHoldSummary.cs +++ b/OpenNest.Data/MaterialLedger/LedgerHoldSummary.cs @@ -50,7 +50,7 @@ public sealed class LedgerHoldSummary public int OpenHolds { get; } - /// Holds in any other status: closed, cancelled, exception or unknown. + /// Holds in any other status: released, closed, cancelled, exception or unknown. public int ClosedHolds { get; } /// Sheets without an open hold. diff --git a/OpenNest.Data/MaterialLedger/LedgerHolds.cs b/OpenNest.Data/MaterialLedger/LedgerHolds.cs index 13a1f1ae..fe761171 100644 --- a/OpenNest.Data/MaterialLedger/LedgerHolds.cs +++ b/OpenNest.Data/MaterialLedger/LedgerHolds.cs @@ -30,13 +30,13 @@ public static class LedgerHoldStatuses public const string Exception = "Exception"; /// - /// True for holds that still keep a sheet for the nest and need closing out. Closed, - /// cancelled, exception and unknown statuses are not open. + /// 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, cancelled, 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, Released, StringComparison.OrdinalIgnoreCase) || string.Equals(status, AwaitingCloseout, StringComparison.OrdinalIgnoreCase); } diff --git a/OpenNest.Tests/Data/LedgerHoldSummaryTests.cs b/OpenNest.Tests/Data/LedgerHoldSummaryTests.cs index b1e75d14..1081af9c 100644 --- a/OpenNest.Tests/Data/LedgerHoldSummaryTests.cs +++ b/OpenNest.Tests/Data/LedgerHoldSummaryTests.cs @@ -23,19 +23,20 @@ public class LedgerHoldSummaryTests [Fact] public void AllSheetsHeld() { - var summary = Summarize(4, Hold("Approved"), Hold("Released"), Hold("Proposed"), Hold("AwaitingCloseout")); + var summary = Summarize(4, Hold("Approved"), Hold("Approved"), Hold("Proposed"), Hold("AwaitingCloseout")); Assert.Equal(LedgerHoldState.Held, summary.State); Assert.Equal("Ledger: 4 of 4 sheets held", summary.Text); Assert.Equal(0, summary.ShortSheets); } + // ML's Release lets a hold go: the sheet is free stock again, so the nest is short of it. [Fact] - public void ClosedAndUnknownHoldsDoNotCountAsHeld() + public void ReleasedClosedAndUnknownHoldsDoNotCountAsHeld() { - var summary = Summarize(4, Hold("Approved"), Hold("Released"), Hold("ClosedConsumed"), + var summary = Summarize(4, Hold("Approved"), Hold("Proposed"), Hold("Released"), Hold("ClosedConsumed"), Hold("Cancelled"), Hold("Exception"), Hold("OnTruck")); Assert.Equal(LedgerHoldState.Short, summary.State); - Assert.Equal((2, 4, 2), (summary.OpenHolds, summary.ClosedHolds, summary.ShortSheets)); + Assert.Equal((2, 5, 2), (summary.OpenHolds, summary.ClosedHolds, summary.ShortSheets)); Assert.Equal("Ledger: 2 of 4 held, 2 short", summary.Text); } diff --git a/OpenNest.WinForms.Tests/Forms/NestHoldStatusTests.cs b/OpenNest.WinForms.Tests/Forms/NestHoldStatusTests.cs index c3513473..d9ec6dc5 100644 --- a/OpenNest.WinForms.Tests/Forms/NestHoldStatusTests.cs +++ b/OpenNest.WinForms.Tests/Forms/NestHoldStatusTests.cs @@ -47,7 +47,7 @@ public class NestHoldStatusTests var document = Bound(sheets: 4); var changes = 0; HttpRequestMessage seen = null; - var status = Status(document, databaseMode: true, request => { seen = request; return Holds("Approved", "Released"); }); + var status = Status(document, databaseMode: true, request => { seen = request; return Holds("Approved", "Proposed", "Released"); }); status.Changed += (_, _) => changes++; await status.RefreshAfterSaveAsync(); @@ -56,7 +56,7 @@ public class NestHoldStatusTests Assert.False(status.IsRefreshing); Assert.Equal("Ledger: 2 of 4 held, 2 short", status.Summary.Text); Assert.Contains(document.RemoteId.ToString("D"), seen.RequestUri!.Query); - Assert.Equal($"http://ledger:5000/Nests/{document.RemoteId:D}", status.LedgerNestUrl); + Assert.Equal($"http://ledger:5000/Nests/Details/{document.RemoteId:D}", status.LedgerNestUrl); Assert.Equal(2, changes); // Refreshing, then the answer. // An on-demand refresh counts the sheets of the last save, not unsaved edits. diff --git a/OpenNest/Forms/NestHoldStatus.cs b/OpenNest/Forms/NestHoldStatus.cs index 4e772a63..70b467f3 100644 --- a/OpenNest/Forms/NestHoldStatus.cs +++ b/OpenNest/Forms/NestHoldStatus.cs @@ -60,7 +60,7 @@ namespace OpenNest.Forms public bool IsVisible => IsApplicable && (Summary != null || IsRefreshing); /// The nest's page in MaterialLedger, where its holds are closed out. - public string LedgerNestUrl => $"{ledgerSettings().BaseUrl.TrimEnd('/')}/Nests/{document.RemoteId:D}"; + public string LedgerNestUrl => $"{ledgerSettings().BaseUrl.TrimEnd('/')}/Nests/Details/{document.RemoteId:D}"; /// /// Rereads the holds after the nest was opened or saved, counting the sheets of the nest diff --git a/docs/nest-storage.md b/docs/nest-storage.md index ca165409..6c50e274 100644 --- a/docs/nest-storage.md +++ b/docs/nest-storage.md @@ -172,9 +172,11 @@ Each read uses `MaterialLedgerClient.GetHoldsAsync` (`GET /api/stock/holds?openN **Summary.** `LedgerHoldSummary` (`OpenNest.Data/MaterialLedger/`) compares the open holds with the sheets of the last open or save: the sum of plate quantities, -skipping the trailing empty plate as `/sheets` does. Proposed, Approved, Released -and AwaitingCloseout holds are open. Closed, cancelled, exception and unknown -statuses are listed but not counted; unknown status strings are kept as sent. +skipping the trailing empty plate as `/sheets` does. Proposed, Approved and +AwaitingCloseout holds are open, the statuses ML counts against free stock. Released +means the hold was let go, not sent to cutting, so it is listed but not counted, as +are closed, cancelled, exception and unknown statuses; unknown status strings are kept +as sent. | Holds | Label | |-------|-------| @@ -189,7 +191,7 @@ nest's material label beside it. **Has Been Cut.** When Nest Info changes the status to Has Been Cut, the desktop rereads the holds. If any are still open, it shows a non-modal note, "Close out N holds -in MaterialLedger", with a link to `{ledgerUrl}/Nests/{id}`. Closeout happens there. +in MaterialLedger", with a link to `{ledgerUrl}/Nests/Details/{id}`. Closeout happens there. The note never blocks the dialog, save or post, and posting is not gated on holds. ### Generated nest names