Эх сурвалжийг харах

生产排产代码走查,修复bug

heteng 2 жил өмнө
parent
commit
230811794f

+ 73 - 70
MicroServices/Business/Business.Application/ResourceExamineManagement/ProductionScheduleAppService.cs

@@ -709,10 +709,9 @@ namespace Business.ResourceExamineManagement
                                 //剩余可用工作时长不能满足清场时长
                                 else
                                 {
-                                    endTime = dto.EndTime;
                                     //还需排产的清场时间
                                     decimal qcTime = needTime - remainTime;
-                                    endTime.AddMinutes((double)qcTime);
+                                    endTime = dto.EndTime.AddMinutes((double)qcTime);
                                     remainTime = 0;
                                 }
                                 //最后一个工单的清场时长
@@ -797,7 +796,7 @@ namespace Business.ResourceExamineManagement
                             item.QtyWorked = item.QtyOrded;
                         }
                         //当天产能完全占用,且最后一个工单的清场时间刚好下班或者在下班后
-                        if (curPoint == null || endTime == dto.EndTime)
+                        if (endTime >= dto.EndTime)
                         {
                             sumTsTimes = 0;//排产完毕,特殊工单时长置0
                             //获取下一个工作日
@@ -965,17 +964,17 @@ namespace Business.ResourceExamineManagement
                                 });
                                 //当前工单已排产完成,已排产时间=工单生产时长,已排产数量=工单数量
                                 item.Worked = item.LbrVar;
