diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java index d6424ba25a8..bf066ed8320 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java @@ -45,6 +45,7 @@ public class SavingsAccountTransactionData { private final CurrencyData currency; private final PaymentDetailData paymentDetailData; private final BigDecimal amount; + private final BigDecimal outstandingChargeAmount; private final BigDecimal runningBalance; private final boolean reversed; private final AccountTransferData transfer; @@ -56,20 +57,22 @@ public class SavingsAccountTransactionData { public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType, final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date, - final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed, + final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount,final BigDecimal runningBalance, final boolean reversed, final AccountTransferData transfer, final boolean interestedPostedAsOn) { final Collection paymentTypeOptions = null; return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, - amount, runningBalance, reversed, transfer, paymentTypeOptions, interestedPostedAsOn); + amount, outstandingChargeAmount,runningBalance, reversed, transfer, paymentTypeOptions, interestedPostedAsOn); } public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType, final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date, - final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed, - final AccountTransferData transfer, final LocalDate submittedOnDate, final boolean interestedPostedAsOn) { + final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount, + final BigDecimal runningBalance, final boolean reversed, final AccountTransferData transfer, final LocalDate submittedOnDate, + final boolean interestedPostedAsOn) { final Collection paymentTypeOptions = null; return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, - amount, runningBalance, reversed, transfer, paymentTypeOptions, submittedOnDate, interestedPostedAsOn); + amount, outstandingChargeAmount, runningBalance, reversed, transfer, paymentTypeOptions, submittedOnDate, + interestedPostedAsOn); } public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo, @@ -77,13 +80,14 @@ public static SavingsAccountTransactionData template(final Long savingsId, final final Long id = null; final SavingsAccountTransactionEnumData transactionType = null; final BigDecimal amount = null; + final BigDecimal outstandingChargeAmount = null; final BigDecimal runningBalance = null; final boolean reversed = false; final PaymentDetailData paymentDetailData = null; final Collection paymentTypeOptions = null; final boolean interestedPostedAsOn = false; return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, defaultLocalDate, - currency, amount, runningBalance, reversed, null, null, interestedPostedAsOn); + currency, amount, outstandingChargeAmount, runningBalance, reversed, null, null, interestedPostedAsOn); } public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTransactionData savingsAccountTransactionData, @@ -91,22 +95,23 @@ public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTr return new SavingsAccountTransactionData(savingsAccountTransactionData.id, savingsAccountTransactionData.transactionType, savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId, savingsAccountTransactionData.accountNo, savingsAccountTransactionData.date, savingsAccountTransactionData.currency, - savingsAccountTransactionData.amount, savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed, + savingsAccountTransactionData.amount,savingsAccountTransactionData.outstandingChargeAmount, savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed, savingsAccountTransactionData.transfer, paymentTypeOptions, savingsAccountTransactionData.interestedPostedAsOn); } private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType, final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date, - final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed, - final AccountTransferData transfer, final Collection paymentTypeOptions, final boolean interestedPostedAsOn) { + final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount, + final BigDecimal runningBalance, final boolean reversed, final AccountTransferData transfer, + final Collection paymentTypeOptions, final boolean interestedPostedAsOn) { - this(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, amount, runningBalance, reversed, - transfer, paymentTypeOptions, null, interestedPostedAsOn); + this(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, amount, outstandingChargeAmount, + runningBalance, reversed, transfer, paymentTypeOptions, null, interestedPostedAsOn); } private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType, final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date, - final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed, + final CurrencyData currency, final BigDecimal amount,final BigDecimal outstandingChargeAmount, final BigDecimal runningBalance, final boolean reversed, final AccountTransferData transfer, final Collection paymentTypeOptions, final LocalDate submittedOnDate, final boolean interestedPostedAsOn) { this.id = id; @@ -117,6 +122,7 @@ private SavingsAccountTransactionData(final Long id, final SavingsAccountTransac this.date = date; this.currency = currency; this.amount = amount; + this.outstandingChargeAmount= outstandingChargeAmount; this.runningBalance = runningBalance; this.reversed = reversed; this.transfer = transfer; @@ -135,8 +141,9 @@ public static SavingsAccountTransactionData withWithDrawalTransactionDetails( return new SavingsAccountTransactionData(savingsAccountTransactionData.id, transactionType, savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId, savingsAccountTransactionData.accountNo, currentDate, savingsAccountTransactionData.currency, - savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.runningBalance, - savingsAccountTransactionData.reversed, savingsAccountTransactionData.transfer, - savingsAccountTransactionData.paymentTypeOptions, savingsAccountTransactionData.interestedPostedAsOn); + savingsAccountTransactionData.amount, savingsAccountTransactionData.outstandingChargeAmount, + savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed, + savingsAccountTransactionData.transfer, savingsAccountTransactionData.paymentTypeOptions, + savingsAccountTransactionData.interestedPostedAsOn); } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java index 05d2269c745..32d12bec364 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java @@ -38,6 +38,7 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException; import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency; import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; @@ -71,6 +72,7 @@ @Service public class DepositAccountDomainServiceJpa implements DepositAccountDomainService { + private final PlatformSecurityContext context; private final SavingsAccountRepositoryWrapper savingsAccountRepository; private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper; private final JournalEntryWritePlatformService journalEntryWritePlatformService; @@ -83,7 +85,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi private final CalendarInstanceRepository calendarInstanceRepository; @Autowired - public DepositAccountDomainServiceJpa(final SavingsAccountRepositoryWrapper savingsAccountRepository, + public DepositAccountDomainServiceJpa(final PlatformSecurityContext context,final SavingsAccountRepositoryWrapper savingsAccountRepository, final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper, final JournalEntryWritePlatformService journalEntryWritePlatformService, final AccountNumberGenerator accountNumberGenerator, final DepositAccountAssembler depositAccountAssembler, final SavingsAccountDomainService savingsAccountDomainService, @@ -91,6 +93,7 @@ public DepositAccountDomainServiceJpa(final SavingsAccountRepositoryWrapper savi final ConfigurationDomainService configurationDomainService, final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository, final CalendarInstanceRepository calendarInstanceRepository) { + this.context = context; this.savingsAccountRepository = savingsAccountRepository; this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper; this.journalEntryWritePlatformService = journalEntryWritePlatformService; @@ -133,7 +136,7 @@ public SavingsAccountTransaction handleFDDeposit(final FixedDepositAccount accou public SavingsAccountTransaction handleRDDeposit(final RecurringDepositAccount account, final DateTimeFormatter fmt, final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final boolean isRegularTransaction) { - + AppUser user = getAppUserIfPresent(); final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService .isSavingsInterestPostingAtCurrentPeriodEnd(); final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth(); @@ -144,10 +147,15 @@ public SavingsAccountTransaction handleRDDeposit(final RecurringDepositAccount a account.updateDepositAmount(transactionAmount); final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate, transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction); - + final Set existingTransactionIds = new HashSet<>(); + final Set existingReversedTransactionIds = new HashSet<>(); + updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); + account.processAccountUponActivation(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, user); + this.savingsAccountRepository.saveAndFlush(account); account.handleScheduleInstallments(deposit); account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); account.updateOverduePayments(DateUtils.getLocalDateOfTenant()); + postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer); return deposit; } @@ -477,4 +485,12 @@ private void updateAlreadyPostedTransactions(final Set existingTransaction } } } + + private AppUser getAppUserIfPresent() { + AppUser user = null; + if (this.context != null) { + user = this.context.getAuthenticatedUserIfPresent(); + } + return user; + } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java index cf9496b6284..3df1138c0c8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java @@ -480,8 +480,7 @@ public SavingsAccountTransactionData retrieveRecurringAccountDepositTransactionT try { final String sql = "select " + this.rdTransactionTemplateMapper.schema() + " where sa.id = ? and sa.deposit_type_enum = ? order by mss.installment limit 1"; - - return this.jdbcTemplate.queryForObject(sql, this.rdTransactionTemplateMapper, new Object[] { accountId, + return this.jdbcTemplate.queryForObject(sql, this.rdTransactionTemplateMapper, new Object[] { accountId, accountId, DepositAccountType.RECURRING_DEPOSIT.getValue() }); } catch (final EmptyResultDataAccessException e) { throw new DepositAccountNotFoundException(DepositAccountType.RECURRING_DEPOSIT, accountId); @@ -998,6 +997,7 @@ public SavingsAccountTransactionData mapRow(final ResultSet rs, @SuppressWarning final LocalDate date = JdbcSupport.getLocalDate(rs, "transactionDate"); final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "transactionAmount"); + final BigDecimal outstandingChargeAmount = null; final BigDecimal runningBalance = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "runningBalance"); final boolean reversed = rs.getBoolean("reversed"); @@ -1051,7 +1051,7 @@ public SavingsAccountTransactionData mapRow(final ResultSet rs, @SuppressWarning } final boolean postInterestAsOn = false; return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency, - amount, runningBalance, reversed, transfer, postInterestAsOn); + amount, outstandingChargeAmount, runningBalance, reversed, transfer, postInterestAsOn); } } @@ -1405,10 +1405,17 @@ public RecurringAccountDepositTransactionTemplateMapper() { sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, "); sqlBuilder.append("sa.account_balance_derived as runningBalance, "); sqlBuilder - .append("mss.duedate as duedate, (mss.deposit_amount - ifnull(mss.deposit_amount_completed_derived,0)) as dueamount "); + .append("mss.duedate as duedate, (mss.deposit_amount - ifnull(mss.deposit_amount_completed_derived,0)) as dueamount, "); + sqlBuilder.append("IFNULL(sac.amount_outstanding_derived,0.0) AS outstandingChargeAmount "); sqlBuilder.append("from m_savings_account sa "); sqlBuilder.append("join m_mandatory_savings_schedule mss on mss.savings_account_id=sa.id and mss.completed_derived = false "); sqlBuilder.append("join m_currency curr on curr.code = sa.currency_code "); + sqlBuilder.append("LEFT JOIN(SELECT s.savings_account_id AS savings_account_id "); + sqlBuilder.append(",SUM(IFNULL(s.amount_outstanding_derived,0.0)) AS amount_outstanding_derived "); + sqlBuilder.append("FROM m_savings_account_charge s "); + sqlBuilder.append("JOIN m_charge c ON c.id = s.charge_id AND c.charge_time_enum = 3 "); + sqlBuilder.append("WHERE s.savings_account_id = ? "); + sqlBuilder.append("AND s.is_active = TRUE GROUP BY s.savings_account_id)sac ON sac.savings_account_id = sa.id "); this.schemaSql = sqlBuilder.toString(); } @@ -1423,6 +1430,7 @@ public SavingsAccountTransactionData mapRow(final ResultSet rs, @SuppressWarning final Long savingsId = rs.getLong("id"); final String accountNo = rs.getString("accountNo"); final BigDecimal dueamount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "dueamount"); + final BigDecimal outstandingChargeAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "outstandingChargeAmount"); final LocalDate duedate = JdbcSupport.getLocalDate(rs, "duedate"); final String currencyCode = rs.getString("currencyCode"); final String currencyName = rs.getString("currencyName"); @@ -1439,7 +1447,7 @@ public SavingsAccountTransactionData mapRow(final ResultSet rs, @SuppressWarning final BigDecimal runningBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "runningBalance"); final boolean postInterestAsOn = false; return SavingsAccountTransactionData.create(savingsId, transactionType, paymentDetailData, savingsId, accountNo, duedate, - currency, dueamount, runningBalance, false, transfer, postInterestAsOn); + currency, dueamount, outstandingChargeAmount, runningBalance, false, transfer, postInterestAsOn); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java index f5ba5fe10f1..6b0402ed6ec 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java @@ -433,7 +433,7 @@ public CommandProcessingResult depositToRDAccount(final Long savingsId, final Js final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes); final SavingsAccountTransaction deposit = this.depositAccountDomainService.handleRDDeposit(account, fmt, transactionDate, transactionAmount, paymentDetail, isRegularTransaction); - + return new CommandProcessingResultBuilder() // .withEntityId(deposit.getId()) // .withOfficeId(account.officeId()) // diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java index c91281111ae..cdf6bc2c8e6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java @@ -40,7 +40,6 @@ import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksReadService; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.organisation.monetary.data.CurrencyData; -import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.organisation.staff.data.StaffData; import org.apache.fineract.organisation.staff.service.StaffReadPlatformService; import org.apache.fineract.portfolio.account.data.AccountTransferData; @@ -805,6 +804,7 @@ public SavingsAccountTransactionData mapRow(final ResultSet rs, @SuppressWarning final LocalDate date = JdbcSupport.getLocalDate(rs, "transactionDate"); final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate"); final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "transactionAmount"); + final BigDecimal outstandingChargeAmount = null; final BigDecimal runningBalance = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "runningBalance"); final boolean reversed = rs.getBoolean("reversed"); @@ -861,7 +861,7 @@ public SavingsAccountTransactionData mapRow(final ResultSet rs, @SuppressWarning } return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency, - amount, runningBalance, reversed, transfer, submittedOnDate, postInterestAsOn); + amount, outstandingChargeAmount, runningBalance, reversed, transfer, submittedOnDate, postInterestAsOn); } }