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