diff --git a/mifosng-db/migrations/core_db/V181__standing_instruction_logging.sql b/mifosng-db/migrations/core_db/V181__standing_instruction_logging.sql new file mode 100755 index 000000000..797ac3de0 --- /dev/null +++ b/mifosng-db/migrations/core_db/V181__standing_instruction_logging.sql @@ -0,0 +1,11 @@ +CREATE TABLE `m_account_transfer_standing_instructions_history` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `standing_instruction_id` BIGINT(20) NOT NULL, + `status` VARCHAR(20) NOT NULL, + `execution_time` DATETIME NOT NULL, + `amount` DECIMAL(19,6) NOT NULL, + `error_log` VARCHAR(500) NULL DEFAULT NULL, + PRIMARY KEY (`id`), + INDEX `FK_m_account_transfer_standing_instructions_history` (`standing_instruction_id`), + CONSTRAINT `FK_m_account_transfer_standing_instructions_m_history` FOREIGN KEY (`standing_instruction_id`) REFERENCES `m_account_transfer_standing_instructions` (`id`) +); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/api/StandingInstructionApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/api/StandingInstructionApiResource.java index eddce12f3..bd1811a3e 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/api/StandingInstructionApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/api/StandingInstructionApiResource.java @@ -6,6 +6,7 @@ package org.mifosplatform.portfolio.account.api; import java.util.Arrays; +import java.util.Date; import java.util.Set; import javax.ws.rs.Consumes; @@ -144,8 +145,10 @@ public class StandingInstructionApiResource { final SearchParameters searchParameters = SearchParameters.forAccountTransfer(sqlSearch, externalId, offset, limit, orderBy, sortOrder); + final Date startDateRange = null; + final Date endDateRange = null; StandingInstructionDTO standingInstructionDTO = new StandingInstructionDTO(searchParameters, transferType, clientName, clientId, - fromAccount, fromAccountType); + fromAccount, fromAccountType, startDateRange, endDateRange); final Page transfers = this.standingInstructionReadPlatformService.retrieveAll(standingInstructionDTO); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/api/StandingInstructionHistoryApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/api/StandingInstructionHistoryApiResource.java new file mode 100755 index 000000000..4a02ec051 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/api/StandingInstructionHistoryApiResource.java @@ -0,0 +1,88 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.account.api; + +import java.util.Date; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; + +import org.mifosplatform.accounting.journalentry.api.DateParam; +import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; +import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; +import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.mifosplatform.infrastructure.core.service.Page; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.account.data.StandingInstructionDTO; +import org.mifosplatform.portfolio.account.data.StandingInstructionHistoryData; +import org.mifosplatform.portfolio.account.service.StandingInstructionHistoryReadPlatformService; +import org.mifosplatform.portfolio.group.service.SearchParameters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/standinginstructions/history") +@Component +@Scope("singleton") +public class StandingInstructionHistoryApiResource { + + private final PlatformSecurityContext context; + private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final ApiRequestParameterHelper apiRequestParameterHelper; + private final StandingInstructionHistoryReadPlatformService standingInstructionHistoryReadPlatformService; + + @Autowired + public StandingInstructionHistoryApiResource(final PlatformSecurityContext context, + final ApiRequestParameterHelper apiRequestParameterHelper, + final StandingInstructionHistoryReadPlatformService standingInstructionHistoryReadPlatformService, + final DefaultToApiJsonSerializer toApiJsonSerializer) { + this.context = context; + this.toApiJsonSerializer = toApiJsonSerializer; + this.apiRequestParameterHelper = apiRequestParameterHelper; + this.standingInstructionHistoryReadPlatformService = standingInstructionHistoryReadPlatformService; + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch, + @QueryParam("externalId") final String externalId, @QueryParam("offset") final Integer offset, + @QueryParam("limit") final Integer limit, @QueryParam("orderBy") final String orderBy, + @QueryParam("sortOrder") final String sortOrder, @QueryParam("transferType") final Integer transferType, + @QueryParam("clientName") final String clientName, @QueryParam("clientId") final Long clientId, + @QueryParam("fromAccountId") final Long fromAccount, @QueryParam("fromAccountType") final Integer fromAccountType, + @QueryParam("locale") final String locale, @QueryParam("dateFormat") final String dateFormat, + @QueryParam("fromDate") final DateParam fromDateParam, @QueryParam("toDate") final DateParam toDateParam) { + + this.context.authenticatedUser().validateHasReadPermission(StandingInstructionApiConstants.STANDING_INSTRUCTION_RESOURCE_NAME); + + final SearchParameters searchParameters = SearchParameters.forAccountTransfer(sqlSearch, externalId, offset, limit, orderBy, + sortOrder); + Date startDateRange = null; + Date endDateRange = null; + if (fromDateParam != null) { + startDateRange = fromDateParam.getDate("fromDate", dateFormat, locale); + } + if (toDateParam != null) { + endDateRange = toDateParam.getDate("toDate", dateFormat, locale); + } + + StandingInstructionDTO standingInstructionDTO = new StandingInstructionDTO(searchParameters, transferType, clientName, clientId, + fromAccount, fromAccountType, startDateRange, endDateRange); + + final Page history = this.standingInstructionHistoryReadPlatformService + .retrieveAll(standingInstructionDTO); + + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, history); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/StandingInstructionDTO.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/StandingInstructionDTO.java index c4eb19055..2ca083d11 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/StandingInstructionDTO.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/StandingInstructionDTO.java @@ -1,5 +1,7 @@ package org.mifosplatform.portfolio.account.data; +import java.util.Date; + import org.mifosplatform.portfolio.group.service.SearchParameters; public class StandingInstructionDTO { @@ -10,15 +12,19 @@ public class StandingInstructionDTO { final Integer transferType; final Integer fromAccountType; final Long fromAccount; + final Date startDateRange; + final Date endDateRange; public StandingInstructionDTO(final SearchParameters searchParameters, final Integer transferType, final String clientName, - final Long clientId, final Long fromAccount,final Integer fromAccountType) { + final Long clientId, final Long fromAccount, final Integer fromAccountType, final Date startDateRange, final Date endDateRange) { this.searchParameters = searchParameters; this.transferType = transferType; this.clientName = clientName; this.clientId = clientId; this.fromAccount = fromAccount; this.fromAccountType = fromAccountType; + this.startDateRange = startDateRange; + this.endDateRange = endDateRange; } public SearchParameters searchParameters() { @@ -41,9 +47,21 @@ public class StandingInstructionDTO { return this.fromAccount; } - public Integer fromAccountType() { return this.fromAccountType; } + public Integer getTransferType() { + return this.transferType; + } + + public Date startDateRange() { + return this.startDateRange; + } + + + public Date endDateRange() { + return this.endDateRange; + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/StandingInstructionHistoryData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/StandingInstructionHistoryData.java new file mode 100755 index 000000000..cbf95836f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/StandingInstructionHistoryData.java @@ -0,0 +1,49 @@ +package org.mifosplatform.portfolio.account.data; + +import java.math.BigDecimal; +import java.util.Date; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.organisation.office.data.OfficeData; +import org.mifosplatform.portfolio.client.data.ClientData; + +@SuppressWarnings("unused") +public class StandingInstructionHistoryData { + + private final Long standingInstructionId; + private final String name; + private final OfficeData fromOffice; + private final ClientData fromClient; + private final EnumOptionData fromAccountType; + private final PortfolioAccountData fromAccount; + private final EnumOptionData toAccountType; + private final PortfolioAccountData toAccount; + private final OfficeData toOffice; + private final ClientData toClient; + private final BigDecimal amount; + private final String status; + private final LocalDate executionTime; + private final String errorLog; + + public StandingInstructionHistoryData(final Long standingInstructionId, final String name, final OfficeData fromOffice, + final ClientData fromClient, final EnumOptionData fromAccountType, final PortfolioAccountData fromAccount, + final EnumOptionData toAccountType, final PortfolioAccountData toAccount, final OfficeData toOffice, final ClientData toClient, + final BigDecimal amount, final String status, final LocalDate executionTime, final String errorLog) { + this.standingInstructionId = standingInstructionId; + this.name = name; + this.fromOffice = fromOffice; + this.fromClient = fromClient; + this.fromAccountType = fromAccountType; + this.toAccountType = toAccountType; + this.fromAccount = fromAccount; + this.toAccount = toAccount; + this.toOffice = toOffice; + this.toClient = toClient; + this.amount = amount; + this.errorLog = errorLog; + this.status = status; + this.executionTime = executionTime; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionHistoryReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionHistoryReadPlatformService.java new file mode 100755 index 000000000..faa9cbec6 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionHistoryReadPlatformService.java @@ -0,0 +1,16 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.account.service; + +import org.mifosplatform.infrastructure.core.service.Page; +import org.mifosplatform.portfolio.account.data.StandingInstructionDTO; +import org.mifosplatform.portfolio.account.data.StandingInstructionHistoryData; + +public interface StandingInstructionHistoryReadPlatformService { + + Page retrieveAll(StandingInstructionDTO standingInstructionDTO); + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionHistoryReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionHistoryReadPlatformServiceImpl.java new file mode 100755 index 000000000..2128826ac --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionHistoryReadPlatformServiceImpl.java @@ -0,0 +1,258 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.account.service; + +import static org.mifosplatform.portfolio.account.service.AccountTransferEnumerations.accountType; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.domain.JdbcSupport; +import org.mifosplatform.infrastructure.core.service.Page; +import org.mifosplatform.infrastructure.core.service.PaginationHelper; +import org.mifosplatform.infrastructure.core.service.RoutingDataSource; +import org.mifosplatform.organisation.office.data.OfficeData; +import org.mifosplatform.portfolio.account.PortfolioAccountType; +import org.mifosplatform.portfolio.account.data.PortfolioAccountData; +import org.mifosplatform.portfolio.account.data.StandingInstructionDTO; +import org.mifosplatform.portfolio.account.data.StandingInstructionHistoryData; +import org.mifosplatform.portfolio.client.data.ClientData; +import org.mifosplatform.portfolio.group.service.SearchParameters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class StandingInstructionHistoryReadPlatformServiceImpl implements StandingInstructionHistoryReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + + // mapper + private final StandingInstructionHistoryMapper standingInstructionHistoryMapper; + + // pagination + private final PaginationHelper paginationHelper = new PaginationHelper<>(); + + @Autowired + public StandingInstructionHistoryReadPlatformServiceImpl(final RoutingDataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + this.standingInstructionHistoryMapper = new StandingInstructionHistoryMapper(); + } + + @Override + public Page retrieveAll(StandingInstructionDTO standingInstructionDTO) { + + final StringBuilder sqlBuilder = new StringBuilder(200); + sqlBuilder.append("select SQL_CALC_FOUND_ROWS "); + sqlBuilder.append(this.standingInstructionHistoryMapper.schema()); + if (standingInstructionDTO.transferType() != null || standingInstructionDTO.clientId() != null + || standingInstructionDTO.clientName() != null) { + sqlBuilder.append(" where "); + } + boolean addAndCaluse = false; + List 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; + } + + if (standingInstructionDTO.startDateRange() != null) { + if (addAndCaluse) { + sqlBuilder.append(" and "); + } + final DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); + sqlBuilder.append(" atsih.execution_time >= ? "); + paramObj.add(df.format(standingInstructionDTO.startDateRange())); + if (standingInstructionDTO.endDateRange() != null) { + sqlBuilder.append(" and "); + sqlBuilder.append(" atsih.execution_time < ? "); + paramObj.add(df.format(standingInstructionDTO.endDateRange())); + } + addAndCaluse = true; + } + + final SearchParameters searchParameters = standingInstructionDTO.searchParameters(); + if (searchParameters.isOrderByRequested()) { + sqlBuilder.append(" order by ").append(searchParameters.getOrderBy()); + + if (searchParameters.isSortOrderProvided()) { + sqlBuilder.append(' ').append(searchParameters.getSortOrder()); + } + } + + if (searchParameters.isLimited()) { + sqlBuilder.append(" limit ").append(searchParameters.getLimit()); + if (searchParameters.isOffset()) { + sqlBuilder.append(" offset ").append(searchParameters.getOffset()); + } + } + + final Object[] finalObjectArray = paramObj.toArray(); + final String sqlCountRows = "SELECT FOUND_ROWS()"; + return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray, + this.standingInstructionHistoryMapper); + } + + private static final class StandingInstructionHistoryMapper implements RowMapper { + + private final String schemaSql; + + public StandingInstructionHistoryMapper() { + final StringBuilder sqlBuilder = new StringBuilder(400); + sqlBuilder.append("atsi.id as id,atsi.name as name, "); + sqlBuilder.append("atsih.status as status, atsih.execution_time as executionTime, "); + sqlBuilder.append("atsih.amount as amount, atsih.error_log as errorLog, "); + 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_history atsih "); + sqlBuilder.append(" join m_account_transfer_standing_instructions atsi on atsi.id = atsih.standing_instruction_id "); + 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 StandingInstructionHistoryData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = rs.getLong("id"); + final String name = rs.getString("name"); + + final String status = rs.getString("status"); + final LocalDate executionTime = JdbcSupport.getLocalDate(rs, "executionTime"); + final BigDecimal transferAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "amount"); + final String errorLog = rs.getString("errorLog"); + + 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 new StandingInstructionHistoryData(id, name, fromOffice, fromClient, fromAccountType, fromAccount, toAccountType, + toAccount, toOffice, toClient, transferAmount, status, executionTime, errorLog); + } + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java index 8e7ac25c7..8e25269d3 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java @@ -19,8 +19,10 @@ import org.joda.time.LocalDate; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformServiceUnavailableException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.core.service.RoutingDataSource; import org.mifosplatform.infrastructure.jobs.annotation.CronTarget; import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException; import org.mifosplatform.infrastructure.jobs.service.JobName; @@ -48,6 +50,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -62,6 +65,7 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst private final StandingInstructionRepository standingInstructionRepository; private final StandingInstructionReadPlatformService standingInstructionReadPlatformService; private final AccountTransfersWritePlatformService accountTransfersWritePlatformService; + private final JdbcTemplate jdbcTemplate; @Autowired public StandingInstructionWritePlatformServiceImpl(final StandingInstructionDataValidator standingInstructionDataValidator, @@ -69,13 +73,14 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst final AccountTransferDetailRepository accountTransferDetailRepository, final StandingInstructionRepository standingInstructionRepository, final StandingInstructionReadPlatformService standingInstructionReadPlatformService, - final AccountTransfersWritePlatformService accountTransfersWritePlatformService) { + final AccountTransfersWritePlatformService accountTransfersWritePlatformService, final RoutingDataSource dataSource) { this.standingInstructionDataValidator = standingInstructionDataValidator; this.standingInstructionAssembler = standingInstructionAssembler; this.accountTransferDetailRepository = accountTransferDetailRepository; this.standingInstructionRepository = standingInstructionRepository; this.standingInstructionReadPlatformService = standingInstructionReadPlatformService; this.accountTransfersWritePlatformService = accountTransfersWritePlatformService; + this.jdbcTemplate = new JdbcTemplate(dataSource); } @Transactional @@ -234,16 +239,43 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst * @param accountTransferDTO */ private void transferAmount(final StringBuilder sb, final AccountTransferDTO accountTransferDTO, final Long instructionId) { + StringBuffer errorLog = new StringBuffer(); + StringBuffer updateQuery = new StringBuffer( + "INSERT INTO `m_account_transfer_standing_instructions_history` (`standing_instruction_id`, `status`, `amount`,`execution_time`, `error_log`) VALUES ("); try { this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); } catch (final PlatformApiDataValidationException e) { sb.append("Validation exception while trasfering funds for standing Instruction id").append(instructionId).append(" from ") .append(accountTransferDTO.getFromAccountId()).append(" to ").append(accountTransferDTO.getToAccountId()) .append("--------"); + errorLog.append("Validation exception while trasfering funds " + e.getDefaultUserMessage()); } catch (final InsufficientAccountBalanceException e) { sb.append("InsufficientAccountBalance Exception while trasfering funds for standing Instruction id").append(instructionId) .append(" from ").append(accountTransferDTO.getFromAccountId()).append(" to ") .append(accountTransferDTO.getToAccountId()).append("--------"); + errorLog.append("InsufficientAccountBalance Exception "); + } catch (final AbstractPlatformServiceUnavailableException e) { + sb.append("Platform exception while trasfering funds for standing Instruction id").append(instructionId).append(" from ") + .append(accountTransferDTO.getFromAccountId()).append(" to ").append(accountTransferDTO.getToAccountId()) + .append("--------"); + errorLog.append("Platform exception while trasfering funds " + e.getDefaultUserMessage()); + } catch (Exception e) { + sb.append("Exception while trasfering funds for standing Instruction id").append(instructionId).append(" from ") + .append(accountTransferDTO.getFromAccountId()).append(" to ").append(accountTransferDTO.getToAccountId()) + .append("--------"); + errorLog.append("Exception while trasfering funds " + e.getMessage()); + } + updateQuery.append(instructionId).append(","); + if (errorLog.length() > 0) { + updateQuery.append("'failed'").append(","); + } else { + updateQuery.append("'success'").append(","); + } + updateQuery.append(accountTransferDTO.getTransactionAmount().doubleValue()); + updateQuery.append(", now(),"); + updateQuery.append("'").append(errorLog.toString()).append("')"); + this.jdbcTemplate.update(updateQuery.toString()); + } } \ No newline at end of file