2 Commits d16f837575 ... 37725f6512

Autor SHA1 Nachricht Datum
  liutao 37725f6512 Merge branch 'smb' vor 3 Wochen
  liuj 76155c76be 分账逻辑优化 vor 3 Wochen

+ 182 - 197
src/main/java/com/sunxung/factoring/service/ledger/impl/LedgerManagementServiceImpl.java

@@ -1492,7 +1492,7 @@ public class LedgerManagementServiceImpl implements LedgerManagementService {
                     BigDecimal assignAmount;
                     if (ledgerAccountBasicInfo.getSmbFinancing()) {
                         //如果是苏商资方、走苏商分账逻辑
-                        assignAmount = SMBAssign(ledgerAccountInfoVo, principalDict, interestDict, managementFeeDict, goodsAssignVo, ledgerPlanFactoringAssignList);
+                        assignAmount = SMBAssign(principalDict, managementFeeDict, goodsAssignVo, ledgerPlanFactoringAssignList);
                     } else {
                         //如果不是、走正常分账逻辑
                         assignAmount = normalAssign(ledgerAccountInfoVo, principalDict, interestDict, managementFeeDict, goodsAssignVo, ledgerPlanFactoringAssignList);
@@ -1674,15 +1674,13 @@ public class LedgerManagementServiceImpl implements LedgerManagementService {
     /**
      * 苏商资方分账逻辑
      *
-     * @param ledgerAccountInfoVo
      * @param principalDict
-     * @param interestDict
      * @param managementFeeDict
      * @param goodsAssignVo
      * @param ledgerPlanFactoringAssignList
      * @return
      */
-    private BigDecimal SMBAssign(LedgerAccountInfoVo ledgerAccountInfoVo, Dictionary principalDict, Dictionary interestDict, Dictionary managementFeeDict, LedgerFundGoodsAssign goodsAssignVo, List<LedgerPlanFactoringAssign> ledgerPlanFactoringAssignList) {
+    private BigDecimal SMBAssign(Dictionary principalDict, Dictionary managementFeeDict, LedgerFundGoodsAssign goodsAssignVo, List<LedgerPlanFactoringAssign> ledgerPlanFactoringAssignList) {
 
         BigDecimal financePrincipal = BigDecimal.ZERO;
         BigDecimal financeInterest = BigDecimal.ZERO;
@@ -1705,10 +1703,6 @@ public class LedgerManagementServiceImpl implements LedgerManagementService {
                     goodsAssignVo.getBillingFactoringBusinessLoanRecordId());
             planFactoringList.stream().filter(p -> p.getPlanDate() != null).forEach(p -> p.setPlanDate(DateUtil.beginOfDay(p.getPlanDate())));
 
-            //入账日期
-            LedgerAccountBasicInfo ledgerAccountBasicInfo = ledgerAccountInfoVo.getLedgerAccountBasicInfo();
-            Date ledgerDate = ledgerAccountBasicInfo.getLedgerDate();
-
             Long sopAccountsReceivableId = goodsAssignVo.getSopAccountsReceivableId();
             Long billingFactoringBusinessLoanRecordId = goodsAssignVo.getBillingFactoringBusinessLoanRecordId();
 
@@ -1718,14 +1712,7 @@ public class LedgerManagementServiceImpl implements LedgerManagementService {
             List<PaymentCollectionPlanFactoring> principalFactoringList = getFactoringByAmountType(allPlanFactoringList, principalDict);
             //检验本金是否存在
             //validatePlanFactoring(principalFactoringList);
-            Boolean assignOverdueInterest = hasAssignOverdueInterest(allPlanFactoringList, goodsAssignVo.getHasAssignOverdueInterest());
-
-            Date actualDate;
-            if (assignOverdueInterest) {
-                actualDate = new Date();
-            } else {
-                actualDate = ledgerDate;
-            }
+            Date actualDate = new Date();
             //1.查看计划是否有逾期利息未分完的,存在先分逾期利息
             if (goodsAssignVo.getHasAssignOverdueInterest() && assignAmount.compareTo(BigDecimal.ZERO) > 0) {
                 List<PaymentCollectionPlanFactoring> overdueInterestList = planFactoringList.stream()
@@ -1747,203 +1734,146 @@ public class LedgerManagementServiceImpl implements LedgerManagementService {
             //2.判断是否分配长银融资利息、管理费和本金
             if (goodsAssignVo.getHasAssignInterest() && assignAmount.compareTo(BigDecimal.ZERO) > 0) {
                 //利息分配 取所有垫付标识的
-                if (goodsAssignVo.getHasAssignOverdueInterest()) {
-                    List<PaymentCollectionPlanFactoring> interestList = planFactoringList.stream()
-                            .filter(f -> "interest".equals(f.getAmountType().getCode()) && f.getAdvanceFlag().equals(1))
-                            .sorted(Comparator.comparing(PaymentCollectionPlanFactoring::getPlanDate)).collect(Collectors.toList());
-                    if (interestList != null && interestList.size() > 0) {
-                        for (PaymentCollectionPlanFactoring factoring : interestList) {
-                            BigDecimal currentAssignAmount = assignAmount(assignAmount, factoring);
-                            financeInterest = financeInterest.add(currentAssignAmount);
-                            assignAmount = assignAmount.subtract(currentAssignAmount);
-                            ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(actualDate, currentAssignAmount, factoring, goodsAssignVo, 0));
-                            if (assignAmount.compareTo(BigDecimal.ZERO) == 0) {
-                                //说明钱已经分完了,结束分配
-                                break;
-                            }
+                List<PaymentCollectionPlanFactoring> interestList = planFactoringList.stream()
+                        .filter(f -> "interest".equals(f.getAmountType().getCode()) && f.getAdvanceFlag().equals(1))
+                        .sorted(Comparator.comparing(PaymentCollectionPlanFactoring::getPlanDate)).collect(Collectors.toList());
+                if (interestList != null && interestList.size() > 0) {
+                    for (PaymentCollectionPlanFactoring factoring : interestList) {
+                        BigDecimal currentAssignAmount = assignAmount(assignAmount, factoring);
+                        financeInterest = financeInterest.add(currentAssignAmount);
+                        assignAmount = assignAmount.subtract(currentAssignAmount);
+                        ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(actualDate, currentAssignAmount, factoring, goodsAssignVo, 0));
+                        if (assignAmount.compareTo(BigDecimal.ZERO) == 0) {
+                            //说明钱已经分完了,结束分配
+                            break;
                         }
                     }
                 }
+            }
 
-                PrePaymentCalculateVo paymentCalculateVo = findPrepaymentInterestCal(sopAccountsReceivableId, billingFactoringBusinessLoanRecordId);
-                if (paymentCalculateVo.getPayBackMethod() == null || paymentCalculateVo.getPayBackMethod().getId() == null) {
-                    throw new BusinessException(CodeUtil.FAIL, "无法获取到该业务的还款方式");
-                }
-                //获取所有已经收款的管理费之和
-                BigDecimal actualManagementTotal = getActualAmountTotal(allPlanFactoringList, managementFeeDict);
-                //获取截至到分账日期的新的本金计划
-                List<PaymentCollectionPlanFactoring> newPrincipalFactoringList = getPrincipalFactoringByLedgerDate(principalFactoringList, actualDate, returnedAmount);
-                //计算截至到分账日期计划应收管理费总和
-                BigDecimal planManagementTotal = getAllocatedAmountByPlanFactoring(newPrincipalFactoringList, managementFeeDict,
-                        goodsAssignVo, paymentCalculateVo, actualDate);
-
-                //剩余未分配管理费
-                BigDecimal unAssignManagement = BigDecimal.ZERO;
-
-                //用已收管理费之和减去计划应收、判断需不需要退还
-                refundManagement = actualManagementTotal.subtract(planManagementTotal);
-                //获取所有的管理费收款计划
-                List<PaymentCollectionPlanFactoring> managementFeeFactoringList = getFactoringByAmountType(allPlanFactoringList, managementFeeDict);
-                if (refundManagement.compareTo(BigDecimal.ZERO) > 0) {
-                    //说明管理费分多了,需要将多的退掉
-                    unAssignManagement = refundManagement.negate();
-                    //删除未分配的管理费
-                    deleteUnAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo, null);
-                    //将部分分配的管理费计划金额改为实收金额
-                    updatePartAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
-                } else if (refundManagement.compareTo(BigDecimal.ZERO) == 0) {
-                    //说明管理费正好,只需要处理未完成的计划
-                    //删除未分配的管理费
-                    deleteUnAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo, null);
-                    //将部分分配的管理费计划金额改为实收金额
-                    updatePartAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
-                } else if (refundManagement.compareTo(BigDecimal.ZERO) < 0) {
-                    //说明管理费还需要补
-                    BigDecimal toAssignManagement = refundManagement.negate();
-                    if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
-                        //这种场景可能存在未分配的管理费,要删除分账日期之前的状态为计划中的数据
-                        deleteUnAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo, actualDate);
-                        //判断是否需要分配
-                        if (goodsAssignVo.getHasAssignInterest()) {
-                            if (assignAmount.compareTo(toAssignManagement) >= 0) {
-                                ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, toAssignManagement, toAssignManagement,
-                                        IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
-                                financingManagementFee = financingManagementFee.add(toAssignManagement);
-                                assignAmount = assignAmount.subtract(toAssignManagement);
-                            } else if (assignAmount.compareTo(toAssignManagement) < 0) {
-                                ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, assignAmount, assignAmount,
-                                        IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
-                                financingManagementFee = financingManagementFee.add(assignAmount);
-                                //剩余未分配管理费
-                                unAssignManagement = toAssignManagement.subtract(assignAmount);
-                                assignAmount = BigDecimal.ZERO;
-                            }
-                        } else {
-                            //如果本次选择不分管理费
-                            ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, toAssignManagement, BigDecimal.ZERO,
+            //无论是否分配长银本金利息管理费  都得先算下应收管理费金额 因为可能存在退的
+            PrePaymentCalculateVo paymentCalculateVo = findPrepaymentInterestCal(sopAccountsReceivableId, billingFactoringBusinessLoanRecordId);
+            if (paymentCalculateVo.getPayBackMethod() == null || paymentCalculateVo.getPayBackMethod().getId() == null) {
+                throw new BusinessException(CodeUtil.FAIL, "无法获取到该业务的还款方式");
+            }
+            //获取所有已经收款的管理费之和
+            BigDecimal actualManagementTotal = getActualAmountTotal(allPlanFactoringList, managementFeeDict);
+            //获取截至到分账日期的新的本金计划
+            List<PaymentCollectionPlanFactoring> newPrincipalFactoringList = getPrincipalFactoringByLedgerDate(principalFactoringList, actualDate, returnedAmount);
+            //计算截至到分账日期计划应收管理费总和
+            BigDecimal planManagementTotal = getAllocatedAmountByPlanFactoring(newPrincipalFactoringList, managementFeeDict,
+                    goodsAssignVo, paymentCalculateVo, actualDate);
+
+            //剩余未分配管理费
+            BigDecimal unAssignManagement = BigDecimal.ZERO;
+
+            //用已收管理费之和减去计划应收、判断需不需要退还
+            refundManagement = actualManagementTotal.subtract(planManagementTotal);
+            //获取所有的管理费收款计划
+            List<PaymentCollectionPlanFactoring> managementFeeFactoringList = getFactoringByAmountType(allPlanFactoringList, managementFeeDict);
+            if (refundManagement.compareTo(BigDecimal.ZERO) > 0) {
+                //说明管理费分多了,需要将多的退掉
+                unAssignManagement = refundManagement.negate();
+                //删除未分配的管理费
+                deleteUnAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo, null);
+                //将部分分配的管理费计划金额改为实收金额
+                updatePartAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
+            } else if (refundManagement.compareTo(BigDecimal.ZERO) == 0) {
+                //说明管理费正好,只需要处理未完成的计划
+                //删除未分配的管理费
+                deleteUnAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo, null);
+                //将部分分配的管理费计划金额改为实收金额
+                updatePartAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo);
+            } else if (refundManagement.compareTo(BigDecimal.ZERO) < 0) {
+                //说明管理费还需要补
+                BigDecimal toAssignManagement = refundManagement.negate();
+                if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
+                    //这种场景可能存在未分配的管理费,要删除分账日期之前的状态为计划中的数据
+                    deleteUnAssignList(managementFeeFactoringList, ledgerPlanFactoringAssignList, goodsAssignVo, actualDate);
+                    //判断是否需要分配
+                    if (goodsAssignVo.getHasAssignInterest()) {
+                        if (assignAmount.compareTo(toAssignManagement) >= 0) {
+                            ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, toAssignManagement, toAssignManagement,
+                                    IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
+                            financingManagementFee = financingManagementFee.add(toAssignManagement);
+                            assignAmount = assignAmount.subtract(toAssignManagement);
+                        } else if (assignAmount.compareTo(toAssignManagement) < 0) {
+                            ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, assignAmount, assignAmount,
                                     IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
+                            financingManagementFee = financingManagementFee.add(assignAmount);
+                            //剩余未分配管理费
+                            unAssignManagement = toAssignManagement.subtract(assignAmount);
+                            assignAmount = BigDecimal.ZERO;
                         }
+                    } else {
+                        //如果本次选择不分管理费
+                        ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, toAssignManagement, BigDecimal.ZERO,
+                                IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
                     }
                 }
+            }
 
-                if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
-                    //取所有有垫付标识的本金
-
-                    List<PaymentCollectionPlanFactoring> filterPrincipalFactoringList = principalFactoringList.stream().filter(p -> p.getAdvanceFlag().equals(1))
-                            .collect(Collectors.toList());
-                    //分配完还有钱去分配本金
-                    if (CollectionUtil.isNotEmpty(filterPrincipalFactoringList)) {
-                        //按计划日期升序排列
-                        Collections.sort(filterPrincipalFactoringList, Comparator.comparing(PaymentCollectionPlanFactoring::getPlanDate));
-                        Boolean flag = false;
-                        for (PaymentCollectionPlanFactoring planFactoring : filterPrincipalFactoringList) {
-                            if (!PaymentCollectionPlanStatusDict.ChildEnum.COMPLETED.getCode().equals(planFactoring.getStatus().getCode()) &&
-                                    !PaymentCollectionPlanStatusDict.ChildEnum.OVERDUE_COMPLETED.getCode().equals(planFactoring.getStatus().getCode())) {
-                                if (flag) {
-                                    //金额已分完了
-                                    ledgerPlanFactoringAssignList.add(addPlanFactoringDeleteAssign(planFactoring, goodsAssignVo, 1));
-                                    continue;
+            if (goodsAssignVo.getHasAssignInterest() && assignAmount.compareTo(BigDecimal.ZERO) > 0) {
+                //取所有有垫付标识的本金
+                List<PaymentCollectionPlanFactoring> filterPrincipalFactoringList = principalFactoringList.stream().filter(p -> p.getAdvanceFlag().equals(1))
+                        .collect(Collectors.toList());
+                //分配完还有钱去分配本金
+                if (CollectionUtil.isNotEmpty(filterPrincipalFactoringList)) {
+                    //按计划日期升序排列
+                    Collections.sort(filterPrincipalFactoringList, Comparator.comparing(PaymentCollectionPlanFactoring::getPlanDate));
+                    Boolean flag = false;
+                    for (PaymentCollectionPlanFactoring planFactoring : filterPrincipalFactoringList) {
+                        if (!PaymentCollectionPlanStatusDict.ChildEnum.COMPLETED.getCode().equals(planFactoring.getStatus().getCode()) &&
+                                !PaymentCollectionPlanStatusDict.ChildEnum.OVERDUE_COMPLETED.getCode().equals(planFactoring.getStatus().getCode())) {
+                            if (flag) {
+                                //金额已分完了
+                                ledgerPlanFactoringAssignList.add(addPlanFactoringDeleteAssign(planFactoring, goodsAssignVo, 1));
+                                continue;
+                            }
+                            if (assignAmount.compareTo(planFactoring.getAmount()) >= 0) {
+                                //本金分配金额>计划金额、说明本金够分
+                                //修改一笔本金收款记录
+                                if (actualDate.before(planFactoring.getPlanDate())) {
+                                    //分账日期早于计划日期
+                                    planFactoring.setPlanDate(actualDate);
                                 }
-                                if (assignAmount.compareTo(planFactoring.getAmount()) >= 0) {
-                                    //本金分配金额>计划金额、说明本金够分
-                                    //修改一笔本金收款记录
-                                    if (actualDate.before(planFactoring.getPlanDate())) {
-                                        //分账日期早于计划日期
-                                        planFactoring.setPlanDate(actualDate);
-                                    }
-                                    ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(actualDate, planFactoring.getAmount(),
-                                            planFactoring, goodsAssignVo, 1));
-                                    assignAmount = assignAmount.subtract(planFactoring.getAmount());
-                                    returnedAmount = returnedAmount.subtract(planFactoring.getAmount());
-                                    financePrincipal = financePrincipal.add(planFactoring.getAmount());
-                                } else {
-                                    if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
-                                        //说明本金不够分了
-                                        //判断本金状态是否逾期,如果逾期,本金不能拆分
-                                        if (PaymentCollectionPlanStatusDict.ChildEnum.OVERDUE.getCode().equals(planFactoring.getStatus().getCode())) {
-                                            //计划已逾期
-                                            ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(actualDate, assignAmount,
-                                                    planFactoring, goodsAssignVo, 1));
-                                        } else {
-                                            if (actualDate.before(planFactoring.getPlanDate())) {
-                                                //分账日期早于计划日期
-                                                planFactoring.setPlanDate(actualDate);
-                                            }
-                                            planFactoring.setAmount(assignAmount);
-                                            planFactoring.setActualCashFlow(assignAmount);
-                                            //修改一笔本金收款记录
-                                            ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(actualDate, assignAmount,
-                                                    planFactoring, goodsAssignVo, 1));
-                                            Date lastPlanDate = goodsAssignVo.getLastPlanDate();
-                                            //增加一笔剩余本金收款记录
-                                            ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(lastPlanDate, returnedAmount.subtract(assignAmount), BigDecimal.ZERO,
-                                                    IncomeExpenditureTypeDict.ChildEnum.PRINCIPAL.getCode(), goodsAssignVo, 1));
-                                            flag = true;
+                                ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(actualDate, planFactoring.getAmount(),
+                                        planFactoring, goodsAssignVo, 1));
+                                assignAmount = assignAmount.subtract(planFactoring.getAmount());
+                                returnedAmount = returnedAmount.subtract(planFactoring.getAmount());
+                                financePrincipal = financePrincipal.add(planFactoring.getAmount());
+                            } else {
+                                if (assignAmount.compareTo(BigDecimal.ZERO) > 0) {
+                                    //说明本金不够分了
+                                    //判断本金状态是否逾期,如果逾期,本金不能拆分
+                                    if (PaymentCollectionPlanStatusDict.ChildEnum.OVERDUE.getCode().equals(planFactoring.getStatus().getCode())) {
+                                        //计划已逾期
+                                        ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(actualDate, assignAmount,
+                                                planFactoring, goodsAssignVo, 1));
+                                    } else {
+                                        if (actualDate.before(planFactoring.getPlanDate())) {
+                                            //分账日期早于计划日期
+                                            planFactoring.setPlanDate(actualDate);
                                         }
-                                        financePrincipal = financePrincipal.add(assignAmount);
-                                        returnedAmount = returnedAmount.subtract(assignAmount);
-                                        assignAmount = BigDecimal.ZERO;
+                                        planFactoring.setAmount(assignAmount);
+                                        planFactoring.setActualCashFlow(assignAmount);
+                                        //修改一笔本金收款记录
+                                        ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(actualDate, assignAmount,
+                                                planFactoring, goodsAssignVo, 1));
+                                        Date lastPlanDate = goodsAssignVo.getLastPlanDate();
+                                        //增加一笔剩余本金收款记录
+                                        ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(lastPlanDate, returnedAmount.subtract(assignAmount), BigDecimal.ZERO,
+                                                IncomeExpenditureTypeDict.ChildEnum.PRINCIPAL.getCode(), goodsAssignVo, 1));
+                                        flag = true;
                                     }
+                                    financePrincipal = financePrincipal.add(assignAmount);
+                                    returnedAmount = returnedAmount.subtract(assignAmount);
+                                    assignAmount = BigDecimal.ZERO;
                                 }
                             }
                         }
                     }
                 }
-                if (returnedAmount.compareTo(BigDecimal.ZERO) == 0) {
-                    //说明此分配本金已经分完了
-                    if (unAssignManagement.compareTo(BigDecimal.ZERO) < 0) {
-                        //将之前未分配的管理费分完
-                        ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, unAssignManagement, BigDecimal.ZERO,
-                                IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
-                    }
-                } else if (returnedAmount.compareTo(BigDecimal.ZERO) > 0) {
-                    //说明此次本金未分完
-                    Date lastPlanDate = goodsAssignVo.getLastPlanDate();
-                    Boolean hasPrincipalAssign = false;
-                    if (returnedAmount.compareTo(goodsAssignVo.getReturnedAmount()) < 0) {
-                        //说明分配过本金
-                        hasPrincipalAssign = true;
-                    }
-                    //增加一笔剩余管理费计划
-                    //计算剩余应收管理费
-                    BigDecimal calculateManagementFee = calculateAssignInterest(returnedAmount, actualDate, lastPlanDate,
-                            !hasPrincipalAssign, paymentCalculateVo, IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode());
-                    BigDecimal surplusManagement = calculateManagementFee.add(unAssignManagement);
-                    if (surplusManagement.compareTo(new BigDecimal("0.5")) <= 0 && surplusManagement.compareTo(new BigDecimal("-0.5")) >= 0) {
-                        //误差范围在+0.5之内的、直接忽略
-                        surplusManagement = BigDecimal.ZERO;
-                        refundManagement = BigDecimal.ZERO;
-                    }
-                    if (surplusManagement.compareTo(BigDecimal.ZERO) < 0) {
-                        refundManagement = surplusManagement.negate();
-
-                        ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, surplusManagement, BigDecimal.ZERO,
-                                IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
-                    }
-                    if (surplusManagement.compareTo(BigDecimal.ZERO) > 0) {
-                        PaymentCollectionPlanFactoring lastManagementFactoring = getLastPrincipalFactoring(allPlanFactoringList, managementFeeDict, lastPlanDate);
-                        //可能存在计划已经在之前的判断中被删除的情况,所以需要再判断一次
-                        if (lastManagementFactoring == null) {
-                            ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, surplusManagement, BigDecimal.ZERO,
-                                    IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
-                        } else {
-                            //可能存在计划已经在之前的判断中被删除的情况,所以需要再判断一次
-                            boolean exist = ledgerPlanFactoringAssignList.stream().anyMatch(planFactoringAssign ->
-                                    planFactoringAssign.getDeleteFlag() != null && planFactoringAssign.getDeleteFlag()
-                                            && planFactoringAssign.getPlanFactoringId() != null && lastManagementFactoring.getId().equals(planFactoringAssign.getPlanFactoringId()));
-                            if (exist) {
-                                //说明最后一期计划被删了
-                                ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(lastManagementFactoring.getPlanDate(), surplusManagement, BigDecimal.ZERO,
-                                        IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
-                            } else {
-                                lastManagementFactoring.setAmount(surplusManagement);
-                                ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(lastManagementFactoring.getPlanDate(), BigDecimal.ZERO,
-                                        lastManagementFactoring, goodsAssignVo, 0));
-                            }
-                        }
-                        refundManagement = BigDecimal.ZERO;
-                    }
-                }
             }
             //3.判断是否分配资方本金和利息
             if (goodsAssignVo.getHasAssignManagement() && assignAmount.compareTo(BigDecimal.ZERO) > 0) {
@@ -1968,10 +1898,65 @@ public class LedgerManagementServiceImpl implements LedgerManagementService {
                         assignAmount = assignAmount.subtract(remandTotAmt);
                         repayKind = "3";
                     }
+                    returnedAmount = returnedAmount.subtract(managementPrincipal);
                 }
             }
+            //判断管理费有没有需要退还或新增
+            if (returnedAmount.compareTo(BigDecimal.ZERO) == 0) {
+                //说明此分配本金已经分完了
+                if (unAssignManagement.compareTo(BigDecimal.ZERO) < 0) {
+                    //将之前未分配的管理费分完
+                    ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, unAssignManagement, BigDecimal.ZERO,
+                            IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
+                }
+            } else if (returnedAmount.compareTo(BigDecimal.ZERO) > 0) {
+                //说明此次本金未分完
+                Date lastPlanDate = goodsAssignVo.getLastPlanDate();
+                Boolean hasPrincipalAssign = false;
+                if (returnedAmount.compareTo(goodsAssignVo.getReturnedAmount()) < 0) {
+                    //说明分配过本金
+                    hasPrincipalAssign = true;
+                }
+                //增加一笔剩余管理费计划
+                //计算剩余应收管理费
+                BigDecimal calculateManagementFee = calculateAssignInterest(returnedAmount, actualDate, lastPlanDate,
+                        !hasPrincipalAssign, paymentCalculateVo, IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode());
+                BigDecimal surplusManagement = calculateManagementFee.add(unAssignManagement);
+                if (surplusManagement.compareTo(new BigDecimal("0.5")) <= 0 && surplusManagement.compareTo(new BigDecimal("-0.5")) >= 0) {
+                    //误差范围在+0.5之内的、直接忽略
+                    surplusManagement = BigDecimal.ZERO;
+                    refundManagement = BigDecimal.ZERO;
+                }
+                if (surplusManagement.compareTo(BigDecimal.ZERO) < 0) {
+                    refundManagement = surplusManagement.negate();
 
-
+                    ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, surplusManagement, BigDecimal.ZERO,
+                            IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
+                }
+                if (surplusManagement.compareTo(BigDecimal.ZERO) > 0) {
+                    PaymentCollectionPlanFactoring lastManagementFactoring = getLastPrincipalFactoring(allPlanFactoringList, managementFeeDict, lastPlanDate);
+                    //可能存在计划已经在之前的判断中被删除的情况,所以需要再判断一次
+                    if (lastManagementFactoring == null) {
+                        ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(actualDate, surplusManagement, BigDecimal.ZERO,
+                                IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
+                    } else {
+                        //可能存在计划已经在之前的判断中被删除的情况,所以需要再判断一次
+                        boolean exist = ledgerPlanFactoringAssignList.stream().anyMatch(planFactoringAssign ->
+                                planFactoringAssign.getDeleteFlag() != null && planFactoringAssign.getDeleteFlag()
+                                        && planFactoringAssign.getPlanFactoringId() != null && lastManagementFactoring.getId().equals(planFactoringAssign.getPlanFactoringId()));
+                        if (exist) {
+                            //说明最后一期计划被删了
+                            ledgerPlanFactoringAssignList.add(addPlanFactoringInsertAssign(lastManagementFactoring.getPlanDate(), surplusManagement, BigDecimal.ZERO,
+                                    IncomeExpenditureTypeDict.ChildEnum.MANAGEMENT_FEE.getCode(), goodsAssignVo, 0));
+                        } else {
+                            lastManagementFactoring.setAmount(surplusManagement);
+                            ledgerPlanFactoringAssignList.add(addPlanFactoringUpdateAssign(lastManagementFactoring.getPlanDate(), BigDecimal.ZERO,
+                                    lastManagementFactoring, goodsAssignVo, 0));
+                        }
+                    }
+                    refundManagement = BigDecimal.ZERO;
+                }
+            }
             goodsAssignVo.setFinancingPrincipal(financePrincipal);
             goodsAssignVo.setFinancingInterest(financeInterest);
             goodsAssignVo.setFinancingManagementFee(financingManagementFee);

+ 9 - 0
src/main/java/com/sunxung/factoring/service/smb/IFinancingLoanInfoService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.sunxung.factoring.entity.GridPage;
 import com.sunxung.factoring.entity.smb.FinancingLoanInfo;
 import com.sunxung.factoring.entity.smb.vo.FinancingLoanInfoSearch;
+import com.sunxung.factoring.service.smbApi.resp.RepayTrialResp;
 
 /**
  * <p>
@@ -56,4 +57,12 @@ public interface IFinancingLoanInfoService extends IService<FinancingLoanInfo> {
      * @param id
      */
     void refinancingReport(Long id);
+
+    /**
+     * 提前结清还款试算
+     *
+     * @param id
+     * @return
+     */
+    RepayTrialResp repayTrial(Long id);
 }

+ 14 - 0
src/main/java/com/sunxung/factoring/service/smb/impl/FinancingLoanInfoServiceImpl.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.Page;
 import com.github.pagehelper.PageHelper;
 import com.snb.fsos.bean.LoanApply;
+import com.snb.fsos.bean.RepayTrial;
 import com.sunxung.factoring.component.exception.BusinessException;
 import com.sunxung.factoring.component.exception.ValidatorException;
 import com.sunxung.factoring.component.util.CodeUtil;
@@ -48,6 +49,7 @@ import com.sunxung.factoring.service.smbApi.api.SMBApiService;
 import com.sunxung.factoring.service.smbApi.dto.LoanCreditRiskMsgDto;
 import com.sunxung.factoring.service.smbApi.resp.LoanApplyResp;
 import com.sunxung.factoring.service.smbApi.resp.LoanApplyStatusResp;
+import com.sunxung.factoring.service.smbApi.resp.RepayTrialResp;
 import com.sunxung.factoring.service.sys.PermissionService;
 import com.sunxung.factoring.service.sys.RoleService;
 import com.sunxung.factoring.service.sys.UserService;
@@ -374,6 +376,18 @@ public class FinancingLoanInfoServiceImpl extends ServiceImpl<FinancingLoanInfoM
         }
     }
 
