FINERACT-1946: Change the loan transaction ordering
This commit is contained in:
@@ -143,7 +143,7 @@ public class CommandSource extends AbstractPersistableCustom {
|
||||
this.subResourceId = subResourceId;
|
||||
this.commandAsJson = commandSerializedAsJson;
|
||||
this.maker = maker;
|
||||
this.madeOnDate = DateUtils.getOffsetDateTimeOfTenant();
|
||||
this.madeOnDate = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
this.status = status;
|
||||
this.idempotencyKey = idempotencyKey;
|
||||
}
|
||||
@@ -170,13 +170,13 @@ public class CommandSource extends AbstractPersistableCustom {
|
||||
|
||||
public void markAsChecked(final AppUser checker) {
|
||||
this.checker = checker;
|
||||
this.checkedOnDate = DateUtils.getOffsetDateTimeOfTenant();
|
||||
this.checkedOnDate = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
this.status = CommandProcessingResultType.PROCESSED.getValue();
|
||||
}
|
||||
|
||||
public void markAsRejected(final AppUser checker) {
|
||||
this.checker = checker;
|
||||
this.checkedOnDate = DateUtils.getOffsetDateTimeOfTenant();
|
||||
this.checkedOnDate = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
this.status = CommandProcessingResultType.REJECTED.getValue();
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -32,4 +32,5 @@
|
||||
<include relativeToChangelogFile="true" file="parts/0008_add_mappings.xml"/>
|
||||
<include relativeToChangelogFile="true" file="parts/0009_add_loan_ownership_transfer_events.xml"/>
|
||||
<include relativeToChangelogFile="true" file="parts/0010_external_transafer_status_external_transfer_id_constraints.xml"/>
|
||||
<include relativeToChangelogFile="true" file="parts/0011_set_datetime_precision.xml"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
|
||||
<changeSet author="fineract" id="1">
|
||||
<changeSet author="fineract" id="1" context="mysql">
|
||||
<addUniqueConstraint tableName="m_external_asset_owner_transfer" columnNames="status, external_id" constraintName="external_transfer_status_external_id"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
|
||||
<changeSet author="fineract" id="1" context="mysql">
|
||||
<modifyDataType tableName="m_external_asset_owner" columnName="created_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner" columnName="last_modified_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner_journal_entry_mapping" columnName="created_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner_journal_entry_mapping" columnName="last_modified_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner_transfer" columnName="created_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner_transfer" columnName="last_modified_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner_transfer_details" columnName="created_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner_transfer_details" columnName="last_modified_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner_transfer_journal_entry_mapping" columnName="created_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner_transfer_journal_entry_mapping" columnName="last_modified_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner_transfer_loan_mapping" columnName="created_on_utc" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="m_external_asset_owner_transfer_loan_mapping" columnName="last_modified_on_utc" newDataType="datetime(6)"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+1
-1
@@ -345,7 +345,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
private List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = new ArrayList<>();
|
||||
|
||||
@OrderBy(value = "dateOf, id")
|
||||
@OrderBy(value = "dateOf, createdDate, id")
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
private List<LoanTransaction> loanTransactions = new ArrayList<>();
|
||||
|
||||
|
||||
+1
-1
@@ -841,7 +841,7 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
}
|
||||
|
||||
public OffsetDateTime getCreatedDateTime() {
|
||||
return (this.getCreatedDate().isPresent() ? this.getCreatedDate().get() : DateUtils.getOffsetDateTimeOfTenant());
|
||||
return (this.getCreatedDate().isPresent() ? this.getCreatedDate().get() : DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
}
|
||||
|
||||
public boolean isLastTransaction(final LoanTransaction loanTransaction) {
|
||||
|
||||
+3
-2
@@ -175,7 +175,8 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
|
||||
BigDecimal runningBalance = calculateRunningBalance(entryData, runningBalanceMap);
|
||||
|
||||
params.add(new Object[] { Boolean.TRUE, runningBalance, officeRunningBalance,
|
||||
platformSecurityContext.authenticatedUser().getId(), DateUtils.getOffsetDateTimeOfTenant(), entryData.getId() });
|
||||
platformSecurityContext.authenticatedUser().getId(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(),
|
||||
entryData.getId() });
|
||||
batchIndex++;
|
||||
if (batchIndex == batchUpdateSize || index == entryDataList.size() - 1) {
|
||||
this.jdbcTemplate.batchUpdate(sql, params);
|
||||
@@ -212,7 +213,7 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
|
||||
for (JournalEntryData entryData : entryDataList) {
|
||||
BigDecimal runningBalance = calculateRunningBalance(entryData, runningBalanceMap);
|
||||
params.add(new Object[] { runningBalance, platformSecurityContext.authenticatedUser().getId(),
|
||||
DateUtils.getOffsetDateTimeOfTenant(), entryData.getId() });
|
||||
DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(), entryData.getId() });
|
||||
}
|
||||
this.jdbcTemplate.batchUpdate(sql, params);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public class LoanAccountLock {
|
||||
public LoanAccountLock(Long loanId, LockOwner lockOwner, LocalDate lockPlacedOnCobBusinessDate) {
|
||||
this.loanId = loanId;
|
||||
this.lockOwner = lockOwner;
|
||||
this.lockPlacedOn = DateUtils.getOffsetDateTimeOfTenant();
|
||||
this.lockPlacedOn = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
this.lockPlacedOnCobBusinessDate = lockPlacedOnCobBusinessDate;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,6 @@ public class LoanAccountLock {
|
||||
|
||||
public void setNewLockOwner(LockOwner newLockOwner) {
|
||||
this.lockOwner = newLockOwner;
|
||||
this.lockPlacedOn = DateUtils.getOffsetDateTimeOfTenant();
|
||||
this.lockPlacedOn = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ public class LoanLockingServiceImpl implements LoanLockingService {
|
||||
UPDATE m_loan_account_locks SET version= version + 1, lock_owner = ?, lock_placed_on = ? WHERE loan_id = ?
|
||||
""", accountsToLock, getInClauseParameterSizeLimit(), (ps, id) -> {
|
||||
ps.setString(1, lockOwner.name());
|
||||
ps.setObject(2, DateUtils.getOffsetDateTimeOfTenant());
|
||||
ps.setObject(2, DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
ps.setLong(3, id);
|
||||
});
|
||||
}
|
||||
@@ -97,7 +97,7 @@ public class LoanLockingServiceImpl implements LoanLockingService {
|
||||
ps.setLong(1, loanId);
|
||||
ps.setLong(2, 1);
|
||||
ps.setString(3, lockOwner.name());
|
||||
ps.setObject(4, DateUtils.getOffsetDateTimeOfTenant());
|
||||
ps.setObject(4, DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
ps.setObject(5, cobBusinessDate);
|
||||
});
|
||||
}
|
||||
|
||||
+3
-2
@@ -63,7 +63,7 @@ public class UpdateNpaTasklet implements Tasklet {
|
||||
resetNPASqlBuilder.append("set is_npa = false").append(", last_modified_by = ?, last_modified_on_utc = ? ").append(" FROM ")
|
||||
.append(fromPart).append(wherePart);
|
||||
}
|
||||
jdbcTemplate.update(resetNPASqlBuilder.toString(), user.getId(), DateUtils.getOffsetDateTimeOfTenant());
|
||||
jdbcTemplate.update(resetNPASqlBuilder.toString(), user.getId(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
|
||||
final StringBuilder updateSqlBuilder = new StringBuilder(900);
|
||||
|
||||
@@ -82,7 +82,8 @@ public class UpdateNpaTasklet implements Tasklet {
|
||||
.append(fromPart).append(wherePart);
|
||||
}
|
||||
|
||||
final int result = jdbcTemplate.update(updateSqlBuilder.toString(), user.getId(), DateUtils.getOffsetDateTimeOfTenant());
|
||||
final int result = jdbcTemplate.update(updateSqlBuilder.toString(), user.getId(),
|
||||
DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
|
||||
log.debug("{}: Records affected by updateNPA: {}", ThreadLocalContextUtil.getTenant().getName(), result);
|
||||
return RepeatStatus.FINISHED;
|
||||
|
||||
+2
-2
@@ -73,7 +73,7 @@ public class LoanScheduleHistoryWritePlatformServiceImpl implements LoanSchedule
|
||||
final BigDecimal penaltyCharges = repaymentScheduleInstallment.getPenaltyChargesCharged(currency).getAmount();
|
||||
|
||||
Map<String, Object> oldDates = null;
|
||||
OffsetDateTime createdOnDate = DateUtils.getOffsetDateTimeOfTenant();
|
||||
OffsetDateTime createdOnDate = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
LocalDateTime oldCreatedOnDate = null;
|
||||
LocalDateTime oldLastModifiedOnDate = null;
|
||||
if (repaymentScheduleInstallment.getCreatedDate().isPresent()) {
|
||||
@@ -89,7 +89,7 @@ public class LoanScheduleHistoryWritePlatformServiceImpl implements LoanSchedule
|
||||
final Long lastModifiedByUser = repaymentScheduleInstallment.getLastModifiedBy()
|
||||
.orElse(platformSecurityContext.authenticatedUser().getId());
|
||||
|
||||
OffsetDateTime lastModifiedOnDate = DateUtils.getOffsetDateTimeOfTenant();
|
||||
OffsetDateTime lastModifiedOnDate = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
if (repaymentScheduleInstallment.getLastModifiedDate().isPresent()) {
|
||||
lastModifiedOnDate = repaymentScheduleInstallment.getLastModifiedDate().get();
|
||||
} else if (repaymentScheduleInstallment.getId() != null && oldDates == null) {
|
||||
|
||||
+1
-1
@@ -318,7 +318,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
baseDataValidator.reset().parameter(LoanApiConstants.amortizationTypeParameterName).value(amortizationType).notNull()
|
||||
.inMinMaxRange(0, 1);
|
||||
|
||||
if (!amortizationType.equals(AmortizationMethod.EQUAL_PRINCIPAL.getValue()) && fixedPrincipalPercentagePerInstallment != null) {
|
||||
if (!AmortizationMethod.EQUAL_PRINCIPAL.getValue().equals(amortizationType) && fixedPrincipalPercentagePerInstallment != null) {
|
||||
baseDataValidator.reset().parameter(LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName).failWithCode(
|
||||
"not.supported.principal.fixing.not.allowed.with.equal.installments",
|
||||
"Principal fixing cannot be done with equal installment amortization");
|
||||
|
||||
+2
-2
@@ -271,7 +271,7 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
||||
this.jdbcTemplate.update(transactionSql, scheduleAccrualData.getLoanId(), scheduleAccrualData.getOfficeId(),
|
||||
externalIdFactory.create().getValue(), LoanTransactionType.ACCRUAL.getValue(), accruedTill, amount, interestPortion,
|
||||
feePortion, penaltyPortion, DateUtils.getBusinessLocalDate(), user.getId(), user.getId(),
|
||||
DateUtils.getOffsetDateTimeOfTenant(), DateUtils.getOffsetDateTimeOfTenant());
|
||||
DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
final Long transactionId = this.jdbcTemplate.queryForObject("SELECT " + sqlGenerator.lastInsertId(), Long.class); // NOSONAR
|
||||
|
||||
Map<LoanChargeData, BigDecimal> applicableCharges = scheduleAccrualData.getApplicableCharges();
|
||||
@@ -291,7 +291,7 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
||||
scheduleAccrualData.getRepaymentScheduleId());
|
||||
|
||||
String updateLoan = "UPDATE m_loan SET accrued_till=?, last_modified_by=?, last_modified_on_utc=? WHERE id=?";
|
||||
this.jdbcTemplate.update(updateLoan, accruedTill, user.getId(), DateUtils.getOffsetDateTimeOfTenant(),
|
||||
this.jdbcTemplate.update(updateLoan, accruedTill, user.getId(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(),
|
||||
scheduleAccrualData.getLoanId());
|
||||
|
||||
Optional<LoanTransaction> loanAccrualTransaction = loanTransactionRepository.findByIdAndLoanId(transactionId,
|
||||
|
||||
+2
-2
@@ -280,7 +280,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
* TODO Vishwas: Remove references to "Contra" from the codebase
|
||||
***/
|
||||
final String sql = "select " + rm.loanPaymentsSchema() + " where tr.loan_id = ? and tr.transaction_type_enum not in (0, 3) "
|
||||
+ " and (tr.is_reversed=false or tr.manually_adjusted_or_reversed = true) order by tr.transaction_date ASC,id ";
|
||||
+ " and (tr.is_reversed=false or tr.manually_adjusted_or_reversed = true) order by tr.transaction_date, tr.created_on_utc, tr.id ";
|
||||
Collection<LoanTransactionData> loanTransactionData = this.jdbcTemplate.query(sql, rm, loanId); // NOSONAR
|
||||
// TODO: would worth to rework in the future. It is not nice to fetch relations one by one... might worth to
|
||||
// give a try to get rid of native queries
|
||||
@@ -2140,7 +2140,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
final LoanTransactionDerivedComponentMapper rm = new LoanTransactionDerivedComponentMapper(sqlGenerator);
|
||||
|
||||
final String sql = "select " + rm.schema()
|
||||
+ " where tr.loan_id = ? and tr.transaction_type_enum = ? and tr.is_reversed=false order by tr.transaction_date ASC,id ";
|
||||
+ " where tr.loan_id = ? and tr.transaction_type_enum = ? and tr.is_reversed=false order by tr.transaction_date, tr.created_on_utc, tr.id ";
|
||||
return this.jdbcTemplate.query(sql, rm, loanId, LoanTransactionType.WAIVE_INTEREST.getValue()); // NOSONAR
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
return null;
|
||||
|
||||
+2
-2
@@ -493,8 +493,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
AppUser user = context.authenticatedUser();
|
||||
jdbcTemplate.update(transactionSql, loanId, loan.getOfficeId(), externalIdFactory.create().getValue(),
|
||||
LoanTransactionType.ACCRUAL.getValue(), actualDisbursementDate, loanCharge.amount(), loanCharge.amount(),
|
||||
DateUtils.getBusinessLocalDate(), user.getId(), user.getId(), DateUtils.getOffsetDateTimeOfTenant(),
|
||||
DateUtils.getOffsetDateTimeOfTenant());
|
||||
DateUtils.getBusinessLocalDate(), user.getId(), user.getId(),
|
||||
DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -120,8 +120,8 @@ public class SavingsSchedularInterestPoster {
|
||||
savingsAccountTransactionData.getId(), null, false, null, false,
|
||||
savingsAccountTransactionData.getTransactionDate(), JournalEntryType.CREDIT.getValue().longValue(),
|
||||
savingsAccountTransactionData.getAmount(), null, JournalEntryType.CREDIT.getValue().longValue(),
|
||||
savingsAccountData.getId(), DateUtils.getOffsetDateTimeOfTenant(),
|
||||
DateUtils.getOffsetDateTimeOfTenant(), false, BigDecimal.ZERO, BigDecimal.ZERO, null,
|
||||
savingsAccountData.getId(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(),
|
||||
DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(), false, BigDecimal.ZERO, BigDecimal.ZERO, null,
|
||||
savingsAccountTransactionData.getTransactionDate(), null, userId, userId,
|
||||
DateUtils.getBusinessLocalDate() });
|
||||
|
||||
@@ -131,8 +131,8 @@ public class SavingsSchedularInterestPoster {
|
||||
savingsAccountTransactionData.getId(), null, false, null, false,
|
||||
savingsAccountTransactionData.getTransactionDate(), JournalEntryType.DEBIT.getValue().longValue(),
|
||||
savingsAccountTransactionData.getAmount(), null, JournalEntryType.DEBIT.getValue().longValue(),
|
||||
savingsAccountData.getId(), DateUtils.getOffsetDateTimeOfTenant(),
|
||||
DateUtils.getOffsetDateTimeOfTenant(), false, BigDecimal.ZERO, BigDecimal.ZERO, null,
|
||||
savingsAccountData.getId(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(),
|
||||
DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(), false, BigDecimal.ZERO, BigDecimal.ZERO, null,
|
||||
savingsAccountTransactionData.getTransactionDate(), null, userId, userId,
|
||||
DateUtils.getBusinessLocalDate() });
|
||||
}
|
||||
|
||||
+1
@@ -30,4 +30,5 @@
|
||||
<include file="parts/0007_x_extend_tenant_ro_passwords.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0008_encrypt_existing_ro_tenant_passwords.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0009_set_and_encrypt_ro_if_not_exists.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0010_set_datetime_precision.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
<changeSet author="fineract" id="1" context="tenant_store_db">
|
||||
<modifyDataType tableName="tenants" columnName="created_date" newDataType="datetime(6)"/>
|
||||
<modifyDataType tableName="tenants" columnName="lastmodified_date" newDataType="datetime(6)"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -136,4 +136,5 @@
|
||||
<include file="parts/0114_create_cob_indices.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/0115_create_index_from_loan_transaction_id.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/0116_add_configuration_asset_externalization_of_non_active_loans.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/0117_set_datetime_precision.xml" relativeToChangelogFile="true" />
|
||||
</databaseChangeLog>
|
||||
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
|
||||
<changeSet author="fineract" id="1" context="mysql">
|
||||
<modifyDataType tableName="acc_gl_closure" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="acc_gl_closure" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="acc_gl_journal_entry" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="acc_gl_journal_entry" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="acc_gl_journal_entry" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="acc_gl_journal_entry" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="client_device_registration" columnName="updatedon_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="interop_identifier" columnName="created_on" newDataType="timestamp(6)" />
|
||||
<modifyDataType tableName="interop_identifier" columnName="modified_on" newDataType="timestamp(6)" />
|
||||
<modifyDataType tableName="job" columnName="create_time" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="job" columnName="previous_run_start_time" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="job" columnName="next_run_time" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="job_run_history" columnName="start_time" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="job_run_history" columnName="end_time" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_account_transfer_standing_instructions_history" columnName="execution_time" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_adhoc" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_adhoc" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_adhoc" columnName="last_run" newDataType="timestamp(6)" />
|
||||
<modifyDataType tableName="m_business_date" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_business_date" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_business_date" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_business_date" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_calendar" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_calendar" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_calendar" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_calendar" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_cashier_transactions" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_client" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_client" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_client_identifier" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_client_identifier" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_client_identifier" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_client_identifier" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_client_transaction" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_client_transaction" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_client_transaction" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_delinquency_bucket" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_delinquency_bucket" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_delinquency_bucket_mappings" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_delinquency_bucket_mappings" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_delinquency_range" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_delinquency_range" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_deposit_account_on_hold_transaction" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_floating_rates" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_floating_rates" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_floating_rates" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_floating_rates" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_floating_rates_periods" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_floating_rates_periods" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_floating_rates_periods" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_floating_rates_periods" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_hook" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_hook" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_import_document" columnName="import_time" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_import_document" columnName="end_time" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_account_locks" columnName="lock_placed_on" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_delinquency_tag_history" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_delinquency_tag_history" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_officer_assignment_history" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_officer_assignment_history" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_repayment_schedule" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_repayment_schedule" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_repayment_schedule" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_repayment_schedule" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_repayment_schedule_history" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_repayment_schedule_history" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_repayment_schedule_history" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_repayment_schedule_history" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_transaction" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_transaction" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_transaction" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_transaction_relation" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_loan_transaction_relation" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_mandatory_savings_schedule" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_mandatory_savings_schedule" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_note" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_note" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_note" columnName="created_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_note" columnName="last_modified_on_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_portfolio_command_source" columnName="made_on_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_portfolio_command_source" columnName="checked_on_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_portfolio_command_source" columnName="made_on_date_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_portfolio_command_source" columnName="checked_on_date_utc" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_provisioning_criteria" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_provisioning_criteria" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_rate" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_rate" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_report_mailing_job" columnName="start_datetime" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_report_mailing_job" columnName="previous_run_datetime" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_report_mailing_job" columnName="next_run_datetime" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_report_mailing_job_run_history" columnName="start_datetime" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_report_mailing_job_run_history" columnName="end_datetime" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_savings_officer_assignment_history" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_savings_officer_assignment_history" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_share_account" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_share_account" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_share_product" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_share_product" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_share_product_dividend_pay_out" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_share_product_dividend_pay_out" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_staff_assignment_history" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_staff_assignment_history" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_survey_scorecards" columnName="created_on" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_tax_component" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_tax_component" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_tax_component_history" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_tax_component_history" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_tax_group" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_tax_group" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_tax_group_mappings" columnName="created_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="m_tax_group_mappings" columnName="lastmodified_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="mix_taxonomy_mapping" columnName="last_update_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="notification_generator" columnName="created_at" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="notification_mapper" columnName="created_at" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="scheduled_email_campaign" columnName="next_trigger_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="scheduled_email_campaign" columnName="last_trigger_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="scheduled_email_campaign" columnName="recurrence_start_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="sms_campaign" columnName="next_trigger_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="sms_campaign" columnName="last_trigger_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="sms_campaign" columnName="recurrence_start_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="sms_messages_outbound" columnName="delivered_on_date" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="twofactor_access_token" columnName="valid_from" newDataType="datetime(6)" />
|
||||
<modifyDataType tableName="twofactor_access_token" columnName="valid_to" newDataType="datetime(6)" />
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+6430
-6291
File diff suppressed because it is too large
Load Diff
+100
-77
@@ -56,7 +56,6 @@ import org.apache.fineract.client.models.JournalEntryTransactionItem;
|
||||
import org.apache.fineract.client.models.PostClientsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||
import org.apache.fineract.client.models.PutJobsJobIDRequest;
|
||||
import org.apache.fineract.client.util.CallFailedRuntimeException;
|
||||
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
@@ -656,62 +655,68 @@ public class SchedulerJobsTestResults {
|
||||
|
||||
@Test
|
||||
public void testLoanCOBJobOutcome() {
|
||||
this.savingsAccountHelper = new SavingsAccountHelper(requestSpec, responseSpec);
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
|
||||
try {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
||||
this.savingsAccountHelper = new SavingsAccountHelper(requestSpec, responseSpec);
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
|
||||
|
||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec);
|
||||
Assertions.assertNotNull(clientID);
|
||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec);
|
||||
Assertions.assertNotNull(clientID);
|
||||
|
||||
Integer overdueFeeChargeId = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||
ChargesHelper.getLoanOverdueFeeJSONWithCalculationTypePercentage("1"));
|
||||
Assertions.assertNotNull(overdueFeeChargeId);
|
||||
Integer overdueFeeChargeId = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||
ChargesHelper.getLoanOverdueFeeJSONWithCalculationTypePercentage("1"));
|
||||
Assertions.assertNotNull(overdueFeeChargeId);
|
||||
|
||||
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "10", false));
|
||||
Assertions.assertNotNull(fee);
|
||||
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "10", false));
|
||||
Assertions.assertNotNull(fee);
|
||||
|
||||
final Integer loanProductID = createLoanProduct(overdueFeeChargeId.toString());
|
||||
Assertions.assertNotNull(loanProductID);
|
||||
List<Integer> loanIDs = new ArrayList<>();
|
||||
HashMap loanStatusHashMap;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
final Integer loanID = applyForLoanApplication(clientID.toString(), loanProductID.toString(), null, "10 January 2020");
|
||||
final Integer loanProductID = createLoanProduct(overdueFeeChargeId.toString());
|
||||
Assertions.assertNotNull(loanProductID);
|
||||
List<Integer> loanIDs = new ArrayList<>();
|
||||
HashMap loanStatusHashMap;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
final Integer loanID = applyForLoanApplication(clientID.toString(), loanProductID.toString(), null, "10 January 2020");
|
||||
|
||||
Assertions.assertNotNull(loanID);
|
||||
Assertions.assertNotNull(loanID);
|
||||
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
|
||||
loanStatusHashMap = this.loanTransactionHelper.approveLoan("01 March 2020", loanID);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
loanStatusHashMap = this.loanTransactionHelper.approveLoan("01 March 2020", loanID);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
|
||||
String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
|
||||
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 March 2020", loanID,
|
||||
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
|
||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||
loanIDs.add(loanID);
|
||||
String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
|
||||
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 March 2020", loanID,
|
||||
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
|
||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||
loanIDs.add(loanID);
|
||||
|
||||
this.loanTransactionHelper.addChargesForLoan(loanID,
|
||||
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee), "02 March 2020", "10", null));
|
||||
}
|
||||
this.loanTransactionHelper.addChargesForLoan(loanID,
|
||||
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee), "02 March 2020", "10", null));
|
||||
}
|
||||
|
||||
String jobName = "Loan COB";
|
||||
this.schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||
for (Integer loanId : loanIDs) {
|
||||
List<HashMap> repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec,
|
||||
loanId);
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 9, 2));
|
||||
String jobName = "Loan COB";
|
||||
this.schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||
for (Integer loanId : loanIDs) {
|
||||
List<HashMap> repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec,
|
||||
loanId);
|
||||
|
||||
Assertions.assertEquals(10.00f, (Float) repaymentScheduleDataAfter.get(1).get("feeChargesDue"),
|
||||
"Verifying From Fee Charges due for first Repayment after Successful completion of Scheduler Job");
|
||||
Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due for first Repayment after Successful completion of Scheduler Job");
|
||||
Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(2).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due for first Repayment after Successful completion of Scheduler Job");
|
||||
Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(3).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due for first Repayment after Successful completion of Scheduler Job");
|
||||
Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(4).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due for first Repayment after Successful completion of Scheduler Job");
|
||||
Assertions.assertEquals(10.00f, (Float) repaymentScheduleDataAfter.get(1).get("feeChargesDue"),
|
||||
"Verifying From Fee Charges due for first Repayment after Successful completion of Scheduler Job");
|
||||
Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due for first Repayment after Successful completion of Scheduler Job");
|
||||
Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(2).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due for first Repayment after Successful completion of Scheduler Job");
|
||||
Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(3).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due for first Repayment after Successful completion of Scheduler Job");
|
||||
Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(4).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due for first Repayment after Successful completion of Scheduler Job");
|
||||
|
||||
}
|
||||
} finally {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,7 +725,7 @@ public class SchedulerJobsTestResults {
|
||||
try {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
||||
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 3, 2));
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 6, 2));
|
||||
this.savingsAccountHelper = new SavingsAccountHelper(requestSpec, responseSpec);
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
|
||||
|
||||
@@ -741,16 +746,16 @@ public class SchedulerJobsTestResults {
|
||||
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
|
||||
loanStatusHashMap = this.loanTransactionHelper.approveLoan("01 March 2020", loanID);
|
||||
loanStatusHashMap = this.loanTransactionHelper.approveLoan("01 June 2020", loanID);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
|
||||
String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
|
||||
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 March 2020", loanID,
|
||||
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 June 2020", loanID,
|
||||
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
|
||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||
|
||||
this.loanTransactionHelper.addChargesForLoan(loanID,
|
||||
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee), "02 March 2020", "10", null));
|
||||
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee), "02 June 2020", "10", null));
|
||||
|
||||
String jobName = "Loan COB";
|
||||
this.schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||
@@ -765,7 +770,7 @@ public class SchedulerJobsTestResults {
|
||||
// First accrual transaction
|
||||
assertTrue(getLoansLoanIdResponse.getTransactions().get(1).getType().getAccrual());
|
||||
assertEquals(10.0f, getLoansLoanIdResponse.getTransactions().get(1).getFeeChargesPortion());
|
||||
assertEquals(LocalDate.of(2020, 3, 2), getLoansLoanIdResponse.getTransactions().get(1).getDate());
|
||||
assertEquals(LocalDate.of(2020, 6, 2), getLoansLoanIdResponse.getTransactions().get(1).getDate());
|
||||
Long transactionId = getLoansLoanIdResponse.getTransactions().get(1).getId();
|
||||
|
||||
final GetJournalEntriesTransactionIdResponse journalEntriesResponse = journalEntryHelper.getJournalEntries("L" + transactionId);
|
||||
@@ -774,8 +779,8 @@ public class SchedulerJobsTestResults {
|
||||
assertEquals(2, journalEntries.size());
|
||||
assertEquals(10, journalEntries.get(0).getAmount());
|
||||
assertEquals(10, journalEntries.get(1).getAmount());
|
||||
assertEquals(LocalDate.of(2020, 3, 2), journalEntries.get(1).getTransactionDate());
|
||||
assertEquals(LocalDate.of(2020, 3, 2), journalEntries.get(0).getTransactionDate());
|
||||
assertEquals(LocalDate.of(2020, 6, 2), journalEntries.get(1).getTransactionDate());
|
||||
assertEquals(LocalDate.of(2020, 6, 2), journalEntries.get(0).getTransactionDate());
|
||||
} finally {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
|
||||
}
|
||||
@@ -806,31 +811,31 @@ public class SchedulerJobsTestResults {
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
|
||||
loanStatusHashMap = loanTransactionHelper.approveLoan("01 March 2020", loanID);
|
||||
loanStatusHashMap = loanTransactionHelper.approveLoan("01 July 2020", loanID);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
|
||||
String loanDetails = loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
|
||||
loanStatusHashMap = loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 March 2020", loanID,
|
||||
loanStatusHashMap = loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 July 2020", loanID,
|
||||
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
|
||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 3, 2));
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 7, 2));
|
||||
String jobName = "Loan COB";
|
||||
|
||||
schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||
GetLoansLoanIdResponse loan = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanID);
|
||||
Assertions.assertEquals(LocalDate.of(2020, 3, 2), loan.getLastClosedBusinessDate());
|
||||
Assertions.assertEquals(LocalDate.of(2020, 7, 2), loan.getLastClosedBusinessDate());
|
||||
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 3, 3));
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 7, 3));
|
||||
schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||
|
||||
loan = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanID);
|
||||
Assertions.assertEquals(LocalDate.of(2020, 3, 3), loan.getLastClosedBusinessDate());
|
||||
Assertions.assertEquals(LocalDate.of(2020, 7, 3), loan.getLastClosedBusinessDate());
|
||||
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 3, 5));
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 7, 5));
|
||||
schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||
|
||||
loan = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanID);
|
||||
Assertions.assertEquals(LocalDate.of(2020, 3, 3), loan.getLastClosedBusinessDate());
|
||||
Assertions.assertEquals(LocalDate.of(2020, 7, 3), loan.getLastClosedBusinessDate());
|
||||
} finally {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
|
||||
}
|
||||
@@ -840,7 +845,7 @@ public class SchedulerJobsTestResults {
|
||||
public void testLoanCOBApplyPenaltyOnDue() {
|
||||
try {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
||||
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2019, 2, 2));
|
||||
// set penalty wait period to 0
|
||||
GlobalConfigurationHelper.updateValueForGlobalConfiguration(this.requestSpec, this.responseSpec, "10", "0");
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
|
||||
@@ -856,21 +861,21 @@ public class SchedulerJobsTestResults {
|
||||
Assertions.assertNotNull(loanProductID);
|
||||
HashMap loanStatusHashMap;
|
||||
|
||||
final Integer loanID = applyForLoanApplication(clientID.toString(), loanProductID.toString(), null, "10 January 2020");
|
||||
final Integer loanID = applyForLoanApplication(clientID.toString(), loanProductID.toString(), null, "10 January 2019");
|
||||
|
||||
Assertions.assertNotNull(loanID);
|
||||
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
|
||||
loanStatusHashMap = this.loanTransactionHelper.approveLoan("01 March 2020", loanID);
|
||||
loanStatusHashMap = this.loanTransactionHelper.approveLoan("01 March 2019", loanID);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
|
||||
String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
|
||||
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 March 2020", loanID,
|
||||
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 March 2019", loanID,
|
||||
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
|
||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 4, 1));
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2019, 4, 1));
|
||||
String jobName = "Loan COB";
|
||||
|
||||
this.schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||
@@ -879,7 +884,7 @@ public class SchedulerJobsTestResults {
|
||||
Assertions.assertEquals(0, (Integer) repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job");
|
||||
|
||||
LocalDate lastBusinessDateBeforeFastForward = LocalDate.of(2020, 4, 2);
|
||||
LocalDate lastBusinessDateBeforeFastForward = LocalDate.of(2019, 4, 2);
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, lastBusinessDateBeforeFastForward);
|
||||
this.schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||
repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec, loanID);
|
||||
@@ -888,10 +893,34 @@ public class SchedulerJobsTestResults {
|
||||
|
||||
List<Map> transactions = this.loanTransactionHelper.getLoanTransactions(this.requestSpec, this.responseSpec, loanID);
|
||||
Assertions.assertEquals(39.39f, (Float) transactions.get(2).get("amount"));
|
||||
Assertions.assertEquals(2020, ((List) transactions.get(2).get("date")).get(0));
|
||||
Assertions.assertEquals(2019, ((List) transactions.get(2).get("date")).get(0));
|
||||
Assertions.assertEquals(4, ((List) transactions.get(2).get("date")).get(1));
|
||||
Assertions.assertEquals(2, ((List) transactions.get(2).get("date")).get(2));
|
||||
} finally {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
|
||||
GlobalConfigurationHelper.updateValueForGlobalConfiguration(this.requestSpec, this.responseSpec, "10", "2");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoanCOBApplyPenaltyOnDue1DayGracePeriod() {
|
||||
try {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 2, 2));
|
||||
// set penalty wait period to 0
|
||||
GlobalConfigurationHelper.updateValueForGlobalConfiguration(this.requestSpec, this.responseSpec, "10", "0");
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
|
||||
|
||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec);
|
||||
Assertions.assertNotNull(clientID);
|
||||
|
||||
Integer overdueFeeChargeId = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||
ChargesHelper.getLoanOverdueFeeJSONWithCalculationTypePercentage("1"));
|
||||
Assertions.assertNotNull(overdueFeeChargeId);
|
||||
|
||||
final Integer loanProductID = createLoanProduct(overdueFeeChargeId.toString());
|
||||
Assertions.assertNotNull(loanProductID);
|
||||
HashMap loanStatusHashMap;
|
||||
// Test penalty where there is 1 day grace period
|
||||
final Integer loanID2 = applyForLoanApplication(clientID.toString(), loanProductID.toString(), null, "10 January 2020");
|
||||
|
||||
@@ -910,10 +939,11 @@ public class SchedulerJobsTestResults {
|
||||
|
||||
GlobalConfigurationHelper.updateValueForGlobalConfiguration(this.requestSpec, this.responseSpec, "10", "1");
|
||||
LocalDate dateToFastForward = LocalDate.of(2020, 5, 2);
|
||||
|
||||
String jobName = "Loan COB";
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, dateToFastForward);
|
||||
this.schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||
repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec, loanID2);
|
||||
List<HashMap> repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec,
|
||||
loanID2);
|
||||
Assertions.assertEquals(0, (Integer) repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job");
|
||||
|
||||
@@ -923,7 +953,7 @@ public class SchedulerJobsTestResults {
|
||||
Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
||||
"Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job");
|
||||
|
||||
transactions = this.loanTransactionHelper.getLoanTransactions(this.requestSpec, this.responseSpec, loanID2);
|
||||
List<Map> transactions = this.loanTransactionHelper.getLoanTransactions(this.requestSpec, this.responseSpec, loanID2);
|
||||
Assertions.assertEquals(39.39f, (Float) transactions.get(2).get("amount"));
|
||||
Assertions.assertEquals(2020, ((List) transactions.get(2).get("date")).get(0));
|
||||
Assertions.assertEquals(5, ((List) transactions.get(2).get("date")).get(1));
|
||||
@@ -1148,13 +1178,6 @@ public class SchedulerJobsTestResults {
|
||||
assertEquals(LocalDate.of(2022, 9, 5), loanDetails.getTransactions().get(1).getDate());
|
||||
} finally {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
|
||||
}
|
||||
|
||||
try {
|
||||
this.schedulerJobHelper.updateSchedulerJob(16L, new PutJobsJobIDRequest().cronExpression("0 2 0 1/1 * ? *"));
|
||||
} catch (CallFailedRuntimeException e) {
|
||||
// Try again (maybe it was executed by scheduler at the same time when it was called... :/
|
||||
Thread.sleep(2000);
|
||||
this.schedulerJobHelper.updateSchedulerJob(16L, new PutJobsJobIDRequest().cronExpression("0 2 0 1/1 * ? *"));
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -68,6 +68,8 @@ import org.apache.fineract.client.models.PostLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
|
||||
import org.apache.fineract.client.models.PostLoansRequest;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.models.PutChargeTransactionChangesRequest;
|
||||
import org.apache.fineract.client.models.PutChargeTransactionChangesResponse;
|
||||
import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
|
||||
@@ -790,6 +792,10 @@ public class LoanTransactionHelper extends IntegrationTest {
|
||||
return (Integer) response.get("resourceId");
|
||||
}
|
||||
|
||||
public PostLoansLoanIdChargesResponse addChargesForLoan(final Long loanId, PostLoansLoanIdChargesRequest request) {
|
||||
return ok(fineract().loanCharges.executeLoanCharge(loanId, request, null));
|
||||
}
|
||||
|
||||
public PostLoansLoanIdChargesResponse addChargeForLoan(final Integer loanId, final String payload,
|
||||
final ResponseSpecification responseSpecParam) {
|
||||
log.info("--------------------------------- ADD CHARGES FOR LOAN --------------------------------");
|
||||
@@ -1752,10 +1758,18 @@ public class LoanTransactionHelper extends IntegrationTest {
|
||||
return ok(fineract().loans.getDelinquencyTagHistory1(loanExternalId));
|
||||
}
|
||||
|
||||
public PostLoansResponse applyLoan(PostLoansRequest request) {
|
||||
return ok(fineract().loans.calculateLoanScheduleOrSubmitLoanApplication(request, null));
|
||||
}
|
||||
|
||||
public PostLoansLoanIdResponse approveLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "approve"));
|
||||
}
|
||||
|
||||
public PostLoansLoanIdResponse approveLoan(Long loanId, PostLoansLoanIdRequest request) {
|
||||
return ok(fineract().loans.stateTransitions(loanId, request, "approve"));
|
||||
}
|
||||
|
||||
public PostLoansLoanIdResponse rejectLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "reject"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user