drop loan status table in favour of enum for now.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
ALTER TABLE `portfolio_loan` DROP FOREIGN KEY `FK7C885878B1147D1`;
|
||||
|
||||
ALTER TABLE `portfolio_loan` DROP INDEX `FK7C885878B1147D1`;
|
||||
|
||||
drop table `ref_loan_status`;
|
||||
|
||||
+2
-3
@@ -242,10 +242,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
"l.id as id, l.external_id as externalId,");
|
||||
loanAccountSummary
|
||||
.append("l.product_id as productId, lp.name as productName,")
|
||||
.append("l.loan_status_id as statusId, ls.display_name as statusName ")
|
||||
.append("l.loan_status_id as statusId ")
|
||||
.append("from portfolio_loan l ")
|
||||
.append("LEFT JOIN portfolio_product_loan AS lp ON lp.id = l.product_id ")
|
||||
.append("LEFT JOIN ref_loan_status AS ls ON ls.id = l.loan_status_id ");
|
||||
.append("LEFT JOIN portfolio_product_loan AS lp ON lp.id = l.product_id ");
|
||||
|
||||
return loanAccountSummary.toString();
|
||||
}
|
||||
|
||||
+36
-38
@@ -2,87 +2,86 @@ package org.mifosng.platform.loan.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultLoanLifecycleStateMachine implements
|
||||
LoanLifecycleStateMachine {
|
||||
public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachine {
|
||||
|
||||
private final List<LoanStatus> allowedLoanStatuses;
|
||||
private final List<LoanStatusEnum> allowedLoanStatuses;
|
||||
|
||||
public DefaultLoanLifecycleStateMachine(List<LoanStatus> allowedLoanStatuses) {
|
||||
public DefaultLoanLifecycleStateMachine(List<LoanStatusEnum> allowedLoanStatuses) {
|
||||
this.allowedLoanStatuses = allowedLoanStatuses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanStatus transition(LoanEvent loanEvent, LoanStatus from) {
|
||||
public LoanStatusEnum transition(LoanEvent loanEvent, LoanStatusEnum from) {
|
||||
|
||||
LoanStatus newState = null;
|
||||
LoanStatusEnum newState = null;
|
||||
|
||||
switch (loanEvent) {
|
||||
case LOAN_CREATED:
|
||||
if (from == null) {
|
||||
newState = stateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL,
|
||||
newState = stateOf(LoanStatusEnum.SUBMITED_AND_PENDING_APPROVAL,
|
||||
allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_REJECTED:
|
||||
if (from.hasStateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL)) {
|
||||
newState = stateOf(LoanStatus.REJECTED, allowedLoanStatuses);
|
||||
if (from.hasStateOf(LoanStatusEnum.SUBMITED_AND_PENDING_APPROVAL)) {
|
||||
newState = stateOf(LoanStatusEnum.REJECTED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_APPROVED:
|
||||
if (from.hasStateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL)) {
|
||||
newState = stateOf(LoanStatus.APPROVED, allowedLoanStatuses);
|
||||
if (from.hasStateOf(LoanStatusEnum.SUBMITED_AND_PENDING_APPROVAL)) {
|
||||
newState = stateOf(LoanStatusEnum.APPROVED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_WITHDRAWN:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.SUBMITED_AND_PENDING_APPROVAL, LoanStatus.APPROVED)) {
|
||||
newState = stateOf(LoanStatus.WITHDRAWN_BY_CLIENT, allowedLoanStatuses);
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatusEnum.SUBMITED_AND_PENDING_APPROVAL, LoanStatusEnum.APPROVED)) {
|
||||
newState = stateOf(LoanStatusEnum.WITHDRAWN_BY_CLIENT, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_DISBURSED:
|
||||
if (from.hasStateOf(LoanStatus.APPROVED)) {
|
||||
newState = stateOf(LoanStatus.ACTIVE, allowedLoanStatuses);
|
||||
if (from.hasStateOf(LoanStatusEnum.APPROVED)) {
|
||||
newState = stateOf(LoanStatusEnum.ACTIVE, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_APPROVAL_UNDO:
|
||||
if (from.hasStateOf(LoanStatus.APPROVED)) {
|
||||
newState = stateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL, allowedLoanStatuses);
|
||||
if (from.hasStateOf(LoanStatusEnum.APPROVED)) {
|
||||
newState = stateOf(LoanStatusEnum.SUBMITED_AND_PENDING_APPROVAL, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_DISBURSAL_UNDO:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.APPROVED, allowedLoanStatuses);
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatusEnum.ACTIVE)) {
|
||||
newState = stateOf(LoanStatusEnum.APPROVED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_REPAYMENT:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE, LoanStatus.CLOSED, LoanStatus.OVERPAID)) {
|
||||
newState = stateOf(LoanStatus.ACTIVE, allowedLoanStatuses);
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatusEnum.ACTIVE, LoanStatusEnum.CLOSED, LoanStatusEnum.OVERPAID)) {
|
||||
newState = stateOf(LoanStatusEnum.ACTIVE, allowedLoanStatuses);
|
||||
} else {
|
||||
newState = from;
|
||||
}
|
||||
break;
|
||||
case REPAID_IN_FULL:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.CLOSED, allowedLoanStatuses);
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatusEnum.ACTIVE)) {
|
||||
newState = stateOf(LoanStatusEnum.CLOSED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_WRITE_OFF:
|
||||
if (this.anyOfAllowedWhenComingFrom(from,LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.CLOSED, allowedLoanStatuses);
|
||||
if (this.anyOfAllowedWhenComingFrom(from,LoanStatusEnum.ACTIVE)) {
|
||||
newState = stateOf(LoanStatusEnum.CLOSED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_RESCHEDULE:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.CLOSED, allowedLoanStatuses);
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatusEnum.ACTIVE)) {
|
||||
newState = stateOf(LoanStatusEnum.CLOSED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case INTERST_REBATE_OWED:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED)) {
|
||||
newState = stateOf(LoanStatus.CLOSED, allowedLoanStatuses);
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatusEnum.CLOSED)) {
|
||||
newState = stateOf(LoanStatusEnum.CLOSED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_OVERPAYMENT:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.OVERPAID, allowedLoanStatuses);
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatusEnum.CLOSED, LoanStatusEnum.ACTIVE)) {
|
||||
newState = stateOf(LoanStatusEnum.OVERPAID, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -90,9 +89,9 @@ public class DefaultLoanLifecycleStateMachine implements
|
||||
return newState;
|
||||
}
|
||||
|
||||
private LoanStatus stateOf(Integer state, List<LoanStatus> allowedLoanStatuses) {
|
||||
LoanStatus match = null;
|
||||
for (LoanStatus loanStatus : allowedLoanStatuses) {
|
||||
private LoanStatusEnum stateOf(LoanStatusEnum state, List<LoanStatusEnum> allowedLoanStatuses) {
|
||||
LoanStatusEnum match = null;
|
||||
for (LoanStatusEnum loanStatus : allowedLoanStatuses) {
|
||||
if (loanStatus.hasStateOf(state)) {
|
||||
match = loanStatus;
|
||||
break;
|
||||
@@ -101,11 +100,11 @@ public class DefaultLoanLifecycleStateMachine implements
|
||||
return match;
|
||||
}
|
||||
|
||||
private boolean anyOfAllowedWhenComingFrom(final LoanStatus state,
|
||||
final Integer... allowedStates) {
|
||||
private boolean anyOfAllowedWhenComingFrom(final LoanStatusEnum state,
|
||||
final LoanStatusEnum... allowedStates) {
|
||||
boolean allowed = false;
|
||||
|
||||
for (Integer allowedState : allowedStates) {
|
||||
for (LoanStatusEnum allowedState : allowedStates) {
|
||||
if (state.hasStateOf(allowedState)) {
|
||||
allowed = true;
|
||||
break;
|
||||
@@ -114,5 +113,4 @@ public class DefaultLoanLifecycleStateMachine implements
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -72,9 +72,8 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
@Column(name = "term_period_frequency_enum", nullable = false)
|
||||
private PeriodFrequencyType termPeriodFrequencyType;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "loan_status_id", nullable = false)
|
||||
private LoanStatus loanStatus;
|
||||
@Column(name = "loan_status_id", nullable = false)
|
||||
private Integer loanStatus;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "submittedon_date")
|
||||
@@ -165,13 +164,17 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
public Loan(final Client client, Fund fund, LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct,
|
||||
final LoanProductRelatedDetail loanRepaymentScheduleDetail,
|
||||
final LoanStatus loanStatus) {
|
||||
final LoanStatusEnum loanStatus) {
|
||||
this.client = client;
|
||||
this.fund = fund;
|
||||
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
||||
this.loanProduct = loanProduct;
|
||||
this.loanRepaymentScheduleDetail = loanRepaymentScheduleDetail;
|
||||
this.loanStatus = loanStatus;
|
||||
if (loanStatus != null) {
|
||||
this.loanStatus = loanStatus.getValue();
|
||||
} else {
|
||||
this.loanStatus = null;
|
||||
}
|
||||
this.interestRebateOwed = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
@@ -200,7 +203,8 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
final LocalDate interestChargedFromDate,
|
||||
final LoanLifecycleStateMachine lifecycleStateMachine) {
|
||||
|
||||
this.loanStatus = lifecycleStateMachine.transition(LoanEvent.LOAN_CREATED, this.loanStatus);
|
||||
LoanStatusEnum statusEnum = lifecycleStateMachine.transition(LoanEvent.LOAN_CREATED, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.termFrequency = loanTermFrequency;
|
||||
this.termPeriodFrequencyType = loanTermFrequencyType;
|
||||
@@ -245,9 +249,9 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
public void reject(final LocalDate rejectedOn,
|
||||
LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(
|
||||
LoanEvent.LOAN_REJECTED, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REJECTED, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.rejectedOnDate = rejectedOn.toDateTimeAtCurrentTime().toDate();
|
||||
this.closedOnDate = rejectedOn.toDateTimeAtCurrentTime().toDate();
|
||||
|
||||
@@ -268,9 +272,9 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
public void withdraw(final LocalDate withdrawnOn,
|
||||
LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(
|
||||
LoanEvent.LOAN_WITHDRAWN, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_WITHDRAWN, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.withdrawnOnDate = withdrawnOn.toDateTimeAtCurrentTime().toDate();
|
||||
this.closedOnDate = withdrawnOn.toDateTimeAtCurrentTime().toDate();
|
||||
|
||||
@@ -290,8 +294,10 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
public void approve(final LocalDate approvedOn,
|
||||
LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(
|
||||
LoanEvent.LOAN_APPROVED, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_APPROVED, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.approvedOnDate = approvedOn.toDateTimeAtCurrentTime().toDate();
|
||||
|
||||
LocalDate submittalDate = new LocalDate(this.submittedOnDate);
|
||||
@@ -311,8 +317,10 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
}
|
||||
|
||||
public void undoApproval(LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(
|
||||
LoanEvent.LOAN_APPROVAL_UNDO, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_APPROVAL_UNDO, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.approvedOnDate = null;
|
||||
}
|
||||
|
||||
@@ -330,8 +338,10 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
public void disburse(final LocalDate disbursedOn,
|
||||
LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(
|
||||
LoanEvent.LOAN_DISBURSED, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_DISBURSED, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.disbursedOnDate = disbursedOn.toDateTimeAtCurrentTime().toDate();
|
||||
this.expectedMaturityDate = this.repaymentScheduleInstallments
|
||||
.get(this.repaymentScheduleInstallments.size() - 1)
|
||||
@@ -369,14 +379,19 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
public void undoDisbursal(
|
||||
LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(
|
||||
LoanEvent.LOAN_DISBURSAL_UNDO, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_DISBURSAL_UNDO, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.loanTransactions.clear();
|
||||
this.disbursedOnDate = null;
|
||||
}
|
||||
|
||||
public void waive(final LoanTransaction loanTransaction, final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
loanTransaction.updateLoan(this);
|
||||
this.loanTransactions.add(loanTransaction);
|
||||
|
||||
@@ -424,7 +439,10 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
private void handleRepaymentTransaction(
|
||||
final LoanTransaction loanTransaction,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final boolean adjusted) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
loanTransaction.updateLoan(this);
|
||||
|
||||
boolean isTransactionChronologicallyLatest = isChronologicallyLatestRepaymentOrWaiver(loanTransaction, this.loanTransactions);
|
||||
@@ -482,21 +500,29 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
}
|
||||
|
||||
private void handleLoanRepaymentInFull(final LoanTransaction loanTransaction, final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(LoanEvent.REPAID_IN_FULL, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.REPAID_IN_FULL, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.closedOnDate = loanTransaction.getTransactionDate().toDate();
|
||||
this.maturedOnDate = loanTransaction.getTransactionDate().toDate();
|
||||
|
||||
if (isInterestRebateAllowed()) {
|
||||
Money rebateDue = calculateRebateWhenPaidInFullOn(loanTransaction.getTransactionDate());
|
||||
if (rebateDue.isGreaterThanZero()) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(LoanEvent.INTERST_REBATE_OWED, this.loanStatus);
|
||||
statusEnum = loanLifecycleStateMachine.transition(LoanEvent.INTERST_REBATE_OWED, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.interestRebateOwed = rebateDue.getAmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleLoanOverpayment(@SuppressWarnings("unused") final LoanTransaction loanTransaction, final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(LoanEvent.LOAN_OVERPAYMENT, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_OVERPAYMENT, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.closedOnDate = null;
|
||||
this.maturedOnDate = null;
|
||||
}
|
||||
@@ -635,8 +661,10 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
public void writeOff(final DateTime writtenOffOn,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(
|
||||
LoanEvent.LOAN_WRITE_OFF, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_WRITE_OFF, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.closedOnDate = writtenOffOn.toDate();
|
||||
this.writtenOffOnDate = writtenOffOn.toDate();
|
||||
|
||||
@@ -658,8 +686,10 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
public void reschedule(final DateTime rescheduledOn,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
this.loanStatus = loanLifecycleStateMachine.transition(
|
||||
LoanEvent.LOAN_RESCHEDULE, this.loanStatus);
|
||||
|
||||
LoanStatusEnum statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_RESCHEDULE, LoanStatusEnum.fromInt(this.loanStatus));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
|
||||
this.closedOnDate = rescheduledOn.toDate();
|
||||
this.rescheduledOnDate = rescheduledOn.toDate();
|
||||
|
||||
@@ -682,13 +712,17 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
public boolean isNotSubmittedAndPendingApproval() {
|
||||
return !isSubmittedAndPendingApproval();
|
||||
}
|
||||
|
||||
private LoanStatusEnum status() {
|
||||
return LoanStatusEnum.fromInt(this.loanStatus);
|
||||
}
|
||||
|
||||
public boolean isSubmittedAndPendingApproval() {
|
||||
return this.loanStatus.isSubmittedAndPendingApproval();
|
||||
return status().isSubmittedAndPendingApproval();
|
||||
}
|
||||
|
||||
public boolean isApproved() {
|
||||
return this.loanStatus.isApproved();
|
||||
return status().isApproved();
|
||||
}
|
||||
|
||||
public boolean isNotApproved() {
|
||||
@@ -712,7 +746,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return this.loanStatus.isClosed() || this.isCancelled();
|
||||
return status().isClosed() || this.isCancelled();
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
@@ -720,11 +754,11 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
}
|
||||
|
||||
public boolean isWithdrawn() {
|
||||
return this.loanStatus.isWithdrawnByClient();
|
||||
return status().isWithdrawnByClient();
|
||||
}
|
||||
|
||||
public boolean isRejected() {
|
||||
return this.loanStatus.isRejected();
|
||||
return status().isRejected();
|
||||
}
|
||||
|
||||
public boolean isNotClosed() {
|
||||
@@ -732,7 +766,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return this.loanStatus.isActive();
|
||||
return status().isActive();
|
||||
}
|
||||
|
||||
public boolean isOpenWithNoRepaymentMade() {
|
||||
@@ -1031,10 +1065,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|| identifier.equalsIgnoreCase(this.getId().toString());
|
||||
}
|
||||
|
||||
public String getLoanStatusDisplayName() {
|
||||
return this.loanStatus.getDisplayName();
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
return this.loanRepaymentScheduleDetail.getCurrency();
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,6 +2,6 @@ package org.mifosng.platform.loan.domain;
|
||||
|
||||
public interface LoanLifecycleStateMachine {
|
||||
|
||||
LoanStatus transition(LoanEvent loanEvent, LoanStatus from);
|
||||
LoanStatusEnum transition(LoanEvent loanEvent, LoanStatusEnum from);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
package org.mifosng.platform.loan.domain;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.springframework.data.domain.Persistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "ref_loan_status")
|
||||
public class LoanStatus implements Persistable<Integer> {
|
||||
|
||||
public static final Integer SUBMITED_AND_PENDING_APPROVAL = 100;
|
||||
public static final Integer APPROVED = 200;
|
||||
public static final Integer ACTIVE = 300;
|
||||
public static final Integer WITHDRAWN_BY_CLIENT = 400;
|
||||
public static final Integer REJECTED = 500;
|
||||
public static final Integer CLOSED = 600;
|
||||
public static final Integer OVERPAID = 700;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Integer id;
|
||||
|
||||
@Column(name = "display_name")
|
||||
private String displayName;
|
||||
|
||||
public LoanStatus() {
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasStateOf(Integer state) {
|
||||
return this.id.equals(state);
|
||||
}
|
||||
|
||||
public boolean isSubmittedAndPendingApproval() {
|
||||
return hasStateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL);
|
||||
}
|
||||
|
||||
public boolean isApproved() {
|
||||
return hasStateOf(LoanStatus.APPROVED);
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return hasStateOf(LoanStatus.CLOSED);
|
||||
}
|
||||
|
||||
public boolean isWithdrawnByClient() {
|
||||
return hasStateOf(LoanStatus.WITHDRAWN_BY_CLIENT);
|
||||
}
|
||||
|
||||
public boolean isRejected() {
|
||||
return hasStateOf(LoanStatus.REJECTED);
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return hasStateOf(LoanStatus.ACTIVE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package org.mifosng.platform.loan.domain;
|
||||
|
||||
public enum LoanStatusEnum {
|
||||
|
||||
INVALID(0, "loanStatusType.invalid"), //
|
||||
SUBMITED_AND_PENDING_APPROVAL(100, "loanStatusType.submitted.and.pending.approval"), //
|
||||
APPROVED(200, "loanStatusType.approved"), //
|
||||
ACTIVE(300, "loanStatusType.active"), //
|
||||
WITHDRAWN_BY_CLIENT(400, "loanStatusType.withdrawn.by.client"), //
|
||||
REJECTED(500, "loanStatusType.rejected"), //
|
||||
CLOSED(600, "loanStatusType.closed"), //
|
||||
OVERPAID(700, "loanStatusType.overpaid");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
public static LoanStatusEnum fromInt(final Integer selectedMethod) {
|
||||
|
||||
LoanStatusEnum enumeration = LoanStatusEnum.INVALID;
|
||||
switch (selectedMethod) {
|
||||
case 100:
|
||||
enumeration = LoanStatusEnum.SUBMITED_AND_PENDING_APPROVAL;
|
||||
break;
|
||||
case 200:
|
||||
enumeration = LoanStatusEnum.APPROVED;
|
||||
break;
|
||||
case 300:
|
||||
enumeration = LoanStatusEnum.ACTIVE;
|
||||
break;
|
||||
case 400:
|
||||
enumeration = LoanStatusEnum.WITHDRAWN_BY_CLIENT;
|
||||
break;
|
||||
case 500:
|
||||
enumeration = LoanStatusEnum.REJECTED;
|
||||
break;
|
||||
case 600:
|
||||
enumeration = LoanStatusEnum.CLOSED;
|
||||
break;
|
||||
case 700:
|
||||
enumeration = LoanStatusEnum.OVERPAID;
|
||||
break;
|
||||
}
|
||||
return enumeration;
|
||||
}
|
||||
|
||||
private LoanStatusEnum(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public boolean hasStateOf(final LoanStatusEnum state) {
|
||||
return this.value.equals(state.getValue());
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public boolean isSubmittedAndPendingApproval() {
|
||||
return this.value.equals(LoanStatusEnum.SUBMITED_AND_PENDING_APPROVAL.getValue());
|
||||
}
|
||||
|
||||
public boolean isApproved() {
|
||||
return this.value.equals(LoanStatusEnum.APPROVED.getValue());
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.value.equals(LoanStatusEnum.ACTIVE.getValue());
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return this.value.equals(LoanStatusEnum.CLOSED.getValue());
|
||||
}
|
||||
|
||||
public boolean isWithdrawnByClient() {
|
||||
return this.value.equals(LoanStatusEnum.WITHDRAWN_BY_CLIENT.getValue());
|
||||
}
|
||||
|
||||
public boolean isRejected() {
|
||||
return this.value.equals(LoanStatusEnum.REJECTED.getValue());
|
||||
}
|
||||
}
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
package org.mifosng.platform.loan.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface LoanStatusRepository extends JpaRepository<LoanStatus, Long>, JpaSpecificationExecutor<LoanStatus> {
|
||||
// no added behaviour
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.mifosng.platform.loan.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosng.platform.api.commands.SubmitLoanApplicationCommand;
|
||||
@@ -26,8 +27,7 @@ import org.mifosng.platform.loan.domain.LoanProduct;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.mifosng.platform.loan.domain.LoanStatus;
|
||||
import org.mifosng.platform.loan.domain.LoanStatusRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanStatusEnum;
|
||||
import org.mifosng.platform.loan.domain.LoanTransactionProcessingStrategy;
|
||||
import org.mifosng.platform.loan.domain.LoanTransactionProcessingStrategyRepository;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
@@ -38,7 +38,6 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class LoanAssembler {
|
||||
|
||||
private final LoanStatusRepository loanStatusRepository;
|
||||
private final LoanProductRepository loanProductRepository;
|
||||
private final ClientRepository clientRepository;
|
||||
private final AprCalculator aprCalculator = new AprCalculator();
|
||||
@@ -46,12 +45,11 @@ public class LoanAssembler {
|
||||
private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository;
|
||||
|
||||
@Autowired
|
||||
public LoanAssembler(final LoanStatusRepository loanStatusRepository,
|
||||
public LoanAssembler(
|
||||
final LoanProductRepository loanProductRepository,
|
||||
final ClientRepository clientRepository,
|
||||
final ClientRepository clientRepository,
|
||||
final FundRepository fundRepository,
|
||||
final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository) {
|
||||
this.loanStatusRepository = loanStatusRepository;
|
||||
this.loanProductRepository = loanProductRepository;
|
||||
this.clientRepository = clientRepository;
|
||||
this.fundRepository = fundRepository;
|
||||
@@ -123,7 +121,7 @@ public class LoanAssembler {
|
||||
}
|
||||
|
||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||
List<LoanStatus> allowedLoanStatuses = this.loanStatusRepository.findAll();
|
||||
List<LoanStatusEnum> allowedLoanStatuses = Arrays.asList(LoanStatusEnum.values());
|
||||
return new DefaultLoanLifecycleStateMachine(allowedLoanStatuses);
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -31,6 +31,7 @@ import org.mifosng.platform.infrastructure.JdbcSupport;
|
||||
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
|
||||
import org.mifosng.platform.loan.domain.Loan;
|
||||
import org.mifosng.platform.loan.domain.LoanRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanStatusEnum;
|
||||
import org.mifosng.platform.loan.domain.LoanTransaction;
|
||||
import org.mifosng.platform.loan.domain.LoanTransactionRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanTransactionType;
|
||||
@@ -411,12 +412,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
+ " l.nominal_interest_rate_per_period as interestRatePerPeriod, l.annual_nominal_interest_rate as annualInterestRate, "
|
||||
+ " l.repayment_period_frequency_enum as repaymentFrequencyType, l.interest_period_frequency_enum as interestRateFrequencyType, "
|
||||
+ " l.amortization_method_enum as amortizationType, l.interest_method_enum as interestType, l.interest_calculated_in_period_enum as interestCalculationPeriodType,"
|
||||
+ " l.loan_status_id as lifeCycleStatusId, st.display_name as lifeCycleStatusText, "
|
||||
+ " l.loan_status_id as lifeCycleStatusId, "
|
||||
+ " l.currency_code as currencyCode, l.currency_digits as currencyDigits, rc.`name` as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode"
|
||||
+ " from portfolio_loan l"
|
||||
+ " join portfolio_product_loan lp on lp.id = l.product_id"
|
||||
+ " join ref_currency rc on rc.`code` = l.currency_code"
|
||||
+ " join ref_loan_status st on st.id = l.loan_status_id"
|
||||
+ " left join org_fund f on f.id = l.fund_id";
|
||||
}
|
||||
|
||||
@@ -494,9 +494,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
EnumOptionData interestCalculationPeriodType = LoanEnumerations
|
||||
.interestCalculationPeriodType(interestCalculationPeriodTypeInt);
|
||||
|
||||
Integer lifeCycleStatusId = JdbcSupport.getInteger(rs,
|
||||
"lifeCycleStatusId");
|
||||
String lifeCycleStatusText = rs.getString("lifeCycleStatusText");
|
||||
Integer lifeCycleStatusId = JdbcSupport.getInteger(rs, "lifeCycleStatusId");
|
||||
String lifeCycleStatusText = LoanStatusEnum.fromInt(lifeCycleStatusId).getCode();
|
||||
|
||||
LocalDate lifeCycleStatusDate = submittedOnDate;
|
||||
if (approvedOnDate != null) {
|
||||
|
||||
+3
-6
@@ -2,6 +2,7 @@ package org.mifosng.platform.loan.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@@ -28,8 +29,7 @@ import org.mifosng.platform.loan.domain.Loan;
|
||||
import org.mifosng.platform.loan.domain.LoanLifecycleStateMachine;
|
||||
import org.mifosng.platform.loan.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.mifosng.platform.loan.domain.LoanRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanStatus;
|
||||
import org.mifosng.platform.loan.domain.LoanStatusRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanStatusEnum;
|
||||
import org.mifosng.platform.loan.domain.LoanTransaction;
|
||||
import org.mifosng.platform.loan.domain.LoanTransactionRepository;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
@@ -45,7 +45,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final LoanRepository loanRepository;
|
||||
private final LoanStatusRepository loanStatusRepository;
|
||||
private final NoteRepository noteRepository;
|
||||
private final CalculationPlatformService calculationPlatformService;
|
||||
private final LoanTransactionRepository loanTransactionRepository;
|
||||
@@ -54,13 +53,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Autowired
|
||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final LoanAssembler loanAssembler,
|
||||
final LoanRepository loanRepository, final LoanTransactionRepository loanTransactionRepository,
|
||||
final LoanStatusRepository loanStatusRepository,
|
||||
final NoteRepository noteRepository, final CalculationPlatformService calculationPlatformService) {
|
||||
this.context = context;
|
||||
this.loanAssembler = loanAssembler;
|
||||
this.loanRepository = loanRepository;
|
||||
this.loanTransactionRepository = loanTransactionRepository;
|
||||
this.loanStatusRepository = loanStatusRepository;
|
||||
this.noteRepository = noteRepository;
|
||||
this.calculationPlatformService = calculationPlatformService;
|
||||
}
|
||||
@@ -70,7 +67,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
|
||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||
List<LoanStatus> allowedLoanStatuses = this.loanStatusRepository.findAll();
|
||||
List<LoanStatusEnum> allowedLoanStatuses = Arrays.asList(LoanStatusEnum.values());
|
||||
return new DefaultLoanLifecycleStateMachine(allowedLoanStatuses);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user