+    @Override
+    public RepayTrialResp repayTrial(Long id) {
+        FinancingLoanInfo financingLoanInfo = this.getById(id);
+        if (financingLoanInfo != null) {
+            RepayTrial repayTrial = new RepayTrial();
+            repayTrial.setDuebillNo(financingLoanInfo.getDueBillNo());
+            repayTrial.setRepayKind("1");
+            return smbApiService.repayTrial(repayTrial, financingLoanInfo.getOpenId());
+        }
+        return null;
+    }
+
     /**
      * 保存资方放款信息
      *

+ 23 - 5
src/main/java/com/sunxung/factoring/web/smb/FinancingLoanInfoController.java

@@ -7,6 +7,7 @@ import com.sunxung.factoring.entity.smb.FinancingLoanInfo;
 import com.sunxung.factoring.entity.smb.vo.FinancingFromInvestorsSearchVo;
 import com.sunxung.factoring.entity.smb.vo.FinancingLoanInfoSearch;
 import com.sunxung.factoring.service.smb.IFinancingLoanInfoService;
+import com.sunxung.factoring.service.smbApi.resp.RepayTrialResp;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -23,54 +24,71 @@ public class FinancingLoanInfoController {
 
     /**
      * 列表页查询
+     *
      * @param
      * @return
      */
     @PostMapping("/list")
