Просмотр исходного кода

Merge branch 'master' of http://123.60.180.165:4647/ZZYDOP/DOPCore

Murphy 3 лет назад
Родитель
Сommit
3e9cdaaafe

+ 4 - 0
MicroServices/Business/Business.Application.Contracts/Business.Application.Contracts.csproj

@@ -37,4 +37,8 @@
     <PackageReference Include="Volo.Abp.PermissionManagement.Application.Contracts" Version="6.0.0" />
   </ItemGroup>
 
+  <ItemGroup>
+    <ProjectReference Include="..\Bussiness.Model\Bussiness.Model.csproj" />
+  </ItemGroup>
+
 </Project>

+ 16 - 1
MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/Dto/BomChildExamineDto.cs

@@ -24,6 +24,21 @@ namespace Business.ResourceExamineManagement.Dto
         /// </summary>
         public long? bom_child_id { get; set; }
 
+        /// <summary>
+        /// 版本
+        /// </summary>
+        public string version { get; set; }
+
+        /// <summary>
+        /// bom编号
+        /// </summary>
+        public string bom_number { get; set; }
+
+        /// <summary>
+        /// 物料编号
+        /// </summary>
+        public string item_number { get; set; }
+
         /// <summary>
         /// level
         /// </summary>
@@ -215,7 +230,7 @@ namespace Business.ResourceExamineManagement.Dto
         public int substitute_mode { get; set; }
 
         /// <summary>
-        /// 物料状态--0.缺料 1.充足 2.可制,时间满足 3.可制,时间不满足 4.采购 5.委外
+        /// 物料状态-- -1.无需求 0.缺料 1.充足 2.可制,时间满足 3.可制,时间不满足 4.采购 5.委外
         /// </summary>
         public int stock_state { get; set; }
 

+ 7 - 0
MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/Dto/PschedDto.cs

@@ -2,6 +2,8 @@ using System;
 using System.Collections.Generic;
 using Volo.Abp.Application.Dtos;
 using System.ComponentModel.DataAnnotations;
+using Bussiness.Model.MES.IC;
+
 namespace Business.ResourceExamineManagement.Dto
 {
     /// <summary>
@@ -18,6 +20,11 @@ namespace Business.ResourceExamineManagement.Dto
         /// 资源检查明细list
         /// </summary>
         public List<ExamineResult> examines { get; set; }
+
+        /// <summary>
+        /// 物料占用记录
+        /// </summary>
+        public List<ic_item_stockoccupy> sklist { get; set; }
     }
 
     /// <summary>

+ 5 - 0
MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/Dto/StartTimeDto.cs

@@ -30,5 +30,10 @@ namespace Business.ResourceExamineManagement.Dto
         /// 下一工序需要等待时长,如果是最后一个工序的话,就是最后一个工序生产所需时间
         /// </summary>
         public decimal wait_time { get; set; }
+
+        /// <summary>
+        /// 当前工序生产所需时间
+        /// </summary>
+        public decimal take_time { get; set; }
     }
 }

+ 216 - 90
MicroServices/Business/Business.Application/ResourceExamineManagement/ResourceExamineAppService.cs

@@ -354,7 +354,7 @@ namespace Business.ResourceExamineManagement
             param.sorderId = input.sorderId;
             param.tenantId = input.tenantId;
             param.factoryId = input.factoryId;
-            
+
             //资源检查结果
             PschedDto rtn = new PschedDto();
             rtn.sorderid = input.sorderId;
@@ -391,7 +391,8 @@ namespace Business.ResourceExamineManagement
             List<ic_bom_child> bomchildlist = new List<ic_bom_child>();
             //获取物料bom,物料bom明细
             GetIcBomData(boms, bomlist, bomchildlist);
-            
+            //物料占用记录
+            List<ic_item_stockoccupy> sklist = new List<ic_item_stockoccupy>();
             //获取物料数据
             List<long> itemIds = bomlist.Select(p => p.icitem_id).ToList();
             itemIds.AddRange(bomchildlist.Select(p => p.icitem_id).ToList());
