From 29b900cccd43a12f2b0332eda076ff9b935dad8f Mon Sep 17 00:00:00 2001 From: Ruchi Dhamankar Date: Mon, 5 Dec 2022 19:38:05 +0530 Subject: [PATCH] FINERACT-1818-Loan-Retrieve-Api-data-addition --- .../loanaccount/api/LoansApiResource.java | 6 + .../api/LoansApiResourceSwagger.java | 26 ++ .../loanaccount/data/LoanSummaryData.java | 89 ++++++- .../api/SelfLoansApiResourceSwagger.java | 26 ++ .../LoanTransactionSummaryTest.java | 225 ++++++++++++++++++ 5 files changed, 370 insertions(+), 2 deletions(-) create mode 100644 integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionSummaryTest.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java index a168fe814..e1e8ae05d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java @@ -119,6 +119,7 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData; import org.apache.fineract.portfolio.loanaccount.data.LoanApprovalData; import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData; import org.apache.fineract.portfolio.loanaccount.data.LoanCollateralManagementData; +import org.apache.fineract.portfolio.loanaccount.data.LoanSummaryData; import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData; import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData; import org.apache.fineract.portfolio.loanaccount.data.PaidInAdvanceData; @@ -713,6 +714,11 @@ public class LoansApiResource { rates = this.rateReadService.retrieveLoanRates(loanId); } + // updating summary with transaction amounts summary + if (loanRepayments != null) { + loanBasicDetails.setSummary(LoanSummaryData.withTransactionAmountsSummary(loanBasicDetails.getSummary(), loanRepayments)); + } + final LoanAccountData loanAccount = LoanAccountData.associationsAndTemplate(loanBasicDetails, repaymentSchedule, loanRepayments, charges, loanCollateralManagementData, guarantors, meeting, productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions, diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java index fbd8777b0..fa32ec58a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java @@ -561,6 +561,32 @@ final class LoansApiResourceSwagger { public Boolean inArrears; @Schema(example = "false") public Boolean isNPA; + @Schema(example = "0.000000") + public Double totalMerchantRefund; + @Schema(example = "0.000000") + public Double totalMerchantRefundReversed; + @Schema(example = "0.000000") + public Double totalPayoutRefund; + @Schema(example = "0.000000") + public Double totalPayoutRefundReversed; + @Schema(example = "0.000000") + public Double totalGoodwillCredit; + @Schema(example = "0.000000") + public Double totalGoodwillCreditReversed; + @Schema(example = "0.000000") + public Double totalChargeAdjustment; + @Schema(example = "0.000000") + public Double totalChargeAdjustmentReversed; + @Schema(example = "0.000000") + public Double totalChargeback; + @Schema(example = "0.000000") + public Double totalCreditBalanceRefund; + @Schema(example = "0.000000") + public Double totalCreditBalanceRefundReversed; + @Schema(example = "0.000000") + public Double totalRepaymentTransaction; + @Schema(example = "0.000000") + public Double totalRepaymentTransactionReversed; public Set overdueCharges; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanSummaryData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanSummaryData.java index d9f33e2d7..ee2c9797a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanSummaryData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanSummaryData.java @@ -20,13 +20,17 @@ package org.apache.fineract.portfolio.loanaccount.data; import java.math.BigDecimal; import java.time.LocalDate; -import lombok.Getter; +import java.util.Collection; +import lombok.Data; +import lombok.experimental.Accessors; import org.apache.fineract.organisation.monetary.data.CurrencyData; +import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType; /** * Immutable data object representing loan summary information. */ -@Getter +@Data +@Accessors(chain = true) public class LoanSummaryData { private final CurrencyData currency; @@ -68,6 +72,21 @@ public class LoanSummaryData { private final Long writeoffReasonId; private final String writeoffReason; + // Adding fields for transaction summary + private BigDecimal totalMerchantRefund; + private BigDecimal totalMerchantRefundReversed; + private BigDecimal totalPayoutRefund; + private BigDecimal totalPayoutRefundReversed; + private BigDecimal totalGoodwillCredit; + private BigDecimal totalGoodwillCreditReversed; + private BigDecimal totalChargeAdjustment; + private BigDecimal totalChargeAdjustmentReversed; + private BigDecimal totalChargeback; + private BigDecimal totalCreditBalanceRefund; + private BigDecimal totalCreditBalanceRefundReversed; + private BigDecimal totalRepaymentTransaction; + private BigDecimal totalRepaymentTransactionReversed; + public LoanSummaryData(final CurrencyData currency, final BigDecimal principalDisbursed, final BigDecimal principalAdjustments, final BigDecimal principalPaid, final BigDecimal principalWrittenOff, final BigDecimal principalOutstanding, final BigDecimal principalOverdue, final BigDecimal interestCharged, final BigDecimal interestPaid, @@ -120,4 +139,70 @@ public class LoanSummaryData { this.writeoffReason = writeoffReason; this.totalRecovered = totalRecovered; } + + public static LoanSummaryData withTransactionAmountsSummary(final LoanSummaryData defaultSummaryData, + final Collection loanTransactions) { + + BigDecimal totalMerchantRefund = computeTotalAmountForNonReversedTransactions(LoanTransactionType.MERCHANT_ISSUED_REFUND, + loanTransactions); + BigDecimal totalMerchantRefundReversed = computeTotalAmountForReversedTransactions(LoanTransactionType.MERCHANT_ISSUED_REFUND, + loanTransactions); + BigDecimal totalPayoutRefund = computeTotalAmountForNonReversedTransactions(LoanTransactionType.PAYOUT_REFUND, loanTransactions); + BigDecimal totalPayoutRefundReversed = computeTotalAmountForReversedTransactions(LoanTransactionType.PAYOUT_REFUND, + loanTransactions); + BigDecimal totalGoodwillCredit = computeTotalAmountForNonReversedTransactions(LoanTransactionType.GOODWILL_CREDIT, + loanTransactions); + BigDecimal totalGoodwillCreditReversed = computeTotalAmountForReversedTransactions(LoanTransactionType.GOODWILL_CREDIT, + loanTransactions); + BigDecimal totalChargeAdjustment = computeTotalAmountForNonReversedTransactions(LoanTransactionType.CHARGE_ADJUSTMENT, + loanTransactions); + BigDecimal totalChargeAdjustmentReversed = computeTotalAmountForReversedTransactions(LoanTransactionType.CHARGE_ADJUSTMENT, + loanTransactions); + BigDecimal totalChargeback = computeTotalAmountForNonReversedTransactions(LoanTransactionType.CHARGEBACK, loanTransactions); + BigDecimal totalCreditBalanceRefund = computeTotalAmountForNonReversedTransactions(LoanTransactionType.CREDIT_BALANCE_REFUND, + loanTransactions); + BigDecimal totalCreditBalanceRefundReversed = computeTotalAmountForReversedTransactions(LoanTransactionType.CREDIT_BALANCE_REFUND, + loanTransactions); + BigDecimal totalRepaymentTransaction = computeTotalAmountForNonReversedTransactions(LoanTransactionType.REPAYMENT, + loanTransactions); + BigDecimal totalRepaymentTransactionReversed = computeTotalAmountForReversedTransactions(LoanTransactionType.REPAYMENT, + loanTransactions); + + return new LoanSummaryData(defaultSummaryData.currency, defaultSummaryData.principalDisbursed, + defaultSummaryData.principalAdjustments, defaultSummaryData.principalPaid, defaultSummaryData.principalWrittenOff, + defaultSummaryData.principalOutstanding, defaultSummaryData.principalOverdue, defaultSummaryData.interestCharged, + defaultSummaryData.interestPaid, defaultSummaryData.interestWaived, defaultSummaryData.interestWrittenOff, + defaultSummaryData.interestOutstanding, defaultSummaryData.interestOverdue, defaultSummaryData.feeChargesCharged, + defaultSummaryData.feeChargesDueAtDisbursementCharged, defaultSummaryData.feeChargesPaid, + defaultSummaryData.feeChargesWaived, defaultSummaryData.feeChargesWrittenOff, defaultSummaryData.feeChargesOutstanding, + defaultSummaryData.feeChargesOverdue, defaultSummaryData.penaltyChargesCharged, defaultSummaryData.penaltyChargesPaid, + defaultSummaryData.penaltyChargesWaived, defaultSummaryData.penaltyChargesWrittenOff, + defaultSummaryData.penaltyChargesOutstanding, defaultSummaryData.penaltyChargesOverdue, + defaultSummaryData.totalExpectedRepayment, defaultSummaryData.totalRepayment, defaultSummaryData.totalExpectedCostOfLoan, + defaultSummaryData.totalCostOfLoan, defaultSummaryData.totalWaived, defaultSummaryData.totalWrittenOff, + defaultSummaryData.totalOutstanding, defaultSummaryData.totalOverdue, defaultSummaryData.overdueSinceDate, + defaultSummaryData.writeoffReasonId, defaultSummaryData.writeoffReason, defaultSummaryData.totalRecovered) + .setTotalMerchantRefund(totalMerchantRefund).setTotalMerchantRefundReversed(totalMerchantRefundReversed) + .setTotalPayoutRefund(totalPayoutRefund).setTotalPayoutRefundReversed(totalPayoutRefundReversed) + .setTotalGoodwillCredit(totalGoodwillCredit).setTotalGoodwillCreditReversed(totalGoodwillCreditReversed) + .setTotalChargeAdjustment(totalChargeAdjustment).setTotalChargeAdjustmentReversed(totalChargeAdjustmentReversed) + .setTotalChargeback(totalChargeback).setTotalCreditBalanceRefund(totalCreditBalanceRefund) + .setTotalCreditBalanceRefundReversed(totalCreditBalanceRefundReversed) + .setTotalRepaymentTransaction(totalRepaymentTransaction) + .setTotalRepaymentTransactionReversed(totalRepaymentTransactionReversed); + } + + private static BigDecimal computeTotalAmountForReversedTransactions(LoanTransactionType transactionType, + Collection loanTransactions) { + return loanTransactions.stream().filter( + transaction -> transaction.getType().getCode().equals(transactionType.getCode()) && transaction.getReversedOnDate() != null) + .map(txn -> txn.getAmount()).reduce(BigDecimal.ZERO, BigDecimal::add); + } + + private static BigDecimal computeTotalAmountForNonReversedTransactions(LoanTransactionType transactionType, + Collection loanTransactions) { + return loanTransactions.stream().filter( + transaction -> transaction.getType().getCode().equals(transactionType.getCode()) && transaction.getReversedOnDate() == null) + .map(txn -> txn.getAmount()).reduce(BigDecimal.ZERO, BigDecimal::add); + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResourceSwagger.java index c00a3b6da..5f988beb5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResourceSwagger.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResourceSwagger.java @@ -434,6 +434,32 @@ final class SelfLoansApiResourceSwagger { public Boolean inArrears; @Schema(example = "false") public Boolean isNPA; + @Schema(example = "0.000000") + public Double totalMerchantRefund; + @Schema(example = "0.000000") + public Double totalMerchantRefundReversed; + @Schema(example = "0.000000") + public Double totalPayoutRefund; + @Schema(example = "0.000000") + public Double totalPayoutRefundReversed; + @Schema(example = "0.000000") + public Double totalGoodwillCredit; + @Schema(example = "0.000000") + public Double totalGoodwillCreditReversed; + @Schema(example = "0.000000") + public Double totalChargeAdjustment; + @Schema(example = "0.000000") + public Double totalChargeAdjustmentReversed; + @Schema(example = "0.000000") + public Double totalChargeback; + @Schema(example = "0.000000") + public Double totalCreditBalanceRefund; + @Schema(example = "0.000000") + public Double totalCreditBalanceRefundReversed; + @Schema(example = "0.000000") + public Double totalRepaymentTransaction; + @Schema(example = "0.000000") + public Double totalRepaymentTransactionReversed; public Set overdueCharges; } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionSummaryTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionSummaryTest.java new file mode 100644 index 000000000..8c5f2881e --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionSummaryTest.java @@ -0,0 +1,225 @@ +/** + * 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.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.util.HashMap; +import java.util.UUID; +import org.apache.fineract.client.models.GetDelinquencyBucketsResponse; +import org.apache.fineract.client.models.GetLoanProductsProductIdResponse; +import org.apache.fineract.client.models.GetLoansLoanIdResponse; +import org.apache.fineract.client.models.GetLoansLoanIdSummary; +import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest; +import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdResponse; +import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest; +import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse; +import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest; +import org.apache.fineract.integrationtests.common.ClientHelper; +import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.integrationtests.common.charges.ChargesHelper; +import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder; +import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder; +import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper; +import org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class LoanTransactionSummaryTest { + + private ResponseSpecification responseSpec; + private ResponseSpecification responseSpecErr400; + private ResponseSpecification responseSpecErr503; + private RequestSpecification requestSpec; + private ClientHelper clientHelper; + private LoanTransactionHelper loanTransactionHelper; + private DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder().appendPattern("dd MMMM yyyy").toFormatter(); + + @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.responseSpecErr400 = new ResponseSpecBuilder().expectStatusCode(400).build(); + this.responseSpecErr503 = new ResponseSpecBuilder().expectStatusCode(503).build(); + this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + } + + @Test + public void loanTransactionSummaryTest() { + // Loan ExternalId + String loanExternalIdStr = UUID.randomUUID().toString(); + + // Delinquency Bucket + final Integer delinquencyBucketId = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, responseSpec); + final GetDelinquencyBucketsResponse delinquencyBucket = DelinquencyBucketsHelper.getDelinquencyBucket(requestSpec, responseSpec, + delinquencyBucketId); + + // Client and Loan account creation + + final Integer clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue(); + final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper, + delinquencyBucketId); + assertNotNull(getLoanProductsProductResponse); + + final Integer loanId = createLoanAccount(clientId, getLoanProductsProductResponse.getId(), loanExternalIdStr); + + // make Repayments + final PostLoansLoanIdTransactionsResponse repaymentTransaction_1 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("5 September 2022").locale("en") + .transactionAmount(100.0)); + + final PostLoansLoanIdTransactionsResponse repaymentTransaction_2 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("6 September 2022").locale("en") + .transactionAmount(100.0)); + + final PostLoansLoanIdTransactionsResponse repaymentTransaction_3 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("7 September 2022").locale("en") + .transactionAmount(50.0)); + + // reverse Repayment + loanTransactionHelper.reverseRepayment(loanId, repaymentTransaction_3.getResourceId().intValue(), "7 September 2022"); + + // Merchant Refund + final PostLoansLoanIdTransactionsResponse merchantIssuedRefund_1 = loanTransactionHelper.makeMerchantIssuedRefund((long) loanId, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("8 September 2022").locale("en") + .transactionAmount(100.0)); + + final PostLoansLoanIdTransactionsResponse merchantIssuedRefund_2 = loanTransactionHelper.makeMerchantIssuedRefund((long) loanId, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("8 September 2022").locale("en") + .transactionAmount(50.0)); + + // reverse Merchant Refund + loanTransactionHelper.reverseRepayment(loanId, merchantIssuedRefund_2.getResourceId().intValue(), "8 September 2022"); + + // Payout Refund + final PostLoansLoanIdTransactionsResponse payoutRefund_1 = loanTransactionHelper.makePayoutRefund((long) loanId, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("9 September 2022").locale("en") + .transactionAmount(100.0)); + + final PostLoansLoanIdTransactionsResponse payoutRefund_2 = loanTransactionHelper.makePayoutRefund((long) loanId, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("9 September 2022").locale("en") + .transactionAmount(50.0)); + + // reverse Payout Refund + loanTransactionHelper.reverseRepayment(loanId, payoutRefund_2.getResourceId().intValue(), "9 September 2022"); + + // Goodwill Credit + final PostLoansLoanIdTransactionsResponse goodwillCredit_1 = loanTransactionHelper.makeGoodwillCredit((long) loanId, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("10 September 2022").locale("en") + .transactionAmount(100.0)); + + final PostLoansLoanIdTransactionsResponse goodwillCredit_2 = loanTransactionHelper.makeGoodwillCredit((long) loanId, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("10 September 2022").locale("en") + .transactionAmount(50.0)); + + // reverse Goodwill Credit + loanTransactionHelper.reverseRepayment(loanId, goodwillCredit_2.getResourceId().intValue(), "10 September 2022"); + + // Chargeback + + final PostLoansLoanIdTransactionsResponse repaymentTransaction_4 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("11 September 2022").locale("en") + .transactionAmount(150.0)); + + loanTransactionHelper.chargebackLoanTransaction(loanExternalIdStr, repaymentTransaction_4.getResourceId(), + new PostLoansLoanIdTransactionsTransactionIdRequest().locale("en").transactionAmount(50.0).paymentTypeId(1L)); + + // Charge Adjustment + + // Add Charge + Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "10", true)); + + LocalDate targetDate = LocalDate.of(2022, 9, 10); + final String penaltyCharge1AddedDate = dateFormatter.format(targetDate); + + Integer penalty1LoanChargeId = this.loanTransactionHelper.addChargesForLoan(loanId, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), penaltyCharge1AddedDate, "10")); + + PostLoansLoanIdChargesChargeIdResponse chargeAdjustmentResult = loanTransactionHelper.chargeAdjustment((long) loanId, + (long) penalty1LoanChargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(10.0).locale("en")); + + // Retrieve Loan with loanId + + GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); + + // verify transaction summary fields + + GetLoansLoanIdSummary loanSummary = loanDetails.getSummary(); + + assertNotNull(loanSummary); + + // repayment + assertEquals(loanSummary.getTotalRepaymentTransaction(), 350.00); + // repayment reversed + assertEquals(loanSummary.getTotalRepaymentTransactionReversed(), 50.00); + // merchant refund + assertEquals(loanSummary.getTotalMerchantRefund(), 100.00); + // merchant refund reversed + assertEquals(loanSummary.getTotalMerchantRefundReversed(), 50.00); + // payout refund + assertEquals(loanSummary.getTotalPayoutRefund(), 100.00); + // payout refund reversed + assertEquals(loanSummary.getTotalPayoutRefundReversed(), 50.00); + // goodwill credit + assertEquals(loanSummary.getTotalGoodwillCredit(), 100.00); + // goodwill credit reversed + assertEquals(loanSummary.getTotalGoodwillCreditReversed(), 50.00); + // charge adjustment + assertEquals(loanSummary.getTotalChargeAdjustment(), 10.00); + // charge + assertEquals(loanSummary.getTotalChargeback(), 50.00); + + } + + private GetLoanProductsProductIdResponse createLoanProduct(final LoanTransactionHelper loanTransactionHelper, + final Integer delinquencyBucketId) { + final HashMap loanProductMap = new LoanProductTestBuilder().build(null, delinquencyBucketId); + final Integer loanProductId = loanTransactionHelper.getLoanProductId(Utils.convertToJson(loanProductMap)); + return loanTransactionHelper.getLoanProduct(loanProductId); + } + + private Integer createLoanAccount(final Integer clientID, final Long loanProductID, final String externalId) { + + String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency("1") + .withLoanTermFrequencyAsMonths().withNumberOfRepayments("1").withRepaymentEveryAfter("1") + .withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod("0").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.disburseLoanWithNetDisbursalAmount("03 September 2022", loanId, "1000"); + return loanId; + } + +}