Explorar el Código

配额管理、工单时长计算。

tangdi hace 2 años
padre
commit
db53c9394c

+ 37 - 0
MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/Dto/PrPurchaseDto.cs

@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Business.ResourceExamineManagement.Dto
+{
+    public class PrPurchaseDto
+    {
+        /// <summary>
+        /// 供应商id
+        /// </summary>
+        public long? pr_purchaseid { get; set; }
+
+        /// <summary>
+        /// 数量
+        /// </summary>
+        public decimal num { get; set; }
+
+        /// <summary>
+        /// 占比
+        /// </summary>
+        public decimal ratio { get; set; }
+
+        /// <summary>
+        /// 优先级
+        /// </summary>
+        public int quota_priority { get; set; }
+
+        /// <summary>
+        /// 配额比例
+        /// </summary>
+        public decimal quota_rate { get; set; }
+
+    }
+}

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

@@ -25,5 +25,10 @@ namespace Business.ResourceExamineManagement.Dto
         /// 计划开始时间
         /// </summary>
         public DateTime PlanStart { get; set; }
+
+        /// <summary>
+        /// 工厂ID
+        /// </summary>
+        public string Domain { get; set; }
     }
 }

+ 73 - 19
MicroServices/Business/Business.Application/ResourceExamineManagement/CalcBomViewAppService.cs

@@ -43,6 +43,10 @@ namespace Business.ResourceExamineManagement
         public crm_seorder seorder = new crm_seorder();
 
         public mes_morder mes_morder = new mes_morder();
+        public List<mo_srm_pr_main> quarter_srm_pr_mains = new List<mo_srm_pr_main>();
+
+        public DateTime quarter_starttime;
+        public DateTime quarter_endtime;
 
         /// <summary>
         /// 是否倒排
@@ -267,14 +271,20 @@ namespace Business.ResourceExamineManagement
                     //先设定在制的齐套时间
                     //level1Dto.satisfy_time = mooccupylist[0]?.moo_etime;
                     level1Dto.stock_state = 0;
-                    
                     if (param.checkflag || (!param.checkflag && param.checkPlan))
                     {
+                        ProdExamineParamDto prodExamine = new ProdExamineParamDto()
+                        {
+                            ItemNum = level1Dto.item_number,
+                            PlanStart = plan_date.GetValueOrDefault(),
+                            QtyOrd = level1Dto.lack_qty,
+                            Domain = param.factoryId.ToString()
+                        };
+                        int make_time = _productExamineAppService.ProductTime(prodExamine);
                         //根据成品属性来判断是自制还是委外还是外购,需要考虑这种场景
                         if (level1Dto.erp_cls == 1 && param.checkflag)
                         {
                             //设置成品的生产时长为子物料的提前准备期
-                            level1Dto.make_time = 7;
                             //param.checkflag=true 销售订单产生工单
                             level1Dto.make_qty = level1Dto.lack_qty;
                             //生成主工单
@@ -292,7 +302,7 @@ namespace Business.ResourceExamineManagement
                                 morder_state = MorderEnum.Initial_state,
                                 bang_id = bangid
                             };
-                            CreateMainOrder(generateMorderDto, level1Dto, childList, returnlist, bangid, plan_date, sklist, sentrys, icitemlist);
+                            CreateMainOrder(generateMorderDto, level1Dto, childList, returnlist, bangid, plan_date, sklist, sentrys, icitemlist, make_time);
                         }
                         else if (level1Dto.erp_cls == 3)
                         {
@@ -319,7 +329,6 @@ namespace Business.ResourceExamineManagement
                                 var mesorder = CreateMesOOder(level1Dto, param.company_id, param.factoryId, bangid, leadTimeList, supplierList, plan_date.Value);
                                 mesorder.ooentry_etime = plan_date.GetValueOrDefault().AddDays(-1);
                                 var srmprDto = PackageSRMPR(level1Dto, bangid, sentrys, plan_date);
-                                level1Dto.make_time = srmprDto.totalLeadTime;//加上物料的采购提前期
                                 mesorder.ooentry_stime = plan_date.GetValueOrDefault().AddDays(-srmprDto.totalLeadTime.GetValueOrDefault());
 
                                 //先计算末级数据的齐套时间。
@@ -358,12 +367,10 @@ namespace Business.ResourceExamineManagement
                         }
                         else
                         {
-                            level1Dto.make_time = 7;
                             MatterTileDevelop(level1Dto, childList, returnlist, sklist, bangid, plan_date, sentrys, icitemlist);
                         }
                     }
                     else {
-                        level1Dto.make_time = 7;
                         MatterTileDevelop(level1Dto, childList, returnlist, sklist, bangid, plan_date, sentrys, icitemlist);
                     }
                     //CalcLevelMakeTime(returnlist);