@@ -414,7 +415,7 @@ namespace Business.ResourceExamineManagement
                 //库存初始化
                 BomStock(getBomList, bangid, input.factoryId);
                 //计算
-                calcTest(getBomList, bangid, item.Id, item.qty.Value, input, item.plan_date);
+                calcTest(getBomList, bangid, item.Id, item.qty.Value, input, item.plan_date, sklist);
 
                 //TODO:最晚开始时间
                 var curFacDtl = leadTimes.FirstOrDefault(p => p.item_id == childBom.icitem_id);
@@ -431,6 +432,7 @@ namespace Business.ResourceExamineManagement
             }
             //订单行资源检查明细list
             rtn.examines = examines;
+            rtn.sklist = sklist;
             return JsonConvert.SerializeObject(rtn);
         }
 
@@ -571,10 +573,11 @@ namespace Business.ResourceExamineManagement
         /// <summary>
         /// 产能计算
         /// </summary>
-        /// <param name="tech_id">工艺路径主键</param>
+        /// <param name="bom_number">bom编号</param>
+        /// <param name="version">版本号</param>
         /// <param name="packages">需要生产产品件数</param>
         /// <returns>生产时长</returns>
-        public async Task<decimal> ProductiveExamine(string bom_number, int packages)
+        public async Task<decimal> ProductiveExamine(string bom_number, string version, int packages)
         {
             if (packages <= 0)
             {
@@ -582,7 +585,7 @@ namespace Business.ResourceExamineManagement
             }
             #region 1、数据准备
             //1.1、获取工艺路径数据
-            mes_technique tech = _mes_technique.Find(p => p.bom == bom_number && p.tenant_id == param.tenantId && p.factory_id == param.factoryId && !p.IsDeleted).Result.FirstOrDefault();
+            mes_technique tech = _mes_technique.Find(p => p.bom == bom_number && p.bomver == version && p.tenant_id == param.tenantId && p.factory_id == param.factoryId && !p.IsDeleted).Result.FirstOrDefault();
             if (tech == null)
             {
                 throw new NotImplementedException("请先配置工艺路径!");
@@ -606,10 +609,6 @@ namespace Business.ResourceExamineManagement
             List<mes_tech_proc_workshop> tech_Proc_Workshops = await _mes_tech_proc_workshop.GetManyByCondition(p => techProcIds.Contains(p.tech_proc_id.Value) && p.tenant_id == param.tenantId && p.factory_id == param.factoryId && !p.IsDeleted);
             #endregion
 
-            #region 计算产能,得到耗时
-            decimal sumTimes = 0.00m;//总耗时(分钟)
-            //工序需要等待时间记录
-            List<StartTimeDto> starts = new List<StartTimeDto>();
             //1、获取工艺路径下的第一层级工序
             List<mes_tech_process> fistChilds = tech_Processes.Where(p => p.parentprocid == tech.Id).ToList();
             if (fistChilds.Count == 0)
@@ -618,91 +617,174 @@ namespace Business.ResourceExamineManagement
             }
             List<mes_tech_process> sortChilds = new List<mes_tech_process>();
             //添加最后一个工序
-            var last = fistChilds.First(p => p.nextprocid == null);
+            var last = fistChilds.FirstOrDefault(p => p.nextprocid == null);
+            if (last == null)
+            {
+                throw new NotImplementedException("当前工艺路径没有配置最终工序,请调整!");
+            }
             sortChilds.Add(last);
-            SortProcess(fistChilds, last.Id, sortChilds);
+            //递归按工序先后顺序排序
+            SortProcess(fistChilds, last.proc_id.Value, sortChilds);
+            //总耗时(分钟)
+            //decimal sumTimes = CalcTakeTimeByLq(sortChilds, packages);//通过Lq计算
+            decimal sumTimes = CalcTakeTimeByLqt(sortChilds, packages);//通过Lqt计算
+            return sumTimes;
+        }
 
