patch_dev_uapbd_ic_添加项目及项目专用料值逻辑_V1_sdlizheng_20250613

This commit is contained in:
李正@用友 2025-06-13 15:27:11 +08:00
parent 39b17b94cf
commit 96b7ce570c
9 changed files with 1434 additions and 0 deletions

View File

@ -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<PurchaseInVO>,
IInsertRuleProvider<PurchaseInVO> {
@Override
public void addAfterRule(PurchaseInVO[] vos,
AroundProcesser<PurchaseInVO> processor) {
//红字采购入库单保存的时候增加判断逻辑如果表头仓库是直运仓不检查物料的现存量 放在前面设置session
processor.addAfterRule(new IsRedBookThrough());
/**
* 放在现存量更新规则OnhandAfterUpdate之后因为现存量更新时会调用预留接口预留接口会回写采购订单
* 如果入库数量=订单数量订单会自动入库关闭入库关闭会解除预留导致后续操作错误
*/
((ICAroundProcesser<PurchaseInVO>) processor).addAfterRuleAt(
new InsertRewritePORule(), AtpAfterUpdate.class);
processor.addAfterRule(new InsReWritePIM());
processor.addAfterRule(new InsertRewriteITRule());
processor.addAfterRule(new MobAfterPurchaseInSave());
processor.addAfterRule(new FeeDetailInsert());
//红字采购入库单原单退回保存回写累计入库退回主数量由于预留处理需要查询蓝字采购入库单回写操作应放在现存量更新规则OnhandAfterUpdate之后
((ICAroundProcesser<PurchaseInVO>) processor).addAfterRuleAt(new InsertRedReturnInRewriteRule(), AtpAfterUpdate.class);
((ICAroundProcesser<PurchaseInVO>) 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<PurchaseInVO> 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<PurchaseInVO>());
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<PurchaseInVO>(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<PurchaseInVO> insertBP =
new InsertBPTemplate<PurchaseInVO>(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);
}
}
}
}

View File

@ -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<PurchaseInVO> {
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<String,String> material_construct = new HashMap<>();
Map<String,String> 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<String, String> materialConstruct, Map<String, String> materialStock, String pkOrg) throws BusinessException {
List<String> 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<Map<String,Object>> remain = (List<Map<String, Object>>) dao.executeQuery(sql.toString(), new MapListProcessor());
if(remain==null || remain.isEmpty()){
throw new BusinessException("物料查询辅助属性结构失败,sql【"+sql+"");
}
for (Map<String,Object> 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);
}
}
}

View File

@ -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<PurchaseInVO>, IUpdateRuleProvider<PurchaseInVO> {
@Override
public void addAfterRule(PurchaseInVO[] vos, PurchaseInVO[] originVOs,
CompareAroundProcesser<PurchaseInVO> processor) {
//红字采购入库修改单保存的时候增加判断逻辑如果表头仓库是直运仓不检查物料的现存量 放在前面设置session
processor.addAfterRule(new IsRedBookThroughUpdate());
/**
* 放在现存量更新规则OnhandAfterUpdate之后因为现存量更新时会调用预留接口预留接口会回写采购订单
* 如果入库数量=订单数量订单会自动入库关闭入库关闭会解除预留导致后续操作错误
*/
((ICCompareAroundProcesser<PurchaseInVO>) 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<PurchaseInVO>) 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<PurchaseInVO> processor) {
// sagas冻结校验
processor.addBeforeRule(new VOSagaFrozenValidateRule<PurchaseInVO>(true));
processor.addBeforeRule(new FillCostOrgRule());
processor.addBeforeRule(new PurchaseBillCheckRule());
processor.addBeforeRule(new PurchaseInAssetWarehouseCheck());
processor.addBeforeRule(new CtplcustomeridCheck<PurchaseInVO>());
processor.addBeforeRule(new VmiCheckRule());
processor.addBeforeRule(new ReturnSnIsExistInEquipcardCheck());
processor.addBeforeRule(new PurchaseinRetMarginProcess());
processor.addBeforeRule(new PurchaseinRetMarginProcessFor5805());
processor.addBeforeRule(new PurchaseInVOScaleCheckRule());
// 利润中心校验规则
// processor.addBeforeRule(
// new CheckCliabilityValue<PurchaseInVO>(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<String, Serializable> paramMap = new HashMap<String, Serializable>();
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<PurchaseInVO> updateBP = new UpdateBPTemplate<PurchaseInVO>(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);
}
}
}
}
}

View File

