You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by na...@apache.org on 2016/08/01 13:39:28 UTC
[4/5] incubator-fineract git commit: FINERACT-202 : enabling the
option for multi reshedule
FINERACT-202 : enabling the option for multi reshedule
Project: http://git-wip-us.apache.org/repos/asf/incubator-fineract/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-fineract/commit/fe617123
Tree: http://git-wip-us.apache.org/repos/asf/incubator-fineract/tree/fe617123
Diff: http://git-wip-us.apache.org/repos/asf/incubator-fineract/diff/fe617123
Branch: refs/heads/develop
Commit: fe6171237e09cb1f347dc6577800ca4c665e361e
Parents: ada9ced
Author: venkatconflux <ve...@confluxtechnologies.com>
Authored: Fri Jul 29 18:22:46 2016 +0530
Committer: venkatconflux <ve...@confluxtechnologies.com>
Committed: Mon Aug 1 17:07:34 2016 +0530
----------------------------------------------------------------------
api-docs/apiLive.htm | 90 ++-
.../LoanRescheduleRequestTest.java | 2 +-
.../data/LoanTermVariationsData.java | 6 +-
.../data/LoanTermVariationsDataWrapper.java | 78 +-
.../portfolio/loanaccount/domain/Loan.java | 55 +-
.../domain/LoanAccountDomainService.java | 2 +
.../domain/LoanAccountDomainServiceJpa.java | 23 +-
.../LoanRepaymentScheduleInstallment.java | 6 +
...RescheduleRequestToTermVariationMapping.java | 53 ++
.../domain/LoanTermVariationType.java | 34 +-
.../loanaccount/domain/LoanTermVariations.java | 43 +-
.../loanaccount/domain/LoanTransaction.java | 6 +
.../domain/AbstractLoanScheduleGenerator.java | 750 ++++++++-----------
...ingBalanceInterestLoanScheduleGenerator.java | 6 +-
.../FlatInterestLoanScheduleGenerator.java | 8 +-
.../domain/LoanApplicationTerms.java | 217 +++++-
.../domain/LoanScheduleGenerator.java | 25 +-
.../service/LoanScheduleAssembler.java | 20 +-
...nScheduleCalculationPlatformServiceImpl.java | 8 +-
.../api/RescheduleLoansApiResource.java | 22 +-
.../data/LoanRescheduleRequestData.java | 71 +-
.../LoanRescheduleRequestDataValidator.java | 31 +-
.../domain/DefaultLoanReschedulerFactory.java | 62 --
.../domain/LoanRescheduleRequest.java | 244 +++---
.../domain/LoanReschedulerFactory.java | 37 -
.../LoanReschedulePreviewPlatformService.java | 4 +-
...oanReschedulePreviewPlatformServiceImpl.java | 187 +++--
...escheduleRequestReadPlatformServiceImpl.java | 71 +-
...scheduleRequestWritePlatformServiceImpl.java | 488 ++++++------
.../loanproduct/service/LoanEnumerations.java | 16 +
.../core_db/V313__multi_rescheduling_script.sql | 141 ++++
31 files changed, 1496 insertions(+), 1310 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/api-docs/apiLive.htm
----------------------------------------------------------------------
diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm
index 696e066..7fe3fc9 100644
--- a/api-docs/apiLive.htm
+++ b/api-docs/apiLive.htm
@@ -11877,11 +11877,11 @@ Content-Type: application/json Request Body:
{
"loanId": 1,
"graceOnPrincipal": 2,
- "rescheduleFromDate": "04 December 2014",
- "adjustedDueDate": "20 December 2014",
+ "rescheduleFromDate": "25 December 2013",
+ "adjustedDueDate": "31 December 2013",
"dateFormat": "dd MMMM yyyy",
"locale": "en",
- "submittedOnDate": "04 September 2014",
+ "submittedOnDate": "04 September 2013",
"rescheduleReasonComment" : "Client has gone AWOL",
"rescheduleReasonId": 1
}
@@ -11907,52 +11907,80 @@ GET https://DomainName/api/v1/rescheduleloans/{requestId}
</code>
<code class="method-response">
{
- "id": 2,
- "loanId": 17,
- "clientId": 4,
- "clientName": "Fernando Michael Torres",
- "loanAccountNumber": "000000017",
+ "id": 1,
+ "loanId": 1,
+ "clientId": 1,
+ "clientName": "test test",
+ "loanAccountNumber": "000000001",
"statusEnum": {
- "id": 500,
- "code": "loanStatusType.rejected",
- "value": "Rejected",
- "pendingApproval": false,
+ "id": 100,
+ "code": "loanStatusType.submitted.and.pending.approval",
+ "value": "Submitted and pending approval",
+ "pendingApproval": true,
"approved": false,
- "rejected": true
+ "rejected": false
},
"rescheduleFromInstallment": 5,
- "graceOnPrincipal": 3,
"rescheduleFromDate": [
2013,
12,
- 6
+ 25
],
"recalculateInterest": false,
"rescheduleReasonCodeValue": {
- "id": 239,
- "name": "client cannot pay on time"
+ "id": 1,
+ "name": "Passport",
+ "isActive": false
},
"timeline": {
"submittedOnDate": [
- 2014,
- 8,
+ 2013,
+ 9,
4
],
"submittedByUsername": "mifos",
"submittedByFirstname": "App",
- "submittedByLastname": "Administrator",
- "rejectedOnDate": [
- 2014,
- 8,
- 5
- ],
- "rejectedByUsername": "mifos",
- "rejectedByFirstname": "App",
- "rejectedByLastname": "Administrator"
+ "submittedByLastname": "Administrator"
},
- "rescheduleReasonComment": ""
-}
- </code>
+ "rescheduleReasonComment": "Client has gone AWOL",
+ "loanTermVariationsData": [
+ {
+ "id": 13,
+ "termType": {
+ "id": 4,
+ "code": "loanTermType.dueDate",
+ "value": "dueDate"
+ },
+ "termVariationApplicableFrom": [
+ 2013,
+ 12,
+ 25
+ ],
+ "dateValue": [
+ 2013,
+ 12,
+ 31
+ ],
+ "isSpecificToInstallment": false
+ },
+ {
+ "id": 14,
+ "termType": {
+ "id": 8,
+ "code": "loanTermType.graceOnPrincipal",
+ "value": "graceOnPrincipal"
+ },
+ "termVariationApplicableFrom": [
+ 2013,
+ 12,
+ 25
+ ],
+ "decimalValue": 2,
+ "isSpecificToInstallment": false
+ }
+ ]
+}
+</code>
</div>
</div>
<a id="loan_reschedule_preview_retrieve" name="loan_reschedule_preview_retrieve" class="old-syle-anchor"> </a>
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
index 2b00a98..ae39433 100644
--- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
@@ -211,7 +211,7 @@ public class LoanRescheduleRequestTest {
final HashMap loanSummary = this.loanTransactionHelper.getLoanSummary(requestSpec, generalResponseSpec, loanId);
final Float totalExpectedRepayment = (Float) loanSummary.get("totalExpectedRepayment");
- assertEquals("NUMBER OF REPAYMENTS SHOULD BE 16, NOT 12", "16", numberOfRepayments.toString());
+ assertEquals("NUMBER OF REPAYMENTS SHOULD BE 16, NOT 12", "12", numberOfRepayments.toString());
assertEquals("TOTAL EXPECTED REPAYMENT MUST BE EQUAL TO 118000.0", "118000.0", totalExpectedRepayment.toString());
System.out.println("Successfully approved loan reschedule request (ID: " + this.loanRescheduleRequestId + ")");
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsData.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsData.java
index f5d2cc0..a19d3b1 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsData.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsData.java
@@ -29,7 +29,7 @@ public class LoanTermVariationsData implements Comparable<LoanTermVariationsData
@SuppressWarnings("unused")
private final Long id;
private final EnumOptionData termType;
- private final LocalDate termVariationApplicableFrom;
+ private LocalDate termVariationApplicableFrom;
private final BigDecimal decimalValue;
private final LocalDate dateValue;
private final boolean isSpecificToInstallment;
@@ -113,5 +113,9 @@ public class LoanTermVariationsData implements Comparable<LoanTermVariationsData
}
return comparsion;
}
+
+ public void setApplicableFromDate(final LocalDate applicableFromDate) {
+ this.termVariationApplicableFrom = applicableFromDate;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsDataWrapper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsDataWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsDataWrapper.java
index 65730e7..ea784e3 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsDataWrapper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsDataWrapper.java
@@ -22,37 +22,27 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
-
import org.joda.time.LocalDate;
public class LoanTermVariationsDataWrapper {
private final List<LoanTermVariationsData> exceptionData;
- private final ListIterator<LoanTermVariationsData> iterator;
+ private ListIterator<LoanTermVariationsData> iterator;
private final List<LoanTermVariationsData> interestRateChanges;
+ private final List<LoanTermVariationsData> interestRateFromInstallment;
private final List<LoanTermVariationsData> dueDateVariation;
- private final ListIterator<LoanTermVariationsData> dueDateIterator;
+ private ListIterator<LoanTermVariationsData> dueDateIterator;
public LoanTermVariationsDataWrapper(final List<LoanTermVariationsData> exceptionData) {
if (exceptionData == null) {
this.exceptionData = new ArrayList<>(1);
} else {
this.exceptionData = exceptionData;
- Collections.sort(this.exceptionData);
}
this.interestRateChanges = new ArrayList<>();
this.dueDateVariation = new ArrayList<>();
- for (LoanTermVariationsData loanTermVariationsData : this.exceptionData) {
- if (loanTermVariationsData.getTermVariationType().isInterestRateVariation()) {
- this.interestRateChanges.add(loanTermVariationsData);
- } else if (loanTermVariationsData.getTermVariationType().isDueDateVariation()) {
- this.dueDateVariation.add(loanTermVariationsData);
- }
- }
- this.exceptionData.removeAll(this.interestRateChanges);
- this.exceptionData.removeAll(this.dueDateVariation);
- iterator = this.exceptionData.listIterator();
- dueDateIterator = this.dueDateVariation.listIterator();
+ this.interestRateFromInstallment = new ArrayList<>();
+ deriveLoanTermVariations();
}
public boolean hasVariation(final LocalDate date) {
@@ -84,6 +74,10 @@ public class LoanTermVariationsDataWrapper {
public LoanTermVariationsData nextDueDateVariation() {
return this.dueDateIterator.next();
}
+
+ public LoanTermVariationsData previousDueDateVariation() {
+ return this.dueDateIterator.previous();
+ }
public List<LoanTermVariationsData> getInterestRateChanges() {
return this.interestRateChanges;
@@ -96,6 +90,23 @@ public class LoanTermVariationsDataWrapper {
public List<LoanTermVariationsData> getExceptionData() {
return this.exceptionData;
}
+
+ public void setExceptionData(final List<LoanTermVariationsData> exceptionData) {
+ clearTerms();
+ this.exceptionData.addAll(exceptionData);
+ deriveLoanTermVariations();
+ }
+
+ public void clearTerms() {
+ this.exceptionData.clear();
+ this.interestRateChanges.clear();
+ this.dueDateVariation.clear();
+ this.interestRateFromInstallment.clear();
+ }
+
+ public List<LoanTermVariationsData> getInterestRateFromInstallment() {
+ return this.interestRateFromInstallment;
+ }
public int adjustNumberOfRepayments() {
int repaymetsForAdjust = 0;
@@ -108,7 +119,7 @@ public class LoanTermVariationsDataWrapper {
}
return repaymetsForAdjust;
}
-
+
public LoanTermVariationsData fetchLoanTermDueDateVariationsData(final LocalDate onDate) {
LoanTermVariationsData data = null;
for (LoanTermVariationsData termVariationsData : this.dueDateVariation) {
@@ -125,4 +136,39 @@ public class LoanTermVariationsDataWrapper {
return hasNext(date, iterator);
}
+ public void updateLoanTermVariationsData(final List<LoanTermVariationsData> exceptionData){
+ if(this.exceptionData != null && exceptionData != null && exceptionData.size() > 0){
+ this.exceptionData.addAll(exceptionData);
+ deriveLoanTermVariations();
+ }
+ }
+
+ private void deriveLoanTermVariations() {
+ Collections.sort(this.exceptionData);
+ for (LoanTermVariationsData loanTermVariationsData : this.exceptionData) {
+ if (loanTermVariationsData.getTermVariationType().isInterestRateVariation()) {
+ this.interestRateChanges.add(loanTermVariationsData);
+ } else if (loanTermVariationsData.getTermVariationType().isDueDateVariation()) {
+ this.dueDateVariation.add(loanTermVariationsData);
+ } else if (loanTermVariationsData.getTermVariationType().isInterestRateFromInstallment()) {
+ this.interestRateFromInstallment.add(loanTermVariationsData);
+ }
+ }
+ Collections.sort(this.dueDateVariation);
+ this.exceptionData.removeAll(this.interestRateChanges);
+ this.exceptionData.removeAll(this.dueDateVariation);
+ this.exceptionData.removeAll(this.interestRateFromInstallment);
+ this.iterator = this.exceptionData.listIterator();
+ this.dueDateIterator = this.dueDateVariation.listIterator();
+ }
+
+ public void resetVariations(){
+
+ for (LoanTermVariationsData loanTermVariationsData : this.exceptionData) {
+ loanTermVariationsData.setProcessed(false);
+ }
+ this.iterator = this.exceptionData.listIterator();
+ this.dueDateIterator = this.dueDateVariation.listIterator();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index 5bd7a0b..adb516e 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -2734,6 +2734,8 @@ public class Loan extends AbstractPersistable<Long> {
final LoanStatus currentStatus = LoanStatus.fromInt(this.loanStatus);
final LoanStatus statusEnum = this.loanLifecycleStateMachine.transition(LoanEvent.LOAN_DISBURSAL_UNDO, currentStatus);
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_DISBURSAL_UNDO, getDisbursementDate());
+ existingTransactionIds.addAll(findExistingTransactionIds());
+ existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
if (!statusEnum.hasStateOf(currentStatus)) {
this.loanStatus = statusEnum.getValue();
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
@@ -2750,6 +2752,7 @@ public class Loan extends AbstractPersistable<Long> {
}
}
boolean isEmiAmountChanged = this.loanTermVariations.size() > 0;
+
updateLoanToPreDisbursalState();
if (isScheduleRegenerateRequired || isDisbursedAmountChanged || isEmiAmountChanged
|| this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
@@ -2760,14 +2763,14 @@ public class Loan extends AbstractPersistable<Long> {
if (isDisbursedAmountChanged) {
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
}
+ }else if(isPeriodicAccrualAccountingEnabledOnLoanProduct()){
+ for (final LoanRepaymentScheduleInstallment period : getRepaymentScheduleInstallments()) {
+ period.resetAccrualComponents();
+ }
}
actualChanges.put("actualDisbursementDate", "");
- existingTransactionIds.addAll(findExistingTransactionIds());
- existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
- this.accruedTill = null;
- reverseExistingTransactions();
updateLoanSummaryDerivedFields();
}
@@ -2776,14 +2779,22 @@ public class Loan extends AbstractPersistable<Long> {
}
private final void reverseExistingTransactions() {
-
+ Collection<LoanTransaction> retainTransactions = new ArrayList<>();
for (final LoanTransaction transaction : this.loanTransactions) {
transaction.reverse();
+ if(transaction.getId() != null){
+ retainTransactions.add(transaction);
+ }
}
+ this.loanTransactions.retainAll(retainTransactions);
+ isTransactionsListDirty = true ;
}
private void updateLoanToPreDisbursalState() {
this.actualDisbursementDate = null;
+
+ this.accruedTill = null;
+ reverseExistingTransactions();
for (final LoanCharge charge : charges()) {
if (charge.isOverdueInstallmentCharge()) {
@@ -2796,13 +2807,11 @@ public class Loan extends AbstractPersistable<Long> {
for (final LoanRepaymentScheduleInstallment currentInstallment : installments) {
currentInstallment.resetDerivedComponents();
}
- final List<LoanTermVariations> removeTerms = new ArrayList<>(this.loanTermVariations.size());
for (LoanTermVariations variations : this.loanTermVariations) {
if (variations.getOnLoanStatus().equals(LoanStatus.ACTIVE.getValue())) {
- removeTerms.add(variations);
+ variations.markAsInactive();
}
}
- this.loanTermVariations.removeAll(removeTerms);
final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper();
wrapper.reprocess(getCurrency(), getDisbursementDate(), getRepaymentScheduleInstallments(), charges());
@@ -5024,7 +5033,7 @@ public class Loan extends AbstractPersistable<Long> {
}
- private ChangedTransactionDetail processTransactions() {
+ public ChangedTransactionDetail processTransactions() {
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
.determineProcessor(this.transactionProcessingStrategy);
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
@@ -5292,9 +5301,8 @@ public class Loan extends AbstractPersistable<Long> {
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
.determineProcessor(this.transactionProcessingStrategy);
- return loanScheduleGenerator.rescheduleNextInstallments(mc, loanApplicationTerms, charges(), generatorDTO.getHolidayDetailDTO(),
- retreiveListOfTransactionsPostDisbursementExcludeAccruals(), loanRepaymentScheduleTransactionProcessor,
- getRepaymentScheduleInstallments(), generatorDTO.getRecalculateFrom());
+ return loanScheduleGenerator.rescheduleNextInstallments(mc, loanApplicationTerms, this, generatorDTO.getHolidayDetailDTO(),
+ loanRepaymentScheduleTransactionProcessor, generatorDTO.getRecalculateFrom());
}
public LoanRepaymentScheduleInstallment fetchPrepaymentDetail(final ScheduleGeneratorDTO scheduleGeneratorDTO, final LocalDate onDate) {
@@ -5310,9 +5318,8 @@ public class Loan extends AbstractPersistable<Long> {
final LoanScheduleGenerator loanScheduleGenerator = scheduleGeneratorDTO.getLoanScheduleFactory().create(interestMethod);
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
.determineProcessor(this.transactionProcessingStrategy);
- installment = loanScheduleGenerator.calculatePrepaymentAmount(getCurrency(), onDate, loanApplicationTerms, mc, charges(),
- scheduleGeneratorDTO.getHolidayDetailDTO(), retreiveListOfTransactionsPostDisbursementExcludeAccruals(),
- loanRepaymentScheduleTransactionProcessor, getRepaymentScheduleInstallments());
+ installment = loanScheduleGenerator.calculatePrepaymentAmount(getCurrency(), onDate, loanApplicationTerms, mc, this,
+ scheduleGeneratorDTO.getHolidayDetailDTO(), loanRepaymentScheduleTransactionProcessor);
} else {
installment = this.getTotalOutstandingOnLoan();
}
@@ -5377,10 +5384,12 @@ public class Loan extends AbstractPersistable<Long> {
return loanApplicationTerms;
}
- private BigDecimal constructLoanTermVariations(FloatingRateDTO floatingRateDTO, BigDecimal annualNominalInterestRate,
+ public BigDecimal constructLoanTermVariations(FloatingRateDTO floatingRateDTO, BigDecimal annualNominalInterestRate,
List<LoanTermVariationsData> loanTermVariations) {
for (LoanTermVariations variationTerms : this.loanTermVariations) {
- loanTermVariations.add(variationTerms.toData());
+ if(variationTerms.isActive()) {
+ loanTermVariations.add(variationTerms.toData());
+ }
}
annualNominalInterestRate = constructFloatingInterestRates(annualNominalInterestRate, floatingRateDTO, loanTermVariations);
return annualNominalInterestRate;
@@ -6332,4 +6341,16 @@ public class Loan extends AbstractPersistable<Long> {
return isForeClosure;
}
+ public Set<LoanTermVariations> getActiveLoanTermVariations() {
+ Set<LoanTermVariations> retData = new HashSet<>();
+ if(this.loanTermVariations != null && this.loanTermVariations.size() > 0){
+ for (LoanTermVariations loanTermVariations : this.loanTermVariations) {
+ if(loanTermVariations.isActive()){
+ retData.add(loanTermVariations);
+ }
+ }
+ }
+ return retData.size()>0?retData:null;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
index b1052c3..407a706 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
@@ -65,4 +65,6 @@ public interface LoanAccountDomainService {
* @param loan {@link Loan} object
*/
void disableStandingInstructionsLinkedToClosedLoan(Loan loan);
+
+ void recalculateAccruals(Loan loan, boolean isInterestCalcualtionHappened);
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
index a46b43f..f7b1a6b 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
@@ -447,15 +447,21 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
*/
@Override
public void recalculateAccruals(Loan loan) {
+ boolean isInterestCalcualtionHappened = loan.repaymentScheduleDetail().isInterestRecalculationEnabled();
+ recalculateAccruals(loan, isInterestCalcualtionHappened);
+ }
+
+ @Override
+ public void recalculateAccruals(Loan loan, boolean isInterestCalcualtionHappened) {
LocalDate accruedTill = loan.getAccruedTill();
+ if (!loan.isPeriodicAccrualAccountingEnabledOnLoanProduct() || !isInterestCalcualtionHappened
+ || accruedTill == null || loan.isNpa() || !loan.status().isActive()) { return; }
+
boolean isOrganisationDateEnabled = this.configurationDomainService.isOrganisationstartDateEnabled();
Date organisationStartDate = new Date();
if(isOrganisationDateEnabled){
organisationStartDate = this.configurationDomainService.retrieveOrganisationStartDate();
}
-
- if (!loan.isPeriodicAccrualAccountingEnabledOnLoanProduct() || !loan.repaymentScheduleDetail().isInterestRecalculationEnabled()
- || accruedTill == null || loan.isNpa() || !loan.status().isActive()) { return; }
Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas = new ArrayList<>();
List<LoanRepaymentScheduleInstallment> installments = loan.getRepaymentScheduleInstallments();
Long loanId = loan.getId();
@@ -697,17 +703,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
}
- private LoanRepaymentScheduleInstallment fetchLoanRepaymentScheduleInstallment(LocalDate fromDate, final Loan loan) {
- LoanRepaymentScheduleInstallment installment = null;
- for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : loan.getRepaymentScheduleInstallments()) {
- if (fromDate.equals(loanRepaymentScheduleInstallment.getFromDate())) {
- installment = loanRepaymentScheduleInstallment;
- break;
- }
- }
- return installment;
- }
-
private Map<BUSINESS_ENTITY, Object> constructEntityMap(final BUSINESS_ENTITY entityEvent, Object entity) {
Map<BUSINESS_ENTITY, Object> map = new HashMap<>(1);
map.put(entityEvent, entity);
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
index d95d741..c31d1ec 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
@@ -344,6 +344,12 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus
this.obligationsMet = false;
this.obligationsMetOnDate = null;
}
+
+ public void resetAccrualComponents() {
+ this.interestAccrued = null;
+ this.feeAccrued = null;
+ this.penaltyAccrued = null;
+ }
public Money payPenaltyChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRescheduleRequestToTermVariationMapping.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRescheduleRequestToTermVariationMapping.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRescheduleRequestToTermVariationMapping.java
new file mode 100644
index 0000000..af9a8e2
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRescheduleRequestToTermVariationMapping.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.fineract.portfolio.loanaccount.domain;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.springframework.data.jpa.domain.AbstractPersistable;
+
+@Entity
+@Table(name="m_loan_reschedule_request_term_variations_mapping")
+public class LoanRescheduleRequestToTermVariationMapping extends AbstractPersistable<Long> {
+
+
+ @ManyToOne(optional = false, cascade = CascadeType.PERSIST)
+ @JoinColumn(name = "loan_term_variations_id", nullable = false)
+ private LoanTermVariations loanTermVariations;
+
+ protected LoanRescheduleRequestToTermVariationMapping(){
+
+ }
+
+ private LoanRescheduleRequestToTermVariationMapping(final LoanTermVariations loanTermVariations) {
+ this.loanTermVariations = loanTermVariations;
+ }
+
+ public static LoanRescheduleRequestToTermVariationMapping createNew(final LoanTermVariations loanTermVariation) {
+ return new LoanRescheduleRequestToTermVariationMapping(loanTermVariation);
+ }
+
+ public LoanTermVariations getLoanTermVariations() {
+ return this.loanTermVariations;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariationType.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariationType.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariationType.java
index c0df3bb..0b12182 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariationType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariationType.java
@@ -26,7 +26,11 @@ public enum LoanTermVariationType {
PRINCIPAL_AMOUNT(3, "loanTermType.principalAmount"), //
DUE_DATE(4, "loanTermType.dueDate"), //
INSERT_INSTALLMENT(5, "loanTermType.insertInstallment"), //
- DELETE_INSTALLMENT(6, "loanTermType.deleteInstallment");
+ DELETE_INSTALLMENT(6, "loanTermType.deleteInstallment"),
+ GRACE_ON_INTEREST(7, "loanTermType.graceOnInterest"),
+ GRACE_ON_PRINCIPAL(8, "loanTermType.graceOnPrincipal"),
+ EXTEND_REPAYMENT_PERIOD(9, "loanTermType.extendRepaymentPeriod"),
+ INTEREST_RATE_FROM_INSTALLMENT(10, "loanTermType.interestRateFromInstallment");
private final Integer value;
private final String code;
@@ -66,6 +70,18 @@ public enum LoanTermVariationType {
case 6:
enumeration = LoanTermVariationType.DELETE_INSTALLMENT;
break;
+ case 7:
+ enumeration = LoanTermVariationType.GRACE_ON_INTEREST;
+ break;
+ case 8:
+ enumeration = LoanTermVariationType.GRACE_ON_PRINCIPAL;
+ break;
+ case 9:
+ enumeration = LoanTermVariationType.EXTEND_REPAYMENT_PERIOD;
+ break;
+ case 10:
+ enumeration = LoanTermVariationType.INTEREST_RATE_FROM_INSTALLMENT;
+ break;
}
return enumeration;
}
@@ -93,4 +109,20 @@ public enum LoanTermVariationType {
public boolean isDeleteInstallment() {
return this.value.equals(LoanTermVariationType.DELETE_INSTALLMENT.getValue());
}
+
+ public boolean isGraceOnInterest() {
+ return this.value.equals(LoanTermVariationType.GRACE_ON_INTEREST.getValue());
+ }
+
+ public boolean isGraceOnPrincipal() {
+ return this.value.equals(LoanTermVariationType.GRACE_ON_PRINCIPAL.getValue());
+ }
+
+ public boolean isExtendRepaymentPeriod() {
+ return this.value.equals(LoanTermVariationType.EXTEND_REPAYMENT_PERIOD.getValue());
+ }
+
+ public boolean isInterestRateFromInstallment() {
+ return this.value.equals(LoanTermVariationType.INTEREST_RATE_FROM_INSTALLMENT.getValue());
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java
index 01245b9..6dbadad 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java
@@ -23,12 +23,13 @@ import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
-
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
@@ -62,6 +63,13 @@ public class LoanTermVariations extends AbstractPersistable<Long> {
@Column(name = "applied_on_loan_status", nullable = false)
private Integer onLoanStatus;
+
+ @Column(name = "is_active", nullable = false)
+ private Boolean isActive;
+
+ @OneToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "parent_id")
+ private LoanTermVariations parent;
public LoanTermVariations(final Integer termType, final Date termApplicableFrom, final BigDecimal decimalValue, final Date dateValue,
final boolean isSpecificToInstallment, final Loan loan) {
@@ -72,6 +80,8 @@ public class LoanTermVariations extends AbstractPersistable<Long> {
this.dateValue = dateValue;
this.isSpecificToInstallment = isSpecificToInstallment;
this.onLoanStatus = loan.status().getValue();
+ this.isActive = true;
+ this.parent = null;
}
public LoanTermVariations(final Integer termType, final Date termApplicableFrom, final BigDecimal decimalValue, final Date dateValue,
@@ -83,6 +93,21 @@ public class LoanTermVariations extends AbstractPersistable<Long> {
this.dateValue = dateValue;
this.isSpecificToInstallment = isSpecificToInstallment;
this.onLoanStatus = loanStatus;
+ this.isActive = true;
+ this.parent = null;
+ }
+
+ public LoanTermVariations(final Integer termType, final Date termApplicableFrom, final BigDecimal decimalValue, final Date dateValue,
+ final boolean isSpecificToInstallment, final Loan loan, final Integer loanStatus, final Boolean isActive, final LoanTermVariations parent) {
+ this.loan = loan;
+ this.termApplicableFrom = termApplicableFrom;
+ this.termType = termType;
+ this.decimalValue = decimalValue;
+ this.dateValue = dateValue;
+ this.isSpecificToInstallment = isSpecificToInstallment;
+ this.onLoanStatus = loanStatus;
+ this.isActive = isActive;
+ this.parent = parent;
}
protected LoanTermVariations() {
@@ -135,5 +160,21 @@ public class LoanTermVariations extends AbstractPersistable<Long> {
public Integer getOnLoanStatus() {
return this.onLoanStatus;
}
+
+ public Boolean isActive() {
+ return this.isActive;
+ }
+
+ public LoanTermVariations parent() {
+ return this.parent;
+ }
+
+ public void updateIsActive(final Boolean isActive){
+ this.isActive = isActive;
+ }
+
+ public void markAsInactive() {
+ this.isActive = false;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/fe617123/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
index 414ca14..7b16a5c 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
@@ -777,4 +777,10 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
public boolean isAccrualTransaction() {
return isAccrual();
}
+
+ public boolean isPaymentTransaction() {
+ return this.isNotReversed()
+ && !(this.isDisbursement() || this.isAccrual() || this.isRepaymentAtDisbursement() || this.isNonMonetaryTransaction() || this
+ .isIncomePosting());
+ }
}
\ No newline at end of file