ソースを参照

VSM进出存倒推期初数

Murphy 2 年 前
コミット
1c0b1b3b47

+ 9 - 1
MicroServices/Business/Business.Application.Contracts/Dto/VSMDto.cs

@@ -230,6 +230,7 @@ namespace Business.Dto
         public decimal Month14 { get; set; }
     }
 
+    [Keyless]
     public partial class ForecastActualDto
     {
         public string ItemNum { get; set; }
@@ -243,7 +244,7 @@ namespace Business.Dto
         public decimal M2Real { get; set; }
         public string M2Diff { get; set; }
     }
-
+    [Keyless]
     public partial class InventoryDto
     {
         public string ItemNumber { get; set; }
@@ -263,5 +264,12 @@ namespace Business.Dto
         public decimal GKCoverageMonth { get; set; }
         public decimal TotalCoverageMonth { get; set; }
     }
+    [Keyless]
+    public partial class DMSShippingDetailDto
+    {
+        public string ItemNum { get; set; }
+        public string UPN { get; set; }
+        public decimal Qty { get; set; }
+    }
 }
 

+ 416 - 106
MicroServices/Business/Business.Application/VSM/VSMAppService.cs

@@ -18,9 +18,11 @@ using Microsoft.EntityFrameworkCore;
 using Microsoft.EntityFrameworkCore.Metadata.Internal;
 using Microsoft.Extensions.Configuration;
 using MongoDB.Driver.Linq;
+using NetTopologySuite.Mathematics;
 using Newtonsoft.Json;
 using NLog;
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Data;
 using System.Diagnostics.Metrics;
@@ -54,6 +56,7 @@ namespace Business.VSMManagement
         private readonly IRepository<MonthlyShipmentPlan> _monthlyShipmentPlan;
         private readonly ISqlRepository<ASNBOLShipperDetail> _aSNBOLShipperDetail;
         private readonly BusinessDbContext _businessDbContext;
+        private readonly BusinessExtRADbContext _businessExtRADbContext;
         public VSMAppService(
          ISqlRepository<ItemMaster> itemMaster,
          ISqlRepository<InvTransHist> invTransHist,
@@ -68,7 +71,8 @@ namespace Business.VSMManagement
          ISqlRepository<SAPInv> SAPInv,
          IRepository<MonthlyShipmentPlan> monthlyShipmentPlan,
          ISqlRepository<ASNBOLShipperDetail> aSNBOLShipperDetail,
-        BusinessDbContext businessDbContext
+        BusinessDbContext businessDbContext,
+        BusinessExtRADbContext businessExtRADbContext
          )
         {
             _itemMaster = itemMaster;
@@ -85,6 +89,7 @@ namespace Business.VSMManagement
             _monthlyShipmentPlan=monthlyShipmentPlan;
             _aSNBOLShipperDetail = aSNBOLShipperDetail;
             _businessDbContext = businessDbContext;
+            _businessExtRADbContext = businessExtRADbContext;
         }
         public string ValueFrequency(string Loc, string BeginDate, string EndDate, string KanBan, string Frequency)
         {
@@ -292,8 +297,8 @@ namespace Business.VSMManagement
                         kanBanDtos[i].AmountTotal = totalAmount;
                         kanBanDtos[i].MovePencent = totalmoveCount == 0 ? 0 : kanBanDtos[i].MoveCount * 100 / totalmoveCount;
                     }
