MRP修改
This commit is contained in:
parent
aa2b0501a5
commit
ba87992368
@ -59,6 +59,8 @@ namespace DOAN.Service.MES.mm.paintedparts_call
|
||||
.AndIF(parm.WorkOrderDate != null, it => it.WorkOrderDate == parm.WorkOrderDate)
|
||||
.And(it => it.Quantity > 0);
|
||||
var response = Queryable()
|
||||
.OrderBy(m => m.MaterialCode) // 按预定义的物料号顺序
|
||||
.OrderBy(m => m.LineCode)
|
||||
.Where(predicate.ToExpression())
|
||||
.ToPage<MmCallMrp, MmCallMrpDto>(parm);
|
||||
|
||||
@ -202,20 +204,49 @@ namespace DOAN.Service.MES.mm.paintedparts_call
|
||||
.Queryable<ProWorkorder>()
|
||||
.WhereIF(!string.IsNullOrEmpty(parm.LineCode) && !parm.LineCode.Contains("全部"), it => it.LineCode == parm.LineCode)
|
||||
.Where(x => x.WorkorderDate == checkDate)
|
||||
.Select(x => new { x.ProductionCode, x.DeliveryNum })
|
||||
.Select(x => new { x.ProductionCode, x.DeliveryNum, x.LineCode })
|
||||
.ToList();
|
||||
|
||||
List<string> lineProductionCodeList = workorders
|
||||
.Select(x => x.ProductionCode)
|
||||
.Distinct()
|
||||
// 1. 按ProductionCode和LineCode分组并计算每个组的累加数量
|
||||
var productionGroups = workorders
|
||||
.GroupBy(x => new { x.ProductionCode, x.LineCode })
|
||||
.Select(g => new
|
||||
{
|
||||
ProductionCode = g.Key.ProductionCode,
|
||||
LineCode = g.Key.LineCode,
|
||||
GroupTotal = g.Sum(x => x.DeliveryNum) ?? 0
|
||||
})
|
||||
.ToList();
|
||||
if (!lineProductionCodeList.Any())
|
||||
|
||||
if (!productionGroups.Any())
|
||||
{
|
||||
Context.Ado.RollbackTran();
|
||||
return 0;
|
||||
//throw new Exception("未找到该线别对应的工单");
|
||||
}
|
||||
|
||||
// 计算所有组的总数量
|
||||
int totalQuantityAcrossAllGroups = productionGroups.Sum(g => g.GroupTotal);
|
||||
if (totalQuantityAcrossAllGroups <= 0)
|
||||
{
|
||||
Context.Ado.RollbackTran();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 将总数量分成四份
|
||||
int baseBatch = totalQuantityAcrossAllGroups / 4;
|
||||
int remainder = totalQuantityAcrossAllGroups % 4;
|
||||
int[] batchQuantities = new int[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
batchQuantities[i] = baseBatch + (i < remainder ? 1 : 0);
|
||||
}
|
||||
|
||||
// 获取所有唯一的ProductionCode
|
||||
List<string> lineProductionCodeList = productionGroups
|
||||
.Select(x => x.ProductionCode)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
// 查询 BOM 表
|
||||
List<MmCallMaterialBom> mmCallMaterialBoms = Context
|
||||
.Queryable<MmCallMaterialBom>()
|
||||
@ -223,58 +254,10 @@ namespace DOAN.Service.MES.mm.paintedparts_call
|
||||
.Where(it => !string.IsNullOrEmpty(it.subInvCode))
|
||||
.ToList();
|
||||
|
||||
// 计算每个 ProductionCode 的 DeliveryNum 总和
|
||||
var totalDeliveryDict = workorders
|
||||
.GroupBy(x => x.ProductionCode)
|
||||
.ToDictionary(g => g.Key, g => g.Sum(x => x.DeliveryNum));
|
||||
|
||||
// 生成 MmCallRequests
|
||||
List<MmCallMrp> mmCallMrpList = new();
|
||||
|
||||
//// 1. 按工单顺序排序 (假设按ProductionCode排序,可根据实际需求调整)
|
||||
//var sortedWorkorders = workorders.OrderBy(x => x.ProductionCode).ToList();
|
||||
|
||||
//// 2. 计算总交货量并拆分为四组
|
||||
//int totalDeliveryNum = sortedWorkorders.Sum(x => x.DeliveryNum).Value;
|
||||
//int groupTarget = totalDeliveryNum / 4;
|
||||
|
||||
//List<List<dynamic>> groups = new List<List<dynamic>>();
|
||||
//List<dynamic> currentGroup = new List<dynamic>();
|
||||
//int currentSum = 0;
|
||||
|
||||
//foreach (var wo in sortedWorkorders)
|
||||
//{
|
||||
// currentGroup.Add(wo);
|
||||
// currentSum += wo.DeliveryNum.Value;
|
||||
|
||||
// if (currentSum >= groupTarget * (groups.Count + 1))
|
||||
// {
|
||||
// groups.Add(currentGroup);
|
||||
// currentGroup = new List<dynamic>();
|
||||
// currentSum = 0;
|
||||
// }
|
||||
//}
|
||||
|
||||
//// 处理剩余工单
|
||||
//if (currentGroup.Any())
|
||||
//{
|
||||
// if (groups.Count < 4)
|
||||
// {
|
||||
// groups.Add(currentGroup);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// groups[3].AddRange(currentGroup);
|
||||
// }
|
||||
//}
|
||||
|
||||
//// 确保有四组
|
||||
//while (groups.Count < 4)
|
||||
//{
|
||||
// groups.Add(new List<dynamic>());
|
||||
//}
|
||||
|
||||
// 3. 定义四个时间段
|
||||
// 定义四个时间段
|
||||
var timePeriods = new List<(DateTime Start, DateTime End)>
|
||||
{
|
||||
(checkDate.Date.AddHours(8), checkDate.Date.AddHours(10)), // 8:00~10:00
|
||||
@ -283,89 +266,117 @@ namespace DOAN.Service.MES.mm.paintedparts_call
|
||||
(checkDate.Date.AddHours(14), checkDate.Date.AddHours(16)) // 14:00~16:00
|
||||
};
|
||||
|
||||
// 4. 分时段计算物料需求
|
||||
foreach (var (startTime, endTime) in timePeriods)
|
||||
// 4. 为每个时间段分配批次数量(核心修复部分)
|
||||
foreach (var timePeriod in timePeriods.Select((tp, idx) => new { Period = tp, Index = idx }))
|
||||
{
|
||||
// 获取该组的ProductionCode列表并转换为HashSet以提高查找效率
|
||||
// 显式指定泛型类型参数确保从dynamic转换为string
|
||||
var groupProductionCodes = new HashSet<string>(lineProductionCodeList);
|
||||
var (startTime, endTime) = timePeriod.Period;
|
||||
int currentBatchIndex = timePeriod.Index;
|
||||
int currentBatchQuantity = batchQuantities[currentBatchIndex];
|
||||
|
||||
//// 计算该组的DeliveryNum字典
|
||||
//var groupDeliveryDict = group
|
||||
// .GroupBy(x => x.ProductionCode)
|
||||
// .ToDictionary(g => g.Key, g => g.Sum(x => x.DeliveryNum));
|
||||
if (currentBatchQuantity <= 0)
|
||||
continue;
|
||||
|
||||
// 按linecode与MaterialCode进行聚合统计
|
||||
var aggregatedData = mmCallMaterialBoms
|
||||
.Where(bom => groupProductionCodes.Contains(bom.InvCode))
|
||||
.GroupBy(bom => new
|
||||
{
|
||||
bom.subInvCode,
|
||||
bom.subInvName,
|
||||
bom.InvCode,
|
||||
bom.InvName
|
||||
})
|
||||
.Select(g => new
|
||||
{
|
||||
ProductionCode = g.Key.InvCode,
|
||||
ProductionName = g.Key.InvName,
|
||||
MaterialCode = g.Key.subInvCode,
|
||||
MaterialName = g.Key.subInvName,
|
||||
TotalQuantity = g.Sum(bom =>
|
||||
{
|
||||
int totalDeliveryNum = workorders
|
||||
.Where(w => w.ProductionCode == bom.InvCode)
|
||||
.Sum(w => w.DeliveryNum) ?? 0;
|
||||
// 计算比例分配比例
|
||||
decimal batchRatio = (decimal)currentBatchQuantity / totalQuantityAcrossAllGroups;
|
||||
|
||||
if (totalDeliveryNum <= 0)
|
||||
{
|
||||
return 0m; // 没有交货量则跳过
|
||||
}
|
||||
// 使用具体元组存储分配信息,避免dynamic类型问题
|
||||
var groupAllocations = new List<(string ProductionCode, string LineCode, int Allocated)>();
|
||||
int itemIndex = 0;
|
||||
|
||||
decimal iusequantity;
|
||||
if (!decimal.TryParse(bom.Iusequantity, out iusequantity))
|
||||
{
|
||||
Context.Ado.RollbackTran();
|
||||
throw new Exception($"{bom.subInvCode}BOM使用数量异常");
|
||||
}
|
||||
|
||||
return totalDeliveryNum * iusequantity;
|
||||
})
|
||||
})
|
||||
.ToList();
|
||||
|
||||
// 生成该时间段的物料需求记录
|
||||
foreach (var item in aggregatedData)
|
||||
foreach (var group in productionGroups)
|
||||
{
|
||||
mmCallMrpList.Add(
|
||||
new MmCallMrp
|
||||
int allocated = itemIndex < productionGroups.Count - 1
|
||||
? (int)Math.Round(group.GroupTotal * batchRatio)
|
||||
: currentBatchQuantity - groupAllocations.Sum(a => a.Allocated);
|
||||
|
||||
groupAllocations.Add((group.ProductionCode, group.LineCode, allocated));
|
||||
itemIndex++;
|
||||
}
|
||||
|
||||
// 生成当前时间段的物料需求记录
|
||||
foreach (var allocation in groupAllocations)
|
||||
{
|
||||
if (allocation.Allocated <= 0) continue;
|
||||
|
||||
// 获取BOM数据并计算需求
|
||||
var relatedBoms = mmCallMaterialBoms
|
||||
.Where(bom => bom.InvCode == allocation.ProductionCode)
|
||||
.ToList();
|
||||
|
||||
var aggregatedData = relatedBoms
|
||||
.GroupBy(bom => new { bom.subInvCode, bom.subInvName, bom.InvCode, bom.InvName })
|
||||
.Select(g => new
|
||||
{
|
||||
ProductionCode = g.Key.InvCode,
|
||||
ProductionName = g.Key.InvName,
|
||||
MaterialCode = g.Key.subInvCode,
|
||||
MaterialName = g.Key.subInvName,
|
||||
TotalQuantity = g.Sum(bom =>
|
||||
{
|
||||
decimal iusequantity;
|
||||
decimal.TryParse(bom.Iusequantity, out iusequantity);
|
||||
return allocation.Allocated * iusequantity;
|
||||
})
|
||||
})
|
||||
.ToList();
|
||||
|
||||
// 为每个物料创建带时间段信息的记录
|
||||
foreach (var item in aggregatedData)
|
||||
{
|
||||
mmCallMrpList.Add(new MmCallMrp
|
||||
{
|
||||
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
||||
LineCode = lineCode,
|
||||
LineCode = allocation.LineCode,
|
||||
WorkOrderDate = parm.WorkOrderDate.Value,
|
||||
ProductionCode = item.ProductionCode,
|
||||
ProductionName = item.ProductionName,
|
||||
MaterialCode = item.MaterialCode,
|
||||
MaterialName = item.MaterialName,
|
||||
Quantity = (int?)item.TotalQuantity,
|
||||
IssuanceTime =
|
||||
startTime.ToString("HH:mm") + "-" + endTime.ToString("HH:mm"),
|
||||
Sort = getSort(startTime),
|
||||
IssuanceTime = $"{startTime:HH:mm}-{endTime:HH:mm}",
|
||||
Sort = currentBatchIndex + 1,
|
||||
CreatedBy = "系统自动生成",
|
||||
CreatedTime = DateTime.Now,
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
mmCallMrpList = mmCallMrpList
|
||||
.Where(it => !string.IsNullOrEmpty(it.MaterialCode) &&
|
||||
(it.MaterialCode.Contains("-") || it.MaterialCode.Contains("—")))
|
||||
.ToList();
|
||||
|
||||
foreach (var mrp in mmCallMrpList.Take(10))
|
||||
// 过滤并合并相同物料号和线别的记录
|
||||
var processedList = mmCallMrpList
|
||||
.Where(it => !string.IsNullOrEmpty(it.MaterialCode) &&
|
||||
(it.MaterialCode.Contains("-") || it.MaterialCode.Contains("—")))
|
||||
.GroupBy(m => new { m.MaterialCode, m.LineCode, m.IssuanceTime }) // 按时间段分组合并
|
||||
.Select(g => new MmCallMrp
|
||||
{
|
||||
Console.WriteLine($"MaterialCode: {mrp.MaterialCode}");
|
||||
}
|
||||
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
||||
LineCode = g.Key.LineCode,
|
||||
WorkOrderDate = g.First().WorkOrderDate,
|
||||
ProductionCode = g.First().ProductionCode,
|
||||
ProductionName = g.First().ProductionName,
|
||||
MaterialCode = g.Key.MaterialCode,
|
||||
MaterialName = g.First().MaterialName,
|
||||
Quantity = g.Sum(m => m.Quantity),
|
||||
IssuanceTime = g.Key.IssuanceTime, // 保留时间段信息
|
||||
Sort = g.First().Sort,
|
||||
CreatedBy = "系统自动生成",
|
||||
CreatedTime = DateTime.Now
|
||||
})
|
||||
.ToList();
|
||||
|
||||
// 创建排序键字典确保相同物料号排在一起
|
||||
var materialOrderDict = processedList
|
||||
.Select(m => m.MaterialCode)
|
||||
.Distinct()
|
||||
.OrderBy(MaterialCode => MaterialCode)
|
||||
.Select((MaterialCode, index) => new { MaterialCode, index })
|
||||
.ToDictionary(item => item.MaterialCode, item => item.index);
|
||||
|
||||
// 按物料号和时间段排序
|
||||
mmCallMrpList = processedList
|
||||
.OrderBy(m => materialOrderDict[m.MaterialCode])
|
||||
.ThenBy(m => m.Sort) // 按时间段排序
|
||||
.ToList();
|
||||
|
||||
// 删除旧数据并插入新数据
|
||||
Context
|
||||
@ -377,7 +388,6 @@ namespace DOAN.Service.MES.mm.paintedparts_call
|
||||
{
|
||||
Context.Ado.CommitTran();
|
||||
return 0;
|
||||
//throw new Exception($"该线别:{lineCode}日期:{checkDate}无涂装MRP清单");
|
||||
}
|
||||
|
||||
int result = Context.Insertable(mmCallMrpList).ExecuteCommand();
|
||||
@ -401,14 +411,15 @@ namespace DOAN.Service.MES.mm.paintedparts_call
|
||||
|
||||
public static int getSort(DateTime startTime)
|
||||
{
|
||||
if(startTime.ToString("HH:mm") == "08:00")
|
||||
if (startTime.ToString("HH:mm") == "08:00")
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if(startTime.ToString("HH:mm") == "10:00")
|
||||
else if (startTime.ToString("HH:mm") == "10:00")
|
||||
{
|
||||
return 2;
|
||||
}else if(startTime.ToString("HH:mm") == "12:00")
|
||||
}
|
||||
else if (startTime.ToString("HH:mm") == "12:00")
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user