Kaynağa Gözat

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

# Conflicts:
#	MicroServices/Business/Business.Application/ResourceExamineManagement/ResourceExamineAppService.cs
tangdi 2 yıl önce
ebeveyn
işleme
7c91a89098

+ 22 - 24
MicroServices/Business/Business.Application/ResourceExamineManagement/ResourceExamineAppService.cs

@@ -1797,9 +1797,8 @@ namespace Business.ResourceExamineManagement
                 var mes_mooccupy = _mysql_mes_mooccupy.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId && mes_morder.Select(c => c.morder_no).Contains(x.moo_mo)).Result;
                 if (mes_mooccupy.Count > 0)
                 {
-                    mes_mooccupy.ForEach(item => { item.bang_id = bangid; });
                     var moMes_mooccupy = ObjectMapper.Map<List<mes_mooccupy>, List<mo_mes_mooccupy>>(mes_mooccupy);
-                    moMes_mooccupy.ForEach(item => { item.GenerateNewId(help.NextId()); });
+                    moMes_mooccupy.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; });
                     await _mes_mooccupy.InsertManyAsync(moMes_mooccupy);
                 }
             }
@@ -1808,9 +1807,8 @@ namespace Business.ResourceExamineManagement
             var srm_po_main = _mysql_srm_po_main.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId).Result;
             if (srm_po_main.Count > 0)
             {
-                srm_po_main.ForEach(item => { item.bang_id = bangid; });
                 var moSrm_po_main = ObjectMapper.Map<List<srm_po_main>, List<mo_srm_po_main>>(srm_po_main);
-                moSrm_po_main.ForEach(item => { item.GenerateNewId(help.NextId()); });
+                moSrm_po_main.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; });
                 await _srm_po_main.InsertManyAsync(moSrm_po_main);
             }
 
@@ -1818,9 +1816,8 @@ namespace Business.ResourceExamineManagement
             var srm_po_list = _mysql_srm_po_list.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId).Result;
             if (srm_po_list.Count > 0)
             {
-                srm_po_list.ForEach(item => { item.bang_id = bangid; });
                 var moSrm_po_list = ObjectMapper.Map<List<srm_po_list>, List<mo_srm_po_list>>(srm_po_list);
-                moSrm_po_list.ForEach(item => { item.GenerateNewId(help.NextId()); });
+                moSrm_po_list.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; });
                 await _srm_po_list.InsertManyAsync(moSrm_po_list);
             }
 
@@ -1828,9 +1825,8 @@ namespace Business.ResourceExamineManagement
             var srm_po_occupy = _mysql_srm_po_occupy.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId).Result;
             if (srm_po_occupy.Count > 0)
             {
-                srm_po_occupy.ForEach(item => { item.bang_id = bangid; });
                 var moSrm_po_occupy = ObjectMapper.Map<List<srm_po_occupy>, List<mo_srm_po_occupy>>(srm_po_occupy);
-                moSrm_po_occupy.ForEach(item => { item.GenerateNewId(help.NextId()); });
+                moSrm_po_occupy.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; });
                 await _srm_po_occupy.InsertManyAsync(moSrm_po_occupy);
             }
         }
