|
|
@@ -29,6 +29,8 @@ using MathNet.Numerics.RootFinding;
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
using System.Collections;
|
|
|
+using MongoDB.Driver.Linq;
|
|
|
+using System.Reflection;
|
|
|
|
|
|
namespace Business.Replenishment
|
|
|
{
|
|
|
@@ -103,8 +105,9 @@ namespace Business.Replenishment
|
|
|
private readonly IRepository<mo_mes_oorder, long> _mes_oorder;
|
|
|
private readonly ISqlRepository<ScheduleResultOpMaster> _scheduleResultOpMaster;
|
|
|
private readonly IRepository<ProductionMasterPlan, long> _productionMasterPlan;
|
|
|
-
|
|
|
-
|
|
|
+ private readonly IRepository<ReplenishmentWeekPlan, long> _replenishmentWeekPlan;
|
|
|
+ private readonly IRepository<b_examine_result, long> _mysql_examine_result;
|
|
|
+ private readonly IRepository<b_bom_child_examine, long> _mysql_bom_child_examine;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 年度销售预测
|
|
|
@@ -174,6 +177,8 @@ namespace Business.Replenishment
|
|
|
/// </summary>
|
|
|
private readonly PretreatmentAppService _pretreatmentAppService;
|
|
|
|
|
|
+ private readonly SerialNumberAppService _serialNumberAppService;
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 产能检查
|
|
|
/// </summary>
|
|
|
@@ -233,8 +238,8 @@ namespace Business.Replenishment
|
|
|
ISqlRepository<SAPInv> SAPInv,
|
|
|
IRepository<srm_purchase, long> srmPurchase,
|
|
|
ISqlRepository<MonthlyShipmentPlan> monthlyShipmentPlan,
|
|
|
- ISqlRepository<GeneralizedCodeMaster> generalizedCodeMaster,
|
|
|
- ISqlRepository<rf_serialnumber> rf_serialnumber,
|
|
|
+ ISqlRepository<GeneralizedCodeMaster> generalizedCodeMaster,
|
|
|
+ ISqlRepository<rf_serialnumber> rf_serialnumber,
|
|
|
ISqlRepository<LocationDetail> locationDetail,
|
|
|
IRepository<mo_ic_item, long> ic_item,
|
|
|
IRepository<ic_item, long> mysql_ic_item,
|
|
|
@@ -296,10 +301,11 @@ namespace Business.Replenishment
|
|
|
IRepository<MonthlyProdCapacityDtl, long> monthlyProdCapacityDtl,
|
|
|
IRepository<crm_planorder, long> crm_planorder,
|
|
|
IRepository<WMS_PlatformInventory, long> platformInventory,
|
|
|
+ IRepository<ReplenishmentWeekPlan, long> replenishmentWeekPlan,
|
|
|
+ IRepository<b_examine_result, long> mysql_examine_result,
|
|
|
+ IRepository<b_bom_child_examine, long> mysql_bom_child_examine,
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ SerialNumberAppService serialNumberAppService,
|
|
|
PretreatmentAppService pretreatmentAppService,
|
|
|
PurchaseOrderAppService purchaseOrderAppService,
|
|
|
CalcBomViewAppService CalcBomViewAppService,
|
|
|
@@ -370,7 +376,9 @@ namespace Business.Replenishment
|
|
|
_mes_oorder = mes_oorder;
|
|
|
_scheduleResultOpMaster = scheduleResultOpMaster;
|
|
|
_productionMasterPlan=productionMasterPlan;
|
|
|
-
|
|
|
+ _replenishmentWeekPlan=replenishmentWeekPlan;
|
|
|
+ _mysql_examine_result = mysql_examine_result;
|
|
|
+ _mysql_bom_child_examine= mysql_bom_child_examine;
|
|
|
|
|
|
_PlatformInventory = PlatformInventory;
|
|
|
_workOrdRouting = workOrdRouting;
|
|
|
@@ -384,6 +392,7 @@ namespace Business.Replenishment
|
|
|
_crm_planorder = crm_planorder;
|
|
|
_platformInventory = platformInventory;
|
|
|
|
|
|
+ _serialNumberAppService= serialNumberAppService;
|
|
|
_pretreatmentAppService = pretreatmentAppService;
|
|
|
_CalcBomViewAppService = CalcBomViewAppService;
|
|
|
_purchaseOrderAppService = purchaseOrderAppService;
|
|
|
@@ -723,133 +732,6 @@ namespace Business.Replenishment
|
|
|
return sumDays;
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 生成整体需求计划
|
|
|
- /// </summary>
|
|
|
- /// <param name="input"></param>
|
|
|
- /// <returns></returns>
|
|
|
- /// <exception cref="NotImplementedException"></exception>
|
|
|
- //public async Task<string> OverallDemandPlan(InputDto input)
|
|
|
- //{
|
|
|
- // //1.1、获取海外销售预测数据
|
|
|
- // List<OverseasSaleFcst> overseasSales = _overseasSaleFcst.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.OrderBy(p => p.OrderNum).ToList();
|
|
|
- // //1.2、获取平台预测收集数据
|
|
|
- // List<PlatformFcstCollect> platformFcsts = _platformFcstCollect.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.OrderBy(p => p.OrderNum).ToList();
|
|
|
- // //1.3、获取国内终端预测-T1汇总数据
|
|
|
- // List<DomesticTerminalFcst> domesticFcsts = _domesticTerminalFcst.GetListAsync(p => p.TypeEnum == 2 && 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.OrderBy(p => p.OrderNum).ToList();
|
|
|
-
|
|
|
- // //计算当前年月的N+1,N+2
|
|
|
- // string strN0 = input.year.ToString() + "-" + input.month.ToString("00");
|
|
|
- // int newYear = input.month == 12 ? input.year + 1 : input.year;
|
|
|
- // int newMonth = input.month == 12 ? 1 : input.month + 1;
|
|
|
- // string strN1 = newYear.ToString() + "-" + newMonth.ToString("00");
|
|
|
- // newYear = newMonth == 12 ? newYear + 1 : newYear;
|
|
|
- // newMonth = newMonth == 12 ? 1 : newMonth + 1;
|
|
|
- // string strN2 = newYear.ToString() + "-" + newMonth.ToString("00");
|
|
|
-
|
|
|
- // //整体需求计划
|
|
|
- // List<OverallDemandPlan> plans = new List<OverallDemandPlan>();
|
|
|
- // //计算海外
|
|
|
- // List<string> hwModels = overseasSales.Select(p => p.Model).Distinct().ToList();
|
|
|
- // int OrderNum = 1;
|
|
|
- // foreach (var item in hwModels)
|
|
|
- // {
|
|
|
- // var curFcsts = overseasSales.Where(p => p.Model == item).ToList();
|
|
|
- // OverallDemandPlan plan = new OverallDemandPlan();
|
|
|
- // plan.Area = "海外";
|
|
|
- // plan.Model = item;
|
|
|
- // plan.PlanMonth = strN0;
|
|
|
- // plan.Qty = curFcsts.Where(p => p.PlanMonth == strN0).Sum(p => p.Qty);
|
|
|
- // plan.OrderNum = OrderNum;
|
|
|
- // plans.Add(plan);
|
|
|
-
|
|
|
- // plan = new OverallDemandPlan();
|
|
|
- // plan.Area = "海外";
|
|
|
- // plan.Model = item;
|
|
|
- // plan.PlanMonth = strN1;
|
|
|
- // plan.Qty = curFcsts.Where(p => p.PlanMonth == strN1).Sum(p => p.Qty);
|
|
|
- // plan.OrderNum = OrderNum;
|
|
|
- // plans.Add(plan);
|
|
|
-
|
|
|
- // plan = new OverallDemandPlan();
|
|
|
- // plan.Area = "海外";
|
|
|
- // plan.Model = item;
|
|
|
- // plan.PlanMonth = strN2;
|
|
|
- // plan.Qty = curFcsts.Where(p => p.PlanMonth == strN2).Sum(p => p.Qty);
|
|
|
- // plan.OrderNum = OrderNum;
|
|
|
- // plans.Add(plan);
|
|
|
-
|
|
|
- // OrderNum += 1;
|
|
|
- // }
|
|
|
- // //计算国内
|
|
|
- // List<string> gnModels = domesticFcsts.Select(p => p.Model).ToList();
|
|
|
- // gnModels.AddRange(platformFcsts.Select(p => p.Model).ToList());
|
|
|
- // gnModels = gnModels.Distinct().ToList();
|
|
|
- // OrderNum = 1;
|
|
|
- // foreach (var item in gnModels)
|
|
|
- // {
|
|
|
- // var curDFcsts = domesticFcsts.Where(p => p.Model == item).ToList();
|
|
|
- // var curPFcsts = platformFcsts.Where(p => p.Model == item).ToList();
|
|
|
- // OverallDemandPlan plan = new OverallDemandPlan();
|
|
|
- // plan.Area = "国内";
|
|
|
- // plan.Model = item;
|
|
|
- // plan.PlanMonth = strN0;
|
|
|
- // plan.Qty = curDFcsts.Where(p => p.PlanMonth == strN0).Sum(p => p.Qty) + curPFcsts.Where(p => p.PlanMonth == strN0).Sum(p => p.Qty);
|
|
|
- // plan.OrderNum = OrderNum;
|
|
|
- // plans.Add(plan);
|
|
|
-
|
|
|
- // plan = new OverallDemandPlan();
|
|
|
- // plan.Area = "国内";
|
|
|
- // plan.Model = item;
|
|
|
- // plan.PlanMonth = strN1;
|
|
|
- // plan.Qty = curDFcsts.Where(p => p.PlanMonth == strN1).Sum(p => p.Qty) + curPFcsts.Where(p => p.PlanMonth == strN1).Sum(p => p.Qty);
|
|
|
- // plan.OrderNum = OrderNum;
|
|
|
- // plans.Add(plan);
|
|
|
-
|
|
|
- // plan = new OverallDemandPlan();
|
|
|
- // plan.Area = "国内";
|
|
|
- // plan.Model = item;
|
|
|
- // plan.PlanMonth = strN2;
|
|
|
- // plan.Qty = curDFcsts.Where(p => p.PlanMonth == strN2).Sum(p => p.Qty) + curPFcsts.Where(p => p.PlanMonth == strN2).Sum(p => p.Qty);
|
|
|
- // plan.OrderNum = OrderNum;
|
|
|
- // plans.Add(plan);
|
|
|
-
|
|
|
- // OrderNum += 1;
|
|
|
- // }
|
|
|
-
|
|
|
- // plans.ForEach(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.org_id = input.org_id;
|
|
|
- // p.create_by = input.create_by;
|
|
|
- // p.create_by_name = input.create_by_name;
|
|
|
- // p.create_time = DateTime.Now;
|
|
|
- // });
|
|
|
-
|
|
|
- // //保存数据
|
|
|
- // using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
|
|
|
- // {
|
|
|
- // try
|
|
|
- // {
|
|
|
- // //先删除
|
|
|
- // await _overallDemandPlan.HardDeleteAsync(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);
|
|
|
- // //保存整体需求计划
|
|
|
- // await _overallDemandPlan.InsertManyAsync(plans);
|
|
|
- // await unitOfWork.CompleteAsync();
|
|
|
- // }
|
|
|
- // catch (Exception e)
|
|
|
- // {
|
|
|
- // unitOfWork.Dispose();
|
|
|
- // new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("OverallDemandPlan", "生成【" + input.year + "年" + input.month + "月】整体需求计划失败:" + e.Message, _currentTenant.Id.ToString());
|
|
|
- // return "NO|" + e.Message;
|
|
|
- // };
|
|
|
- // }
|
|
|
- // return "OK|刷新成功!";
|
|
|
- //}
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// 调整ROP和最高库存水位(按照成品展开到原材料,原材料用领料算出库)
|
|
|
/// </summary>
|
|
|
@@ -1031,143 +913,172 @@ namespace Business.Replenishment
|
|
|
{
|
|
|
//1.获取补货模型全局参数
|
|
|
ReplenishmentDto replenishmentDto = GetROPParam(input.factory_id.ToString());
|
|
|
-
|
|
|
- //Step1:按照瑞奇、两大平台分别根据历史出库数据和预测出货数据计算ROP
|
|
|
- //Step2:计算瑞奇的M-M+2共12周补货(每次补EOP/4),计算海王的M-M+2共12周补货(每次补EOP/4),计算国科的M-M+2共12周补货(每次补EOP/4)
|
|
|
- //Step3:汇总Step2所有补货,为工厂的制造需求
|
|
|
- //Step4:按照Step3制造需求做资源检查,按月统计各物料消耗预测
|
|
|
- //Step5:按照各SKU的历史出库数据和Step4里计算的预测消耗数量计算参数
|
|
|
- //Step6:计算各SKU的12周采购补货
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
//获取月度发货计划(一次导入三个月的销售预测),因为是固定格式yyyy-MM所以可以用字符串比较,避免写很多字符串判断相等
|
|
|
string planMonth = $"{DateTime.Now.Year}-{DateTime.Now.Month.ToString("00")}";
|
|
|
string planMonthMax = $"{DateTime.Now.AddMonths(replenishmentDto.SaleFcstMonth).Year}-{DateTime.Now.AddMonths(replenishmentDto.SaleFcstMonth).Month.ToString("00")}";
|
|
|
var planList = _monthlyShipmentPlan.Select(a => a.PlanMonth.CompareTo(planMonth) >= 0 && a.PlanMonth.CompareTo(planMonthMax) <= 0 && !a.IsDeleted).ToList();
|
|
|
-
|
|
|
-
|
|
|
- var itemList = _ic_item.GetListAsync(a => planList.Select(p => p.SAPItemNumber).Contains(a.number) && a.tenant_id == input.tenant_id && a.company_id == input.company_id && !a.IsDeleted).Result;
|
|
|
- var mesItemList = _itemMaster.Select(a => planList.Select(p => p.SAPItemNumber).Contains(a.ItemNum) && a.Domain == input.factory_id.ToString() && a.IsActive);
|
|
|
- var srm_purchaseList = _srmPurchase.GetListAsync(a => planList.Select(p => p.SAPItemNumber).Contains(a.number) && a.tenant_id == input.tenant_id && a.company_id == input.company_id && !a.IsDeleted).Result;
|
|
|
-
|
|
|
- //获取补货模型前H周期和未来F个周期的数据
|
|
|
- var ropModelList = _replenishmentROP.GetListAsync(a => a.zero_based_seqno >= -1 * replenishmentDto.HistoryOutStockMonth && a.zero_based_seqno <= replenishmentDto.SaleFcstMonth).Result;
|
|
|
//发货计划物料列表
|
|
|
List<string> planItemList = planList?.Select(a => a.SAPItemNumber).ToList();
|
|
|
- //获取成品库存、灭菌库存、在制库存(会从SAP同步的库存表更新到LocationDetail、ic_item表中)
|
|
|
- //List<SAPInv> sAPInvs = _SAPInv.Select(p => p.WERKS == input.factory_id.ToString() && itemNums.Contains(p.MATNR));
|
|
|
- var locations = _locationDetail.Select(p => p.Domain == input.factory_id.ToString() && planList.Select(a => a.SAPItemNumber).Contains(p.ItemNum) && p.IsActive);
|
|
|
- var sapItemInv = _SAPInv.Select(a => planItemList.Contains(a.MATNR) && a.WERKS == input.factory_id.ToString());
|
|
|
-
|
|
|
- //取上一个月发货出库记录
|
|
|
- var shipList = _ASNBOLShipperDetail.Select(a => a.Domain == input.factory_id.ToString() && a.IsActive && a.shtype == "SH" && a.Typed != "S" && a.RealQty > 0 && planItemList.Contains(a.ContainerItem) && a.ShipDate >= getMonthStartTime(-1) && a.ShipDate <= getMonthEndTime(-1));
|
|
|
-
|
|
|
- //取本月发货出库记录
|
|
|
- var shipMList = _ASNBOLShipperDetail.Select(a => a.Domain == input.factory_id.ToString() && a.IsActive && a.shtype == "SH" && a.Typed != "S" && a.RealQty > 0 && planItemList.Contains(a.ContainerItem) && a.ShipDate >= getMonthStartTime(0) && a.ShipDate <= DateTime.Now);
|
|
|
- //按照物料分组统计出货金额
|
|
|
- var itemGroup = shipList.GroupBy(p => p.ContainerItem)
|
|
|
- .Select(p => new ASNBOLShipperDetail
|
|
|
- {
|
|
|
- QtyToShip = p.Sum(a => a.QtyToShip),
|
|
|
- ContainerItem = p.Key
|
|
|
- }).ToList();
|
|
|
- //按照物料分组统计出货金额
|
|
|
- var itemMGroup = shipMList.GroupBy(p => p.ContainerItem)
|
|
|
- .Select(p => new ASNBOLShipperDetail
|
|
|
- {
|
|
|
- QtyToShip = p.Sum(a => a.QtyToShip),
|
|
|
- ContainerItem = p.Key
|
|
|
- }).ToList();
|
|
|
- List<ReplenishmentROP> addList = new List<ReplenishmentROP>();
|
|
|
- List<ReplenishmentROP> updateList = new List<ReplenishmentROP>();//更新上一个月的实际出库数量
|
|
|
- var mathtool = new MathNet.Numerics.Distributions.Normal();
|
|
|
- ropModelList?.Where(r => r.isparam && r.seqno == DateTime.Now.AddMonths(-1).Month && r.year == DateTime.Now.AddMonths(-1).Year).ToList()?.ForEach
|
|
|
- (m =>
|
|
|
- {
|
|
|
- if (itemGroup.Any(a => a.ContainerItem == m.number))
|
|
|
+ var itemList = _ic_item.GetListAsync(a => planList.Select(p => p.SAPItemNumber).Contains(a.number) && a.tenant_id == input.tenant_id && a.company_id == input.company_id && !a.IsDeleted).Result;
|
|
|
+ var bomList = _ic_bom.GetListAsync(a => planItemList.Contains(a.item_number) && !a.IsDeleted && a.factory_id == input.factory_id).Result;
|
|
|
+ var monthPlan = _productionMasterPlan.GetListAsync(a => planItemList.Contains(a.ItemNumber) && !a.IsDeleted && a.factory_id == input.factory_id).Result;
|
|
|
+ //获取补货模型前H周期和未来F个周期的数据
|
|
|
+ var ropModelList = _replenishmentROP.GetListAsync(a => a.zero_based_seqno >= -1 * replenishmentDto.HistoryOutStockMonth && a.zero_based_seqno <= replenishmentDto.SaleFcstMonth && planItemList.Contains(a.number)).Result;
|
|
|
+ planList = planList.OrderBy(a => a.OrderNum).ToList();
|
|
|
+ List<mes_morder> moList = new List<mes_morder>();
|
|
|
+ List<mes_moentry> moentryList = new List<mes_moentry>();
|
|
|
+ List<ReplenishmentWeekPlan> weekPlan = new List<ReplenishmentWeekPlan>();
|
|
|
+ long bang_id = help.NextId();
|
|
|
+ DateTime currentTime = DateTime.Now;
|
|
|
+ int week = Convert.ToInt32(currentTime.DayOfWeek);
|
|
|
+ week = week == 0 ? 7 : week;
|
|
|
+
|
|
|
+ int count = planList.Count * 12;
|
|
|
+ var list = _serialNumberAppService.GetBillNo(input.factory_id.ToString(), "MPO", count, "", 1);
|
|
|
+ var nbrlistDto = _serialNumberAppService.GetBillNo(input.factory_id.ToString(), "M5", count, "", 1);
|
|
|
+ int j = 0;
|
|
|
+ for (int i=0;i<12;i++)
|
|
|
+ {
|
|
|
+ planList.ForEach(a =>
|
|
|
+ {
|
|
|
+ var ic_item = itemList.Find(x => x.number == a.SAPItemNumber);
|
|
|
+ var itemrop= ropModelList.Find(x=>x.number == a.SAPItemNumber);
|
|
|
+ var monthPlanItem = monthPlan.Find(x => x.ItemNumber == a.SAPItemNumber);
|
|
|
+ if (ic_item?.erp_cls == 1)
|
|
|
{
|
|
|
- m.actual_out_qty = itemGroup.Find(a => a.ContainerItem == m.number)?.QtyToShip;
|
|
|
- updateList.Add(m);
|
|
|
+ var bom = bomList.Find(b => b.item_number == a.SAPItemNumber);
|
|
|
+ mes_morder mes_Morder = new mes_morder();
|
|
|
+ mes_Morder.GenerateNewId(help.NextId());
|
|
|
+ mes_Morder.morder_type = MorderEnum.JhMorder;
|
|
|
+ //mes_Morder.morder_icitem_type
|
|
|
+ mes_Morder.work_order_type = MorderEnum.FhMorder;
|
|
|
+ mes_Morder.morder_state = MorderEnum.Initial_state;
|
|
|
+ mes_Morder.morder_no = list[j].NbrResult;
|
|
|
+ mes_Morder.fms_number = ic_item.fms_number;
|
|
|
+ mes_Morder.bom_number = bom.bom_number;
|
|
|
+ mes_Morder.fmodel = ic_item.model;
|
|
|
+ mes_Morder.urgent = 1;
|
|
|
+ mes_Morder.moentry_startup_status = 0;
|
|
|
+ mes_Morder.tenant_id = input.tenant_id;
|
|
|
+ mes_Morder.factory_id = input.factory_id;
|
|
|
+ mes_Morder.company_id = input.company_id;
|
|
|
+ mes_Morder.org_id = input.org_id;
|
|
|
+ mes_Morder.product_code = ic_item.number;
|
|
|
+ mes_Morder.product_name = ic_item.name;
|
|
|
+ mes_Morder.morder_date = DateTime.Now.Date.AddDays(1);
|
|
|
+ //成品半成品取周一开始 + 取供应提前期为结束时间
|
|
|
+ mes_Morder.moentry_stime = currentTime.AddDays(1 - week + 7 * (i + 1));
|
|
|
+ mes_Morder.moentry_sys_etime = currentTime.AddDays(1 - week + 7*(i+1)+ Convert.ToDouble(itemrop.supply_leadtime));
|
|
|
+ //mes_Morder.morder_fstate = "计划";
|
|
|
+ //TODO:目前没有取值位置
|
|
|
+ mes_Morder.moentry_prd = null;
|
|
|
+ mes_Morder.moentry_prdname = null;
|
|
|
+ mes_Morder.moentry_wrkc = null;
|
|
|
+ mes_Morder.moentry_wrkcname = null;
|
|
|
+ mes_Morder.picking_qty = 0;
|
|
|
+ //TODO:可删除主表字段
|
|
|
+ mes_Morder.unit = ic_item.unit;
|
|
|
+ mes_Morder.morder_production_number = itemrop.eop/4;
|
|
|
+ mes_Morder.need_number = itemrop.eop/4;
|
|
|
+ mes_Morder.remaining_number = 0;
|
|
|
+ mes_Morder.create_time = DateTime.Now;
|
|
|
+ mes_Morder.bang_id = bang_id;
|
|
|
+ //生成工单子表数据
|
|
|
+ mes_moentry mes_Moentry = new mes_moentry();
|
|
|
+ mes_Moentry.GenerateNewId(help.NextId());
|
|
|
+ mes_Moentry.moentry_moid = mes_Morder.Id;
|
|
|
+ mes_Moentry.moentry_mono = mes_Morder.morder_no;
|
|
|
+ mes_Moentry.unit = ic_item.unit;
|
|
|
+ mes_Moentry.morder_production_number = itemrop.eop/4;
|
|
|
+ mes_Moentry.need_number = itemrop.eop/4;
|
|
|
+ mes_Moentry.remaining_number = 0;
|
|
|
+ mes_Moentry.tenant_id = input.tenant_id;
|
|
|
+ mes_Moentry.factory_id = input.factory_id;
|
|
|
+ mes_Moentry.company_id = input.company_id;
|
|
|
+ mes_Moentry.org_id = input.org_id;
|
|
|
+ mes_Moentry.create_time = DateTime.Now;
|
|
|
+ mes_Moentry.bang_id = bang_id;
|
|
|
+ moList.Add(mes_Morder);
|
|
|
+ moentryList.Add(mes_Moentry);
|
|
|
+
|
|
|
+ ReplenishmentWeekPlan weekItem = new ReplenishmentWeekPlan();
|
|
|
+ weekItem.GenerateNewId(help.NextId());
|
|
|
+ weekItem.Priority = 1;
|
|
|
+ weekItem.Area = itemrop.area;
|
|
|
+ weekItem.PlanStartDate = mes_Morder.moentry_stime.Value;
|
|
|
+ weekItem.Week =$"WK{GetWeekOfYear(mes_Morder.moentry_stime.Value).ToString("00")}";
|
|
|
+ weekItem.OrderNO = list[j].NbrResult;
|
|
|
+ weekItem.ProductionOrder = nbrlistDto[j].NbrResult;
|
|
|
+ weekItem.SAPOrderNO = "";
|
|
|
+ weekItem.OrderType = "量产";
|
|
|
+ weekItem.ProductionBatch = "";
|
|
|
+ weekItem.ProductionStatus = "";
|
|
|
+ weekItem.ProdLine =a.ProdLine;
|
|
|
+ weekItem.ProdRange =a.ProdRange;
|
|
|
+ weekItem.Line = monthPlanItem.WorkshopLine;
|
|
|
+ weekItem.ItemNumber =a.SAPItemNumber;
|
|
|
+ weekItem.Model =a.Model;
|
|
|
+ weekItem.Languages =a.Languages;
|
|
|
+ weekItem.Qty = mes_Morder.morder_production_number.Value;
|
|
|
+ weekItem.ItemStatus = "";
|
|
|
+ weekItem.PlanKittingDate = DateTime.Now;
|
|
|
+ if(itemrop.area=="国内")
|
|
|
+ {
|
|
|
+ weekItem.SterilizationDate = mes_Morder.moentry_sys_etime.Value.AddDays(8);
|
|
|
+ }else
|
|
|
+ {
|
|
|
+ weekItem.SterilizationDate = mes_Morder.moentry_sys_etime.Value.AddDays(15);
|
|
|
+ }
|
|
|
+
|
|
|
+ weekItem.InStockDate = mes_Morder.moentry_sys_etime;
|
|
|
+ weekItem.AssembleHours = 0;
|
|
|
+ weekItem.HeatSealHours = 0;
|
|
|
+ weekItem.PackageHours = 0;
|
|
|
+ weekItem.TotalHours = 0;
|
|
|
+ weekPlan.Add(weekItem);
|
|
|
+ j++;
|
|
|
}
|
|
|
});
|
|
|
- //需要按照成品资源检查计算原材料
|
|
|
- planList?.Where(s => s.PlanMonth == planMonth).ToList()?.ForEach(a =>
|
|
|
+ }
|
|
|
+ await _mysql_mes_morder.InsertManyAsync(moList);
|
|
|
+ await _mysql_mes_moentry.InsertManyAsync(moentryList);
|
|
|
+
|
|
|
+ await PlanOrderResourceCheck(moList, moentryList, bang_id, input);
|
|
|
+ List<RoutingOpDetail> routingOps = _routingOpDetail.Select(p => planItemList.Contains(p.RoutingCode) && p.Domain == input.factory_id.ToString() && p.IsActive);
|
|
|
+ var examine_resultList= _mysql_examine_result.GetListAsync(a=>a.bangid == bang_id).Result;
|
|
|
+ weekPlan.ForEach(a =>
|
|
|
{
|
|
|
- ReplenishmentROP rop = new ReplenishmentROP();
|
|
|
- rop.number = a.SAPItemNumber;
|
|
|
- var icItem = itemList.Find(s => s.number == a.SAPItemNumber);
|
|
|
- if (icItem != null)
|
|
|
- {
|
|
|
- rop.name = icItem.name;
|
|
|
- rop.model = a.Model;
|
|
|
- rop.erp_cls = icItem.erp_cls; //物料属性: 0.配置类 1.自制 2.委外加工 3.外购 4.虚拟件
|
|
|
- rop.fversion = icItem.fversion;
|
|
|
- rop.min_pack_qty = icItem.minpackqty;
|
|
|
- rop.moq = icItem.moq;
|
|
|
- }
|
|
|
- rop.actual_period_start_instock = 0;
|
|
|
- if (rop.distributionchannel == "海王" || rop.distributionchannel == "国科")
|
|
|
- {
|
|
|
- rop.actual_period_start_instock = locations.Find(l => l.ItemNum == a.SAPItemNumber)?.QtyOnHand;
|
|
|
- }
|
|
|
- else
|
|
|
+ var moItem = examine_resultList.Find(b => b.morder_no == a.OrderNO);
|
|
|
+ var routingOp = routingOps.Where(x => x.RoutingCode == a.ItemNumber).ToList();
|
|
|
+ //组装标准工时
|
|
|
+ var Assembly = routingOp.Where(x => x.Descr == "组装").FirstOrDefault();
|
|
|
+ //热封标准工时
|
|
|
+ var HeatSealing = routingOp.Where(x => x.Descr == "热封").FirstOrDefault();
|
|
|
+ //包装标准工时
|
|
|
+ var Packaging = routingOp.Where(x => x.Descr == "包装").FirstOrDefault();
|
|
|
+ if (moItem!=null && moItem.kitting_times<a.PlanStartDate)
|
|
|
{
|
|
|
- rop.actual_period_start_instock = sapItemInv.Find(s => s.MATNR == a.SAPItemNumber)?.LABST.ToDecimal();
|
|
|
- }
|
|
|
- rop.distributionchannel = a.DistributionChannel;
|
|
|
- rop.lifecycle = a.LifeCycle;
|
|
|
- rop.area = a.Area;
|
|
|
- rop.plan_out_qty = Math.Ceiling(a.Qty);
|
|
|
- rop.actual_out_qty = 0;
|
|
|
- if (itemMGroup.Any(m => m.ContainerItem == a.SAPItemNumber))
|
|
|
- {
|
|
|
- rop.actual_out_qty = itemMGroup.Find(m => m.ContainerItem == a.SAPItemNumber)?.QtyToShip;
|
|
|
- }
|
|
|
- rop.year = DateTime.Now.Year;
|
|
|
- rop.long_period = "Y";
|
|
|
- rop.short_period = "M";
|
|
|
- rop.seqno = DateTime.Now.Month;
|
|
|
- rop.zero_based_seqno = 0;
|
|
|
- rop.period_start_date = getMonthStartTime(0);
|
|
|
- rop.period_end_date = getMonthEndTime(0);
|
|
|
- //rop.monthl_avg_demand = CalcAvgDemand(planList, a.SAPItemNumber);
|
|
|
- //rop.monthl_avg_demand_variance = Math.Ceiling(Convert.ToDecimal(CalcVariance(planList, a.SAPItemNumber)));
|
|
|
- rop.monthl_avg_outstock = CalcAvgOutStock(ropModelList, replenishmentDto, rop.actual_out_qty.Value, a.SAPItemNumber);
|
|
|
- if (mesItemList.Find(s => s.ItemNum == a.SAPItemNumber) != null)
|
|
|
- {
|
|
|
- rop.stock_turnover = mesItemList.Find(s => s.ItemNum == a.SAPItemNumber).StockTurnOver;
|
|
|
- rop.supply_leadtime = mesItemList.Find(s => s.ItemNum == a.SAPItemNumber)?.PurLT;
|
|
|
- rop.stock_turnover = mesItemList.Find(s => s.ItemNum == a.SAPItemNumber)?.StockTurnOver;
|
|
|
+ a.ItemStatus = "齐套";
|
|
|
+ a.PlanKittingDate = moItem.kitting_times;
|
|
|
+ a.AssembleHours = Assembly == null ? 0 : Assembly.RunTime * a.Qty;
|
|
|
+ a.HeatSealHours = HeatSealing == null ? 0 : HeatSealing.RunTime * a.Qty;
|
|
|
+ a.PackageHours = Packaging == null ? 0 : Packaging.RunTime * a.Qty;
|
|
|
+ a.TotalHours = a.AssembleHours + a.HeatSealHours + a.PackageHours;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- rop.stock_turnover = 4;
|
|
|
- }
|
|
|
- if (srm_purchaseList.Find(s => s.number == a.SAPItemNumber) != null)
|
|
|
- {
|
|
|
- rop.supply_leadtime = srm_purchaseList.Find(s => s.number == a.SAPItemNumber).lead_time;
|
|
|
+ a.ItemStatus = "欠料";
|
|
|
+ a.PlanKittingDate = moItem.kitting_times;
|
|
|
+ a.AssembleHours = Assembly == null ? 0 : Assembly.RunTime * a.Qty;
|
|
|
+ a.HeatSealHours = HeatSealing == null ? 0 : HeatSealing.RunTime * a.Qty;
|
|
|
+ a.PackageHours = Packaging == null ? 0 : Packaging.RunTime * a.Qty;
|
|
|
+ a.TotalHours = a.AssembleHours + a.HeatSealHours + a.PackageHours;
|
|
|
}
|
|
|
- CalcFMRAndABC(rop, replenishmentDto, 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.rop_computed = rop.security_stock + rop.eop;
|
|
|
- rop.max_stock_level = rop.monthl_avg_outstock * (12 / rop.stock_turnover);
|
|
|
- rop.rop_revised = Math.Min(rop.rop_computed.Value, rop.max_stock_level.Value);
|
|
|
- rop.isparam = true;
|
|
|
- rop.tenant_id = input.tenant_id;
|
|
|
- rop.factory_id = input.factory_id;
|
|
|
- rop.create_time = DateTime.Now;
|
|
|
- rop.org_id = input.org_id;
|
|
|
- addList.Add(rop);
|
|
|
});
|
|
|
- addList?.ForEach(item => { item.GenerateNewId(help.NextId()); });
|
|
|
|
|
|
- await _replenishmentROP.InsertManyAsync(addList);
|
|
|
- await _replenishmentROP.UpdateManyAsync(updateList);
|
|
|
- var ropModeAllList = _replenishmentROP.GetListAsync(a => a.year != DateTime.Now.Year && a.seqno != DateTime.Now.Month && a.isparam).Result;
|
|
|
- ropModeAllList?.ForEach(item => { item.seqno = item.seqno - 1; });
|
|
|
- await _replenishmentROP.UpdateManyAsync(ropModeAllList);
|
|
|
+ await _replenishmentWeekPlan.InsertManyAsync(weekPlan);
|
|
|
+ //TODO:优先级排序
|
|
|
+
|
|
|
return "OK";
|
|
|
}
|
|
|
|
|
|
@@ -1212,7 +1123,7 @@ namespace Business.Replenishment
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
- /// 根据工单编号拍优先级
|
|
|
+ /// 根据工单编号排优先级
|
|
|
/// </summary>
|
|
|
/// <param name="workOrdMasters">工单编号列表</param>
|
|
|
/// <param name="domain">工厂编码</param>
|
|
|
@@ -1295,6 +1206,46 @@ namespace Business.Replenishment
|
|
|
return orderedList;
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 手动调整优先级
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="workOrdMasters">工单编号列表</param>
|
|
|
+ /// <param name="domain">工厂编码</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ //计算工单优先级
|
|
|
+ public async Task<string> ChangePriority(string weekplanid, string tenant_id, string factory_id, string company_id, string itemNumber, string qty, string instockdate, string priority)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (string.IsNullOrEmpty(qty))
|
|
|
+ return "数量不正确,请检查";
|
|
|
+ if (string.IsNullOrEmpty(instockdate))
|
|
|
+ return "成品入库日期不正确,请检查";
|
|
|
+ if (string.IsNullOrEmpty(priority))
|
|
|
+ return "优先级不正确,请检查";
|
|
|
+ decimal newpriority=Convert.ToDecimal(priority);
|
|
|
+ DateTime newinstockdate=Convert.ToDateTime(instockdate);
|
|
|
+ decimal newqty=Convert.ToDecimal(qty);
|
|
|
+ long id= Convert.ToInt64(weekplanid);
|
|
|
+ long tenantid=Convert.ToInt64(tenant_id);
|
|
|
+ long factoryid=Convert.ToInt64(factory_id);
|
|
|
+ long companyid=Convert.ToInt64(company_id);
|
|
|
+ var weekPlan=_replenishmentWeekPlan.FindAsync(a => a.Id == id && a.tenant_id == tenantid && a.factory_id == factoryid && a.company_id == companyid).Result;
|
|
|
+ var isExistSamePriority= _replenishmentWeekPlan.FindAsync(a => a.Id != id && a.Week == weekPlan.Week && a.Priority == newpriority).Result;
|
|
|
+ if(isExistSamePriority!=null)
|
|
|
+ return "优先级重复,请重新调整。";
|
|
|
+ weekPlan.Priority= newpriority;
|
|
|
+ weekPlan.Qty= newqty;
|
|
|
+ weekPlan.InStockDate= newinstockdate;
|
|
|
+ await _replenishmentWeekPlan.UpdateAsync(weekPlan);
|
|
|
+ }
|
|
|
+ catch(Exception e)
|
|
|
+ {
|
|
|
+ return "调整失败,请联系管理员。";
|
|
|
+ }
|
|
|
+ return "ok";
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 根据物料编码获取可用库存
|
|
|
/// 成品半成品可用库存为没有被其他SO和PO占用的(合格成品或半成品库存+WIP)
|
|
|
@@ -1355,7 +1306,7 @@ namespace Business.Replenishment
|
|
|
/// </summary>
|
|
|
/// <param name="input"></param>
|
|
|
/// <returns></returns>
|
|
|
- public async Task<string> PlanOrderResourceCheck(List<mes_morder> Mes_Morders, List<mes_moentry> moentryList, InputDto input)
|
|
|
+ public async Task<string> PlanOrderResourceCheck(List<mes_morder> Mes_Morders, List<mes_moentry> moentryList,long bangid, InputDto input)
|
|
|
{
|
|
|
//先排除锁定期内的工单 //优先级排序
|
|
|
var sysSet = _generalizedCodeMaster.Select(s => s.FldName == "SystemConfig" && s.Val == "WorkOrderLockPeriod" && s.Domain == input.company_id.ToString()).ToList();
|
|
|
@@ -1427,7 +1378,7 @@ namespace Business.Replenishment
|
|
|
_scheduleResultOpMaster.Delete(s => monolist.Contains(s.WorkOrd));
|
|
|
}
|
|
|
//只走计划工单
|
|
|
- var rtn = await OrderKittingCheck(Mes_Morders, moentryList, true);
|
|
|
+ var rtn = await OrderKittingCheck(Mes_Morders, moentryList, bangid, true);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -1477,7 +1428,7 @@ namespace Business.Replenishment
|
|
|
/// 工单检查物料齐套
|
|
|
/// </summary>
|
|
|
/// <param name="input"></param>
|
|
|
- public async Task<PschedDto> OrderKittingCheck(List<mes_morder> mo_Mes_Morders, List<mes_moentry> moentryList, bool planCheck = false)
|
|
|
+ public async Task<PschedDto> OrderKittingCheck(List<mes_morder> mo_Mes_Morders, List<mes_moentry> moentryList,long bangid, bool planCheck = false)
|
|
|
{
|
|
|
//资源检查结果
|
|
|
PschedDto rtn = new PschedDto();
|
|
|
@@ -1494,8 +1445,6 @@ namespace Business.Replenishment
|
|
|
param.factoryId = input.factoryId;
|
|
|
param.checkflag = false;
|
|
|
param.checkPlan = planCheck;
|
|
|
- //生成当前计算bangid
|
|
|
- long bangid = help.NextId();
|
|
|
|
|
|
/*List<mo_mes_morder> mo_Mes_Morders = _mes_morder.GetManyByCondition(x => x.start_time > DateTime
|
|
|
.Now.Date.AddDays(1) && x.start_time < DateTime
|
|
|
@@ -2326,18 +2275,6 @@ namespace Business.Replenishment
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 检查所有成品半成品原材料是否需要补货先判断SS再判断ROP
|
|
|
- /// </summary>
|
|
|
- /// <param name="input"></param>
|
|
|
- /// <returns></returns>
|
|
|
- public async Task<string> DayCheckAllByFinalGoods(InputDto input)
|
|
|
- {
|
|
|
- //先找成品,就是年度销售预测
|
|
|
- //_replenishmentModel.
|
|
|
- return "OK";
|
|
|
- }
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// 生产长周期物料PR
|
|
|
/// </summary>
|
|
|
@@ -2354,17 +2291,19 @@ 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);
|
|
|
+ long bangid = help.NextId();
|
|
|
for (int i = 0;i< productList.Count();i++)
|
|
|
{
|
|
|
var ic_item = planList.Find(x => x.number == productList[i].SAPItemNumber);
|
|
|
var bom = bomList.Find(a => a.item_number == productList[i].SAPItemNumber);
|
|
|
mes_morder mes_Morder = new mes_morder();
|
|
|
mes_Morder.GenerateNewId(help.NextId());
|
|
|
- mes_Morder.morder_type = MorderEnum.XsMorder;
|
|
|
+ mes_Morder.morder_type = MorderEnum.JhMorder;
|
|
|
//mes_Morder.morder_icitem_type
|
|
|
mes_Morder.work_order_type = MorderEnum.CgMorder;
|
|
|
mes_Morder.morder_state = MorderEnum.Initial_state;
|
|
|
- mes_Morder.morder_no = GetMaxSerialNumber(457253186445381);
|
|
|
+ mes_Morder.morder_no = list[i].NbrResult;
|
|
|
mes_Morder.fms_number = ic_item.fms_number;
|
|
|
mes_Morder.bom_number = bom.bom_number;
|
|
|
mes_Morder.fmodel = ic_item.model;
|
|
|
@@ -2411,60 +2350,10 @@ namespace Business.Replenishment
|
|
|
}
|
|
|
await _mysql_mes_morder.InsertManyAsync(moList);
|
|
|
await _mysql_mes_moentry.InsertManyAsync(moentryList);
|
|
|
- await PlanOrderResourceCheck(moList,moentryList,input);
|
|
|
+ await PlanOrderResourceCheck(moList,moentryList, bangid,input);
|
|
|
return "OK";
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 得到一个流水号的最大流水号
|
|
|
- /// </summary>
|
|
|
- /// <param name="id">流水号id</param>
|
|
|
- /// <param name="formData">json数据,可以用json中的某个字段值作为通配符字替换流水号格式。</param>
|
|
|
- /// <returns></returns>
|
|
|
- public string GetMaxSerialNumber(long id, JObject? formData = null)
|
|
|
- {
|
|
|
- var modelList = _rf_serialnumber.Select(s => s.Id == id);
|
|
|
- if (modelList == null || modelList.Count < 1)
|
|
|
- {
|
|
|
- return string.Empty;
|
|
|
- }
|
|
|
- var model = modelList[0];
|
|
|
- int max = model.CurrentNumber + 1;
|
|
|
- var date = DateTime.Now;
|
|
|
- var lastDate = model.LastTime;
|
|
|
- switch (model.NumberType)
|
|
|
- {
|
|
|
- case 1: //年流水
|
|
|
- if (date.Year > lastDate.Year)
|
|
|
- {
|
|
|
- max = 1;
|
|
|
- }
|
|
|
- break;
|
|
|
- case 2: //月流水
|
|
|
- if (date.Year > lastDate.Year || date.Month > lastDate.Month)
|
|
|
- {
|
|
|
- max = 1;
|
|
|
- }
|
|
|
- break;
|
|
|
- case 3: //日流水
|
|
|
- if (date.Year > lastDate.Year || date.Month > lastDate.Month || date.Day > lastDate.Day)
|
|
|
- {
|
|
|
- max = 1;
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- string number = max.ToString().PadLeft(model.NumberSize, '0');
|
|
|
- string serialNumber = string.IsNullOrWhiteSpace(model.Format) ? number
|
|
|
- : model.Format.ContainsIgnoreCase("{number}")
|
|
|
- ? model.Format.ReplaceIgnoreCase("{number}", number)
|
|
|
- : model.Format + number;
|
|
|
- //更新当前编号和最后时间
|
|
|
- model.LastTime = date;
|
|
|
- model.CurrentNumber = max;
|
|
|
- _rf_serialnumber.Update(model);
|
|
|
- return Wildcard.Replace(serialNumber, formData);
|
|
|
- }
|
|
|
-
|
|
|
public ReplenishmentDto GetROPParam(string domain)
|
|
|
{
|
|
|
//select [Domain],Val,Ufld1,UDeci1 from GeneralizedCodeMaster where [Domain] = '1001' AND FldName ='SystemConfig'
|