Merge pull request #1082 from pramodn02/develop
interest recalculation test cases + fixes
This commit is contained in:
+167
-38
@@ -29,6 +29,7 @@ import org.mifosplatform.integrationtests.common.accounting.Account;
|
|||||||
import org.mifosplatform.integrationtests.common.accounting.AccountHelper;
|
import org.mifosplatform.integrationtests.common.accounting.AccountHelper;
|
||||||
import org.mifosplatform.integrationtests.common.accounting.JournalEntry;
|
import org.mifosplatform.integrationtests.common.accounting.JournalEntry;
|
||||||
import org.mifosplatform.integrationtests.common.accounting.JournalEntryHelper;
|
import org.mifosplatform.integrationtests.common.accounting.JournalEntryHelper;
|
||||||
|
import org.mifosplatform.integrationtests.common.accounting.PeriodicAccrualAccountingHelper;
|
||||||
import org.mifosplatform.integrationtests.common.charges.ChargesHelper;
|
import org.mifosplatform.integrationtests.common.charges.ChargesHelper;
|
||||||
import org.mifosplatform.integrationtests.common.loans.LoanApplicationTestBuilder;
|
import org.mifosplatform.integrationtests.common.loans.LoanApplicationTestBuilder;
|
||||||
import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
|
import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
|
||||||
@@ -66,6 +67,7 @@ public class ClientLoanIntegrationTest {
|
|||||||
private JournalEntryHelper journalEntryHelper;
|
private JournalEntryHelper journalEntryHelper;
|
||||||
private AccountHelper accountHelper;
|
private AccountHelper accountHelper;
|
||||||
private SchedulerJobHelper schedulerJobHelper;
|
private SchedulerJobHelper schedulerJobHelper;
|
||||||
|
private PeriodicAccrualAccountingHelper periodicAccrualAccountingHelper;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
@@ -3139,7 +3141,7 @@ public class ClientLoanIntegrationTest {
|
|||||||
final Integer loanProductID = createLoanProductWithInterestRecalculation(LoanProductTestBuilder.MIFOS_STANDARD_STRATEGY,
|
final Integer loanProductID = createLoanProductWithInterestRecalculation(LoanProductTestBuilder.MIFOS_STANDARD_STRATEGY,
|
||||||
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE,
|
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE,
|
||||||
LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_EMI_AMOUN,
|
LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_EMI_AMOUN,
|
||||||
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_SAME_AS_REPAYMENT_PERIOD, "0", null);
|
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_SAME_AS_REPAYMENT_PERIOD, "0", null,null);
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, LOAN_DISBURSEMENT_DATE, null,
|
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, LOAN_DISBURSEMENT_DATE, null,
|
||||||
LoanApplicationTestBuilder.MIFOS_STANDARD_STRATEGY, new ArrayList<HashMap>(0));
|
LoanApplicationTestBuilder.MIFOS_STANDARD_STRATEGY, new ArrayList<HashMap>(0));
|
||||||
@@ -3204,6 +3206,7 @@ public class ClientLoanIntegrationTest {
|
|||||||
addRepaymentValues(expectedvalues, todaysDate, 1, "1771.88", "16.39", "0.0", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, 1, "1771.88", "16.39", "0.0", "0.0");
|
||||||
addRepaymentValues(expectedvalues, todaysDate, 1, "1780.05", "8.22", "0.0", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, 1, "1780.05", "8.22", "0.0", "0.0");
|
||||||
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
||||||
|
|
||||||
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
|
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
|
||||||
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
|
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
|
||||||
todaysDate = Calendar.getInstance();
|
todaysDate = Calendar.getInstance();
|
||||||
@@ -3228,7 +3231,7 @@ public class ClientLoanIntegrationTest {
|
|||||||
final Integer loanProductID = createLoanProductWithInterestRecalculation(LoanProductTestBuilder.RBI_INDIA_STRATEGY,
|
final Integer loanProductID = createLoanProductWithInterestRecalculation(LoanProductTestBuilder.RBI_INDIA_STRATEGY,
|
||||||
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_INTEREST,
|
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_INTEREST,
|
||||||
LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS,
|
LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS,
|
||||||
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_DAILY, "1", LOAN_DISBURSEMENT_DATE);
|
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_DAILY, "1", LOAN_DISBURSEMENT_DATE,null);
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, LOAN_DISBURSEMENT_DATE,
|
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, LOAN_DISBURSEMENT_DATE,
|
||||||
LOAN_DISBURSEMENT_DATE, LoanApplicationTestBuilder.RBI_INDIA_STRATEGY, new ArrayList<HashMap>(0));
|
LOAN_DISBURSEMENT_DATE, LoanApplicationTestBuilder.RBI_INDIA_STRATEGY, new ArrayList<HashMap>(0));
|
||||||
@@ -3266,6 +3269,15 @@ public class ClientLoanIntegrationTest {
|
|||||||
|
|
||||||
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
||||||
|
|
||||||
|
loanSchedule = this.loanTransactionHelper.getLoanFutureRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
|
||||||
|
expectedvalues = new ArrayList<>();
|
||||||
|
todaysDate = Calendar.getInstance();
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 0, "4965.31", "92.51", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2505.67", "23.24", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2529.02", "11.67", "0.0", "0.0");
|
||||||
|
|
||||||
|
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues, 0);
|
||||||
|
|
||||||
todaysDate = Calendar.getInstance();
|
todaysDate = Calendar.getInstance();
|
||||||
todaysDate.add(Calendar.DAY_OF_MONTH, -7);
|
todaysDate.add(Calendar.DAY_OF_MONTH, -7);
|
||||||
final String LOAN_FIRST_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
|
final String LOAN_FIRST_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
|
||||||
@@ -3302,6 +3314,14 @@ public class ClientLoanIntegrationTest {
|
|||||||
addRepaymentValues(expectedvalues, todaysDate, 1, "1009.87", "4.66", "0.0", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, 1, "1009.87", "4.66", "0.0", "0.0");
|
||||||
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
||||||
|
|
||||||
|
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
|
||||||
|
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
|
||||||
|
todaysDate = Calendar.getInstance();
|
||||||
|
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
|
||||||
|
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, new Float(prepayAmount), loanID);
|
||||||
|
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
|
||||||
|
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -3313,6 +3333,7 @@ public class ClientLoanIntegrationTest {
|
|||||||
Calendar todaysDate = Calendar.getInstance();
|
Calendar todaysDate = Calendar.getInstance();
|
||||||
todaysDate.add(Calendar.DAY_OF_MONTH, -14);
|
todaysDate.add(Calendar.DAY_OF_MONTH, -14);
|
||||||
final String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
|
final String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
|
||||||
|
todaysDate.add(Calendar.DAY_OF_MONTH, -2);
|
||||||
final String REST_START_DATE = dateFormat.format(todaysDate.getTime());
|
final String REST_START_DATE = dateFormat.format(todaysDate.getTime());
|
||||||
|
|
||||||
todaysDate = Calendar.getInstance();
|
todaysDate = Calendar.getInstance();
|
||||||
@@ -3335,7 +3356,7 @@ public class ClientLoanIntegrationTest {
|
|||||||
final Integer loanProductID = createLoanProductWithInterestRecalculation(LoanProductTestBuilder.MIFOS_STANDARD_STRATEGY,
|
final Integer loanProductID = createLoanProductWithInterestRecalculation(LoanProductTestBuilder.MIFOS_STANDARD_STRATEGY,
|
||||||
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_INTEREST_AND_FEE,
|
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_INTEREST_AND_FEE,
|
||||||
LoanProductTestBuilder.RECALCULATION_STRATEGY_RESCHEDULE_NEXT_REPAYMENTS,
|
LoanProductTestBuilder.RECALCULATION_STRATEGY_RESCHEDULE_NEXT_REPAYMENTS,
|
||||||
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_WEEKLY, "1", REST_START_DATE);
|
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_WEEKLY, "1", REST_START_DATE,null);
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, LOAN_DISBURSEMENT_DATE,
|
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, LOAN_DISBURSEMENT_DATE,
|
||||||
REST_START_DATE, LoanApplicationTestBuilder.MIFOS_STANDARD_STRATEGY, charges);
|
REST_START_DATE, LoanApplicationTestBuilder.MIFOS_STANDARD_STRATEGY, charges);
|
||||||
@@ -3366,9 +3387,9 @@ public class ClientLoanIntegrationTest {
|
|||||||
expectedvalues = new ArrayList<>();
|
expectedvalues = new ArrayList<>();
|
||||||
todaysDate = Calendar.getInstance();
|
todaysDate = Calendar.getInstance();
|
||||||
addRepaymentValues(expectedvalues, todaysDate, -1, "2482.76", "46.15", "100.0", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, -1, "2482.76", "46.15", "100.0", "0.0");
|
||||||
addRepaymentValues(expectedvalues, todaysDate, 1, "2482.09", "46.82", "0.0", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2490.75", "38.16", "0.0", "0.0");
|
||||||
addRepaymentValues(expectedvalues, todaysDate, 1, "2505.67", "23.24", "12.79", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2505.71", "23.2", "11.91", "0.0");
|
||||||
addRepaymentValues(expectedvalues, todaysDate, 1, "2529.48", "11.67", "0.0", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2520.78", "11.63", "0.0", "0.0");
|
||||||
|
|
||||||
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
||||||
|
|
||||||
@@ -3397,9 +3418,9 @@ public class ClientLoanIntegrationTest {
|
|||||||
expectedvalues = new ArrayList<>();
|
expectedvalues = new ArrayList<>();
|
||||||
todaysDate = Calendar.getInstance();
|
todaysDate = Calendar.getInstance();
|
||||||
addRepaymentValues(expectedvalues, todaysDate, -1, "2482.76", "46.15", "100.0", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, -1, "2482.76", "46.15", "100.0", "0.0");
|
||||||
addRepaymentValues(expectedvalues, todaysDate, 1, "5065.31", "34.69", "0.0", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, 1, "5100", "27.96", "0.0", "0.0");
|
||||||
addRepaymentValues(expectedvalues, todaysDate, 1, "0", "11.32", "10.35", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, 1, "0", "11.16", "9.64", "0.0");
|
||||||
addRepaymentValues(expectedvalues, todaysDate, 1, "2451.93", "11.32", "0.0", "0.0");
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2417.24", "11.16", "0.0", "0.0");
|
||||||
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
||||||
|
|
||||||
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
|
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
|
||||||
@@ -3412,7 +3433,107 @@ public class ClientLoanIntegrationTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addRepaymentValues(List<Map<String, Object>> expectedvalues, Calendar todaysDate, int addMonths, String principalDue,
|
@Test
|
||||||
|
public void testLoanScheduleWithInterestRecalculation_WITH_PERIODIC_ACCOUNTING() {
|
||||||
|
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
|
||||||
|
this.periodicAccrualAccountingHelper = new PeriodicAccrualAccountingHelper(this.requestSpec, this.responseSpec);
|
||||||
|
this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec);
|
||||||
|
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
|
||||||
|
|
||||||
|
final Account assetAccount = this.accountHelper.createAssetAccount();
|
||||||
|
final Account incomeAccount = this.accountHelper.createIncomeAccount();
|
||||||
|
final Account expenseAccount = this.accountHelper.createExpenseAccount();
|
||||||
|
final Account overpaymentAccount = this.accountHelper.createLiabilityAccount();
|
||||||
|
|
||||||
|
Calendar todaysDate = Calendar.getInstance();
|
||||||
|
todaysDate.add(Calendar.DAY_OF_MONTH, -14);
|
||||||
|
final String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
|
||||||
|
|
||||||
|
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
|
||||||
|
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
|
||||||
|
Account[] accounts = { assetAccount, incomeAccount, expenseAccount, overpaymentAccount };
|
||||||
|
final Integer loanProductID = createLoanProductWithInterestRecalculation(LoanProductTestBuilder.MIFOS_STANDARD_STRATEGY,
|
||||||
|
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE,
|
||||||
|
LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_EMI_AMOUN,
|
||||||
|
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_SAME_AS_REPAYMENT_PERIOD, "0", null, accounts);
|
||||||
|
|
||||||
|
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, LOAN_DISBURSEMENT_DATE, null,
|
||||||
|
LoanApplicationTestBuilder.MIFOS_STANDARD_STRATEGY, new ArrayList<HashMap>(0));
|
||||||
|
|
||||||
|
Assert.assertNotNull(loanID);
|
||||||
|
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
|
||||||
|
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||||
|
|
||||||
|
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
|
||||||
|
List<Map<String, Object>> expectedvalues = new ArrayList<>();
|
||||||
|
todaysDate = Calendar.getInstance();
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, -1, "2482.76", "46.15", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2494.22", "34.69", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2505.73", "23.18", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2517.29", "11.62", "0.0", "0.0");
|
||||||
|
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
||||||
|
|
||||||
|
System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------");
|
||||||
|
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
|
||||||
|
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||||
|
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||||
|
|
||||||
|
System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------");
|
||||||
|
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID);
|
||||||
|
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||||
|
|
||||||
|
loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
|
||||||
|
expectedvalues = new ArrayList<>();
|
||||||
|
todaysDate = Calendar.getInstance();
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, -1, "2482.76", "46.15", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2482.76", "46.15", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2505.67", "23.24", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2528.81", "11.67", "0.0", "0.0");
|
||||||
|
|
||||||
|
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
||||||
|
|
||||||
|
final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(10000.0f, JournalEntry.TransactionType.CREDIT),
|
||||||
|
new JournalEntry(10000.0f, JournalEntry.TransactionType.DEBIT), };
|
||||||
|
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, LOAN_DISBURSEMENT_DATE, assetAccountInitialEntry);
|
||||||
|
todaysDate = Calendar.getInstance();
|
||||||
|
String runOndate = dateFormat.format(todaysDate.getTime());
|
||||||
|
this.periodicAccrualAccountingHelper.runPeriodicAccrualAccounting(runOndate);
|
||||||
|
this.loanTransactionHelper.checkAccrualTransactionForRepayment(LocalDate.now().minusDays(7), 46.15f, 0f, 0f, loanID);
|
||||||
|
this.loanTransactionHelper.checkAccrualTransactionForRepayment(LocalDate.now(), 46.15f, 0f, 0f, loanID);
|
||||||
|
|
||||||
|
todaysDate = Calendar.getInstance();
|
||||||
|
todaysDate.add(Calendar.DAY_OF_MONTH, -7);
|
||||||
|
final String LOAN_FIRST_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
|
||||||
|
Float totalDueForCurrentPeriod = (Float) loanSchedule.get(1).get("totalDueForPeriod");
|
||||||
|
this.loanTransactionHelper.makeRepayment(LOAN_FIRST_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
|
||||||
|
|
||||||
|
loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
|
||||||
|
expectedvalues = new ArrayList<>();
|
||||||
|
todaysDate = Calendar.getInstance();
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, -1, "2482.76", "46.15", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2494.22", "34.69", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2505.73", "23.18", "0.0", "0.0");
|
||||||
|
addRepaymentValues(expectedvalues, todaysDate, 1, "2517.29", "11.62", "0.0", "0.0");
|
||||||
|
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
|
||||||
|
|
||||||
|
this.loanTransactionHelper.checkAccrualTransactionForRepayment(LocalDate.now().minusDays(7), 46.15f, 0f, 0f, loanID);
|
||||||
|
this.loanTransactionHelper.checkAccrualTransactionForRepayment(LocalDate.now(), 34.69f, 0f, 0f, loanID);
|
||||||
|
|
||||||
|
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
|
||||||
|
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
|
||||||
|
todaysDate = Calendar.getInstance();
|
||||||
|
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
|
||||||
|
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, new Float(prepayAmount), loanID);
|
||||||
|
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
|
||||||
|
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
|
||||||
|
|
||||||
|
this.loanTransactionHelper.checkAccrualTransactionForRepayment(LocalDate.now().minusDays(7), 46.15f, 0f, 0f, loanID);
|
||||||
|
this.loanTransactionHelper.checkAccrualTransactionForRepayment(LocalDate.now(), 34.69f, 0f, 0f, loanID);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRepaymentValues(List<Map<String, Object>> expectedvalues, Calendar todaysDate, int addMonths, String principalDue,
|
||||||
String interestDue, String feeChargesDue, String penaltyChargesDue) {
|
String interestDue, String feeChargesDue, String penaltyChargesDue) {
|
||||||
Map<String, Object> values = new HashMap<>(3);
|
Map<String, Object> values = new HashMap<>(3);
|
||||||
values.put("dueDate", getDateAsArray(todaysDate, addMonths));
|
values.put("dueDate", getDateAsArray(todaysDate, addMonths));
|
||||||
@@ -3438,22 +3559,26 @@ public class ClientLoanIntegrationTest {
|
|||||||
private Integer createLoanProductWithInterestRecalculation(final String repaymentStrategy,
|
private Integer createLoanProductWithInterestRecalculation(final String repaymentStrategy,
|
||||||
final String interestRecalculationCompoundingMethod, final String rescheduleStrategyMethod,
|
final String interestRecalculationCompoundingMethod, final String rescheduleStrategyMethod,
|
||||||
final String recalculationRestFrequencyType, final String recalculationRestFrequencyInterval,
|
final String recalculationRestFrequencyType, final String recalculationRestFrequencyInterval,
|
||||||
final String recalculationRestFrequencyDate) {
|
final String recalculationRestFrequencyDate, final Account[] accounts) {
|
||||||
System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
|
System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
|
||||||
final String loanProductJSON = new LoanProductTestBuilder() //
|
LoanProductTestBuilder builder = new LoanProductTestBuilder()
|
||||||
.withPrincipal("10000000.00") //
|
.withPrincipal("10000000.00")
|
||||||
.withNumberOfRepayments("24") //
|
.withNumberOfRepayments("24")
|
||||||
.withRepaymentAfterEvery("1") //
|
.withRepaymentAfterEvery("1")
|
||||||
.withRepaymentTypeAsWeek() //
|
.withRepaymentTypeAsWeek()
|
||||||
.withinterestRatePerPeriod("2") //
|
.withinterestRatePerPeriod("2")
|
||||||
.withInterestRateFrequencyTypeAsMonths() //
|
.withInterestRateFrequencyTypeAsMonths()
|
||||||
.withRepaymentStrategy(repaymentStrategy) //
|
.withRepaymentStrategy(repaymentStrategy)
|
||||||
.withAmortizationTypeAsEqualPrincipalPayment() //
|
.withAmortizationTypeAsEqualPrincipalPayment()
|
||||||
.withInterestTypeAsDecliningBalance() //
|
.withInterestTypeAsDecliningBalance()
|
||||||
.withInterestRecalculationDetails(interestRecalculationCompoundingMethod, rescheduleStrategyMethod)//
|
.withInterestRecalculationDetails(interestRecalculationCompoundingMethod, rescheduleStrategyMethod)
|
||||||
.withInterestRecalculationRestFrequencyDetails(recalculationRestFrequencyType, recalculationRestFrequencyInterval,
|
.withInterestRecalculationRestFrequencyDetails(recalculationRestFrequencyType, recalculationRestFrequencyInterval,
|
||||||
recalculationRestFrequencyDate)//
|
recalculationRestFrequencyDate);
|
||||||
.build(null);
|
if (accounts != null) {
|
||||||
|
builder = builder.withAccountingRulePeriodicAccrual(accounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String loanProductJSON = builder.build(null);
|
||||||
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3481,20 +3606,24 @@ public class ClientLoanIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void verifyLoanRepaymentSchedule(final ArrayList<HashMap> loanSchedule, List<Map<String, Object>> expectedvalues) {
|
private void verifyLoanRepaymentSchedule(final ArrayList<HashMap> loanSchedule, List<Map<String, Object>> expectedvalues) {
|
||||||
System.out.println("--------------------VERIFYING THE PRINCIPAL DUES,INTEREST DUE AND DUE DATE--------------------------");
|
int index = 1;
|
||||||
int i = 1;
|
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues, index);
|
||||||
for (Map<String, Object> values : expectedvalues) {
|
|
||||||
assertEquals("Checking for Due Date for Month " + i, values.get("dueDate"), loanSchedule.get(i).get("dueDate"));
|
|
||||||
validateNumberForEqualWithMsg("Checking for Principal Due for Month " + i, String.valueOf(values.get("principalDue")),
|
|
||||||
String.valueOf(loanSchedule.get(i).get("principalDue")));
|
|
||||||
validateNumberForEqualWithMsg("Checking for Interest Due for Month " + i, String.valueOf(values.get("interestDue")),
|
|
||||||
String.valueOf(loanSchedule.get(i).get("interestDue")));
|
|
||||||
validateNumberForEqualWithMsg("Checking for Fee charge Due for Month " + i, String.valueOf(values.get("feeChargesDue")),
|
|
||||||
String.valueOf(loanSchedule.get(i).get("feeChargesDue")));
|
|
||||||
validateNumberForEqualWithMsg("Checking for Penalty charge Due for Month " + i,
|
|
||||||
String.valueOf(values.get("penaltyChargesDue")), String.valueOf(loanSchedule.get(i).get("penaltyChargesDue")));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void verifyLoanRepaymentSchedule(final ArrayList<HashMap> loanSchedule, List<Map<String, Object>> expectedvalues, int index) {
|
||||||
|
System.out.println("--------------------VERIFYING THE PRINCIPAL DUES,INTEREST DUE AND DUE DATE--------------------------");
|
||||||
|
for (Map<String, Object> values : expectedvalues) {
|
||||||
|
assertEquals("Checking for Due Date for installment " + index, values.get("dueDate"), loanSchedule.get(index).get("dueDate"));
|
||||||
|
validateNumberForEqualWithMsg("Checking for Principal Due for installment " + index,
|
||||||
|
String.valueOf(values.get("principalDue")), String.valueOf(loanSchedule.get(index).get("principalDue")));
|
||||||
|
validateNumberForEqualWithMsg("Checking for Interest Due for installment " + index, String.valueOf(values.get("interestDue")),
|
||||||
|
String.valueOf(loanSchedule.get(index).get("interestDue")));
|
||||||
|
validateNumberForEqualWithMsg("Checking for Fee charge Due for installment " + index,
|
||||||
|
String.valueOf(values.get("feeChargesDue")), String.valueOf(loanSchedule.get(index).get("feeChargesDue")));
|
||||||
|
validateNumberForEqualWithMsg("Checking for Penalty charge Due for installment " + index,
|
||||||
|
String.valueOf(values.get("penaltyChargesDue")), String.valueOf(loanSchedule.get(index).get("penaltyChargesDue")));
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -63,7 +63,7 @@ public class LoanTransactionHelper {
|
|||||||
|
|
||||||
public ArrayList getLoanFutureRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
public ArrayList getLoanFutureRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
final Integer loanID) {
|
final Integer loanID) {
|
||||||
final String URL = "/mifosng-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule&futureSchedule&" + Utils.TENANT_IDENTIFIER;
|
final String URL = "/mifosng-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule,futureSchedule&" + Utils.TENANT_IDENTIFIER;
|
||||||
final HashMap response = Utils.performServerGet(requestSpec, responseSpec, URL, "repaymentSchedule");
|
final HashMap response = Utils.performServerGet(requestSpec, responseSpec, URL, "repaymentSchedule");
|
||||||
return (ArrayList) response.get("futurePeriods");
|
return (ArrayList) response.get("futurePeriods");
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-2
@@ -444,6 +444,13 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
final LoanTransaction preCloseTransaction) {
|
final LoanTransaction preCloseTransaction) {
|
||||||
List<RecalculationDetail> earlypaymentDetail = new ArrayList<>();
|
List<RecalculationDetail> earlypaymentDetail = new ArrayList<>();
|
||||||
Money currentInstallmentOutstanding = installment.getTotalOutstanding(currency);
|
Money currentInstallmentOutstanding = installment.getTotalOutstanding(currency);
|
||||||
|
LocalDate maxTransactionDate = null;
|
||||||
|
Set<LocalDate> transaDates = recalculationDates.keySet();
|
||||||
|
for (LocalDate transactionDate : transaDates) {
|
||||||
|
if (maxTransactionDate == null || transactionDate.isAfter(maxTransactionDate)) {
|
||||||
|
maxTransactionDate = transactionDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (final LoanTransaction loanTransaction : transactionsPostDisbursement) {
|
for (final LoanTransaction loanTransaction : transactionsPostDisbursement) {
|
||||||
Money amountToProcess = null;
|
Money amountToProcess = null;
|
||||||
LocalDate transactionDate = loanTransaction.getTransactionDate();
|
LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
@@ -454,10 +461,14 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
if (newLoanTransaction.isRepayment() || newLoanTransaction.isInterestWaiver() || newLoanTransaction.isRecoveryRepayment()) {
|
if (newLoanTransaction.isRepayment() || newLoanTransaction.isInterestWaiver() || newLoanTransaction.isRecoveryRepayment()) {
|
||||||
newLoanTransaction.resetDerivedComponents();
|
newLoanTransaction.resetDerivedComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
Money unProcessed = processTransaction(newLoanTransaction, currency, installments, amountToProcess);
|
Money unProcessed = processTransaction(newLoanTransaction, currency, installments, amountToProcess);
|
||||||
if (transactionDate.isAfter(installment.getFromDate()) && transactionDate.isBefore(installment.getDueDate())) {
|
if (loanTransaction.getTransactionDate().isEqual(maxTransactionDate) && transactionDate.isAfter(installment.getFromDate())
|
||||||
|
&& transactionDate.isBefore(installment.getDueDate())) {
|
||||||
Money earlyPayment = currentInstallmentOutstanding.minus(installment.getTotalOutstanding(currency));
|
Money earlyPayment = currentInstallmentOutstanding.minus(installment.getTotalOutstanding(currency));
|
||||||
if (earlyPayment.isGreaterThanZero() && (newLoanTransaction.isRepayment() || newLoanTransaction.isInterestWaiver() || newLoanTransaction.isRecoveryRepayment())) {
|
if (earlyPayment.isGreaterThanZero()
|
||||||
|
&& (newLoanTransaction.isRepayment() || newLoanTransaction.isInterestWaiver() || newLoanTransaction
|
||||||
|
.isRecoveryRepayment())) {
|
||||||
earlypaymentDetail.add(new RecalculationDetail(false, transactionDate, null, earlyPayment, false));
|
earlypaymentDetail.add(new RecalculationDetail(false, transactionDate, null, earlyPayment, false));
|
||||||
}
|
}
|
||||||
currentInstallmentOutstanding = installment.getTotalOutstanding(currency);
|
currentInstallmentOutstanding = installment.getTotalOutstanding(currency);
|
||||||
|
|||||||
+16
-8
@@ -405,6 +405,10 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
outstandingBalance = outstandingBalance.zero();
|
outstandingBalance = outstandingBalance.zero();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fixedEmiAmount.isZero() && !recalculatedInterestComponent) {
|
||||||
|
fixedEmiAmount = principalForThisPeriod.plus(interestForThisinstallment);
|
||||||
|
}
|
||||||
reducePrincipal = reducePrincipal.minus(reducePrincipalForCurrentInstallment);
|
reducePrincipal = reducePrincipal.minus(reducePrincipalForCurrentInstallment);
|
||||||
|
|
||||||
if (principalForThisPeriod.isGreaterThan(reducePrincipalForCurrentInstallment)) {
|
if (principalForThisPeriod.isGreaterThan(reducePrincipalForCurrentInstallment)) {
|
||||||
@@ -436,10 +440,6 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
|
|
||||||
reducePrincipal = reducePrincipal.plus(reducePrincipalForCurrentInstallment);
|
reducePrincipal = reducePrincipal.plus(reducePrincipalForCurrentInstallment);
|
||||||
|
|
||||||
if (fixedEmiAmount.isZero() && !recalculatedInterestComponent) {
|
|
||||||
fixedEmiAmount = principalForThisPeriod.plus(interestForThisinstallment);
|
|
||||||
}
|
|
||||||
|
|
||||||
actualOutstandingbalance = actualOutstandingbalance.minus(reducePrincipal);
|
actualOutstandingbalance = actualOutstandingbalance.minus(reducePrincipal);
|
||||||
if (actualOutstandingbalance.isLessThanZero()) {
|
if (actualOutstandingbalance.isLessThanZero()) {
|
||||||
actualOutstandingbalance = actualOutstandingbalance.zero();
|
actualOutstandingbalance = actualOutstandingbalance.zero();
|
||||||
@@ -1292,9 +1292,13 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (installment.isRecalculatedInterestComponent() && installment.getPrincipal(currency).isGreaterThanZero()) {
|
/*
|
||||||
diffAmt.add(new RecalculationDetail(false, installment.getDueDate(), null, installment.getPrincipal(currency), false));
|
* if (installment.isRecalculatedInterestComponent() &&
|
||||||
}
|
* installment.getPrincipal(currency).isGreaterThanZero()) {
|
||||||
|
* diffAmt.add(new RecalculationDetail(false,
|
||||||
|
* installment.getDueDate(), null,
|
||||||
|
* installment.getPrincipal(currency), false)); }
|
||||||
|
*/
|
||||||
List<RecalculationDetail> earlypaymentDetail = loanRepaymentScheduleTransactionProcessor.handleRepaymentSchedule(
|
List<RecalculationDetail> earlypaymentDetail = loanRepaymentScheduleTransactionProcessor.handleRepaymentSchedule(
|
||||||
transactionsForInstallment, currency, processinstallmets, installment, recalculationDates, preCloseTransaction);
|
transactionsForInstallment, currency, processinstallmets, installment, recalculationDates, preCloseTransaction);
|
||||||
|
|
||||||
@@ -1648,18 +1652,22 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
List<LoanRepaymentScheduleInstallment> installments, MonetaryCurrency currency, final LoanApplicationTerms applicationTerms,
|
List<LoanRepaymentScheduleInstallment> installments, MonetaryCurrency currency, final LoanApplicationTerms applicationTerms,
|
||||||
MathContext mc, final Set<LoanCharge> loanCharges) {
|
MathContext mc, final Set<LoanCharge> loanCharges) {
|
||||||
LoanTransaction precloseTransaction = null;
|
LoanTransaction precloseTransaction = null;
|
||||||
|
Money collectedPrincipal = Money.zero(currency);
|
||||||
for (LoanTransaction loanTransaction : loanTransactions) {
|
for (LoanTransaction loanTransaction : loanTransactions) {
|
||||||
if (precloseTransaction == null
|
if (precloseTransaction == null
|
||||||
|| (!precloseTransaction.getTransactionDate().isAfter(loanTransaction.getTransactionDate()) && (loanTransaction.getId() == null || (precloseTransaction
|
|| (!precloseTransaction.getTransactionDate().isAfter(loanTransaction.getTransactionDate()) && (loanTransaction.getId() == null || (precloseTransaction
|
||||||
.getId() != null && loanTransaction.getId().compareTo(precloseTransaction.getId()) == 1)))) {
|
.getId() != null && loanTransaction.getId().compareTo(precloseTransaction.getId()) == 1)))) {
|
||||||
precloseTransaction = loanTransaction;
|
precloseTransaction = loanTransaction;
|
||||||
}
|
}
|
||||||
|
collectedPrincipal = collectedPrincipal.plus(loanTransaction.getPrincipalPortion());
|
||||||
}
|
}
|
||||||
if (precloseTransaction != null) {
|
if (precloseTransaction != null) {
|
||||||
LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = calculatePrepaymentAmount(installments, currency,
|
LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = calculatePrepaymentAmount(installments, currency,
|
||||||
precloseTransaction.getTransactionDate(), applicationTerms.getInterestChargedFromLocalDate(), applicationTerms, mc,
|
precloseTransaction.getTransactionDate(), applicationTerms.getInterestChargedFromLocalDate(), applicationTerms, mc,
|
||||||
loanCharges);
|
loanCharges);
|
||||||
if (precloseTransaction.getAmount(currency).isLessThan(loanRepaymentScheduleInstallment.getTotalOutstanding(currency))) {
|
Money pendingPrinciapl = applicationTerms.getPrincipal().minus(collectedPrincipal).plus(precloseTransaction.getPrincipalPortion());
|
||||||
|
if (pendingPrinciapl.isGreaterThan(loanRepaymentScheduleInstallment.getPrincipal(currency))
|
||||||
|
|| precloseTransaction.getAmount(currency).isLessThan(loanRepaymentScheduleInstallment.getTotalOutstanding(currency))) {
|
||||||
precloseTransaction = null;
|
precloseTransaction = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user