|
|
@@ -8,11 +8,13 @@ using Business.StructuredDB.Production;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Collections.Immutable;
|
|
|
+using System.Configuration;
|
|
|
using System.Linq;
|
|
|
using System.Threading.Tasks;
|
|
|
using System.Transactions;
|
|
|
using Volo.Abp.Application.Services;
|
|
|
using Volo.Abp.MultiTenancy;
|
|
|
+using Microsoft.Extensions.Configuration;
|
|
|
|
|
|
namespace Business.ResourceExamineManagement
|
|
|
{
|
|
|
@@ -155,8 +157,13 @@ namespace Business.ResourceExamineManagement
|
|
|
/// </summary>
|
|
|
public async void DoExt()
|
|
|
{
|
|
|
+ //定时任务排产:获取工厂id
|
|
|
+ IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build();
|
|
|
+ domain = configuration.GetConnectionString("Factory_id");
|
|
|
+
|
|
|
+ //获取需要排产的工单
|
|
|
List<WorkOrdMaster> workOrds = new List<WorkOrdMaster>();
|
|
|
- domain = "1001";//定时任务跑资源检查,需要定义工厂id
|
|
|
+
|
|
|
await DoProductShcedule(workOrds, domain);
|
|
|
}
|
|
|
|
|
|
@@ -168,30 +175,18 @@ namespace Business.ResourceExamineManagement
|
|
|
/// <returns></returns>
|
|
|
public async Task DoProductShcedule(List<WorkOrdMaster> workOrds, string factoryid)
|
|
|
{
|
|
|
+ //记录工厂id
|
|
|
domain = factoryid;
|
|
|
- if (workOrds.Count == 0)//定时任务调用时,需要获取工单数据
|
|
|
- {
|
|
|
- //1、获取需要排产的工单:Status为空且IsActive==1
|
|
|
- workOrds = _workOrdMaster.Select(p => string.IsNullOrEmpty(p.Status) && p.IsActive && p.Domain == domain);
|
|
|
- }
|
|
|
if (workOrds.Count == 0)//没有工单需要排产
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
//获取排产工单的最早计划开工日期
|
|
|
- DateTime earlist;
|
|
|
- if (workOrds.Min(p => p.OrdDate) == null)
|
|
|
- {
|
|
|
- earlist = DateTime.Now.Date.AddDays(7);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- earlist = workOrds.Min(p => p.OrdDate.GetValueOrDefault()).Date;
|
|
|
- }
|
|
|
-
|
|
|
+ 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 == domain && p.Status != "C" && p.IsActive);
|
|
|
+ List<WorkOrdRouting> workOrdRoutings = _workOrdRouting.Select(p => workOrds.Select(m => m.WorkOrd).Contains(p.WorkOrd) && p.ParentOp == 0 && p.Domain == domain && p.Status != "C" && p.IsActive);
|
|
|
//获取物料对应的生产线信息:物料、工序对应的生产线
|
|
|
List<ProdLineDetail> prodLines = _prodLineDetail.Select(p => workOrds.Select(m => m.ItemNum).Contains(p.Part) && p.Domain == domain && p.IsActive);
|
|
|
List<string> lines = prodLines.Select(p => p.Line).ToList();
|
|
|
@@ -228,7 +223,7 @@ namespace Business.ResourceExamineManagement
|
|
|
//var curSchedules = dbSchedules.Where(p => curLines.Contains(p.Line)).ToList();
|
|
|
allResults.AddRange(scheduleMasters);
|
|
|
|
|
|
- //工序预处理:确定每层级工序对应的产线
|
|
|
+ //计算当前物料排产开始产线
|
|
|
List<WorkOrdRoutingDto> routingDtos = ProcPretreatment(item, workOrdRoutings.Where(p => p.WorkOrd == item.WorkOrd).ToList(), prodLines, allResults);
|
|
|
|
|
|
//排产前的数据校验
|
|
|
@@ -860,130 +855,42 @@ namespace Business.ResourceExamineManagement
|
|
|
/// <returns></returns>
|
|
|
public List<WorkOrdRoutingDto> ProcPretreatment(WorkOrdMaster workOrd, List<WorkOrdRouting> woRuntings, List<ProdLineDetail> prodLines, List<ScheduleResultOpMaster> schedules)
|
|
|
{
|
|
|
- #region 注释旧逻辑
|
|
|
- //List<WorkOrdRoutingDto> routingDtos = new List<WorkOrdRoutingDto>();
|
|
|
- ////当前工单计划开始时间(默认加两天)
|
|
|
- //DateTime planStart = workOrd.OrdDate.GetValueOrDefault().AddDays(2);
|
|
|
- ////取主工序(第一层级工序)
|
|
|
- //var firsts = woRuntings.Where(p => p.ParentOp == 0).OrderByDescending(p => p.OP).ToList();
|
|
|
- //if (firsts.Count == 0)
|
|
|
- //{
|
|
|
- // return routingDtos;
|
|
|
- //}
|
|
|
- //WorkOrdRoutingDto dto = new WorkOrdRoutingDto();
|
|
|
- ////主工序按照Op排序,取最大Op
|
|
|
- //var lastOp = firsts.First();
|
|
|
- //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)
|
|
|
- //{
|
|
|
- // dto.Line = line.Line;
|
|
|
- // dto.Rate = line.Rate;
|
|
|
- // dto.SetupTime = 0;
|
|
|
- // //获取产线占用结束时间
|
|
|
- // var schedule = schedules.Where(p => p.Line == line.Line).OrderByDescending(p => p.WorkEndTime).FirstOrDefault();
|
|
|
- // dto.StartTime = schedule == null ? planStart : schedule.WorkEndTime <= planStart ? planStart : schedule.WorkEndTime;
|
|
|
- //}
|
|
|
- //routingDtos.Add(dto);
|
|
|
-
|
|
|
- ////递归处理其他层级工序
|
|
|
- //RecursionProc(woRuntings, firsts, 1, routingDtos, prodLines);
|
|
|
- #endregion
|
|
|
- #region 新逻辑
|
|
|
List<WorkOrdRoutingDto> routingDtos = new List<WorkOrdRoutingDto>();
|
|
|
//当前工单计划开始时间(默认加两天)
|
|
|
- DateTime planStart = workOrd.OrdDate.GetValueOrDefault().AddDays(2);
|
|
|
-
|
|
|
- var firsts = woRuntings.Where(x => x.WorkOrd == workOrd.WorkOrd && x.MilestoneOp).ToList();
|
|
|
+ DateTime planStart = workOrd.OrdDate.GetValueOrDefault();
|
|
|
+ //取主工序(第一层级工序)
|
|
|
+ var firsts = woRuntings.Where(p => p.ParentOp == 0 && p.MilestoneOp).OrderByDescending(p => p.OP).ToList();
|
|
|
if (firsts.Count == 0)
|
|
|
{
|
|
|
return routingDtos;
|
|
|
}
|
|
|
- foreach (var item in firsts)
|
|
|
+ WorkOrdRoutingDto dto = new WorkOrdRoutingDto();
|
|
|
+ //主工序按照Op排序,取最大Op
|
|
|
+ var lastOp = firsts.First();
|
|
|
+ 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)
|
|
|
{
|
|
|
- //多产线处理
|
|
|
- var line = prodLines.Where(p => p.Part == item.ItemNum && p.Op == item.OP).ToList();
|
|
|
- foreach (var data in line)
|
|
|
- {
|
|
|
- WorkOrdRoutingDto dto = new WorkOrdRoutingDto();
|
|
|
- dto.Line = data.Line;
|
|
|
- dto.Rate = data.Rate;
|
|
|
- dto.SetupTime = data.SetupTime;
|
|
|
- dto.sequence = data.Sequence;
|
|
|
- dto.Op = data.Op.Value;
|
|
|
- //获取产线占用结束时间
|
|
|
- var schedule = schedules.Where(p => p.Line == data.Line).OrderByDescending(p => p.WorkEndTime).FirstOrDefault();
|
|
|
- dto.StartTime = schedule == null ? planStart : schedule.WorkEndTime <= planStart ? planStart : schedule.WorkEndTime;
|
|
|
- routingDtos.Add(dto);
|
|
|
- }
|
|
|
+ dto.ChdParentOps = childs;
|
|
|
}
|
|
|
- //多生产线优先级处理
|
|
|
- //var
|
|
|
- //var Lines = routingDtos.GroupBy(x => x.Line);
|
|
|
- //递归处理其他层级工序
|
|
|
- //RecursionProc(woRuntings, firsts, 1, routingDtos, prodLines);
|
|
|
- #endregion
|
|
|
- return routingDtos;
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 递归处理工序
|
|
|
- /// </summary>
|
|
|
- /// <param name="woRuntings">工单工序</param>
|
|
|
- /// <param name="preLevels">上-层级工序</param>
|
|
|
- /// <param name="level">层级</param>
|
|
|
- /// <param name="routingDtos">返回结果</param>
|
|
|
- /// <param name="prodLines">产线</param>
|
|
|
- public void RecursionProc(List<WorkOrdRouting> woRuntings, List<WorkOrdRouting> preLevels, int level, List<WorkOrdRoutingDto> routingDtos, List<ProdLineDetail> prodLines)
|
|
|
- {
|
|
|
- //获取当前层级工序
|
|
|
- var curLevels = woRuntings.Where(p => preLevels.Select(m => m.OP).Contains(p.ParentOp)).ToList();
|
|
|
- if (curLevels.Count == 0)
|
|
|
+ //主工序对应的产线(目前只考虑一个产品对应一条产线的情况)
|
|
|
+ var line = prodLines.Where(p => p.Part == lastOp.ItemNum && p.Op == lastOp.OP).FirstOrDefault();
|
|
|
+ if (line != null)
|
|
|
{
|
|
|
- return;
|
|
|
+ dto.Line = line.Line;
|
|
|
+ dto.Rate = line.Rate;
|
|
|
+ dto.SetupTime = 0;
|
|
|
+ //获取产线占用结束时间
|
|
|
+ var schedule = schedules.Where(p => p.Line == line.Line).OrderByDescending(p => p.WorkEndTime).FirstOrDefault();
|
|
|
+ dto.StartTime = schedule == null ? planStart : schedule.WorkEndTime <= planStart ? planStart : schedule.WorkEndTime;
|
|
|
}
|
|
|
- //获取父级Op-当前层级有几条子产线
|
|
|
- var parentOps = curLevels.Select(m => m.ParentOp).Distinct().ToList();
|
|
|
- foreach (var item in parentOps)
|
|
|
- {
|
|
|
- var dto = new WorkOrdRoutingDto();
|
|
|
- var lastOp = curLevels.Where(p => p.ParentOp == item).OrderByDescending(m => m.OP).FirstOrDefault();
|
|
|
- if (lastOp == null)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- 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)
|
|
|
- {
|
|
|
- dto.Line = maxRateLine.Line;
|
|
|
- dto.Rate = maxRateLine.Rate;
|
|
|
- dto.SetupTime = maxRateLine.SetupTime;
|
|
|
- }
|
|
|
- routingDtos.Add(dto);
|
|
|
- }
|
|
|
- //递归
|
|
|
- RecursionProc(woRuntings, curLevels, level + 1, routingDtos, prodLines);
|
|
|
+ routingDtos.Add(dto);
|
|
|
+
|
|
|
+ return routingDtos;
|
|
|
}
|
|
|
}
|
|
|
}
|