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;
}
}
}