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

Merge branch 'dev' of http://123.60.180.165:4647/ZZYDOP/DOPCore into dev

fayimi 3 éve
szülő
commit
d2307e9905
26 módosított fájl, 1337 hozzáadás és 667 törlés
  1. 44 0
      MicroServices/Business/Business.Application.Contracts/Dto/KittingTimeDto.cs
  2. 22 0
      MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/Dto/ICItemLeadTimeDto.cs
  3. 6 6
      MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/Dto/ProdExamineParamDto.cs
  4. 8 1
      MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/IResourceExamineAppService.cs
  5. 51 35
      MicroServices/Business/Business.Application/Quartz/ProductionScheduleAppService.cs
  6. 57 34
      MicroServices/Business/Business.Application/ResourceExamineManagement/CalcBomViewAppService.cs
  7. 93 20
      MicroServices/Business/Business.Application/ResourceExamineManagement/MorderAppService.cs
  8. 130 209
      MicroServices/Business/Business.Application/ResourceExamineManagement/ProductExamineAppService.cs
  9. 506 219
      MicroServices/Business/Business.Application/ResourceExamineManagement/ResourceExamineAppService.cs
  10. 31 31
      MicroServices/Business/Business.Application/SyncDataManagement/SyncMySQLDataAppService.cs
  11. 134 30
      MicroServices/Business/Business.Application/SyncDataManagement/SyncWMSDataAppService.cs
  12. 2 5
      MicroServices/Business/Business.EntityFrameworkCore/EntityFrameworkCore/DOP/BusinessDbContext.cs
  13. 1 1
      MicroServices/Business/Business.Host/BusinessHostModule.cs
  14. 2 0
      MicroServices/Business/Business.Host/Startup.cs
  15. 15 3
      MicroServices/Business/Business.HttpApi/Controllers/ResourceExamineController.cs
  16. 10 10
      MicroServices/Business/Business.Test/MorderTest.cs
  17. 12 12
      MicroServices/Business/Business.Test/ProductExamineTest.cs
  18. 2 2
      MicroServices/Business/Bussiness.ApplicationTest/ResourceExamineManagement/ResourceExamineAppService_Tests.cs
  19. 10 1
      MicroServices/Business/Bussiness.Model/MES/IC/ItemMaster.cs
  20. 49 0
      MicroServices/Business/Bussiness.Model/MES/IC/ItemPackMaster.cs
  21. 55 0
      MicroServices/Business/Bussiness.Model/MES/IC/LocationDetail.cs
  22. 37 0
      MicroServices/Business/Bussiness.Model/MES/IC/NbrDetail.cs
  23. 43 0
      MicroServices/Business/Bussiness.Model/MES/IC/NbrMaster.cs
  24. 0 48
      MicroServices/Business/Bussiness.Model/Production/ScheduleExceptionMaster.cs
  25. 9 0
      MicroServices/Business/Bussiness.Model/SRM/srm_po_list.cs
  26. 8 0
      MicroServices/Business/Bussiness.MongoModel/SRM/mo_srm_po_list.cs

+ 44 - 0
MicroServices/Business/Business.Application.Contracts/Dto/KittingTimeDto.cs

@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Business.Dto
+{
+    /// <summary>
+    /// 订单行建议交期
+    /// </summary>
+    public class KittingTimeDto
+    {
+        /// <summary>
+        /// 订单行id
+        /// </summary>
+        public long sentry_id { get; set; }
+
+        /// <summary>
+        /// 物料编码
+        /// </summary>
+        public string ItemNum { get; set; }
+
+        /// <summary>
+        /// 生产数量
+        /// </summary>
+        public decimal LackQty { get; set; }
+
+        /// <summary>
+        /// 物料齐套时间
+        /// </summary>
+        public DateTime sys_capacity_date { get; set; }
+
+        /// <summary>
+        /// 系统建议交期(产能)
+        /// </summary>
+        public DateTime kitting_time { get; set; }
+
+        /// <summary>
+        /// 系统建议交期(物料)
+        /// </summary>
+        public DateTime sys_material_date { get; set; }
+    }
+}

+ 22 - 0
MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/Dto/ICItemLeadTimeDto.cs

@@ -41,5 +41,27 @@ namespace Business.ResourceExamineManagement.Dto
         /// </summary>
         [Comment("最小订单量")]
         public decimal? minorderqty { get; set; }
+
+        /// <summary>
+        /// 投料自动取整
+        /// </summary>
+        [Comment("投料自动取整")]
+        public int? put_integer { get; set; }
+
+        /// <summary>
+        /// 工单发料时间/天
+        /// </summary>
+        [Precision(23, 10)]
+        [Comment("工单发料时间/天")]
+        public decimal? ordissu_days { get; set; }
+
+        /// <summary>
+        /// 最小包装量
+        /// </summary>
+        [Comment("最小包装量")]
+        [Required]
+        [DefaultValue(0)]
+        [Precision(23, 10)]
+        public decimal? minpackqty { get; set; }
     }
 }

+ 6 - 6
MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/Dto/ProdExamineParamDto.cs

@@ -12,18 +12,18 @@ namespace Business.ResourceExamineManagement.Dto
     public class ProdExamineParamDto
     {
         /// <summary>
-        /// bom编号
+        /// 物料编码
         /// </summary>
-        public string? bom_number { get; set; }
+        public string ItemNum { get; set; }
 
         /// <summary>
-        /// bom版本
+        /// 订单行数量
         /// </summary>
-        public string? version { get; set; }
+        public decimal QtyOrd { get; set; }
 
         /// <summary>
-        /// 生产件数
+        /// 计划开始时间
         /// </summary>
-        public int packages { get; set; }
+        public DateTime PlanStart { get; set; }
     }
 }

+ 8 - 1
MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/IResourceExamineAppService.cs

@@ -12,12 +12,19 @@ namespace Business.ResourceExamineManagement
     /// </summary>
     public interface IResourceExamineAppService : IApplicationService
     {
+        /// <summary>
+        /// 汜莉齬莉
+        /// </summary>
+        /// <param name="workOrds"></param>
+        /// <returns></returns>
+        Task<string> ProductionSchedule(string workOrds);
+
         /// <summary>
         /// 訧埭潰脤
         /// </summary>
         /// <param name="input"></param>
         /// <returns></returns>
-        Task<string> ReceiveResult(ResourceCheckInputDto input);
+        Task<string> ReceiveResult(string ids);
 
         /// <summary>
         /// 馱等潰脤

+ 51 - 35
MicroServices/Business/Business.Application/Quartz/ProductionScheduleAppService.cs

@@ -13,6 +13,7 @@ using System.Globalization;
 using System.Linq;
 using System.Threading.Tasks;
 using Volo.Abp.Application.Services;
+using Volo.Abp.MultiTenancy;
 
 namespace Business.Quartz
 {
@@ -67,11 +68,6 @@ namespace Business.Quartz
         /// </summary>
         private ISqlRepository<ShopCalendarWorkCtr> _shopCalendarWorkCtr;
 
-        /// <summary>
-        /// 排产异常记录表
-        /// </summary>
-        private ISqlRepository<ScheduleExceptionMaster> _scheduleExceptionMaster;
-
         /// <summary>
         /// 产线休息时间记录表
         /// </summary>
@@ -87,6 +83,8 @@ namespace Business.Quartz
         /// </summary>
         SnowFlake help = new SnowFlake();
 
+        private readonly ICurrentTenant _currentTenant;
+
         /// <summary>
         /// 工作日历数据
         /// </summary>
@@ -118,9 +116,9 @@ namespace Business.Quartz
             ISqlRepository<ScheduleResultOpMaster> scheduleResultOpMaster,
             ISqlRepository<InvMaster> invMaster,
             ISqlRepository<ShopCalendarWorkCtr> shopCalendarWorkCtr,
-            ISqlRepository<ScheduleExceptionMaster> scheduleExceptionMaster,
             ISqlRepository<QualityLineWorkDetail> qualityLineWorkDetail,
-            ISqlRepository<HolidayMaster> holidayMaster
+            ISqlRepository<HolidayMaster> holidayMaster,
+            ICurrentTenant currentTenant
             )
         { 
             _itemMaster= itemMaster;
@@ -132,9 +130,9 @@ namespace Business.Quartz
             _scheduleResultOpMaster= scheduleResultOpMaster;
             _invMaster= invMaster;
             _shopCalendarWorkCtr= shopCalendarWorkCtr;
-            _scheduleExceptionMaster= scheduleExceptionMaster;
             _qualityLineWorkDetail= qualityLineWorkDetail;
             _holidayMaster = holidayMaster;
+            _currentTenant= currentTenant;
         }
         #endregion
 
@@ -182,8 +180,6 @@ namespace Business.Quartz
             holidays = _holidayMaster.Select(p => p.Domain == "1001" && p.IsActive && p.Dated >= earlist);
 
             //3、排产
-            //排产异常记录
-            List<ScheduleExceptionMaster> scheduleExceptions = new List<ScheduleExceptionMaster>();
             //生产周期
             List<PeriodSequenceDet> periodSequenceDtls = new List<PeriodSequenceDet>();
             //排产记录表
@@ -202,28 +198,14 @@ namespace Business.Quartz
                 if (routingDtos.Count() == 0)//没有维护主工序
                 {
                     //记录排产异常原因
-                    scheduleExceptions.Add(new ScheduleExceptionMaster
-                    {
-                        RecID = help.NextId(),
-                        Domain = "1001",
-                        WorkOrd = item.WorkOrd,
-                        Remark = "工单的工序数据维护错误",
-                        CreatTime = DateTime.Now
-                    });
+                    new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductShcedule", "工单<"+ item.WorkOrd + ">的工序数据维护错误", _currentTenant.Id.ToString());
                     continue;
                 }
                 //校验每层级工序是否都维护了产线
                 if (routingDtos.Exists(p=> string.IsNullOrEmpty(p.Line)))
                 {
                     //记录排产异常原因
-                    scheduleExceptions.Add(new ScheduleExceptionMaster
-                    {
-                        RecID = help.NextId(),
-                        Domain = "1001",
-                        WorkOrd = item.WorkOrd,
-                        Remark = "工单的产线数据维护错误",
-                        CreatTime = DateTime.Now
-                    });
+                    new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductShcedule", "工单<" + item.WorkOrd + ">的产线数据维护错误", _currentTenant.Id.ToString());
                     continue;
                 }
                 //校验每个层级是否维护了工作日历
@@ -240,14 +222,7 @@ namespace Business.Quartz
                 if (flag)
                 {
                     //记录排产异常原因
-                    scheduleExceptions.Add(new ScheduleExceptionMaster
-                    {
-                        RecID = help.NextId(),
-                        Domain = "1001",
-                        WorkOrd = item.WorkOrd,
-                        Remark = "工单产线的工作日历数据维护错误",
-                        CreatTime = DateTime.Now
-                    });
+                    new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductShcedule", "工单<" + item.WorkOrd + ">的产线工作日历数据维护错误", _currentTenant.Id.ToString());
                     continue;
                 }
 
@@ -261,7 +236,6 @@ namespace Business.Quartz
             _workOrdMaster.Update(workOrds);
             _periodSequenceDet.Insert(periodSequenceDtls);
             _scheduleResultOpMaster.Insert(scheduleMasters);
-            _scheduleExceptionMaster.Insert(scheduleExceptions);
         }
 
         /// <summary>
@@ -480,6 +454,8 @@ namespace Business.Quartz
                 return actStart;
             }
 
+            //开始时间往后推到半小时/整点节点
+            actStart = CalcStartTimeAfter(actStart);
             //当天的工作日历
             var shopCal = curCalendars.Where(p => p.WeekDay == weekDay).First();
             //当前日期的工作时间段
@@ -528,6 +504,40 @@ namespace Business.Quartz
             return actStart;
         }
 
+        /// <summary>
+        /// 排产开始时间处理为半小时/整点开始--向后取整
+        /// </summary>
+        /// <param name="startTime"></param>
+        /// <returns></returns>
+        public DateTime CalcStartTimeAfter(DateTime startTime)
+        {
+            DateTime rtnTime = startTime;
+            DateTime curDate = startTime.Date;
+            //时间转换为分钟
+            TimeSpan span = rtnTime - curDate;
+            decimal sumMinutes = (decimal)span.TotalMinutes;
+            int times = (int)Math.Ceiling(sumMinutes / 30);
+            rtnTime = curDate.AddMinutes(times * 30);
+            return rtnTime;
+        }
+
+        /// <summary>
+        /// 排产开始时间处理为半小时/整点开始--向前取整
+        /// </summary>
+        /// <param name="startTime"></param>
+        /// <returns></returns>
+        public DateTime CalcStartTimeBefore(DateTime startTime)
+        {
+            DateTime rtnTime = startTime;
+            DateTime curDate = startTime.Date;
+            //时间转换为分钟
+            TimeSpan span = rtnTime - curDate;
+            decimal sumMinutes = (decimal)span.TotalMinutes;
+            int times = (int)Math.Floor(sumMinutes / 30);
+            rtnTime = curDate.AddMinutes(times * 30);
+            return rtnTime;
+        }
+
         /// <summary>
         /// 判断当天是否是工作日
         /// </summary>
@@ -583,6 +593,8 @@ namespace Business.Quartz
             if (curMins >= needMinute)//当前时间段的可用提前期满足
             {
                 actStart = startTime.AddMinutes((double)-needMinute);
+                //开始时间往前推到半小时/整点节点
+                actStart = CalcStartTimeBefore(actStart);
                 return actStart;
             }
             //当前时间段的可用提前期不满足
@@ -603,6 +615,8 @@ namespace Business.Quartz
             }
             if (!flag)
             {
+                //开始时间往前推到半小时/整点节点
+                actStart = CalcStartTimeBefore(actStart);
                 return actStart;
             }
             //今天可用提前期不够,往前工作日找
@@ -634,6 +648,8 @@ namespace Business.Quartz
                     needMinute -= sumWorkMins;
                 }
             }
+            //开始时间往前推到半小时/整点节点
+            actStart = CalcStartTimeBefore(actStart);
             return actStart;
         }
 

+ 57 - 34
MicroServices/Business/Business.Application/ResourceExamineManagement/CalcBomViewAppService.cs

@@ -1,5 +1,6 @@
 using Business.Core.Enum;
 using Business.Core.Utilities;
+using Business.Model.Production;
 using Business.Model.Sale;
 using Business.Model.SRM;
 using Business.MongoModel.MES.IC;
@@ -7,9 +8,11 @@ using Business.MongoModel.Production;
 using Business.MongoModel.SRM;
 using Business.MongoModel.Tech;
 using Business.ResourceExamineManagement.Dto;
+using MongoDB.Driver.Linq;
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
 using Volo.Abp.Application.Services;
 using static Spire.Pdf.General.Render.Decode.Jpeg2000.j2k.codestream.HeaderInfo;
@@ -47,24 +50,34 @@ namespace Business.ResourceExamineManagement
         SnowFlake help = new SnowFlake();
 
         /// <summary>
-        /// 工艺路径
+        /// 生产线明细表
         /// </summary>
-        public List<mo_mes_technique> techs = new List<mo_mes_technique>();
+        public List<ProdLineDetail> prodLines = new List<ProdLineDetail>();
 
         /// <summary>
-        /// 工艺关联工序
+        /// 标准工艺路径表
         /// </summary>
-        public List<mo_mes_tech_process> tech_Processes = new List<mo_mes_tech_process>();
+        public List<RoutingOpDetail> routingOps = new List<RoutingOpDetail>();
 
         /// <summary>
-        /// 工序
+        /// 排产记录表
         /// </summary>
-        public List<mo_mes_process> process = new List<mo_mes_process>();
+        public List<PeriodSequenceDet> periodSequences = new List<PeriodSequenceDet>();
 
         /// <summary>
-        /// 工艺工序关联工位
+        /// 工作日历
         /// </summary>
-        public List<mo_mes_tech_proc_workshop> tech_Proc_Workshops = new List<mo_mes_tech_proc_workshop>();
+        public List<ShopCalendarWorkCtr> calendarWorks = new List<ShopCalendarWorkCtr>();
+
+        /// <summary>
+        /// 休息时间段
+        /// </summary>
+        public List<QualityLineWorkDetail> qualityLineWorks = new List<QualityLineWorkDetail>();
+
+        /// <summary>
+        /// 节假日
+        /// </summary>
+        public List<HolidayMaster> holidays = new List<HolidayMaster>();
 
         /// <summary>
         /// 工单App
