|
|
@@ -1140,13 +1140,17 @@ namespace Business.Replenishment
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- rop.monthl_avg_outstock = Math.Ceiling(SumOutQty / MonthCount);
|
|
|
-
|
|
|
+ if(MonthCount==0)
|
|
|
+ {
|
|
|
+ rop.monthl_avg_outstock = 0;
|
|
|
+ }else
|
|
|
+ {
|
|
|
+ rop.monthl_avg_outstock = Math.Ceiling(SumOutQty / MonthCount);
|
|
|
+ }
|
|
|
rop.year = DateTime.Now.AddMonths(j).Year;
|
|
|
rop.month = DateTime.Now.AddMonths(j).Month;
|
|
|
rop.planmonth = $"{DateTime.Now.AddMonths(j).Year}-{DateTime.Now.AddMonths(j).Month.ToString("00")}";
|
|
|
//供应提前期,成品取物料主数据维护的,原材料从货源清单取取不到取物料维护的
|
|
|
- rop.supply_leadtime = 22;//默认
|
|
|
if(icItem.erp_cls==1)
|
|
|
{
|
|
|
rop.supply_leadtime = icItem.PurLT;//默认
|
|
|
@@ -1160,6 +1164,8 @@ namespace Business.Replenishment
|
|
|
rop.supply_leadtime = icItem.PurLT;//默认
|
|
|
}
|
|
|
}
|
|
|
+ if(rop.supply_leadtime==0)
|
|
|
+ rop.supply_leadtime = 22;//默认
|
|
|
//存货周转率先取规格型号,没有再取产品系列,没有取产品线,再没有取物料配置的(主要是原材料),再没有就默认
|
|
|
if (turnOverlist.Find(t => t.Model == rop.model) != null)
|
|
|
{
|
|
|
@@ -1184,7 +1190,7 @@ namespace Business.Replenishment
|
|
|
CalcFMRAndABC(rop, replenishmentDto, shipList, pickbilllist, input);
|
|
|
rop.security_stock = Math.Ceiling((decimal)(mathtool.InverseCumulativeDistribution((double)rop.service_level_pct.Value) * (double)rop.monthl_avg_demand_variance));
|
|
|
|
|
|
- rop.eop = Math.Ceiling(rop.monthl_avg_demand.Value * rop.supply_leadtime.Value / DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month));
|
|
|
+ rop.eop = Math.Ceiling(rop.monthl_avg_demand.Value * rop.supply_leadtime.Value / DateTime.DaysInMonth(DateTime.Now.AddMonths(j).Year, DateTime.Now.AddMonths(months: j).Month));
|
|
|
rop.rop_computed = rop.security_stock + rop.eop;
|
|
|
rop.max_stock_level = rop.monthl_avg_outstock * (12 / rop.stock_turnover);
|
|
|
//瑞奇是ROP和最高库存值两者之间取较小的值,平台是取较大的值。
|
|
|
@@ -1198,14 +1204,14 @@ namespace Business.Replenishment
|
|
|
}
|
|
|
|
|
|
//存在上一个月补货
|
|
|
- if (updateList.Find(r => r.number == a.SAPItemNumber && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}") != null)
|
|
|
+ if (updateList.Find(r => r.number == a.SAPItemNumber && r.distributionchannel==a.DistributionChannel && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}") != null)
|
|
|
{
|
|
|
- var avaItem = updateList.Find(r => r.number == a.SAPItemNumber && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}");
|
|
|
+ var avaItem = updateList.Find(r => r.number == a.SAPItemNumber && r.distributionchannel == a.DistributionChannel && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}");
|
|
|
rop.avaStockQty = Math.Ceiling(avaItem.avaStockQty.GetValueOrDefault() + avaItem.montheop1.GetValueOrDefault() + avaItem.montheop2.GetValueOrDefault() - a.Qty);
|
|
|
}
|
|
|
- else if (addList.Find(r => r.number == a.SAPItemNumber && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}") != null)
|
|
|
+ else if (addList.Find(r => r.number == a.SAPItemNumber && r.distributionchannel == a.DistributionChannel && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}") != null)
|
|
|
{
|
|
|
- var avaItem = addList.Find(r => r.number == a.SAPItemNumber && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}");
|
|
|
+ var avaItem = addList.Find(r => r.number == a.SAPItemNumber && r.distributionchannel == a.DistributionChannel && r.planmonth == $"{DateTime.Now.AddMonths(j - 1).Year}-{DateTime.Now.AddMonths(j - 1).Month.ToString("00")}");
|
|
|
rop.avaStockQty = Math.Ceiling(avaItem.avaStockQty.GetValueOrDefault() + avaItem.montheop1.GetValueOrDefault() + avaItem.montheop2.GetValueOrDefault() - a.Qty);
|
|
|
}
|
|
|
else
|
|
|
@@ -1240,8 +1246,8 @@ namespace Business.Replenishment
|
|
|
rop.avaStockQty = dictItemStock[a.SAPItemNumber];
|
|
|
}
|
|
|
}
|
|
|
- rop.montheop1 = rop.rop_computed > rop.avaStockQty ? rop.eop : 0;
|
|
|
- rop.montheop2 = rop.security_stock > rop.avaStockQty ? rop.eop : 0;
|
|
|
+ rop.montheop1 = rop.rop_computed > rop.avaStockQty.GetValueOrDefault() ? rop.eop : 0;
|
|
|
+ rop.montheop2 = rop.security_stock > rop.avaStockQty.GetValueOrDefault() ? rop.eop : 0;
|
|
|
rop.ProdLine = a.ProdLine;
|
|
|
rop.ProdRange = a.ProdRange;
|
|
|
rop.Languages = a.Languages;
|
|
|
@@ -1303,7 +1309,6 @@ namespace Business.Replenishment
|
|
|
rop.month = DateTime.Now.AddMonths(j).Month;
|
|
|
rop.planmonth = $"{DateTime.Now.AddMonths(j).Year}-{DateTime.Now.AddMonths(j).Month.ToString("00")}";
|
|
|
//供应提前期,成品取物料主数据维护的,原材料从货源清单取取不到取物料维护的
|
|
|
- rop.supply_leadtime = 22;//默认
|
|
|
if (icItem.erp_cls == 1)
|
|
|
{
|
|
|
rop.supply_leadtime = icItem.PurLT;//默认
|
|
|
@@ -1319,23 +1324,39 @@ namespace Business.Replenishment
|
|
|
rop.supply_leadtime = icItem.PurLT;//默认
|
|
|
}
|
|
|
}
|
|
|
+ if(rop.supply_leadtime==0)
|
|
|
+ rop.supply_leadtime = 22;//默认
|
|
|
//原材料周转率取物料
|
|
|
if (mesItemList.Find(s => s.ItemNum ==rop.number) != null)
|
|
|
{
|
|
|
rop.stock_turnover = mesItemList.Find(s => s.ItemNum == rop.number).StockTurnOver;
|
|
|
+ if(rop.stock_turnover==0)
|
|
|
+ {
|
|
|
+ rop.stock_turnover = 4;
|
|
|
+ }
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
rop.stock_turnover = 4;
|
|
|
}
|
|
|
+ if (rop.stock_turnover == 0)
|
|
|
+ rop.stock_turnover = 4;
|
|
|
CalcFMRAndABC(rop, replenishmentDto, shipList, pickbilllist, input);
|
|
|
rop.security_stock = Math.Ceiling((decimal)(mathtool.InverseCumulativeDistribution((double)rop.service_level_pct.Value) * (double)rop.monthl_avg_demand_variance));
|
|
|
|
|
|
- rop.eop = Math.Ceiling(rop.monthl_avg_demand.Value * rop.supply_leadtime.Value / DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month));
|
|
|
+ rop.eop = Math.Ceiling(rop.monthl_avg_demand.Value * rop.supply_leadtime.Value / DateTime.DaysInMonth(DateTime.Now.AddMonths(j).Year, DateTime.Now.AddMonths(j).Month));
|
|
|
rop.rop_computed = rop.security_stock + rop.eop;
|
|
|
rop.max_stock_level = rop.monthl_avg_outstock * (12 / rop.stock_turnover);
|
|
|
//瑞奇是ROP和最高库存值两者之间取较小的值,平台是取较大的值。
|
|
|
- rop.rop_revised = Math.Min(rop.rop_computed.Value, rop.max_stock_level.Value);
|
|
|
+ //瑞奇是ROP和最高库存值两者之间取较小的值,平台是取较大的值。
|
|
|
+ if (a.DistributionChannel != "瑞奇")
|
|
|
+ {
|
|
|
+ rop.rop_revised = Math.Max(rop.rop_computed.Value, rop.max_stock_level.Value);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ rop.rop_revised = Math.Min(rop.rop_computed.Value, rop.max_stock_level.Value);
|
|
|
+ }
|
|
|
|
|
|
|
|
|
//存在上一个月补货
|
|
|
@@ -1352,10 +1373,11 @@ namespace Business.Replenishment
|
|
|
else
|
|
|
{
|
|
|
//取实际库存
|
|
|
- rop.avaStockQty = locations.Where(a=>a.ItemNum==rop.number).Sum(a=>a.QtyOnHand);
|
|
|
+ //1开始的库位为原料仓
|
|
|
+ rop.avaStockQty = locations.Where(a=>a.ItemNum==rop.number && a.Location.StartsWith("1")).Sum(a=>a.QtyOnHand);
|
|
|
}
|
|
|
- rop.montheop1 = rop.rop_computed > rop.avaStockQty ? rop.eop : 0;
|
|
|
- rop.montheop2 = rop.security_stock > rop.avaStockQty ? rop.eop : 0;
|
|
|
+ rop.montheop1 = rop.rop_computed > rop.avaStockQty.GetValueOrDefault() ? rop.eop : 0;
|
|
|
+ rop.montheop2 = rop.security_stock > rop.avaStockQty.GetValueOrDefault() ? rop.eop : 0;
|
|
|
rop.ProdLine = a.ProdLine;
|
|
|
rop.ProdRange = a.ProdRange;
|
|
|
rop.Languages = a.Languages;
|
|
|
@@ -1502,9 +1524,26 @@ namespace Business.Replenishment
|
|
|
_workOrdMaster.Delete(a => workOrderDelete.Contains(a.WorkOrd) && a.Domain == input.factory_id.ToString());
|
|
|
_workOrdRouting.Delete(a => workOrderDelete.Contains(a.WorkOrd) && a.Domain == input.factory_id.ToString());
|
|
|
_workOrdDetail.Delete(a => workOrderDelete.Contains(a.WorkOrd) && a.Domain == input.factory_id.ToString());
|
|
|
- await _mysql_mes_morder.DeleteAsync(a => workOrderDelete.Contains(a.morder_no) && a.factory_id == input.factory_id);
|
|
|
- await _mysql_mes_moentry.DeleteAsync(a => workOrderDelete.Contains(a.moentry_mono) && a.factory_id == input.factory_id);
|
|
|
+ var deletedOrderList=_mysql_mes_morder.GetListAsync(a=>workOrderDelete.Contains(a.morder_no) && a.factory_id == input.factory_id).Result;
|
|
|
+ var deletedIds = deletedOrderList.Select(a => a.Id).ToList();
|
|
|
+ await _mysql_mes_morder.DeleteManyAsync(deletedOrderList);
|
|
|
+ var deletedEntryList= _mysql_mes_moentry.GetListAsync(a => workOrderDelete.Contains(a.moentry_mono) && a.factory_id == input.factory_id).Result;
|
|
|
+ await _mysql_mes_moentry.DeleteManyAsync(deletedEntryList);
|
|
|
var examine_result = _mysql_examine_result.GetListAsync(a => workOrderDelete.Contains(a.morder_no) && a.factory_id == input.factory_id).Result;
|
|
|
+ List<srm_po_occupy> occupy = await _mysql_srm_po_occupy.GetListAsync(s => workOrderDelete.Contains(s.morder_mo));
|
|
|
+ _businessDbContext.BulkDelete(occupy);
|
|
|
+ //清理工单占用
|
|
|
+ List<mes_mooccupy> mooccupy = await _mysql_mes_mooccupy.GetListAsync(s => deletedIds.Contains(s.moo_id.GetValueOrDefault()));
|
|
|
+ if (mooccupy.Any())
|
|
|
+ {
|
|
|
+ _businessDbContext.BulkDelete(mooccupy);
|
|
|
+ }
|
|
|
+ //清理掉库存占用
|
|
|
+ var itemstockoccupy = _mysql_ic_item_stockoccupy.GetListAsync(s => workOrderDelete.Contains(s.morder_mo)).Result;
|
|
|
+ if (itemstockoccupy.Any())
|
|
|
+ {
|
|
|
+ _businessDbContext.BulkDelete(itemstockoccupy);
|
|
|
+ }
|
|
|
await _mysql_bom_child_examine.DeleteAsync(a => examine_result.Select(b => b.Id).ToList().Contains(a.examine_id.Value) && a.factory_id == input.factory_id);
|
|
|
await _mysql_examine_result.DeleteManyAsync(examine_result);
|
|
|
await _replenishmentWeekPlan.HardDeleteAsync(weekPlanDelete);
|
|
|
@@ -1525,6 +1564,23 @@ namespace Business.Replenishment
|
|
|
List<ReplenishmentWeekPlan> weekPlan = new List<ReplenishmentWeekPlan>();
|
|
|
long bang_id = help.NextId();
|
|
|
|
|
|
+ //获取BOM用于分解到原材料
|
|
|
+ var boms = _ic_bom.GetListAsync(a => planItemList.Contains(a.item_number) && a.factory_id == input.factory_id).Result;
|
|
|
+ var pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result;
|
|
|
+ List<mo_ic_bom> autoCreates = new List<mo_ic_bom>();
|
|
|
+ boms.ForEach(p =>
|
|
|
+ {
|
|
|
+ if (!pretreatments.Where(s => s.sourceid == p.mysql_id).Any())
|
|
|
+ {
|
|
|
+ autoCreates.Add(p);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (autoCreates.Any())
|
|
|
+ {
|
|
|
+ AutoCreateBomBill(input.company_id.ToString(), autoCreates);
|
|
|
+ pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result;
|
|
|
+ }
|
|
|
+
|
|
|
List<string> weeks = new List<string>();
|
|
|
for (int k = 0; k < replenishmentDto.SaleFcstMonth; k++)
|
|
|
{
|
|
|
@@ -1564,9 +1620,9 @@ namespace Business.Replenishment
|
|
|
{
|
|
|
ReplenishmentWeekPlan weekItemPlanAdd = new ReplenishmentWeekPlan();
|
|
|
weekItemPlanAdd.Area = item.area;
|
|
|
- weekItemPlanAdd.Week = $"WK{GetWeekOfYear(DateTime.Now.AddMonths(k).AddDays( 7 * (w))).ToString("00")}";
|
|
|
+ weekItemPlanAdd.Week = $"WK{GetWeekOfYear(DateTime.Now.AddDays(1 - DateTime.Now.Day).AddMonths(k).AddDays( 7 * (w))).ToString("00")}";
|
|
|
weekItemPlanAdd.DistributionChannel = item.distributionchannel;
|
|
|
- weekItemPlanAdd.ProdLine = item.planmonth;
|
|
|
+ weekItemPlanAdd.ProdLine = item.ProdLine;
|
|
|
weekItemPlanAdd.ProdRange = item.ProdRange;
|
|
|
weekItemPlanAdd.Model = item.model;
|
|
|
weekItemPlanAdd.ItemNumber = item.number;
|
|
|
@@ -1600,6 +1656,8 @@ namespace Business.Replenishment
|
|
|
kTime = kTime.AddDays(1 - kTime.Day);//某月第一天
|
|
|
var monthWeekPlan = planList.Where(a => a.planmonth == kMonth).ToList();
|
|
|
var ropList = planList.Select(t => t.number).Distinct().ToList();
|
|
|
+ //中间件汇总,比如A成品10、11、12月都需要中间件C,B成品11、12月都需要中间件C,那么中间件C需要每个月汇总平均分到4周
|
|
|
+ Dictionary<string, decimal?> subProductItem = new Dictionary<string, decimal?>();
|
|
|
foreach (var itemSeq in ropList)
|
|
|
{
|
|
|
if(shipPlanList.Select(s=>s.SAPItemNumber).ToList().Contains(itemSeq))
|
|
|
@@ -1609,7 +1667,7 @@ namespace Business.Replenishment
|
|
|
var monthPlanTotal = monthWeekPlan.Where(x => x.number == itemSeq).ToList();
|
|
|
var item = monthPlanTotal[0];
|
|
|
//瑞奇补货计划!Y5 + 瑞奇补货计划!Z5 + 国科补货计划!Y5 + 国科补货计划!Z5 + 海王补货计划!Y4 + 海王补货计划!Z4
|
|
|
- var itemQty = monthPlanTotal.Sum(a => a.montheop1) + monthPlanTotal.Sum(a => a.montheop1);
|
|
|
+ var itemQty = monthPlanTotal.Sum(a => a.montheop1) + monthPlanTotal.Sum(a => a.montheop2);
|
|
|
//每次都是发布12周,每个月4周,不用判断存不存在(退市的可能没有)
|
|
|
int days = 15;
|
|
|
if (item.area != "国内" && item.area != "中国")
|
|
|
@@ -1726,6 +1784,28 @@ namespace Business.Replenishment
|
|
|
moentryList.Add(mes_Moentry);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ var planBOM = boms.Find(b => b.item_number == itemSeq);
|
|
|
+ var pretreament = pretreatments.Where(c => c.sourceid == planBOM.mysql_id).ToList();
|
|
|
+ var returnlist = ObjectMapper.Map<List<b_bom_pretreatment>, List<BomChildExamineDto>>(pretreament);
|
|
|
+ returnlist = returnlist.OrderBy(s => s.num_order).ToList();
|
|
|
+ var level1Dto = returnlist[0];
|
|
|
+ level1Dto.needCount = itemQty.GetValueOrDefault();
|
|
|
+ CaclMaterialShortage(returnlist);
|
|
|
+ foreach (var r in returnlist)
|
|
|
+ {
|
|
|
+ if(r.item_number!=itemSeq && r.erp_cls==1)
|
|
|
+ {
|
|
|
+ if (subProductItem.ContainsKey(r.item_number))
|
|
|
+ {
|
|
|
+ subProductItem[r.item_number] += r.needCount;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ subProductItem.Add(r.item_number, r.needCount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -1739,13 +1819,16 @@ namespace Business.Replenishment
|
|
|
weekPlan[i].OrderNO = OrderNOList[i].NbrResult;
|
|
|
}
|
|
|
|
|
|
- await _mysql_mes_morder.InsertManyAsync(moList);
|
|
|
- await _mysql_mes_moentry.InsertManyAsync(moentryList);
|
|
|
-
|
|
|
await PlanOrderResourceCheck(moList, moentryList, bang_id, input);
|
|
|
|
|
|
-
|
|
|
var examine_resultList = _mysql_examine_result.GetListAsync(a => a.bangid == bang_id).Result;
|
|
|
+ moList.ForEach(mo =>
|
|
|
+ {
|
|
|
+ var moItem = examine_resultList.Find(b => b.morder_no == mo.morder_no);
|
|
|
+ mo.moentry_sys_stime = moItem.kitting_times;
|
|
|
+ });
|
|
|
+ await _mysql_mes_morder.InsertManyAsync(moList);
|
|
|
+ await _mysql_mes_moentry.InsertManyAsync(moentryList);
|
|
|
|
|
|
//批量保存 后期考虑子工单
|
|
|
List<WorkOrdMaster> workOrdSave = new List<WorkOrdMaster>();
|
|
|
@@ -2302,6 +2385,7 @@ namespace Business.Replenishment
|
|
|
var productStructureMs = _productStructureMaster.Select(x => morders.Select(c => c.morder_no).Contains(x.ParentItem) && x.Domain == param.factoryId.ToString());
|
|
|
foreach (var item in morders)
|
|
|
{
|
|
|
+ var moItem = exmResult.Find(b => b.morder_no ==item.morder_no);
|
|
|
//添加工单数据
|
|
|
workOrd = new WorkOrdMaster();
|
|
|
workOrd.Domain = item.factory_id.ToString();
|
|
|
@@ -3654,7 +3738,7 @@ namespace Business.Replenishment
|
|
|
var bomList = _mysql_ic_bom.GetListAsync(a => itemList.Contains(a.item_number) && !a.IsDeleted && a.factory_id == input.factory_id).Result;
|
|
|
List<mes_morder> moList=new List<mes_morder>();
|
|
|
List<mes_moentry> moentryList = new List<mes_moentry>();
|
|
|
- var list = _serialNumberAppService.GetBillNo(input.factory_id.ToString(), "MPO", productList.Count(), "", 1);
|
|
|
+ var list = _serialNumberAppService.GetBillNo(input.factory_id.ToString(), "M5", productList.Count(), "", 1);
|
|
|
long bangid = help.NextId();
|
|
|
for (int i = 0;i< productList.Count();i++)
|
|
|
{
|