-            decimal curTakeTime = 0.00m;//当前工序耗时(分钟)
-            //添加第一个工序需要等待时间记录
+        /// <summary>
+        /// 递归:工序按照先后顺序排序-暂时不考虑两个分支合并到一个分支的情况
+        /// </summary>
+        /// <param name="Processes"></param>
+        /// <param name="processId"></param>
+        /// <param name="sortProcesses"></param>
+        private void SortProcess(List<mes_tech_process> Processes, long processId, List<mes_tech_process> sortProcesses)
+        {
+            var curProcess = Processes.Where(p => p.nextprocid == processId).FirstOrDefault();
+            if (curProcess != null)
+            {
+                sortProcesses.AddFirst(curProcess);
+                SortProcess(Processes, curProcess.proc_id.Value, sortProcesses);
+            }
+        }
+
+        /// <summary>
+        /// 通过Lq计算工艺耗时
+        /// </summary>
+        /// <param name="Processes"></param>
+        /// <param name="packages"></param>
+        /// <returns></returns>
+        private decimal CalcTakeTimeByLq(List<mes_tech_process> Processes, int packages)
+        {
+            decimal sumTimes = 0.00m;//总耗时(分钟)
+            //工序需要等待时间记录
+            List<StartTimeDto> starts = new List<StartTimeDto>();
             StartTimeDto dto;
-            foreach (var chd in fistChilds)
+            foreach (var chd in Processes)
             {
                 dto = new StartTimeDto();
                 if (chd.nextprocid == null)//最后一个工序
                 {
                     //计算最后一个工序耗时
-                    curTakeTime = CalcTakeTime(chd, packages);
+                    dto = CalcProcTakeTimeByLq(chd, packages, packages);
                 }
                 else
                 {
-                    curTakeTime = CalcTakeTime(chd, chd.lq.Value);
+                    dto = CalcProcTakeTimeByLq(chd, chd.lq.Value, packages);
                 }
-                sumTimes += curTakeTime;
-                //添加耗时记录
-                dto.tech_id = tech.Id;
-                dto.proc_id = chd.proc_id.Value;
-                dto.nextproc_id = chd.nextprocid;
-                dto.wait_time = curTakeTime;
+                sumTimes += dto.wait_time;
+                //添加记录
                 starts.Add(dto);
             }
-            #endregion
-
             return sumTimes;
         }
 
         /// <summary>
-        /// 递归:工序按照先后顺序排序-暂时不考虑两个分支合并到一个分支的情况
+        /// 通过Lq计算当前工序前置准备时间
+        /// </summary>
+        /// <param name="proc"></param>
+        /// <param name="quantity">LeadQuantity to Start Next</param>
+        /// <param name="packages">件数</param>
+        /// <returns></returns>
+        private StartTimeDto CalcProcTakeTimeByLq(mes_tech_process proc, decimal quantity, int packages)
+        {
+            //记录当前工序耗时
+            StartTimeDto dto = new StartTimeDto();
+            //添加耗时记录
+            dto.tech_id = proc.tech_id.Value;
+            dto.proc_id = proc.proc_id.Value;
+            dto.nextproc_id = proc.nextprocid;
+            if (proc.wctype == 1)//人工型:数量/uph(一小时生产数量)*60(小时转换为分钟)/wsinuse(工位数)
+            {
+                dto.wait_time = quantity / proc.uph.Value * 60 / proc.wsinuse.Value;
+                dto.take_time = packages / proc.uph.Value * 60 / proc.wsinuse.Value;
+            }
+            else if (proc.wctype == 2)//流水线型:数量*ct(生产一件所需时间)/wsinuse(工位数)
+            {
+                dto.wait_time = quantity * proc.ct.Value / proc.wsinuse.Value;
+                dto.take_time = packages * proc.ct.Value / proc.wsinuse.Value;
+            }
+            else if (proc.wctype == 3)//设备型:向上取整(数量/一次可加工数量/wsinuse(工位数))*ct(老化一次所需时间)
+            {
+                dto.wait_time = Math.Ceiling(quantity / proc.upe.Value / proc.wsinuse.Value) * proc.ct.Value;
+                dto.take_time = Math.Ceiling(packages / proc.upe.Value / proc.wsinuse.Value) * proc.ct.Value;
+            }
+            return dto;
+        }
+
+        /// <summary>
+        /// 通过Lqt计算工艺耗时
         /// </summary>
         /// <param name="Processes"></param>