@@ -333,10 +346,13 @@ namespace Business.ResourceExamineManagement
             ? plan_date, List<mo_ic_item_stockoccupy> sklist, crm_seorderentry sentrys,int urgent, List<mo_ic_item> icitemlist)
         {
             //生成主工单
-            _morderAppService.process = process;
-            _morderAppService.techs = techs;
-            _morderAppService.tech_Processes = tech_Processes;
-            _morderAppService.tech_Proc_Workshops = tech_Proc_Workshops;
+            _morderAppService.prodLines = prodLines;
+            _morderAppService.routingOps = routingOps;
+            _morderAppService.periodSequences = periodSequences;
+            _morderAppService.calendarWorks = calendarWorks;
+            _morderAppService.qualityLineWorks = qualityLineWorks;
+            _morderAppService.holidays = holidays;
+
             Mes_MorderDto mes_MorderDto = _morderAppService.GenerateMorder(generateMorderDto, urgent);
             MatterTileDevelop(level1Dto, childList, returnlist, sklist, bangid, plan_date, sentrys, icitemlist);
             //这里更新产品得满足时间。
@@ -348,37 +364,43 @@ namespace Business.ResourceExamineManagement
                 {
                     if (!string.IsNullOrEmpty(mes_Morders.bom_number))
                     {
+                        mes_Morders.moentry_sys_stime = childList.Max(s => s.kitting_time.GetValueOrDefault()).AddDays(1).Date;//数据齐套完成后隔天开始生产;
                         //var ProductiveDate = ProductiveExamine(mes_Morders.bom_number, level1Dto.version, (int)mes_Morders.morder_production_number.Value);
                         ProdExamineParamDto prodExamine = new ProdExamineParamDto()
                         {
-                            bom_number = mes_Morders.bom_number,
-                            version = level1Dto.version,
-                            packages = (int)mes_Morders.morder_production_number.Value
+                            ItemNum = mes_Morders.bom_number,
+                            PlanStart = mes_Morders.moentry_sys_stime.Value,
+                            QtyOrd = (int)mes_Morders.morder_production_number.Value
                         };
-                        _productExamineAppService.process = process;
-                        _productExamineAppService.techs = techs;
-                        _productExamineAppService.tech_Processes = tech_Processes;
-                        _productExamineAppService.tech_Proc_Workshops = tech_Proc_Workshops;
+                        _productExamineAppService.prodLines = prodLines;
+                        _productExamineAppService.routingOps = routingOps;
+                        _productExamineAppService.periodSequences = periodSequences;
+                        _productExamineAppService.calendarWorks = calendarWorks;
+                        _productExamineAppService.qualityLineWorks = qualityLineWorks;
+                        _productExamineAppService.holidays = holidays;
 
                         var plan = planList.Find(x => x.icitem_id == level1Dto.item_id);
                         var ProductiveDate = _productExamineAppService.ProductiveExamine(prodExamine);
-                        var Day = ProductiveDate / (60 * 10); //返回的分钟除以十个小时得出工作天数;
-                        mes_Morders.moentry_sys_stime = childList.Max(s => s.kitting_time.GetValueOrDefault()).AddDays(1);//数据齐套完成后隔天开始生产;
+                        //var Day = ProductiveDate / (60 * 10); //返回的分钟除以十个小时得出工作天数;
+
                         //结束日期=开始时间+生产时长+自检提前期+入库提前期+发运提前期;
-                        var LeadTime = 0.00m;
+                        DateTime LeadTime;
                         if (plan != null)
                         {
-                            LeadTime = Day + plan.self_inspection_date.GetValueOrDefault() + plan.Warehousing_date.GetValueOrDefault();
+                            var TQdate = plan.self_inspection_date.GetValueOrDefault() + plan.Warehousing_date.GetValueOrDefault();
+                            LeadTime = ProductiveDate.AddDays((double)TQdate);
                         }
                         else
                         {
-                            LeadTime = Day;
+                            LeadTime = ProductiveDate;
                         }
-                        ProductionTimeDay = LeadTime;
-                        mes_Morders.moentry_sys_etime = mes_Morders.moentry_sys_stime.Value.AddDays((double)Day);
-                        mes_Morders.morder_need_time = ProductiveDate;
+                        //ProductionTimeDay = LeadTime;
+                        mes_Morders.moentry_sys_etime = LeadTime;
+                        TimeSpan span = ProductiveDate - mes_Morders.moentry_sys_stime.Value;
+                        mes_Morders.morder_need_time = (decimal)span.TotalMinutes;
+
                         //满足资源检查的时间需加上提前期
-                        level1Dto.satisfy_time = mes_Morders.moentry_sys_stime.Value.AddDays((double)LeadTime);
+                        level1Dto.satisfy_time = LeadTime;
                         if (sentrys != null)
                         {
                             sentrys.sys_capacity_date = level1Dto.satisfy_time;
@@ -618,7 +640,7 @@ namespace Business.ResourceExamineManagement
                             item.kitting_time = cilList.Max(s => s.kitting_time);
                         }
                         item.make_qty = item.lack_qty;
-                        //走自制
+                        /*//走自制
                         ProdExamineParamDto prodExamine = new ProdExamineParamDto()
                         {
                             bom_number = item.bom_number,
@@ -630,17 +652,17 @@ namespace Business.ResourceExamineManagement
                         _productExamineAppService.tech_Processes = tech_Processes;
                         _productExamineAppService.tech_Proc_Workshops = tech_Proc_Workshops;
 
-                        /*if (param.checkflag)
+                        *//*if (param.checkflag)
                         {
                             //todo:增加生成子工单后,这里需要加上生成的子工单的明细。
-                        }*/
+                        }*//*
                         item.make_list = new List<moorder>();
                         var minute = _productExamineAppService.ProductiveExamine(prodExamine);
                         //系统建议完工日期为 开工日期+产能检查时间=完工日期
                         var Day = minute / (60 * 10); //返回的分钟除以十个小时得出工作天数;
                         var ktime = item.kitting_time.Value.AddDays((double)Day);
                         //item.kitting_time = ktime > mooccupylist[0].moo_etime ? ktime : mooccupylist[0].moo_etime;
-                        item.kitting_time = ktime;
+                        item.kitting_time = ktime;*/
                     }
                 }
                 else if (item.erp_cls == 3)
@@ -1007,7 +1029,8 @@ namespace Business.ResourceExamineManagement
                                 CalcIcitem(cilList, returnlist, bangid, sklist, plan_date, icitemlist, sentrys, childidList);
                                 sct.kitting_time = cilList.Max(s => s.kitting_time);
                             }
-                            //走自制
+                            sct.make_qty = sct.lack_qty;
+                            /*//走自制
                             ProdExamineParamDto prodExamine = new ProdExamineParamDto()
                             {
                                 bom_number = sct.bom_number,
@@ -1023,7 +1046,7 @@ namespace Business.ResourceExamineManagement
                             //系统建议完工日期为 开工日期+产能检查时间=完工日期
                             var Day = minute / (60 * 10); //返回的分钟除以十个小时得出工作天数;
                             sct.kitting_time = sct.kitting_time.Value.AddDays((double)Day);
-                            sct.make_qty = sct.lack_qty;
+                            sct.make_qty = sct.lack_qty;*/
                             //todo:
                             sct.make_list = new List<moorder>();
                         }

+ 93 - 20
MicroServices/Business/Business.Application/ResourceExamineManagement/MorderAppService.cs

@@ -1,12 +1,16 @@
 using Business.Core.Enum;
 using Business.Core.Utilities;
+using Business.EntityFrameworkCore.SqlRepositories;
+using Business.Model.Production;
 using Business.Model.Sale;
 using Business.MongoModel.MES.IC;
 using Business.MongoModel.Production;
 using Business.MongoModel.Tech;
 using Business.ResourceExamineManagement.Dto;
+using Newtonsoft.Json.Linq;
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
 using Volo.Abp.Application.Services;
 
@@ -52,24 +56,36 @@ namespace Business.ResourceExamineManagement
         SnowFlake snowFlake = new SnowFlake();
 
         /// <summary>
-        /// 工艺路径
+        /// 生产线明细表
         /// </summary>
-        public List<mo_mes_technique> techs = new List<mo_mes_technique>();
+        public List<ProdLineDetail> prodLines = new List<ProdLineDetail>();
 
         /// <summary>
-        /// 工艺关联工序
+        /// 标准工艺路径表
         /// </summary>
-        public List<mo_mes_tech_process> tech_Processes = new List<mo_mes_tech_process>();
+        public List<RoutingOpDetail> routingOps = new List<RoutingOpDetail>();
 
         /// <summary>
-        /// 工序
+        /// 排产记录表
         /// </summary>
-        public List<mo_mes_process> process = new List<mo_mes_process>();
+        public List<PeriodSequenceDet> periodSequences = new List<PeriodSequenceDet>();
 
         /// <summary>
-        /// 工艺工序关联工位
+        /// 工作日历
         /// </summary>
-        public List<mo_mes_tech_proc_workshop> tech_Proc_Workshops = new List<mo_mes_tech_proc_workshop>();
+        public List<ShopCalendarWorkCtr> calendarWorks = new List<ShopCalendarWorkCtr>();
+
+        /// <summary>
+        /// 休息时间段
+        /// </summary>
+        public List<QualityLineWorkDetail> qualityLineWorks = new List<QualityLineWorkDetail>();
+
+        /// <summary>
+        /// 节假日
+        /// </summary>
+        public List<HolidayMaster> holidays = new List<HolidayMaster>();
+
+
         /// <summary>
         /// 工单
         /// </summary>
@@ -83,6 +99,8 @@ namespace Business.ResourceExamineManagement
         /// </summary>
         public List<mo_mes_mooccupy> mo_Mes_Mooccupies = new List<mo_mes_mooccupy>();
 
+
+        private readonly ISqlRepository<rf_serialnumber> _rf_serialnumber;
         #endregion
         #region 构造函数
         /// <summary>
@@ -96,7 +114,8 @@ namespace Business.ResourceExamineManagement
             //IMongoDB<mo_mes_mooccupy> mo_mes_mooccupy,
             //IRepository<crm_seorder, long> mysql_crm_seorder,
             //IRepository<crm_seorderentry, long> mysql_crm_seorderentry,
-            ProductExamineAppService productExamineAppService
+            ProductExamineAppService productExamineAppService,
+            ISqlRepository<rf_serialnumber> rf_serialnumber
             )
         {
 
@@ -106,6 +125,7 @@ namespace Business.ResourceExamineManagement
             //_mysql_crm_seorder = mysql_crm_seorder;
             //_mysql_crm_seorderentry = mysql_crm_seorderentry;
             _productExamineAppService = productExamineAppService;
+            _rf_serialnumber = rf_serialnumber;
         }
         #endregion
 
@@ -134,7 +154,7 @@ namespace Business.ResourceExamineManagement
             //mes_Morder.morder_icitem_type
             mes_Morder.work_order_type = generateMorderDto.work_order_type;
             mes_Morder.morder_state = generateMorderDto.morder_state;
-            mes_Morder.morder_no = string.Format("VMO{0}", DateTime.Now.ToString("yyyyMMddhhmmss"));//测试编码
+            mes_Morder.morder_no = GetMaxSerialNumber(418022612537413);//WWPO
             mes_Morder.fms_number = generateMorderDto.ic_Item.fms_number;
             mes_Morder.bom_number = generateMorderDto.BomNumber;
             mes_Morder.fmodel = generateMorderDto.ic_Item.model;
@@ -148,20 +168,23 @@ namespace Business.ResourceExamineManagement
                 {
                     ProdExamineParamDto prodExamine = new ProdExamineParamDto()
                     {
-                        bom_number = generateMorderDto.BomNumber,
-                        version = generateMorderDto.version,
-                        packages = (int)generateMorderDto.Quantity.GetValueOrDefault()
+                        ItemNum = generateMorderDto.BomNumber,
+                        PlanStart = generateMorderDto.moentry_sys_stime.Value,
+                        QtyOrd = (int)generateMorderDto.Quantity.GetValueOrDefault()
                     };
-                    _productExamineAppService.process = process;
-                    _productExamineAppService.techs = techs;
-                    _productExamineAppService.tech_Processes = tech_Processes;
-                    _productExamineAppService.tech_Proc_Workshops = tech_Proc_Workshops;
+                    _productExamineAppService.prodLines = prodLines;
+                    _productExamineAppService.routingOps = routingOps;
+                    _productExamineAppService.periodSequences = periodSequences;
+                    _productExamineAppService.calendarWorks = calendarWorks;
+                    _productExamineAppService.qualityLineWorks = qualityLineWorks;
+                    _productExamineAppService.holidays = holidays;
 
                     var ProductiveDate = _productExamineAppService.ProductiveExamine(prodExamine);
                     //系统建议完工日期为 开工日期+产能检查时间=完工日期
-                    var Day = ProductiveDate / (60 * 10); //返回的分钟除以十个小时得出工作天数;
-                    mes_Morder.moentry_sys_etime = mes_Morder.moentry_sys_stime.GetValueOrDefault().AddDays((double)Day);
-                    mes_Morder.morder_need_time = ProductiveDate;
+                    //var Day = ProductiveDate / (60 * 10); //返回的分钟除以十个小时得出工作天数;
+                    mes_Morder.moentry_sys_etime = ProductiveDate;
+                    TimeSpan span = ProductiveDate - generateMorderDto.moentry_sys_stime.Value;
+                    mes_Morder.morder_need_time = (decimal)span.TotalMinutes;
                 }
             }
 
@@ -480,5 +503,55 @@ namespace Business.ResourceExamineManagement
             mes_Mooccupy.factory_id = param.factoryId;
             return mes_Mooccupy;
         }
+
+        /// <summary>
+        /// 得到一个流水号的最大流水号
+        /// </summary>
+        /// <param name="id">流水号id</param>
+        /// <param name="formData">json数据,可以用json中的某个字段值作为通配符字替换流水号格式。</param>
+        /// <returns></returns>
+        public string GetMaxSerialNumber(long id, JObject? formData = null)
+        {
+            var modelList = _rf_serialnumber.Select(s => s.Id == id);
+            if (modelList == null && modelList.Count < 1)
+            {
+                return string.Empty;
+            }
+            var model = modelList[0];
+            int max = model.CurrentNumber + 1;
+            var date = DateTime.Now;
+            var lastDate = model.LastTime;
+            switch (model.NumberType)
+            {
+                case 1: //年流水
+                    if (date.Year > lastDate.Year)
+                    {
+                        max = 1;
+                    }
+                    break;
+                case 2: //月流水
+                    if (date.Year > lastDate.Year || date.Month > lastDate.Month)
+                    {
+                        max = 1;
+                    }
+                    break;
+                case 3: //日流水
+                    if (date.Year > lastDate.Year || date.Month > lastDate.Month || date.Day > lastDate.Day)
+                    {
+                        max = 1;
+                    }
+                    break;
+            }
+            string number = max.ToString().PadLeft(model.NumberSize, '0');
+            string serialNumber = string.IsNullOrWhiteSpace(model.Format) ? number
+                : model.Format.ContainsIgnoreCase("{number}")
+                ? model.Format.ReplaceIgnoreCase("{number}", number)
+                : model.Format + number;
+            //更新当前编号和最后时间
+            model.LastTime = date;
+            model.CurrentNumber = max;
+            _rf_serialnumber.Update(model);
+            return Wildcard.Replace(serialNumber, formData);
+        }
     }
 }

+ 130 - 209
MicroServices/Business/Business.Application/ResourceExamineManagement/ProductExamineAppService.cs

@@ -11,6 +11,8 @@ using System.Text;
 using System.Threading.Tasks;
 using Volo.Abp.Application.Services;
 using Volo.Abp.Domain.Repositories;
