FINERACT-1971 Credit balance refund for future date shall be rejected

This commit is contained in:
Peter Bagrij
2023-11-30 16:27:52 +01:00
committed by Adam Saghy
parent 5e5511f70a
commit 8505145fde
3 changed files with 58 additions and 5 deletions
@@ -688,6 +688,10 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
@Override @Override
public LoanTransaction creditBalanceRefund(final Loan loan, final LocalDate transactionDate, final BigDecimal transactionAmount, public LoanTransaction creditBalanceRefund(final Loan loan, final LocalDate transactionDate, final BigDecimal transactionAmount,
final String noteText, final ExternalId externalId, PaymentDetail paymentDetail) { final String noteText, final ExternalId externalId, PaymentDetail paymentDetail) {
if (transactionDate.isAfter(DateUtils.getBusinessLocalDate())) {
throw new GeneralPlatformDomainRuleException("error.msg.transaction.date.cannot.be.in.the.future",
"Loan: " + loan.getId() + ", Credit Balance Refund transaction cannot be created for the future.", loan.getId());
}
if (loan.isChargedOff() && DateUtils.isBefore(transactionDate, loan.getChargedOffOnDate())) { if (loan.isChargedOff() && DateUtils.isBefore(transactionDate, loan.getChargedOffOnDate())) {
throw new GeneralPlatformDomainRuleException("error.msg.transaction.date.cannot.be.earlier.than.charge.off.date", "Loan: " throw new GeneralPlatformDomainRuleException("error.msg.transaction.date.cannot.be.earlier.than.charge.off.date", "Loan: "
+ loan.getId() + loan.getId()
@@ -271,7 +271,7 @@ public abstract class BaseLoanIntegrationTest {
.transactionAmount(amount).locale("en")); .transactionAmount(amount).locale("en"));
} }
protected void verifyJournalEntries(Long loanId, JournalEntry... entries) { protected void verifyJournalEntries(Long loanId, Journal... entries) {
GetJournalEntriesTransactionIdResponse journalEntriesForLoan = journalEntryHelper.getJournalEntriesForLoan(loanId); GetJournalEntriesTransactionIdResponse journalEntriesForLoan = journalEntryHelper.getJournalEntriesForLoan(loanId);
Assertions.assertEquals(entries.length, journalEntriesForLoan.getPageItems().size()); Assertions.assertEquals(entries.length, journalEntriesForLoan.getPageItems().size());
Arrays.stream(entries).forEach(journalEntry -> { Arrays.stream(entries).forEach(journalEntry -> {
@@ -405,8 +405,8 @@ public abstract class BaseLoanIntegrationTest {
new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en")); new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en"));
} }
protected JournalEntry journalEntry(double principalAmount, Account account, String type) { protected Journal journalEntry(double principalAmount, Account account, String type) {
return new JournalEntry(principalAmount, account, type); return new Journal(principalAmount, account, type);
} }
protected Transaction transaction(double principalAmount, String type, String date) { protected Transaction transaction(double principalAmount, String type, String date) {
@@ -454,7 +454,7 @@ public abstract class BaseLoanIntegrationTest {
@ToString @ToString
@AllArgsConstructor @AllArgsConstructor
public static class JournalEntry { public static class Journal {
Double amount; Double amount;
Account account; Account account;
@@ -62,7 +62,7 @@ import org.junit.jupiter.params.provider.MethodSource;
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@ExtendWith(LoanTestLifecycleExtension.class) @ExtendWith(LoanTestLifecycleExtension.class)
@Slf4j @Slf4j
public class ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest { public class ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest extends BaseLoanIntegrationTest {
private ResponseSpecification responseSpec; private ResponseSpecification responseSpec;
private ResponseSpecification responseSpec403; private ResponseSpecification responseSpec403;
@@ -251,7 +251,56 @@ public class ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest {
totalOverpaidAtEnd = floatZero; totalOverpaidAtEnd = floatZero;
} }
assertEquals(totalOverpaidAtEnd, floatZero); assertEquals(totalOverpaidAtEnd, floatZero);
}
@ParameterizedTest
@MethodSource("loanProductFactory")
public void refundAcceptedOnTheCurrentBusinessDate(LoanProductTestBuilder loanProductTestBuilder) {
runAt("09 January 2022", () -> {
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
final Float totalOverpaid = (Float) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec,
disbursedLoanID, "totalOverpaid");
final String creditBalanceRefundDate = "09 January 2022";
final String externalId = null;
loanTransactionHelper.creditBalanceRefund(creditBalanceRefundDate, totalOverpaid, externalId, disbursedLoanID, null);
loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, disbursedLoanID,
"status");
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
final Float floatZero = 0.0f;
Float totalOverpaidAtEnd = (Float) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec,
disbursedLoanID, "totalOverpaid");
if (totalOverpaidAtEnd == null) {
totalOverpaidAtEnd = floatZero;
}
assertEquals(totalOverpaidAtEnd, floatZero);
});
}
@ParameterizedTest
@MethodSource("loanProductFactory")
public void refundCannotBeDuneForFutureDate(LoanProductTestBuilder loanProductTestBuilder) {
runAt("06 January 2022", () -> {
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
final Float totalOverpaid = (Float) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec,
disbursedLoanID, "totalOverpaid");
final String creditBalanceRefundDate = "09 January 2022";
final String externalId = null;
ArrayList<HashMap> cbrErrors = (ArrayList<HashMap>) loanTransactionHelperValidationError.creditBalanceRefund(
creditBalanceRefundDate, totalOverpaid, externalId, disbursedLoanID, CommonConstants.RESPONSE_ERROR);
assertEquals("error.msg.transaction.date.cannot.be.in.the.future",
cbrErrors.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
});
} }
@ParameterizedTest @ParameterizedTest