-        /// <param name="processId"></param>
-        /// <param name="sortProcesses"></param>
-        private void SortProcess(List<mes_tech_process> Processes, long processId, List<mes_tech_process> sortProcesses)
+        /// <param name="packages"></param>
+        /// <returns></returns>
+        private decimal CalcTakeTimeByLqt(List<mes_tech_process> Processes, int packages)
         {
-            var curProcess = Processes.Where(p => p.nextprocid == processId).FirstOrDefault();
-            if (curProcess != null)
+            //总耗时
+            decimal sumTimes = 0;
+            //工序需要等待时间记录
+            List<StartTimeDto> starts = new List<StartTimeDto>();
+            StartTimeDto dto;
+            foreach (var chd in Processes)
             {
-                sortProcesses.AddFirst(curProcess);
-                SortProcess(Processes, curProcess.Id, sortProcesses);
+                dto = new StartTimeDto();
+                //添加耗时记录
+                dto.tech_id = chd.tech_id.Value;
+                dto.proc_id = chd.proc_id.Value;
+                dto.nextproc_id = chd.nextprocid;
+
+                //计算当前工序生产耗时
+                dto.take_time = CalcProcTakeTime(chd, packages);
+                if (chd.nextprocid == null)//最后一个工序
+                {
+                    dto.wait_time = dto.take_time;
+                }
+                else
+                {
+                    dto.wait_time = chd.lqt.Value;
+                }
+                sumTimes += dto.wait_time;
+                //添加记录
+                starts.Add(dto);
             }
+            return sumTimes;
         }
 
         /// <summary>
-        /// 计算当前工序前置准备时间
+        /// 计算当前工序生产时间
         /// </summary>
         /// <param name="proc"></param>
-        /// <param name="quantity">LeadQuantity to Start Next</param>
+        /// <param name="packages">件数</param>
         /// <returns></returns>
-        private decimal CalcTakeTime(mes_tech_process proc, decimal quantity)
+        private decimal CalcProcTakeTime(mes_tech_process proc, int packages)
         {
-            decimal takeTime = 0.00m;//当前工序前置准备时间(分钟)
+            //当前工序生产时间
+            decimal takeTiem = 0.00m;
+            
             if (proc.wctype == 1)//人工型:数量/uph(一小时生产数量)*60(小时转换为分钟)/wsinuse(工位数)
             {
-                takeTime = quantity / proc.uph.Value * 60 / proc.wsinuse.Value;
-                return takeTime;
+                takeTiem = packages / proc.uph.Value * 60 / proc.wsinuse.Value;
             }
             else if (proc.wctype == 2)//流水线型:数量*ct(生产一件所需时间)/wsinuse(工位数)
             {
-                takeTime = quantity * proc.ct.Value / proc.wsinuse.Value;
-                return takeTime;
+                takeTiem = packages * proc.ct.Value / proc.wsinuse.Value;
             }
             else if (proc.wctype == 3)//设备型:向上取整(数量/一次可加工数量/wsinuse(工位数))*ct(老化一次所需时间)
             {
-                takeTime = Math.Ceiling(quantity / proc.upe.Value / proc.wsinuse.Value) * proc.ct.Value;
-                return takeTime;
+                takeTiem = Math.Ceiling(packages / proc.upe.Value / proc.wsinuse.Value) * proc.ct.Value;
             }
-            return takeTime;
+            return takeTiem;
         }
 
-
         /// <summary>
         /// 生成工单
         /// </summary>
         /// <param name="seorderentry">销售订单子表</param>
         /// <param name="BomNumber">Bom编号</param>