+using Business.Dto;
+using Business.Model.Sale;
 
 namespace Business.ResourceExamineManagement
 {
@@ -21,24 +23,34 @@ namespace Business.ResourceExamineManagement
     {
         #region 服务
         /// <summary>
-        /// 工艺路径
+        /// 生产线明细表
         /// </summary>
-        public List<mo_mes_technique> techs = new List<mo_mes_technique>();
+        public List<ProdLineDetail> prodLines = new List<ProdLineDetail>();
 
         /// <summary>
-        /// 工艺关联工序
+        /// 标准工艺路径表
         /// </summary>
-        public List<mo_mes_tech_process> tech_Processes = new List<mo_mes_tech_process>();
+        public List<RoutingOpDetail> routingOps = new List<RoutingOpDetail>();
 
         /// <summary>
-        /// 工序
+        /// 排产记录表
         /// </summary>
-        public List<mo_mes_process> process = new List<mo_mes_process>();
+        public List<PeriodSequenceDet> periodSequences = new List<PeriodSequenceDet>();
 
         /// <summary>
-        /// 工艺工序关联工位
+        /// 工作日历
         /// </summary>
-        public List<mo_mes_tech_proc_workshop> tech_Proc_Workshops = new List<mo_mes_tech_proc_workshop>();
+        public List<ShopCalendarWorkCtr> calendarWorks = new List<ShopCalendarWorkCtr>();
+
+        /// <summary>
+        /// 休息时间段
+        /// </summary>
+        public List<QualityLineWorkDetail> qualityLineWorks = new List<QualityLineWorkDetail>();
+
+        /// <summary>
+        /// 节假日
+        /// </summary>
+        public List<HolidayMaster> holidays = new List<HolidayMaster>();
 
         #endregion
 
@@ -50,255 +62,164 @@ namespace Business.ResourceExamineManagement
         }
 
         /// <summary>
-        /// 产能计算
+        /// 产能计算-批量
         /// </summary>
-        /// <param name="packages">件数</param>
-        /// <returns>生产时长</returns>
-        public decimal ProductiveExamine(ProdExamineParamDto param)
+        /// <param name="param">产能检查入参</param>
+        /// <returns>生产时长(天)</returns>
+        public DateTime ProductiveExamine(ProdExamineParamDto param)
         {
-            if (param.packages <= 0)
+            //生产结束时间
+            DateTime planEnd = param.PlanStart.Date;
+            if (param.QtyOrd <= 0)
             {
-                //throw new NotImplementedException("产能计算参数有误!");
+                return planEnd;
             }
-            //过滤数据
-            //1.1、获取工艺路径数据
-            mo_mes_technique curTech = techs.FirstOrDefault(p => p.bom == param.bom_number && p.bomver == param.version);
-            if (curTech == null)
+            //获取当前产品的工艺路线:主产线,最后一道工序
+            var curRoutingOps = routingOps.Where(p => p.RoutingCode == param.ItemNum && p.ParentOp == 0).OrderByDescending(p => p.Op).ToList();
+            if (curRoutingOps.Count() == 0)
             {
-                return param.packages * 20;
-                //throw new NotImplementedException("工艺路径不存在,请调整!");
+                return planEnd;
             }
-            //1.2、获取工艺关联工序数据
-            List<mo_mes_tech_process> curTechProcess = tech_Processes.Where(p => p.tech_id == curTech.mysql_id).ToList();
-            if (curTechProcess.Count == 0)
+            var lastOp = curRoutingOps.First();
+            //获取产线
+            var curProdLine = prodLines.FirstOrDefault(p => p.Part == param.ItemNum && p.Op == lastOp.Op);
+            if (curProdLine == null)
             {
-                return param.packages * 20;
-                //throw new NotImplementedException("当前工艺路径没有配置工序,请调整!");
+                return planEnd;
             }
-            //1.3、获取工序数据
-            List<mo_mes_process> curProcess = process.Where(p => curTechProcess.Select(m => m.proc_id).Contains(p.mysql_id)).ToList();
-            if (curProcess.Count == 0)
+            //获取产线工作日历
+            var curCalendars = calendarWorks.Where(p => p.ProdLine == curProdLine.Line).ToList();
+            if (curCalendars.Count() == 0 || curCalendars.Count() != 7)
             {
-                return param.packages * 20;
-                //throw new NotImplementedException("工序数据不存在,请调整!");
+                return planEnd;
             }
-            //1.4、获取工位数据
-            List<mo_mes_tech_proc_workshop> curWorkShops = tech_Proc_Workshops.Where(p=> curTechProcess.Select(m=>m.mysql_id).Contains(p.tech_proc_id)).ToList(); ;
-
-            //2、获取工艺路径下的第一层级工序:目前只考虑第一层级
-            List<mo_mes_tech_process> fistLevels = curTechProcess.Where(p => p.parentprocid == curTech.mysql_id).ToList();
-            if (fistLevels.Count == 0)
+            //获取产线休息时间
+            var curqualityLines = qualityLineWorks.Where(p=>p.ProdLine == curProdLine.Line).ToList();
+            //生产数量
+            decimal sumAmount = 0m;
+            do
             {
-                return param.packages * 20;
-                //throw new NotImplementedException("当前工艺路径没有配置工序,请调整!");
-            }
-            //工艺预处理
-            List<TechProcDto> teches = TechProcPretreatment(fistLevels,param.packages);
-            decimal sumTimes = teches.OrderByDescending(p => p.sumTimes).First().sumTimes;
-            return sumTimes;
+                //获取工作日
+                planEnd = GetNextWorkDay(planEnd, curCalendars);
+                //计算工作日的产能
+                sumAmount += CalcCapacity(planEnd, curProdLine, curCalendars, curqualityLines);
+                planEnd = planEnd.AddDays(1);
+            } while (sumAmount < param.QtyOrd);
+            return planEnd.AddDays(-1);
         }
 
         /// <summary>
-        /// 工序预处理,按照多分支生成多条单独的工艺路径
+        /// 获取工作日
         /// </summary>
-        /// <param name="proc">当前工序</param>
-        /// <param name="processes">工艺关联工序list</param>
-        /// <param name="packages">生产件数</param>
+        /// <param name="weekDay">当前周几</param>
+        /// <param name="startTime">开始时间:年-月-日</param>
+        /// <param name="curCalendars">当前产线的工作日历</param>
         /// <returns></returns>
-        private List<TechProcDto> TechProcPretreatment(List<mo_mes_tech_process> processes,int packages)
-        { 
-            //工艺路径预处理dto
-            List<TechProcDto> techProcDtos = new List<TechProcDto>();
-            TechProcDto dto;
-            //获取下一步工序id
-            List<long> nextProcIds = processes.Where(p=>p.nextprocid != null).Select(p => p.nextprocid.GetValueOrDefault()).ToList();
-            //获取起点工序
-            var startProcs = processes.Where(p => !nextProcIds.Contains(p.proc_id)).ToList();
-            //递归处理工序返回值
-            List<mo_mes_tech_process> rtnList;
-            for (int i = 0; i < startProcs.Count; i++)
-            {
-                dto = new TechProcDto();
-                rtnList = new List<mo_mes_tech_process>();
-                GetNextProc(startProcs[i], processes, rtnList);
-                dto.serialno = i + 1;
-                dto.processes = rtnList;
-                //dto.details = CalcTakeTimeByLq(rtnList, packages);//通过Lq计算
-                dto.details = CalcTakeTimeByLqt(rtnList, packages);//通过Lqt计算
-                dto.sumTimes = dto.details.Sum(p=>p.wait_time);
-                techProcDtos.Add(dto);
-            }
-            return techProcDtos;
-        }
-
-        /// <summary>
-        /// 递归:根据起始工序,获取后续工序
-        /// </summary>
-        /// <param name="proc"></param>
-        /// <param name="processes"></param>
-        /// <param name="rtnList"></param>
-        private void GetNextProc(mo_mes_tech_process proc, List<mo_mes_tech_process> processes, List<mo_mes_tech_process> rtnList)
+        public DateTime GetNextWorkDay(DateTime startTime, List<ShopCalendarWorkCtr> curCalendars)
         {
-            rtnList.Add(proc);
-            //下一工序id为null,终止
-            if (proc?.nextprocid == null)
+            DateTime rtnData = startTime;
+            int weekDay = (int)startTime.DayOfWeek;
+            var calendar = curCalendars.FirstOrDefault(p => p.WeekDay == weekDay);
+            //判断当天是否是工作日
+            if (weekDay == 0 || weekDay == 6)//周六,周日
             {
-                return;
+                if (!holidays.Exists(p => p.Dated.GetValueOrDefault().Date == startTime && p.Ufld1 == "调班"))//今天是周末
+                {
+                    //递归继续找下一个工作日
+                    rtnData = GetNextWorkDay(startTime.AddDays(1), curCalendars);
+                    return rtnData;
+                }
+                return rtnData;
             }
-            //获取下一个工序
-            var nextProc = processes.FirstOrDefault(p=>p.proc_id == proc.nextprocid);
-            if (nextProc == null) 
+            //今天不是周六周日,需要判断是不是节假日
+            if (holidays.Exists(p => p.Dated.GetValueOrDefault().Date == startTime && p.Ufld1 == "休假"))//是节假日
             {
-                return;
+                //递归继续找下一个工作日
+                rtnData = GetNextWorkDay(startTime.AddDays(1), curCalendars);
+                return rtnData;
             }
-            GetNextProc(nextProc, processes, rtnList);
+            return rtnData;
         }
 
         /// <summary>
-        /// 通过Lq计算工艺耗时
+        /// 计算当天的产能
         /// </summary>
-        /// <param name="Processes"></param>
-        /// <param name="packages"></param>
+        /// <param name="startTime"></param>
+        /// <param name="prodLine"></param>
+        /// <param name="curCalendars"></param>
+        /// <param name="curQualityLines"></param>
         /// <returns></returns>
-        private List<StartTimeDto> CalcTakeTimeByLq(List<mo_mes_tech_process> Processes, int packages)
+        public decimal CalcCapacity(DateTime startTime,ProdLineDetail prodLine, List<ShopCalendarWorkCtr> curCalendars, List<QualityLineWorkDetail> curQualityLines)
         {
-            //工序需要等待时间记录
-            List<StartTimeDto> starts = new List<StartTimeDto>();
-            StartTimeDto dto;
-            foreach (var chd in Processes)
-            {
-                dto = new StartTimeDto();
-                if (chd.nextprocid == null)//最后一个工序
-                {
-                    //计算最后一个工序耗时
-                    dto = CalcProcTakeTimeByLq(chd, packages, packages);
-                }
-                else
-                {
-                    dto = CalcProcTakeTimeByLq(chd, chd.lq.GetValueOrDefault(), packages);
-                }
-                //添加记录
-                starts.Add(dto);
-            }
-            return starts;
+            decimal sumQty = 0m;
+            //获取休息时长(分钟)
+            decimal sumResrt = curQualityLines.Sum(p => p.RestTime);
+            //获取当天的工作时长(分钟)
+            decimal workTime = curCalendars.First(p => p.WeekDay == (int)startTime.DayOfWeek).ShiftsHours1 * 60;
+            //计算产能
+            sumQty = Math.Floor((workTime - sumResrt) / 60 * prodLine.Rate);
+            return sumQty;
         }
 
         /// <summary>
-        /// 通过Lq计算当前工序前置准备时间
+        /// 计算订单行的建议交期(产能/物料)
         /// </summary>
-        /// <param name="proc"></param>
-        /// <param name="quantity">LeadQuantity to Start Next</param>
-        /// <param name="packages">件数</param>
+        /// <param name="sentrys"></param>
+        /// <param name="kittingTimes"></param>
         /// <returns></returns>
-        private StartTimeDto CalcProcTakeTimeByLq(mo_mes_tech_process proc, decimal quantity, int packages)
+        public List<crm_seorderentry> CalcSuggestTime(List<crm_seorderentry> sentrys, List<KittingTimeDto> kittingTimes)
         {
-            //记录当前工序耗时
-            StartTimeDto dto = new StartTimeDto();
-            //添加耗时记录
-            dto.tech_id = proc.tech_id;
-            dto.proc_id = proc.proc_id;
-            dto.nextproc_id = proc.nextprocid;
-            if (proc.wctype == 1)//人工型:数量/uph(一小时生产数量)*60(小时转换为分钟)/wsinuse(工位数)
+            ProdExamineParamDto param;
+            foreach (var item in sentrys)
             {
-                if ( proc.uph.GetValueOrDefault() == 0 || proc.wsinuse.GetValueOrDefault() == 0)
+                var dto = kittingTimes.FirstOrDefault(p=>p.sentry_id == item.Id);
+                if (dto == null)
                 {
-                    throw new NotImplementedException("当前工序uph或wsinuse参数配置错误,请调整!");
+                    continue;
                 }
-                dto.wait_time = quantity / proc.uph.GetValueOrDefault() * 60 / proc.wsinuse.GetValueOrDefault();
-                dto.take_time = packages / proc.uph.GetValueOrDefault() * 60 / proc.wsinuse.GetValueOrDefault();
-            }
-            else if (proc.wctype == 2)//流水线型:数量*ct(生产一件所需时间)/wsinuse(工位数)
-            {
-                if (proc.ct.GetValueOrDefault() == 0 || proc.wsinuse.GetValueOrDefault() == 0)
+                if (dto.LackQty == 0)//当前订单行库存足够
                 {
-                    throw new NotImplementedException("当前工序ct或wsinuse参数配置错误,请调整!");
+                    item.sys_material_date = dto.kitting_time;
+                    item.sys_capacity_date = dto.kitting_time;
                 }
-                dto.wait_time = quantity * proc.ct.GetValueOrDefault() / proc.wsinuse.GetValueOrDefault();
-                dto.take_time = packages * proc.ct.GetValueOrDefault() / proc.wsinuse.GetValueOrDefault();
-            }
-            else if (proc.wctype == 3)//设备型:向上取整(数量/一次可加工数量/wsinuse(工位数))*ct(老化一次所需时间)
-            {
-                if (proc.upe.GetValueOrDefault() == 0 || proc.wsinuse.GetValueOrDefault() == 0|| proc.ct.GetValueOrDefault() == 0)
+                //计算系统建议交期(物料)
+                param = new ProdExamineParamDto
                 {
-                    throw new NotImplementedException("当前工序upe或ct或wsinuse参数配置错误,请调整!");
-                }
-                dto.wait_time = Math.Ceiling(quantity / proc.upe.GetValueOrDefault() / proc.wsinuse.GetValueOrDefault()) * proc.ct.GetValueOrDefault();
-                dto.take_time = Math.Ceiling(packages / proc.upe.GetValueOrDefault() / proc.wsinuse.GetValueOrDefault()) * proc.ct.GetValueOrDefault();
-            }
-            return dto;
-        }
-
-        /// <summary>
-        /// 通过Lqt计算工艺耗时
-        /// </summary>
-        /// <param name="Processes"></param>
-        /// <param name="packages"></param>
-        /// <returns></returns>
-        private List<StartTimeDto> CalcTakeTimeByLqt(List<mo_mes_tech_process> Processes, int packages)
-        {
-            //工序需要等待时间记录
-            List<StartTimeDto> starts = new List<StartTimeDto>();
-            StartTimeDto dto;
-            foreach (var chd in Processes)
-            {
-                dto = new StartTimeDto();
-                //添加耗时记录
-                dto.tech_id = chd.tech_id;
-                dto.proc_id = chd.proc_id;
-                dto.nextproc_id = chd.nextprocid;
-
-                //计算当前工序生产耗时
-                dto.take_time = CalcProcTakeTime(chd, packages);
-                if (chd.nextprocid == null)//最后一个工序
+                    ItemNum = item.item_number,
+                    QtyOrd = dto.LackQty,
+                    PlanStart = dto.kitting_time.Date.AddDays(1)
+                };
+                item.sys_material_date = ProductiveExamine(param);
+                item.sys_capacity_date = item.sys_material_date;
+                //计算系统交期(产能)
+                //获取主线最后一道工序
+                var routings = routingOps.Where(p => p.RoutingCode == item.item_number && p.ParentOp == 0).OrderBy(p=>p.Op).ToList();
+                if (routings.Count() == 0)
                 {
-                    dto.wait_time = dto.take_time;
+                    continue;
                 }
-                else
+                //获取产线
+                var prodLine = prodLines.FirstOrDefault(p=>p.Part == item.item_number && p.Op == routings.Last().Op);
+                if (prodLine == null)
                 {
-                    dto.wait_time = chd.lqt.Value;
+                    continue;
                 }
-                //添加记录
-                starts.Add(dto);
-            }
-            return starts;
-        }
-
-        /// <summary>
-        /// 计算当前工序生产时间
-        /// </summary>
-        /// <param name="proc"></param>
-        /// <param name="packages">件数</param>
-        /// <returns></returns>
-        private decimal CalcProcTakeTime(mo_mes_tech_process proc, int packages)
-        {
-            //当前工序生产时间
-            decimal takeTiem = 0.00m;
-
-            if (proc.wctype == 1)//人工型:数量/uph(一小时生产数量)*60(小时转换为分钟)/wsinuse(工位数)
-            {
-                if (proc.uph.GetValueOrDefault() == 0 || proc.wsinuse.GetValueOrDefault() == 0)
+                //获取产线空闲开始时间
+                var schedules= periodSequences.Where(p => p.ItemNum == item.item_number && p.Op == prodLine.Op && p.Line == prodLine.Line).OrderByDescending(p => p.PlanDate).ToList();
+                if (schedules.Count() == 0)
                 {
-                    throw new NotImplementedException("当前工序uph或wsinuse参数配置错误,请调整!");
+                    continue;
                 }
-                takeTiem = packages / proc.uph.GetValueOrDefault() * 60 / proc.wsinuse.GetValueOrDefault();
-            }
-            else if (proc.wctype == 2)//流水线型:数量*ct(生产一件所需时间)/wsinuse(工位数)
-            {
-                if (proc.ct.GetValueOrDefault() == 0 || proc.wsinuse.GetValueOrDefault() == 0)
-                {
-                    throw new NotImplementedException("当前工序ct或wsinuse参数配置错误,请调整!");
-                }
-                takeTiem = packages * proc.ct.GetValueOrDefault() / proc.wsinuse.GetValueOrDefault();
-            }
-            else if (proc.wctype == 3)//设备型:向上取整(数量/一次可加工数量/wsinuse(工位数))*ct(老化一次所需时间)
-            {
-                if (proc.upe.GetValueOrDefault() == 0 || proc.wsinuse.GetValueOrDefault() == 0 || proc.ct.GetValueOrDefault() == 0)
+                //产线空闲开始时间
+                var lastTime = schedules.First().PlanDate.GetValueOrDefault().Date;
+                if (lastTime >= param.PlanStart)//如果产线空闲时间大于或者等于系统建议交期(物料)的开工时间
                 {
-                    throw new NotImplementedException("当前工序upe或ct或wsinuse参数配置错误,请调整!");
+                    //取下一天开始计算生产结束时间
+                    param.PlanStart = lastTime.AddDays(1);
+                    item.sys_capacity_date = ProductiveExamine(param);
                 }
-                takeTiem = Math.Ceiling(packages / proc.upe.GetValueOrDefault() / proc.wsinuse.GetValueOrDefault()) * proc.ct.GetValueOrDefault();
             }
-            return takeTiem;
+            return sentrys;
         }
     }
 }

