From 019cdab4349b75981752f0af93fbb188cbe2801e Mon Sep 17 00:00:00 2001 From: Apurb Rajdhan <103931815+apurbraj@users.noreply.github.com> Date: Sat, 23 Jul 2022 01:07:42 +0530 Subject: [PATCH] Fineract-1646 (#2440) * FINERACT 1646 * updated the order of import Co-authored-by: Manoj <56669674+fynmanoj@users.noreply.github.com> --- .../SavingsSchedularInterestPoster.java | 52 +++++++++++++------ ...ingsInterestPostingJobIntegrationTest.java | 25 +++++++++ 2 files changed, 62 insertions(+), 15 deletions(-) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java index 57c6797d6..79d5e012a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java @@ -21,10 +21,10 @@ package org.apache.fineract.portfolio.savings.service; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.math.BigDecimal; import java.security.SecureRandom; -import java.sql.Date; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collection; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.UUID; @@ -248,8 +248,10 @@ public class SavingsSchedularInterestPoster implements Callable { private void batchUpdate(final List savingsAccountDataList) throws DataAccessException { String queryForSavingsUpdate = batchQueryForSavingsSummaryUpdate(); String queryForTransactionInsertion = batchQueryForTransactionInsertion(); + String queryForTransactionUpdate = batchQueryForTransactionsUpdate(); List paramsForTransactionInsertion = new ArrayList<>(); List paramsForSavingsSummary = new ArrayList<>(); + List paramsForTransactionUpdate = new ArrayList<>(); List transRefNo = new ArrayList<>(); for (SavingsAccountData savingsAccountData : savingsAccountDataList) { SavingsAccountSummaryData savingsAccountSummaryData = savingsAccountData.getSummary(); @@ -269,22 +271,29 @@ public class SavingsSchedularInterestPoster implements Callable { savingsAccountData.getId() }); List savingsAccountTransactionDataList = savingsAccountData.getSavingsAccountTransactionData(); for (SavingsAccountTransactionData savingsAccountTransactionData : savingsAccountTransactionDataList) { + Date balanceEndDate = null; + if (savingsAccountTransactionData.getBalanceEndDate() != null) { + balanceEndDate = Date.from(savingsAccountTransactionData.getBalanceEndDate() + .atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant()); + } if (savingsAccountTransactionData.getId() == null) { UUID uuid = UUID.randomUUID(); savingsAccountTransactionData.setRefNo(uuid.toString()); transRefNo.add(uuid.toString()); - java.util.Date balanceEndDate = null; - if (savingsAccountTransactionData.getBalanceEndDate() != null) { - balanceEndDate = Date.from(savingsAccountTransactionData.getBalanceEndDate() - .atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant()); - } paramsForTransactionInsertion.add(new Object[] { savingsAccountData.getId(), savingsAccountData.getOfficeId(), - savingsAccountTransactionData.getTransactionType().getId(), savingsAccountTransactionData.getTransactionDate(), - savingsAccountTransactionData.getAmount(), balanceEndDate, + savingsAccountTransactionData.isReversed(), savingsAccountTransactionData.getTransactionType().getId(), + savingsAccountTransactionData.getTransactionDate(), savingsAccountTransactionData.getAmount(), balanceEndDate, savingsAccountTransactionData.getBalanceNumberOfDays(), savingsAccountTransactionData.getRunningBalance(), savingsAccountTransactionData.getCumulativeBalance(), savingsAccountTransactionData.getSubmittedOnDate(), Integer.valueOf(1), savingsAccountTransactionData.isManualTransaction(), - savingsAccountTransactionData.getRefNo() }); + savingsAccountTransactionData.getRefNo(), savingsAccountTransactionData.isReversalTransaction(), + savingsAccountTransactionData.getOverdraftAmount(), }); + } else { + paramsForTransactionUpdate.add(new Object[] { savingsAccountTransactionData.isReversed(), + savingsAccountTransactionData.getAmount(), savingsAccountTransactionData.getOverdraftAmount(), balanceEndDate, + savingsAccountTransactionData.getBalanceNumberOfDays(), savingsAccountTransactionData.getRunningBalance(), + savingsAccountTransactionData.getCumulativeBalance(), savingsAccountTransactionData.isReversalTransaction(), + savingsAccountTransactionData.getId() }); } } savingsAccountData.setUpdatedTransactions(savingsAccountTransactionDataList); @@ -293,6 +302,7 @@ public class SavingsSchedularInterestPoster implements Callable { if (transRefNo.size() > 0) { this.jdbcTemplate.batchUpdate(queryForSavingsUpdate, paramsForSavingsSummary); this.jdbcTemplate.batchUpdate(queryForTransactionInsertion, paramsForTransactionInsertion); + this.jdbcTemplate.batchUpdate(queryForTransactionUpdate, paramsForTransactionUpdate); LOG.info("`Total No Of Interest Posting:` {}", transRefNo.size()); List savingsAccountTransactionDataList = fetchTransactionsFromIds(transRefNo); if (savingsAccountDataList != null) { @@ -311,11 +321,12 @@ public class SavingsSchedularInterestPoster implements Callable { private String batchQueryForTransactionInsertion() { StringBuilder query = new StringBuilder(100); - query.append("INSERT INTO m_savings_account_transaction (savings_account_id, office_id, is_reversed,"); - query.append("transaction_type_enum, transaction_date, amount, balance_end_date_derived,"); - query.append("balance_number_of_days_derived, running_balance_derived, cumulative_balance_derived,"); - query.append("created_date, appuser_id, is_manual, is_loan_disbursement, ref_no) VALUES "); - query.append("(?, ?, false, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, false, ?)"); + query.append("INSERT INTO m_savings_account_transaction (savings_account_id, office_id, is_reversed, "); + query.append("transaction_type_enum, transaction_date, amount, balance_end_date_derived, "); + query.append("balance_number_of_days_derived, running_balance_derived, cumulative_balance_derived, "); + query.append("created_date, appuser_id, is_manual, ref_no, is_reversal, "); + query.append("overdraft_amount_derived) VALUES "); + query.append("(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); return query.toString(); } @@ -326,7 +337,18 @@ public class SavingsSchedularInterestPoster implements Callable { query.append("total_interest_earned_derived=?, total_interest_posted_derived=?, total_withdrawal_fees_derived=?, "); query.append("total_fees_charge_derived=?, total_penalty_charge_derived=?, total_annual_fees_derived=?, "); query.append("account_balance_derived=?, total_overdraft_interest_derived=?, total_withhold_tax_derived=?, "); - query.append("last_interest_calculation_date=?, interest_posted_till_date=? where id=?"); + query.append("last_interest_calculation_date=?, interest_posted_till_date=? where id=? "); + return query.toString(); + } + + private String batchQueryForTransactionsUpdate() { + StringBuilder query = new StringBuilder(100); + query.append("UPDATE m_savings_account_transaction "); + query.append("SET is_reversed=?, "); + query.append("amount=?, overdraft_amount_derived=?, balance_end_date_derived=?, "); + query.append("balance_number_of_days_derived=?, running_balance_derived=?, cumulative_balance_derived=?, "); + query.append("is_reversal=? "); + query.append("WHERE id=?"); return query.toString(); } } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsInterestPostingJobIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsInterestPostingJobIntegrationTest.java index a5667f19f..3bd89a308 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsInterestPostingJobIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsInterestPostingJobIntegrationTest.java @@ -113,6 +113,31 @@ public class SavingsInterestPostingJobIntegrationTest { assertEquals(0, journalEntries.size()); } + @Test + public void testDuplicateOverdraftInterestPostingJob() { + // client activation, savings activation and 1st transaction date + final String startDate = "01 July 2022"; + final String jobName = "Post Interest For Savings"; + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, startDate); + Assertions.assertNotNull(clientID); + + final Integer savingsId = createSavingsAccountDailyPostingOverdraft(clientID, startDate); + + this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, "1000", startDate, CommonConstants.RESPONSE_RESOURCE_ID); + + this.scheduleJobHelper.executeAndAwaitJob(jobName); + this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, "1000", startDate, CommonConstants.RESPONSE_RESOURCE_ID); + Object transactionObj = this.savingsAccountHelper.getSavingsDetails(savingsId, "transactions"); + ArrayList> transactions = (ArrayList>) transactionObj; + Integer dateCount = 0; + for (HashMap transaction : transactions) { + if (transaction.get("date").toString().equals("[2022, 7, 10]") && transaction.get("reversed").toString().equals("false")) { + dateCount++; + } + } + assertEquals(1, dateCount, "No Duplicate Overdraft Interest Posting"); + } + @Test public void testSavingsDailyInterestPostingJob() { // client activation, savings activation and 1st transaction date