-                    kanBanDtos=kanBanDtos.Where(a=>a.ABC==JZ&&a.FMR==PC && a.Kanban > Convert.ToDecimal(KanBan) && a.MovePencent > Convert.ToDecimal(Frequency)).OrderByDescending(a=>a.Amount).ToList();
-                    for(int i=0;i< kanBanDtos.Count(); i++)
+                    kanBanDtos=kanBanDtos.Where(a=>a.ABC==JZ&&a.FMR==PC && a.Kanban > Convert.ToDecimal(KanBan) && a.MovePencent*100 > Convert.ToDecimal(Frequency)).OrderByDescending(a=>a.Amount).ToList();
+                    for (int i=0;i< kanBanDtos.Count(); i++)
                     {
                         ValueFrequencyDetailDto detailDto = new ValueFrequencyDetailDto();
                         detailDto.RowSeq =i+1;
@@ -727,21 +732,21 @@ namespace Business.VSMManagement
         {
             string sql = $"exec [dbo].[pr_DOP_InventoryMonitoring]";
             var InventoryDto = _businessDbContext.InventoryDto.FromSqlRaw(sql).ToList();
-
             DateOnly dateOnly = DateOnly.FromDateTime(DateTime.Now.AddMonths(-2));
             var polist = _DMS_IN_PODETAIL.Select(a =>a.SubmitDate >= dateOnly && a.OrderStatus != "Revoked" && a.OrderStatus != "Rejected");
             var rqShip = _aSNBOLShipperDetail.Select(a => a.CreateTime >= DateTime.Now.AddMonths(-2) && a.Domain == factory_id);
             List<ForecastActualDto> modelMonthOuts = new List<ForecastActualDto>();
+            string strMonth1 = DateTime.Now.AddMonths(-1).ToString("yyyy-MM");
+            string strMonth2 = DateTime.Now.ToString("yyyy-MM");
             //按照物料统计
             if (isItemNum == "M")
             {
                 switch (itemNumRange)
                 {
                     case "F":
-                        if(itemNum!="")
+                        if(!string.IsNullOrEmpty(itemNum))
                         {
-                            var shipPlan=_monthlyShipmentPlan.GetListAsync(a => a.SAPItemNumber == itemNum 
-                            && (a.PlanMonth==DateTime.Now.AddMonths(-1).ToString("yyyy-MM") || a.PlanMonth == DateTime.Now.ToString("yyyy-MM"))
+                            var shipPlan=_monthlyShipmentPlan.GetListAsync(a => a.SAPItemNumber == itemNum && (a.PlanMonth== strMonth1 || a.PlanMonth == strMonth2)
                             && a.DistributionChannel == "瑞奇").Result;
                             var itemDto = InventoryDto.Find(a => a.ItemNumber == itemNum);
                             if(itemDto!=null)
@@ -769,10 +774,12 @@ namespace Business.VSMManagement
                             }
                         }else
                         {
-                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => (a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM") || a.PlanMonth == DateTime.Now.ToString("yyyy-MM"))
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2)
                             && a.DistributionChannel == "瑞奇").Result;
-                            var itemList= shipPlan.Select(a=>a.SAPItemNumber).Distinct().ToList();
-                            itemList.ForEach(x=>
+                            var itemList = _itemMaster.Select(a =>a.ItemType == "RS50" && a.Domain==factory_id).Select(a=>a.ItemNum).Distinct().ToList();
+                            var shipItemList = shipPlan.Select(a => a.SAPItemNumber).Distinct().ToList();
+                            var intersection = itemList.Intersect(shipItemList).ToList();
+                            intersection.ForEach(x=>
                             {
                                 var itemDto = InventoryDto.Find(a => a.ItemNumber == x);
                                 if (itemDto != null)
@@ -802,18 +809,23 @@ namespace Business.VSMManagement
                         }
                         break;
                     case "G":
-                        if (itemNum != "")
+                    case "H":
+                        string gkhw = itemNumRange == "G" ? "国科" : "海王";
+                        string gkhwcode = itemNumRange == "G" ? "RQ000005" : "RQ000002";
+                        if (!string.IsNullOrEmpty(itemNum))
                         {
-                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => a.SAPItemNumber == itemNum
-                            && (a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM") || a.PlanMonth == DateTime.Now.ToString("yyyy-MM"))
-                            && a.DistributionChannel == "国科").Result;
-
-                            var item=_DMS_IN_ITEMMAPPING.Select(a => a.CfnERPCode == itemNum);
-                            if(item!=null)
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => a.SAPItemNumber == itemNum && (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2) && a.DistributionChannel == gkhw).Result;
+                            var item = _DMS_IN_ITEMMAPPING.Select(a => a.CfnERPCode == itemNum);
+                            if (item != null && item.Count>0)
                             {
                                 var itemDto = InventoryDto.Find(a => a.ItemNumber == itemNum);
                                 if (itemDto != null)
                                 {
+                                    //表没有主键索引,用仓储查询很慢,改用这种方式
+                                    string month1 = $"select '{itemNum}' AS ItemNum,UPN,SUM(Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] where UPN='{item[0].CfnCode}' and DealerLevel='T2' and ParentDealerCode='{gkhwcode}' and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-2).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}'  group by UPN";
+                                    var month1Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month1).ToList();
+                                    string month2 = $"select '{itemNum}' AS ItemNum,UPN,SUM(Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] where UPN='{item[0].CfnCode}' and DealerLevel='T2' and ParentDealerCode='{gkhwcode}' and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.ToString("yyyy-MM-dd")}'  group by UPN";
+                                    var month2Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month2).ToList();
                                     ForecastActualDto forecastActualDto = new ForecastActualDto();
                                     forecastActualDto.ItemNum = itemNum;
                                     forecastActualDto.GroupBy = itemDto.Series;
@@ -829,8 +841,8 @@ namespace Business.VSMManagement
                                     {
                                         forecastActualDto.M2Plan = shipPlan.Find(a => a.PlanMonth == DateTime.Now.ToString("yyyy-MM")).Qty;
                                     }
-                                    forecastActualDto.M1Real = rqShip.Where(a => a.ContainerItem == itemNum && a.CreateTime >= DateTime.Now.AddMonths(-2) && a.CreateTime < DateTime.Now.AddMonths(-1)).Sum(b => b.QtyToShip.Value);
-                                    forecastActualDto.M2Real = rqShip.Where(a => a.ContainerItem == itemNum && a.CreateTime >= DateTime.Now.AddMonths(-1) && a.CreateTime < DateTime.Now).Sum(b => b.QtyToShip.Value);
+                                    forecastActualDto.M1Real = month1Qty.Sum(a => a.Qty);
+                                    forecastActualDto.M2Real = month2Qty.Sum(a => a.Qty);
                                     forecastActualDto.M1Diff = (forecastActualDto.M1Plan == 0 || forecastActualDto.M1Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M1Real / forecastActualDto.M1Plan)}%";
                                     forecastActualDto.M2Diff = (forecastActualDto.M2Plan == 0 || forecastActualDto.M2Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M2Real / forecastActualDto.M2Plan)}%";
                                     modelMonthOuts.Add(forecastActualDto);
@@ -839,10 +851,15 @@ namespace Business.VSMManagement
                         }
                         else
                         {
-                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => (a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM") || a.PlanMonth == DateTime.Now.ToString("yyyy-MM"))
-                            && a.DistributionChannel == "瑞奇").Result;
-                            var itemList = shipPlan.Select(a => a.SAPItemNumber).Distinct().ToList();
-                            itemList.ForEach(x =>
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2) && a.DistributionChannel == gkhw).Result;
+                            var itemList = _itemMaster.Select(a => a.ItemType == "RS50" && a.Domain == factory_id).Select(a => a.ItemNum).Distinct().ToList();
+                            string month1 = $"Select B.CfnERPCode AS ItemNum,A.UPN,SUM(A.Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode where DealerLevel='T2' and ParentDealerCode='{gkhwcode}' and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-2).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' group by B.CfnERPCode,UPN";
+                            var month1Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month1).ToList();
+                            string month2 = $"Select B.CfnERPCode AS ItemNum,A.UPN,SUM(A.Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode where DealerLevel='T2' and ParentDealerCode='{gkhwcode}' and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.ToString("yyyy-MM-dd")}' group by B.CfnERPCode,UPN";
+                            var month2Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month2).ToList();
+                            var shipItemList = shipPlan.Select(a => a.SAPItemNumber).Distinct().ToList();
+                            var intersection = itemList.Intersect(shipItemList).ToList();
+                            intersection.ForEach(x =>
                             {
                                 var itemDto = InventoryDto.Find(a => a.ItemNumber == x);
                                 if (itemDto != null)
@@ -854,6 +871,46 @@ namespace Business.VSMManagement
                                     //月度发货计划找不到可以去月度发货计划历史表按照版本号找,暂不处理
                                     forecastActualDto.M1Plan = 0;
                                     forecastActualDto.M2Plan = 0;
+                                    if (shipPlan.Any(a => a.SAPItemNumber==x && a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M1Plan = shipPlan.Find(a => a.SAPItemNumber == x && a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")).Qty;
+                                    }
+                                    if (shipPlan.Any(a => a.SAPItemNumber == x && a.PlanMonth == DateTime.Now.ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M2Plan = shipPlan.Find(a => a.SAPItemNumber == x && a.PlanMonth == DateTime.Now.ToString("yyyy-MM")).Qty;
+                                    }
+                                    forecastActualDto.M1Real = month1Qty.Where(a => a.ItemNum == x).Sum(a => a.Qty);
+                                    forecastActualDto.M2Real = month2Qty.Where(a => a.ItemNum == x).Sum(a => a.Qty);
+                                    forecastActualDto.M1Diff = (forecastActualDto.M1Plan == 0 || forecastActualDto.M1Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M1Real / forecastActualDto.M1Plan)}%";
+                                    forecastActualDto.M2Diff = (forecastActualDto.M2Plan == 0 || forecastActualDto.M2Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M2Real / forecastActualDto.M2Plan)}%";
+                                    modelMonthOuts.Add(forecastActualDto);
+                                }
+                            });
+                        }
+                        break;
+                    case "A":
+                        if (!string.IsNullOrEmpty(itemNum))
+                        {
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => a.SAPItemNumber == itemNum && (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2)).Result;
+
+                            var item = _DMS_IN_ITEMMAPPING.Select(a => a.CfnERPCode == itemNum);
+                            if (item != null && item.Count>0)
+                            {
+                                var itemDto = InventoryDto.Find(a => a.ItemNumber == itemNum);
+                                if (itemDto != null)
+                                {
+                                    //表没有主键索引,用仓储查询很慢,改用这种方式
+                                    string month1 = $"select '{itemNum}' AS ItemNum,UPN,SUM(Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] where UPN='{item[0].CfnCode}' and ((DealerLevel='T2' and (ParentDealerCode='RQ000005' or ParentDealerCode='RQ000002')) or (DealerLevel='T1'  or DealerLevel='LS')) and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-2).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' group by UPN";
+                                    var month1Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month1).ToList();
+                                    string month2 = $"select '{itemNum}' AS ItemNum,UPN,SUM(Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] where UPN='{item[0].CfnCode}' and ((DealerLevel='T2' and (ParentDealerCode='RQ000005' or ParentDealerCode='RQ000002')) or (DealerLevel='T1'  or DealerLevel='LS')) and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.ToString("yyyy-MM-dd")}' group by UPN";
+                                    var month2Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month2).ToList();
+                                    ForecastActualDto forecastActualDto = new ForecastActualDto();
+                                    forecastActualDto.ItemNum = itemNum;
+                                    forecastActualDto.GroupBy = itemDto.Series;
+                                    forecastActualDto.StockTurnOver = itemDto.GKMonthlyDemand + itemDto.HWMonthlyDemand == 0 ? 0 : decimal.Ceiling((itemDto.GKInv + itemDto.HWInv) / (itemDto.GKMonthlyDemand + itemDto.HWMonthlyDemand));
+                                    //月度发货计划找不到可以去月度发货计划历史表按照版本号找,暂不处理
+                                    forecastActualDto.M1Plan = 0;
+                                    forecastActualDto.M2Plan = 0;
                                     if (shipPlan.Any(a => a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")))
                                     {
                                         forecastActualDto.M1Plan = shipPlan.Find(a => a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")).Qty;
@@ -862,8 +919,46 @@ namespace Business.VSMManagement
                                     {
                                         forecastActualDto.M2Plan = shipPlan.Find(a => a.PlanMonth == DateTime.Now.ToString("yyyy-MM")).Qty;
                                     }
-                                    forecastActualDto.M1Real = rqShip.Where(a => a.ContainerItem == itemNum && a.CreateTime >= DateTime.Now.AddMonths(-2) && a.CreateTime < DateTime.Now.AddMonths(-1)).Sum(b => b.QtyToShip.Value);
-                                    forecastActualDto.M2Real = rqShip.Where(a => a.ContainerItem == itemNum && a.CreateTime >= DateTime.Now.AddMonths(-1) && a.CreateTime < DateTime.Now).Sum(b => b.QtyToShip.Value);
+                                    forecastActualDto.M1Real = month1Qty.Sum(a => a.Qty);
+                                    forecastActualDto.M2Real = month2Qty.Sum(a => a.Qty);
+                                    forecastActualDto.M1Diff = (forecastActualDto.M1Plan == 0 || forecastActualDto.M1Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M1Real / forecastActualDto.M1Plan)}%";
+                                    forecastActualDto.M2Diff = (forecastActualDto.M2Plan == 0 || forecastActualDto.M2Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M2Real / forecastActualDto.M2Plan)}%";
+                                    modelMonthOuts.Add(forecastActualDto);
+                                }
+                            }
+                        }
+                        else
+                        {
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2)).Result;
+                            var itemList = _itemMaster.Select(a => a.ItemType == "RS50" && a.Domain == factory_id).Select(a => a.ItemNum).Distinct().ToList();
+                            string month1 = $"Select B.CfnERPCode AS ItemNum,A.UPN,SUM(A.Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode where ((DealerLevel='T2' and (ParentDealerCode='RQ000005' or ParentDealerCode='RQ000002')) or (DealerLevel='T1'  or DealerLevel='LS')) and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-2).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' group by B.CfnERPCode,UPN";
+                            var month1Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month1).ToList();
+                            string month2 = $"Select B.CfnERPCode AS ItemNum,A.UPN,SUM(A.Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode where ((DealerLevel='T2' and (ParentDealerCode='RQ000005' or ParentDealerCode='RQ000002')) or (DealerLevel='T1'  or DealerLevel='LS')) and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.ToString("yyyy-MM-dd")}' group by B.CfnERPCode,UPN";
+                            var month2Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month2).ToList();
+                            var shipItemList = shipPlan.Select(a => a.SAPItemNumber).Distinct().ToList();
+                            var intersection = itemList.Intersect(shipItemList).ToList();
+                            intersection.ForEach(x =>
+                            {
+                                var itemDto = InventoryDto.Find(a => a.ItemNumber == x);
+                                if (itemDto != null)
+                                {
+                                    ForecastActualDto forecastActualDto = new ForecastActualDto();
+                                    forecastActualDto.ItemNum = x;
+                                    forecastActualDto.GroupBy = itemDto.Series;
+                                    forecastActualDto.StockTurnOver = itemDto.GKMonthlyDemand + itemDto.HWMonthlyDemand == 0 ? 0 : decimal.Ceiling((itemDto.GKInv + itemDto.HWInv) / (itemDto.GKMonthlyDemand + itemDto.HWMonthlyDemand));
+                                    //月度发货计划找不到可以去月度发货计划历史表按照版本号找,暂不处理
+                                    forecastActualDto.M1Plan = 0;
+                                    forecastActualDto.M2Plan = 0;
+                                    if (shipPlan.Any(a => a.SAPItemNumber == x && a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M1Plan = shipPlan.Find(a => a.SAPItemNumber == x && a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")).Qty;
+                                    }
+                                    if (shipPlan.Any(a => a.SAPItemNumber == x && a.PlanMonth == DateTime.Now.ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M2Plan = shipPlan.Find(a => a.SAPItemNumber == x && a.PlanMonth == DateTime.Now.ToString("yyyy-MM")).Qty;
+                                    }
+                                    forecastActualDto.M1Real = month1Qty.Where(a => a.ItemNum == x).Sum(a => a.Qty);
+                                    forecastActualDto.M2Real = month2Qty.Where(a => a.ItemNum == x).Sum(a => a.Qty);
                                     forecastActualDto.M1Diff = (forecastActualDto.M1Plan == 0 || forecastActualDto.M1Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M1Real / forecastActualDto.M1Plan)}%";
                                     forecastActualDto.M2Diff = (forecastActualDto.M2Plan == 0 || forecastActualDto.M2Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M2Real / forecastActualDto.M2Plan)}%";
                                     modelMonthOuts.Add(forecastActualDto);
@@ -871,111 +966,326 @@ namespace Business.VSMManagement
                             });
                         }
                         break;
-                    case "H":
-                        break;
-                    case "A":
-                        break;
                     default:
                         break;        
                 }
             }else
             {
-
-            }
-            return JsonConvert.SerializeObject(modelMonthOuts);
-        }
-
-        public string CalcInvDayHist(string domain)
-        {
-            string sql = $"select distinct ItemNum,Min(CreateTime) AS HistMinTime from InvTransHist where Domain='{domain}' group by ItemNum";
-            var InvTransHistDto = _businessDbContext.InvTransHistDayDto.FromSqlRaw(sql).ToList();
-
-            string invHistTime = $"select A.ItemNum,Sum((case when a.QtyChange>0 then a.QtyChange else 0 end)) as QtyChangeAdvance,Sum((case when a.QtyChange<0 then abs(a.QtyChange) else 0 end)) as QtyChangeOut,CONVERT(varchar,a.createTime, 23) AS createTime from InvTransHist A where Domain='{domain}' group by ItemNum,CONVERT(varchar,a.createTime, 23)";
-            var InvTransHistDetailDto = _businessDbContext.InvTransHistDetailDto.FromSqlRaw(invHistTime).ToList();
-
-            string sqlMaxTime = $"select t1.* from InvTransHistDay t1 inner join (SELECT max(HistDayTime) as HistDayTime, ItemNum FROM InvTransHistDay where Domain='{domain}' group by ItemNum) t2 on t1.HistDayTime=t2.HistDayTime and t1.ItemNum=t2.ItemNum and t1.Domain='{domain}'";
-            var InvTransHistMaxTimeDayDto = _businessDbContext.InvTransHistDay.FromSqlRaw(sqlMaxTime).ToList();
-
-            string sqlQtyChange = $"select ItemNum,Sum(QtyChange) AS QtyChange from InvTransHist where Domain='{domain}' group by ItemNum";
-            var QtyChangeDto = _businessDbContext.QtyChangeDto.FromSqlRaw(sqlQtyChange).ToList();
-
-            string sqlBalanceNum = $"select a.ItemNum,Sum(BeginBalance)+Sum(QtyChange) AS BalanceNum from InvTransHist a inner join (select ItemNum,LotSerial,Max(CreateTime) AS CreateTime from InvTransHist group by ItemNum,LotSerial ) b on a.ItemNum=b.ItemNum and a.LotSerial=b.LotSerial and a.CreateTime=b.CreateTime and Domain='{domain}' group by a.ItemNum";
-            var BalanceNumDto = _businessDbContext.BalanceNumDto.FromSqlRaw(sqlBalanceNum).ToList();
-
-            List<InvTransHistDay> daysHist = new List<InvTransHistDay>();
-            InvTransHistDto?.ForEach(x => {
-                if(InvTransHistMaxTimeDayDto.Any(a=>a.ItemNum==x.ItemNum))
+                switch (itemNumRange)
                 {
-                    var xMaxDay = InvTransHistMaxTimeDayDto.Find(a => a.ItemNum == x.ItemNum).HistDayTime;
-                    int day = 1;
-                    while(true)
-                    {
-                        if(xMaxDay.AddDays(day).Date<=DateTime.Now.Date)
+                    case "F":
+                        if (!string.IsNullOrEmpty(groupBy))
                         {
-                            InvTransHistDay invTransHistDay = new InvTransHistDay();
-                            var daydetail = InvTransHistDetailDto.Find(a => a.ItemNum == x.ItemNum && a.CreateTime== xMaxDay.AddDays(day).Date.ToString("yyyy-MM-dd"));
-                            invTransHistDay.Domain = domain;
-                            invTransHistDay.ItemNum = x.ItemNum;
-                            if(day==1)
-                            {
-                                invTransHistDay.BeginBalance = InvTransHistMaxTimeDayDto.Find(a => a.ItemNum == x.ItemNum).BalanceNum;
-                            }else
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => a.ProdRange == groupBy && (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2) && a.DistributionChannel == "瑞奇").Result;
+                            var itemList=_itemMaster.Select(a => a.Series == groupBy && a.ItemType == "RS50").Select(b => b.ItemNum).Distinct().ToList();
+                            var itemDto = InventoryDto.Where(a => a.Series == groupBy && itemList.Contains(a.ItemNumber)).ToList();
+                            if (itemDto != null && itemDto.Count>0)
                             {
-                                invTransHistDay.BeginBalance = daysHist.Find(a => a.ItemNum == x.ItemNum && a.HistDayTime.Date == xMaxDay.AddDays(day - 1).Date).BalanceNum;
+                                ForecastActualDto forecastActualDto = new ForecastActualDto();
+                                forecastActualDto.GroupBy =groupBy;
+                                decimal sumDemand = itemDto.Sum(a => a.GKMonthlyDemand + a.HWMonthlyDemand);
+                                decimal sumInv = itemDto.Sum(a => a.GKInv + a.HWInv);
+                                forecastActualDto.StockTurnOver = sumDemand == 0 ? 0 : decimal.Ceiling(sumInv / sumDemand);
+                                //月度发货计划找不到可以去月度发货计划历史表按照版本号找,暂不处理
+                                forecastActualDto.M1Plan = 0;
+                                forecastActualDto.M2Plan = 0;
+                                if (shipPlan.Any(a => a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM") && itemList.Contains(a.SAPItemNumber)))
+                                {
+                                    forecastActualDto.M1Plan = shipPlan.Where(a => a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM") && itemList.Contains(a.SAPItemNumber)).Sum(x=>x.Qty);
+                                }
+                                if (shipPlan.Any(a => a.PlanMonth == DateTime.Now.ToString("yyyy-MM")))
+                                {
+                                    forecastActualDto.M2Plan = shipPlan.Where(a => a.PlanMonth == DateTime.Now.ToString("yyyy-MM") && itemList.Contains(a.SAPItemNumber)).Sum(x=>x.Qty);
+                                }
+                                forecastActualDto.M1Real = rqShip.Where(a => itemList.Contains(a.ContainerItem) && a.CreateTime >= DateTime.Now.AddMonths(-2) && a.CreateTime < DateTime.Now.AddMonths(-1)).Sum(b => b.QtyToShip.Value);
+                                forecastActualDto.M2Real = rqShip.Where(a => itemList.ToList().Contains(a.ContainerItem) && a.CreateTime >= DateTime.Now.AddMonths(-1) && a.CreateTime < DateTime.Now).Sum(b => b.QtyToShip.Value);
+                                forecastActualDto.M1Diff = (forecastActualDto.M1Plan == 0 || forecastActualDto.M1Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M1Real / forecastActualDto.M1Plan)}%";
+                                forecastActualDto.M2Diff = (forecastActualDto.M2Plan == 0 || forecastActualDto.M2Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M2Real / forecastActualDto.M2Plan)}%";
+                                modelMonthOuts.Add(forecastActualDto);
                             }
-                            invTransHistDay.QtyChangeAdvance = daydetail == null ? 0 : daydetail.QtyChangeAdvance;
-                            invTransHistDay.QtyChangeOut = daydetail == null ? 0 : daydetail.QtyChangeOut;
-                            invTransHistDay.BalanceNum = invTransHistDay.BeginBalance + invTransHistDay.QtyChangeAdvance - invTransHistDay.QtyChangeOut;
-                            invTransHistDay.HistDayTime = xMaxDay.AddDays(day).Date;
-                            daysHist.Add(invTransHistDay);
-                            day++;
-                        }else
-                        {
-                            break;
                         }
-                    }
-                }else
-                {
-                    var xMaxDay = InvTransHistDto.Find(a => a.ItemNum == x.ItemNum).HistMinTime.Value;
-                    int day = 0;
-                    while (true)
-                    {
-                        if (xMaxDay.AddDays(day).Date <= DateTime.Now.Date)
+                        else
                         {
-                            InvTransHistDay invTransHistDay = new InvTransHistDay();
-                            var daydetail = InvTransHistDetailDto.Find(a => a.ItemNum == x.ItemNum && a.CreateTime == xMaxDay.AddDays(day).Date.ToString("yyyy-MM-dd"));
-                            invTransHistDay.Domain = domain;
-                            invTransHistDay.ItemNum = x.ItemNum;
-                            if (day == 0)
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2)&& a.DistributionChannel == "瑞奇").Result;
+                            var itemSeriesList = _itemMaster.Select(a =>a.ItemType == "RS50");
+                            var shipSeriesList = shipPlan.Select(a => a.ProdRange).Distinct().ToList();
+                            var ItemSeriesList = itemSeriesList.Select(a => a.Series).Distinct().ToList();
+                            var intersection = ItemSeriesList.Intersect(shipSeriesList).ToList();
+                            intersection.ForEach(x =>
                             {
-                                var xBalanceNum = BalanceNumDto.Find(b => b.ItemNum == x.ItemNum);
-                                var xQtyChangeDto = QtyChangeDto.Find(b => b.ItemNum == x.ItemNum);
-                                if (xBalanceNum != null && xQtyChangeDto != null)
+                                var itemDto = InventoryDto.Where(a => a.Series == x).ToList();
+                                var itemNumList= itemSeriesList.Where(a=>a.Series==x).Select(a=>a.ItemNum).Distinct().ToList();
+                                if (itemDto != null && itemDto.Count > 0)
                                 {
-                                    invTransHistDay.BeginBalance = xBalanceNum.BalanceNum + xQtyChangeDto.QtyChange;
+                                    ForecastActualDto forecastActualDto = new ForecastActualDto();
+                                    forecastActualDto.GroupBy =x;
+                                    decimal sumDemand = itemDto.Sum(a => a.GKMonthlyDemand + a.HWMonthlyDemand);
+                                    decimal sumInv = itemDto.Sum(a => a.GKInv + a.HWInv);
+                                    forecastActualDto.StockTurnOver = sumDemand == 0 ? 0 : decimal.Ceiling(sumInv / sumDemand);
+                                    //月度发货计划找不到可以去月度发货计划历史表按照版本号找,暂不处理
+                                    forecastActualDto.M1Plan = 0;
+                                    forecastActualDto.M2Plan = 0;
+                                    if (shipPlan.Any(a => itemNumList.Contains(a.SAPItemNumber) && a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M1Plan = shipPlan.Find(a => itemNumList.Contains(a.SAPItemNumber) && a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")).Qty;
+                                    }
+                                    if (shipPlan.Any(a => itemNumList.Contains(a.SAPItemNumber) && a.PlanMonth == DateTime.Now.ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M2Plan = shipPlan.Find(a => itemNumList.Contains(a.SAPItemNumber) && a.PlanMonth == DateTime.Now.ToString("yyyy-MM")).Qty;
+                                    }
+                                    forecastActualDto.M1Real = rqShip.Where(a => itemNumList.Contains(a.ContainerItem) && a.CreateTime >= DateTime.Now.AddMonths(-2) && a.CreateTime < DateTime.Now.AddMonths(-1)).Sum(b => b.QtyToShip.Value);
+                                    forecastActualDto.M2Real = rqShip.Where(a => itemNumList.Contains(a.ContainerItem) && a.CreateTime >= DateTime.Now.AddMonths(-1) && a.CreateTime < DateTime.Now).Sum(b => b.QtyToShip.Value);
+                                    forecastActualDto.M1Diff = (forecastActualDto.M1Plan == 0 || forecastActualDto.M1Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M1Real / forecastActualDto.M1Plan)}%";
+                                    forecastActualDto.M2Diff = (forecastActualDto.M2Plan == 0 || forecastActualDto.M2Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M2Real / forecastActualDto.M2Plan)}%";
+                                    modelMonthOuts.Add(forecastActualDto);
                                 }
-                                else
+                            });
+                        }
+                        break;
+                    case "G":
+                    case "H":
+                        string gkhw = itemNumRange == "G" ? "国科" : "海王";
+                        string gkhwcode = itemNumRange == "G" ? "RQ000005" : "RQ000002";
+                        if (!string.IsNullOrEmpty(groupBy))
+                        {
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => a.ProdRange == groupBy && (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2) && a.DistributionChannel == gkhw).Result;
+                            var itemList = _itemMaster.Select(a => a.Series == groupBy && a.ItemType == "RS50").Distinct().ToList();
+                            var item = _DMS_IN_ITEMMAPPING.Select(a => itemList.Select(a => a.ItemNum).ToList().Contains(a.CfnERPCode));
+                            string result = string.Join("','", item.Select(a=>a.CfnCode).Distinct().ToList());
+                            if (item != null)
+                            {
+                                var itemDto = InventoryDto.Where(a =>a.Series==groupBy).ToList();
+                                if (itemDto != null && itemDto.Count > 0)
                                 {
-                                    invTransHistDay.BeginBalance = 0;
+                                    //表没有主键索引,用仓储查询很慢,改用这种方式
+                                    string month1 = $"select B.CfnERPCode AS ItemNum,UPN,SUM(Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode and UPN in('{result}') and DealerLevel='T2' and ParentDealerCode='{gkhwcode}' and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-2).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' group by B.CfnERPCode,UPN";
+                                    var month1Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month1).ToList();
+                                    string month2 = $"select B.CfnERPCode AS ItemNum,UPN,SUM(Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode and UPN in('{result}') and DealerLevel='T2' and ParentDealerCode='{gkhwcode}' and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.ToString("yyyy-MM-dd")}' group by B.CfnERPCode,UPN";
+                                    var month2Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month2).ToList();
+                                    ForecastActualDto forecastActualDto = new ForecastActualDto();
+                                    forecastActualDto.GroupBy = groupBy;
+                                    decimal sumDemand = itemDto.Sum(a => a.GKMonthlyDemand + a.HWMonthlyDemand);
+                                    decimal sumInv = itemDto.Sum(a => a.GKInv + a.HWInv);
+                                    forecastActualDto.StockTurnOver = sumDemand == 0 ? 0 : decimal.Ceiling(sumInv / sumDemand);
+                                    //月度发货计划找不到可以去月度发货计划历史表按照版本号找,暂不处理
+                                    forecastActualDto.M1Plan = 0;
+                                    forecastActualDto.M2Plan = 0;
+                                    if (shipPlan.Any(a => a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M1Plan = shipPlan.Find(a => a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")).Qty;
+                                    }
+                                    if (shipPlan.Any(a => a.PlanMonth == DateTime.Now.ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M2Plan = shipPlan.Find(a => a.PlanMonth == DateTime.Now.ToString("yyyy-MM")).Qty;
+                                    }
+                                    forecastActualDto.M1Real = month1Qty.Sum(a => a.Qty);
+                                    forecastActualDto.M2Real = month2Qty.Sum(a => a.Qty);
+                                    forecastActualDto.M1Diff = (forecastActualDto.M1Plan == 0 || forecastActualDto.M1Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M1Real / forecastActualDto.M1Plan)}%";
+                                    forecastActualDto.M2Diff = (forecastActualDto.M2Plan == 0 || forecastActualDto.M2Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M2Real / forecastActualDto.M2Plan)}%";
+                                    modelMonthOuts.Add(forecastActualDto);
                                 }
                             }
-                            else
+                        }
+                        else
+                        {
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2)&& a.DistributionChannel == gkhw).Result;
+                            string month1 = $"select B.CfnERPCode AS ItemNum,A.UPN,SUM(A.Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode where DealerLevel='T2' and ParentDealerCode='{gkhwcode}' and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-2).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' group by B.CfnERPCode,UPN";
+                            var month1Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month1).ToList();
+                            string month2 = $"select B.CfnERPCode AS ItemNum,A.UPN,SUM(A.Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode where DealerLevel='T2' and ParentDealerCode='{gkhwcode}' and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.ToString("yyyy-MM-dd")}' group by  B.CfnERPCode,UPN";
+                            var month2Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month2).ToList();
+                            var itemList = _itemMaster.Select(a =>a.ItemType == "RS50").Distinct().ToList();
+                            var item = _DMS_IN_ITEMMAPPING.Select(a => itemList.Select(a => a.ItemNum).ToList().Contains(a.CfnERPCode));
+                            string result = string.Join("','", item.Select(a => a.CfnCode).Distinct().ToList());
+                            var seriesList=itemList.Select(a => a.Series).Distinct().ToList();
+                            seriesList.ForEach(x =>
                             {
-                                var dayPredetail = daysHist.Find(a => a.ItemNum == x.ItemNum && a.HistDayTime.Date == xMaxDay.AddDays(day - 1).Date);
-                                invTransHistDay.BeginBalance = dayPredetail == null ? 0 : dayPredetail.BalanceNum;
+                                var itemDto = InventoryDto.Where(a => a.Series == x).ToList();
+                                if (itemDto != null && itemDto.Count > 0)
+                                {
+                                    ForecastActualDto forecastActualDto = new ForecastActualDto();
+                                    forecastActualDto.GroupBy = x;
+                                    decimal sumDemand = itemDto.Sum(a => a.GKMonthlyDemand + a.HWMonthlyDemand);
+                                    decimal sumInv = itemDto.Sum(a => a.GKInv + a.HWInv);
+                                    forecastActualDto.StockTurnOver = sumDemand == 0 ? 0 : decimal.Ceiling(sumInv / sumDemand);
+                                    //月度发货计划找不到可以去月度发货计划历史表按照版本号找,暂不处理
+                                    forecastActualDto.M1Plan = 0;
+                                    forecastActualDto.M2Plan = 0;
+                                    if (shipPlan.Any(a => a.ProdRange == x && a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M1Plan = shipPlan.Where(a => a.ProdRange == x && a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")).Sum(q=>q.Qty);
+                                    }
+                                    if (shipPlan.Any(a => a.SAPItemNumber == x && a.PlanMonth == DateTime.Now.ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M2Plan = shipPlan.Where(a => a.ProdRange == x && a.PlanMonth == DateTime.Now.ToString("yyyy-MM")).Sum(q => q.Qty);
+                                    }
+                                    List<string> seriesItemnum = new List<string>();
+                                    seriesItemnum.AddRange(itemList.Where(a => a.Series == x).Select(a => a.ItemNum).Distinct());
+                                    forecastActualDto.M1Real = month1Qty.Where(a => seriesItemnum.Contains(a.ItemNum)).Sum(a => a.Qty);
+                                    forecastActualDto.M2Real = month2Qty.Where(a => seriesItemnum.Contains(a.ItemNum)).Sum(a => a.Qty);
+                                    forecastActualDto.M1Diff = (forecastActualDto.M1Plan == 0 || forecastActualDto.M1Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M1Real / forecastActualDto.M1Plan)}%";
+                                    forecastActualDto.M2Diff = (forecastActualDto.M2Plan == 0 || forecastActualDto.M2Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M2Real / forecastActualDto.M2Plan)}%";
+                                    modelMonthOuts.Add(forecastActualDto);
+                                }
+                            });
+                        }
+                        break;
+                    case "A":
+                        if (!string.IsNullOrEmpty(groupBy))
+                        {
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => a.ProdRange == groupBy && (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2)).Result;
+                            var itemList = _itemMaster.Select(a => a.Series == groupBy && a.ItemType == "RS50").Distinct().ToList();
+                            var item = _DMS_IN_ITEMMAPPING.Select(a => itemList.Select(a => a.ItemNum).ToList().Contains(a.CfnERPCode));
+                            string result = string.Join("','", item.Select(a => a.CfnCode).Distinct().ToList());
+                            if (item != null)
+                            {
+                                var itemDto = InventoryDto.Where(a => a.Series == groupBy).ToList();
+                                if (itemDto != null && itemDto.Count > 0)
+                                {
+                                    //表没有主键索引,用仓储查询很慢,改用这种方式
+                                    string month1 = $"select B.CfnERPCode AS ItemNum,UPN,SUM(Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode and UPN='{item[0].CfnCode}' and ((DealerLevel='T2' and (ParentDealerCode='RQ000005' or ParentDealerCode='RQ000002')) or (DealerLevel='T1'  or DealerLevel='LS')) and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-2).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' group by B.CfnERPCode,UPN";
+                                    var month1Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month1).ToList();
+                                    string month2 = $"select B.CfnERPCode AS ItemNum,UPN,SUM(Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode and UPN='{item[0].CfnCode}' and ((DealerLevel='T2' and (ParentDealerCode='RQ000005' or ParentDealerCode='RQ000002')) or (DealerLevel='T1'  or DealerLevel='LS')) and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.ToString("yyyy-MM-dd")}' group by B.CfnERPCode,UPN";
+                                    var month2Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month2).ToList();
+                                    ForecastActualDto forecastActualDto = new ForecastActualDto();
+                                    forecastActualDto.GroupBy = groupBy;
+                                    decimal sumDemand = itemDto.Sum(a => a.GKMonthlyDemand + a.HWMonthlyDemand);
+                                    decimal sumInv = itemDto.Sum(a => a.GKInv + a.HWInv);
+                                    forecastActualDto.StockTurnOver = sumDemand == 0 ? 0 : decimal.Ceiling(sumInv / sumDemand);
+                                    //月度发货计划找不到可以去月度发货计划历史表按照版本号找,暂不处理
+                                    forecastActualDto.M1Plan = 0;
+                                    forecastActualDto.M2Plan = 0;
+                                    if (shipPlan.Any(a => a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M1Plan = shipPlan.Find(a => a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")).Qty;
+                                    }
+                                    if (shipPlan.Any(a => a.PlanMonth == DateTime.Now.ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M2Plan = shipPlan.Find(a => a.PlanMonth == DateTime.Now.ToString("yyyy-MM")).Qty;
+                                    }
+                                    forecastActualDto.M1Real = month1Qty.Sum(a => a.Qty);
+                                    forecastActualDto.M2Real = month2Qty.Sum(a => a.Qty);
+                                    forecastActualDto.M1Diff = (forecastActualDto.M1Plan == 0 || forecastActualDto.M1Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M1Real / forecastActualDto.M1Plan)}%";
+                                    forecastActualDto.M2Diff = (forecastActualDto.M2Plan == 0 || forecastActualDto.M2Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M2Real / forecastActualDto.M2Plan)}%";
+                                    modelMonthOuts.Add(forecastActualDto);
+                                }
                             }
