|
|
@@ -19,6 +19,7 @@ using MongoDB.Driver.Linq;
|
|
|
using Amazon.Runtime.Internal.Util;
|
|
|
using IdentityModel.Client;
|
|
|
using Amazon.Runtime;
|
|
|
+using Magicodes.ExporterAndImporter.Core.Extension;
|
|
|
|
|
|
namespace Business.ResourceExamineManagement
|
|
|
{
|
|
|
@@ -192,15 +193,12 @@ namespace Business.ResourceExamineManagement
|
|
|
IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build();
|
|
|
domain = configuration.GetConnectionString("Factory_id");
|
|
|
|
|
|
- //获取排产锁定期
|
|
|
- var generalizedCodeMaster = _generalizedCodeMaster.Select(p => p.FldName == "SystemConfig" && p.Val == "WorkOrderLockPeriod" && p.Domain == domain && p.IsActive).FirstOrDefault();
|
|
|
- decimal lockDays = generalizedCodeMaster != null ? generalizedCodeMaster.UDeci1 : 0;
|
|
|
-
|
|
|
//获取需要排产的工单(获取四周的工单:正常工单+已审批通过的特殊工单)
|
|
|
DateTime endDate = DateTime.Now.Date.AddDays(28).AddDays(1);
|
|
|
- //取数开始时间需要排除掉锁定期内的工单
|
|
|
- DateTime startDate = DateTime.Now.Date.AddDays(1).AddDays((double)lockDays);
|
|
|
- var workOrds = _workOrdMaster.Select(p => p.IsActive && p.Domain == domain && p.OrdDate < endDate && p.OrdDate >= startDate && string.IsNullOrEmpty(p.Status) && (string.IsNullOrEmpty(p.Typed) || (!string.IsNullOrEmpty(p.Typed) && p.BusinessID >0 ))).ToList();
|
|
|
+ //取数开始时间为当前天的下一天
|
|
|
+ DateTime startDate = DateTime.Now.Date.AddDays(1);
|
|
|
+ //尚未开始生产的工单+正在生产的工单
|
|
|
+ var workOrds = _workOrdMaster.Select(p => p.IsActive && p.Domain == domain && ((p.OrdDate < endDate && p.OrdDate >= startDate && (string.IsNullOrEmpty(p.Typed) || (!string.IsNullOrEmpty(p.Typed) && p.BusinessID >0 ))) || p.Status.ToLower() == "w")).ToList();
|
|
|
await DoProductSchedule(workOrds, domain, 1);
|
|
|
}
|
|
|
|
|
|
@@ -242,11 +240,11 @@ namespace Business.ResourceExamineManagement
|
|
|
List<PeriodSequenceDet> dbPeriodSequences = _periodSequenceDet.Select(p => lines.Contains(p.Line) && p.PlanDate >= earlist && p.Domain == domain && p.IsActive);
|
|
|
//获取当前日期往后的排产记录数据
|
|
|
List<ScheduleResultOpMaster> dbSchedules = _scheduleResultOpMaster.Select(p => lines.Contains(p.Line) && p.WorkDate >= earlist && p.Domain == domain);
|
|
|
- //获取锁定期之外的工单排产数据
|
|
|
- List<PeriodSequenceDet> delPeriodSequences = dbPeriodSequences.Where(p => workOrds.Select(m => m.WorkOrd).Contains(p.WorkOrds)).ToList();
|
|
|
- List<ScheduleResultOpMaster> delSchedules = dbSchedules.Where(p => workOrds.Select(m => m.WorkOrd).Contains(p.WorkOrd)).ToList();
|
|
|
- //产线占用记录排除锁定期之前的工单
|
|
|
- dbSchedules = dbSchedules.Where(p => !workOrds.Select(m => m.WorkOrd).Contains(p.WorkOrd)).ToList();
|
|
|
+ ////获取锁定期之外的工单排产数据
|
|
|
+ //List<PeriodSequenceDet> delPeriodSequences = dbPeriodSequences.Where(p => workOrds.Select(m => m.WorkOrd).Contains(p.WorkOrds)).ToList();
|
|
|
+ //List<ScheduleResultOpMaster> delSchedules = dbSchedules.Where(p => workOrds.Select(m => m.WorkOrd).Contains(p.WorkOrd)).ToList();
|
|
|
+ ////产线占用记录排除锁定期之前的工单
|
|
|
+ //dbSchedules = dbSchedules.Where(p => !workOrds.Select(m => m.WorkOrd).Contains(p.WorkOrd)).ToList();
|
|
|
//获取工作日历数据:产线的工作日历+默认的工作日历
|
|
|
calendars = _shopCalendarWorkCtr.Select(p => (lines.Contains(p.ProdLine) || string.IsNullOrEmpty(p.ProdLine)) && p.Domain == domain && p.IsActive);
|
|
|
//获取产线休息记录数据
|
|
|
@@ -280,11 +278,13 @@ namespace Business.ResourceExamineManagement
|
|
|
List<PeriodSequenceDet> periodSequenceDtls = new List<PeriodSequenceDet>();
|
|
|
//排产记录表
|
|
|
List<ScheduleResultOpMaster> scheduleMasters = new List<ScheduleResultOpMaster>();
|
|
|
- //排产结果
|
|
|
+ //记录排产结果
|
|
|
List<ScheduleResultOpMaster> allResults = new List<ScheduleResultOpMaster>();
|
|
|
- allResults.AddRange(dbSchedules);
|
|
|
+ //allResults.AddRange(dbSchedules);
|
|
|
//记录特殊工单排产结果
|
|
|
List<string> ypcWorkOrds = new List<string>();
|
|
|
+ //按照优先级排序
|
|
|
+ zcWorkOrds = zcWorkOrds.OrderBy(p=>p.Priority).ToList();
|
|
|
foreach (var item in zcWorkOrds)
|
|
|
{
|
|
|
//记录产线占用情况
|
|
|
@@ -310,14 +310,29 @@ namespace Business.ResourceExamineManagement
|
|
|
foreach (var item in notSchedules)
|
|
|
{
|
|
|
var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
|
|
|
+ //剩余排产数量
|
|
|
+ decimal qtyNeed = item.QtyOrded - curOp.QtyComplete;
|
|
|
+ //剩余工作时长(分钟)
|
|
|
+ decimal usedTime = Math.Ceiling(qtyNeed / item.QtyOrded * item.LbrVar * 60);
|
|
|
+ //特殊工单排产开始时间
|
|
|
+ DateTime startTime = item.OrdDate.GetValueOrDefault();
|
|
|
+ //如果当前特殊工单正在生产,则开工日期为当天的下一个工作日
|
|
|
+ if (item.Status.ToLower() == "w" && item.JointTyped.ToUpper() != "B")
|
|
|
+ {
|
|
|
+ DateTime nowDate = DateTime.Now.Date;
|
|
|
+ //当前产线的工作日历
|
|
|
+ var mLCalendars = calendars.Where(p => p.ProdLine == item.ProdLine || string.IsNullOrEmpty(p.ProdLine)).ToList();
|
|
|
+ //获取下一个工作日
|
|
|
+ startTime = GetNextWorkDay((int)nowDate.DayOfWeek, nowDate, mLCalendars);
|
|
|
+ }
|
|
|
workDtos.Add(new WorkOrdMstDto
|
|
|
{
|
|
|
WorkOrd = item.WorkOrd,
|
|
|
ItemNum = item.ItemNum,
|
|
|
- QtyOrded = item.QtyOrded,
|
|
|
- OrdDate = item.OrdDate.GetValueOrDefault(),
|
|
|
+ QtyOrded = qtyNeed,
|
|
|
+ OrdDate = startTime,
|
|
|
ProdLine = item.ProdLine,
|
|
|
- LbrVar = item.LbrVar * 60,
|
|
|
+ LbrVar = usedTime,
|
|
|
Worked = 0,
|
|
|
QtyWorked = 0,
|
|
|
Op = curOp.OP,
|
|
|
@@ -341,9 +356,9 @@ namespace Business.ResourceExamineManagement
|
|
|
{
|
|
|
//更新工单计划开工时间、计划结束时间
|
|
|
_workOrdMaster.Update(workOrds);
|
|
|
- //删除锁定期之外的工单排产记录
|
|
|
- _periodSequenceDet.Delete(delPeriodSequences);
|
|
|
- _scheduleResultOpMaster.Delete(delSchedules);
|
|
|
+ //删除当前日期下一天开始的工单排产记录
|
|
|
+ _periodSequenceDet.Delete(dbPeriodSequences);
|
|
|
+ _scheduleResultOpMaster.Delete(dbSchedules);
|
|
|
//保存排产记录
|
|
|
_periodSequenceDet.Insert(periodSequenceDtls);
|
|
|
_scheduleResultOpMaster.Insert(scheduleMasters);
|
|
|
@@ -545,22 +560,27 @@ namespace Business.ResourceExamineManagement
|
|
|
List<ScheduleResultOpMaster> curScheduleRsts = new List<ScheduleResultOpMaster>();
|
|
|
//记录上一产线排产开始时间
|
|
|
LineStartDto lineStart = new LineStartDto();
|
|
|
+ //产线开工时间默认为当前日期的下一天
|
|
|
+ lineStart.StartTime = DateTime.Now.Date.AddDays(1);
|
|
|
TimeSpan span = TimeSpan.Zero;
|
|
|
//第一层级工序有几个关键工序,就有几条产线
|
|
|
for (int i = 0; i < workOrdRoutings.Count; i++)
|
|
|
{
|
|
|
+ //如果当前工序已经生产完成,则跳过
|
|
|
+ if (workOrdRoutings[i].QtyComplete == workOrd.QtyOrded)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
//产线实际排产开始时间
|
|
|
if (i == 0)//第一条产线
|
|
|
{
|
|
|
- lineStart = DealStartTime(workOrd, workOrdRoutings[i].OP, prodLines, allResults);
|
|
|
+ lineStart = DealStartTime(workOrd, workOrdRoutings[i], prodLines, allResults);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//获取前一产线排产开始时间,通过提前期计算当前产线排产开始时间
|
|
|
- lineStart = DealNextStartTime(workOrd, lineStart, workOrdRoutings[i].OP, prodLines, allResults);
|
|
|
+ lineStart = DealNextStartTime(workOrd, lineStart, workOrdRoutings[i], prodLines, allResults);
|
|
|
}
|
|
|
- //添加关键工序清场时长
|
|
|
- lineStart.WaitTime = workOrdRoutings[i].WaitTime * 60;
|
|
|
//当前产线的工作日历
|
|
|
var mLCalendars = calendars.Where(p => p.ProdLine == lineStart.Line || string.IsNullOrEmpty(p.ProdLine)).ToList();
|
|
|
//当前产线的休息时间设置
|
|
|
@@ -568,7 +588,7 @@ namespace Business.ResourceExamineManagement
|
|
|
//产线排产开始时间
|
|
|
DateTime workStartTime = lineStart.StartTime;
|
|
|
//记录特殊工单:获取第一天是否有特殊工单
|
|
|
- List<WorkOrdMaster> fstWOMasters = tsWorkOrds.Where(p => p.ProdLine == lineStart.Line && p.OrdDate.Value.Date == workStartTime.Date).OrderBy(p => p.OrdDate).ToList();
|
|
|
+ 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>();
|
|
|
//记录排产开始第二天及以后安排的特殊工单
|
|
|
var secWOMasters = new List<WorkOrdMaster>();
|
|
|
@@ -578,31 +598,35 @@ namespace Business.ResourceExamineManagement
|
|
|
decimal lstCleanTime = 0m;
|
|
|
//新增特殊工单最后一个清场时长
|
|
|
decimal secCleanTime = 0m;
|
|
|
+ //特殊工单排产需要考虑的时长
|
|
|
+ decimal sumTsTimes = 0m;
|
|
|
if (fstWOMasters.Any())
|
|
|
{
|
|
|
foreach (var item in fstWOMasters)
|
|
|
{
|
|
|
var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
|
|
|
+ //计算已完成耗时(分钟)
|
|
|
+ decimal usedTime = Math.Ceiling(curOp.QtyComplete / item.QtyOrded * item.LbrVar * 60);
|
|
|
workDtos.Add(new WorkOrdMstDto
|
|
|
{
|
|
|
WorkOrd = item.WorkOrd,
|
|
|
ItemNum = item.ItemNum,
|
|
|
- QtyOrded = item.QtyOrded,
|
|
|
- LbrVar = item.LbrVar * 60,
|
|
|
+ QtyOrded = item.QtyOrded - curOp.QtyComplete,
|
|
|
+ LbrVar = item.LbrVar * 60 - usedTime,
|
|
|
Worked = 0,
|
|
|
QtyWorked = 0,
|
|
|
Op = curOp.OP,
|
|
|
WaitTime = curOp.WaitTime * 60,
|
|
|
- PlanDate = item.OrdDate.Value
|
|
|
+ Priority = item.Priority
|
|
|
});
|
|
|
sumCleanTimes += curOp.WaitTime * 60;
|
|
|
}
|
|
|
//获取最后一个特殊工单的清场时长
|
|
|
var last = fstWOMasters.Last();
|
|
|
lstCleanTime = tsWoRoutings.Where(p => p.WorkOrd == last.WorkOrd).OrderByDescending(p => p.OP).First().WaitTime * 60;
|
|
|
+ //特殊工单排产需要考虑的时长=特殊工单工作时长(分钟)+除最后一个特殊工单之外的清场时长
|
|
|
+ sumTsTimes = workDtos.Sum(p => p.LbrVar) + sumCleanTimes - lstCleanTime;
|
|
|
}
|
|
|
- //特殊工单排产需要考虑的时长=特殊工单工作时长(分钟)+除最后一个特殊工单之外的清场时长
|
|
|
- decimal sumTsTimes = fstWOMasters.Sum(p => p.LbrVar) * 60 + sumCleanTimes - lstCleanTime;
|
|
|
//工单排产第一天标识
|
|
|
bool isFstDay = true;
|
|
|
//产线排产开始当天安排了特殊工单,则先安排特殊工单
|
|
|
@@ -622,40 +646,45 @@ namespace Business.ResourceExamineManagement
|
|
|
if (dto.EffTime > sumTsTimes && !isFstDay)
|
|
|
{
|
|
|
//获取特殊工单
|
|
|
- secWOMasters = tsWorkOrds.Where(p => p.ProdLine == lineStart.Line && p.OrdDate.Value.Date == workStartTime.Date).OrderBy(p => p.OrdDate).ToList();
|
|
|
+ secWOMasters = tsWorkOrds.Where(p => p.ProdLine == lineStart.Line && p.OrdDate.Value.Date == workStartTime.Date).OrderBy(p => p.Priority).ToList();
|
|
|
if (secWOMasters.Any())
|
|
|
{
|
|
|
sumCleanTimes = 0m;
|
|
|
//新增特殊工单最后一个清场时长
|
|
|
secCleanTime = 0m;
|
|
|
+ //生产时长
|
|
|
+ decimal sumLbrVar = 0m;
|
|
|
//记录新增待排产特殊工单
|
|
|
foreach (var item in secWOMasters)
|
|
|
{
|
|
|
var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
|
|
|
+ //计算已完成数量耗时(分钟)
|
|
|
+ decimal usedTime = Math.Ceiling(curOp.QtyComplete / item.QtyOrded * item.LbrVar * 60);
|
|
|
workDtos.Add(new WorkOrdMstDto
|
|
|
{
|
|
|
WorkOrd = item.WorkOrd,
|
|
|
ItemNum = item.ItemNum,
|
|
|
- QtyOrded = item.QtyOrded,
|
|
|
- LbrVar = item.LbrVar * 60,
|
|
|
+ QtyOrded = item.QtyOrded - curOp.QtyComplete,
|
|
|
+ LbrVar = item.LbrVar * 60 - usedTime,
|
|
|
Worked = 0,
|
|
|
QtyWorked = 0,
|
|
|
Op = curOp.OP,
|
|
|
WaitTime = curOp.WaitTime * 60,
|
|
|
- PlanDate = item.OrdDate.Value
|
|
|
+ Priority = item.Priority
|
|
|
});
|
|
|
+ sumLbrVar += item.QtyOrded - curOp.QtyComplete;
|
|
|
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);
|
|
|
+ sumTsTimes += (lstCleanTime + sumLbrVar + sumCleanTimes - secCleanTime);
|
|
|
lstCleanTime = secCleanTime;
|
|
|
}
|
|
|
}
|
|
|
//特殊工单排序
|
|
|
- workDtos = workDtos.OrderBy(p => p.PlanDate).ToList();
|
|
|
+ workDtos = workDtos.OrderBy(p => p.Priority).ToList();
|
|
|
//当天的可用生产时长满足特殊工单生产时长+清场时间(最后一个工单清场时间除外)
|
|
|
if (dto.EffTime >= sumTsTimes)
|
|
|
{
|
|
|
@@ -803,27 +832,31 @@ namespace Business.ResourceExamineManagement
|
|
|
workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
|
|
|
isFstDay = true;
|
|
|
//特殊工单排产完成,占用了当天的全部产能,则需要判断下一个工作日是否存在特殊工单,如果存在,则需要继续排特殊工单
|
|
|
- secWOMasters = tsWorkOrds.Where(p => p.ProdLine == lineStart.Line && p.OrdDate.Value.Date == workStartTime.Date).OrderBy(p => p.OrdDate).ToList();
|
|
|
+ secWOMasters = tsWorkOrds.Where(p => p.ProdLine == lineStart.Line && p.OrdDate.Value.Date == workStartTime.Date).OrderBy(p => p.Priority).ToList();
|
|
|
//记录新增待排产特殊工单
|
|
|
if (secWOMasters.Any())
|
|
|
{
|
|
|
sumCleanTimes = 0m;
|
|
|
//新增特殊工单最后一个清场时长(分钟)
|
|
|
secCleanTime = 0m;
|
|
|
+ //生产时长
|
|
|
+ decimal sumLbrVar = 0m;
|
|
|
foreach (var item in secWOMasters)
|
|
|
{
|
|
|
var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
|
|
|
+ //计算已完成数量耗时(分钟)
|
|
|
+ decimal usedTime = Math.Ceiling(curOp.QtyComplete / item.QtyOrded * item.LbrVar * 60);
|
|
|
workDtos.Add(new WorkOrdMstDto
|
|
|
{
|
|
|
WorkOrd = item.WorkOrd,
|
|
|
ItemNum = item.ItemNum,
|
|
|
- QtyOrded = item.QtyOrded,
|
|
|
- LbrVar = item.LbrVar * 60,
|
|
|
+ QtyOrded = item.QtyOrded - curOp.QtyComplete,
|
|
|
+ LbrVar = item.LbrVar * 60 - usedTime,
|
|
|
Worked = 0,
|
|
|
QtyWorked = 0,
|
|
|
Op = curOp.OP,
|
|
|
WaitTime = curOp.WaitTime * 60,
|
|
|
- PlanDate = item.OrdDate.Value
|
|
|
+ Priority = item.Priority
|
|
|
});
|
|
|
sumCleanTimes += curOp.WaitTime * 60;
|
|
|
}
|
|
|
@@ -831,7 +864,7 @@ namespace Business.ResourceExamineManagement
|
|
|
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);
|
|
|
+ sumTsTimes += (lstCleanTime + sumLbrVar + sumCleanTimes - secCleanTime);
|
|
|
lstCleanTime = secCleanTime;
|
|
|
}
|
|
|
}
|
|
|
@@ -1047,7 +1080,7 @@ namespace Business.ResourceExamineManagement
|
|
|
isFstDay = true;
|
|
|
//前一天是否有特殊工单未排产完全
|
|
|
bool isFullPC = true;
|
|
|
- while (sumQty < workOrd.QtyOrded || sumTsTimes > 0)
|
|
|
+ while (sumQty < lineStart.QtyRemain || sumTsTimes > 0)
|
|
|
{
|
|
|
secWOMasters.Clear();
|
|
|
sumCleanTimes = 0m;
|
|
|
@@ -1065,31 +1098,36 @@ namespace Business.ResourceExamineManagement
|
|
|
if (!isFstDay)
|
|
|
{
|
|
|
//获取特殊工单
|
|
|
- secWOMasters = tsWorkOrds.Where(p => p.ProdLine == lineStart.Line && p.OrdDate.Value.Date == workStartTime.Date).OrderBy(p => p.OrdDate).ToList();
|
|
|
+ secWOMasters = tsWorkOrds.Where(p => p.ProdLine == lineStart.Line && p.OrdDate.Value.Date == workStartTime.Date).OrderBy(p => p.Priority).ToList();
|
|
|
if (secWOMasters.Any())
|
|
|
{
|
|
|
+ //生产时长
|
|
|
+ decimal sumLbrVar = 0m;
|
|
|
foreach (var item in secWOMasters)
|
|
|
{
|
|
|
var curOp = tsWoRoutings.Where(p => p.WorkOrd == item.WorkOrd).OrderByDescending(p => p.OP).First();
|
|
|
+ //计算已完成数量耗时(分钟)
|
|
|
+ decimal usedTime = Math.Ceiling(curOp.QtyComplete / item.QtyOrded * item.LbrVar * 60);
|
|
|
workDtos.Add(new WorkOrdMstDto
|
|
|
{
|
|
|
WorkOrd = item.WorkOrd,
|
|
|
ItemNum = item.ItemNum,
|
|
|
- QtyOrded = item.QtyOrded,
|
|
|
- LbrVar = item.LbrVar * 60,
|
|
|
+ QtyOrded = item.QtyOrded - curOp.QtyComplete,
|
|
|
+ LbrVar = item.LbrVar * 60 - usedTime,
|
|
|
Worked = 0,
|
|
|
QtyWorked = 0,
|
|
|
Op = curOp.OP,
|
|
|
WaitTime = curOp.WaitTime * 60,
|
|
|
- PlanDate = item.OrdDate.Value
|
|
|
+ Priority = item.Priority
|
|
|
});
|
|
|
+ sumLbrVar += item.LbrVar * 60 - usedTime;
|
|
|
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);
|
|
|
+ sumTsTimes += (lstCleanTime + sumLbrVar + sumCleanTimes - secCleanTime);
|
|
|
lstCleanTime = secCleanTime;
|
|
|
}
|
|
|
}
|
|
|
@@ -1106,14 +1144,14 @@ namespace Business.ResourceExamineManagement
|
|
|
//2、如果是排产中间日期,则先安排特殊工单排产
|
|
|
//当天剩余产能
|
|
|
decimal sumAmount = Math.Floor(dto.Rate * residueTime / 60);
|
|
|
- //已排产数量+当天的剩余产能小于工单数量,当天的产能需要全部排产
|
|
|
- if (sumQty + sumAmount < workOrd.QtyOrded)
|
|
|
+ //已排产数量+当天的剩余产能小于工单剩余需排产数量,当天的产能需要全部排产
|
|
|
+ if (sumQty + sumAmount < lineStart.QtyRemain)
|
|
|
{
|
|
|
//当天有特殊工单,且当天的产能不能满足工单剩余需排产数量,则优先排特殊工单
|
|
|
if (sumTsTimes > 0)
|
|
|
{
|
|
|
//特殊工单排序
|
|
|
- workDtos = workDtos.OrderBy(p => p.PlanDate).ToList();
|
|
|
+ workDtos = workDtos.OrderBy(p => p.Priority).ToList();
|
|
|
DateTime beginTime = workStartTime;//排产开始时间
|
|
|
DateTime endTime = dto.EndTime;//排产结束时间
|
|
|
//当天的可用生产时长满足特殊工单生产时长+清场时长(最后一个特殊工单的清场时长除外)
|
|
|
@@ -1533,7 +1571,7 @@ namespace Business.ResourceExamineManagement
|
|
|
{
|
|
|
#region 正常工单排产-开始
|
|
|
//剩余需要排产的数量
|
|
|
- decimal residueQty = workOrd.QtyOrded - sumQty;
|
|
|
+ decimal residueQty = lineStart.QtyRemain - sumQty;
|
|
|
//剩余数量生产需要时长(分钟)
|
|
|
decimal workTime = Math.Ceiling(residueQty / dto.Rate * 60);
|
|
|
//处理工作时长:防止相上取整导致时间大于剩余可用时长
|
|
|
@@ -1565,8 +1603,8 @@ namespace Business.ResourceExamineManagement
|
|
|
nextMins -= p.WorkMinutes;
|
|
|
}
|
|
|
}
|
|
|
- //工单排产完成,已排产数量=工单数量
|
|
|
- sumQty = workOrd.QtyOrded;
|
|
|
+ //工单排产完成,已排产数量=工单需排产数量数量
|
|
|
+ sumQty = lineStart.QtyRemain;
|
|
|
//当天剩余可用生产时长
|
|
|
residueTime -= workTime;
|
|
|
//处理清场时间,两种场景:
|
|
|
@@ -1648,7 +1686,7 @@ namespace Business.ResourceExamineManagement
|
|
|
//当天存在特殊工单
|
|
|
if (sumTsTimes > 0)
|
|
|
{
|
|
|
- workDtos = workDtos.OrderBy(p => p.PlanDate).ToList();
|
|
|
+ workDtos = workDtos.OrderBy(p => p.Priority).ToList();
|
|
|
//当天剩余生产时长大于0,特殊工单排产
|
|
|
if (restTime > 0)
|
|
|
{
|
|
|
@@ -2025,7 +2063,7 @@ namespace Business.ResourceExamineManagement
|
|
|
decimal residueTime = dto.EffTime;
|
|
|
DateTime beginTime = workStartTime;//排产开始时间
|
|
|
DateTime endTime = dto.EndTime;//排产结束时间
|
|
|
- workDtos = workDtos.OrderBy(p => p.PlanDate).ToList();
|
|
|
+ workDtos = workDtos.OrderBy(p => p.Priority).ToList();
|
|
|
//当天的可用生产时长满足特殊工单生产时长+清场时长(最后一个工单清场时间除外)
|
|
|
if (residueTime >= sumTsTimes)
|
|
|
{
|
|
|
@@ -2176,13 +2214,13 @@ namespace Business.ResourceExamineManagement
|
|
|
//剩余可用生产时长
|
|
|
residueTime = residueTime < 0 ? 0 : residueTime;
|
|
|
//特殊工单处理完成,剩余生产时长大于0且还有正常工单待排产,则继续排正常工单
|
|
|
- if (residueTime > 0 && sumQty < workOrd.QtyOrded)
|
|
|
+ if (residueTime > 0 && sumQty < lineStart.QtyRemain)
|
|
|
{
|
|
|
workStartTime = beginTime;//排产开始时间
|
|
|
//剩余产能继续排正常工单
|
|
|
decimal sumAmount = Math.Floor(dto.Rate * residueTime / 60);
|
|
|
//如果剩余产能不能满足正常工单,剩余产能全部排产
|
|
|
- if (sumQty + sumAmount < workOrd.QtyOrded)
|
|
|
+ if (sumQty + sumAmount < lineStart.QtyRemain)
|
|
|
{
|
|
|
//记录生产周期
|
|
|
curSequences.Add(new PeriodSequenceDet
|
|
|
@@ -2223,7 +2261,7 @@ namespace Business.ResourceExamineManagement
|
|
|
else
|
|
|
{
|
|
|
//剩余需要排产的数量
|
|
|
- decimal residueQty = workOrd.QtyOrded - sumQty;
|
|
|
+ decimal residueQty = lineStart.QtyRemain - sumQty;
|
|
|
//剩余数量生产需要时长(分钟)
|
|
|
decimal workTime = Math.Ceiling(residueQty / dto.Rate * 60);
|
|
|
//处理剩余需要生产时长:防止向上取整导致超过residueTime
|
|
|
@@ -2254,7 +2292,7 @@ namespace Business.ResourceExamineManagement
|
|
|
}
|
|
|
}
|
|
|
//工单排产完成,已排产数量=工单数量
|
|
|
- sumQty = workOrd.QtyOrded;
|
|
|
+ sumQty = lineStart.QtyRemain;
|
|
|
|
|
|
//剩余可用生产时长
|
|
|
residueTime = (residueTime - workTime) < 0 ? 0 : (residueTime - workTime);
|
|
|
@@ -2531,7 +2569,7 @@ namespace Business.ResourceExamineManagement
|
|
|
//当天之前的特殊工单全部排产完毕
|
|
|
else {
|
|
|
//已排产数量+当天的产能小于工单数量,当天的产能需要全部排产
|
|
|
- if (sumQty + dto.ProductQty < workOrd.QtyOrded)
|
|
|
+ if (sumQty + dto.ProductQty < lineStart.QtyRemain)
|
|
|
{
|
|
|
//当天有特殊工单,先排特殊工单
|
|
|
if (sumTsTimes > 0)
|
|
|
@@ -2540,7 +2578,7 @@ namespace Business.ResourceExamineManagement
|
|
|
decimal residueTime = dto.EffTime;
|
|
|
DateTime beginTime = workStartTime;//排产开始时间
|
|
|
DateTime endTime = dto.EndTime;//排产结束时间
|
|
|
- workDtos = workDtos.OrderBy(p => p.PlanDate).ToList();
|
|
|
+ workDtos = workDtos.OrderBy(p => p.Priority).ToList();
|
|
|
//当天的可用产能满足特殊工单生产时长+清场时长(最后一个工单清场时间除外)
|
|
|
if (residueTime >= sumTsTimes)
|
|
|
{
|
|
|
@@ -2963,11 +3001,11 @@ namespace Business.ResourceExamineManagement
|
|
|
//正常工单生产时长
|
|
|
decimal workTime = 0m;
|
|
|
DateTime workEndTime = workStartTime;
|
|
|
- if (sumQty < workOrd.QtyOrded)
|
|
|
+ if (sumQty < lineStart.QtyRemain)
|
|
|
{
|
|
|
#region 正常工单排产-开始
|
|
|
//剩余需要排产的数量
|
|
|
- decimal residueQty = workOrd.QtyOrded - sumQty;
|
|
|
+ decimal residueQty = lineStart.QtyRemain - sumQty;
|
|
|
//剩余数量生产需要时长(分钟)
|
|
|
workTime = Math.Ceiling(residueQty / dto.Rate * 60);
|
|
|
//处理需要生产时长
|
|
|
@@ -2998,7 +3036,7 @@ namespace Business.ResourceExamineManagement
|
|
|
}
|
|
|
}
|
|
|
//工单排产完成,已排产数量=工单数量
|
|
|
- sumQty = workOrd.QtyOrded;
|
|
|
+ sumQty = lineStart.QtyRemain;
|
|
|
//剩余可用生产时长
|
|
|
residueTime = (residueTime - workTime) < 0 ? 0 : (residueTime - workTime);
|
|
|
//处理清场时间,两种场景:
|
|
|
@@ -3094,7 +3132,7 @@ namespace Business.ResourceExamineManagement
|
|
|
#region 特殊工单排产-开始
|
|
|
DateTime beginTime = workStartTime;//排产开始时间
|
|
|
DateTime endTime = dto.EndTime;//排产结束时间
|
|
|
- workDtos = workDtos.OrderBy(p => p.PlanDate).ToList();
|
|
|
+ workDtos = workDtos.OrderBy(p => p.Priority).ToList();
|
|
|
//当天的可用产能满足特殊工单生产时长+清场时长(最后一个工单清场时间除外)
|
|
|
if (residueTime >= sumTsTimes)
|
|
|
{
|
|
|
@@ -3679,12 +3717,13 @@ namespace Business.ResourceExamineManagement
|
|
|
/// 计算主产线实际排产开始时间
|
|
|
/// </summary>
|
|
|
/// <param name="workOrd">工单</param>
|
|
|
- /// <param name="op">工序</param>
|
|
|
+ /// <param name="routing">工序</param>
|
|
|
/// <param name="prodLines">生产线明细</param>
|
|
|
/// <param name="allResults">产线占用记录</param>
|
|
|
/// <returns></returns>
|
|
|
- public LineStartDto DealStartTime(WorkOrdMaster workOrd,int op,List<ProdLineDetail> prodLines, List<ScheduleResultOpMaster> allResults)
|
|
|
+ public LineStartDto DealStartTime(WorkOrdMaster workOrd,WorkOrdRouting routing,List<ProdLineDetail> prodLines, List<ScheduleResultOpMaster> allResults)
|
|
|
{
|
|
|
+ int op = routing.OP;
|
|
|
DateTime actStart = DateTime.Now.Date.AddDays(1);
|
|
|
LineStartDto lineStart = new LineStartDto();
|
|
|
//获取工序对应的产线,根据优先级排序
|
|
|
@@ -3702,7 +3741,6 @@ namespace Business.ResourceExamineManagement
|
|
|
lineStart.StartTime = actStart;
|
|
|
lineStart.setupTime = lines[0].SetupTime;
|
|
|
lineStart.Rate = lines[0].Rate;
|
|
|
- lineStart.Op = op;
|
|
|
//循环其他产线
|
|
|
for (int i = 1; i < lines.Count; i++)
|
|
|
{
|
|
|
@@ -3720,9 +3758,16 @@ namespace Business.ResourceExamineManagement
|
|
|
lineStart.StartTime = StartTime;
|
|
|
lineStart.setupTime = lines[i].SetupTime;
|
|
|
lineStart.Rate = lines[i].Rate;
|
|
|
- lineStart.Op = op;
|
|
|
}
|
|
|
}
|
|
|
+ //如果当前工单正在排产,且是连续排产时,重新排产不需要考虑产线准备时间
|
|
|
+ if (workOrd.Status.ToLower() == "w" && workOrd.JointTyped.ToUpper() !="B")
|
|
|
+ {
|
|
|
+ lineStart.setupTime = 0m;
|
|
|
+ }
|
|
|
+ lineStart.Op = op;
|
|
|
+ lineStart.WaitTime = routing.WaitTime * 60;
|
|
|
+ lineStart.QtyRemain = workOrd.QtyOrded - routing.QtyComplete;
|
|
|
return lineStart;
|
|
|
}
|
|
|
|
|
|
@@ -3869,12 +3914,13 @@ namespace Business.ResourceExamineManagement
|
|
|
/// </summary>
|
|
|
/// <param name="workOrd">工单</param>
|
|
|
/// <param name="lineStart">上一产线开始时间</param>
|
|
|
- /// <param name="op">工序</param>
|
|
|
+ /// <param name="routing">工序</param>
|
|
|
/// <param name="prodLines">产线明细</param>
|
|
|
/// <param name="allResults">产线占用记录</param>
|
|
|
/// <returns></returns>
|
|
|
- public LineStartDto DealNextStartTime(WorkOrdMaster workOrd,LineStartDto lineStart,int op, List<ProdLineDetail> prodLines, List<ScheduleResultOpMaster> allResults)
|
|
|
+ public LineStartDto DealNextStartTime(WorkOrdMaster workOrd,LineStartDto lineStart,WorkOrdRouting routing, List<ProdLineDetail> prodLines, List<ScheduleResultOpMaster> allResults)
|
|
|
{
|
|
|
+ int op = routing.OP;
|
|
|
LineStartDto startDto = new LineStartDto();
|
|
|
//获取产线
|
|
|
var lines = prodLines.Where(p => p.Part == workOrd.ItemNum && p.Op == op).OrderBy(p=>p.Sequence).ToList();
|
|
|
@@ -3886,7 +3932,6 @@ namespace Business.ResourceExamineManagement
|
|
|
startDto.setupTime = lines[0].SetupTime;
|
|
|
startDto.StartTime = schedule == null ? startTime : (startTime < schedule.WorkEndTime ? schedule.WorkEndTime : startTime);
|
|
|
startDto.Rate = lines[0].Rate;
|
|
|
- startDto.Op = op;
|
|
|
//循环剩余产线,找到最早可开工产线
|
|
|
for (int i = 1; i < lines.Count(); i++)
|
|
|
{
|
|
|
@@ -3900,9 +3945,16 @@ namespace Business.ResourceExamineManagement
|
|
|
startDto.setupTime = lines[i].SetupTime;
|
|
|
startDto.StartTime = startTime;
|
|
|
startDto.Rate = lines[i].Rate;
|
|
|
- startDto.Op = op;
|
|
|
}
|
|
|
}
|
|
|
+ //如果当前工单正在排产,且是连续排产时,重新排产不需要考虑产线准备时间
|
|
|
+ if (workOrd.Status.ToLower() == "w" && workOrd.JointTyped.ToUpper() != "B")
|
|
|
+ {
|
|
|
+ startDto.setupTime = 0m;
|
|
|
+ }
|
|
|
+ startDto.Op = op;
|
|
|
+ startDto.WaitTime = routing.WaitTime * 60;
|
|
|
+ startDto.QtyRemain = workOrd.QtyOrded - routing.QtyComplete;
|
|
|
return startDto;
|
|
|
}
|
|
|
|