93 lines
3.0 KiB
C#
93 lines
3.0 KiB
C#
using System.Globalization;
|
||
using YY.Admin.Core.Entity;
|
||
|
||
namespace YY.Admin.Core.Util;
|
||
|
||
/// <summary>
|
||
/// 「已入场重量」桌面端本地累计计算器。
|
||
/// 与后端 IMesXslRawMaterialEntryService.sumEnteredWeightByBillNos 保持同一口径:
|
||
/// ① 把 totalPortions / portionWeight 按 "x/y/z/" 拆分
|
||
/// ② 逐位 (份数 × 每份重量) 累加,得到该 entry 的小计
|
||
/// ③ 同一榜单(BillNo)下所有 entry 的小计再次累加
|
||
/// 任一位置解析失败或缺失:静默跳过,保证 UI 降级可用。
|
||
/// </summary>
|
||
public static class EnteredWeightCalculator
|
||
{
|
||
/// <summary>累计一条入场记录的小计。</summary>
|
||
public static double SumOneEntry(string? totalPortions, string? portionWeight)
|
||
{
|
||
var portions = SplitJoined(totalPortions);
|
||
var weights = SplitJoined(portionWeight);
|
||
if (portions.Length == 0 || weights.Length == 0)
|
||
{
|
||
return 0d;
|
||
}
|
||
var n = Math.Min(portions.Length, weights.Length);
|
||
double sum = 0d;
|
||
for (var i = 0; i < n; i++)
|
||
{
|
||
if (!TryParse(portions[i], out var p) || !TryParse(weights[i], out var w))
|
||
{
|
||
continue;
|
||
}
|
||
sum += p * w;
|
||
}
|
||
return sum;
|
||
}
|
||
|
||
/// <summary>按 BillNo 分组累计「已入场重量」。返回 Dictionary<BillNo, 总和>。</summary>
|
||
public static Dictionary<string, double> SumByBillNos(
|
||
IEnumerable<MesXslRawMaterialEntry> entries,
|
||
IEnumerable<string?> billNos)
|
||
{
|
||
var keys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||
foreach (var b in billNos)
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(b)) keys.Add(b!);
|
||
}
|
||
var result = new Dictionary<string, double>(StringComparer.OrdinalIgnoreCase);
|
||
if (keys.Count == 0)
|
||
{
|
||
return result;
|
||
}
|
||
|
||
foreach (var e in entries)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(e.BillNo) || !keys.Contains(e.BillNo!))
|
||
{
|
||
continue;
|
||
}
|
||
var sub = SumOneEntry(e.TotalPortions, e.PortionWeight);
|
||
if (sub == 0d)
|
||
{
|
||
continue;
|
||
}
|
||
if (result.TryGetValue(e.BillNo!, out var acc))
|
||
{
|
||
result[e.BillNo!] = acc + sub;
|
||
}
|
||
else
|
||
{
|
||
result[e.BillNo!] = sub;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
private static string[] SplitJoined(string? value)
|
||
{
|
||
// 兼容 "x/y/z" 与 "x/y/z/" 两种格式;过滤空段
|
||
if (string.IsNullOrWhiteSpace(value))
|
||
{
|
||
return Array.Empty<string>();
|
||
}
|
||
return value.Split('/')
|
||
.Select(s => s.Trim())
|
||
.Where(s => s.Length > 0)
|
||
.ToArray();
|
||
}
|
||
|
||
private static bool TryParse(string s, out double v) =>
|
||
double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out v);
|
||
}
|