|
@@ -0,0 +1,694 @@
|
|
|
+package fi.fa.opplugin;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Comparator;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import kd.bos.dataentity.entity.DynamicObject;
|
|
|
+import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
|
+import kd.bos.dataentity.metadata.dynamicobject.DynamicProperty;
|
|
|
+import kd.bos.dataentity.resource.ResManager;
|
|
|
+import kd.bos.dataentity.utils.StringUtils;
|
|
|
+import kd.bos.entity.EntityMetadataCache;
|
|
|
+import kd.bos.entity.MainEntityType;
|
|
|
+import kd.bos.entity.property.BasedataProp;
|
|
|
+import kd.bos.entity.property.DateProp;
|
|
|
+import kd.bos.entity.property.DecimalProp;
|
|
|
+import kd.bos.entity.property.EntryProp;
|
|
|
+import kd.bos.entity.property.LongProp;
|
|
|
+import kd.bos.entity.property.TextProp;
|
|
|
+import kd.bos.entity.validate.BillStatus;
|
|
|
+import kd.bos.exception.KDBizException;
|
|
|
+import kd.bos.logging.Log;
|
|
|
+import kd.bos.logging.LogFactory;
|
|
|
+import kd.bos.orm.query.QFilter;
|
|
|
+import kd.bos.servicehelper.BusinessDataServiceHelper;
|
|
|
+import kd.bos.servicehelper.QueryServiceHelper;
|
|
|
+import kd.bos.servicehelper.botp.BFTrackerServiceHelper;
|
|
|
+import kd.fi.fa.business.calc.DynamicObjectWrapper;
|
|
|
+import kd.fi.fa.business.enums.lease.InterestAmortizeSchema;
|
|
|
+import kd.fi.fa.business.enums.lease.LeaseContractBizStatus;
|
|
|
+import kd.fi.fa.business.enums.lease.LeaseContractRentSettleStatus;
|
|
|
+import kd.fi.fa.business.enums.lease.LeaseContractSourceType;
|
|
|
+import kd.fi.fa.business.enums.lease.PayFrequency;
|
|
|
+import kd.fi.fa.business.lease.LeaseContractCal;
|
|
|
+import kd.fi.fa.business.lease.LeaseFutureBizChecker;
|
|
|
+import kd.fi.fa.business.lease.model.PayRuleCompareResult;
|
|
|
+import kd.fi.fa.business.lease.utils.LeaseChangeUtil;
|
|
|
+import kd.fi.fa.business.lease.utils.LeaseUtil;
|
|
|
+import kd.fi.fa.business.utils.FaBizUtils;
|
|
|
+import kd.fi.fa.business.utils.FaDepreUtil;
|
|
|
+import kd.fi.fa.business.utils.FaUtils;
|
|
|
+import kd.fi.fa.business.utils.SystemParamHelper;
|
|
|
+import kd.fi.fa.common.util.DateUtil;
|
|
|
+import kd.fi.fa.common.util.Fa;
|
|
|
+
|
|
|
+public class LeaseChangeBillExValidator {
|
|
|
+ private static final Log logger = LogFactory.getLog(LeaseChangeBillExValidator.class);
|
|
|
+ private static final Set<String> EFFECTIVE_FIN_ITEMS = new HashSet<String>() {
|
|
|
+ {
|
|
|
+ this.add("payruleentryentity");
|
|
|
+ this.add("leaseenddate");
|
|
|
+ this.add("discountrate");
|
|
|
+ this.add("leaser");
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ public LeaseChangeBillExValidator() {
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<String> validate4Save(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(2);
|
|
|
+ String billNo = bill.getString("billno");
|
|
|
+ if (StringUtils.isBlank(billNo)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("“单据编号”不能为空。", "LeaseChangeBillValidator_0", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ if (leaseContract == null) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("“原合同”不能为空。", "LeaseChangeBillValidator_1", "fi-fa-business", new Object[0]));
|
|
|
+ } else {
|
|
|
+ String bizStatus = leaseContract.getString("bizstatus");
|
|
|
+ boolean fromDatabase = bill.getDataEntityState().getFromDatabase();
|
|
|
+ if (!fromDatabase && !LeaseContractBizStatus.A.name().equals(bizStatus)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("“原合同”业务状态不是“正常”,不允许变更。", "LeaseChangeBillValidator_2", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ DynamicObjectCollection changeItems = bill.getDynamicObjectCollection("changeitems");
|
|
|
+ if (changeItems.isEmpty()) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("“变更项目”不能为空。", "LeaseChangeBillValidator_3", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ vadateChangeItemInDbIsChanged(bill, errorInfo);
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void vadateChangeItemInDbIsChanged(DynamicObject bill, List<String> errorInfo) {
|
|
|
+ if (bill != null) {
|
|
|
+ Object id = bill.getPkValue();
|
|
|
+ if (id != null && (Long)id != 0L) {
|
|
|
+ boolean isExistedBill = QueryServiceHelper.exists("fa_lease_change_bill", id);
|
|
|
+ if (isExistedBill) {
|
|
|
+ DynamicObject changeBillInDb = BusinessDataServiceHelper.loadSingle(id, "fa_lease_change_bill", "changeitems");
|
|
|
+ Set<Object> itemsSetInDb = new HashSet(8);
|
|
|
+ DynamicObjectCollection itemsInDb = changeBillInDb.getDynamicObjectCollection("changeitems");
|
|
|
+ Iterator var7 = itemsInDb.iterator();
|
|
|
+
|
|
|
+ while(var7.hasNext()) {
|
|
|
+ DynamicObject items1 = (DynamicObject)var7.next();
|
|
|
+ DynamicObject item = items1.getDynamicObject("fbasedataid");
|
|
|
+ itemsSetInDb.add(item.getPkValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ DynamicObjectCollection items = bill.getDynamicObjectCollection("changeitems");
|
|
|
+ Set<Object> itemsSet = new HashSet(8);
|
|
|
+ Iterator var14 = items.iterator();
|
|
|
+
|
|
|
+ while(var14.hasNext()) {
|
|
|
+ DynamicObject item1 = (DynamicObject)var14.next();
|
|
|
+ DynamicObject item = item1.getDynamicObject("fbasedataid");
|
|
|
+ itemsSet.add(item.getPkValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ itemsSetInDb.removeAll(itemsSet);
|
|
|
+ if (itemsSetInDb.size() > 0) {
|
|
|
+ Map<Object, DynamicObject> changItemsDyMap = BusinessDataServiceHelper.loadFromCache(itemsSetInDb.toArray(new Object[1]), "fa_change_item");
|
|
|
+ Set<String> alsterSet = (Set)changItemsDyMap.values().stream().map((t) -> {
|
|
|
+ return t.getString("name");
|
|
|
+ }).collect(Collectors.toSet());
|
|
|
+ errorInfo.add(String.format(ResManager.loadKDString("已保存的变更单不能删除变更项%1$s。", "LeaseChangeBillValidator_4", "fi-fa-business", new Object[0]), alsterSet.toString()));
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<String> validate4Submit(DynamicObject bill, DynamicObject aftContract, DynamicObject oriLeaseContract) {
|
|
|
+ List<String> errorInfo = validate4Save(bill);
|
|
|
+ if (!errorInfo.isEmpty()) {
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ if (aftContract == null) {
|
|
|
+ aftContract = bill.getDynamicObject("changebakcontract");
|
|
|
+ aftContract = reloadContractFromCache(aftContract.getPkValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ errorInfo.addAll(checkLeaseInitEnable(bill));
|
|
|
+ errorInfo.addAll(checkLeaseContactAllowsChange(bill));
|
|
|
+ errorInfo.addAll(checkContractChangeInfo(bill, aftContract, oriLeaseContract));
|
|
|
+ errorInfo.addAll(checkForFinChanged(bill));
|
|
|
+ errorInfo.addAll(checkAmortizationPeriodIsNull(bill));
|
|
|
+ errorInfo.addAll(checkAmortizeDateAftEffectiveDate(bill));
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<String> validate4Audit(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = checkLeaseInitEnable(bill);
|
|
|
+ errorInfo.addAll(checkForFinChanged(bill));
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<String> validate4Push(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(8);
|
|
|
+ String leaseChangeBillNo = bill.getString("billno");
|
|
|
+ String billStatus = bill.getString("billstatus");
|
|
|
+ if (!"C".equals(billStatus)) {
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ String pushStatus = bill.getString("pushstatus");
|
|
|
+ if ("C".equals(pushStatus)) {
|
|
|
+ errorInfo.add(String.format(ResManager.loadKDString("租赁变更单编号:%s 存在关联单据,不能重复下推。", "LeaseChangeBillValidator_5", "fi-fa-business", new Object[0]), leaseChangeBillNo));
|
|
|
+ return errorInfo;
|
|
|
+ } else if ("B".equals(pushStatus)) {
|
|
|
+ errorInfo.add(String.format(ResManager.loadKDString("租赁变更单编号:%s 下推标识为无需下推,不能下推。", "LeaseChangeBillValidator_6", "fi-fa-business", new Object[0]), leaseChangeBillNo));
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ long leaseContractId = bill.getLong(Fa.id("leasecontract"));
|
|
|
+ Date effectiveDate = bill.getDate("effectivedate");
|
|
|
+ Date audiDate = bill.getDate("auditdate");
|
|
|
+ QFilter[] qFilters = new QFilter[]{new QFilter("leasecontract", "=", leaseContractId), new QFilter("auditdate", "<", audiDate), new QFilter("pushstatus", "=", "A")};
|
|
|
+ boolean existsNeedPush = QueryServiceHelper.exists("fa_lease_change_bill", qFilters);
|
|
|
+ if (existsNeedPush) {
|
|
|
+ errorInfo.add(String.format(ResManager.loadKDString("租赁变更单编号:%s 对应的合同存在历史变更生效的租赁变更单未下推。", "LeaseChangeBillValidator_7", "fi-fa-business", new Object[0]), leaseChangeBillNo));
|
|
|
+ }
|
|
|
+
|
|
|
+ DynamicObject aftContract = bill.getDynamicObject("aftcontract");
|
|
|
+ Long orgId = aftContract.getLong(Fa.id("org"));
|
|
|
+ DynamicObject mainBookByOrg = FaUtils.getMainBookByOrg(orgId);
|
|
|
+ if (mainBookByOrg == null) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("请先创建核算组织对应的主账簿。", "LeaseChangeBillValidator_8", "fi-fa-business", new Object[0]));
|
|
|
+ return errorInfo;
|
|
|
+ } else if ("B".equals(mainBookByOrg.get("status"))) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("核算组织对应的主账簿未启用。", "LeaseChangeBillValidator_9", "fi-fa-business", new Object[0]));
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ Long periodId = mainBookByOrg.getLong("curperiod");
|
|
|
+ DynamicObject mainBookNext;
|
|
|
+ if (periodId > 0L) {
|
|
|
+ mainBookNext = BusinessDataServiceHelper.loadSingleFromCache("bd_period", "enddate", (new QFilter("id", "=", periodId)).toArray());
|
|
|
+ long leaseContractMasterId = aftContract.getLong("masterid");
|
|
|
+ DynamicObject realCard = QueryServiceHelper.queryOne("fa_card_real", "masterid", new QFilter[]{new QFilter("isbak", "in", false), new QFilter("srcbillid", "=", leaseContractMasterId)});
|
|
|
+ if (realCard == null) {
|
|
|
+ throw new KDBizException(ResManager.loadKDString("租赁合同关联的资产卡片丢失,请联系系统管理员。", "LeaseChangeBillValidator_10", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ Long masterId = realCard.getLong("masterid");
|
|
|
+ Date endDate = mainBookNext.getDate("enddate");
|
|
|
+ QFilter[] qFinFilter = new QFilter[]{new QFilter("finaccountdate", ">", endDate), new QFilter("realcardmasterid", "=", masterId)};
|
|
|
+ boolean exists = QueryServiceHelper.exists("fa_card_fin", qFinFilter);
|
|
|
+ if (exists) {
|
|
|
+ errorInfo.add(String.format(ResManager.loadKDString("租赁变更单编号:%s 对应的财务卡片是未来期间入账卡片,不能下推。", "LeaseChangeBillValidator_11", "fi-fa-business", new Object[0]), leaseChangeBillNo));
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ mainBookNext = FaBizUtils.queryNeighborPeriod(periodId, 1);
|
|
|
+ if (mainBookNext == null) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("未找到主账簿的下一期间,请先维护期间数据。", "LeaseChangeBillValidator_12", "fi-fa-business", new Object[0]));
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ Date mainBookEndDateNext = mainBookNext.getDate("enddate");
|
|
|
+ if (mainBookEndDateNext.before(effectiveDate)) {
|
|
|
+ errorInfo.add(String.format(ResManager.loadKDString("租赁变更单编号:%s 变更生效日超过主账簿的下期结束日,不能下推。", "LeaseChangeBillValidator_13", "fi-fa-business", new Object[0]), leaseChangeBillNo));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<String> validate4UnAudit(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(4);
|
|
|
+ if (!checkContractBizStatus(bill)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("合同业务状态不是“正常”,不允许反审核。", "LeaseChangeBillValidator_14", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (checkLeaseChangeBillIsPush(bill)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("存在下游单据,不允许反审核。", "LeaseChangeBillValidator_15", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isEffectiveFinInfo(bill)) {
|
|
|
+ if (checkRentSettleHasVoucherAfterAmortizationDate(bill)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("变更生效日后摊销与计息已经生成凭证,不允许反审核。", "LeaseChangeBillValidator_16", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ errorInfo.addAll(checkPayPlanIsPushOrPaid(bill));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (checkFutureLeaseChange(bill)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("已存在未来生效的租赁变更单,不允许反审核。", "LeaseChangeBillValidator_17", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkLeaseContactAllowsChange(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(8);
|
|
|
+ errorInfo.addAll(checkEffectiveDateRange(bill));
|
|
|
+ errorInfo.addAll(checkChangeItems(bill));
|
|
|
+ if (checkFutureLeaseChange(bill)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("已存在当天或未来生效的租赁变更单,不允许变更。", "LeaseChangeBillValidator_18", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ errorInfo.addAll(checkContractIsPushAndCardStatus(bill));
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkContractChangeInfo(DynamicObject bill, DynamicObject aftContract, DynamicObject oriLeaseContract) {
|
|
|
+ List<String> errorInfo = new ArrayList(8);
|
|
|
+ if (checkIsExemptChanged(bill, aftContract)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("合同是否豁免发生变化,不允许变更。", "LeaseChangeBillValidator_19", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (checkExemptPropertyError(aftContract, oriLeaseContract)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("原合同为豁免合同,不能变更为适用租赁期(月)大于12个月。", "LeaseChangeBillValidator_43", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> contractSubmitValidateResult = LeaseContractExValidator.validateContractForSubmit(aftContract);
|
|
|
+ if (!contractSubmitValidateResult.isEmpty()) {
|
|
|
+ errorInfo.add(String.format(ResManager.loadKDString("变更后的合同信息存在以下问题,请修改:%s", "LeaseChangeBillValidator_20", "fi-fa-business", new Object[0]), String.join("", contractSubmitValidateResult)));
|
|
|
+ } else {
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ String rentStatus = leaseContract.getString("rentsettlestatus");
|
|
|
+ if (LeaseContractRentSettleStatus.A.name().equals(rentStatus)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("合同未计息,不允许变更。", "LeaseChangeBillValidator_21", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (LeaseChangeUtil.isEffectPayPlan(bill)) {
|
|
|
+ LeaseUtil.generatePayPlan4Chg(aftContract, oriLeaseContract);
|
|
|
+ LeaseUtil.calLeaseContractAmount4Submit(aftContract);
|
|
|
+ errorInfo.addAll(isPayRuleChangedBeforeEffectiveDate(bill, aftContract, oriLeaseContract));
|
|
|
+ errorInfo.addAll(checkRentSettleStatusChanged(bill, aftContract));
|
|
|
+ }
|
|
|
+
|
|
|
+ errorInfo.addAll(checkHasChanged(bill, aftContract));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkForFinChanged(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(4);
|
|
|
+ if (!isEffectiveFinInfo(bill)) {
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ errorInfo.addAll(checkRentSettleHasVoucher4Submit(bill));
|
|
|
+ errorInfo.addAll(checkPayPlanIsPushOrPaid(bill));
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isEffectiveFinInfo(DynamicObject bill) {
|
|
|
+ Set<String> changeFields = LeaseChangeUtil.getChangeFields(bill);
|
|
|
+ changeFields.retainAll(EFFECTIVE_FIN_ITEMS);
|
|
|
+ return !changeFields.isEmpty();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkAmortizeDateAftEffectiveDate(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ Date effectiveDate = bill.getDate("effectivedate");
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ leaseContract = BusinessDataServiceHelper.loadSingleFromCache(leaseContract.getPkValue(), "fa_lease_contract");
|
|
|
+ DynamicObject org = leaseContract.getDynamicObject("org");
|
|
|
+ String interestAmortizeSchema = SystemParamHelper.getStringParam("interest_amortize_schema", (Long)org.getPkValue(), InterestAmortizeSchema.A.name());
|
|
|
+ if (InterestAmortizeSchema.A.name().equals(interestAmortizeSchema)) {
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ List<Date> payDateList = new ArrayList();
|
|
|
+ DynamicObjectCollection payPlanEntry = leaseContract.getDynamicObjectCollection("payplanentryentity");
|
|
|
+ Iterator var8 = payPlanEntry.iterator();
|
|
|
+
|
|
|
+ while(true) {
|
|
|
+ Date planStartDate;
|
|
|
+ Date planEndDate;
|
|
|
+ DynamicObject payRuleRow;
|
|
|
+ String frequency;
|
|
|
+ do {
|
|
|
+ DynamicObject row;
|
|
|
+ DynamicObject payItem;
|
|
|
+ String acctClass;
|
|
|
+ do {
|
|
|
+ Date planPayDate;
|
|
|
+ do {
|
|
|
+ if (!var8.hasNext()) {
|
|
|
+ if (!payDateList.isEmpty()) {
|
|
|
+ Date lastAmortizeDate = (Date)payDateList.stream().max(DateUtil::compareDate).get();
|
|
|
+ errorInfo.add(String.format(ResManager.loadKDString("存在计划付款日在变更生效日之前,但摊销到变更生效日之后的付款计划,请调整变更生效日到[%s]之后。", "LeaseChangeBillValidator_22", "fi-fa-business", new Object[0]), DateUtil.getShortDate().format(lastAmortizeDate)));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ row = (DynamicObject)var8.next();
|
|
|
+ planPayDate = row.getDate("planpaydate");
|
|
|
+ } while(DateUtil.compareDate(planPayDate, effectiveDate) >= 0);
|
|
|
+
|
|
|
+ payItem = row.getDynamicObject("plan_payitem");
|
|
|
+ acctClass = payItem.getString("accountingclass");
|
|
|
+ } while(!"A".equals(acctClass));
|
|
|
+
|
|
|
+ planStartDate = row.getDate("plan_startdate");
|
|
|
+ planEndDate = row.getDate("plan_enddate");
|
|
|
+ payRuleRow = LeaseUtil.getPayRuleRow(leaseContract, payItem.getLong("id"), planStartDate);
|
|
|
+ frequency = payRuleRow.getString("frequency");
|
|
|
+ } while(PayFrequency.F.name().equals(frequency));
|
|
|
+
|
|
|
+ String payPoint = payRuleRow.getString("paypoint");
|
|
|
+ int relativePayDate = payRuleRow.getInt("relativepaydate");
|
|
|
+ Date startDate = planStartDate;
|
|
|
+
|
|
|
+ while(DateUtil.compareDate(startDate, planEndDate) <= 0) {
|
|
|
+ Date endDate = DateUtil.addNaturalMonth(startDate, 1);
|
|
|
+ endDate = DateUtil.addDay(endDate, -1);
|
|
|
+ if (DateUtil.compareDate(endDate, planEndDate) > 0) {
|
|
|
+ endDate = planEndDate;
|
|
|
+ }
|
|
|
+
|
|
|
+ Date payDate = LeaseUtil.calPlanPayDate(startDate, endDate, payPoint, relativePayDate);
|
|
|
+ startDate = DateUtil.addDay(endDate, 1);
|
|
|
+ if (DateUtil.compareDate(payDate, effectiveDate) >= 0) {
|
|
|
+ payDateList.add(payDate);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkLeaseInitEnable(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ DynamicObject leaseInit = getLeaseInitFromCache(bill);
|
|
|
+ if (leaseInit == null) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("请先创建核算组织对应的租赁初始化。", "LeaseChangeBillValidator_23", "fi-fa-business", new Object[0]));
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ String status = leaseInit.getString("status");
|
|
|
+ boolean enable = leaseInit.getBoolean("enable");
|
|
|
+ if (!BillStatus.C.name().equals(status) || !enable) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("请先启用核算组织的租赁初始化。", "LeaseChangeBillValidator_24", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkEffectiveDateRange(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ String sourceType = leaseContract.getString("sourcetype");
|
|
|
+ Date sysSwitchDate = leaseContract.getDate("sysswitchdate");
|
|
|
+ Date initConfirmDate = leaseContract.getDate("initconfirmdate");
|
|
|
+ Date leaseEndDate = leaseContract.getDate("leaseenddate");
|
|
|
+ Date effectiveDate = bill.getDate("effectivedate");
|
|
|
+ if (LeaseContractSourceType.A.name().equals(sourceType)) {
|
|
|
+ if (effectiveDate.compareTo(initConfirmDate) < 0 || effectiveDate.compareTo(leaseEndDate) > 0) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("“变更生效日”必须大于等于原合同“初始确认日”且小于等于原合同“租赁结束日”。", "LeaseChangeBillValidator_25", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+ } else if (effectiveDate.compareTo(sysSwitchDate) < 0 || effectiveDate.compareTo(leaseEndDate) > 0) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("“变更生效日”必须大于等于原合同“系统切换日”且小于等于原合同“租赁结束日”。", "LeaseChangeBillValidator_26", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkChangeItems(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ boolean isExempt = leaseContract.getBoolean("isexempt");
|
|
|
+ Set<String> changeFields = LeaseChangeUtil.getChangeFields(bill);
|
|
|
+ if (isExempt && changeFields.contains("discountrate")) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("豁免合同不允许变更年折现率。", "LeaseChangeBillValidator_27", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean checkFutureLeaseChange(DynamicObject bill) {
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ Date effectiveDate = bill.getDate("effectivedate");
|
|
|
+ return LeaseFutureBizChecker.existFutureLeaseChangeBill(bill.getPkValue(), leaseContract.getPkValue(), effectiveDate);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkContractIsPushAndCardStatus(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ boolean isExempt = leaseContract.getBoolean("isexempt");
|
|
|
+ if (isExempt) {
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ QFilter[] realCardFilters = new QFilter[]{new QFilter("srcbillid", "=", leaseContract.getPkValue()), new QFilter("isbak", "=", Boolean.FALSE)};
|
|
|
+ DynamicObject realCard = QueryServiceHelper.queryOne("fa_card_real", "id", realCardFilters);
|
|
|
+ if (realCard == null) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("合同未下推生成卡片,不允许变更。", "LeaseChangeBillValidator_28", "fi-fa-business", new Object[0]));
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ QFilter finCardFilter = new QFilter("realcard", "=", realCard.getLong("id"));
|
|
|
+ DynamicObject finCard = QueryServiceHelper.queryOne("fa_card_fin", "billstatus", finCardFilter.toArray());
|
|
|
+ if (finCard == null) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("合同下推的实物卡片未生成财务卡片,不允许变更。", "LeaseChangeBillValidator_29", "fi-fa-business", new Object[0]));
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ String billStatus = finCard.getString("billstatus");
|
|
|
+ if (!BillStatus.C.name().equals(billStatus)) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("合同下推的财务卡片未审核,不允许变更。", "LeaseChangeBillValidator_30", "fi-fa-business", new Object[0]));
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean checkIsExemptChanged(DynamicObject bill, DynamicObject aftContract) {
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ boolean isExempt = leaseContract.getBoolean("isexempt");
|
|
|
+ boolean aftIsExempt = aftContract.getBoolean("isexempt");
|
|
|
+ return isExempt ^ aftIsExempt;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkHasChanged(DynamicObject bill, DynamicObject aftContract) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ leaseContract = reloadContractFromCache(leaseContract.getPkValue());
|
|
|
+ Set<String> changeFields = LeaseChangeUtil.getChangeFields(bill);
|
|
|
+ MainEntityType entityType = EntityMetadataCache.getDataEntityType("fa_lease_contract");
|
|
|
+ List<String> noChangedFields = new ArrayList(changeFields.size());
|
|
|
+ Iterator var7 = changeFields.iterator();
|
|
|
+
|
|
|
+ while(var7.hasNext()) {
|
|
|
+ String field = (String)var7.next();
|
|
|
+ DynamicProperty property = entityType.getProperty(field);
|
|
|
+ if (!(property instanceof EntryProp)) {
|
|
|
+ boolean isDiff = false;
|
|
|
+ if (property instanceof DateProp) {
|
|
|
+ Date befDate = leaseContract.getDate(field);
|
|
|
+ Date aftDate = aftContract.getDate(field);
|
|
|
+ isDiff = DateUtil.compareDate(befDate, aftDate) == 0;
|
|
|
+ } else {
|
|
|
+ long aft;
|
|
|
+ long bef;
|
|
|
+ if (property instanceof BasedataProp) {
|
|
|
+ bef = leaseContract.getLong(field + "_id");
|
|
|
+ aft = aftContract.getLong(field + "_id");
|
|
|
+ isDiff = bef == aft;
|
|
|
+ } else if (property instanceof TextProp) {
|
|
|
+ String befString = leaseContract.getString(field);
|
|
|
+ String aftString = aftContract.getString(field);
|
|
|
+ isDiff = Objects.equals(befString, aftString);
|
|
|
+ } else if (property instanceof DecimalProp) {
|
|
|
+ BigDecimal befDecimal = leaseContract.getBigDecimal(field);
|
|
|
+ befDecimal = befDecimal == null ? BigDecimal.ZERO : befDecimal;
|
|
|
+ BigDecimal aftDecimal = aftContract.getBigDecimal(field);
|
|
|
+ aftDecimal = aftDecimal == null ? BigDecimal.ZERO : aftDecimal;
|
|
|
+ isDiff = befDecimal.compareTo(aftDecimal) == 0;
|
|
|
+ } else if (property instanceof LongProp) {
|
|
|
+ bef = leaseContract.getLong(field);
|
|
|
+ aft = aftContract.getLong(field);
|
|
|
+ isDiff = bef == aft;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isDiff) {
|
|
|
+ noChangedFields.add(property.getDisplayName().getLocaleValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (changeFields.contains("payruleentryentity")) {
|
|
|
+ Date effectiveDate = bill.getDate("effectivedate");
|
|
|
+ PayRuleCompareResult compareResult = LeaseChangeUtil.comparePayRule(leaseContract, aftContract, effectiveDate);
|
|
|
+ if (compareResult.getChangedPayItemIds().isEmpty()) {
|
|
|
+ noChangedFields.add(ResManager.loadKDString("付款规则", "LeaseChangeBillValidator_31", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!noChangedFields.isEmpty()) {
|
|
|
+ errorInfo.add(String.format(ResManager.loadKDString("以下变更项没有发生变更,请修改对应的字段或移除该变更项:%s。", "LeaseChangeBillValidator_32", "fi-fa-business", new Object[0]), String.join(", ", noChangedFields)));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> isPayRuleChangedBeforeEffectiveDate(DynamicObject bill, DynamicObject aftContract, DynamicObject oriLeaseContract) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ Date effectiveDate = bill.getDate("effectivedate");
|
|
|
+ PayRuleCompareResult compareResult = LeaseChangeUtil.comparePayRule(oriLeaseContract, aftContract, effectiveDate);
|
|
|
+ if (compareResult.isChangedBeforeEffective()) {
|
|
|
+ Set<String> planNumberSet = compareResult.getChangedPlanNumberBeforeEffective();
|
|
|
+ String planNumbers = (String)planNumberSet.stream().sorted(Comparator.naturalOrder()).collect(Collectors.joining(", "));
|
|
|
+ errorInfo.add(String.format(ResManager.loadKDString("变更生效日之前的付款规则发生变化,不允许变更,请核对具体的付款计划:%s。", "LeaseChangeBillValidator_33", "fi-fa-business", new Object[0]), planNumbers));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkRentSettleStatusChanged(DynamicObject bill, DynamicObject aftContract) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ leaseContract = reloadContractFromCache(leaseContract.getPkValue());
|
|
|
+ boolean befNeedRentSettle = LeaseUtil.isNeedRentSettle(leaseContract);
|
|
|
+ boolean aftNeedRentSettle = LeaseUtil.isNeedRentSettle(aftContract);
|
|
|
+ if (befNeedRentSettle && !aftNeedRentSettle) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("变更前合同需要计息,不能变更为无需计息的合同。", "LeaseChangeBillValidator_34", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkRentSettleHasVoucher4Submit(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ DynamicObject leaseInit = getLeaseInitFromCache(bill);
|
|
|
+ Date endDate = leaseInit.getDate("curperiod.enddate");
|
|
|
+ Date beginDate = leaseInit.getDate("curperiod.begindate");
|
|
|
+ Date effectiveDate = bill.getDate("effectivedate");
|
|
|
+ boolean isFutureEffective = DateUtil.compareShortDate(effectiveDate, endDate) > 0;
|
|
|
+ Date checkStartDate = isFutureEffective ? effectiveDate : beginDate;
|
|
|
+ long leaseContractId = bill.getLong(Fa.id("leasecontract"));
|
|
|
+ boolean hasVoucher = checkRentSettleHasVoucherAfterDate(leaseContractId, checkStartDate);
|
|
|
+ if (hasVoucher) {
|
|
|
+ if (isFutureEffective) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("变更生效日所在期间及后续期间的计息与摊销已生成凭证,不允许变更。", "LeaseChangeBillValidator_36", "fi-fa-business", new Object[0]));
|
|
|
+ } else {
|
|
|
+ errorInfo.add(ResManager.loadKDString("主账簿当前期间及后续期间的计息与摊销已生成凭证,不允许变更。", "LeaseChangeBillValidator_37", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean checkRentSettleHasVoucherAfterDate(long leaseContractId, Date date) {
|
|
|
+ QFilter[] filters = new QFilter[]{new QFilter("leasecontract", "=", leaseContractId), new QFilter("settledate", ">=", date)};
|
|
|
+ DynamicObjectCollection rentSettle = QueryServiceHelper.query("fa_lease_rent_settle", "id", filters);
|
|
|
+ List<Object> rentSettleIds = (List)rentSettle.stream().map((v) -> {
|
|
|
+ return v.get("id");
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ return FaDepreUtil.hashVouncherV2(rentSettleIds, "fa_lease_rent_settle");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkPayPlanIsPushOrPaid(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ Date effectiveDate = bill.getDate("effectivedate");
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ leaseContract = reloadContractFromCache(leaseContract.getPkValue());
|
|
|
+ DynamicObjectCollection planEntry = leaseContract.getDynamicObjectCollection("payplanentryentity");
|
|
|
+ boolean findErrData = false;
|
|
|
+ Iterator var6 = planEntry.iterator();
|
|
|
+
|
|
|
+ while(var6.hasNext()) {
|
|
|
+ DynamicObject row = (DynamicObject)var6.next();
|
|
|
+ Date planPayDate = row.getDate("planpaydate");
|
|
|
+ if (DateUtil.compareDate(planPayDate, effectiveDate) >= 0) {
|
|
|
+ BigDecimal realPayAmount = row.getBigDecimal("realpayamount");
|
|
|
+ if (BigDecimal.ZERO.compareTo(realPayAmount) != 0) {
|
|
|
+ findErrData = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean isPush = BFTrackerServiceHelper.isPush("fa_lease_pay_plan", (Long)row.getPkValue());
|
|
|
+ if (isPush) {
|
|
|
+ findErrData = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (findErrData) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("变更生效日后付款计划存在下游单据或实际付款金额不为0。", "LeaseChangeBillValidator_38", "fi-fa-business", new Object[0]));
|
|
|
+ }
|
|
|
+
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean checkContractBizStatus(DynamicObject bill) {
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ String bizStatus = leaseContract.getString("bizstatus");
|
|
|
+ return LeaseContractBizStatus.A.name().equals(bizStatus);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean checkLeaseChangeBillIsPush(DynamicObject bill) {
|
|
|
+ return "C".equals(bill.getString("pushstatus"));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean checkRentSettleHasVoucherAfterAmortizationDate(DynamicObject bill) {
|
|
|
+ Date amortizationDate = bill.getDate("amortizationdate");
|
|
|
+ long leaseContractId = bill.getLong(Fa.id("leasecontract"));
|
|
|
+ return checkRentSettleHasVoucherAfterDate(leaseContractId, amortizationDate);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> checkAmortizationPeriodIsNull(DynamicObject bill) {
|
|
|
+ List<String> errorInfo = new ArrayList(1);
|
|
|
+ long leaseContractId = bill.getLong(Fa.id("leasecontract"));
|
|
|
+ QFilter[] rentSettleFilters = new QFilter[]{new QFilter("leasecontract", "=", leaseContractId), new QFilter("amortizationperiod", "=", 0L)};
|
|
|
+ boolean existsRentSettle = QueryServiceHelper.exists("fa_lease_rent_settle", rentSettleFilters);
|
|
|
+ if (existsRentSettle) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("存在摊销与计息的“摊销期间”为空,请先维护会计期间并升级数据。", "LeaseChangeBillValidator_39", "fi-fa-business", new Object[0]));
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ QFilter[] interestDetailFilters = new QFilter[]{new QFilter("leasecontract", "=", leaseContractId), new QFilter(Fa.dot(new String[]{"detailentry", "amortizationperiod"}), "=", 0L)};
|
|
|
+ boolean existsInterestDetail = QueryServiceHelper.exists("fa_interest_detail", interestDetailFilters);
|
|
|
+ if (existsInterestDetail) {
|
|
|
+ errorInfo.add(ResManager.loadKDString("存在计息明细的“摊销期间”为空,请先维护会计期间并升级数据。", "LeaseChangeBillValidator_40", "fi-fa-business", new Object[0]));
|
|
|
+ return errorInfo;
|
|
|
+ } else {
|
|
|
+ return errorInfo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static DynamicObject getLeaseInitFromCache(DynamicObject bill) {
|
|
|
+ DynamicObject leaseContract = bill.getDynamicObject("leasecontract");
|
|
|
+ long orgId = leaseContract.getLong(Fa.id("org"));
|
|
|
+ QFilter[] filter = new QFilter[]{new QFilter("org", "=", orgId)};
|
|
|
+ String fields = Fa.comma(new String[]{"enable", "status", "curperiod.begindate", "curperiod.enddate"});
|
|
|
+ return BusinessDataServiceHelper.loadSingleFromCache("fa_lease_init", fields, filter);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static DynamicObject reloadContractFromCache(Object pk) {
|
|
|
+ return BusinessDataServiceHelper.loadSingleFromCache(pk, "fa_lease_contract");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean checkExemptPropertyError(DynamicObject aftContract, DynamicObject oriLeaseContract) {
|
|
|
+ boolean oriLeaseIsExempt = oriLeaseContract.getBoolean("isexempt");
|
|
|
+ if (oriLeaseIsExempt) {
|
|
|
+ DynamicObjectWrapper wrapper = new DynamicObjectWrapper(aftContract);
|
|
|
+ Boolean isExempt4Cal = LeaseContractCal.getIsExempt(wrapper);
|
|
|
+ if (!isExempt4Cal) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|