|
|
@@ -155,7 +155,8 @@ namespace Business.Quartz
|
|
|
public async Task DoProductShcedule()
|
|
|
{
|
|
|
//1、获取需要排产的工单:Status为空且IsActive==1
|
|
|
- List<WorkOrdMaster> workOrds = _workOrdMaster.Select(p => string.IsNullOrEmpty(p.Status) && p.IsActive == 1).Result;
|
|
|
+ //List<WorkOrdMaster> workOrds = _workOrdMaster.Select(p => string.IsNullOrEmpty(p.Status) && p.IsActive == 1).Result;
|
|
|
+ List<WorkOrdMaster> workOrds = _workOrdMaster.Select(p => p.WorkOrd == "Test0000001").Result;
|
|
|
if (workOrds.Count == 0)
|
|
|
{
|
|
|
return;
|
|
|
@@ -164,19 +165,19 @@ namespace Business.Quartz
|
|
|
DateTime earlist = workOrds.Min(p => p.OrdDate.GetValueOrDefault()).Date;
|
|
|
//2、获取数据
|
|
|
//获取工单工艺路径数据
|
|
|
- List<WorkOrdRouting> workOrdRoutings = _workOrdRouting.Select(p => workOrds.Select(m => m.WorkOrd).Contains(p.WorkOrd) && p.Domain == "1001" && p.Status != "C" && p.IsActive == 1).Result;
|
|
|
+ List<WorkOrdRouting> workOrdRoutings = _workOrdRouting.Select(p => workOrds.Select(m => m.WorkOrd).Contains(p.WorkOrd) && p.Domain == "1001" && p.Status != "C" && p.IsActive).Result;
|
|
|
//获取物料对应的生产线信息:物料、工序对应的生产线
|
|
|
- List<ProdLineDetail> prodLines = _prodLineDetail.Select(p => workOrds.Select(m => m.ItemNum).Contains(p.Part) && p.Domain == "1001" && p.IsActive == 1).Result;
|
|
|
+ List<ProdLineDetail> prodLines = _prodLineDetail.Select(p => workOrds.Select(m => m.ItemNum).Contains(p.Part) && p.Domain == "1001" && p.IsActive).Result;
|
|
|
//获取生产周期数据
|
|
|
- List<PeriodSequenceDet> dbPeriodSequences = _periodSequenceDet.Select(p=> workOrds.Select(m => m.ItemNum).Contains(p.ItemNum) && p.PlanDate >= earlist && p.Domain == "1001" && p.IsActive == 1).Result;
|
|
|
+ List<PeriodSequenceDet> dbPeriodSequences = _periodSequenceDet.Select(p=> workOrds.Select(m => m.ItemNum).Contains(p.ItemNum) && p.PlanDate >= earlist && p.Domain == "1001" && p.IsActive).Result;
|
|
|
//获取当前日期往后的排产记录数据
|
|
|
List<ScheduleResultOpMaster> dbSchedules = _scheduleResultOpMaster.Select(p => workOrds.Select(m => m.ItemNum).Contains(p.ItemNum) && p.WorkDate >= earlist && p.Domain == "1001").Result;
|
|
|
//获取工作日历数据
|
|
|
- calendars = _shopCalendarWorkCtr.Select(p=>p.Domain == "1001" && p.IsActive == 1).Result;
|
|
|
+ calendars = _shopCalendarWorkCtr.Select(p=>p.Domain == "1001" && p.IsActive).Result;
|
|
|
//获取产线休息记录数据
|
|
|
- qualityLines = _qualityLineWorkDetail.Select(p => p.Domain == "1001" && p.IsActive == 1).Result;
|
|
|
+ qualityLines = _qualityLineWorkDetail.Select(p => p.Domain == "1001" && p.IsActive).Result;
|
|
|
//获取节假日记录数据
|
|
|
- holidays = _holidayMaster.Select(p => p.Domain == "1001" && p.IsActive == 1 && p.Dated >= earlist).Result;
|
|
|
+ holidays = _holidayMaster.Select(p => p.Domain == "1001" && p.IsActive && p.Dated >= earlist).Result;
|
|
|
|
|
|
//3、排产
|
|
|
//排产异常记录
|
|
|
@@ -283,7 +284,7 @@ namespace Business.Quartz
|
|
|
//当前产线的工作日历
|
|
|
var mLCalendars = calendars.Where(p => p.ProdLine == item.Line).ToList();
|
|
|
//当前产线的每天休息时间记录
|
|
|
- var mlqtyWorkDtls = qualityLines.Where(p => p.ProdLine == item.Line).ToList();
|
|
|
+ var mlqtyWorkDtls = qualityLines.Where(p => p.ProdLine == item.Line).OrderBy(p => p.Line).ToList();
|
|
|
|
|
|
//产线已排产数量
|
|
|
decimal sumQty = 0m;
|
|
|
@@ -297,15 +298,17 @@ namespace Business.Quartz
|
|
|
{
|
|
|
//子产线获取实际排产开始日期
|
|
|
//获取父级排产开始时间
|
|
|
- DateTime parentStartTime = lineStarts.First(p => p.Op == item.ParentOp).StartTime;
|
|
|
+ DateTime parentStartTime = lineStarts.First(p => p.ChdParentOps.Contains(item.ParentOp)).StartTime;
|
|
|
workStartTime = DealChildStartTime(parentStartTime, item.SetupTime, mLCalendars, mlqtyWorkDtls);
|
|
|
}
|
|
|
//记录产线排产开始时间
|
|
|
- lineStarts.Add(new LineStartDto {
|
|
|
+ lineStarts.Add(new LineStartDto
|
|
|
+ {
|
|
|
level = item.level,
|
|
|
Line = item.Line,
|
|
|
- Op= item.Op,
|
|
|
- StartTime = workStartTime
|
|
|
+ Op = item.Op,
|
|
|
+ StartTime = workStartTime,
|
|
|
+ ChdParentOps = item.ChdParentOps
|
|
|
});
|
|
|
//排产
|
|
|
while (sumQty < workOrd.QtyOrded)
|
|
|
@@ -326,7 +329,7 @@ namespace Business.Quartz
|
|
|
OrdQty = dto.ProductQty,
|
|
|
WorkOrds = workOrd.WorkOrd,
|
|
|
Op = item.Op,
|
|
|
- IsActive = 1
|
|
|
+ IsActive = true
|
|
|
});
|
|
|
//记录排产记录
|
|
|
curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
@@ -340,7 +343,7 @@ namespace Business.Quartz
|
|
|
WorkQty = dto.ProductQty,
|
|
|
WorkStartTime = dto.StartTime,
|
|
|
WorkEndTime = dto.EndTime,
|
|
|
- CreatTime = DateTime.Now
|
|
|
+ CreateTime = DateTime.Now
|
|
|
});
|
|
|
//累计已排产数量
|
|
|
sumQty += dto.ProductQty;
|
|
|
@@ -352,7 +355,7 @@ namespace Business.Quartz
|
|
|
//剩余需要排产的数量
|
|
|
decimal residueQty = workOrd.QtyOrded - sumQty;
|
|
|
//剩余数量生产需要时长(分钟)
|
|
|
- decimal workTime = residueQty / item.Rate * 60;
|
|
|
+ decimal workTime = Math.Ceiling(residueQty / item.Rate * 60);
|
|
|
//获取当天的工作时间段
|
|
|
List<LineWorkPointDto> workPoints = DealWorkDayToLevels(workStartTime, mLCalendars.First(p => p.WeekDay == (int)workStartTime.DayOfWeek), mlqtyWorkDtls);
|
|
|
var curPoint = workPoints.First(p => p.StartPoint >= workStartTime && workStartTime <= p.EndPoint);
|
|
|
@@ -380,6 +383,7 @@ namespace Business.Quartz
|
|
|
nextMins -= p.WorkMinutes;
|
|
|
}
|
|
|
}
|
|
|
+ sumQty = workOrd.QtyOrded;
|
|
|
//记录生产周期
|
|
|
curSequences.Add(new PeriodSequenceDet
|
|
|
{
|
|
|
@@ -391,7 +395,7 @@ namespace Business.Quartz
|
|
|
OrdQty = residueQty,
|
|
|
WorkOrds = workOrd.WorkOrd,
|
|
|
Op = item.Op,
|
|
|
- IsActive = 1
|
|
|
+ IsActive = true
|
|
|
});
|
|
|
//记录排产记录
|
|
|
curScheduleRsts.Add(new ScheduleResultOpMaster
|
|
|
@@ -405,7 +409,7 @@ namespace Business.Quartz
|
|
|
WorkQty = residueQty,
|
|
|
WorkStartTime = workStartTime,
|
|
|
WorkEndTime = workEndTime,
|
|
|
- CreatTime = DateTime.Now
|
|
|
+ CreateTime = DateTime.Now
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
@@ -448,7 +452,7 @@ namespace Business.Quartz
|
|
|
scheduledDto.EffTime += (decimal)span.TotalHours;
|
|
|
}
|
|
|
//计算当天的产能
|
|
|
- scheduledDto.ProductQty = scheduledDto.EffTime * routingDto.Rate;
|
|
|
+ scheduledDto.ProductQty = Math.Floor(scheduledDto.EffTime * routingDto.Rate);
|
|
|
return scheduledDto;
|
|
|
}
|
|
|
|
|
|
@@ -640,6 +644,7 @@ namespace Business.Quartz
|
|
|
//下一天是周几
|
|
|
int nextWeekDay = (weekDay + 1) % 7;
|
|
|
var calendar = curCalendars.FirstOrDefault(p=>p.WeekDay == nextWeekDay);
|
|
|
+ string strStart = calendar.ShiftsStart1.ToString("0.00").Replace(".", ":");
|
|
|
//判断下一天是否是工作日
|
|
|
if (nextWeekDay == 0 || nextWeekDay == 6)//下一天是周六或者周日,需要判断是否调休,需要加班
|
|
|
{
|
|
|
@@ -648,7 +653,7 @@ namespace Business.Quartz
|
|
|
//递归继续找下一个工作日
|
|
|
GetNextWorkDay(nextWeekDay, nextDate, curCalendars);
|
|
|
}
|
|
|
- rtnData = nextDate.AddHours((double)calendar.ShiftsStart1);
|
|
|
+ rtnData = Convert.ToDateTime(nextDate.ToString("yyyy-MM-dd") + " " + strStart);
|
|
|
return rtnData;
|
|
|
}
|
|
|
//下一天不是周六周日,需要判断是不是节假日
|
|
|
@@ -657,7 +662,7 @@ namespace Business.Quartz
|
|
|
//递归继续找下一个工作日
|
|
|
GetNextWorkDay(nextWeekDay, nextDate, curCalendars);
|
|
|
}
|
|
|
- rtnData = nextDate.AddHours((double)calendar.ShiftsStart1);
|
|
|
+ rtnData = Convert.ToDateTime(nextDate.ToString("yyyy-MM-dd") + " " + strStart);
|
|
|
return rtnData;
|
|
|
}
|
|
|
|
|
|
@@ -675,6 +680,7 @@ namespace Business.Quartz
|
|
|
//前一天是周几
|
|
|
int preWeekDay = (int)preDate.DayOfWeek;
|
|
|
var calendar = curCalendars.FirstOrDefault(p => p.WeekDay == preWeekDay);
|
|
|
+ string strStart = calendar.ShiftsStart1.ToString("0.00").Replace(".", ":");
|
|
|
//判断前一天是否是工作日
|
|
|
if (preWeekDay == 0 || preWeekDay == 6)//前一天是周六或者周日,需要判断是否调休,需要加班
|
|
|
{
|
|
|
@@ -683,7 +689,7 @@ namespace Business.Quartz
|
|
|
//递归继续找下一个工作日
|
|
|
GetPreWorkDay(preDate, curCalendars);
|
|
|
}
|
|
|
- rtnData = preDate.AddHours((double)calendar.ShiftsStart1);
|
|
|
+ rtnData = Convert.ToDateTime(preDate.ToString("yyyy-MM-dd") + " " + strStart);
|
|
|
return rtnData;
|
|
|
}
|
|
|
//前一天不是周六周日,需要判断是不是节假日
|
|
|
@@ -692,7 +698,7 @@ namespace Business.Quartz
|
|
|
//递归继续找前一个工作日
|
|
|
GetPreWorkDay(preDate, curCalendars);
|
|
|
}
|
|
|
- rtnData = preDate.AddHours((double)calendar.ShiftsStart1);
|
|
|
+ rtnData = Convert.ToDateTime(preDate.ToString("yyyy-MM-dd") + " " + strStart);
|
|
|
return rtnData;
|
|
|
}
|
|
|
|
|
|
@@ -711,7 +717,7 @@ namespace Business.Quartz
|
|
|
int weekDay = (int)startTime.DayOfWeek;
|
|
|
//计算当天的开工时间点,停工时间点
|
|
|
string strStart = shopCal.ShiftsStart1.ToString("0.00").Replace(".", ":");
|
|
|
- DateTime dayStartPoint = Convert.ToDateTime(date + strStart);
|
|
|
+ DateTime dayStartPoint = Convert.ToDateTime(date + " "+ strStart);
|
|
|
DateTime dayEndPoint = dayStartPoint.AddHours(Convert.ToDouble(shopCal.ShiftsHours1));
|
|
|
//工作时间段
|
|
|
List<LineWorkPointDto> workPoints = new List<LineWorkPointDto>();
|
|
|
@@ -769,6 +775,13 @@ namespace Business.Quartz
|
|
|
dto.ParentOp = lastOp.ParentOp;
|
|
|
dto.level = 1;
|
|
|
dto.Op = lastOp.OP;
|
|
|
+ dto.ChdParentOps = new List<int>();
|
|
|
+ //获取当前层级工序中有子级的工序集合
|
|
|
+ var childs = woRuntings.Where(p => firsts.Select(m => m.OP).Contains(p.ParentOp)).Select(m => m.ParentOp).Distinct().ToList();
|
|
|
+ if (childs.Count() > 0)
|
|
|
+ {
|
|
|
+ dto.ChdParentOps = childs;
|
|
|
+ }
|
|
|
//主工序对应的产线(目前只考虑一个产品对应一条产线的情况)
|
|
|
var line = prodLines.Where(p => p.Part == lastOp.ItemNum && p.Op == lastOp.OP).FirstOrDefault();
|
|
|
if (line != null) {
|
|
|
@@ -815,6 +828,13 @@ namespace Business.Quartz
|
|
|
dto.Op = lastOp.OP;
|
|
|
dto.ParentOp = lastOp.ParentOp;
|
|
|
dto.level = level + 1;
|
|
|
+ dto.ChdParentOps = new List<int>();
|
|
|
+ //获取当前层级工序中有子级的工序集合
|
|
|
+ var childs = woRuntings.Where(p => curLevels.Where(p => p.ParentOp == item).Select(m => m.OP).Contains(p.ParentOp)).Select(m => m.ParentOp).Distinct().ToList();
|
|
|
+ if (childs.Count() > 0)
|
|
|
+ {
|
|
|
+ dto.ChdParentOps = childs;
|
|
|
+ }
|
|
|
//当前层级工序对应的产线
|
|
|
var maxRateLine = prodLines.Where(p => p.Part == lastOp.ItemNum && p.Op == lastOp.OP).OrderByDescending(p => p.Rate).FirstOrDefault();
|
|
|
if (maxRateLine != null)
|