+        /// <param name="version">Bom版本</param>
         /// <param name="number">物料编码</param>
         /// <param name="Quantity"></param>
         /// <param name="ParentId"></param>
-        public void GenerateMorder(crm_seorderentry seorderentry, string BomNumber, string number, decimal? Quantity, long? ParentId)
+        public void GenerateMorder(crm_seorderentry seorderentry, string BomNumber,string version, string number, decimal? Quantity, long? ParentId=null)
         {
             //1.库存、在制工单检查完成后 当前BOM需要自制时 产生工单。
 
@@ -732,7 +814,7 @@ namespace Business.ResourceExamineManagement
             mes_Morder.moentry_sys_stime = StartDate;
             if (!string.IsNullOrEmpty(BomNumber))
             {
-                var ProductiveDate = ProductiveExamine(BomNumber, (int)(Quantity.Value));
+                var ProductiveDate = ProductiveExamine(BomNumber, version,(int)(Quantity.Value));
                 //系统建议完工日期为 开工日期+产能检查时间=完工日期
                 var Day = ProductiveDate.Result / (60 * 10); //返回的分钟除以十个小时得出工作天数;
                 mes_Morder.moentry_sys_etime = StartDate.AddDays((double)Day);
@@ -953,6 +1035,7 @@ namespace Business.ResourceExamineManagement
             var dto = new BomChildExamineDto();
             dto.item_id = bom.icitem_id;
             dto.bom_id = BomId.Value;
+            dto.bom_number = bom.bom_number;
             dto.level = 1;
             dto.id = help.NextId();
             dto.parent_id = help.NextId();
@@ -1002,6 +1085,7 @@ namespace Business.ResourceExamineManagement
             dto.erp_cls = item.erp_cls;
             dto.erp_cls_name = item.erp_cls_name;
             dto.type = type;
+            dto.item_number = item.number;
 
             //var bdto = ObjectMapper.Map<ic_bom,BomChildExamineDto>(bom);
             returnlist.Add(dto);
@@ -1032,6 +1116,7 @@ namespace Business.ResourceExamineManagement
                     cdto.type = type;
                     cdto.item_id = childBom.icitem_id;
                     cdto.bom_id = childBom.Id;
+                    cdto.bom_number = childBom.bom_number;
                     //递归寻找子级
                     GetBomList(bomlist, bomchildlist, icitemlist, cdto, returnlist, type);
                 }
@@ -1061,6 +1146,7 @@ namespace Business.ResourceExamineManagement
                         childDto.substitute_code = c.substitute_code;
                         childDto.icitem_ids = c.icitem_ids;
                         childDto.type = type;
+                        childDto.item_number = icitem.number;
                         returnlist.Add(childDto);
                     }
                 }