@ -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;
/**
* <p>
* <b>材料出库单新增BP</b>
* <ul>
* <li>
* </ul>
* <p>
* <p>
*
* @version 6.0
* @since 6.0
* @author chennn
* @time 2010-4-19 上午09:51:08
*/
public class InsertBP implements IInsertBP<MaterialOutVO>,
IInsertRuleProvider<MaterialOutVO> {
@Override
public void addAfterRule(MaterialOutVO[] vos,
AroundProcesser<MaterialOutVO> processor) {
/*
* 放在现存量更新规则之后因为回写销售订单发货单时如果出库数量等于订单数量
* 订单自动行关闭行关闭会执行预留解除导致现存量更新时处理预留业务产生错误
*/
((ICAroundProcesser<MaterialOutVO>) processor).addAfterRuleAt(
new UpdRewriteWorkOrder(), AtpAfterUpdate.class);
processor.addAfterRule(new InsReWriteSapplyBillRule());// 回写出库申请申请
processor.addAfterRule(new InsReWriteBuyingReqRule());// 回写物资需求申请
// 回写项目管理备料表放在回写出库申请之前为了解决以下问题
// 不能计算预占量的问题根本原因是因为出库申请的行关闭状态导致
// 之前出库单先回写出库申请再回写备料备料表回写备料表时项目管理要查询当前出库申请的行状态是否关闭根据该状态计算预占量
// 这样就不能区分此状态是因为出库单保存回写的还是出库单保存前就是关闭的
((ICAroundProcesser<MaterialOutVO>) processor).addAfterRuleAt(
new InsReWritePIM(), InsReWriteSapplyBillRule.class);
// 回写资产的领用单
processor.addAfterRule(new InsRewriteRM());
// 回写紧急放行单
processor.addAfterRule(new RewriteQCInsertRule<MaterialOutVO>());
/*
* 放在现存量更新规则之后因为回写销售订单发货单时如果出库数量等于订单数量
* 订单自动行关闭行关闭会执行预留解除导致现存量更新时处理预留业务产生错误
*/
((ICAroundProcesser<MaterialOutVO>) 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<MaterialOutVO>());
((ICAroundProcesser<MaterialOutVO>) processor).replaceAfterRuleAt(
new InsAfterfEventRuleFor4D(), InsertAfterEventRule.class);
}
@Override
public void addBeforeRule(MaterialOutVO[] vos,
AroundProcesser<MaterialOutVO> processor) {
processor.addBeforeRule(new MaterialOutValueProcRule());
processor.addBeforeRule(new MaterialOutCheckRule());
// 利润中心校验规则
processor.addBeforeRule(new CheckCliabilityValue<MaterialOutVO>(MetaNameConst.CIOLIABILITYOID,MetaNameConst.CLIABILITYOID));
//processor.addBeforeRule(new CheckBiliValue<MaterialOutVO>());//领料利润中心有值时出库利润中心不能为空
processor.addBeforeRule(new CtplcustomeridCheck<MaterialOutVO>());//表体货主客户寄存供应商不能同时存在
processor.addBeforeRule(new MaterialOutWarehouseAttriCheck());
// 材料出库参照采购入库业务日期校验
processor.addBeforeRule(new PurchaseInDateCheck());
// 交叉校验规则
processor.addBeforeRule(new CrossRuleValidateRule<MaterialOutVO>());
((ICAroundProcesser<MaterialOutVO>) processor).replaceBeforeRuleAt(
new InsBeforeEventRuleFor4D(), InsertBeforeEventRule.class);
//2025年6月13日09点38分 -- 物料档案基本页签启用项目辅助属性+库存组织未启用项目采购入库单保存时包含接口导入清除行项目材料出库单保存时包含接口导入清除行项目
processor.addBeforeRule(new MaterialOutProjectRule());
}
@Override
public MaterialOutVO[] insert(MaterialOutVO[] bills) {
M4dInsertBPTemplate<MaterialOutVO> insertBP =
new M4dInsertBPTemplate<MaterialOutVO>(BPPlugInPoint.InsertBP, this);
return insertBP.insert(bills);
}
}

View File

@ -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<MaterialOutVO> {
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<String,String> material_construct = new HashMap<>();
Map<String,String> 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<String, String> materialConstruct, Map<String, String> materialStock, String pkOrg) throws BusinessException {
List<String> 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<Map<String,Object>> remain = (List<Map<String, Object>>) dao.executeQuery(sql.toString(), new MapListProcessor());
if(remain==null || remain.isEmpty()){
throw new BusinessException("物料查询辅助属性结构失败,sql【"+sql+"");
}
for (Map<String,Object> 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);
}
}
}

View File