+ 506 - 219
MicroServices/Business/Business.Application/ResourceExamineManagement/ResourceExamineAppService.cs

@@ -38,6 +38,8 @@ using Volo.Abp.Uow;
 using Spire.Pdf.Exporting.XPS.Schema;
 using Business.PriorityManagement;
 using Newtonsoft.Json.Linq;
+using Business.Dto;
+using NetTopologySuite.Simplify;
 
 namespace Business.ResourceExamineManagement
 {
@@ -220,14 +222,53 @@ namespace Business.ResourceExamineManagement
         /// </summary>
         private readonly ISqlRepository<RoutingOpDetail> _routingOpDetail;
 
+        /// <summary>
+        /// 生产线明细
+        /// </summary>
+        private readonly ISqlRepository<ProdLineDetail> _prodLineDetail;
+
+        /// <summary>
+        /// 排产记录表
+        /// </summary>
+        private readonly ISqlRepository<PeriodSequenceDet> _periodSequenceDet;
+
+        /// <summary>
+        /// 工作日历
+        /// </summary>
+        private readonly ISqlRepository<ShopCalendarWorkCtr> _shopCalendarWorkCtr;
+
+        /// <summary>
+        /// 休息时间段
+        /// </summary>
+        private readonly ISqlRepository<QualityLineWorkDetail> _qualityLineWorkDetail;
+
+        /// <summary>
+        /// 节假日
+        /// </summary>
+        private readonly ISqlRepository<HolidayMaster> _holidayMaster;
+
         /// <summary>
         /// 标准BOM表
         /// </summary>
         private readonly ISqlRepository<ProductStructureMaster> _productStructureMaster;
-        private readonly ISqlRepository<WorkOrdRouting> _workOrdRouting;
-        private readonly ISqlRepository<WorkOrdMaster> _workOrdMaster;
-        private readonly ISqlRepository<WorkOrdDetail> _workOrdDetail;
+
+        /// <summary>
+        /// 工单工序表
+        /// </summary>
+        private ISqlRepository<WorkOrdRouting> _workOrdRouting;
+
+        /// <summary>
+        /// 工单主表
+        /// </summary>
+        private ISqlRepository<WorkOrdMaster> _workOrdMaster;
+
+        /// <summary>
+        /// 工单物料明细
+        /// </summary>
+        private ISqlRepository<WorkOrdDetail> _workOrdDetail;
+
         private readonly ISqlRepository<rf_serialnumber> _rf_serialnumber;
+        private readonly ISqlRepository<LocationDetail> _locationDetail;
         /// <summary>
         /// 资源检查入参
         /// </summary>
@@ -263,17 +304,13 @@ namespace Business.ResourceExamineManagement
         private readonly BusinessDbContext _businessDbContext;
         private readonly ISqlRepository<TagMaster> _tagMasterRepository;
         /// <summary>
-        /// 生产周期明细
-        /// </summary>
-        private ISqlRepository<PeriodSequenceDet> _periodSequenceDet;
-        /// <summary>
         /// 生产线维护表
         /// </summary>
         private ISqlRepository<LineMaster> _lineMaster;
         private ISqlRepository<ItemMaster> _itemMaster;
         private ISqlRepository<NbrMaster> _nbrMaster;
         private ISqlRepository<NbrDetail> _nbrDetail;
-
+        private ISqlRepository<ItemPackMaster> _itemPackMaster;
         /// <summary>
         /// 生产排产
         /// </summary>
@@ -283,6 +320,41 @@ namespace Business.ResourceExamineManagement
         /// 优先级
         /// </summary>
         private readonly PriorityAppService _priorityAppService;
+
+        /// <summary>
+        /// 产能检查
+        /// </summary>
+        private readonly ProductExamineAppService _productExamineAppService;
+
+        /// <summary>
+        /// 生产线明细表
+        /// </summary>
+        public List<ProdLineDetail> prodLines = new List<ProdLineDetail>();
+
+        /// <summary>
+        /// 标准工艺路径表
+        /// </summary>
+        public List<RoutingOpDetail> routingOps = new List<RoutingOpDetail>();
+
+        /// <summary>
+        /// 排产记录表
+        /// </summary>
+        public List<PeriodSequenceDet> periodSequences = new List<PeriodSequenceDet>();
+
+        /// <summary>
+        /// 工作日历
+        /// </summary>
+        public List<ShopCalendarWorkCtr> calendarWorks = new List<ShopCalendarWorkCtr>();
+
+        /// <summary>
+        /// 休息时间段
+        /// </summary>
+        public List<QualityLineWorkDetail> qualityLineWorks = new List<QualityLineWorkDetail>();
+
+        /// <summary>
+        /// 节假日
+        /// </summary>
+        public List<HolidayMaster> holidays = new List<HolidayMaster>();
         #endregion
 
         #region 构造函数
@@ -366,7 +438,14 @@ namespace Business.ResourceExamineManagement
             ISqlRepository<NbrMaster> nbrMaster,
             ISqlRepository<NbrDetail> nbrDetail,
             PriorityAppService priorityAppService,
-            ISqlRepository<rf_serialnumber> rf_serialnumber
+            ISqlRepository<ProdLineDetail> prodLineDetail,
+            ISqlRepository<ShopCalendarWorkCtr> shopCalendarWorkCtr,
+            ISqlRepository<QualityLineWorkDetail> qualityLineWorkDetail,
+            ISqlRepository<HolidayMaster> holidayMaster,
+            ProductExamineAppService productExamineAppService,
+            ISqlRepository<rf_serialnumber> rf_serialnumber,
+            ISqlRepository<LocationDetail> locationDetail,
+            ISqlRepository<ItemPackMaster> itemPackMaster
             )
         {
             _mes_technique = mes_technique;
@@ -441,7 +520,14 @@ namespace Business.ResourceExamineManagement
             _nbrDetail = nbrDetail;
             _priorityAppService= priorityAppService;
             _rf_serialnumber = rf_serialnumber;
-    }
+            _prodLineDetail = prodLineDetail;
+            _shopCalendarWorkCtr = shopCalendarWorkCtr;
+            _qualityLineWorkDetail = qualityLineWorkDetail;
+            _holidayMaster = holidayMaster;
+            _productExamineAppService= productExamineAppService;
+            _locationDetail = locationDetail;
+            _itemPackMaster = itemPackMaster;
+        }
         #endregion
 
 
@@ -452,8 +538,23 @@ namespace Business.ResourceExamineManagement
         /// <param name="input"></param>
         /// <returns></returns>
         /// <exception cref="NotImplementedException"></exception>
-        public async Task<string> ReceiveResult(ResourceCheckInputDto input)
+        public async Task<string> ReceiveResult(string ids)
         {
+            if (string.IsNullOrEmpty(ids))
+            {
+                throw new NotImplementedException("请输入正确的订单号!");
+            }
+            Array alist = ids.Split(',');
+
+            ResourceCheckInputDto input = new ResourceCheckInputDto();
+            input.sorderId = new List<long>();
+            foreach (string longid in alist)
+            {
+                input.sorderId.Add(long.Parse(longid));
+            }
+            input.tenantId = 1000;
+            input.factoryId = 1001;
+
             //资源检查入参全局变量赋值
             param.tenantId = input.tenantId;
             param.factoryId = input.factoryId;
@@ -479,6 +580,9 @@ namespace Business.ResourceExamineManagement
             //获取订单行数据
             List<crm_seorderentry> sentrys = await _mysql_crm_seorderentry.GetListAsync(p => p.tenant_id == input.tenantId && p.factory_id == input.factoryId && input.sorderId.Contains(p.seorder_id.GetValueOrDefault()) && !p.IsDeleted);
 
+            //处理销售订单优先级
+            sorders = _priorityAppService.CalcOrderPriority(sorders, sentrys);
+            AsyncItemStockFromWMS(sentrys);
             //处理订单行优先级
             sentrys = _priorityAppService.CalcOrderEntryPriority(sorders, sentrys);
 
@@ -512,7 +616,8 @@ namespace Business.ResourceExamineManagement
                 AutoCreateBomBill(autoCreates);
                 pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result;
             }
-
+            //记录订单行的物料齐套时间
+            List<KittingTimeDto> kittingTimes = new List<KittingTimeDto>();
             DataInitialization(boms, bangid, icitemlist, stocklist, pretreatments);
             foreach (var sorder in sorders)
             {
@@ -569,8 +674,18 @@ namespace Business.ResourceExamineManagement
                     dtl.BomChildExamineList = getBomList;
                     //添加订单行开工信息
                     examines.Add(dtl);
+
+                    //记录订单行的建议交期
+                    KittingTimeDto dto = new KittingTimeDto();
+                    dto.sentry_id = item.Id;
+                    dto.ItemNum = item.item_number;
+                    dto.LackQty = getBomList.First(p => p.level == 1).lack_qty;
+                    dto.kitting_time = dtl.kitting_times;
+                    kittingTimes.Add(dto);
                 }
             }
+            //计算订单行的建议交期(产能/物料)
+            CalcSuggestDate(sentrys, kittingTimes);
 
             await _mysql_crm_seorderentry.UpdateManyAsync(sentrys);
 
@@ -582,9 +697,8 @@ namespace Business.ResourceExamineManagement
                 var mesorders = ObjectMapper.Map<List<mo_mes_morder>, List<mes_morder>>(_CalcBomViewAppService.mordersInsertList);
                 _businessDbContext.BulkInsert(mesorders);
                 rtn.mordersList = _CalcBomViewAppService.mordersInsertList;
-
-                //插入工单相关数据
-                CreateWorkOrdDates(_CalcBomViewAppService.mordersInsertList);
+                //同步工单
+                CreateWorkOrdDates(mesorders);
             }
             if (_CalcBomViewAppService.mooccupyAllInsertList.Any())
             {
@@ -656,8 +770,16 @@ namespace Business.ResourceExamineManagement
                 b_ex.GenerateNewId();// = help.NextId();
                 if (_CalcBomViewAppService.mordersInsertList.Any())
                 {
-                    b_ex.morder_id = _CalcBomViewAppService.mordersInsertList[0].mysql_id;
-                    b_ex.morder_no = _CalcBomViewAppService.mordersInsertList[0].morder_no;
+                    var moentry = _CalcBomViewAppService.moentriesInsertList.Where(s => s.soentry_id == b_ex.sentry_id).FirstOrDefault();
+                    if (moentry != null)
+                    {
+                        var sentryMo = _CalcBomViewAppService.mordersInsertList.Where(s => s.mysql_id == moentry.moentry_moid).FirstOrDefault();
+                        if (sentryMo != null)
+                        {
+                            b_ex.morder_id = sentryMo.mysql_id;
+                            b_ex.morder_no = sentryMo.morder_no;
+                        }
+                    }
                 }
                 b_ex.create_time = DateTime.Now;
                 b_ex.tenant_id = param.tenantId;
@@ -997,7 +1119,10 @@ namespace Business.ResourceExamineManagement
                     stock_leadtime = x.stock_leadtime,
                     production_leadtime = x.production_leadtime,
                     order_leadtime = x.order_leadtime,
-                    minorderqty = x.minorderqty
+                    minorderqty = x.minorderqty,
+                    put_integer=x.put_integer,
+                    minpackqty=x.minpackqty,
+                    ordissu_days=x.ordissu_days
                 }).AsQueryable<ICItemLeadTimeDto>().ToList();
         }
 
