From be2728441b4a22a8c4290f9ece49b16c810daa90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E8=B4=B5=E5=BC=BA?= Date: Tue, 1 Apr 2025 17:51:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B6=E6=AC=BE=E5=A4=84=E7=90=86-=E6=B1=87?= =?UTF-8?q?=E7=A5=A8=E5=87=AD=E8=AF=81=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operate/DraPushVoucherOperation.java | 236 ++++++++++++++++++ .../operate/RecPushVoucherOperation.java | 82 ++++-- 2 files changed, 296 insertions(+), 22 deletions(-) create mode 100644 main/java/shjh/jhzj7/fi/fi/plugin/operate/DraPushVoucherOperation.java diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/operate/DraPushVoucherOperation.java b/main/java/shjh/jhzj7/fi/fi/plugin/operate/DraPushVoucherOperation.java new file mode 100644 index 0000000..eb5d978 --- /dev/null +++ b/main/java/shjh/jhzj7/fi/fi/plugin/operate/DraPushVoucherOperation.java @@ -0,0 +1,236 @@ +package shjh.jhzj7.fi.fi.plugin.operate; + +import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.dataentity.entity.DynamicObjectCollection; +import kd.bos.dataentity.utils.StringUtils; +import kd.bos.entity.ExtendedDataEntity; +import kd.bos.entity.formula.RowDataModel; +import kd.bos.entity.plugin.AbstractOperationServicePlugIn; +import kd.bos.entity.plugin.AddValidatorsEventArgs; +import kd.bos.entity.plugin.PreparePropertysEventArgs; +import kd.bos.entity.plugin.args.AfterOperationArgs; +import kd.bos.entity.validate.AbstractValidator; +import kd.bos.logging.Log; +import kd.bos.logging.LogFactory; +import kd.bos.orm.query.QCP; +import kd.bos.orm.query.QFilter; +import kd.bos.servicehelper.BusinessDataServiceHelper; +import kd.sdk.plugin.Plugin; +import scala.Array; +import shjh.jhzj7.fi.fi.utils.JhzjUtils; + +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; + +/** + * 单据操作插件 + * 票据业务处理-推送SAP凭证接口-弃用 + */ +public class DraPushVoucherOperation extends AbstractOperationServicePlugIn implements Plugin { + + private final static Log logger = LogFactory.getLog(DraPushVoucherOperation.class); + + private static final String INTERFACE_ID = "FinancialTransactionVoucher";//识别被调接口并进行路由-凭证 + + private static final String RECEIVER_ID = "SAP";//定义的发送者 + + /** + * 操作标识 + */ + private static final String KEY_PUSH_VOUCHER = "pushvoucher"; + + /** + * 操作执行前,准备加载单据数据之前,触发此事件 + * + * @remark 插件可以在此事件中,指定需要加载的字段 + */ + @Override + public void onPreparePropertys(PreparePropertysEventArgs e) { + super.onPreparePropertys(e); + e.getFieldKeys().add(PushVoucherValidator.KEY_IS_VOUCHER); + e.getFieldKeys().add(PushVoucherValidator.KEY_BILL_STATUS); + e.getFieldKeys().add(PushVoucherValidator.KEY_BILL_NUMBER); + e.getFieldKeys().add(PushVoucherValidator.KEY_IS_PUSH_SAP); + } + + /** + * 执行操作校验前,触发此事件 + * + * @remark 插件可以在此事件,调整预置的操作校验器;或者增加自定义操作校验器 + */ + @Override + public void onAddValidators(AddValidatorsEventArgs e) { + super.onAddValidators(e); + //添加自定义校验器:1.单据状态=已审核 2.生成凭证(金蝶)=true 3.是否已推送SAP=false + e.addValidator(new RebReversalFiOperation.ReversalValidator()); + } + + /** + * 自定义校验器 + */ + static class PushVoucherValidator extends AbstractValidator { + /** + * 单据编码 + */ + public final static String KEY_BILL_NUMBER = "billno"; + /** + * 单据状态 + */ + public final static String KEY_BILL_STATUS = "billstatus"; + + /** + * 是否已推送SAP + */ + public final static String KEY_IS_PUSH_SAP = "shjh_ispushsap"; + /** + * 是否已生成凭证 + */ + public final static String KEY_IS_VOUCHER = "isvoucher"; + + @Override + public void validate() { + //取数模型 + RowDataModel rowDataModel = new RowDataModel(this.entityKey, this.getValidateContext().getSubEntityType()); + ExtendedDataEntity[] dataEntities = this.getDataEntities(); + if (dataEntities != null && dataEntities.length >= 1) { + for (ExtendedDataEntity dataEntity : dataEntities) { + if (dataEntity != null) { + rowDataModel.setRowContext(dataEntity.getDataEntity()); + String billNo = (String) rowDataModel.getValue(KEY_BILL_NUMBER); + String type = (String) rowDataModel.getValue(KEY_BILL_STATUS); + if (!"C".equals(type)) { + this.addErrorMessage(dataEntity, "【" + billNo + "】未审核,无法推送。"); + } + boolean result = (boolean) rowDataModel.getValue(KEY_IS_PUSH_SAP); + if (result) { + this.addErrorMessage(dataEntity, "【" + billNo + "】已推送SAP,请勿重复推送。"); + } + boolean isVoucher = (boolean) rowDataModel.getValue(KEY_IS_VOUCHER); + if (!isVoucher) { + this.addErrorMessage(dataEntity, "【" + billNo + "】未生成金蝶凭证,无法推送。"); + } + } + } + } + } + } + + @Override + public void afterExecuteOperationTransaction(AfterOperationArgs e) { + String operationKey = e.getOperationKey(); + if (StringUtils.equals(KEY_PUSH_VOUCHER, operationKey)) { + DynamicObject[] dataEntities = e.getDataEntities(); + if (dataEntities != null && dataEntities.length >= 1) { + for (DynamicObject dataEntity : dataEntities) { + DynamicObject draftTradeBill = BusinessDataServiceHelper.loadSingle(dataEntity.getLong("id"), "cdm_drafttradebill"); + if (null != draftTradeBill) { + //组装data + HashMap data = new HashMap<>(); + HashMap IS_HEADER = new HashMap<>(); + // 使用线程安全的日期格式化 + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + // 公司代码-资金组织 + IS_HEADER.put("BUKRS", draftTradeBill.getString("company.number")); + // 凭证类型 + IS_HEADER.put("BLART", "DX"); + // 凭证日期 + Date bizDate = draftTradeBill.getDate("bizdate"); + IS_HEADER.put("BLDAT", bizDate != null ? format.format(bizDate) : ""); + // 过账日期 + Date payeeDate = draftTradeBill.getDate("payeedate"); + IS_HEADER.put("BUDAT", payeeDate != null ? format.format(payeeDate) : ""); + // 币种 + DynamicObject currency = draftTradeBill.getDynamicObject("currency"); + String isoCode = currency != null ? currency.getString("number") : ""; + IS_HEADER.put("WAERS", JhzjUtils.getCurrencyCode(isoCode)); + // 参考凭证号 + IS_HEADER.put("XBLNR", draftTradeBill.getString("billno")); + // 凭证抬头文本-被背书人 + IS_HEADER.put("BKTXT", draftTradeBill.getString("beendorsortext")); + // 固定值 + IS_HEADER.put("USNAM", "资金系统"); + //被背书人类型 + String number=""; + String payeeType = draftTradeBill.getString("payeetypetext"); + if (payeeType!=null){ + DynamicObject beendorsor = draftTradeBill.getDynamicObject("beendorsor"); + if(beendorsor!=null){ + number=beendorsor.getString("number"); + switch (payeeType){ + case "bd_customer": + IS_HEADER.put("KUNNR", number); // 客户编号 + break; + case "bd_supplier": + IS_HEADER.put("LIFNR", number); // 供应商编号 + break; + default: + break; + } + } + } + IS_HEADER.put("ZUONR", ""); // 分配编号 + data.put("data", IS_HEADER); + List> IT_ITEM = new ArrayList<>(); + DynamicObject gl_voucher = BusinessDataServiceHelper.loadSingle("gl_voucher", + "id,sourcebill,entries,entries.account,entries.debitlocal,entries.creditlocal,entries.entrydc", + new QFilter("sourcebill", QCP.equals, draftTradeBill.getPkValue()).toArray()); + + if (gl_voucher != null) { + DynamicObjectCollection entries = gl_voucher.getDynamicObjectCollection("entries"); + if (entries != null && !entries.isEmpty()) { + for (DynamicObject entry : entries) { + HashMap IT_ITEMS = new HashMap<>(); + switch (payeeType){ + case "bd_customer": + IT_ITEMS.put("KUNNR", number); // 客户编号 + break; + case "bd_supplier": + IT_ITEMS.put("LIFNR", number); // 供应商编号 + break; + default: + break; + } + // 设置科目 + DynamicObject account = entry.getDynamicObject("account"); + if (account != null) { + IT_ITEMS.put("HKONT", account.getString("number")); + } + + IT_ITEMS.put("UMSKZ", "W");//特殊总账标识 + + // 处理金额 + BigDecimal debitlocal = (BigDecimal) entry.get("debitlocal"); + BigDecimal creditlocal = (BigDecimal) entry.get("creditlocal"); + String entrydc = (String) entry.get("entrydc"); + + if (debitlocal != null && creditlocal != null && entrydc != null) { + BigDecimal amount = BigDecimal.ZERO; + switch (entrydc) { + case "1": // 借方 + amount = debitlocal; + break; + case "-1": // 贷方 + amount = creditlocal.negate(); + break; + default: + logger.warn("无效的分录方向: " + entrydc); + } + IT_ITEMS.put("DMBTR", amount.toString()); + } else { + logger.warn("凭证分录金额或方向为空"); + } + + IT_ITEM.add(IT_ITEMS); + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/operate/RecPushVoucherOperation.java b/main/java/shjh/jhzj7/fi/fi/plugin/operate/RecPushVoucherOperation.java index 024e274..dec4c84 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/operate/RecPushVoucherOperation.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/operate/RecPushVoucherOperation.java @@ -48,7 +48,7 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl /** * 操作标识 */ - private static final String KEY_PUSH_VOUCHER= "pushvoucher"; + private static final String KEY_PUSH_VOUCHER = "pushvoucher"; /** * 操作执行前,准备加载单据数据之前,触发此事件 @@ -62,6 +62,7 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl e.getFieldKeys().add(PushVoucherValidator.KEY_BILL_STATUS); e.getFieldKeys().add(PushVoucherValidator.KEY_BILL_NUMBER); e.getFieldKeys().add(PushVoucherValidator.KEY_IS_PUSH_SAP); + e.getFieldKeys().add(PushVoucherValidator.KEY_IS_VOUCHER); } /** @@ -73,7 +74,7 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl public void onAddValidators(AddValidatorsEventArgs e) { super.onAddValidators(e); //添加自定义校验器:1.单据状态=已收款 2.收款明细!=空 3.是否已推送SAP=false 4.SAP凭证号=空 - e.addValidator(new RebReversalFiOperation.ReversalValidator()); + e.addValidator(new PushVoucherValidator()); } /** @@ -95,11 +96,11 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl /** * 是否已推送SAP */ - public final static String KEY_IS_PUSH_SAP ="shjh_vouchernum"; + public final static String KEY_IS_PUSH_SAP = "shjh_ispushsap"; /** * 是否已生成凭证 */ - public final static String KEY_IS_VOUCHER ="isvoucher"; + public final static String KEY_IS_VOUCHER = "isvoucher"; @Override public void validate() { @@ -112,12 +113,12 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl rowDataModel.setRowContext(dataEntity.getDataEntity()); String billNo = (String) rowDataModel.getValue(KEY_BILL_NUMBER); String type = (String) rowDataModel.getValue(KEY_BILL_STATUS); - if (!"D".equals(type)){ + if (!"D".equals(type)) { this.addErrorMessage(dataEntity, "【" + billNo + "】未付款,无法推送。"); } String voucherNum = (String) rowDataModel.getValue(KEY_VOUCHER_NUM); boolean result = (boolean) rowDataModel.getValue(KEY_IS_PUSH_SAP); - if (!voucherNum.isEmpty()||result) { + if (!voucherNum.isEmpty() || result) { this.addErrorMessage(dataEntity, "【" + billNo + "】已推送SAP,请勿重复推送。"); } boolean isVoucher = (boolean) rowDataModel.getValue(KEY_IS_VOUCHER); @@ -147,25 +148,31 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl data.put("IT_ITEM", getIT_ITEM(recBill)); //收款类型=推预付款、员工还款需要传清账数据 String receivingType = recBill.getString("receivingtype.number"); - if ("103".equals(receivingType)||"109".equals(receivingType)) { + if ("103".equals(receivingType) || "109".equals(receivingType)) { //清账数据,参考《IT_CLEAR》,仅清账需要输入 data.put("IT_CLEAR", getIT_CLEAR(recBill)); } - String type = recBill.getString(RecFieldsInfo.PAYER_TYPE); - long id = recBill.getLong("payer"); - if (null!=type&&id!=0L){ + String type = recBill.getString(RecFieldsInfo.PAYER_TYPE);//付款人类型 + long id = recBill.getLong("payer");//付款人id + if (null != type && id != 0L) { Boolean disposableCusOrSup = SysUtils.isDisposableCusOrSup(id, type); - if (disposableCusOrSup){ + if (disposableCusOrSup) { //一次性供应商或客户信息(仅需要填写) data.put("IS_CUSTOMERCPD", getIS_CUSTOMERCPD(recBill)); } } JSONObject response = sap_accounVoucher(data, recBill.getString("billno")); - if (null!=response){ + if (null != response) { String code = (String) response.get("code"); if ("0".equals(code)) { - recBill.set("shjh_ispushsap",true); + recBill.set("shjh_ispushsap", true); SaveServiceHelper.update(recBill); + }else { + OperateErrorInfo operateErrorInfo = new OperateErrorInfo(); + operateErrorInfo.setMessage((String) response.get("msg")); + operateErrorInfo.setErrorLevel(ErrorLevel.Error.name()); + operateErrorInfo.setPkValue(dataEntity.getPkValue()); + this.operationResult.addErrorInfo(operateErrorInfo); } } } @@ -177,6 +184,7 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl /** * 获取SAP凭证头信息 + * * @param recBill 收款单动态对象 * @return 包含凭证头信息的JSONObject */ @@ -189,14 +197,15 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl // 公司代码 IS_HEADER.put("BUKRS", recBill.getString("org.number")); - // 凭证类型(留空) - IS_HEADER.put("BLART", "DZ"); + String sourceBillType = recBill.getString("sourcebilltype"); + // 凭证类型 + IS_HEADER.put("BLART", sourceBillType.equals("cdm_receivablebill") ? "DX" : "DZ"); // 凭证日期 Date bizDate = recBill.getDate("bizdate"); IS_HEADER.put("BLDAT", bizDate != null ? format.format(bizDate) : ""); - // 过账日期(修正了原代码中错误的条件判断) + // 过账日期 Date payeeDate = recBill.getDate("payeedate"); IS_HEADER.put("BUDAT", payeeDate != null ? format.format(payeeDate) : ""); @@ -214,9 +223,19 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl // 固定值 IS_HEADER.put("USNAM", "资金系统"); + String payerType = recBill.getString("payertype"); + if (payerType != null) { + String cusOrSupNumber = getCustomerOrSupplierNumber(payerType, recBill); + switch (payerType) { + case "bd_customer": + IS_HEADER.put("KUNNR", cusOrSupNumber); + break; + case "bd_supplier": + IS_HEADER.put("LIFNR", cusOrSupNumber); + break; + } + } // 以下字段初始化为空 - IS_HEADER.put("KUNNR", ""); // 客户编号 - IS_HEADER.put("LIFNR", ""); // 供应商编号 IS_HEADER.put("ZUONR", ""); // 分配编号 return IS_HEADER; @@ -224,12 +243,14 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl /** * 获取SAP凭证行项目信息 + * * @param recBill 收款单动态对象 * @return 包含行项目信息的JSONArray */ private JSONArray getIT_ITEM(DynamicObject recBill) { JSONArray IT_ITEM = new JSONArray(); - + //源单类型 + String sourceBillType = recBill.getString("sourcebilltype"); // 1. 获取客户/供应商编号 String payerType = recBill.getString("payertype"); String cusOrSupNumber = getCustomerOrSupplierNumber(payerType, recBill); @@ -242,7 +263,7 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl DynamicObject entry = entrys.get(0); DynamicObject shjhYym = entry.getDynamicObject("shjh_yym"); RSTGR = shjhYym != null ? shjhYym.getString("number") : ""; - SGTXT = entry.getString("shjh_sapline"); + //SGTXT = entry.getString("shjh_sapline"); } // 3. 获取成本中心 @@ -313,7 +334,22 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl IT_ITEMS.put("RSTGR", RSTGR); IT_ITEMS.put("KOSTL", KOSTL); IT_ITEMS.put("PRCTR", PRCTR); - + //设置汇票字段 + if (sourceBillType.equals("cdm_receivablebill")) { + IT_ITEMS.put("UMSKZ", "W");//特殊总账标识 + DynamicObjectCollection draftInfo = recBill.getDynamicObjectCollection("cas_draftinfo"); + if (null != draftInfo && draftInfo.size() != 0) { + DynamicObject draftBillInfo = draftInfo.get(0).getDynamicObject("draftbillinfo"); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Date draftBillExpireDate = draftBillInfo.getDate("draftbillexpiredate"); + IT_ITEMS.put("ZFBDT", draftBillExpireDate !=null ? format.format(draftBillExpireDate) : "");//汇票到期日 + Date issueDate = draftBillInfo.getDate("issuedate"); + IT_ITEMS.put("WDATE",issueDate !=null ? format.format(issueDate) : "");//汇票签发日期 + IT_ITEMS.put("WNAME",draftBillInfo.getString("drawername"));//出票人 + IT_ITEMS.put("WBZOG",draftBillInfo.getString("receivername"));//受票人 + IT_ITEMS.put("WBANK",draftBillInfo.getString("draftbillno"));//票据号 + } + } IT_ITEM.add(IT_ITEMS); } } @@ -324,6 +360,7 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl /** * 生成收款清账凭证数据 + * * @param recBill 收款单动态对象 * @return 清账凭证数据JSON数组 */ @@ -499,8 +536,9 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl /** * 根据付款方类型获取客户或供应商编号 + * * @param payerType 付款方类型 ("bd_customer" 或 "bd_supplier") - * @param recBill 收款单动态对象 + * @param recBill 收款单动态对象 * @return 客户/供应商编号,如果找不到则返回空字符串 */ private String getCustomerOrSupplierNumber(String payerType, DynamicObject recBill) {