MIFOSX-432: ability to transfer from savings account to savings account.
This commit is contained in:
+1484
-66
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() {
|
||||
return this.entityName.equalsIgnoreCase("SCHEDULER");
|
||||
}
|
||||
|
||||
public boolean isAccountTransferResource() {
|
||||
return this.entityName.equalsIgnoreCase("ACCOUNTTRANSFER");
|
||||
}
|
||||
}
|
||||
+8
@@ -808,6 +808,14 @@ public class CommandWrapperBuilder {
|
||||
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) {
|
||||
this.actionName = "DEPOSIT";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
|
||||
+8
-1
@@ -105,7 +105,14 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) {
|
||||
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);
|
||||
} else if (wrapper.isDatatableResource()) {
|
||||
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 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;
|
||||
|
||||
|
||||
+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();
|
||||
}
|
||||
}
|
||||
+11
-12
@@ -23,7 +23,6 @@ import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
||||
*/
|
||||
final public class ClientData implements Comparable<ClientData> {
|
||||
|
||||
|
||||
private final Long id;
|
||||
private final String accountNo;
|
||||
private final String externalId;
|
||||
@@ -49,16 +48,17 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
|
||||
// associations
|
||||
private final Collection<GroupGeneralData> groups;
|
||||
|
||||
|
||||
// template
|
||||
private final Collection<OfficeData> officeOptions;
|
||||
private final Collection<StaffData> staffOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<CodeValueData> closureReasons;
|
||||
|
||||
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) {
|
||||
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) {
|
||||
@@ -81,11 +81,12 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
final String officeName) {
|
||||
|
||||
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) {
|
||||
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,
|
||||
@@ -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,
|
||||
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 Collection<OfficeData> allowedOffices, final Collection<GroupGeneralData> groups, final Collection<StaffData> staffOptions,
|
||||
final Collection<CodeValueData> closureReasons) {
|
||||
final Collection<OfficeData> allowedOffices, final Collection<GroupGeneralData> groups,
|
||||
final Collection<StaffData> staffOptions, final Collection<CodeValueData> closureReasons) {
|
||||
this.accountNo = accountNo;
|
||||
this.status = status;
|
||||
if (status != null) {
|
||||
@@ -122,7 +123,7 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
if (imageId != null) {
|
||||
this.imagePresent = Boolean.TRUE;
|
||||
} else {
|
||||
this.imagePresent = Boolean.FALSE;
|
||||
this.imagePresent = null;
|
||||
}
|
||||
this.staffId = staffId;
|
||||
this.staffName = staffName;
|
||||
@@ -189,7 +190,6 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
.toHashCode();
|
||||
}
|
||||
|
||||
// TODO - kw - look into removing usage of the getters below
|
||||
public String getExternalId() {
|
||||
return this.externalId;
|
||||
}
|
||||
@@ -205,5 +205,4 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
public LocalDate getActivationDate() {
|
||||
return this.activationDate;
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -8,6 +8,8 @@ package org.mifosplatform.portfolio.savings.data;
|
||||
import java.math.BigDecimal;
|
||||
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.MonthDay;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
@@ -93,6 +95,26 @@ public class SavingsAccountData {
|
||||
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,
|
||||
final Collection<SavingsAccountTransactionData> transactions) {
|
||||
|
||||
@@ -263,4 +285,23 @@ public class SavingsAccountData {
|
||||
public Long productId() {
|
||||
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.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.accounttransfers.data.AccountTransferData;
|
||||
import org.mifosplatform.portfolio.paymentdetail.data.PaymentDetailData;
|
||||
|
||||
/**
|
||||
@@ -29,16 +30,18 @@ public class SavingsAccountTransactionData {
|
||||
private final BigDecimal amount;
|
||||
private final BigDecimal runningBalance;
|
||||
private final boolean reversed;
|
||||
private final AccountTransferData transfer;
|
||||
|
||||
// templates
|
||||
final Collection<CodeValueData> paymentTypeOptions;
|
||||
|
||||
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
||||
final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed) {
|
||||
final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed,
|
||||
final AccountTransferData transfer) {
|
||||
final Collection<CodeValueData> paymentTypeOptions = null;
|
||||
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,
|
||||
@@ -51,7 +54,7 @@ public class SavingsAccountTransactionData {
|
||||
final PaymentDetailData paymentDetailData = null;
|
||||
final Collection<CodeValueData> paymentTypeOptions = null;
|
||||
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,
|
||||
@@ -60,13 +63,13 @@ public class SavingsAccountTransactionData {
|
||||
savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId,
|
||||
savingsAccountTransactionData.accountNo, savingsAccountTransactionData.date, savingsAccountTransactionData.currency,
|
||||
savingsAccountTransactionData.amount, savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed,
|
||||
paymentTypeOptions);
|
||||
savingsAccountTransactionData.transfer, paymentTypeOptions);
|
||||
}
|
||||
|
||||
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
||||
final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed,
|
||||
final Collection<CodeValueData> paymentTypeOptions) {
|
||||
final AccountTransferData transfer, final Collection<CodeValueData> paymentTypeOptions) {
|
||||
this.id = id;
|
||||
this.transactionType = transactionType;
|
||||
this.paymentDetailData = paymentDetailData;
|
||||
@@ -77,6 +80,7 @@ public class SavingsAccountTransactionData {
|
||||
this.amount = amount;
|
||||
this.runningBalance = runningBalance;
|
||||
this.reversed = reversed;
|
||||
this.transfer = transfer;
|
||||
this.paymentTypeOptions = paymentTypeOptions;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -699,7 +699,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
boolean transactionBeforeLastInterestPosting = false;
|
||||
|
||||
for (SavingsAccountTransaction transaction : retreiveListOfTransactions()) {
|
||||
if (transaction.isNotReversed() && transaction.isInterestPostingAndNotReversed() && transaction.isAfter(transactionDate)) {
|
||||
if (transaction.isInterestPostingAndNotReversed() && transaction.isAfter(transactionDate)) {
|
||||
transactionBeforeLastInterestPosting = true;
|
||||
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);
|
||||
|
||||
Collection<SavingsAccountData> retrieveAllForLookup(Long clientId);
|
||||
|
||||
SavingsAccountData retrieveOne(Long savingsId);
|
||||
|
||||
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.staff.data.StaffData;
|
||||
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.service.ClientReadPlatformService;
|
||||
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
||||
@@ -74,7 +75,6 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
// pagination
|
||||
private final PaginationHelper<SavingsAccountData> paginationHelper = new PaginationHelper<SavingsAccountData>();
|
||||
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
|
||||
final ClientReadPlatformService clientReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
|
||||
@@ -93,6 +93,16 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
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
|
||||
public Page<SavingsAccountData> retrieveAll(final SearchParameters searchParameters) {
|
||||
|
||||
@@ -148,12 +158,9 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
public SavingsAccountData retrieveOne(final Long accountId) {
|
||||
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
final String sql = "select " + this.savingAccountMapper.schema() + " where sa.id = ?";
|
||||
|
||||
final SavingAccountMapper mapper = new SavingAccountMapper();
|
||||
final String sql = "select " + mapper.schema() + " where sa.id = ?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { accountId });
|
||||
return this.jdbcTemplate.queryForObject(sql, this.savingAccountMapper, new Object[] { accountId });
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
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.transaction_date as transactionDate, tr.amount as transactionAmount,");
|
||||
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("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, ");
|
||||
@@ -528,6 +541,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
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_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_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,
|
||||
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,
|
||||
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.domain.SavingsAccount;
|
||||
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.SavingsAccountStatusType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
|
||||
@@ -53,6 +54,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
private final PaymentDetailWritePlatformService paymentDetailWritePlatformService;
|
||||
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper;
|
||||
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||
private final SavingsAccountDomainService savingsAccountDomainService;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
@@ -62,7 +64,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator,
|
||||
final PaymentDetailWritePlatformService paymentDetailWritePlatformService,
|
||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
|
||||
final JournalEntryWritePlatformService journalEntryWritePlatformService) {
|
||||
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
||||
final SavingsAccountDomainService savingsAccountDomainService) {
|
||||
this.context = context;
|
||||
this.savingAccountRepository = savingAccountRepository;
|
||||
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
||||
@@ -71,6 +74,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
||||
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
|
||||
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
||||
this.savingsAccountDomainService = savingsAccountDomainService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -120,36 +124,19 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
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>();
|
||||
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||
|
||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||
final SavingsAccountTransaction deposit = account.deposit(fmt, transactionDate, transactionAmount, existingTransactionIds,
|
||||
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);
|
||||
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate,
|
||||
transactionAmount, paymentDetail);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(transactionId) //
|
||||
.withEntityId(deposit.getId()) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
.withClientId(account.clientId()) //
|
||||
.withGroupId(account.groupId()) //
|
||||
.withSavingsId(savingsId) //
|
||||
.with(changes)//
|
||||
.with(changes) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -162,42 +149,24 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
this.savingsAccountTransactionDataValidator.validate(command);
|
||||
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
||||
|
||||
final Locale locale = command.extractLocale();
|
||||
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>();
|
||||
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||
|
||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||
final SavingsAccountTransaction withdrawal = account.withdraw(fmt, transactionDate, transactionAmount, existingTransactionIds,
|
||||
existingReversedTransactionIds, paymentDetail);
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||
|
||||
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(withdrawal);
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
|
||||
transactionAmount, paymentDetail);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(transactionId) //
|
||||
.withEntityId(withdrawal.getId()) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
.withClientId(account.clientId()) //
|
||||
.withGroupId(account.groupId()) //
|
||||
@@ -273,7 +242,6 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
private void postInterest(final SavingsAccount account) {
|
||||
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||
@@ -290,7 +258,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@CronTarget(jobName = JobName.POST_INTEREST_FOR_SAVINGS)
|
||||
@Override
|
||||
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) {
|
||||
this.savingAccountAssembler.assignSavingAccountHelpers(savingsAccount);
|
||||
postInterest(savingsAccount);
|
||||
|
||||
Reference in New Issue
Block a user