| /** |
| * 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. |
| */ |
| package org.apache.fineract.portfolio.account.service; |
| |
| import static org.apache.fineract.portfolio.account.service.AccountTransferEnumerations.accountType; |
| import static org.apache.fineract.portfolio.account.service.AccountTransferEnumerations.recurrenceType; |
| import static org.apache.fineract.portfolio.account.service.AccountTransferEnumerations.standingInstructionPriority; |
| import static org.apache.fineract.portfolio.account.service.AccountTransferEnumerations.standingInstructionStatus; |
| import static org.apache.fineract.portfolio.account.service.AccountTransferEnumerations.standingInstructionType; |
| import static org.apache.fineract.portfolio.account.service.AccountTransferEnumerations.transferType; |
| |
| import java.math.BigDecimal; |
| import java.sql.ResultSet; |
| import java.sql.SQLException; |
| import java.time.LocalDate; |
| import java.time.MonthDay; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.List; |
| import org.apache.fineract.infrastructure.core.data.EnumOptionData; |
| import org.apache.fineract.infrastructure.core.domain.JdbcSupport; |
| import org.apache.fineract.infrastructure.core.service.DateUtils; |
| import org.apache.fineract.infrastructure.core.service.Page; |
| import org.apache.fineract.infrastructure.core.service.PaginationHelper; |
| import org.apache.fineract.infrastructure.core.service.SearchParameters; |
| import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator; |
| import org.apache.fineract.infrastructure.security.utils.ColumnValidator; |
| import org.apache.fineract.organisation.office.data.OfficeData; |
| import org.apache.fineract.organisation.office.service.OfficeReadPlatformService; |
| import org.apache.fineract.portfolio.account.PortfolioAccountType; |
| import org.apache.fineract.portfolio.account.data.PortfolioAccountDTO; |
| import org.apache.fineract.portfolio.account.data.PortfolioAccountData; |
| import org.apache.fineract.portfolio.account.data.StandingInstructionDTO; |
| import org.apache.fineract.portfolio.account.data.StandingInstructionData; |
| import org.apache.fineract.portfolio.account.data.StandingInstructionDuesData; |
| import org.apache.fineract.portfolio.account.domain.AccountTransferRecurrenceType; |
| import org.apache.fineract.portfolio.account.domain.AccountTransferType; |
| import org.apache.fineract.portfolio.account.domain.StandingInstructionPriority; |
| import org.apache.fineract.portfolio.account.domain.StandingInstructionStatus; |
| import org.apache.fineract.portfolio.account.domain.StandingInstructionType; |
| import org.apache.fineract.portfolio.account.exception.AccountTransferNotFoundException; |
| import org.apache.fineract.portfolio.client.data.ClientData; |
| import org.apache.fineract.portfolio.client.service.ClientReadPlatformService; |
| import org.apache.fineract.portfolio.common.service.CommonEnumerations; |
| import org.apache.fineract.portfolio.common.service.DropdownReadPlatformService; |
| import org.springframework.dao.EmptyResultDataAccessException; |
| import org.springframework.jdbc.core.JdbcTemplate; |
| import org.springframework.jdbc.core.RowMapper; |
| import org.springframework.util.CollectionUtils; |
| |
| public class StandingInstructionReadPlatformServiceImpl implements StandingInstructionReadPlatformService { |
| |
| private final JdbcTemplate jdbcTemplate; |
| private final ColumnValidator columnValidator; |
| private final ClientReadPlatformService clientReadPlatformService; |
| private final OfficeReadPlatformService officeReadPlatformService; |
| private final PortfolioAccountReadPlatformService portfolioAccountReadPlatformService; |
| private final DropdownReadPlatformService dropdownReadPlatformService; |
| private final DatabaseSpecificSQLGenerator sqlGenerator; |
| |
| // mapper |
| private final StandingInstructionMapper standingInstructionMapper; |
| |
| // pagination |
| private final PaginationHelper paginationHelper; |
| |
| public StandingInstructionReadPlatformServiceImpl(final JdbcTemplate jdbcTemplate, |
| final ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService, |
| final PortfolioAccountReadPlatformService portfolioAccountReadPlatformService, |
| final DropdownReadPlatformService dropdownReadPlatformService, final ColumnValidator columnValidator, |
| DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) { |
| this.jdbcTemplate = jdbcTemplate; |
| this.clientReadPlatformService = clientReadPlatformService; |
| this.officeReadPlatformService = officeReadPlatformService; |
| this.portfolioAccountReadPlatformService = portfolioAccountReadPlatformService; |
| this.dropdownReadPlatformService = dropdownReadPlatformService; |
| this.sqlGenerator = sqlGenerator; |
| this.standingInstructionMapper = new StandingInstructionMapper(); |
| this.columnValidator = columnValidator; |
| this.paginationHelper = paginationHelper; |
| } |
| |
| @Override |
| public StandingInstructionData retrieveTemplate(final Long fromOfficeId, final Long fromClientId, final Long fromAccountId, |
| final Integer fromAccountType, final Long toOfficeId, final Long toClientId, final Long toAccountId, |
| final Integer toAccountType, Integer transferType) { |
| |
| AccountTransferType accountTransferType = AccountTransferType.INVALID; |
| if (transferType != null) { |
| accountTransferType = AccountTransferType.fromInt(transferType); |
| } |
| |
| final EnumOptionData loanAccountType = accountType(PortfolioAccountType.LOAN); |
| final EnumOptionData savingsAccountType = accountType(PortfolioAccountType.SAVINGS); |
| |
| final Integer mostRelevantFromAccountType = fromAccountType; |
| Collection<EnumOptionData> fromAccountTypeOptions = null; |
| Collection<EnumOptionData> toAccountTypeOptions = null; |
| |
| if (accountTransferType.isAccountTransfer()) { |
| fromAccountTypeOptions = Arrays.asList(savingsAccountType); |
| toAccountTypeOptions = Arrays.asList(savingsAccountType); |
| } else if (accountTransferType.isLoanRepayment()) { |
| fromAccountTypeOptions = Arrays.asList(savingsAccountType); |
| toAccountTypeOptions = Arrays.asList(loanAccountType); |
| } else { |
| fromAccountTypeOptions = Arrays.asList(savingsAccountType, loanAccountType); |
| toAccountTypeOptions = Arrays.asList(loanAccountType, savingsAccountType); |
| } |
| final Integer mostRelevantToAccountType = toAccountType; |
| |
| final EnumOptionData fromAccountTypeData = accountType(mostRelevantFromAccountType); |
| final EnumOptionData toAccountTypeData = accountType(mostRelevantToAccountType); |
| |
| // from settings |
| OfficeData fromOffice = null; |
| ClientData fromClient = null; |
| PortfolioAccountData fromAccount = null; |
| |
| OfficeData toOffice = null; |
| ClientData toClient = null; |
| PortfolioAccountData toAccount = null; |
| |
| // template |
| Collection<PortfolioAccountData> fromAccountOptions = null; |
| Collection<PortfolioAccountData> toAccountOptions = null; |
| |
| Long mostRelevantFromOfficeId = fromOfficeId; |
| Long mostRelevantFromClientId = fromClientId; |
| |
| Long mostRelevantToOfficeId = toOfficeId; |
| Long mostRelevantToClientId = toClientId; |
| |
| if (fromAccountId != null) { |
| Integer accountType; |
| if (mostRelevantFromAccountType == 1) { |
| accountType = PortfolioAccountType.LOAN.getValue(); |
| } else { |
| accountType = PortfolioAccountType.SAVINGS.getValue(); |
| } |
| fromAccount = this.portfolioAccountReadPlatformService.retrieveOne(fromAccountId, accountType); |
| |
| // override provided fromClient with client of account |
| mostRelevantFromClientId = fromAccount.getClientId(); |
| } |
| |
| if (mostRelevantFromClientId != null) { |
| fromClient = this.clientReadPlatformService.retrieveOne(mostRelevantFromClientId); |
| mostRelevantFromOfficeId = fromClient.getOfficeId(); |
| long[] loanStatus = null; |
| if (mostRelevantFromAccountType == 1) { |
| loanStatus = new long[] { 300, 700 }; |
| } |
| PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(mostRelevantFromAccountType, mostRelevantFromClientId, |
| loanStatus); |
| fromAccountOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(portfolioAccountDTO); |
| } |
| |
| Collection<OfficeData> fromOfficeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown(); |
| Collection<ClientData> fromClientOptions = null; |
| |
| if (mostRelevantFromOfficeId != null) { |
| fromOffice = this.officeReadPlatformService.retrieveOffice(mostRelevantFromOfficeId); |
| fromClientOptions = this.clientReadPlatformService.retrieveAllForLookupByOfficeId(mostRelevantFromOfficeId); |
| } |
| |
| // defaults |
| final LocalDate transferDate = DateUtils.getBusinessLocalDate(); |
| Collection<OfficeData> toOfficeOptions = fromOfficeOptions; |
| Collection<ClientData> toClientOptions = null; |
| |
| if (toAccountId != null && fromAccount != null) { |
| toAccount = this.portfolioAccountReadPlatformService.retrieveOne(toAccountId, mostRelevantToAccountType, |
| fromAccount.getCurrencyCode()); |
| mostRelevantToClientId = toAccount.getClientId(); |
| } |
| |
| if (mostRelevantToClientId != null) { |
| toClient = this.clientReadPlatformService.retrieveOne(mostRelevantToClientId); |
| mostRelevantToOfficeId = toClient.getOfficeId(); |
| |
| toClientOptions = this.clientReadPlatformService.retrieveAllForLookupByOfficeId(mostRelevantToOfficeId); |
| |
| toAccountOptions = retrieveToAccounts(fromAccount, mostRelevantToAccountType, mostRelevantToClientId); |
| } |
| |
| if (mostRelevantToOfficeId != null) { |
| toOffice = this.officeReadPlatformService.retrieveOffice(mostRelevantToOfficeId); |
| toOfficeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown(); |
| |
| toClientOptions = this.clientReadPlatformService.retrieveAllForLookupByOfficeId(mostRelevantToOfficeId); |
| if (toClientOptions != null && toClientOptions.size() == 1) { |
| toClient = new ArrayList<>(toClientOptions).get(0); |
| |
| toAccountOptions = retrieveToAccounts(fromAccount, mostRelevantToAccountType, mostRelevantToClientId); |
| } |
| } |
| |
| final Collection<EnumOptionData> transferTypeOptions = Arrays.asList(transferType(AccountTransferType.ACCOUNT_TRANSFER), |
| transferType( |
| AccountTransferType.LOAN_REPAYMENT)/* |
| * , transferType( AccountTransferType . CHARGE_PAYMENT ) |
| */); |
| final Collection<EnumOptionData> statusOptions = Arrays.asList(standingInstructionStatus(StandingInstructionStatus.ACTIVE), |
| standingInstructionStatus(StandingInstructionStatus.DISABLED)); |
| final Collection<EnumOptionData> instructionTypeOptions = Arrays.asList(standingInstructionType(StandingInstructionType.FIXED), |
| standingInstructionType(StandingInstructionType.DUES)); |
| final Collection<EnumOptionData> priorityOptions = Arrays.asList(standingInstructionPriority(StandingInstructionPriority.URGENT), |
| standingInstructionPriority(StandingInstructionPriority.HIGH), |
| standingInstructionPriority(StandingInstructionPriority.MEDIUM), |
| standingInstructionPriority(StandingInstructionPriority.LOW)); |
| final Collection<EnumOptionData> recurrenceTypeOptions = Arrays.asList(recurrenceType(AccountTransferRecurrenceType.PERIODIC), |
| recurrenceType(AccountTransferRecurrenceType.AS_PER_DUES)); |
| final Collection<EnumOptionData> recurrenceFrequencyOptions = this.dropdownReadPlatformService.retrievePeriodFrequencyTypeOptions(); |
| |
| return StandingInstructionData.template(fromOffice, fromClient, fromAccountTypeData, fromAccount, transferDate, toOffice, toClient, |
| toAccountTypeData, toAccount, fromOfficeOptions, fromClientOptions, fromAccountTypeOptions, fromAccountOptions, |
| toOfficeOptions, toClientOptions, toAccountTypeOptions, toAccountOptions, transferTypeOptions, statusOptions, |
| instructionTypeOptions, priorityOptions, recurrenceTypeOptions, recurrenceFrequencyOptions); |
| } |
| |
| private Collection<PortfolioAccountData> retrieveToAccounts(final PortfolioAccountData excludeThisAccountFromOptions, |
| final Integer toAccountType, final Long toClientId) { |
| |
| final String currencyCode = excludeThisAccountFromOptions != null ? excludeThisAccountFromOptions.getCurrencyCode() : null; |
| |
| PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(toAccountType, toClientId, currencyCode, null, null); |
| Collection<PortfolioAccountData> accountOptions = this.portfolioAccountReadPlatformService |
| .retrieveAllForLookup(portfolioAccountDTO); |
| if (!CollectionUtils.isEmpty(accountOptions)) { |
| accountOptions.remove(excludeThisAccountFromOptions); |
| } else { |
| accountOptions = null; |
| } |
| |
| return accountOptions; |
| } |
| |
| @Override |
| public Page<StandingInstructionData> retrieveAll(final StandingInstructionDTO standingInstructionDTO) { |
| |
| final StringBuilder sqlBuilder = new StringBuilder(200); |
| sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " "); |
| sqlBuilder.append(this.standingInstructionMapper.schema()); |
| if (standingInstructionDTO.transferType() != null || standingInstructionDTO.clientId() != null |
| || standingInstructionDTO.clientName() != null) { |
| sqlBuilder.append(" where "); |
| } |
| boolean addAndCaluse = false; |
| List<Object> paramObj = new ArrayList<>(); |
| if (standingInstructionDTO.transferType() != null) { |
| if (addAndCaluse) { |
| sqlBuilder.append(" and "); |
| } |
| sqlBuilder.append(" atd.transfer_type=? "); |
| paramObj.add(standingInstructionDTO.transferType()); |
| addAndCaluse = true; |
| } |
| if (standingInstructionDTO.clientId() != null) { |
| if (addAndCaluse) { |
| sqlBuilder.append(" and "); |
| } |
| sqlBuilder.append(" fromclient.id=? "); |
| paramObj.add(standingInstructionDTO.clientId()); |
| addAndCaluse = true; |
| } else if (standingInstructionDTO.clientName() != null) { |
| if (addAndCaluse) { |
| sqlBuilder.append(" and "); |
| } |
| sqlBuilder.append(" fromclient.display_name=? "); |
| paramObj.add(standingInstructionDTO.clientName()); |
| addAndCaluse = true; |
| } |
| |
| if (standingInstructionDTO.fromAccountType() != null && standingInstructionDTO.fromAccount() != null) { |
| PortfolioAccountType accountType = PortfolioAccountType.fromInt(standingInstructionDTO.fromAccountType()); |
| if (addAndCaluse) { |
| sqlBuilder.append(" and "); |
| } |
| if (accountType.isSavingsAccount()) { |
| sqlBuilder.append(" fromsavacc.id=? "); |
| paramObj.add(standingInstructionDTO.fromAccount()); |
| } else if (accountType.isLoanAccount()) { |
| sqlBuilder.append(" fromloanacc.id=? "); |
| paramObj.add(standingInstructionDTO.fromAccount()); |
| } |
| addAndCaluse = true; |
| } |
| |
| final SearchParameters searchParameters = standingInstructionDTO.searchParameters(); |
| if (searchParameters.hasOrderBy()) { |
| sqlBuilder.append(" order by ").append(searchParameters.getOrderBy()); |
| this.columnValidator.validateSqlInjection(sqlBuilder.toString(), searchParameters.getOrderBy()); |
| if (searchParameters.hasSortOrder()) { |
| sqlBuilder.append(' ').append(searchParameters.getSortOrder()); |
| this.columnValidator.validateSqlInjection(sqlBuilder.toString(), searchParameters.getSortOrder()); |
| } |
| } |
| |
| if (searchParameters.hasLimit()) { |
| sqlBuilder.append(" "); |
| if (searchParameters.hasOffset()) { |
| sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset())); |
| } else { |
| sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit())); |
| } |
| } |
| |
| final Object[] finalObjectArray = paramObj.toArray(); |
| return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, this.standingInstructionMapper); |
| } |
| |
| @Override |
| public Collection<StandingInstructionData> retrieveAll(final Integer status) { |
| final StringBuilder sqlBuilder = new StringBuilder(200); |
| String businessDate = sqlGenerator.currentBusinessDate(); |
| sqlBuilder.append("select "); |
| sqlBuilder.append(this.standingInstructionMapper.schema()); |
| sqlBuilder |
| .append(" where atsi.status=? and " + businessDate + " >= atsi.valid_from and (atsi.valid_till IS NULL or " + businessDate |
| + " < atsi.valid_till) ") |
| .append(" and (atsi.last_run_date <> " + businessDate + " or atsi.last_run_date IS NULL)") |
| .append(" ORDER BY atsi.priority DESC"); |
| return this.jdbcTemplate.query(sqlBuilder.toString(), this.standingInstructionMapper, status); |
| } |
| |
| @Override |
| public StandingInstructionData retrieveOne(final Long instructionId) { |
| |
| try { |
| final String sql = "select " + this.standingInstructionMapper.schema() + " where atsi.id = ?"; |
| |
| return this.jdbcTemplate.queryForObject(sql, this.standingInstructionMapper, new Object[] { instructionId }); // NOSONAR |
| } catch (final EmptyResultDataAccessException e) { |
| throw new AccountTransferNotFoundException(instructionId, e); |
| } |
| } |
| |
| @Override |
| public StandingInstructionDuesData retriveLoanDuesData(final Long loanId) { |
| final StandingInstructionLoanDuesMapper rm = new StandingInstructionLoanDuesMapper(); |
| final String sql = "select " + rm.schema() + " where ml.id= ? and ls.duedate <= " + sqlGenerator.currentBusinessDate() |
| + " and ls.completed_derived <> 1"; |
| return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanId }); // NOSONAR |
| } |
| |
| private static final class StandingInstructionMapper implements RowMapper<StandingInstructionData> { |
| |
| private final String schemaSql; |
| |
| StandingInstructionMapper() { |
| final StringBuilder sqlBuilder = new StringBuilder(400); |
| sqlBuilder.append("atsi.id as id,atsi.name as name, atsi.priority as priority,"); |
| sqlBuilder.append("atsi.status as status, atsi.instruction_type as instructionType,"); |
| sqlBuilder.append("atsi.amount as amount,"); |
| sqlBuilder.append("atsi.valid_from as validFrom, atsi.valid_till as validTill,"); |
| sqlBuilder.append("atsi.recurrence_type as recurrenceType, atsi.recurrence_frequency as recurrenceFrequency,"); |
| sqlBuilder.append("atsi.recurrence_interval as recurrenceInterval, atsi.recurrence_on_day as recurrenceOnDay,"); |
| sqlBuilder.append("atsi.recurrence_on_month as recurrenceOnMonth,"); |
| sqlBuilder.append("atd.id as accountDetailId,atd.transfer_type as transferType,"); |
| sqlBuilder.append("fromoff.id as fromOfficeId, fromoff.name as fromOfficeName,"); |
| sqlBuilder.append("tooff.id as toOfficeId, tooff.name as toOfficeName,"); |
| sqlBuilder.append("fromclient.id as fromClientId, fromclient.display_name as fromClientName,"); |
| sqlBuilder.append("toclient.id as toClientId, toclient.display_name as toClientName,"); |
| sqlBuilder.append("fromsavacc.id as fromSavingsAccountId, fromsavacc.account_no as fromSavingsAccountNo,"); |
| sqlBuilder.append("fromsp.id as fromProductId, fromsp.name as fromProductName, "); |
| sqlBuilder.append("fromloanacc.id as fromLoanAccountId, fromloanacc.account_no as fromLoanAccountNo,"); |
| sqlBuilder.append("fromlp.id as fromLoanProductId, fromlp.name as fromLoanProductName,"); |
| sqlBuilder.append("tosavacc.id as toSavingsAccountId, tosavacc.account_no as toSavingsAccountNo,"); |
| sqlBuilder.append("tosp.id as toProductId, tosp.name as toProductName, "); |
| sqlBuilder.append("toloanacc.id as toLoanAccountId, toloanacc.account_no as toLoanAccountNo, "); |
| sqlBuilder.append("tolp.id as toLoanProductId, tolp.name as toLoanProductName "); |
| sqlBuilder.append(" FROM m_account_transfer_standing_instructions atsi "); |
| sqlBuilder.append("join m_account_transfer_details atd on atd.id = atsi.account_transfer_details_id "); |
| sqlBuilder.append("join m_office fromoff on fromoff.id = atd.from_office_id "); |
| sqlBuilder.append("join m_office tooff on tooff.id = atd.to_office_id "); |
| sqlBuilder.append("join m_client fromclient on fromclient.id = atd.from_client_id "); |
| sqlBuilder.append("join m_client toclient on toclient.id = atd.to_client_id "); |
| sqlBuilder.append("left join m_savings_account fromsavacc on fromsavacc.id = atd.from_savings_account_id "); |
| sqlBuilder.append("left join m_savings_product fromsp ON fromsavacc.product_id = fromsp.id "); |
| sqlBuilder.append("left join m_loan fromloanacc on fromloanacc.id = atd.from_loan_account_id "); |
| sqlBuilder.append("left join m_product_loan fromlp ON fromloanacc.product_id = fromlp.id "); |
| sqlBuilder.append("left join m_savings_account tosavacc on tosavacc.id = atd.to_savings_account_id "); |
| sqlBuilder.append("left join m_savings_product tosp ON tosavacc.product_id = tosp.id "); |
| sqlBuilder.append("left join m_loan toloanacc on toloanacc.id = atd.to_loan_account_id "); |
| sqlBuilder.append("left join m_product_loan tolp ON toloanacc.product_id = tolp.id "); |
| |
| this.schemaSql = sqlBuilder.toString(); |
| } |
| |
| public String schema() { |
| return this.schemaSql; |
| } |
| |
| @Override |
| public StandingInstructionData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { |
| |
| final Long id = rs.getLong("id"); |
| final Long accountDetailId = rs.getLong("accountDetailId"); |
| final String name = rs.getString("name"); |
| final Integer priority = JdbcSupport.getInteger(rs, "priority"); |
| EnumOptionData priorityEnum = AccountTransferEnumerations.standingInstructionPriority(priority); |
| |
| final Integer status = JdbcSupport.getInteger(rs, "status"); |
| EnumOptionData statusEnum = AccountTransferEnumerations.standingInstructionStatus(status); |
| final Integer instructionType = JdbcSupport.getInteger(rs, "instructionType"); |
| EnumOptionData instructionTypeEnum = AccountTransferEnumerations.standingInstructionType(instructionType); |
| final LocalDate validFrom = JdbcSupport.getLocalDate(rs, "validFrom"); |
| final LocalDate validTill = JdbcSupport.getLocalDate(rs, "validTill"); |
| final BigDecimal transferAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "amount"); |
| final Integer recurrenceType = JdbcSupport.getInteger(rs, "recurrenceType"); |
| EnumOptionData recurrenceTypeEnum = AccountTransferEnumerations.recurrenceType(recurrenceType); |
| final Integer recurrenceFrequency = JdbcSupport.getInteger(rs, "recurrenceFrequency"); |
| |
| EnumOptionData recurrenceFrequencyEnum = null; |
| if (recurrenceFrequency != null) { |
| recurrenceFrequencyEnum = CommonEnumerations.termFrequencyType(recurrenceFrequency, "recurrence"); |
| } |
| final Integer recurrenceInterval = JdbcSupport.getInteger(rs, "recurrenceInterval"); |
| |
| MonthDay recurrenceOnMonthDay = null; |
| final Integer recurrenceOnDay = JdbcSupport.getInteger(rs, "recurrenceOnDay"); |
| final Integer recurrenceOnMonth = JdbcSupport.getInteger(rs, "recurrenceOnMonth"); |
| if (recurrenceOnDay != null) { |
| recurrenceOnMonthDay = MonthDay.now(DateUtils.getDateTimeZoneOfTenant()).withMonth(recurrenceOnMonth) |
| .withDayOfMonth(recurrenceOnDay); |
| } |
| |
| final Integer transferType = rs.getInt("transferType"); |
| EnumOptionData transferTypeEnum = AccountTransferEnumerations.transferType(transferType); |
| |
| /* |
| * final String currencyCode = rs.getString("currencyCode"); final String currencyName = |
| * rs.getString("currencyName"); final String currencyNameCode = rs.getString("currencyNameCode"); final |
| * String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol"); final Integer currencyDigits = |
| * JdbcSupport.getInteger(rs, "currencyDigits"); final Integer inMultiplesOf = JdbcSupport.getInteger(rs, |
| * "inMultiplesOf"); final CurrencyData currency = new CurrencyData(currencyCode, currencyName, |
| * currencyDigits, inMultiplesOf, currencyDisplaySymbol, currencyNameCode); |
| */ |
| final Long fromOfficeId = JdbcSupport.getLong(rs, "fromOfficeId"); |
| final String fromOfficeName = rs.getString("fromOfficeName"); |
| final OfficeData fromOffice = OfficeData.dropdown(fromOfficeId, fromOfficeName, null); |
| |
| final Long toOfficeId = JdbcSupport.getLong(rs, "toOfficeId"); |
| final String toOfficeName = rs.getString("toOfficeName"); |
| final OfficeData toOffice = OfficeData.dropdown(toOfficeId, toOfficeName, null); |
| |
| final Long fromClientId = JdbcSupport.getLong(rs, "fromClientId"); |
| final String fromClientName = rs.getString("fromClientName"); |
| final ClientData fromClient = ClientData.lookup(fromClientId, fromClientName, fromOfficeId, fromOfficeName); |
| |
| final Long toClientId = JdbcSupport.getLong(rs, "toClientId"); |
| final String toClientName = rs.getString("toClientName"); |
| final ClientData toClient = ClientData.lookup(toClientId, toClientName, toOfficeId, toOfficeName); |
| |
| final Long fromSavingsAccountId = JdbcSupport.getLong(rs, "fromSavingsAccountId"); |
| final String fromSavingsAccountNo = rs.getString("fromSavingsAccountNo"); |
| final Long fromProductId = JdbcSupport.getLong(rs, "fromProductId"); |
| final String fromProductName = rs.getString("fromProductName"); |
| final Long fromLoanAccountId = JdbcSupport.getLong(rs, "fromLoanAccountId"); |
| final String fromLoanAccountNo = rs.getString("fromLoanAccountNo"); |
| final Long fromLoanProductId = JdbcSupport.getLong(rs, "fromLoanProductId"); |
| final String fromLoanProductName = rs.getString("fromLoanProductName"); |
| PortfolioAccountData fromAccount = null; |
| EnumOptionData fromAccountType = null; |
| if (fromSavingsAccountId != null) { |
| fromAccount = new PortfolioAccountData(fromSavingsAccountId, fromSavingsAccountNo, null, null, null, null, null, |
| fromProductId, fromProductName, null, null, null); |
| fromAccountType = accountType(PortfolioAccountType.SAVINGS); |
| } else if (fromLoanAccountId != null) { |
| fromAccount = new PortfolioAccountData(fromLoanAccountId, fromLoanAccountNo, null, null, null, null, null, |
| fromLoanProductId, fromLoanProductName, null, null, null); |
| fromAccountType = accountType(PortfolioAccountType.LOAN); |
| } |
| |
| PortfolioAccountData toAccount = null; |
| EnumOptionData toAccountType = null; |
| final Long toSavingsAccountId = JdbcSupport.getLong(rs, "toSavingsAccountId"); |
| final String toSavingsAccountNo = rs.getString("toSavingsAccountNo"); |
| final Long toProductId = JdbcSupport.getLong(rs, "toProductId"); |
| final String toProductName = rs.getString("toProductName"); |
| final Long toLoanAccountId = JdbcSupport.getLong(rs, "toLoanAccountId"); |
| final String toLoanAccountNo = rs.getString("toLoanAccountNo"); |
| final Long toLoanProductId = JdbcSupport.getLong(rs, "toLoanProductId"); |
| final String toLoanProductName = rs.getString("toLoanProductName"); |
| |
| if (toSavingsAccountId != null) { |
| toAccount = new PortfolioAccountData(toSavingsAccountId, toSavingsAccountNo, null, null, null, null, null, toProductId, |
| toProductName, null, null, null); |
| toAccountType = accountType(PortfolioAccountType.SAVINGS); |
| } else if (toLoanAccountId != null) { |
| toAccount = new PortfolioAccountData(toLoanAccountId, toLoanAccountNo, null, null, null, null, null, toLoanProductId, |
| toLoanProductName, null, null, null); |
| toAccountType = accountType(PortfolioAccountType.LOAN); |
| } |
| |
| return StandingInstructionData.instance(id, accountDetailId, name, fromOffice, toOffice, fromClient, toClient, fromAccountType, |
| fromAccount, toAccountType, toAccount, transferTypeEnum, priorityEnum, instructionTypeEnum, statusEnum, transferAmount, |
| validFrom, validTill, recurrenceTypeEnum, recurrenceFrequencyEnum, recurrenceInterval, recurrenceOnMonthDay); |
| } |
| } |
| |
| private static final class StandingInstructionLoanDuesMapper implements RowMapper<StandingInstructionDuesData> { |
| |
| private final String schemaSql; |
| |
| StandingInstructionLoanDuesMapper() { |
| final StringBuilder sqlBuilder = new StringBuilder(400); |
| |
| sqlBuilder.append("max(ls.duedate) as dueDate,sum(ls.principal_amount) as principalAmount,"); |
| sqlBuilder.append("sum(ls.principal_completed_derived) as principalCompleted,"); |
| sqlBuilder.append("sum(ls.principal_writtenoff_derived) as principalWrittenOff,"); |
| sqlBuilder.append("sum(ls.interest_amount) as interestAmount,"); |
| sqlBuilder.append("sum(ls.interest_completed_derived) as interestCompleted,"); |
| sqlBuilder.append("sum(ls.interest_writtenoff_derived) as interestWrittenOff,"); |
| sqlBuilder.append("sum(ls.interest_waived_derived) as interestWaived,"); |
| sqlBuilder.append("sum(ls.penalty_charges_amount) as penalityAmount,"); |
| sqlBuilder.append("sum(ls.penalty_charges_completed_derived) as penalityCompleted,"); |
| sqlBuilder.append("sum(ls.penalty_charges_writtenoff_derived)as penaltyWrittenOff,"); |
| sqlBuilder.append("sum(ls.penalty_charges_waived_derived) as penaltyWaived,"); |
| sqlBuilder.append("sum(ls.fee_charges_amount) as feeAmount,"); |
| sqlBuilder.append("sum(ls.fee_charges_completed_derived) as feecompleted,"); |
| sqlBuilder.append("sum(ls.fee_charges_writtenoff_derived) as feeWrittenOff,"); |
| sqlBuilder.append("sum(ls.fee_charges_waived_derived) as feeWaived "); |
| sqlBuilder.append("from m_loan_repayment_schedule ls "); |
| sqlBuilder.append(" join m_loan ml on ml.id = ls.loan_id "); |
| |
| this.schemaSql = sqlBuilder.toString(); |
| } |
| |
| public String schema() { |
| return this.schemaSql; |
| } |
| |
| @Override |
| public StandingInstructionDuesData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { |
| |
| final LocalDate dueDate = JdbcSupport.getLocalDate(rs, "dueDate"); |
| final BigDecimal principalDue = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalAmount"); |
| final BigDecimal principalPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalCompleted"); |
| final BigDecimal principalWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalWrittenOff"); |
| final BigDecimal principalOutstanding = principalDue.subtract(principalPaid).subtract(principalWrittenOff); |
| |
| final BigDecimal interestExpectedDue = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestAmount"); |
| final BigDecimal interestPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestCompleted"); |
| final BigDecimal interestWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestWrittenOff"); |
| final BigDecimal interestWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestWaived"); |
| final BigDecimal interestActualDue = interestExpectedDue.subtract(interestWaived).subtract(interestWrittenOff); |
| final BigDecimal interestOutstanding = interestActualDue.subtract(interestPaid); |
| |
| final BigDecimal penaltyChargesExpectedDue = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penalityAmount"); |
| final BigDecimal penaltyChargesPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penalityCompleted"); |
| final BigDecimal penaltyChargesWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penaltyWrittenOff"); |
| final BigDecimal penaltyChargesWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penaltyWaived"); |
| final BigDecimal penaltyChargesActualDue = penaltyChargesExpectedDue.subtract(penaltyChargesWaived) |
| .subtract(penaltyChargesWrittenOff); |
| final BigDecimal penaltyChargesOutstanding = penaltyChargesActualDue.subtract(penaltyChargesPaid); |
| |
| final BigDecimal feeChargesExpectedDue = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "feeAmount"); |
| final BigDecimal feeChargesPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "feecompleted"); |
| final BigDecimal feeChargesWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "feeWrittenOff"); |
| final BigDecimal feeChargesWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "feeWaived"); |
| final BigDecimal feeChargesActualDue = feeChargesExpectedDue.subtract(feeChargesWaived).subtract(feeChargesWrittenOff); |
| final BigDecimal feeChargesOutstanding = feeChargesActualDue.subtract(feeChargesPaid); |
| |
| final BigDecimal totalOutstanding = principalOutstanding.add(interestOutstanding).add(feeChargesOutstanding) |
| .add(penaltyChargesOutstanding); |
| |
| return new StandingInstructionDuesData(dueDate, totalOutstanding); |
| } |
| } |
| |
| } |