From d07ae19d46252a96fe8a96eebd5c081d9324b55a Mon Sep 17 00:00:00 2001 From: yuxueliang0813 <407010292@qq.com> Date: Mon, 3 Mar 2025 18:28:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E8=B4=A6=E5=8D=95=E5=92=8C=E6=98=8E?= =?UTF-8?q?=E7=BB=86=E5=8D=95=E6=93=8D=E4=BD=9C=E6=8F=92=E4=BB=B6=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operate/ClearAccountBillOperation.java | 104 ++++++++++++++++-- .../operate/ClearDetailBillOperation.java | 100 +++++++++++++++-- .../shjh/jhzj7/fi/fi/utils/JhzjUtils.java | 14 +++ 3 files changed, 200 insertions(+), 18 deletions(-) diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/operate/ClearAccountBillOperation.java b/main/java/shjh/jhzj7/fi/fi/plugin/operate/ClearAccountBillOperation.java index e2facbc..bc7f123 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/operate/ClearAccountBillOperation.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/operate/ClearAccountBillOperation.java @@ -25,9 +25,11 @@ import java.util.*; public class ClearAccountBillOperation extends AbstractOperationServicePlugIn implements Plugin { private static final String updateClearStatus = "update tk_shjh_clear_account set fbillstatus='D' where fid=?;"; + private static final String updateSrcClear = "update tk_shjh_clear_account set fk_shjh_iscopy=1 where fid=?;"; + private static final String updateUnClearStatus = "update tk_shjh_clear_account set fbillstatus='D',fk_shjh_clearstatus='C',fk_shjh_unpzh=? where fid=?;"; private static final String updateDetailStatusByBill = "update tk_shjh_clear_acctdetail set fbillstatus='D' where fk_shjh_clearbillid=?;"; private static final String updateDetailStatusByID = "update tk_shjh_clear_acctdetail set fbillstatus='D' where fid=?;"; - private static final String updateDetailClearStatus = "update tk_shjh_clear_acctdetail set fk_shjh_clearstatus='C' where fk_shjh_clearbillid=?;"; + private static final String updateDetailClearStatus = "update tk_shjh_clear_acctdetail set fbillstatus='D',fk_shjh_clearstatus='C' where fk_shjh_clearbillid=?;"; private static final String entityName = "shjh_clear_acctdetail";//清账明细单 private static final String pzbName = "shjh_jgqzcust";//结构性清账客户映射表 @@ -39,9 +41,9 @@ public class ClearAccountBillOperation extends AbstractOperationServicePlugIn im @Override public void beforeExecuteOperationTransaction(BeforeOperationArgs e) { super.beforeExecuteOperationTransaction(e); - //反清账、作废、复制增加校验。 + //反清账、作废、复制、修改清账单状态增加校验。 String eok = e.getOperationKey(); - if("unclearacctount".equals(eok) || "invalid".equals(eok) || "copy".equals(eok)){ + if("unclearacctount".equals(eok) || "invalid".equals(eok) || "copyqz".equals(eok) || "updatestatus".equals(eok)){ DynamicObject[] dos = e.getDataEntities(); DynamicObject prinfo; String billno; @@ -67,13 +69,19 @@ public class ClearAccountBillOperation extends AbstractOperationServicePlugIn im e.setCancelMessage(billno+"【单据状态】=暂存 and【清账状态】=待清账,才允许作废"); e.setCancel(true); } - }else if("copy".equals(eok)){ + }else if("copyqz".equals(eok)){ //清账单【单据状态】=作废 and【清账状态】=反清账 and【反清后处理方式】=收款信息变更 and【是否被复制】=否,才允许复制按钮。 if(!"D".equals(billstatus) || !"C".equals(clearstatus) || !"B".equals(prinfo.getString("shjh_unclearway")) || prinfo.getBoolean("shjh_iscopy")){ e.setCancelMessage(billno+"【单据状态】=作废 and【清账状态】=反清账 and【反清后处理方式】=收款信息变更 and【是否被复制】=否,才允许复制"); e.setCancel(true); } + }else if("updatestatus".equals(eok)){ + //清账单【单据状态】=暂存 and【清账状态】=待清账,才允许点击修改清账单状态。 + if(!"A".equals(billstatus) || !"B".equals(clearstatus)){ + e.setCancelMessage(billno+"【单据状态】=暂存 and【清账状态】=待清账,才允许修改清账单状态"); + e.setCancel(true); + } } } } @@ -103,6 +111,44 @@ public class ClearAccountBillOperation extends AbstractOperationServicePlugIn im case "audit": handleAudit(e);//审核 case "notice": handleNotice(e);//清账实时通知 case "invalid": handleInvalid(e);//作废 + case "copyqz": handleCopy(e);//复制 + case "updatestatus": handleUpdateStatus(e);//修改清账单状态 + } + } + + private void handleUpdateStatus(AfterOperationArgs e){ + //清账单清账状态支持手工修改,可由待清账转为已清账状态并填写清账原因 + DynamicObject[] dos = e.getDataEntities(); + DynamicObject prinfo; + for (int i = 0; i < dos.length; i++) { + prinfo = dos[i]; + //TODO 点击此按钮,弹框填写修改原因。填写后,可由待清账改为已清账,单据状态改为已审核; + //TODO 反写上游收款单,分录行【清账状态】=已清账。 + //下游清账明细单,【单据状态】=作废。若清账信息有误,需在SAP反清账后修改。 + DB.update(DBRoute.of("fi"), updateDetailStatusByBill, new Object[]{prinfo.getString("id")}); + //下游清账明细单处理OA已办 + handleOAUpdate(prinfo.getString("id")); + } + } + + private void handleOAUpdate(String clearbillid){ + DynamicObject[] ddos = BusinessDataServiceHelper.load(entityName,"id,billno,billstatus,shjh_clearbillid,shjh_clearbillno,createtime,creator,modifier", + new QFilter[]{new QFilter("shjh_clearbillid","=", clearbillid)}); + DynamicObject detailinfo; + for (int j = 0; j < ddos.length; j++) { + detailinfo = ddos[j]; + //消除OA待办为已办 + JhzjUtils.handleOA(detailinfo,"2", "0"); + } + } + + private void handleCopy(AfterOperationArgs e){ + DynamicObject[] dos = e.getDataEntities(); + DynamicObject prinfo; + for (int i = 0; i < dos.length; i++) { + prinfo = dos[i]; + //根据源清账单复制一份新的清账单出来 + handleCopyInfo(prinfo); } } @@ -174,16 +220,60 @@ public class ClearAccountBillOperation extends AbstractOperationServicePlugIn im private void handleUnClear(AfterOperationArgs e){ //反清账具体实现 - //TODO 调用SAP反清账接口,更新清账单中反清状态和反清凭证号。 - //撤销原有清账信息。更新清账单【清账状态】=反清账,清账明细单【清账状态】=反清账。 DynamicObject[] dos = e.getDataEntities(); - DynamicObject prinfo; + DynamicObject prinfo;//清账单 + String fqzpzh;//反清账凭证号 for (int i = 0; i < dos.length; i++) { prinfo = dos[i]; + //TODO 调用SAP反清账接口,更新清账单中反清状态和反清凭证号。 + fqzpzh = null; + if(fqzpzh == null){ + this.operationResult.setSuccess(false); + this.operationResult.setMessage("反清账失败,原因是:");//前端界面提示内容 + this.operationResult.setShowMessage(true);//前端界面 是否显示提示消息 + continue; + } + //若SAP反清成功,清账单【单据状态】=作废,【清账状态】=反清账,反写【反清账凭证号】。 + DB.update(DBRoute.of("fi"), updateUnClearStatus, new Object[]{fqzpzh,prinfo.getLong("id")}); + //更新下游清账明细单【单据状态】=作废;【清账状态】=反清账。 DB.update(DBRoute.of("fi"), updateDetailClearStatus, new Object[]{prinfo.getString("id")}); + //TODO 更新上游收款单分录行【清账状态】=反清账,表头清账状态如何标记? + + //若选择的反清后处理方式=重新清账,则复制原清账单,在新清账单上重新清账 + if("".equals(prinfo.getString(""))){ + handleCopyInfo(prinfo); + } } } + private void handleCopyInfo(DynamicObject srcinfo){ + //根据清账单复制另一个清账单出来 + //被复制的字段为:公司、币别、收款单编号、收款凭证号、收款金额、客户、业务大类、业务小类 + DynamicObject destinfo = BusinessDataServiceHelper.newDynamicObject(srcinfo.getDataEntityType().getName()); + destinfo.set("org",srcinfo.getDynamicObject("org"));//公司 + destinfo.set("shjh_currency",srcinfo.getDynamicObject("shjh_currency"));//币别 + destinfo.set("shjh_customer",srcinfo.getDynamicObject("shjh_customer"));//客户 + destinfo.set("shjh_recebillno",srcinfo.getString("shjh_recebillno"));//收款单编号 + destinfo.set("shjh_recepzh",srcinfo.getString("shjh_recepzh"));//收款单凭证号 + destinfo.set("shjh_receamount",srcinfo.getBigDecimal("shjh_receamount"));//收款金额 + destinfo.set("shjh_bizbig",srcinfo.getDynamicObject("shjh_bizbig"));//业务大类 + destinfo.set("shjh_bizsmall",srcinfo.getDynamicObject("shjh_bizsmall"));//业务小类 + + //新清账单需处理的字段为:业务日期为源清账单的反清账日期;单据状态=暂存;清账日期=业务日期,可修改;清账状态=待清账;已认领收款金额=0; + //未认领收款金额=收款金额;源清账单号=被复制的清账单单号;【是否被复制】=否 + destinfo.set("shjh_bizdate",srcinfo.getDate("shjh_uncleardate"));//业务日期 + destinfo.set("billstatus","A");//单据状态-暂存 + destinfo.set("",srcinfo.getDate("shjh_uncleardate"));//清账日期=业务日期 + destinfo.set("shjh_clearstatus","B");//清账状态-待清账 + destinfo.set("",BigDecimal.ZERO);//已认领收款金额=0 + destinfo.set("",srcinfo.getBigDecimal("shjh_receamount"));//未认领收款金额=收款金额 + destinfo.set("",srcinfo.getString("billno"));//源清账单号=被复制的清账单单号 + + SaveServiceHelper.save(new DynamicObject[]{destinfo}); + //原清账单:【是否被复制】=是 + DB.update(DBRoute.of("fi"), updateSrcClear, new Object[]{srcinfo.getLong("id")}); + } + private void handleAudit(AfterOperationArgs e){ //审核具体实现 DynamicObject[] dos = e.getDataEntities(); 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 e871e38..1d3d96e 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/operate/ClearDetailBillOperation.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/operate/ClearDetailBillOperation.java @@ -13,6 +13,8 @@ import kd.sdk.plugin.Plugin; import shjh.jhzj7.fi.fi.utils.JhzjUtils; import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; /** * 清账明细单据操作插件 @@ -39,7 +41,7 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp DynamicObject clearBillInfo;//清账单 String billno; for (int i = 0; i < dos.length; i++) { - //反审核操作之前系统未把info对象所有属性加载出来,尤其是二开的字段,需要在此处重新load一下 + //列表操作时系统未把info对象所有属性加载出来,尤其是二开的字段,需要在此处重新load一下 prinfo = BusinessDataServiceHelper.loadSingle(dos[i].getPkValue(),dos[i].getDataEntityType().getName()); billno = prinfo.getString("billno"); if("submit".equals(eok)){ @@ -58,12 +60,21 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp e.setCancelMessage(clearBillInfo.getString("billno")+"清账单已提交,此明细单无需提交"); e.setCancel(true); } - }else if("revoke".equals(eok) && !"B".equals(prinfo.getString("billstatus"))){ - //清账明细单【单据状态】=已提交,才允许撤销 - e.setCancelMessage(billno+"【单据状态】=已提交,才允许撤销"); - e.setCancel(true); + }else if("revoke".equals(eok)){ + //撤销校验 + if(!"B".equals(prinfo.getString("billstatus"))){ + //清账明细单【单据状态】=已提交,才允许撤销 + e.setCancelMessage(billno+"【单据状态】=已提交,才允许撤销"); + 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("reject".equals(eok)){ + //驳回校验 if(!"B".equals(prinfo.getString("billstatus"))){ //清账明细单【单据状态】=已提交,才允许点击驳回按钮 e.setCancelMessage(billno+"【单据状态】=已提交,才允许驳回"); @@ -113,9 +124,9 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp super.afterExecuteOperationTransaction(e); String eok = e.getOperationKey(); switch (eok){ - case "submit": handleSubmit(e);//提交 - case "revoke": handleRevoke(e);//撤销 - case "reject": handleReject(e);//驳回 + case "submit": handleSubmit(e);//提交--业务主动点击 + case "revoke": handleRevoke(e);//撤销--业务主动点击 + case "reject": handleReject(e);//驳回--财务人员主动点击 } } @@ -126,7 +137,7 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp String result; for (int i = 0; i < dos.length; i++) { prinfo = dos[i]; - //TODO 将清账明细分录反写至清账单分录,清账单【收款金额】+【账扣】+【尾差】≥【本次核销金额合计】 + //将清账明细分录反写至清账单分录,清账单【收款金额】+【账扣】+【尾差】≥【本次核销金额合计】 result = reWriteClearBill(prinfo); if(!"success".equals(result)){ this.operationResult.setSuccess(false); @@ -140,7 +151,7 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp } private String reWriteClearBill(DynamicObject detailBillInfo){ - //根据清账明细单反写清账单 + //根据清账明细单反写清账单-新增 String clearBillid = detailBillInfo.getString("shjh_clearbillid"); DynamicObject clearBillInfo = BusinessDataServiceHelper.loadSingle(clearBillid,clearBillName); if(clearBillInfo == null){ @@ -176,6 +187,7 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp clearEntryInfo.set("",detailEntryInfo.getBigDecimal(""));//本次核销金额 clearEntryInfo.set("",detailEntryInfo.getString(""));//会计年度 clearEntryInfo.set("",detailEntryInfo.getString(""));// 清账凭证文本 + clearEntryInfo.set("",detailEntryInfo.getString("id"));// 明细单分录ID } //处理清账单账扣 BigDecimal q1 = JhzjUtils.addTwoAmount(clearBillInfo.getBigDecimal(""), @@ -204,13 +216,69 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp return "success"; } + private String reDeleteClearBill(DynamicObject detailBillInfo){ + //根据清账明细单反写清账单-删除 + String clearBillid = detailBillInfo.getString("shjh_clearbillid"); + DynamicObject clearBillInfo = BusinessDataServiceHelper.loadSingle(clearBillid,clearBillName); + if(clearBillInfo == null){ + return detailBillInfo.getString("shjh_clearbillno")+"清账单未找到"; + } + //给清账单增加互斥锁,如果失败反馈用户 + String lockresult = JhzjUtils.lockBill(clearBillInfo); + if(!"success".equals(lockresult)){ + return clearBillInfo.getString("billno")+lockresult; + } + //清账明细单分录 + DynamicObjectCollection detaildoc = detailBillInfo.getDynamicObjectCollection(""); + Set idsets = new HashSet<>(detaildoc.size()); + DynamicObject detailEntryInfo; + for (int i = 0; i < detaildoc.size(); i++) { + detailEntryInfo = detaildoc.get(i); + idsets.add(detailEntryInfo.getString("id")); + } + + //清账单分录 + DynamicObjectCollection cleardoc = clearBillInfo.getDynamicObjectCollection(""); + DynamicObject clearEntryInfo; + for (int i = cleardoc.size()-1; i >=0; i--) { + clearEntryInfo = cleardoc.get(i); + if(idsets.contains(clearEntryInfo.getString("id"))){ + cleardoc.remove(clearEntryInfo); + } + } + //处理清账单账扣 + BigDecimal q1 = JhzjUtils.reduceTwoAmount(clearBillInfo.getBigDecimal(""), + detailBillInfo.getBigDecimal("")); + clearBillInfo.set("",q1); + //处理清账单尾差 + BigDecimal q2 = JhzjUtils.reduceTwoAmount(clearBillInfo.getBigDecimal(""), + detailBillInfo.getBigDecimal("")); + clearBillInfo.set("",q2); + + SaveServiceHelper.save(new DynamicObject[]{clearBillInfo}); + //解除清账单互斥锁 + JhzjUtils.unLockBill(clearBillInfo); + + return "success"; + } + private void handleRevoke(AfterOperationArgs e){ //撤销具体实现 - //清账明细单,单据状态变成暂存 DynamicObject[] dos = e.getDataEntities(); DynamicObject prinfo; + String result; for (int i = 0; i < dos.length; i++) { prinfo = dos[i]; + + //删除对应清账单中由明细单反写的表头和分录数据 + result = reDeleteClearBill(prinfo); + if(!"success".equals(result)){ + this.operationResult.setSuccess(false); + this.operationResult.setMessage("反写清账单失败,原因是:"+result);//前端界面提示内容 + this.operationResult.setShowMessage(true);//前端界面 是否显示提示消息 + continue; + } + //清账明细单,单据状态变成暂存 DB.update(DBRoute.of("fi"), updateDetailSave, new Object[]{prinfo.getLong("id")}); } } @@ -219,12 +287,22 @@ public class ClearDetailBillOperation extends AbstractOperationServicePlugIn imp //驳回具体实现 DynamicObject[] dos = e.getDataEntities(); DynamicObject prinfo; + String result; for (int i = 0; i < dos.length; i++) { prinfo = BusinessDataServiceHelper.loadSingle(dos[i].getPkValue(),dos[i].getDataEntityType().getName()); + //驳回时,删除对应清账单中由明细单反写的表头和分录数据 + result = reDeleteClearBill(prinfo); + if(!"success".equals(result)){ + this.operationResult.setSuccess(false); + this.operationResult.setMessage("反写清账单失败,原因是:"+result);//前端界面提示内容 + this.operationResult.setShowMessage(true);//前端界面 是否显示提示消息 + continue; + } //若清账单【单据状态】=已提交,则更新清账单【单据状态】=暂存。 DB.update(DBRoute.of("fi"), updateClearBillSave, new Object[]{prinfo.getString("shjh_clearbillid")}); //清账明细单【单据状态】=驳回 DB.update(DBRoute.of("fi"), updateDetailReject, new Object[]{prinfo.getLong("id")}); + //驳回时,对清账明细单修改人发送邮件通知,OA待办 业务员可修改后,再次提交。 JhzjUtils.sendEmail(prinfo.getDynamicObject("modifier").getString("email"),"请登录资金系统操作清账明细单", prinfo.getString("billno")+"\n 详情页面"+JhzjUtils.getBillPCURL(prinfo),"清账明细单新增"); diff --git a/main/java/shjh/jhzj7/fi/fi/utils/JhzjUtils.java b/main/java/shjh/jhzj7/fi/fi/utils/JhzjUtils.java index c77e4cc..e1378f9 100644 --- a/main/java/shjh/jhzj7/fi/fi/utils/JhzjUtils.java +++ b/main/java/shjh/jhzj7/fi/fi/utils/JhzjUtils.java @@ -253,6 +253,20 @@ public class JhzjUtils { return BigDecimal.ZERO; } + /* + * 两个金额字段相减,如果两个都为null,返回0 + * */ + public static BigDecimal reduceTwoAmount(BigDecimal a1, BigDecimal a2){ + if(a1 == null && a2 != null){ + return a2.negate();//取负数 + }else if(a2 == null && a1 != null){ + return a1; + }else if(a1 != null && a2 != null){ + return a1.subtract(a2); + } + return BigDecimal.ZERO; + } + /** * 根据指定的对象获取其详情界面的url * @param prinfo 具体对象,可以是收付款单、清账单和明细单