You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ar...@apache.org on 2022/06/22 12:41:57 UTC

[fineract] branch develop updated: Specify query parameters for LoansApi retrieveLoan

This is an automated email from the ASF dual-hosted git repository.

arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new fb0556c20 Specify query parameters for LoansApi retrieveLoan
fb0556c20 is described below

commit fb0556c20ea92628a953f371b8cd500681e5bcb0
Author: Jose Alberto Hernandez <al...@MacBook-Pro.local>
AuthorDate: Thu Jun 16 10:02:39 2022 -0500

    Specify query parameters for LoansApi retrieveLoan
---
 .../AdHocScheduledJobRunnerServiceImpl.java        |  2 +-
 .../internal/GetLoanByIdCommandStrategy.java       | 22 ++++++++++-
 .../core/api/ApiParameterHelper.java               | 28 +++++++-------
 .../loanaccount/api/LoanApiConstants.java          |  5 +++
 .../loanaccount/api/LoansApiResource.java          | 18 ++++-----
 .../LoanWritePlatformServiceJpaRepositoryImpl.java | 14 ++-----
 .../self/loanaccount/api/SelfLoansApiResource.java |  6 ++-
 .../internal/GetLoanByIdCommandStrategyTest.java   | 44 +++++++++++++++-------
 8 files changed, 89 insertions(+), 50 deletions(-)

diff --git a/fineract-provider/src/main/java/org/apache/fineract/adhocquery/service/AdHocScheduledJobRunnerServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/adhocquery/service/AdHocScheduledJobRunnerServiceImpl.java
index e5f62bcc3..f2a81e238 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/adhocquery/service/AdHocScheduledJobRunnerServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/adhocquery/service/AdHocScheduledJobRunnerServiceImpl.java
@@ -82,7 +82,7 @@ public class AdHocScheduledJobRunnerServiceImpl implements AdHocScheduledJobRunn
                                 run = Math.toIntExact(ChronoUnit.YEARS.between(start, end)) >= 1;
                             break;
                             case CUSTOM:
