/// <summary> /// Handler /// </summary> public void Handler() { ///获取已启用计划零件类集合 List <PlanPartBoxInfo> planPartBoxInfos = new PlanPartBoxBLL().GetList("[STATUS] = " + (int)BasicDataStatusConstants.Enable + "", string.Empty); if (planPartBoxInfos.Count == 0) { throw new Exception("3x00000023");///没有已启用的计划拉动零件类 } ///获取零件类对应物料拉动信息 List <MaintainInhouseLogisticStandardInfo> maintainInhouseLogisticStandardInfos = new MaintainInhouseLogisticStandardBLL().GetList("[INHOUSE_PART_CLASS] in ('" + string.Join("','", planPartBoxInfos.Select(d => d.PartBoxCode).ToArray()) + "') and [STATUS] = " + (int)BasicDataStatusConstants.Enable + " and [INHOUSE_SYSTEM_MODE]=N'60'", string.Empty); if (maintainInhouseLogisticStandardInfos.Count == 0) { throw new Exception("0x00000233");///没有已启用的物料拉动信息 } ///循环零件类集合 foreach (PlanPartBoxInfo planPartBoxInfo in planPartBoxInfos) { #region 基础变量 ///窗口时间 string windowTimes = string.Empty; ///当前窗口时间 DateTime currentWindowTime = DateTime.MinValue; ///下一窗口时间 DateTime nextWindowTime = DateTime.MaxValue; ///时区 string timeZone = string.Empty; List <long> planTimeIds = new List <long>(); ///范围 工厂、车间、产线 string sqlwhere = string.Empty; if (!string.IsNullOrEmpty(planPartBoxInfo.AssemblyLine)) { sqlwhere = "and [ASSEMBLY_LINE] = N'" + planPartBoxInfo.AssemblyLine + "' "; } else { sqlwhere = "and [WERK] = N'" + planPartBoxInfo.Plant + "' "; } #endregion #region 获取生产订单BOM集合 ///通过这些生产订单号①=①获取订单BOM(TT_BAS_PULL_ORDER_BOM) List <PullOrderBomInfo> pullOrderBomInfos = new List <PullOrderBomInfo>(); ///生产订单集合 List <PullOrdersInfo> pullOrdersInfos = new List <PullOrdersInfo>(); ///获取零件类对应的最近一次未发单窗口时间 ///当此参数为true时以计划拉动窗口时间TT_MPM_PLAN_WINDOW_TIME中发单状态⑥为10.未发单且发单时间④已早于当前时间作为当前执行依据 if (planPullWindowTimeEnable.ToLower() == "true") { PlanWindowTimeInfo planWindowTimeInfo = new PlanWindowTimeBLL().GetLastNoSendTimeInfo(planPartBoxInfo.Fid.GetValueOrDefault()); ///并根据窗口时间⑤匹配生产订单计划执行时间同时核对未生成计划拉动单的生产订单(先以小于等于窗口时间作为条件再加上TT_MPM_PLAN_PULL_CREATE_STATUS表的SEQID not exist条件进行过滤) ///如果没有符合条件的窗口时间,则执行下一个零件类 if (planWindowTimeInfo == null) { continue; } if (planWindowTimeInfo.WindowTime == null) { continue; } planTimeIds.Add(planWindowTimeInfo.Id); currentWindowTime = planWindowTimeInfo.WindowTime.GetValueOrDefault(); ///窗口时间 windowTimes = currentWindowTime.ToString("MM:dd"); ///时区为窗口时间中设定的时间 timeZone = planWindowTimeInfo.TimeZone; nextWindowTime = new PlanWindowTimeBLL().GetNextWindowTime(planPartBoxInfo.Fid.GetValueOrDefault(), currentWindowTime); ///获取未处理生产订单对应的BOM pullOrderBomInfos = new PullOrderBomBLL().GetUnPlanPullingOrders(currentWindowTime, nextWindowTime, sqlwhere, planPartBoxInfo.Fid.GetValueOrDefault()); } ///若为false时以计划当日零点作为交付时间依据并根据零件类中设定的时间合计⑫+⑬+⑭扣减后作为发单时间 ///并根据计划当日零点(大于等于)与计划次日零点(小于)之间同时核对未生成计划拉动单的生产订单 else if (planPullWindowTimeEnable.ToLower() == "false") { ///获取计划拉动提前期(分钟) int sumLeadTime = planPartBoxInfo.DelayTime.GetValueOrDefault() + planPartBoxInfo.DeliveryTime.GetValueOrDefault() + planPartBoxInfo.PickUpTime.GetValueOrDefault(); ///根据提前期用当前时间向后推得窗口时间的零点 currentWindowTime = DateTime.Parse(DateTime.Now.AddMinutes(sumLeadTime).ToShortDateString()); ///下一窗口时间为次日零点 nextWindowTime = currentWindowTime.AddDays(1); ///获取未处理生产订单对应的BOM pullOrderBomInfos = new PullOrderBomBLL().GetUnPlanPullingOrders(currentWindowTime, nextWindowTime, sqlwhere, planPartBoxInfo.Fid.GetValueOrDefault()); ///拼接窗口时间 List <DateTime> planWindowTimes = new PlanWindowTimeBLL().GetWindowTimesByWorkDay(planPartBoxInfo.Fid.GetValueOrDefault(), currentWindowTime); if (planWindowTimes.Count > 0) { windowTimes = string.Join(",", planWindowTimes.Select(d => d.ToString("HH:mm")).ToArray()); } ///拼接时区 List <PlanWindowTimeInfo> PlanWindowTimeInfos = new PlanWindowTimeBLL().GetList("", "WINDOW_TIME"); if (PlanWindowTimeInfos.Count > 0) { foreach (var p in PlanWindowTimeInfos) { planTimeIds.Add(p.Id); } timeZone = string.Join(",", PlanWindowTimeInfos.Select(d => d.TimeZone).ToArray()); } } else { throw new Exception("1x00000045");///系统配置参数错误 } #endregion #region 处理集合取交集 ///根据物料号、供应商、工厂将BOM分组并计算数量 var pullOrderBomQuery = pullOrderBomInfos .GroupBy(b => new { b.Zcomno, b.SupplierNum, b.Zkwerk }) .Select(p => new { PartNo = p.Key.Zcomno, p.Key.SupplierNum, Plant = p.Key.Zkwerk, Zqty = p.Sum(x => x.Zqty.GetValueOrDefault()) }).ToList(); ///获取零件类对应的物料拉动信息 var maintainInhouseLogisticStandardQuery = maintainInhouseLogisticStandardInfos.Where(d => d.InhousePartClass == planPartBoxInfo.PartBoxCode).ToList(); ///校验是否全部维护了入库单包装数量,否则除数为零时程序会报错 int cnt = maintainInhouseLogisticStandardQuery.Count(d => d.InboundPackage.GetValueOrDefault() == 0); if (cnt > 0) { throw new Exception("3x00000024");///物料拉动信息中入库单包装数量未维护 } ///并将计划零件类对应的物料拉动信息与订单BOM的交集部分作为计划拉动物料需求(比对依据为物料号②、供应商代码③、工厂) var materialRequirementInfos = (from m in maintainInhouseLogisticStandardQuery join b in pullOrderBomQuery on new { m.PartNo, m.SupplierNum, m.Plant } equals new { b.PartNo, b.SupplierNum, b.Plant } select new { m.PartNo, ///物料号 m.SupplierNum, ///供应商代码 m.Plant, ///工厂代码 m.PartCname, ///物料中文描述 m.PartEname, ///物料英文描述 m.PartUnits, ///计量单位 m.InboundPackage, ///入库单包装数量 m.InboundPackageModel, ///入库包装型号 RequirePackageQty = Math.Ceiling((b.Zqty * 1.0) / m.InboundPackage.GetValueOrDefault()), ///需求包装数 b.Zqty ///需求物料数量 }).ToList(); #endregion ///生成单据时为了保障效率需要拼接整个insert语句后提交至数据库执行 StringBuilder sql = new StringBuilder(); ///检验模式 if (inspectionModeDistinguishOrderFlag.ToLower() == "true") { ///获取所有涉及的检验模式 List <PartInspectionModeInfo> partInspectionModeInfos = new PartInspectionModeBLL().GetList("" + "[PART_NO] in ('" + string.Join("','", materialRequirementInfos.Select(d => d.PartNo).ToArray()) + "') and " + "[SUPPLIER_NUM] in ('" + string.Join("','", materialRequirementInfos.Select(d => d.SupplierNum).ToArray()) + "')", string.Empty); ///给物料需求的集合赋予检验模式 var partInspectionmaterialRequirementInfos = (from m in materialRequirementInfos join p in partInspectionModeInfos on new { m.PartNo, m.SupplierNum } equals new { p.PartNo, p.SupplierNum } into g select new { m.PartNo, ///物料号 m.SupplierNum, ///供应商代码 m.Plant, ///工厂代码 m.PartCname, ///物料中文描述 m.PartEname, ///物料英文描述 m.PartUnits, ///计量单位 m.InboundPackage, ///入库单包装数量 m.InboundPackageModel, ///入库包装型号 m.RequirePackageQty, ///需求包装数 m.Zqty, ///需求物料数量 Inspection = g.Select(d => d.InspectionMode.GetValueOrDefault()).FirstOrDefault() ///物料检验 }).ToList(); #region 免检 ///免检 var exemptionInspectionMaterialRequirementInfos = partInspectionmaterialRequirementInfos.Where(d => d.Inspection == (int)InspectionModeConstants.ExemptionInspection).ToList(); ///生成计划拉动单同时记录该生产订单该计划零件类已生成单据 ///当有物料需求时,才会生成计划拉动单 if (exemptionInspectionMaterialRequirementInfos.Count > 0) { ///实例化主表Guid Guid planPullOrderFid = Guid.NewGuid(); ///主表计划拉动单号 string orderCode = new SeqDefineBLL().GetCurrentCode("PLAN_PULL_ORDER_CODE", planPartBoxInfo.PartBoxCode.Substring(0, 1).ToUpper());///TODO:计划拉动单编号规则可能还会更改,待客户确认 MaterialPullingOrderInfo materialPullingOrderInfo = CreateMaterialPullingOrderInfo(planPartBoxInfo, orderCode, currentWindowTime, true); materialPullingOrderInfo.MaterialPullingOrderDetailInfos = (from m in exemptionInspectionMaterialRequirementInfos select new MaterialPullingOrderDetailInfo { OrderNo = orderCode, ///拉动单号1 SupplierNum = m.SupplierNum, ///供应商2 PartNo = m.PartNo, ///物料号3 PartCname = m.PartCname, ///物料号中文名称4 PartEname = m.PartEname, ///物料号英文名称5 Uom = m.PartUnits, ///计量单位6 PackageQty = m.InboundPackage.GetValueOrDefault(), ///入库单包装数量7 PackageModel = m.InboundPackageModel, ///入库包装编号8 RequirePackageQty = Convert.ToInt32(m.RequirePackageQty), ///需求包装数量9 RequirePartQty = m.Zqty, ///需求物料数量10 TargetZoneNo = planPartBoxInfo.TargetZoneNo, InspectMode = m.Inspection ///校验模式 }).ToList(); sql.AppendLine(CreatePlanPullOrderSql(planPullOrderFid, materialPullingOrderInfo, windowTimes, timeZone, (int)InspectionFlagConstants.Exemption)); sql.AppendLine(CreatePlanPullOrderDetailSql(planPullOrderFid, materialPullingOrderInfo.MaterialPullingOrderDetailInfos)); sql.AppendFormat(MaterialPullingCommonBLL.Handler(materialPullingOrderInfo, loginUser)); } #endregion #region 免检 ///不免检 var inspectionmaterialRequirementInfos = partInspectionmaterialRequirementInfos.Where(d => d.Inspection != (int)InspectionModeConstants.ExemptionInspection).ToList(); ///生成计划拉动单同时记录该生产订单该计划零件类已生成单据 ///当有物料需求时,才会生成计划拉动单 if (inspectionmaterialRequirementInfos.Count > 0) { ///实例化主表Guid Guid planPullOrderFid = Guid.NewGuid(); ///主表计划拉动单号 string orderCode = new SeqDefineBLL().GetCurrentCode("PLAN_PULL_ORDER_CODE", planPartBoxInfo.PartBoxCode.Substring(0, 1).ToUpper());///TODO:计划拉动单编号规则可能还会更改,待客户确认 MaterialPullingOrderInfo materialPullingOrderInfo = CreateMaterialPullingOrderInfo(planPartBoxInfo, orderCode, currentWindowTime, false); materialPullingOrderInfo.MaterialPullingOrderDetailInfos = (from m in inspectionmaterialRequirementInfos select new MaterialPullingOrderDetailInfo { OrderNo = orderCode, ///拉动单号1 SupplierNum = m.SupplierNum, ///供应商2 PartNo = m.PartNo, ///物料号3 PartCname = m.PartCname, ///物料号中文名称4 PartEname = m.PartEname, ///物料号英文名称5 Uom = m.PartUnits, ///计量单位6 PackageQty = m.InboundPackage.GetValueOrDefault(), ///入库单包装数量7 PackageModel = m.InboundPackageModel, ///入库包装编号8 RequirePackageQty = Convert.ToInt32(m.RequirePackageQty), ///需求包装数量9 RequirePartQty = m.Zqty, ///需求物料数量10 TargetZoneNo = planPartBoxInfo.TargetZoneNo, InspectMode = m.Inspection ///校验模式 }).ToList(); /// sql.AppendLine(CreatePlanPullOrderSql(planPullOrderFid, materialPullingOrderInfo, windowTimes, timeZone, (int)InspectionFlagConstants.Inspect)); sql.AppendLine(CreatePlanPullOrderDetailSql(planPullOrderFid, materialPullingOrderInfo.MaterialPullingOrderDetailInfos)); sql.AppendFormat(MaterialPullingCommonBLL.Handler(materialPullingOrderInfo, loginUser)); } #endregion } else { ///生成计划拉动单同时记录该生产订单该计划零件类已生成单据 ///当有物料需求时,才会生成计划拉动单 if (materialRequirementInfos.Count > 0) { ///实例化主表Guid Guid planPullOrderFid = Guid.NewGuid(); ///主表计划拉动单号 string orderCode = new SeqDefineBLL().GetCurrentCode("PLAN_PULL_ORDER_CODE", planPartBoxInfo.PartBoxCode.Substring(0, 1).ToUpper());///TODO:计划拉动单编号规则可能还会更改,待客户确认 MaterialPullingOrderInfo materialPullingOrderInfo = CreateMaterialPullingOrderInfo(planPartBoxInfo, orderCode, currentWindowTime, false); materialPullingOrderInfo.MaterialPullingOrderDetailInfos = (from m in materialRequirementInfos select new MaterialPullingOrderDetailInfo { OrderNo = orderCode, ///拉动单号1 SupplierNum = m.SupplierNum, ///供应商2 PartNo = m.PartNo, ///物料号3 PartCname = m.PartCname, ///物料号中文名称4 PartEname = m.PartEname, ///物料号英文名称5 Uom = m.PartUnits, ///计量单位6 PackageQty = m.InboundPackage.GetValueOrDefault(), ///入库单包装数量7 PackageModel = m.InboundPackageModel, ///入库包装编号8 RequirePackageQty = Convert.ToInt32(m.RequirePackageQty), ///需求包装数量9 RequirePartQty = m.Zqty, ///需求物料数量10 TargetZoneNo = planPartBoxInfo.TargetZoneNo }).ToList(); ///生成计划拉动单 sql.AppendLine(CreatePlanPullOrderSql(planPullOrderFid, materialPullingOrderInfo, windowTimes, timeZone, null)); ///生成计划拉动单明细 sql.AppendLine(CreatePlanPullOrderDetailSql(planPullOrderFid, materialPullingOrderInfo.MaterialPullingOrderDetailInfos)); ///单据衔接 sql.AppendLine(MaterialPullingCommonBLL.Handler(materialPullingOrderInfo, loginUser)); } } ///订单BOM存在时才需要更新 if (pullOrderBomInfos.Count > 0) { ///更新中间表处理状态 = 已处理 sql.AppendFormat("update [LES].[TT_MPM_PLAN_PULL_CREATE_STATUS] set " + "[STATUS] = " + (int)ProcessFlagConstants.Processed + "," + "[MODIFY_USER] = N'" + loginUser + "'," + "[MODIFY_DATE] = GETDATE() where " + "[VALID_FLAG] = 1 and " + "[PART_BOX_FID] = N'{0}' and " + "[ORDER_FID] in ('{1}');", planPartBoxInfo.Fid.GetValueOrDefault(), string.Join("','", pullOrderBomInfos.Select(d => d.Orderfid.GetValueOrDefault()).ToArray())); } #region 执行 if (sql.Length > 0) { ///更改窗口时间发单状态 if (planPullWindowTimeEnable.ToLower() == "true") { sql.AppendFormat("update [LES].[TT_MPM_PLAN_WINDOW_TIME] set " + "[SEND_TIME_STATUS] = " + (int)SendTimeStatusConstants.Sent + "," + "[MODIFY_USER] = N'" + loginUser + "'," + "[MODIFY_DATE] = GETDATE() where [ID] in (" + string.Join(",", planTimeIds.ToArray()) + ");"); } using (TransactionScope trans = new TransactionScope()) { if (!BLL.LES.CommonBLL.ExecuteNonQueryBySql(sql.ToString())) { throw new Exception("0x00000736");///写入数据库失败 } trans.Complete(); } } #endregion } #endregion }
/// <summary> /// JIS /// </summary> /// <param name="vehiclePointStatusInfo"></param> /// <param name="jisPartBoxInfos"></param> /// <param name="jisCounterInfos"></param> /// <param name="jisMaintainInhouseLogisticStandardInfos"></param> /// <returns></returns> private string JisCounterDeal(VehiclePointStatusInfo vehiclePointStatusInfo, List <JisPartBoxInfo> jisPartBoxInfos, List <MaintainInhouseLogisticStandardInfo> jisMaintainInhouseLogisticStandardInfos) { /// StringBuilder stringBuilder = new StringBuilder(); ///根据车辆状态信息中的生产订单号①获取到对应的生产订单物料清单、此处为了保障执行效率,需要根据已获取的物料拉动信息过滤获取物料清单 List <PullOrderBomInfo> pullOrderBomInfos = new PullOrderBomBLL().GetList("" + "[ZORDNO] = N'" + vehiclePointStatusInfo.OrderNo + "' and " + "[ZCOMNO] in ('" + string.Join("','", jisMaintainInhouseLogisticStandardInfos.Select(d => d.PartNo).ToArray()) + "')", string.Empty); if (pullOrderBomInfos.Count == 0) { return(string.Empty); } /// foreach (JisPartBoxInfo jisPartBoxInfo in jisPartBoxInfos) { ///不是这个信息点的零件类忽略 if (vehiclePointStatusInfo.StatusPointCode != jisPartBoxInfo.StatusPointCode) { continue; } ///根据物料拉动信息外键获取计数器,未能成功获取时需要创建 JisCounterInfo jisCounterInfo = new JisCounterBLL().GetInfoByPartBoxFid(jisPartBoxInfo.Fid.GetValueOrDefault()); if (jisCounterInfo == null) { jisCounterInfo = CreateJisCounterInfo(jisPartBoxInfo); } ///零件类对应的物料拉动信息 List <MaintainInhouseLogisticStandardInfo> maintainInhouseLogisticStandards = jisMaintainInhouseLogisticStandardInfos.Where(d => d.InhousePartClass == jisPartBoxInfo.PartBoxCode).ToList(); if (maintainInhouseLogisticStandards.Count == 0) { continue; } ///零件类过滤后的物料拉动信息对应的物料清单 List <PullOrderBomInfo> pullOrderBoms = pullOrderBomInfos.Where(d => maintainInhouseLogisticStandards.Select(m => m.PartNo).Contains(d.Zcomno)).ToList(); if (pullOrderBoms.Count == 0) { continue; } ///当排序计数器的累计方式⑧为按车辆累计时 if (jisPartBoxInfo.AccumulativeType.GetValueOrDefault() == (int)JisAccumulativeTypeConstants.VehicleAccumulative) { ///本次可累计车辆数量 decimal vehicleQty = jisCounterInfo.AccumulativeQty.GetValueOrDefault() - jisCounterInfo.CurrentQty.GetValueOrDefault(); int vehicleCounterStatus = (int)JisCounterStatusConstants.Accumulating; if (vehicleQty == 1) { vehicleCounterStatus = (int)JisCounterStatusConstants.AccumulativeCompletion; } /// stringBuilder.AppendLine(UpdateJisCounter(jisPartBoxInfo, jisCounterInfo, 1, vehicleCounterStatus)); } /// foreach (PullOrderBomInfo pullOrderBom in pullOrderBoms) { ///匹配物料拉动信息的最小维度是 物料图号+供应商+工位,依次降低维度来获取唯一的物料拉动信息 MaintainInhouseLogisticStandardInfo maintainInhouseLogisticStandard = maintainInhouseLogisticStandards.FirstOrDefault(d => d.PartNo == pullOrderBom.Zcomno && d.SupplierNum == pullOrderBom.SupplierNum && d.Location == pullOrderBom.Zloc); ///物料图号+供应商 if (maintainInhouseLogisticStandard == null) { maintainInhouseLogisticStandard = maintainInhouseLogisticStandards.FirstOrDefault(d => d.PartNo == pullOrderBom.Zcomno && d.SupplierNum == pullOrderBom.SupplierNum); } ///物料图号 if (maintainInhouseLogisticStandard == null) { maintainInhouseLogisticStandard = maintainInhouseLogisticStandards.FirstOrDefault(d => d.PartNo == pullOrderBom.Zcomno); } ///未能成功获取到正确的物料拉动信息 if (maintainInhouseLogisticStandard == null) { continue; } ///当排序计数器的累计方式⑧为按车辆累计时 if (jisPartBoxInfo.AccumulativeType.GetValueOrDefault() == (int)JisAccumulativeTypeConstants.VehicleAccumulative) { stringBuilder.AppendLine(UpdateJisCounter(jisPartBoxInfo, jisCounterInfo, vehiclePointStatusInfo, maintainInhouseLogisticStandard, pullOrderBom.Zqty.GetValueOrDefault())); } ///当排序计数器的累计方式⑧为按器具累计时 if (jisPartBoxInfo.AccumulativeType.GetValueOrDefault() == (int)JisAccumulativeTypeConstants.UtensilAccumulative) { ///物料需求数量 decimal requireQty = pullOrderBom.Zqty.GetValueOrDefault(); while (requireQty > 0) { int jisCounterStatus = (int)JisCounterStatusConstants.Accumulating; ///本次可累计数量 decimal currentQty = jisCounterInfo.AccumulativeQty.GetValueOrDefault() - jisCounterInfo.CurrentQty.GetValueOrDefault(); if (currentQty == 0) { break; } ///需求大于本次可累计 if (currentQty <= requireQty) { ///剩余需累计数量 requireQty -= currentQty; ///累计完成 jisCounterStatus = (int)JisCounterStatusConstants.AccumulativeCompletion; } else { ///将需求赋予本次 currentQty = requireQty; ///需求清空 requireQty = 0; } /// stringBuilder.AppendLine(UpdateJisCounter(jisPartBoxInfo, jisCounterInfo, currentQty, jisCounterStatus)); /// stringBuilder.AppendLine(UpdateJisCounter(jisPartBoxInfo, jisCounterInfo, vehiclePointStatusInfo, maintainInhouseLogisticStandard, currentQty)); ///当剩余需求数量大于零时,需要创建计数器 if (requireQty > 0) { jisCounterInfo = CreateJisCounterInfo(jisPartBoxInfo); } } } ///触发层级拉动 stringBuilder.AppendLine(TwdCounterBLL.LevelPullRequirementCounter( maintainInhouseLogisticStandard, pullOrderBom.Zqty.GetValueOrDefault(), loginUser, jisCounterInfo.Fid.GetValueOrDefault(), jisCounterInfo.PartBoxCode)); } } return(stringBuilder.ToString()); }
/// <summary> /// 缺件生产订单生成 /// </summary> public void CheckLackProductionOrder() { ///获取状态⑦为50已发布的缺件表数据,记录开始计算时间⑧并将状态⑦更新为60处理中 ///数据库执行语句 StringBuilder sqlText = new StringBuilder(); ///获取状态⑦为50反馈完成的缺件表 List <LackOfMaterialInfo> lackOfMaterialInfos = lackOfMaterialBLL.GetListByPage("" + "[STATUS] = " + (int)LackOfMaterialStatusConstants.Feedbacked + "", "[ID]", 1, 1, out int dataCnt); ///没有需要计算的缺件表 if (lackOfMaterialInfos.Count == 0) { return; } LackOfMaterialInfo lackOfMaterialInfo = lackOfMaterialInfos.FirstOrDefault(); ///获取状态⑦为50已发布的缺件表数据,记录开始计算时间⑧并将状态⑦更新为60处理中 lackOfMaterialBLL.UpdateStatus((int)LackOfMaterialStatusConstants.OrderCalculating, lackOfMaterialInfo.Id, "", loginUser); ///工厂 string plantCondition = string.Empty; if (!string.IsNullOrEmpty(lackOfMaterialInfo.Plant)) { plantCondition = " and [WERK] = N'" + lackOfMaterialInfo.Plant + "' "; } ///根据开始日期⑤与结束日期⑥、工厂代码④范围获取生产订单列表,按生产日期+生产顺序从晚到早进行排列 ///供货计划与生产订单日期相差一天 List <PullOrdersInfo> pullOrdersInfos = new PullOrdersBLL().GetList("" + plantCondition + " and " + "[ORDER_DATE] between " + "N'" + lackOfMaterialInfo.StartDate.GetValueOrDefault().AddDays(materialRequrieAdvanceDays) + "' and " + "N'" + lackOfMaterialInfo.EndDate.GetValueOrDefault().AddDays(materialRequrieAdvanceDays) + "'", "[ORDER_DATE] desc,[VEHICLE_ORDER] desc"); ///没有生产订单时计算失败 if (pullOrdersInfos.Count == 0) { lackOfMaterialBLL.UpdateStatus((int)LackOfMaterialStatusConstants.OrderCalculateFailed, lackOfMaterialInfo.Id, "没有生产订单时计算失败", loginUser); return; } ///根据缺件表明细中的物料号②、供应商代码③获取该生产订单的订单BOM中的数据 List <LackOfMaterialDetailInfo> lackOfMaterialDetailInfos = new LackOfMaterialDetailBLL().GetList("" + "[LACK_ORDER_FID] = N'" + lackOfMaterialInfo.Fid.GetValueOrDefault() + "' and " + "[FEEDBACK_FLAG] = 1", string.Empty); if (lackOfMaterialDetailInfos.Count == 0) { lackOfMaterialBLL.UpdateStatus((int)LackOfMaterialStatusConstants.OrderCalculateFailed, lackOfMaterialInfo.Id, "缺件表中无物料缺件信息", loginUser); return; } ///BOM List <PullOrderBomInfo> pullOrderBomInfos = new PullOrderBomBLL().GetList("" + "[ORDERFID] in ('" + string.Join("','", pullOrdersInfos.Select(d => d.Fid.GetValueOrDefault()).ToArray()) + "') and " + "[ZCOMNO] in ('" + string.Join("','", lackOfMaterialDetailInfos.Select(d => d.PartNo).ToArray()) + "') and " + "[SUPPLIER_NUM] in ('" + string.Join("','", lackOfMaterialDetailInfos.Select(d => d.SupplierNum).ToArray()) + "')", string.Empty); ///历史缺件生产订单 ORDER_DATE List <PorderLackMaterialInfo> lackOfMaterialProductionOrderInfos = new PorderLackMaterialBLL().GetList( "[ORDER_DATE] between " + "N'" + lackOfMaterialInfo.StartDate.GetValueOrDefault().AddDays(materialRequrieAdvanceDays) + "' and " + "N'" + lackOfMaterialInfo.EndDate.GetValueOrDefault().AddDays(materialRequrieAdvanceDays) + "'", string.Empty); ///LOG_FID Guid logFid = Guid.NewGuid(); foreach (PullOrdersInfo pullOrdersInfo in pullOrdersInfos) { ///并将该数据集合中的消耗数量与反馈缺件数量⑦进行对比,当反馈缺件数量⑦ – 消耗数量 >= 0 时 List <PullOrderBomInfo> pullOrderBoms = pullOrderBomInfos.Where(d => d.Orderfid.GetValueOrDefault() == pullOrdersInfo.Fid.GetValueOrDefault()).ToList(); if (pullOrderBoms.Count == 0) { continue; } ///此时需要记录对比结果到生产订单缺件明细中,物料号③、供应商代码④、工厂代码⑤、需求数量⑥即为BOM消耗数量 var pullOrderBomQuery = pullOrderBoms .GroupBy(b => new { b.Zcomno, b.SupplierNum }) .Select(d => new { PartNo = d.Key.Zcomno, d.Key.SupplierNum, Zqty = d.Sum(x => x.Zqty.GetValueOrDefault()) }).ToList(); ///缺件数量⑦即当反馈缺件数量⑦ – 消耗数量 >= 0 是为消耗数量,否则为反馈缺件剩余数量⑦ ///同时记录缺件生产订单,生产订单号③、生产订单外键②、工厂代码④、车间代码⑤、生产线代码⑥从生产订单中继承、缺件表外键①从缺件表继承、缺件标记⑦为True var lackDetailInfos = (from l in lackOfMaterialDetailInfos join p in pullOrderBomQuery on new { l.PartNo, l.SupplierNum } equals new { p.PartNo, p.SupplierNum } where l.FeedbackLackQty > 0 select new { l.PartNo, l.SupplierNum, l.Plant, l.PartPurchaser, p.Zqty, l.FeedbackLackQty, l.Fid, l.LackOrderFid }).ToList(); ///历史生产订单中是否存在此订单号 PorderLackMaterialInfo lackOfMaterialProductionOrderInfo = lackOfMaterialProductionOrderInfos.FirstOrDefault(d => d.ProductionOrderFid.GetValueOrDefault() == pullOrdersInfo.Fid.GetValueOrDefault()); ///当缺件明细中的反馈缺件数量全部被扣除到小于等于零时,不再记录生产订单缺件明细,仅记录缺件生产订单,此时开始缺件标记⑦为False Guid lackOfMaterialProductionOrderFid = Guid.NewGuid(); #region TT_ATP_PORDER_LACK_MATERIAL if (lackOfMaterialProductionOrderInfo == null) { ///不存在、直接插入 sqlText.AppendFormat("insert into [LES].[TT_ATP_PORDER_LACK_MATERIAL] (" + "[FID],[LACK_ORDER_FID],[PRODUCTION_ORDER_FID],[PRODUCTION_ORDER_NO],[PLANT],[ASSEMBLY_LINE]," + "[VALID_FLAG],[LACK_FLAG],[CREATE_USER],[CREATE_DATE],[ORDER_DATE]) values (" + "'{8}','{0}','{1}','{2}','{3}','{4}'," + "1,{7},'{5}',GETDATE(),'{6}');", lackOfMaterialInfo.Fid, ///LACK_ORDER_FID,0 pullOrdersInfo.Fid, ///PRODUCTION_ORDER_FID,1 pullOrdersInfo.OrderNo, ///PRODUCTION_ORDER_NO,2 pullOrdersInfo.Werk, ///PLANT,3 pullOrdersInfo.AssemblyLine, ///ASSEMBLY_LINE,4 loginUser, ///CREATE_USER,5 pullOrdersInfo.OrderDate.GetValueOrDefault(), ///ORDER_DATE,6 (lackDetailInfos.Count == 0 ? 0 : 1), ///LACK_FLAG,7 lackOfMaterialProductionOrderFid ///FID,8 ); } else { lackOfMaterialProductionOrderFid = lackOfMaterialProductionOrderInfo.Fid.GetValueOrDefault(); ///已存在、更新状态 sqlText.AppendFormat("update [LES].[TT_ATP_PORDER_LACK_MATERIAL] set " + "[LACK_FLAG] = {4}," + "[LACK_ORDER_FID] = N'{0}'," + "[ORDER_DATE] = N'{3}'," + "[MODIFY_USER] = N'{1}'," + "[MODIFY_DATE] = GETDATE() where " + "[FID] = N'{2}';", lackOfMaterialInfo.Fid.GetValueOrDefault(), ///LACK_ORDER_FID,0 loginUser, ///MODIFY_USER,1 lackOfMaterialProductionOrderFid, ///FID,2 pullOrdersInfo.OrderDate.GetValueOrDefault(), ///ORDER_DATE,3 (lackDetailInfos.Count == 0 ? 0 : 1) ///LACK_FLAG,4 ); ///删除之前计算的生产订单缺件明细 sqlText.AppendFormat("delete from [LES].[TT_ATP_PORDER_LACK_MATERIAL_DETAIL] where " + "[LACK_PORDER_FID] = N'{0}';", lackOfMaterialProductionOrderFid///LACK_PORDER_FID,0 ); ///移除 //lackOfMaterialProductionOrderInfos.Remove(lackOfMaterialProductionOrderInfo); } #endregion #region TI_IFM_SAP_PRODUCTION_ORDER_LACK_MATERIAL ///插入到SAP中间表 if (lackMaterialProductionOrdersToSap.ToLower() == "true") { sqlText.AppendFormat(" insert into [LES].[TI_IFM_SAP_PRODUCTION_ORDER_LACK_MATERIAL] (" + "[FID],[ENTERPRISE],[AREA_NO],[DMS_NO],[MATERIAL_CHECK],[SEND_TIME],[VALID_FLAG],[CREATE_USER],[CREATE_DATE],[PROCESS_FLAG],[LOG_FID]) values (" + "NEWID(),'{0}','{1}','{2}',0,GETDATE(),1,'{3}',GETDATE(),{5},'{4}');", pullOrdersInfo.Werk, ///ENTERPRISE,0 pullOrdersInfo.AssemblyLine, ///AREA_NO,1 pullOrdersInfo.OrderNo, ///DMS_NO,2 loginUser, /// CREATE_USER,3 logFid, ///LOG_FID,4 (int)ProcessFlagConstants.Untreated ///PROCESS_FLAG,5 ); } #endregion #region TI_IFM_MES_PRODUCTION_ORDER_LACK_MATERIAL ///插入到MES中间表 if (lackMaterialProductionOrdersToMes.ToLower() == "true") { sqlText.AppendFormat("insert into [LES].[TI_IFM_MES_PRODUCTION_ORDER_LACK_MATERIAL] (" + "[FID],[ENTERPRISE],[AREA_NO],[DMS_NO],[MATERIAL_CHECK],[SEND_TIME],[VALID_FLAG],[CREATE_USER],[CREATE_DATE],[PROCESS_FLAG],[LOG_FID]) values (" + "NEWID(),'{0}','{1}','{2}',0,GETDATE(),1,'{3}',GETDATE(),{5},'{4}');", pullOrdersInfo.Werk, ///ENTERPRISE,0 pullOrdersInfo.AssemblyLine, ///AREA_NO,1 pullOrdersInfo.OrderNo, ///DMS_NO,2 loginUser, /// CREATE_USER,3 logFid, ///LOG_FID,4 (int)ProcessFlagConstants.Untreated ///PROCESS_FLAG,5 ); } #endregion #region TT_ATP_PORDER_LACK_MATERIAL_DETAIL if (lackDetailInfos.Count > 0) { ///写入生产订单缺件明细 foreach (var lackDetailInfo in lackDetailInfos) { sqlText.AppendFormat("insert into [LES].[TT_ATP_PORDER_LACK_MATERIAL_DETAIL] (" + "[FID],[LACK_PORDER_FID],[PRODUCTION_ORDER_FID],[LACK_DETAIL_FID],[PART_NO],[SUPPLIER_NUM],[PLANT],[REQUIRE_QTY],[LACK_QTY]," + "[VALID_FLAG],[CREATE_USER],[CREATE_DATE]," + "[PART_PURCHASER],[PRODUCTION_ORDER_NO],[ASSEMBLY_LINE],[ORDER_DATE],[LACK_ORDER_FID]) values " + "(NEWID(),'{0}','{1}','{2}','{3}','{4}','{5}',{6},{7}," + "1,'{8}',GETDATE(),'{9}','{10}','{11}','{12}','{13}');", lackOfMaterialProductionOrderFid, ///LACK_PORDER_FID,0 pullOrdersInfo.Fid.GetValueOrDefault(), ///PRODUCTION_ORDER_FID,1 lackDetailInfo.Fid.GetValueOrDefault(), ///LACK_DETAIL_FID,2 lackDetailInfo.PartNo, ///PART_NO,3 lackDetailInfo.SupplierNum, ///SUPPLIER_NUM,4 lackDetailInfo.Plant, ///PLANT,5 lackDetailInfo.Zqty, ///REQUIRE_QTY,6 lackDetailInfo.FeedbackLackQty >= lackDetailInfo.Zqty ? lackDetailInfo.Zqty : lackDetailInfo.FeedbackLackQty, ///LACK_QTY,7 loginUser, ///CREATE_USER,8 lackDetailInfo.PartPurchaser, ///PART_PURCHASER,9 pullOrdersInfo.OrderNo, ///PRODUCTION_ORDER_NO,10 pullOrdersInfo.AssemblyLine, ///ASSEMBLY_LINE,11 pullOrdersInfo.OrderDate.GetValueOrDefault(), ///ORDER_DATE,12 lackDetailInfo.LackOrderFid.GetValueOrDefault() ///LACK_ORDER_FID,13 ); } } #endregion ///将差异值作为缺件数量以用于下一份生产订单的比对 lackOfMaterialDetailInfos = (from l in lackOfMaterialDetailInfos join p in pullOrderBomQuery on new { l.PartNo, l.SupplierNum } equals new { p.PartNo, p.SupplierNum } into temp from tt in temp.DefaultIfEmpty() select new LackOfMaterialDetailInfo { PartNo = l.PartNo, SupplierNum = l.SupplierNum, Plant = l.Plant, PartPurchaser = l.PartPurchaser, FeedbackLackQty = l.FeedbackLackQty - (tt == null ? 0 : tt.Zqty), Fid = l.Fid, LackOrderFid = l.LackOrderFid }).ToList(); } #region 从检查日期范围内移出的生产订单 ///移除的历史生产订单 var lackOfMaterialProductionOrderRemoveInfos = (from l in lackOfMaterialProductionOrderInfos where !(from p in pullOrdersInfos where p.OrderNo == l.ProductionOrderNo select p).Any() select l).ToList(); foreach (var lackOfMaterialProductionOrderRemoveInfo in lackOfMaterialProductionOrderRemoveInfos) { ///更新状态 sqlText.AppendFormat("update [LES].[TT_ATP_PORDER_LACK_MATERIAL] set " + "[LACK_FLAG] = {3}," + "[LACK_ORDER_FID] = N'{0}'," + "[MODIFY_USER] = N'{1}'," + "[MODIFY_DATE] = GETDATE() where " + "[PRODUCTION_ORDER_FID] = N'{2}';", lackOfMaterialInfo.Fid.GetValueOrDefault(), ///LACK_ORDER_FID,0 loginUser, ///MODIFY_USER,1 lackOfMaterialProductionOrderRemoveInfo.ProductionOrderFid.GetValueOrDefault(), ///PRODUCTION_ORDER_FID,2 0 ///LACK_FLAG,3 ); ///删除明细 sqlText.AppendFormat("delete from [LES].[TT_ATP_PORDER_LACK_MATERIAL_DETAIL] where " + "[PRODUCTION_ORDER_FID] = N'{0}';", lackOfMaterialProductionOrderRemoveInfo.ProductionOrderFid.GetValueOrDefault()///PRODUCTION_ORDER_FID,0 ); ///插入到SAP中间表 if (lackMaterialProductionOrdersToSap.ToLower() == "true") { sqlText.AppendFormat(" insert into [LES].[TI_IFM_SAP_PRODUCTION_ORDER_LACK_MATERIAL] (" + "[FID],[ENTERPRISE],[AREA_NO],[DMS_NO],[MATERIAL_CHECK],[SEND_TIME],[VALID_FLAG],[CREATE_USER],[CREATE_DATE],[PROCESS_FLAG],[LOG_FID]) values (" + "NEWID(),'{0}','{1}','{2}',{6},GETDATE(),1,'{3}',GETDATE(),{5},'{4}');", lackOfMaterialProductionOrderRemoveInfo.Plant, ///ENTERPRISE,0 lackOfMaterialProductionOrderRemoveInfo.AssemblyLine, ///AREA_NO,1 lackOfMaterialProductionOrderRemoveInfo.ProductionOrderNo, ///DMS_NO,2 loginUser, /// CREATE_USER,3 logFid, ///LOG_FID,4 (int)ProcessFlagConstants.Untreated, ///PROCESS_FLAG,5 0 ///MATERIAL_CHECK,6 ); } ///插入到MES中间表 if (lackMaterialProductionOrdersToMes.ToLower() == "true") { sqlText.AppendFormat("insert into [LES].[TI_IFM_MES_PRODUCTION_ORDER_LACK_MATERIAL] (" + "[FID],[ENTERPRISE],[AREA_NO],[DMS_NO],[MATERIAL_CHECK],[SEND_TIME],[VALID_FLAG],[CREATE_USER],[CREATE_DATE],[PROCESS_FLAG],[LOG_FID]) values (" + "NEWID(),'{0}','{1}','{2}',{6},GETDATE(),1,'{3}',GETDATE(),{5},'{4}');", lackOfMaterialProductionOrderRemoveInfo.Plant, ///ENTERPRISE,0 lackOfMaterialProductionOrderRemoveInfo.AssemblyLine, ///AREA_NO,1 lackOfMaterialProductionOrderRemoveInfo.ProductionOrderNo, ///DMS_NO,2 loginUser, /// CREATE_USER,3 logFid, ///LOG_FID,4 (int)ProcessFlagConstants.Untreated, ///PROCESS_FLAG,5 0 ///MATERIAL_CHECK,6 ); } } #endregion /// if (sqlText.Length > 0) { ///调用发送数据 string keyValue = lackOfMaterialInfo.StartDate.GetValueOrDefault().ToString("yyyyMMdd") + "~" + lackOfMaterialInfo.EndDate.GetValueOrDefault().ToString("yyyyMMdd"); if (lackMaterialProductionOrdersToSap.ToLower() == "true") { sqlText.AppendFormat(BLL.LES.CommonBLL.GetCreateOutboundLogSql("SAP", logFid, "LES-SAP-017", keyValue, loginUser)); } if (lackMaterialProductionOrdersToMes.ToLower() == "true") { sqlText.AppendFormat(BLL.LES.CommonBLL.GetCreateOutboundLogSql("MES", logFid, "LES-MES-002", keyValue, loginUser)); } ///计算完成后记录计算结束时间⑨并更新状态⑦为70已完成,同时将缺件生产订单及生产订单缺件明细一次性写入数据库中 sqlText.AppendFormat("update [LES].[TT_ATP_LACK_OF_MATERIAL] set " + "[STATUS] = {2}," + "[EXECUTE_END_TIME] = GETDATE()," + "[MODIFY_USER] = N'{0}'," + "[MODIFY_DATE] = GETDATE() where " + "[ID] = {1};", loginUser, ///MODIFY_USER,0 lackOfMaterialInfo.Id, ///ID,1 (int)LackOfMaterialStatusConstants.OrderCompleted ///STATUS,2 ); #region 执行 using (TransactionScope trans = new TransactionScope()) { BLL.LES.CommonBLL.ExecuteNonQueryBySql(sqlText.ToString()); trans.Complete(); } #endregion } }
/// <summary> /// TWD /// </summary> /// <param name="vehiclePointStatusInfo"></param> /// <param name="twdCounterInfos"></param> /// <param name="twdMaintainInhouseLogisticStandardInfos"></param> /// <returns></returns> private string TwdCounterDeal(VehiclePointStatusInfo vehiclePointStatusInfo, List <TwdPartBoxInfo> twdPartBoxInfos, List <MaintainInhouseLogisticStandardInfo> twdMaintainInhouseLogisticStandardInfos) { /// StringBuilder stringBuilder = new StringBuilder(); ///根据车辆状态信息中的生产订单号①获取到对应的生产订单物料清单、此处为了保障执行效率,需要根据已获取的计数器的物料号⑩过滤获取物料清单 ///ZORDNO = 生产订单号 ///ZCOMNO = 物料图号 List <PullOrderBomInfo> pullOrderBomInfos = new PullOrderBomBLL().GetList("" + "[ZORDNO] = N'" + vehiclePointStatusInfo.OrderNo + "' and " + "[ZCOMNO] in ('" + string.Join("','", twdMaintainInhouseLogisticStandardInfos.Select(d => d.PartNo).ToArray()) + "')", string.Empty); if (pullOrderBomInfos.Count == 0) { return(string.Empty); } /// foreach (TwdPartBoxInfo twdPartBoxInfo in twdPartBoxInfos) { ///不是这个信息点的零件类忽略 if (vehiclePointStatusInfo.StatusPointCode != twdPartBoxInfo.StatusPointCode) { continue; } ///本零件类对应的物料拉动信息 List <MaintainInhouseLogisticStandardInfo> maintainInhouseLogisticStandards = twdMaintainInhouseLogisticStandardInfos.Where(d => d.InhousePartClass == twdPartBoxInfo.PartBoxCode).ToList(); ///若本零件类无物料拉动信息则返回 if (twdMaintainInhouseLogisticStandardInfos.Count == 0) { continue; } ///零件类过滤后的物料拉动信息对应的物料清单 List <PullOrderBomInfo> pullOrderBoms = pullOrderBomInfos.Where(d => maintainInhouseLogisticStandards.Select(m => m.PartNo).Contains(d.Zcomno)).ToList(); ///循环过滤后的物料清单 foreach (PullOrderBomInfo pullOrderBom in pullOrderBoms) { ///匹配物料拉动信息的最小维度是 物料图号+供应商+工位,依次降低维度来获取唯一的物料拉动信息 MaintainInhouseLogisticStandardInfo maintainInhouseLogisticStandard = maintainInhouseLogisticStandards.FirstOrDefault(d => d.PartNo == pullOrderBom.Zcomno && d.SupplierNum == pullOrderBom.SupplierNum && d.Location == pullOrderBom.Zloc); ///物料图号+供应商 if (maintainInhouseLogisticStandard == null) { maintainInhouseLogisticStandard = maintainInhouseLogisticStandards.FirstOrDefault(d => d.PartNo == pullOrderBom.Zcomno && d.SupplierNum == pullOrderBom.SupplierNum); } ///物料图号 if (maintainInhouseLogisticStandard == null) { maintainInhouseLogisticStandard = maintainInhouseLogisticStandards.FirstOrDefault(d => d.PartNo == pullOrderBom.Zcomno); } ///未能成功获取到正确的物料拉动信息 if (maintainInhouseLogisticStandard == null) { continue; } ///根据物料拉动信息外键获取计数器,未能成功获取时需要创建 TwdCounterInfo twdCounterInfo = TwdCounterBLL.GetInfoByPartPullFid(maintainInhouseLogisticStandard.Fid); if (twdCounterInfo == null) { ///创建计数器 twdCounterInfo = TwdCounterBLL.CreateTwdCounterInfo(loginUser); ///以物料拉动信息填充计数器 TwdCounterBLL.GetTwdCounterInfo(maintainInhouseLogisticStandard, ref twdCounterInfo); ///以零件类信息填充计数器 TwdCounterBLL.GetTwdCounterInfo(twdPartBoxInfo, ref twdCounterInfo); /// twdCounterInfo.Id = new TwdCounterBLL().InsertInfo(twdCounterInfo); if (twdCounterInfo.Id == 0) { throw new Exception("MC:0x00000453");///时间窗计数器创建失败 } } ///计数器状态未处于启用 if (twdCounterInfo.Status != (int)BasicDataStatusConstants.Enable) { continue; } stringBuilder.AppendLine(TwdCounterBLL.UpdateTwdCounter(maintainInhouseLogisticStandard, twdPartBoxInfo, pullOrderBom.Zqty.GetValueOrDefault(), twdCounterInfo.Id, loginUser)); ///创建计数器日志 TwdCounterLogInfo twdCounterLogInfo = TwdCounterLogBLL.CreateTwdCounterLogInfo(twdCounterInfo.Fid.GetValueOrDefault(), loginUser); ///以车辆过点信息填充计数器日志 TwdCounterLogBLL.GetTwdCounterLogInfo(vehiclePointStatusInfo, ref twdCounterLogInfo); ///以物料拉动信息填充计数器日志 TwdCounterLogBLL.GetTwdCounterLogInfo(maintainInhouseLogisticStandard, ref twdCounterLogInfo); ///以零件类信息填充计数器日志 TwdCounterLogBLL.GetTwdCounterLogInfo(twdPartBoxInfo, ref twdCounterLogInfo); ///PART_QTY twdCounterLogInfo.PartQty = pullOrderBom.Zqty.GetValueOrDefault(); /// stringBuilder.AppendLine(TwdCounterLogDAL.GetInsertSql(twdCounterLogInfo)); ///触发层级拉动 stringBuilder.AppendLine(TwdCounterBLL.LevelPullRequirementCounter( maintainInhouseLogisticStandard, pullOrderBom.Zqty.GetValueOrDefault(), loginUser, twdCounterInfo.Fid.GetValueOrDefault(), twdCounterInfo.PartBoxCode)); } } return(stringBuilder.ToString()); }
public void Handler() { #region 基础变量 ///最近一条的中间表数据状态 int processFlag = 0; ///本次线程已处理的中间表主键 List <long> dealedIds = new List <long>(); //数据库执行语句 StringBuilder @string = new StringBuilder(); ///物料需求提前天数 int.TryParse(materialRequireAdvanceDays, out int intMaterialRequrieAdvanceDays); intMaterialRequrieAdvanceDays = 0 - intMaterialRequrieAdvanceDays; #endregion while (processFlag != 10) { ///开始处理时间 DateTime startExecuteTime = DateTime.Now; ///获取状态⑮为10.未处理的SAP生产订单数据 ///因为后续处理过程较为复杂,所以一次获取一条ID主键最靠前的10.未处理或30.挂起或40.逆处理状态数据 ///当上一条处理数据为30.挂起状态时需要继续处理下一条,否则执行结束 ///也就意味着30.挂起的数据将优先处理且为了保障挂起数据不影响正常未处理数据而设定的逻辑 #region 获取待处理的数据 string textWhere = "[PROCESS_FLAG] in (" + (int)ProcessFlagConstants.Untreated + "," + (int)ProcessFlagConstants.Suspend + "," + (int)ProcessFlagConstants.ConverseProgress + ")"; ///集合大于0,排除 if (dealedIds.Count > 0) { textWhere += "and [ID] not in (" + string.Join(",", dealedIds.ToArray()) + ")"; } /// SapProductOrderInfo sapProductOrderInfo = new SapProductOrderBLL().GetTopOneInfo(textWhere, "[ID] asc"); if (sapProductOrderInfo == null) { throw new Exception("MC:3x00000015");///没有已启用的SAP生产订单信息 } if (sapProductOrderInfo.OnlineDate == null) { throw new Exception("MC:3x00000033");///SAP生产订单上线日期信息错误 } Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ":Start " + sapProductOrderInfo.Aufnr); ///SAP生产订单上线日期 string sapProductOrderDate = sapProductOrderInfo.OnlineDate.GetValueOrDefault().ToString("yyyyMMdd"); ///处理状态 processFlag = sapProductOrderInfo.ProcessFlag.GetValueOrDefault(); /// dealedIds.Add(sapProductOrderInfo.Id); #endregion #region SAP生产订单物料清单 ///获取SAP生产订单中订单号⑤=③对应的SAP生产订单物料清单 SapProductOrderBomInfo sapProductOrderBomInfo = new SapProductOrderBomBLL().GetInfoByAufnr(sapProductOrderInfo.Aufnr); ///若此时未能获取到数据则表示该SAP生产订单的物料清单还未能从SAP成功接收到 if (sapProductOrderBomInfo == null) { ///需要终止该条生产订单的处理,并且标记为挂起状态⑮ new SapProductOrderBLL().UpdateInfo("[PROCESS_FLAG] = " + (int)ProcessFlagConstants.Suspend + ",[MODIFY_USER] = N'" + loginUser + "',[MODIFY_DATE] = GETDATE()", sapProductOrderInfo.Id); continue; } #endregion #region 订单物料清单XML解析 ///SAP生产订单物料清单中的物料信息⑦需要XML解析后并逐条以工厂③=②、物料号①=⑦.MATNR、供应商②=⑦.LIFNR XmlWrapper xmlWrapper = new XmlWrapper(sapProductOrderBomInfo.Matnrs, LoadType.FromString); List <object> objMatnrs = xmlWrapper.XmlToList("/MatnrsAll/Matnrs", typeof(Matnrs)); if (objMatnrs.Count == 0) { throw new Exception("0x00000182");///无订单物料清单 } List <string> partNos = new List <string>(); List <string> supplierNums = new List <string>(); foreach (Matnrs matnr in objMatnrs) { partNos.Add(matnr.Matnr); supplierNums.Add(matnr.Lifnr); } List <MaintainPartsInfo> maintainPartsInfos = new MaintainPartsBLL().GetListForInterfaceDataSync(partNos); if (maintainPartsInfos.Count == 0) { throw new Exception("0x00000182");///无订单物料清单 } List <SupplierInfo> supplierInfos = new SupplierBLL().GetListForInterfaceDataSync(supplierNums); #endregion ///需根据SAP生产订单中的上线日期⑩判定供货计划TT_ATP_SUPPLY_PLAN中的对应日期列是否存在 ///日期列的列名规则为yyyyMMdd数据类型为decimal(18,4),不存在则需要新建列 ProcessSupplyPlanDate(sapProductOrderInfo.OnlineDate.GetValueOrDefault().AddDays(intMaterialRequrieAdvanceDays)); /// string plant = new PlantBLL().GetPlantBySapPlantCode(sapProductOrderInfo.Dwerk); if (string.IsNullOrEmpty(plant)) { throw new Exception("3x00000016");///工厂不存在 } string assemblyLine = new AssemblyLineBLL().GetAssemblyLineBySapAssemblyLine(sapProductOrderInfo.Verid); if (string.IsNullOrEmpty(assemblyLine)) { throw new Exception("3x00000017");///产线不存在 } ///根据生产订单号⑤=①获取生产订单TT_BAS_PULL_ORDERS数据 PullOrdersInfo pullOrdersInfo = new PullOrdersBLL().GetInfoByOrderNo(sapProductOrderInfo.Aufnr); ///生产订单上线日期 string productOrderDate = sapProductOrderDate; ///供货日期 string materialRequireDate = sapProductOrderInfo.OnlineDate.GetValueOrDefault().AddDays(intMaterialRequrieAdvanceDays).ToString("yyyyMMdd"); #region 首次下发 ///若此时未能成功获取数据则表示该生产订单为首次下发,且不是删除的生产订单 if (pullOrdersInfo == null && string.IsNullOrEmpty(sapProductOrderInfo.Zsc)) { if (calculateSupplyPlanFlag.ToLower() == "true") { #region 供货计划 foreach (Matnrs matnr in objMatnrs) { decimal partQty = 0; decimal.TryParse(matnr.Bdmng, out partQty); MaintainPartsInfo maintainPartsInfo = maintainPartsInfos.FirstOrDefault(d => d.PartNo == matnr.Matnr); string partCname = maintainPartsInfo == null ? string.Empty : maintainPartsInfo.PartCname.Replace("'", "''"); string partPurchaser = maintainPartsInfo == null ? string.Empty : maintainPartsInfo.PartPurchaser; SupplierInfo supplierInfo = supplierInfos.FirstOrDefault(d => d.SupplierNum == matnr.Lifnr); string supplierName = supplierInfo == null ? string.Empty : supplierInfo.SupplierName; ///若不存在则insert,再以工厂③、物料号①、供应商②更新其对应日期的物料数量 @string.AppendFormat(@" if not exists (select 1 from [LES].[TT_ATP_SUPPLY_PLAN] with(nolock) where [PART_NO] = N'{0}' and [SUPPLIER_NUM] = N'{1}' and [PLANT] = N'{2}' and [VALID_FLAG] = 1) begin insert into [LES].[TT_ATP_SUPPLY_PLAN] ([FID],[PART_NO],[PART_CNAME],[PART_PURCHASER],[SUPPLIER_NUM],[SUPPLIER_NAME],[PLANT],[VALID_FLAG],[CREATE_USER],[CREATE_DATE]) values (NEWID(),N'{0}',N'{6}',N'{7}',N'{1}',N'{8}',N'{2}',1,N'{5}',GETDATE()); end update [LES].[TT_ATP_SUPPLY_PLAN] set [PART_CNAME] = N'{6}',[PART_PURCHASER] = N'{7}',[SUPPLIER_NAME] = N'{8}',[{3}] = ISNULL([{3}] , 0) + {4},[MODIFY_USER] = N'{5}',[MODIFY_DATE] = GETDATE() where [PART_NO] = N'{0}' and [SUPPLIER_NUM] = N'{1}' and [PLANT] = N'{2}';" , matnr.Matnr, matnr.Lifnr, plant, materialRequireDate, partQty, loginUser, partCname, partPurchaser, supplierName); } #endregion } #region 生产订单 /// pullOrdersInfo = PullOrdersBLL.CreatePullOrdersInfo(loginUser); /// PullOrdersBLL.GetPullOrdersInfo(sapProductOrderInfo, ref pullOrdersInfo); ///WERK,接口_工厂 pullOrdersInfo.Werk = plant; ///ORDER_DATE,订单日期 pullOrdersInfo.OrderDate = BLL.LES.CommonBLL.TryParseDatetime(sapProductOrderDate); ///ASSEMBLY_LINE,工厂模型_流水线 pullOrdersInfo.AssemblyLine = assemblyLine; ///PLAN_EXECUTE_TIME,计划执行时间 pullOrdersInfo.PlanExecuteTime = BLL.LES.CommonBLL.TryParseDatetime(sapProductOrderDate); /// @string.AppendLine(PullOrdersDAL.GetInsertSql(pullOrdersInfo)); ///并批量插入生产订单物料清单(参见TT_BAS_PULL_ORDER_BOM备注中的对应关系) WmsVmiProductOrderInfo wmsVmiProductOrderInfo = WmsVmiProductOrderBLL.CreateWmsVmiProductOrderInfo(loginUser); /// WmsVmiProductOrderBLL.GetWmsVmiProductOrderInfo(pullOrdersInfo, ref wmsVmiProductOrderInfo); /// wmsVmiProductOrderInfo.DownLineTime = sapProductOrderInfo.OfflineDate; wmsVmiProductOrderInfo.OnlineTime = sapProductOrderInfo.OnlineDate; wmsVmiProductOrderInfo.LockFlag = sapProductOrderInfo.LockFlag; @string.AppendLine(WmsVmiProductOrderDAL.GetInsertSql(wmsVmiProductOrderInfo)); @string.AppendLine(BLL.LES.CommonBLL.GetCreateOutboundLogSql("VMI", wmsVmiProductOrderInfo.LogFid.GetValueOrDefault(), "LES-WMS-012", wmsVmiProductOrderInfo.OrderNo, loginUser)); foreach (Matnrs matnr in objMatnrs) { decimal partQty = 0; decimal.TryParse(matnr.Bdmng, out partQty); MaintainPartsInfo maintainPartsInfo = maintainPartsInfos.FirstOrDefault(d => d.PartNo == matnr.Matnr); string partCname = maintainPartsInfo == null ? string.Empty : maintainPartsInfo.PartCname; @string.AppendFormat(@"insert into [LES].[TT_BAS_PULL_ORDER_BOM] ([FID],[ORDERFID],[ZORDNO],[ZKWERK],[ZBOMID],[ZCOMNO],[ZQTY],[ZLOC],[SUPPLIER_NUM],[PLATFORM],[CREATE_USER],[CREATE_DATE],[VALID_FLAG],[ZCOMDS],[ZDATE]) values (NEWID(),N'{0}',N'{1}',N'{2}',N'{3}',N'{4}',{5},N'{6}',N'{7}',N'{8}',N'{9}',GETDATE(),1,N'{10}',N'{11}');" , pullOrdersInfo.Fid.GetValueOrDefault(), sapProductOrderInfo.Aufnr, plant, matnr.Aennr, matnr.Matnr, partQty, matnr.Ebort, matnr.Lifnr, matnr.Platform, loginUser, partCname, sapProductOrderDate); } #endregion #region 计划拉动状态 ///获取已启用的计划零件类的零件类外键① ///并将TT_BAS_PULL_ORDERS的订单外键②写入TT_MPM_PLAN_PULL_CREATE_STATUS ///其中的状态③为10.未生成(20.已生成,在系统代码中创建CREATE_STATUS,还需修改计划拉动单生成逻辑中的对应枚举项) List <PlanPartBoxInfo> planPartBoxInfos = new PlanPartBoxBLL().GetList("[STATUS] = " + (int)BasicDataStatusConstants.Enable + "", string.Empty); /// foreach (PlanPartBoxInfo planPartBoxInfo in planPartBoxInfos) { @string.AppendFormat(@"insert into [LES].[TT_MPM_PLAN_PULL_CREATE_STATUS] (FID,PART_BOX_FID,ORDER_FID,STATUS,CREATE_USER,CREATE_DATE,VALID_FLAG) values (NEWID(),N'{0}',N'{1}',{2},'{3}',GETDATE(),1);" , planPartBoxInfo.Fid.GetValueOrDefault(), pullOrdersInfo.Fid.GetValueOrDefault(), (int)CreateStatusConstants.NotGenerated, loginUser); } #endregion ///同时更新SAP生产订单物料清单处理状态⑮为20.已处理 @string.AppendFormat(@"update [LES].[TI_IFM_SAP_PRODUCT_ORDER_BOM] set PROCESS_FLAG = {0},PROCESS_TIME = GETDATE(),[MODIFY_USER] = N'{1}',[MODIFY_DATE] = GETDATE() where [ID] = {2};" , (int)ProcessFlagConstants.Processed, loginUser, sapProductOrderBomInfo.Id); } #endregion #region 是首次下发 else { if (calculateSupplyPlanFlag.ToLower() == "true") { ///若之前成功获取了生产订单则比对上线日期⑩⑤是否较SAP生产订单有变化 #region 供货计划 ///获取生产订单物料清单 List <PullOrderBomInfo> pullOrderBomInfos = new PullOrderBomBLL().GetList("[ZORDNO] = N'" + pullOrdersInfo.OrderNo + "'", string.Empty); ///SAP订单删除,需要重新计算供货计划 if (sapProductOrderInfo.Zsc.ToUpper() == "X") { ///需要根据生产订单物料清单TT_BAS_PULL_ORDER_BOM和生产订单的订单日期⑤扣减供货计划 foreach (PullOrderBomInfo pullOrderBomInfo in pullOrderBomInfos) { @string.AppendLine("update [LES].[TT_ATP_SUPPLY_PLAN] " + "set [" + materialRequireDate + "] = ISNULL([" + materialRequireDate + "] , 0) - " + pullOrderBomInfo.Zqty.GetValueOrDefault() + "," + "[MODIFY_USER] = N'" + loginUser + "'," + "[MODIFY_DATE] = GETDATE() " + "where [PART_NO] = N'" + pullOrderBomInfo.Zcomno + "' and " + "[SUPPLIER_NUM] = N'" + pullOrderBomInfo.SupplierNum + "' and " + "[PLANT] = N'" + plant + "';"); } } else { ///若日期无变化⑩=⑤处理状态⑮为10.未处理或30.挂起时不需要更新供货计划 if (sapProductOrderInfo.OnlineDate.GetValueOrDefault() == pullOrdersInfo.OrderDate.GetValueOrDefault()) { ///若处理状态⑮为40.逆处理时 if (processFlag == (int)ProcessFlagConstants.ConverseProgress) { ///根据SAP生产订单上线日期⑩及物料清单扣减供货计划 foreach (Matnrs matnr in objMatnrs) { decimal partQty = 0; decimal.TryParse(matnr.Bdmng, out partQty); @string.AppendFormat(@"update [LES].[TT_ATP_SUPPLY_PLAN] set [{3}] = ISNULL([{3}] , 0) - {4},[MODIFY_USER] = N'{5}',[MODIFY_DATE] = GETDATE() where [PART_NO] = N'{0}' and [SUPPLIER_NUM] = N'{1}' and [PLANT] = N'{2}';" , matnr.Matnr, matnr.Lifnr, plant, materialRequireDate, partQty, loginUser); } ///再以生产订单⑤日期及物料清单累加供货计划 foreach (PullOrderBomInfo pullOrderBomInfo in pullOrderBomInfos) { MaintainPartsInfo maintainPartsInfo = maintainPartsInfos.FirstOrDefault(d => d.PartNo == pullOrderBomInfo.Zcomno); string partCname = maintainPartsInfo == null ? string.Empty : maintainPartsInfo.PartCname; string partPurchaser = maintainPartsInfo == null ? string.Empty : maintainPartsInfo.PartPurchaser; SupplierInfo supplierInfo = supplierInfos.FirstOrDefault(d => d.SupplierNum == pullOrderBomInfo.SupplierNum); string supplierName = supplierInfo == null ? string.Empty : supplierInfo.SupplierName; @string.AppendFormat(@"update [LES].[TT_ATP_SUPPLY_PLAN] set [PART_CNAME] = N'{6}',[PART_PURCHASER] = N'{7}',[SUPPLIER_NAME] = N'{8}',[{3}] = ISNULL([{3}] , 0) + {4},[MODIFY_USER] = N'{5}',[MODIFY_DATE] = GETDATE() where [PART_NO] = N'{0}' and [SUPPLIER_NUM] = N'{1}' and [PLANT] = N'{2}';" , pullOrderBomInfo.Zcomno, pullOrderBomInfo.SupplierNum, plant, materialRequireDate, pullOrderBomInfo.Zqty.GetValueOrDefault(), loginUser, partCname, partPurchaser, supplierName); } } } ///日期有变化⑩<>⑤ else { ///SAP生产订单处理状态⑮为10.未处理或30.挂起时 if (processFlag == (int)ProcessFlagConstants.Untreated || processFlag == (int)ProcessFlagConstants.Suspend) { ///需要根据生产订单物料清单TT_BAS_PULL_ORDER_BOM和生产订单的订单日期⑤扣减供货计划 foreach (PullOrderBomInfo pullOrderBomInfo in pullOrderBomInfos) { @string.AppendFormat(@"update [LES].[TT_ATP_SUPPLY_PLAN] set [{3}] = ISNULL([{3}] , 0) - {4},[MODIFY_USER] = N'{5}',[MODIFY_DATE] = GETDATE() where [PART_NO] = N'{0}' and [SUPPLIER_NUM] = N'{1}' and [PLANT] = N'{2}';" , pullOrderBomInfo.Zcomno, pullOrderBomInfo.SupplierNum, plant, materialRequireDate, pullOrderBomInfo.Zqty.GetValueOrDefault(), loginUser); } ///同时根据SAP生产订单上线日期⑩及物料清单累加供货计划 foreach (Matnrs matnr in objMatnrs) { decimal partQty = 0; decimal.TryParse(matnr.Bdmng, out partQty); MaintainPartsInfo maintainPartsInfo = maintainPartsInfos.FirstOrDefault(d => d.PartNo == matnr.Matnr); string partCname = maintainPartsInfo == null ? string.Empty : maintainPartsInfo.PartCname; string partPurchaser = maintainPartsInfo == null ? string.Empty : maintainPartsInfo.PartPurchaser; SupplierInfo supplierInfo = supplierInfos.FirstOrDefault(d => d.SupplierNum == matnr.Lifnr); string supplierName = supplierInfo == null ? string.Empty : supplierInfo.SupplierName; @string.AppendFormat(@"update [LES].[TT_ATP_SUPPLY_PLAN] set [PART_CNAME] = N'{6}',[PART_PURCHASER] = N'{7}',[SUPPLIER_NAME] = N'{8}',[{3}] = ISNULL([{3}] , 0) + {4},[MODIFY_USER] = N'{5}',[MODIFY_DATE] = GETDATE() where [PART_NO] = N'{0}' and [SUPPLIER_NUM] = N'{1}' and [PLANT] = N'{2}';" , matnr.Matnr, matnr.Lifnr, plant, materialRequireDate, partQty, loginUser, partCname, partPurchaser, supplierName); } } } } #endregion } #region 更新生产订单 ///生产订单删除 if (sapProductOrderInfo.Zsc.ToUpper() == "X") { @string.AppendLine("update [LES].[TT_BAS_PULL_ORDERS] " + "set [VALID_FLAG] = 0," + "[MODIFY_USER] = N'" + loginUser + "'," + "[MODIFY_DATE] = GETDATE() " + "where [ID] = " + sapProductOrderInfo.Id + " and " + "[VALID_FLAG] = 1;"); @string.AppendLine("update [LES].[TT_BAS_PULL_ORDER_BOM] " + "set [VALID_FLAG] = 0," + "[MODIFY_USER] = N'" + loginUser + "'," + "[MODIFY_DATE] = GETDATE() " + "where [ZORDNO] = N'" + pullOrdersInfo.OrderNo + "' and " + "[VALID_FLAG] = 1;"); } else { ///更新生产订单时版本号⑨累加,同时更新生产订单内容、以及SAP生产订单处理状态⑮为20.已处理 @string.AppendFormat("update [LES].[TT_BAS_PULL_ORDERS] set " + "[WERK] = N'{1}'," + "[MODEL_YEAR] = N'{2}'," + "[VEHICLE_ORDER] = N'{3}'," + "[ORDER_DATE] = N'{4}'," + "[ASSEMBLY_LINE] = N'{5}'," + "[PART_NO] = N'{6}'," + "[VERSION] = ISNULL([VERSION],0) + 1," + "[MODIFY_USER] = N'{7}'," + "[MODIFY_DATE] = GETDATE()," + "[PLAN_EXECUTE_TIME] = N'{8}' " + "where [ID] = {0};", pullOrdersInfo.Id, plant, sapProductOrderInfo.CarColor, sapProductOrderInfo.OnlineSeq, sapProductOrderDate, assemblyLine, sapProductOrderInfo.Matnr, loginUser, sapProductOrderDate); } ///TODO:在下发给WMS时也需要提供生产订单删除的逻辑标识 WmsVmiProductOrderInfo wmsVmiProductOrderInfo = WmsVmiProductOrderBLL.CreateWmsVmiProductOrderInfo(loginUser); /// PullOrdersBLL.GetPullOrdersInfo(sapProductOrderInfo, ref pullOrdersInfo); ///WERK,接口_工厂 pullOrdersInfo.Werk = plant; ///ORDER_DATE,订单日期 pullOrdersInfo.OrderDate = BLL.LES.CommonBLL.TryParseDatetime(sapProductOrderDate); ///ASSEMBLY_LINE,工厂模型_流水线 pullOrdersInfo.AssemblyLine = assemblyLine; ///PLAN_EXECUTE_TIME,计划执行时间 pullOrdersInfo.PlanExecuteTime = BLL.LES.CommonBLL.TryParseDatetime(sapProductOrderDate); ///VERSION,版本号 pullOrdersInfo.Version = pullOrdersInfo.Version.GetValueOrDefault() + 1; /// WmsVmiProductOrderBLL.GetWmsVmiProductOrderInfo(pullOrdersInfo, ref wmsVmiProductOrderInfo); /// wmsVmiProductOrderInfo.DownLineTime = sapProductOrderInfo.OfflineDate; wmsVmiProductOrderInfo.OnlineTime = sapProductOrderInfo.OnlineDate; wmsVmiProductOrderInfo.LockFlag = sapProductOrderInfo.LockFlag; @string.AppendLine(WmsVmiProductOrderDAL.GetInsertSql(wmsVmiProductOrderInfo)); @string.AppendLine(BLL.LES.CommonBLL.GetCreateOutboundLogSql("VMI", wmsVmiProductOrderInfo.LogFid.GetValueOrDefault(), "LES-WMS-012", wmsVmiProductOrderInfo.OrderNo, loginUser)); #endregion } #endregion #region 更新SAP生产订单 @string.AppendFormat(@"update [LES].[TI_IFM_SAP_PRODUCT_ORDER] set PROCESS_FLAG = {0},PROCESS_TIME = GETDATE(),[MODIFY_USER] = N'{1}',[MODIFY_DATE] = GETDATE() where [ID] = {2};" , (int)ProcessFlagConstants.Processed, loginUser, sapProductOrderInfo.Id); #endregion #region 数据库语句执行 using (TransactionScope trans = new TransactionScope()) { if (@string.Length > 0) { BLL.LES.CommonBLL.ExecuteNonQueryBySql(@string.ToString()); } trans.Complete(); } ///这个很重要 @string.Clear(); #endregion ///订单计算用时 TimeSpan ts = new TimeSpan(); ts = DateTime.Now - startExecuteTime; Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ":End " + sapProductOrderInfo.Aufnr + "," + ts.TotalSeconds + "s"); } }