diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/convert/ClaimConvertPlugin.java b/main/java/shjh/jhzj7/fi/fi/plugin/convert/ClaimConvertPlugin.java index 1799f75..c366b0a 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/convert/ClaimConvertPlugin.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/convert/ClaimConvertPlugin.java @@ -171,6 +171,9 @@ public class ClaimConvertPlugin extends AbstractConvertPlugIn implements Plugin targetEntry.set("shjh_detailid", entry.getString("shjh_detailid")); targetEntry.set("shjh_usercode", entry.getString("shjh_usercode")); targetEntry.set("shjh_deptcode", entry.getString("shjh_deptcode")); + targetEntry.set("shjh_postingdate", entry.getDate("shjh_postingdate")); + targetEntry.set("shjh_accountsap", entry.getDynamicObject("shjh_coaitemcode")); + targetEntry.set("shjh_yym", entry.getDynamicObject("shjh_reasoncode")); } } } diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/form/ClaimBillButtonAssPlugin.java b/main/java/shjh/jhzj7/fi/fi/plugin/form/ClaimBillButtonAssPlugin.java index 64b0746..39fa8bb 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/form/ClaimBillButtonAssPlugin.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/form/ClaimBillButtonAssPlugin.java @@ -1,5 +1,6 @@ package shjh.jhzj7.fi.fi.plugin.form; +import kd.bos.dataentity.entity.DynamicObject; import kd.bos.dataentity.entity.DynamicObjectCollection; import kd.bos.entity.datamodel.IDataModel; import kd.bos.form.CloseCallBack; @@ -11,6 +12,9 @@ import kd.bos.form.events.ClosedCallBackEvent; import kd.bos.form.plugin.AbstractFormPlugin; 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 shjh.jhzj7.fi.fi.plugin.form.info.ClaimFieldsInfo; @@ -204,6 +208,21 @@ public class ClaimBillButtonAssPlugin extends AbstractFormPlugin implements Plug this.getModel().setValue(ClaimFieldsInfo.USER_CODE, returnData.get(i).getString(ClaimFieldsInfo.USER_CODE), i); //部门编码 this.getModel().setValue(ClaimFieldsInfo.DEPT_CODE, returnData.get(i).getString(ClaimFieldsInfo.DEPT_CODE), i); + + //过账日期 + this.getModel().setValue("shjh_postingdate", returnData.get(i).getDate("shjh_postingdate"), i); + //科目 + String accountCode = returnData.get(i).getString("shjh_coaitemcode"); + DynamicObject account = BusinessDataServiceHelper.loadSingle("bd_accountview", (new QFilter("number", QCP.equals, accountCode)).toArray()); + if (null!=account){ + this.getModel().setValue("shjh_coaitemcode", account, i); + } + //原因码 + String code = returnData.get(i).getString("shjh_reasoncode"); + DynamicObject reason = BusinessDataServiceHelper.loadSingle("gl_cashflowitem", (new QFilter("number", QCP.equals, code)).toArray()); + if (null!=reason){ + this.getModel().setValue("shjh_reasoncode", reason, i); + } } } \ No newline at end of file diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/form/FeeControlApiPlugin.java b/main/java/shjh/jhzj7/fi/fi/plugin/form/FeeControlApiPlugin.java index bd27aed..1129dcc 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/form/FeeControlApiPlugin.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/form/FeeControlApiPlugin.java @@ -35,11 +35,11 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { private static final String ENTRY_KEY = "shjh_entryentity"; private static final String PAYMENT_API = "paymentApi"; private static final String LOAN_API = "loanApi"; - private static final String INTERFACE_ID1 ="FMGetJahYFKList";//识别被调接口并进行路由-预付款退回 + private static final String INTERFACE_ID1 = "FMGetJahYFKList";//识别被调接口并进行路由-预付款退回 - private static final String INTERFACE_ID2 ="FMGetJahJKYList";//识别被调接口并进行路由-员工借款 + private static final String INTERFACE_ID2 = "FMGetJahJKYList";//识别被调接口并进行路由-员工借款 - private static final String RECEIVER_ID ="FeiKong";//定义的发送者 + private static final String RECEIVER_ID = "FeiKong";//定义的发送者 /** * 按钮监听 @@ -69,7 +69,7 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { JSONObject org = showParameter.getCustomParam("org"); String idStr = org.getString("id"); Long id = Long.parseLong(idStr); - this.getModel().setValue("shjh_orgfield",id); + this.getModel().setValue("shjh_orgfield", id); this.getView().updateView("shjh_orgfield"); String apiKey = showParameter.getCustomParam("Apikey"); if (LOAN_API.equals(apiKey)) { @@ -166,7 +166,7 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { return; } String supplierCode = supplier.getString("number"); - HashMap head = ApiUtils.buildHead(INTERFACE_ID1,RECEIVER_ID); + HashMap head = ApiUtils.buildHead(INTERFACE_ID1, RECEIVER_ID); HashMap body = ApiUtils.buildBody(companyCode, this.getUserCode(), startDate, endDate); HashMap data = (HashMap) body.get("data"); @@ -197,7 +197,7 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { */ private void handleLoanApi(String companyCode, Date startDate, Date endDate, String billNumber) { try { - HashMap head = ApiUtils.buildHead(INTERFACE_ID2,RECEIVER_ID); + HashMap head = ApiUtils.buildHead(INTERFACE_ID2, RECEIVER_ID); HashMap body = ApiUtils.buildBody(companyCode, this.getUserCode(), startDate, endDate); String response = ApiUtils.sendPost(head, body, "https://hipint-stg.jahwa.com.cn:6443/gateway/HIP_ReceiveFromFM/1.0/fm/send"); if (response != null) { @@ -233,7 +233,7 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { for (int j = 0; j < loanDetailInfo.size(); j++) { JSONObject detail = (JSONObject) loanDetailInfo.get(j); entry.addNew(); - setPaymentApiValues(top, detail, i ,voucherItems ); + setPaymentApiValues(top, detail, i, voucherItems); } } } catch (Exception e) { @@ -260,7 +260,7 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { for (int i = 0; i < rows.size(); i++) { JSONObject top = (JSONObject) rows.get(i); entry.addNew(); - setLoanApiValues(top, i,voucherItems); + setLoanApiValues(top, i, voucherItems); } } catch (Exception e) { logger.error("借款单数据解析异常: " + e.getMessage(), e); @@ -274,7 +274,7 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { * @param detail json分录参数 * @param i */ - private void setPaymentApiValues(JSONObject top, JSONObject detail, int i ,JSONArray voucherItems) { + private void setPaymentApiValues(JSONObject top, JSONObject detail, int i, JSONArray voucherItems) { try { this.getModel().setValue("shjh_prepaymentnum", detail.getString("RequestCode"), i); this.getModel().setValue("shjh_purchasenum", detail.getString("PoOrderNo"), i); @@ -284,7 +284,7 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { this.getModel().setValue("shjh_paymentamount", detail.getBigDecimal("RequestAmt"), i); this.getModel().setValue("shjh_documentamount", detail.getBigDecimal("AvailableAmt"), i); this.getModel().setValue("shjh_detailid", detail.getString("DetailID"), i); - setPublicValues(top,i,voucherItems); + setPublicValues(top, i, voucherItems); } catch (Exception e) { logger.error("预付单赋值异常: " + e.getMessage(), e); } @@ -296,35 +296,38 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { * @param top * @param i */ - private void setLoanApiValues(JSONObject top,int i,JSONArray voucherItems) { + private void setLoanApiValues(JSONObject top, int i, JSONArray voucherItems) { try { this.getModel().setValue("shjh_loannum", top.getString("RequestCode"), i); this.getModel().setValue("shjh_loanamount", top.getBigDecimal("RequestAmt"), i); this.getModel().setValue("shjh_loanbalance", top.getBigDecimal("AvailableAmt"), i); - setPublicValues(top,i,voucherItems); + setPublicValues(top, i, voucherItems); } catch (Exception e) { logger.error("借款单赋值异常: " + e.getMessage(), e); } } - private void setPublicValues(JSONObject top,int i,JSONArray voucherItems) { + private void setPublicValues(JSONObject top, int i, JSONArray voucherItems) { try { this.getModel().setValue("shjh_billno", top.getString("CompanyCode"), i);//公司编号 this.getModel().setValue("shjh_verificationnum", top.getString("StrColumn20"), i);//核销单凭证号 this.getModel().setValue("shjh_fiscalyear", top.getString("GLDate").substring(0, 4), i);//会计年度 this.getModel().setValue("shjh_billheaderid", top.getString("ID"), i); - this.getModel().setValue("shjh_usercode", top.getString("RequestUserCode"), i); - this.getModel().setValue("shjh_deptcode", top.getString("RequestDeptCode"), i); - String id = top.getString("ID"); - for (int i1 = 0; i1 < voucherItems.size(); i1++) { - JSONObject voucherItem = (JSONObject)voucherItems.get(i1); - if (voucherItem.getString("BillHeaderID").equals(id)){ - this.getModel().setValue("shjh_coaitemfullname", voucherItem.getString("COAItemFullName"), i); - this.getModel().setValue("shjh_coaitemcode", voucherItem.getString("COAItemCode"), i); - this.getModel().setValue("shjh_coaitemname", voucherItem.getString("COAItemName"), i); - this.getModel().setValue("shjh_reasoncode", voucherItem.getString("ReasonCode"), i); - this.getModel().setValue("shjh_reasoncodename", voucherItem.getString("ReasonCodeName"), i); - break; + this.getModel().setValue("shjh_usercode", top.getString("RequestUserCode"), i);//员工工号 + this.getModel().setValue("shjh_deptcode", top.getString("RequestDeptCode"), i);//部门编码 + this.getModel().setValue("shjh_postingdate", top.getString("GLDate"), i);//过账日期 + if (voucherItems != null && voucherItems.size() != 0) { + String id = top.getString("ID"); + for (int i1 = 0; i1 < voucherItems.size(); i1++) { + JSONObject voucherItem = (JSONObject) voucherItems.get(i1); + if (voucherItem.getString("BillHeaderID").equals(id)) { + this.getModel().setValue("shjh_coaitemfullname", voucherItem.getString("COAItemFullName"), i);//会计科目全称 + this.getModel().setValue("shjh_coaitemcode", voucherItem.getString("COAItemCode"), i);//会计科目编码 + this.getModel().setValue("shjh_coaitemname", voucherItem.getString("COAItemName"), i);//会计科目名称 + this.getModel().setValue("shjh_reasoncode", voucherItem.getString("ReasonCode"), i);//原因码 + this.getModel().setValue("shjh_reasoncodename", voucherItem.getString("ReasonCodeName"), i);//原因码名称 + break; + } } } } catch (Exception e) { @@ -393,6 +396,7 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { /** * 获取当前操作用户工号 + * * @return */ public String getUserCode() { @@ -421,10 +425,11 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { /** * 日志记录 - * @param response 响应参数 + * + * @param response 响应参数 * @param billNumber 本单单号 - * @param body 请求体 - * @param apiName 接口名 + * @param body 请求体 + * @param apiName 接口名 * @return */ private Boolean parseResponse(String response, String billNumber, String body, String apiName) { @@ -438,15 +443,15 @@ public class FeeControlApiPlugin extends AbstractFormPlugin implements Plugin { EsbUtils.saveLog(billNumber, apiName, body, response, true, "ESBQueryApi", "查询成功"); break; case "1": - this.getView().showMessage("服务异常:"+result.getString("msg")); + this.getView().showMessage("服务异常:" + result.getString("msg")); EsbUtils.saveLog(billNumber, apiName, body, response, false, "ESBQueryApi", "服务异常"); break; case "2": - this.getView().showMessage("三方服务异常:"+result.getString("msg")); + this.getView().showMessage("三方服务异常:" + result.getString("msg")); EsbUtils.saveLog(billNumber, apiName, body, response, false, "ESBQueryApi", "三方服务异常"); break; case "3": - this.getView().showMessage("业务异常:"+result.getString("msg")); + this.getView().showMessage("业务异常:" + result.getString("msg")); EsbUtils.saveLog(billNumber, apiName, body, response, false, "ESBQueryApi", "业务异常"); break; default: diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/form/RecBillChangeListExtendPlugin.java b/main/java/shjh/jhzj7/fi/fi/plugin/form/RecBillChangeListExtendPlugin.java index 2787b0d..3a0f6ec 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/form/RecBillChangeListExtendPlugin.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/form/RecBillChangeListExtendPlugin.java @@ -63,14 +63,14 @@ public class RecBillChangeListExtendPlugin extends AbstractListPlugin implements String qzState = recBill.getString("shjh_qzzt"); BigDecimal actrecamt = recBill.getBigDecimal("actrecamt"); - // 状态 + 来源校验 - if (!("C".equals(billStatus) && ( - "cas_claimcenterbill".equals(sourceBillType) || - "bei_intelrec".equals(sourceBillType)))) { - this.getView().showTipNotification("所选单据不满足变更条件,只有状态=“已收款”且源单类型=“收款入账中心/认领通知单”的收款单才允许变更。"); - evt.setCancel(true); - return; - } + // 状态 + 来源校验-----标品已有 +// if (!("C".equals(billStatus) && ( +// "cas_claimcenterbill".equals(sourceBillType) || +// "bei_intelrec".equals(sourceBillType)))) { +// this.getView().showTipNotification("所选单据不满足变更条件,只有状态=“已收款”且源单类型=“收款入账中心/认领通知单”的收款单才允许变更。"); +// evt.setCancel(true); +// return; +// } // 凭证号非空 if (voucherNum == null || voucherNum.trim().isEmpty()) { diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/operate/RecRedPushOperation.java b/main/java/shjh/jhzj7/fi/fi/plugin/operate/RecRedPushOperation.java new file mode 100644 index 0000000..c6d8c6a --- /dev/null +++ b/main/java/shjh/jhzj7/fi/fi/plugin/operate/RecRedPushOperation.java @@ -0,0 +1,198 @@ +package shjh.jhzj7.fi.fi.plugin.operate; + +import kd.bos.context.RequestContext; +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.operate.result.OperateErrorInfo; +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.entity.validate.ErrorLevel; +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.bos.servicehelper.operation.SaveServiceHelper; +import kd.sdk.plugin.Plugin; +import shjh.jhzj7.fi.fi.utils.ApiUtils; +import shjh.jhzj7.fi.fi.utils.EsbUtils; +import shjh.jhzj7.fi.fi.utils.ObjUtils; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 单据操作插件 + * SAP反清账接口按钮 + */ +public class RecRedPushOperation extends AbstractOperationServicePlugIn implements Plugin { + + private final static Log logger = LogFactory.getLog(RecRedPushOperation.class); + + private static final String INTERFACE_ID ="ReversalVoucher";//识别被调接口并进行路由-SAP反清账 + + private static final String RECEIVER_ID ="SAP";//定义的发送者 + /** + * 操作标识 + */ + private static final String KEY_RED_PUSH= "redpunch"; + + @Override + public void onPreparePropertys(PreparePropertysEventArgs e) { + super.onPreparePropertys(e); + e.getFieldKeys().add(RedPushValidator.KEY_HOT_ACCOUNT); + + } + + @Override + public void onAddValidators(AddValidatorsEventArgs e) { + super.onAddValidators(e); + e.addValidator(new RedPushValidator()); + } + + /** + * 自定义校验器 + */ + static class RedPushValidator extends AbstractValidator { + /** + * 单据编号 + */ + public final static String KEY_BILL_NUM = "billno"; + /** + * 红冲标识 + */ + public final static String KEY_HOT_ACCOUNT = "hotaccount"; + + /** + * 已推送SAP + */ + public final static String IS_PUSH_SAP = "shjh_ispushsap"; + + @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 billNum = (String) rowDataModel.getValue(KEY_BILL_NUM); + String hotAccount = (String) rowDataModel.getValue(KEY_HOT_ACCOUNT); + if (!"2".equals(hotAccount)) { + this.addErrorMessage(dataEntity, billNum+"所选单据不符合反清账要求。"); + } + Boolean isPushSap = (Boolean) rowDataModel.getValue(IS_PUSH_SAP); + if (isPushSap){ + this.addErrorMessage(dataEntity, billNum+"所选单据已反清账。"); + } + } + } + } + } + } + + @Override + public void afterExecuteOperationTransaction(AfterOperationArgs e) { + String operationKey = e.getOperationKey(); + if (StringUtils.equals(KEY_RED_PUSH, operationKey)) { + DynamicObject[] dataEntities = e.getDataEntities(); + if (dataEntities != null && dataEntities.length >= 1) { + StringBuilder message = new StringBuilder(); + for (DynamicObject dataEntity : dataEntities) { + DynamicObject recBill = BusinessDataServiceHelper.loadSingle(dataEntity.getLong("id"), "cas_recbill"); + if (null != recBill) { + //单号 + String billNumber = recBill.getString("billno"); + + HashMap responseHead = ApiUtils.buildHead(INTERFACE_ID,RECEIVER_ID); + HashMap responseBody = this.assembleRequest(billNumber, recBill,message); + try { + String response = ApiUtils.sendPost(responseHead, responseBody, "https://hipint-stg.jahwa.com.cn:6443/gateway/HIP_ReceiveFromFM/1.0/fm/send"); + if (!response.isEmpty()) { + boolean success = ApiUtils.parseResponse(response, billNumber, responseBody, INTERFACE_ID, message); + if (success){ + recBill.set("shjh_ispushsap",true); + SaveServiceHelper.update(recBill); + } + } + } catch (IOException ex) { + message.append("收款处理【").append(billNumber).append("】:").append(ex.getMessage()).append("\n"); + } + if (message.length()!=0){ + OperateErrorInfo operateErrorInfo = new OperateErrorInfo(); + operateErrorInfo.setMessage(String.valueOf(message)); + operateErrorInfo.setErrorLevel(ErrorLevel.Error.name()); + operateErrorInfo.setPkValue(dataEntity.getPkValue()); + this.operationResult.addErrorInfo(operateErrorInfo); + } + } + } + } + } + } + + + + /** + * 请求头组装 + * + * @param billNumber 单据编号 + * @param recBill 收款处理 + * @return + */ + private HashMap assembleRequest(String billNumber, DynamicObject recBill, StringBuilder message){ + HashMap responseBody = null; + try { + // 生成唯一事务ID + String rootContextId = UUID.randomUUID().toString(); + // 获取当前请求时间,格式为 yyyy-MM-dd HH:mm:ss.SSS + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + String requestTime = sdf.format(new Date()); + responseBody = new HashMap<>(5); + responseBody.put("rootContextID", rootContextId); + responseBody.put("requestTime", requestTime); + HashMap data = new HashMap<>(10); + List> IT_ITEM = new ArrayList<>(); + //用户名 + DynamicObject userinfo = BusinessDataServiceHelper.loadSingleFromCache(RequestContext.get().getCurrUserId(), "bos_user"); + String oaUser = userinfo.getString("shjh_oauser"); + //冲销原因 + String cause=""; + Long id = ObjUtils.getLongSafely(recBill, "sourcebillid"); + if (id!=0L){ + DynamicObject changeBill = BusinessDataServiceHelper.loadSingle("cas_recchgbill", (new QFilter("sourcebillid", QCP.equals, id).toArray())); + if (null!=changeBill){ + cause=changeBill.getString("chgreson"); + } + } + DynamicObjectCollection entryCollection = recBill.getDynamicObjectCollection("entry"); + if (!entryCollection.isEmpty()){ + for (DynamicObject entry : entryCollection) { + Map IT_ITEMS = new HashMap<>(6); + IT_ITEMS.put("BELNR",entry.getString("shjh_verificationnum"));//会计凭证编号 + IT_ITEMS.put("BUKRS",entry.getString("realreccompany.number"));//公司代码 + IT_ITEMS.put("GJAHR",entry.getString("shjh_fiscalyear"));//会计年度 + IT_ITEMS.put("STGRD",cause);//冲销原因 + IT_ITEMS.put("UNAME",oaUser);//用户名 + IT_ITEMS.put("BUDAT",entry.getDate("shjh_postingdate").toString());//凭证中的过帐日期 + IT_ITEM.add(IT_ITEMS); + } + } + data.put("IT_ITEM", IT_ITEM); + responseBody.put("data", data); + } catch (Exception e) { + message.append("收款处理【").append(billNumber).append("】:").append(e.getMessage()).append("\n"); + EsbUtils.saveLog(billNumber, INTERFACE_ID, null, e.getMessage(), false, "ESBPushApi", "数据异常"); + } + return responseBody; + } + +} \ No newline at end of file diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/task/RecPushSapTask.java b/main/java/shjh/jhzj7/fi/fi/plugin/task/RecPushSapTask.java index bdb5501..1cb30d7 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/task/RecPushSapTask.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/task/RecPushSapTask.java @@ -16,8 +16,11 @@ import kd.bos.servicehelper.operation.OperationServiceHelper; import kd.sdk.plugin.Plugin; import shjh.jhzj7.fi.fi.plugin.form.info.RecFieldsInfo; +import java.math.BigDecimal; import java.util.ArrayList; +import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; /** * 后台任务插件 @@ -29,41 +32,70 @@ public class RecPushSapTask extends AbstractTask implements Plugin { @Override public void execute(RequestContext requestContext, Map map) throws KDException { - //收款、已生成金蝶凭证、未推送SAP - QFilter qFilter = new QFilter("billstatus", QCP.equals, "D"); - qFilter.and(new QFilter("isvoucher", QCP.equals, true)); - qFilter.and(new QFilter("shjh_ispushsap", QCP.equals, false)); + // 查询条件:收款单、已生成凭证、未推送SAP、金额≠0 + QFilter qFilter = new QFilter("billstatus", QCP.equals, "D") + .and(new QFilter("isvoucher", QCP.equals, true)) + .and(new QFilter("shjh_ispushsap", QCP.equals, false)) + .and(new QFilter("actrecamt", QCP.not_equals, BigDecimal.ZERO)); - DynamicObject[] recBillList = BusinessDataServiceHelper.load("cas_recbill", "id", qFilter.toArray()); + DynamicObject[] recBillList = BusinessDataServiceHelper.load("cas_recbill", "id,billno,actrecamt", qFilter.toArray()); - if (recBillList.length != 0) { - ArrayList ids = new ArrayList<>(); - for (DynamicObject dynamicObject : recBillList) { - ids.add(dynamicObject.getLong("id")); - } + if (recBillList.length == 0) { + logger.info("未找到符合条件的收款单"); + return; + } - Map recBillMap = BusinessDataServiceHelper.loadFromCache(ids.toArray(), "cas_recbill"); + // 按金额正负分组 + List normalBills = new ArrayList<>(); // 正数单据 + List redBills = new ArrayList<>(); // 负数单据(红冲) - OperateOption operateOption = OperateOption.create(); - // 不执行警告级别校验器 - operateOption.setVariableValue(OperateOptionConst.IGNOREWARN, String.valueOf(true)); - // 不显示交互提示,自动执行到底 - operateOption.setVariableValue(OperateOptionConst.IGNOREINTERACTION, String.valueOf(true)); - // 全部校验通过才保存 - operateOption.setVariableValue(OperateOptionConst.STRICTVALIDATION, String.valueOf(true)); - //同一个用户在多个界面操作同一张,也不允许操作 - operateOption.setVariableValue(OperateOptionConst.MUTEX_ISSTRICT, String.valueOf(true)); - - // Convert map values to array for batch operation - DynamicObject[] billArray = recBillMap.values().toArray(new DynamicObject[0]); - - OperationResult operationResult = OperationServiceHelper.executeOperate("pushvoucher", "cas_recbill", billArray, operateOption); - - if (operationResult.isSuccess()) { - logger.info("执行 pushvoucher 成功,共处理 " + billArray.length + " 张单据"); + for (DynamicObject bill : recBillList) { + if (bill.getBigDecimal("actrecamt").compareTo(BigDecimal.ZERO) > 0) { + normalBills.add(bill); } else { - logger.error("批量推送SAP失败: " + operationResult.getMessage()); + redBills.add(bill); } } + + // 配置操作选项(共用) + OperateOption operateOption = createStrictOperateOption(); + + // 并行处理两组数据 + CompletableFuture normalFuture = processBillsAsync(normalBills, "pushvoucher", operateOption); + CompletableFuture redFuture = processBillsAsync(redBills, "redpunch", operateOption); + + // 等待所有任务完成 + CompletableFuture.allOf(normalFuture, redFuture).join(); + } + + // 创建严格的操作选项 + private OperateOption createStrictOperateOption() { + OperateOption option = OperateOption.create(); + option.setVariableValue(OperateOptionConst.IGNOREWARN, "true"); + option.setVariableValue(OperateOptionConst.IGNOREINTERACTION, "true"); + option.setVariableValue(OperateOptionConst.STRICTVALIDATION, "true"); + option.setVariableValue(OperateOptionConst.MUTEX_ISSTRICT, "true"); + return option; + } + + // 异步处理单据组 + private CompletableFuture processBillsAsync(List bills, String operation, OperateOption option) { + return CompletableFuture.runAsync(() -> { + if (bills.isEmpty()) return; + + try { + DynamicObject[] billArray = bills.toArray(new DynamicObject[0]); + OperationResult result = OperationServiceHelper.executeOperate(operation, "cas_recbill", billArray, option); + + if (result.isSuccess()) { + logger.info(String.format("【%s】批量处理成功:%d 张单据", operation, bills.size())); + } else { + logger.error(String.format("【%s】处理失败:%s", operation, result.getMessage())); + // 可在此添加失败重试逻辑 + } + } catch (Exception e) { + logger.error(String.format("【%s】执行异常:", operation), e); + } + }); } } \ No newline at end of file diff --git a/main/java/shjh/jhzj7/fi/fi/utils/ObjUtils.java b/main/java/shjh/jhzj7/fi/fi/utils/ObjUtils.java new file mode 100644 index 0000000..c657b04 --- /dev/null +++ b/main/java/shjh/jhzj7/fi/fi/utils/ObjUtils.java @@ -0,0 +1,31 @@ +package shjh.jhzj7.fi.fi.utils; + +import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.logging.Log; +import kd.bos.logging.LogFactory; + +public class ObjUtils { + + private final static Log logger = LogFactory.getLog(ObjUtils.class); + + /** + * 安全获取源单ID + * @param obj 数据包 + * @param fieldName 字段名 + * @return id + */ + public static Long getLongSafely(DynamicObject obj, String fieldName) { + if (obj == null) { + return null; + } + try { + Object value = obj.get(fieldName); + return value != null ? Long.parseLong(value.toString()) : 0L; + } catch (Exception e) { + logger.error("转换字段[" + fieldName + "]到Long失败", e); + return null; + } + } + + +}