-                            invTransHistDay.QtyChangeAdvance = daydetail == null ? 0 : daydetail.QtyChangeAdvance;
-                            invTransHistDay.QtyChangeOut = daydetail == null ? 0 : daydetail.QtyChangeOut;
-                            invTransHistDay.BalanceNum = invTransHistDay.BeginBalance + invTransHistDay.QtyChangeAdvance - invTransHistDay.QtyChangeOut;
-                            invTransHistDay.HistDayTime = xMaxDay.AddDays(day).Date;
-                            daysHist.Add(invTransHistDay);
-                            day++;
                         }
                         else
                         {
-                            break;
+                            var shipPlan = _monthlyShipmentPlan.GetListAsync(a => (a.PlanMonth == strMonth1 || a.PlanMonth == strMonth2)).Result;
+                            string month1 = $"select B.CfnERPCode AS ItemNum,A.UPN,SUM(A.Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode where ((DealerLevel='T2' and (ParentDealerCode='RQ000005' or ParentDealerCode='RQ000002')) or (DealerLevel='T1'  or DealerLevel='LS')) and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-2).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' group by B.CfnERPCode,UPN";
+                            var month1Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month1).ToList();
+                            string month2 = $"select B.CfnERPCode AS ItemNum,A.UPN,SUM(A.Qty) AS Qty from [dbo].[DMS_IN_SHIPPINGDETAIL] A Inner join [dbo].[DMS_IN_ITEMMAPPING] B on A.UPN=B.CfnCode where ((DealerLevel='T2' and (ParentDealerCode='RQ000005' or ParentDealerCode='RQ000002')) or (DealerLevel='T1'  or DealerLevel='LS')) and Status !='Revoked' and Status !='Rejected' and ShipmentDate>='{DateTime.Now.AddMonths(-1).ToString("yyyy-MM-dd")}' and ShipmentDate<'{DateTime.Now.ToString("yyyy-MM-dd")}' group by  B.CfnERPCode,UPN";
+                            var month2Qty = _businessExtRADbContext.DMSShippingDetailDto.FromSqlRaw(month2).ToList();
+                            var itemList = _itemMaster.Select(a =>a.ItemType == "RS50").Distinct().ToList();
+                            var item = _DMS_IN_ITEMMAPPING.Select(a => itemList.Select(a => a.ItemNum).ToList().Contains(a.CfnERPCode));
+                            string result = string.Join("','", item.Select(a => a.CfnCode).Distinct().ToList());
+                            var seriesList = itemList.Select(a => a.Series).Distinct().ToList();
+                            seriesList.ForEach(x =>
+                            {
+                                var itemDto = InventoryDto.Where(a => a.Series == x).ToList();
+                                if (itemDto != null && itemDto.Count > 0)
+                                {
+                                    ForecastActualDto forecastActualDto = new ForecastActualDto();
+                                    forecastActualDto.GroupBy = x;
+                                    decimal sumDemand = itemDto.Sum(a => a.GKMonthlyDemand + a.HWMonthlyDemand);
+                                    decimal sumInv = itemDto.Sum(a => a.GKInv + a.HWInv);
+                                    forecastActualDto.StockTurnOver = sumDemand == 0 ? 0 : decimal.Ceiling(sumInv / sumDemand);
+                                    //月度发货计划找不到可以去月度发货计划历史表按照版本号找,暂不处理
+                                    forecastActualDto.M1Plan = 0;
+                                    forecastActualDto.M2Plan = 0;
+                                    if (shipPlan.Any(a => a.ProdRange == x && a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M1Plan = shipPlan.Where(a => a.ProdRange == x && a.PlanMonth == DateTime.Now.AddMonths(-1).ToString("yyyy-MM")).Sum(q => q.Qty);
+                                    }
+                                    if (shipPlan.Any(a => a.SAPItemNumber == x && a.PlanMonth == DateTime.Now.ToString("yyyy-MM")))
+                                    {
+                                        forecastActualDto.M2Plan = shipPlan.Where(a => a.ProdRange == x && a.PlanMonth == DateTime.Now.ToString("yyyy-MM")).Sum(q => q.Qty);
+                                    }
+                                    List<string> seriesItemnum = new List<string>();
+                                    seriesItemnum.AddRange(itemList.Where(a => a.Series == x).Select(a => a.ItemNum).Distinct());
+                                    forecastActualDto.M1Real = month1Qty.Where(a => seriesItemnum.Contains(a.ItemNum)).Sum(a => a.Qty);
+                                    forecastActualDto.M2Real = month2Qty.Where(a => seriesItemnum.Contains(a.ItemNum)).Sum(a => a.Qty);
+                                    forecastActualDto.M1Diff = (forecastActualDto.M1Plan == 0 || forecastActualDto.M1Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M1Real / forecastActualDto.M1Plan)}%";
+                                    forecastActualDto.M2Diff = (forecastActualDto.M2Plan == 0 || forecastActualDto.M2Real == 0) ? "100%" : $"{decimal.Ceiling(forecastActualDto.M2Real / forecastActualDto.M2Plan)}%";
+                                    modelMonthOuts.Add(forecastActualDto);
+                                }
+                            });
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+            return JsonConvert.SerializeObject(modelMonthOuts);
+        }
+
+        /// <summary>
+        /// 从当前日期往前倒推进出存,最小默认取到2024-01-01
+        /// </summary>
+        /// <param name="domain"></param>
+        /// <returns></returns>
+        public string CalcInvDayHist(string domain)
+        {
+            //取物料已计算进出存的最新日期
+            string sqlMaxHistDayTime = $"select t1.* from InvTransHistDay t1 inner join (SELECT max(HistDayTime) as HistDayTime, ItemNum FROM InvTransHistDay where Domain='{domain}' group by ItemNum) t2 on t1.HistDayTime=t2.HistDayTime and t1.ItemNum=t2.ItemNum and t1.Domain='{domain}'";
+            var HistMaxTimeDayDto = _businessDbContext.InvTransHistDay.FromSqlRaw(sqlMaxHistDayTime).ToList();
+
+            string sqlHistDetail = $"select A.ItemNum,Sum((case when a.QtyChange>0 then a.QtyChange else 0 end)) as QtyChangeAdvance,Sum((case when a.QtyChange<0 then abs(a.QtyChange) else 0 end)) as QtyChangeOut,CONVERT(varchar,a.createTime, 23) AS createTime from InvTransHist A where Domain='{domain}' and CreateTime>='2024-01-01' group by ItemNum,CONVERT(varchar,a.createTime, 23)";
+            string sqlLastBalanceNum = $"select a.ItemNum,Sum(BeginBalance)+Sum(QtyChange) AS BalanceNum from InvTransHist a inner join (select ItemNum,LotSerial,Max(CreateTime) AS CreateTime from InvTransHist where CreateTime>='2024-01-01' group by ItemNum,LotSerial ) b on a.ItemNum=b.ItemNum and a.LotSerial=b.LotSerial and a.CreateTime=b.CreateTime and Domain='{domain}' group by a.ItemNum";
+            if (HistMaxTimeDayDto.Count>0)
+            {
+                sqlHistDetail = $"select A.ItemNum,Sum((case when a.QtyChange>0 then a.QtyChange else 0 end)) as QtyChangeAdvance,Sum((case when a.QtyChange<0 then abs(a.QtyChange) else 0 end)) as QtyChangeOut,CONVERT(varchar,a.createTime, 23) AS createTime from InvTransHist A where Domain='{domain}' and CreateTime>='{HistMaxTimeDayDto[0].HistDayTime.Date}' group by ItemNum,CONVERT(varchar,a.createTime, 23)";
+                sqlLastBalanceNum = $"select a.ItemNum,Sum(BeginBalance)+Sum(QtyChange) AS BalanceNum from InvTransHist a inner join (select ItemNum,LotSerial,Max(CreateTime) AS CreateTime from InvTransHist where CreateTime>='{HistMaxTimeDayDto[0].HistDayTime.Date}' group by ItemNum,LotSerial ) b on a.ItemNum=b.ItemNum and a.LotSerial=b.LotSerial and a.CreateTime=b.CreateTime and Domain='{domain}' group by a.ItemNum";
+            }
+            //取物料进出存明细
+            var HistDetailDto = _businessDbContext.InvTransHistDetailDto.FromSqlRaw(sqlHistDetail).ToList();
+            //取物料的最新期末库存数
+            var LastBalanceNumDto = _businessDbContext.BalanceNumDto.FromSqlRaw(sqlLastBalanceNum).ToList();
+            //取出所有有进出存记录的物料
+            string sqlItemList = $"select distinct ItemNum from InvTransHist where Domain='{domain}' and CreateTime>='2024-01-01' group by ItemNum";
+            var QtyChangeDto = _businessDbContext.QtyChangeDto.FromSqlRaw(sqlItemList).ToList();
+            List<InvTransHistDay> daysHist = new List<InvTransHistDay>();
+            QtyChangeDto?.ForEach(x => 
+            {
+                DateTime dtMin = new DateTime(2024, 1, 1);
+                if (HistMaxTimeDayDto.Any(a=>a.ItemNum==x.ItemNum))
+                {
+                    dtMin = HistMaxTimeDayDto.Find(a => a.ItemNum == x.ItemNum).HistDayTime;
+                }
+                var xMaxDay = DateTime.Now;
+                int day = 0;
+                while (true)
+                {
+                    if (xMaxDay.AddDays(day).Date<dtMin)
+                        break;
+
+                    InvTransHistDay invTransHistDay = new InvTransHistDay();
+                    invTransHistDay.Domain = domain;
+                    invTransHistDay.ItemNum = x.ItemNum;
+                    invTransHistDay.HistDayTime = xMaxDay.AddDays(day).Date;
+                    //如果当前计算日期大于最大进出明细
+                    var xBalanceNum = LastBalanceNumDto.Find(b => b.ItemNum == x.ItemNum);
+                    var daydetail = HistDetailDto.Find(a => a.ItemNum == x.ItemNum && a.CreateTime == xMaxDay.AddDays(day).Date.ToString("yyyy-MM-dd"));
+                    if (xBalanceNum != null)
+                    {
+                        invTransHistDay.QtyChangeAdvance = daydetail == null ? 0 : daydetail.QtyChangeAdvance;
+                        invTransHistDay.QtyChangeOut = daydetail == null ? 0 : daydetail.QtyChangeOut;
+                        if (day==0)
+                        {
+                            invTransHistDay.BeginBalance = daydetail == null ? xBalanceNum.BalanceNum : xBalanceNum.BalanceNum;
+                            invTransHistDay.BalanceNum = daydetail == null ? xBalanceNum.BalanceNum : xBalanceNum.BalanceNum;
+                        }else
+                        {
+                            var nextDayQty = daysHist.Find(a => a.HistDayTime == xMaxDay.AddDays(day + 1).Date && a.ItemNum == x.ItemNum);
+                            //倒推期初数
+                            invTransHistDay.BalanceNum = nextDayQty.BeginBalance;
+                            invTransHistDay.BeginBalance = daydetail == null ? nextDayQty.BeginBalance : nextDayQty.BeginBalance+daydetail.QtyChangeOut-daydetail.QtyChangeAdvance;
+                          
                         }
+                        daysHist.Add(invTransHistDay);
                     }
+                    day--;
                 }
             });
             _businessDbContext.BulkInsert(daysHist);

+ 2 - 0
MicroServices/Business/Business.Domain/StructuredDB/MES/IC/ItemMaster.cs

@@ -160,5 +160,7 @@ namespace Business.Domain
         /// 物料状态
         /// </summary>
         public string PORcptStatus { get; set; }
+
+        public string Series { get; set; }
     }
 }

