MIFOSX-432: ability to transfer from savings account to savings account.
This commit is contained in:
+1483
-65
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
|||||||
|
INSERT INTO `m_permission`
|
||||||
|
(`grouping`,`code`,`entity_name`,`action_name`,`can_maker_checker`)
|
||||||
|
VALUES
|
||||||
|
('transaction_savings', 'READ_ACCOUNTTRANSFER', 'ACCOUNTTRANSFER', 'READ', 0),
|
||||||
|
('transaction_savings', 'CREATE_ACCOUNTTRANSFER', 'ACCOUNTTRANSFER', 'CREATE', 1),
|
||||||
|
('transaction_savings', 'CREATE_ACCOUNTTRANSFER_CHECKER', 'ACCOUNTTRANSFER', 'CREATE', 0);
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `m_savings_account_transfer`;
|
||||||
|
|
||||||
|
CREATE TABLE `m_savings_account_transfer` (
|
||||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||||
|
`from_office_id` bigint(20) NOT NULL,
|
||||||
|
`to_office_id` bigint(20) NOT NULL,
|
||||||
|
`from_client_id` bigint(20) NOT NULL,
|
||||||
|
`to_client_id` bigint(20) NOT NULL,
|
||||||
|
`from_savings_account_id` bigint(20) DEFAULT NULL,
|
||||||
|
`to_savings_account_id` bigint(20) DEFAULT NULL,
|
||||||
|
`from_loan_account_id` bigint(20) DEFAULT NULL,
|
||||||
|
`to_loan_account_id` bigint(20) DEFAULT NULL,
|
||||||
|
`from_savings_transaction_id` bigint(20) DEFAULT NULL,
|
||||||
|
`from_loan_transaction_id` bigint(20) DEFAULT NULL,
|
||||||
|
`to_savings_transaction_id` bigint(20) DEFAULT NULL,
|
||||||
|
`to_loan_transaction_id` bigint(20) DEFAULT NULL,
|
||||||
|
`is_reversed` tinyint(1) NOT NULL,
|
||||||
|
`transaction_date` date NOT NULL,
|
||||||
|
`currency_code` varchar(3) NOT NULL,
|
||||||
|
`currency_digits` smallint(5) NOT NULL,
|
||||||
|
`amount` decimal(19,6) NOT NULL,
|
||||||
|
`description` varchar(200) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `FKTRAN000000001` (`from_office_id`),
|
||||||
|
KEY `FKTRAN000000002` (`from_client_id`),
|
||||||
|
KEY `FKTRAN000000003` (`from_savings_account_id`),
|
||||||
|
KEY `FKTRAN000000004` (`to_office_id`),
|
||||||
|
KEY `FKTRAN000000005` (`to_client_id`),
|
||||||
|
KEY `FKTRAN000000006` (`to_savings_account_id`),
|
||||||
|
KEY `FKTRAN000000007` (`to_loan_account_id`),
|
||||||
|
KEY `FKTRAN000000008` (`from_savings_transaction_id`),
|
||||||
|
KEY `FKTRAN000000009` (`to_savings_transaction_id`),
|
||||||
|
KEY `FKTRAN000000010` (`to_loan_transaction_id`),
|
||||||
|
KEY `FKTRAN000000011` (`from_loan_account_id`),
|
||||||
|
KEY `FKTRAN000000012` (`from_loan_transaction_id`),
|
||||||
|
CONSTRAINT `FKTRAN000000001` FOREIGN KEY (`from_office_id`) REFERENCES `m_office` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000002` FOREIGN KEY (`from_client_id`) REFERENCES `m_client` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000003` FOREIGN KEY (`from_savings_account_id`) REFERENCES `m_savings_account` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000004` FOREIGN KEY (`to_office_id`) REFERENCES `m_office` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000005` FOREIGN KEY (`to_client_id`) REFERENCES `m_client` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000006` FOREIGN KEY (`to_savings_account_id`) REFERENCES `m_savings_account` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000007` FOREIGN KEY (`to_loan_account_id`) REFERENCES `m_loan` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000008` FOREIGN KEY (`from_savings_transaction_id`) REFERENCES `m_savings_account_transaction` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000009` FOREIGN KEY (`to_savings_transaction_id`) REFERENCES `m_savings_account_transaction` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000010` FOREIGN KEY (`to_loan_transaction_id`) REFERENCES `m_loan_transaction` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000011` FOREIGN KEY (`from_loan_account_id`) REFERENCES `m_loan` (`id`),
|
||||||
|
CONSTRAINT `FKTRAN000000012` FOREIGN KEY (`from_loan_transaction_id`) REFERENCES `m_loan_transaction` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
@@ -563,4 +563,8 @@ public class CommandWrapper {
|
|||||||
public boolean isSchedulerResource() {
|
public boolean isSchedulerResource() {
|
||||||
return this.entityName.equalsIgnoreCase("SCHEDULER");
|
return this.entityName.equalsIgnoreCase("SCHEDULER");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAccountTransferResource() {
|
||||||
|
return this.entityName.equalsIgnoreCase("ACCOUNTTRANSFER");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+8
@@ -808,6 +808,14 @@ public class CommandWrapperBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder createAccountTransfer() {
|
||||||
|
this.actionName = "CREATE";
|
||||||
|
this.entityName = "ACCOUNTTRANSFER";
|
||||||
|
this.entityId = null;
|
||||||
|
this.href = "/accounttransfers";
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public CommandWrapperBuilder savingsAccountDeposit(final Long accountId) {
|
public CommandWrapperBuilder savingsAccountDeposit(final Long accountId) {
|
||||||
this.actionName = "DEPOSIT";
|
this.actionName = "DEPOSIT";
|
||||||
this.entityName = "SAVINGSACCOUNT";
|
this.entityName = "SAVINGSACCOUNT";
|
||||||
|
|||||||
+8
-1
@@ -105,7 +105,14 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
|||||||
private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) {
|
private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) {
|
||||||
NewCommandSourceHandler handler = null;
|
NewCommandSourceHandler handler = null;
|
||||||
|
|
||||||
if (wrapper.isConfigurationResource()) {
|
if (wrapper.isAccountTransferResource()) {
|
||||||
|
if (wrapper.isCreate()) {
|
||||||
|
handler = this.applicationContext.getBean("createAccountTransferCommandHandler", NewCommandSourceHandler.class);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedCommandException(wrapper.commandName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (wrapper.isConfigurationResource()) {
|
||||||
handler = this.applicationContext.getBean("updateGlobalConfigurationCommandHandler", NewCommandSourceHandler.class);
|
handler = this.applicationContext.getBean("updateGlobalConfigurationCommandHandler", NewCommandSourceHandler.class);
|
||||||
} else if (wrapper.isDatatableResource()) {
|
} else if (wrapper.isDatatableResource()) {
|
||||||
if (wrapper.isCreateDatatable()) {
|
if (wrapper.isCreateDatatable()) {
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ public enum JobName {
|
|||||||
|
|
||||||
UPDATE_LOAN_SUMMARY("Update loan Summary"), UPDATE_LOAN_ARREARS_AGEING("Update Loan Arrears Ageing"), UPDATE_LOAN_PAID_IN_ADVANCE(
|
UPDATE_LOAN_SUMMARY("Update loan Summary"), UPDATE_LOAN_ARREARS_AGEING("Update Loan Arrears Ageing"), UPDATE_LOAN_PAID_IN_ADVANCE(
|
||||||
"Update Loan Paid In Advance"), APPLY_ANNUAL_FEE_FOR_SAVINGS("Apply Annual Fee For Savings"), APPLY_HOLIDAYS_TO_LOANS(
|
"Update Loan Paid In Advance"), APPLY_ANNUAL_FEE_FOR_SAVINGS("Apply Annual Fee For Savings"), APPLY_HOLIDAYS_TO_LOANS(
|
||||||
"Apply Holidays To Loans"),POST_INTEREST_FOR_SAVINGS("Post Interest For Savings");
|
"Apply Holidays To Loans"), POST_INTEREST_FOR_SAVINGS("Post Interest For Savings");
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.data.AccountTransferData;
|
||||||
|
|
||||||
|
public class AccountTransfersApiConstants {
|
||||||
|
|
||||||
|
public static final String ACCOUNT_TRANSFER_RESOURCE_NAME = "accounttransfer";
|
||||||
|
|
||||||
|
// general
|
||||||
|
public static final String localeParamName = "locale";
|
||||||
|
public static final String dateFormatParamName = "dateFormat";
|
||||||
|
|
||||||
|
// savings product and account parameters
|
||||||
|
public static final String idParamName = "id";
|
||||||
|
public static final String fromOfficeIdParamName = "fromOfficeId";
|
||||||
|
public static final String fromClientIdParamName = "fromClientId";
|
||||||
|
public static final String fromAccountIdParamName = "fromAccountId";
|
||||||
|
public static final String fromAccountTypeParamName = "fromAccountType";
|
||||||
|
public static final String toOfficeIdParamName = "toOfficeId";
|
||||||
|
public static final String toClientIdParamName = "toClientId";
|
||||||
|
public static final String toAccountIdParamName = "toAccountId";
|
||||||
|
public static final String toAccountTypeParamName = "toAccountType";
|
||||||
|
|
||||||
|
// transaction parameters
|
||||||
|
public static final String transferDateParamName = "transferDate";
|
||||||
|
public static final String transferAmountParamName = "transferAmount";
|
||||||
|
public static final String transferDescriptionParamName = "transferDescription";
|
||||||
|
|
||||||
|
public static final Set<String> REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName, dateFormatParamName,
|
||||||
|
fromOfficeIdParamName, fromClientIdParamName, fromAccountTypeParamName, fromAccountIdParamName, toOfficeIdParamName,
|
||||||
|
toClientIdParamName, toAccountTypeParamName, toAccountIdParamName, transferDateParamName, transferAmountParamName,
|
||||||
|
transferDescriptionParamName));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These parameters will match the class level parameters of
|
||||||
|
* {@link AccountTransferData}. Where possible, we try to get response
|
||||||
|
* parameters to match those of request parameters.
|
||||||
|
*/
|
||||||
|
public static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName, transferDescriptionParamName,
|
||||||
|
"currency"));
|
||||||
|
}
|
||||||
+122
@@ -0,0 +1,122 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.api;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
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.commands.domain.CommandWrapper;
|
||||||
|
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||||
|
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
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.accounttransfers.AccountTransfersApiConstants;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.data.AccountTransferData;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.service.AccountTransfersReadPlatformService;
|
||||||
|
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("/accounttransfers")
|
||||||
|
@Component
|
||||||
|
@Scope("singleton")
|
||||||
|
public class AccountTransfersApiResource {
|
||||||
|
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
private final DefaultToApiJsonSerializer<AccountTransferData> toApiJsonSerializer;
|
||||||
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
|
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||||
|
private final AccountTransfersReadPlatformService accountTransfersReadPlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountTransfersApiResource(final PlatformSecurityContext context,
|
||||||
|
final DefaultToApiJsonSerializer<AccountTransferData> toApiJsonSerializer,
|
||||||
|
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||||
|
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||||
|
final AccountTransfersReadPlatformService accountTransfersReadPlatformService) {
|
||||||
|
this.context = context;
|
||||||
|
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||||
|
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||||
|
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||||
|
this.accountTransfersReadPlatformService = accountTransfersReadPlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("template")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String template(@QueryParam("fromOfficeId") final Long fromOfficeId, @QueryParam("fromClientId") final Long fromClientId,
|
||||||
|
@QueryParam("fromAccountId") final Long fromAccountId, @QueryParam("fromAccountType") final Integer fromAccountType,
|
||||||
|
@QueryParam("toOfficeId") final Long toOfficeId, @QueryParam("toClientId") final Long toClientId,
|
||||||
|
@QueryParam("toAccountId") final Long toAccountId, @QueryParam("toAccountType") final Integer toAccountType,
|
||||||
|
@Context final UriInfo uriInfo) {
|
||||||
|
|
||||||
|
context.authenticatedUser().validateHasReadPermission(AccountTransfersApiConstants.ACCOUNT_TRANSFER_RESOURCE_NAME);
|
||||||
|
|
||||||
|
AccountTransferData transferData = this.accountTransfersReadPlatformService.retrieveTemplate(fromOfficeId, fromClientId,
|
||||||
|
fromAccountId, fromAccountType, toOfficeId, toClientId, toAccountId, toAccountType);
|
||||||
|
|
||||||
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
|
return this.toApiJsonSerializer.serialize(settings, transferData, AccountTransfersApiConstants.RESPONSE_DATA_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String create(final String apiRequestBodyAsJson) {
|
||||||
|
|
||||||
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().createAccountTransfer().withJson(apiRequestBodyAsJson).build();
|
||||||
|
|
||||||
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
|
||||||
|
context.authenticatedUser().validateHasReadPermission(AccountTransfersApiConstants.ACCOUNT_TRANSFER_RESOURCE_NAME);
|
||||||
|
|
||||||
|
final SearchParameters searchParameters = SearchParameters.forLoans(sqlSearch, externalId, offset, limit, orderBy, sortOrder);
|
||||||
|
|
||||||
|
final Page<AccountTransferData> transfers = this.accountTransfersReadPlatformService.retrieveAll(searchParameters);
|
||||||
|
|
||||||
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
|
return this.toApiJsonSerializer.serialize(settings, transfers, AccountTransfersApiConstants.RESPONSE_DATA_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{transferId}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String retrieveOne(@PathParam("transferId") final Long transferId, @Context final UriInfo uriInfo) {
|
||||||
|
|
||||||
|
context.authenticatedUser().validateHasReadPermission(AccountTransfersApiConstants.ACCOUNT_TRANSFER_RESOURCE_NAME);
|
||||||
|
|
||||||
|
AccountTransferData transfer = this.accountTransfersReadPlatformService.retrieveOne(transferId);
|
||||||
|
|
||||||
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
|
return this.toApiJsonSerializer.serialize(settings, transfer, AccountTransfersApiConstants.RESPONSE_DATA_PARAMETERS);
|
||||||
|
}
|
||||||
|
}
|
||||||
+108
@@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
|
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||||
|
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||||
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable data object representing a savings account.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class AccountTransferData {
|
||||||
|
|
||||||
|
private final Long id;
|
||||||
|
private final Boolean reversed;
|
||||||
|
private final CurrencyData currency;
|
||||||
|
private final BigDecimal transferAmount;
|
||||||
|
private final LocalDate transferDate;
|
||||||
|
private final String transferDescription;
|
||||||
|
private final OfficeData fromOffice;
|
||||||
|
private final ClientData fromClient;
|
||||||
|
private final SavingsAccountData fromAccount;
|
||||||
|
private final OfficeData toOffice;
|
||||||
|
private final ClientData toClient;
|
||||||
|
private final SavingsAccountData toAccount;
|
||||||
|
|
||||||
|
// template
|
||||||
|
private final Collection<OfficeData> fromOfficeOptions;
|
||||||
|
private final Collection<ClientData> fromClientOptions;
|
||||||
|
private final Collection<SavingsAccountData> fromAccountOptions;
|
||||||
|
private final Collection<OfficeData> toOfficeOptions;
|
||||||
|
private final Collection<ClientData> toClientOptions;
|
||||||
|
private final Collection<SavingsAccountData> toAccountOptions;
|
||||||
|
|
||||||
|
public static AccountTransferData template(final OfficeData fromOffice, final ClientData fromClient,
|
||||||
|
final SavingsAccountData fromAccount, final LocalDate transferDate, final OfficeData toOffice, final ClientData toClient,
|
||||||
|
final SavingsAccountData toAccount, final Collection<OfficeData> fromOfficeOptions,
|
||||||
|
final Collection<ClientData> fromClientOptions, final Collection<SavingsAccountData> fromAccountOptions,
|
||||||
|
final Collection<OfficeData> toOfficeOptions, final Collection<ClientData> toClientOptions,
|
||||||
|
final Collection<SavingsAccountData> toAccountOptions) {
|
||||||
|
final Long id = null;
|
||||||
|
CurrencyData currency = null;
|
||||||
|
if (fromAccount != null) {
|
||||||
|
currency = fromAccount.currency();
|
||||||
|
}
|
||||||
|
|
||||||
|
final BigDecimal transferAmount = BigDecimal.ZERO;
|
||||||
|
final String transferDescription = null;
|
||||||
|
final Boolean reversed = null;
|
||||||
|
return new AccountTransferData(id, reversed, fromOffice, fromClient, fromAccount, currency, transferAmount, transferDate,
|
||||||
|
transferDescription, toOffice, toClient, toAccount, fromOfficeOptions, fromClientOptions, fromAccountOptions,
|
||||||
|
toOfficeOptions, toClientOptions, toAccountOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AccountTransferData instance(final Long id, final Boolean reversed, final LocalDate transferDate,
|
||||||
|
final CurrencyData currency, final BigDecimal transferAmount, final String transferDescription, final OfficeData fromOffice,
|
||||||
|
final OfficeData toOffice, final ClientData fromClient, final ClientData toClient, final SavingsAccountData fromSavingsAccount,
|
||||||
|
final SavingsAccountData toSavingsAccount) {
|
||||||
|
|
||||||
|
return new AccountTransferData(id, reversed, fromOffice, fromClient, fromSavingsAccount, currency, transferAmount, transferDate,
|
||||||
|
transferDescription, toOffice, toClient, toSavingsAccount, null, null, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AccountTransferData transferBasicDetails(final Long id, final CurrencyData currency, final BigDecimal transferAmount,
|
||||||
|
final LocalDate transferDate, final String description, final Boolean reversed) {
|
||||||
|
|
||||||
|
return new AccountTransferData(id, reversed, null, null, null, currency, transferAmount, transferDate, description, null, null,
|
||||||
|
null, null, null, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AccountTransferData(final Long id, final Boolean reversed, final OfficeData fromOffice, final ClientData fromClient,
|
||||||
|
final SavingsAccountData fromAccount, final CurrencyData currency, final BigDecimal transferAmount,
|
||||||
|
final LocalDate transferDate, final String transferDescription, final OfficeData toOffice, final ClientData toClient,
|
||||||
|
final SavingsAccountData toAccount, final Collection<OfficeData> fromOfficeOptions,
|
||||||
|
final Collection<ClientData> fromClientOptions, final Collection<SavingsAccountData> fromAccountOptions,
|
||||||
|
final Collection<OfficeData> toOfficeOptions, final Collection<ClientData> toClientOptions,
|
||||||
|
final Collection<SavingsAccountData> toAccountOptions) {
|
||||||
|
this.id = id;
|
||||||
|
this.reversed = reversed;
|
||||||
|
this.fromOffice = fromOffice;
|
||||||
|
this.fromClient = fromClient;
|
||||||
|
this.fromAccount = fromAccount;
|
||||||
|
this.toOffice = toOffice;
|
||||||
|
this.toClient = toClient;
|
||||||
|
this.toAccount = toAccount;
|
||||||
|
|
||||||
|
this.currency = currency;
|
||||||
|
this.transferAmount = transferAmount;
|
||||||
|
this.transferDate = transferDate;
|
||||||
|
this.transferDescription = transferDescription;
|
||||||
|
|
||||||
|
this.fromOfficeOptions = fromOfficeOptions;
|
||||||
|
this.fromClientOptions = fromClientOptions;
|
||||||
|
this.fromAccountOptions = fromAccountOptions;
|
||||||
|
this.toOfficeOptions = toOfficeOptions;
|
||||||
|
this.toClientOptions = toClientOptions;
|
||||||
|
this.toAccountOptions = toAccountOptions;
|
||||||
|
}
|
||||||
|
}
|
||||||
+108
@@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.data;
|
||||||
|
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.ACCOUNT_TRANSFER_RESOURCE_NAME;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.REQUEST_DATA_PARAMETERS;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.transferDescriptionParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.fromAccountIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.fromAccountTypeParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.fromClientIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.fromOfficeIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.toAccountIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.toAccountTypeParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.toClientIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.toOfficeIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.transferAmountParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.transferDateParamName;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AccountTransfersDataValidator {
|
||||||
|
|
||||||
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountTransfersDataValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||||
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(final JsonCommand command) {
|
||||||
|
|
||||||
|
final String json = command.json();
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||||
|
|
||||||
|
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||||
|
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, REQUEST_DATA_PARAMETERS);
|
||||||
|
|
||||||
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||||
|
.resource(ACCOUNT_TRANSFER_RESOURCE_NAME);
|
||||||
|
|
||||||
|
final JsonElement element = command.parsedJson();
|
||||||
|
|
||||||
|
final Long fromOfficeId = fromApiJsonHelper.extractLongNamed(fromOfficeIdParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(fromOfficeIdParamName).value(fromOfficeId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long fromClientId = fromApiJsonHelper.extractLongNamed(fromClientIdParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(fromClientIdParamName).value(fromClientId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long fromAccountId = fromApiJsonHelper.extractLongNamed(fromAccountIdParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(fromAccountIdParamName).value(fromAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Integer fromAccountType = fromApiJsonHelper.extractIntegerSansLocaleNamed(fromAccountTypeParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(fromAccountTypeParamName).value(fromAccountType)
|
||||||
|
.isOneOfTheseValues(Integer.valueOf(1), Integer.valueOf(2));
|
||||||
|
|
||||||
|
final Long toOfficeId = fromApiJsonHelper.extractLongNamed(toOfficeIdParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(toOfficeIdParamName).value(toOfficeId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long toClientId = fromApiJsonHelper.extractLongNamed(toClientIdParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(toClientIdParamName).value(toClientId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long toAccountId = fromApiJsonHelper.extractLongNamed(toAccountIdParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(toAccountIdParamName).value(toAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Integer toAccountType = fromApiJsonHelper.extractIntegerSansLocaleNamed(toAccountTypeParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(toAccountTypeParamName).value(toAccountType)
|
||||||
|
.isOneOfTheseValues(Integer.valueOf(1), Integer.valueOf(2));
|
||||||
|
|
||||||
|
final LocalDate transactionDate = fromApiJsonHelper.extractLocalDateNamed(transferDateParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(transferDateParamName).value(transactionDate).notNull();
|
||||||
|
|
||||||
|
final BigDecimal transactionAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(transferAmountParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(transferAmountParamName).value(transactionAmount).notNull().positiveAmount();
|
||||||
|
|
||||||
|
final String transactionDescription = fromApiJsonHelper.extractStringNamed(transferDescriptionParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(transferDescriptionParamName).value(transactionDescription).notBlank().notExceedingLengthOf(200);
|
||||||
|
|
||||||
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||||
|
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||||
|
}
|
||||||
|
}
|
||||||
+111
@@ -0,0 +1,111 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.domain;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
|
||||||
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "m_savings_account_transfer")
|
||||||
|
public class AccountTransfer extends AbstractPersistable<Long> {
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "from_office_id", nullable = false)
|
||||||
|
private Office fromOffice;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "from_client_id", nullable = false)
|
||||||
|
private Client fromClient;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "from_savings_account_id", nullable = true)
|
||||||
|
private SavingsAccount fromAccount;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "to_office_id", nullable = false)
|
||||||
|
private Office toOffice;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "to_client_id", nullable = false)
|
||||||
|
private Client toClient;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "to_savings_account_id", nullable = true)
|
||||||
|
private SavingsAccount toAccount;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "from_savings_transaction_id", nullable = true)
|
||||||
|
private SavingsAccountTransaction fromTransaction;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "to_savings_transaction_id", nullable = true)
|
||||||
|
private SavingsAccountTransaction toSavingsTransaction;
|
||||||
|
|
||||||
|
@Column(name = "is_reversed", nullable = false)
|
||||||
|
private final boolean reversed = false;
|
||||||
|
|
||||||
|
@Temporal(TemporalType.DATE)
|
||||||
|
@Column(name = "transaction_date")
|
||||||
|
private Date date;
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
private MonetaryCurrency currency;
|
||||||
|
|
||||||
|
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
||||||
|
private BigDecimal amount;
|
||||||
|
|
||||||
|
@Column(name = "description", length = 100)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public static AccountTransfer savingsToSavingsTransfer(final Office fromOffice, final Client fromClient,
|
||||||
|
final SavingsAccount fromSavingsAccount, final Office toOffice, final Client toClient, final SavingsAccount toSavingsAccount,
|
||||||
|
final SavingsAccountTransaction withdrawal, final SavingsAccountTransaction deposit, final LocalDate transactionDate,
|
||||||
|
final Money transactionAmount, final String description) {
|
||||||
|
|
||||||
|
return new AccountTransfer(fromOffice, fromClient, fromSavingsAccount, toOffice, toClient, toSavingsAccount, withdrawal, deposit,
|
||||||
|
transactionDate, transactionAmount, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AccountTransfer() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
private AccountTransfer(final Office fromOffice, final Client fromClient, final SavingsAccount fromSavingsAccount,
|
||||||
|
final Office toOffice, final Client toClient, final SavingsAccount toSavingsAccount,
|
||||||
|
final SavingsAccountTransaction withdrawal, final SavingsAccountTransaction deposit, final LocalDate transactionDate,
|
||||||
|
final Money transactionAmount, final String description) {
|
||||||
|
this.fromOffice = fromOffice;
|
||||||
|
this.fromClient = fromClient;
|
||||||
|
this.fromAccount = fromSavingsAccount;
|
||||||
|
this.toOffice = toOffice;
|
||||||
|
this.toClient = toClient;
|
||||||
|
this.toAccount = toSavingsAccount;
|
||||||
|
this.fromTransaction = withdrawal;
|
||||||
|
this.toSavingsTransaction = deposit;
|
||||||
|
this.date = transactionDate.toDate();
|
||||||
|
this.currency = transactionAmount.getCurrency();
|
||||||
|
this.amount = transactionAmount.getAmountDefaultedToNullIfZero();
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.domain;
|
||||||
|
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.transferDescriptionParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.fromAccountIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.fromClientIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.fromOfficeIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.toAccountIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.toClientIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.toOfficeIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.transferAmountParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.transferDateParamName;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
|
import org.mifosplatform.organisation.office.domain.OfficeRepository;
|
||||||
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
|
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AccountTransferAssembler {
|
||||||
|
|
||||||
|
private final ClientRepositoryWrapper clientRepository;
|
||||||
|
private final OfficeRepository officeRepository;
|
||||||
|
private final SavingsAccountAssembler savingsAccountAssembler;
|
||||||
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountTransferAssembler(final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository,
|
||||||
|
final SavingsAccountAssembler savingsAccountAssembler, final FromJsonHelper fromApiJsonHelper) {
|
||||||
|
this.clientRepository = clientRepository;
|
||||||
|
this.officeRepository = officeRepository;
|
||||||
|
this.savingsAccountAssembler = savingsAccountAssembler;
|
||||||
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountTransfer assembleSavingsToSavingsTransfer(final JsonCommand command, final SavingsAccountTransaction withdrawal,
|
||||||
|
final SavingsAccountTransaction deposit) {
|
||||||
|
|
||||||
|
final JsonElement element = command.parsedJson();
|
||||||
|
|
||||||
|
final Long fromOfficeId = fromApiJsonHelper.extractLongNamed(fromOfficeIdParamName, element);
|
||||||
|
final Office fromOffice = this.officeRepository.findOne(fromOfficeId);
|
||||||
|
|
||||||
|
final Long fromClientId = fromApiJsonHelper.extractLongNamed(fromClientIdParamName, element);
|
||||||
|
final Client fromClient = this.clientRepository.findOneWithNotFoundDetection(fromClientId);
|
||||||
|
|
||||||
|
final Long fromSavingsId = command.longValueOfParameterNamed(fromAccountIdParamName);
|
||||||
|
final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsId);
|
||||||
|
|
||||||
|
final Long toOfficeId = fromApiJsonHelper.extractLongNamed(toOfficeIdParamName, element);
|
||||||
|
final Office toOffice = this.officeRepository.findOne(toOfficeId);
|
||||||
|
|
||||||
|
final Long toClientId = fromApiJsonHelper.extractLongNamed(toClientIdParamName, element);
|
||||||
|
final Client toClient = this.clientRepository.findOneWithNotFoundDetection(toClientId);
|
||||||
|
|
||||||
|
final Long toSavingsId = command.longValueOfParameterNamed(toAccountIdParamName);
|
||||||
|
final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsId);
|
||||||
|
|
||||||
|
final LocalDate transactionDate = command.localDateValueOfParameterNamed(transferDateParamName);
|
||||||
|
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed(transferAmountParamName);
|
||||||
|
final Money transactionMonetaryAmount = Money.of(fromSavingsAccount.getCurrency(), transactionAmount);
|
||||||
|
|
||||||
|
final String description = command.stringValueOfParameterNamed(transferDescriptionParamName);
|
||||||
|
|
||||||
|
return AccountTransfer.savingsToSavingsTransfer(fromOffice, fromClient, fromSavingsAccount, toOffice, toClient, toSavingsAccount,
|
||||||
|
withdrawal, deposit, transactionDate, transactionMonetaryAmount, description);
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.domain;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
public interface AccountTransferRepository extends JpaRepository<AccountTransfer, Long>, JpaSpecificationExecutor<AccountTransfer> {
|
||||||
|
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||||
|
|
||||||
|
public class AccountTransferNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
|
public AccountTransferNotFoundException(final Long id) {
|
||||||
|
super("error.msg.accounttransfer.id.invalid", "Account transfer with identifier " + id + " does not exist", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.handler;
|
||||||
|
|
||||||
|
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.service.AccountTransfersWritePlatformService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CreateAccountTransferCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final AccountTransfersWritePlatformService writePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CreateAccountTransferCommandHandler(final AccountTransfersWritePlatformService writePlatformService) {
|
||||||
|
this.writePlatformService = writePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
|
||||||
|
return writePlatformService.create(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.service;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.service.Page;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.data.AccountTransferData;
|
||||||
|
import org.mifosplatform.portfolio.group.service.SearchParameters;
|
||||||
|
|
||||||
|
public interface AccountTransfersReadPlatformService {
|
||||||
|
|
||||||
|
AccountTransferData retrieveTemplate(Long fromOfficeId, Long fromClientId, Long fromAccountId, Integer fromAccountType,
|
||||||
|
Long toOfficeId, Long toClientId, Long toAccountId, Integer toAccountType);
|
||||||
|
|
||||||
|
Page<AccountTransferData> retrieveAll(SearchParameters searchParameters);
|
||||||
|
|
||||||
|
AccountTransferData retrieveOne(Long transferId);
|
||||||
|
}
|
||||||
+291
@@ -0,0 +1,291 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.commands.exception.UnsupportedCommandException;
|
||||||
|
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||||
|
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||||
|
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.monetary.data.CurrencyData;
|
||||||
|
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||||
|
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.data.AccountTransferData;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.exception.AccountTransferNotFoundException;
|
||||||
|
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||||
|
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
||||||
|
import org.mifosplatform.portfolio.group.service.SearchParameters;
|
||||||
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
||||||
|
import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.EmptyResultDataAccessException;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AccountTransfersReadPlatformServiceImpl implements AccountTransfersReadPlatformService {
|
||||||
|
|
||||||
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
private final ClientReadPlatformService clientReadPlatformService;
|
||||||
|
private final OfficeReadPlatformService officeReadPlatformService;
|
||||||
|
private final SavingsAccountReadPlatformService savingsAccountReadPlatformService;
|
||||||
|
|
||||||
|
// mapper
|
||||||
|
private final AccountTransfersMapper accountTransfersMapper;
|
||||||
|
|
||||||
|
// pagination
|
||||||
|
private final PaginationHelper<AccountTransferData> paginationHelper = new PaginationHelper<AccountTransferData>();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountTransfersReadPlatformServiceImpl(final RoutingDataSource dataSource,
|
||||||
|
final ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService,
|
||||||
|
final SavingsAccountReadPlatformService savingsAccountReadPlatformService) {
|
||||||
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
|
this.clientReadPlatformService = clientReadPlatformService;
|
||||||
|
this.officeReadPlatformService = officeReadPlatformService;
|
||||||
|
this.savingsAccountReadPlatformService = savingsAccountReadPlatformService;
|
||||||
|
|
||||||
|
this.accountTransfersMapper = new AccountTransfersMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccountTransferData 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 mostRelevantFromAccountType = fromAccountType;
|
||||||
|
if (mostRelevantFromAccountType == null) {
|
||||||
|
mostRelevantFromAccountType = 2; // savings
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer mostRelevantToAccountType = toAccountType;
|
||||||
|
if (mostRelevantToAccountType == null) {
|
||||||
|
mostRelevantToAccountType = 2; // savings
|
||||||
|
}
|
||||||
|
// check for now that only savings account type is passed and used.
|
||||||
|
if (mostRelevantFromAccountType != 2) { throw new UnsupportedCommandException("transferFromLoanAccount"); }
|
||||||
|
|
||||||
|
// from settings
|
||||||
|
OfficeData fromOffice = null;
|
||||||
|
ClientData fromClient = null;
|
||||||
|
SavingsAccountData fromAccount = null;
|
||||||
|
|
||||||
|
OfficeData toOffice = null;
|
||||||
|
ClientData toClient = null;
|
||||||
|
SavingsAccountData toAccount = null;
|
||||||
|
|
||||||
|
// template
|
||||||
|
Collection<SavingsAccountData> fromAccountOptions = null;
|
||||||
|
Collection<SavingsAccountData> toAccountOptions = null;
|
||||||
|
|
||||||
|
Long mostRelevantFromOfficeId = fromOfficeId;
|
||||||
|
Long mostRelevantFromClientId = fromClientId;
|
||||||
|
|
||||||
|
Long mostRelevantToOfficeId = toOfficeId;
|
||||||
|
Long mostRelevantToClientId = toClientId;
|
||||||
|
|
||||||
|
if (fromAccountId != null && fromAccountType == 2) {
|
||||||
|
fromAccount = this.savingsAccountReadPlatformService.retrieveOne(fromAccountId);
|
||||||
|
|
||||||
|
// override provided fromClient with client of account
|
||||||
|
mostRelevantFromClientId = fromAccount.clientId();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mostRelevantFromClientId != null) {
|
||||||
|
fromClient = this.clientReadPlatformService.retrieveOne(mostRelevantFromClientId);
|
||||||
|
mostRelevantFromOfficeId = fromClient.officeId();
|
||||||
|
toClient = fromClient;
|
||||||
|
fromAccountOptions = this.savingsAccountReadPlatformService.retrieveAllForLookup(mostRelevantFromClientId);
|
||||||
|
toAccountOptions = new ArrayList<SavingsAccountData>(fromAccountOptions);
|
||||||
|
toAccountOptions.remove(fromAccount);
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<OfficeData> fromOfficeOptions = null;
|
||||||
|
Collection<ClientData> fromClientOptions = null;
|
||||||
|
if (mostRelevantFromOfficeId != null) {
|
||||||
|
fromOffice = this.officeReadPlatformService.retrieveOffice(mostRelevantFromOfficeId);
|
||||||
|
fromOfficeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown();
|
||||||
|
fromClientOptions = this.clientReadPlatformService.retrieveAllForLookupByOfficeId(mostRelevantFromOfficeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaults
|
||||||
|
LocalDate transferDate = DateUtils.getLocalDateOfTenant();
|
||||||
|
toOffice = fromOffice;
|
||||||
|
Collection<OfficeData> toOfficeOptions = fromOfficeOptions;
|
||||||
|
Collection<ClientData> toClientOptions = fromClientOptions;
|
||||||
|
|
||||||
|
if (toAccountId != null) {
|
||||||
|
toAccount = this.savingsAccountReadPlatformService.retrieveOne(toAccountId);
|
||||||
|
|
||||||
|
// override provided toClient with client of account
|
||||||
|
mostRelevantToClientId = toAccount.clientId();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mostRelevantToClientId != null && mostRelevantToClientId != mostRelevantFromClientId) {
|
||||||
|
toClient = this.clientReadPlatformService.retrieveOne(mostRelevantToClientId);
|
||||||
|
mostRelevantToOfficeId = toClient.officeId();
|
||||||
|
|
||||||
|
toClientOptions = this.clientReadPlatformService.retrieveAllForLookupByOfficeId(mostRelevantToOfficeId);
|
||||||
|
|
||||||
|
toAccountOptions = this.savingsAccountReadPlatformService.retrieveAllForLookup(mostRelevantToClientId);
|
||||||
|
toAccountOptions.remove(fromAccount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mostRelevantToOfficeId != null && mostRelevantToOfficeId != mostRelevantFromOfficeId) {
|
||||||
|
toOffice = this.officeReadPlatformService.retrieveOffice(mostRelevantToOfficeId);
|
||||||
|
toOfficeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown();
|
||||||
|
|
||||||
|
toClientOptions = this.clientReadPlatformService.retrieveAllForLookupByOfficeId(mostRelevantToOfficeId);
|
||||||
|
if (toClientOptions != null && toClientOptions.size() == 1) {
|
||||||
|
toClient = new ArrayList<ClientData>(toClientOptions).get(0);
|
||||||
|
|
||||||
|
toAccountOptions = this.savingsAccountReadPlatformService.retrieveAllForLookup(mostRelevantToClientId);
|
||||||
|
toAccountOptions.remove(fromAccount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AccountTransferData.template(fromOffice, fromClient, fromAccount, transferDate, toOffice, toClient, toAccount,
|
||||||
|
fromOfficeOptions, fromClientOptions, fromAccountOptions, toOfficeOptions, toClientOptions, toAccountOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<AccountTransferData> retrieveAll(final SearchParameters searchParameters) {
|
||||||
|
|
||||||
|
StringBuilder sqlBuilder = new StringBuilder(200);
|
||||||
|
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
|
||||||
|
sqlBuilder.append(accountTransfersMapper.schema());
|
||||||
|
|
||||||
|
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[] objectArray = new Object[2];
|
||||||
|
int arrayPos = 0;
|
||||||
|
final Object[] finalObjectArray = Arrays.copyOf(objectArray, arrayPos);
|
||||||
|
final String sqlCountRows = "SELECT FOUND_ROWS()";
|
||||||
|
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray,
|
||||||
|
this.accountTransfersMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccountTransferData retrieveOne(final Long transferId) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
final String sql = "select " + this.accountTransfersMapper.schema() + " where sat.id = ?";
|
||||||
|
|
||||||
|
return this.jdbcTemplate.queryForObject(sql, this.accountTransfersMapper, new Object[] { transferId });
|
||||||
|
} catch (EmptyResultDataAccessException e) {
|
||||||
|
throw new AccountTransferNotFoundException(transferId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class AccountTransfersMapper implements RowMapper<AccountTransferData> {
|
||||||
|
|
||||||
|
private final String schemaSql;
|
||||||
|
|
||||||
|
public AccountTransfersMapper() {
|
||||||
|
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||||
|
sqlBuilder.append("sat.id as id, sat.is_reversed as isReversed,");
|
||||||
|
sqlBuilder.append("sat.transaction_date as transferDate, sat.amount as transferAmount,");
|
||||||
|
sqlBuilder.append("sat.description as transferDescription,");
|
||||||
|
sqlBuilder.append("sat.currency_code as currencyCode, sat.currency_digits as currencyDigits,");
|
||||||
|
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||||
|
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||||
|
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("tosavacc.id as toSavingsAccountId, tosavacc.account_no as toSavingsAccountNo,");
|
||||||
|
sqlBuilder.append("fromsavtran.id as fromSavingsAccountTransactionId,");
|
||||||
|
sqlBuilder.append("fromsavtran.transaction_type_enum as fromSavingsAccountTransactionType,");
|
||||||
|
sqlBuilder.append("tosavtran.id as toSavingsAccountTransactionId,");
|
||||||
|
sqlBuilder.append("tosavtran.transaction_type_enum as toSavingsAccountTransactionType");
|
||||||
|
sqlBuilder.append(" FROM m_savings_account_transfer sat ");
|
||||||
|
sqlBuilder.append("join m_currency curr on curr.code = sat.currency_code ");
|
||||||
|
sqlBuilder.append("join m_office fromoff on fromoff.id = sat.from_office_id ");
|
||||||
|
sqlBuilder.append("join m_office tooff on tooff.id = sat.to_office_id ");
|
||||||
|
sqlBuilder.append("join m_client fromclient on fromclient.id = sat.from_client_id ");
|
||||||
|
sqlBuilder.append("join m_client toclient on toclient.id = sat.to_client_id ");
|
||||||
|
sqlBuilder.append("left join m_savings_account fromsavacc on fromsavacc.id = sat.from_savings_account_id ");
|
||||||
|
sqlBuilder.append("left join m_savings_account tosavacc on tosavacc.id = sat.to_savings_account_id ");
|
||||||
|
sqlBuilder.append("left join m_savings_account_transaction fromsavtran on fromsavtran.id = sat.from_savings_transaction_id ");
|
||||||
|
sqlBuilder.append("left join m_savings_account_transaction tosavtran on tosavtran.id = sat.to_savings_transaction_id ");
|
||||||
|
|
||||||
|
this.schemaSql = sqlBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String schema() {
|
||||||
|
return this.schemaSql;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccountTransferData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||||
|
|
||||||
|
final Long id = rs.getLong("id");
|
||||||
|
final boolean reversed = rs.getBoolean("isReversed");
|
||||||
|
|
||||||
|
final LocalDate transferDate = JdbcSupport.getLocalDate(rs, "transferDate");
|
||||||
|
final BigDecimal transferAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "transferAmount");
|
||||||
|
final String transferDescription = rs.getString("transferDescription");
|
||||||
|
|
||||||
|
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 CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||||
|
currencyNameCode);
|
||||||
|
|
||||||
|
final Long fromOfficeId = JdbcSupport.getLong(rs, "fromOfficeId");
|
||||||
|
final String fromOfficeName = rs.getString("fromOfficeName");
|
||||||
|
OfficeData fromOffice = OfficeData.dropdown(fromOfficeId, fromOfficeName, null);
|
||||||
|
|
||||||
|
final Long toOfficeId = JdbcSupport.getLong(rs, "toOfficeId");
|
||||||
|
final String toOfficeName = rs.getString("toOfficeName");
|
||||||
|
OfficeData toOffice = OfficeData.dropdown(toOfficeId, toOfficeName, null);
|
||||||
|
|
||||||
|
final Long fromClientId = JdbcSupport.getLong(rs, "fromClientId");
|
||||||
|
final String fromClientName = rs.getString("fromClientName");
|
||||||
|
ClientData fromClient = ClientData.lookup(fromClientId, fromClientName, fromOfficeId, fromOfficeName);
|
||||||
|
|
||||||
|
final Long toClientId = JdbcSupport.getLong(rs, "toClientId");
|
||||||
|
final String toClientName = rs.getString("toClientName");
|
||||||
|
ClientData toClient = ClientData.lookup(toClientId, toClientName, toOfficeId, toOfficeName);
|
||||||
|
|
||||||
|
final Long fromSavingsAccountId = JdbcSupport.getLong(rs, "fromSavingsAccountId");
|
||||||
|
final String fromSavingsAccountNo = rs.getString("fromSavingsAccountNo");
|
||||||
|
SavingsAccountData fromSavingsAccount = SavingsAccountData.lookup(fromSavingsAccountId, fromSavingsAccountNo);
|
||||||
|
|
||||||
|
final Long toSavingsAccountId = JdbcSupport.getLong(rs, "toSavingsAccountId");
|
||||||
|
final String toSavingsAccountNo = rs.getString("toSavingsAccountNo");
|
||||||
|
SavingsAccountData toSavingsAccount = SavingsAccountData.lookup(toSavingsAccountId, toSavingsAccountNo);
|
||||||
|
|
||||||
|
return AccountTransferData.instance(id, reversed, transferDate, currency, transferAmount, transferDescription, fromOffice,
|
||||||
|
toOffice, fromClient, toClient, fromSavingsAccount, toSavingsAccount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.service;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
|
||||||
|
public interface AccountTransfersWritePlatformService {
|
||||||
|
|
||||||
|
CommandProcessingResult create(JsonCommand command);
|
||||||
|
}
|
||||||
+91
@@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
* 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.accounttransfers.service;
|
||||||
|
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.fromAccountIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.toAccountIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.transferAmountParamName;
|
||||||
|
import static org.mifosplatform.portfolio.accounttransfers.AccountTransfersApiConstants.transferDateParamName;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.joda.time.format.DateTimeFormat;
|
||||||
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.data.AccountTransfersDataValidator;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.domain.AccountTransfer;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.domain.AccountTransferAssembler;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.domain.AccountTransferRepository;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountDomainService;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AccountTransfersWritePlatformServiceImpl implements AccountTransfersWritePlatformService {
|
||||||
|
|
||||||
|
private final AccountTransfersDataValidator accountTransfersDataValidator;
|
||||||
|
private final AccountTransferAssembler accountTransferAssembler;
|
||||||
|
private final AccountTransferRepository accountTransferRepository;
|
||||||
|
private final SavingsAccountAssembler savingsAccountAssembler;
|
||||||
|
private final SavingsAccountDomainService savingsAccountDomainService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountTransfersWritePlatformServiceImpl(final AccountTransfersDataValidator accountTransfersDataValidator,
|
||||||
|
final AccountTransferAssembler accountTransferAssembler, final AccountTransferRepository accountTransferRepository,
|
||||||
|
final SavingsAccountAssembler savingsAccountAssembler, final SavingsAccountDomainService savingsAccountDomainService) {
|
||||||
|
this.accountTransfersDataValidator = accountTransfersDataValidator;
|
||||||
|
this.accountTransferAssembler = accountTransferAssembler;
|
||||||
|
this.accountTransferRepository = accountTransferRepository;
|
||||||
|
this.savingsAccountAssembler = savingsAccountAssembler;
|
||||||
|
this.savingsAccountDomainService = savingsAccountDomainService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult create(final JsonCommand command) {
|
||||||
|
|
||||||
|
this.accountTransfersDataValidator.validate(command);
|
||||||
|
|
||||||
|
final LocalDate transactionDate = command.localDateValueOfParameterNamed(transferDateParamName);
|
||||||
|
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed(transferAmountParamName);
|
||||||
|
|
||||||
|
final Locale locale = command.extractLocale();
|
||||||
|
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||||
|
|
||||||
|
// check fromAccountType settings to see if its a savings account
|
||||||
|
// withdrawal or a loan account transfer
|
||||||
|
final Long fromSavingsId = command.longValueOfParameterNamed(fromAccountIdParamName);
|
||||||
|
final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsId);
|
||||||
|
|
||||||
|
final PaymentDetail paymentDetail = null;
|
||||||
|
|
||||||
|
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, fmt,
|
||||||
|
transactionDate, transactionAmount, paymentDetail);
|
||||||
|
|
||||||
|
final Long toSavingsId = command.longValueOfParameterNamed(toAccountIdParamName);
|
||||||
|
final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsId);
|
||||||
|
|
||||||
|
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, fmt, transactionDate,
|
||||||
|
transactionAmount, paymentDetail);
|
||||||
|
|
||||||
|
AccountTransfer transferTransaction = this.accountTransferAssembler.assembleSavingsToSavingsTransfer(command, withdrawal, deposit);
|
||||||
|
this.accountTransferRepository.saveAndFlush(transferTransaction);
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder() //
|
||||||
|
.withSavingsId(fromSavingsId) //
|
||||||
|
.withEntityId(transferTransaction.getId()) //
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-9
@@ -23,7 +23,6 @@ import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
|||||||
*/
|
*/
|
||||||
final public class ClientData implements Comparable<ClientData> {
|
final public class ClientData implements Comparable<ClientData> {
|
||||||
|
|
||||||
|
|
||||||
private final Long id;
|
private final Long id;
|
||||||
private final String accountNo;
|
private final String accountNo;
|
||||||
private final String externalId;
|
private final String externalId;
|
||||||
@@ -58,7 +57,8 @@ final public class ClientData implements Comparable<ClientData> {
|
|||||||
|
|
||||||
public static ClientData template(final Long officeId, final LocalDate joinedDate, final Collection<OfficeData> officeOptions,
|
public static ClientData template(final Long officeId, final LocalDate joinedDate, final Collection<OfficeData> officeOptions,
|
||||||
final Collection<StaffData> staffOptions, final Collection<CodeValueData> closureReasons) {
|
final Collection<StaffData> staffOptions, final Collection<CodeValueData> closureReasons) {
|
||||||
return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, joinedDate, null, null, null, officeOptions, null, staffOptions, closureReasons);
|
return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, joinedDate, null, null, null,
|
||||||
|
officeOptions, null, staffOptions, closureReasons);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClientData templateOnTop(final ClientData clientData, final ClientData templateData) {
|
public static ClientData templateOnTop(final ClientData clientData, final ClientData templateData) {
|
||||||
@@ -81,11 +81,12 @@ final public class ClientData implements Comparable<ClientData> {
|
|||||||
final String officeName) {
|
final String officeName) {
|
||||||
|
|
||||||
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, null,
|
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, null,
|
||||||
null, null, null, null, null, null,null, null);
|
null, null, null, null, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClientData lookup(final Long id, final String displayName, final Long officeId, final String officeName) {
|
public static ClientData lookup(final Long id, final String displayName, final Long officeId, final String officeName) {
|
||||||
return new ClientData(null, null, officeId, officeName, id, null, null, null, null, displayName, null, null, null, null, null, null, null, null, null);
|
return new ClientData(null, null, officeId, officeName, id, null, null, null, null, displayName, null, null, null, null, null,
|
||||||
|
null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClientData instance(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName,
|
public static ClientData instance(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName,
|
||||||
@@ -99,8 +100,8 @@ final public class ClientData implements Comparable<ClientData> {
|
|||||||
private ClientData(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName, final Long id,
|
private ClientData(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName, final Long id,
|
||||||
final String firstname, final String middlename, final String lastname, final String fullname, final String displayName,
|
final String firstname, final String middlename, final String lastname, final String fullname, final String displayName,
|
||||||
final String externalId, final LocalDate activationDate, final Long imageId, final Long staffId, final String staffName,
|
final String externalId, final LocalDate activationDate, final Long imageId, final Long staffId, final String staffName,
|
||||||
final Collection<OfficeData> allowedOffices, final Collection<GroupGeneralData> groups, final Collection<StaffData> staffOptions,
|
final Collection<OfficeData> allowedOffices, final Collection<GroupGeneralData> groups,
|
||||||
final Collection<CodeValueData> closureReasons) {
|
final Collection<StaffData> staffOptions, final Collection<CodeValueData> closureReasons) {
|
||||||
this.accountNo = accountNo;
|
this.accountNo = accountNo;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
if (status != null) {
|
if (status != null) {
|
||||||
@@ -122,7 +123,7 @@ final public class ClientData implements Comparable<ClientData> {
|
|||||||
if (imageId != null) {
|
if (imageId != null) {
|
||||||
this.imagePresent = Boolean.TRUE;
|
this.imagePresent = Boolean.TRUE;
|
||||||
} else {
|
} else {
|
||||||
this.imagePresent = Boolean.FALSE;
|
this.imagePresent = null;
|
||||||
}
|
}
|
||||||
this.staffId = staffId;
|
this.staffId = staffId;
|
||||||
this.staffName = staffName;
|
this.staffName = staffName;
|
||||||
@@ -189,7 +190,6 @@ final public class ClientData implements Comparable<ClientData> {
|
|||||||
.toHashCode();
|
.toHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - kw - look into removing usage of the getters below
|
|
||||||
public String getExternalId() {
|
public String getExternalId() {
|
||||||
return this.externalId;
|
return this.externalId;
|
||||||
}
|
}
|
||||||
@@ -205,5 +205,4 @@ final public class ClientData implements Comparable<ClientData> {
|
|||||||
public LocalDate getActivationDate() {
|
public LocalDate getActivationDate() {
|
||||||
return this.activationDate;
|
return this.activationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+41
@@ -8,6 +8,8 @@ package org.mifosplatform.portfolio.savings.data;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.joda.time.MonthDay;
|
import org.joda.time.MonthDay;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
@@ -93,6 +95,26 @@ public class SavingsAccountData {
|
|||||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions);
|
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SavingsAccountData lookup(final Long accountId, final String accountNo) {
|
||||||
|
|
||||||
|
final Collection<SavingsProductData> productOptions = null;
|
||||||
|
final Collection<StaffData> fieldOfficerOptions = null;
|
||||||
|
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||||
|
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
|
||||||
|
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||||
|
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||||
|
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||||
|
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
|
||||||
|
|
||||||
|
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||||
|
|
||||||
|
return new SavingsAccountData(accountId, accountNo, null, null, null, null, null, null, null, null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null, null, null, null, null, null, null, null, transactions, productOptions,
|
||||||
|
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
|
||||||
|
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
|
||||||
|
withdrawalFeeTypeOptions);
|
||||||
|
}
|
||||||
|
|
||||||
public static SavingsAccountData withTemplateOptions(final SavingsAccountData account, final SavingsAccountData template,
|
public static SavingsAccountData withTemplateOptions(final SavingsAccountData account, final SavingsAccountData template,
|
||||||
final Collection<SavingsAccountTransactionData> transactions) {
|
final Collection<SavingsAccountTransactionData> transactions) {
|
||||||
|
|
||||||
@@ -263,4 +285,23 @@ public class SavingsAccountData {
|
|||||||
public Long productId() {
|
public Long productId() {
|
||||||
return this.savingsProductId;
|
return this.savingsProductId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CurrencyData currency() {
|
||||||
|
return this.currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
|
||||||
|
if (obj == null) { return false; }
|
||||||
|
if (obj == this) { return true; }
|
||||||
|
if (obj.getClass() != getClass()) { return false; }
|
||||||
|
SavingsAccountData rhs = (SavingsAccountData) obj;
|
||||||
|
return new EqualsBuilder().append(this.id, rhs.id).append(this.accountNo, rhs.accountNo).isEquals();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return new HashCodeBuilder(17, 37).append(this.id).append(this.accountNo).toHashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+9
-5
@@ -11,6 +11,7 @@ import java.util.Collection;
|
|||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.data.AccountTransferData;
|
||||||
import org.mifosplatform.portfolio.paymentdetail.data.PaymentDetailData;
|
import org.mifosplatform.portfolio.paymentdetail.data.PaymentDetailData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,16 +30,18 @@ public class SavingsAccountTransactionData {
|
|||||||
private final BigDecimal amount;
|
private final BigDecimal amount;
|
||||||
private final BigDecimal runningBalance;
|
private final BigDecimal runningBalance;
|
||||||
private final boolean reversed;
|
private final boolean reversed;
|
||||||
|
private final AccountTransferData transfer;
|
||||||
|
|
||||||
// templates
|
// templates
|
||||||
final Collection<CodeValueData> paymentTypeOptions;
|
final Collection<CodeValueData> paymentTypeOptions;
|
||||||
|
|
||||||
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||||
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
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 runningBalance, final boolean reversed,
|
||||||
|
final AccountTransferData transfer) {
|
||||||
final Collection<CodeValueData> paymentTypeOptions = null;
|
final Collection<CodeValueData> paymentTypeOptions = null;
|
||||||
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
|
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
|
||||||
amount, runningBalance, reversed, paymentTypeOptions);
|
amount, runningBalance, reversed, transfer, paymentTypeOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo,
|
public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo,
|
||||||
@@ -51,7 +54,7 @@ public class SavingsAccountTransactionData {
|
|||||||
final PaymentDetailData paymentDetailData = null;
|
final PaymentDetailData paymentDetailData = null;
|
||||||
final Collection<CodeValueData> paymentTypeOptions = null;
|
final Collection<CodeValueData> paymentTypeOptions = null;
|
||||||
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, defaultLocalDate,
|
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, defaultLocalDate,
|
||||||
currency, amount, runningBalance, reversed, null);
|
currency, amount, runningBalance, reversed, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTransactionData savingsAccountTransactionData,
|
public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTransactionData savingsAccountTransactionData,
|
||||||
@@ -60,13 +63,13 @@ public class SavingsAccountTransactionData {
|
|||||||
savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId,
|
savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId,
|
||||||
savingsAccountTransactionData.accountNo, savingsAccountTransactionData.date, savingsAccountTransactionData.currency,
|
savingsAccountTransactionData.accountNo, savingsAccountTransactionData.date, savingsAccountTransactionData.currency,
|
||||||
savingsAccountTransactionData.amount, savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed,
|
savingsAccountTransactionData.amount, savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed,
|
||||||
paymentTypeOptions);
|
savingsAccountTransactionData.transfer, paymentTypeOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||||
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
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 runningBalance, final boolean reversed,
|
||||||
final Collection<CodeValueData> paymentTypeOptions) {
|
final AccountTransferData transfer, final Collection<CodeValueData> paymentTypeOptions) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.transactionType = transactionType;
|
this.transactionType = transactionType;
|
||||||
this.paymentDetailData = paymentDetailData;
|
this.paymentDetailData = paymentDetailData;
|
||||||
@@ -77,6 +80,7 @@ public class SavingsAccountTransactionData {
|
|||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.runningBalance = runningBalance;
|
this.runningBalance = runningBalance;
|
||||||
this.reversed = reversed;
|
this.reversed = reversed;
|
||||||
|
this.transfer = transfer;
|
||||||
this.paymentTypeOptions = paymentTypeOptions;
|
this.paymentTypeOptions = paymentTypeOptions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -699,7 +699,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
boolean transactionBeforeLastInterestPosting = false;
|
boolean transactionBeforeLastInterestPosting = false;
|
||||||
|
|
||||||
for (SavingsAccountTransaction transaction : retreiveListOfTransactions()) {
|
for (SavingsAccountTransaction transaction : retreiveListOfTransactions()) {
|
||||||
if (transaction.isNotReversed() && transaction.isInterestPostingAndNotReversed() && transaction.isAfter(transactionDate)) {
|
if (transaction.isInterestPostingAndNotReversed() && transaction.isAfter(transactionDate)) {
|
||||||
transactionBeforeLastInterestPosting = true;
|
transactionBeforeLastInterestPosting = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* 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.savings.domain;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
|
|
||||||
|
public interface SavingsAccountDomainService {
|
||||||
|
|
||||||
|
SavingsAccountTransaction handleWithdrawal(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
|
||||||
|
BigDecimal transactionAmount, PaymentDetail paymentDetail);
|
||||||
|
|
||||||
|
SavingsAccountTransaction handleDeposit(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
|
||||||
|
BigDecimal transactionAmount, PaymentDetail paymentDetail);
|
||||||
|
}
|
||||||
+117
@@ -0,0 +1,117 @@
|
|||||||
|
/**
|
||||||
|
* 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.savings.domain;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
|
import org.mifosplatform.accounting.journalentry.service.JournalEntryWritePlatformService;
|
||||||
|
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainService {
|
||||||
|
|
||||||
|
private final SavingsAccountRepositoryWrapper savingsAccountRepository;
|
||||||
|
private final SavingsAccountTransactionRepository savingsAccountTransactionRepository;
|
||||||
|
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper;
|
||||||
|
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SavingsAccountDomainServiceJpa(final SavingsAccountRepositoryWrapper savingsAccountRepository,
|
||||||
|
final SavingsAccountTransactionRepository savingsAccountTransactionRepository,
|
||||||
|
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
|
||||||
|
final JournalEntryWritePlatformService journalEntryWritePlatformService) {
|
||||||
|
this.savingsAccountRepository = savingsAccountRepository;
|
||||||
|
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
||||||
|
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
|
||||||
|
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account, final DateTimeFormatter fmt,
|
||||||
|
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail) {
|
||||||
|
|
||||||
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||||
|
|
||||||
|
final SavingsAccountTransaction withdrawal = account.withdraw(fmt, transactionDate, transactionAmount, existingTransactionIds,
|
||||||
|
existingReversedTransactionIds, paymentDetail);
|
||||||
|
|
||||||
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
|
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||||
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
|
account.postInterest(mc, today, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
} else {
|
||||||
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
|
account.calculateInterestUsing(mc, today);
|
||||||
|
}
|
||||||
|
|
||||||
|
saveTransactionToGenerateTransactionId(withdrawal);
|
||||||
|
this.savingsAccountRepository.save(account);
|
||||||
|
|
||||||
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
|
return withdrawal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public SavingsAccountTransaction handleDeposit(final SavingsAccount account, final DateTimeFormatter fmt,
|
||||||
|
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail) {
|
||||||
|
|
||||||
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||||
|
|
||||||
|
final SavingsAccountTransaction deposit = account.deposit(fmt, transactionDate, transactionAmount, existingTransactionIds,
|
||||||
|
existingReversedTransactionIds, paymentDetail);
|
||||||
|
|
||||||
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
|
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||||
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
|
account.postInterest(mc, today, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
} else {
|
||||||
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
|
account.calculateInterestUsing(mc, today);
|
||||||
|
}
|
||||||
|
|
||||||
|
saveTransactionToGenerateTransactionId(deposit);
|
||||||
|
|
||||||
|
this.savingsAccountRepository.save(account);
|
||||||
|
|
||||||
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
|
return deposit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long saveTransactionToGenerateTransactionId(final SavingsAccountTransaction transaction) {
|
||||||
|
this.savingsAccountTransactionRepository.save(transaction);
|
||||||
|
return transaction.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postJournalEntries(final SavingsAccount savingsAccount, final List<Long> existingTransactionIds,
|
||||||
|
final List<Long> existingReversedTransactionIds) {
|
||||||
|
|
||||||
|
final MonetaryCurrency currency = savingsAccount.getCurrency();
|
||||||
|
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepositoryWrapper.findOneWithNotFoundDetection(currency);
|
||||||
|
|
||||||
|
final Map<String, Object> accountingBridgeData = savingsAccount.deriveAccountingBridgeData(applicationCurrency.toData(),
|
||||||
|
existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
journalEntryWritePlatformService.createJournalEntriesForSavings(accountingBridgeData);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -17,6 +17,8 @@ public interface SavingsAccountReadPlatformService {
|
|||||||
|
|
||||||
Page<SavingsAccountData> retrieveAll(SearchParameters searchParameters);
|
Page<SavingsAccountData> retrieveAll(SearchParameters searchParameters);
|
||||||
|
|
||||||
|
Collection<SavingsAccountData> retrieveAllForLookup(Long clientId);
|
||||||
|
|
||||||
SavingsAccountData retrieveOne(Long savingsId);
|
SavingsAccountData retrieveOne(Long savingsId);
|
||||||
|
|
||||||
SavingsAccountData retrieveTemplate(Long clientId, Long groupId, Long productId, boolean staffInSelectedOfficeOnly);
|
SavingsAccountData retrieveTemplate(Long clientId, Long groupId, Long productId, boolean staffInSelectedOfficeOnly);
|
||||||
|
|||||||
+43
-7
@@ -26,6 +26,7 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
|
|||||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
import org.mifosplatform.organisation.staff.data.StaffData;
|
import org.mifosplatform.organisation.staff.data.StaffData;
|
||||||
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
|
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
|
||||||
|
import org.mifosplatform.portfolio.accounttransfers.data.AccountTransferData;
|
||||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||||
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
||||||
@@ -74,7 +75,6 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
// pagination
|
// pagination
|
||||||
private final PaginationHelper<SavingsAccountData> paginationHelper = new PaginationHelper<SavingsAccountData>();
|
private final PaginationHelper<SavingsAccountData> paginationHelper = new PaginationHelper<SavingsAccountData>();
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SavingsAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
|
public SavingsAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
|
||||||
final ClientReadPlatformService clientReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
|
final ClientReadPlatformService clientReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
|
||||||
@@ -93,6 +93,16 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
this.annualFeeMapper = new SavingsAccountAnnualFeeMapper();
|
this.annualFeeMapper = new SavingsAccountAnnualFeeMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<SavingsAccountData> retrieveAllForLookup(final Long clientId) {
|
||||||
|
|
||||||
|
StringBuilder sqlBuilder = new StringBuilder("select " + this.savingAccountMapper.schema());
|
||||||
|
sqlBuilder.append(" where sa.client_id = ? and sa.status_enum = 300");
|
||||||
|
|
||||||
|
Object[] queryParameters = new Object[] { clientId };
|
||||||
|
return this.jdbcTemplate.query(sqlBuilder.toString(), this.savingAccountMapper, queryParameters);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<SavingsAccountData> retrieveAll(final SearchParameters searchParameters) {
|
public Page<SavingsAccountData> retrieveAll(final SearchParameters searchParameters) {
|
||||||
|
|
||||||
@@ -148,12 +158,9 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
public SavingsAccountData retrieveOne(final Long accountId) {
|
public SavingsAccountData retrieveOne(final Long accountId) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.context.authenticatedUser();
|
final String sql = "select " + this.savingAccountMapper.schema() + " where sa.id = ?";
|
||||||
|
|
||||||
final SavingAccountMapper mapper = new SavingAccountMapper();
|
return this.jdbcTemplate.queryForObject(sql, this.savingAccountMapper, new Object[] { accountId });
|
||||||
final String sql = "select " + mapper.schema() + " where sa.id = ?";
|
|
||||||
|
|
||||||
return this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { accountId });
|
|
||||||
} catch (EmptyResultDataAccessException e) {
|
} catch (EmptyResultDataAccessException e) {
|
||||||
throw new SavingsAccountNotFoundException(accountId);
|
throw new SavingsAccountNotFoundException(accountId);
|
||||||
}
|
}
|
||||||
@@ -518,6 +525,12 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
|
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
|
||||||
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,");
|
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,");
|
||||||
sqlBuilder.append("tr.running_balance_derived as runningBalance, tr.is_reversed as reversed,");
|
sqlBuilder.append("tr.running_balance_derived as runningBalance, tr.is_reversed as reversed,");
|
||||||
|
sqlBuilder.append("fromtran.id as fromTransferId, fromtran.is_reversed as fromTransferReversed,");
|
||||||
|
sqlBuilder.append("fromtran.transaction_date as fromTransferDate, fromtran.amount as fromTransferAmount,");
|
||||||
|
sqlBuilder.append("fromtran.description as fromTransferDescription,");
|
||||||
|
sqlBuilder.append("totran.id as toTransferId, totran.is_reversed as toTransferReversed,");
|
||||||
|
sqlBuilder.append("totran.transaction_date as toTransferDate, totran.amount as toTransferAmount,");
|
||||||
|
sqlBuilder.append("totran.description as toTransferDescription,");
|
||||||
sqlBuilder.append("sa.id as savingsId, sa.account_no as accountNo,");
|
sqlBuilder.append("sa.id as savingsId, sa.account_no as accountNo,");
|
||||||
sqlBuilder.append("pd.payment_type_cv_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, ");
|
sqlBuilder.append("pd.payment_type_cv_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, ");
|
||||||
sqlBuilder.append("pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, ");
|
sqlBuilder.append("pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, ");
|
||||||
@@ -528,6 +541,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
sqlBuilder.append("from m_savings_account sa ");
|
sqlBuilder.append("from m_savings_account sa ");
|
||||||
sqlBuilder.append("join m_savings_account_transaction tr on tr.savings_account_id = sa.id ");
|
sqlBuilder.append("join m_savings_account_transaction tr on tr.savings_account_id = sa.id ");
|
||||||
sqlBuilder.append("join m_currency curr on curr.code = sa.currency_code ");
|
sqlBuilder.append("join m_currency curr on curr.code = sa.currency_code ");
|
||||||
|
sqlBuilder.append("left join m_savings_account_transfer fromtran on fromtran.from_savings_transaction_id = tr.id ");
|
||||||
|
sqlBuilder.append("left join m_savings_account_transfer totran on totran.to_savings_transaction_id = tr.id ");
|
||||||
sqlBuilder.append("left join m_payment_detail pd on tr.payment_detail_id = pd.id ");
|
sqlBuilder.append("left join m_payment_detail pd on tr.payment_detail_id = pd.id ");
|
||||||
sqlBuilder.append("left join m_code_value cv on pd.payment_type_cv_id = cv.id ");
|
sqlBuilder.append("left join m_code_value cv on pd.payment_type_cv_id = cv.id ");
|
||||||
|
|
||||||
@@ -576,8 +591,29 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||||
currencyNameCode);
|
currencyNameCode);
|
||||||
|
|
||||||
|
AccountTransferData transfer = null;
|
||||||
|
final Long fromTransferId = JdbcSupport.getLong(rs, "fromTransferId");
|
||||||
|
final Long toTransferId = JdbcSupport.getLong(rs, "toTransferId");
|
||||||
|
if (fromTransferId != null) {
|
||||||
|
final LocalDate fromTransferDate = JdbcSupport.getLocalDate(rs, "fromTransferDate");
|
||||||
|
final BigDecimal fromTransferAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "fromTransferAmount");
|
||||||
|
final boolean fromTransferReversed = rs.getBoolean("fromTransferReversed");
|
||||||
|
final String fromTransferDescription = rs.getString("fromTransferDescription");
|
||||||
|
|
||||||
|
transfer = AccountTransferData.transferBasicDetails(fromTransferId, currency, fromTransferAmount, fromTransferDate,
|
||||||
|
fromTransferDescription, fromTransferReversed);
|
||||||
|
} else if (toTransferId != null) {
|
||||||
|
final LocalDate toTransferDate = JdbcSupport.getLocalDate(rs, "toTransferDate");
|
||||||
|
final BigDecimal toTransferAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "toTransferAmount");
|
||||||
|
final boolean toTransferReversed = rs.getBoolean("toTransferReversed");
|
||||||
|
final String toTransferDescription = rs.getString("toTransferDescription");
|
||||||
|
|
||||||
|
transfer = AccountTransferData.transferBasicDetails(toTransferId, currency, toTransferAmount, toTransferDate,
|
||||||
|
toTransferDescription, toTransferReversed);
|
||||||
|
}
|
||||||
|
|
||||||
return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency,
|
return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency,
|
||||||
amount, runningBalance, reversed);
|
amount, runningBalance, reversed, transfer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-46
@@ -33,6 +33,7 @@ import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatf
|
|||||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDataValidator;
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDataValidator;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler;
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountDomainService;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountRepository;
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountRepository;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountStatusType;
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountStatusType;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
|
||||||
@@ -53,6 +54,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
private final PaymentDetailWritePlatformService paymentDetailWritePlatformService;
|
private final PaymentDetailWritePlatformService paymentDetailWritePlatformService;
|
||||||
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper;
|
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper;
|
||||||
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||||
|
private final SavingsAccountDomainService savingsAccountDomainService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
@@ -62,7 +64,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator,
|
final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator,
|
||||||
final PaymentDetailWritePlatformService paymentDetailWritePlatformService,
|
final PaymentDetailWritePlatformService paymentDetailWritePlatformService,
|
||||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
|
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
|
||||||
final JournalEntryWritePlatformService journalEntryWritePlatformService) {
|
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
||||||
|
final SavingsAccountDomainService savingsAccountDomainService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.savingAccountRepository = savingAccountRepository;
|
this.savingAccountRepository = savingAccountRepository;
|
||||||
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
||||||
@@ -71,6 +74,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
||||||
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
|
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
|
||||||
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
||||||
|
this.savingsAccountDomainService = savingsAccountDomainService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -120,36 +124,19 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||||
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
|
||||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||||
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||||
|
|
||||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate,
|
||||||
final SavingsAccountTransaction deposit = account.deposit(fmt, transactionDate, transactionAmount, existingTransactionIds,
|
transactionAmount, paymentDetail);
|
||||||
existingReversedTransactionIds, paymentDetail);
|
|
||||||
|
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
|
||||||
account.postInterest(mc, today, existingTransactionIds, existingReversedTransactionIds);
|
|
||||||
} else {
|
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
|
||||||
account.calculateInterestUsing(mc, today);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Long transactionId = saveTransactionToGenerateTransactionId(deposit);
|
|
||||||
|
|
||||||
this.savingAccountRepository.save(account);
|
|
||||||
|
|
||||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(transactionId) //
|
.withEntityId(deposit.getId()) //
|
||||||
.withOfficeId(account.officeId()) //
|
.withOfficeId(account.officeId()) //
|
||||||
.withClientId(account.clientId()) //
|
.withClientId(account.clientId()) //
|
||||||
.withGroupId(account.groupId()) //
|
.withGroupId(account.groupId()) //
|
||||||
.withSavingsId(savingsId) //
|
.withSavingsId(savingsId) //
|
||||||
.with(changes)//
|
.with(changes) //
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,42 +149,24 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command) {
|
public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command) {
|
||||||
|
|
||||||
this.context.authenticatedUser();
|
|
||||||
|
|
||||||
this.savingsAccountTransactionDataValidator.validate(command);
|
this.savingsAccountTransactionDataValidator.validate(command);
|
||||||
|
|
||||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
|
||||||
|
|
||||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||||
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
||||||
|
|
||||||
final Locale locale = command.extractLocale();
|
final Locale locale = command.extractLocale();
|
||||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
|
||||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||||
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||||
|
|
||||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||||
final SavingsAccountTransaction withdrawal = account.withdraw(fmt, transactionDate, transactionAmount, existingTransactionIds,
|
|
||||||
existingReversedTransactionIds, paymentDetail);
|
|
||||||
|
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
transactionAmount, paymentDetail);
|
||||||
account.postInterest(mc, today, existingTransactionIds, existingReversedTransactionIds);
|
|
||||||
} else {
|
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
|
||||||
account.calculateInterestUsing(mc, today);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Long transactionId = saveTransactionToGenerateTransactionId(withdrawal);
|
|
||||||
this.savingAccountRepository.save(account);
|
|
||||||
|
|
||||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(transactionId) //
|
.withEntityId(withdrawal.getId()) //
|
||||||
.withOfficeId(account.officeId()) //
|
.withOfficeId(account.officeId()) //
|
||||||
.withClientId(account.clientId()) //
|
.withClientId(account.clientId()) //
|
||||||
.withGroupId(account.groupId()) //
|
.withGroupId(account.groupId()) //
|
||||||
@@ -273,7 +242,6 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
private void postInterest(final SavingsAccount account) {
|
private void postInterest(final SavingsAccount account) {
|
||||||
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
@@ -290,7 +258,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
@CronTarget(jobName = JobName.POST_INTEREST_FOR_SAVINGS)
|
@CronTarget(jobName = JobName.POST_INTEREST_FOR_SAVINGS)
|
||||||
@Override
|
@Override
|
||||||
public void postInterestForAccounts() {
|
public void postInterestForAccounts() {
|
||||||
final List<SavingsAccount> savingsAccounts = this.savingAccountRepository.findSavingAccountByStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
final List<SavingsAccount> savingsAccounts = this.savingAccountRepository.findSavingAccountByStatus(SavingsAccountStatusType.ACTIVE
|
||||||
|
.getValue());
|
||||||
for (final SavingsAccount savingsAccount : savingsAccounts) {
|
for (final SavingsAccount savingsAccount : savingsAccounts) {
|
||||||
this.savingAccountAssembler.assignSavingAccountHelpers(savingsAccount);
|
this.savingAccountAssembler.assignSavingAccountHelpers(savingsAccount);
|
||||||
postInterest(savingsAccount);
|
postInterest(savingsAccount);
|
||||||
|
|||||||
Reference in New Issue
Block a user