-                                item.QtyWorked = item.QtyWorked;
+                                item.QtyWorked = item.QtyOrded;
 
                                 beginTime = endTime;
                                 //当天可用生产时长还有剩余
                                 if (residueTime > 0)
                                 {
                                     //获取结束时间所处时间段
-                                    curPoint = workPoints.Find(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
+                                    curPoint = workPoints.FirstOrDefault(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
                                     if (endTime == curPoint.EndPoint)
                                     {
-                                        var nextPoint = workPoints.Find(p => p.Level == curPoint.Level + 1);
+                                        var nextPoint = workPoints.FirstOrDefault(p => p.Level == curPoint.Level + 1);
                                         endTime = nextPoint == null ? endTime : nextPoint.StartPoint;
                                     }
                                     beginTime = endTime;
@@ -1067,29 +1066,32 @@ namespace Business.ResourceExamineManagement
                     {
                         //获取特殊工单
                         secWOMasters = tsWorkOrds.Where(p => p.ProdLine == lineStart.Line && p.OrdDate.Value.Date == workStartTime.Date).OrderBy(p => p.OrdDate).ToList();
-                        foreach (var item in secWOMasters)
+                        if (secWOMasters.Any())
                         {
-                            var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
-                            workDtos.Add(new WorkOrdMstDto
+                            foreach (var item in secWOMasters)
                             {
-                                WorkOrd = item.WorkOrd,
-                                ItemNum = item.ItemNum,
-                                QtyOrded = item.QtyOrded,
-                                LbrVar = item.LbrVar * 60,
-                                Worked = 0,
-                                QtyWorked = 0,
-                                Op = curOp.OP,
-                                WaitTime = curOp.WaitTime * 60,
-                                PlanDate = item.OrdDate.Value
-                            });
-                            sumCleanTimes += curOp.WaitTime * 60;
+                                var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
+                                workDtos.Add(new WorkOrdMstDto
+                                {
+                                    WorkOrd = item.WorkOrd,
+                                    ItemNum = item.ItemNum,
+                                    QtyOrded = item.QtyOrded,
+                                    LbrVar = item.LbrVar * 60,
+                                    Worked = 0,
+                                    QtyWorked = 0,
+                                    Op = curOp.OP,
+                                    WaitTime = curOp.WaitTime * 60,
+                                    PlanDate = item.OrdDate.Value
+                                });
+                                sumCleanTimes += curOp.WaitTime * 60;
+                            }
+                            //获取最后一个特殊工单的清场时长
+                            var last = secWOMasters.Last();
+                            secCleanTime = tsWoRoutings.Where(p => p.WorkOrd == last.WorkOrd).OrderByDescending(p => p.OP).First().WaitTime * 60;
+                            //特殊工单待排产时长=前一天特殊工单到最后一个清场时长+新增的特殊工单生产时长+新增特殊工单除最后一个清场时长之外的清场时长之和
+                            sumTsTimes += (lstCleanTime + secWOMasters.Sum(p => p.LbrVar) * 60 + sumCleanTimes - secCleanTime);
+                            lstCleanTime = secCleanTime;
                         }
-                        //获取最后一个特殊工单的清场时长
-                        var last = secWOMasters.Last();
-                        secCleanTime = tsWoRoutings.Where(p => p.WorkOrd == last.WorkOrd).OrderByDescending(p => p.OP).First().WaitTime * 60;
-                        //特殊工单待排产时长=前一天特殊工单到最后一个清场时长+新增的特殊工单生产时长+新增特殊工单除最后一个清场时长之外的清场时长之和
-                        sumTsTimes += (lstCleanTime + secWOMasters.Sum(p => p.LbrVar) * 60 + sumCleanTimes - secCleanTime);
-                        lstCleanTime = secCleanTime;
                     }
                     //排产开始时,需要先减去产线准备时间(产线提前期满足的当天排产)
                     if (sumTimes < lineStart.setupTime * 60)
@@ -1097,7 +1099,7 @@ namespace Business.ResourceExamineManagement
                         //当天的可用生产时长能满足提前期
                         if (dto.EffTime > lineStart.setupTime * 60 - sumTimes)
                         {
-                            //当天剩余时长(分钟)
+                            //当天剩余时长(分钟)=当天可用上产时长-剩余产线准备时间
                             decimal residueTime = dto.EffTime - (lineStart.setupTime * 60 - sumTimes);
                             //产线提前期安排完之后,需要考虑当前是否存在特殊工单:
                             //1、如果当天是排产的最后一天,则先排完正常工单,再安排特殊工单;
@@ -1164,10 +1166,9 @@ namespace Business.ResourceExamineManagement
                                                 //剩余可用工作时长不能满足清场时长
                                                 else
                                                 {
-                                                    endTime = dto.EndTime;
                                                     //还需排产的清场时间
                                                     decimal qcTime = needTime - residueTime;
-                                                    endTime.AddMinutes((double)qcTime);
+                                                    endTime = dto.EndTime.AddMinutes((double)qcTime);
                                                     residueTime = 0;
                                                 }
                                             }
@@ -1259,7 +1260,7 @@ namespace Business.ResourceExamineManagement
                                             //处理正常工单开工时间
                                             workStartTime = endTime;
                                             //剩余产能继续排正常工单
-                                            sumAmount = Math.Floor(dto.Rate * (residueTime - sumTsTimes - lstCleanTime) / 60);
+                                            sumAmount = Math.Floor(dto.Rate * residueTime / 60);
                                             //记录生产周期
                                             curSequences.Add(new PeriodSequenceDet
                                             {
@@ -1387,10 +1388,6 @@ namespace Business.ResourceExamineManagement
                                                     //剩余生产时长
                                                     residueTime -= needTime;
                                                 }
-                                                //当前工单已排产完成,已排产时间=工单生产时长,已排产数量=工单数量
-                                                item.Worked = item.LbrVar;
-                                                item.QtyWorked = item.QtyWorked;
-
                                                 //处理特殊工单剩余时长减去当前工单待排产时长和清场时长
                                                 sumTsTimes -= (item.LbrVar - item.Worked + item.WaitTime);
                                                 //记录生产周期
@@ -1422,6 +1419,9 @@ namespace Business.ResourceExamineManagement
                                                     WorkEndTime = endTime,
                                                     CreateTime = DateTime.Now
                                                 });
+                                                //当前工单已排产完成,已排产时间=工单生产时长,已排产数量=工单数量
+                                                item.Worked = item.LbrVar;
+                                                item.QtyWorked = item.QtyOrded;
 
                                                 beginTime = endTime;
                                                 //当天可用生产时长还有剩余
@@ -1471,7 +1471,7 @@ namespace Business.ResourceExamineManagement
                                                     WorkDate = beginTime.Date,
                                                     WorkQty = qty,
                                                     WorkStartTime = beginTime,
-                                                    WorkEndTime = endTime,
+                                                    WorkEndTime = dto.EndTime,
                                                     CreateTime = DateTime.Now
                                                 });
                                                 item.Worked += residueTime;
@@ -1536,11 +1536,14 @@ namespace Business.ResourceExamineManagement
                                 decimal residueQty = workOrd.QtyOrded - sumQty;
                                 //剩余数量生产需要时长(分钟)
                                 decimal workTime = Math.Ceiling(residueQty / dto.Rate * 60);
+                                //处理工作时长:防止相上取整导致时间大于剩余可用时长
+                                workTime = workTime >= residueTime ? residueTime : workTime;
+                                //排产结束时间
+                                DateTime workEndTime = workStartTime;
                                 var curPoint = workPoints.Find(p => p.StartPoint <= workStartTime && workStartTime <= p.EndPoint);
                                 span = curPoint.EndPoint - workStartTime;
                                 //当天工作时间段的有效生产时间
                                 decimal effMins = (decimal)span.TotalMinutes;
