From eb460303c933e3a96b7ac9b36938de144057751b Mon Sep 17 00:00:00 2001 From: Muhimbura Brian Mart Date: Tue, 3 Dec 2024 18:12:39 +0300 Subject: [PATCH 1/2] FSF-89 running balances fix --- ...lEntryRunningBalanceUpdateServiceImpl.java | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java index fd463f606a1..313504bd62b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java @@ -106,21 +106,21 @@ private void updateOrganizationRunningBalance(LocalDate entityDate) { Map> officesRunningBalance = new HashMap<>(); final String organizationRunningBalanceQuery = """ - WITH latest_entries AS ( - SELECT account_id, MAX(entry_date) AS max_entry_date, MAX(id) AS max_id - FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY account_id - ) - SELECT - je.organization_running_balance AS runningBalance, - je.account_id AS accountId - FROM acc_gl_journal_entry je - INNER JOIN latest_entries le ON je.account_id = le.account_id AND je.entry_date = le.max_entry_date - AND je.id = le.max_id ORDER BY je.entry_date DESC LIMIT 10000; + je.organization_running_balance AS runningBalance, + je.account_id AS accountId + FROM + acc_gl_journal_entry je + INNER JOIN ( SELECT max( id ) AS id FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY account_id, entry_date ) je2 ON je2.id = je.id + INNER JOIN ( SELECT max( entry_date ) AS entrydt FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY account_id ) je3 ON je.entry_date = je3.entrydt + GROUP BY + je.id + ORDER BY + je.entry_date DESC LIMIT 10000; """; List> list = jdbcTemplate.queryForList(organizationRunningBalanceQuery, // NOSONAR - entityDate); + entityDate, entityDate); list.forEach(entry -> { Long accountId = Long.parseLong(entry.get("accountId").toString()); @@ -128,20 +128,22 @@ SELECT account_id, MAX(entry_date) AS max_entry_date, MAX(id) AS max_id }); final String offlineRunningBalanceQuery = """ - WITH latest_entries AS ( - SELECT office_id, account_id, MAX(entry_date) AS max_entry_date, MAX(id) AS max_id - FROM acc_gl_journal_entry WHERE entry_date < ? - GROUP BY office_id, account_id - ) - - SELECT je.office_running_balance AS runningBalance, je.account_id AS accountId, je.office_id AS officeId - FROM acc_gl_journal_entry je - INNER JOIN latest_entries le ON je.office_id = le.office_id AND je.account_id = le.account_id - AND je.entry_date = le.max_entry_date AND je.id = le.max_id ORDER BY je.entry_date DESC LIMIT 10000; + SELECT + je.office_running_balance AS runningBalance, + je.account_id AS accountId, + je.office_id AS officeId + FROM + acc_gl_journal_entry je + INNER JOIN ( SELECT max( id ) AS id FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY office_id, account_id, entry_date ) je2 ON je2.id = je.id + INNER JOIN ( SELECT max( entry_date ) AS entrydt FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY office_id, account_id ) je3 ON je.entry_date = je3.entrydt + GROUP BY + je.id + ORDER BY + je.entry_date DESC LIMIT 10000; """; List> officesRunningBalanceList = jdbcTemplate.queryForList(offlineRunningBalanceQuery, // NOSONAR - entityDate); + entityDate, entityDate); officesRunningBalanceList.forEach(entry -> { Long accountId = Long.parseLong(entry.get("accountId").toString()); From 16eedfedceb0474c6a332deada83701694b75f88 Mon Sep 17 00:00:00 2001 From: Muhimbura Brian Mart Date: Wed, 4 Dec 2024 15:45:05 +0300 Subject: [PATCH 2/2] fix/FSF-80 --- ...lEntryRunningBalanceUpdateServiceImpl.java | 14 ++++---- .../CollateralReadPlatformServiceImpl.java | 6 ++-- .../loanaccount/api/LoansApiResource.java | 18 +++++----- .../loanaccount/data/LoanAccountData.java | 36 +++++++++---------- 4 files changed, 36 insertions(+), 38 deletions(-) diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java index 313504bd62b..7c1f6a83bc8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java @@ -108,13 +108,13 @@ private void updateOrganizationRunningBalance(LocalDate entityDate) { final String organizationRunningBalanceQuery = """ SELECT je.organization_running_balance AS runningBalance, - je.account_id AS accountId + je.account_id AS accountId FROM acc_gl_journal_entry je - INNER JOIN ( SELECT max( id ) AS id FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY account_id, entry_date ) je2 ON je2.id = je.id - INNER JOIN ( SELECT max( entry_date ) AS entrydt FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY account_id ) je3 ON je.entry_date = je3.entrydt + INNER JOIN ( SELECT max( id ) AS id FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY account_id, entry_date ) je2 ON je2.id = je.id + INNER JOIN ( SELECT max( entry_date ) AS entrydt FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY account_id ) je3 ON je.entry_date = je3.entrydt GROUP BY - je.id + je.id ORDER BY je.entry_date DESC LIMIT 10000; """; @@ -131,13 +131,13 @@ INNER JOIN ( SELECT max( entry_date ) AS entrydt FROM acc_gl_journal_entry WHERE SELECT je.office_running_balance AS runningBalance, je.account_id AS accountId, - je.office_id AS officeId + je.office_id AS officeId FROM acc_gl_journal_entry je INNER JOIN ( SELECT max( id ) AS id FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY office_id, account_id, entry_date ) je2 ON je2.id = je.id - INNER JOIN ( SELECT max( entry_date ) AS entrydt FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY office_id, account_id ) je3 ON je.entry_date = je3.entrydt + INNER JOIN ( SELECT max( entry_date ) AS entrydt FROM acc_gl_journal_entry WHERE entry_date < ? GROUP BY office_id, account_id ) je3 ON je.entry_date = je3.entrydt GROUP BY - je.id + je.id ORDER BY je.entry_date DESC LIMIT 10000; """; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralReadPlatformServiceImpl.java index f81f52e3bb1..8896ec010cf 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralReadPlatformServiceImpl.java @@ -54,9 +54,9 @@ private static final class CollateralMapper implements RowMapper private final StringBuilder sqlBuilder = new StringBuilder( "lc.id as id, lc.description as description, lc.value as value, cv.id as typeId, cv.code_value as typeName, oc.code as currencyCode, ") - .append(" oc.name as currencyName,oc.decimal_places as currencyDecimalPlaces, oc.currency_multiplesof as inMultiplesOf, " + - "oc.display_symbol as currencyDisplaySymbol, oc.internationalized_name_code as currencyNameCode, " + - "oc.int_code as intCode") + .append(" oc.name as currencyName,oc.decimal_places as currencyDecimalPlaces, oc.currency_multiplesof as inMultiplesOf, " + + "oc.display_symbol as currencyDisplaySymbol, oc.internationalized_name_code as currencyNameCode, " + + "oc.int_code as intCode") .append(" FROM m_loan_collateral lc") // .append(" JOIN m_code_value cv on lc.type_cv_id = cv.id")// .append(" JOIN m_loan loan on lc.loan_id = loan.id")// diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java index 61716b81563..0d8a7198057 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java @@ -315,9 +315,8 @@ public LoansApiResource(final PlatformSecurityContext context, final LoanReadPla final ConfigurationDomainService configurationDomainService, final DefaultToApiJsonSerializer glimTemplateToApiJsonSerializer, final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService, - final CollateralReadPlatformService collateralReadPlatformService, - final CupoReadService cupoReadService, AppUserReadPlatformService appUserReadPlatformService, - EconomicActivityReadPlatformService economicActivityReadPlatformService, + final CollateralReadPlatformService collateralReadPlatformService, final CupoReadService cupoReadService, + AppUserReadPlatformService appUserReadPlatformService, EconomicActivityReadPlatformService economicActivityReadPlatformService, AgencyReadPlatformServiceImpl agencyReadPlatformService, CenterReadPlatformServiceImpl centerReadPlatformService) { this.context = context; this.loanReadPlatformService = loanReadPlatformService; @@ -934,13 +933,12 @@ public String retrieveLoan(@PathParam("loanId") @Parameter(description = "loanId } final LoanAccountData loanAccount = LoanAccountData.associationsAndTemplate(loanBasicDetails, repaymentSchedule, loanRepayments, - charges, collateralData, guarantors, meeting, productOptions, loanTermFrequencyTypeOptions, - repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions, - repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, - interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, loanPurposeOptions, - loanCollateralOptions, calendarOptions, notes, accountLinkingOptions, linkedAccount, disbursementData, emiAmountVariations, - overdueCharges, paidInAdvanceTemplate, interestRatesPeriods, clientActiveLoanOptions, rates, isRatesEnabled, - collectionData); + charges, collateralData, guarantors, meeting, productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions, + repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions, repaymentStrategyOptions, + interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, + fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, loanPurposeOptions, loanCollateralOptions, calendarOptions, + notes, accountLinkingOptions, linkedAccount, disbursementData, emiAmountVariations, overdueCharges, paidInAdvanceTemplate, + interestRatesPeriods, clientActiveLoanOptions, rates, isRatesEnabled, collectionData); loanAccount.setLinkedCupo(linkedCupo); loanAccount.setCupoLinkingOptions(cupoLinkingOptions); loanAccount.setPrequalificationId(prequalificationId); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java index dab15e674e2..df53ce85826 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java @@ -1773,24 +1773,24 @@ public static LoanAccountData basicLoanDetails(final Long id, final String accou * Used to combine the associations and template data on top of exist loan account data */ public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final LoanScheduleData repaymentSchedule, - final Collection transactions, final Collection charges, - final Collection collateral, final Collection guarantors, - final CalendarData calendarData, final Collection productOptions, - final Collection termFrequencyTypeOptions, final Collection repaymentFrequencyTypeOptions, - final Collection repaymentFrequencyNthDayTypeOptions, - final Collection repaymentFrequencyDayOfWeekTypeOptions, - final Collection transactionProcessingStrategyOptions, - final Collection interestRateFrequencyTypeOptions, final Collection amortizationTypeOptions, - final Collection interestTypeOptions, final Collection interestCalculationPeriodTypeOptions, - final Collection fundOptions, final Collection chargeOptions, final ChargeData chargeTemplate, - final Collection loanOfficerOptions, final Collection loanPurposeOptions, - final Collection loanCollateralOptions, final Collection calendarOptions, - final Collection notes, final Collection accountLinkingOptions, - final PortfolioAccountData linkedAccount, final Collection disbursementDetails, - final Collection emiAmountVariations, final Collection overdueCharges, - final PaidInAdvanceData paidInAdvance, Collection interestRatesPeriods, - final Collection clientActiveLoanOptions, final List rates, final Boolean isRatesEnabled, - final CollectionData delinquent) { + final Collection transactions, final Collection charges, + final Collection collateral, final Collection guarantors, final CalendarData calendarData, + final Collection productOptions, final Collection termFrequencyTypeOptions, + final Collection repaymentFrequencyTypeOptions, + final Collection repaymentFrequencyNthDayTypeOptions, + final Collection repaymentFrequencyDayOfWeekTypeOptions, + final Collection transactionProcessingStrategyOptions, + final Collection interestRateFrequencyTypeOptions, final Collection amortizationTypeOptions, + final Collection interestTypeOptions, final Collection interestCalculationPeriodTypeOptions, + final Collection fundOptions, final Collection chargeOptions, final ChargeData chargeTemplate, + final Collection loanOfficerOptions, final Collection loanPurposeOptions, + final Collection loanCollateralOptions, final Collection calendarOptions, + final Collection notes, final Collection accountLinkingOptions, + final PortfolioAccountData linkedAccount, final Collection disbursementDetails, + final Collection emiAmountVariations, final Collection overdueCharges, + final PaidInAdvanceData paidInAdvance, Collection interestRatesPeriods, + final Collection clientActiveLoanOptions, final List rates, final Boolean isRatesEnabled, + final CollectionData delinquent) { LoanProductConfigurableAttributes loanProductConfigurableAttributes = null; if (acc.product != null) { loanProductConfigurableAttributes = acc.product.getloanProductConfigurableAttributes();