@@ -1089,13 +1214,14 @@ namespace Business.ResourceExamineManagement
         {
             List<mo_srm_po_main> polist = new List<mo_srm_po_main>();
             List<mo_srm_po_list> podetaillist = new List<mo_srm_po_list>();
+            var itemList = _ic_item.Find(a => a.tenant_id == input.tenantId && a.factory_id == input.factoryId).Result;
             //将PR按供应商和物料和日期(一周内)进行合并,生成PO
             //1.按照供应商、需求日期排序
             //2.判断是不是同一个供应商,不是的话就新建一个PO;是的话判断是不是同一周,不是的话就新建一个PO,是的话判断有没有相同物料,有的话合并物料数量价格,没有的话新建一条明细
             list = list.OrderBy(a => a.pr_purchaseid).ThenBy(b => b.pr_rarrive_date).ToList();
             long? supplierId = -1;
             DateTime supplierDate = DateTime.Now;
-            foreach (var item in list)
+            foreach (mo_srm_pr_main item in list)
             {
                 if (item.pr_purchaseid != supplierId)
                 {
@@ -1144,6 +1270,7 @@ namespace Business.ResourceExamineManagement
                     podetail.pr_purchase_id = po_Main.supplier_id;
                     podetail.pr_purchase_name = po_Main.supplier_name;
                     podetail.icitem_id = item.icitem_id;
+                    podetail.ItemNum = itemList.First(a => a.mysql_id == item.icitem_id).number;
                     podetail.icitem_name = item.icitem_name;
                     podetail.qty = item.pr_aqty;
                     podetail.netprice = item.pr_price;
@@ -1198,6 +1325,7 @@ namespace Business.ResourceExamineManagement
                             podetail.pr_purchase_id = pomain.supplier_id;
                             podetail.pr_purchase_name = pomain.supplier_name;
                             podetail.icitem_id = item.icitem_id;
+                            podetail.ItemNum = itemList.First(a => a.mysql_id == item.icitem_id).number;
                             podetail.icitem_name = item.icitem_name;
                             podetail.qty = item.pr_aqty;
                             podetail.netprice = item.pr_price;
@@ -1268,6 +1396,7 @@ namespace Business.ResourceExamineManagement
                         podetail.pr_purchase_id = po_Main.supplier_id;
                         podetail.pr_purchase_name = po_Main.supplier_name;
                         podetail.icitem_id = item.icitem_id;
+                        podetail.ItemNum = itemList.First(a => a.mysql_id == item.icitem_id).number;
                         podetail.icitem_name = item.icitem_name;
                         podetail.qty = item.pr_aqty;
                         podetail.netprice = item.pr_price;
@@ -1303,6 +1432,7 @@ namespace Business.ResourceExamineManagement
         {
             List<mo_srm_po_main> polist = new List<mo_srm_po_main>();
             List<mo_srm_po_list> podetaillist = new List<mo_srm_po_list>();
+            var itemList = _ic_item.Find(a => a.tenant_id == input.tenantId && a.factory_id == input.factoryId).Result;
             //将PR按供应商和物料和日期(一周内)进行合并,生成PO
             //1.按照供应商、需求日期排序
             //2.判断是不是同一个供应商,不是的话就新建一个PO;是的话判断是不是同一周,不是的话就新建一个PO,是的话判断有没有相同物料,有的话合并物料数量价格,没有的话新建一条明细
@@ -1358,6 +1488,7 @@ namespace Business.ResourceExamineManagement
                     podetail.pr_purchase_id = po_Main.supplier_id;
                     podetail.pr_purchase_name = po_Main.supplier_name;
                     podetail.icitem_id = item.icitem_id;
+                    podetail.ItemNum = itemList.First(a => a.mysql_id == item.icitem_id).number;
                     podetail.icitem_name = item.icitem_name;
                     podetail.qty = item.pr_aqty;
                     podetail.netprice = item.pr_price;
@@ -1412,6 +1543,7 @@ namespace Business.ResourceExamineManagement
                             podetail.pr_purchase_id = pomain.supplier_id;
                             podetail.pr_purchase_name = pomain.supplier_name;
                             podetail.icitem_id = item.icitem_id;
+                            podetail.ItemNum = itemList.First(a => a.mysql_id == item.icitem_id).number;
                             podetail.icitem_name = item.icitem_name;
                             podetail.qty = item.pr_aqty;
                             podetail.netprice = item.pr_price;
@@ -1482,6 +1614,7 @@ namespace Business.ResourceExamineManagement
                         podetail.pr_purchase_id = po_Main.supplier_id;
                         podetail.pr_purchase_name = po_Main.supplier_name;
                         podetail.icitem_id = item.icitem_id;
+                        podetail.ItemNum = itemList.First(a => a.mysql_id == item.icitem_id).number;
                         podetail.icitem_name = item.icitem_name;
                         podetail.qty = item.pr_aqty;
                         podetail.netprice = item.pr_price;
@@ -1838,29 +1971,23 @@ namespace Business.ResourceExamineManagement
         {
             List<long> itemIds = pretreatments.Select(p => p.item_id.GetValueOrDefault()).ToList();
             icitemlist.AddRange(_ic_item.GetManyByCondition(p => itemIds.Contains(p.mysql_id) && !p.IsDeleted).Result);
-            #region 1、数据准备
-            //1.1、获取工艺路径数据
-            List<mo_ic_bom> bomlist = _ic_bom.GetManyByCondition(p => itemIds.Contains(p.icitem_id) && p.use_status == 1 && p.tenant_id == param.tenantId && p.factory_id == param.factoryId && !p.IsDeleted).Result.ToList();
-            List<mo_mes_technique> techs = GetMesTechniques(bomlist);
-            if (techs.Count == 0)
-            {
-                //throw new NotImplementedException("请先配置工艺路径!");
-            }
 
-            //1.2、获取工艺路径关联工序数据
-            List<mo_mes_tech_process> tech_Processes = _mes_tech_process.GetManyByCondition(p => techs.Select(m => m.mysql_id).Contains(p.tech_id) && p.tenant_id == param.tenantId && p.factory_id == param.factoryId && !p.IsDeleted).Result;
-            if (tech_Processes.Count == 0)
-            {
-                //throw new NotImplementedException("请先配置工序!");
-            }
-
-            //1.3、获取当前工艺路径下的工序数据
-            List<long> procIds = tech_Processes.Select(m => m.proc_id).ToList();
-            List<mo_mes_process> process = _mes_process.GetManyByCondition(p => procIds.Contains(p.mysql_id) && p.tenant_id == param.tenantId && p.factory_id == param.factoryId && !p.IsDeleted).Result;
+            #region 1、数据准备
+            //1.1、获取产能检查相关数据
+            //产品物料编码
+            List<string> itemnums = pretreatments.Where(p => p.level == 1).Select(p => p.item_number).Distinct().ToList();
+            //产线明细
+            prodLines = _prodLineDetail.Select(p=> itemnums.Contains(p.Part)).ToList();
+            //标准工序
+            routingOps = _routingOpDetail.Select(p => itemnums.Contains(p.RoutingCode)).ToList();
+            List<string> lines = prodLines.Select(p=>p.Line).Distinct().ToList();
+            //工作日历
+            calendarWorks = _shopCalendarWorkCtr.Select(p=>lines.Contains(p.ProdLine)).ToList();
+            //休息日
+            qualityLineWorks = _qualityLineWorkDetail.Select(p => lines.Contains(p.ProdLine)).ToList();
+            //节假日
+            holidays = _holidayMaster.Select(p => p.Dated >= DateTime.Now.Date);
 
-            //1.3、获取工艺工序关联工位信息
-            List<long> techProcIds = tech_Processes.Select(m => m.mysql_id).ToList();
-            List<mo_mes_tech_proc_workshop> tech_Proc_Workshops = _mes_tech_proc_workshop.GetManyByCondition(p => techProcIds.Contains(p.tech_proc_id) && p.tenant_id == param.tenantId && p.factory_id == param.factoryId && !p.IsDeleted).Result;
             //主工单
             List<mo_mes_morder> mo_Mes_Morders = _mes_morder.GetManyByCondition(x => boms.Select(p => p.bom_number).Contains(x.bom_number) && (x.morder_state != MorderEnum.Accomplish_state || x.morder_state != MorderEnum.Close_state
           && x.morder_icitem_type != MorderEnum.XgwyMorder) && x.tenant_id == param.tenantId && x.bang_id == bangid).Result;
@@ -1888,11 +2015,14 @@ namespace Business.ResourceExamineManagement
             _CalcBomViewAppService.planList = planList;
             _CalcBomViewAppService.leadTimeList = leadTimeList;
             _CalcBomViewAppService.supplierList = supplierList;
-            //资源检查添加工艺路径数据
-            _CalcBomViewAppService.techs = techs;//工艺路径
-            _CalcBomViewAppService.tech_Processes = tech_Processes;//工艺关联工序
-            _CalcBomViewAppService.process = process;//工序
-            _CalcBomViewAppService.tech_Proc_Workshops = tech_Proc_Workshops;//工艺工序关联工位
+
+            //资源检查添加产线工序等数据
+            _CalcBomViewAppService.prodLines = prodLines;
+            _CalcBomViewAppService.routingOps = routingOps;
+            _CalcBomViewAppService.calendarWorks = calendarWorks;
+            _CalcBomViewAppService.qualityLineWorks = qualityLineWorks;
+            _CalcBomViewAppService.holidays = holidays;
+
             _CalcBomViewAppService.mordersList = mo_Mes_Morders;//工单
             _CalcBomViewAppService.moentriesList = mo_Mes_Moentry;//工单子表
             _CalcBomViewAppService.mooccupyAllList = mes_mooccupyList;//工单占用表
@@ -2017,17 +2147,301 @@ namespace Business.ResourceExamineManagement
             AutoCreateBomBill();
         }
 
+        public void AutoCreatePickBill(List<string> workOrds)
+        {
+            //获取生产周期数据
+            List<PeriodSequenceDet> dbPeriodSequences = _periodSequenceDet.Select(p => workOrds.Contains(p.WorkOrds) && p.Domain == "1001" && p.IsActive);
+            List<NbrMaster> nbrMasterList = new List<NbrMaster>();//需要生成领料单列表
+            List<NbrDetail> nbrDetailList = new List<NbrDetail>();//需要生成领料单明细列表
+            if (dbPeriodSequences.Any())
+            {
+                //按照工单领料,一个工单一个领料单,之前是按照排产日期和产线分别领料
+                foreach(var workord in workOrds)
+                {
+                    Dictionary<string, decimal> dictItemQty = new Dictionary<string, decimal>();
+                    List<string> lines = dbPeriodSequences.Where(a=>a.WorkOrds==workord).Select(a => a.Line).Distinct().ToList();
+                    List<LineMaster> lineMasters = _lineMaster.Select(p => lines.Contains(p.Line) && p.Domain == "1001" && p.IsActive);
+                    List<ProductStructureMaster> itemList = GetProductStructure(dbPeriodSequences.First(a => a.WorkOrds == workord).ItemNum);
+                    var childrenList = itemList.Select(a => a.ComponentItem).Distinct().ToList();
+                    List<ItemMaster> itemLocList = _itemMaster.Select(p => childrenList.Contains(p.ItemNum) && p.Domain == "1001" && p.IsActive).Distinct().ToList();
+                    List<ItemPackMaster> itemPackList = _itemPackMaster.Select(p => childrenList.Contains(p.ItemNum) && p.Domain == "1001" && p.IsActive).Distinct().ToList();
+                    var Nbr = GetMaxSerialNumber(417416915624005);
+                    //根据某一产线汇总即该工单的总数
+                    decimal QtyOrdSum = dbPeriodSequences.Where(a => a.WorkOrds == workord && a.Line == lines[0]).Sum(a => a.OrdQty.GetValueOrDefault());
+                    nbrMasterList.Add(new NbrMaster
+                    {
+                        Domain = "1001",
+                        Type = "SM",
+                        Nbr = Nbr,
+                        Remark = "排产自动领料",
+                        Date = dbPeriodSequences.Where(a => a.WorkOrds == workord).Min(a=>a.PlanDate),
+                        //ProdLine = item.Line,
+                        Status = "",
+                        WorkOrd = workord,
+                        QtyOrd = QtyOrdSum,
+                        IsActive = true,
+                        IsChanged = true,
+                        Name = "1001",
+                        Department = "101",
+                        CreateTime = DateTime.Now,
+                        UpdateTime = DateTime.Now,
+                        CreateUser = "1001",
+                        UpdateUser = "1001"
+                    });
+                    int i = 1;
+                    itemList?.ForEach(a =>
+                    {
+                        var find = itemLocList?.Find(c => c.ItemNum == a.ComponentItem);
+                        string LocationTo = "";
+                        if (find!=null)
+                        {
+                            LocationTo=find.Location;
+                        }
+                        //相同物料汇总
+                        var itemComponent = nbrDetailList.Find(b => b.Nbr == Nbr && b.ItemNum == a.ComponentItem);
+                        if (itemComponent==null)
+                        {
+                            nbrDetailList.Add(new NbrDetail
+                            {
+                                Domain = "1001",
+                                Type = "SM",
+                                Nbr = Nbr,
+                                ItemNum = a.ComponentItem,
+                                QtyFrom = 0,
+                                QtyTo = 0,
+                                LocationFrom = LocationTo,
+                                LocationTo = "",
+                                WorkOrd = workord,
+                                QtyOrd =QtyOrdSum * a.Qty,
+                                CurrQtyOpened = QtyOrdSum * a.Qty ,
+                                Line = i,
+                                IsActive = true,
+                                CreateTime = DateTime.Now,
+                                UpdateTime = DateTime.Now,
+                                CreateUser = "1001",
+                                UpdateUser = "1001",
+                                UM = a.UM
+                            });
+                            i++;
+                        }
+                        else
+                        {
+                            nbrDetailList.First( b=> b.Nbr == Nbr && b.ItemNum == a.ComponentItem).QtyOrd= itemComponent.QtyOrd+ QtyOrdSum * a.Qty;
+                            nbrDetailList.First(b => b.Nbr == Nbr && b.ItemNum == a.ComponentItem).CurrQtyOpened = itemComponent.CurrQtyOpened + QtyOrdSum * a.Qty;
+                        }
+                    });
+                    nbrDetailList.ForEach(a => 
+                    {
+                        if(a.Nbr==Nbr)
+                        {
+                            var find = itemLocList?.Find(c => c.ItemNum == a.ItemNum);
+                            var packfind = itemPackList?.Find(c => c.ItemNum == a.ItemNum);
+                            if (find != null && !find.TraceDetail && packfind != null && packfind.PackingQty > 0)
+                            {
+                                a.CurrQtyOpened = Math.Ceiling(a.CurrQtyOpened.GetValueOrDefault() / packfind.PackingQty.GetValueOrDefault()) * packfind.PackingQty;
+                                dictItemQty.Add(a.ItemNum, QtyOrdSum * itemList.First(b => b.ComponentItem == a.ItemNum).Qty);
+                            }
+                            else
+                            {
+                                dictItemQty.Add(a.ItemNum, QtyOrdSum * itemList.First(b => b.ComponentItem == a.ItemNum).Qty);
+                            }
+                        }
+                    });
+                    List<string> itemKeys = dictItemQty.Keys.ToList();
+                    //var items = _mysql_ic_item.GetListAsync(a => itemKeys.Contains(a.number) && a.factory_id == 1001 && a.tenant_id == 1000).Result;
+                    //var itemIds = items.Select(b => b.Id).ToList();
+                    //var leadTimes = GetLeadTime(itemIds, 1000, 1001).Max(a=>a.ordissu_days.GetValueOrDefault());
+                    decimal leadTimes=itemLocList.Select(a => a.MFGMTTR).Max();
+                    //没有维护备料提前期,默认取7天
+                    if (leadTimes > 0)
+                    {
+                        nbrMasterList.First(a => a.Nbr == Nbr).Date = dbPeriodSequences.Where(a => a.WorkOrds == workord).Min(a => a.PlanDate).GetValueOrDefault().AddDays(-1 * Convert.ToDouble(leadTimes));
+                    }
+                    else
+                    {
+                        nbrMasterList.First(a => a.Nbr == Nbr).Date = dbPeriodSequences.Where(a => a.WorkOrds == workord).Min(a => a.PlanDate).GetValueOrDefault().AddDays(-7);
+                    }
+                    //TODO:
+                    //因为我们并没有模拟发料的过程,在自动生成领料单的时候就要扣减库存,实际业务不能这么做。
+                    //在有上料和追溯的系统,可以在扫码上料或报工时(从线边仓)扣减。或者在实际发料出库时扣减。
+                    var locStock=_locationDetail.Select(a => itemKeys.Contains(a.ItemNum) && a.IsActive && a.Domain == "1001");
+                    locStock?.ForEach(a =>
+                    {
+                        nbrDetailList.ForEach(b =>
+                        {
+                            if(a.ItemNum==b.ItemNum && a.Location==b.LocationFrom && a.QtyOnHand - dictItemQty[a.ItemNum] > 0)
+                            {
+                                a.QtyOnHand = a.QtyOnHand - dictItemQty[a.ItemNum];
+                            }
+                        });
+                    });
+                    _locationDetail.Update(locStock);
+                }
+                _nbrMaster.Insert(nbrMasterList);
+                //快开平台用自增列RecId关联,所以需要插入后再查给明细表赋相应的值
+                List<string> nbrs = nbrMasterList.Select(a => a.Nbr).ToList();
+                var nbrList = _nbrMaster.Select(a => a.Domain == "1001" && a.Type == "SM" && nbrs.Contains(a.Nbr));
+                nbrDetailList.ForEach(c =>
+                {
+                    c.NbrRecID = nbrList.Where(a => a.Nbr == c.Nbr).First().RecID;
+                });
+                _nbrDetail.Insert(nbrDetailList);
+            }
+        }
+
+        public void AsyncItemStockFromWMS(List<crm_seorderentry> sentrys)
+        {
+            //产品编码
+            var itemList = sentrys.Select(a => a.item_number).Distinct().ToList();
+            List<string> itemChildList = new List<string>();
+            itemList.ForEach(a =>
+            {
+                itemChildList.AddRange(GetChildItemNumber(a, new List<string>()));
+            });
+            var stockList = _locationDetail.Select(a => a.Domain == "1001" && a.IsActive && itemChildList.Distinct().Contains(a.ItemNum));
+            var groupList = stockList.
+                GroupBy(m => new { m.ItemNum }).
+                Select(a => new { ItemNum = a.Key.ItemNum, Qty = a.Sum(c => c.QtyOnHand) }).ToList();
+            var itemNums = groupList.Select(b => b.ItemNum).ToList();//需要处理的dop物料编码集合
+            var items = _mysql_ic_item.GetListAsync(a => itemNums.Contains(a.number) && a.factory_id == 1001 && a.tenant_id == 1000).Result;
+            var itemIds = items.Select(b => b.Id).ToList();//需要处理的dop物料id集合
+            List<ic_item_stock> mysqlStock = _mysql_ic_item_stock.GetListAsync(a => itemIds.Contains(a.Id) && a.factory_id == 1001 && a.tenant_id == 1000).Result;
+            List<ic_item_stock> needAddList = new List<ic_item_stock>();
+
+            foreach(var stockWMS in groupList)
+            {
+                foreach (var num in items)
+                {
+                    if (stockWMS.ItemNum==num.number)
+                    {
+                        var item = mysqlStock.Find(a => a.Id == num.Id);
+                        if(item!=null)
+                        {
+                            item.sqty = groupList.First(a => a.ItemNum == num.number).Qty;
+                        }else
+                        {
+                            ic_item_stock stock= new ic_item_stock();
+                            stock.GenerateNewId();
+                            stock.factory_id = 1001;
+                            stock.tenant_id = 1000;
+                            stock.icitem_id = num.Id;
+                            stock.icitem_name = num.name;
+                            stock.sqty= groupList.First(a => a.ItemNum == num.number).Qty;
+                        }
+                        break;
+                    }
+                };
+            }
+            if(needAddList.Count>0)
+            {
+                _businessDbContext.BulkInsert(needAddList);
+            }
+            _businessDbContext.BulkUpdate(mysqlStock);
+        }
+        //循环获取子级物料编码,包括产品本身,有重复的结果去重即可
+        public List<string> GetChildItemNumber(string itemNum,List<string> list)
+        {
+            list.Add(itemNum);
+            var productStructures = _productStructureMaster.Select(p =>p.ParentItem== itemNum && p.Domain == "1001" && p.IsActive);
+            list.AddRange(productStructures.Select(a=>a.ComponentItem));
+            foreach (var item in productStructures)
+            {
+                if(item.StructureType.ToUpper()=="X")
+                {
+                    GetChildItemNumber(item.ComponentItem, list);
+                }
+            }
+            return list;
+        }
+
+        /// <summary>
+        /// 得到一个流水号的最大流水号
+        /// </summary>
+        /// <param name="id">流水号id</param>
+        /// <param name="formData">json数据,可以用json中的某个字段值作为通配符字替换流水号格式。</param>
+        /// <returns></returns>
+        public string GetMaxSerialNumber(long id, JObject? formData = null)
+        {
+            var modelList = _rf_serialnumber.Select(s => s.Id == id);
+            if (modelList == null && modelList.Count < 1)
+            {
+                return string.Empty;
+            }
+            var model = modelList[0];
+            int max = model.CurrentNumber + 1;
+            var date = DateTime.Now;
+            var lastDate = model.LastTime;
+            switch (model.NumberType)
+            {
+                case 1: //年流水
+                    if (date.Year > lastDate.Year)
+                    {
+                        max = 1;
+                    }
+                    break;
+                case 2: //月流水
+                    if (date.Year > lastDate.Year || date.Month > lastDate.Month)
+                    {
+                        max = 1;
+                    }
+                    break;
+                case 3: //日流水
+                    if (date.Year > lastDate.Year || date.Month > lastDate.Month || date.Day > lastDate.Day)
+                    {
+                        max = 1;
+                    }
+                    break;
+            }
+            string number = max.ToString().PadLeft(model.NumberSize, '0');
+            string serialNumber = string.IsNullOrWhiteSpace(model.Format) ? number
+                : model.Format.ContainsIgnoreCase("{number}")
+                ? model.Format.ReplaceIgnoreCase("{number}", number)
+                : model.Format + number;
+            //更新当前编号和最后时间
+            model.LastTime = date;
+            model.CurrentNumber = max;
+            _rf_serialnumber.Update(model);
+            return Wildcard.Replace(serialNumber, formData);
+        }
+
+        /// <summary>
+        /// 生产排产
+        /// </summary>
+        /// <param name="workOrd"></param>
+        /// <returns></returns>
+        /// <exception cref="NotImplementedException"></exception>
+        public async Task<string> ProductionSchedule(string workOrd)
+        {
+            List<string> workOrds = workOrd.Split(",").ToList();
+            if (workOrds.Count() == 0)
+            {
+                return "";
+            }
+            //获取工单数据
+            var workOrdMasters = _workOrdMaster.Select(p => workOrds.Contains(p.WorkOrd));
+            //获取已排产的工单
+            List<string> dbWorkOrds = _periodSequenceDet.Select(p => workOrds.Contains(p.WorkOrds)).Select(p => p.WorkOrds).Distinct().ToList();
+            //过滤掉已排产的工单
+            workOrdMasters = workOrdMasters.Where(p => !dbWorkOrds.Contains(p.WorkOrd)).ToList();
+            if (workOrdMasters.Count() == 0)
+            {
+                return JsonConvert.SerializeObject("ok");
+            }
+            //排产
+            await _productionScheduleAppService.DoProductShcedule(workOrdMasters);
+            AutoCreatePickBill(workOrdMasters.Select(p => p.WorkOrd).ToList());
+            return JsonConvert.SerializeObject("ok");
+        }
+
         /// <summary>
         /// 同步工单等相关数据
         /// </summary>
         /// <param name="morders"></param>
-        [UnitOfWork]
-        public void CreateWorkOrdDates(List<mo_mes_morder> morders)
+        public void CreateWorkOrdDates(List<mes_morder> morders)
         {
             //获取工艺路线数据:product_code=物料编码
             List<RoutingOpDetail> allRoutings = _routingOpDetail.Select(p => morders.Select(m => m.product_code).Contains(p.RoutingCode));
-            //获取标准BOM数据
-            List<ProductStructureMaster> productStructures = GetProductStructure(morders.Select(p => p.product_code).ToList());
+            
             //工单主表
             List<WorkOrdMaster> workOrds = new List<WorkOrdMaster>();
             WorkOrdMaster workOrd;
@@ -2043,19 +2457,18 @@ namespace Business.ResourceExamineManagement
                 workOrd = new WorkOrdMaster();
                 workOrd.Domain = "1001";
                 workOrd.OrdDate = item.moentry_sys_stime;
-                workOrd.ReleaseDate =Convert.ToDateTime(item.moentry_sys_stime.GetValueOrDefault().ToString("u"));
+                workOrd.ReleaseDate = Convert.ToDateTime(item.moentry_sys_stime.GetValueOrDefault().ToString("u"));
                 workOrd.WorkOrd = item.morder_no;
                 workOrd.ItemNum = item.product_code;//物料编码
                 workOrd.QtyOrded = item.need_number.GetValueOrDefault();
                 workOrd.RoutingCode = item.product_code;
                 workOrd.Period = 1;
                 workOrd.Priority = item.urgent;
-                workOrd.Status = "";
+                workOrd.Status = " ";
                 workOrd.IsActive = true;
-                workOrd.ProdLine = "组装线";
                 workOrd.IsConfirm = true;
                 workOrds.Add(workOrd);
-
+                
                 //添加工单工艺路线数据
                 var curRoutings = allRoutings.Where(p => p.RoutingCode == item.product_code).ToList();
                 foreach (var dtl in curRoutings)
@@ -2076,8 +2489,7 @@ namespace Business.ResourceExamineManagement
                     workOrdRoutings.Add(woRouting);
                 }
 
-                //添加工单物料数据
-                var curStructures = productStructures.Where(p => p.ParentItem == item.product_code).ToList();
+                List<ProductStructureMaster> curStructures = GetProductStructure(item.product_code);
                 foreach (var structure in curStructures)
                 {
                     //添加工单的物料信息
@@ -2094,42 +2506,33 @@ namespace Business.ResourceExamineManagement
                     workOrdDetails.Add(woDetail);
                 }
             }
-
-            //await _businessDbContext.BulkInsertAsync(workOrds);
-            //await _businessDbContext.BulkInsertAsync(workOrdRoutings);
-            //await _businessDbContext.BulkInsertAsync(workOrdDetails);
-             _workOrdMaster.Insert(workOrds);
-             _workOrdRouting.Insert(workOrdRoutings);
-             _workOrdDetail.Insert(workOrdDetails);
-
-            //排产
-             _productionScheduleAppService.DoProductShcedule(workOrds);
-            AutoCreatePickBill(workOrds.Select(a => a.WorkOrd).ToList());
+            _workOrdMaster.Insert(workOrds);
+            _workOrdRouting.Insert(workOrdRoutings);
+            _workOrdDetail.Insert(workOrdDetails);
         }
 
         /// <summary>
         /// 获取标准Bom数据--TODO:存在循环查询数据库问题,后续调整
         /// </summary>
-        /// <param name="itenNums">产品物料编码</param>
+        /// <param name="itenNum">产品物料编码</param>
         /// <returns></returns>
-        public List<ProductStructureMaster> GetProductStructure(List<string> itenNums)
+        public List<ProductStructureMaster> GetProductStructure(string itenNum)
         {
             List<ProductStructureMaster> rtnStructures = new List<ProductStructureMaster>();
             //根据itemNum获取bom数据
-            var productStructures = _productStructureMaster.Select(p => itenNums.Contains(p.ParentItem) && p.Domain == "1001" && p.IsActive);
+            var productStructures = _productStructureMaster.Select(p => itenNum == p.ParentItem && p.Domain == "1001" && p.IsActive);
             //添加非虚拟件
             rtnStructures.AddRange(productStructures.Where(p => p.StructureType.ToUpper() != "X").ToList());
-            foreach (var item in itenNums)
+
+            //获取当前产品的虚拟件
+            var curPhantoms = productStructures.Where(p => p.StructureType.ToUpper() == "X").ToList();
+            if (curPhantoms.Count() == 0)
             {
-                //获取当前产品的虚拟件
-                var curPhantoms = productStructures.Where(p => p.ParentItem == item && p.StructureType.ToUpper() == "X").ToList();
-                if (curPhantoms.Count() == 0)
-                {
-                    continue;
-                }
-                //递归获取所有虚拟件对应的子物料
-                RecursionProductStructure(item, curPhantoms, rtnStructures);
+                return rtnStructures;
             }
+            //递归获取所有虚拟件对应的子物料
+            RecursionProductStructure(itenNum, curPhantoms, rtnStructures);
+            
             return rtnStructures;
         }
 
@@ -2142,18 +2545,16 @@ namespace Business.ResourceExamineManagement
         public void RecursionProductStructure(string parentItem, List<ProductStructureMaster> structures, List<ProductStructureMaster> rtnStructures)
         {
             //获取虚拟件的子物料
-            var chdStructures = _productStructureMaster.Select(p => structures.Select(m => m.ComponentItem).Contains(p.ParentItem) && p.Domain == "1001" && p.IsActive);
+            List<ProductStructureMaster> chdStructures = _productStructureMaster.Select(p => structures.Select(m => m.ComponentItem).Contains(p.ParentItem) && p.Domain == "1001" && p.IsActive);
             //非虚拟件
             var notPhantoms = chdStructures.Where(p => p.StructureType.ToUpper() != "X").ToList();
             //存在非虚拟件
-            if (notPhantoms.Count() > 0)
+            foreach (var item in notPhantoms)
             {
-                notPhantoms.ForEach(p =>
-                {
-                    p.ParentItem = parentItem;
-                });
-                rtnStructures.AddRange(notPhantoms);
+                item.ParentItem = parentItem;
             }
+            rtnStructures.AddRange(notPhantoms);
+
             //虚拟件
             var phantoms = chdStructures.Where(p => p.StructureType.ToUpper() == "X").ToList();
             if (phantoms.Count() > 0)
@@ -2163,145 +2564,31 @@ namespace Business.ResourceExamineManagement
             }
         }
 
-
-        public void AutoCreatePickBill(List<string> workOrds)
-        {
-            //获取生产周期数据
-            List<PeriodSequenceDet> dbPeriodSequences = _periodSequenceDet.Select(p => workOrds.Contains(p.WorkOrds) && p.Domain == "1001" && p.IsActive);
-            List<LineMaster> lineMasters = new List<LineMaster>();
-            List<string> lines = new List<string>();//产线列表,
-            List<NbrMaster> nbrMasterList = new List<NbrMaster>();//需要生成领料单列表
-            List<NbrDetail> nbrDetailList = new List<NbrDetail>();//需要生成领料单明细列表
-            Dictionary<string, decimal> dictItemQty = new Dictionary<string, decimal>();
-            if (dbPeriodSequences.Any())
-            {
-                lines = dbPeriodSequences.Select(a => a.Line).Distinct().ToList();
-                lineMasters = _lineMaster.Select(p => lines.Contains(p.Line) && p.Domain == "1001" && p.IsActive);
-                List<ProductStructureMaster>  itemList=GetProductStructure(dbPeriodSequences.Select(a=>a.ItemNum).Distinct().ToList());
-                var childrenList= itemList.Select(a=>a.ComponentItem).Distinct().ToList();
-                List<ItemMaster> itemLocList = _itemMaster.Select(p => childrenList.Contains(p.ItemNum) && p.Domain == "1001" && p.IsActive).Distinct().ToList();
-                foreach (var item in dbPeriodSequences)
-                {
-                    var Nbr = GetMaxSerialNumber(417416915624005);
-                    nbrMasterList.Add(new NbrMaster
-                    {
-                        Domain = "1001",
-                        Type = "SM",
-                        Nbr = Nbr,
-                        Remark = "",
-                        Date = item.PlanDate,
-                        ProdLine = item.Line,
-                        Status = "",
-                        WorkOrd = item.WorkOrds,
-                        QtyOrd = item.OrdQty.HasValue ? item.OrdQty.Value : 0,
-                        IsActive = true,
-                        IsChanged = false
-                    });
-                    int i = 1;
-                    itemList.Where(a => a.ParentItem == item.ItemNum).ToList()?.ForEach(a =>
-                    {
-                        string LocationTo = "";
-                        if (itemLocList.Where(c => c.ItemNum == a.ComponentItem).ToList().Any())
-                        {
-                            LocationTo = itemLocList?.Where(c => c.ItemNum == a.ComponentItem).First().Location;
-                        }
-                        nbrDetailList.Add(new NbrDetail
-                        {
-                            Domain = "1001",
-                            Type = "SM",
-                            Nbr = Nbr,
-                            ItemNum = a.ComponentItem,
-                            QtyFrom = 0,
-                            QtyTo = 0,
-                            LocationFrom = LocationTo,
-                            LocationTo = "",
-                            WorkOrd = item.WorkOrds,
-                            QtyOrd = item.OrdQty * a.Qty,
-                            Line = i,
-                            IsActive = true,
-                        });
-                        if(dictItemQty.ContainsKey(a.ComponentItem))
-                        {
-                            dictItemQty[a.ComponentItem] = dictItemQty[a.ComponentItem] + item.OrdQty.Value * a.Qty;
-                        }else
-                        {
-                            dictItemQty.Add(a.ComponentItem, item.OrdQty.Value * a.Qty);
-                        }
-                        i++;
-                    });
-                }
-                _nbrMaster.Insert(nbrMasterList);
-                //快开平台用自增列RecId关联,所以需要插入后再查给明细表赋相应的值
-                List<string> nbrs= nbrMasterList.Select(a=>a.Nbr).ToList();
-                var nbrList= _nbrMaster.Select(a => a.Domain == "1001" && a.Type == "SM" && nbrs.Contains(a.Nbr));
-                nbrDetailList.ForEach(c =>
-                {
-                    c.NbrRecID= nbrList.Where(a=>a.Nbr==c.Nbr).First().RecID;
-                });
-                _nbrDetail.Insert(nbrDetailList);
-                //TODO:
-                //因为我们并没有模拟发料的过程,在自动生成领料单的时候就要扣减库存,实际业务不能这么做。
-                //在有上料和追溯的系统,可以在扫码上料或报工时(从线边仓)扣减。或者在实际发料出库时扣减。
-                List<string> itemKeys= dictItemQty.Keys.ToList();
-                var items=_mysql_ic_item.GetListAsync(a => itemKeys.Contains(a.number) && a.factory_id == 1001 && a.tenant_id == 1000).Result;
-                var itemIds=items.Select(b => b.Id).ToList();
-                var stockList=_mysql_ic_item_stock.GetListAsync(a => itemIds.Contains(a.Id) && a.factory_id == 1001 && a.tenant_id == 1000).Result;
-                stockList?.ForEach(a =>
-                {
-                    a.sqty = a.sqty - dictItemQty[items.First(b => b.Id == a.Id).number];
-                });
-                //_mysql_ic_item_stock.UpdateManyAsync(stockList);
-            }
-        }
-
         /// <summary>
-        /// 得到一个流水号的最大流水号
+        /// 计算订单行的系统建议交期
         /// </summary>
-        /// <param name="id">流水号id</param>
-        /// <param name="formData">json数据,可以用json中的某个字段值作为通配符字替换流水号格式。</param>
-        /// <returns></returns>
-        public string GetMaxSerialNumber(long id, JObject? formData = null)
+        /// <param name="sentrys"></param>
+        /// <param name="kittingTimes"></param>
+        public async void CalcSuggestDate(List<crm_seorderentry> sentrys, List<KittingTimeDto> kittingTimes) 
         {
-            var modelList = _rf_serialnumber.Select(s => s.Id == id);
-            if (modelList == null && modelList.Count < 1)
+            //获取排产记录
+            List<string> itemNums = sentrys.Select(p=>p.item_number).Distinct().ToList();
+            DateTime eralist = kittingTimes.Min(p => p.kitting_time).Date;
+            List<PeriodSequenceDet> periodSequences = _periodSequenceDet.Select(p => itemNums.Contains(p.ItemNum) && p.PlanDate >= eralist).ToList();
+
+            //资源检查添加产线工序等数据
+            _productExamineAppService.prodLines = prodLines;
+            _productExamineAppService.routingOps = routingOps;
+            _productExamineAppService.calendarWorks = calendarWorks;
+            _productExamineAppService.qualityLineWorks = qualityLineWorks;
+            _productExamineAppService.holidays = holidays;
+            _productExamineAppService.periodSequences = periodSequences;
+            if (sentrys.Count() == 0)
             {
-                return string.Empty;
-            }
-            var model = modelList[0];
-            int max = model.CurrentNumber + 1;
-            var date = DateTime.Now;
-            var lastDate = model.LastTime;
-            switch (model.NumberType)
-            {
-                case 1: //年流水
-                    if (date.Year > lastDate.Year)
-                    {
-                        max = 1;
-                    }
-                    break;
-                case 2: //月流水
-                    if (date.Year > lastDate.Year || date.Month > lastDate.Month)
-                    {
-                        max = 1;
-                    }
-                    break;
-                case 3: //日流水
-                    if (date.Year > lastDate.Year || date.Month > lastDate.Month || date.Day > lastDate.Day)
-                    {
-                        max = 1;
-                    }
-                    break;
+                return;
             }
-            string number = max.ToString().PadLeft(model.NumberSize, '0');
-            string serialNumber = string.IsNullOrWhiteSpace(model.Format) ? number
-                : model.Format.ContainsIgnoreCase("{number}")
-                ? model.Format.ReplaceIgnoreCase("{number}", number)
-                : model.Format + number;
-            //更新当前编号和最后时间
-            model.LastTime = date;
-            model.CurrentNumber = max;
-            _rf_serialnumber.Update(model);
-            return Wildcard.Replace(serialNumber, formData);
+            sentrys = _productExamineAppService.CalcSuggestTime(sentrys, kittingTimes);
+            await _mysql_crm_seorderentry.UpdateManyAsync(sentrys);
         }
     }
 }