-                                DateTime workEndTime = workStartTime;
                                 //当前工作时间段即可满足产能
                                 if (effMins >= workTime)
                                 {
@@ -1608,7 +1611,7 @@ namespace Business.ResourceExamineManagement
                                     }
                                     residueTime -= workTime;
                                 }
-
+                                
                                 //记录生产周期
                                 curSequences.Add(new PeriodSequenceDet
                                 {
@@ -1708,10 +1711,9 @@ namespace Business.ResourceExamineManagement
                                                     //剩余可用工作时长不能满足清场时长
                                                     else
                                                     {
-                                                        endTime = dto.EndTime;
                                                         //还需排产的清场时间
                                                         decimal qcTime = needTime - restTime;
-                                                        endTime.AddMinutes((double)qcTime);
+                                                        endTime = dto.EndTime.AddMinutes((double)qcTime);
                                                         restTime = 0;
                                                     }
                                                     //最后一个工单的清场时长
@@ -1917,10 +1919,9 @@ namespace Business.ResourceExamineManagement
                                                     });
                                                     //当前工单已排产完成,已排产时间=工单生产时长,已排产数量=工单数量
                                                     item.Worked = item.LbrVar;
-                                                    item.QtyWorked = item.QtyWorked;
+                                                    item.QtyWorked = item.QtyOrded;
 
                                                     beginTime = endTime;
-                                                    curPoint = workPoints.Find(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
                                                     if (restTime > 0)
                                                     {
                                                         curPoint = workPoints.Find(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
@@ -1931,6 +1932,7 @@ namespace Business.ResourceExamineManagement
                                                             {
                                                                 endTime = nextPoint.StartPoint;
                                                             }
+                                                            beginTime = endTime;
                                                         }
                                                     }
                                                     //当天产能已全部用完
@@ -1970,14 +1972,14 @@ namespace Business.ResourceExamineManagement
                                                         WorkDate = beginTime.Date,
                                                         WorkQty = qty,
                                                         WorkStartTime = beginTime,
-                                                        WorkEndTime = endTime,
+                                                        WorkEndTime = dto.EndTime,
                                                         CreateTime = DateTime.Now
                                                     });
                                                     item.Worked += restTime;
                                                     item.QtyWorked += qty;
-                                                    restTime = 0m;
                                                     //特殊工单剩余待排产时长(分钟)
                                                     sumTsTimes -= restTime;
+                                                    restTime = 0m;
                                                     break;
                                                 }
                                             }