@@ -1249,12 +1335,8 @@ namespace Business.ResourceExamineManagement
         /// <param name="input"></param>
         /// <param name="plan_date"></param>
         public void calcTest(List<BomChildExamineDto> returnlist, long bangid, long orderid, decimal count, SeorderentryDto input, DateTime
-            ? plan_date)
+            ? plan_date, List<ic_item_stockoccupy> sklist)
         {
-            //占用情况
-            List<ic_item_stockoccupy> sklist = new List<ic_item_stockoccupy>();
-            //var occupylist = _ic_item_stockoccupy.GetManyByCondition(p => p.icitem_id == bangid && p.order_id == orderid).Result;
-
             //第一级
             returnlist = returnlist.OrderBy(s => s.num).ToList();
             var childList = returnlist.Where(s => s.parent_id == returnlist[0].id && s.type == 0).ToList();
@@ -1265,12 +1347,7 @@ namespace Business.ResourceExamineManagement
             //先处理下最顶级的产品需要数量
             returnlist[0].needCount = returnlist[0].qty * count;
             returnlist[0].lack_qty = returnlist[0].needCount - returnlist[0].sqty;
-            if (returnlist[0].lack_qty > 0)
-            {
-                var seorderentry = _mysql_crm_seorderentry.FindAsync(x => x.Id == orderid).Result;
-                //生成自制工单
-                //GenerateMorder(seorderentry, returnlist[0].lack_qty);
-            }
+            
             foreach (var item in returnlist)
             {
                 if (item.level == 1)
@@ -1281,12 +1358,20 @@ namespace Business.ResourceExamineManagement
                 CaclMaterialShortage(returnlist, item, count);
             }
 
+            if (returnlist[0].lack_qty > 0)
+            {
+                var seorderentry = _mysql_crm_seorderentry.FindAsync(x => x.Id == orderid).Result;
+                //生成主工单
+                GenerateMorder(seorderentry, returnlist[0].bom_number, returnlist[0].version, returnlist[0].item_number, returnlist[0].lack_qty);
+            }
+
             //这是从上往下展开计算缺料和可制
             calcTest2(returnlist[0], childList, returnlist, sklist);
             //returnlist[0].kz = childList.Min(s => s.kz);//得到最小可制数量。
             //再加个循环,来根据替代关系里的检查结果,根据规则明确使用和生成占用关系。
-
             CalcIcitem(childList, returnlist, bangid, orderid, input, sklist, plan_date);
+            returnlist[0].kitting_time = childList.Max(s => s.kitting_time);
+            //这里更新产品得满足时间。
 
         }
 
@@ -1300,7 +1385,7 @@ namespace Business.ResourceExamineManagement
         /// <param name="input"></param>
         /// <param name="sklist"></param>
         /// <param name="plan_date"></param>