+ 31 - 31
MicroServices/Business/Business.Application/SyncDataManagement/SyncMySQLDataAppService.cs

@@ -173,39 +173,39 @@ namespace Business.SyncDataManagement
         public async void SyncBaseDataToMongoDB()
         {
             //同步物料Bom数据
-            //var icBoms = _mysql_ic_bom.GetListAsync().Result;
-            //if (icBoms.Count > 0)
-            //{
-            //    //先清空表数据
-            //    await _ic_bom.Delete(p => p.mysql_id != -1);
-            //    var moIcBoms = ObjectMapper.Map<List<ic_bom>, List<mo_ic_bom>>(icBoms);
-            //    moIcBoms.ForEach(s => s.id = help.NextId());
-            //    //插入数据
-            //    await _ic_bom.InsertMany(moIcBoms);
-            //}
+            var icBoms = _mysql_ic_bom.GetListAsync().Result;
+            if (icBoms.Count > 0)
+            {
+                //先清空表数据
+                await _ic_bom.Delete(p => p.mysql_id != -1);
+                var moIcBoms = ObjectMapper.Map<List<ic_bom>, List<mo_ic_bom>>(icBoms);
+                moIcBoms.ForEach(s => s.id = help.NextId());
+                //插入数据
+                await _ic_bom.InsertMany(moIcBoms);
+            }
 
-            ////同步物料BOM明细数据
-            //var icbom_childs = _mysql_ic_bom_child.GetListAsync().Result;
-            //if (icbom_childs.Count > 0)
-            //{
-            //    //先清空表数据
-            //    await _ic_bom_child.Delete(p => p.mysql_id != -1);
-            //    var moIcbom_childs = ObjectMapper.Map<List<ic_bom_child>, List<mo_ic_bom_child>>(icbom_childs);
-            //    moIcbom_childs.ForEach(s => s.id = help.NextId());
-            //    //插入数据
-            //    await _ic_bom_child.InsertMany(moIcbom_childs);
-            //}
+            //同步物料BOM明细数据
+            var icbom_childs = _mysql_ic_bom_child.GetListAsync().Result;
+            if (icbom_childs.Count > 0)
+            {
+                //先清空表数据
+                await _ic_bom_child.Delete(p => p.mysql_id != -1);
+                var moIcbom_childs = ObjectMapper.Map<List<ic_bom_child>, List<mo_ic_bom_child>>(icbom_childs);
+                moIcbom_childs.ForEach(s => s.id = help.NextId());
+                //插入数据
+                await _ic_bom_child.InsertMany(moIcbom_childs);
+            }
 
-            ////工厂物料明细表
-            //var ic_factory_details = _mysql_ic_factory_details.GetListAsync().Result;
-            //if (ic_factory_details.Count > 0)
-            //{
-            //    //先清空表数据
-            //    await _ic_factory_details.Delete(p => p.mysql_id != -1);
-            //    var moIc_factory_details = ObjectMapper.Map<List<ic_factory_details>, List<mo_ic_factory_details>>(ic_factory_details);
-            //    moIc_factory_details.ForEach(s => s.id = help.NextId());
-            //    await _ic_factory_details.InsertMany(moIc_factory_details);
-            //}
+            //工厂物料明细表
+            var ic_factory_details = _mysql_ic_factory_details.GetListAsync().Result;
+            if (ic_factory_details.Count > 0)
+            {
+                //先清空表数据
+                await _ic_factory_details.Delete(p => p.mysql_id != -1);
+                var moIc_factory_details = ObjectMapper.Map<List<ic_factory_details>, List<mo_ic_factory_details>>(ic_factory_details);
+                moIc_factory_details.ForEach(s => s.id = help.NextId());
+                await _ic_factory_details.InsertMany(moIc_factory_details);
+            }
 
             //同步物料数据
             var icItems = _mysql_ic_item.GetListAsync().Result;

+ 134 - 30
MicroServices/Business/Business.Application/SyncDataManagement/SyncWMSDataAppService.cs

@@ -6,13 +6,19 @@ using Business.Model.Sale;
 using Business.Model.SRM;
 using EFCore.BulkExtensions;
 using Microsoft.EntityFrameworkCore;
+using NetTopologySuite.Algorithm;
 using Newtonsoft.Json;
+using SixLabors.ImageSharp;
+using Spire.Pdf;
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
 using System.Linq;
 using Volo.Abp.Application.Services;
 using Volo.Abp.Domain.Repositories;
+using WkHtmlToPdfDotNet;
 
 namespace Business.SyncDataManagement
 {
@@ -442,9 +448,22 @@ namespace Business.SyncDataManagement
         //同步物料
         public void SyncItemMaster()
         {
-            var ic_itemList = _mysql_ic_item.GetListAsync(a=>a.tenant_id==1000 && a.factory_id==1001).Result;
-            var custList = _itemMaster.Select(a => a.IsActive);
+            bool isAll = true;//是否同步所有物料
+            var ic_itemList = _mysql_ic_item.GetListAsync(a => a.tenant_id == 1000 && a.factory_id == 1001).Result;
+            List<ItemMaster> custList = new List<ItemMaster>();
+            if(isAll)
+            {
+                custList = _itemMaster.Select(a => a.IsActive && a.Domain=="1001");
+            }else
+            {
+                //格努产品编码同步子级物料
+                List<string> childItems = GetChildItemNumber("", new List<string>());
+                custList= _itemMaster.Select(a => a.IsActive && a.Domain == "1001" && childItems.Distinct().Contains(a.ItemNum));
+            }
             List<ic_item> ItemsAdd = new List<ic_item>();
+            List<ic_factory_details> ic_factory_detailsAdd = new List<ic_factory_details>();
+            List<ic_plan> ic_planAdd = new List<ic_plan>();
+            List<srm_purchase> srm_purchaseAdd = new List<srm_purchase>();
             if (custList != null && custList.Count > 0)
             {
                 for (int i = 0; i < custList.Count; i++)
@@ -452,7 +471,8 @@ namespace Business.SyncDataManagement
                     var ic_item = ic_itemList.Find(x => x.number == custList[i].ItemNum && x.tenant_id == 1000 && x.factory_id == 1001);
                     if (ic_item == null)
                     {
-                        ItemsAdd.Add(new ic_item(help.NextId())
+                        long itemId = help.NextId();
+                        ItemsAdd.Add(new ic_item(itemId)
                         {
                             number = custList[i].ItemNum, //物料编码
                             name = custList[i].Descr, //物料名称
@@ -483,66 +503,134 @@ namespace Business.SyncDataManagement
                             factory_id = 1001,
                             tenant_id = 1000,
                             IsDeleted = false
-                        }); 
+                        });
+                        ic_factory_detailsAdd.Add(new ic_factory_details(help.NextId())
+                        {
+                            icitem_id= itemId,
+                            icitem_name=custList[i].Descr,
+                            batch_manager= custList[i].LotSerialControl?1:0,
+                            item_shelve= custList[i].DefaultShelf,
+                            qty_max= custList[i].MaxOrd,
+                            minorderqty= custList[i].MinOrd,
+                            minpackqty= 1,
+                            ordissu_days = 1,
+                            mat_enter_days= 1,
+                            prd_out_days= 2,
+                            transportation_leadtime= 3,
+                            stock_leadtime= 1,
+                            production_leadtime= 4,
+                            order_leadtime= 4,
+                            factory_id = 1001,
+                            tenant_id = 1000,
+                            IsDeleted = false
+                        });
+                        ic_planAdd.Add(new ic_plan(help.NextId())
+                        {
+                            icitem_id = itemId,
+                            icitem_name = custList[i].Descr,
+                            fix_leadtime = 1,
+                            order_inter_val = 1,
+                            lead_time=1,
+                            bat_change_economy=1,
+                            total_tqq=1,
+                            order_point=1,
+                            secinv=1,
+                            secinv_ratio=1,
+                            self_inspection_date=1,
+                            Warehousing_date=1,
+                            Shipping_date=3,
+                            factory_id = 1001,
+                            tenant_id = 1000,
+                            IsDeleted = false
+                        });
+                        srm_purchaseAdd.Add(new srm_purchase(help.NextId())
+                        {
+                            icitem_id = itemId,
+                            icitem_name = custList[i].Descr,
+                            sourcelist_number = "HYQD12064",
+                            supplier_id = 10101000051,
+                            supplier_number = "",
+                            supplier_name = "广州市伟正金属构件有限公司",
+                            purchgroup = "",
+                            purcher = "",
+                            purchase_unit = "",
+                            netpurchase_price = 1,
+                            taxrate = 0.13m,
+                            currency_type = 1,
+                            order_rector_name = "",
+                            order_rector_num = "",
+                            factory_code = "",
+                            order_dept = "",
+                            order_price = 13,
+                            sale_price = 130,
+                            qty_min = 10,
+                            batch_append_qty = 10,
+                            factory_id = 1001,
+                            tenant_id = 1000,
+                            IsDeleted = false
+                        });
                     }
                 }
             }
             _businessDbContext.BulkInsert(ItemsAdd);
+            _businessDbContext.BulkInsert(ic_factory_detailsAdd);
+            _businessDbContext.BulkInsert(ic_planAdd);
+            _businessDbContext.BulkInsert(srm_purchaseAdd);
         }
 
         public void SyncBom()
         {
-            var ic_bomList = _mysql_ic_bom.GetListAsync(a=>a.tenant_id==1000 && a.factory_id==1001).Result;
+            var ic_bomList = _mysql_ic_bom.GetListAsync(a => a.tenant_id == 1000 && a.factory_id == 1001).Result;
             var ic_itemList = _mysql_ic_item.GetListAsync(a => a.tenant_id == 1000 && a.factory_id == 1001).Result;
-            List<ProductStructureMaster> wmsBomList =_productStructureMaster.Select(a=>a.Domain=="1001" && (a.ParentItem== "1.SD1.D.0056-F" || a.ParentItem == "1.ZC1.D.0001" || a.ParentItem == "1.BW1.D.0030") && a.IsActive);
+            List<ProductStructureMaster> wmsBomList = _productStructureMaster.Select(a => a.Domain == "1001" && (a.ParentItem == "1.SD1.D.0056-F" || a.ParentItem == "1.ZC1.D.0001" || a.ParentItem == "1.BW1.D.0030") && a.IsActive);
             List<ic_bom> ItemsAdd = new List<ic_bom>();
             List<ic_bom_child> childItemsAdd = new List<ic_bom_child>();
             if (wmsBomList != null && wmsBomList.Count > 0)
             {
                 var ItemMasterDS = wmsBomList.Select(a => a.ParentItem).Distinct().ToList();
-                foreach(var c in ItemMasterDS)
+                foreach (var c in ItemMasterDS)
                 {
                     var item = ic_itemList.Find(a => a.number == c);
-                    var ItemList = wmsBomList.Where(a=>a.ParentItem ==c);
+                    var ItemList = wmsBomList.Where(a => a.ParentItem == c);
                     long domain = Convert.ToInt64(ItemList.First().Domain);
                     long factory_id = domain % 1000;
                     long tenant_id = domain - factory_id;
                     var bom = new ic_bom(help.NextId())
                     {
                         bom_number = c,
-                        icitem_id = item==null ? help.NextId() : item.Id,
-                        item_name= item==null? "" : item.name,
-                        item_number =c,
-                        version= ItemList.First().Refs,
+                        icitem_id = item == null ? help.NextId() : item.Id,
+                        item_name = item == null ? "" : item.name,
+                        item_number = c,
+                        version = ItemList.First().Refs,
                         factory_id = 1001,
                         tenant_id = 1000,
-                        IsDeleted=false,
-                        use_status=1
+                        IsDeleted = false,
+                        use_status = 1
                     };
                     ItemsAdd.Add(bom);
 
-                    foreach(var child in ItemList)
+                    foreach (var child in ItemList)
                     {
                         var itemchild = ic_itemList.Find(a => a.number == child.ComponentItem);
                         var bomchild = new ic_bom_child(help.NextId())
                         {
-                            bom_id= bom.Id,
-                            bom_number=bom.bom_number,
-                            icitem_id= itemchild==null ?long.MinValue : itemchild.Id,
-                            item_number= child.ComponentItem,
-                            item_name= itemchild==null? "" : item.name,
-                            unit=child.UM,
-                            qty=child.Qty,
-                            entryid=child.SequenceNum,
-                            erp_cls= itemchild==null ? 2: itemchild.erp_cls,
-                            begin_day=child.StartEff,
-                            end_day=child.EndEff,
-                            child_num= child.SequenceNum,
-                            version=child.Refs,
+                            bom_id = bom.Id,
+                            bom_number = bom.bom_number,
+                            icitem_id = itemchild == null ? long.MinValue : itemchild.Id,
+                            item_number = child.ComponentItem,
+                            item_name = itemchild == null ? "" : item.name,
+                            unit = child.UM,
+                            qty = child.Qty,
+                            entryid = child.SequenceNum,
+                            erp_cls = itemchild == null ? 2 : itemchild.erp_cls,
+                            begin_day = child.StartEff,
+                            end_day = child.EndEff,
+                            child_num = child.SequenceNum,
+                            version = child.Refs,
                             factory_id = 1001,
                             tenant_id = 1000,
-                            IsDeleted=false,
-                            use_status=1
+                            IsDeleted = false,
+                            use_status = 1
                         };
                         childItemsAdd.Add(bomchild);
                     }
@@ -551,5 +639,21 @@ namespace Business.SyncDataManagement
                 _businessDbContext.BulkInsert(childItemsAdd);
             }
         }
+
+        //循环获取子级物料编码,包括产品本身,有重复的结果去重即可
+        public List<string> GetChildItemNumber(string itemNum, List<string> list)
+        {
+            list.Add(itemNum);
+            var productStructures = _productStructureMaster.Select(p => p.ParentItem == itemNum && p.Domain == "1001" && p.IsActive);
+            list.AddRange(productStructures.Select(a => a.ComponentItem));
+            foreach (var item in productStructures)
+            {
+                if (item.StructureType.ToUpper() == "X")
+                {
+                    GetChildItemNumber(item.ComponentItem, list);
+                }
+            }
+            return list;
+        }
     }
 }

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

