|
|
@@ -852,6 +852,8 @@ namespace Business.ResourceExamineManagement
|
|
|
sumTsTimes = 0m;
|
|
|
//正常工单排产第一天标识
|
|
|
bool isFstDay = true;
|
|
|
+ //前一天是否有特殊工单未排产完全
|
|
|
+ bool isFullPC = true;
|
|
|
while (sumQty < workOrd.QtyOrded || sumTsTimes > 0)
|
|
|
{
|
|
|
secWOMasters.Clear();
|
|
|
@@ -886,7 +888,7 @@ namespace Business.ResourceExamineManagement
|
|
|
//记录特殊工单剩余生产时长
|
|
|
sumTsTimes += secWOMasters.Sum(p => p.LbrVar) * 60;
|
|
|
}
|
|
|
- //排产开始时,需要先减去产线准备时间
|
|
|
+ //排产开始时,需要先减去产线准备时间(产线提前期满足的当天排产)
|
|
|
if (sumTimes < lineStart.setupTime * 60)
|
|
|
{
|
|
|
//当天的可用生产时长能满足提前期
|
|
|
@@ -1034,6 +1036,7 @@ namespace Business.ResourceExamineManagement
|
|
|
|
|
|
//排产完毕,特殊工单时长置0
|
|
|
sumTsTimes = 0;
|
|
|
+ isFullPC = true;
|
|
|
}
|
|
|
//当天的可用产能不满足或者刚好满足特殊工单生产时长
|
|
|
else
|
|
|
@@ -1165,6 +1168,13 @@ namespace Business.ResourceExamineManagement
|
|
|
}
|
|
|
//特殊工单剩余待排产时长(分钟)
|
|
|
sumTsTimes -= residueTime;
|
|
|
+ //当天产能刚好满足特殊工单排产
|
|
|
+ isFullPC = true;
|
|
|
+ //当天的特殊工单没排产完成
|
|
|
+ if (sumTsTimes > 0)
|
|
|
+ {
|
|
|
+ isFullPC = false;
|
|
|
+ }
|
|
|
//获取下一个工作日
|
|
|
workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
isFstDay = false;
|
|
|
@@ -1380,6 +1390,7 @@ namespace Business.ResourceExamineManagement
|
|
|
sumTsTimes -= needTime;
|
|
|
}
|
|
|
sumTsTimes = 0;//排产完毕,特殊工单时长置0
|
|
|
+ isFullPC = true;
|
|
|
}
|
|
|
//当天的剩余生产时长不满足特殊工单生产时长
|
|
|
else
|
|
|
@@ -1514,6 +1525,8 @@ namespace Business.ResourceExamineManagement
|
|
|
//获取下一个工作日
|
|
|
workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
isFstDay = false;
|
|
|
+ //当天特殊工单未排产完全
|
|
|
+ isFullPC = false;
|
|
|
}
|
|
|
#endregion 特殊工单排产-结束
|
|
|
}
|
|
|
@@ -1523,6 +1536,8 @@ namespace Business.ResourceExamineManagement
|
|
|
//继续排下一个工作日
|
|
|
workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
isFstDay = false;
|
|
|
+ //当天特殊工单未排产完全
|
|
|
+ isFullPC = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -1539,36 +1554,234 @@ namespace Business.ResourceExamineManagement
|
|
|
isFstDay = false;
|
|
|
}
|
|
|
}
|
|
|
+ //产线提前期满足的下一个工作日排产
|
|
|
else
|
|
|
{
|
|
|
- //已排产数量+当天的产能小于或者等于工单数量,当天的产能需要全部排产
|
|
|
- if (sumQty + dto.ProductQty <= workOrd.QtyOrded)
|
|
|
+ //如果前一天的特殊工单没排产完,则先排特殊工单,如果当天还安排有特殊工单,则将特殊工单提前
|
|
|
+ if (!isFullPC)
|
|
|
{
|
|
|
- //当天有特殊工单,先排特殊工单
|
|
|
- if (sumTsTimes > 0)
|
|
|
+ //当天可用生产时长(分钟)
|
|
|
+ decimal residueTime = dto.EffTime;
|
|
|
+ DateTime beginTime = workStartTime;//排产开始时间
|
|
|
+ DateTime endTime = dto.EndTime;//排产结束时间
|
|
|
+ //当天的可用生产时长满足特殊工单生产时长
|
|
|
+ if (residueTime > sumTsTimes)
|
|
|
{
|
|
|
- //当天剩余产能(分钟)
|
|
|
- decimal residueTime = dto.EffTime;
|
|
|
- DateTime beginTime = workStartTime;//排产开始时间
|
|
|
- DateTime endTime = dto.EndTime;//排产结束时间
|
|
|
- //当天的可用产能满足特殊工单生产时长
|
|
|
- if (residueTime > sumTsTimes)
|
|
|
+ //特殊工单排产
|
|
|
+ foreach (var item in workDtos)
|
|
|
+ {
|
|
|
+ if (item.LbrVar == item.Worked)//当前工单已排产,跳过
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //当前工单还需工作时长
|
|
|
+ decimal needTime = item.LbrVar - item.Worked;
|
|
|
+ //计算工单排产结束时间
|
|
|
+ var curPoint = workPoints.Find(p => p.StartPoint <= beginTime && beginTime <= p.EndPoint);
|
|
|
+ span = curPoint.EndPoint - beginTime;
|
|
|
+ //当天工作时间段的有效生产时间(分钟)
|
|
|
+ decimal effMins = (decimal)span.TotalMinutes;
|
|
|
+ //当前工作时间段即可满足产能
|
|
|
+ if (effMins >= needTime)
|
|
|
+ {
|
|
|
+ endTime = beginTime.AddMinutes((double)needTime);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //获取后续生产时间段
|
|
|
+ var nextPoints = workPoints.Where(p => p.Level > curPoint.Level).OrderBy(p => p.Level).ToList();
|
|
|
+ //剩余需要工作时长
|
|
|
+ decimal nextMins = needTime - effMins;
|
|
|
+ foreach (var p in nextPoints)
|
|
|
+ {
|
|
|
+ if (p.WorkMinutes >= nextMins)
|
|
|
+ {
|
|
|
+ endTime = p.StartPoint.AddMinutes((double)nextMins);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ nextMins -= p.WorkMinutes;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //记录生产周期
|
|
|
+ curSequences.Add(new PeriodSequenceDet
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ PlanDate = beginTime.Date,
|
|
|
+ Period = dto.Period,
|
|
|
+ OrdQty = item.QtyOrded - item.QtyWorked,
|
|
|
+ WorkOrds = item.WorkOrd,
|
|
|
+ Op = item.Op,
|
|
|
+ IsActive = true,
|
|
|
+ Status = "",
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录排产记录
|
|
|
+ curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = item.Op,
|
|
|
+ WorkDate = beginTime.Date,
|
|
|
+ WorkQty = item.QtyOrded - item.QtyWorked,
|
|
|
+ WorkStartTime = beginTime,
|
|
|
+ WorkEndTime = endTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //下一工单开始时间=当前工单结束时间,如果位于工作区间结尾,则为下一工作区间开始时间
|
|
|
+ curPoint = workPoints.Find(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
|
|
|
+ //结束时间位于工作区间结尾
|
|
|
+ if (endTime == curPoint.EndPoint)
|
|
|
+ {
|
|
|
+ //获取后续生产时间段
|
|
|
+ var nextPoint = workPoints.Where(p => p.Level == curPoint.Level + 1).FirstOrDefault();
|
|
|
+ //存在后续工作区间
|
|
|
+ if (nextPoint != null)
|
|
|
+ {
|
|
|
+ endTime = nextPoint.StartPoint;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ beginTime = endTime;
|
|
|
+ //工单排产完成,排产时长=工单工作时长
|
|
|
+ item.Worked = item.LbrVar;
|
|
|
+ item.QtyWorked = item.QtyOrded;
|
|
|
+ }
|
|
|
+
|
|
|
+ //处理正常工单开工时间
|
|
|
+ workStartTime = endTime;
|
|
|
+ //剩余产能继续排正常工单
|
|
|
+ decimal sumAmount = Math.Floor(dto.Rate * (residueTime - sumTsTimes) / 60);
|
|
|
+ //如果剩余产能不能满足正常工单,剩余产能全部排产
|
|
|
+ if (sumQty + sumAmount < workOrd.QtyOrded)
|
|
|
{
|
|
|
- //特殊工单排产
|
|
|
- foreach (var item in workDtos)
|
|
|
+ //记录生产周期
|
|
|
+ curSequences.Add(new PeriodSequenceDet
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = workOrd.ItemNum,
|
|
|
+ PlanDate = workStartTime.Date,
|
|
|
+ Period = dto.Period,
|
|
|
+ OrdQty = sumAmount,
|
|
|
+ WorkOrds = workOrd.WorkOrd,
|
|
|
+ Op = lineStart.Op,
|
|
|
+ IsActive = true,
|
|
|
+ Status = "",
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录排产记录
|
|
|
+ curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ WorkOrd = workOrd.WorkOrd,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = workOrd.ItemNum,
|
|
|
+ Op = lineStart.Op,
|
|
|
+ WorkDate = workStartTime.Date,
|
|
|
+ WorkQty = sumAmount,
|
|
|
+ WorkStartTime = workStartTime,
|
|
|
+ WorkEndTime = dto.EndTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //累计已排产数量
|
|
|
+ sumQty += sumAmount;
|
|
|
+ //继续排下一个工作日
|
|
|
+ workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
+ isFstDay = false;
|
|
|
+ }
|
|
|
+ //剩余产能满足正常工单待排产数量
|
|
|
+ else{
|
|
|
+ //剩余需要排产的数量
|
|
|
+ decimal residueQty = workOrd.QtyOrded - sumQty;
|
|
|
+ //剩余数量生产需要时长(分钟)
|
|
|
+ decimal workTime = Math.Ceiling(residueQty / dto.Rate * 60);
|
|
|
+ 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)
|
|
|
+ {
|
|
|
+ workEndTime = workStartTime.AddMinutes((double)workTime);
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- if (item.LbrVar == item.Worked)//当前工单已排产
|
|
|
+ //获取后续生产时间段
|
|
|
+ var nextPoints = workPoints.Where(p => p.Level > curPoint.Level).OrderBy(p => p.Level).ToList();
|
|
|
+ //剩余需要工作时长
|
|
|
+ decimal nextMins = workTime - effMins;
|
|
|
+ foreach (var p in nextPoints)
|
|
|
{
|
|
|
- continue;
|
|
|
+ if (p.WorkMinutes >= nextMins)
|
|
|
+ {
|
|
|
+ workEndTime = p.StartPoint.AddMinutes((double)nextMins);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ nextMins -= p.WorkMinutes;
|
|
|
}
|
|
|
- //当前工单还需工作时长
|
|
|
- decimal needTime = item.LbrVar - item.Worked;
|
|
|
+ }
|
|
|
+ sumQty = workOrd.QtyOrded;
|
|
|
+ //记录生产周期
|
|
|
+ curSequences.Add(new PeriodSequenceDet
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = workOrd.ItemNum,
|
|
|
+ PlanDate = workStartTime.Date,
|
|
|
+ Period = dto.Period,
|
|
|
+ OrdQty = residueQty,
|
|
|
+ WorkOrds = workOrd.WorkOrd,
|
|
|
+ Op = lineStart.Op,
|
|
|
+ IsActive = true,
|
|
|
+ Status = "",
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录排产记录
|
|
|
+ curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ WorkOrd = workOrd.WorkOrd,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = workOrd.ItemNum,
|
|
|
+ Op = lineStart.Op,
|
|
|
+ WorkDate = workStartTime.Date,
|
|
|
+ WorkQty = residueQty,
|
|
|
+ WorkStartTime = workStartTime,
|
|
|
+ WorkEndTime = workEndTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ }
|
|
|
+ //排产完毕,特殊工单时长置0
|
|
|
+ sumTsTimes = 0;
|
|
|
+ //当天特殊工单全部排产完成
|
|
|
+ isFullPC = true;
|
|
|
+ }
|
|
|
+ //当天的可用产能不满足或者刚好满足特殊工单生产时长
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //特殊工单排产
|
|
|
+ foreach (var item in workDtos)
|
|
|
+ {
|
|
|
+ if (item.LbrVar == item.Worked)//当前工单已排产
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //当前工单剩余待排产时长(分钟)
|
|
|
+ decimal needTime = item.LbrVar - item.Worked;
|
|
|
+ //当天剩余产能满足当前工单的剩余待排产时长
|
|
|
+ if (residueTime >= needTime)
|
|
|
+ {
|
|
|
//计算工单排产结束时间
|
|
|
var curPoint = workPoints.Find(p => p.StartPoint <= beginTime && beginTime <= p.EndPoint);
|
|
|
span = curPoint.EndPoint - beginTime;
|
|
|
- //当天工作时间段的有效生产时间(分钟)
|
|
|
+ //当前工作时间段的有效生产时间(分钟)
|
|
|
decimal effMins = (decimal)span.TotalMinutes;
|
|
|
- if (effMins >= needTime)//当前工作时间段即可满足产能
|
|
|
+ //当前工作时间段即可满足产能
|
|
|
+ if (effMins >= needTime)
|
|
|
{
|
|
|
endTime = beginTime.AddMinutes((double)needTime);
|
|
|
}
|
|
|
@@ -1617,84 +1830,107 @@ namespace Business.ResourceExamineManagement
|
|
|
WorkEndTime = endTime,
|
|
|
CreateTime = DateTime.Now
|
|
|
});
|
|
|
- //下一工单开始时间=当前工单结束时间,如果位于工作区间结尾,则为下一工作区间开始时间
|
|
|
curPoint = workPoints.Find(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
|
|
|
- if (endTime == curPoint.EndPoint)//结束时间位于工作区间结尾
|
|
|
+ if (endTime == curPoint.EndPoint)
|
|
|
{
|
|
|
- //获取后续生产时间段
|
|
|
var nextPoint = workPoints.FirstOrDefault(p => p.Level == curPoint.Level + 1);
|
|
|
- if (nextPoint != null)//存在后续工作区间
|
|
|
+ if (nextPoint != null)
|
|
|
{
|
|
|
endTime = nextPoint.StartPoint;
|
|
|
}
|
|
|
}
|
|
|
beginTime = endTime;
|
|
|
- //工单排产完成,排产时长=工单工作时长
|
|
|
+ //当前工单已排产完成,已排产时间=工单生产时长,已排产数量=工单数量
|
|
|
item.Worked = item.LbrVar;
|
|
|
- item.QtyWorked = item.QtyOrded;
|
|
|
- sumTsTimes -= needTime;
|
|
|
+ item.QtyWorked = item.QtyWorked;
|
|
|
+ //当天剩余产能
|
|
|
+ residueTime -= needTime;
|
|
|
+ if (residueTime == 0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- //处理正常工单开工时间
|
|
|
- workStartTime = endTime;
|
|
|
- //剩余产能继续排正常工单
|
|
|
- decimal sumAmount = Math.Floor(dto.Rate * (dto.EffTime - sumTsTimes) / 60);
|
|
|
- //记录生产周期
|
|
|
- curSequences.Add(new PeriodSequenceDet
|
|
|
- {
|
|
|
- Domain = domain,
|
|
|
- Line = lineStart.Line,
|
|
|
- ItemNum = workOrd.ItemNum,
|
|
|
- PlanDate = workStartTime.Date,
|
|
|
- Period = dto.Period,
|
|
|
- OrdQty = sumAmount,
|
|
|
- WorkOrds = workOrd.WorkOrd,
|
|
|
- Op = lineStart.Op,
|
|
|
- IsActive = true,
|
|
|
- Status = "",
|
|
|
- CreateTime = DateTime.Now
|
|
|
- });
|
|
|
- //记录排产记录
|
|
|
- curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
+ //当天剩余产能不满足当前工单的剩余待排产时长
|
|
|
+ else
|
|
|
{
|
|
|
- Domain = domain,
|
|
|
- WorkOrd = workOrd.WorkOrd,
|
|
|
- Line = lineStart.Line,
|
|
|
- ItemNum = workOrd.ItemNum,
|
|
|
- Op = lineStart.Op,
|
|
|
- WorkDate = workStartTime.Date,
|
|
|
- WorkQty = sumAmount,
|
|
|
- WorkStartTime = workStartTime,
|
|
|
- WorkEndTime = dto.EndTime,
|
|
|
- CreateTime = DateTime.Now
|
|
|
- });
|
|
|
- //累计已排产数量
|
|
|
- sumQty += sumAmount;
|
|
|
- //继续排下一个工作日
|
|
|
- workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
- isFstDay = false;
|
|
|
-
|
|
|
- //排产完毕,特殊工单时长置0
|
|
|
- sumTsTimes = 0;
|
|
|
+ //计算生产数量
|
|
|
+ decimal qty = Math.Ceiling(residueTime / item.LbrVar * item.QtyOrded);
|
|
|
+ //记录生产周期
|
|
|
+ curSequences.Add(new PeriodSequenceDet
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ PlanDate = beginTime.Date,
|
|
|
+ Period = dto.Period,
|
|
|
+ OrdQty = qty,
|
|
|
+ WorkOrds = item.WorkOrd,
|
|
|
+ Op = item.Op,
|
|
|
+ IsActive = true,
|
|
|
+ Status = "",
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录排产记录
|
|
|
+ curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = item.Op,
|
|
|
+ WorkDate = beginTime.Date,
|
|
|
+ WorkQty = qty,
|
|
|
+ WorkStartTime = beginTime,
|
|
|
+ WorkEndTime = endTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ item.Worked += residueTime;
|
|
|
+ item.QtyWorked += qty;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
- //当天的可用产能不满足或者刚好满足特殊工单生产时长
|
|
|
- else
|
|
|
+ //特殊工单剩余待排产时长(分钟)
|
|
|
+ sumTsTimes -= residueTime;
|
|
|
+ //当天产能刚好满足特殊工单排产
|
|
|
+ isFullPC = true;
|
|
|
+ //当天的特殊工单没排产完成
|
|
|
+ if (sumTsTimes > 0)
|
|
|
+ {
|
|
|
+ isFullPC = false;
|
|
|
+ }
|
|
|
+ //获取下一个工作日
|
|
|
+ workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
+ isFstDay = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //当天之前的特殊工单全部排产完毕
|
|
|
+ else {
|
|
|
+ //已排产数量+当天的产能小于工单数量,当天的产能需要全部排产
|
|
|
+ if (sumQty + dto.ProductQty < workOrd.QtyOrded)
|
|
|
+ {
|
|
|
+ //当天有特殊工单,先排特殊工单
|
|
|
+ if (sumTsTimes > 0)
|
|
|
{
|
|
|
- foreach (var item in workDtos)
|
|
|
+ //当天剩余产能(分钟)
|
|
|
+ decimal residueTime = dto.EffTime;
|
|
|
+ DateTime beginTime = workStartTime;//排产开始时间
|
|
|
+ DateTime endTime = dto.EndTime;//排产结束时间
|
|
|
+ //当天的可用产能满足特殊工单生产时长
|
|
|
+ if (residueTime > sumTsTimes)
|
|
|
{
|
|
|
- if (item.LbrVar == item.Worked)//当前工单已排产
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- //当前工单剩余待排产时长(分钟)
|
|
|
- decimal needTime = item.LbrVar - item.Worked;
|
|
|
- //当天剩余产能满足当前工单的剩余待排产时长
|
|
|
- if (residueTime >= needTime)
|
|
|
+ //特殊工单排产
|
|
|
+ foreach (var item in workDtos)
|
|
|
{
|
|
|
+ if (item.LbrVar == item.Worked)//当前工单已排产
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //当前工单还需工作时长
|
|
|
+ decimal needTime = item.LbrVar - item.Worked;
|
|
|
//计算工单排产结束时间
|
|
|
var curPoint = workPoints.Find(p => p.StartPoint <= beginTime && beginTime <= p.EndPoint);
|
|
|
span = curPoint.EndPoint - beginTime;
|
|
|
- //当前工作时间段的有效生产时间(分钟)
|
|
|
+ //当天工作时间段的有效生产时间(分钟)
|
|
|
decimal effMins = (decimal)span.TotalMinutes;
|
|
|
if (effMins >= needTime)//当前工作时间段即可满足产能
|
|
|
{
|
|
|
@@ -1745,273 +1981,69 @@ namespace Business.ResourceExamineManagement
|
|
|
WorkEndTime = endTime,
|
|
|
CreateTime = DateTime.Now
|
|
|
});
|
|
|
+ //下一工单开始时间=当前工单结束时间,如果位于工作区间结尾,则为下一工作区间开始时间
|
|
|
curPoint = workPoints.Find(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
|
|
|
- if (endTime == curPoint.EndPoint)
|
|
|
+ if (endTime == curPoint.EndPoint)//结束时间位于工作区间结尾
|
|
|
{
|
|
|
+ //获取后续生产时间段
|
|
|
var nextPoint = workPoints.FirstOrDefault(p => p.Level == curPoint.Level + 1);
|
|
|
- if (nextPoint != null)
|
|
|
+ if (nextPoint != null)//存在后续工作区间
|
|
|
{
|
|
|
endTime = nextPoint.StartPoint;
|
|
|
}
|
|
|
}
|
|
|
beginTime = endTime;
|
|
|
- //当前工单已排产完成,已排产时间=工单生产时长,已排产数量=工单数量
|
|
|
+ //工单排产完成,排产时长=工单工作时长
|
|
|
item.Worked = item.LbrVar;
|
|
|
- item.QtyWorked = item.QtyWorked;
|
|
|
- //当天剩余产能
|
|
|
- residueTime -= needTime;
|
|
|
- if (residueTime == 0)
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
+ item.QtyWorked = item.QtyOrded;
|
|
|
+ sumTsTimes -= needTime;
|
|
|
}
|
|
|
- else//当天剩余产能不满足当前工单的剩余待排产时长
|
|
|
+
|
|
|
+ //处理正常工单开工时间
|
|
|
+ workStartTime = endTime;
|
|
|
+ //剩余产能继续排正常工单
|
|
|
+ decimal sumAmount = Math.Floor(dto.Rate * (residueTime - sumTsTimes) / 60);
|
|
|
+ //记录生产周期
|
|
|
+ curSequences.Add(new PeriodSequenceDet
|
|
|
{
|
|
|
- //计算生产数量
|
|
|
- decimal qty = Math.Ceiling(residueTime / item.LbrVar * item.QtyOrded);
|
|
|
- //记录生产周期
|
|
|
- curSequences.Add(new PeriodSequenceDet
|
|
|
- {
|
|
|
- Domain = domain,
|
|
|
- Line = lineStart.Line,
|
|
|
- ItemNum = item.ItemNum,
|
|
|
- PlanDate = beginTime.Date,
|
|
|
- Period = dto.Period,
|
|
|
- OrdQty = qty,
|
|
|
- WorkOrds = item.WorkOrd,
|
|
|
- Op = item.Op,
|
|
|
- IsActive = true,
|
|
|
- Status = "",
|
|
|
- CreateTime = DateTime.Now
|
|
|
- });
|
|
|
- //记录排产记录
|
|
|
- curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
- {
|
|
|
- Domain = domain,
|
|
|
- WorkOrd = item.WorkOrd,
|
|
|
- Line = lineStart.Line,
|
|
|
- ItemNum = item.ItemNum,
|
|
|
- Op = item.Op,
|
|
|
- WorkDate = beginTime.Date,
|
|
|
- WorkQty = qty,
|
|
|
- WorkStartTime = beginTime,
|
|
|
- WorkEndTime = endTime,
|
|
|
- CreateTime = DateTime.Now
|
|
|
- });
|
|
|
- item.Worked += residueTime;
|
|
|
- item.QtyWorked += qty;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- //特殊工单剩余待排产时长(分钟)
|
|
|
- sumTsTimes -= residueTime;
|
|
|
- //获取下一个工作日
|
|
|
- workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
- isFstDay = false;
|
|
|
- }
|
|
|
- }
|
|
|
- //不存在特殊工单
|
|
|
- else
|
|
|
- {
|
|
|
- //记录生产周期
|
|
|
- curSequences.Add(new PeriodSequenceDet
|
|
|
- {
|
|
|
- Domain = domain,
|
|
|
- Line = lineStart.Line,
|
|
|
- ItemNum = workOrd.ItemNum,
|
|
|
- PlanDate = workStartTime.Date,
|
|
|
- Period = dto.Period,
|
|
|
- OrdQty = dto.ProductQty,
|
|
|
- WorkOrds = workOrd.WorkOrd,
|
|
|
- Op = lineStart.Op,
|
|
|
- IsActive = true,
|
|
|
- Status = "",
|
|
|
- CreateTime = DateTime.Now
|
|
|
- });
|
|
|
- //记录排产记录
|
|
|
- curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
- {
|
|
|
- Domain = domain,
|
|
|
- WorkOrd = workOrd.WorkOrd,
|
|
|
- Line = lineStart.Line,
|
|
|
- ItemNum = workOrd.ItemNum,
|
|
|
- Op = lineStart.Op,
|
|
|
- WorkDate = workStartTime.Date,
|
|
|
- WorkQty = dto.ProductQty,
|
|
|
- WorkStartTime = dto.StartTime,
|
|
|
- WorkEndTime = dto.EndTime,
|
|
|
- CreateTime = DateTime.Now
|
|
|
- });
|
|
|
- //累计已排产数量
|
|
|
- sumQty += dto.ProductQty;
|
|
|
- //继续排下一个工作日
|
|
|
- workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
- isFstDay = false;
|
|
|
- }
|
|
|
- }
|
|
|
- else// 当天的产能正常工单只能占用一部分
|
|
|
- {
|
|
|
- decimal workTime = 0m;
|
|
|
- DateTime workEndTime = workStartTime;
|
|
|
- if (sumQty < workOrd.QtyOrded)
|
|
|
- {
|
|
|
- #region 正常工单排产-开始
|
|
|
- //剩余需要排产的数量
|
|
|
- decimal residueQty = workOrd.QtyOrded - sumQty;
|
|
|
- //剩余数量生产需要时长(分钟)
|
|
|
- workTime = Math.Ceiling(residueQty / dto.Rate * 60);
|
|
|
- var curPoint = workPoints.Find(p => p.StartPoint <= workStartTime && workStartTime <= p.EndPoint);
|
|
|
- span = curPoint.EndPoint - workStartTime;
|
|
|
- //当天工作时间段的有效生产时间
|
|
|
- decimal effMins = (decimal)span.TotalMinutes;
|
|
|
- //当前工作时间段即可满足产能
|
|
|
- if (effMins >= workTime)
|
|
|
- {
|
|
|
- workEndTime = workStartTime.AddMinutes((double)workTime);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //获取后续生产时间段
|
|
|
- var nextPoints = workPoints.Where(p => p.Level > curPoint.Level).OrderBy(p => p.Level).ToList();
|
|
|
- //剩余需要工作时长
|
|
|
- decimal nextMins = workTime - effMins;
|
|
|
- foreach (var p in nextPoints)
|
|
|
- {
|
|
|
- if (p.WorkMinutes >= nextMins)
|
|
|
+ Domain = domain,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = workOrd.ItemNum,
|
|
|
+ PlanDate = workStartTime.Date,
|
|
|
+ Period = dto.Period,
|
|
|
+ OrdQty = sumAmount,
|
|
|
+ WorkOrds = workOrd.WorkOrd,
|
|
|
+ Op = lineStart.Op,
|
|
|
+ IsActive = true,
|
|
|
+ Status = "",
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录排产记录
|
|
|
+ curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
{
|
|
|
- workEndTime = p.StartPoint.AddMinutes((double)nextMins);
|
|
|
- break;
|
|
|
- }
|
|
|
- nextMins -= p.WorkMinutes;
|
|
|
- }
|
|
|
- }
|
|
|
- sumQty = workOrd.QtyOrded;
|
|
|
- //记录生产周期
|
|
|
- curSequences.Add(new PeriodSequenceDet
|
|
|
- {
|
|
|
- Domain = domain,
|
|
|
- Line = lineStart.Line,
|
|
|
- ItemNum = workOrd.ItemNum,
|
|
|
- PlanDate = workStartTime.Date,
|
|
|
- Period = dto.Period,
|
|
|
- OrdQty = residueQty,
|
|
|
- WorkOrds = workOrd.WorkOrd,
|
|
|
- Op = lineStart.Op,
|
|
|
- IsActive = true,
|
|
|
- Status = "",
|
|
|
- CreateTime = DateTime.Now
|
|
|
- });
|
|
|
- //记录排产记录
|
|
|
- curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
- {
|
|
|
- Domain = domain,
|
|
|
- WorkOrd = workOrd.WorkOrd,
|
|
|
- Line = lineStart.Line,
|
|
|
- ItemNum = workOrd.ItemNum,
|
|
|
- Op = lineStart.Op,
|
|
|
- WorkDate = workStartTime.Date,
|
|
|
- WorkQty = residueQty,
|
|
|
- WorkStartTime = workStartTime,
|
|
|
- WorkEndTime = workEndTime,
|
|
|
- CreateTime = DateTime.Now
|
|
|
- });
|
|
|
- #endregion 正常工单排产-结束
|
|
|
- }
|
|
|
+ Domain = domain,
|
|
|
+ WorkOrd = workOrd.WorkOrd,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = workOrd.ItemNum,
|
|
|
+ Op = lineStart.Op,
|
|
|
+ WorkDate = workStartTime.Date,
|
|
|
+ WorkQty = sumAmount,
|
|
|
+ WorkStartTime = workStartTime,
|
|
|
+ WorkEndTime = dto.EndTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //累计已排产数量
|
|
|
+ sumQty += sumAmount;
|
|
|
+ //继续排下一个工作日
|
|
|
+ workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
+ isFstDay = false;
|
|
|
|
|
|
- //当天剩余产能(分钟)
|
|
|
- decimal restTime = (dto.EffTime - workTime) < 0 ? 0 : (dto.EffTime - workTime);
|
|
|
- if (sumTsTimes > 0)//存在特殊工单
|
|
|
- {
|
|
|
- if (restTime > 0)
|
|
|
- {
|
|
|
- #region 特殊工单排产-开始
|
|
|
- DateTime beginTime = workEndTime;//排产开始时间
|
|
|
- DateTime endTime = dto.EndTime;//排产结束时间
|
|
|
- //当天的可用产能满足特殊工单生产时长
|
|
|
- if (restTime >= sumTsTimes)
|
|
|
- {
|
|
|
- foreach (var item in workDtos)
|
|
|
- {
|
|
|
- if (item.LbrVar == item.Worked)//当前工单已排产
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- //当前工单还需工作时长
|
|
|
- decimal needTime = item.LbrVar - item.Worked;
|
|
|
- //计算工单排产结束时间
|
|
|
- var curPoint = workPoints.Find(p => p.StartPoint <= beginTime && beginTime <= p.EndPoint);
|
|
|
- span = curPoint.EndPoint - beginTime;
|
|
|
- //当天工作时间段的有效生产时间(分钟)
|
|
|
- decimal effMins = (decimal)span.TotalMinutes;
|
|
|
- if (effMins >= needTime)//当前工作时间段即可满足产能
|
|
|
- {
|
|
|
- endTime = beginTime.AddMinutes((double)needTime);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //获取后续生产时间段
|
|
|
- var nextPoints = workPoints.Where(p => p.Level > curPoint.Level).OrderBy(p => p.Level).ToList();
|
|
|
- //剩余需要工作时长
|
|
|
- decimal nextMins = needTime - effMins;
|
|
|
- foreach (var p in nextPoints)
|
|
|
- {
|
|
|
- if (p.WorkMinutes >= nextMins)
|
|
|
- {
|
|
|
- endTime = p.StartPoint.AddMinutes((double)nextMins);
|
|
|
- break;
|
|
|
- }
|
|
|
- nextMins -= p.WorkMinutes;
|
|
|
- }
|
|
|
- }
|
|
|
- //记录生产周期
|
|
|
- curSequences.Add(new PeriodSequenceDet
|
|
|
- {
|
|
|
- Domain = domain,
|
|
|
- Line = lineStart.Line,
|
|
|
- ItemNum = item.ItemNum,
|
|
|
- PlanDate = beginTime.Date,
|
|
|
- Period = dto.Period,
|
|
|
- OrdQty = item.QtyOrded - item.QtyWorked,
|
|
|
- WorkOrds = item.WorkOrd,
|
|
|
- Op = item.Op,
|
|
|
- IsActive = true,
|
|
|
- Status = "",
|
|
|
- CreateTime = DateTime.Now
|
|
|
- });
|
|
|
- //记录排产记录
|
|
|
- curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
- {
|
|
|
- Domain = domain,
|
|
|
- WorkOrd = item.WorkOrd,
|
|
|
- Line = lineStart.Line,
|
|
|
- ItemNum = item.ItemNum,
|
|
|
- Op = item.Op,
|
|
|
- WorkDate = beginTime.Date,
|
|
|
- WorkQty = item.QtyOrded - item.QtyWorked,
|
|
|
- WorkStartTime = beginTime,
|
|
|
- WorkEndTime = endTime,
|
|
|
- CreateTime = DateTime.Now
|
|
|
- });
|
|
|
- //下一工单开始时间=当前工单结束时间,如果位于工作区间结尾,则为下一工作区间开始时间
|
|
|
- curPoint = workPoints.Find(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
|
|
|
- if (endTime == curPoint.EndPoint)//结束时间位于工作区间结尾
|
|
|
- {
|
|
|
- //获取后续生产时间段
|
|
|
- var nextPoint = workPoints.Where(p => p.Level == curPoint.Level + 1).FirstOrDefault();
|
|
|
- if (nextPoint != null)//存在后续工作区间
|
|
|
- {
|
|
|
- endTime = nextPoint.StartPoint;
|
|
|
- }
|
|
|
- }
|
|
|
- beginTime = endTime;
|
|
|
- //工单排产完成,排产时长=工单工作时长
|
|
|
- item.Worked = item.LbrVar;
|
|
|
- item.QtyWorked = item.QtyOrded;
|
|
|
- sumTsTimes -= needTime;
|
|
|
- }
|
|
|
- sumTsTimes = 0;//排产完毕,特殊工单时长置0
|
|
|
+ //排产完毕,特殊工单时长置0
|
|
|
+ sumTsTimes = 0;
|
|
|
+ //当天的特殊工单排产完成
|
|
|
+ isFullPC = true;
|
|
|
}
|
|
|
- //当天的可用产能不满足特殊工单生产时长
|
|
|
+ //当天的可用产能不满足或者刚好满足特殊工单生产时长
|
|
|
else
|
|
|
{
|
|
|
foreach (var item in workDtos)
|
|
|
@@ -2023,7 +2055,7 @@ namespace Business.ResourceExamineManagement
|
|
|
//当前工单剩余待排产时长(分钟)
|
|
|
decimal needTime = item.LbrVar - item.Worked;
|
|
|
//当天剩余产能满足当前工单的剩余待排产时长
|
|
|
- if (restTime >= needTime)
|
|
|
+ if (residueTime >= needTime)
|
|
|
{
|
|
|
//计算工单排产结束时间
|
|
|
var curPoint = workPoints.Find(p => p.StartPoint <= beginTime && beginTime <= p.EndPoint);
|
|
|
@@ -2093,8 +2125,8 @@ namespace Business.ResourceExamineManagement
|
|
|
item.Worked = item.LbrVar;
|
|
|
item.QtyWorked = item.QtyWorked;
|
|
|
//当天剩余产能
|
|
|
- restTime -= needTime;
|
|
|
- if (restTime == 0)
|
|
|
+ residueTime -= needTime;
|
|
|
+ if (residueTime == 0)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
@@ -2102,7 +2134,7 @@ namespace Business.ResourceExamineManagement
|
|
|
else//当天剩余产能不满足当前工单的剩余待排产时长
|
|
|
{
|
|
|
//计算生产数量
|
|
|
- decimal qty = Math.Ceiling(restTime / item.LbrVar * item.QtyOrded);
|
|
|
+ decimal qty = Math.Ceiling(residueTime / item.LbrVar * item.QtyOrded);
|
|
|
//记录生产周期
|
|
|
curSequences.Add(new PeriodSequenceDet
|
|
|
{
|
|
|
@@ -2132,25 +2164,373 @@ namespace Business.ResourceExamineManagement
|
|
|
WorkEndTime = endTime,
|
|
|
CreateTime = DateTime.Now
|
|
|
});
|
|
|
- item.Worked += restTime;
|
|
|
+ item.Worked += residueTime;
|
|
|
item.QtyWorked += qty;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
//特殊工单剩余待排产时长(分钟)
|
|
|
- sumTsTimes -= restTime;
|
|
|
+ sumTsTimes -= residueTime;
|
|
|
+ isFullPC = true;
|
|
|
+ if (sumTsTimes > 0)
|
|
|
+ {
|
|
|
+ //当天的特殊工单未排产完成
|
|
|
+ isFullPC = false;
|
|
|
+ }
|
|
|
//获取下一个工作日
|
|
|
workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
isFstDay = false;
|
|
|
}
|
|
|
- #endregion 特殊工单排产-结束
|
|
|
}
|
|
|
- else {
|
|
|
+ //不存在特殊工单
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //记录生产周期
|
|
|
+ curSequences.Add(new PeriodSequenceDet
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = workOrd.ItemNum,
|
|
|
+ PlanDate = workStartTime.Date,
|
|
|
+ Period = dto.Period,
|
|
|
+ OrdQty = dto.ProductQty,
|
|
|
+ WorkOrds = workOrd.WorkOrd,
|
|
|
+ Op = lineStart.Op,
|
|
|
+ IsActive = true,
|
|
|
+ Status = "",
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录排产记录
|
|
|
+ curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ WorkOrd = workOrd.WorkOrd,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = workOrd.ItemNum,
|
|
|
+ Op = lineStart.Op,
|
|
|
+ WorkDate = workStartTime.Date,
|
|
|
+ WorkQty = dto.ProductQty,
|
|
|
+ WorkStartTime = dto.StartTime,
|
|
|
+ WorkEndTime = dto.EndTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //累计已排产数量
|
|
|
+ sumQty += dto.ProductQty;
|
|
|
//继续排下一个工作日
|
|
|
workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
isFstDay = false;
|
|
|
}
|
|
|
}
|
|
|
+ else// 当天的产能正常工单刚好占用或者只能占用一部分
|
|
|
+ {
|
|
|
+ decimal workTime = 0m;
|
|
|
+ DateTime workEndTime = workStartTime;
|
|
|
+ if (sumQty < workOrd.QtyOrded)
|
|
|
+ {
|
|
|
+ #region 正常工单排产-开始
|
|
|
+ //剩余需要排产的数量
|
|
|
+ decimal residueQty = workOrd.QtyOrded - sumQty;
|
|
|
+ //剩余数量生产需要时长(分钟)
|
|
|
+ workTime = Math.Ceiling(residueQty / dto.Rate * 60);
|
|
|
+ var curPoint = workPoints.Find(p => p.StartPoint <= workStartTime && workStartTime <= p.EndPoint);
|
|
|
+ span = curPoint.EndPoint - workStartTime;
|
|
|
+ //当天工作时间段的有效生产时间
|
|
|
+ decimal effMins = (decimal)span.TotalMinutes;
|
|
|
+ //当前工作时间段即可满足产能
|
|
|
+ if (effMins >= workTime)
|
|
|
+ {
|
|
|
+ workEndTime = workStartTime.AddMinutes((double)workTime);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //获取后续生产时间段
|
|
|
+ var nextPoints = workPoints.Where(p => p.Level > curPoint.Level).OrderBy(p => p.Level).ToList();
|
|
|
+ //剩余需要工作时长
|
|
|
+ decimal nextMins = workTime - effMins;
|
|
|
+ foreach (var p in nextPoints)
|
|
|
+ {
|
|
|
+ if (p.WorkMinutes >= nextMins)
|
|
|
+ {
|
|
|
+ workEndTime = p.StartPoint.AddMinutes((double)nextMins);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ nextMins -= p.WorkMinutes;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sumQty = workOrd.QtyOrded;
|
|
|
+ //记录生产周期
|
|
|
+ curSequences.Add(new PeriodSequenceDet
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = workOrd.ItemNum,
|
|
|
+ PlanDate = workStartTime.Date,
|
|
|
+ Period = dto.Period,
|
|
|
+ OrdQty = residueQty,
|
|
|
+ WorkOrds = workOrd.WorkOrd,
|
|
|
+ Op = lineStart.Op,
|
|
|
+ IsActive = true,
|
|
|
+ Status = "",
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录排产记录
|
|
|
+ curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ WorkOrd = workOrd.WorkOrd,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = workOrd.ItemNum,
|
|
|
+ Op = lineStart.Op,
|
|
|
+ WorkDate = workStartTime.Date,
|
|
|
+ WorkQty = residueQty,
|
|
|
+ WorkStartTime = workStartTime,
|
|
|
+ WorkEndTime = workEndTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ #endregion 正常工单排产-结束
|
|
|
+ }
|
|
|
+
|
|
|
+ //当天剩余产能(分钟)
|
|
|
+ decimal restTime = (dto.EffTime - workTime) < 0 ? 0 : (dto.EffTime - workTime);
|
|
|
+ if (sumTsTimes > 0)//存在特殊工单
|
|
|
+ {
|
|
|
+ if (restTime > 0)
|
|
|
+ {
|
|
|
+ #region 特殊工单排产-开始
|
|
|
+ DateTime beginTime = workEndTime;//排产开始时间
|
|
|
+ DateTime endTime = dto.EndTime;//排产结束时间
|
|
|
+ //当天的可用产能满足特殊工单生产时长
|
|
|
+ if (restTime >= sumTsTimes)
|
|
|
+ {
|
|
|
+ foreach (var item in workDtos)
|
|
|
+ {
|
|
|
+ if (item.LbrVar == item.Worked)//当前工单已排产
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //当前工单还需工作时长
|
|
|
+ decimal needTime = item.LbrVar - item.Worked;
|
|
|
+ //计算工单排产结束时间
|
|
|
+ var curPoint = workPoints.Find(p => p.StartPoint <= beginTime && beginTime <= p.EndPoint);
|
|
|
+ span = curPoint.EndPoint - beginTime;
|
|
|
+ //当天工作时间段的有效生产时间(分钟)
|
|
|
+ decimal effMins = (decimal)span.TotalMinutes;
|
|
|
+ if (effMins >= needTime)//当前工作时间段即可满足产能
|
|
|
+ {
|
|
|
+ endTime = beginTime.AddMinutes((double)needTime);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //获取后续生产时间段
|
|
|
+ var nextPoints = workPoints.Where(p => p.Level > curPoint.Level).OrderBy(p => p.Level).ToList();
|
|
|
+ //剩余需要工作时长
|
|
|
+ decimal nextMins = needTime - effMins;
|
|
|
+ foreach (var p in nextPoints)
|
|
|
+ {
|
|
|
+ if (p.WorkMinutes >= nextMins)
|
|
|
+ {
|
|
|
+ endTime = p.StartPoint.AddMinutes((double)nextMins);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ nextMins -= p.WorkMinutes;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //记录生产周期
|
|
|
+ curSequences.Add(new PeriodSequenceDet
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ PlanDate = beginTime.Date,
|
|
|
+ Period = dto.Period,
|
|
|
+ OrdQty = item.QtyOrded - item.QtyWorked,
|
|
|
+ WorkOrds = item.WorkOrd,
|
|
|
+ Op = item.Op,
|
|
|
+ IsActive = true,
|
|
|
+ Status = "",
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录排产记录
|
|
|
+ curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = item.Op,
|
|
|
+ WorkDate = beginTime.Date,
|
|
|
+ WorkQty = item.QtyOrded - item.QtyWorked,
|
|
|
+ WorkStartTime = beginTime,
|
|
|
+ WorkEndTime = endTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //下一工单开始时间=当前工单结束时间,如果位于工作区间结尾,则为下一工作区间开始时间
|
|
|
+ curPoint = workPoints.Find(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
|
|
|
+ if (endTime == curPoint.EndPoint)//结束时间位于工作区间结尾
|
|
|
+ {
|
|
|
+ //获取后续生产时间段
|
|
|
+ var nextPoint = workPoints.Where(p => p.Level == curPoint.Level + 1).FirstOrDefault();
|
|
|
+ if (nextPoint != null)//存在后续工作区间
|
|
|
+ {
|
|
|
+ endTime = nextPoint.StartPoint;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ beginTime = endTime;
|
|
|
+ //工单排产完成,排产时长=工单工作时长
|
|
|
+ item.Worked = item.LbrVar;
|
|
|
+ item.QtyWorked = item.QtyOrded;
|
|
|
+ sumTsTimes -= needTime;
|
|
|
+ }
|
|
|
+ sumTsTimes = 0;//排产完毕,特殊工单时长置0
|
|
|
+ //当天的特殊工单以排产完成
|
|
|
+ isFullPC = true;
|
|
|
+ }
|
|
|
+ //当天的可用产能不满足特殊工单生产时长
|
|
|
+ else
|
|
|
+ {
|
|
|
+ foreach (var item in workDtos)
|
|
|
+ {
|
|
|
+ if (item.LbrVar == item.Worked)//当前工单已排产
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //当前工单剩余待排产时长(分钟)
|
|
|
+ decimal needTime = item.LbrVar - item.Worked;
|
|
|
+ //当天剩余产能满足当前工单的剩余待排产时长
|
|
|
+ if (restTime >= needTime)
|
|
|
+ {
|
|
|
+ //计算工单排产结束时间
|
|
|
+ var curPoint = workPoints.Find(p => p.StartPoint <= beginTime && beginTime <= p.EndPoint);
|
|
|
+ span = curPoint.EndPoint - beginTime;
|
|
|
+ //当前工作时间段的有效生产时间(分钟)
|
|
|
+ decimal effMins = (decimal)span.TotalMinutes;
|
|
|
+ if (effMins >= needTime)//当前工作时间段即可满足产能
|
|
|
+ {
|
|
|
+ endTime = beginTime.AddMinutes((double)needTime);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //获取后续生产时间段
|
|
|
+ var nextPoints = workPoints.Where(p => p.Level > curPoint.Level).OrderBy(p => p.Level).ToList();
|
|
|
+ //剩余需要工作时长
|
|
|
+ decimal nextMins = needTime - effMins;
|
|
|
+ foreach (var p in nextPoints)
|
|
|
+ {
|
|
|
+ if (p.WorkMinutes >= nextMins)
|
|
|
+ {
|
|
|
+ endTime = p.StartPoint.AddMinutes((double)nextMins);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ nextMins -= p.WorkMinutes;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //记录生产周期
|
|
|
+ curSequences.Add(new PeriodSequenceDet
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ PlanDate = beginTime.Date,
|
|
|
+ Period = dto.Period,
|
|
|
+ OrdQty = item.QtyOrded - item.QtyWorked,
|
|
|
+ WorkOrds = item.WorkOrd,
|
|
|
+ Op = item.Op,
|
|
|
+ IsActive = true,
|
|
|
+ Status = "",
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录排产记录
|
|
|
+ curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = item.Op,
|
|
|
+ WorkDate = beginTime.Date,
|
|
|
+ WorkQty = item.QtyOrded - item.QtyWorked,
|
|
|
+ WorkStartTime = beginTime,
|
|
|
+ WorkEndTime = endTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ curPoint = workPoints.Find(p => p.StartPoint <= endTime && endTime <= p.EndPoint);
|
|
|
+ if (endTime == curPoint.EndPoint)
|
|
|
+ {
|
|
|
+ var nextPoint = workPoints.FirstOrDefault(p => p.Level == curPoint.Level + 1);
|
|
|
+ if (nextPoint != null)
|
|
|
+ {
|
|
|
+ endTime = nextPoint.StartPoint;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ beginTime = endTime;
|
|
|
+ //当前工单已排产完成,已排产时间=工单生产时长,已排产数量=工单数量
|
|
|
+ item.Worked = item.LbrVar;
|
|
|
+ item.QtyWorked = item.QtyWorked;
|
|
|
+ //当天剩余产能
|
|
|
+ restTime -= needTime;
|
|
|
+ if (restTime == 0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else//当天剩余产能不满足当前工单的剩余待排产时长
|
|
|
+ {
|
|
|
+ //计算生产数量
|
|
|
+ decimal qty = Math.Ceiling(restTime / item.LbrVar * item.QtyOrded);
|
|
|
+ //记录生产周期
|
|
|
+ curSequences.Add(new PeriodSequenceDet
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ PlanDate = beginTime.Date,
|
|
|
+ Period = dto.Period,
|
|
|
+ OrdQty = qty,
|
|
|
+ WorkOrds = item.WorkOrd,
|
|
|
+ Op = item.Op,
|
|
|
+ IsActive = true,
|
|
|
+ Status = "",
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录排产记录
|
|
|
+ curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
+ {
|
|
|
+ Domain = domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ Line = lineStart.Line,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = item.Op,
|
|
|
+ WorkDate = beginTime.Date,
|
|
|
+ WorkQty = qty,
|
|
|
+ WorkStartTime = beginTime,
|
|
|
+ WorkEndTime = endTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ item.Worked += restTime;
|
|
|
+ item.QtyWorked += qty;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //特殊工单剩余待排产时长(分钟)
|
|
|
+ sumTsTimes -= restTime;
|
|
|
+ //当天的特殊工单未排产完成
|
|
|
+ isFullPC = false;
|
|
|
+ //获取下一个工作日
|
|
|
+ workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
+ isFstDay = false;
|
|
|
+ }
|
|
|
+ #endregion 特殊工单排产-结束
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //继续排下一个工作日
|
|
|
+ workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
+ isFstDay = false;
|
|
|
+ //当天的特殊工单未排产完成
|
|
|
+ isFullPC = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|