mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 22:01:07 -04:00
fix(desktop): count only active MaterialLedger holds and link the nest page
MaterialLedger's Release lets a hold go, so a Released hold no longer keeps
a sheet for the nest; only Proposed, Approved and AwaitingCloseout holds,
the statuses ML counts against free stock, are open. The Has Been Cut
note's link pointed at /Nests/{id}, which ML does not serve; its nest page
is /Nests/Details/{id}.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c27188c722
commit
079dfaf9ea
6 files changed
+18
-15
No files matched your search
@@ -50,7 +50,7 @@ public sealed class LedgerHoldSummary
|
||||
|
||||
public int OpenHolds { get; }
|
||||
|
||||
/// <summary>Holds in any other status: closed, cancelled, exception or unknown.</summary>
|
||||
/// <summary>Holds in any other status: released, closed, cancelled, exception or unknown.</summary>
|
||||
public int ClosedHolds { get; }
|
||||
|
||||
/// <summary>Sheets without an open hold.</summary>
|
||||
|
||||
@@ -30,13 +30,13 @@ public static class LedgerHoldStatuses
|
||||
public const string Exception = "Exception";
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace OpenNest.Forms
|
||||
public bool IsVisible => IsApplicable && (Summary != null || IsRefreshing);
|
||||
|
||||
/// <summary>The nest's page in MaterialLedger, where its holds are closed out.</summary>
|
||||
public string LedgerNestUrl => $"{ledgerSettings().BaseUrl.TrimEnd('/')}/Nests/{document.RemoteId:D}";
|
||||
public string LedgerNestUrl => $"{ledgerSettings().BaseUrl.TrimEnd('/')}/Nests/Details/{document.RemoteId:D}";
|
||||
|
||||
/// <summary>
|
||||
/// Rereads the holds after the nest was opened or saved, counting the sheets of the nest
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user