|
@@ -145,6 +145,11 @@ namespace Business.SaleForecastManagement
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
private ISqlRepository<GeneralizedCodeMaster> _generalizedCodeMaster;
|
|
private ISqlRepository<GeneralizedCodeMaster> _generalizedCodeMaster;
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// SAP库存表
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ private ISqlRepository<SAPInv> _SAPInv;
|
|
|
|
|
+
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// 雪花算法
|
|
/// 雪花算法
|
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -178,7 +183,8 @@ namespace Business.SaleForecastManagement
|
|
|
IRepository<crm_planorder, long> crm_planorder,
|
|
IRepository<crm_planorder, long> crm_planorder,
|
|
|
IRepository<PlatStockMonitorSetting, long> platStockMonitorSetting,
|
|
IRepository<PlatStockMonitorSetting, long> platStockMonitorSetting,
|
|
|
IRepository<WMS_PlatformInventory, long> platformInventory,
|
|
IRepository<WMS_PlatformInventory, long> platformInventory,
|
|
|
- ISqlRepository<GeneralizedCodeMaster> generalizedCodeMaster
|
|
|
|
|
|
|
+ ISqlRepository<GeneralizedCodeMaster> generalizedCodeMaster,
|
|
|
|
|
+ ISqlRepository<SAPInv> SAPInv
|
|
|
)
|
|
)
|
|
|
{
|
|
{
|
|
|
_ic_item = ic_item;
|
|
_ic_item = ic_item;
|
|
@@ -204,6 +210,7 @@ namespace Business.SaleForecastManagement
|
|
|
_platStockMonitorSetting = platStockMonitorSetting;
|
|
_platStockMonitorSetting = platStockMonitorSetting;
|
|
|
_platformInventory = platformInventory;
|
|
_platformInventory = platformInventory;
|
|
|
_generalizedCodeMaster = generalizedCodeMaster;
|
|
_generalizedCodeMaster = generalizedCodeMaster;
|
|
|
|
|
+ _SAPInv = SAPInv;
|
|
|
}
|
|
}
|
|
|
#endregion
|
|
#endregion
|
|
|
|
|
|
|
@@ -248,15 +255,11 @@ namespace Business.SaleForecastManagement
|
|
|
//1.5、获取规格型号对应的标准SKU数据:获取最小包装单位
|
|
//1.5、获取规格型号对应的标准SKU数据:获取最小包装单位
|
|
|
List<string> itemNums = standards.Select(p=>p.ItemNumber).Distinct().ToList();
|
|
List<string> itemNums = standards.Select(p=>p.ItemNumber).Distinct().ToList();
|
|
|
List<ic_item> items = _ic_item.GetListAsync(p=> itemNums.Contains(p.number) && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result;
|
|
List<ic_item> items = _ic_item.GetListAsync(p=> itemNums.Contains(p.number) && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result;
|
|
|
- //1.6、获取成品库存、灭菌库存
|
|
|
|
|
- //List<LocationDetail> locations = _locationDetail.Select(p=>p.Domain == input.factory_id.ToString() && p.IsActive && itemNums.Contains(p.ItemNum));
|
|
|
|
|
- //1.7、获取在制库存:计划开始时间、计划结束时间都在本月,并且未关闭的工单
|
|
|
|
|
- //DateTime monStart = Convert.ToDateTime(input.year + "-" + input.month + "-01");
|
|
|
|
|
- //DateTime monEnd = monStart.AddMonths(1).AddDays(-1);
|
|
|
|
|
- //List<WorkOrdMaster> workOrds = _workOrdMaster.Select(p=>p.Domain);
|
|
|
|
|
- //1.9、获取节假日设置
|
|
|
|
|
|
|
+ //1.6、获取成品库存、灭菌库存、在制库存
|
|
|
|
|
+ List<SAPInv> sAPInvs = _SAPInv.Select(p => p.WERKS == input.factory_id.ToString() && itemNums.Contains(p.MATNR));
|
|
|
|
|
+ //1.7、获取节假日设置
|
|
|
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<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);
|
|
|
- //2.0、获取平台库存监控月份设置
|
|
|
|
|
|
|
+ //1.8、获取平台库存监控月份设置
|
|
|
List<PlatStockMonitorSetting> monitorSettings = _platStockMonitorSetting.GetListAsync(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 && !p.IsDeleted).Result;
|
|
List<PlatStockMonitorSetting> monitorSettings = _platStockMonitorSetting.GetListAsync(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 && !p.IsDeleted).Result;
|
|
|
#region 数据校验
|
|
#region 数据校验
|
|
|
//1、校验当前年的年度生产大纲是否导入
|
|
//1、校验当前年的年度生产大纲是否导入
|
|
@@ -370,19 +373,28 @@ namespace Business.SaleForecastManagement
|
|
|
var curStd = standards.FirstOrDefault(p => p.Model == gnModel);
|
|
var curStd = standards.FirstOrDefault(p => p.Model == gnModel);
|
|
|
decimal packQty = 1m;//最小包装单位
|
|
decimal packQty = 1m;//最小包装单位
|
|
|
decimal cycle = 0m;//补货周期
|
|
decimal cycle = 0m;//补货周期
|
|
|
|
|
+ //获取成品库存、在制库存、灭菌库存,参与计算
|
|
|
|
|
+ decimal cpQty = 0m;
|
|
|
|
|
+ decimal zzQty = 0m;
|
|
|
|
|
+ decimal mjQty = 0m;
|
|
|
if (curStd != null)
|
|
if (curStd != null)
|
|
|
{
|
|
{
|
|
|
var curItem = items.FirstOrDefault(p => p.number == curStd.ItemNumber);
|
|
var curItem = items.FirstOrDefault(p => p.number == curStd.ItemNumber);
|
|
|
packQty = curItem == null ? 1 : (curItem.minpackqty.GetValueOrDefault() == 0.0m ? 1 : curItem.minpackqty.Value);
|
|
packQty = curItem == null ? 1 : (curItem.minpackqty.GetValueOrDefault() == 0.0m ? 1 : curItem.minpackqty.Value);
|
|
|
cycle = curStd.ReplenishCycle;
|
|
cycle = curStd.ReplenishCycle;
|
|
|
|
|
+ //成品库存
|
|
|
|
|
+ cpQty = sAPInvs.Where(p => p.MATNR == curStd.ItemNumber && p.LGORT == "8001").Sum(p => Convert.ToDecimal(p.LABST));
|
|
|
|
|
+ //在制库存
|
|
|
|
|
+ zzQty = sAPInvs.Where(p => p.MATNR == curStd.ItemNumber && p.LGORT == "8000").Sum(p => Convert.ToDecimal(p.LABST));
|
|
|
|
|
+ //灭菌库存
|
|
|
|
|
+ mjQty = sAPInvs.Where(p => p.MATNR == curStd.ItemNumber && p.LGORT == "5008").Sum(p => Convert.ToDecimal(p.LABST));
|
|
|
}
|
|
}
|
|
|
- //TODO:获取成品库存、在制库存、灭菌库存,参与计算
|
|
|
|
|
//N+1月使用N+2月的再订货点参与计算
|
|
//N+1月使用N+2月的再订货点参与计算
|
|
|
decimal rop = CalcRop(strN2+"-01", sumN2, packQty, holidays, cycle);
|
|
decimal rop = CalcRop(strN2+"-01", sumN2, packQty, holidays, cycle);
|
|
|
- monthN1.Qty = Math.Ceiling((sumN1 / 2 + sumN2 / 2 + rop - 0 - 0 - 0) / packQty) * packQty;
|
|
|
|
|
|
|
+ monthN1.Qty = Math.Ceiling((sumN1 / 2 + sumN2 / 2 + rop - cpQty - zzQty - mjQty) / packQty) * packQty;
|
|
|
//N+2月使用本月的需求量,下一月的工作天数
|
|
//N+2月使用本月的需求量,下一月的工作天数
|
|
|
rop = CalcRop(Convert.ToDateTime(strN2 + "-01").AddMonths(1).ToString("yyyy-MM-dd"), sumN2, packQty, holidays, cycle);
|
|
rop = CalcRop(Convert.ToDateTime(strN2 + "-01").AddMonths(1).ToString("yyyy-MM-dd"), sumN2, packQty, holidays, cycle);
|
|
|
- monthN2.Qty = Math.Ceiling((sumN2 + rop - 0 - 0 - 0) / packQty) * packQty;
|
|
|
|
|
|
|
+ monthN2.Qty = Math.Ceiling((sumN2 + rop - cpQty - zzQty - mjQty) / packQty) * packQty;
|
|
|
//负数置0
|
|
//负数置0
|
|
|
monthN1.Qty = monthN1.Qty < 0 ? 0m : monthN1.Qty;
|
|
monthN1.Qty = monthN1.Qty < 0 ? 0m : monthN1.Qty;
|
|
|
monthN2.Qty = monthN2.Qty < 0 ? 0m : monthN2.Qty;
|
|
monthN2.Qty = monthN2.Qty < 0 ? 0m : monthN2.Qty;
|
|
@@ -425,16 +437,26 @@ namespace Business.SaleForecastManagement
|
|
|
//当前规格型号对应标准SKU的最小包装单位、补货周期
|
|
//当前规格型号对应标准SKU的最小包装单位、补货周期
|
|
|
var curStd = standards.FirstOrDefault(p => p.Model == hwModel);
|
|
var curStd = standards.FirstOrDefault(p => p.Model == hwModel);
|
|
|
decimal packQty = 1m;//最小包装单位
|
|
decimal packQty = 1m;//最小包装单位
|
|
|
|
|
+ //获取成品库存、在制库存、灭菌库存,参与计算
|
|
|
|
|
+ decimal cpQty = 0m;
|
|
|
|
|
+ decimal zzQty = 0m;
|
|
|
|
|
+ decimal mjQty = 0m;
|
|
|
if (curStd != null)
|
|
if (curStd != null)
|
|
|
{
|
|
{
|
|
|
var curItem = items.FirstOrDefault(p => p.number == curStd.ItemNumber);
|
|
var curItem = items.FirstOrDefault(p => p.number == curStd.ItemNumber);
|
|
|
packQty = curItem == null ? 1 : (curItem.minpackqty.GetValueOrDefault() == 0.0m ? 1 : curItem.minpackqty.Value);
|
|
packQty = curItem == null ? 1 : (curItem.minpackqty.GetValueOrDefault() == 0.0m ? 1 : curItem.minpackqty.Value);
|
|
|
|
|
+ //成品库存
|
|
|
|
|
+ cpQty = sAPInvs.Where(p => p.MATNR == curStd.ItemNumber && p.LGORT == "8001").Sum(p => Convert.ToDecimal(p.LABST));
|
|
|
|
|
+ //在制库存
|
|
|
|
|
+ zzQty = sAPInvs.Where(p => p.MATNR == curStd.ItemNumber && p.LGORT == "8000").Sum(p => Convert.ToDecimal(p.LABST));
|
|
|
|
|
+ //灭菌库存
|
|
|
|
|
+ mjQty = sAPInvs.Where(p => p.MATNR == curStd.ItemNumber && p.LGORT == "5008").Sum(p => Convert.ToDecimal(p.LABST));
|
|
|
}
|
|
}
|
|
|
//海外生产需求量=当月的50%+下一月的50%-成品库存-在制库存-灭菌库存
|
|
//海外生产需求量=当月的50%+下一月的50%-成品库存-在制库存-灭菌库存
|
|
|
//TODO:获取成品库存、在制库存、灭菌库存,参与运算
|
|
//TODO:获取成品库存、在制库存、灭菌库存,参与运算
|
|
|
//计算N+1月,N+2月
|
|
//计算N+1月,N+2月
|
|
|
- monthN1.Qty = Math.Ceiling((sumN1 / 2 + sumN2 / 2 - 0 - 0 - 0) / packQty) * packQty;
|
|
|
|
|
- monthN2.Qty = Math.Ceiling((sumN2 - 0 - 0 - 0) / packQty) *packQty; ;
|
|
|
|
|
|
|
+ monthN1.Qty = Math.Ceiling((sumN1 / 2 + sumN2 / 2 - cpQty - zzQty - mjQty) / packQty) * packQty;
|
|
|
|
|
+ monthN2.Qty = Math.Ceiling((sumN2 - cpQty - zzQty - mjQty) / packQty) *packQty; ;
|
|
|
//负数置0
|
|
//负数置0
|
|
|
monthN1.Qty = monthN1.Qty < 0 ? 0m : monthN1.Qty;
|
|
monthN1.Qty = monthN1.Qty < 0 ? 0m : monthN1.Qty;
|
|
|
monthN2.Qty = monthN2.Qty < 0 ? 0m : monthN2.Qty;
|
|
monthN2.Qty = monthN2.Qty < 0 ? 0m : monthN2.Qty;
|
|
@@ -452,7 +474,7 @@ namespace Business.SaleForecastManagement
|
|
|
var nextMonDFcsts = domesticFcst.Where(p => p.PlanMonth == strN2).ToList();
|
|
var nextMonDFcsts = domesticFcst.Where(p => p.PlanMonth == strN2).ToList();
|
|
|
var nextMonT2Fcsts = T2Fcsts.Where(p => p.PlanMonth == strN2).ToList();
|
|
var nextMonT2Fcsts = T2Fcsts.Where(p => p.PlanMonth == strN2).ToList();
|
|
|
var nextMonMonitors = monitorSettings.Where(p => p.PlanMonth == strN1).ToList();
|
|
var nextMonMonitors = monitorSettings.Where(p => p.PlanMonth == strN1).ToList();
|
|
|
- var replenishs = MonthlyReplenish(input,strN1, nextMonPFcsts, nextMonDFcsts, nextMonT2Fcsts, standards, items, holidays, nextMonMonitors);
|
|
|
|
|
|
|
+ var replenishs = MonthlyReplenish(input,strN1, nextMonPFcsts, nextMonDFcsts, nextMonT2Fcsts, standards, items, holidays, nextMonMonitors, sAPInvs);
|
|
|
|
|
|
|
|
//保存数据
|
|
//保存数据
|
|
|
using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
|
|
using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
|
|
@@ -623,16 +645,17 @@ namespace Business.SaleForecastManagement
|
|
|
/// <param name="items">物料</param>
|
|
/// <param name="items">物料</param>
|
|
|
/// <param name="holidays">节假日</param>
|
|
/// <param name="holidays">节假日</param>
|
|
|
/// <param name="monitorSettings">库存监控月份设置</param>
|
|
/// <param name="monitorSettings">库存监控月份设置</param>
|
|
|
|
|
+ /// <param name="sAPInvs">SAP库存</param>
|
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
|
- public List<crm_planorder> MonthlyReplenish(InputDto input,string strN1, List<PlatformFcstCollect> platformFcsts, List<DomesticTerminalFcst> domesticFcsts, List<DomesticTerminalFcst> T2Fcsts, List<StandardItemModelSet> standards, List<ic_item> items, List<HolidayMaster> holidays, List<PlatStockMonitorSetting> monitorSettings)
|
|
|
|
|
|
|
+ public List<crm_planorder> MonthlyReplenish(InputDto input,string strN1, List<PlatformFcstCollect> platformFcsts, List<DomesticTerminalFcst> domesticFcsts, List<DomesticTerminalFcst> T2Fcsts, List<StandardItemModelSet> standards, List<ic_item> items, List<HolidayMaster> holidays, List<PlatStockMonitorSetting> monitorSettings, List<SAPInv> sAPInvs)
|
|
|
{
|
|
{
|
|
|
List<crm_planorder> planorders = new List<crm_planorder>();
|
|
List<crm_planorder> planorders = new List<crm_planorder>();
|
|
|
//获取T1中规格型号对应的不同版本的物料编码
|
|
//获取T1中规格型号对应的不同版本的物料编码
|
|
|
var T1Models = domesticFcsts.Select(p => p.Model).Distinct().ToList();
|
|
var T1Models = domesticFcsts.Select(p => p.Model).Distinct().ToList();
|
|
|
List<SkuVersionSet> skus = _skuVersionSet.GetListAsync(p=> T1Models.Contains(p.Model) && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result;
|
|
List<SkuVersionSet> skus = _skuVersionSet.GetListAsync(p=> T1Models.Contains(p.Model) && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result;
|
|
|
//获取T1库存
|
|
//获取T1库存
|
|
|
- List<string> itemNums = skus.Select(p=>p.ItemNum).Distinct().ToList();
|
|
|
|
|
- List<LocationDetail> locationDetails = _locationDetail.Select(p=> itemNums.Contains(p.ItemNum) && p.Domain == input.factory_id.ToString() && p.IsActive);
|
|
|
|
|
|
|
+ //List<string> itemNums = skus.Select(p=>p.ItemNum).Distinct().ToList();
|
|
|
|
|
+ //List<LocationDetail> locationDetails = _locationDetail.Select(p=> itemNums.Contains(p.ItemNum) && p.Domain == input.factory_id.ToString() && p.IsActive);
|
|
|
|
|
|
|
|
//获取临期库存设置
|
|
//获取临期库存设置
|
|
|
GeneralizedCodeMaster master = _generalizedCodeMaster.Select(p => p.Domain == input.factory_id.ToString() && p.IsActive && p.Val == "LongPeriodItemPlanMonth").FirstOrDefault();
|
|
GeneralizedCodeMaster master = _generalizedCodeMaster.Select(p => p.Domain == input.factory_id.ToString() && p.IsActive && p.Val == "LongPeriodItemPlanMonth").FirstOrDefault();
|
|
@@ -653,7 +676,7 @@ namespace Business.SaleForecastManagement
|
|
|
var curSkus = skus.Where(p => p.Model == item).ToList();
|
|
var curSkus = skus.Where(p => p.Model == item).ToList();
|
|
|
if (curSkus.Any())
|
|
if (curSkus.Any())
|
|
|
{
|
|
{
|
|
|
- sumQty = locationDetails.Where(p => curSkus.Select(p => p.ItemNum).Contains(p.ItemNum)).Sum(p => p.QtyOnHand);
|
|
|
|
|
|
|
+ sumQty = sAPInvs.Where(p => curSkus.Select(p => p.ItemNum).Contains(p.MATNR)).Sum(p => Convert.ToDecimal(p.LABST));
|
|
|
}
|
|
}
|
|
|
//计算Rop
|
|
//计算Rop
|
|
|
//当前规格型号对应标准SKU的最小包装单位、补货周期
|
|
//当前规格型号对应标准SKU的最小包装单位、补货周期
|
|
@@ -779,7 +802,7 @@ namespace Business.SaleForecastManagement
|
|
|
//获取国科当前规格型号库存
|
|
//获取国科当前规格型号库存
|
|
|
sumQty = pInventories.Where(p => p.SpecificationModel == item && p.Code == "GK0001").Sum(p => p.InventoryQuantity);
|
|
sumQty = pInventories.Where(p => p.SpecificationModel == item && p.Code == "GK0001").Sum(p => p.InventoryQuantity);
|
|
|
//获取N+1月的库存监控设置
|
|
//获取N+1月的库存监控设置
|
|
|
- var curMonitor = monitorSettings.FirstOrDefault(p => p.Platform == "GK0001" && p.ProdType == curFcsts[0].ProdType);
|
|
|
|
|
|
|
+ var curMonitor = monitorSettings.FirstOrDefault(p => p.Platform == "国科" && p.ProdType == curFcsts[0].ProdType);
|
|
|
if (curMonitor == null)
|
|
if (curMonitor == null)
|
|
|
{
|
|
{
|
|
|
new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("DemandAnalysis", "国科未维护产品类型为【" + curFcsts[0].ProdType + "】的库存监控月份", _currentTenant.Id.ToString());
|
|
new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("DemandAnalysis", "国科未维护产品类型为【" + curFcsts[0].ProdType + "】的库存监控月份", _currentTenant.Id.ToString());
|
|
@@ -834,11 +857,6 @@ namespace Business.SaleForecastManagement
|
|
|
p.create_by_name = input.create_by_name;
|
|
p.create_by_name = input.create_by_name;
|
|
|
p.create_time = DateTime.Now;
|
|
p.create_time = DateTime.Now;
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
return planorders;
|
|
return planorders;
|
|
|
}
|
|
}
|
|
|
|
|
|