From 1e4be8f2bde182ac279d0ccc272804c38605014e Mon Sep 17 00:00:00 2001 From: zengweihai Date: Mon, 20 May 2024 13:58:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E6=A0=A1=E9=AA=8C=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validator/CommonAmountCheckCondition.java | 232 ++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 shkd-cosmic-debug/src/main/java/kd/fi/er/business/datacheck/validator/CommonAmountCheckCondition.java diff --git a/shkd-cosmic-debug/src/main/java/kd/fi/er/business/datacheck/validator/CommonAmountCheckCondition.java b/shkd-cosmic-debug/src/main/java/kd/fi/er/business/datacheck/validator/CommonAmountCheckCondition.java new file mode 100644 index 0000000..2f4026e --- /dev/null +++ b/shkd-cosmic-debug/src/main/java/kd/fi/er/business/datacheck/validator/CommonAmountCheckCondition.java @@ -0,0 +1,232 @@ +package kd.fi.er.business.datacheck.validator; + +import java.math.BigDecimal; +import java.util.function.Function; +import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.dataentity.entity.DynamicObjectCollection; +import kd.bos.dataentity.metadata.IDataEntityProperty; +import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection; +import kd.bos.dataentity.resource.ResManager; +import kd.bos.logging.Log; +import kd.bos.logging.LogFactory; +import kd.fi.er.business.domain.amount.BillAmountServiceFacade; +import kd.fi.er.business.domain.amount.IBillAmountService; +import kd.fi.er.business.domain.amount.ILoanBillAmountService; +import kd.fi.er.business.domain.amount.IReimurseBillAmountSevice; +import kd.fi.er.business.isc.IscHelper; +import kd.fi.er.business.utils.AmountUtils; +import kd.fi.er.business.utils.ErEntityTypeUtils; +import kd.fi.er.business.utils.ErStdConfig; +import kd.fi.er.business.utils.FieldNameHelper; +import kd.fi.er.common.field.expenseentry.ExpenseEntryFields; +import kd.fi.er.common.field.head.BillHeadFields; +import org.apache.commons.lang3.StringUtils; + +public class CommonAmountCheckCondition { + private static Log logger = LogFactory.getLog(CommonAmountCheckCondition.class); +// public static final Function encashedAmtValidator = encashedAmtValidator(); +// public static final Function reCalcEncashedAmtValidator = reCalcEncashedAmtValidator(); +// public static final Function accountEntryAmtValidator = accountEntryAmtValidator(); +// public static final Function sumOfEntryAndHeadAmtValidator = sumOfEntryAndHeadAmtValidator(); +// public static final Function payOrNotAmtValidator = payOrNotAmtValidator(); +// public static final Function reCalcEntryCurApproveAmtValidator = reCalcEntryCurApproveAmtValidator(); + + + + public CommonAmountCheckCondition() { + } + + public static Function encashedAmtValidator() { + return (dataEntity) -> { + String entityname = dataEntity.getDataEntityType().getName(); + BillHeadFields billHeadInstance = FieldNameHelper.getBillHeadInstance(entityname); + if (billHeadInstance != null) { + if (ErEntityTypeUtils.isApplyPayBill(entityname)) { + return null; + } + + BigDecimal payAmount = dataEntity.getBigDecimal(billHeadInstance.encashAmtField); + DynamicObjectCollection accEntry = dataEntity.getDynamicObjectCollection("accountentry"); + BigDecimal accEntryTotalPayAmount = (BigDecimal)accEntry.stream().map((row) -> { + return row.getBigDecimal("receiveamount"); + }).reduce(BigDecimal.ZERO, BigDecimal::add); + if (payAmount.compareTo(accEntryTotalPayAmount) != 0) { + String currencySign = dataEntity.getDynamicObject("currency").getString("sign"); + return String.format(ResManager.loadKDString("付现金额和收款信息分录不相等。付现金额%1$s,收款信息收款金额总计%2$s。", "CommonAmountCheckCondition_0", "fi-er-business", new Object[0]), StringUtils.joinWith((String)null, new Object[]{currencySign, stripTrailingZeros(payAmount)}), StringUtils.joinWith((String)null, new Object[]{currencySign, stripTrailingZeros(accEntryTotalPayAmount)})); + } + } + + return null; + }; + } + + public static Function reCalcEncashedAmtValidator() { + return (dataEntity) -> { + if (ErStdConfig.get("ext.service.er.payamountCalc") != null) { + return null; + } else { + IBillAmountService service = BillAmountServiceFacade.getService(dataEntity.getDataEntityType().getName()); + if (service != null) { + BigDecimal calcPayAmount = service.calcPayAmount(dataEntity); + BigDecimal payAmountNow = service.getPayAmountNow(dataEntity); + if (payAmountNow.compareTo(calcPayAmount) != 0) { + if (calcPayAmount.compareTo(BigDecimal.ZERO) < 0 && payAmountNow.compareTo(BigDecimal.ZERO) == 0) { + return null; + } + + return String.format(ResManager.loadKDString("单头付现金额%1s和重新计算的付现金额%2s不相等,数据疑似发生错误。", "CommonAmountCheckCondition_1", "fi-er-business", new Object[0]), stripTrailingZeros(payAmountNow), stripTrailingZeros(calcPayAmount)); + } + } + + return null; + } + }; + } + + public static String stripTrailingZeros(BigDecimal decimal) { + return decimal == null ? "null" : decimal.stripTrailingZeros().toPlainString(); + } + + public static Function accountEntryAmtValidator() { + return (dataEntity) -> { + IDataEntityProperty accountEntryProp = (IDataEntityProperty)dataEntity.getDataEntityType().getProperties().get("accountentry"); + if (accountEntryProp != null) { + DynamicObjectCollection accEntry = dataEntity.getDynamicObjectCollection("accountentry"); + + for(int idx = 0; idx < accEntry.size(); ++idx) { + DynamicObject row = (DynamicObject)accEntry.get(idx); + BigDecimal receiveAmount = row.getBigDecimal("receiveamount"); + BigDecimal oriReceiveAmount = row.getBigDecimal("orireceiveamount"); + BigDecimal exchangeRate = row.getBigDecimal("accexchangerate"); + DynamicObject currency = dataEntity.getDynamicObject("currency"); + int precision = 2; + if (currency != null) { + precision = currency.getInt("amtprecision"); + } + + String quoteType = StringUtils.isBlank(row.getString("accquotetype")) ? "0" : row.getString("accquotetype"); + BigDecimal realReceviceAmount = AmountUtils.getCurrencyAmount(oriReceiveAmount, exchangeRate, precision, quoteType); + if (realReceviceAmount.subtract(receiveAmount).abs().compareTo(new BigDecimal("0.1")) > 0) { + String currencySign = dataEntity.getDynamicObject("currency").getString("sign"); + return String.format(ResManager.loadKDString("收款信息分录第%1$s行,收款金额本位币%2$s, 实际计算收款金额本位币%3$s 存在较大误差。", "CommonAmountCheckCondition_2", "fi-er-business", new Object[0]), idx + 1, StringUtils.joinWith((String)null, new Object[]{currencySign, stripTrailingZeros(receiveAmount)}), StringUtils.joinWith((String)null, new Object[]{currencySign, stripTrailingZeros(realReceviceAmount)})); + } + } + } + + return null; + }; + } + + public static Function payOrNotAmtValidator() { + return !IscHelper.isIntegratedWithEAS() && !IscHelper.isIntegratedWithXK() ? (dataEntity) -> { + String entityName = dataEntity.getDataEntityType().getName(); + BillHeadFields billHeadInstance = FieldNameHelper.getBillHeadInstance(entityName); + if (ErEntityTypeUtils.isApplyPayBill(entityName)) { + return null; + } else { + if (billHeadInstance != null) { + BigDecimal notPayAmount = dataEntity.getBigDecimal("notpayamount"); + BigDecimal payAmount = dataEntity.getBigDecimal(billHeadInstance.payedAmtFiled); + BigDecimal encashAmount = dataEntity.getBigDecimal(billHeadInstance.encashAmtField); + if (encashAmount.subtract(payAmount.add(notPayAmount)).compareTo(BigDecimal.ZERO) != 0) { + return ResManager.loadKDString("单头未付金额加已付金额不等于付现金额。", "CommonAmountCheckCondition_3", "fi-er-formplugin", new Object[0]); + } + } + + DataEntityPropertyCollection properties = dataEntity.getDataEntityType().getProperties(); + IDataEntityProperty accountEntryProp = (IDataEntityProperty)properties.get("accountentry"); + if (accountEntryProp != null) { + DynamicObjectCollection accEntry = dataEntity.getDynamicObjectCollection("accountentry"); + + for(int index = accEntry.getStartRowIndex(); index < accEntry.size(); ++index) { + DynamicObject row = (DynamicObject)accEntry.get(index); + BigDecimal receiveAmount = row.getBigDecimal("receiveamount"); + BigDecimal payAmountx = row.getBigDecimal("accpayedamount"); + BigDecimal notPayAmountx = row.getBigDecimal("accnotpayamount"); + if (receiveAmount.subtract(payAmountx.add(notPayAmountx)).compareTo(BigDecimal.ZERO) != 0) { + String currencySign = dataEntity.getDynamicObject("currency").getString("sign"); + return String.format(ResManager.loadKDString("收款信息分录第%1$s行,未付金额本位币%2$s与已付金额本位币%3$s之和,不等于收款金额本位币%4$s。", "CommonAmountCheckCondition_4", "fi-er-business", new Object[0]), index + 1, StringUtils.joinWith((String)null, new Object[]{currencySign, stripTrailingZeros(notPayAmountx)}), StringUtils.joinWith((String)null, new Object[]{currencySign, stripTrailingZeros(payAmountx)}), StringUtils.joinWith((String)null, new Object[]{currencySign, stripTrailingZeros(receiveAmount)})); + } + } + } + + return null; + } + } : null; + } + + public static Function sumOfEntryAndHeadAmtValidator() { + return !IscHelper.isIntegratedWithEAS() && !IscHelper.isIntegratedWithXK() ? (dataEntity) -> { + IBillAmountService service = BillAmountServiceFacade.getService(dataEntity.getDataEntityType().getName()); + if (service != null) { + DataEntityPropertyCollection properties = dataEntity.getDataEntityType().getProperties(); + if (properties.get("approveamount") != null) { + BigDecimal sumApproveAmountOfEntry = service.calcCurrApproveAmount(dataEntity); + BigDecimal headApproveAmount = dataEntity.getBigDecimal("approveamount"); + if (sumApproveAmountOfEntry.compareTo(headApproveAmount) != 0) { + return String.format(ResManager.loadKDString("[费用明细/借款明细/差旅明细]分录核定金额汇总%1$s与单头核定金额%2$s不相等。", "CommonAmountCheckCondition_5", "fi-er-business", new Object[0]), stripTrailingZeros(sumApproveAmountOfEntry), stripTrailingZeros(headApproveAmount)); + } + } + + if (service instanceof ILoanBillAmountService) { + return (new BizAmountCheckCondition.LoanBizAmountCheck()).sumOfEntryAndHeadValidator(dataEntity, (ILoanBillAmountService)service); + } + + if (service instanceof IReimurseBillAmountSevice) { + return (new BizAmountCheckCondition.ReimBurseBizAmountCheck()).sumOfEntryAndHeadValidator(dataEntity, (IReimurseBillAmountSevice)service); + } + } + + return null; + } : null; + } + + public static Function reCalcEntryCurApproveAmtValidator() { + return (dataEntity) -> { + ExpenseEntryFields expenseEntryFields = FieldNameHelper.getExpenseEntryFields(dataEntity.getDataEntityType().getName()); + String msg = null; + if (expenseEntryFields != null) { + int currencyPrecision = AmountUtils.getCurrencyPrecision(dataEntity, expenseEntryFields.currencyKey); + if (expenseEntryFields.isTripExpenseEntry()) { + DynamicObjectCollection tripEntries = dataEntity.getDynamicObjectCollection("tripentry"); + boolean isCardView = "0".equals(dataEntity.getString("billkind")); + String entryName = tripEntries.getDynamicObjectType().getDisplayName().getLocaleValue_zh_CN(); + + for(int index = 0; index < tripEntries.size(); ++index) { + msg = reCalcEntryCurApproveAmt((DynamicObject)tripEntries.get(index), expenseEntryFields, currencyPrecision); + if (msg != null) { + if (isCardView) { + msg = ResManager.loadKDString(String.format("%1$s第%2$s个行程中", entryName, index + 1), "CommonAmountCheckCondition_9", "fi-er-business", new Object[0]) + msg; + } + + return msg; + } + } + } else { + msg = reCalcEntryCurApproveAmt(dataEntity, expenseEntryFields, currencyPrecision); + } + } + + return msg; + }; + } + + public static String reCalcEntryCurApproveAmt(DynamicObject dynamicObject, ExpenseEntryFields expenseEntryFields, int precision) { + DynamicObjectCollection entryEnties = dynamicObject.getDynamicObjectCollection(expenseEntryFields.entryKey); + String localeValue = entryEnties.getDynamicObjectType().getDisplayName().getLocaleValue_zh_CN(); + + for(int index = 0; index < entryEnties.size(); ++index) { + DynamicObject row = (DynamicObject)entryEnties.get(index); + BigDecimal oriApproveAmt = row.getBigDecimal(expenseEntryFields.oriApproveAmtKey); + BigDecimal curApproveAmt = row.getBigDecimal(expenseEntryFields.curApproveAmtKey); + BigDecimal exchangeRate = row.getBigDecimal(expenseEntryFields.entryExchangerateKey); + String quoteType = row.getString(expenseEntryFields.quoteType); + BigDecimal recalcurAppAmount = AmountUtils.getCurrencyAmount(oriApproveAmt, exchangeRate, precision, quoteType); + if (recalcurAppAmount.subtract(curApproveAmt).abs().compareTo(new BigDecimal("0.1")) > 0) { + return ResManager.loadKDString(String.format("第%1$s行%2$s重算的核定金额(本位币)与分录存储核定金额(本位币)的值存在差异,数据可能发生错误。【核定金额:%3$s,汇率:%4$s,换算方式:%5$s,重算后的核定金额(本位币):%6$s。 核定金额(本位币):%7$s】", index + 1, localeValue, stripTrailingZeros(oriApproveAmt), stripTrailingZeros(exchangeRate), quoteType, stripTrailingZeros(recalcurAppAmount), stripTrailingZeros(curApproveAmt)), "CommonAmountCheckCondition_10", "fi-er-business", new Object[0]); + } + } + + return null; + } +}