tidy up state transitions and transactions support through api.
This commit is contained in:
@@ -26,7 +26,7 @@ import org.mifosng.platform.api.commands.SubmitLoanApplicationCommand;
|
||||
import org.mifosng.platform.api.commands.UndoStateTransitionCommand;
|
||||
import org.mifosng.platform.api.data.EntityIdentifier;
|
||||
import org.mifosng.platform.api.data.LoanAccountData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentData;
|
||||
import org.mifosng.platform.api.data.LoanTransactionData;
|
||||
import org.mifosng.platform.api.data.LoanSchedule;
|
||||
import org.mifosng.platform.api.data.NewLoanData;
|
||||
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
|
||||
@@ -49,7 +49,7 @@ public class LoansApiResource {
|
||||
private String loanFilterName = "loanFilter";
|
||||
private String loanAllowedFieldList = "";
|
||||
private String loanRepaymentFilterName = "loanRepaymentFilter";
|
||||
private String loanRepaymentDefaultFieldList = "date,total";
|
||||
private String loanRepaymentDefaultFieldList = "transactionType,date,total";
|
||||
private String loanRepaymentAllowedFieldList = "";
|
||||
|
||||
@Autowired
|
||||
@@ -280,13 +280,13 @@ public class LoansApiResource {
|
||||
String json = "";
|
||||
String selectedFields = loanRepaymentDefaultFieldList;
|
||||
if (is(commandParam, "repayment")) {
|
||||
LoanRepaymentData loanRepaymentData = this.loanReadPlatformService
|
||||
LoanTransactionData loanRepaymentData = this.loanReadPlatformService
|
||||
.retrieveNewLoanRepaymentDetails(loanId);
|
||||
json = this.jsonFormattingService.convertRequest(loanRepaymentData,
|
||||
loanRepaymentFilterName, loanRepaymentAllowedFieldList, selectedFields,
|
||||
uriInfo.getQueryParameters());
|
||||
} else if (is(commandParam, "waiver")) {
|
||||
LoanRepaymentData loanWaiverData = this.loanReadPlatformService
|
||||
LoanTransactionData loanWaiverData = this.loanReadPlatformService
|
||||
.retrieveNewLoanWaiverDetails(loanId);
|
||||
json = this.jsonFormattingService.convertRequest(loanWaiverData,
|
||||
loanRepaymentFilterName, loanRepaymentAllowedFieldList, selectedFields,
|
||||
@@ -304,15 +304,15 @@ public class LoansApiResource {
|
||||
@Path("{loanId}/transactions/{transactionId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
@Produces({ MediaType.APPLICATION_JSON})
|
||||
public String retrieveRepaymentDetails(
|
||||
public String retrieveTransaction(
|
||||
@PathParam("loanId") final Long loanId,
|
||||
@PathParam("transactionId") final Long transactionId,
|
||||
@Context UriInfo uriInfo) {
|
||||
|
||||
LoanRepaymentData loanRepaymentData = this.loanReadPlatformService
|
||||
.retrieveLoanRepaymentDetails(loanId, transactionId);
|
||||
LoanTransactionData loanRepaymentData = this.loanReadPlatformService
|
||||
.retrieveLoanTransactionDetails(loanId, transactionId);
|
||||
|
||||
String selectedFields = "";
|
||||
String selectedFields = loanRepaymentDefaultFieldList;
|
||||
return this.jsonFormattingService.convertRequest(loanRepaymentData,
|
||||
loanRepaymentFilterName, loanRepaymentAllowedFieldList, selectedFields,
|
||||
uriInfo.getQueryParameters());
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ public class ApiGlobalErrorResponse {
|
||||
public static ApiGlobalErrorResponse dataIntegrityError(final String globalisationMessageCode, final String defaultUserMessage, final String parameterName, final Object... defaultUserMessageArgs) {
|
||||
|
||||
ApiGlobalErrorResponse globalErrorResponse = new ApiGlobalErrorResponse();
|
||||
globalErrorResponse.setHttpStatusCode("400");
|
||||
globalErrorResponse.setHttpStatusCode("403");
|
||||
globalErrorResponse.setDeveloperMessage("The request caused a data integrity issue to be fired by the database.");
|
||||
globalErrorResponse.setDeveloperDocLink("https://github.com/keithwoodlock/mifosx/wiki/HTTP-API-Error-codes");
|
||||
globalErrorResponse.setUserMessageGlobalisationCode(globalisationMessageCode);
|
||||
|
||||
@@ -6,13 +6,13 @@ public class DerivedLoanData {
|
||||
|
||||
private LoanRepaymentScheduleData repaymentSchedule;
|
||||
private LoanAccountSummaryData summary;
|
||||
private List<LoanRepaymentData> loanRepayments;
|
||||
private List<LoanTransactionData> loanRepayments;
|
||||
|
||||
public DerivedLoanData() {
|
||||
//
|
||||
}
|
||||
|
||||
public DerivedLoanData(LoanRepaymentScheduleData repaymentScheduleData, LoanAccountSummaryData summaryData, List<LoanRepaymentData> loanRepayments) {
|
||||
public DerivedLoanData(LoanRepaymentScheduleData repaymentScheduleData, LoanAccountSummaryData summaryData, List<LoanTransactionData> loanRepayments) {
|
||||
this.repaymentSchedule = repaymentScheduleData;
|
||||
this.summary = summaryData;
|
||||
this.loanRepayments = loanRepayments;
|
||||
@@ -34,11 +34,11 @@ public class DerivedLoanData {
|
||||
this.summary = summary;
|
||||
}
|
||||
|
||||
public List<LoanRepaymentData> getLoanRepayments() {
|
||||
public List<LoanTransactionData> getLoanRepayments() {
|
||||
return loanRepayments;
|
||||
}
|
||||
|
||||
public void setLoanRepayments(List<LoanRepaymentData> loanRepayments) {
|
||||
public void setLoanRepayments(List<LoanTransactionData> loanRepayments) {
|
||||
this.loanRepayments = loanRepayments;
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ public class LoanAccountData {
|
||||
|
||||
private LoanAccountSummaryData summary;
|
||||
private LoanRepaymentScheduleData repaymentSchedule;
|
||||
private List<LoanRepaymentData> loanRepayments;
|
||||
private List<LoanTransactionData> loanRepayments;
|
||||
|
||||
private LoanPermissionData permissions;
|
||||
|
||||
@@ -55,7 +55,7 @@ public class LoanAccountData {
|
||||
public LoanAccountData(LoanBasicDetailsData basicDetails,
|
||||
LoanAccountSummaryData summary,
|
||||
LoanRepaymentScheduleData repaymentSchedule,
|
||||
List<LoanRepaymentData> loanRepayments, LoanPermissionData permissions) {
|
||||
List<LoanTransactionData> loanRepayments, LoanPermissionData permissions) {
|
||||
this.summary = summary;
|
||||
this.repaymentSchedule = repaymentSchedule;
|
||||
this.loanRepayments = loanRepayments;
|
||||
@@ -130,11 +130,11 @@ public class LoanAccountData {
|
||||
this.repaymentSchedule = repaymentSchedule;
|
||||
}
|
||||
|
||||
public List<LoanRepaymentData> getLoanRepayments() {
|
||||
public List<LoanTransactionData> getLoanRepayments() {
|
||||
return loanRepayments;
|
||||
}
|
||||
|
||||
public void setLoanRepayments(List<LoanRepaymentData> loanRepayments) {
|
||||
public void setLoanRepayments(List<LoanTransactionData> loanRepayments) {
|
||||
this.loanRepayments = loanRepayments;
|
||||
}
|
||||
|
||||
|
||||
+14
-8
@@ -4,9 +4,10 @@ import org.codehaus.jackson.map.annotate.JsonFilter;
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
@JsonFilter("loanRepaymentFilter")
|
||||
public class LoanRepaymentData {
|
||||
public class LoanTransactionData {
|
||||
|
||||
private Long id;
|
||||
private EnumOptionData transactionType;
|
||||
private LocalDate date;
|
||||
private MoneyData principal;
|
||||
private MoneyData interest;
|
||||
@@ -14,16 +15,17 @@ public class LoanRepaymentData {
|
||||
private MoneyData totalWaived;
|
||||
private MoneyData overpaid;
|
||||
|
||||
public LoanRepaymentData() {
|
||||
public LoanTransactionData() {
|
||||
//
|
||||
}
|
||||
|
||||
public LoanRepaymentData(
|
||||
Long id, final LocalDate date,
|
||||
public LoanTransactionData(
|
||||
Long id, EnumOptionData transactionType, final LocalDate date,
|
||||
final MoneyData principal,
|
||||
final MoneyData interest,
|
||||
final MoneyData total, final MoneyData overpaid) {
|
||||
this.id = id;
|
||||
this.transactionType = transactionType;
|
||||
this.date = date;
|
||||
this.principal = principal;
|
||||
this.interest = interest;
|
||||
@@ -38,15 +40,19 @@ public class LoanRepaymentData {
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public EnumOptionData getTransactionType() {
|
||||
return transactionType;
|
||||
}
|
||||
|
||||
public void setTransactionType(EnumOptionData transactionType) {
|
||||
this.transactionType = transactionType;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
// public int getTransactionOffsetFromToday() {
|
||||
// return Days.daysBetween(new DateMidnight().toDateTime(), this.date.toDateMidnight().toDateTime()).getDays();
|
||||
// }
|
||||
|
||||
public void setDate(LocalDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
+1
-1
@@ -26,6 +26,6 @@ public class PlatformDataIntegrityExceptionMapper implements ExceptionMapper<Pla
|
||||
ApiGlobalErrorResponse dataIntegrityError = ApiGlobalErrorResponse.dataIntegrityError(exception.getGlobalisationMessageCode(), exception.getDefaultUserMessage(),
|
||||
exception.getParameterName(), exception.getDefaultUserMessageArgs());
|
||||
|
||||
return Response.status(Status.BAD_REQUEST).entity(dataIntegrityError).build();
|
||||
return Response.status(Status.FORBIDDEN).entity(dataIntegrityError).build();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -6,6 +6,6 @@ package org.mifosng.platform.exceptions;
|
||||
public class InvalidLoanStateTransitionException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public InvalidLoanStateTransitionException(final String action, String postFix, String defaultUserMessage, Object... defaultUserMessageArgs) {
|
||||
super("error.msg.loan." + action + postFix, defaultUserMessage, defaultUserMessageArgs);
|
||||
super("error.msg.loan." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package org.mifosng.platform.exceptions;
|
||||
|
||||
/**
|
||||
* {@link AbstractPlatformDomainRuleException} thrown an action to transition a loan from one state to another violates a domain rule.
|
||||
*/
|
||||
public class InvalidLoanTransactionTypeException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public InvalidLoanTransactionTypeException(final String action, String postFix, String defaultUserMessage, Object... defaultUserMessageArgs) {
|
||||
super("error.msg.loan." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs);
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -6,6 +6,10 @@ package org.mifosng.platform.exceptions;
|
||||
public class LoanTransactionNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public LoanTransactionNotFoundException(Long id) {
|
||||
super("error.msg.loan.id.invalid", "Loan with identifier " + id + " does not exist", id);
|
||||
super("error.msg.loan.id.invalid", "Transaction with identifier " + id + " does not exist", id);
|
||||
}
|
||||
|
||||
public LoanTransactionNotFoundException(Long id, Long loanId) {
|
||||
super("error.msg.loan.id.invalid", "Transaction with identifier " + id + " does not exist for loan with identifier " + loanId + "." , id, loanId);
|
||||
}
|
||||
}
|
||||
+12
-8
@@ -7,13 +7,15 @@ import java.util.List;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.DerivedLoanData;
|
||||
import org.mifosng.platform.api.data.EnumOptionData;
|
||||
import org.mifosng.platform.api.data.LoanAccountSummaryData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentData;
|
||||
import org.mifosng.platform.api.data.LoanTransactionData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentPeriodData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentScheduleData;
|
||||
import org.mifosng.platform.api.data.MoneyData;
|
||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
||||
import org.mifosng.platform.currency.domain.Money;
|
||||
import org.mifosng.platform.loanproduct.service.LoanEnumerations;
|
||||
|
||||
// FIXME - The derived details of the loan schedule are now updated on the fly when someone does a transaction against a loan. So this is not fully needed.
|
||||
// - we still use this to figure out how much of a given transactions amount was principal versus interest but might not need this and we should probably
|
||||
@@ -28,7 +30,7 @@ public class DerivedLoanDataProcessor {
|
||||
List<LoanRepaymentPeriodData> loanRepaymentPeriods = repaymentScheduleDetails.getPeriods();
|
||||
|
||||
// break up payments based on principal and interest
|
||||
List<LoanRepaymentData> loanRepayments = new ArrayList<LoanRepaymentData>();
|
||||
List<LoanTransactionData> loanRepayments = new ArrayList<LoanTransactionData>();
|
||||
int repaymentScheduleIndex = 0;
|
||||
for (LoanTransaction transaction : loanTransactions) {
|
||||
if (transaction.isRepayment() || transaction.isWaiver()) {
|
||||
@@ -40,7 +42,7 @@ public class DerivedLoanDataProcessor {
|
||||
.get(repaymentScheduleIndex);
|
||||
|
||||
if (transaction.isRepayment()) {
|
||||
LoanRepaymentData repaymentData = processLoanRepayment(
|
||||
LoanTransactionData repaymentData = processLoanRepayment(
|
||||
transaction, scheduledRepaymentPeriod,
|
||||
repaymentScheduleIndex, loanRepaymentPeriods,
|
||||
arrearsTolerance, currencyDetail);
|
||||
@@ -48,7 +50,7 @@ public class DerivedLoanDataProcessor {
|
||||
}
|
||||
|
||||
if (transaction.isWaiver()) {
|
||||
LoanRepaymentData repaymentData = processWaiver(transaction, scheduledRepaymentPeriod, currencyDetail);
|
||||
LoanTransactionData repaymentData = processWaiver(transaction, scheduledRepaymentPeriod, currencyDetail);
|
||||
loanRepayments.add(repaymentData);
|
||||
}
|
||||
|
||||
@@ -73,7 +75,7 @@ public class DerivedLoanDataProcessor {
|
||||
return new DerivedLoanData(processRepaymentScheduleData, summaryData, loanRepayments);
|
||||
}
|
||||
|
||||
private LoanRepaymentData processWaiver(LoanTransaction transaction,
|
||||
private LoanTransactionData processWaiver(LoanTransaction transaction,
|
||||
LoanRepaymentPeriodData scheduledRepaymentPeriod, CurrencyData currencyData) {
|
||||
|
||||
MonetaryCurrency currency = new MonetaryCurrency(currencyData.getCode(), currencyData.getDecimalPlaces());
|
||||
@@ -125,7 +127,8 @@ public class DerivedLoanDataProcessor {
|
||||
Money remainingOutstanding = totalOutstanding.minus(moneyFrom(totalWaived));
|
||||
scheduledRepaymentPeriod.setTotalOutstanding(moneyDataFrom(currencyData, remainingOutstanding));
|
||||
|
||||
LoanRepaymentData loanRepaymentData = new LoanRepaymentData(transaction.getId(), transaction.getTransactionDate(), moneyDataFrom(currencyData, principalWaived),
|
||||
EnumOptionData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WAIVED);
|
||||
LoanTransactionData loanRepaymentData = new LoanTransactionData(transaction.getId(), transactionType, transaction.getTransactionDate(), moneyDataFrom(currencyData, principalWaived),
|
||||
moneyDataFrom(currencyData, interestWaived), totalWaived, zero);
|
||||
loanRepaymentData.setTotalWaived(totalWaived);
|
||||
return loanRepaymentData;
|
||||
@@ -270,7 +273,7 @@ public class DerivedLoanDataProcessor {
|
||||
/**
|
||||
* TODO - pays off interest first then principal so should make this configurable when generating 'derived view of loan account'
|
||||
*/
|
||||
private LoanRepaymentData processLoanRepayment(LoanTransaction repayment,
|
||||
private LoanTransactionData processLoanRepayment(LoanTransaction repayment,
|
||||
LoanRepaymentPeriodData scheduledRepayment,
|
||||
int repaymentScheduleIndex,
|
||||
List<LoanRepaymentPeriodData> repaymentSchedulePeriods,
|
||||
@@ -443,7 +446,8 @@ public class DerivedLoanDataProcessor {
|
||||
|
||||
MoneyData totalPaid = moneyDataFrom(currencyDetail, totalPrincipalComponent.plus(totalInterestComponent));
|
||||
|
||||
LoanRepaymentData loanRepaymentData = new LoanRepaymentData(repayment.getId(), repayment.getTransactionDate(), cumulativePrincipalPaid, cumulativeInterestPaid, totalPaid, overpaid);
|
||||
EnumOptionData transactionType = LoanEnumerations.transactionType(LoanTransactionType.REPAYMENT);
|
||||
LoanTransactionData loanRepaymentData = new LoanTransactionData(repayment.getId(), transactionType, repayment.getTransactionDate(), cumulativePrincipalPaid, cumulativeInterestPaid, totalPaid, overpaid);
|
||||
return loanRepaymentData;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,13 +32,14 @@ import org.mifosng.platform.api.data.LoanAccountData;
|
||||
import org.mifosng.platform.api.data.LoanAccountSummaryData;
|
||||
import org.mifosng.platform.api.data.LoanBasicDetailsData;
|
||||
import org.mifosng.platform.api.data.LoanPermissionData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentScheduleData;
|
||||
import org.mifosng.platform.api.data.LoanTransactionData;
|
||||
import org.mifosng.platform.api.data.MoneyData;
|
||||
import org.mifosng.platform.client.domain.Client;
|
||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
||||
import org.mifosng.platform.currency.domain.Money;
|
||||
import org.mifosng.platform.exceptions.InvalidLoanStateTransitionException;
|
||||
import org.mifosng.platform.exceptions.InvalidLoanTransactionTypeException;
|
||||
import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
|
||||
import org.mifosng.platform.loanproduct.service.LoanEnumerations;
|
||||
import org.mifosng.platform.organisation.domain.Organisation;
|
||||
@@ -336,6 +337,17 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
throw new InvalidLoanStateTransitionException("waive", "cannot.be.a.futre.date", errorMessage, loanTransactionDate);
|
||||
}
|
||||
|
||||
if (getTotalOutstanding().isGreaterThan(this.getInArrearsTolerance())) {
|
||||
final String errorMessage = "Waiver is only allowed when the total outstanding amount left on loan (" + getTotalOutstanding() +") is less than thethe in arrears tolerance setting of " + getInArrearsTolerance().getAmount();
|
||||
throw new InvalidLoanStateTransitionException("waive", "cannot.exceed.in.arrears.tolerance.setting", errorMessage, getTotalOutstanding(), getInArrearsTolerance());
|
||||
}
|
||||
|
||||
Money waived = Money.of(getCurrency(), loanTransaction.getAmount());
|
||||
if (waived.isGreaterThan(this.getInArrearsTolerance())) {
|
||||
final String errorMessage = "The amount being waived cannot exceed the in arrears tolerance setting of " + getInArrearsTolerance().getAmount();
|
||||
throw new InvalidLoanStateTransitionException("waive", "cannot.exceed.in.arrears.tolerance.setting", errorMessage, waived, getInArrearsTolerance());
|
||||
}
|
||||
|
||||
if (this.isRepaidInFull()) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(LoanEvent.REPAID_IN_FULL, this.loanStatus);
|
||||
this.closedOnDate = loanTransaction.getTransactionDate().toDate();
|
||||
@@ -361,8 +373,8 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
deriveLoanRepaymentScheduleCompletedData();
|
||||
|
||||
if (loanTransaction.isNotRepayment()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Only repayment transactions can be passed to makeRepayment.");
|
||||
final String errorMessage = "A transaction of type repayment was expected but not received.";
|
||||
throw new InvalidLoanTransactionTypeException("transaction", "is.not.a.repayment.transaction", errorMessage);
|
||||
}
|
||||
|
||||
LocalDate loanTransactionDate = loanTransaction.getTransactionDate();
|
||||
@@ -469,7 +481,8 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
LoanTransaction newTransactionDetail, LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
|
||||
if (transactionForAdjustment.isNotRepayment() && transactionForAdjustment.isNotWaiver()) {
|
||||
throw new IllegalArgumentException("Only repayment and waiver transactions can be adjusted.");
|
||||
final String errorMessage = "A transaction of type repayment or waiver was expected but not received.";
|
||||
throw new InvalidLoanTransactionTypeException("transaction", "is.not.a.repayment.or.waiver.transaction", errorMessage);
|
||||
}
|
||||
|
||||
transactionForAdjustment.contra();
|
||||
@@ -982,7 +995,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
}
|
||||
|
||||
public LoanAccountData toLoanAccountData(LoanAccountSummaryData summary, LoanRepaymentScheduleData repaymentSchedule,
|
||||
List<LoanRepaymentData> loanRepayments,
|
||||
List<LoanTransactionData> loanRepayments,
|
||||
CurrencyData currencyData) {
|
||||
|
||||
LoanBasicDetailsData basicDetails = toBasicDetailsData(currencyData);
|
||||
|
||||
+3
-3
@@ -2,13 +2,13 @@ package org.mifosng.platform.loan.domain;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.mifosng.platform.api.data.LoanRepaymentData;
|
||||
import org.mifosng.platform.api.data.LoanTransactionData;
|
||||
|
||||
|
||||
public class LoanRepaymentDataComparator implements Comparator<LoanRepaymentData> {
|
||||
public class LoanRepaymentDataComparator implements Comparator<LoanTransactionData> {
|
||||
|
||||
@Override
|
||||
public int compare(final LoanRepaymentData o1, final LoanRepaymentData o2) {
|
||||
public int compare(final LoanTransactionData o1, final LoanTransactionData o2) {
|
||||
return o2.getDate().compareTo(o1.getDate());
|
||||
}
|
||||
|
||||
|
||||
@@ -140,6 +140,14 @@ public class LoanTransaction extends AbstractAuditableCustom<AppUser, Long> {
|
||||
public boolean isIdentifiedBy(Long identifier) {
|
||||
return this.getId().equals(identifier);
|
||||
}
|
||||
|
||||
public boolean isBelongingToLoanOf(Loan check) {
|
||||
return this.loan.getId().equals(check.getId());
|
||||
}
|
||||
|
||||
public boolean isNotBelongingToLoanOf(Loan check) {
|
||||
return !isBelongingToLoanOf(check);
|
||||
}
|
||||
|
||||
public void contra() {
|
||||
this.contra = LoanTransaction.contra(this);
|
||||
|
||||
+10
-4
@@ -1,22 +1,28 @@
|
||||
package org.mifosng.platform.loan.domain;
|
||||
|
||||
public enum LoanTransactionType {
|
||||
UNKNOWN(0), DISBURSEMENT(1), REPAYMENT(2), REVERSAL(3), WAIVED(4);
|
||||
INVALID(0, "loanTransactionType.invalid"), DISBURSEMENT(1, "loanTransactionType.disbursement"), REPAYMENT(2, "loanTransactionType.repayment"), REVERSAL(3, "loanTransactionType.reversal"), WAIVED(4, "loanTransactionType.waiver");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private LoanTransactionType(final Integer value) {
|
||||
private LoanTransactionType(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static LoanTransactionType fromInt(final Integer transactionType) {
|
||||
|
||||
if (transactionType == null) {
|
||||
return LoanTransactionType.UNKNOWN;
|
||||
return LoanTransactionType.INVALID;
|
||||
}
|
||||
|
||||
LoanTransactionType loanTransactionType = null;
|
||||
@@ -34,7 +40,7 @@ public enum LoanTransactionType {
|
||||
loanTransactionType = LoanTransactionType.WAIVED;
|
||||
break;
|
||||
default:
|
||||
loanTransactionType = LoanTransactionType.UNKNOWN;
|
||||
loanTransactionType = LoanTransactionType.INVALID;
|
||||
break;
|
||||
}
|
||||
return loanTransactionType;
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
package org.mifosng.platform.loan.service;
|
||||
|
||||
import org.mifosng.platform.api.data.LoanAccountData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentData;
|
||||
import org.mifosng.platform.api.data.LoanTransactionData;
|
||||
import org.mifosng.platform.api.data.NewLoanData;
|
||||
|
||||
public interface LoanReadPlatformService {
|
||||
@@ -10,9 +10,9 @@ public interface LoanReadPlatformService {
|
||||
|
||||
NewLoanData retrieveClientAndProductDetails(Long clientId, Long productId);
|
||||
|
||||
LoanRepaymentData retrieveNewLoanRepaymentDetails(Long loanId);
|
||||
LoanTransactionData retrieveNewLoanRepaymentDetails(Long loanId);
|
||||
|
||||
LoanRepaymentData retrieveNewLoanWaiverDetails(Long loanId);
|
||||
LoanTransactionData retrieveNewLoanWaiverDetails(Long loanId);
|
||||
|
||||
LoanRepaymentData retrieveLoanRepaymentDetails(Long loanId, Long transactionId);
|
||||
LoanTransactionData retrieveLoanTransactionDetails(Long loanId, Long transactionId);
|
||||
}
|
||||
+16
-7
@@ -13,7 +13,7 @@ import org.mifosng.platform.api.data.DerivedLoanData;
|
||||
import org.mifosng.platform.api.data.LoanAccountData;
|
||||
import org.mifosng.platform.api.data.LoanProductData;
|
||||
import org.mifosng.platform.api.data.LoanProductLookup;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentData;
|
||||
import org.mifosng.platform.api.data.LoanTransactionData;
|
||||
import org.mifosng.platform.api.data.MoneyData;
|
||||
import org.mifosng.platform.api.data.NewLoanData;
|
||||
import org.mifosng.platform.client.service.ClientReadPlatformService;
|
||||
@@ -27,6 +27,8 @@ import org.mifosng.platform.loan.domain.Loan;
|
||||
import org.mifosng.platform.loan.domain.LoanRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanTransaction;
|
||||
import org.mifosng.platform.loan.domain.LoanTransactionRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanTransactionType;
|
||||
import org.mifosng.platform.loanproduct.service.LoanEnumerations;
|
||||
import org.mifosng.platform.loanproduct.service.LoanProductReadPlatformService;
|
||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||
import org.mifosng.platform.user.domain.AppUser;
|
||||
@@ -137,7 +139,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanRepaymentData retrieveNewLoanRepaymentDetails(Long loanId) {
|
||||
public LoanTransactionData retrieveNewLoanRepaymentDetails(Long loanId) {
|
||||
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
|
||||
@@ -167,7 +169,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
MoneyData possibleNextRepayment = MoneyData.of(currencyData,
|
||||
possibleNextRepaymentAmount.getAmount());
|
||||
|
||||
LoanRepaymentData newRepaymentDetails = new LoanRepaymentData();
|
||||
LoanTransactionData newRepaymentDetails = new LoanTransactionData();
|
||||
newRepaymentDetails.setTransactionType(LoanEnumerations.transactionType(LoanTransactionType.REPAYMENT));
|
||||
newRepaymentDetails.setDate(earliestUnpaidInstallmentDate);
|
||||
newRepaymentDetails.setTotal(possibleNextRepayment);
|
||||
|
||||
@@ -175,7 +178,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanRepaymentData retrieveNewLoanWaiverDetails(Long loanId) {
|
||||
public LoanTransactionData retrieveNewLoanWaiverDetails(Long loanId) {
|
||||
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
|
||||
@@ -203,7 +206,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
MoneyData totalOutstandingData = MoneyData.of(currencyData,
|
||||
totalOutstanding.getAmount());
|
||||
|
||||
LoanRepaymentData newWaiverDetails = new LoanRepaymentData();
|
||||
LoanTransactionData newWaiverDetails = new LoanTransactionData();
|
||||
newWaiverDetails.setTransactionType(LoanEnumerations.transactionType(LoanTransactionType.WAIVED));
|
||||
newWaiverDetails.setDate(new LocalDate());
|
||||
newWaiverDetails.setTotal(totalOutstandingData);
|
||||
|
||||
@@ -211,7 +215,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanRepaymentData retrieveLoanRepaymentDetails(Long loanId,
|
||||
public LoanTransactionData retrieveLoanTransactionDetails(Long loanId,
|
||||
Long transactionId) {
|
||||
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
@@ -236,6 +240,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
if (transaction == null) {
|
||||
throw new LoanTransactionNotFoundException(transactionId);
|
||||
}
|
||||
|
||||
if (transaction.isNotBelongingToLoanOf(loan)) {
|
||||
throw new LoanTransactionNotFoundException(transactionId, loanId);
|
||||
}
|
||||
|
||||
CurrencyData currencyData = new CurrencyData(currency.getCode(),
|
||||
currency.getName(), currency.getDecimalPlaces(),
|
||||
@@ -243,7 +251,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
MoneyData total = MoneyData.of(currencyData, transaction.getAmount());
|
||||
LocalDate date = transaction.getTransactionDate();
|
||||
|
||||
LoanRepaymentData loanRepaymentData = new LoanRepaymentData();
|
||||
LoanTransactionData loanRepaymentData = new LoanTransactionData();
|
||||
loanRepaymentData.setTransactionType(LoanEnumerations.transactionType(transaction.getTypeOf()));
|
||||
loanRepaymentData.setId(transactionId);
|
||||
loanRepaymentData.setTotal(total);
|
||||
loanRepaymentData.setDate(date);
|
||||
|
||||
+9
-9
@@ -152,7 +152,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
return new EntityIdentifier(loan.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -175,7 +175,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
return new EntityIdentifier(loan.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -206,7 +206,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
return new EntityIdentifier(loan.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -237,7 +237,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
return new EntityIdentifier(loan.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -324,7 +324,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
return new EntityIdentifier(loan.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -352,7 +352,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
return new EntityIdentifier(loan.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -389,7 +389,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
return new EntityIdentifier(loan.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -435,7 +435,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
return new EntityIdentifier(loan.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -470,6 +470,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
return new EntityIdentifier(loan.getId());
|
||||
}
|
||||
}
|
||||
+29
-2
@@ -4,6 +4,7 @@ import org.mifosng.platform.api.data.EnumOptionData;
|
||||
import org.mifosng.platform.loan.domain.AmortizationMethod;
|
||||
import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod;
|
||||
import org.mifosng.platform.loan.domain.InterestMethod;
|
||||
import org.mifosng.platform.loan.domain.LoanTransactionType;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
|
||||
public class LoanEnumerations {
|
||||
@@ -87,7 +88,7 @@ public class LoanEnumerations {
|
||||
optionData = new EnumOptionData(InterestMethod.DECLINING_BALANCE.getValue().longValue(), InterestMethod.DECLINING_BALANCE.getCode(), "Declining Balance");
|
||||
break;
|
||||
default:
|
||||
optionData = new EnumOptionData(AmortizationMethod.INVALID.getValue().longValue(), AmortizationMethod.INVALID.getCode(), "Invalid");
|
||||
optionData = new EnumOptionData(InterestMethod.INVALID.getValue().longValue(), InterestMethod.INVALID.getCode(), "Invalid");
|
||||
break;
|
||||
}
|
||||
return optionData;
|
||||
@@ -107,7 +108,33 @@ public class LoanEnumerations {
|
||||
optionData = new EnumOptionData(InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD.getValue().longValue(), InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD.getCode(), "Same as repayment period");
|
||||
break;
|
||||
default:
|
||||
optionData = new EnumOptionData(AmortizationMethod.INVALID.getValue().longValue(), AmortizationMethod.INVALID.getCode(), "Invalid");
|
||||
optionData = new EnumOptionData(InterestCalculationPeriodMethod.INVALID.getValue().longValue(), InterestCalculationPeriodMethod.INVALID.getCode(), "Invalid");
|
||||
break;
|
||||
}
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static EnumOptionData transactionType(Integer id) {
|
||||
return transactionType(LoanTransactionType.fromInt(id));
|
||||
}
|
||||
|
||||
public static EnumOptionData transactionType(LoanTransactionType type) {
|
||||
EnumOptionData optionData = null;
|
||||
switch (type) {
|
||||
case DISBURSEMENT:
|
||||
optionData= new EnumOptionData(LoanTransactionType.DISBURSEMENT.getValue().longValue(), LoanTransactionType.DISBURSEMENT.getCode(), "Dibursement");
|
||||
break;
|
||||
case REPAYMENT:
|
||||
optionData = new EnumOptionData(LoanTransactionType.REPAYMENT.getValue().longValue(), LoanTransactionType.REPAYMENT.getCode(), "Repayment");
|
||||
break;
|
||||
case REVERSAL:
|
||||
optionData = new EnumOptionData(LoanTransactionType.REVERSAL.getValue().longValue(), LoanTransactionType.REVERSAL.getCode(), "Reversal");
|
||||
break;
|
||||
case WAIVED:
|
||||
optionData = new EnumOptionData(LoanTransactionType.WAIVED.getValue().longValue(), LoanTransactionType.WAIVED.getCode(), "Waiver");
|
||||
break;
|
||||
default:
|
||||
optionData = new EnumOptionData(LoanTransactionType.INVALID.getValue().longValue(), LoanTransactionType.INVALID.getCode(), "Invalid");
|
||||
break;
|
||||
}
|
||||
return optionData;
|
||||
|
||||
+11
-11
@@ -12,7 +12,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.DerivedLoanData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentData;
|
||||
import org.mifosng.platform.api.data.LoanTransactionData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentPeriodData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentScheduleData;
|
||||
import org.mifosng.platform.api.data.MoneyData;
|
||||
@@ -81,11 +81,11 @@ public class DerivedLoanDataProcessorTest {
|
||||
assertThat(periodData.getInterestOutstanding(), is(expectedInterestOutstanding));
|
||||
|
||||
// assert repayments are ok
|
||||
List<LoanRepaymentData> loanRepayments = derivedData.getLoanRepayments();
|
||||
List<LoanTransactionData> loanRepayments = derivedData.getLoanRepayments();
|
||||
assertThat(loanRepayments, is(notNullValue()));
|
||||
assertThat(loanRepayments.size(), is(1));
|
||||
|
||||
LoanRepaymentData firstRepayment = loanRepayments.get(0);
|
||||
LoanTransactionData firstRepayment = loanRepayments.get(0);
|
||||
assertThat(firstRepayment.getPrincipal(), is(expectedPrincipalPaid));
|
||||
assertThat(firstRepayment.getInterest(), is(expectedInterestPaid));
|
||||
assertThat(firstRepayment.getTotal(), is(expectedTotal));
|
||||
@@ -147,11 +147,11 @@ public class DerivedLoanDataProcessorTest {
|
||||
assertThat(periodData.getInterestOutstanding(), is(expectedInterestOutstanding));
|
||||
|
||||
// assert repayments are ok
|
||||
List<LoanRepaymentData> loanRepayments = derivedData.getLoanRepayments();
|
||||
List<LoanTransactionData> loanRepayments = derivedData.getLoanRepayments();
|
||||
assertThat(loanRepayments, is(notNullValue()));
|
||||
assertThat(loanRepayments.size(), is(1));
|
||||
|
||||
LoanRepaymentData firstRepayment = loanRepayments.get(0);
|
||||
LoanTransactionData firstRepayment = loanRepayments.get(0);
|
||||
assertThat(firstRepayment.getPrincipal(), is(expectedPrincipalPaid));
|
||||
assertThat(firstRepayment.getInterest(), is(expectedInterestPaid));
|
||||
assertThat(firstRepayment.getTotal(), is(expectedTotal));
|
||||
@@ -210,11 +210,11 @@ public class DerivedLoanDataProcessorTest {
|
||||
assertThat(periodData.getInterestOutstanding(), is(expectedInterestOutstanding));
|
||||
|
||||
// assert repayments are ok
|
||||
List<LoanRepaymentData> loanRepayments = derivedData.getLoanRepayments();
|
||||
List<LoanTransactionData> loanRepayments = derivedData.getLoanRepayments();
|
||||
assertThat(loanRepayments, is(notNullValue()));
|
||||
assertThat(loanRepayments.size(), is(1));
|
||||
|
||||
LoanRepaymentData firstRepayment = loanRepayments.get(0);
|
||||
LoanTransactionData firstRepayment = loanRepayments.get(0);
|
||||
assertThat(firstRepayment.getPrincipal(), is(expectedPrincipalPaid));
|
||||
assertThat(firstRepayment.getInterest(), is(expectedInterestPaid));
|
||||
assertThat(firstRepayment.getTotal(), is(expectedTotal));
|
||||
@@ -273,11 +273,11 @@ public class DerivedLoanDataProcessorTest {
|
||||
assertThat(periodData.getInterestOutstanding(), is(expectedInterestOutstanding));
|
||||
|
||||
// assert repayments are ok
|
||||
List<LoanRepaymentData> loanRepayments = derivedData.getLoanRepayments();
|
||||
List<LoanTransactionData> loanRepayments = derivedData.getLoanRepayments();
|
||||
assertThat(loanRepayments, is(notNullValue()));
|
||||
assertThat(loanRepayments.size(), is(1));
|
||||
|
||||
LoanRepaymentData firstRepayment = loanRepayments.get(0);
|
||||
LoanTransactionData firstRepayment = loanRepayments.get(0);
|
||||
assertThat(firstRepayment.getPrincipal(), is(expectedPrincipalPaid));
|
||||
assertThat(firstRepayment.getInterest(), is(expectedInterestPaid));
|
||||
assertThat(firstRepayment.getTotal(), is(expectedTotal));
|
||||
@@ -359,11 +359,11 @@ public class DerivedLoanDataProcessorTest {
|
||||
assertThat(secondPeriod.getInterestOutstanding(), is(expectedInterestOutstanding));
|
||||
|
||||
// assert repayments are ok
|
||||
List<LoanRepaymentData> loanRepayments = derivedData.getLoanRepayments();
|
||||
List<LoanTransactionData> loanRepayments = derivedData.getLoanRepayments();
|
||||
assertThat(loanRepayments, is(notNullValue()));
|
||||
assertThat(loanRepayments.size(), is(1));
|
||||
|
||||
LoanRepaymentData firstRepayment = loanRepayments.get(0);
|
||||
LoanTransactionData firstRepayment = loanRepayments.get(0);
|
||||
assertThat(firstRepayment.getPrincipal(), is(moneyDataFrom(new MoneyBuilder().with(cfaCurrency).with("1180").build())));
|
||||
assertThat(firstRepayment.getInterest(), is(moneyDataFrom(new MoneyBuilder().with(cfaCurrency).with("20").build())));
|
||||
assertThat(firstRepayment.getTotal(), is(moneyDataFrom(new MoneyBuilder().with(cfaCurrency).with("1200").build())));
|
||||
|
||||
Reference in New Issue
Block a user