Files
OpenNest/OpenNest.IO/Bom/BomImportSummary.cs
T
aj 81d3253580 feat(bom): validate edited part quantities
Prepare BOM rows for quantity editing:

- BomQuantity.TryParse accepts only a whole number of at least 1
  (surrounding spaces allowed; no sign, decimal, exponent, separator or
  overflow).
- BomPartRow keeps the BOM's own quantity (BomQty), refuses invalid
  typed quantities in TrySetQuantity, and raises PropertyChanged for
  Material, Thickness and Qty plus the status they affect, so a bound
  grid can refresh.
- A blank BOM quantity becomes 1, as it was imported before, but is now
  visible in the row and counted in the summary ("had no BOM quantity
  (1 used)"). A BOM quantity below 1 is no longer imported as 0: the
  row reads "Needs quantity" until the operator enters one.

BomImportFlowTests covers BOM items to rows to an edited quantity to the
group total and the created nest's required quantity. Mutation reds:
a zero floor, signed or decimal input, ignoring the quantity in the
status, not assuming 1 for blanks, setting unparsed text and dropping
the status notification each fail the Bom tests.
2026-10-05 17:56:35 -04:00

40 lines
1.6 KiB
C#

using System.Collections.Generic;
using System.Linq;
namespace OpenNest.IO.Bom;
/// <summary>The import dialog's one-line summary of the part rows.</summary>
public static class BomImportSummary
{
/// <summary>
/// For example "12 ready, 2 need a thickness, 1 no drawing found, 3 had
/// no BOM quantity (1 used)".
/// </summary>
public static string Describe(IEnumerable<BomPartRow> rows)
{
var list = rows.ToList();
var counts = list.GroupBy(r => r.Status).ToDictionary(g => g.Key, g => g.Count());
int Count(BomRowStatus status) => counts.TryGetValue(status, out var n) ? n : 0;
var parts = new List<string> { $"{Count(BomRowStatus.Ready)} ready" };
Add(parts, Count(BomRowStatus.NeedsMaterial), "needs a material", "need a material");
Add(parts, Count(BomRowStatus.NeedsThickness), "needs a thickness", "need a thickness");
Add(parts, Count(BomRowStatus.NeedsQuantity), "needs a quantity", "need a quantity");
Add(parts, Count(BomRowStatus.NoDrawing), "no drawing found", "no drawing found");
Add(parts, Count(BomRowStatus.NoFileName), "no file name", "no file name");
Add(
parts,
list.Count(r => r.IsEditable && r.QtyAssumed),
"had no BOM quantity (1 used)",
"had no BOM quantity (1 used)"
);
return string.Join(", ", parts);
}
private static void Add(List<string> parts, int count, string one, string many)
{
if (count > 0)
parts.Add($"{count} {(count == 1 ? one : many)}");
}
}