@@ -2244,16 +2240,18 @@ namespace Business.ResourceExamineManagement
                 foreach (var pr in prlist)
                 {
                     //找到没有关闭的PR,如果关联上的PR都是已关闭,则说明已经转了PO。
+                    //TODO:解决Database operation expected to affect 1 row(s) but actually affected 0 row(s). 如果业务逻辑有问题自行修改
                     var getPr = RerunPr(pr, alllist);
                     if (getPr != null)
                     {
-                        getPr.pr_aqty = getPr.pr_aqty - pr.pr_aqty;
-                        if (getPr.pr_aqty <= 0)
+                        if (getPr.pr_aqty - pr.pr_aqty <= 0)
                         {
                             //删除这个pr,没有小于0则是更新
                             dellist.Add(getPr);
                         }
-                        else {
+                        else 
+                        {
+                            getPr.pr_aqty = getPr.pr_aqty - pr.pr_aqty;
                             updatelist.Add(getPr);
                         }
                     }
@@ -2843,7 +2841,7 @@ namespace Business.ResourceExamineManagement
                     var wkordPrList = prmainlist.Where(s => s.pr_mono == wod.WorkOrd).ToList();
 
                     //反算所有的PR,根据时间减去提前期   //按最大预处理时间倒排
-                    var moIcitems = icitemlist.Where(s => wkordPrList.Select(c => c.icitem_id).Contains(s.Id)).ToList();
+                    var moIcitems = icitemlist.Where(s => wkordPrList.Select(c => c.icitem_id).Contains(s.mysql_id)).ToList();
                     var maxTime = moIcitems.Max(s => s.clean_leadtime.GetValueOrDefault());
                     wkordPrList.ForEach(pr =>
                     {
@@ -3125,7 +3123,7 @@ namespace Business.ResourceExamineManagement
                     }
                     nbrMasterList.Add(new NbrMaster
                     {
-                        Domain = "1001",
+                        Domain = workOrdMasters[0].Domain,
                         Type = "SM",
                         Nbr = Nbr,
                         Remark = "下达自动领料",
@@ -3138,12 +3136,12 @@ namespace Business.ResourceExamineManagement
                         QtyOrd = QtyOrdSum,
                         IsActive = true,
                         IsChanged = true,
-                        Name = "1001",
+                        Name = workOrdMasters[0].Domain,
                         Department = "101",
                         CreateTime = DateTime.Now,
                         UpdateTime = DateTime.Now,
-                        CreateUser = "1001",
-                        UpdateUser = "1001"
+                        CreateUser = workOrdMasters[0].Domain,
+                        UpdateUser = workOrdMasters[0].Domain
                     });
                     int i = 1;
                     itemList?.ForEach(a =>
@@ -3160,7 +3158,7 @@ namespace Business.ResourceExamineManagement
                         {
                             nbrDetailList.Add(new NbrDetail
                             {
-                                Domain = "1001",
+                                Domain = workOrdMasters[0].Domain,
                                 Type = "SM",
                                 Nbr = Nbr,
                                 ItemNum = a.ComponentItem,
@@ -3175,8 +3173,8 @@ namespace Business.ResourceExamineManagement
                                 IsActive = true,
                                 CreateTime = DateTime.Now,
                                 UpdateTime = DateTime.Now,
-                                CreateUser = "1001",
-                                UpdateUser = "1001",
+                                CreateUser = workOrdMasters[0].Domain,
+                                UpdateUser = workOrdMasters[0].Domain,
                                 UM = a.UM
                             });
                             i++;
@@ -3219,7 +3217,7 @@ namespace Business.ResourceExamineManagement
                     //TODO:
                     //因为我们并没有模拟发料的过程,在自动生成领料单的时候就要扣减库存,实际业务不能这么做。
                     //在有上料和追溯的系统,可以在扫码上料或报工时(从线边仓)扣减。或者在实际发料出库时扣减。
-                    var locStock = _locationDetail.Select(a => itemKeys.Contains(a.ItemNum) && a.IsActive && a.Domain == "1001");
+                    var locStock = _locationDetail.Select(a => itemKeys.Contains(a.ItemNum) && a.IsActive && a.Domain == workOrdMasters[0].Domain);
                     locStock?.ForEach(a =>
                     {
                         nbrDetailList.ForEach(b =>
@@ -3406,13 +3404,13 @@ namespace Business.ResourceExamineManagement
                 return "没有需要下达的工单。";
             }
             //获取已排产的工单
-            List<PeriodSequenceDet> dbPeriodSequences = _periodSequenceDet.Select(p => workOrds.Contains(p.WorkOrds) && p.Domain == "1001" && p.IsActive);
+            List<PeriodSequenceDet> dbPeriodSequences = _periodSequenceDet.Select(p => workOrds.Contains(p.WorkOrds) && p.Domain == workOrdMasters[0].Domain && p.IsActive);
             List<string> dbWorkOrds = dbPeriodSequences.Select(p => p.WorkOrds).Distinct().ToList();
 
             //查出已排产的工单
             workOrdMasters = workOrdMasters.Where(p => dbWorkOrds.Contains(p.WorkOrd)).ToList();
             //查出已产生领料单、过滤掉,取出未领料的工单
-            var nbrList = _nbrMaster.Select(a => a.Domain == "1001" && a.Type == "SM" && dbWorkOrds.Contains(a.WorkOrd));
+            var nbrList = _nbrMaster.Select(a => a.Domain == workOrdMasters[0].Domain && a.Type == "SM" && dbWorkOrds.Contains(a.WorkOrd));
             var noNbrlist = nbrList.Select(p => p.WorkOrd).ToList();
             workOrdMasters = workOrdMasters.Where(p => !noNbrlist.Contains(p.WorkOrd)).ToList();
             if (workOrdMasters.Count == 0)
@@ -3431,7 +3429,7 @@ namespace Business.ResourceExamineManagement
                 dbPeriodSequences.ForEach(p => { p.Status = "r"; });
                 workOrdMasters.ForEach(p => { p.Status = "r"; });
                 //获取工单工艺路径数据
-                List<WorkOrdRouting> workOrdRoutings = _workOrdRouting.Select(p => ords.Contains(p.WorkOrd) && p.MilestoneOp && p.Domain == "1001" && p.Status != "C" && p.IsActive);
+                List<WorkOrdRouting> workOrdRoutings = _workOrdRouting.Select(p => ords.Contains(p.WorkOrd) && p.MilestoneOp && p.Domain == workOrdMasters[0].Domain && p.Status != "C" && p.IsActive);
                 workOrdRoutings.ForEach(p => { p.Status = "r"; });
                 using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
                 {
@@ -3445,7 +3443,7 @@ namespace Business.ResourceExamineManagement
                         });
                         //快开平台用自增列RecId关联,所以需要插入后再查给明细表赋相应的值
                         List<string> nbrs = nbrMasterList.Select(a => a.Nbr).ToList();
-                        var DBnbrList = _nbrMaster.Select(a => a.Domain == "1001" && a.Type == "SM" && nbrs.Contains(a.Nbr));
+                        var DBnbrList = _nbrMaster.Select(a => a.Domain == workOrdMasters[0].Domain && a.Type == "SM" && nbrs.Contains(a.Nbr));
                         nbrDetailList.ForEach(c =>
                         {
                             c.NbrRecID = DBnbrList.Where(a => a.Nbr == c.Nbr).First().RecID;

+ 112 - 156
MicroServices/Business/Business.Application/SaleForecastManagement/MonthlyCapacityLoadAppService.cs

@@ -17,6 +17,7 @@ using Volo.Abp.DependencyInjection;
 using Volo.Abp.Domain.Repositories;
 using Volo.Abp.MultiTenancy;
 using Volo.Abp.Uow;
+using Volo.Abp.Validation.Localization;
 
 namespace Business.SaleForecastManagement
 {
@@ -51,16 +52,6 @@ namespace Business.SaleForecastManagement
         /// </summary>
         private ISqlRepository<HolidayMaster> _holidayMaster;
 
-        /// <summary>
-        /// 月度产能共识主表
-        /// </summary>
-        private ISqlRepository<MonthlyProdCapacityMain> _monthlyProdCapacityMain;
-
-        /// <summary>
-        /// 月度产能共识明细表
-        /// </summary>
-        private ISqlRepository<MonthlyProdCapacityDtl> _monthlyProdCapacityDtl;
-
         /// <summary>
         /// 工作单元
         /// </summary>
@@ -116,6 +107,11 @@ namespace Business.SaleForecastManagement
         /// </summary>
         private IRepository<OverallDemandPlan, long> _overallDemandPlan;
 
+        /// <summary>
+        /// 月度产能共识表
+        /// </summary>
+        private IRepository<MonthlyProdCapacity, long> _monthlyProdCapacity;
+
         /// <summary>
         /// 雪花算法
         /// </summary>
@@ -132,8 +128,7 @@ namespace Business.SaleForecastManagement
             ISqlRepository<ShopCalendarWorkCtr> shopCalendarWorkCtr,
             ISqlRepository<QualityLineWorkDetail> qualityLineWorkDetail,
             ISqlRepository<HolidayMaster> holidayMaster,
-            ISqlRepository<MonthlyProdCapacityMain> monthlyProdCapacityMain,
-            ISqlRepository<MonthlyProdCapacityDtl> monthlyProdCapacityDtl,
+            IRepository<MonthlyProdCapacity, long> monthlyProdCapacity,
             IUnitOfWorkManager unitOfWorkManager,
             ICurrentTenant currentTenant,
             IRepository<StandardItemModelSet,long> standardItemModelSet,
@@ -152,8 +147,7 @@ namespace Business.SaleForecastManagement
             _shopCalendarWorkCtr = shopCalendarWorkCtr;
             _qualityLineWorkDetail = qualityLineWorkDetail;
             _holidayMaster = holidayMaster;
-            _monthlyProdCapacityMain = monthlyProdCapacityMain;
-            _monthlyProdCapacityDtl = monthlyProdCapacityDtl;
+            _monthlyProdCapacity = monthlyProdCapacity;
             _unitOfWorkManager = unitOfWorkManager;
             _currentTenant = currentTenant;
             _standardItemModelSet = standardItemModelSet;
@@ -168,147 +162,6 @@ namespace Business.SaleForecastManagement
         }
         #endregion
 
-        ///// <summary>
-        ///// 产能分析
-        ///// </summary>
-        ///// <param name="input"></param>
-        ///// <returns></returns>
-        ///// <exception cref="NotImplementedException"></exception>
-        //public async Task<string> CapacityAnalysis(InputDto input)
-        //{
-        //    //1、获取数据
-        //    //1.1 根据年、月、版本号获取整体需求计划明细
-        //    List<OverallDemandPlanDtl> planDtls = _overallDemandPlanDtl.Select(p => p.Year == input.year && p.Month == input.month && p.Version == input.version && p.tenant_id == input.tenant_id && p.factory_id == input.factory_id).OrderBy(p => p.ProdLine).ThenBy(p => p.ProdRange).ThenBy(p => p.Model).ThenBy(p => p.PlanDate).ToList();
-        //    //1.2 根据规格型号获取物料数据
-        //    List<string> models = planDtls.Select(p => p.Model).Distinct().ToList();
-        //    List<StandardItemModelSet> standards = _standardItemModelSet.Select(p => models.Contains(p.Model) && p.tenant_id == input.tenant_id && p.factory_id == input.factory_id);
-        //    //1.3 根据物料编码获取产线数据
-        //    List<ProdLineDetail> lines = _prodLineDetail.Select(p => standards.Select(m => m.ItemNumber).Contains(p.Part) && p.Domain == input.factory_id.ToString() && p.IsActive);
-        //    //1.4 根据产线获取工作日历数据和产线休息配置数据
-        //    List<ShopCalendarWorkCtr> calendars = _shopCalendarWorkCtr.Select(p => lines.Select(m => m.Line).Contains(p.ProdLine) && p.Domain == input.factory_id.ToString() && p.IsActive);
-        //    List<QualityLineWorkDetail> lineWorks = _qualityLineWorkDetail.Select(p => lines.Select(m => m.Line).Contains(p.ProdLine) && p.Domain == input.factory_id.ToString() && p.IsActive);
-        //    //1.5 获取当前年和下一年的节假日配置数据
-        //    List<HolidayMaster> holidays = _holidayMaster.Select(p => (p.Dated.Value.Year == input.year || p.Dated.Value.Year == (input.year + 1)) && p.Domain == input.factory_id.ToString() && p.IsActive);
-
-        //    //月度产能共识主表
-        //    List<MonthlyProdCapacityMain> capacityMains = new List<MonthlyProdCapacityMain>();
-        //    //月度产能共识明细表
-        //    List<MonthlyProdCapacityDtl> capacityDtls = new List<MonthlyProdCapacityDtl>();
-        //    foreach (var item in planDtls)
-        //    {
-        //        //获取当前产品的生产线
-        //        var std = standards.FirstOrDefault(p => p.Model == item.Model);
-        //        if (std == null)
-        //        {
-        //            new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("CapacityAnalysis", "规格型号【" + item.Model + "】没有维护标准物料数据", _currentTenant.Id.ToString());
-        //            return "NO|规格型号【" + item.Model + "】没有维护标准物料数据,请维护后再发布!";
-        //        }
-        //        var curLines = lines.Where(p => p.Part == std.ItemNumber).OrderBy(p => p.Line).ToList();
-        //        //过滤产线
-        //        var distLines = curLines.Select(p => p.Line).Distinct().ToList();
-        //        if (distLines.Count == 0)
-        //        {
-        //            new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("CapacityAnalysis", "物料【" + std.ItemNumber + "】没有维护产线数据", _currentTenant.Id.ToString());
-        //            return "NO|物料【" + std.ItemNumber + "】没有维护产线数据,请维护后再发布!";
-        //        }
-        //        foreach (var dl in distLines)
-        //        {
-        //            //添加月度产能共识主表数据
-        //            MonthlyProdCapacityMain main = new MonthlyProdCapacityMain();
-        //            main.Id = help.NextId();
-        //            main.Version = input.version;//整体需求计划版本号
-        //            main.Year = Convert.ToInt16(item.PlanDate.Substring(0, 4));
-        //            main.Month = Convert.ToInt16(item.PlanDate.Substring(4, 2));
-        //            main.ProdRange = item.ProdRange;
-        //            main.Model = item.Model;
-        //            main.ProdQty = item.Qty;
-        //            main.ProdLine = dl;
-        //            main.Qty = item.Qty;
-        //            main.tenant_id = item.tenant_id;
-        //            main.factory_id = item.factory_id;
-        //            main.Version = item.Version;
-        //            main.CreateTime = DateTime.Now;
-        //            capacityMains.Add(main);
-
-        //            //添加月度产能共识产能效率数据
-        //            MonthlyProdCapacityDtl dtl = new MonthlyProdCapacityDtl();
-        //            dtl.MainId = main.Id;
-        //            dtl.Version = input.version;
-        //            dtl.Year = main.Year;
-        //            dtl.Month = main.Month;
-        //            dtl.ProdLine = dl;
-        //            //计算每天工作时间
-        //            var curCal = calendars.FirstOrDefault(p => p.ProdLine == dl);
-        //            if (curCal == null)
-        //            {
-        //                continue;
-        //            }
-        //            dtl.DailyWorks = curCal.ShiftsHours1;
-        //            dtl.FlightQty = 1;
-        //            //计算当月工作天数
-        //            var curHoildays = holidays.Where(p => p.Dated.Value.Year == main.Year && p.Dated.Value.Month == main.Month).ToList();
-        //            //当月天数
-        //            int days = DateTime.DaysInMonth(main.Year.Value, main.Month.Value);
-        //            //当月周末天数
-        //            int weekDays = CalcWeekDays(days, Convert.ToDateTime(main.Year.ToString() + "-" + main.Month.ToString() + "-01"));
-        //            dtl.YearWorks = days - weekDays - curHoildays.Where(p => p.Ufld1 == "休假").Count() + curHoildays.Where(p => p.Ufld1 == "调班").Count();
-        //            dtl.AvailableTimes = dtl.DailyWorks * dtl.FlightQty * dtl.YearWorks;
-        //            //计算产线耗时
-        //            var line = curLines.Where(p => p.Line == dl).OrderByDescending(p => p.Op).First();
-        //            dtl.NeedWorks = line.Rate == 0 ? 0 : (Math.Ceiling(main.Qty.GetValueOrDefault() / line.Rate));
-        //            dtl.ProdRate = 100;
-        //            dtl.Rate = dtl.AvailableTimes == 0 ? 0 : Math.Floor(dtl.NeedWorks.GetValueOrDefault() / dtl.AvailableTimes.GetValueOrDefault() * 100);
-        //            dtl.IsOverTime = dtl.NeedWorks > dtl.YearWorks ? "是" : "否";
-        //            dtl.OverTimes = dtl.IsOverTime == "是" ? (dtl.NeedWorks - dtl.YearWorks) : 0;
-        //            dtl.tenant_id = main.tenant_id;
-        //            dtl.factory_id = main.factory_id;
-        //            capacityDtls.Add(dtl);
-        //        }
-        //    }
-        //    //保存数据
-        //    using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
-        //    {
-        //        try
-        //        {
-        //            //先删除数据
-        //            _monthlyProdCapacityMain.Delete(p => p.tenant_id == input.tenant_id && p.factory_id == input.factory_id && p.Version.Contains(input.version.Substring(0, 7)));
-        //            _monthlyProdCapacityDtl.Delete(p => p.tenant_id == input.tenant_id && p.factory_id == input.factory_id && p.Version.Contains(input.version.Substring(0, 7)));
-
-        //            //插入数据
-        //            _monthlyProdCapacityMain.Insert(capacityMains);
-        //            _monthlyProdCapacityDtl.Insert(capacityDtls);
-        //            await unitOfWork.CompleteAsync();
-        //        }
-        //        catch (Exception e)
-        //        {
-        //            unitOfWork.Dispose();
-        //            new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("CapacityAnalysis", "生成【" + input.year + "年" + input.month + "月】月度产能共识失败:" + e.Message, _currentTenant.Id.ToString());
-        //            return "NO|" + e.Message;
-        //        };
-        //    }
-        //    return "OK|发布成功!";
-        //}
-
-        /// <summary>
-        /// 计算当月有多少个周末
-        /// </summary>
-        /// <param name="days"></param>
-        /// <param name="startDay"></param>
-        /// <returns></returns>
-        private int CalcWeekDays(int days, DateTime startDay)
-        {
-            int sumDays = 0;
-            for (int i = 0; i < days; i++)
-            {
-                int weekDays = (int)startDay.AddDays(i).DayOfWeek;
-                if (weekDays == 0 || weekDays == 6)
-                {
-                    sumDays++;
-                }
-            }
-            return sumDays;
-        }
-
         /// <summary>
         /// 月度需求预测更新
         /// </summary>
@@ -404,13 +257,16 @@ namespace Business.SaleForecastManagement
             }
             #endregion
 
-            //计算当前年月的N+1,N+2
+            //计算当前年月的N0,N+1,N+2
+            List<string> planMons = new List<string>();
             int newYear = input.month == 12 ? input.year + 1 : input.year;
             int newMonth = input.month == 12 ? 1 : input.month + 1;
             string strN1 = newYear.ToString() + "-" + newMonth.ToString("00");
+            planMons.Add(strN1);
             newYear = newMonth == 12 ? newYear + 1 : newYear;
             newMonth = newMonth == 12 ? 1 : newMonth + 1;
             string strN2 = newYear.ToString() + "-" + newMonth.ToString("00");
+            planMons.Add(strN2);
 
             //需要回写的数据
             List<YearDemandManagement> updates = new List<YearDemandManagement>();
@@ -540,6 +396,9 @@ namespace Business.SaleForecastManagement
             }
             #endregion
 
+            //生成月度产能共识
+            List<MonthlyProdCapacity> capacities = CapacityAnalysis(input, updates, planMons);
+
             //保存数据
             using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
             {
@@ -562,6 +421,10 @@ namespace Business.SaleForecastManagement
                     }
                     //回写年度生产大纲
                     await _yearDemandManagement.UpdateManyAsync(updates);
+                    //先删除产能共识
+                    await _monthlyProdCapacity.HardDeleteAsync(p=>p.Year == input.year && p.Month == input.month && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id);
+                    await _monthlyProdCapacity.InsertManyAsync(capacities);
+
                     await unitOfWork.CompleteAsync();
                 }
                 catch (Exception e)
@@ -574,6 +437,79 @@ namespace Business.SaleForecastManagement
             return "OK|修订成功!";
         }
 
+        /// <summary>
+        /// 生成月度产能共识
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public List<MonthlyProdCapacity> CapacityAnalysis(InputDto input,List<YearDemandManagement> yearDemands, List<string> planMons)
+        {
+            //1、获取数据
+            //1.1 根据规格型号获取物料数据
+            List<string> models = yearDemands.Select(p => p.Model).Distinct().ToList();
+            List<StandardItemModelSet> standards = _standardItemModelSet.GetListAsync(p => models.Contains(p.Model) && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id).Result;
+            //1.3 根据物料编码获取产线数据
+            List<ProdLineDetail> lineDtls = _prodLineDetail.Select(p => standards.Select(m => m.ItemNumber).Contains(p.Part) && p.Domain == input.factory_id.ToString() && p.IsActive).OrderBy(p => p.Line).ToList();
+            //1.4 根据产线获取工作日历数据和产线休息配置数据
+            List<ShopCalendarWorkCtr> calendars = _shopCalendarWorkCtr.Select(p => lineDtls.Select(m => m.Line).Contains(p.ProdLine) && p.Domain == input.factory_id.ToString() && p.IsActive);
+            List<QualityLineWorkDetail> lineWorks = _qualityLineWorkDetail.Select(p => lineDtls.Select(m => m.Line).Contains(p.ProdLine) && p.Domain == input.factory_id.ToString() && p.IsActive);
+            //1.5 获取当前年和下一年的节假日配置数据
+            List<HolidayMaster> holidays = _holidayMaster.Select(p => (p.Dated.Value.Year == input.year || p.Dated.Value.Year == (input.year + 1)) && p.Domain == input.factory_id.ToString() && p.IsActive);
+
+            //月度产能共识表
+            List<MonthlyProdCapacity> capacities = new List<MonthlyProdCapacity>();
+            //产线
+            List<string> lines = lineDtls.Select(p => p.Line).Distinct().ToList();
+            foreach (var item in lines)
+            {
+                //计算每天工作时间
+                var curCal = calendars.FirstOrDefault(p => p.ProdLine == item);
+                if (curCal == null)
+                {
+                    continue;
+                }
+                foreach (var pm in planMons)
+                {
+                    //添加月度产能共识产能效率数据
+                    MonthlyProdCapacity dtl = new MonthlyProdCapacity();
+                    dtl.Year = input.year;
+                    dtl.Month = input.month;
+                    dtl.PlanMonth = pm;
+                    dtl.ProdLine = item;
+
+                    dtl.DailyWorks = curCal.ShiftsHours1 + curCal.ShiftsHours2 + curCal.ShiftsHours3 + curCal.ShiftsHours4;
+                    dtl.FlightQty = 1;
+                    //计算当月工作天数
+                    var curHoildays = holidays.Where(p => p.Dated.Value.Year == Convert.ToInt16(pm.Substring(0,4)) && p.Dated.Value.Month == Convert.ToInt16(pm.Substring(5, 2))).ToList();
+                    //当月天数
+                    int days = DateTime.DaysInMonth(input.year, input.month);
+                    //当月周末天数
+                    int weekDays = CalcWeekDays(days, Convert.ToDateTime(pm + "-01"));
+                    dtl.MonthWorks = days - weekDays - curHoildays.Where(p => p.Ufld1 == "休假").Count() + curHoildays.Where(p => p.Ufld1 == "调班").Count();
+                    dtl.AvailableTimes = dtl.DailyWorks * dtl.MonthWorks;
+                    //计算产线耗时
+                    var curLines = lineDtls.Where(p => p.Line == item).ToList();
+                    var line = curLines.OrderByDescending(p => p.Op).First();
+                    var curStands = standards.Where(p=> curLines.Select(m=>m.Part).Contains(p.ItemNumber)).ToList();
+                    var curDemands = yearDemands.Where(p => curStands.Select(m => m.Model).Contains(p.Model) && p.PlanMonth == pm).ToList();
+                    dtl.NeedWorks = line.Rate == 0 ? 0 : (Math.Ceiling(curDemands.Sum(p=>p.Qty) / line.Rate));
+                    dtl.ProdRate = 100;
+                    dtl.Rate = dtl.AvailableTimes == 0 ? 0 : Math.Floor(dtl.NeedWorks / dtl.AvailableTimes * 100);
+                    dtl.IsOverTime = dtl.NeedWorks > dtl.AvailableTimes ? "是" : "否";
+                    dtl.OverTimes = dtl.IsOverTime == "是" ? (dtl.NeedWorks - dtl.AvailableTimes) : 0;
+                    dtl.tenant_id = input.tenant_id;
+                    dtl.company_id= input.company_id;
+                    dtl.factory_id = input.factory_id;
+                    dtl.org_id= input.org_id;
+                    dtl.create_by= input.create_by;
+                    dtl.create_by_name = input.create_by_name;
+                    dtl.create_time = DateTime.Now;
+                    capacities.Add(dtl);
+                }
+            }
+            return capacities;
+        }
+
         /// <summary>
         /// 计算再订货点
         /// </summary>
@@ -601,6 +537,26 @@ namespace Business.SaleForecastManagement
             return rop;
         }
 
+        /// <summary>
+        /// 计算当月有多少个周末
+        /// </summary>
+        /// <param name="days"></param>
+        /// <param name="startDay"></param>
+        /// <returns></returns>
+        private int CalcWeekDays(int days, DateTime startDay)
+        {
+            int sumDays = 0;
+            for (int i = 0; i < days; i++)
+            {
+                int weekDays = (int)startDay.AddDays(i).DayOfWeek;
+                if (weekDays == 0 || weekDays == 6)
+                {
+                    sumDays++;
+                }
+            }
+            return sumDays;
+        }
+
         /// <summary>
         /// 生成整体需求计划
         /// </summary>

+ 0 - 92
MicroServices/Business/Business.Domain/StructuredDB/Production/MonthlyProdCapacityMain.cs

@@ -1,92 +0,0 @@
-using Microsoft.EntityFrameworkCore;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Business.Domain
-{
-    /// <summary>
-    /// 月度产能共识主表
-    /// </summary>
-    [Comment("月度产能共识主表")]
-    [Index(nameof(Year), nameof(Month), nameof(ProdRange), nameof(Model), nameof(ProdLine), nameof(tenant_id), nameof(factory_id), IsUnique = true)]
-    public class MonthlyProdCapacityMain
-    {
-        /// <summary>
-        /// 主键
-        /// </summary>
-        [Comment("主键")]
-        [Key]
-        public long Id { get; set; }
-
-        /// <summary>
-        /// 年
-        /// </summary>
-        [Comment("年")]
-        public int? Year { get; set; }
-
-        /// <summary>
-        /// 月
-        /// </summary>
-        [Comment("月")]
-        public int? Month { get; set; }
-
-        /// <summary>
-        /// 产品系列
-        /// </summary>
-        [Comment("产品系列")]
-        public string ProdRange { get; set; }
-
-        /// <summary>
-        /// 规格型号
-        /// </summary>
-        [Comment("规格型号")]
-        public string Model { get; set; }
-
-        /// <summary>
-        /// 产品数量
-        /// </summary>
-        [Comment("产品数量")]
-        public decimal? ProdQty { get; set; }
-
-        /// <summary>
-        /// 生产线
-        /// </summary>
-        [Comment("生产线")]
-        public string ProdLine { get; set; }
-
-        /// <summary>
-        /// 产线生产数量
-        /// </summary>
-        [Comment("产线生产数量")]
-        public decimal? Qty { get; set; }
-
-        /// <summary>
-        /// 集团id
-        /// </summary>
-        [Comment("集团id")]
-        public long? tenant_id { get; set; }
-
-        /// <summary>
-        /// 工厂id
-        /// </summary>
-        [Comment("工厂id")]
-        public long? factory_id { get; set; }
-
-        /// <summary>
-        /// 创建时间
-        /// </summary>
-        [Comment("创建时间")]
-        public DateTime? CreateTime { get; set; }
-
-        /// <summary>
-        /// 整体需求计划版本号
-        /// </summary>
-        [Comment("整体需求计划版本号")]
-        public string Version { get; set; }
-    }
-}

+ 16 - 40
MicroServices/Business/Business.Domain/StructuredDB/Production/MonthlyProdCapacityDtl.cs → MicroServices/Business/Business.Domain/StructuredDB/SaleFcst/MonthlyProdCapacity.cs

@@ -13,21 +13,9 @@ namespace Business.Domain
     /// 月度产能共识明细表
     /// </summary>
     [Comment("月度产能共识主表")]
-    [Index(nameof(Year), nameof(Month), nameof(ProdLine), nameof(tenant_id), nameof(factory_id), IsUnique = true)]
-    public class MonthlyProdCapacityDtl
+    [Index(nameof(Year), nameof(Month),nameof(PlanMonth), nameof(ProdLine), nameof(tenant_id),nameof(company_id), nameof(factory_id), IsUnique = true)]
+    public class MonthlyProdCapacity:BaseEntity
     {
-        /// <summary>
-        /// 主键
-        /// </summary>
-        [Comment("主键")]
-        [Key]
-        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
-        public long Id { get; set; }
-
-        /// <summary>
-        /// 主表id
-        /// </summary>
-        public long MainId { get; set; }
 
         /// <summary>
         /// 年
@@ -41,6 +29,12 @@ namespace Business.Domain
         [Comment("月")]
         public int? Month { get; set; }
 
+        /// <summary>
+        /// 计划年月
+        /// </summary>
+        [Comment("计划年月")]
+        public string PlanMonth { get; set; }
+
         /// <summary>
         /// 生产线
         /// </summary>
@@ -51,43 +45,43 @@ namespace Business.Domain
         /// 日工作时间(小时)
         /// </summary>
         [Comment("日工作时间(小时)")]
-        public decimal? DailyWorks { get; set; }
+        public decimal DailyWorks { get; set; }
 
         /// <summary>
         /// 月工作天数(天)
         /// </summary>
         [Comment("月工作天数(天)")]
-        public decimal? YearWorks { get; set; }
+        public decimal MonthWorks { get; set; }
 
         /// <summary>
         /// 班次数
         /// </summary>
         [Comment("班次数")]
-        public int? FlightQty { get; set; }
+        public int FlightQty { get; set; }
 
         /// <summary>
         /// 月度可利用工作时间(小时)
         /// </summary>
         [Comment("月度可利用工作时间(小时)")]
-        public decimal? AvailableTimes { get; set; }
+        public decimal AvailableTimes { get; set; }
 
         /// <summary>
         /// 月度需求工作时间(小时)
         /// </summary>
         [Comment("月度需求工作时间(小时)")]
-        public decimal? NeedWorks { get; set; }
+        public decimal NeedWorks { get; set; }
 
         /// <summary>
         /// 排产效率
         /// </summary>
         [Comment("排产效率")]
-        public decimal? ProdRate { get; set; }
+        public decimal ProdRate { get; set; }
 
         /// <summary>
         /// 产线标准产能符合率
         /// </summary>
         [Comment("产线标准产能符合率")]
-        public decimal? Rate { get; set; }
+        public decimal Rate { get; set; }
 
         /// <summary>
         /// 是否加班:是,否
@@ -99,24 +93,6 @@ namespace Business.Domain
         /// 加班工时
         /// </summary>
         [Comment("加班工时")]
-        public decimal? OverTimes { get; set; }
-
-        /// <summary>
-        /// 集团id
-        /// </summary>
-        [Comment("集团id")]
-        public long? tenant_id { get; set; }
-
-        /// <summary>
-        /// 工厂id
-        /// </summary>
-        [Comment("工厂id")]
-        public long? factory_id { get; set; }
-
-        /// <summary>
-        /// 整体需求计划版本号
-        /// </summary>
-        [Comment("整体需求计划版本号")]
-        public string Version { get; set; }
+        public decimal OverTimes { get; set; }
     }
 }

+ 2 - 2
MicroServices/Business/Business.Domain/StructuredDB/SaleFcst/OverseasSaleFcst.cs

@@ -20,13 +20,13 @@ namespace Business.Domain
         /// 年
         /// </summary>
         [Comment("年")]
-        public int? Year { get; set; }
+        public int Year { get; set; }
 
         /// <summary>
         /// 月
         /// </summary>
         [Comment("月")]
-        public int? Month { get; set; }
+        public int Month { get; set; }
 
         /// <summary>
         /// 产品线

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

@@ -144,14 +144,9 @@ namespace Business.EntityFrameworkCore
         public DbSet<ItemPackMaster> ItemPackMaster { get; set; }
 
         /// <summary>
-        /// 月度共识产能
+        /// 月度共识产能表
         /// </summary>
-        public DbSet<MonthlyProdCapacityMain> MonthlyProdCapacityMain { get; set; }
-
-        /// <summary>
-        /// 月度共识产能明细表
-        /// </summary>
-        public DbSet<MonthlyProdCapacityDtl> MonthlyProdCapacityDtl { get; set; }
+        public DbSet<MonthlyProdCapacity> MonthlyProdCapacity { get; set; }
 
         /// <summary>
         /// 标准物料规格型号设置表