@@ -2044,7 +2046,7 @@ namespace Business.ResourceExamineManagement
                                     if (item.WorkOrd == lastWork.WorkOrd)
                                     {
                                         //最后一个工单的生产时长+清场时长
-                                        needTime = lastWork.QtyOrded - lastWork.QtyWorked + lastWork.WaitTime;
+                                        needTime = lastWork.LbrVar - lastWork.Worked + lastWork.WaitTime;
                                         //剩余可用工作时长满足最后一个特殊工单的生产时长+清场时长
                                         if (residueTime >= needTime)
                                         {
@@ -2072,10 +2074,9 @@ namespace Business.ResourceExamineManagement
                                         //剩余可用工作时长不能满足清场时长
                                         else
                                         {
-                                            endTime = dto.EndTime;
                                             //还需排产的清场时间
                                             decimal qcTime = needTime - residueTime;
-                                            endTime.AddMinutes((double)qcTime);
+                                            endTime = dto.EndTime.AddMinutes((double)qcTime);
                                             residueTime = 0;
                                         }
                                         //最后一个工单的清场时长
@@ -2165,12 +2166,19 @@ namespace Business.ResourceExamineManagement
                                     item.Worked = item.LbrVar;
                                     item.QtyWorked = item.QtyOrded;
                                 }
+                                //排产完毕,特殊工单时长置0
+                                sumTsTimes = 0;
+                                //当天特殊工单全部排产完成
+                                isFullPC = true;
+                                //特殊工单排产完成,最后一个工单的清场时长置0
+                                lstCleanTime = 0m;
 
                                 //剩余可用生产时长
                                 residueTime = residueTime < 0 ? 0 : residueTime;
                                 //特殊工单处理完成,剩余生产时长大于0且还有正常工单待排产,则继续排正常工单
                                 if (residueTime > 0 && sumQty < workOrd.QtyOrded)
                                 {
+                                    workStartTime = beginTime;//排产开始时间
                                     //剩余产能继续排正常工单
                                     decimal sumAmount = Math.Floor(dto.Rate * residueTime / 60);
                                     //如果剩余产能不能满足正常工单,剩余产能全部排产
@@ -2214,20 +2222,20 @@ namespace Business.ResourceExamineManagement
                                     //剩余产能满足正常工单待排产数量,此时需要排清场时长
                                     else
                                     {
-                                        workStartTime = beginTime;
                                         //剩余需要排产的数量
                                         decimal residueQty = workOrd.QtyOrded - sumQty;
                                         //剩余数量生产需要时长(分钟)
                                         decimal workTime = Math.Ceiling(residueQty / dto.Rate * 60);
+                                        //处理剩余需要生产时长:防止向上取整导致超过residueTime
+                                        workTime = workTime > residueTime ? residueTime : workTime;
                                         curPoint = workPoints.Find(p => p.StartPoint <= workStartTime && workStartTime <= p.EndPoint);
                                         span = curPoint.EndPoint - workStartTime;
                                         //当天工作时间段的有效生产时间
                                         decimal effMins = (decimal)span.TotalMinutes;
-                                        DateTime workEndTime = workStartTime;
                                         //当前工作时间段即可满足产能
                                         if (effMins >= workTime)
                                         {
-                                            workEndTime = workStartTime.AddMinutes((double)workTime);
+                                            endTime = workStartTime.AddMinutes((double)workTime);
                                         }
                                         else
                                         {
@@ -2239,7 +2247,7 @@ namespace Business.ResourceExamineManagement
                                             {
                                                 if (p.WorkMinutes >= nextMins)
                                                 {
-                                                    workEndTime = p.StartPoint.AddMinutes((double)nextMins);
+                                                    endTime = p.StartPoint.AddMinutes((double)nextMins);
                                                     break;
                                                 }
                                                 nextMins -= p.WorkMinutes;
@@ -2319,7 +2327,7 @@ namespace Business.ResourceExamineManagement
                                             WorkDate = workStartTime.Date,
                                             WorkQty = residueQty,
                                             WorkStartTime = workStartTime,
-                                            WorkEndTime = workEndTime,
+                                            WorkEndTime = endTime,
                                             CreateTime = DateTime.Now
                                         });
                                     }
@@ -2329,12 +2337,6 @@ namespace Business.ResourceExamineManagement
                                     workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
                                     isFstDay = false;
                                 }
-                                //排产完毕,特殊工单时长置0
-                                sumTsTimes = 0;
-                                //当天特殊工单全部排产完成
-                                isFullPC = true;
-                                //特殊工单排产完成,最后一个工单的清场时长置0
-                                lstCleanTime = 0m;
                             }
                             //当天的可用产能不满特殊工单生产时长,则当天产能全部排特殊工单(至少最后一个特殊工单的生产时长不能满足)
                             else
@@ -2456,7 +2458,7 @@ namespace Business.ResourceExamineManagement
                                         });
                                         //当前工单已排产完成,已排产时间=工单生产时长,已排产数量=工单数量
                                         item.Worked = item.LbrVar;
-                                        item.QtyWorked = item.QtyWorked;
+                                        item.QtyWorked = item.QtyOrded;
 
                                         beginTime = endTime;
                                         //当天可用生产时长还有剩余
@@ -2466,7 +2468,7 @@ namespace Business.ResourceExamineManagement
                                             curPoint = workPoints.Find(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
                                             if (endTime == curPoint.EndPoint)
                                             {
-                                                var nextPoint = workPoints.Find(p => p.Level == curPoint.Level + 1);
+                                                var nextPoint = workPoints.FirstOrDefault(p => p.Level == curPoint.Level + 1);
                                                 endTime = nextPoint == null ? endTime : nextPoint.StartPoint;
                                             }
                                             beginTime = endTime;
@@ -2508,7 +2510,7 @@ namespace Business.ResourceExamineManagement
                                             WorkDate = beginTime.Date,
                                             WorkQty = qty,
                                             WorkStartTime = beginTime,
-                                            WorkEndTime = endTime,
+                                            WorkEndTime = dto.EndTime,
                                             CreateTime = DateTime.Now
                                         });
                                         item.Worked += residueTime;
