From 96b7ce570c39e7e96ccb644afcca787ea314125a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=AD=A3=40=E7=94=A8=E5=8F=8B?= Date: Fri, 13 Jun 2025 15:27:11 +0800 Subject: [PATCH] =?UTF-8?q?patch=5Fdev=5Fuapbd=5Fic=5F=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=8F=8A=E9=A1=B9=E7=9B=AE=E4=B8=93=E7=94=A8?= =?UTF-8?q?=E6=96=99=E5=80=BC=E9=80=BB=E8=BE=91=5FV1=5Fsdlizheng=5F2025061?= =?UTF-8?q?3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../private/nc/bs/ic/m45/insert/InsertBP.java | 128 ++++++ .../insert/rule/PurchaseInProjectRule.java | 77 ++++ .../private/nc/bs/ic/m45/update/UpdateBP.java | 153 +++++++ .../private/nc/bs/ic/m4d/insert/InsertBP.java | 121 ++++++ .../insert/rule/MaterialOutProjectRule.java | 77 ++++ .../private/nc/bs/ic/m4d/update/UpdateBP.java | 122 ++++++ .../nc/bs/bd/bom/bom0202/bp/BomInsertBP.java | 273 ++++++++++++ .../nc/bs/bd/bom/bom0202/bp/BomUpdateBP.java | 399 ++++++++++++++++++ .../rule/BOMBprojectmaterialEnableRule.java | 84 ++++ 9 files changed, 1434 insertions(+) create mode 100644 ic/src/private/nc/bs/ic/m45/insert/InsertBP.java create mode 100644 ic/src/private/nc/bs/ic/m45/insert/rule/PurchaseInProjectRule.java create mode 100644 ic/src/private/nc/bs/ic/m45/update/UpdateBP.java create mode 100644 ic/src/private/nc/bs/ic/m4d/insert/InsertBP.java create mode 100644 ic/src/private/nc/bs/ic/m4d/insert/rule/MaterialOutProjectRule.java create mode 100644 ic/src/private/nc/bs/ic/m4d/update/UpdateBP.java create mode 100644 uapbd/src/private/nc/bs/bd/bom/bom0202/bp/BomInsertBP.java create mode 100644 uapbd/src/private/nc/bs/bd/bom/bom0202/bp/BomUpdateBP.java create mode 100644 uapbd/src/private/nc/bs/bd/bom/bom0202/rule/BOMBprojectmaterialEnableRule.java diff --git a/ic/src/private/nc/bs/ic/m45/insert/InsertBP.java b/ic/src/private/nc/bs/ic/m45/insert/InsertBP.java new file mode 100644 index 00000000..54a9edf5 --- /dev/null +++ b/ic/src/private/nc/bs/ic/m45/insert/InsertBP.java @@ -0,0 +1,128 @@ +package nc.bs.ic.m45.insert; + +import nc.bs.ic.general.insert.IInsertBP; +import nc.bs.ic.general.insert.InsertBPTemplate; +import nc.bs.ic.general.insert.rule.before.CheckCliabilityValue; +import nc.bs.ic.general.rule.after.AtpAfterUpdate; +import nc.bs.ic.general.rule.before.CtplcustomeridCheck; +import nc.bs.ic.m45.base.BPPlugInPoint; +import nc.bs.ic.m45.base.rule.FillCostOrgRule; +import nc.bs.ic.m45.base.rule.PurchaseBillCheckRule; +import nc.bs.ic.m45.base.rule.PurchaseInAssetWarehouseCheck; +import nc.bs.ic.m45.base.rule.PurchaseInVOScaleCheckRule; +import nc.bs.ic.m45.base.rule.PurchaseinRetMarginProcess; +import nc.bs.ic.m45.base.rule.PurchaseinRetMarginProcessFor5805; +import nc.bs.ic.m45.base.rule.ReturnSnIsExistInEquipcardCheck; +import nc.bs.ic.m45.base.rule.VmiCheckRule; +import nc.bs.ic.m45.insert.rule.*; +import nc.bs.ic.pub.base.ICAroundProcesser; +import nc.bs.ic.pub.base.IInsertRuleProvider; +import nc.impl.pubapp.pattern.rule.processer.AroundProcesser; +import nc.vo.bd.payment.IPaymentUtil; +import nc.vo.ic.general.define.MetaNameConst; +import nc.vo.ic.m45.entity.PurchaseInBodyVO; +import nc.vo.ic.m45.entity.PurchaseInVO; +import nc.vo.ic.pub.util.StringUtil; +import nccloud.bs.ic.mobile.inbound.operation.rewrite.MobAfterPurchaseInSave; + +/** + * 采购入库单后台新增BP + * + * @author songhy + */ +public class InsertBP implements IInsertBP, + IInsertRuleProvider { + + @Override + public void addAfterRule(PurchaseInVO[] vos, + AroundProcesser processor) { + //红字采购入库单保存的时候,增加判断逻辑,如果表头仓库是直运仓,不检查物料的现存量 放在前面设置session + processor.addAfterRule(new IsRedBookThrough()); + + /** + * 放在现存量更新规则(OnhandAfterUpdate)之后,因为现存量更新时会调用预留接口,预留接口会回写采购订单, + * 如果入库数量=订单数量,订单会自动入库关闭,入库关闭会解除预留,导致后续操作错误 + */ + ((ICAroundProcesser) processor).addAfterRuleAt( + new InsertRewritePORule(), AtpAfterUpdate.class); + processor.addAfterRule(new InsReWritePIM()); + processor.addAfterRule(new InsertRewriteITRule()); + processor.addAfterRule(new MobAfterPurchaseInSave()); + processor.addAfterRule(new FeeDetailInsert()); + //红字采购入库单原单退回保存回写累计入库退回主数量,由于预留处理需要查询蓝字采购入库单,回写操作应放在现存量更新规则(OnhandAfterUpdate)之后 + ((ICAroundProcesser) processor).addAfterRuleAt(new InsertRedReturnInRewriteRule(), AtpAfterUpdate.class); + ((ICAroundProcesser) processor).addAfterRuleAt(new InsertRedReturnInRewriteSORule(), InsertRedReturnInRewriteRule.class); + // 回写付款计划 + processor.addAfterRule(new InsertRewritePayPlanConfirmDataRule()); + // 回写付款计划子孙开票数据 先票后入库 入库日期时点, + processor.addAfterRule(new InsertOrSignRewritePayPlanInvoiceRule(IPaymentUtil.STORE_RECEIPT_DATE)); + // 入库单保存回写采购合同付款计划 + processor.addAfterRule(new M45SaveAndRewriteCTPayPlan()); + + // processor.addAfterRule(new InsertRewritePORule()); + } + + @Override + public void addBeforeRule(PurchaseInVO[] vos, + AroundProcesser processor) { + // 检查是否可以生成入库单 + processor.addBeforeRule(new InsertCheckCanInRule()); + processor.addBeforeRule(new FillCostOrgRule()); +// processor.addBeforeRule(new SaveCheckFeeMnyRule()); + processor.addBeforeRule(new PurchaseBillCheckRule()); + processor.addBeforeRule(new PurchaseInAssetWarehouseCheck()); + // 当数量(主数量,数量,报价数量)与采购订单一致时,使采购入库单表体价格和单价与采购订单一致 + //下面的规则处理会使入库单的改价不生效 hujieh +// processor.addBeforeRule(new AdjustPriceAndMnyWhenSameNumRule()); + processor.addBeforeRule(new CtplcustomeridCheck()); + processor.addBeforeRule(new VmiCheckRule()); + processor.addBeforeRule(new ReturnSnIsExistInEquipcardCheck()); + // 红蓝字入库单倒挤,跟订单倒挤 + processor.addBeforeRule(new PurchaseinRetMarginProcess()); + processor.addBeforeRule(new PurchaseinRetMarginProcessFor5805()); + processor.addBeforeRule(new PurchaseInVOScaleCheckRule()); + processor.addBeforeRule(new InsertCheckMaterialUnit()); + // 利润中心校验规则 + processor.addBeforeRule(new CheckCliabilityValue(MetaNameConst.CLIABILITYOID,MetaNameConst.CIOLIABILITYOID)); + // 来源于进口模块--流向单,填充报价单位、报价换算率 + processor.addBeforeRule(new FillInVqtunitRule()); + + //2025年6月13日09点38分 -- 物料档案基本页签启用项目辅助属性+库存组织未启用项目,采购入库单保存时(包含接口导入)清除行项目,材料出库单保存时(包含接口导入)清除行项目 + processor.addBeforeRule(new PurchaseInProjectRule()); + } + + @Override + public PurchaseInVO[] insert(PurchaseInVO[] bills) { + // 应该在“物理自由辅助属性检查”规则执行前补充供应商 + this.fillCvendorid(bills); + InsertBPTemplate insertBP = + new InsertBPTemplate(BPPlugInPoint.InsertBP, this); + return insertBP.insert(bills); + } + + /** + * 补表体的供应商,供应商已经挪到表头,表体的供应商要跟表头供应商一样 + * + * @param vos + */ + private void fillCvendorid(PurchaseInVO[] vos) { + String cvendor = null; + String cvendorvid = null; + for (PurchaseInVO vo : vos) { + + // 取表头供应商 + cvendor = vo.getHead().getCvendorid(); + cvendorvid = vo.getHead().getCvendorvid(); + if (StringUtil.isSEmptyOrNull(cvendor)) { + continue; + } + + // 为表体供应商赋值 + for (PurchaseInBodyVO body : vo.getBodys()) { + body.setCvendorid(cvendor); + body.setCvendorvid(cvendorvid); + } + } + } + +} diff --git a/ic/src/private/nc/bs/ic/m45/insert/rule/PurchaseInProjectRule.java b/ic/src/private/nc/bs/ic/m45/insert/rule/PurchaseInProjectRule.java new file mode 100644 index 00000000..6c1eae8c --- /dev/null +++ b/ic/src/private/nc/bs/ic/m45/insert/rule/PurchaseInProjectRule.java @@ -0,0 +1,77 @@ +package nc.bs.ic.m45.insert.rule; + +import nc.bs.dao.BaseDAO; +import nc.bs.ic.pub.base.ICRule; +import nc.jdbc.framework.processor.MapListProcessor; +import nc.vo.ic.general.define.ICBillBodyVO; +import nc.vo.ic.general.define.ICBillVO; +import nc.vo.ic.m45.entity.PurchaseInVO; +import nc.vo.pub.BusinessException; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; +import nc.vo.pubapp.pattern.pub.SqlBuilder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Classname PurchaseInProjectRule + * @Description TODO + * @Version 1.0.0 + * @Date 2025/6/13 14:19 + * @Created by ame + */ +public class PurchaseInProjectRule extends ICRule { + private static BaseDAO dao=new BaseDAO(); + @Override + public void process(PurchaseInVO[] vos) { + if(vos==null || vos.length<1){ + return; + } + try { + //获取表头计划组织及表体行物料 + for (ICBillVO vo : vos) { + String pk_org = (String) vo.getParentVO().getAttributeValue("pk_org"); + ICBillBodyVO[] bodys = vo.getBodys(); + Map material_construct = new HashMap<>(); + Map material_stock = new HashMap<>(); + queryFix2ByMaterial(bodys,material_construct,material_stock,pk_org); + for(ICBillBodyVO body:bodys){ + String cmaterialvid = body.getCmaterialvid(); + if(material_construct.containsKey(cmaterialvid)&& "Y".equals(material_construct.get(cmaterialvid))&& (!material_stock.containsKey(cmaterialvid)|| "N".equals(material_stock.get(cmaterialvid)))){ + body.setCprojectid(null); + } + } + } + } catch (BusinessException var6) { + ExceptionUtils.wrappException(var6); + } + } + private void queryFix2ByMaterial(ICBillBodyVO[] childrenVOs, Map materialConstruct, Map materialStock, String pkOrg) throws BusinessException { + List materials=new ArrayList<>(); + + for (ICBillBodyVO childrenVO : childrenVOs){ + String cmaterialvid = childrenVO.getCmaterialvid(); + materials.add(cmaterialvid); + } + SqlBuilder sql =new SqlBuilder(); + sql.append(" SELECT bdm.pk_material ,bdmf.fix2,bdms.fixasst2 "); + sql.append(" FROM bd_material bdm "); + sql.append(" LEFT JOIN bd_marasstframe bdmf ON bdm.pk_marasstframe =bdmf.pk_marasstframe "); + sql.append(" LEFT JOIN bd_materialstock bdms ON bdms.PK_MATERIAL =bdm.PK_MATERIAL AND bdms.PK_ORG ='"+pkOrg+"' "); + sql.append(" where "); + sql.append("bdm.pk_material",materials.toArray(new String[0])); + List> remain = (List>) dao.executeQuery(sql.toString(), new MapListProcessor()); + if(remain==null || remain.isEmpty()){ + throw new BusinessException("物料查询辅助属性结构失败,sql【"+sql+"】"); + } + for (Map map:remain){ + String fix2=map.get("fix2")==null?"N":map.get("fix2").toString(); + String fixasst2=map.get("fixasst2")==null?"N":map.get("fixasst2").toString(); + materialConstruct.put(map.get("pk_material").toString(),fix2); + materialStock.put(map.get("pk_material").toString(),fixasst2); + } + } + +} diff --git a/ic/src/private/nc/bs/ic/m45/update/UpdateBP.java b/ic/src/private/nc/bs/ic/m45/update/UpdateBP.java new file mode 100644 index 00000000..b0fc71cd --- /dev/null +++ b/ic/src/private/nc/bs/ic/m45/update/UpdateBP.java @@ -0,0 +1,153 @@ +package nc.bs.ic.m45.update; + +import nc.bs.ic.general.rule.after.AtpAfterUpdate; +import nc.bs.ic.general.rule.before.CtplcustomeridCheck; +import nc.bs.ic.general.update.IUpdateBP; +import nc.bs.ic.general.update.UpdateBPTemplate; +import nc.bs.ic.m45.base.BPPlugInPoint; +import nc.bs.ic.m45.base.rule.FillCostOrgRule; +import nc.bs.ic.m45.base.rule.PurchaseBillCheckRule; +import nc.bs.ic.m45.base.rule.PurchaseInAssetWarehouseCheck; +import nc.bs.ic.m45.base.rule.PurchaseInVOScaleCheckRule; +import nc.bs.ic.m45.base.rule.PurchaseinRetMarginProcess; +import nc.bs.ic.m45.base.rule.PurchaseinRetMarginProcessFor5805; +import nc.bs.ic.m45.base.rule.ReturnSnIsExistInEquipcardCheck; +import nc.bs.ic.m45.base.rule.VmiCheckRule; +import nc.bs.ic.m45.insert.rule.InsertCheckMaterialUnit; +import nc.bs.ic.m45.insert.rule.M45SaveAndRewriteCTPayPlan; +import nc.bs.ic.m45.insert.rule.PurchaseInProjectRule; +import nc.bs.ic.m45.update.rule.FeeDetailUpdate; +import nc.bs.ic.m45.update.rule.IsRedBookThroughUpdate; +import nc.bs.ic.m45.update.rule.UpdReWritePIM; +import nc.bs.ic.m45.update.rule.UpdateNumCheck; +import nc.bs.ic.m45.update.rule.UpdateRedReturnInRewriteRule; +import nc.bs.ic.m45.update.rule.UpdateRewriteITRule; +import nc.bs.ic.m45.update.rule.UpdateRewritePORule; +import nc.bs.ic.m45.update.rule.UpdateRewritePayPlanConfirmDataRule; +import nc.bs.ic.m45.update.rule.UpdateRewritePayPlanConfirmInvoicenumRule; +import nc.bs.ic.pub.base.ICCompareAroundProcesser; +import nc.bs.ic.pub.base.IUpdateRuleProvider; +import nc.bs.ic.pub.util.SagasUtils; +import nc.bs.scmpub.rule.VOSagaFrozenValidateRule; +import nc.impl.pubapp.pattern.rule.processer.CompareAroundProcesser; +import nc.itf.ic.m45.compensate.IPurchaseInSagasCompensate; +import nc.vo.ic.general.define.SagasConst; +import nc.vo.ic.m45.entity.PurchaseInBodyVO; +import nc.vo.ic.m45.entity.PurchaseInVO; +import nc.vo.ic.pub.util.StringUtil; +import nc.vo.pub.VOStatus; +import nc.vo.scmpub.res.billtype.ICBillType; +import nccloud.bs.ic.mobile.inbound.operation.rewrite.MobAfterPurchaseInUpdate; +import nccloud.bs.ic.mobile.inbound.operation.rewrite.MobBeforePurchaseInUpdate; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * 采购入库单后台更新BP + * + * @author songhy + */ +public class UpdateBP implements IUpdateBP, IUpdateRuleProvider { + + @Override + public void addAfterRule(PurchaseInVO[] vos, PurchaseInVO[] originVOs, + CompareAroundProcesser processor) { + //红字采购入库修改单保存的时候,增加判断逻辑,如果表头仓库是直运仓,不检查物料的现存量 放在前面设置session + processor.addAfterRule(new IsRedBookThroughUpdate()); + + /** + * 放在现存量更新规则(OnhandAfterUpdate)之后,因为现存量更新时会调用预留接口,预留接口会回写采购订单, + * 如果入库数量=订单数量,订单会自动入库关闭,入库关闭会解除预留,导致后续操作错误 + */ + ((ICCompareAroundProcesser) processor).addAfterRuleAt(new UpdateRewritePORule(), + AtpAfterUpdate.class); + processor.addAfterRule(new UpdReWritePIM()); + processor.addAfterRule(new FeeDetailUpdate()); + // processor.addAfterRule(new UpdateRewritePORule()); + processor.addAfterRule(new UpdateRewriteITRule()); + // 2020年3月19日 补充微协同,增加采购入库单修改后消息 + processor.addAfterRule(new MobAfterPurchaseInUpdate()); + //红字采购入库单原单退回保存回写累计入库退回主数量,由于预留处理需要查询蓝字采购入库单,回写操作应放在现存量更新规则(OnhandAfterUpdate)之后 + ((ICCompareAroundProcesser) processor).addAfterRuleAt(new UpdateRedReturnInRewriteRule(), AtpAfterUpdate.class); + + // 入库单保存回写采购合同付款计划 + processor.addAfterRule(new M45SaveAndRewriteCTPayPlan()); + // 入库修改保存回写采购订单付款计划 add by yinliangc 20220219 + processor.addAfterRule(new UpdateRewritePayPlanConfirmDataRule()); + // 入库修改保存回写付款计划开票信息 + processor.addAfterRule(new UpdateRewritePayPlanConfirmInvoicenumRule()); + + } + + @Override + public void addBeforeRule(PurchaseInVO[] vos, PurchaseInVO[] originVOs, + CompareAroundProcesser processor) { + // sagas冻结校验 + processor.addBeforeRule(new VOSagaFrozenValidateRule(true)); + processor.addBeforeRule(new FillCostOrgRule()); + processor.addBeforeRule(new PurchaseBillCheckRule()); + processor.addBeforeRule(new PurchaseInAssetWarehouseCheck()); + processor.addBeforeRule(new CtplcustomeridCheck()); + processor.addBeforeRule(new VmiCheckRule()); + processor.addBeforeRule(new ReturnSnIsExistInEquipcardCheck()); + processor.addBeforeRule(new PurchaseinRetMarginProcess()); + processor.addBeforeRule(new PurchaseinRetMarginProcessFor5805()); + processor.addBeforeRule(new PurchaseInVOScaleCheckRule()); + // 利润中心校验规则 +// processor.addBeforeRule( +// new CheckCliabilityValue(MetaNameConst.CLIABILITYOID, MetaNameConst.CIOLIABILITYOID)); + processor.addBeforeRule(new InsertCheckMaterialUnit()); + processor.addBeforeRule(new MobBeforePurchaseInUpdate()); + //新加校验 出库跟踪入库场景 将采购入库单入库数量改小校验 + processor.addBeforeRule(new UpdateNumCheck()); + + //2025年6月13日09点38分 -- 物料档案基本页签启用项目辅助属性+库存组织未启用项目,采购入库单保存时(包含接口导入)清除行项目,材料出库单保存时(包含接口导入)清除行项目 + processor.addBeforeRule(new PurchaseInProjectRule()); + + } + + /** + * 父类方法重写 + * + */ + @Override + public PurchaseInVO[] update(PurchaseInVO[] vos, PurchaseInVO[] originVOs) { + SagasUtils.frozenAndAddSaga(vos, ICBillType.PurchaseIn.getCode(), SagasConst.COMPENSABLE, null); + Map paramMap = new HashMap(); + paramMap.put(SagasConst.KEY_ACTIONNAME, SagasConst.UPDATE_45); + paramMap.put(SagasConst.KEY_VOS, SagasUtils.produceLightVO(vos, originVOs)); + SagasUtils.compensate(paramMap, IPurchaseInSagasCompensate.class); + this.fillCvendorid(vos); + UpdateBPTemplate updateBP = new UpdateBPTemplate(BPPlugInPoint.UpdateBP, this); + PurchaseInVO[] retVOs = updateBP.update(vos, originVOs); + return retVOs; + } + + private void fillCvendorid(PurchaseInVO[] vos) { + String cvendor = null; + String cvendorvid = null; + for (PurchaseInVO vo : vos) { + // 取表头供应商 + cvendor = vo.getHead().getCvendorid(); + //取表头供应商vid + cvendorvid = vo.getHead().getCvendorvid(); + + // 为表体供应商赋值 + for (PurchaseInBodyVO body : vo.getBodys()) { + if (StringUtil.isStringEqual(cvendor, body.getCvendorid())) { + continue; + } + body.setCvendorid(cvendor); + body.setCvendorvid(cvendorvid); + if (VOStatus.UNCHANGED == body.getStatus()) { + // 此处必须判断状态,不能全部设为UPDATED,否则删行后,再新增行,保存会报错 + body.setStatus(VOStatus.UPDATED); + } + + } + } + } + +} diff --git a/ic/src/private/nc/bs/ic/m4d/insert/InsertBP.java b/ic/src/private/nc/bs/ic/m4d/insert/InsertBP.java new file mode 100644 index 00000000..d7c138eb --- /dev/null +++ b/ic/src/private/nc/bs/ic/m4d/insert/InsertBP.java @@ -0,0 +1,121 @@ +package nc.bs.ic.m4d.insert; + +import nc.bs.ic.general.insert.IInsertBP; +import nc.bs.ic.general.insert.rule.after.InsertAfterEventRule; +import nc.bs.ic.general.insert.rule.after.RewriteQCInsertRule; +import nc.bs.ic.general.insert.rule.before.CheckCliabilityValue; +import nc.bs.ic.general.insert.rule.before.InsertBeforeEventRule; +import nc.bs.ic.general.rule.after.AfterInsertRuleForRewriteSpecial; +import nc.bs.ic.general.rule.after.AtpAfterUpdate; +import nc.bs.ic.general.rule.before.CtplcustomeridCheck; +import nc.bs.ic.m45.insert.rule.PurchaseInProjectRule; +import nc.bs.ic.m4d.base.BPPlugInPoint; +import nc.bs.ic.m4d.base.MaterialOutCheckRule; +import nc.bs.ic.m4d.base.MaterialOutValueProcRule; +import nc.bs.ic.m4d.base.MaterialOutWarehouseAttriCheck; +import nc.bs.ic.m4d.base.PurchaseInDateCheck; +import nc.bs.ic.m4d.insert.rule.*; +import nc.bs.ic.pub.base.ICAroundProcesser; +import nc.bs.ic.pub.base.IInsertRuleProvider; +import nc.bs.scmpub.rule.CrossRuleValidateRule; +import nc.impl.pubapp.pattern.rule.processer.AroundProcesser; +import nc.vo.ic.general.define.MetaNameConst; +import nc.vo.ic.m4d.entity.MaterialOutVO; + +/** + *

+ * 材料出库单新增BP: + *

    + *
  • + *
+ *

+ *

+ * + * @version 6.0 + * @since 6.0 + * @author chennn + * @time 2010-4-19 上午09:51:08 + */ +public class InsertBP implements IInsertBP, + IInsertRuleProvider { + + @Override + public void addAfterRule(MaterialOutVO[] vos, + AroundProcesser processor) { + /* + * 放在现存量更新规则之后,因为回写销售订单,发货单时,如果出库数量等于订单数量, + * 订单自动行关闭,行关闭会执行预留解除,导致现存量更新时,处理预留业务产生错误 + */ + ((ICAroundProcesser) processor).addAfterRuleAt( + new UpdRewriteWorkOrder(), AtpAfterUpdate.class); + processor.addAfterRule(new InsReWriteSapplyBillRule());// 回写出库申请申请 + processor.addAfterRule(new InsReWriteBuyingReqRule());// 回写物资需求申请 + // 回写项目管理备料表,放在回写出库申请之前,为了解决以下问题: + // 不能计算预占量的问题,根本原因是因为出库申请的行关闭状态导致。 + // 之前出库单先回写出库申请,再回写备料备料表,回写备料表时,项目管理要查询当前出库申请的行状态是否关闭,根据该状态计算预占量。 + // 这样就不能区分此状态是因为出库单保存回写的还是出库单保存前就是关闭的 + ((ICAroundProcesser) processor).addAfterRuleAt( + new InsReWritePIM(), InsReWriteSapplyBillRule.class); + + // 回写资产的领用单 + processor.addAfterRule(new InsRewriteRM()); + + // 回写紧急放行单 + processor.addAfterRule(new RewriteQCInsertRule()); + + /* + * 放在现存量更新规则之后,因为回写销售订单,发货单时,如果出库数量等于订单数量, + * 订单自动行关闭,行关闭会执行预留解除,导致现存量更新时,处理预留业务产生错误 + */ + ((ICAroundProcesser) processor).addAfterRuleAt( + new InsRewriteMMPAC(), AtpAfterUpdate.class); + + // 回写生产报告 + processor.addAfterRule(new InsRewriteWR()); + + //回写发货单 + processor.addAfterRule(new ReWriteSOInsertRule()); + + // 工序完工报告倒冲时,回写备料计划 + processor.addAfterRule(new InsRewriteMMSFC()); + // 回写计划独立需求 + processor.addAfterRule(new InsertRewriteMMDP()); + // 回写特殊单据 + processor + .addAfterRule(new AfterInsertRuleForRewriteSpecial()); + + ((ICAroundProcesser) processor).replaceAfterRuleAt( + new InsAfterfEventRuleFor4D(), InsertAfterEventRule.class); + + } + + @Override + public void addBeforeRule(MaterialOutVO[] vos, + AroundProcesser processor) { + processor.addBeforeRule(new MaterialOutValueProcRule()); + processor.addBeforeRule(new MaterialOutCheckRule()); + // 利润中心校验规则 + processor.addBeforeRule(new CheckCliabilityValue(MetaNameConst.CIOLIABILITYOID,MetaNameConst.CLIABILITYOID)); + //processor.addBeforeRule(new CheckBiliValue());//“领料利润中心有值时,出库利润中心不能为空” + processor.addBeforeRule(new CtplcustomeridCheck());//表体“货主客户”与“寄存供应商”不能同时存在 + processor.addBeforeRule(new MaterialOutWarehouseAttriCheck()); + // 材料出库参照采购入库业务日期校验 + processor.addBeforeRule(new PurchaseInDateCheck()); + // 交叉校验规则 + processor.addBeforeRule(new CrossRuleValidateRule()); + + ((ICAroundProcesser) processor).replaceBeforeRuleAt( + new InsBeforeEventRuleFor4D(), InsertBeforeEventRule.class); + + //2025年6月13日09点38分 -- 物料档案基本页签启用项目辅助属性+库存组织未启用项目,采购入库单保存时(包含接口导入)清除行项目,材料出库单保存时(包含接口导入)清除行项目 + processor.addBeforeRule(new MaterialOutProjectRule()); + } + + @Override + public MaterialOutVO[] insert(MaterialOutVO[] bills) { + M4dInsertBPTemplate insertBP = + new M4dInsertBPTemplate(BPPlugInPoint.InsertBP, this); + return insertBP.insert(bills); + } + +} diff --git a/ic/src/private/nc/bs/ic/m4d/insert/rule/MaterialOutProjectRule.java b/ic/src/private/nc/bs/ic/m4d/insert/rule/MaterialOutProjectRule.java new file mode 100644 index 00000000..44e82b94 --- /dev/null +++ b/ic/src/private/nc/bs/ic/m4d/insert/rule/MaterialOutProjectRule.java @@ -0,0 +1,77 @@ +package nc.bs.ic.m4d.insert.rule; + +import nc.bs.dao.BaseDAO; +import nc.bs.ic.pub.base.ICRule; +import nc.jdbc.framework.processor.MapListProcessor; +import nc.vo.ic.general.define.ICBillBodyVO; +import nc.vo.ic.general.define.ICBillVO; +import nc.vo.ic.m4d.entity.MaterialOutVO; +import nc.vo.pub.BusinessException; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; +import nc.vo.pubapp.pattern.pub.SqlBuilder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Classname MaterialOutProjectRule + * @Description TODO + * @Version 1.0.0 + * @Date 2025/6/13 14:59 + * @Created by ame + */ +public class MaterialOutProjectRule extends ICRule { + private static BaseDAO dao=new BaseDAO(); + @Override + public void process(MaterialOutVO[] vos) { + if(vos==null || vos.length<1){ + return; + } + try { + //获取表头计划组织及表体行物料 + for (ICBillVO vo : vos) { + String pk_org = (String) vo.getParentVO().getAttributeValue("pk_org"); + ICBillBodyVO[] bodys = vo.getBodys(); + Map material_construct = new HashMap<>(); + Map material_stock = new HashMap<>(); + queryFix2ByMaterial(bodys,material_construct,material_stock,pk_org); + for(ICBillBodyVO body:bodys){ + String cmaterialvid = body.getCmaterialvid(); + if(material_construct.containsKey(cmaterialvid)&& "Y".equals(material_construct.get(cmaterialvid))&& (!material_stock.containsKey(cmaterialvid)|| "N".equals(material_stock.get(cmaterialvid)))){ + body.setCprojectid(null); + } + } + } + } catch (BusinessException var6) { + ExceptionUtils.wrappException(var6); + } + } + private void queryFix2ByMaterial(ICBillBodyVO[] childrenVOs, Map materialConstruct, Map materialStock, String pkOrg) throws BusinessException { + List materials=new ArrayList<>(); + + for (ICBillBodyVO childrenVO : childrenVOs){ + String cmaterialvid = childrenVO.getCmaterialvid(); + materials.add(cmaterialvid); + } + SqlBuilder sql =new SqlBuilder(); + sql.append(" SELECT bdm.pk_material ,bdmf.fix2,bdms.fixasst2 "); + sql.append(" FROM bd_material bdm "); + sql.append(" LEFT JOIN bd_marasstframe bdmf ON bdm.pk_marasstframe =bdmf.pk_marasstframe "); + sql.append(" LEFT JOIN bd_materialstock bdms ON bdms.PK_MATERIAL =bdm.PK_MATERIAL AND bdms.PK_ORG ='"+pkOrg+"' "); + sql.append(" where "); + sql.append("bdm.pk_material",materials.toArray(new String[0])); + List> remain = (List>) dao.executeQuery(sql.toString(), new MapListProcessor()); + if(remain==null || remain.isEmpty()){ + throw new BusinessException("物料查询辅助属性结构失败,sql【"+sql+"】"); + } + for (Map map:remain){ + String fix2=map.get("fix2")==null?"N":map.get("fix2").toString(); + String fixasst2=map.get("fixasst2")==null?"N":map.get("fixasst2").toString(); + materialConstruct.put(map.get("pk_material").toString(),fix2); + materialStock.put(map.get("pk_material").toString(),fixasst2); + } + } + +} diff --git a/ic/src/private/nc/bs/ic/m4d/update/UpdateBP.java b/ic/src/private/nc/bs/ic/m4d/update/UpdateBP.java new file mode 100644 index 00000000..17af2905 --- /dev/null +++ b/ic/src/private/nc/bs/ic/m4d/update/UpdateBP.java @@ -0,0 +1,122 @@ +package nc.bs.ic.m4d.update; + +import nc.bs.ic.general.insert.rule.before.CheckCliabilityValue; +import nc.bs.ic.general.rule.after.AtpAfterUpdate; +import nc.bs.ic.general.rule.before.CtplcustomeridCheck; +import nc.bs.ic.general.update.IUpdateBP; +import nc.bs.ic.general.update.rule.after.RewriteQCUpdateRule; +import nc.bs.ic.m4d.base.BPPlugInPoint; +import nc.bs.ic.m4d.base.MaterialOutCheckRule; +import nc.bs.ic.m4d.base.MaterialOutValueProcRule; +import nc.bs.ic.m4d.base.MaterialOutWarehouseAttriCheck; +import nc.bs.ic.m4d.base.PurchaseInDateCheck; +import nc.bs.ic.m4d.insert.rule.MaterialOutProjectRule; +import nc.bs.ic.m4d.update.rule.ReWriteSOUpdateRule; +import nc.bs.ic.m4d.update.rule.UpdReWritePIM; +import nc.bs.ic.m4d.update.rule.UpdateRewriteMMDP; +import nc.bs.ic.pub.base.ICCompareAroundProcesser; +import nc.bs.ic.pub.base.IUpdateRuleProvider; +import nc.bs.scmpub.rule.CrossRuleValidateRule; +import nc.bs.scmpub.rule.VOSagaFrozenValidateRule; +import nc.impl.pubapp.pattern.rule.processer.CompareAroundProcesser; +import nc.vo.ic.general.define.MetaNameConst; +import nc.vo.ic.m4d.entity.MaterialOutVO; + +/** + *

+ * 材料出库单修改BP: + *

    + *
  • + *
+ *

+ *

+ * + * @version 6.0 + * @since 6.0 + * @author chennn + * @time 2010-4-19 上午09:56:22 + */ +public class UpdateBP implements IUpdateBP, + IUpdateRuleProvider { + + @Override + public void addAfterRule(MaterialOutVO[] vos, MaterialOutVO[] originVOs, + CompareAroundProcesser processor) { + /* + * 放在现存量更新规则之后,因为回写销售订单,发货单时,如果出库数量等于订单数量, + * 订单自动行关闭,行关闭会执行预留解除,导致现存量更新时,处理预留业务产生错误 + */ + ((ICCompareAroundProcesser) processor).addAfterRuleAt( + new UpdRewriteWorkOrder(), AtpAfterUpdate.class); + // processor.addAfterRule(new UpdRewriteWorkOrder()); + + processor.addAfterRule(new UpdReWriteSapplyBillRule());// 回写出库申请单 + processor.addAfterRule(new UpdReWriteBuyingReqRule());// 回写物资需求申请 + + // 回写资产的领用单 + processor.addAfterRule(new UpdRewriteRM()); + // 回写紧急放行单 + processor.addAfterRule(new RewriteQCUpdateRule()); + + // 回写批次关联 + processor.addAfterRule(new UpdRewriteBacthJoin()); + + //回写发货单 + processor.addAfterRule(new ReWriteSOUpdateRule()); + + /* + * 放在现存量更新规则之后,因为回写销售订单,发货单时,如果出库数量等于订单数量, + * 订单自动行关闭,行关闭会执行预留解除,导致现存量更新时,处理预留业务产生错误 + */ + ((ICCompareAroundProcesser) processor).addAfterRuleAt( + new UpdRewriteMMPAC(), AtpAfterUpdate.class); + // 回写备料计划 + processor.addAfterRule(new UpdRewriteMMSFC()); + // 回写计划独立需求 + processor.addAfterRule(new UpdateRewriteMMDP()); + + // 回写项目管理备料表,放在回写出库申请之前,为了解决以下问题: + // 不能计算预占量的问题,根本原因是因为出库申请的行关闭状态导致。 + // 之前出库单先回写出库申请,再回写备料备料表,回写备料表时,项目管理要查询当前出库申请的行状态是否关闭,根据该状态计算预占量。 + // 这样就不能区分此状态是因为出库单保存回写的还是出库单保存前就是关闭的 + ((ICCompareAroundProcesser) processor).addAfterRuleAt( + new UpdReWritePIM(), UpdReWriteSapplyBillRule.class); + +// ((ICCompareAroundProcesser) processor).replaceAfterRuleAt( +// new UpdAfterEventRuleFor4D(), UpdateAfterEventRule.class); + + } + + @Override + public void addBeforeRule(MaterialOutVO[] vos, MaterialOutVO[] originVOs, + CompareAroundProcesser processor) { + + //saga状态校验,材料出库既要校验表头也要校验表体 + processor.addBeforeRule(new VOSagaFrozenValidateRule(true)); + processor.addBeforeRule(new CtplcustomeridCheck());//表体“货主客户”与“寄存供应商”不能同时存在 + processor.addBeforeRule(new MaterialOutValueProcRule()); + processor.addBeforeRule(new MaterialOutCheckRule()); + // 利润中心校验规则 + processor.addBeforeRule(new CheckCliabilityValue(MetaNameConst.CIOLIABILITYOID,MetaNameConst.CLIABILITYOID)); + processor.addBeforeRule(new MaterialOutWarehouseAttriCheck()); + + // 交叉校验规则 + processor.addBeforeRule(new CrossRuleValidateRule()); + // 材料出库参照采购入库业务日期校验 + processor.addBeforeRule(new PurchaseInDateCheck()); + +// ((ICCompareAroundProcesser) processor).replaceBeforeRuleAt( +// new UpdBeforeEventRuleFor4D(), UpdateBeforeEventRule.class); + + //2025年6月13日09点38分 -- 物料档案基本页签启用项目辅助属性+库存组织未启用项目,采购入库单保存时(包含接口导入)清除行项目,材料出库单保存时(包含接口导入)清除行项目 + processor.addBeforeRule(new MaterialOutProjectRule()); + } + + @Override + public MaterialOutVO[] update(MaterialOutVO[] vos, MaterialOutVO[] originVOs) { + M4DUpdateBPTempate updateBP = + new M4DUpdateBPTempate(BPPlugInPoint.UpdateBP, this); + return updateBP.update(vos, originVOs); + } + +} diff --git a/uapbd/src/private/nc/bs/bd/bom/bom0202/bp/BomInsertBP.java b/uapbd/src/private/nc/bs/bd/bom/bom0202/bp/BomInsertBP.java new file mode 100644 index 00000000..fea1fab1 --- /dev/null +++ b/uapbd/src/private/nc/bs/bd/bom/bom0202/bp/BomInsertBP.java @@ -0,0 +1,273 @@ +package nc.bs.bd.bom.bom0202.bp; + +import nc.bs.bd.bom.bom0202.plugin.bpplugin.BomPluginPoint; +import nc.bs.bd.bom.bom0202.rule.*; +import nc.bs.mmbd.pub.rule.MMAutoMaterialAssignRule; +import nc.bs.pubapp.pub.rule.FieldLengthCheckRule; +import nc.bs.pubapp.pub.rule.FillInsertDataRule; +import nc.bs.pubapp.pub.rule.OrgDisabledCheckRule; +import nc.impl.pubapp.bd.material.assistant.MarAssistantSaveRule; +import nc.impl.pubapp.pattern.rule.IRule; +import nc.impl.pubapp.pattern.rule.processer.AroundProcesser; +import nc.itf.org.IOrgConstBasic; +import nc.util.mmf.busi.rule.MMRowNoCheckRule; +import nc.util.mmf.framework.gc.GCInsertBPTemplate; +import nc.vo.bd.bom.bom0202.entity.AggBomVO; +import nc.vo.bd.bom.bom0202.entity.BomActivityVO; +import nc.vo.bd.bom.bom0202.entity.BomItemVO; +import nc.vo.bd.bom.bom0202.entity.BomOutputsVO; +import nc.vo.bd.bom.bom0202.entity.BomPosVO; +import nc.vo.bd.bom.bom0202.entity.BomReplVO; +import nc.vo.bd.bom.bom0202.entity.BomVO; +import nc.vo.bd.bom.bom0202.entity.BomWipVO; + +public class BomInsertBP { + /** + * 是否校验工程变更单是否启用 + */ + private boolean checkEcn = true; + + /** + * 是否支持审批流 + */ + private boolean isOnApprove; + + public boolean isOnApprove() { + return this.isOnApprove; + } + + public void setOnApprove(boolean isOnApprove) { + this.isOnApprove = isOnApprove; + } + + public AggBomVO[] insert(AggBomVO[] aggVO) { + return this.insert(aggVO, true); + } + + /** + * 跨组织复制时,原bom主键 + */ + private String[] origins = null; + + /** + * 带参数的BOM新增插入方法 + * + * @param aggVO + * @param newCheckEcn + * @return + */ + public AggBomVO[] insert(AggBomVO[] aggVO, boolean newCheckEcn) { + return this.insert(aggVO, newCheckEcn, null, false); + } + + /** + * 带参数的BOM新增插入方法 + * + * @param aggVO + * @param newCheckEcn + * @param orgins 跨组织复制原bom主键 + * @param param 无效参数,占位 + * @return + */ + public AggBomVO[] insert(AggBomVO[] aggVO, boolean newCheckEcn, String[] origins, boolean param) { + this.setCheckEcn(newCheckEcn); + if (origins != null) { + this.setOrigins(origins); + } + GCInsertBPTemplate bp = new GCInsertBPTemplate(BomPluginPoint.INSERT); + // 执行前规则 + this.addBeforeRule(bp.getAroundProcesser()); + // 执行后规则 + this.addAfterRule(bp.getAroundProcesser()); + AggBomVO[] returnvo = bp.insert(aggVO); + return returnvo; + } + + /** + * 带参的新增方法:是否支持ECN,是否支持审批流 + * + * @param aggVO + * @param isCheckEcn + * @param isOnApprove + * @return + */ + public AggBomVO[] insert(AggBomVO[] aggVO, boolean isCheckEcn, boolean isOnApprove) { + this.setCheckEcn(isCheckEcn); + this.setOnApprove(isOnApprove); + GCInsertBPTemplate bp = new GCInsertBPTemplate(BomPluginPoint.INSERT); + // 执行前规则 + this.addBeforeRule(bp.getAroundProcesser()); + // 执行后规则 + this.addAfterRule(bp.getAroundProcesser()); + AggBomVO[] returnvo = bp.insert(aggVO); + return returnvo; + } + + /** + * 新增前规则 + * + * @param processor + */ + @SuppressWarnings("unchecked") + private void addBeforeRule(AroundProcesser processer) { + // 补充默认值规则 + IRule rule = new FillInsertDataRule(); + processer.addBeforeRule(rule); + + // 组织停用校验 + rule = new OrgDisabledCheckRule(BomVO.PK_ORG, IOrgConstBasic.PRODUCEPLANTYPE); + processer.addBeforeRule(rule); + if (this.getCheckEcn()) { + // 是否启用工程变更校验 + rule = new ECNOrgEnableCheckRule(); + processer.addBeforeRule(rule); + } + + if (!this.getCheckEcn()) { + // 数据检查并设置默认值 + rule = new BomSaveDataCheckRule(); + processer.addBeforeRule(rule); + } else { + // 数据检查并设置默认值 + rule = new BomSaveDataCheckRule(this.getCheckEcn()); + processer.addBeforeRule(rule); + } + + // 行号检查 + rule = new MMRowNoCheckRule(); + processer.addBeforeRule(rule); + + // 物料信息检查 + rule = new BomMaterialCheckRule(); + processer.addBeforeRule(rule); + + // 长度检查 + rule = new FieldLengthCheckRule(); + processer.addBeforeRule(rule); + + // bom自定义项检查 + String[] prefixs = new String[] { "hvdef", "vdef", "vbdef", "vdef", "vdef", "vdef", "vdef" }; + Class[] voClasses = new Class[] { BomVO.class, BomItemVO.class, BomOutputsVO.class, BomActivityVO.class, + BomWipVO.class, BomPosVO.class, BomReplVO.class }; + rule = new nc.impl.pubapp.bd.userdef.UserDefSaveRule(prefixs, voClasses); + processer.addBeforeRule(rule); + + // 检查自由项 + rule = new MarAssistantSaveRule(); + processer.addBeforeRule(rule); + + // delete by qianzhx + // BOM在非审批通过态可以支持存在多个默认 20150425 + // BOM默认版本规则 + // rule = new BomDefaultVersionCheckRule(); + // processer.addBeforeRule(rule); + // edited by renshch 20150507 + // 定制BOM不支持审批流,最多一个默认,此规则已做调整,只对定制BOM处理 + //选配修改:这个规则仅处理定制BOM是否默认,定制BOM生成的时候已经处理过默认了,不需要再特殊校验,为了性能,先注释掉 + //rule = new BomDefaultVersionCheckRule(); + //processer.addBeforeRule(rule); + + // 默认卷积:在同一维度下只能有一个默认卷积(业务单元+物料+物料版本+bom类型) + ConvolutionRule ctRule = new ConvolutionRule(); + processer.addBeforeRule(ctRule); + + // 是否委外:在同一维度下只能有一个委外BOM(业务单元+物料+物料版本) + OutsourceRule osRule = new OutsourceRule(); + processer.addBeforeRule(osRule); + + // 子项物料启用序列号校验规则 + //此校验在BomSaveDataCheckRule里头已经校验,这里注释掉 + //rule = new SerialManageCheckRule(); + //processer.addBeforeRule(rule); + + // 定制/配置BOM材料页签的相关校验 + // 选配修改:去掉之前定制BOM关于特征码的校验,改到下面的rule里校验 + rule = new CfgBomAndCBomItemCheckRule(); + processer.addBeforeRule(rule); + + //选配修改:增加模型BOM/可选类BOM/定制BOM 设置状态和校验 + rule=new BomCheckForMatchRule(); + processer.addBeforeRule(rule); + + // 分配部分校验 + rule = new BomSaveAssignVersionCheckRule(); + processer.addBeforeRule(rule); + // 物料表头自动分配 + rule = new MMAutoMaterialAssignRule(new String[] { BomVO.HCMATERIALVID, BomVO.HCMATERIALID }, null, + null, new String[] { BomVO.PK_ORG }, null, null, BomVO.class, false); + processer.addBeforeFinalRule(rule); + // 表体材料物料自动分配 + rule = new MMAutoMaterialAssignRule(null, + new String[] { BomItemVO.CMATERIALVID, BomItemVO.CMATERIALID }, null, null, + new String[] { BomItemVO.PK_ORG }, null, BomItemVO.class, false); + processer.addBeforeFinalRule(rule); + // 表体联副产品物料自动分配 + rule = new MMAutoMaterialAssignRule(null, + new String[] { BomOutputsVO.CMATERIALVID, BomOutputsVO.CMATERIALID }, null, null, + new String[] { BomOutputsVO.PK_ORG }, null, BomOutputsVO.class, false); + processer.addBeforeFinalRule(rule); + // 孙表线上仓物料表体自动分配 +// rule = new MMAutoMaterialAssignRule(null, BomWipVO.G_CMATERIALVID, null, +// new String[] { BomWipVO.PK_ORG }); +// processer.addBeforeFinalRule(rule); +// // 孙表组装位置物料表体自动分配 +// rule = new MMAutoMaterialAssignRule(null, BomPosVO.G_CMATERIALVID, null, +// new String[] { BomPosVO.PK_ORG }); +// processer.addBeforeFinalRule(rule); +// // 孙表阶梯变动损耗物料表体自动分配 +// rule = new MMAutoMaterialAssignRule(null, BomLossVO.CLMATERIALVID, null, +// new String[] { BomLossVO.PK_ORG }); +// processer.addBeforeFinalRule(rule); + + // 孙表替代料物料表体自动分配 + rule = new MMAutoMaterialAssignRule(null, null, + new String[] { BomReplVO.CREPLMATERIALVID, BomReplVO.CREPLMATERIALOID }, null, null, + new String[] { BomReplVO.PK_ORG }, BomReplVO.class, false); + processer.addBeforeFinalRule(rule); + // 注册事件源 + rule = new BomAddBeforeEventRule(); + processer.addBeforeRule(rule); + + if (this.origins != null) { + // 替代方案-物料分配 + rule = new BomReplsMaterialAssignRule(this.origins); + processer.addBeforeRule(rule); + } + //2025年6月13日09点38分 -- BOM保存时校验各BOM子件本业务单元库存组织是否启用项目,如果启用,则项目专用料自动启用(包含接口导入) + rule =new BOMBprojectmaterialEnableRule(); + processer.addBeforeRule(rule); + } + + /** + * 新增后规则 + * + * @param processor + */ + private void addAfterRule(AroundProcesser processer) { + // BOM版本检查规则 + IRule rule = new BomVersionCheckRule(); + processer.addAfterRule(rule); + + // 注册事件源 + rule = new BomAddAfterEventRule(); + processer.addAfterRule(rule); + + } + + public void setCheckEcn(boolean checkEcn) { + this.checkEcn = checkEcn; + } + + public boolean getCheckEcn() { + return this.checkEcn; + } + + public String[] getOrigins() { + return origins; + } + + public void setOrigins(String[] origins) { + this.origins = origins; + } + +} diff --git a/uapbd/src/private/nc/bs/bd/bom/bom0202/bp/BomUpdateBP.java b/uapbd/src/private/nc/bs/bd/bom/bom0202/bp/BomUpdateBP.java new file mode 100644 index 00000000..1268ef06 --- /dev/null +++ b/uapbd/src/private/nc/bs/bd/bom/bom0202/bp/BomUpdateBP.java @@ -0,0 +1,399 @@ +package nc.bs.bd.bom.bom0202.bp; + +import nc.bs.bd.bom.bom0202.plugin.bpplugin.BomPluginPoint; +import nc.bs.bd.bom.bom0202.rule.*; +import nc.bs.mmbd.pub.rule.MMAutoMaterialAssignRule; +import nc.bs.pubapp.pub.rule.FieldLengthCheckRule; +import nc.bs.pubapp.pub.rule.FillUpdateDataRule; +import nc.bs.pubapp.pub.rule.OrgDisabledCheckRule; +import nc.impl.pubapp.bd.material.assistant.MarAssistantSaveRule; +import nc.impl.pubapp.pattern.rule.ICompareRule; +import nc.impl.pubapp.pattern.rule.IRule; +import nc.impl.pubapp.pattern.rule.processer.CompareAroundProcesser; +import nc.itf.org.IOrgConstBasic; +import nc.mmbd.utils.factoryparam.MMBDFactoryParameter; +import nc.util.mmf.busi.rule.MMRowNoCheckRule; +import nc.util.mmf.framework.gc.GCUpdateBPTemplate; +import nc.vo.bd.bom.bom0202.entity.AggBomVO; +import nc.vo.bd.bom.bom0202.entity.BomActivityVO; +import nc.vo.bd.bom.bom0202.entity.BomItemVO; +import nc.vo.bd.bom.bom0202.entity.BomOutputsVO; +import nc.vo.bd.bom.bom0202.entity.BomPosVO; +import nc.vo.bd.bom.bom0202.entity.BomReplVO; +import nc.vo.bd.bom.bom0202.entity.BomVO; +import nc.vo.bd.bom.bom0202.entity.BomWipVO; +import nc.vo.pub.VOStatus; + +import java.util.Map; + +/** + * BOM更新BP + * + * @author baijl + */ +public class BomUpdateBP { + /** + * 是否校验工程变更单是否启用 + */ + private boolean checkEcn = true; + + public boolean getCheckEcn() { + return this.checkEcn; + } + + public void setCheckEcn(boolean checkEcn) { + this.checkEcn = checkEcn; + } + + /** + * 是否支持审批流 + */ + private boolean onApprove; + + public boolean getOnApprove() { + return this.onApprove; + } + + public void setOnApprove(boolean onApprove) { + this.onApprove = onApprove; + } + + /** + * 是否是bom或bom树修改保存,区分反向bom维护、bom子项批量修改等节点 + */ + private boolean isFromBomAndBomTree = false; + + private boolean isEcnOrgChanged = false; + + private boolean isAssign = false; + + private boolean isCancleAssign = false; + + /** + * 跨组织复制时,原bom主键 + */ + private String[] origins = null; + + private Map rownoMap = null; + + public Map getRownoMap() { + return rownoMap; + } + + public void setRownoMap(Map rownoMap) { + this.rownoMap = rownoMap; + } + public AggBomVO[] update(AggBomVO[] fullBills, AggBomVO[] originBills) { + return this.update(fullBills, originBills, true, false, false); + } + + public AggBomVO[] update(AggBomVO[] fullBills, AggBomVO[] originBills, boolean newCheckEcn) { + return this.update(fullBills, originBills, newCheckEcn, false, false); + } + + public AggBomVO[] update(AggBomVO[] fullBills, AggBomVO[] originBills, boolean newCheckEcn, boolean isFromBom, + boolean isEcnOrg) { + return this.update(fullBills, originBills, newCheckEcn, isFromBom, isEcnOrg, null, false); + } + + public AggBomVO[] update(AggBomVO[] fullBills, AggBomVO[] originBills, boolean newCheckEcn, boolean isFromBom, + boolean isEcnOrg, String[] origins, Boolean param) { + this.setCheckEcn(newCheckEcn); + this.setFromBomAndBomTree(isFromBom); + this.setEcnOrgChanged(this.getIsOrgChanged(fullBills[0], isEcnOrg)); + if (origins != null) { + this.setOrigins(origins); + } + // 调用修改模板 + GCUpdateBPTemplate bp = new GCUpdateBPTemplate(BomPluginPoint.UPDATE); + for (AggBomVO vo : fullBills) { + if (vo.getParent().getStatus() != VOStatus.UPDATED && !this.isAssign) { + vo.getParent().setStatus(VOStatus.UPDATED); + } + } + // 执行前规则 + this.addBeforeRule(bp.getAroundProcesser()); + // 执行后规则 + this.addAfterRule(bp.getAroundProcesser()); + return bp.update(fullBills, originBills); + } + + /** + * 带参的更新方法(是否支持ECN;是否支持审批流) + * + * @param fullBills + * @param originBills + * @param newCheckEcn + * @param onApprove + * @param isFromBom + * @param isEcnOrg + * @return + */ + public AggBomVO[] update(AggBomVO[] fullBills, AggBomVO[] originBills, boolean newCheckEcn, boolean onapprove, + boolean isFromBom, boolean isEcnOrg) { + this.setCheckEcn(newCheckEcn); + this.setOnApprove(onapprove); + this.setFromBomAndBomTree(isFromBom); + this.setEcnOrgChanged(this.getIsOrgChanged(fullBills[0], isEcnOrg)); + // 调用修改模板 + GCUpdateBPTemplate bp = new GCUpdateBPTemplate(BomPluginPoint.UPDATE); + for (AggBomVO vo : fullBills) { + if (vo.getParent().getStatus() != VOStatus.UPDATED && !this.isAssign) { + vo.getParent().setStatus(VOStatus.UPDATED); + } + } + // 执行前规则 + this.addBeforeRule(bp.getAroundProcesser()); + // 执行后规则 + if (!this.isAssign && !this.isCancleAssign) { + this.addAfterRule(bp.getAroundProcesser()); + } + return bp.update(fullBills, originBills); + } + + /** + * 更新前规则 + * + * @param processer + */ + @SuppressWarnings("unchecked") + private void addBeforeRule(CompareAroundProcesser processer) { + IRule rule = null; + if (this.isAssign || this.isCancleAssign) { + // 分配校验 + if (this.isAssign) { + rule = new BomAssignCheckRule(); + processer.addBeforeRule(rule); + + // 分配组织vid + rule = new BomAssgnUseorgRule(); + processer.addBeforeRule(rule); + } + if (this.isCancleAssign) { + // 分配部分校验 + rule = new BomCancelAssignCheckRule(); + processer.addBeforeRule(rule); + } + } else { + + // 组织停用校验 + rule = new OrgDisabledCheckRule(BomVO.PK_ORG, IOrgConstBasic.PRODUCEPLANTYPE); + processer.addBeforeRule(rule); + + if (this.getIsFromBomAndBomTree()) { + // 判断组织启用工程变更的状态前后是否一致,不一致不能修改 + if (this.getIsEcnOrgChanged()) { + rule = new ECNOrgChangedRule(); + processer.addBeforeRule(rule); + } + } else { + if (this.getCheckEcn()) { + // 如果启用工程的话,不能修改保存bom(适用于批改、反向bom维护、bom子项批量替换场景) + rule = new ECNCheckForModifyBomRule(); + processer.addBeforeRule(rule); + } + } + + if (this.getCheckEcn()) { + // 数据检查 + BomSaveDataCheckRule saveDataCheckRule = new BomSaveDataCheckRule(); + saveDataCheckRule.setRownoMap(this.getRownoMap()); + processer.addBeforeRule(saveDataCheckRule); + } else { + // 数据检查 + BomSaveDataCheckRule saveDataCheckRule = new BomSaveDataCheckRule(!this.getCheckEcn()); + saveDataCheckRule.setRownoMap(this.getRownoMap()); + processer.addBeforeRule(saveDataCheckRule); + } + // 行号检查 + rule = new MMRowNoCheckRule(); + processer.addBeforeRule(rule); + + // 物料信息检查 + rule = new BomMaterialCheckRule(); + processer.addBeforeRule(rule); + + // 保存时分配信息校验 + rule = new BomSaveAssignVersionCheckRule(); + processer.addBeforeRule(rule); + + // 长度检查 + rule = new FieldLengthCheckRule(); + processer.addBeforeRule(rule); + + // if (this.getOnApprove()) { + // // 设置审计信息 + // rule = new FillUpdateDataRule(); + // processer.addBeforeRule(rule); + // } 注掉 因为定制BOM修改保存时最后修改人修改时间信息会写不进去 + // 设置审计信息 + rule = new FillUpdateDataRule(); + processer.addBeforeRule(rule); + + // 检查自由项 + rule = new MarAssistantSaveRule(); + processer.addBeforeRule(rule); + + // 检查自定义项 + String[] prefixs = new String[] { "hvdef", "vdef", "vbdef", "vdef", "vdef", "vdef", "vdef" }; + Class[] voClasses = new Class[] { BomVO.class, BomItemVO.class, BomOutputsVO.class, + BomActivityVO.class, BomWipVO.class, BomPosVO.class, BomReplVO.class }; + rule = new nc.impl.pubapp.bd.userdef.UserDefSaveRule(prefixs, voClasses); + processer.addBeforeRule(rule); + + // delete by qianzhx + // BOM在非审批通过态可以支持存在多个默认 20150425 + // BOM默认版本规则 + // rule = new BomDefaultVersionCheckRule(); + // processer.addBeforeRule(rule); + // edited by renshch 20150507 + // 定制BOM不支持审批流,最多一个默认,此规则已做调整,只对定制BOM处理 + rule = new BomDefaultVersionCheckRule(); + processer.addBeforeRule(rule); + + //选配修改:增加模型BOM/可选类BOM/定制BOM 校验 + rule=new BomCheckForMatchRule(); + processer.addBeforeRule(rule); + + // 默认卷积:在同一维度下只能有一个默认卷积(业务单元+物料+物料版本+bom类型) + ConvolutionRule ctRule = new ConvolutionRule(); + processer.addBeforeRule(ctRule); + + // 是否委外:在同一维度下只能有一个委外BOM(业务单元+物料+物料版本) + OutsourceRule osRule = new OutsourceRule(); + processer.addBeforeRule(osRule); + + // 子项物料启用序列号校验规则 + rule = new SerialManageCheckRule(); + processer.addBeforeRule(rule); + + // 配置BOM 材料页签的相关校验 + // 选配修改:去掉之前定制BOM关于特征码的校验,改到下面的rule里校验 + rule = new CfgBomAndCBomItemCheckRule(); + processer.addBeforeRule(rule); + + // 注册事件源 + rule = new BomUpdateBeforeEventRule(); + processer.addBeforeRule(rule); + + // 被替代方案引用的子项不能修改 + ICompareRule compareRule = new UpdateHasReplsCheckRule(); + processer.addBeforeRule(compareRule); + + } + // 物料表头自动分配 + rule = new MMAutoMaterialAssignRule(new String[] { BomVO.HCMATERIALVID, BomVO.HCMATERIALID }, null, + null, new String[] { BomVO.PK_ORG }, null, null, BomVO.class, this.isAssign); + processer.addBeforeFinalRule(rule); + // 表体材料物料自动分配 + rule = new MMAutoMaterialAssignRule(null, + new String[] { BomItemVO.CMATERIALVID, BomItemVO.CMATERIALID }, null, null, + new String[] { BomItemVO.PK_ORG }, null, BomItemVO.class, this.isAssign); + processer.addBeforeFinalRule(rule); + // 表体联副产品物料自动分配 + rule = new MMAutoMaterialAssignRule(null, + new String[] { BomOutputsVO.CMATERIALVID, BomOutputsVO.CMATERIALID }, null, null, + new String[] { BomOutputsVO.PK_ORG }, null, BomOutputsVO.class, this.isAssign); + processer.addBeforeFinalRule(rule); + // 孙表线上仓物料表体自动分配 +// rule = new MMAutoMaterialAssignRule(null, BomWipVO.G_CMATERIALVID, null, +// new String[] { BomWipVO.PK_ORG }); +// processer.addBeforeFinalRule(rule); +// // 孙表组装位置物料表体自动分配 +// rule = new MMAutoMaterialAssignRule(null, BomPosVO.G_CMATERIALVID, null, +// new String[] { BomPosVO.PK_ORG }); +// processer.addBeforeFinalRule(rule); +// // 孙表阶梯变动损耗物料表体自动分配 +// rule = new MMAutoMaterialAssignRule(null, BomLossVO.CLMATERIALVID, null, +// new String[] { BomLossVO.PK_ORG }); +// processer.addBeforeFinalRule(rule); + + // 孙表替代料物料表体自动分配 + rule = new MMAutoMaterialAssignRule(null, null, + new String[] { BomReplVO.CREPLMATERIALVID, BomReplVO.CREPLMATERIALOID }, null, null, + new String[] { BomReplVO.PK_ORG }, BomReplVO.class, this.isAssign); + processer.addBeforeFinalRule(rule); + + if (this.origins != null) { + // 替代方案-物料分配 + rule = new BomReplsMaterialAssignRule(this.origins); + processer.addBeforeRule(rule); + } + + //2025年6月13日09点38分 -- BOM保存时校验各BOM子件本业务单元库存组织是否启用项目,如果启用,则项目专用料自动启用(包含接口导入) + rule =new BOMBprojectmaterialEnableRule(); + processer.addBeforeRule(rule); + } + + /** + * 更新后规则 + * + * @param processer + */ + + private void addAfterRule(CompareAroundProcesser processer) { + // BOM版本检查规则 + IRule rule = new BomVersionCheckRule(); + processer.addAfterRule(rule); + + // 同步BOM匹配规则中的BOM版本 add by lijbe + ICompareRule updateBmrtRule = new BomUpdateBmrtVersionRule(); + processer.addBeforeRule(updateBmrtRule); + + // 注册事件源 + IRule eventRrule = new BomUpdateAfterEventRule(); + processer.addAfterRule(eventRrule); + + } + + public boolean getIsFromBomAndBomTree() { + return this.isFromBomAndBomTree; + } + + public void setFromBomAndBomTree(boolean isFromBomAndBomTree) { + this.isFromBomAndBomTree = isFromBomAndBomTree; + } + + public boolean getIsEcnOrgChanged() { + return false; + } + + public void setEcnOrgChanged(boolean isEcnOrgChanged) { + this.isEcnOrgChanged = isEcnOrgChanged; + } + + public boolean getIsOrgChanged(AggBomVO aggvo, boolean isEcn_old) { + BomVO bomvo = (BomVO) aggvo.getParentVO(); + boolean isEcn_new = MMBDFactoryParameter.isAlterCtrl(bomvo.getPk_org()); + if (isEcn_new != isEcn_old) { + // 前后不一致则赋值 + return true; + } + return false; + } + + public boolean isAssign() { + return this.isAssign; + } + + public void setAssign(boolean isAssign) { + this.isAssign = isAssign; + } + + public boolean isCancleAssign() { + return this.isCancleAssign; + } + + public void setCancleAssign(boolean isCancleAssign) { + this.isCancleAssign = isCancleAssign; + } + + public String[] getOrigins() { + return origins; + } + + public void setOrigins(String[] origins) { + this.origins = origins; + } + +} diff --git a/uapbd/src/private/nc/bs/bd/bom/bom0202/rule/BOMBprojectmaterialEnableRule.java b/uapbd/src/private/nc/bs/bd/bom/bom0202/rule/BOMBprojectmaterialEnableRule.java new file mode 100644 index 00000000..2c7cf25f --- /dev/null +++ b/uapbd/src/private/nc/bs/bd/bom/bom0202/rule/BOMBprojectmaterialEnableRule.java @@ -0,0 +1,84 @@ +package nc.bs.bd.bom.bom0202.rule; + +import nc.bs.dao.BaseDAO; +import nc.bs.dao.DAOException; +import nc.impl.pubapp.pattern.rule.IRule; +import nc.jdbc.framework.processor.ColumnProcessor; +import nc.jdbc.framework.processor.MapListProcessor; +import nc.util.mmf.framework.base.MMValueCheck; +import nc.vo.bd.bom.bom0202.entity.AggBomVO; +import nc.vo.bd.bom.bom0202.entity.BomItemVO; +import nc.vo.org.OrgVO; +import nc.vo.pub.BusinessException; +import nc.vo.pub.lang.UFBoolean; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; +import nc.vo.pubapp.pattern.pub.SqlBuilder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Classname BOMBprojectmaterialEnableRule + * @Description TODO + * @Version 1.0.0 + * @Date 2025/6/13 9:43 + * @Created by ame + */ +public class BOMBprojectmaterialEnableRule implements IRule { + private static BaseDAO dao = new BaseDAO(); + + @Override + public void process(AggBomVO[] vos) { + if (!MMValueCheck.isEmpty(vos)) { + try { + //获取表头计划组织及表体行物料 + for (AggBomVO vo : vos) { + String pk_org = (String) vo.getParentVO().getAttributeValue("pk_org"); + BomItemVO[] childrenVOs = vo.getChildrenVO(); + Map material_construct = new HashMap<>(); + Map material_stock = new HashMap<>(); + queryFix2ByMaterial(childrenVOs,material_construct,material_stock,pk_org); + for(BomItemVO bomItemVO:childrenVOs){ + String cmaterialvid = bomItemVO.getCmaterialvid(); + if(material_construct.containsKey(cmaterialvid)&& "Y".equals(material_construct.get(cmaterialvid))&& material_stock.containsKey(cmaterialvid)&& "Y".equals(material_stock.get(cmaterialvid))){ + bomItemVO.setBprojectmaterial(UFBoolean.TRUE); + } + } + } + } catch (BusinessException var6) { + ExceptionUtils.wrappException(var6); + } + } + } + + + + private void queryFix2ByMaterial(BomItemVO[] childrenVOs, Map materialConstruct, Map materialStock, String pkOrg) throws BusinessException { + List materials=new ArrayList<>(); + + for (BomItemVO childrenVO : childrenVOs){ + String cmaterialvid = childrenVO.getCmaterialvid(); + materials.add(cmaterialvid); + } + SqlBuilder sql =new SqlBuilder(); + sql.append(" SELECT bdm.pk_material ,bdmf.fix2,bdms.fixasst2 "); + sql.append(" FROM bd_material bdm "); + sql.append(" LEFT JOIN bd_marasstframe bdmf ON bdm.pk_marasstframe =bdmf.pk_marasstframe "); + sql.append(" LEFT JOIN bd_materialstock bdms ON bdms.PK_MATERIAL =bdm.PK_MATERIAL AND bdms.PK_ORG ='"+pkOrg+"' "); + sql.append(" where "); + sql.append("bdm.pk_material",materials.toArray(new String[0])); + List> remain = (List>) dao.executeQuery(sql.toString(), new MapListProcessor()); + if(remain==null || remain.isEmpty()){ + throw new BusinessException("物料查询辅助属性结构失败,sql【"+sql+"】"); + } + for (Map map:remain){ + String fix2=map.get("fix2")==null?"N":map.get("fix2").toString(); + String fixasst2=map.get("fixasst2")==null?"N":map.get("fixasst2").toString(); + materialConstruct.put(map.get("pk_material").toString(),fix2); + materialStock.put(map.get("pk_material").toString(),fixasst2); + } + } + +}