Modelled Teller Management use case in which the customer wishes to know which costs a payment will be applied to.
diff --git a/api/src/main/java/io/mifos/individuallending/api/v1/domain/caseinstance/PlannedPayment.java b/api/src/main/java/io/mifos/individuallending/api/v1/domain/caseinstance/PlannedPayment.java
index f8c62fb..6157f37 100644
--- a/api/src/main/java/io/mifos/individuallending/api/v1/domain/caseinstance/PlannedPayment.java
+++ b/api/src/main/java/io/mifos/individuallending/api/v1/domain/caseinstance/PlannedPayment.java
@@ -15,6 +15,8 @@
*/
package io.mifos.individuallending.api.v1.domain.caseinstance;
+import io.mifos.portfolio.api.v1.domain.CostComponent;
+
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
@@ -24,57 +26,6 @@
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public final class PlannedPayment {
- static public final class CostComponent
- {
- private String chargeIdentifier;
- private BigDecimal amount;
-
- public CostComponent() {
- }
-
- public CostComponent(String chargeIdentifier, BigDecimal amount) {
- this.chargeIdentifier = chargeIdentifier;
- this.amount = amount;
- }
-
- public String getChargeIdentifier() {
- return chargeIdentifier;
- }
-
- public void setChargeIdentifier(String chargeIdentifier) {
- this.chargeIdentifier = chargeIdentifier;
- }
-
- public BigDecimal getAmount() {
- return amount;
- }
-
- public void setAmount(BigDecimal amount) {
- this.amount = amount;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- CostComponent that = (CostComponent) o;
- return Objects.equals(chargeIdentifier, that.chargeIdentifier) &&
- Objects.equals(amount, that.amount);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(chargeIdentifier, amount);
- }
-
- @Override
- public String toString() {
- return "CostComponent{" +
- "chargeIdentifier='" + chargeIdentifier + '\'' +
- ", amount=" + amount +
- '}';
- }
- }
private Double interestRate;
private List<CostComponent> costComponents;
private BigDecimal remainingPrincipal;
diff --git a/api/src/main/java/io/mifos/individuallending/api/v1/domain/workflow/AcceptPaymentParameters.java b/api/src/main/java/io/mifos/individuallending/api/v1/domain/workflow/AcceptPaymentParameters.java
deleted file mode 100644
index f5f5882..0000000
--- a/api/src/main/java/io/mifos/individuallending/api/v1/domain/workflow/AcceptPaymentParameters.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * 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.api.v1.domain.workflow;
-
-/**
- * @author Myrle Krantz
- */
-public class AcceptPaymentParameters {
-}
diff --git a/api/src/main/java/io/mifos/individuallending/api/v1/domain/workflow/DisburseParameters.java b/api/src/main/java/io/mifos/individuallending/api/v1/domain/workflow/DisburseParameters.java
deleted file mode 100644
index 16483cd..0000000
--- a/api/src/main/java/io/mifos/individuallending/api/v1/domain/workflow/DisburseParameters.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * 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.api.v1.domain.workflow;
-
-/**
- * @author Myrle Krantz
- */
-public class DisburseParameters {
-}
diff --git a/api/src/main/java/io/mifos/portfolio/api/v1/client/PortfolioManager.java b/api/src/main/java/io/mifos/portfolio/api/v1/client/PortfolioManager.java
index 8e11724..cd02791 100644
--- a/api/src/main/java/io/mifos/portfolio/api/v1/client/PortfolioManager.java
+++ b/api/src/main/java/io/mifos/portfolio/api/v1/client/PortfolioManager.java
@@ -246,26 +246,27 @@
@PathVariable("caseidentifier") final String caseIdentifier);
@RequestMapping(
- value = "/products/{productidentifier}/cases/{caseidentifier}/commands/",
+ value = "/products/{productidentifier}/cases/{caseidentifier}/actions/{actionidentifier}/costcomponents",
+ method = RequestMethod.GET,
+ produces = MediaType.ALL_VALUE,
+ consumes = MediaType.APPLICATION_JSON_VALUE
+ )
+ List<CostComponent> getCostComponentsForAction(@PathVariable("productidentifier") final String productIdentifier,
+ @PathVariable("caseidentifier") final String caseIdentifier,
+ @PathVariable("actionidentifier") final String actionIdentifier);
+
+ @RequestMapping(
+ value = "/products/{productidentifier}/cases/{caseidentifier}/commands/{actionidentifier}",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE
)
void executeCaseCommand(@PathVariable("productidentifier") final String productIdentifier,
@PathVariable("caseidentifier") final String caseIdentifier,
+ @PathVariable("actionidentifier") final String actionIdentifier,
final Command command);
@RequestMapping(
- value = "/products/{productidentifier}/cases/{caseidentifier}/commands/{commandidentifier}",
- method = RequestMethod.GET,
- produces = MediaType.ALL_VALUE,
- consumes = MediaType.APPLICATION_JSON_VALUE
- )
- Command getExecutedCommandForCase(@PathVariable("productidentifier") final String productIdentifier,
- @PathVariable("caseidentifier") final String caseIdentifier,
- @PathVariable("commandidentifier") final String commandIdentifier);
-
- @RequestMapping(
value = "/products/{productidentifier}/cases/{caseidentifier}/tasks/",
method = RequestMethod.GET,
produces = MediaType.ALL_VALUE,
diff --git a/api/src/main/java/io/mifos/portfolio/api/v1/domain/Command.java b/api/src/main/java/io/mifos/portfolio/api/v1/domain/Command.java
index 198f1c1..4cb0cc6 100644
--- a/api/src/main/java/io/mifos/portfolio/api/v1/domain/Command.java
+++ b/api/src/main/java/io/mifos/portfolio/api/v1/domain/Command.java
@@ -17,14 +17,14 @@
import org.hibernate.validator.constraints.NotBlank;
+import java.util.List;
+
/**
* @author Myrle Krantz
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public final class Command {
- @NotBlank
- private String action;
- private String parameters;
+ private List<AccountAssignment> oneTimeAccountAssignments;
private String comment;
private String createdOn;
private String createdBy;
@@ -32,27 +32,6 @@
public Command() {
}
- public Command(String action, String parameters) {
- this.action = action;
- this.parameters = parameters;
- }
-
- public String getAction() {
- return action;
- }
-
- public void setAction(String action) {
- this.action = action;
- }
-
- public String getParameters() {
- return parameters;
- }
-
- public void setParameters(String parameters) {
- this.parameters = parameters;
- }
-
public String getComment() {
return comment;
}
diff --git a/api/src/main/java/io/mifos/portfolio/api/v1/domain/CostComponent.java b/api/src/main/java/io/mifos/portfolio/api/v1/domain/CostComponent.java
new file mode 100644
index 0000000..058aade
--- /dev/null
+++ b/api/src/main/java/io/mifos/portfolio/api/v1/domain/CostComponent.java
@@ -0,0 +1,59 @@
+package io.mifos.portfolio.api.v1.domain;
+
+import java.math.BigDecimal;
+import java.util.Objects;
+
+/**
+ * @author Myrle Krantz
+ */
+@SuppressWarnings({"WeakerAccess", "unused"})
+public class CostComponent {
+ private String chargeIdentifier;
+ private BigDecimal amount;
+
+ public CostComponent() {
+ }
+
+ public CostComponent(String chargeIdentifier, BigDecimal amount) {
+ this.chargeIdentifier = chargeIdentifier;
+ this.amount = amount;
+ }
+
+ public String getChargeIdentifier() {
+ return chargeIdentifier;
+ }
+
+ public void setChargeIdentifier(String chargeIdentifier) {
+ this.chargeIdentifier = chargeIdentifier;
+ }
+
+ public BigDecimal getAmount() {
+ return amount;
+ }
+
+ public void setAmount(BigDecimal amount) {
+ this.amount = amount;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ CostComponent that = (CostComponent) o;
+ return Objects.equals(chargeIdentifier, that.chargeIdentifier) &&
+ Objects.equals(amount, that.amount);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(chargeIdentifier, amount);
+ }
+
+ @Override
+ public String toString() {
+ return "CostComponent{" +
+ "chargeIdentifier='" + chargeIdentifier + '\'' +
+ ", amount=" + amount +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/component-test/src/main/java/io/mifos/portfolio/TestCommands.java b/component-test/src/main/java/io/mifos/portfolio/TestCommands.java
index 2485ae3..963f499 100644
--- a/component-test/src/main/java/io/mifos/portfolio/TestCommands.java
+++ b/component-test/src/main/java/io/mifos/portfolio/TestCommands.java
@@ -106,8 +106,8 @@
final Action action,
final String event,
final Case.State nextState) throws InterruptedException {
- final Command command = new Command(action.name(), null);
- portfolioManager.executeCaseCommand(productIdentifier, caseIdentifier, command);
+ final Command command = new Command();
+ portfolioManager.executeCaseCommand(productIdentifier, caseIdentifier, action.name(), command);
Assert.assertTrue(eventRecorder.waitForMatch(event,
(IndividualLoanCommandEvent x) -> individualLoanCommandEventMatches(x, productIdentifier, caseIdentifier)));
@@ -121,9 +121,9 @@
final Action action,
final String event,
final Case.State initialState) throws InterruptedException {
- final Command command = new Command(action.name(), null);
+ final Command command = new Command();
try {
- portfolioManager.executeCaseCommand(productIdentifier, caseIdentifier, command);
+ portfolioManager.executeCaseCommand(productIdentifier, caseIdentifier, action.name(), command);
Assert.fail();
}
catch (final IllegalArgumentException ignored) {}
diff --git a/service/src/main/java/io/mifos/individuallending/IndividualLendingCommandDispatcher.java b/service/src/main/java/io/mifos/individuallending/IndividualLendingCommandDispatcher.java
index b9eb9b5..5b685b3 100644
--- a/service/src/main/java/io/mifos/individuallending/IndividualLendingCommandDispatcher.java
+++ b/service/src/main/java/io/mifos/individuallending/IndividualLendingCommandDispatcher.java
@@ -38,8 +38,8 @@
}
@Override
- public void dispatch(final String productIdentifier, final String caseIdentifier, final Command command) {
- final Action action = Action.valueOf(command.getAction());
+ public void dispatch(final String productIdentifier, final String caseIdentifier, final String actionIdentifier, final Command command) {
+ final Action action = Action.valueOf(actionIdentifier);
switch (action) {
case OPEN:
this.commandGateway.process(new OpenCommand(productIdentifier, caseIdentifier));
@@ -66,7 +66,7 @@
this.commandGateway.process(new RecoverCommand(productIdentifier, caseIdentifier));
break;
default:
- throw ServiceException.badRequest("Action " + command.getAction() + " cannot be taken from current state.");
+ throw ServiceException.badRequest("Action ''{0}'' cannot be taken from current state.", actionIdentifier);
}
}
}
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 8f5a0b7..7b70948 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,6 +15,7 @@
*/
package io.mifos.individuallending.internal.service;
+import io.mifos.portfolio.api.v1.domain.CostComponent;
import io.mifos.portfolio.service.internal.service.ChargeDefinitionService;
import io.mifos.portfolio.service.internal.service.ProductService;
import io.mifos.core.lang.DateConverter;
@@ -181,14 +182,14 @@
final List<PlannedPayment> plannedPayments = new ArrayList<>();
for (final Period repaymentPeriod : sortedRepaymentPeriods)
{
- final Map<String, PlannedPayment.CostComponent> costComponentMap = new HashMap<>();
+ final Map<String, CostComponent> costComponentMap = new HashMap<>();
final SortedSet<ScheduledCharge> scheduledChargesInPeriod = orderedScheduledChargesGroupedByPeriod.get(repaymentPeriod);
for (final ScheduledCharge scheduledCharge : scheduledChargesInPeriod)
{
- final PlannedPayment.CostComponent costComponent = costComponentMap
+ final CostComponent costComponent = costComponentMap
.computeIfAbsent(scheduledCharge.getChargeDefinition().getIdentifier(),
chargeIdentifier -> {
- final PlannedPayment.CostComponent ret = new PlannedPayment.CostComponent();
+ final CostComponent ret = new CostComponent();
ret.setChargeIdentifier(scheduledCharge.getChargeDefinition().getIdentifier());
ret.setAmount(BigDecimal.ZERO);
return ret;
@@ -210,7 +211,7 @@
if (balance.compareTo(BigDecimal.ZERO) != 0)
{
final PlannedPayment lastPayment = plannedPayments.get(plannedPayments.size() - 1);
- final Optional<PlannedPayment.CostComponent> lastPaymentPayment = lastPayment.getCostComponents().stream()
+ final Optional<CostComponent> lastPaymentPayment = lastPayment.getCostComponents().stream()
.filter(x -> x.getChargeIdentifier().equals(PAYMENT_ID)).findAny();
lastPaymentPayment.ifPresent(x -> {
x.setAmount(x.getAmount().subtract(lastPayment.getRemainingPrincipal()));
diff --git a/service/src/main/java/io/mifos/portfolio/service/rest/CaseRestController.java b/service/src/main/java/io/mifos/portfolio/service/rest/CaseRestController.java
index a72ec2b..22e5a75 100644
--- a/service/src/main/java/io/mifos/portfolio/service/rest/CaseRestController.java
+++ b/service/src/main/java/io/mifos/portfolio/service/rest/CaseRestController.java
@@ -24,6 +24,7 @@
import io.mifos.portfolio.api.v1.domain.Case;
import io.mifos.portfolio.api.v1.domain.CasePage;
import io.mifos.portfolio.api.v1.domain.Command;
+import io.mifos.portfolio.api.v1.domain.CostComponent;
import io.mifos.portfolio.service.internal.command.ChangeCaseCommand;
import io.mifos.portfolio.service.internal.command.CreateCaseCommand;
import io.mifos.portfolio.service.internal.service.CaseService;
@@ -36,6 +37,8 @@
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
+import java.util.Collections;
+import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -176,22 +179,41 @@
@Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.CASE_MANAGEMENT)
@RequestMapping(
- value = "{caseidentifier}/commands/",
+ value = "{caseidentifier}/actions/{actionidentifier}/costcomponents",
+ method = RequestMethod.GET,
+ consumes = MediaType.ALL_VALUE,
+ produces = MediaType.APPLICATION_JSON_VALUE
+ )
+ @ResponseBody
+ List<CostComponent> getCostComponentsForAction(@PathVariable("productidentifier") final String productIdentifier,
+ @PathVariable("caseidentifier") final String caseIdentifier,
+ @PathVariable("actionidentifier") final String actionIdentifier)
+ {
+ checkThatCaseExists(productIdentifier, caseIdentifier);
+
+ return Collections.emptyList();
+ //return caseService.getActionCostComponentsForCase(productIdentifier, caseIdentifier);
+ }
+
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.CASE_MANAGEMENT)
+ @RequestMapping(
+ value = "{caseidentifier}/commands/{actionidentifier}",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE
)
public @ResponseBody ResponseEntity<Void> executeCaseCommand(@PathVariable("productidentifier") final String productIdentifier,
@PathVariable("caseidentifier") final String caseIdentifier,
+ @PathVariable("actionidentifier") final String actionIdentifier,
@RequestBody @Valid final Command command)
{
checkThatCaseExists(productIdentifier, caseIdentifier);
final Set<String> nextActions = caseService.getNextActionsForCase(productIdentifier, caseIdentifier);
- if (!nextActions.contains(command.getAction()))
- throw ServiceException.badRequest("Action " + command.getAction() + " cannot be taken from current state.");
+ if (!nextActions.contains(actionIdentifier))
+ throw ServiceException.badRequest("Action " + actionIdentifier + " cannot be taken from current state.");
final ProductCommandDispatcher productCommandDispatcher = caseService.getProductCommandDispatcher(productIdentifier);
- productCommandDispatcher.dispatch(productIdentifier, caseIdentifier, command);
+ productCommandDispatcher.dispatch(productIdentifier, caseIdentifier, actionIdentifier, command);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
diff --git a/service/src/main/java/io/mifos/products/spi/ProductCommandDispatcher.java b/service/src/main/java/io/mifos/products/spi/ProductCommandDispatcher.java
index f338c58..e5f0bd9 100644
--- a/service/src/main/java/io/mifos/products/spi/ProductCommandDispatcher.java
+++ b/service/src/main/java/io/mifos/products/spi/ProductCommandDispatcher.java
@@ -21,5 +21,5 @@
* @author Myrle Krantz
*/
public interface ProductCommandDispatcher {
- void dispatch(String productIdentifier, String caseIdentifier, Command command);
+ void dispatch(String productIdentifier, String caseIdentifier, final String actionIdentifier, Command command);
}