@ -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;
/**
* <p>
* <b>材料出库单修改BP</b>
* <ul>
* <li>
* </ul>
* <p>
* <p>
*
* @version 6.0
* @since 6.0
* @author chennn
* @time 2010-4-19 上午09:56:22
*/
public class UpdateBP implements IUpdateBP<MaterialOutVO>,
IUpdateRuleProvider<MaterialOutVO> {
@Override
public void addAfterRule(MaterialOutVO[] vos, MaterialOutVO[] originVOs,
CompareAroundProcesser<MaterialOutVO> processor) {
/*
* 放在现存量更新规则之后因为回写销售订单发货单时如果出库数量等于订单数量
* 订单自动行关闭行关闭会执行预留解除导致现存量更新时处理预留业务产生错误
*/
((ICCompareAroundProcesser<MaterialOutVO>) 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<MaterialOutVO>());
// 回写批次关联
processor.addAfterRule(new UpdRewriteBacthJoin());
//回写发货单
processor.addAfterRule(new ReWriteSOUpdateRule());
/*
* 放在现存量更新规则之后因为回写销售订单发货单时如果出库数量等于订单数量
* 订单自动行关闭行关闭会执行预留解除导致现存量更新时处理预留业务产生错误
*/
((ICCompareAroundProcesser<MaterialOutVO>) processor).addAfterRuleAt(
new UpdRewriteMMPAC(), AtpAfterUpdate.class);
// 回写备料计划
processor.addAfterRule(new UpdRewriteMMSFC());
// 回写计划独立需求
processor.addAfterRule(new UpdateRewriteMMDP());
// 回写项目管理备料表放在回写出库申请之前为了解决以下问题
// 不能计算预占量的问题根本原因是因为出库申请的行关闭状态导致
// 之前出库单先回写出库申请再回写备料备料表回写备料表时项目管理要查询当前出库申请的行状态是否关闭根据该状态计算预占量
// 这样就不能区分此状态是因为出库单保存回写的还是出库单保存前就是关闭的
((ICCompareAroundProcesser<MaterialOutVO>) processor).addAfterRuleAt(
new UpdReWritePIM(), UpdReWriteSapplyBillRule.class);
// ((ICCompareAroundProcesser<MaterialOutVO>) processor).replaceAfterRuleAt(
// new UpdAfterEventRuleFor4D(), UpdateAfterEventRule.class);
}
@Override
public void addBeforeRule(MaterialOutVO[] vos, MaterialOutVO[] originVOs,
CompareAroundProcesser<MaterialOutVO> processor) {
//saga状态校验材料出库既要校验表头也要校验表体
processor.addBeforeRule(new VOSagaFrozenValidateRule<MaterialOutVO>(true));
processor.addBeforeRule(new CtplcustomeridCheck<MaterialOutVO>());//表体货主客户寄存供应商不能同时存在
processor.addBeforeRule(new MaterialOutValueProcRule());
processor.addBeforeRule(new MaterialOutCheckRule());
// 利润中心校验规则
processor.addBeforeRule(new CheckCliabilityValue<MaterialOutVO>(MetaNameConst.CIOLIABILITYOID,MetaNameConst.CLIABILITYOID));
processor.addBeforeRule(new MaterialOutWarehouseAttriCheck());
// 交叉校验规则
processor.addBeforeRule(new CrossRuleValidateRule<MaterialOutVO>());
// 材料出库参照采购入库业务日期校验
processor.addBeforeRule(new PurchaseInDateCheck());
// ((ICCompareAroundProcesser<MaterialOutVO>) processor).replaceBeforeRuleAt(
// new UpdBeforeEventRuleFor4D(), UpdateBeforeEventRule.class);
//2025年6月13日09点38分 -- 物料档案基本页签启用项目辅助属性+库存组织未启用项目采购入库单保存时包含接口导入清除行项目材料出库单保存时包含接口导入清除行项目
processor.addBeforeRule(new MaterialOutProjectRule());
}
@Override
public MaterialOutVO[] update(MaterialOutVO[] vos, MaterialOutVO[] originVOs) {
M4DUpdateBPTempate<MaterialOutVO> updateBP =
new M4DUpdateBPTempate<MaterialOutVO>(BPPlugInPoint.UpdateBP, this);
return updateBP.update(vos, originVOs);
}
}

View File

