diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/operate/ClearDetailBillOperation.java b/main/java/shjh/jhzj7/fi/fi/plugin/operate/ClearDetailBillOperation.java index c185d3a..616bfb2 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/operate/ClearDetailBillOperation.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/operate/ClearDetailBillOperation.java @@ -50,6 +50,17 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp prinfo = BusinessDataServiceHelper.loadSingle(dos[i].getPkValue(),dos[i].getDataEntityType().getName()); billno = prinfo.getString("billno"); if("submit".equals(eok)){ + //判断对应的清账单是否已提交,如果是,则不允许提交此明细单 + clearBillInfo = BusinessDataServiceHelper.loadSingle(prinfo.getString("shjh_clearbillid"),clearBillName,"id,billno,billstatus"); + if("B".equals(clearBillInfo.getString("billstatus"))){ + e.setCancelMessage(clearBillInfo.getString("billno")+"清账单已提交,此明细单无需提交"); + e.setCancel(true); + } + //判断对应的清账单是否已被他人打开界面占用,如果是,不允许提交明细单 + if(JhzjUtils.isLockedBill(clearBillInfo)){ + e.setCancelMessage(clearBillInfo.getString("billno")+"清账单已被他人正在编辑,此明细单无法提交"); + e.setCancel(true); + } if("B".equals(prinfo.getString("billstatus"))){ e.setCancelMessage(billno+"单据已提交,不允许重复提交"); e.setCancel(true); @@ -68,12 +79,6 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp e.setCancelMessage(billno+"分录本次核销或账扣尾差金额填写有误,合计等于0,分录负数金额合计的绝对值小于等于未清金额,才允许提交"); e.setCancel(true); } - //判断对应的清账单是否已提交,如果是,则不允许提交此明细单 - clearBillInfo = BusinessDataServiceHelper.loadSingle(prinfo.getString("shjh_clearbillid"),clearBillName,"id,billno,billstatus"); - if("B".equals(clearBillInfo.getString("billstatus"))){ - e.setCancelMessage(clearBillInfo.getString("billno")+"清账单已提交,此明细单无需提交"); - e.setCancel(true); - } }else if("revoke".equals(eok)){ //撤销校验 if(!"B".equals(prinfo.getString("billstatus"))){ @@ -87,6 +92,11 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp e.setCancelMessage(clearBillInfo.getString("billno")+"清账单已提交,此明细单不能撤销,可联系财务驳回"); e.setCancel(true); } + //判断对应的清账单是否已被他人打开界面占用,如果是,不允许撤销明细单 + if(JhzjUtils.isLockedBill(clearBillInfo)){ + e.setCancelMessage(clearBillInfo.getString("billno")+"清账单已被他人正在编辑,此明细单无法撤销"); + e.setCancel(true); + } }else if("reject".equals(eok)){ //驳回校验 if(!"B".equals(prinfo.getString("billstatus"))){ @@ -100,6 +110,11 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp e.setCancelMessage(clearBillInfo.getString("billno")+"清账单已审核,此明细单无需驳回"); e.setCancel(true); } + //判断对应的清账单是否已被他人打开界面占用,如果是,不允许驳回明细单 + if(JhzjUtils.isLockedBill(clearBillInfo)){ + e.setCancelMessage(clearBillInfo.getString("billno")+"清账单已被他人正在编辑,此明细单无法驳回"); + e.setCancel(true); + } } } } diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/operate/DepositpreintRedWriteOp.java b/main/java/shjh/jhzj7/fi/fi/plugin/operate/DepositpreintRedWriteOp.java new file mode 100644 index 0000000..23d6ef0 --- /dev/null +++ b/main/java/shjh/jhzj7/fi/fi/plugin/operate/DepositpreintRedWriteOp.java @@ -0,0 +1,49 @@ +package shjh.jhzj7.fi.fi.plugin.operate; + +import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.db.DB; +import kd.bos.db.DBRoute; +import kd.bos.entity.plugin.AbstractOperationServicePlugIn; +import kd.bos.entity.plugin.args.AfterOperationArgs; +import kd.bos.entity.plugin.args.BeforeOperationArgs; +import kd.bos.servicehelper.BusinessDataServiceHelper; +import kd.sdk.plugin.Plugin; + +public class DepositpreintRedWriteOp extends AbstractOperationServicePlugIn implements Plugin { + + private static final String updateSapFlag = "update t_cfm_preinterestbill set fk_shjh_sendsap=0 where fwriteoffpreintbillid=?;"; + + @Override + public void beforeExecuteOperationTransaction(BeforeOperationArgs e) { + super.beforeExecuteOperationTransaction(e); + String eok = e.getOperationKey(); + if("unredwriteoff".equals(eok)){ + //反冲销标识 + DynamicObject[] dos = e.getDataEntities(); + DynamicObject prinfo; + for (int i = 0; i < dos.length; i++) { + prinfo = BusinessDataServiceHelper.loadSingle(dos[i].getPkValue(), dos[i].getDataEntityType().getName()); + //判断预提记账处理单-红单是否已推送了sap,如果已推送了,则不允许反冲销 + if(prinfo.getBoolean("shjh_sendsap")){ + e.setCancelMessage(prinfo.getString("billno") + "已推送至SAP,不允许反冲销"); + e.setCancel(true); + } + } + } + } + + @Override + public void afterExecuteOperationTransaction(AfterOperationArgs e) { + super.afterExecuteOperationTransaction(e); + String eok = e.getOperationKey(); + if("redwriteoff".equals(eok)){ + //冲销标识 + DynamicObject[] dos = e.getDataEntities(); + for (DynamicObject prinfo : dos) { + //预提记账处理单-原蓝单 prinfo 拿此id找到对应的红单并其清空已推送sap标记 + //红单中的被冲销预提单id writeoffpreintbillid 字段存的是蓝单的id + DB.update(DBRoute.of("fi"), updateSapFlag, new Object[]{prinfo.getPkValue()}); + } + } + } +} diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/operate/DepositpreintSapOperation.java b/main/java/shjh/jhzj7/fi/fi/plugin/operate/DepositpreintSapOperation.java index 5b73e86..cb85732 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/operate/DepositpreintSapOperation.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/operate/DepositpreintSapOperation.java @@ -27,6 +27,7 @@ import shjh.jhzj7.fi.fi.utils.domin.ResponseData; import java.math.BigDecimal; import java.text.SimpleDateFormat; +import java.util.Date; /** * 定期预提记账处理 shjh_cim_depositprein_ext-单据推送sap操作插件 @@ -34,7 +35,7 @@ import java.text.SimpleDateFormat; */ public class DepositpreintSapOperation extends AbstractOperationServicePlugIn implements Plugin { - private static final String updateVoucherFlag = "update t_cfm_preinterestbill set fk_shjh_sendsap=1,fk_shjh_sappzh=? where fid=?;"; + private static final String updateVoucherFlag = "update t_cfm_preinterestbill set fk_shjh_sendsap=1,fk_shjh_sappzh=?,fk_shjh_sapyear=? where fid=?;"; private static final String userName = "bos_user";//用户 private static final String voucherName = "gl_voucher";//凭证 private static final String pcName = "shjh_pc";//利润中心 @@ -77,29 +78,98 @@ public class DepositpreintSapOperation extends AbstractOperationServicePlugIn im for (int i = 0; i < dos.length; i++) { prinfo = BusinessDataServiceHelper.loadSingle(dos[i].getPkValue(), dos[i].getDataEntityType().getName()); if(prinfo.getBoolean("shjh_needvoucher") && !prinfo.getBoolean("shjh_sendsap")){ - //如果定期预提记账处理单需要生成凭证且未推送sap的才推送sap - sapReturnData = sendVoucher(prinfo); - if(sapReturnData != null && "0".equals(sapReturnData.getString("code"))){ - //解析sap凭证接口返回值 - respdata = ApiUtils.getResponseData(sapReturnData); - if(respdata == null){ - addErrorInfo(prinfo,"SAP凭证接口返回值为空,详见接口日志"); - continue; + //如果预提记账处理单需要生成凭证且未推送sap的才推送sap + //判断原蓝单和红单,调用sap不同接口 操作类别 冲销预提收益-红单 预提收益-蓝单 + if("preint".equals(prinfo.getString("operatetype"))){ + sapReturnData = sendBlueVoucher(prinfo);//蓝单 + if(sapReturnData != null && "0".equals(sapReturnData.getString("code"))){ + //解析sap凭证接口返回值 + respdata = ApiUtils.getResponseData(sapReturnData); + if(respdata == null){ + addErrorInfo(prinfo,"SAP凭证接口返回值为空,详见接口日志"); + continue; + } + //推送sap成功后,反写已推送标记和sap凭证号和年度至预提单中 + DB.update(DBRoute.of("fi"), updateVoucherFlag, new Object[]{respdata.getNumber(),respdata.getYear(),prinfo.getPkValue()}); + this.operationResult.addSuccessPkId(prinfo.getPkValue()); + }else if(sapReturnData != null){ + addErrorInfo(prinfo,"推送SAP接口失败:"+sapReturnData.getString("msg")); + }else{ + addErrorInfo(prinfo,"推送SAP接口失败,SAP返回值为空;或者金蝶凭证未审核,请检查"); + } + }else if("reverseint".equals(prinfo.getString("operatetype"))){ + sapReturnData = sendRedVoucher(prinfo);//红单 + if(sapReturnData != null && "0".equals(sapReturnData.getString("code"))){ + //解析sap凭证接口返回值 + JSONObject data = sapReturnData.getJSONObject("data"); + if(data == null){ + addErrorInfo(prinfo,"推送SAP接口失败,SAP返回值data为空"); + continue; + } + JSONArray rows = data.getJSONArray("IT_ITEM"); + if(rows == null){ + addErrorInfo(prinfo,"推送SAP接口失败,SAP返回值IT_ITEM为空"); + continue; + } + JSONObject resultData = rows.getJSONObject(0); + if(resultData == null){ + addErrorInfo(prinfo,"推送SAP接口失败,SAP返回值IT_ITEM为空"); + continue; + } + String key = resultData.getString("OBJ_KEY"); + if(JhzjUtils.isEmpty(key)){ + addErrorInfo(prinfo,"推送SAP接口失败,SAP返回值OBJ_KEY为空"); + continue; + } + //推送sap成功后,反写已推送标记和sap凭证号和年度至预提单中 + DB.update(DBRoute.of("fi"), updateVoucherFlag, new Object[]{key.length() >= 10 ? key.substring(0, 10) : key, + key.length() >= 4 ? key.substring(key.length() - 4) : key, prinfo.getPkValue()}); + this.operationResult.addSuccessPkId(prinfo.getPkValue()); + }else if(sapReturnData != null){ + addErrorInfo(prinfo,"推送SAP接口失败:"+sapReturnData.getString("msg")); + }else{ + addErrorInfo(prinfo,"推送SAP接口失败,SAP返回值为空"); } - //推送sap成功后,反写已推送标记和sap凭证号至预提单中 - DB.update(DBRoute.of("fi"), updateVoucherFlag, new Object[]{respdata.getNumber(),prinfo.getPkValue()}); - this.operationResult.addSuccessPkId(prinfo.getPkValue()); - }else if(sapReturnData != null){ - addErrorInfo(prinfo,"推送SAP接口失败:"+sapReturnData.getString("msg")); - }else{ - addErrorInfo(prinfo,"推送SAP接口失败,SAP返回值为空;或者金蝶凭证未审核,请检查"); } } } } } - private JSONObject sendVoucher(DynamicObject prinfo){ + private JSONObject sendRedVoucher(DynamicObject prinfo){ + //SAP反清账接口入参组装和调用 + JSONArray IT_LIST = new JSONArray(); + JSONObject iteminfo = new JSONObject(); + String companyCode = prinfo.getString("org.number"); + //添加公司 + iteminfo.put("BUKRS", companyCode); + String shjh_pzh = prinfo.getString("shjh_sappzh"); + //添加会计凭证编号 + iteminfo.put("BELNR", shjh_pzh); + String shjh_year = prinfo.getString("shjh_sapyear"); + //添加会计年度 + iteminfo.put("GJAHR", shjh_year); + //添加冲销原因-04-跨期冲销;默认04,冲销日期必传 + iteminfo.put("STGRD", "04"); + //添加用户名-操作反清账按钮的用户(OA用户名) + DynamicObject userinfo = BusinessDataServiceHelper.loadSingleFromCache(RequestContext.get().getCurrUserId(), userName); + String oauser = userinfo.getString("shjh_oauser"); + if(JhzjUtils.isEmpty(oauser)){ + iteminfo.put("UNAME","资金系统");//用户名 + }else{ + iteminfo.put("UNAME",oauser);//用户名 + } + //添加反清账日期 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String datestr = sdf.format(new Date()); + iteminfo.put("BUDAT", datestr); + IT_LIST.add(iteminfo); + + JSONObject sapReturnData = SapUtils.sapReversalAPI(IT_LIST,prinfo.getString("billno")); + return sapReturnData; + } + + private JSONObject sendBlueVoucher(DynamicObject prinfo){ //SAP定期预提收益凭证接口入参组装和调用 JSONObject IS_HEADER = new JSONObject();//抬头 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//日期格式化工具 diff --git a/main/java/shjh/jhzj7/fi/fi/utils/JhzjUtils.java b/main/java/shjh/jhzj7/fi/fi/utils/JhzjUtils.java index 7cf84e7..4e80b38 100644 --- a/main/java/shjh/jhzj7/fi/fi/utils/JhzjUtils.java +++ b/main/java/shjh/jhzj7/fi/fi/utils/JhzjUtils.java @@ -414,6 +414,26 @@ public class JhzjUtils { } } + /** + * 根据指定的对象判断是否被他人占用 + * @param prinfo 具体对象,可以是收付款单、清账单和明细单 + **/ + public static boolean isLockedBill(DynamicObject prinfo){ + try (DataMutex dataMutex = DataMutex.create()) { + //对象id dataObjId, 互斥默认分组 groupId, 对象标识 entityKey + Map lockInfo = dataMutex.getLockInfo(prinfo.getString("id"),netctrlgroupId,prinfo.getDataEntityType().getName()); + if(lockInfo != null){ + //说明已经存在锁的信息 + logger.info(prinfo.getString("billno")+"已锁定:"+lockInfo); + return true; + } + } catch (Exception e) { + logger.error(prinfo.getString("billno")+"获取锁定信息异常:"+e); + return false; + } + return false; + } + /** * 根据指定的对象清除网络互斥,让其他人可修改 * @param prinfo 具体对象,可以是收付款单、清账单和明细单