@@ -117,11 +117,6 @@ namespace Business.EntityFrameworkCore
         /// </summary>
         public DbSet<ShopCalendarWorkCtr> ShopCalendarWorkCtr { get; set; }
 
-        /// <summary>
-        /// 排产异常记录表
-        /// </summary>
-        public DbSet<ScheduleExceptionMaster> ScheduleExceptionMaster { get; set; }
-
         /// <summary>
         /// 产线休息时间记录表
         /// </summary>
@@ -145,7 +140,9 @@ namespace Business.EntityFrameworkCore
         public DbSet<LineMaster> LineMaster { get; set; }
 
         public DbSet<rf_serialnumber> rf_serialnumber { get; set; }
+        public DbSet<LocationDetail> LocationDetail { get; set; }
 
+        public DbSet<ItemPackMaster> ItemPackMaster { get; set; }
         #endregion
 
         //Code generation...

+ 1 - 1
MicroServices/Business/Business.Host/BusinessHostModule.cs

@@ -113,7 +113,7 @@ namespace Business
                 q.AddTrigger(opts => opts
                     .ForJob(jobKey)
                     .WithIdentity("SyncDataJob-trigger")
-                    .WithCronSchedule("0 29 1 * * ?")
+                    .WithCronSchedule("0 38 10 * * ?")
                     .WithDescription("定时同步MySQL基础数据到MongoDB"));
 
                 var NLogJobKey = new JobKey("NLogJob");

