using System.Globalization; using YY.Admin.Core.Entity; namespace YY.Admin.Services.Service.MixerMaterialTareStrategy; /// /// 密炼物料皮重策略匹配:按密炼物料、供应商、入场日期、每份重量(对应策略物料规格)筛选。 /// public static class MixerMaterialTareStrategyMatcher { public static List FilterCandidates( IEnumerable strategies, string? mixerMaterialId, string? supplierId, DateTime? entryDate, double? portionWeight) { if (string.IsNullOrWhiteSpace(mixerMaterialId) || string.IsNullOrWhiteSpace(supplierId)) { return new List(); } var entryDay = entryDate?.Date; return strategies .Where(s => string.Equals(s.MixerMaterialId, mixerMaterialId, StringComparison.OrdinalIgnoreCase)) .Where(s => string.Equals(s.SupplierId, supplierId, StringComparison.OrdinalIgnoreCase)) .Where(s => IsEntryDateInRange(entryDay, s.EffectiveStartDate, s.EffectiveEndDate)) .Where(s => MaterialSpecMatchesPortionWeight(s.MaterialSpec, portionWeight)) .OrderByDescending(s => s.EffectiveStartDate ?? DateTime.MinValue) .ThenByDescending(s => s.CreateTime ?? DateTime.MinValue) .ToList(); } public static MesXslMixerMaterialTareStrategy? PickBestMatch( IEnumerable strategies, string? mixerMaterialId, string? supplierId, DateTime? entryDate, double? portionWeight) { var list = FilterCandidates(strategies, mixerMaterialId, supplierId, entryDate, portionWeight); return list.FirstOrDefault(); } public static bool IsEntryDateInRange(DateTime? entryDay, DateTime? start, DateTime? end) { if (!entryDay.HasValue || !start.HasValue || !end.HasValue) { return false; } var day = entryDay.Value.Date; return day >= start.Value.Date && day <= end.Value.Date; } /// 策略「物料规格」与拆码明细「每份重量」比对(支持数值或文本形式)。 public static bool MaterialSpecMatchesPortionWeight(string? materialSpec, double? portionWeight) { if (!portionWeight.HasValue) { return string.IsNullOrWhiteSpace(materialSpec); } var weight = portionWeight.Value; if (string.IsNullOrWhiteSpace(materialSpec)) { return false; } var spec = materialSpec.Trim(); if (double.TryParse(spec, NumberStyles.Float, CultureInfo.InvariantCulture, out var specNum)) { return Math.Abs(specNum - weight) < 0.0001d; } var weightText = weight.ToString("0.##", CultureInfo.InvariantCulture); return string.Equals(spec, weightText, StringComparison.OrdinalIgnoreCase) || string.Equals(spec, weight.ToString(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase); } }