FINERACT-2020:Added currency field to LoanAccountSummaryData, also added integration test and swagger documentation
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/LoanAccountSummaryData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/LoanAccountSummaryData.java
index 4ef5400..aa52620 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/LoanAccountSummaryData.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/LoanAccountSummaryData.java
@@ -22,6 +22,7 @@
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 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.LoanStatusEnumData;
 
@@ -40,6 +41,7 @@
     private final String productName;
     private final String shortProductName;
     private final LoanStatusEnumData status;
+    private final CurrencyData currency;
     private final EnumOptionData loanType;
     private final Integer loanCycle;
     private final LoanApplicationTimelineData timeline;
@@ -50,8 +52,8 @@
 
     public LoanAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId,
             final String loanProductName, final String shortLoanProductName, final LoanStatusEnumData loanStatus,
-            final EnumOptionData loanType, final Integer loanCycle, final LoanApplicationTimelineData timeline, final Boolean inArrears,
-            final BigDecimal originalLoan, final BigDecimal loanBalance, final BigDecimal amountPaid) {
+            final CurrencyData currency, final EnumOptionData loanType, final Integer loanCycle, final LoanApplicationTimelineData timeline,
+            final Boolean inArrears, final BigDecimal originalLoan, final BigDecimal loanBalance, final BigDecimal amountPaid) {
         this.id = id;
         this.accountNo = accountNo;
         this.parentAccountNumber = null;
@@ -60,6 +62,7 @@
         this.productName = loanProductName;
         this.shortProductName = shortLoanProductName;
         this.status = loanStatus;
+        this.currency = currency;
         this.loanType = loanType;
         this.loanCycle = loanCycle;
         this.timeline = timeline;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
index 2f5e161..7c1f508 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
@@ -452,6 +452,11 @@
 
                     .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(" sbu.username as submittedByUsername, sbu.firstname as submittedByFirstname, sbu.lastname as submittedByLastname,")
 
@@ -474,6 +479,7 @@
                     .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("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 rbu on rbu.id = l.rejectedon_userid")
                     .append(" left join m_appuser wbu on wbu.id = l.withdrawnon_userid")
@@ -503,6 +509,15 @@
             final EnumOptionData loanType = AccountEnumerations.loanType(loanTypeId);
             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 String submittedByUsername = rs.getString("submittedByUsername");
             final String submittedByFirstname = rs.getString("submittedByFirstname");
@@ -561,7 +576,8 @@
                     chargedOffOnDate, chargedOffByUsername, chargedOffByFirstname, chargedOffByLastname);
 
             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);
         }
 
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java
index bf5e6dd..b93d661 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java
@@ -470,6 +470,24 @@
 
             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 {
 
                 private GetClientsLoanAccountsStatus() {}
@@ -520,6 +538,7 @@
             public Long productId;
             @Schema(example = "TestOne")
             public String productName;
+            public GetClientsLoansAccountsCurrency currency;
             public GetClientsLoanAccountsStatus status;
             public GetClientsLoanAccountsType loanType;
             @Schema(example = "1")
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountsContainsCurrencyFieldTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountsContainsCurrencyFieldTest.java
new file mode 100644
index 0000000..4ee2cc9
--- /dev/null
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountsContainsCurrencyFieldTest.java
@@ -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);
+    }
+
+}