using System.ComponentModel; using Kingdee.BOS.Contracts; using Kingdee.BOS; using Kingdee.BOS.Core; using Kingdee.BOS.ServiceHelper; using System.Data; using ZD.Cloud.Logger; using Newtonsoft.Json.Linq; using System; using Kingdee.BOS.Util; using System.Linq; using ZD.Cloud.WebApi; using Demo.Model.Model; using Demo.Model.Model.PODemandPlan; using System.Diagnostics; using System.Collections.Generic; using ZD.Share.Common; namespace Demo.TimedTaskPlugIn.PRD { [Description("日计划发生变动时执行")] [HotUpdate] public class TLPlanTimeTask : Kingdee.BOS.Contracts.IScheduleService { CloudClient cloudClient = new CloudClient("http://localhost//k3cloud/"); public Context Context; public void Run(Context ctx, Schedule schedule) { try { Context = ctx; string sql = "/*dialect*/ select FID,FDAYPLANID from sc_TLPLANZXJH where FISZX = 0"; List sqlList = new List(); DataTable dt = DBServiceHelper.ExecuteDataSet(Context, sql).Tables[0]; if (dt.Rows.Count > 0) { Stopwatch sw = new Stopwatch(); sw.Start(); Extraction(); sqlList.Add($"/*dialect*/ update sc_TLPLANZXJH set FZXDATE = getdate(), FISZX = 1 where FISZX = 0 "); DBServiceHelper.ExecuteBatch(Context, sqlList); LogHelper.Info("提料计划时长:" + sw.Elapsed); sw.Stop(); } } catch (System.Exception ex) { LogHelper.Error(ex.Message.ToString()); } } public void Extraction() { LogHelper.Info("[生产订单缺料生成提料计划--准备阶段]:开始执行提料计划逻辑"); try { //Stopwatch sw = new Stopwatch(); //sw.Start();//开始计时 //提料计划预处理 清理提料计划单数据 更新采购订单提料计划数量 string sql = string.Format(@" /*dialect*/ exec [提料计划预处理] "); DBServiceHelper.Execute(Context, sql); //LogHelper.Info("[提料计划准备阶段]提料计划预处理sql:" + sql); //采购订单数据 sql = @" /*dialect*/ select t1.FID,t1.FBillNo,t2.FENTRYID,t1.FSUPPLIERID,t3.fnumber,t2.FMATERIALID,(t2.FQTY-t2.FPODemandPlanCount)FQTY,FPurchaseOrgId FStockOrgId,t5.FNUMBER FORGNumber,FSTOCKINQTY,FReceiveQty,FCloseStatus,FMRPCLOSESTATUS from t_PUR_POOrder t1 join t_PUR_POOrderEntry t2 on t1.FID = t2.FID join t_BD_Supplier t3 on t1.FSUPPLIERID = t3.FSUPPLIERID join T_PUR_POORDERENTRY_R t4 on t2.FENTRYID = t4.FENTRYID join T_ORG_Organizations t5 on t1.FPurchaseOrgId = t5.FORGID where t2.FQTY-t2.FPODemandPlanCount>0 and FCloseStatus in('A') and FMRPCLOSESTATUS in('A') and t1.FBillTypeID in('83d822ca3e374b4ab01e5dd46a0062bd','6d01d059713d42a28bb976c90a121142') "; List PurchaseInventory = DBServiceHelper.ExecuteDataSet(Context, sql).ToModelList(); //LogHelper.Info("[提料计划准备阶段]可用采购订单数据sql:" + sql); sql = string.Format(@" /*dialect*/ SELECT T1.FID,FHMASTERDATE,t1.FEntryID,T1.FBILLNO, FNeedQty,(FLeadtime+FLeadTtime2)FFIXLEADTIME,t5.FMAXPOQTY,FJITBatch FMINPOQTY,FJITMATERIALGROUP,FJITMaterielDemand,FJITSafeStock,t1.FMATERIALID,t6.FNumber,NeedQty, FStockOrgId ,FErpClsID FROM ( select FHICMOINTERID FID,FHICMOENTRYID FEntryID,FPlanDate FHMASTERDATE,FLackCount NeedQty,FHMATERID FMATERIALID,FHStockOrgID FStockOrgId,FPRDBILLNO FBillNo,FSumPlanCount FNeedQty from JIT_MOMaterReadysBill a right join (select max(FID)FID from JIT_MOMaterReadysBill GROUP BY FHICMOENTRYID,FHMATERID) b on a.FID = b.FID )T1 JOIN T_BD_MATERIAL T6 ON T1.FMATERIALID = T6.FMATERIALID join t_BD_MaterialBase t4 on T1.FMATERIALID = t4.FMATERIALID join t_BD_MaterialPlan t5 on T1.FMATERIALID = t5.FMATERIALID WHERE DATEDIFF(D,GETDATE(),FHMASTERDATE) >=0 AND FERPCLSID in ('1','3') AND T1.NeedQty>0 AND T1.FENTRYID not in (select distinct FHSOURCEENTRYID from CG_PODEMANDPLANBILLSUB where FHSOURCEINTERID IN (select distinct FDAYPLANID from sc_TLPLANZXJH where FISZX = 0)) AND T1.FID in (select distinct FDAYPLANID from sc_TLPLANZXJH where FISZX = 0) order by FHMASTERDATE "); //LogHelper.Info("[提料计划准备阶段]需要提料数据sql:" + sql); DataSet ds = DBServiceHelper.ExecuteDataSet(Context, sql); List DayPlanPpbom = ds.ToModelList(); //物料+库存组织分类 var MaterialIDList = DayPlanPpbom.GroupBy(p => new { p.FMATERIALID, p.FStockOrgId }).Select(x => new PODemandPlanTemp { FMATERIALID = x.Key.FMATERIALID, FStockOrgId = x.Key.FStockOrgId }).ToList(); var _MaterialIDList = MaterialIDList.Where(p => p.FMATERIALID == "163165").ToList(); //LogHelper.Info("[提料计划准备阶段]总物料行数" + MaterialIDList.Count); //提料计划数据集临时存储集合 List PODemandPlanTemp = new List(); //sql集合 更新采购订单占用的提料计划数量 List sqlList = new List(); //MaterialIDList = new List { "105773" }; foreach (var item in MaterialIDList) { //当前物料没有采购订单时 直接跳出 List _PurchaseInventory = PurchaseInventory.Where(x => x.FMATERIALID == item.FMATERIALID && x.FStockOrgId == item.FStockOrgId && x.FQTY > 0).OrderBy(x => x.FENTRYID).ToList(); if (_PurchaseInventory.Count == 0) { LogHelper.Info("[提料计划开始]当前物料无采购信息:" + item.FMATERIALID + " 库存组织:" + item.FStockOrgId); continue; } //LogHelper.Info(item.FMATERIALID.ToString()); //当前物料和库存组织对应的需进行提料计划的数据 List _DayPlanPpbom = DayPlanPpbom.Where(x => x.FMATERIALID == item.FMATERIALID && x.FStockOrgId == item.FStockOrgId).ToList(); decimal FMINPOQTY = _DayPlanPpbom.FirstOrDefault().FMINPOQTY;//最小起订量 double FFIXLEADTIME = _DayPlanPpbom.FirstOrDefault().FFIXLEADTIME;//提前期 string FJITmaterialGroup = _DayPlanPpbom.FirstOrDefault().FJITmaterialGroup;//jit物料分类 string FJITMaterielDemand = _DayPlanPpbom.FirstOrDefault().FJITMaterielDemand; //JIT物料需求供货周期 string FJITSafeStock = _DayPlanPpbom.FirstOrDefault().FJITSafeStock; //JIT安全库存 decimal NeedQty = 0; DateTime DATE = _DayPlanPpbom.FirstOrDefault().FHMASTERDATE;//第一个订货起始日期 int i = 0; //记录在最小采购量需求下的日计划明细FentyrID List FEntryIdList = new List(); foreach (var _item in _DayPlanPpbom) { i++; _PurchaseInventory = PurchaseInventory.Where(x => x.FMATERIALID == item.FMATERIALID && x.FStockOrgId == item.FStockOrgId && x.FQTY > 0).OrderBy(x => x.FENTRYID).ToList(); if (_PurchaseInventory.Count == 0) { //LogHelper.Info("[提料计划开始]当前物料明细无采购信息:" + item.FMATERIALID + " 库存组织:" + item.FStockOrgId); break; } if (NeedQty == 0) DATE = Convert.ToDateTime(_item.FHMASTERDATE).AddDays(-FFIXLEADTIME); FEntryIdList.Add(_item.FENTRYID); NeedQty += _item.NeedQty; //LogHelper.Info("记录明细id:" + _item.FENTRYID + ""); //LogHelper.Info("总需求量:" + NeedQty + ""); //LogHelper.Info("最小起订量:" + FMINPOQTY + ""); if (NeedQty <= FMINPOQTY) { LogHelper.Info("[提料计划]当前物料明细无采购信息:" + item.FMATERIALID + ",数量:" + NeedQty + ",最小起订量:" + FMINPOQTY + ""); } if ((FJITmaterialGroup == "总量控制规格类" || FJITmaterialGroup == "订单专用个性类") && FEntryIdList.Count < Convert.ToInt32(FJITMaterielDemand) && i < _DayPlanPpbom.Count) //订单专用个性类 continue; //if (NeedQty >= FMINPOQTY) //{ foreach (var Purchase in _PurchaseInventory) { //LogHelper.Info("采购订单号测试:" + Purchase.FBillNo); //LogHelper.Info("物料:" + Purchase.FMATERIALID + ",采购订单数量:" + Purchase.FQTY); if (Purchase.FQTY >= NeedQty) { foreach (int id in FEntryIdList) { var DayPlanPpbomls = DayPlanPpbom.Where(c => c.FENTRYID == id && c.FMATERIALID == _item.FMATERIALID).FirstOrDefault(); PODemandPlanTemp.Add(new Demo.Model.Model.PODemandPlan.PODemandPlanTemp { FID = DayPlanPpbomls.FID, FHMASTERDATE = DATE, FQty = DayPlanPpbomls.NeedQty, FBILLNO = DayPlanPpbomls.FBILLNO, FENTRYID = DayPlanPpbomls.FENTRYID, FMATERIALID = DayPlanPpbomls.FMATERIALID, FNumber = DayPlanPpbomls.FNumber, OLDDATE = DayPlanPpbomls.FHMASTERDATE, FFIXLEADTIME = FFIXLEADTIME, FErpClsID = DayPlanPpbomls.FErpClsID, PurchseFID = Purchase.FID, PurchseFentryID = Purchase.FENTRYID, FSUPPLIERID = Purchase.FSUPPLIERID, PurchseFNUMBER = Purchase.FNUMBER, PurchseFBillNo = Purchase.FBillNo, PurchseFqty = Purchase.FQTY, FStockOrgId = Purchase.FStockOrgId, //采购组织 FORGNumber = Purchase.FORGNumber }); //扣除日计划明细已被分配的数量 DayPlanPpbomls.NeedQty = 0; } FEntryIdList.Clear(); //更新采购订单 sqlList.Add($"/*dialect*/ update t_PUR_POOrderEntry set FPODemandPlanCount =isnull(FPODemandPlanCount,0)+ '{NeedQty}' where FENTRYID = {Purchase.FENTRYID}"); //扣除当前行对应采购订单数量 var ls = PurchaseInventory.Where(c => c.FENTRYID == Purchase.FENTRYID).FirstOrDefault(); ls.FQTY -= NeedQty; break; } else { //更新总需求数量 NeedQty = NeedQty - Purchase.FQTY; //采购订单数量 decimal _NeedQty = Purchase.FQTY; List mmm = new List(); foreach (int id in FEntryIdList) { var DayPlanPpbomls = DayPlanPpbom.Where(c => c.FENTRYID == id && c.FMATERIALID == _item.FMATERIALID).FirstOrDefault(); decimal Qty = DayPlanPpbomls.NeedQty;//订单数量 //if (Qty == 0) // LogHelper.Info("订单数量为0"); if (Qty > _NeedQty) Qty = _NeedQty; //订单数量>采购订单数量 取采购订单 //if (_NeedQty == 0) // LogHelper.Info("订单数量为0"); _NeedQty = _NeedQty - Qty; PODemandPlanTemp.Add(new Demo.Model.Model.PODemandPlan.PODemandPlanTemp { FID = DayPlanPpbomls.FID, FHMASTERDATE = DATE, FQty = Qty, FBILLNO = DayPlanPpbomls.FBILLNO, FENTRYID = DayPlanPpbomls.FENTRYID, FMATERIALID = DayPlanPpbomls.FMATERIALID, FNumber = DayPlanPpbomls.FNumber, OLDDATE = DayPlanPpbomls.FHMASTERDATE, FFIXLEADTIME = FFIXLEADTIME, FErpClsID = DayPlanPpbomls.FErpClsID, PurchseFID = Purchase.FID, PurchseFentryID = Purchase.FENTRYID, FSUPPLIERID = Purchase.FSUPPLIERID, PurchseFNUMBER = Purchase.FNUMBER, PurchseFBillNo = Purchase.FBillNo, PurchseFqty = Purchase.FQTY, FStockOrgId = Purchase.FStockOrgId, //采购组织 FORGNumber = Purchase.FORGNumber }); //更新计划数量(剩余需要排的) 继续去计算下一个采购订单 DayPlanPpbomls.NeedQty -= Qty; //更新采购订单 sqlList.Add($"/*dialect*/ update t_PUR_POOrderEntry set FPODemandPlanCount = isnull(FPODemandPlanCount,0)+ '{Qty}' where FENTRYID = {Purchase.FENTRYID}"); //更新Model var ls = PurchaseInventory.Where(c => c.FENTRYID == Purchase.FENTRYID).FirstOrDefault(); ls.FQTY -= Qty; if (_NeedQty <= 0) { foreach (var mm in mmm) { FEntryIdList.Remove(mm); } break; } mmm.Add(id); } //foreach (var mm in mmm) //{ // FEntryIdList.Remove(mm); //} } } NeedQty = 0; //} #region 剩下不足时按最小采购批次生成 //剩下不足时按最小采购批次生成 //else if (i == _DayPlanPpbom.Count && NeedQty > 0) //{ // NeedQty = FMINPOQTY; // List _PurchaseInventory = PurchaseInventory.Where(x => x.FMATERIALID == item.FMATERIALID && x.FStockOrgId == item.FStockOrgId && x.FQTY > 0).ToList(); // if (_PurchaseInventory.Count == 0) // { // NeedQty = 0; // break; // } // foreach (var Purchase in _PurchaseInventory) // { // if (Purchase.FQTY >= NeedQty) // { // List mmm = new List(); // foreach (int id in FEntryIdList) // { // mmm.Add(id); // var DayPlanPpbomls = DayPlanPpbom.Where(c => c.FENTRYID == id && c.FMATERIALID == _item.FMATERIALID).FirstOrDefault(); // PODemandPlanTemp.Add(new Demo.Model.Model.PODemandPlan.PODemandPlanTemp // { // FID = DayPlanPpbomls.FID, // FHMASTERDATE = DATE, // FQty = DayPlanPpbomls.NeedQty, // FBILLNO = DayPlanPpbomls.FBILLNO, // FENTRYID = DayPlanPpbomls.FENTRYID, // FMATERIALID = DayPlanPpbomls.FMATERIALID, // FNumber = DayPlanPpbomls.FNumber, // OLDDATE = DayPlanPpbomls.FHMASTERDATE, // FFIXLEADTIME = FFIXLEADTIME, // PurchseFID = Purchase.FID, // PurchseFentryID = Purchase.FENTRYID, // FSUPPLIERID = Purchase.FSUPPLIERID, // PurchseFNUMBER = Purchase.FNUMBER, // PurchseFBillNo = Purchase.FBillNo, // PurchseFqty = Purchase.FQTY // }); // //扣除日计划明细已被分配的数量 // DayPlanPpbomls.NeedQty = 0; // } // FEntryIdList.Clear(); // //更新采购订单 // sqlList.Add($"/*dialect*/ update t_PUR_POOrderEntry set FPODemandPlanCount =isnull(FPODemandPlanCount,0)+ '{NeedQty}' where FENTRYID = {Purchase.FENTRYID}"); // //扣除当前行对应采购订单数量 // var ls = PurchaseInventory.Where(c => c.FENTRYID == Purchase.FENTRYID).FirstOrDefault(); // ls.FQTY -= NeedQty; // break; // } // else // { // NeedQty = NeedQty - Purchase.FQTY; // decimal _NeedQty = Purchase.FQTY;//采购订单数量 // List mmm = new List(); // foreach (int id in FEntryIdList) // { // var DayPlanPpbomls = DayPlanPpbom.Where(c => c.FENTRYID == id && c.FMATERIALID == _item.FMATERIALID).FirstOrDefault(); // decimal Qty = DayPlanPpbomls.NeedQty; // if (Qty > _NeedQty) // Qty = _NeedQty; // _NeedQty = _NeedQty - DayPlanPpbomls.NeedQty; // PODemandPlanTemp.Add(new Demo.Model.Model.PODemandPlan.PODemandPlanTemp // { // FID = DayPlanPpbomls.FID, // FHMASTERDATE = DATE, // FQty = Qty, // FBILLNO = DayPlanPpbomls.FBILLNO, // FENTRYID = DayPlanPpbomls.FENTRYID, // FMATERIALID = DayPlanPpbomls.FMATERIALID, // FNumber = DayPlanPpbomls.FNumber, // OLDDATE = DayPlanPpbomls.FHMASTERDATE, // FFIXLEADTIME = FFIXLEADTIME, // PurchseFID = Purchase.FID, // PurchseFentryID = Purchase.FENTRYID, // FSUPPLIERID = Purchase.FSUPPLIERID, // PurchseFNUMBER = Purchase.FNUMBER, // PurchseFBillNo = Purchase.FBillNo, // PurchseFqty = Purchase.FQTY // }); // DayPlanPpbomls.NeedQty -= Qty; // //更新采购订单 // sqlList.Add($"/*dialect*/ update t_PUR_POOrderEntry set FPODemandPlanCount = isnull(FPODemandPlanCount,0)+ '{Qty}' where FENTRYID = {Purchase.FENTRYID}"); // //更新Model // var ls = PurchaseInventory.Where(c => c.FENTRYID == Purchase.FENTRYID).FirstOrDefault(); // ls.FQTY -= Qty; // if (_NeedQty < 0) // { // foreach (var mm in mmm) // { // FEntryIdList.Remove(mm); // } // break; // } // mmm.Add(id); // } // foreach (var mm in mmm) // { // FEntryIdList.Remove(mm); // } // } // } // NeedQty = 0; //} #endregion } } var PODemandPlanList222 = PODemandPlanTemp.GroupBy(p => new PODemandPlanTemp { PurchseFNUMBER = p.PurchseFNUMBER, FHMASTERDATE = p.FHMASTERDATE }).Select(x => new PODemandPlanTemp { PurchseFNUMBER = x.Key.PurchseFNUMBER, FHMASTERDATE = x.Key.FHMASTERDATE }).ToList(); var PODemandPlanList = PODemandPlanTemp.GroupBy(p => new { p.PurchseFNUMBER, p.FHMASTERDATE }).Select(x => new PODemandPlanTemp { PurchseFNUMBER = x.Key.PurchseFNUMBER, FHMASTERDATE = x.Key.FHMASTERDATE }).ToList(); LogHelper.Info($"提料计划,数据准备完成,保存到Model实体,总行数:{PODemandPlanTemp.Count}"); int tlmmm = 1; JArray FinalyResult = new JArray(); foreach (var item in PODemandPlanList) { DateTime date = item.FHMASTERDATE; string PurchseFNUMBER = item.PurchseFNUMBER; JObject model = new JObject(); model.Add("FHDate", date); model.Add("FSettleCurrId", new JObject() { ["Fnumber"] = "PRE001" }); model.Add("FSupplierID", new JObject() { ["Fnumber"] = PurchseFNUMBER }); JArray Fentity = new JArray(); List _PODemandPlanList = PODemandPlanTemp.Where(x => x.FHMASTERDATE == date && x.PurchseFNUMBER == PurchseFNUMBER).ToList(); int FSEQ = 1; foreach (var _item in _PODemandPlanList) { JObject FentityModel = new JObject(); FentityModel.Add("FHPURCHASEORGID", new JObject() { ["Fnumber"] = _item.FORGNumber });//采购组织 FentityModel.Add("FHMaterID", new JObject() { ["Fnumber"] = _item.FNumber });//物料 FentityModel.Add("FHQty", _item.FQty);//数量 FentityModel.Add("FHSourceInterID", _item.FID);//日计划工单FID FentityModel.Add("FHSourceEntryID", _item.FENTRYID);//日计划工单FENTRYID FentityModel.Add("FHSourceBillNo", _item.FBILLNO);//日计划工单单号 FentityModel.Add("FHSourceBillType", "");//日计划工单类型 FentityModel.Add("FDayPlanDate", _item.OLDDATE);//日计划工单类型 FentityModel.Add("FHRelationQty", _item.PurchseFqty);//关联数量 FentityModel.Add("FFIXLEADTIME", _item.FFIXLEADTIME);//提前期 FentityModel.Add("FPURCHASEORGID", new JObject() { ["Fnumber"] = _item.FORGNumber });//采购组织 FentityModel.Add("FHPOOrderInterID", _item.PurchseFID);// 采购订单内码:FHPOOrderInterID FentityModel.Add("FHPOOrderEntryID", _item.PurchseFentryID); //采购订单子内码:FHPOOrderEntryID FentityModel.Add("FHPOOrderBillNo", _item.PurchseFBillNo); //采购订单号:FHPOOrderBillNo FentityModel.Add("FERPCLSID", _item.FErpClsID); //发料方式 //FentityModel.Add("FSEQ", FSEQ); //发料方式 FentityModel.Add("FUnitID", new JObject() { ["Fnumber"] = "Pcs" }); //发料方式 Fentity.Add(FentityModel); FSEQ++; } model.Add("FEntity", Fentity); FinalyResult.Add(model); if ((tlmmm >= 20 || tlmmm == PODemandPlanList.Count) && (tlmmm % 20 == 0 || tlmmm == PODemandPlanList.Count)) { LogHelper.Info("提料计划新增批量执行,记录循环的当前条数" + tlmmm); JObject jsonRoot = new JObject() { ["Creator"] = "", ["NeedUpDateFields"] = new JArray(), ["NeedReturnFields"] = new JArray(), ["IsDeleteEntry"] = "false", ["SubSystemId"] = "", ["IsVerifyBaseDataField"] = "false", ["Model"] = FinalyResult }; CloudClient cloudClient = new CloudClient("http://localhost//k3cloud/"); var result = cloudClient.BatchSave("paez_PODemandPlan", jsonRoot.ToString()); JObject saveObj = JObject.Parse(result); string saveIsSuc = saveObj["Result"]["ResponseStatus"]["IsSuccess"].ToString().ToUpper(); if (saveIsSuc != "TRUE") { LogHelper.Error(jsonRoot.ToString()); } FinalyResult = new JArray(); } tlmmm++; } //sw.Stop();//结束计时 //LogHelper.Info("提料计划执行完成,运行总时长:" + sw.Elapsed); DBServiceHelper.ExecuteBatch(Context, sqlList); } catch (Exception ex) { LogHelper.Info("提料计划跳出:" + ex.Message.ToString()); } // var PODemandPlanList22 = PODemandPlanTemp.GroupBy(p => new {p.FSUPPLIERID, p.FHMASTERDATE }).ToList(); } } }