FINERACT-2020:Added currency field to LoanAccountSummaryData, also added integration test and swagger documentation
This commit is contained in:
+5
-2
@@ -22,6 +22,7 @@ import java.math.BigDecimal;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
|
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||||
import org.apache.fineract.portfolio.loanaccount.data.LoanApplicationTimelineData;
|
import org.apache.fineract.portfolio.loanaccount.data.LoanApplicationTimelineData;
|
||||||
import org.apache.fineract.portfolio.loanaccount.data.LoanStatusEnumData;
|
import org.apache.fineract.portfolio.loanaccount.data.LoanStatusEnumData;
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ public class LoanAccountSummaryData {
|
|||||||
private final String productName;
|
private final String productName;
|
||||||
private final String shortProductName;
|
private final String shortProductName;
|
||||||
private final LoanStatusEnumData status;
|
private final LoanStatusEnumData status;
|
||||||
|
private final CurrencyData currency;
|
||||||
private final EnumOptionData loanType;
|
private final EnumOptionData loanType;
|
||||||
private final Integer loanCycle;
|
private final Integer loanCycle;
|
||||||
private final LoanApplicationTimelineData timeline;
|
private final LoanApplicationTimelineData timeline;
|
||||||
@@ -50,8 +52,8 @@ public class LoanAccountSummaryData {
|
|||||||
|
|
||||||
public LoanAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId,
|
public LoanAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId,
|
||||||
final String loanProductName, final String shortLoanProductName, final LoanStatusEnumData loanStatus,
|
final String loanProductName, final String shortLoanProductName, final LoanStatusEnumData loanStatus,
|
||||||
final EnumOptionData loanType, final Integer loanCycle, final LoanApplicationTimelineData timeline, final Boolean inArrears,
|
final CurrencyData currency, final EnumOptionData loanType, final Integer loanCycle, final LoanApplicationTimelineData timeline,
|
||||||
final BigDecimal originalLoan, final BigDecimal loanBalance, final BigDecimal amountPaid) {
|
final Boolean inArrears, final BigDecimal originalLoan, final BigDecimal loanBalance, final BigDecimal amountPaid) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.accountNo = accountNo;
|
this.accountNo = accountNo;
|
||||||
this.parentAccountNumber = null;
|
this.parentAccountNumber = null;
|
||||||
@@ -60,6 +62,7 @@ public class LoanAccountSummaryData {
|
|||||||
this.productName = loanProductName;
|
this.productName = loanProductName;
|
||||||
this.shortProductName = shortLoanProductName;
|
this.shortProductName = shortLoanProductName;
|
||||||
this.status = loanStatus;
|
this.status = loanStatus;
|
||||||
|
this.currency = currency;
|
||||||
this.loanType = loanType;
|
this.loanType = loanType;
|
||||||
this.loanCycle = loanCycle;
|
this.loanCycle = loanCycle;
|
||||||
this.timeline = timeline;
|
this.timeline = timeline;
|
||||||
|
|||||||
+17
-1
@@ -452,6 +452,11 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
|
|||||||
|
|
||||||
.append(" l.loan_product_counter as loanCycle,")
|
.append(" l.loan_product_counter as loanCycle,")
|
||||||
|
|
||||||
|
.append("l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf,")
|
||||||
|
|
||||||
|
.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode,")
|
||||||
|
.append("curr.display_symbol as currencyDisplaySymbol,")
|
||||||
|
|
||||||
.append(" l.submittedon_date as submittedOnDate,")
|
.append(" l.submittedon_date as submittedOnDate,")
|
||||||
.append(" sbu.username as submittedByUsername, sbu.firstname as submittedByFirstname, sbu.lastname as submittedByLastname,")
|
.append(" sbu.username as submittedByUsername, sbu.firstname as submittedByFirstname, sbu.lastname as submittedByLastname,")
|
||||||
|
|
||||||
@@ -474,6 +479,7 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
|
|||||||
.append(" l.charged_off_on_date as chargedOffOnDate, cobu.username as chargedOffByUsername, ")
|
.append(" l.charged_off_on_date as chargedOffOnDate, cobu.username as chargedOffByUsername, ")
|
||||||
.append(" cobu.firstname as chargedOffByFirstname, cobu.lastname as chargedOffByLastname ").append(" from m_loan l ")
|
.append(" cobu.firstname as chargedOffByFirstname, cobu.lastname as chargedOffByLastname ").append(" from m_loan l ")
|
||||||
.append("LEFT JOIN m_product_loan AS lp ON lp.id = l.product_id")
|
.append("LEFT JOIN m_product_loan AS lp ON lp.id = l.product_id")
|
||||||
|
.append(" left join m_currency curr on curr.code = l.currency_code")
|
||||||
.append(" left join m_appuser sbu on sbu.id = l.created_by")
|
.append(" left join m_appuser sbu on sbu.id = l.created_by")
|
||||||
.append(" left join m_appuser rbu on rbu.id = l.rejectedon_userid")
|
.append(" left join m_appuser rbu on rbu.id = l.rejectedon_userid")
|
||||||
.append(" left join m_appuser wbu on wbu.id = l.withdrawnon_userid")
|
.append(" left join m_appuser wbu on wbu.id = l.withdrawnon_userid")
|
||||||
@@ -503,6 +509,15 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
|
|||||||
final EnumOptionData loanType = AccountEnumerations.loanType(loanTypeId);
|
final EnumOptionData loanType = AccountEnumerations.loanType(loanTypeId);
|
||||||
final Integer loanCycle = JdbcSupport.getInteger(rs, "loanCycle");
|
final Integer loanCycle = JdbcSupport.getInteger(rs, "loanCycle");
|
||||||
|
|
||||||
|
final String currencyCode = rs.getString("currencyCode");
|
||||||
|
final String currencyName = rs.getString("currencyName");
|
||||||
|
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||||
|
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||||
|
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||||
|
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
|
||||||
|
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, currencyDisplaySymbol,
|
||||||
|
currencyNameCode);
|
||||||
|
|
||||||
final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
|
final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
|
||||||
final String submittedByUsername = rs.getString("submittedByUsername");
|
final String submittedByUsername = rs.getString("submittedByUsername");
|
||||||
final String submittedByFirstname = rs.getString("submittedByFirstname");
|
final String submittedByFirstname = rs.getString("submittedByFirstname");
|
||||||
@@ -561,7 +576,8 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
|
|||||||
chargedOffOnDate, chargedOffByUsername, chargedOffByFirstname, chargedOffByLastname);
|
chargedOffOnDate, chargedOffByUsername, chargedOffByFirstname, chargedOffByLastname);
|
||||||
|
|
||||||
return new LoanAccountSummaryData(id, accountNo, parentAccountNumber, externalId, productId, loanProductName,
|
return new LoanAccountSummaryData(id, accountNo, parentAccountNumber, externalId, productId, loanProductName,
|
||||||
shortLoanProductName, loanStatus, loanType, loanCycle, timeline, inArrears, originalLoan, loanBalance, amountPaid);
|
shortLoanProductName, loanStatus, currency, loanType, loanCycle, timeline, inArrears, originalLoan, loanBalance,
|
||||||
|
amountPaid);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+19
@@ -470,6 +470,24 @@ final class ClientsApiResourceSwagger {
|
|||||||
|
|
||||||
private GetClientsLoanAccounts() {}
|
private GetClientsLoanAccounts() {}
|
||||||
|
|
||||||
|
static final class GetClientsLoansAccountsCurrency {
|
||||||
|
|
||||||
|
private GetClientsLoansAccountsCurrency() {}
|
||||||
|
|
||||||
|
@Schema(example = "USD")
|
||||||
|
public String code;
|
||||||
|
@Schema(example = "US Dollar")
|
||||||
|
public String name;
|
||||||
|
@Schema(example = "2")
|
||||||
|
public Integer decimalPlaces;
|
||||||
|
@Schema(example = "$")
|
||||||
|
public String displaySymbol;
|
||||||
|
@Schema(example = "currency.USD")
|
||||||
|
public String nameCode;
|
||||||
|
@Schema(example = "US Dollar ($)")
|
||||||
|
public String displayLabel;
|
||||||
|
}
|
||||||
|
|
||||||
static final class GetClientsLoanAccountsStatus {
|
static final class GetClientsLoanAccountsStatus {
|
||||||
|
|
||||||
private GetClientsLoanAccountsStatus() {}
|
private GetClientsLoanAccountsStatus() {}
|
||||||
@@ -520,6 +538,7 @@ final class ClientsApiResourceSwagger {
|
|||||||
public Long productId;
|
public Long productId;
|
||||||
@Schema(example = "TestOne")
|
@Schema(example = "TestOne")
|
||||||
public String productName;
|
public String productName;
|
||||||
|
public GetClientsLoansAccountsCurrency currency;
|
||||||
public GetClientsLoanAccountsStatus status;
|
public GetClientsLoanAccountsStatus status;
|
||||||
public GetClientsLoanAccountsType loanType;
|
public GetClientsLoanAccountsType loanType;
|
||||||
@Schema(example = "1")
|
@Schema(example = "1")
|
||||||
|
|||||||
+151
@@ -0,0 +1,151 @@
|
|||||||
|
/**
|
||||||
|
* 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 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.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.fineract.client.models.GetClientsClientIdAccountsResponse;
|
||||||
|
import org.apache.fineract.client.models.GetClientsLoanAccounts;
|
||||||
|
import org.apache.fineract.client.models.PostClientsResponse;
|
||||||
|
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
|
import org.apache.fineract.integrationtests.common.accounting.Account;
|
||||||
|
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.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class LoanAccountsContainsCurrencyFieldTest {
|
||||||
|
|
||||||
|
private ResponseSpecification responseSpec;
|
||||||
|
private RequestSpecification requestSpec;
|
||||||
|
private LoanTransactionHelper loanTransactionHelper;
|
||||||
|
private static final String principalAmount = "1200.00";
|
||||||
|
private static final String NONE = "1";
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(LoanAccountsContainsCurrencyFieldTest.class);
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setup() {
|
||||||
|
Utils.initializeRESTAssured();
|
||||||
|
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
|
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
|
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||||
|
|
||||||
|
loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetClientLoanAccountsUsingExternalIdContainsCurrency() {
|
||||||
|
|
||||||
|
// Get today's date
|
||||||
|
LocalDate today = LocalDate.now(ZoneId.systemDefault());
|
||||||
|
|
||||||
|
// Define a custom date formatter
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMMM yyyy");
|
||||||
|
|
||||||
|
// Format today's date using the custom formatter
|
||||||
|
String formattedDate = today.format(formatter);
|
||||||
|
|
||||||
|
// given
|
||||||
|
GlobalConfigurationHelper.manageConfigurations(requestSpec, responseSpec,
|
||||||
|
GlobalConfigurationHelper.ENABLE_AUTOGENERATED_EXTERNAL_ID, true);
|
||||||
|
final String jsonPayload = ClientHelper.getBasicClientAsJSON(ClientHelper.DEFAULT_OFFICE_ID, ClientHelper.LEGALFORM_ID_PERSON,
|
||||||
|
null);
|
||||||
|
// when
|
||||||
|
final PostClientsResponse clientResponse = ClientHelper.addClientAsPerson(requestSpec, responseSpec, jsonPayload);
|
||||||
|
final String clientExternalId = clientResponse.getResourceExternalId();
|
||||||
|
final long clientId = clientResponse.getClientId();
|
||||||
|
|
||||||
|
GlobalConfigurationHelper.manageConfigurations(requestSpec, responseSpec,
|
||||||
|
GlobalConfigurationHelper.ENABLE_AUTOGENERATED_EXTERNAL_ID, false);
|
||||||
|
|
||||||
|
Integer loanProductId = createLoanProduct(false, NONE);
|
||||||
|
|
||||||
|
// Create Loan Account
|
||||||
|
final Integer loanId = createLoanAccount(loanTransactionHelper, String.valueOf(clientId), String.valueOf(loanProductId),
|
||||||
|
formattedDate);
|
||||||
|
|
||||||
|
GetClientsClientIdAccountsResponse clientAccountsResponse = ClientHelper.getClientAccounts(requestSpec, responseSpec,
|
||||||
|
clientExternalId);
|
||||||
|
|
||||||
|
if (clientAccountsResponse.getLoanAccounts() == null) {
|
||||||
|
// Handle the case where getClientAccounts returned null
|
||||||
|
throw new IllegalStateException("getClientAccounts returned null");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Set<GetClientsLoanAccounts> loanAccounts = clientAccountsResponse.getLoanAccounts();
|
||||||
|
|
||||||
|
// Assert if loanAccounts contains a loan account with "currency" field
|
||||||
|
boolean containsCurrency = false;
|
||||||
|
if (loanAccounts != null) {
|
||||||
|
containsCurrency = loanAccounts.stream().anyMatch(account -> account.getCurrency() != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform assertion
|
||||||
|
assert containsCurrency;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer createLoanAccount(final LoanTransactionHelper loanTransactionHelper, final String clientId, final String loanProductId,
|
||||||
|
final String operationDate) {
|
||||||
|
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(principalAmount).withLoanTermFrequency("1")
|
||||||
|
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("1").withRepaymentEveryAfter("1")
|
||||||
|
.withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod("0").withInterestTypeAsFlatBalance()
|
||||||
|
.withAmortizationTypeAsEqualPrincipalPayments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod()
|
||||||
|
.withExpectedDisbursementDate("03 September 2022").withSubmittedOnDate("01 September 2022").withLoanType("individual")
|
||||||
|
.build(clientId, loanProductId, null);
|
||||||
|
final Integer loanId = loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||||
|
loanTransactionHelper.approveLoan(operationDate, principalAmount, loanId, null);
|
||||||
|
return loanId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer createLoanProduct(final boolean multiDisburseLoan, final String accountingRule, final Account... accounts) {
|
||||||
|
LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
|
||||||
|
LoanProductTestBuilder builder = new LoanProductTestBuilder() //
|
||||||
|
.withPrincipal("12,000.00") //
|
||||||
|
.withNumberOfRepayments("4") //
|
||||||
|
.withRepaymentAfterEvery("1") //
|
||||||
|
.withRepaymentTypeAsMonth() //
|
||||||
|
.withinterestRatePerPeriod("1") //
|
||||||
|
.withInterestRateFrequencyTypeAsMonths() //
|
||||||
|
.withAmortizationTypeAsEqualInstallments() //
|
||||||
|
.withInterestTypeAsDecliningBalance() //
|
||||||
|
.withTranches(multiDisburseLoan) //
|
||||||
|
.withAccounting(accountingRule, accounts);
|
||||||
|
if (multiDisburseLoan) {
|
||||||
|
builder = builder.withInterestCalculationPeriodTypeAsRepaymentPeriod(true);
|
||||||
|
}
|
||||||
|
final String loanProductJSON = builder.build(null);
|
||||||
|
return loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user