-    public GridPage<FinancingLoanInfo> findBySearch(@RequestBody FinancingLoanInfoSearch search){
+    public GridPage<FinancingLoanInfo> findBySearch(@RequestBody FinancingLoanInfoSearch search) {
         return financingLoanInfoService.findBySearch(search);
     }
 
     /**
      * 详情页查询
+     *
      * @param
      * @return
      */
     @GetMapping("/detail")
-    public ResponseJson<FinancingLoanInfo> getDetail(Long id){
+    public ResponseJson<FinancingLoanInfo> getDetail(Long id) {
         return new ResponseJson<>(financingLoanInfoService.getDetail(id));
     }
 
     /**
      * 放款状态刷新
+     *
      * @param
      * @return
      */
     @GetMapping("/flushStatus")
-    public ResponseJson flushStatus(Long id){
+    public ResponseJson flushStatus(Long id) {
         financingLoanInfoService.flushStatus(id);
         return new ResponseJson<>("刷新成功");
     }
 
     /**
      * 重新发起放款申请
+     *
      * @param
      * @return
      */
     @GetMapping("/loanApplyAgain")
-    public ResponseJson loanApplyAgain(Long id){
+    public ResponseJson loanApplyAgain(Long id) {
         financingLoanInfoService.loanApplyAgain(id);
         return new ResponseJson<>("放款申请成功");
     }
 
     /**
      * 重新发起再融资支用上报
+     *
      * @param
      * @return
      */
     @GetMapping("/refinancingReport")
-    public ResponseJson refinancingReport(Long id){
+    public ResponseJson refinancingReport(Long id) {
         financingLoanInfoService.refinancingReport(id);
         return new ResponseJson<>("再融资支用上报成功");
     }
+
+    /**
+     * 提前结清还款试算
+     *
+     * @param
+     * @return
+     */
+    @GetMapping("/repayTrial")
+    public ResponseJson repayTrial(Long id) {
+        RepayTrialResp repayTrialResp = financingLoanInfoService.repayTrial(id);
+        return new ResponseJson<>(repayTrialResp);
+    }
 }