From 389a1f15b277042025346b3f9a14c839cb4ab8a9 Mon Sep 17 00:00:00 2001 From: taskain7 Date: Mon, 16 Oct 2023 14:11:06 +0200 Subject: [PATCH] FINERACT-1971: Downpayment repayment undo (#3512) [FINERACT-1971] Downpayment repayment undo --- ...edPaymentScheduleTransactionProcessor.java | 4 +- ...paymentWithDownPaymentIntegrationTest.java | 388 ++++++++++++++++++ 2 files changed, 390 insertions(+), 2 deletions(-) create mode 100644 integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoRepaymentWithDownPaymentIntegrationTest.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java index d51a8fb2f..72b46c601 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java @@ -116,7 +116,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep final ChangedTransactionDetail changedTransactionDetail = new ChangedTransactionDetail(); for (final LoanTransaction loanTransaction : transactionsPostDisbursement) { if (loanTransaction.getId() == null) { - processLatestTransaction(loanTransaction, currency, installments, charges, null); + processLatestTransaction(loanTransaction, currency, installments, charges, Money.zero(currency)); loanTransaction.adjustInterestComponent(currency); } else { /** @@ -127,7 +127,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep // Reset derived component of new loan transaction and // re-process transaction - processLatestTransaction(newLoanTransaction, currency, installments, charges, null); + processLatestTransaction(newLoanTransaction, currency, installments, charges, Money.zero(currency)); newLoanTransaction.adjustInterestComponent(currency); /** * Check if the transaction amounts have changed. If so, reverse the original transaction and update diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoRepaymentWithDownPaymentIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoRepaymentWithDownPaymentIntegrationTest.java new file mode 100644 index 000000000..0502db9a6 --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoRepaymentWithDownPaymentIntegrationTest.java @@ -0,0 +1,388 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.integrationtests; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import io.restassured.builder.RequestSpecBuilder; +import io.restassured.builder.ResponseSpecBuilder; +import io.restassured.http.ContentType; +import io.restassured.specification.RequestSpecification; +import io.restassured.specification.ResponseSpecification; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.fineract.client.models.AdvancedPaymentData; +import org.apache.fineract.client.models.AllowAttributeOverrides; +import org.apache.fineract.client.models.ChargeData; +import org.apache.fineract.client.models.ChargeToGLAccountMapper; +import org.apache.fineract.client.models.GetLoanFeeToIncomeAccountMappings; +import org.apache.fineract.client.models.GetLoanPaymentChannelToFundSourceMappings; +import org.apache.fineract.client.models.GetLoanProductsProductIdResponse; +import org.apache.fineract.client.models.GetLoansLoanIdResponse; +import org.apache.fineract.client.models.PaymentAllocationOrder; +import org.apache.fineract.client.models.PostLoanProductsRequest; +import org.apache.fineract.client.models.PostLoanProductsResponse; +import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse; +import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest; +import org.apache.fineract.client.models.PostPaymentTypesRequest; +import org.apache.fineract.client.models.PostPaymentTypesResponse; +import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; +import org.apache.fineract.integrationtests.common.BusinessDateHelper; +import org.apache.fineract.integrationtests.common.ClientHelper; +import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper; +import org.apache.fineract.integrationtests.common.PaymentTypeHelper; +import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.integrationtests.common.accounting.Account; +import org.apache.fineract.integrationtests.common.accounting.AccountHelper; +import org.apache.fineract.integrationtests.common.accounting.JournalEntryHelper; +import org.apache.fineract.integrationtests.common.funds.FundsHelper; +import org.apache.fineract.integrationtests.common.funds.FundsResourceHandler; +import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder; +import org.apache.fineract.integrationtests.common.loans.LoanProductHelper; +import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension; +import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper; +import org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper; +import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(LoanTestLifecycleExtension.class) +public class UndoRepaymentWithDownPaymentIntegrationTest { + + private static final DateTimeFormatter DATE_FORMATTER = new DateTimeFormatterBuilder().appendPattern("dd MMMM yyyy").toFormatter(); + private ResponseSpecification responseSpec; + private RequestSpecification requestSpec; + private ClientHelper clientHelper; + private LoanTransactionHelper loanTransactionHelper; + private JournalEntryHelper journalEntryHelper; + private AccountHelper accountHelper; + private LoanProductHelper loanProductHelper; + private PaymentTypeHelper paymentTypeHelper; + // asset + private Account loansReceivable; + private Account interestFeeReceivable; + private Account suspenseAccount; + private Account fundReceivables; + // liability + private Account suspenseClearingAccount; + private Account overpaymentAccount; + // income + private Account interestIncome; + private Account feeIncome; + private Account feeChargeOff; + private Account recoveries; + private Account interestIncomeChargeOff; + // expense + private Account creditLossBadDebt; + private Account creditLossBadDebtFraud; + private Account writtenOff; + private Account goodwillExpenseAccount; + + @BeforeEach + public void setup() { + Utils.initializeRESTAssured(); + this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); + this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); + this.accountHelper = new AccountHelper(this.requestSpec, this.responseSpec); + this.loanProductHelper = new LoanProductHelper(); + this.paymentTypeHelper = new PaymentTypeHelper(); + + // Asset + this.loansReceivable = this.accountHelper.createAssetAccount(); + this.interestFeeReceivable = this.accountHelper.createAssetAccount(); + this.suspenseAccount = this.accountHelper.createAssetAccount(); + this.fundReceivables = this.accountHelper.createAssetAccount(); + + // Liability + this.suspenseClearingAccount = this.accountHelper.createLiabilityAccount(); + this.overpaymentAccount = this.accountHelper.createLiabilityAccount(); + + // income + this.interestIncome = this.accountHelper.createIncomeAccount(); + this.feeIncome = this.accountHelper.createIncomeAccount(); + this.feeChargeOff = this.accountHelper.createIncomeAccount(); + this.recoveries = this.accountHelper.createIncomeAccount(); + this.interestIncomeChargeOff = this.accountHelper.createIncomeAccount(); + + // expense + this.creditLossBadDebt = this.accountHelper.createExpenseAccount(); + this.creditLossBadDebtFraud = this.accountHelper.createExpenseAccount(); + this.writtenOff = this.accountHelper.createExpenseAccount(); + this.goodwillExpenseAccount = this.accountHelper.createExpenseAccount(); + + this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + } + + @Test + public void undoRepaymentWithDownPaymentAndAdvancedPaymentAllocationTest() { + GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE); + + String loanExternalIdStr = UUID.randomUUID().toString(); + + Boolean enableDownPayment = true; + BigDecimal disbursedAmountPercentageForDownPayment = BigDecimal.valueOf(25); + Boolean enableAutoRepaymentForDownPayment = true; + + final Integer clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue(); + + Integer loanProductId = createLoanProductWithPeriodicAccrualAccountingAndAdvancedPaymentAllocationStrategy(); + + final GetLoanProductsProductIdResponse getLoanProductsProductResponse = loanTransactionHelper.getLoanProduct(loanProductId); + assertNotNull(getLoanProductsProductResponse); + assertEquals(enableDownPayment, getLoanProductsProductResponse.getEnableDownPayment()); + assertEquals(0, getLoanProductsProductResponse.getDisbursedAmountPercentageForDownPayment() + .compareTo(disbursedAmountPercentageForDownPayment)); + assertEquals(enableAutoRepaymentForDownPayment, getLoanProductsProductResponse.getEnableAutoRepaymentForDownPayment()); + + final Integer loanId = createApproveAndDisburseLoanAccount(clientId, loanProductId.longValue(), loanExternalIdStr, "1", "0"); + + GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue()); + + assertNotNull(loanDetails); + assertEquals(enableDownPayment, loanDetails.getEnableDownPayment()); + assertEquals(0, loanDetails.getDisbursedAmountPercentageForDownPayment().compareTo(disbursedAmountPercentageForDownPayment)); + assertEquals(enableAutoRepaymentForDownPayment, loanDetails.getEnableAutoRepaymentForDownPayment()); + + PostLoansLoanIdTransactionsResponse postLoansLoanIdTransactionsResponse = loanTransactionHelper + .makeLoanRepayment("05 September 2022", 500.0f, loanId); + Long repaymentTransactionId = postLoansLoanIdTransactionsResponse.getResourceId(); + + BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 9, 25)); + PostLoansLoanIdTransactionsResponse secondPostLoansLoanIdTransactionsResponse = loanTransactionHelper + .makeLoanRepayment("25 September 2022", 250.0f, loanId); + Long secondRepaymentId = secondPostLoansLoanIdTransactionsResponse.getResourceId(); + + BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 9, 28)); + loanTransactionHelper.chargebackLoanTransaction(loanExternalIdStr, secondRepaymentId, + new PostLoansLoanIdTransactionsTransactionIdRequest().locale("en").transactionAmount(100.0).paymentTypeId(1L)); + + BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 9, 30)); + loanTransactionHelper.makeLoanRepayment("30 September 2022", 100.0f, loanId); + + PostLoansLoanIdTransactionsResponse postLoansLoanIdTransactionsResponse1 = loanTransactionHelper.reverseLoanTransaction(loanId, + repaymentTransactionId, "05 September 2022", responseSpec); + + assertNotNull(postLoansLoanIdTransactionsResponse1); + + loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue()); + assertEquals(500, loanDetails.getSummary().getTotalOutstanding()); + } + + private Integer createLoanProductWithPeriodicAccrualAccountingAndAdvancedPaymentAllocationStrategy() { + + String name = Utils.uniqueRandomStringGenerator("LOAN_PRODUCT_", 6); + String shortName = Utils.uniqueRandomStringGenerator("", 4); + + List principalVariationsForBorrowerCycle = new ArrayList<>(); + List numberOfRepaymentVariationsForBorrowerCycle = new ArrayList<>(); + List interestRateVariationsForBorrowerCycle = new ArrayList<>(); + List charges = new ArrayList<>(); + List penaltyToIncomeAccountMappings = new ArrayList<>(); + List feeToIncomeAccountMappings = new ArrayList<>(); + + String paymentTypeName = PaymentTypeHelper.randomNameGenerator("P_T", 5); + String description = PaymentTypeHelper.randomNameGenerator("PT_Desc", 15); + Boolean isCashPayment = false; + Integer position = 1; + + PostPaymentTypesResponse paymentTypesResponse = paymentTypeHelper.createPaymentType(new PostPaymentTypesRequest() + .name(paymentTypeName).description(description).isCashPayment(isCashPayment).position(position)); + Long paymentTypeIdOne = paymentTypesResponse.getResourceId(); + Assertions.assertNotNull(paymentTypeIdOne); + + List paymentChannelToFundSourceMappings = new ArrayList<>(); + GetLoanPaymentChannelToFundSourceMappings loanPaymentChannelToFundSourceMappings = new GetLoanPaymentChannelToFundSourceMappings(); + loanPaymentChannelToFundSourceMappings.fundSourceAccountId(fundReceivables.getAccountID().longValue()); + loanPaymentChannelToFundSourceMappings.paymentTypeId(paymentTypeIdOne.longValue()); + paymentChannelToFundSourceMappings.add(loanPaymentChannelToFundSourceMappings); + + // fund + FundsHelper fh = FundsHelper.create(Utils.uniqueRandomStringGenerator("", 10)).externalId(UUID.randomUUID().toString()).build(); + String jsonData = fh.toJSON(); + + final Long fundID = createFund(jsonData, this.requestSpec, this.responseSpec); + Assertions.assertNotNull(fundID); + + // Delinquency Bucket + final Integer delinquencyBucketId = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, responseSpec); + + String futureInstallmentAllocationRule = "NEXT_INSTALLMENT"; + AdvancedPaymentData defaultAllocation = createDefaultPaymentAllocation(futureInstallmentAllocationRule); + + PostLoanProductsRequest loanProductsRequest = new PostLoanProductsRequest().name(name)// + .shortName(shortName)// + .description("Loan Product Description")// + .fundId(fundID)// + .startDate(null)// + .closeDate(null)// + .includeInBorrowerCycle(false)// + .currencyCode("USD")// + .digitsAfterDecimal(2)// + .inMultiplesOf(0)// + .installmentAmountInMultiplesOf(1)// + .useBorrowerCycle(false)// + .minPrincipal(100.0)// + .principal(1000.0)// + .maxPrincipal(10000.0)// + .minNumberOfRepayments(1)// + .numberOfRepayments(1)// + .maxNumberOfRepayments(30)// + .isLinkedToFloatingInterestRates(false)// + .minInterestRatePerPeriod((double) 0)// + .interestRatePerPeriod((double) 0)// + .maxInterestRatePerPeriod((double) 0)// + .interestRateFrequencyType(2)// + .repaymentEvery(30)// + .repaymentFrequencyType(0)// + .principalVariationsForBorrowerCycle(principalVariationsForBorrowerCycle)// + .numberOfRepaymentVariationsForBorrowerCycle(numberOfRepaymentVariationsForBorrowerCycle)// + .interestRateVariationsForBorrowerCycle(interestRateVariationsForBorrowerCycle)// + .amortizationType(1)// + .interestType(0)// + .isEqualAmortization(false)// + .interestCalculationPeriodType(1)// + .transactionProcessingStrategyCode("advanced-payment-allocation-strategy")// + .addPaymentAllocationItem(defaultAllocation)// + .daysInYearType(1)// + .daysInMonthType(1)// + .canDefineInstallmentAmount(true)// + .graceOnArrearsAgeing(3)// + .overdueDaysForNPA(179)// + .accountMovesOutOfNPAOnlyOnArrearsCompletion(false)// + .principalThresholdForLastInstallment(50)// + .allowVariableInstallments(false)// + .canUseForTopup(false)// + .isInterestRecalculationEnabled(false)// + .enableDownPayment(true).enableAutoRepaymentForDownPayment(true) + .disbursedAmountPercentageForDownPayment(BigDecimal.valueOf(25)).holdGuaranteeFunds(false)// + .multiDisburseLoan(true)// + .allowAttributeOverrides(new AllowAttributeOverrides()// + .amortizationType(true)// + .interestType(true)// + .transactionProcessingStrategyCode(true)// + .interestCalculationPeriodType(true)// + .inArrearsTolerance(true)// + .repaymentEvery(true)// + .graceOnPrincipalAndInterestPayment(true)// + .graceOnArrearsAgeing(true))// + .allowPartialPeriodInterestCalcualtion(true)// + .maxTrancheCount(10)// + .outstandingLoanBalance(10000.0)// + .charges(charges)// + .accountingRule(3)// + .fundSourceAccountId(suspenseClearingAccount.getAccountID().longValue())// + .loanPortfolioAccountId(loansReceivable.getAccountID().longValue())// + .transfersInSuspenseAccountId(suspenseAccount.getAccountID().longValue())// + .interestOnLoanAccountId(interestIncome.getAccountID().longValue())// + .incomeFromFeeAccountId(feeIncome.getAccountID().longValue())// + .incomeFromPenaltyAccountId(feeIncome.getAccountID().longValue())// + .incomeFromRecoveryAccountId(recoveries.getAccountID().longValue())// + .writeOffAccountId(writtenOff.getAccountID().longValue())// + .overpaymentLiabilityAccountId(overpaymentAccount.getAccountID().longValue())// + .receivableInterestAccountId(interestFeeReceivable.getAccountID().longValue())// + .receivableFeeAccountId(interestFeeReceivable.getAccountID().longValue())// + .receivablePenaltyAccountId(interestFeeReceivable.getAccountID().longValue())// + .dateFormat("dd MMMM yyyy")// + .locale("en_GB")// + .disallowExpectedDisbursements(true)// + .allowApprovedDisbursedAmountsOverApplied(true)// + .overAppliedCalculationType("percentage")// + .overAppliedNumber(50)// + .delinquencyBucketId(delinquencyBucketId.longValue())// + .goodwillCreditAccountId(goodwillExpenseAccount.getAccountID().longValue())// + .incomeFromGoodwillCreditInterestAccountId(interestIncomeChargeOff.getAccountID().longValue())// + .incomeFromGoodwillCreditFeesAccountId(feeChargeOff.getAccountID().longValue())// + .incomeFromGoodwillCreditPenaltyAccountId(feeChargeOff.getAccountID().longValue())// + .paymentChannelToFundSourceMappings(paymentChannelToFundSourceMappings)// + .penaltyToIncomeAccountMappings(penaltyToIncomeAccountMappings)// + .feeToIncomeAccountMappings(feeToIncomeAccountMappings)// + .incomeFromChargeOffInterestAccountId(interestIncomeChargeOff.getAccountID().longValue())// + .incomeFromChargeOffFeesAccountId(feeChargeOff.getAccountID().longValue())// + .chargeOffExpenseAccountId(creditLossBadDebt.getAccountID().longValue())// + .chargeOffFraudExpenseAccountId(creditLossBadDebtFraud.getAccountID().longValue())// + .incomeFromChargeOffPenaltyAccountId(feeChargeOff.getAccountID().longValue());// + + PostLoanProductsResponse loanProductCreateResponse = loanProductHelper.createLoanProduct(loanProductsRequest); + return loanProductCreateResponse.getResourceId().intValue(); + } + + private Integer createApproveAndDisburseLoanAccount(final Integer clientID, final Long loanProductID, final String externalId, + final String numberOfRepayments, final String interestRate) { + + String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency(numberOfRepayments) + .withLoanTermFrequencyAsMonths().withNumberOfRepayments(numberOfRepayments).withRepaymentEveryAfter("1") + .withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod(interestRate).withInterestTypeAsFlatBalance() + .withAmortizationTypeAsEqualPrincipalPayments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod() + .withExpectedDisbursementDate("03 September 2022").withSubmittedOnDate("01 September 2022").withLoanType("individual") + .withExternalId(externalId).build(clientID.toString(), loanProductID.toString(), null); + + final Integer loanId = loanTransactionHelper.getLoanId(loanApplicationJSON); + loanTransactionHelper.approveLoan("02 September 2022", "1000", loanId, null); + loanTransactionHelper.disburseLoanWithTransactionAmount("03 September 2022", loanId, "1000"); + return loanId; + } + + private Long createFund(final String fundJSON, final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { + String fundId = String.valueOf(FundsResourceHandler.createFund(fundJSON, requestSpec, responseSpec)); + if (fundId.equals("null")) { + // Invalid JSON data parameters + return null; + } + + return Long.valueOf(fundId); + } + + private AdvancedPaymentData createDefaultPaymentAllocation(String futureInstallmentAllocationRule) { + AdvancedPaymentData advancedPaymentData = new AdvancedPaymentData(); + advancedPaymentData.setTransactionType("DEFAULT"); + advancedPaymentData.setFutureInstallmentAllocationRule(futureInstallmentAllocationRule); + + List paymentAllocationOrders = getPaymentAllocationOrder(PaymentAllocationType.PAST_DUE_PENALTY, + PaymentAllocationType.PAST_DUE_FEE, PaymentAllocationType.PAST_DUE_PRINCIPAL, PaymentAllocationType.PAST_DUE_INTEREST, + PaymentAllocationType.DUE_PENALTY, PaymentAllocationType.DUE_FEE, PaymentAllocationType.DUE_PRINCIPAL, + PaymentAllocationType.DUE_INTEREST, PaymentAllocationType.IN_ADVANCE_PENALTY, PaymentAllocationType.IN_ADVANCE_FEE, + PaymentAllocationType.IN_ADVANCE_PRINCIPAL, PaymentAllocationType.IN_ADVANCE_INTEREST); + + advancedPaymentData.setPaymentAllocationOrder(paymentAllocationOrders); + return advancedPaymentData; + } + + private List getPaymentAllocationOrder(PaymentAllocationType... paymentAllocationTypes) { + AtomicInteger integer = new AtomicInteger(1); + return Arrays.stream(paymentAllocationTypes).map(pat -> { + PaymentAllocationOrder paymentAllocationOrder = new PaymentAllocationOrder(); + paymentAllocationOrder.setPaymentAllocationRule(pat.name()); + paymentAllocationOrder.setOrder(integer.getAndIncrement()); + return paymentAllocationOrder; + }).toList(); + } +}