package kd.cosmic.jkjt.fi.gl.opplugin; import com.alibaba.fastjson.JSONObject; import kd.bos.business.plugin.AbstractUniqueBillno; import kd.bos.business.plugin.UniqueBillno; import kd.bos.business.plugin.mode.CodeRuleModeFactory; import kd.bos.business.plugin.mode.CodeRuleNumberMode; import kd.bos.coderule.api.CodeRuleInfo; import kd.bos.coderule.opplugin.util.OrgUtil; import kd.bos.dataentity.RefObject; import kd.bos.dataentity.entity.DynamicObject; import kd.bos.dataentity.utils.StringUtils; import kd.bos.entity.BillEntityType; import kd.bos.entity.plugin.AbstractOperationServicePlugIn; import kd.bos.entity.plugin.args.AfterOperationArgs; import kd.bos.entity.plugin.args.BeforeOperationArgs; import kd.bos.entity.plugin.args.BeginOperationTransactionArgs; import kd.bos.entity.plugin.args.EndOperationTransactionArgs; import kd.bos.exception.KDBizException; import kd.bos.exception.KDException; import kd.bos.logging.Log; import kd.bos.logging.LogFactory; import kd.bos.orm.query.QFilter; import kd.bos.servicehelper.coderule.CodeRuleServiceHelper; import kd.fi.gl.util.QFBuilder; import kd.fi.gl.util.voucher.VoucherNumberUtils; import java.util.*; /** * @description 凭证提交操作插件,用来解决标准产品API写入的凭证不会验重的问题 * @author wanghaiwu_kd * @date 2024/12/09 */ public class VoucherSubmitCheckNumberOpPlugin extends AbstractOperationServicePlugIn { private static final Log logger = LogFactory.getLog(VoucherSubmitCheckNumberOpPlugin.class); protected AbstractUniqueBillno uniqueBillno = new UniqueBillno(); protected List numberModes; @Override public void beforeExecuteOperationTransaction(BeforeOperationArgs e) { super.beforeExecuteOperationTransaction(e); if (this.operateOption.tryGetVariableValue("webapitag_of_datasource", new RefObject())) { String datasource = this.operateOption.getVariableValue("webapitag_of_datasource"); if (String.valueOf(true).equals(datasource)) { DynamicObject[] dataEntities = e.getDataEntities(); if(dataEntities.length == 1){ this.numberModes = CodeRuleModeFactory.newInstance(this.operateOption, "AbstractCodeRule", this.getBillNoField((BillEntityType)this.billEntityType)); singleGenerateNumber(dataEntities[0]); } } } } private void singleGenerateNumber(DynamicObject dynamicObject) { BillEntityType billEntityType = (BillEntityType)dynamicObject.getDataEntityType(); CodeRuleInfo codeRuleInfo = this.getCodeRuleInfo(dynamicObject); if (codeRuleInfo != null) { this.singleGenerateNewNumber(dynamicObject, billEntityType, codeRuleInfo); } } protected CodeRuleInfo getCodeRuleInfo(DynamicObject dynamicObject) { // String entityNum = dynamicObject.getDataEntityType().getName(); // String orgId = OrgUtil.getMainOrgId(dynamicObject); // return CodeRuleServiceHelper.getCodeRule(entityNum, dynamicObject, orgId); return VoucherNumberUtils.getCodeRuleInfoWithPriority(dynamicObject.getLong("org.id")); } private void singleGenerateNewNumber(DynamicObject dynamicObject, BillEntityType billEntityType, CodeRuleInfo codeRuleInfo) { logger.info("[CodeRuleOp]生成编号"); String billNoFldKey = this.getBillNoField(billEntityType); this.commonGenerateNewNumber(dynamicObject, codeRuleInfo, billNoFldKey); } private void commonGenerateNewNumber(DynamicObject dynamicObject, CodeRuleInfo codeRuleInfo, String billNoFldKey) { String newNumber = dynamicObject.getString(billNoFldKey); newNumber = this.generateNumberForUniqueBillno(dynamicObject, billNoFldKey, codeRuleInfo, newNumber); dynamicObject.set(billNoFldKey, newNumber); } private String generateNumberForUniqueBillno(DynamicObject dynamicObject, String billNoFldKey, CodeRuleInfo codeRuleInfo, String number) { String entityNum = dynamicObject.getDataEntityType().getName(); int loopCount = 0; while(true) { boolean existBillNum = this.uniqueBillno.checkReatedInDB(entityNum, this.getQFilterExistUniqueBillNo(billNoFldKey, number, dynamicObject)); if (!existBillNum) { logger.info("[CodeRuleOp]尝试" + loopCount + "次后发现不重复的编码"); break; } number = this.executeGenerateProcess(dynamicObject, codeRuleInfo); ++loopCount; if (loopCount > 50) { logger.info("[CodeRuleOp]尝试50次后依然没有发现不重复的编码,停止继续消耗流水号"); break; } } return number; } protected QFilter[] getQFilterExistUniqueBillNo(String billNoFldKey, String number, DynamicObject voucherDyn) { logger.info("getQFilterExistUniqueBillNo is called."); // ((VoucherCodeRuleOp.VoucherUniqueBillNo)this.uniqueBillno).currentCheckVoucherId = voucherDyn.getLong("id"); Set enhancedSortItems = VoucherNumberUtils.getEnhancedSortItems(this.getCodeRuleInfo(voucherDyn)); JSONObject groupByInfos = VoucherNumberUtils.getGroupByInfos(voucherDyn, enhancedSortItems); QFBuilder qfBuilder = VoucherNumberUtils.transJsonToQFBuilder(groupByInfos); qfBuilder.add("billno", "=", number); qfBuilder.add("billstatus", "in", new Object[]{"B", "C", "D"}); return qfBuilder.toArray(); } private String executeGenerateProcess(DynamicObject dynamicObject, CodeRuleInfo codeRuleInfo) { String number = ""; if (null == this.numberModes) { return number; } try { for (CodeRuleNumberMode numberMode : this.numberModes) { number = numberMode.getNumber(dynamicObject, codeRuleInfo); } } catch (KDException e) { if (null != e.getErrorCode() && StringUtils.equals((CharSequence)"CODERULE_NO_EXECUTE", (CharSequence)e.getErrorCode().getCode())) { return number; } if (e.getErrorCode() != null && "ERRCODE_CODERULE_VALIDATE_NUMBER".equals(e.getErrorCode().getCode())) { throw new KDBizException(e.getErrorCode(), new Object[0]); } logger.error((Throwable)e); throw new KDException(e.getErrorCode(), new Object[0]); } return number; } protected String getBillNoField(BillEntityType billEntityType) { return billEntityType.getBillNo(); } @Override public void beginOperationTransaction(BeginOperationTransactionArgs e) { super.beginOperationTransaction(e); } @Override public void endOperationTransaction(EndOperationTransactionArgs e) { super.endOperationTransaction(e); } @Override public void afterExecuteOperationTransaction(AfterOperationArgs e) { super.afterExecuteOperationTransaction(e); } }