-                                next = start.plusDays((int) (long) adhoc.getReportRunEvery());
+                                next = start.plusDays((long) adhoc.getReportRunEvery());
                                 run = Math.toIntExact(ChronoUnit.DAYS.between(start, end)) >= adhoc.getReportRunEvery();
                             break;
                             default:
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetLoanByIdCommandStrategy.java b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetLoanByIdCommandStrategy.java
index 7408aee42..66781ec3a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetLoanByIdCommandStrategy.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetLoanByIdCommandStrategy.java
@@ -72,9 +72,10 @@ public class GetLoanByIdCommandStrategy implements CommandStrategy {
             // - Add them to the UriInfo query parameters list
             // - Call loansApiResource.retrieveLoan(loanId, false, uriInfo)
             // - Remove the relative url query parameters from UriInfo in the finally (after loan details are retrieved)
+            Map<String, String> queryParameters = null;
             if (relativeUrl.indexOf('?') > 0) {
                 loanId = Long.parseLong(StringUtils.substringBetween(relativeUrl, "/", "?"));
-                Map<String, String> queryParameters = getQueryParameters(relativeUrl);
+                queryParameters = getQueryParameters(relativeUrl);
 
                 // Add the query parameters sent in the relative URL to UriInfo
                 addQueryParametersToUriInfo(parameterizedUriInfo, queryParameters);
@@ -84,7 +85,24 @@ public class GetLoanByIdCommandStrategy implements CommandStrategy {
 
             // Calls 'retrieveLoan' function from 'LoansApiResource' to
             // get the loan details based on the loan id
-            responseBody = loansApiResource.retrieveLoan(loanId, false, parameterizedUriInfo);
+            final boolean staffInSelectedOfficeOnly = false;
+            String associations = null;
+            String exclude = null;
+            String fields = null;
+            if (queryParameters != null && queryParameters.size() > 0) {
+                if (queryParameters.containsKey("associations")) {
+                    associations = queryParameters.get("associations");
+                }
+                if (queryParameters.containsKey("exclude")) {
+                    exclude = queryParameters.get("exclude");
+                }
+                if (queryParameters.containsKey("fields")) {
+                    fields = queryParameters.get("fields");
+                }
+            }
+
+            responseBody = loansApiResource.retrieveLoan(loanId, staffInSelectedOfficeOnly, associations, exclude, fields,
+                    parameterizedUriInfo);
 
             response.setStatusCode(HttpStatus.SC_OK);
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/ApiParameterHelper.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/ApiParameterHelper.java
index d1e929fe4..b48d6c95b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/ApiParameterHelper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/ApiParameterHelper.java
@@ -48,11 +48,11 @@ public final class ApiParameterHelper {
 
     public static Set<String> extractFieldsForResponseIfProvided(final MultivaluedMap<String, String> queryParams) {
         Set<String> fields = new HashSet<>();
-        String commaSerperatedParameters = "";
+        String commaSeparatedParameters = "";
         if (queryParams.getFirst("fields") != null) {
-            commaSerperatedParameters = queryParams.getFirst("fields");
-            if (StringUtils.isNotBlank(commaSerperatedParameters)) {
-                fields = new HashSet<>(Arrays.asList(commaSerperatedParameters.split("\\s*,\\s*"))); // NOSONAR
+            commaSeparatedParameters = queryParams.getFirst("fields");
+            if (StringUtils.isNotBlank(commaSeparatedParameters)) {
+                fields = new HashSet<>(Arrays.asList(commaSeparatedParameters.split("\\s*,\\s*"))); // NOSONAR
             }
         }
         return fields;
@@ -60,23 +60,25 @@ public final class ApiParameterHelper {
 
     public static Set<String> extractAssociationsForResponseIfProvided(final MultivaluedMap<String, String> queryParams) {
         Set<String> fields = new HashSet<>();
-        String commaSerperatedParameters = "";
+        String commaSeparatedParameters = "";
         if (queryParams.getFirst("associations") != null) {
-            commaSerperatedParameters = queryParams.getFirst("associations");
-            if (StringUtils.isNotBlank(commaSerperatedParameters)) {
-                fields = new HashSet<>(Arrays.asList(commaSerperatedParameters.split("\\s*,\\s*"))); // NOSONAR
+            commaSeparatedParameters = queryParams.getFirst("associations");
+            if (StringUtils.isNotBlank(commaSeparatedParameters)) {
+                fields = new HashSet<>(Arrays.asList(commaSeparatedParameters.split("\\s*,\\s*"))); // NOSONAR
             }
         }
         return fields;
     }
 
+    public static void excludeAssociationsForResponseIfProvided(final String commaSeparatedParameters, Set<String> fields) {
+        if (StringUtils.isNotBlank(commaSeparatedParameters)) {
+            fields.removeAll(new HashSet<>(Arrays.asList(commaSeparatedParameters.split("\\s*,\\s*")))); // NOSONAR
+        }
+    }
+
     public static void excludeAssociationsForResponseIfProvided(final MultivaluedMap<String, String> queryParams, Set<String> fields) {
-        String commaSerperatedParameters = "";
         if (queryParams.getFirst("exclude") != null) {
-            commaSerperatedParameters = queryParams.getFirst("exclude");
-            if (StringUtils.isNotBlank(commaSerperatedParameters)) {
-                fields.removeAll(new HashSet<>(Arrays.asList(commaSerperatedParameters.split("\\s*,\\s*")))); // NOSONAR
-            }
+            excludeAssociationsForResponseIfProvided(queryParams.getFirst("exclude"), fields);
         }
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java
index 0bac3570e..60c4b81cb 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java
@@ -80,6 +80,10 @@ public interface LoanApiConstants {
     String daysInYearTypeParameterName = "daysInYearType";
     String daysInMonthTypeParameterName = "daysInMonthType";
 
+    String MULTIDISBURSE_DETAILS_PARAMNAME = "multiDisburseDetails";
+    String EMI_AMOUNT_VARIATIONS_PARAMNAME = "emiAmountVariations";
+    String COLLECTION_PARAMNAME = "collection";
+
     // Interest recalculation related
     String isInterestRecalculationEnabledParameterName = "isInterestRecalculationEnabled";
     String interestRecalculationCompoundingMethodParameterName = "interestRecalculationCompoundingMethod";
@@ -137,4 +141,5 @@ public interface LoanApiConstants {
 
     String fixedPrincipalPercentagePerInstallmentParamName = "fixedPrincipalPercentagePerInstallment";
 
+    String LOAN_ASSOCIATIONS_ALL = "all";
 }
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 702cb56cb..58e08f18b 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
@@ -23,7 +23,9 @@ import static org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations
 import com.google.gson.JsonElement;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
 import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.parameters.RequestBody;
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
@@ -96,8 +98,6 @@ import org.apache.fineract.portfolio.charge.data.ChargeData;
 import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
 import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService;
 import org.apache.fineract.portfolio.client.data.ClientData;
-import org.apache.fineract.portfolio.collateral.data.CollateralData;
-import org.apache.fineract.portfolio.collateral.service.CollateralReadPlatformService;
 import org.apache.fineract.portfolio.collateralmanagement.data.LoanCollateralResponseData;
 import org.apache.fineract.portfolio.collateralmanagement.service.LoanCollateralManagementReadPlatformService;
 import org.apache.fineract.portfolio.floatingrates.data.InterestRatePeriodData;
@@ -220,7 +220,8 @@ public class LoansApiResource {
             "loanCounter", "loanProductCounter", "notes", "accountLinkingOptions", "linkedAccount", "interestRateDifferential",
             "isFloatingInterestRate", "interestRatesPeriods", LoanApiConstants.canUseForTopup, LoanApiConstants.isTopup,
             LoanApiConstants.loanIdToClose, LoanApiConstants.topupAmount, LoanApiConstants.clientActiveLoanOptions,
-            LoanApiConstants.datatables, LoanProductConstants.RATES_PARAM_NAME));
+            LoanApiConstants.datatables, LoanProductConstants.RATES_PARAM_NAME, LoanApiConstants.MULTIDISBURSE_DETAILS_PARAMNAME,
+            LoanApiConstants.EMI_AMOUNT_VARIATIONS_PARAMNAME, LoanApiConstants.COLLECTION_PARAMNAME));
 
     private final Set<String> loanApprovalDataParameters = new HashSet<>(Arrays.asList("approvalDate", "approvalAmount"));
     final Set<String> glimAccountsDataParameters = new HashSet<>(Arrays.asList("glimId", "groupId", "clientId", "parentLoanAccountNo",
@@ -234,7 +235,6 @@ public class LoansApiResource {
     private final FundReadPlatformService fundReadPlatformService;
     private final ChargeReadPlatformService chargeReadPlatformService;
     private final LoanChargeReadPlatformService loanChargeReadPlatformService;
-    private final CollateralReadPlatformService loanCollateralReadPlatformService;
     private final LoanScheduleCalculationPlatformService calculationPlatformService;
     private final GuarantorReadPlatformService guarantorReadPlatformService;
     private final CodeValueReadPlatformService codeValueReadPlatformService;
@@ -264,7 +264,6 @@ public class LoansApiResource {
             final LoanProductReadPlatformService loanProductReadPlatformService,
             final LoanDropdownReadPlatformService dropdownReadPlatformService, final FundReadPlatformService fundReadPlatformService,
             final ChargeReadPlatformService chargeReadPlatformService, final LoanChargeReadPlatformService loanChargeReadPlatformService,
-            final CollateralReadPlatformService loanCollateralReadPlatformService,
             final LoanScheduleCalculationPlatformService calculationPlatformService,
             final GuarantorReadPlatformService guarantorReadPlatformService,
             final CodeValueReadPlatformService codeValueReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
@@ -292,7 +291,6 @@ public class LoansApiResource {
         this.fundReadPlatformService = fundReadPlatformService;
         this.chargeReadPlatformService = chargeReadPlatformService;
         this.loanChargeReadPlatformService = loanChargeReadPlatformService;
-        this.loanCollateralReadPlatformService = loanCollateralReadPlatformService;
         this.calculationPlatformService = calculationPlatformService;
         this.guarantorReadPlatformService = guarantorReadPlatformService;
         this.codeValueReadPlatformService = codeValueReadPlatformService;
@@ -495,6 +493,10 @@ public class LoansApiResource {
             @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.GetLoansLoanIdResponse.class))) })
     public String retrieveLoan(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
             @DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") @Parameter(description = "staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly,
+            @DefaultValue("all") @QueryParam("associations") @Parameter(in = ParameterIn.QUERY, name = "associations", description = "Loan object relations to be included in the response", required = false, examples = {
+                    @ExampleObject(value = "all"), @ExampleObject(value = "repaymentSchedule,transactions") }) final String associations,
+            @QueryParam("exclude") @Parameter(in = ParameterIn.QUERY, name = "exclude", description = "Optional Loan object relation list to be filtered in the response", required = false, example = "guarantors,futureSchedule") final String exclude,
+            @QueryParam("fields") @Parameter(in = ParameterIn.QUERY, name = "fields", description = "Optional Loan attribute list to be in the response", required = false, example = "id,principal,annualInterestRate") final String fields,
             @Context final UriInfo uriInfo) {
         this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
 
@@ -535,7 +537,6 @@ public class LoansApiResource {
         LoanScheduleData repaymentSchedule = null;
         Collection<LoanChargeData> charges = null;
         Collection<GuarantorData> guarantors = null;
-        Collection<CollateralData> collateral = null;
         CalendarData meeting = null;
         Collection<NoteData> notes = null;
         PortfolioAccountData linkedAccount = null;
@@ -548,7 +549,6 @@ public class LoansApiResource {
         final Set<String> mandatoryResponseParameters = new HashSet<>();
         final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
         if (!associationParameters.isEmpty()) {
-
             if (associationParameters.contains(DataTableApiConstant.allAssociateParamName)) {
                 associationParameters.addAll(Arrays.asList(DataTableApiConstant.repaymentScheduleAssociateParamName,
                         DataTableApiConstant.futureScheduleAssociateParamName, DataTableApiConstant.originalScheduleAssociateParamName,
@@ -558,7 +558,7 @@ public class LoansApiResource {
                         DataTableApiConstant.multiDisburseDetailsAssociateParamName, DataTableApiConstant.collectionAssociateParamName));
             }
 
-            ApiParameterHelper.excludeAssociationsForResponseIfProvided(uriInfo.getQueryParameters(), associationParameters);
+            ApiParameterHelper.excludeAssociationsForResponseIfProvided(exclude, associationParameters);
 
             if (associationParameters.contains(DataTableApiConstant.guarantorsAssociateParamName)) {
                 mandatoryResponseParameters.add(DataTableApiConstant.guarantorsAssociateParamName);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
index 1db8638a5..080f5a19e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
@@ -142,7 +142,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainService;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargePaidBy;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanChargePaidByRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanCollateralManagement;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails;
@@ -152,7 +151,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtio
 import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanOverdueInstallmentCharge;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
@@ -238,7 +236,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
     private final FromJsonHelper fromApiJsonHelper;
     private final AccountTransferRepository accountTransferRepository;
     private final CalendarRepository calendarRepository;
-    private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository;
     private final LoanScheduleHistoryWritePlatformService loanScheduleHistoryWritePlatformService;
     private final LoanApplicationCommandFromApiJsonHelper loanApplicationCommandFromApiJsonHelper;
     private final AccountAssociationsRepository accountAssociationRepository;
@@ -255,7 +252,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
     private final LoanRepository loanRepository;
     private final RepaymentWithPostDatedChecksAssembler repaymentWithPostDatedChecksAssembler;
     private final PostDatedChecksRepository postDatedChecksRepository;
-    private final LoanChargePaidByRepository loanChargePaidByRepository;
 
     @Autowired
     public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -274,7 +270,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
             final LoanChargeReadPlatformService loanChargeReadPlatformService, final LoanReadPlatformService loanReadPlatformService,
             final FromJsonHelper fromApiJsonHelper, final AccountTransferRepository accountTransferRepository,
             final CalendarRepository calendarRepository,
-            final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository,
             final LoanScheduleHistoryWritePlatformService loanScheduleHistoryWritePlatformService,
             final LoanApplicationCommandFromApiJsonHelper loanApplicationCommandFromApiJsonHelper,
             final AccountAssociationsRepository accountAssociationRepository,
@@ -286,7 +281,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
             final CodeValueRepositoryWrapper codeValueRepository, final LoanRepositoryWrapper loanRepositoryWrapper,
             final CashierTransactionDataValidator cashierTransactionDataValidator, final GLIMAccountInfoRepository glimRepository,
             final LoanRepository loanRepository, final RepaymentWithPostDatedChecksAssembler repaymentWithPostDatedChecksAssembler,
-            final PostDatedChecksRepository postDatedChecksRepository, final LoanChargePaidByRepository loanChargePaidByRepository) {
+            final PostDatedChecksRepository postDatedChecksRepository) {
         this.context = context;
         this.loanEventApiJsonValidator = loanEventApiJsonValidator;
         this.loanAssembler = loanAssembler;
@@ -312,7 +307,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
         this.fromApiJsonHelper = fromApiJsonHelper;
         this.accountTransferRepository = accountTransferRepository;
         this.calendarRepository = calendarRepository;
-        this.repaymentScheduleInstallmentRepository = repaymentScheduleInstallmentRepository;
         this.loanScheduleHistoryWritePlatformService = loanScheduleHistoryWritePlatformService;
         this.loanApplicationCommandFromApiJsonHelper = loanApplicationCommandFromApiJsonHelper;
         this.accountAssociationRepository = accountAssociationRepository;
@@ -329,7 +323,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
         this.glimRepository = glimRepository;
         this.repaymentWithPostDatedChecksAssembler = repaymentWithPostDatedChecksAssembler;
         this.postDatedChecksRepository = postDatedChecksRepository;
-        this.loanChargePaidByRepository = loanChargePaidByRepository;
     }
 
     private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
@@ -1760,7 +1753,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
             break;
         }
 
-        AppUser currentUser = getAppUserIfPresent();
         final Loan loan = this.loanAssembler.assembleFrom(loanId);
         checkClientOrGroupActive(loan);
         final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId);
@@ -2813,10 +2805,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
         LocalDate startDate = dueDate.plusDays(penaltyWaitPeriodValue.intValue() + 1);
         Integer frequencyNunber = 1;
         if (feeFrequency == null) {
-            scheduleDates.put(frequencyNunber++, startDate.minusDays(diff.intValue()));
+            scheduleDates.put(frequencyNunber++, startDate.minusDays(diff));
         } else {
             while (!startDate.isAfter(DateUtils.getLocalDateOfTenant())) {
-                scheduleDates.put(frequencyNunber++, startDate.minusDays(diff.intValue()));
+                scheduleDates.put(frequencyNunber++, startDate.minusDays(diff));
                 LocalDate scheduleDate = scheduledDateGenerator.getRepaymentPeriodDate(PeriodFrequencyType.fromInt(feeFrequency),
                         chargeDefinition.feeInterval(), startDate);
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResource.java
index a601b003f..6fc70e4b7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResource.java
@@ -43,6 +43,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.portfolio.client.exception.ClientNotFoundException;
+import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
 import org.apache.fineract.portfolio.loanaccount.api.LoanChargesApiResource;
 import org.apache.fineract.portfolio.loanaccount.api.LoanTransactionsApiResource;
 import org.apache.fineract.portfolio.loanaccount.api.LoansApiResource;
@@ -106,7 +107,10 @@ public class SelfLoansApiResource {
         validateAppuserLoanMapping(loanId);
 
         final boolean staffInSelectedOfficeOnly = false;
-        return this.loansApiResource.retrieveLoan(loanId, staffInSelectedOfficeOnly, uriInfo);
+        final String associations = LoanApiConstants.LOAN_ASSOCIATIONS_ALL;
+        final String exclude = null;
+        final String fields = null;
+        return this.loansApiResource.retrieveLoan(loanId, staffInSelectedOfficeOnly, associations, exclude, fields, uriInfo);
     }
 
     @GET
diff --git a/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/GetLoanByIdCommandStrategyTest.java b/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/GetLoanByIdCommandStrategyTest.java
index a16cea7a2..40a381488 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/GetLoanByIdCommandStrategyTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/GetLoanByIdCommandStrategyTest.java
@@ -24,6 +24,8 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.verify;
 
+import java.util.HashSet;
+import java.util.Set;
 import java.util.stream.Stream;
 import javax.ws.rs.HttpMethod;
 import javax.ws.rs.core.UriInfo;
@@ -46,8 +48,10 @@ import org.mockito.MockitoAnnotations;
 public class GetLoanByIdCommandStrategyTest {
 
     private static Stream<Arguments> provideQueryParameters() {
-        return Stream.of(Arguments.of(null, 0), Arguments.of("associations=all", 1),
-                Arguments.of("fields=id,principal,annualInterestRate&associations=repaymentSchedule,transactions", 2));
+        return Stream.of(Arguments.of(null, null, null, 0), Arguments.of("all", null, null, 1),
+                Arguments.of("repaymentSchedule,transactions", null, "guarantors,futureSchedule", 2),
+                Arguments.of("repaymentSchedule,transactions", "id,principal,annualInterestRate", null, 2),
+                Arguments.of("repaymentSchedule,transactions", "id,principal,annualInterestRate", "guarantors,futureSchedule", 3));
     }
 
     /**
@@ -56,15 +60,17 @@ public class GetLoanByIdCommandStrategyTest {
      */
     @ParameterizedTest
     @MethodSource("provideQueryParameters")
-    public void testExecuteSuccessScenario(final String queryParameter, final int noOfQueryParams) {
+    public void testExecuteSuccessScenario(final String associations, final String fields, final String exclude,
+            final int noOfQueryParams) {
         // given
         final TestContext testContext = new TestContext();
 
         final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
-        final BatchRequest request = getBatchRequest(loanId, queryParameter);
+        final BatchRequest request = getBatchRequest(loanId, associations, exclude, fields);
         final String responseBody = "{\\\"id\\\":2,\\\"accountNo\\\":\\\"000000002\\\"}";
 
-        given(testContext.loansApiResource.retrieveLoan(eq(loanId), eq(false), any(UriInfo.class))).willReturn(responseBody);
+        given(testContext.loansApiResource.retrieveLoan(eq(loanId), eq(false), eq(associations), eq(exclude), eq(fields),
+                any(UriInfo.class))).willReturn(responseBody);
 
         // when
         final BatchResponse response = testContext.underTest.execute(request, testContext.uriInfo);
@@ -75,7 +81,8 @@ public class GetLoanByIdCommandStrategyTest {
         assertThat(response.getHeaders()).isEqualTo(request.getHeaders());
         assertThat(response.getBody()).isEqualTo(responseBody);
 
-        verify(testContext.loansApiResource).retrieveLoan(eq(loanId), eq(false), testContext.uriInfoCaptor.capture());
+        verify(testContext.loansApiResource).retrieveLoan(eq(loanId), eq(false), eq(associations), eq(exclude), eq(fields),
+                testContext.uriInfoCaptor.capture());
         MutableUriInfo mutableUriInfo = testContext.uriInfoCaptor.getValue();
         assertThat(mutableUriInfo.getAdditionalQueryParameters()).hasSize(noOfQueryParams);
     }
@@ -88,9 +95,9 @@ public class GetLoanByIdCommandStrategyTest {
         // given
         final TestContext testContext = new TestContext();
         final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
-        final BatchRequest request = getBatchRequest(loanId, null);
+        final BatchRequest request = getBatchRequest(loanId, null, null, null);
 
-        given(testContext.loansApiResource.retrieveLoan(eq(loanId), eq(false), any(UriInfo.class)))
+        given(testContext.loansApiResource.retrieveLoan(eq(loanId), eq(false), eq(null), eq(null), eq(null), any(UriInfo.class)))
                 .willThrow(new RuntimeException("Some error"));
 
         // when
@@ -111,9 +118,9 @@ public class GetLoanByIdCommandStrategyTest {
         // given
         final TestContext testContext = new TestContext();
         final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
-        final BatchRequest request = getBatchRequest(loanId, null);
+        final BatchRequest request = getBatchRequest(loanId, null, null, null);
 
-        given(testContext.loansApiResource.retrieveLoan(eq(loanId), eq(false), any(UriInfo.class)))
+        given(testContext.loansApiResource.retrieveLoan(eq(loanId), eq(false), eq(null), eq(null), eq(null), any(UriInfo.class)))
                 .willThrow(new LoanNotFoundException(loanId));
 
         // when
@@ -145,12 +152,23 @@ public class GetLoanByIdCommandStrategyTest {
      *            the loan id
      * @return BatchRequest
      */
-    private BatchRequest getBatchRequest(final Long loanId, final String queryParamStr) {
+    private BatchRequest getBatchRequest(final Long loanId, final String associations, final String exclude, final String fields) {
 
         final BatchRequest br = new BatchRequest();
         String relativeUrl = "loans/" + loanId;
-        if (queryParamStr != null) {
-            relativeUrl = relativeUrl + "?" + queryParamStr;
+
+        Set<String> queryParams = new HashSet<>();
+        if (associations != null) {
+            queryParams.add("associations=" + associations);
+        }
+        if (exclude != null) {
+            queryParams.add("exclude=" + exclude);
+        }
+        if (fields != null) {
+            queryParams.add("fields=" + fields);
+        }
+        if (!queryParams.isEmpty()) {
+            relativeUrl = relativeUrl + "?" + String.join("&", queryParams);
         }
 
         br.setRequestId(Long.valueOf(RandomStringUtils.randomNumeric(5)));