|
|
@@ -411,6 +411,7 @@ namespace Business.ResourceExamineManagement
|
|
|
decimal planQty = Math.Ceiling(sumTimes / (item.LbrVar * 60) * item.QtyOrded);
|
|
|
//剩余排产数量 = 工单数量 - 已报工数量 - 计划数量
|
|
|
decimal qtyNeed = item.QtyOrded - curOp.QtyComplete - planQty;
|
|
|
+ qtyNeed = qtyNeed < 0 ? 0 : qtyNeed;
|
|
|
//剩余工作时长(分钟)
|
|
|
decimal usedTime = Math.Ceiling(qtyNeed / item.QtyOrded * item.LbrVar * 60);
|
|
|
|
|
|
@@ -491,15 +492,15 @@ namespace Business.ResourceExamineManagement
|
|
|
//获取当天重新排产的工单日计划
|
|
|
var tdSeqDtls = periodSequenceDtls.Where(p => p.PlanDate == scheTime.Date).ToList();
|
|
|
var tdSchMsts = scheduleMasters.Where(p => p.WorkDate == scheTime.Date).ToList();
|
|
|
- //删除数据库中的已存在的日计划
|
|
|
- _periodSequenceDet.Delete(p=>p.Domain == domain && tdSeqDtls.Select(m => m.WorkOrds).Contains(p.WorkOrds) && p.PlanDate == scheTime.Date);
|
|
|
- _scheduleResultOpMaster.Delete(p=>p.Domain == domain && tdSchMsts.Select(m => m.WorkOrd).Contains(p.WorkOrd) && p.WorkDate == scheTime.Date);
|
|
|
+ //删除数据库中的已存在的当天日计划
|
|
|
+ _periodSequenceDet.Delete(p=>p.Domain == domain && tdSeqDtls.Select(m => m.Op).Contains(p.Op) && tdSeqDtls.Select(m => m.WorkOrds).Contains(p.WorkOrds) && p.PlanDate == scheTime.Date);
|
|
|
+ _scheduleResultOpMaster.Delete(p=>p.Domain == domain && tdSchMsts.Select(m => m.Op).Contains(p.Op) && tdSchMsts.Select(m => m.WorkOrd).Contains(p.WorkOrd) && p.WorkDate == scheTime.Date);
|
|
|
//更新当天日计划的计划数量,排产数量
|
|
|
foreach (var item in periodSequenceDtls)
|
|
|
{
|
|
|
item.UDeci1 = item.OrdQty.GetValueOrDefault();
|
|
|
//获取历史排产数据
|
|
|
- var curDtl = dbPeriodSequences.FirstOrDefault(p => p.WorkOrds == item.WorkOrds && p.Line == item.Line && p.PlanDate == scheTime.Date);
|
|
|
+ var curDtl = dbPeriodSequences.FirstOrDefault(p => p.Op == item.Op && p.WorkOrds == item.WorkOrds && p.Line == item.Line && p.PlanDate == scheTime.Date);
|
|
|
item.OrdQty = curDtl == null ? item.OrdQty : curDtl.OrdQty;
|
|
|
}
|
|
|
//保存日计划数据
|
|
|
@@ -724,11 +725,6 @@ namespace Business.ResourceExamineManagement
|
|
|
//第一层级工序有几个关键工序,就有几条产线
|
|
|
for (int i = 0; i < workOrdRoutings.Count; i++)
|
|
|
{
|
|
|
- //如果当前工序已经生产完成,则跳过
|
|
|
- if (workOrdRoutings[i].QtyComplete == workOrd.QtyOrded)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
//产线实际排产开始时间
|
|
|
if (i == 0)//第一条产线
|
|
|
{
|
|
|
@@ -739,12 +735,18 @@ namespace Business.ResourceExamineManagement
|
|
|
//获取前一产线排产开始时间,通过提前期计算当前产线排产开始时间
|
|
|
lineStart = DealNextStartTime(workOrd, lineStart, workOrdRoutings[i], prodLines, allResults);
|
|
|
}
|
|
|
+ //如果当前工序已经生产完成,则跳过
|
|
|
+ if (lineStart.QtyRemain == 0)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
//当前产线的工作日历
|
|
|
var mLCalendars = calendars.Where(p => p.ProdLine == lineStart.Line || string.IsNullOrEmpty(p.ProdLine)).ToList();
|
|
|
//当前产线的休息时间设置
|
|
|
var mlqtyWorkDtls = qualityLines.Where(p => p.ProdLine == lineStart.Line).ToList();
|
|
|
//产线排产开始时间
|
|
|
- DateTime workStartTime = scheTime;
|
|
|
+ DateTime workStartTime = lineStart.StartTime;
|
|
|
//记录特殊工单:获取第一天是否有特殊工单
|
|
|
List<WorkOrdMaster> fstWOMasters = tsWorkOrds.Where(p => p.ProdLine == lineStart.Line && p.OrdDate.Value.Date == workStartTime.Date).OrderBy(p => p.Priority).ToList();
|
|
|
List<WorkOrdMstDto> workDtos = new List<WorkOrdMstDto>();
|
|
|
@@ -763,39 +765,86 @@ namespace Business.ResourceExamineManagement
|
|
|
foreach (var item in fstWOMasters)
|
|
|
{
|
|
|
//注:特殊工单暂时只考虑连续生产,不考虑暂停
|
|
|
+ DateTime tsStartTime = workStartTime;
|
|
|
+ var first = fstWOMasters.First();
|
|
|
+ if (item != first)
|
|
|
+ {
|
|
|
+ tsStartTime = item.OrdDate.GetValueOrDefault();
|
|
|
+ }
|
|
|
//特殊工单工序
|
|
|
var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
|
|
|
//获取特殊工单开始排产时间记录
|
|
|
var curRecord = timeRecords.FirstOrDefault(p => p.WorkOrd == item.WorkOrd && p.Op == curOp.OP);
|
|
|
- //if (curRecord == null)
|
|
|
- //{
|
|
|
- // //添加记录
|
|
|
- // inserts.Add(new WorkOrdSetupTimeRecord
|
|
|
- // {
|
|
|
- // Domain = item.Domain,
|
|
|
- // WorkOrd = item.WorkOrd,
|
|
|
- // ItemNum = item.ItemNum,
|
|
|
- // Op = curOp.OP,
|
|
|
- // Line = item.ProdLine,
|
|
|
- // StartTime = tStartTime,
|
|
|
- // CreateTime = DateTime.Now
|
|
|
- // });
|
|
|
- // //记录工序开始准备时间记录
|
|
|
- // timeRecords.Add(new WorkOrdSetupTimeRecord
|
|
|
- // {
|
|
|
- // Domain = item.Domain,
|
|
|
- // WorkOrd = item.WorkOrd,
|
|
|
- // ItemNum = item.ItemNum,
|
|
|
- // Op = curOp.OP,
|
|
|
- // Line = item.ProdLine,
|
|
|
- // StartTime = tStartTime,
|
|
|
- // CreateTime = DateTime.Now
|
|
|
- // });
|
|
|
- //}
|
|
|
-
|
|
|
-
|
|
|
- //剩余排产数量
|
|
|
- decimal qtyNeed = item.QtyOrded - curOp.QtyComplete;
|
|
|
+ //如果产线有准备时间记录且准备开始时间在当前时间之前,说明已在排产中,此时不需要重新获取产线
|
|
|
+ if (curRecord != null && curRecord.StartTime < tsStartTime)
|
|
|
+ {
|
|
|
+ tsStartTime = workStartTime;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (curRecord == null)
|
|
|
+ {
|
|
|
+ //添加记录
|
|
|
+ inserts.Add(new WorkOrdSetupTimeRecord
|
|
|
+ {
|
|
|
+ Domain = item.Domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = curOp.OP,
|
|
|
+ Line = item.ProdLine,
|
|
|
+ StartTime = tsStartTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录工序开始准备时间记录
|
|
|
+ timeRecords.Add(new WorkOrdSetupTimeRecord
|
|
|
+ {
|
|
|
+ Domain = item.Domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = curOp.OP,
|
|
|
+ Line = item.ProdLine,
|
|
|
+ StartTime = tsStartTime,
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //更新准备开始时间记录
|
|
|
+ timeRecords.ForEach(p =>
|
|
|
+ {
|
|
|
+ p.StartTime = p.WorkOrd == curRecord.WorkOrd && p.Op == curRecord.Op ? tsStartTime : p.StartTime;
|
|
|
+ });
|
|
|
+ //存在开始准备时间记录,则更新
|
|
|
+ curRecord.StartTime = tsStartTime;
|
|
|
+ updates.Add(curRecord);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //计算开始排产时间或者上次报工时间到当前时间点的预估产能
|
|
|
+ decimal sumWorkTimes = 0m;
|
|
|
+ //工单没有报工记录
|
|
|
+ if (curOp.Last == null)
|
|
|
+ {
|
|
|
+ if (curRecord == null)
|
|
|
+ {
|
|
|
+ //工单没有开始时间记录,取预计开工时间到当前时间的有效时长
|
|
|
+ sumWorkTimes = 0m;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //工单有开始时间记录,取开始时间到当前时间的有效时长
|
|
|
+ sumWorkTimes = CalcTimeMins(curRecord.StartTime, workStartTime, item.ProdLine);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //工单有报工记录,取最新报工时间到当前时间的有效时长
|
|
|
+ sumWorkTimes = CalcTimeMins(curOp.Last.GetValueOrDefault(), workStartTime, item.ProdLine);
|
|
|
+ }
|
|
|
+ //计算预估数量
|
|
|
+ decimal planQty = Math.Ceiling(sumWorkTimes / (item.LbrVar * 60) * item.QtyOrded);
|
|
|
+ //剩余排产数量 = 工单数量 - 已报工数量 - 计划数量
|
|
|
+ decimal qtyNeed = item.QtyOrded - curOp.QtyComplete - planQty;
|
|
|
+ qtyNeed = qtyNeed < 0 ? 0 : qtyNeed;
|
|
|
//剩余工作时长(分钟)
|
|
|
decimal usedTime = Math.Ceiling(qtyNeed / item.QtyOrded * item.LbrVar * 60);
|
|
|
workDtos.Add(new WorkOrdMstDto
|
|
|
@@ -848,7 +897,35 @@ namespace Business.ResourceExamineManagement
|
|
|
//记录新增待排产特殊工单
|
|
|
foreach (var item in secWOMasters)
|
|
|
{
|
|
|
+ //注:特殊工单暂时只考虑连续生产,不考虑暂停
|
|
|
var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
|
|
|
+ //获取特殊工单开始排产时间记录
|
|
|
+ var curRecord = timeRecords.FirstOrDefault(p => p.WorkOrd == item.WorkOrd && p.Op == curOp.OP);
|
|
|
+ if (curRecord == null)
|
|
|
+ {
|
|
|
+ //添加记录
|
|
|
+ inserts.Add(new WorkOrdSetupTimeRecord
|
|
|
+ {
|
|
|
+ Domain = item.Domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = curOp.OP,
|
|
|
+ Line = item.ProdLine,
|
|
|
+ StartTime = item.OrdDate.GetValueOrDefault(),
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录工序开始准备时间记录
|
|
|
+ timeRecords.Add(new WorkOrdSetupTimeRecord
|
|
|
+ {
|
|
|
+ Domain = item.Domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = curOp.OP,
|
|
|
+ Line = item.ProdLine,
|
|
|
+ StartTime = item.OrdDate.GetValueOrDefault(),
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ }
|
|
|
//剩余排产数量
|
|
|
decimal qtyNeed = item.QtyOrded - curOp.QtyComplete;
|
|
|
//剩余工作时长(分钟)
|
|
|
@@ -1037,6 +1114,33 @@ namespace Business.ResourceExamineManagement
|
|
|
foreach (var item in secWOMasters)
|
|
|
{
|
|
|
var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
|
|
|
+ //获取特殊工单开始排产时间记录
|
|
|
+ var curRecord = timeRecords.FirstOrDefault(p => p.WorkOrd == item.WorkOrd && p.Op == curOp.OP);
|
|
|
+ if (curRecord == null)
|
|
|
+ {
|
|
|
+ //添加记录
|
|
|
+ inserts.Add(new WorkOrdSetupTimeRecord
|
|
|
+ {
|
|
|
+ Domain = item.Domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = curOp.OP,
|
|
|
+ Line = item.ProdLine,
|
|
|
+ StartTime = item.OrdDate.GetValueOrDefault(),
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录工序开始准备时间记录
|
|
|
+ timeRecords.Add(new WorkOrdSetupTimeRecord
|
|
|
+ {
|
|
|
+ Domain = item.Domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = curOp.OP,
|
|
|
+ Line = item.ProdLine,
|
|
|
+ StartTime = item.OrdDate.GetValueOrDefault(),
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ }
|
|
|
//剩余排产数量
|
|
|
decimal qtyNeed = item.QtyOrded - curOp.QtyComplete;
|
|
|
//剩余工作时长(分钟)
|
|
|
@@ -1302,6 +1406,33 @@ namespace Business.ResourceExamineManagement
|
|
|
foreach (var item in secWOMasters)
|
|
|
{
|
|
|
var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
|
|
|
+ //获取特殊工单开始排产时间记录
|
|
|
+ var curRecord = timeRecords.FirstOrDefault(p => p.WorkOrd == item.WorkOrd && p.Op == curOp.OP);
|
|
|
+ if (curRecord == null)
|
|
|
+ {
|
|
|
+ //添加记录
|
|
|
+ inserts.Add(new WorkOrdSetupTimeRecord
|
|
|
+ {
|
|
|
+ Domain = item.Domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = curOp.OP,
|
|
|
+ Line = item.ProdLine,
|
|
|
+ StartTime = item.OrdDate.GetValueOrDefault(),
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ //记录工序开始准备时间记录
|
|
|
+ timeRecords.Add(new WorkOrdSetupTimeRecord
|
|
|
+ {
|
|
|
+ Domain = item.Domain,
|
|
|
+ WorkOrd = item.WorkOrd,
|
|
|
+ ItemNum = item.ItemNum,
|
|
|
+ Op = curOp.OP,
|
|
|
+ Line = item.ProdLine,
|
|
|
+ StartTime = item.OrdDate.GetValueOrDefault(),
|
|
|
+ CreateTime = DateTime.Now
|
|
|
+ });
|
|
|
+ }
|
|
|
//剩余排产数量
|
|
|
decimal qtyNeed = item.QtyOrded - curOp.QtyComplete;
|
|
|
//剩余工作时长(分钟)
|
|
|
@@ -3885,6 +4016,13 @@ namespace Business.ResourceExamineManagement
|
|
|
scheduledDto.EndTime = workPoints.Last().EndPoint;
|
|
|
//计算starttime处于那个工作时间段
|
|
|
var curPoint = workPoints.Where(p => startTime >= p.StartPoint && startTime <= p.EndPoint).First();
|
|
|
+ //开始时间不在工作时间段
|
|
|
+ if (curPoint == null)
|
|
|
+ {
|
|
|
+ //获取离开始时间最近的时间段
|
|
|
+ curPoint = workPoints.Where(p => p.EndPoint < startTime).OrderBy(p => p.Level).Last();
|
|
|
+ startTime = curPoint.EndPoint;
|
|
|
+ }
|
|
|
TimeSpan span = curPoint.EndPoint - startTime;
|
|
|
scheduledDto.EffTime = (decimal)span.TotalMinutes;
|
|
|
//获取后续工作时间段的有效工作时间
|
|
|
@@ -3900,7 +4038,15 @@ namespace Business.ResourceExamineManagement
|
|
|
var curLevel = curRunCrews.FirstOrDefault(p => p.StartDate.GetValueOrDefault().Date <= startTime.Date && p.EndDate.GetValueOrDefault().Date >= startTime.Date);
|
|
|
decimal rate = curLevel == null ? lineStart.Rate : curLevel.Rate;
|
|
|
scheduledDto.Rate = rate;
|
|
|
- //计算当天的产能(向下取整)
|
|
|
+ //产线当天加班设置
|
|
|
+ var curOccupyTimes = resourceOccupancyTimes.Where(p => p.Resource == lineStart.Line && p.StartTime.GetValueOrDefault().Date == startTime.Date).OrderBy(p => p.StartTime).ToList();
|
|
|
+ scheduledDto.EffTime += curOccupyTimes.Sum(p=> Convert.ToDecimal(p.Ufld1) * 60);
|
|
|
+ if (curOccupyTimes.Any())
|
|
|
+ {
|
|
|
+ var last = curOccupyTimes.Last();
|
|
|
+ scheduledDto.EndTime = last.StartTime.GetValueOrDefault().AddHours(Convert.ToDouble(last.Ufld1));
|
|
|
+ }
|
|
|
+ //计算当天的产能(向上取整)
|
|
|
scheduledDto.ProductQty = Math.Ceiling(scheduledDto.EffTime / 60 * rate);
|
|
|
//计算班次
|
|
|
scheduledDto.Period = 1;//默认一班制
|
|
|
@@ -3934,6 +4080,11 @@ namespace Business.ResourceExamineManagement
|
|
|
if (curRecord != null && curRecord.StartTime < actStart)
|
|
|
{
|
|
|
var curLine = lines.First(p=>p.Line == curRecord.Line);
|
|
|
+ //计算产线实际开始时间
|
|
|
+ //产线工作日历:当前产线的工作日历 + 默认工作日历
|
|
|
+ var curCalendars = calendars.Where(p => p.ProdLine == curLine.Line || string.IsNullOrEmpty(p.ProdLine)).ToList();
|
|
|
+ var curQtyDtls = qualityLines.Where(p => p.ProdLine == curLine.Line).ToList();
|
|
|
+ actStart = CalcActStartTime(curLine.Line, actStart, curCalendars, curQtyDtls);
|
|
|
lineStart.RecID = curLine.RecID;
|
|
|
lineStart.Line = curLine.Line;
|
|
|
lineStart.StartTime = actStart;
|
|
|
@@ -4049,6 +4200,7 @@ namespace Business.ResourceExamineManagement
|
|
|
}
|
|
|
//剩余待排产数量=工单数量-已报工数量-预估数量
|
|
|
lineStart.QtyRemain = workOrd.QtyOrded - routing.QtyComplete - planQty;
|
|
|
+ lineStart.QtyRemain = lineStart.QtyRemain < 0 ? 0 : lineStart.QtyRemain;
|
|
|
return lineStart;
|
|
|
}
|
|
|
|
|
|
@@ -4436,6 +4588,7 @@ namespace Business.ResourceExamineManagement
|
|
|
}
|
|
|
//剩余待排产数量=工单数量-已报工数量-预估数量
|
|
|
startDto.QtyRemain = workOrd.QtyOrded - routing.QtyComplete - planQty;
|
|
|
+ startDto.QtyRemain = startDto.QtyRemain < 0 ? 0 : startDto.QtyRemain;
|
|
|
return startDto;
|
|
|
}
|
|
|
|