@ -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<AggBomVO> bp = new GCInsertBPTemplate<AggBomVO>(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<AggBomVO> bp = new GCInsertBPTemplate<AggBomVO>(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<AggBomVO> processer) {
// 补充默认值规则
IRule<AggBomVO> 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<AggBomVO>();
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<AggBomVO>(prefixs, voClasses);
processer.addBeforeRule(rule);
// 检查自由项
rule = new MarAssistantSaveRule<AggBomVO>();
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<AggBomVO>(new String[] { BomVO.HCMATERIALVID, BomVO.HCMATERIALID }, null,
null, new String[] { BomVO.PK_ORG }, null, null, BomVO.class, false);
processer.addBeforeFinalRule(rule);
// 表体材料物料自动分配
rule = new MMAutoMaterialAssignRule<AggBomVO>(null,
new String[] { BomItemVO.CMATERIALVID, BomItemVO.CMATERIALID }, null, null,
new String[] { BomItemVO.PK_ORG }, null, BomItemVO.class, false);
processer.addBeforeFinalRule(rule);
// 表体联副产品物料自动分配
rule = new MMAutoMaterialAssignRule<AggBomVO>(null,
new String[] { BomOutputsVO.CMATERIALVID, BomOutputsVO.CMATERIALID }, null, null,
new String[] { BomOutputsVO.PK_ORG }, null, BomOutputsVO.class, false);
processer.addBeforeFinalRule(rule);
// 孙表线上仓物料表体自动分配
// rule = new MMAutoMaterialAssignRule<AggBomVO>(null, BomWipVO.G_CMATERIALVID, null,
// new String[] { BomWipVO.PK_ORG });
// processer.addBeforeFinalRule(rule);
// // 孙表组装位置物料表体自动分配
// rule = new MMAutoMaterialAssignRule<AggBomVO>(null, BomPosVO.G_CMATERIALVID, null,
// new String[] { BomPosVO.PK_ORG });
// processer.addBeforeFinalRule(rule);
// // 孙表阶梯变动损耗物料表体自动分配
// rule = new MMAutoMaterialAssignRule<AggBomVO>(null, BomLossVO.CLMATERIALVID, null,
// new String[] { BomLossVO.PK_ORG });
// processer.addBeforeFinalRule(rule);
// 孙表替代料物料表体自动分配
rule = new MMAutoMaterialAssignRule<AggBomVO>(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<AggBomVO> processer) {
// BOM版本检查规则
IRule<AggBomVO> 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;
}
}

View File

@ -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<String,String> rownoMap = null;
public Map<String, String> getRownoMap() {
return rownoMap;
}
public void setRownoMap(Map<String, String> 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<AggBomVO> bp = new GCUpdateBPTemplate<AggBomVO>(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<AggBomVO> bp = new GCUpdateBPTemplate<AggBomVO>(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<AggBomVO> processer) {
IRule<AggBomVO> 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<AggBomVO>();
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<AggBomVO>();
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<AggBomVO>(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<AggBomVO> compareRule = new UpdateHasReplsCheckRule();
processer.addBeforeRule(compareRule);
}
// 物料表头自动分配
rule = new MMAutoMaterialAssignRule<AggBomVO>(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<AggBomVO>(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<AggBomVO>(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<AggBomVO>(null, BomWipVO.G_CMATERIALVID, null,
// new String[] { BomWipVO.PK_ORG });
// processer.addBeforeFinalRule(rule);
// // 孙表组装位置物料表体自动分配
// rule = new MMAutoMaterialAssignRule<AggBomVO>(null, BomPosVO.G_CMATERIALVID, null,
// new String[] { BomPosVO.PK_ORG });
// processer.addBeforeFinalRule(rule);
// // 孙表阶梯变动损耗物料表体自动分配
// rule = new MMAutoMaterialAssignRule<AggBomVO>(null, BomLossVO.CLMATERIALVID, null,
// new String[] { BomLossVO.PK_ORG });
// processer.addBeforeFinalRule(rule);
// 孙表替代料物料表体自动分配
rule = new MMAutoMaterialAssignRule<AggBomVO>(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<AggBomVO> processer) {
// BOM版本检查规则
IRule<AggBomVO> rule = new BomVersionCheckRule();
processer.addAfterRule(rule);
// 同步BOM匹配规则中的BOM版本 add by lijbe
ICompareRule<AggBomVO> updateBmrtRule = new BomUpdateBmrtVersionRule();
processer.addBeforeRule(updateBmrtRule);
// 注册事件源
IRule<AggBomVO> 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;
}
}

View File

@ -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<AggBomVO> {
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<String,String> material_construct = new HashMap<>();
Map<String,String> 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<String, String> materialConstruct, Map<String, String> materialStock, String pkOrg) throws BusinessException {
List<String> 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<Map<String,Object>> remain = (List<Map<String, Object>>) dao.executeQuery(sql.toString(), new MapListProcessor());
if(remain==null || remain.isEmpty()){
throw new BusinessException("物料查询辅助属性结构失败,sql【"+sql+"");
}
for (Map<String,Object> 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);
}
}
}