+ 2 - 0
MicroServices/Business/Business.Host/Startup.cs

@@ -1,5 +1,6 @@
 using Business.Core.MongoDBHelper;
 using Business.EntityFrameworkCore.SqlRepositories;
+using Business.Quartz;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.Extensions.DependencyInjection;
@@ -16,6 +17,7 @@ namespace Business
             services.AddScoped(typeof(IMongoDB<>), typeof(MongoDBTools<>));
             services.AddScoped(typeof(ISqlRepository<>), typeof(SqlRepository<>));
             services.AddScoped<Config>();
+            services.AddScoped<LogHostedService>();
         }
 
         public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)

+ 15 - 3
MicroServices/Business/Business.HttpApi/Controllers/ResourceExamineController.cs

@@ -26,16 +26,28 @@ namespace Business.Controllers
             _ResourceExamineAppService = ResourceExamineAppService;
         }
 
+        /// <summary>
+        /// 生产排产
+        /// </summary>
+        /// <param name="workOrds"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [Route("productionschedule")]
+        public Task<string> ProductionSchedule(string workOrds)
+        {
+            return _ResourceExamineAppService.ProductionSchedule(workOrds);
+        }
+
         /// <summary>
         /// 资源检查
         /// </summary>
         /// <param name="input"></param>
         /// <returns></returns>
-        [HttpPost]
+        [HttpGet]
         [Route("receiveresult")]
-        public Task<string> ReceiveResult(ResourceCheckInputDto input)
+        public Task<string> ReceiveResult(string ids)
         {
-            return _ResourceExamineAppService.ReceiveResult(input);
+            return _ResourceExamineAppService.ReceiveResult(ids);
         }
 
         /// <summary>

+ 10 - 10
MicroServices/Business/Business.Test/MorderTest.cs

@@ -20,18 +20,18 @@ namespace Business.Test
             //Arrange
             var ProductExamine = new ProductExamineAppService();
             ProductExamineTest productExamineTest = new ProductExamineTest();
-            ProductExamine.techs = productExamineTest.CreateTechnique();
-            ProductExamine.process = productExamineTest.CreateProcess();
-            ProductExamine.tech_Processes = productExamineTest.CreateTechProcess();
-            var morder = new MorderAppService(ProductExamine);
+            //ProductExamine.techs = productExamineTest.CreateTechnique();
+            //ProductExamine.process = productExamineTest.CreateProcess();
+            //ProductExamine.tech_Processes = productExamineTest.CreateTechProcess();
+            //var morder = new MorderAppService(ProductExamine);
 
             //Act
-            ProdExamineParamDto prodExamine = new ProdExamineParamDto()
-            {
-                bom_number = "R650K",
-                version = "3.0",
-                packages = 1000
-            };
+            //ProdExamineParamDto prodExamine = new ProdExamineParamDto()
+            //{
+            //    bom_number = "R650K",
+            //    version = "3.0",
+            //    packages = 1000
+            //};
             //var result = sut.ProductiveExamine(prodExamine);
             //Assert
             //Xunit.Assert.Equal(14030, result);

+ 12 - 12
MicroServices/Business/Business.Test/ProductExamineTest.cs

@@ -24,20 +24,20 @@ namespace Business.Test
             //dev合并master测试注释
             //Arrange
             var sut = new ProductExamineAppService();
-            sut.techs = CreateTechnique();
-            sut.process = CreateProcess();
-            sut.tech_Processes = CreateTechProcess();
+            //sut.techs = CreateTechnique();
+            //sut.process = CreateProcess();
+            //sut.tech_Processes = CreateTechProcess();
 
             //Act
-            ProdExamineParamDto prodExamine = new ProdExamineParamDto()
-            {
-                bom_number = "R650K",
-                version = "3.0",
-                packages = 1000
-            };
-            var result =  sut.ProductiveExamine(prodExamine);
-            //Assert
-            Xunit.Assert.Equal(14030, result);
+            //ProdExamineParamDto prodExamine = new ProdExamineParamDto()
+            //{
+            //    bom_number = "R650K",
+            //    version = "3.0",
+            //    packages = 1000
+            //};
+            //var result =  sut.ProductiveExamine(prodExamine);
+            ////Assert
+            //Xunit.Assert.Equal(14030, result);
         }
 
         /// <summary>

+ 2 - 2
MicroServices/Business/Bussiness.ApplicationTest/ResourceExamineManagement/ResourceExamineAppService_Tests.cs

@@ -25,7 +25,7 @@ namespace Bussiness.ApplicationTest.ResourceExamineManagement
         public async Task Should_ThrowExcetion()
         {
             var testInput = new ResourceCheckInputDto { factoryId = 10201, sorderId = new List<long> { 111111 }, tenantId = 102 };
-            await Xunit.Assert.ThrowsAsync<NotImplementedException>(async () => await _resourceExamineAppService.ReceiveResult(testInput));
+            await Xunit.Assert.ThrowsAsync<NotImplementedException>(async () => await _resourceExamineAppService.ReceiveResult("111111"));
         }
 
         [Fact]
@@ -33,7 +33,7 @@ namespace Bussiness.ApplicationTest.ResourceExamineManagement
         public async Task Should_ThrowExcetion_Second()
         {
             var testInput = new ResourceCheckInputDto { factoryId = 10201, sorderId = new List<long> { 111111 }, tenantId = 102 };
-            await _resourceExamineAppService.ReceiveResult(testInput);
+            await _resourceExamineAppService.ReceiveResult("111111");
         }
     }
 }

+ 10 - 1
MicroServices/Business/Bussiness.Model/MES/IC/ItemMaster.cs

@@ -69,12 +69,21 @@ namespace Business.Model.MES.IC
         public decimal? Width { get; set; }
         public decimal? Height { get; set; }
         public Boolean LotSerialControl { get; set; }
-
+        public string? DefaultShelf { get; set; }
+        public decimal? MaxOrd { get; set; }
+        public decimal? MinOrd { get; set; }
+        public decimal MFGMTTR { get; set; }
         /// <summary>
         /// 是否有效:1-有效;0-无效
         /// </summary>
         [Comment("是否有效")]
         public Boolean IsActive { get; set; }
 
+        /// <summary>
+        /// 是否有效:1-有效;0-无效
+        /// </summary>
+        [Comment("是否整包发料")]
+        public Boolean TraceDetail { get; set; }
+        
     }
 }

+ 49 - 0
MicroServices/Business/Bussiness.Model/MES/IC/ItemPackMaster.cs

@@ -0,0 +1,49 @@
+using Business.Model;
+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.Model.MES.IC
+{
+    /// <summary>
+    /// 物料包装表
+    /// </summary>
+    [Comment("物料包装表")]
+    public class ItemPackMaster
+    {
+        /// <summary>
+        /// 主键
+        /// </summary>
+        [Comment("主键")]
+        [Key]
+        public int RecID { get; set; }
+
+        /// <summary>
+        /// 域名
+        /// </summary>
+        [Comment("域名")]
+        public string? Domain { get; set; }
+
+        /// <summary>
+        /// 物料编号
+        /// </summary>
+        [Comment("物料编号")]
+        public string? ItemNum { get; set; }
+
+        /// <summary>
+        /// 包装数量
+        /// </summary>
+        [Comment("包装数量")]
+        public decimal? PackingQty { get; set; }
+
+        /// <summary>
+        /// 是否有效:1-有效;0-无效
+        /// </summary>
+        [Comment("是否有效")]
+        public Boolean IsActive { get; set; }
+    }
+}

+ 55 - 0
MicroServices/Business/Bussiness.Model/MES/IC/LocationDetail.cs

@@ -0,0 +1,55 @@
+using Business.Model;
+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.Model.MES.IC
+{
+    /// <summary>
+    /// 库存明细表
+    /// </summary>
+    [Comment("库存明细表")]
+    public class LocationDetail
+    {
+        /// <summary>
+        /// 主键
+        /// </summary>
+        [Comment("主键")]
+        [Key]
+        public int RecID { get; set; }
+
+        /// <summary>
+        /// 域名
+        /// </summary>
+        [Comment("域名")]
+        public string? Domain { get; set; }
+
+        /// <summary>
+        /// 库位
+        /// </summary>
+        [Comment("库位")]
+        public string? Location { get; set; }
+
+        /// <summary>
+        /// 物料编号
+        /// </summary>
+        [Comment("物料编号")]
+        public string? ItemNum { get; set; }
+
+        /// <summary>
+        /// 库存数量
+        /// </summary>
+        [Comment("库存数量")]
+        public decimal? QtyOnHand { get; set; }
+
+        /// <summary>
+        /// 是否有效:1-有效;0-无效
+        /// </summary>
+        [Comment("是否有效")]
+        public Boolean IsActive { get; set; }
+    }
+}

+ 37 - 0
MicroServices/Business/Bussiness.Model/MES/IC/NbrDetail.cs

@@ -81,6 +81,12 @@ namespace Business.Model.MES.IC
         [Comment("订单数量")]
         public decimal? QtyOrd { get; set; }
 
+        /// <summary>
+        /// 工单需求数量
+        /// </summary>
+        [Comment("工单需求数量")]
+        public decimal? CurrQtyOpened { get; set; }
+
         /// <summary>
         /// 行号
         /// </summary>
@@ -97,5 +103,36 @@ namespace Business.Model.MES.IC
         /// </summary>
         [Comment("是否有效")]
         public Boolean IsActive { get; set; }
+
+        /// <summary>
+        /// 单位
+        /// </summary>
+        [Comment("单位")]
+        public string? UM { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        [Comment("创建时间")]
+        public DateTime? CreateTime { get; set; }
+
+        /// <summary>
+        /// 创建人
+        /// </summary>
+        [Comment("创建人")]
+        public string? CreateUser { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        [Comment("修改时间")]
+        public DateTime? UpdateTime { get; set; }
+
+        /// <summary>
+        /// 修改人
+        /// </summary>
+        [Comment("修改人")]
+        public string? UpdateUser { get; set; }
+
     }
 }

+ 43 - 0
MicroServices/Business/Bussiness.Model/MES/IC/NbrMaster.cs

@@ -87,5 +87,48 @@ namespace Business.Model.MES.IC
         /// </summary>
         [Comment("是否编辑")]
         public Boolean IsChanged { get; set; }
+
+        /// <summary>
+        /// 部门
+        /// </summary>
+        [Comment("部门")]
+        public string? Department { get; set; }
+
+
+        /// <summary>
+        /// 领料人姓名
+        /// </summary>
+        [Comment("领料人姓名")]
+        public string? Name { get; set; }
+
+        /// <summary>
+        /// 备料人
+        /// </summary>
+        [Comment("备料人")]
+        public string? User1 { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        [Comment("创建时间")]
+        public DateTime? CreateTime { get; set; }
+
+        /// <summary>
+        /// 创建人
+        /// </summary>
+        [Comment("创建人")]
+        public string? CreateUser { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        [Comment("修改时间")]
+        public DateTime? UpdateTime { get; set; }
+
+        /// <summary>
+        /// 修改人
+        /// </summary>
+        [Comment("修改人")]
+        public string? UpdateUser { get; set; }
     }
 }

+ 0 - 48
MicroServices/Business/Bussiness.Model/Production/ScheduleExceptionMaster.cs

@@ -1,48 +0,0 @@
-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.Model.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 Remark { get; set; }
-
-        /// <summary>
-        /// 创建时间
-        /// </summary>
-        [Comment("创建时间")]
-        public DateTime CreatTime { get; set; }
-    }
-}

+ 9 - 0
MicroServices/Business/Bussiness.Model/SRM/srm_po_list.cs

@@ -77,6 +77,15 @@ namespace Business.Model.SRM
         [Required]
         [Comment("物料id")]
         public long? icitem_id { get; set; }
+
+
+        /// <summary>
+        /// 物料编码
+        /// </summary>
+        [StringLength(100)]
+        [Comment("物料编码")]
+        public string? ItemNum { get; set; }
+
         /// <summary>
         /// 物料名称
         /// </summary>

+ 8 - 0
MicroServices/Business/Bussiness.MongoModel/SRM/mo_srm_po_list.cs

@@ -79,6 +79,14 @@ namespace Business.MongoModel.SRM
         [Required]
         [Comment("物料id")]
         public long? icitem_id { get; set; }
+
+        /// <summary>
+        /// 物料编码
+        /// </summary>
+        [StringLength(100)]
+        [Comment("物料编码")]
+        public string? ItemNum { get; set; }
+
         /// <summary>
         /// 物料名称
         /// </summary>