+ 0 - 6
MicroServices/Business/Business.Domain/StructuredDB/MES/QtyChangeDto.cs

@@ -20,11 +20,5 @@ namespace Business.StructuredDB.MES
         /// </summary>
         [Comment("物料编号")]
         public string ItemNum { get; set; }
-
-        /// <summary>
-        /// 进出总数
-        /// </summary>
-        [Comment("进出总数")]
-        public decimal QtyChange { get; set; }
     }
 }

+ 2 - 0
MicroServices/Business/Business.EntityFrameworkCore/EntityFrameworkCore/ExtRA/BusinessExtRADbContext.cs

@@ -1,4 +1,5 @@
 using Business.Domain;
+using Business.Dto;
 using Microsoft.EntityFrameworkCore;
 using Volo.Abp.Data;
 using Volo.Abp.EntityFrameworkCore;
@@ -16,6 +17,7 @@ namespace Business.EntityFrameworkCore
         public DbSet<DMS_IN_PODETAIL> DMS_IN_PODETAIL { get; set; }
         public DbSet<DMS_IN_RETAILER> DMS_IN_RETAILER { get; set; }
         public DbSet<DMS_IN_SHIPPINGDETAIL> DMS_IN_SHIPPINGDETAIL { get; set; }
+        public DbSet<DMSShippingDetailDto> DMSShippingDetailDto { get; set; }
         public BusinessExtRADbContext(DbContextOptions<BusinessExtRADbContext> options)
             : base(options)
         {