using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using wms.dto.response.sx;
using wms.sqlsugar.model.sx;
namespace wms.service.Extensions
{
///
/// 时效服务扩展
///
public static class SxServiceExtension
{
///
/// 装箱时处理焊点盘
///
/// 箱号对应的装箱规则
/// 库存信息
/// 后续可用的不带焊点盘信息
/// 填充后的焊点盘列表
public static List ProcessWeldingPointsBoxing(BillPboxrule rule, IEnumerable? invlist, out IEnumerable? outInvlist)
{
var solderinvlist = new List();
invlist ??= Enumerable.Empty();
// 如果不控制焊点盘数,则直接按生产时间排序后返回
if (rule.SolderMaxCount <= 0)
{
outInvlist = invlist.OrderBy(p => p.ProductTime);
return solderinvlist;
}
// 计算需要获取的焊点盘数量
int itemsPerBox = (rule.SpoolType == "BS60" || rule.SpoolType == "BS40") ? 72 : 36;
int requiredSolderBoxes = Math.Max(0, rule.FullCountQty / itemsPerBox * rule.SolderMaxCount);
// 获取所有带焊点的盘并排序
var availableSolders = invlist.Where(p => p.SolderCount > 0).OrderBy(p => p.ProductTime).ThenByDescending(p => p.SolderCount).ToList();
// 根据是否管控总焊点数量来选择不同的策略
if (rule.PerSolderMaxCount <= 0)
{
// 不管控总焊点数量,直接取前 N 个
solderinvlist = availableSolders.Take(requiredSolderBoxes).ToList();
}
else
{
// 管控总焊点数量,使用 GetWeldingPointsBoxing 方法
solderinvlist = GetWeldingPointsBoxing(
currentBoxes: solderinvlist,
maxBoxCount: requiredSolderBoxes,
maxTotalSolderCount: rule.PerSolderMaxCount,
inventory: availableSolders
);
}
// 剩余可用库存为无焊点的
outInvlist = invlist.Where(p => p.SolderCount == 0);
return solderinvlist;
}
///
/// 获取焊点盘(装箱处理)
///
/// 已有的焊点盘
/// 最大焊点盘数
/// 最大焊点总数
/// 库存信息
/// 填充后的焊点盘列表
public static List GetWeldingPointsBoxing(List currentBoxes, int maxBoxCount, int maxTotalSolderCount, IEnumerable? inventory)
{
if (inventory == null || !inventory.Any()) return currentBoxes;
// 当前状态统计
var currentBoxCount = currentBoxes.Count;
var currentTotalSolderCount = currentBoxes.Sum(x => x.SolderCount);
// 如果已经满载,直接返回
if (currentBoxCount >= maxBoxCount || currentTotalSolderCount >= maxTotalSolderCount) return currentBoxes;
// 将库存转换为列表并排序,避免重复排序
var availableInventory = inventory.Where(p => p.SolderCount > 0).OrderBy(p => p.ProductTime).ThenByDescending(p => p.SolderCount).ToList();
foreach (var item in availableInventory)
{
// 判断是否还能继续添加
if (currentBoxCount >= maxBoxCount || currentTotalSolderCount >= maxTotalSolderCount) break;
// 添加当前项
currentBoxes.Add(item);
currentBoxCount++;
currentTotalSolderCount += item.SolderCount;
}
return currentBoxes;
}
}
}