@@ -401,7 +408,7 @@ namespace Business.ResourceExamineManagement
         /// 生成主工单
         /// </summary>
         public void CreateMainOrder(GenerateMorderDto generateMorderDto, BomChildExamineDto level1Dto, List<BomChildExamineDto> childList, List<BomChildExamineDto> returnlist, long bangid, DateTime
-            ? plan_date, List<mo_ic_item_stockoccupy> sklist, crm_seorderentry sentrys, List<mo_ic_item> icitemlist)
+            ? plan_date, List<mo_ic_item_stockoccupy> sklist, crm_seorderentry sentrys, List<mo_ic_item> icitemlist,int make_time)
         {
             //生成主工单
             _morderAppService.prodLines = prodLines;
@@ -430,12 +437,12 @@ namespace Business.ResourceExamineManagement
                     }
                     mes_Morders.moentry_sys_etime = plan_date.GetValueOrDefault().AddDays(-(int)Math.Floor(LeadTime));
 
-                    mes_Morders.moentry_sys_stime = mes_Morders.moentry_sys_etime.GetValueOrDefault().AddDays(-(level1Dto.make_time.GetValueOrDefault() - 1));
+                    mes_Morders.moentry_sys_stime = mes_Morders.moentry_sys_etime.GetValueOrDefault().AddDays(-(make_time - 1));
                     MatterTileDevelop(level1Dto, childList, returnlist, sklist, bangid, mes_Morders.moentry_sys_stime, sentrys, icitemlist);
                     if (!string.IsNullOrEmpty(mes_Morders.bom_number))
                     {
                         mes_Morders.mat_start_date = childList.Max(s => s.kitting_time.GetValueOrDefault()).AddDays(1).Date;//数据齐套完成后隔天开始生产;
-                        mes_Morders.mat_end_date = mes_Morders.mat_start_date.GetValueOrDefault().AddDays(level1Dto.make_time.GetValueOrDefault());
+                        mes_Morders.mat_end_date = mes_Morders.mat_start_date.GetValueOrDefault().AddDays(make_time);
 
                         /*ProdExamineParamDto prodExamine = new ProdExamineParamDto()
                         {
@@ -666,7 +673,7 @@ namespace Business.ResourceExamineManagement
             var parent = returnlist.Find(s => s.fid == item.parent_id);
             if (item.lack_qty > 0)
             {
-                item.make_time = parent.make_time.GetValueOrDefault();
+                //item.make_time = parent.make_time.GetValueOrDefault();
                 var cilList = returnlist.Where(s => s.parent_id == item.fid && s.type == item.type).OrderBy(k => k.num_order).ToList();
                 //如果缺料,占用库存,然后走采购或自制
                 if (item.sqty > 0)
@@ -733,8 +740,14 @@ namespace Business.ResourceExamineManagement
                             bang_id = bangid
                         };
                         Mes_MorderDto mes_MorderDto = _morderAppService.GenerateMorder(generateMorderDto);
-                        int make = 7;
-                        item.make_time += make;
+                        ProdExamineParamDto prodExamine = new ProdExamineParamDto()
+                        {
+                            ItemNum = item.item_number,
+                            PlanStart = plan_date.GetValueOrDefault(),
+                            QtyOrd = item.lack_qty,
+                            Domain = param.factoryId.ToString()
+                        };
+                        int make = _productExamineAppService.ProductTime(prodExamine);
                         item.make_qty = item.lack_qty;
                         if (mes_MorderDto != null)
                         {
@@ -1163,7 +1176,6 @@ namespace Business.ResourceExamineManagement
                 //对select执行补充(根据属性采购、外购、自制等)
                 foreach (var sct in select)
                 {
-                    sct.make_time = parent.make_time.GetValueOrDefault();
                     decimal sqty = sct.sqty - sct.use_qty;//这里得出前面混用使用后的库存。
                     decimal lack_Count = parent_lack * sct.qty;//混用后还缺的部分。
                     mo_ic_item_stockoccupy itemStockoccupyDto = new mo_ic_item_stockoccupy();
@@ -1258,8 +1270,14 @@ namespace Business.ResourceExamineManagement
                                     bang_id = bangid
                                 };
                                 Mes_MorderDto mes_MorderDto = _morderAppService.GenerateMorder(generateMorderDto);
-                                int make = 7;
-                                sct.make_time += make;
+                                ProdExamineParamDto prodExamine = new ProdExamineParamDto()
+                                {
+                                    ItemNum = sct.item_number,
+                                    PlanStart = plan_date.GetValueOrDefault(),
+                                    QtyOrd = sct.lack_qty,
+                                    Domain = param.factoryId.ToString()
+                                };
+                                int make = _productExamineAppService.ProductTime(prodExamine);
                                 sct.make_qty = sct.lack_qty;
                                 if (mes_MorderDto != null)
                                 {
@@ -1335,7 +1353,6 @@ namespace Business.ResourceExamineManagement
                                     var mesorder = CreateMesOOder(sct, param.company_id, param.factoryId, bangid, leadTimeList, supplierList, plan_date.GetValueOrDefault());
                                     mesorder.ooentry_etime = plan_date.GetValueOrDefault().AddDays(-1);
                                     var srmprDto = PackageSRMPR(sct, bangid, sentrys, plan_date);
-                                    sct.make_time += srmprDto.totalLeadTime;//加上物料的采购提前期
                                     mesorder.start_time = mesorder.ooentry_etime.GetValueOrDefault().AddDays(-(srmprDto.totalLeadTime.GetValueOrDefault() - 1));
 
                                     //先计算末级数据的齐套时间。
@@ -1421,15 +1438,52 @@ namespace Business.ResourceExamineManagement
                 //判断当前时间与交期还剩余多少天
                 var timesp = plan_date.GetValueOrDefault() - DateTime.Now.Date;
                 //交期-生产时长-物料前处理周期
-                day = Math.Floor(timesp.Days - returnlist.make_time.GetValueOrDefault() - returnlist.clean_leadtime.GetValueOrDefault());
+                day = Math.Floor(timesp.Days - returnlist.clean_leadtime.GetValueOrDefault());
                 if (day > 0)
                 {
                     supplist = supplist.Where(s => s.lead_time.GetValueOrDefault() < day).ToList();
                     if (supplist.Any())
                     {
                         //TODO:走配额管理
-                        //按配额比例,计算使用哪个供应商。
-                        supplier = supplist.OrderByDescending(s => s.quota_priority).FirstOrDefault();//默认取配额优先级
+                        List<mo_srm_pr_main> itemPrlist = quarter_srm_pr_mains.Where(s => s.icitem_id == returnlist.item_id).ToList();
+                        if (itemPrlist.Any())
+                        {
+                            decimal qtyCount = itemPrlist.Sum(x => x.pr_aqty).GetValueOrDefault();
+                            //按配额比例,计算使用哪个供应商。
+                            List<PrPurchaseDto> PrPurchaseDtoList = new List<PrPurchaseDto>();
+                            supplist.ForEach(s => {
+                                PrPurchaseDto purDto = new PrPurchaseDto();
+                                purDto.pr_purchaseid = s.supplier_id;
+                                purDto.num = itemPrlist.Where(x => x.pr_purchaseid == s.supplier_id).Sum(c => c.pr_aqty.GetValueOrDefault());
+                                purDto.ratio = Math.Round(purDto.num / qtyCount, 2, MidpointRounding.AwayFromZero);
+                                purDto.quota_priority = s.quota_priority;
+                                purDto.quota_rate = s.quota_rate.GetValueOrDefault();
+                                PrPurchaseDtoList.Add(purDto);
+                            });
+
+                            //首先取出占比还小于配额比的数据
+                            var priorityPurlist = PrPurchaseDtoList.Where(s => s.quota_rate - s.ratio > 2).ToList();
+                            if (!priorityPurlist.Any())
+                            {
+                                //没有则取出当前集合中的供应商的数据,计算差额
+                                priorityPurlist = PrPurchaseDtoList;
+                            }
+                            //还没有达到配额比的供应商,优先分配
+                            decimal difference = 0;
+                            PrPurchaseDto dto1 = priorityPurlist[0];
+                            priorityPurlist.ForEach(s => {
+                                decimal diff = s.quota_rate - s.ratio;
+                                if (diff > difference)
+                                {
+                                    difference = diff;
+                                    dto1 = s;
+                                }
+                            });
+                            supplier = supplist.Find(s => s.supplier_id == dto1.pr_purchaseid);
+                        }
+                        else {
+                            supplier = supplist.OrderBy(s => s.quota_priority).FirstOrDefault();//默认取配额优先级
+                        }
                     }
                     else
                     {

+ 20 - 0
MicroServices/Business/Business.Application/ResourceExamineManagement/ProductExamineAppService.cs

@@ -54,6 +54,26 @@ namespace Business.ResourceExamineManagement
         {
         }
 
+        /// <summary>
+        /// 根据标准工艺获取生产时长(天)
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        public int ProductTime(ProdExamineParamDto param)
+        {
+            var rtOps = routingOps.Where(s => s.RoutingCode == param.ItemNum && s.Domain == param.Domain && s.MilestoneOp == true).ToList();
+            if (rtOps.Any())
+            { 
+                decimal maxRt = rtOps.Max(s => s.RunTime);
+                decimal sumRt = rtOps.Sum(s => s.RunTime);
+                decimal totalTime = (param.QtyOrd - 1) * maxRt + sumRt;//总计生产小时
+                return (int)(Math.Floor(totalTime / 8));
+            }
+            return 1;
+        }
+
+
+
         /// <summary>
         /// 产能计算-批量
         /// </summary>

+ 5 - 1
MicroServices/Business/Business.Application/ResourceExamineManagement/ResourceExamineAppService.cs

@@ -2060,7 +2060,7 @@ namespace Business.ResourceExamineManagement
                     poDto.polist = new List<srm_po_list>();
                     pOGroupDtos.Add(poDto);
                 }
-                item.state = 0;
+                item.state = 4;
                 srm_po_list podetail = new srm_po_list();
                 podetail.GenerateNewId(help.NextId());
                 podetail.pr_id = item.Id;
@@ -3246,6 +3246,10 @@ namespace Business.ResourceExamineManagement
             _CalcBomViewAppService.srm_Po_Occupies = poOccupys; //采购占用表
             _CalcBomViewAppService.ic_item_List = icitemlist; //物料表
             _CalcBomViewAppService.srm_Pr_Mains = srm_pr_mains;//PR
+            DateTime dt = DateTime.Now;
+            _CalcBomViewAppService.quarter_starttime = dt.AddMonths(0 - (dt.Month - 1) % 3).AddDays(1 - dt.Day).Date;
+            _CalcBomViewAppService.quarter_endtime = _CalcBomViewAppService.quarter_starttime.AddMonths(3);
+            _CalcBomViewAppService.quarter_srm_pr_mains = srm_pr_mains.Where(s => s.pr_psend_date >= _CalcBomViewAppService.quarter_starttime && s.pr_psend_date < _CalcBomViewAppService.quarter_endtime).ToList();//本季度PR
         }
 
         public void GenerateSort(List<BomChildExamineDto> returnlist)