-        public void CalcIcitem(List<BomChildExamineDto> childList, List<BomChildExamineDto> returnlist, long bangid, long orderid, SeorderentryDto input, List<ic_item_stockoccupy> sklist, DateTime
+        public  void CalcIcitem(List<BomChildExamineDto> childList, List<BomChildExamineDto> returnlist, long bangid, long orderid, SeorderentryDto input, List<ic_item_stockoccupy> sklist, DateTime
             ? plan_date)
         {
             foreach (var item in childList)
@@ -1315,38 +1400,65 @@ namespace Business.ResourceExamineManagement
                 }
                 else
                 {
+                    var parent = returnlist.Find(s => s.id == item.parent_id);
+                    Calczykc(item, parent, sklist);
+
                     //直接占用库存,缺料就生成采购
                     ic_item_stockoccupy itemStockoccupyDto = new ic_item_stockoccupy();
                     itemStockoccupyDto.bang_id = bangid;
                     itemStockoccupyDto.icitem_id = item.item_id;
-                    //修改:根据是否缺料判断使用库存,还是使用需要数量needcount
-                    itemStockoccupyDto.quantity = item.sqty;
-                    sklist.Add(itemStockoccupyDto);
-                    item.is_use = true;
-                    CalcIcitem(cilList, returnlist, bangid, orderid, input, sklist, plan_date);
-
-                    if (item.erp_cls == 1)
+                    item.kitting_time = DateTime.Now;
+                    if (cilList.Count() > 0)
                     {
-                        //走自制
-                        //走子物料
-                        //foreach()
+                        CalcIcitem(cilList, returnlist, bangid, orderid, input, sklist, plan_date);
+                        item.kitting_time = cilList.Max(s => s.kitting_time);
                     }
-                    else if (item.erp_cls == 2 || item.erp_cls == 3)
+
+                    if (item.lack_qty > 0)
                     {
-                        var leadTimeList = GetLeadTime(new List<long> { item.item_id }, input.tenantId, input.factoryId);//提前期列表
-                        var supplierList = GetSupplier(new List<BomChildExamineDto> { item }, input.tenantId, input.factoryId);//供应商列表
-                        var planList = GetICPlan(new List<BomChildExamineDto> { item }, input.tenantId, input.factoryId);//plan列表
-                        item.kitting_time = CreateSRMPR(item, input.tenantId, input.factoryId, bangid, item.erp_cls, leadTimeList, supplierList, planList, plan_date.Value);
-                        if (item.erp_cls == 3)
+                        //如果缺料,占用库存,然后走采购或自制
+                        itemStockoccupyDto.quantity = item.sqty;
+                        item.use_qty = item.sqty;
+                        sklist.Add(itemStockoccupyDto);
+                        if (item.erp_cls == 1)
                         {
-                            //生成委外工单
-                            CreateMesOOder(item, input.tenantId, input.factoryId, bangid, leadTimeList, supplierList, plan_date.Value);
-                            //1.先生成委外工单。
-                            //2.再根据委外工单需要检查库存材料,然后提供给第三方组装。
-                            //3.如果委外工单的物料库存不够,先生成物料采购申请单,再生成物料的采购订单,到货后再走委外流程。
-                            //4.再生成委外的采购申请单。
+                            //走自制
+                            var minute = ProductiveExamine(item.bom_number,"1.0", item.lack_qty.GetInt());
+                            //var ProductiveDate = ProductiveExamine(BomNumber, (int)(Quantity.Value));
+                            //系统建议完工日期为 开工日期+产能检查时间=完工日期
+                            var Day = minute.Result / (60 * 10); //返回的分钟除以十个小时得出工作天数;
+                            item.kitting_time = item.kitting_time.Value.AddDays((double)Day);
+                        }
+                        else if (item.erp_cls == 2 || item.erp_cls == 3)
+                        {
+                            var leadTimeList = GetLeadTime(new List<long> { item.item_id }, input.tenantId, input.factoryId);//提前期列表
+                            var supplierList = GetSupplier(new List<BomChildExamineDto> { item }, input.tenantId, input.factoryId);//供应商列表
+                            var planList = GetICPlan(new List<BomChildExamineDto> { item }, input.tenantId, input.factoryId);//plan列表
+                            item.kitting_time = CreateSRMPR(item, input.tenantId, input.factoryId, bangid, item.erp_cls, leadTimeList, supplierList, planList, plan_date.Value);
+                            if (item.erp_cls == 3)
+                            {
+                                //生成委外工单
+                                CreateMesOOder(item, input.tenantId, input.factoryId, bangid, leadTimeList, supplierList, plan_date.Value);
+                                //1.先生成委外工单。
+                                //2.再根据委外工单需要检查库存材料,然后提供给第三方组装。
+                                //3.如果委外工单的物料库存不够,先生成物料采购申请单,再生成物料的采购订单,到货后再走委外流程。
+                                //4.再生成委外的采购申请单。
+                            }
+                        }
+                    }
+                    else {
+                        item.use_qty = 0;
+                        if (parent.stock_state == 1)
+                        {
+                            //如果父级缺料,则本级等于父级缺料*本级使用数量
+                            item.use_qty = parent.lack_qty * item.qty;
+                            itemStockoccupyDto.quantity = item.use_qty;
+                            sklist.Add(itemStockoccupyDto);
                         }
                     }
+                    item.is_use = true;
+
+                    
                 }
             }
         }
