Transporting interest to the calculation. Required some minor restructuring because interest is in the case, rather than the case parameters.
diff --git a/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java b/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
index 9ce0d61..7d5be70 100644
--- a/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
+++ b/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
@@ -30,6 +30,7 @@
import io.mifos.individuallending.internal.repository.CreditWorthinessFactorType;
import io.mifos.individuallending.internal.service.CostComponentService;
import io.mifos.individuallending.internal.service.DataContextOfAction;
+import io.mifos.individuallending.internal.service.DataContextService;
import io.mifos.portfolio.api.v1.domain.Case;
import io.mifos.portfolio.api.v1.domain.ChargeDefinition;
import io.mifos.portfolio.api.v1.domain.CostComponent;
@@ -58,6 +59,7 @@
public class IndividualLendingPatternFactory implements PatternFactory {
final static private String INDIVIDUAL_LENDING_PACKAGE = "io.mifos.individuallending.api.v1";
private final CaseParametersRepository caseParametersRepository;
+ private final DataContextService dataContextService;
private final CostComponentService costComponentService;
private final CustomerManager customerManager;
private final IndividualLendingCommandDispatcher individualLendingCommandDispatcher;
@@ -66,12 +68,14 @@
@Autowired
IndividualLendingPatternFactory(
final CaseParametersRepository caseParametersRepository,
+ final DataContextService dataContextService,
final CostComponentService costComponentService,
final CustomerManager customerManager,
final IndividualLendingCommandDispatcher individualLendingCommandDispatcher,
@Qualifier(ServiceConstants.GSON_NAME) final Gson gson)
{
this.caseParametersRepository = caseParametersRepository;
+ this.dataContextService = dataContextService;
this.costComponentService = costComponentService;
this.customerManager = customerManager;
this.individualLendingCommandDispatcher = individualLendingCommandDispatcher;
@@ -345,7 +349,7 @@
final Set<String> forAccountDesignators,
final BigDecimal forPaymentSize) {
final Action action = Action.valueOf(actionIdentifier);
- final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(productIdentifier, caseIdentifier, Collections.emptyList());
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(productIdentifier, caseIdentifier, Collections.emptyList());
final Case.State caseState = Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState());
checkActionCanBeExecuted(caseState, action);
diff --git a/service/src/main/java/io/mifos/individuallending/internal/command/handler/IndividualLoanCommandHandler.java b/service/src/main/java/io/mifos/individuallending/internal/command/handler/IndividualLoanCommandHandler.java
index 36bbe16..00740d5 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/command/handler/IndividualLoanCommandHandler.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/command/handler/IndividualLoanCommandHandler.java
@@ -61,6 +61,7 @@
@Aggregate
public class IndividualLoanCommandHandler {
private final CaseRepository caseRepository;
+ private final DataContextService dataContextService;
private final CostComponentService costComponentService;
private final AccountingAdapter accountingAdapter;
private final TaskInstanceRepository taskInstanceRepository;
@@ -68,10 +69,12 @@
@Autowired
public IndividualLoanCommandHandler(
final CaseRepository caseRepository,
+ final DataContextService dataContextService,
final CostComponentService costComponentService,
final AccountingAdapter accountingAdapter,
final TaskInstanceRepository taskInstanceRepository) {
this.caseRepository = caseRepository;
+ this.dataContextService = dataContextService;
this.costComponentService = costComponentService;
this.accountingAdapter = accountingAdapter;
this.taskInstanceRepository = taskInstanceRepository;
@@ -85,7 +88,7 @@
public IndividualLoanCommandEvent process(final OpenCommand command) {
final String productIdentifier = command.getProductIdentifier();
final String caseIdentifier = command.getCaseIdentifier();
- final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(
productIdentifier, caseIdentifier, command.getCommand().getOneTimeAccountAssignments());
IndividualLendingPatternFactory.checkActionCanBeExecuted(Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState()), Action.OPEN);
@@ -126,7 +129,7 @@
public IndividualLoanCommandEvent process(final DenyCommand command) {
final String productIdentifier = command.getProductIdentifier();
final String caseIdentifier = command.getCaseIdentifier();
- final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(
productIdentifier, caseIdentifier, command.getCommand().getOneTimeAccountAssignments());
IndividualLendingPatternFactory.checkActionCanBeExecuted(Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState()), Action.DENY);
@@ -162,7 +165,7 @@
public IndividualLoanCommandEvent process(final ApproveCommand command) {
final String productIdentifier = command.getProductIdentifier();
final String caseIdentifier = command.getCaseIdentifier();
- final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(
productIdentifier, caseIdentifier, command.getCommand().getOneTimeAccountAssignments());
IndividualLendingPatternFactory.checkActionCanBeExecuted(Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState()), Action.APPROVE);
@@ -213,7 +216,7 @@
public IndividualLoanCommandEvent process(final DisburseCommand command) {
final String productIdentifier = command.getProductIdentifier();
final String caseIdentifier = command.getCaseIdentifier();
- final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(
productIdentifier, caseIdentifier, command.getCommand().getOneTimeAccountAssignments());
IndividualLendingPatternFactory.checkActionCanBeExecuted(Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState()), Action.DISBURSE);
@@ -262,7 +265,7 @@
public IndividualLoanCommandEvent process(final ApplyInterestCommand command) {
final String productIdentifier = command.getProductIdentifier();
final String caseIdentifier = command.getCaseIdentifier();
- final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(
productIdentifier, caseIdentifier, null);
IndividualLendingPatternFactory.checkActionCanBeExecuted(Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState()), Action.APPLY_INTEREST);
@@ -301,7 +304,7 @@
public IndividualLoanCommandEvent process(final AcceptPaymentCommand command) {
final String productIdentifier = command.getProductIdentifier();
final String caseIdentifier = command.getCaseIdentifier();
- final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(
productIdentifier, caseIdentifier, command.getCommand().getOneTimeAccountAssignments());
IndividualLendingPatternFactory.checkActionCanBeExecuted(Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState()), Action.ACCEPT_PAYMENT);
@@ -346,7 +349,7 @@
public IndividualLoanCommandEvent process(final WriteOffCommand command) {
final String productIdentifier = command.getProductIdentifier();
final String caseIdentifier = command.getCaseIdentifier();
- final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(
productIdentifier, caseIdentifier, command.getCommand().getOneTimeAccountAssignments());
IndividualLendingPatternFactory.checkActionCanBeExecuted(Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState()), Action.WRITE_OFF);
@@ -364,7 +367,7 @@
public IndividualLoanCommandEvent process(final CloseCommand command) {
final String productIdentifier = command.getProductIdentifier();
final String caseIdentifier = command.getCaseIdentifier();
- final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(
productIdentifier, caseIdentifier, command.getCommand().getOneTimeAccountAssignments());
IndividualLendingPatternFactory.checkActionCanBeExecuted(Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState()), Action.CLOSE);
@@ -403,7 +406,7 @@
public IndividualLoanCommandEvent process(final RecoverCommand command) {
final String productIdentifier = command.getProductIdentifier();
final String caseIdentifier = command.getCaseIdentifier();
- final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(
productIdentifier, caseIdentifier, command.getCommand().getOneTimeAccountAssignments());
IndividualLendingPatternFactory.checkActionCanBeExecuted(Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState()), Action.RECOVER);
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java b/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java
index fb76cbc..29a6592 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java
@@ -20,15 +20,8 @@
import io.mifos.individuallending.api.v1.domain.product.AccountDesignators;
import io.mifos.individuallending.api.v1.domain.product.ChargeProportionalDesignator;
import io.mifos.individuallending.api.v1.domain.workflow.Action;
-import io.mifos.individuallending.internal.mapper.CaseParametersMapper;
-import io.mifos.individuallending.internal.repository.CaseParametersRepository;
-import io.mifos.portfolio.api.v1.domain.AccountAssignment;
import io.mifos.portfolio.api.v1.domain.ChargeDefinition;
import io.mifos.portfolio.api.v1.domain.CostComponent;
-import io.mifos.portfolio.service.internal.repository.CaseEntity;
-import io.mifos.portfolio.service.internal.repository.CaseRepository;
-import io.mifos.portfolio.service.internal.repository.ProductEntity;
-import io.mifos.portfolio.service.internal.repository.ProductRepository;
import io.mifos.portfolio.service.internal.util.AccountingAdapter;
import org.javamoney.calc.common.Rate;
import org.javamoney.moneta.Money;
@@ -54,48 +47,17 @@
private static final int EXTRA_PRECISION = 4;
private static final int RUNNING_CALCULATION_PRECISION = 8;
- private final ProductRepository productRepository;
- private final CaseRepository caseRepository;
- private final CaseParametersRepository caseParametersRepository;
private final IndividualLoanService individualLoanService;
private final AccountingAdapter accountingAdapter;
@Autowired
public CostComponentService(
- final ProductRepository productRepository,
- final CaseRepository caseRepository,
- final CaseParametersRepository caseParametersRepository,
final IndividualLoanService individualLoanService,
final AccountingAdapter accountingAdapter) {
- this.productRepository = productRepository;
- this.caseRepository = caseRepository;
- this.caseParametersRepository = caseParametersRepository;
this.individualLoanService = individualLoanService;
this.accountingAdapter = accountingAdapter;
}
- public DataContextOfAction checkedGetDataContext(
- final String productIdentifier,
- final String caseIdentifier,
- final @Nullable List<AccountAssignment> oneTimeAccountAssignments) {
-
- final ProductEntity product =
- productRepository.findByIdentifier(productIdentifier)
- .orElseThrow(() -> ServiceException.notFound("Product not found ''{0}''.", productIdentifier));
- final CaseEntity customerCase =
- caseRepository.findByProductIdentifierAndIdentifier(productIdentifier, caseIdentifier)
- .orElseThrow(() -> ServiceException.notFound("Case not found ''{0}.{1}''.", productIdentifier, caseIdentifier));
-
- final CaseParameters caseParameters =
- caseParametersRepository.findByCaseId(customerCase.getId())
- .map(x -> CaseParametersMapper.mapEntity(x, product.getMinorCurrencyUnitDigits()))
- .orElseThrow(() -> ServiceException.notFound(
- "Individual loan not found ''{0}.{1}''.",
- productIdentifier, caseIdentifier));
-
- return new DataContextOfAction(product, customerCase, caseParameters, oneTimeAccountAssignments);
- }
-
public CostComponentsForRepaymentPeriod getCostComponentsForAction(
final Action action,
final DataContextOfAction dataContextOfAction,
@@ -140,6 +102,7 @@
caseParameters.getMaximumBalance(),
BigDecimal.ZERO,
BigDecimal.ZERO,
+ dataContextOfAction.getCustomerCase().getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -158,6 +121,7 @@
caseParameters.getMaximumBalance(),
BigDecimal.ZERO,
BigDecimal.ZERO,
+ dataContextOfAction.getCustomerCase().getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -177,6 +141,7 @@
caseParameters.getMaximumBalance(),
BigDecimal.ZERO,
BigDecimal.ZERO,
+ dataContextOfAction.getCustomerCase().getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -233,6 +198,7 @@
caseParameters.getMaximumBalance(),
currentBalance,
disbursalSize,
+ dataContextOfAction.getCustomerCase().getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -272,6 +238,7 @@
caseParameters.getMaximumBalance(),
currentBalance,
BigDecimal.ZERO,
+ dataContextOfAction.getCustomerCase().getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -331,6 +298,7 @@
caseParameters.getMaximumBalance(),
currentBalance,
loanPaymentSize,
+ dataContextOfAction.getCustomerCase().getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -414,6 +382,7 @@
caseParameters.getMaximumBalance(),
currentBalance,
BigDecimal.ZERO,
+ dataContextOfAction.getCustomerCase().getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -436,6 +405,7 @@
final BigDecimal maximumBalance,
final BigDecimal runningBalance,
final BigDecimal entryAccountAdjustment, //disbursement or payment size.
+ final BigDecimal interest,
final int minorCurrencyUnitDigits,
final boolean accrualAccounting) {
final Map<String, BigDecimal> balanceAdjustments = new HashMap<>();
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/DataContextService.java b/service/src/main/java/io/mifos/individuallending/internal/service/DataContextService.java
new file mode 100644
index 0000000..225d0a6
--- /dev/null
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/DataContextService.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2017 Kuelap, Inc.
+ *
+ * Licensed 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 io.mifos.individuallending.internal.service;
+
+import io.mifos.core.lang.ServiceException;
+import io.mifos.individuallending.api.v1.domain.caseinstance.CaseParameters;
+import io.mifos.individuallending.internal.mapper.CaseParametersMapper;
+import io.mifos.individuallending.internal.repository.CaseParametersRepository;
+import io.mifos.portfolio.api.v1.domain.AccountAssignment;
+import io.mifos.portfolio.service.internal.repository.CaseEntity;
+import io.mifos.portfolio.service.internal.repository.CaseRepository;
+import io.mifos.portfolio.service.internal.repository.ProductEntity;
+import io.mifos.portfolio.service.internal.repository.ProductRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Nullable;
+import java.util.List;
+
+/**
+ * @author Myrle Krantz
+ */
+@Service
+public class DataContextService {
+ private final ProductRepository productRepository;
+ private final CaseRepository caseRepository;
+ private final CaseParametersRepository caseParametersRepository;
+
+ @Autowired
+ public DataContextService(
+ final ProductRepository productRepository,
+ final CaseRepository caseRepository,
+ final CaseParametersRepository caseParametersRepository) {
+ this.productRepository = productRepository;
+ this.caseRepository = caseRepository;
+ this.caseParametersRepository = caseParametersRepository;
+ }
+
+ public DataContextOfAction checkedGetDataContext(
+ final String productIdentifier,
+ final String caseIdentifier,
+ final @Nullable List<AccountAssignment> oneTimeAccountAssignments) {
+
+ final ProductEntity product =
+ productRepository.findByIdentifier(productIdentifier)
+ .orElseThrow(() -> ServiceException.notFound("Product not found ''{0}''.", productIdentifier));
+ final CaseEntity customerCase =
+ caseRepository.findByProductIdentifierAndIdentifier(productIdentifier, caseIdentifier)
+ .orElseThrow(() -> ServiceException.notFound("Case not found ''{0}.{1}''.", productIdentifier, caseIdentifier));
+
+ final CaseParameters caseParameters =
+ caseParametersRepository.findByCaseId(customerCase.getId())
+ .map(x -> CaseParametersMapper.mapEntity(x, product.getMinorCurrencyUnitDigits()))
+ .orElseThrow(() -> ServiceException.notFound(
+ "Individual loan not found ''{0}.{1}''.",
+ productIdentifier, caseIdentifier));
+
+ return new DataContextOfAction(product, customerCase, caseParameters, oneTimeAccountAssignments);
+ }
+}
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java b/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java
index e7423fb..b24d4d7 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java
@@ -15,15 +15,12 @@
*/
package io.mifos.individuallending.internal.service;
-import io.mifos.individuallending.api.v1.domain.caseinstance.CaseParameters;
import io.mifos.individuallending.api.v1.domain.caseinstance.ChargeName;
import io.mifos.individuallending.api.v1.domain.caseinstance.PlannedPayment;
import io.mifos.individuallending.api.v1.domain.caseinstance.PlannedPaymentPage;
import io.mifos.individuallending.api.v1.domain.product.ChargeProportionalDesignator;
import io.mifos.portfolio.api.v1.domain.ChargeDefinition;
-import io.mifos.portfolio.api.v1.domain.Product;
import io.mifos.portfolio.service.internal.service.ChargeDefinitionService;
-import io.mifos.portfolio.service.internal.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -40,40 +37,35 @@
*/
@Service
public class IndividualLoanService {
- private final ProductService productService;
private final ChargeDefinitionService chargeDefinitionService;
@Autowired
- public IndividualLoanService(final ProductService productService,
- final ChargeDefinitionService chargeDefinitionService) {
- this.productService = productService;
+ public IndividualLoanService(final ChargeDefinitionService chargeDefinitionService) {
this.chargeDefinitionService = chargeDefinitionService;
}
public PlannedPaymentPage getPlannedPaymentsPage(
- final String productIdentifier,
- final CaseParameters caseParameters,
- final int pageIndex,
- final int size,
- final @Nonnull LocalDate initialDisbursalDate) {
- final Product product = productService.findByIdentifier(productIdentifier)
- .orElseThrow(() -> new IllegalArgumentException("Non-existent product identifier."));
- final int minorCurrencyUnitDigits = product.getMinorCurrencyUnitDigits();
+ final DataContextOfAction dataContextOfAction,
+ final int pageIndex,
+ final int size,
+ final @Nonnull LocalDate initialDisbursalDate) {
+ final int minorCurrencyUnitDigits = dataContextOfAction.getProduct().getMinorCurrencyUnitDigits();
- final List<ScheduledAction> scheduledActions = ScheduledActionHelpers.getHypotheticalScheduledActions(initialDisbursalDate, caseParameters);
+ final List<ScheduledAction> scheduledActions = ScheduledActionHelpers.getHypotheticalScheduledActions(initialDisbursalDate, dataContextOfAction.getCaseParameters());
- final List<ScheduledCharge> scheduledCharges = getScheduledCharges(productIdentifier, scheduledActions);
+ final List<ScheduledCharge> scheduledCharges = getScheduledCharges(dataContextOfAction.getProduct().getIdentifier(), scheduledActions);
final BigDecimal loanPaymentSize = CostComponentService.getLoanPaymentSize(
- caseParameters.getMaximumBalance(),
+ dataContextOfAction.getCaseParameters().getMaximumBalance(),
minorCurrencyUnitDigits,
scheduledCharges);
final List<PlannedPayment> plannedPaymentsElements = getPlannedPaymentsElements(
- caseParameters.getMaximumBalance(),
+ dataContextOfAction.getCaseParameters().getMaximumBalance(),
minorCurrencyUnitDigits,
scheduledCharges,
- loanPaymentSize);
+ loanPaymentSize,
+ dataContextOfAction.getCustomerCase().getInterest());
final Set<ChargeName> chargeNames = scheduledCharges.stream()
.map(IndividualLoanService::chargeNameFromChargeDefinition)
@@ -124,7 +116,8 @@
final BigDecimal initialBalance,
final int minorCurrencyUnitDigits,
final List<ScheduledCharge> scheduledCharges,
- final BigDecimal loanPaymentSize) {
+ final BigDecimal loanPaymentSize,
+ final BigDecimal interest) {
final Map<Period, SortedSet<ScheduledCharge>> orderedScheduledChargesGroupedByPeriod
= scheduledCharges.stream()
.collect(Collectors.groupingBy(IndividualLoanService::getPeriodFromScheduledCharge,
@@ -164,6 +157,7 @@
initialBalance,
balance,
currentLoanPaymentSize,
+ interest,
minorCurrencyUnitDigits,
false);
diff --git a/service/src/main/java/io/mifos/individuallending/rest/PlannedPaymentsRestController.java b/service/src/main/java/io/mifos/individuallending/rest/PlannedPaymentsRestController.java
index 3df4fab..4d3dce0 100644
--- a/service/src/main/java/io/mifos/individuallending/rest/PlannedPaymentsRestController.java
+++ b/service/src/main/java/io/mifos/individuallending/rest/PlannedPaymentsRestController.java
@@ -18,12 +18,11 @@
import io.mifos.anubis.annotation.AcceptedTokenType;
import io.mifos.anubis.annotation.Permittable;
-import io.mifos.individuallending.internal.service.CaseParametersService;
-import io.mifos.individuallending.internal.service.IndividualLoanService;
import io.mifos.core.lang.DateConverter;
-import io.mifos.core.lang.ServiceException;
-import io.mifos.individuallending.api.v1.domain.caseinstance.CaseParameters;
import io.mifos.individuallending.api.v1.domain.caseinstance.PlannedPaymentPage;
+import io.mifos.individuallending.internal.service.DataContextOfAction;
+import io.mifos.individuallending.internal.service.DataContextService;
+import io.mifos.individuallending.internal.service.IndividualLoanService;
import io.mifos.portfolio.api.v1.PermittableGroupIds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
@@ -31,6 +30,7 @@
import java.time.LocalDate;
import java.time.ZoneId;
+import java.util.Collections;
/**
* @author Myrle Krantz
@@ -39,14 +39,14 @@
@RestController
@RequestMapping("/individuallending/products/{productidentifier}/cases/{caseidentifier}/plannedpayments")
public class PlannedPaymentsRestController {
- private final CaseParametersService caseParametersService;
+ private final DataContextService dataContextService;
private final IndividualLoanService individualLoanService;
@Autowired
public PlannedPaymentsRestController(
- final CaseParametersService caseParametersService,
- final IndividualLoanService individualLoanService) {
- this.caseParametersService = caseParametersService;
+ final DataContextService dataContextService,
+ final IndividualLoanService individualLoanService) {
+ this.dataContextService = dataContextService;
this.individualLoanService = individualLoanService;
}
@@ -63,11 +63,7 @@
@RequestParam(value = "size", required = false) final Integer size,
@RequestParam(value = "initialDisbursalDate", required = false) final String initialDisbursalDate)
{
- final CaseParameters caseParameters = caseParametersService
- .findByIdentifier(productIdentifier, caseIdentifier)
- .orElseThrow(() -> ServiceException.notFound(
- "Instance with identifier " + productIdentifier + "." + caseIdentifier + " doesn't exist or it is not an individual loan."));
-
+ final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(productIdentifier, caseIdentifier, Collections.emptyList());
final LocalDate parsedInitialDisbursalDate = initialDisbursalDate == null
? LocalDate.now(ZoneId.of("UTC"))
@@ -75,6 +71,6 @@
final Integer pageIndexToUse = pageIndex != null ? pageIndex : 0;
final Integer sizeToUse = size != null ? size : 20;
- return individualLoanService.getPlannedPaymentsPage(productIdentifier, caseParameters, pageIndexToUse, sizeToUse, parsedInitialDisbursalDate);
+ return individualLoanService.getPlannedPaymentsPage(dataContextOfAction, pageIndexToUse, sizeToUse, parsedInitialDisbursalDate);
}
}
\ No newline at end of file
diff --git a/service/src/test/java/io/mifos/individuallending/internal/service/IndividualLoanServiceTest.java b/service/src/test/java/io/mifos/individuallending/internal/service/IndividualLoanServiceTest.java
index 0cbf933..d8691bb 100644
--- a/service/src/test/java/io/mifos/individuallending/internal/service/IndividualLoanServiceTest.java
+++ b/service/src/test/java/io/mifos/individuallending/internal/service/IndividualLoanServiceTest.java
@@ -24,8 +24,9 @@
import io.mifos.individuallending.api.v1.domain.product.ChargeIdentifiers;
import io.mifos.individuallending.api.v1.domain.workflow.Action;
import io.mifos.portfolio.api.v1.domain.*;
+import io.mifos.portfolio.service.internal.repository.CaseEntity;
+import io.mifos.portfolio.service.internal.repository.ProductEntity;
import io.mifos.portfolio.service.internal.service.ChargeDefinitionService;
-import io.mifos.portfolio.service.internal.service.ProductService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -86,6 +87,7 @@
private CaseParameters caseParameters;
private LocalDate initialDisbursementDate;
private List<ChargeDefinition> chargeDefinitions;
+ private BigDecimal interest;
private Set<String> expectedChargeIdentifiers = new HashSet<>(Arrays.asList(
PROCESSING_FEE_ID,
LOAN_FUNDS_ALLOCATION_ID,
@@ -127,6 +129,11 @@
return this;
}
+ TestCase interest(final BigDecimal newVal) {
+ this.interest = newVal;
+ return this;
+ }
+
TestCase expectChargeInstancesForActionDatePair(final Action action,
final LocalDate forDate,
final List<ChargeDefinition> chargeDefinitions) {
@@ -134,6 +141,17 @@
return this;
}
+ DataContextOfAction getDataContextOfAction() {
+
+ final ProductEntity product = new ProductEntity();
+ product.setMinorCurrencyUnitDigits(minorCurrencyUnitDigits);
+ product.setIdentifier(productIdentifier);
+ final CaseEntity customerCase = new CaseEntity();
+ customerCase.setInterest(interest);
+
+ return new DataContextOfAction(product, customerCase, caseParameters, Collections.emptyList());
+ }
+
@Override
public String toString() {
return "TestCase{" +
@@ -153,7 +171,6 @@
private final TestCase testCase;
private final IndividualLoanService testSubject;
- private final Product product;
private final Map<String, List<ChargeDefinition>> chargeDefinitionsByChargeAction;
private final Map<String, List<ChargeDefinition>> chargeDefinitionsByAccrueAction;
@@ -185,6 +202,7 @@
.caseParameters(caseParameters)
.initialDisbursementDate(initialDisbursementDate)
.chargeDefinitions(defaultChargesWithFeesReplaced)
+ .interest(BigDecimal.valueOf(0.01))
.expectChargeInstancesForActionDatePair(Action.OPEN, initialDisbursementDate, Collections.singletonList(processingFeeCharge))
.expectChargeInstancesForActionDatePair(Action.APPROVE, initialDisbursementDate,
Collections.singletonList(loanOriginationFeeCharge));
@@ -205,7 +223,8 @@
.minorCurrencyUnitDigits(3)
.caseParameters(caseParameters)
.initialDisbursementDate(initialDisbursementDate)
- .chargeDefinitions(charges);
+ .chargeDefinitions(charges)
+ .interest(BigDecimal.valueOf(0.10));
}
private static TestCase chargeDefaultsCase()
@@ -222,7 +241,8 @@
.minorCurrencyUnitDigits(2)
.caseParameters(caseParameters)
.initialDisbursementDate(initialDisbursementDate)
- .chargeDefinitions(charges);
+ .chargeDefinitions(charges)
+ .interest(BigDecimal.valueOf(0.05));
}
private static List<ChargeDefinition> chargesWithInterestRate(final double interestRate) {
@@ -258,11 +278,7 @@
{
this.testCase = testCase;
- final ProductService productServiceMock = Mockito.mock(ProductService.class);
final ChargeDefinitionService chargeDefinitionServiceMock = Mockito.mock(ChargeDefinitionService.class);
- product = new Product();
- product.setMinorCurrencyUnitDigits(testCase.minorCurrencyUnitDigits);
- Mockito.doReturn(Optional.of(product)).when(productServiceMock).findByIdentifier(testCase.productIdentifier);
chargeDefinitionsByChargeAction = testCase.chargeDefinitions.stream()
.collect(Collectors.groupingBy(ChargeDefinition::getChargeAction,
Collectors.mapping(x -> x, Collectors.toList())));
@@ -273,21 +289,24 @@
Mockito.doReturn(chargeDefinitionsByChargeAction).when(chargeDefinitionServiceMock).getChargeDefinitionsMappedByChargeAction(testCase.productIdentifier);
Mockito.doReturn(chargeDefinitionsByAccrueAction).when(chargeDefinitionServiceMock).getChargeDefinitionsMappedByAccrueAction(testCase.productIdentifier);
- testSubject = new IndividualLoanService(productServiceMock, chargeDefinitionServiceMock);
+ testSubject = new IndividualLoanService(chargeDefinitionServiceMock);
}
@Test
public void getPlannedPayments() throws Exception {
- final PlannedPaymentPage firstPage = testSubject.getPlannedPaymentsPage(testCase.productIdentifier,
- testCase.caseParameters,
+ final PlannedPaymentPage firstPage = testSubject.getPlannedPaymentsPage(testCase.getDataContextOfAction(),
0,
20,
testCase.initialDisbursementDate);
+ Assert.assertFalse(firstPage.getElements().size() == 0);
+
final List<PlannedPayment> allPlannedPayments =
- Stream.iterate(0, x -> x + 1).limit(firstPage.getTotalPages())
- .map(x -> testSubject.getPlannedPaymentsPage(testCase.productIdentifier,
- testCase.caseParameters, x, 20, testCase.initialDisbursementDate))
+ Stream.iterate(0, x -> x + 1).limit(firstPage.getTotalPages())
+ .map(x -> testSubject.getPlannedPaymentsPage(testCase.getDataContextOfAction(),
+ x,
+ 20,
+ testCase.initialDisbursementDate))
.flatMap(x -> x.getElements().stream())
.collect(Collectors.toList());
@@ -314,8 +333,8 @@
//All entries should have the correct scale.
allPlannedPayments.forEach(x -> {
- x.getCostComponents().forEach(y -> Assert.assertEquals(product.getMinorCurrencyUnitDigits(), y.getAmount().scale()));
- Assert.assertEquals(product.getMinorCurrencyUnitDigits(), x.getRemainingPrincipal().scale());
+ x.getCostComponents().forEach(y -> Assert.assertEquals(testCase.minorCurrencyUnitDigits, y.getAmount().scale()));
+ Assert.assertEquals(testCase.minorCurrencyUnitDigits, x.getRemainingPrincipal().scale());
final int uniqueChargeIdentifierCount = x.getCostComponents().stream()
.map(CostComponent::getChargeIdentifier)
.collect(Collectors.toSet())