using Business.Core.Utilities; using Business.Domain; using Business.Dto; using Business.EntityFrameworkCore.SqlRepositories; using Business.StructuredDB.WMS; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp.Application.Services; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; using Volo.Abp.MultiTenancy; using Volo.Abp.Uow; using IUnitOfWorkManager = Volo.Abp.Uow.IUnitOfWorkManager; namespace Business.DOP { //DOP public class SyncDOPAppService : ApplicationService, ISyncDOPAppService, ITransientDependency { #region 服务 /// /// 平台规格型号对照表 /// private readonly IRepository _PlatformSpecificationComparison; /// /// 平台库存表 /// private readonly IRepository _PlatformInventory; /// /// SAP库存表 /// private readonly ISqlRepository _sapInvRepository; /// /// SAP库存表 /// private readonly ISqlRepository _itemMasterRepository; /// /// 国内终端预测 /// private IRepository _domesticTerminalFcst; /// /// 海外销售预测 /// private IRepository _overseasSaleFcst; /// /// 标准物料规格型号设置表 /// private IRepository _standardItemModelSet; private IRepository _platStockMonitorSetting; private IRepository _yearDemandManagement; private IRepository _ic_item; /// /// 平台预测收集 /// private IRepository _platformFcstCollect; /// /// 节假日记录表 /// private ISqlRepository _holidayMaster; /// /// 雪花算法 /// SnowFlake snowFlake = new SnowFlake(); /// /// 事务 /// private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly ICurrentTenant _currentTenant; #endregion #region 构造函数 /// /// 构造函数 /// public SyncDOPAppService( IRepository PlatformSpecificationComparison, IRepository PlatformInventory, ISqlRepository sapInvRepository, IRepository domesticTerminalFcst, IRepository overseasSaleFcst, IRepository standardItemModelSet, ISqlRepository itemMasterRepository, IRepository platStockMonitorSetting, IRepository yearDemandManagement, IRepository platformFcstCollect, ISqlRepository holidayMaster, IRepository ic_item, IUnitOfWorkManager unitOfWorkManager, ICurrentTenant currentTenant ) { _PlatformSpecificationComparison = PlatformSpecificationComparison; _PlatformInventory = PlatformInventory; _sapInvRepository = sapInvRepository; _domesticTerminalFcst = domesticTerminalFcst; _overseasSaleFcst = overseasSaleFcst; _standardItemModelSet = standardItemModelSet; _itemMasterRepository = itemMasterRepository; _platStockMonitorSetting = platStockMonitorSetting; _yearDemandManagement=yearDemandManagement; _holidayMaster = holidayMaster; _platformFcstCollect = platformFcstCollect; _ic_item = ic_item; _currentTenant = currentTenant; _unitOfWorkManager = unitOfWorkManager; } #endregion /// /// 海王平台成品监控 /// /// /// public async Task SyncPlatformFinishedProductMonitoringHW(List platformInventoryDtoList) { var ret = SavePlatformFinishedProductMonitoringAsync(platformInventoryDtoList, 1); return await ret; } /// /// 国科平台成品监控 /// /// /// public async Task SyncPlatformFinishedProductMonitoringGK(List platformInventoryDtoList) { var ret = SavePlatformFinishedProductMonitoringAsync(platformInventoryDtoList, 2); return await ret; } /// /// 保存库存信息 /// /// /// 1海王,2国科 public async Task SavePlatformFinishedProductMonitoringAsync(List platformInventoryDtoList, int type) { if (platformInventoryDtoList.Count == 0) { return JsonConvert.SerializeObject("成品库存为空!"); } List platformInventoryInsert = new List(); List platformInventoryDel; if (type == 1) { platformInventoryDel = _PlatformInventory.GetListAsync(x => x.Code == "HW0001").Result; } else { platformInventoryDel = _PlatformInventory.GetListAsync(x => x.Code == "HW0002").Result; } foreach (var item in platformInventoryDtoList) { WMS_PlatformInventory platformInventory = new WMS_PlatformInventory(); platformInventory.GenerateNewId(snowFlake.NextId()); platformInventory.Location = item.Location; platformInventory.SpecificationModel = item.SpecificationModel; platformInventory.BatchNumber = item.BatchNumber; platformInventory.InventoryQuantity = item.InventoryQuantity.GetValueOrDefault(); platformInventory.PeriodOfValidity = item.PeriodOfValidity.GetValueOrDefault(); if (type == 1) { platformInventory.Code = "HW0001"; } else { platformInventory.Code = "GK0001"; } platformInventoryInsert.Add(platformInventory); } using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { //先删后插 await _PlatformInventory.DeleteManyAsync(platformInventoryDel); await _PlatformInventory.InsertManyAsync(platformInventoryInsert); await unitOfWork.CompleteAsync(); } catch (Exception e) { new NLogHelper("SyncDOPAppService").WriteLog("PlatformFinishedProductMonitoringAsyncMerge", "接口异常:" + e.Message); unitOfWork.Dispose(); return JsonConvert.SerializeObject(e.Message); } } return JsonConvert.SerializeObject("ok"); } /// /// 库存监控数据报表接口 /// /// public async Task InventoryMonitoring(InputDto input) { List inventoryMonitoringDtos= new List(); var ItemModelSetList = _standardItemModelSet.GetListAsync(a => a.tenant_id == input.tenant_id && a.company_id == input.company_id && !a.IsDeleted).Result; if (ItemModelSetList == null) { new NLogHelper("SyncDOPAppService").WriteLog("InventoryMonitoring", "库存数据不存在", _currentTenant.Id.ToString()); //throw new NotImplementedException("订单数据不存在!"); return "库存数据不存在"; } ItemModelSetList.ForEach(a => { inventoryMonitoringDtos.Add(new InventoryMonitoringDto { Model=a.Model, ItemNumber=a.ItemNumber, FactoryInv=0,GKInv=0,HWInv=0, ReplenishCycle=a.ReplenishCycle }); }); var ItemList = ItemModelSetList.Select(a => a.ItemNumber); var modelList = ItemModelSetList.Select(a => a.Model); var ItemInvList = _sapInvRepository.Select(a => ItemList.Contains(a.MATNR) && a.WERKS == input.factory_id.ToString()); int year = DateTime.Now.AddMonths(1).Year; int month = DateTime.Now.AddMonths(1).Month; string planMonth = $"{year}-01"; string planMonthCurrent = $"{year}-{DateTime.Now.AddMonths(1).ToString("MM")}"; var platformInvList = _PlatformInventory.GetListAsync(a => modelList.Contains(a.SpecificationModel) && a.tenant_id == input.tenant_id && a.factory_id == input.factory_id).Result; var yearDemandList= _yearDemandManagement.GetListAsync(a=>a.Year== year && a.PlanMonth == planMonth && a.tenant_id== input.tenant_id && a.company_id == input.company_id && !a.IsDeleted).Result; List holidays = _holidayMaster.Select(p => (p.Dated.Value.Year == year || p.Dated.Value.Year == (year + 1)) && p.Domain == input.factory_id.ToString() && p.IsActive); List items = _ic_item.GetListAsync(p => ItemList.Contains(p.number) && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result; var platformFcstCollectList= _platformFcstCollect.GetListAsync(p=>p.PlanMonth== planMonthCurrent && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result; var platStockMonitorSettingList = _platStockMonitorSetting.GetListAsync(p => p.PlanMonth == planMonthCurrent && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result; var domesticTerminalFcstList = _domesticTerminalFcst.GetListAsync(p => p.PlanMonth == planMonthCurrent && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result; inventoryMonitoringDtos.ForEach(a => { //产品线和系列 var itemProdRange = yearDemandList.Find(b => b.Model == a.Model); if (itemProdRange != null) { a.ProLine = itemProdRange.ProdLine; a.Series = itemProdRange.ProdRange; } //工厂库存 var itemSap = ItemInvList.Find(b => b.MATNR == a.ItemNumber); if(itemSap!=null) a.FactoryInv =itemSap.LABST; //国科库存 var platformInventoryGK= platformInvList.Find(b => b.SpecificationModel == a.Model && b.Code== "HW0002"); if (platformInventoryGK != null) a.GKInv = platformInventoryGK.InventoryQuantity; //海王库存 var platformInventoryHW = platformInvList.Find(b => b.SpecificationModel == a.Model && b.Code == "HW0001"); if (platformInventoryHW != null) a.HWInv = platformInventoryHW.InventoryQuantity; //全域库存 a.TotalInv = a.FactoryInv + a.GKInv + a.HWInv; //T1月需求 var t1 = domesticTerminalFcstList.Find(b => b.TypeEnum == 2); if (t1 != null) { a.T1MonthlyDemand = t1.Qty; } //T1补货点 decimal rop = 0.0m; //获取当月天数 int days = DateTime.DaysInMonth(year, month); //计算当前月的周末天数 int weeks = CalcWeekDays(days, DateTime.Now.AddDays(1 - DateTime.Now.Day).AddMonths(1)); //获取当前年月的节假日设置 var curHolidays = holidays.Where(p => p.Dated.Value.Year == DateTime.Now.AddMonths(1).Year && p.Dated.Value.Month == DateTime.Now.AddMonths(1).Month).ToList(); //当月工作天数 int workDays = days - weeks - curHolidays.Where(p => p.Ufld1 == "休假").Count() + curHolidays.Where(p => p.Ufld1 == "调班").Count(); decimal packQty = 1m;//最小包装单位 var curItem = items.FirstOrDefault(p => p.number == a.ItemNumber); packQty = curItem == null ? 1 : (curItem.minpackqty.GetValueOrDefault() == 0.0m ? 1 : curItem.minpackqty.Value); //rop = (需求量/月工作天数*补货周期)=>按照最小包装单位元整 rop = Math.Ceiling(a.T1MonthlyDemand / workDays * a.ReplenishCycle / packQty) * packQty; a.ReplenishmentPoint = rop; //国科预估需求 var gk = domesticTerminalFcstList.Find(a => a.TypeEnum == 5); if (gk != null) { a.GKEstimatedDemand = gk.Qty; } //海王预估需求 var hw = domesticTerminalFcstList.Find(a => a.TypeEnum == 4); if (hw != null) { a.HWEstimatedDemand = hw.Qty; } //T2总体需求 //a.TotalDemand = a.GKEstimatedDemand + a.HWEstimatedDemand; var t2 = domesticTerminalFcstList.Find(a => a.TypeEnum == 3); if (t2 != null) { a.T2TotalDemand = t2.Qty; } //总终端需求 a.TotalTerminalDemand = a.T1MonthlyDemand + a.ReplenishmentPoint + a.GKEstimatedDemand + a.HWEstimatedDemand + a.T2TotalDemand; //工厂平台覆盖月 a.FactoryCoveragePlatformMonth = Math.Round(a.FactoryInv / a.T1MonthlyDemand,2); //国科库存最高最低覆盖月 var prodTypeGK=platformFcstCollectList?.Find(b => b.Model == a.Model && b.Platform == "国科"); if(prodTypeGK!=null) { var prodTypeSettingGK = platStockMonitorSettingList?.Find(b => b.ProdType == prodTypeGK.ProdType && b.Platform == "国科"); if(prodTypeSettingGK!=null) { a.GKCoverageMaxMonth = prodTypeSettingGK.MaxTimes; a.GKCoverageMinMonth = prodTypeSettingGK.MinTimes; }else { a.GKCoverageMaxMonth = 0; a.GKCoverageMinMonth = 0; } } //国科库存覆盖月 a.GKCoverageMonth = Math.Round(a.GKInv / a.GKEstimatedDemand, 2); //海王库存最高最低覆盖月 var prodTypeHW = platformFcstCollectList?.Find(b => b.Model == a.Model && b.Platform == "海王"); if (prodTypeHW != null) { var prodTypeSettingHW = platStockMonitorSettingList?.Find(b => b.ProdType == prodTypeHW.ProdType && b.Platform == "海王"); if(prodTypeSettingHW != null) { a.HWCoverageMaxMonth = prodTypeSettingHW.MaxTimes; a.HWCoverageMinMonth = prodTypeSettingHW.MinTimes; }else { a.HWCoverageMaxMonth = 0; a.HWCoverageMinMonth = 0; } } //海王库存覆盖月 a.HWCoverageMonth = Math.Round(a.HWInv / a.HWEstimatedDemand, 2); //全域覆盖 a.TotalCoverageMonth = Math.Round(a.TotalInv / a.TotalTerminalDemand, 2); //T1库存监控 if (a.FactoryInv < a.ReplenishmentPoint) { a.T1MonitoringResult = "按照补货点补货"; } else { a.T1MonitoringResult = a.FactoryCoveragePlatformMonth > 6 ? "库存超出6个月阈值" : "正常覆盖范围"; } //国科库存监控 a.GKMonitoringResult = a.GKCoverageMonth > a.GKCoverageMaxMonth ? "库存高于最高库存水位警戒" : a.GKCoverageMonth < a.GKCoverageMinMonth ? "库存低于最低库存水位,紧急补货" : "正常周转"; //海王库存监控 a.HWMonitoringResult = a.HWCoverageMonth > a.HWCoverageMaxMonth ? "库存高于最高库存水位警戒" : a.HWCoverageMonth < a.HWCoverageMinMonth ? "库存低于最低库存水位,紧急补货" : "正常周转"; //推荐决策 if (a.TotalCoverageMonth <= 3) { a.RecommendDecision = "紧急补货"; } else if (a.TotalCoverageMonth <=6) { a.RecommendDecision = "需要补货"; } else if (a.TotalCoverageMonth <=9) { a.RecommendDecision = "正常库存"; } else if (a.TotalCoverageMonth <= 24) { a.RecommendDecision = "关注库存"; } else { a.RecommendDecision = "呆滞"; } }); return JsonConvert.SerializeObject(inventoryMonitoringDtos); } /// /// 计算当月有多少个周末 /// /// /// /// 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; } } }