@@ -1512,12 +1624,16 @@ namespace Business.ResourceExamineManagement
                 slt.is_use = true;
                 if (slt.lack_qty > 0)
                 {
-
                     itemStockoccupyDto.quantity = slt.sqty;
                     //库存不够的时候,根据属性生成采购和委外。
                     if (slt.erp_cls == 1)
                     {
                         slt.make_qty = slt.lack_qty;
+                        //走自制
+                        var minute = ProductiveExamine(item.bom_number, "1.0", item.lack_qty.GetInt());
+                        //系统建议完工日期为 开工日期+产能检查时间=完工日期
+                        var Day = minute.Result / (60 * 10); //返回的分钟除以十个小时得出工作天数;
+                        slt.kitting_time = slt.kitting_time.Value.AddDays((double)Day);
                         /*var childList = returnlist.Where(s => s.parent_id == slt.id).ToList();
                         if (childList.Count() > 0)
                         {
@@ -1541,6 +1657,7 @@ namespace Business.ResourceExamineManagement
                 }
                 else
                 {
+                    slt.kitting_time = DateTime.Now;
                     itemStockoccupyDto.quantity = slt.needCount;
                     if (parent != null)
                     {   //如果不缺料的情况下,则占用掉父级缺料乘以当前子集使用料数量
@@ -1729,7 +1846,8 @@ namespace Business.ResourceExamineManagement
                 else
                 {
                     //根据占用情况计算库存
-                    Calczykc(item, sockoccupyList);
+                    Calczykc(item, parent, sockoccupyList);
+                    
                     //如果有子集,则丢入循环,判断下库存可制等信息。
                     calcTest2(item, childList, returnlist, sockoccupyList);
                     /*item.kz = childList.Min(s => s.kz);
@@ -1760,8 +1878,9 @@ namespace Business.ResourceExamineManagement
                 //如果替代料库存不够,但是可制够,则也考虑使用优先级最高
                 foreach (var g in group)
                 {
+                    var parent = returnlist.Find(s => s.id == g.parent_id);
                     //根据占用情况计算库存
-                    Calczykc(g, sockoccupyList);
+                    Calczykc(g, parent, sockoccupyList);
                     /*if (g.stock_state != 1)
                     {
                         //判断此料是否BOM,如果是BOM,就考虑自制是否足够,此处递归检查子集
@@ -1821,7 +1940,7 @@ namespace Business.ResourceExamineManagement
         /// </summary>
         /// <param name="item"></param>
         /// <param name="sockoccupyList"></param>
-        public void Calczykc(BomChildExamineDto item, List<ic_item_stockoccupy> sockoccupyList)
+        public void Calczykc(BomChildExamineDto item, BomChildExamineDto parent, List<ic_item_stockoccupy> sockoccupyList)
         {
             //找到当前物料的占用记录
             var itemSockoccupy = sockoccupyList.Where(s => s.icitem_id == item.item_id).ToList();
@@ -1829,10 +1948,17 @@ namespace Business.ResourceExamineManagement
             item.sqty -= itemSockoccupy.Sum(s => s.quantity);
             //如果库存
             item.sqty = item.sqty < 0 ? 0 : item.sqty;
-            //判断缺料数量
-            item.lack_qty = item.needCount - item.sqty;
-            //判断状态
-            item.stock_state = item.lack_qty > 0 ? 0 : 1;
+            if (parent.stock_state == 1 || parent.stock_state == -1)
+            {
+                item.stock_state = parent.stock_state;
+                item.lack_qty = 0;
+            }
+            else {
+                //判断缺料数量
+                item.lack_qty = parent.lack_qty * item.qty - item.sqty;
+                //判断状态
+                item.stock_state = item.lack_qty > 0 ? 0 : 1;
+            }
         }
 
         #region 替代检查第一版,屏蔽

+ 0 - 9
MicroServices/Business/Bussiness.Model/MES/IC/ic_item_stock.cs

@@ -51,14 +51,5 @@ namespace Bussiness.Model.MES.IC
         [Description("计算id")]
         [NotMapped]
         public long? bang_id { get; set; }
-
-        /// <summary>
-        /// mongodb主键-用于资源检查快照
-        /// </summary>
-        [Description("mongodb主键-用于资源检查快照")]
-        [NotMapped]
-        [BsonId]
-        [BsonRepresentation(MongoDB.Bson.BsonType.Int64)]
-        public long? mongodb_id { get; set; }
     }
 }

+ 7 - 0
MicroServices/Business/Bussiness.Model/Tech/mes_tech_process.cs

@@ -67,6 +67,13 @@ namespace Bussiness.Model.Tech
         [Description("前置最小数量")]
         public decimal? lq { get; set; }
 
+        /// <summary>
+        /// 前置等待时间
+        /// </summary>
+        [Precision(20, 8)]
+        [Description("前置等待时间")]
+        public decimal? lqt { get; set; }
+
         /// <summary>
         /// 子工序加工数量UnitPerParent
         /// </summary>