|
|
@@ -16,6 +16,8 @@ using Volo.Abp.Application.Services;
|
|
|
using Volo.Abp.MultiTenancy;
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
using MongoDB.Driver.Linq;
|
|
|
+using Amazon.Runtime.Internal.Util;
|
|
|
+using IdentityModel.Client;
|
|
|
|
|
|
namespace Business.ResourceExamineManagement
|
|
|
{
|
|
|
@@ -74,23 +76,32 @@ namespace Business.ResourceExamineManagement
|
|
|
/// 产线休息时间记录表
|
|
|
/// </summary>
|
|
|
private ISqlRepository<QualityLineWorkDetail> _qualityLineWorkDetail;
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 产线人员配置表
|
|
|
/// </summary>
|
|
|
private ISqlRepository<ProdLineDetailRunCrew> _prodLineDetailRunCrew;
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 加班设置表
|
|
|
/// </summary>
|
|
|
private ISqlRepository<ResourceOccupancyTime> _resourceOccupancyTime;
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 加班设置表
|
|
|
/// </summary>
|
|
|
private ISqlRepository<GeneralizedCodeMaster> _generalizedCodeMaster;
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 节假日记录表
|
|
|
/// </summary>
|
|
|
private ISqlRepository<HolidayMaster> _holidayMaster;
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 排产异常记录
|
|
|
+ /// </summary>
|
|
|
+ private ISqlRepository<ScheduleExceptionMaster> _scheduleExceptionMaster;
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 雪花算法
|
|
|
/// </summary>
|
|
|
@@ -148,7 +159,8 @@ namespace Business.ResourceExamineManagement
|
|
|
ISqlRepository<QualityLineWorkDetail> qualityLineWorkDetail,
|
|
|
ISqlRepository<HolidayMaster> holidayMaster,
|
|
|
ISqlRepository<GeneralizedCodeMaster> generalizedCodeMaster,
|
|
|
- ICurrentTenant currentTenant
|
|
|
+ ICurrentTenant currentTenant,
|
|
|
+ ISqlRepository<ScheduleExceptionMaster> scheduleExceptionMaster
|
|
|
)
|
|
|
{
|
|
|
_itemMaster = itemMaster;
|
|
|
@@ -166,6 +178,7 @@ namespace Business.ResourceExamineManagement
|
|
|
_holidayMaster = holidayMaster;
|
|
|
_generalizedCodeMaster = generalizedCodeMaster;
|
|
|
_currentTenant = currentTenant;
|
|
|
+ _scheduleExceptionMaster = scheduleExceptionMaster;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
@@ -189,7 +202,7 @@ namespace Business.ResourceExamineManagement
|
|
|
DateTime dateTime = DateTime.Now.AddDays(30);
|
|
|
DateTime date = DateTime.Now.AddDays((double)Udecil);
|
|
|
var workOrds = _workOrdMaster.Select(x => x.IsActive && x.Domain == domain && x.OrdDate < dateTime && x.OrdDate > date && x.Status == "初始").ToList();
|
|
|
- await DoProductSchedule(workOrds, domain);
|
|
|
+ await DoProductSchedule(workOrds, domain, 1);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -197,8 +210,9 @@ namespace Business.ResourceExamineManagement
|
|
|
/// </summary>
|
|
|
/// <param name="workOrds">工单:定时任务执行时count=0;资源检查调用count>0</param>
|
|
|
/// <param name="factoryid">工单的工厂id</param>
|
|
|
+ /// <param name="type">排产类型:1-自动排产;2-手动排产</param>
|
|
|
/// <returns></returns>
|
|
|
- public async Task DoProductSchedule(List<WorkOrdMaster> workOrds, string factoryid)
|
|
|
+ public async Task DoProductSchedule(List<WorkOrdMaster> workOrds, string factoryid,int type)
|
|
|
{
|
|
|
//记录工厂id
|
|
|
domain = factoryid;
|
|
|
@@ -230,6 +244,27 @@ namespace Business.ResourceExamineManagement
|
|
|
//获取节假日记录数据
|
|
|
holidays = _holidayMaster.Select(p => p.Domain == domain && p.IsActive && p.Dated >= earlist);
|
|
|
|
|
|
+ //排产前校验
|
|
|
+ List<ScheduleExceptionMaster> exceptions = BeforeScheduleCheck(workOrds, workOrdRoutings, prodLines,type);
|
|
|
+ if (exceptions.Any())
|
|
|
+ {
|
|
|
+ using (TransactionScope scope = new TransactionScope())
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //记录排产异常数据
|
|
|
+ _scheduleExceptionMaster.Insert(exceptions);
|
|
|
+ scope.Complete();
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductSchedule", "保存排产异常数据失败:" + ex.Message, _currentTenant.Id.ToString());
|
|
|
+ scope.Dispose();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
//3、排产
|
|
|
//生产周期
|
|
|
List<PeriodSequenceDet> periodSequenceDtls = new List<PeriodSequenceDet>();
|
|
|
@@ -247,53 +282,6 @@ namespace Business.ResourceExamineManagement
|
|
|
//当前工单的产线明细
|
|
|
var curProdLines = prodLines.Where(p => p.Part == item.ItemNum).ToList();
|
|
|
|
|
|
- #region 校验
|
|
|
- //工单工艺多产线关键工序、物料对应的生产线信息:物料,工序对应的生产线、工作日历数据
|
|
|
- if (curRoutings.Count == 0)
|
|
|
- {
|
|
|
- //记录排产异常原因
|
|
|
- new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductShcedule", "工单<" + item.WorkOrd + ">的工单工艺流程数据维护为空", _currentTenant.Id.ToString());
|
|
|
- continue;
|
|
|
- }
|
|
|
- //TODO:多个关键工序校验
|
|
|
-
|
|
|
- //物料对应生产线校验
|
|
|
- var ProdLineDetails = prodLines.Where(x => x.Part == item.ItemNum).ToList();
|
|
|
- if (ProdLineDetails.Count == 0)
|
|
|
- {
|
|
|
- //记录排产异常原因
|
|
|
- new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductShcedule", "工单<" + item.WorkOrd + ">的生产线物料数据维护为空", _currentTenant.Id.ToString());
|
|
|
- continue;
|
|
|
- }
|
|
|
- var calendarsList = calendars.Where(x => ProdLineDetails.Select(p => p.Line).Contains(x.ProdLine) || string.IsNullOrEmpty(x.ProdLine)).ToList();
|
|
|
- //校验每个层级是否维护了工作日历
|
|
|
- bool flag = false;
|
|
|
- foreach (var rut in ProdLineDetails)
|
|
|
- {
|
|
|
- var lineCals = calendarsList.Where(p => p.ProdLine == rut.Line).ToList();
|
|
|
- //当前产线未配置工作日历取标准无产线工作日历使用
|
|
|
- if (lineCals.Count == 0)
|
|
|
- {
|
|
|
- lineCals = calendars.Where(p => string.IsNullOrEmpty(p.ProdLine)).ToList();
|
|
|
- if (lineCals.Count == 0)
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (lineCals.Select(p => p.WeekDay).Distinct().Count() != 7)
|
|
|
- {
|
|
|
- flag = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (flag)
|
|
|
- {
|
|
|
- //记录排产异常原因
|
|
|
- new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductShcedule", "工单<" + item.WorkOrd + ">的<" + item.ProdLine + ">工作日历数据维护错误", _currentTenant.Id.ToString());
|
|
|
- continue;
|
|
|
- }
|
|
|
- #endregion
|
|
|
-
|
|
|
//产线排产
|
|
|
LineSchedule(item, curRoutings, curProdLines, periodSequenceDtls, scheduleMasters, allResults);
|
|
|
|
|
|
@@ -316,15 +304,131 @@ namespace Business.ResourceExamineManagement
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
- new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductShcedule", "记录排产数据失败:" + ex.Message, _currentTenant.Id.ToString());
|
|
|
+ new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductSchedule", "保存排产数据失败:" + ex.Message, _currentTenant.Id.ToString());
|
|
|
scope.Dispose();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
- public bool BeforeScheduleCheck() {
|
|
|
- return true;
|
|
|
+ /// <summary>
|
|
|
+ /// 排产前校验
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="workOrds">待排产工单</param>
|
|
|
+ /// <param name="workOrdRoutings">工单工艺路线</param>
|
|
|
+ /// <param name="prodLines">产线明细</param>
|
|
|
+ /// <param name="type">排产类型:1-自动排产,2-手动排产</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public List<ScheduleExceptionMaster> BeforeScheduleCheck(List<WorkOrdMaster> workOrds,List<WorkOrdRouting> workOrdRoutings, List<ProdLineDetail> prodLines,int type)
|
|
|
+ {
|
|
|
+ List<ScheduleExceptionMaster> exceptions = new List<ScheduleExceptionMaster>();
|
|
|
+ ScheduleExceptionMaster entity;
|
|
|
+ foreach (var item in workOrds)
|
|
|
+ {
|
|
|
+ var curRoutings = workOrdRoutings.Where(p => p.ItemNum == item.ItemNum && p.MilestoneOp).OrderBy(p=>p.OP).Select(p=>p.OP).ToList();
|
|
|
+ //判断当前工单主产线是否设置了关键工序
|
|
|
+ if (!curRoutings.Any())//当前工单没有维护关键工序
|
|
|
+ {
|
|
|
+ entity = new ScheduleExceptionMaster();
|
|
|
+ entity.Domain = item.Domain;
|
|
|
+ entity.WorkOrd = item.WorkOrd;
|
|
|
+ entity.ItemNum = item.ItemNum;
|
|
|
+ entity.CreateTime = DateTime.Now;
|
|
|
+ entity.Remark = "排产异常:工单的工艺路径没有维护关键工序,请维护后再操作!";
|
|
|
+ entity.Type = type == 1 ? "自动排产" : "手动排产";
|
|
|
+ exceptions.Add(entity);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //获取当前工单物料对应的产线信息
|
|
|
+ var lineDetails = prodLines.Where(x => x.Part == item.ItemNum && curRoutings.Contains(x.Op)).ToList();
|
|
|
+ if (!lineDetails.Any())
|
|
|
+ {
|
|
|
+ entity = new ScheduleExceptionMaster();
|
|
|
+ entity.Domain = item.Domain;
|
|
|
+ entity.WorkOrd = item.WorkOrd;
|
|
|
+ entity.ItemNum = item.ItemNum;
|
|
|
+ entity.CreateTime = DateTime.Now;
|
|
|
+ entity.Remark = "排产异常:工单的关键工序没有维护产线数据,请维护后再操作!";
|
|
|
+ entity.Type = type == 1 ? "自动排产" : "手动排产";
|
|
|
+ exceptions.Add(entity);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //校验关键工序是否维护了产线
|
|
|
+ List<LineStartDto> lines = new List<LineStartDto>();
|
|
|
+ foreach (var op in curRoutings)
|
|
|
+ {
|
|
|
+ var curLines = lineDetails.Where(p => p.Op == op).ToList();
|
|
|
+ if (!curLines.Any())//当前Op没有维护产线
|
|
|
+ {
|
|
|
+ entity = new ScheduleExceptionMaster();
|
|
|
+ entity.Domain = item.Domain;
|
|
|
+ entity.WorkOrd = item.WorkOrd;
|
|
|
+ entity.ItemNum = item.ItemNum;
|
|
|
+ entity.CreateTime = DateTime.Now;
|
|
|
+ entity.Remark = "排产异常:工单的关键工序<"+ op + ">没有维护产线数据,请维护后再操作!";
|
|
|
+ entity.Type = type == 1 ? "自动排产" : "手动排产";
|
|
|
+ exceptions.Add(entity);
|
|
|
+ }
|
|
|
+ foreach (var line in curLines)
|
|
|
+ {
|
|
|
+ lines.Add(new LineStartDto {
|
|
|
+ Line = line.Line,
|
|
|
+ Op = op
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //校验一条产线是否维护了多个关键工序
|
|
|
+ List<string> pdLines = lines.Select(p => p.Line).Distinct().ToList();
|
|
|
+ foreach (var line in pdLines)
|
|
|
+ {
|
|
|
+ var curLines = lines.Where(p => p.Line == line).ToList();
|
|
|
+ if (curLines.Count() > 1)//当前物料的多个关键工序对应一条产线
|
|
|
+ {
|
|
|
+ entity = new ScheduleExceptionMaster();
|
|
|
+ entity.Domain = item.Domain;
|
|
|
+ entity.WorkOrd = item.WorkOrd;
|
|
|
+ entity.ItemNum = item.ItemNum;
|
|
|
+ entity.CreateTime = DateTime.Now;
|
|
|
+ entity.Remark = "排产异常:工单的多个关键工序<" + string.Join(",",curLines.Select(p=>p.Op).ToList()) + ">对应同一条产线,请调整后再操作!";
|
|
|
+ entity.Type = type == 1 ? "自动排产" : "手动排产";
|
|
|
+ exceptions.Add(entity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //校验主产线关键工序对应的产线是否维护了工作日历
|
|
|
+ var curCalendars = calendars.Where(x => lineDetails.Select(p => p.Line).Contains(x.ProdLine) || string.IsNullOrEmpty(x.ProdLine)).ToList();
|
|
|
+ foreach (var rut in lineDetails)
|
|
|
+ {
|
|
|
+ //获取当前产线维护的工作日历
|
|
|
+ var lineCals = curCalendars.Where(p => p.ProdLine == rut.Line).ToList();
|
|
|
+ if (!lineCals.Any())//当前产线未维护工作日历
|
|
|
+ {
|
|
|
+ lineCals = calendars.Where(p => string.IsNullOrEmpty(p.ProdLine)).ToList();
|
|
|
+ if (!lineCals.Any())
|
|
|
+ {
|
|
|
+ entity = new ScheduleExceptionMaster();
|
|
|
+ entity.Domain = item.Domain;
|
|
|
+ entity.WorkOrd = item.WorkOrd;
|
|
|
+ entity.ItemNum = item.ItemNum;
|
|
|
+ entity.CreateTime = DateTime.Now;
|
|
|
+ entity.Remark = "排产异常:产线<"+rut.Line+ ">没有维护工作日历且没有维护标准工作日历,请维护后再操作!";
|
|
|
+ entity.Type = type == 1 ? "自动排产" : "手动排产";
|
|
|
+ exceptions.Add(entity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (lineCals.Select(p => p.WeekDay).Distinct().Count() != 7)//当前产线维护了工作日历,但是没有维护完全
|
|
|
+ {
|
|
|
+ entity = new ScheduleExceptionMaster();
|
|
|
+ entity.Domain = item.Domain;
|
|
|
+ entity.WorkOrd = item.WorkOrd;
|
|
|
+ entity.ItemNum = item.ItemNum;
|
|
|
+ entity.CreateTime = DateTime.Now;
|
|
|
+ entity.Remark = "排产异常:产线<" + rut.Line + ">工作日历没有维护完整,请维护后再操作!";
|
|
|
+ entity.Type = type == 1 ? "自动排产" : "手动排产";
|
|
|
+ exceptions.Add(entity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return exceptions;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|