@@ -2558,7 +2560,7 @@ namespace Business.ResourceExamineManagement
                                             if (item.WorkOrd == lastWork.WorkOrd) 
                                             {
                                                 //最后一个工单的生产时长+清场时长
-                                                needTime = lastWork.QtyOrded - lastWork.QtyWorked + lastWork.WaitTime;
+                                                needTime = lastWork.LbrVar - lastWork.Worked + lastWork.WaitTime;
                                                 //剩余可用工作时长满足最后一个特殊工单的生产时长+清场时长
                                                 if (residueTime >= needTime)
                                                 {
@@ -2586,10 +2588,9 @@ namespace Business.ResourceExamineManagement
                                                 //剩余可用工作时长不能满足清场时长
                                                 else
                                                 {
-                                                    endTime = dto.EndTime;
                                                     //还需排产的清场时间
                                                     decimal qcTime = needTime - residueTime;
-                                                    endTime.AddMinutes((double)qcTime);
+                                                    endTime = dto.EndTime.AddMinutes((double)qcTime);
                                                     residueTime = 0;
                                                 }
                                                 //最后一个工单的清场时长
@@ -2845,7 +2846,7 @@ namespace Business.ResourceExamineManagement
                                                 });
                                                 //当前工单已排产完成,已排产时间=工单生产时长,已排产数量=工单数量
                                                 item.Worked = item.LbrVar;
-                                                item.QtyWorked = item.QtyWorked;
+                                                item.QtyWorked = item.QtyOrded;
 
                                                 beginTime = endTime;
                                                 if (residueTime > 0)
@@ -2896,7 +2897,7 @@ namespace Business.ResourceExamineManagement
                                                     WorkDate = beginTime.Date,
                                                     WorkQty = qty,
                                                     WorkStartTime = beginTime,
-                                                    WorkEndTime = endTime,
+                                                    WorkEndTime = dto.EndTime,
                                                     CreateTime = DateTime.Now
                                                 });
                                                 item.Worked += residueTime;
@@ -2951,6 +2952,7 @@ namespace Business.ResourceExamineManagement
                                     //继续排下一个工作日
                                     workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
                                     isFstDay = false;
+                                    isFullPC = true;
                                 }
                             }
                             //剩余产能满足正常工单待排产数量,此时需要排清场时长
@@ -2968,6 +2970,8 @@ namespace Business.ResourceExamineManagement
                                     decimal residueQty = workOrd.QtyOrded - sumQty;
                                     //剩余数量生产需要时长(分钟)
                                     workTime = Math.Ceiling(residueQty / dto.Rate * 60);
+                                    //处理需要生产时长
+                                    workTime = workTime >= residueTime ? residueTime : workTime;
                                     var curPoint = workPoints.Find(p => p.StartPoint <= workStartTime && workStartTime <= p.EndPoint);
                                     span = curPoint.EndPoint - workStartTime;
                                     //当天工作时间段的有效生产时间
@@ -3110,7 +3114,7 @@ namespace Business.ResourceExamineManagement
                                                 if (item.WorkOrd == lastWork.WorkOrd)
                                                 {
                                                     //最后一个工单的生产时长+清场时长
-                                                    needTime = lastWork.QtyOrded - lastWork.QtyWorked + lastWork.WaitTime;
+                                                    needTime = lastWork.LbrVar - lastWork.Worked + lastWork.WaitTime;
                                                     //剩余可用工作时长满足最后一个特殊工单的生产时长+清场时长
                                                     if (residueTime >= needTime)
                                                     {
@@ -3139,10 +3143,9 @@ namespace Business.ResourceExamineManagement
                                                     //剩余可用工作时长不能满足清场时长
                                                     else
                                                     {
-                                                        endTime = dto.EndTime;
                                                         //还需排产的清场时间
                                                         decimal qcTime = needTime - residueTime;
-                                                        endTime.AddMinutes((double)qcTime);
+                                                        endTime = dto.EndTime.AddMinutes((double)qcTime);
                                                         residueTime = 0;
                                                     }
                                                     //最后一个工单的清场时长
@@ -3352,7 +3355,7 @@ namespace Business.ResourceExamineManagement
                                                     });
                                                     //当前工单已排产完成,已排产时间=工单生产时长,已排产数量=工单数量
                                                     item.Worked = item.LbrVar;
-                                                    item.QtyWorked = item.QtyWorked;
+                                                    item.QtyWorked = item.QtyOrded;
 
                                                     beginTime = endTime;
                                                     if (residueTime > 0)
@@ -3402,7 +3405,7 @@ namespace Business.ResourceExamineManagement
                                                         WorkDate = beginTime.Date,
                                                         WorkQty = qty,
                                                         WorkStartTime = beginTime,
-                                                        WorkEndTime = endTime,
+                                                        WorkEndTime = dto.EndTime,
                                                         CreateTime = DateTime.Now
                                                     });
                                                     item.Worked += residueTime;