Forráskód Böngészése

排产添加校验,记录排产异常原因

heteng 2 éve
szülő
commit
09737093c4

+ 158 - 54
MicroServices/Business/Business.Application/ResourceExamineManagement/ProductionScheduleAppService.cs

@@ -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,24 +76,33 @@ 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>
         SnowFlake help = new SnowFlake();
@@ -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>

+ 1 - 1
MicroServices/Business/Business.Domain/StructuredDB/Production/ProdLineDetail.cs

@@ -49,7 +49,7 @@ namespace Business.Domain
         /// 工序
         /// </summary>
         [Comment("工序")]
-        public int? Op { get; set; }
+        public int Op { get; set; }
 
         /// <summary>
         /// 是否有效:1-有效;0-无效

+ 60 - 0
MicroServices/Business/Business.Domain/StructuredDB/Production/ScheduleExceptionMaster.cs

@@ -0,0 +1,60 @@
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Business.StructuredDB.Production
+{
+    /// <summary>
+    /// 排产异常记录表
+    /// </summary>
+    [Comment("排产异常记录表")]
+    public class ScheduleExceptionMaster
+    {
+        /// <summary>
+        /// 主键
+        /// </summary>
+        [Comment("主键")]
+        [Key]
+        public long RecID { get; set; }
+
+        /// <summary>
+        /// 域名
+        /// </summary>
+        [Comment("域名")]
+        public string Domain { get; set; }
+
+        /// <summary>
+        /// 工单
+        /// </summary>
+        [Comment("工单")]
+        public string WorkOrd { get; set; }
+
+        /// <summary>
+        /// 物料编码
+        /// </summary>
+        [Comment("物料编码")]
+        public string ItemNum { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        [Comment("创建时间")]
+        public DateTime CreateTime { get; set; }
+
+        /// <summary>
+        /// 异常原因
+        /// </summary>
+        [Comment("异常原因")]
+        public string Remark { get; set; }
+
+        /// <summary>
+        /// 异常类型
+        /// </summary>
+        [Comment("异常类型")]
+        public string Type { get; set; }
+    }
+}

+ 5 - 0
MicroServices/Business/Business.EntityFrameworkCore/EntityFrameworkCore/DOP/BusinessDbContext.cs

@@ -41,6 +41,11 @@ namespace Business.EntityFrameworkCore
         public DbSet<ProdLineDetailRunCrew> ProdLineDetailRunCrew { get; set; }
         public DbSet<ResourceOccupancyTime> ResourceOccupancyTime { get; set; }
 
+        /// <summary>
+        /// ÅŲúÒì³£¼Ç¼±í
+        /// </summary>
+        public DbSet<ScheduleExceptionMaster> ScheduleExceptionMaster { get; set; }
+
         #endregion
 
         #region Sale