Rename root folders
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
Welcome to the Mifos community!
|
||||
===============================
|
||||
|
||||
Depending on the OS you're running, you should have "runmifosx.sh" (for Linux and Mac) and
|
||||
"runmifosx.bat" (for Windows) in this directory. These are small scripts that allow you to
|
||||
run MifosX on your computer locally. To be able to run MifosX, just double-click on the script,
|
||||
that is, "runmifosx.sh" if you are on Linux or Mac, or "runmifosx.bat" if you are on Windows.
|
||||
|
||||
If you have a web front-end that you want to use along with the backend server, put your index.html
|
||||
along with all the other source files inside a (sub-folder of) the "apps" folder in the current
|
||||
directory from where runmifosx.bat/.sh is launched. The web UI front-end is then accessible
|
||||
under mifosng-provider/apps - for example:
|
||||
|
||||
https://localhost:8443/mifosng-provider/apps/community-app/index.html?baseApiUrl=https://localhost:8443&tenantIdentifier=default#/home
|
||||
|
||||
We hope you'll have an amazing experience working with MifosX!
|
||||
|
||||
|
||||
PS, internal note to Mifos developers preparing packages, only: For this to work, the WAR of
|
||||
the Mifos X distribution ZIP package will (currently) have to be built using
|
||||
the Gradle 'dev' environment profile - e.g. using this command:
|
||||
|
||||
./gradlew -Penv=dev clean war dist
|
||||
|
||||
We now also have a script which convenently prepares both the
|
||||
UI front-end and the API back-end together into a ZIP:
|
||||
|
||||
git clone --recursive https://github.com/openMF/mifosx/
|
||||
git submodule update --init --recursive; git submodule status
|
||||
./build.sh
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
java -version >nul 2>&1 && (
|
||||
echo "Found Java."
|
||||
) || (
|
||||
echo "Java should be installed to run MifosX."
|
||||
exit
|
||||
)
|
||||
|
||||
echo "Starting MifosX ..... "
|
||||
|
||||
java -Djava.awt.headless=false -jar mifosng-provider.war
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# First of all, check if Java is installed on this computer
|
||||
|
||||
if hash java; then
|
||||
echo "Found Java:"
|
||||
echo $(java -version)
|
||||
else
|
||||
echo "Java should be installed to run MifosX."
|
||||
exit
|
||||
fi
|
||||
|
||||
echo "Starting MifosX ..... "
|
||||
|
||||
java -Djava.awt.headless=false -jar mifosng-provider.war
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.boot.AbstractApplicationConfiguration;
|
||||
import org.mifosplatform.infrastructure.core.boot.ApplicationExitUtil;
|
||||
import org.mifosplatform.infrastructure.core.boot.EmbeddedTomcatWithSSLConfiguration;
|
||||
import org.mifosplatform.infrastructure.core.boot.db.DataSourceConfiguration;
|
||||
import org.mifosplatform.infrastructure.core.boot.db.DataSourceProperties;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Mifos main() application which launches Mifos X in an embedded Tomcat HTTP
|
||||
* (using Spring Boot).
|
||||
*
|
||||
* The DataSource used is a to a "normal" external database (not use MariaDB4j).
|
||||
* This DataSource can be configured with parameters, see {@link DataSourceProperties}.
|
||||
*
|
||||
* You can easily launch this via Debug as Java Application in your IDE -
|
||||
* without needing command line Gradle stuff, no need to build and deploy a WAR,
|
||||
* remote attachment etc.
|
||||
*
|
||||
* It's the old/classic Mifos (non-X) Workspace 2.0 reborn for Mifos X! ;-)
|
||||
*
|
||||
* @see DataSourceProperties about how to configure the DataSource used
|
||||
* @see ServerWithMariaDB4jApplication for an alternative with an embedded DB
|
||||
*/
|
||||
public class ServerApplication {
|
||||
|
||||
@Import({ DataSourceConfiguration.class, EmbeddedTomcatWithSSLConfiguration.class })
|
||||
private static class Configuration extends AbstractApplicationConfiguration { }
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ConfigurableApplicationContext ctx = SpringApplication.run(Configuration.class, args);
|
||||
ApplicationExitUtil.waitForKeyPressToCleanlyExit(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.boot.AbstractApplicationConfiguration;
|
||||
import org.mifosplatform.infrastructure.core.boot.ApplicationExitUtil;
|
||||
import org.mifosplatform.infrastructure.core.boot.EmbeddedTomcatWithSSLConfiguration;
|
||||
import org.mifosplatform.infrastructure.core.boot.db.MariaDB4jDataSourceConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Mifos main() application which launches Mifos X in an embedded Tomcat HTTP
|
||||
* server (using Spring Boot), as well as an embedded database (using
|
||||
* MariaDB4j).
|
||||
*
|
||||
* You can easily launch this via Debug as Java Application in your IDE -
|
||||
* without needing command line Gradle stuff, no need to build and deploy a WAR,
|
||||
* remote attachment etc.
|
||||
*
|
||||
* It's the old/classic Mifos (non-X) Workspace 2.0 reborn for Mifos X! ;-)
|
||||
*
|
||||
* @see ServerApplication for the same without the embedded MariaDB4j database
|
||||
*/
|
||||
public class ServerWithMariaDB4jApplication {
|
||||
private final static Logger logger = LoggerFactory.getLogger(ServerWithMariaDB4jApplication.class);
|
||||
|
||||
@Import({ MariaDB4jDataSourceConfiguration.class, EmbeddedTomcatWithSSLConfiguration.class })
|
||||
public static class Configuration extends AbstractApplicationConfiguration { }
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ConfigurableApplicationContext ctx = SpringApplication.run(Configuration.class, args);
|
||||
if (!Desktop.isDesktopSupported()) {
|
||||
logger.info("Not going to open UI homepage in local web browser, because !Desktop.isDesktopSupported()");
|
||||
|
||||
} else {
|
||||
// apps/community-app/dist/community-app/index.html
|
||||
Resource distResource = ctx.getResource("file:" + System.getProperty("user.dir") +
|
||||
System.getProperty("file.separator") + "apps" +
|
||||
System.getProperty("file.separator") + "community-app" +
|
||||
System.getProperty("file.separator") + "dist" +
|
||||
System.getProperty("file.separator") + "community-app" +
|
||||
System.getProperty("file.separator") + "index.html");
|
||||
URI distURI = URI.create("https://localhost:8443/mifosng-provider" +
|
||||
"/apps/community-app/index.html?baseApiUrl=https://localhost:8443" +
|
||||
"&tenantIdentifier=default#/");
|
||||
|
||||
// apps/community-app/app/index.html
|
||||
Resource devResource = ctx.getResource("file:" + System.getProperty("user.dir") +
|
||||
System.getProperty("file.separator") + "apps" +
|
||||
System.getProperty("file.separator") + "community-app" +
|
||||
System.getProperty("file.separator") + "app" +
|
||||
System.getProperty("file.separator") + "index.html");
|
||||
URI devURI = URI.create("https://localhost:8443/mifosng-provider" +
|
||||
"/apps/community-app/app/index.html?baseApiUrl=https://localhost:8443" +
|
||||
"&tenantIdentifier=default#/");
|
||||
|
||||
if (distResource.exists()) {
|
||||
openWebBrowser(distURI);
|
||||
} else if (devResource.exists()) {
|
||||
openWebBrowser(devURI);
|
||||
} else {
|
||||
logger.error("Cannot open Mifos X UI in browser; not found: " + distResource.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Tray Icon stuff; dig out my very own old @see https://github.com/mifos/head/tree/hudsonBuild-MIFOS-5157_Launch4j-EXE_NewDist-squash1/server-jetty/src/main/java/org/mifos/server/tray
|
||||
|
||||
ApplicationExitUtil.waitForKeyPressToCleanlyExit(ctx);
|
||||
}
|
||||
|
||||
private static void openWebBrowser(URI uri) {
|
||||
try {
|
||||
logger.info("Opening Mifos X UI in browser: " + uri.toString());
|
||||
Desktop.getDesktop().browse(uri);
|
||||
} catch (IOException e) {
|
||||
logger.error("IOException when opening Mifos X UI in browser: " + uri.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* 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.accounting.accrual.api;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/runaccruals")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class AccrualAccountingApiResource {
|
||||
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final DefaultToApiJsonSerializer<String> apiJsonSerializerService;
|
||||
|
||||
@Autowired
|
||||
public AccrualAccountingApiResource(final DefaultToApiJsonSerializer<String> apiJsonSerializerService,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.apiJsonSerializerService = apiJsonSerializerService;
|
||||
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String executePeriodicAccrualAccounting(final String jsonRequestBody) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().excuteAccrualAccounting().withJson(jsonRequestBody).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 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.accounting.accrual.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class AccrualAccountingConstants {
|
||||
|
||||
public static final String accrueTillParamName = "tillDate";
|
||||
public static final String localeParamName = "locale";
|
||||
public static final String dateFormatParamName = "dateFormat";
|
||||
|
||||
public static final String PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME = "periodicaccrual";
|
||||
public static final String PERIODIC_ACCRUAL_ACCOUNTING_EXECUTION_ERROR_CODE = "execution.failed";
|
||||
|
||||
public static final Set<String> LOAN_PERIODIC_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(accrueTillParamName,
|
||||
localeParamName, dateFormatParamName));
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.accounting.accrual.handler;
|
||||
|
||||
import org.mifosplatform.accounting.accrual.service.AccrualAccountingWritePlatformService;
|
||||
import org.mifosplatform.commands.annotation.CommandType;
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "PERIODICACCRUALACCOUNTING", action = "EXECUTE")
|
||||
public class ExecutePeriodicAccrualCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final AccrualAccountingWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public ExecutePeriodicAccrualCommandHandler(final AccrualAccountingWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.executeLoansPeriodicAccrual(command);
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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.accounting.accrual.serialization;
|
||||
|
||||
import static org.mifosplatform.accounting.accrual.api.AccrualAccountingConstants.LOAN_PERIODIC_REQUEST_DATA_PARAMETERS;
|
||||
import static org.mifosplatform.accounting.accrual.api.AccrualAccountingConstants.PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME;
|
||||
import static org.mifosplatform.accounting.accrual.api.AccrualAccountingConstants.accrueTillParamName;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
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.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.FromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.portfolio.loanaccount.guarantor.command.GuarantorCommand;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Implementation of {@link FromApiJsonDeserializer} for
|
||||
* {@link GuarantorCommand}'s.
|
||||
*/
|
||||
@Component
|
||||
public final class AccrualAccountingDataValidator {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public AccrualAccountingDataValidator(final FromJsonHelper fromApiJsonfromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonfromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateLoanPeriodicAccrualData(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, LOAN_PERIODIC_REQUEST_DATA_PARAMETERS);
|
||||
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME);
|
||||
|
||||
final LocalDate date = this.fromApiJsonHelper.extractLocalDateNamed(accrueTillParamName, element);
|
||||
baseDataValidator.reset().parameter(accrueTillParamName).value(date).notNull().validateDateBefore(DateUtils.getLocalDateOfTenant());
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
|
||||
}
|
||||
|
||||
public void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
+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.accounting.accrual.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
|
||||
public interface AccrualAccountingWritePlatformService {
|
||||
|
||||
CommandProcessingResult executeLoansPeriodicAccrual(JsonCommand command);
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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.accounting.accrual.service;
|
||||
|
||||
import static org.mifosplatform.accounting.accrual.api.AccrualAccountingConstants.PERIODIC_ACCRUAL_ACCOUNTING_EXECUTION_ERROR_CODE;
|
||||
import static org.mifosplatform.accounting.accrual.api.AccrualAccountingConstants.PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME;
|
||||
import static org.mifosplatform.accounting.accrual.api.AccrualAccountingConstants.accrueTillParamName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.accounting.accrual.serialization.AccrualAccountingDataValidator;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanAccrualPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class AccrualAccountingWritePlatformServiceImpl implements AccrualAccountingWritePlatformService {
|
||||
|
||||
private final LoanAccrualPlatformService loanAccrualPlatformService;
|
||||
private final AccrualAccountingDataValidator accountingDataValidator;
|
||||
|
||||
@Autowired
|
||||
public AccrualAccountingWritePlatformServiceImpl(final LoanAccrualPlatformService loanAccrualPlatformService,
|
||||
final AccrualAccountingDataValidator accountingDataValidator) {
|
||||
this.loanAccrualPlatformService = loanAccrualPlatformService;
|
||||
this.accountingDataValidator = accountingDataValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult executeLoansPeriodicAccrual(JsonCommand command) {
|
||||
this.accountingDataValidator.validateLoanPeriodicAccrualData(command.json());
|
||||
LocalDate tilldate = command.localDateValueOfParameterNamed(accrueTillParamName);
|
||||
String errorlog = this.loanAccrualPlatformService.addPeriodicAccruals(tilldate);
|
||||
if (errorlog.length() > 0) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME);
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(PERIODIC_ACCRUAL_ACCOUNTING_EXECUTION_ERROR_CODE, errorlog);
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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.accounting.closure.api;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/***
|
||||
* Enum of all parameters passed in while creating/updating a loan product
|
||||
***/
|
||||
public enum GLClosureJsonInputParams {
|
||||
ID("id"), OFFICE_ID("officeId"), CLOSING_DATE("closingDate"), COMMENTS("comments"), LOCALE("locale"), DATE_FORMAT("dateFormat");
|
||||
|
||||
private final String value;
|
||||
|
||||
private GLClosureJsonInputParams(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private static final Set<String> values = new HashSet<>();
|
||||
static {
|
||||
for (final GLClosureJsonInputParams type : GLClosureJsonInputParams.values()) {
|
||||
values.add(type.value);
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> getAllValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
Executable
+138
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* 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.accounting.closure.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
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.accounting.closure.data.GLClosureData;
|
||||
import org.mifosplatform.accounting.closure.service.GLClosureReadPlatformService;
|
||||
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.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/glclosures")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class GLClosuresApiResource {
|
||||
|
||||
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "officeId", "officeName",
|
||||
"closingDate", "deleted", "createdDate", "lastUpdatedDate", "createdByUserId", "createdByUsername", "lastUpdatedByUserId",
|
||||
"lastUpdatedByUsername"));
|
||||
|
||||
private final String resourceNameForPermission = "GLCLOSURE";
|
||||
|
||||
private final GLClosureReadPlatformService glClosureReadPlatformService;
|
||||
private final OfficeReadPlatformService officeReadPlatformService;
|
||||
private final DefaultToApiJsonSerializer<GLClosureData> apiJsonSerializerService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PlatformSecurityContext context;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public GLClosuresApiResource(final PlatformSecurityContext context, final GLClosureReadPlatformService glClosureReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<GLClosureData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||
final OfficeReadPlatformService officeReadPlatformService) {
|
||||
this.context = context;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.apiJsonSerializerService = toApiJsonSerializer;
|
||||
this.glClosureReadPlatformService = glClosureReadPlatformService;
|
||||
this.officeReadPlatformService = officeReadPlatformService;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAllClosures(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
|
||||
final List<GLClosureData> glClosureDatas = this.glClosureReadPlatformService.retrieveAllGLClosures(officeId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serialize(settings, glClosureDatas, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{glClosureId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retreiveClosure(@PathParam("glClosureId") final Long glClosureId, @Context final UriInfo uriInfo) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
final GLClosureData glClosureData = this.glClosureReadPlatformService.retrieveGLClosureById(glClosureId);
|
||||
if (settings.isTemplate()) {
|
||||
glClosureData.setAllowedOffices(this.officeReadPlatformService.retrieveAllOfficesForDropdown());
|
||||
}
|
||||
|
||||
return this.apiJsonSerializerService.serialize(settings, glClosureData, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String createGLClosure(final String jsonRequestBody) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLClosure().withJson(jsonRequestBody).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{glClosureId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateGLClosure(@PathParam("glClosureId") final Long glClosureId, final String jsonRequestBody) {
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLClosure(glClosureId).withJson(jsonRequestBody).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{glClosureId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteGLClosure(@PathParam("glClosureId") final Long glClosureId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLClosure(glClosureId).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
}
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 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.accounting.closure.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.accounting.closure.api.GLClosureJsonInputParams;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
|
||||
/**
|
||||
* Immutable command for adding an accounting closure
|
||||
*/
|
||||
public class GLClosureCommand {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Long id;
|
||||
private final Long officeId;
|
||||
private final LocalDate closingDate;
|
||||
private final String comments;
|
||||
|
||||
public GLClosureCommand(final Long id, final Long officeId, final LocalDate closingDate, final String comments) {
|
||||
this.id = id;
|
||||
this.officeId = officeId;
|
||||
this.closingDate = closingDate;
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public void validateForCreate() {
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("GLClosure");
|
||||
|
||||
baseDataValidator.reset().parameter(GLClosureJsonInputParams.CLOSING_DATE.getValue()).value(this.closingDate).notBlank();
|
||||
baseDataValidator.reset().parameter(GLClosureJsonInputParams.OFFICE_ID.getValue()).value(this.officeId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(GLClosureJsonInputParams.COMMENTS.getValue()).value(this.comments).ignoreIfNull()
|
||||
.notExceedingLengthOf(500);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
public void validateForUpdate() {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("GLClosure");
|
||||
|
||||
baseDataValidator.reset().parameter(GLClosureJsonInputParams.COMMENTS.getValue()).value(this.comments).ignoreIfNull()
|
||||
.notExceedingLengthOf(500);
|
||||
baseDataValidator.reset().anyOfNotNull(this.comments);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* 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.accounting.closure.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||
|
||||
/**
|
||||
* Immutable object representing a General Ledger Account
|
||||
*
|
||||
* Note: no getter/setters required as google-gson will produce json from fields
|
||||
* of object.
|
||||
*/
|
||||
public class GLClosureData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Long id;
|
||||
@SuppressWarnings("unused")
|
||||
private final Long officeId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String officeName;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate closingDate;
|
||||
@SuppressWarnings("unused")
|
||||
private final boolean deleted;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate createdDate;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate lastUpdatedDate;
|
||||
@SuppressWarnings("unused")
|
||||
private final Long createdByUserId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String createdByUsername;
|
||||
@SuppressWarnings("unused")
|
||||
private final Long lastUpdatedByUserId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String lastUpdatedByUsername;
|
||||
@SuppressWarnings("unused")
|
||||
private final String comments;
|
||||
|
||||
private Collection<OfficeData> allowedOffices = new ArrayList<>();
|
||||
|
||||
public GLClosureData(final Long id, final Long officeId, final String officeName, final LocalDate closingDate, final boolean deleted,
|
||||
final LocalDate createdDate, final LocalDate lastUpdatedDate, final Long createdByUserId, final String createdByUsername,
|
||||
final Long lastUpdatedByUserId, final String lastUpdatedByUsername, final String comments) {
|
||||
this.id = id;
|
||||
this.officeId = officeId;
|
||||
this.officeName = officeName;
|
||||
this.closingDate = closingDate;
|
||||
this.deleted = deleted;
|
||||
this.createdDate = createdDate;
|
||||
this.lastUpdatedDate = lastUpdatedDate;
|
||||
this.createdByUserId = createdByUserId;
|
||||
this.createdByUsername = createdByUsername;
|
||||
this.lastUpdatedByUserId = lastUpdatedByUserId;
|
||||
this.lastUpdatedByUsername = lastUpdatedByUsername;
|
||||
this.comments = comments;
|
||||
this.allowedOffices = null;
|
||||
}
|
||||
|
||||
public final Collection<OfficeData> getAllowedOffices() {
|
||||
return this.allowedOffices;
|
||||
}
|
||||
|
||||
public void setAllowedOffices(final Collection<OfficeData> allowedOffices) {
|
||||
this.allowedOffices = allowedOffices;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+92
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 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.accounting.closure.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
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 javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.accounting.closure.api.GLClosureJsonInputParams;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
|
||||
@Entity
|
||||
@Table(name = "acc_gl_closure", uniqueConstraints = { @UniqueConstraint(columnNames = { "office_id", "closing_date" }, name = "office_id_closing_date") })
|
||||
public class GLClosure extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "office_id", nullable = false)
|
||||
private Office office;
|
||||
|
||||
@Column(name = "is_deleted", nullable = false)
|
||||
private boolean deleted = true;
|
||||
|
||||
@Column(name = "closing_date")
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date closingDate;
|
||||
|
||||
@Column(name = "comments", nullable = true, length = 500)
|
||||
private String comments;
|
||||
|
||||
protected GLClosure() {
|
||||
//
|
||||
}
|
||||
|
||||
public GLClosure(final Office office, final Date closingDate, final String comments) {
|
||||
this.office = office;
|
||||
this.deleted = false;
|
||||
this.closingDate = closingDate;
|
||||
this.comments = StringUtils.defaultIfEmpty(comments, null);
|
||||
if (this.comments != null) {
|
||||
this.comments = this.comments.trim();
|
||||
}
|
||||
}
|
||||
|
||||
public static GLClosure fromJson(final Office office, final JsonCommand command) {
|
||||
final Date closingDate = command.DateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue());
|
||||
final String comments = command.stringValueOfParameterNamed(GLClosureJsonInputParams.COMMENTS.getValue());
|
||||
return new GLClosure(office, closingDate, comments);
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(5);
|
||||
handlePropertyUpdate(command, actualChanges, GLClosureJsonInputParams.COMMENTS.getValue(), this.comments);
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private void handlePropertyUpdate(final JsonCommand command, final Map<String, Object> actualChanges, final String paramName,
|
||||
final String propertyToBeUpdated) {
|
||||
if (command.isChangeInStringParameterNamed(paramName, propertyToBeUpdated)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(paramName);
|
||||
actualChanges.put(paramName, newValue);
|
||||
// now update actual property
|
||||
if (paramName.equals(GLClosureJsonInputParams.COMMENTS.getValue())) {
|
||||
this.comments = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Date getClosingDate() {
|
||||
return this.closingDate;
|
||||
}
|
||||
|
||||
public Office getOffice() {
|
||||
return this.office;
|
||||
}
|
||||
|
||||
}
|
||||
fineract-provider/src/main/java/org/mifosplatform/accounting/closure/domain/GLClosureRepository.java
Executable
+17
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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.accounting.closure.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface GLClosureRepository extends JpaRepository<GLClosure, Long>, JpaSpecificationExecutor<GLClosure> {
|
||||
|
||||
@Query("from GLClosure closure where closure.closingDate = (select max(closure1.closingDate) from GLClosure closure1 where closure1.office.id=:officeId) and closure.office.id= :officeId")
|
||||
GLClosure getLatestGLClosureByBranch(@Param("officeId") Long officeId);
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 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.accounting.closure.exception;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when a GL Closure for a given date and
|
||||
* Office combination is already present
|
||||
*/
|
||||
public class GLClosureDuplicateException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public GLClosureDuplicateException(final Long officeId, final LocalDate closureDate) {
|
||||
super("error.msg.glclosure.glcode.duplicate", "An accounting closure for branch with Id " + officeId
|
||||
+ " already exists for the date " + closureDate, officeId, closureDate);
|
||||
}
|
||||
|
||||
}
|
||||
+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.accounting.closure.exception;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when a GL Closure Delte command is invalid
|
||||
*/
|
||||
public class GLClosureInvalidDeleteException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public GLClosureInvalidDeleteException(final Long officeId, final String officeName, final Date latestclosureDate) {
|
||||
super("error.msg.glclosure.invalid.delete", "The latest closure for office with Id " + officeId + " and name " + officeName
|
||||
+ " is on " + latestclosureDate.toString() + ", please delete this closure first", latestclosureDate);
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 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.accounting.closure.exception;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when a GL Closure is Invalid
|
||||
*/
|
||||
public class GLClosureInvalidException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
/*** enum of reasons for invalid Accounting Closure **/
|
||||
public static enum GL_CLOSURE_INVALID_REASON {
|
||||
FUTURE_DATE, ACCOUNTING_CLOSED;
|
||||
|
||||
public String errorMessage() {
|
||||
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
|
||||
return "Accounting closures cannot be made for a future date";
|
||||
} else if (name().toString().equalsIgnoreCase("ACCOUNTING_CLOSED")) { return "Accounting Closure for this branch has already been defined for a greater date"; }
|
||||
return name().toString();
|
||||
}
|
||||
|
||||
public String errorCode() {
|
||||
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
|
||||
return "error.msg.glclosure.invalid.future.date";
|
||||
} else if (name().toString().equalsIgnoreCase("ACCOUNTING_CLOSED")) { return "error.msg.glclosure.invalid.accounting.closed"; }
|
||||
return name().toString();
|
||||
}
|
||||
}
|
||||
|
||||
public GLClosureInvalidException(final GL_CLOSURE_INVALID_REASON reason, final Date date) {
|
||||
super(reason.errorCode(), reason.errorMessage(), date);
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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.accounting.closure.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when GL account closure resources are not
|
||||
* found.
|
||||
*/
|
||||
public class GLClosureNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public GLClosureNotFoundException(final Long id) {
|
||||
super("error.msg.glclosure.id.invalid", "Accounting Closure with identifier " + id + " does not exist", id);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.accounting.closure.handler;
|
||||
|
||||
import org.mifosplatform.accounting.closure.service.GLClosureWritePlatformService;
|
||||
import org.mifosplatform.commands.annotation.CommandType;
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "GLCLOSURE", action = "CREATE")
|
||||
public class CreateGLClosureCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final GLClosureWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CreateGLClosureCommandHandler(final GLClosureWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.createGLClosure(command);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.accounting.closure.handler;
|
||||
|
||||
import org.mifosplatform.accounting.closure.service.GLClosureWritePlatformService;
|
||||
import org.mifosplatform.commands.annotation.CommandType;
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "GLCLOSURE", action = "DELETE")
|
||||
public class DeleteGLClosureCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final GLClosureWritePlatformService closureWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DeleteGLClosureCommandHandler(final GLClosureWritePlatformService guarantorWritePlatformService) {
|
||||
this.closureWritePlatformService = guarantorWritePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.closureWritePlatformService.deleteGLClosure(command.entityId());
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.accounting.closure.handler;
|
||||
|
||||
import org.mifosplatform.accounting.closure.service.GLClosureWritePlatformService;
|
||||
import org.mifosplatform.commands.annotation.CommandType;
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "GLCLOSURE", action = "UPDATE")
|
||||
public class UpdateGLClosureCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final GLClosureWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public UpdateGLClosureCommandHandler(final GLClosureWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.updateGLClosure(command.entityId(), command);
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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.accounting.closure.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.accounting.closure.api.GLClosureJsonInputParams;
|
||||
import org.mifosplatform.accounting.closure.command.GLClosureCommand;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.portfolio.loanaccount.guarantor.command.GuarantorCommand;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Implementation of {@link FromApiJsonDeserializer} for
|
||||
* {@link GuarantorCommand}'s.
|
||||
*/
|
||||
@Component
|
||||
public final class GLClosureCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<GLClosureCommand> {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public GLClosureCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonfromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonfromApiJsonHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GLClosureCommand commandFromApiJson(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
final Set<String> supportedParameters = GLClosureJsonInputParams.getAllValues();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
|
||||
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final Long id = this.fromApiJsonHelper.extractLongNamed(GLClosureJsonInputParams.ID.getValue(), element);
|
||||
final Long officeId = this.fromApiJsonHelper.extractLongNamed(GLClosureJsonInputParams.OFFICE_ID.getValue(), element);
|
||||
final String comments = this.fromApiJsonHelper.extractStringNamed(GLClosureJsonInputParams.COMMENTS.getValue(), element);
|
||||
final LocalDate closingDate = this.fromApiJsonHelper.extractLocalDateNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue(),
|
||||
element);
|
||||
|
||||
return new GLClosureCommand(id, officeId, closingDate, comments);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.accounting.closure.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.closure.data.GLClosureData;
|
||||
|
||||
public interface GLClosureReadPlatformService {
|
||||
|
||||
List<GLClosureData> retrieveAllGLClosures(Long OfficeId);
|
||||
|
||||
GLClosureData retrieveGLClosureById(long glClosureId);
|
||||
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* 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.accounting.closure.service;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.accounting.closure.data.GLClosureData;
|
||||
import org.mifosplatform.accounting.closure.exception.GLClosureNotFoundException;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||
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 GLClosureReadPlatformServiceImpl implements GLClosureReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Autowired
|
||||
public GLClosureReadPlatformServiceImpl(final RoutingDataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
private static final class GLClosureMapper implements RowMapper<GLClosureData> {
|
||||
|
||||
public String schema() {
|
||||
return " glClosure.id as id, glClosure.office_id as officeId,office.name as officeName ,glClosure.closing_date as closingDate,"
|
||||
+ " glClosure.is_deleted as isDeleted, creatingUser.id as creatingUserId,creatingUser.username as creatingUserName,"
|
||||
+ " updatingUser.id as updatingUserId,updatingUser.username as updatingUserName, glClosure.created_date as createdDate,"
|
||||
+ " glClosure.lastmodified_date as updatedDate, glClosure.comments as comments "
|
||||
+ " from acc_gl_closure as glClosure, m_appuser as creatingUser, m_appuser as updatingUser,m_office as office"
|
||||
+ " where glClosure.createdby_id=creatingUser.id and "
|
||||
+ " glClosure.lastmodifiedby_id=updatingUser.id and glClosure.office_id=office.id";
|
||||
}
|
||||
|
||||
@Override
|
||||
public GLClosureData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final Long officeId = rs.getLong("officeId");
|
||||
final String officeName = rs.getString("officeName");
|
||||
final LocalDate closingDate = JdbcSupport.getLocalDate(rs, "closingDate");
|
||||
final Boolean deleted = rs.getBoolean("isDeleted");
|
||||
final LocalDate createdDate = JdbcSupport.getLocalDate(rs, "createdDate");
|
||||
final LocalDate lastUpdatedDate = JdbcSupport.getLocalDate(rs, "updatedDate");
|
||||
final Long creatingByUserId = rs.getLong("creatingUserId");
|
||||
final String createdByUserName = rs.getString("creatingUserName");
|
||||
final Long lastUpdatedByUserId = rs.getLong("updatingUserId");
|
||||
final String lastUpdatedByUserName = rs.getString("updatingUserName");
|
||||
final String comments = rs.getString("comments");
|
||||
|
||||
return new GLClosureData(id, officeId, officeName, closingDate, deleted, createdDate, lastUpdatedDate, creatingByUserId,
|
||||
createdByUserName, lastUpdatedByUserId, lastUpdatedByUserName, comments);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GLClosureData> retrieveAllGLClosures(final Long officeId) {
|
||||
final GLClosureMapper rm = new GLClosureMapper();
|
||||
|
||||
String sql = "select " + rm.schema() + " and glClosure.is_deleted = 0";
|
||||
final Object[] objectArray = new Object[1];
|
||||
int arrayPos = 0;
|
||||
if (officeId != null && officeId != 0) {
|
||||
sql += " and glClosure.office_id = ?";
|
||||
objectArray[arrayPos] = officeId;
|
||||
arrayPos = arrayPos + 1;
|
||||
}
|
||||
|
||||
sql = sql + " order by glClosure.closing_date desc";
|
||||
|
||||
final Object[] finalObjectArray = Arrays.copyOf(objectArray, arrayPos);
|
||||
return this.jdbcTemplate.query(sql, rm, finalObjectArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GLClosureData retrieveGLClosureById(final long glClosureId) {
|
||||
try {
|
||||
|
||||
final GLClosureMapper rm = new GLClosureMapper();
|
||||
final String sql = "select " + rm.schema() + " and glClosure.id = ?";
|
||||
|
||||
final GLClosureData glAccountData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { glClosureId });
|
||||
|
||||
return glAccountData;
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
throw new GLClosureNotFoundException(glClosureId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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.accounting.closure.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
|
||||
public interface GLClosureWritePlatformService {
|
||||
|
||||
CommandProcessingResult createGLClosure(JsonCommand command);
|
||||
|
||||
CommandProcessingResult updateGLClosure(Long glClosureId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult deleteGLClosure(Long glClosureId);
|
||||
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* 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.accounting.closure.service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.accounting.closure.api.GLClosureJsonInputParams;
|
||||
import org.mifosplatform.accounting.closure.command.GLClosureCommand;
|
||||
import org.mifosplatform.accounting.closure.domain.GLClosure;
|
||||
import org.mifosplatform.accounting.closure.domain.GLClosureRepository;
|
||||
import org.mifosplatform.accounting.closure.exception.GLClosureDuplicateException;
|
||||
import org.mifosplatform.accounting.closure.exception.GLClosureInvalidDeleteException;
|
||||
import org.mifosplatform.accounting.closure.exception.GLClosureInvalidException;
|
||||
import org.mifosplatform.accounting.closure.exception.GLClosureInvalidException.GL_CLOSURE_INVALID_REASON;
|
||||
import org.mifosplatform.accounting.closure.exception.GLClosureNotFoundException;
|
||||
import org.mifosplatform.accounting.closure.serialization.GLClosureCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.organisation.office.domain.OfficeRepository;
|
||||
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosureWritePlatformService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(GLClosureWritePlatformServiceJpaRepositoryImpl.class);
|
||||
|
||||
private final GLClosureRepository glClosureRepository;
|
||||
private final OfficeRepository officeRepository;
|
||||
private final GLClosureCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||
|
||||
@Autowired
|
||||
public GLClosureWritePlatformServiceJpaRepositoryImpl(final GLClosureRepository glClosureRepository,
|
||||
final OfficeRepository officeRepository, final GLClosureCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
|
||||
this.glClosureRepository = glClosureRepository;
|
||||
this.officeRepository = officeRepository;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult createGLClosure(final JsonCommand command) {
|
||||
try {
|
||||
final GLClosureCommand closureCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||
closureCommand.validateForCreate();
|
||||
|
||||
// check office is valid
|
||||
final Long officeId = command.longValueOfParameterNamed(GLClosureJsonInputParams.OFFICE_ID.getValue());
|
||||
final Office office = this.officeRepository.findOne(officeId);
|
||||
if (office == null) { throw new OfficeNotFoundException(officeId); }
|
||||
|
||||
// TODO: Get Tenant specific date
|
||||
// ensure closure date is not in the future
|
||||
final Date todaysDate = new Date();
|
||||
final Date closureDate = command.DateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue());
|
||||
if (closureDate.after(todaysDate)) { throw new GLClosureInvalidException(GL_CLOSURE_INVALID_REASON.FUTURE_DATE, closureDate); }
|
||||
// shouldn't be before an existing accounting closure
|
||||
final GLClosure latestGLClosure = this.glClosureRepository.getLatestGLClosureByBranch(officeId);
|
||||
if (latestGLClosure != null) {
|
||||
if (latestGLClosure.getClosingDate().after(closureDate)) { throw new GLClosureInvalidException(
|
||||
GL_CLOSURE_INVALID_REASON.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate()); }
|
||||
}
|
||||
final GLClosure glClosure = GLClosure.fromJson(office, command);
|
||||
|
||||
this.glClosureRepository.saveAndFlush(glClosure);
|
||||
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(officeId)
|
||||
.withEntityId(glClosure.getId()).build();
|
||||
} catch (final DataIntegrityViolationException dve) {
|
||||
handleGLClosureIntegrityIssues(command, dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult updateGLClosure(final Long glClosureId, final JsonCommand command) {
|
||||
final GLClosureCommand closureCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||
closureCommand.validateForUpdate();
|
||||
|
||||
// is the glClosure valid
|
||||
final GLClosure glClosure = this.glClosureRepository.findOne(glClosureId);
|
||||
if (glClosure == null) { throw new GLClosureNotFoundException(glClosureId); }
|
||||
|
||||
final Map<String, Object> changesOnly = glClosure.update(command);
|
||||
|
||||
if (!changesOnly.isEmpty()) {
|
||||
this.glClosureRepository.saveAndFlush(glClosure);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(glClosure.getOffice().getId())
|
||||
.withEntityId(glClosure.getId()).with(changesOnly).build();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult deleteGLClosure(final Long glClosureId) {
|
||||
final GLClosure glClosure = this.glClosureRepository.findOne(glClosureId);
|
||||
|
||||
if (glClosure == null) { throw new GLClosureNotFoundException(glClosureId); }
|
||||
|
||||
/**
|
||||
* check if any closures are present for this branch at a later date
|
||||
* than this closure date
|
||||
**/
|
||||
final Date closureDate = glClosure.getClosingDate();
|
||||
final GLClosure latestGLClosure = this.glClosureRepository.getLatestGLClosureByBranch(glClosure.getOffice().getId());
|
||||
if (latestGLClosure.getClosingDate().after(closureDate)) { throw new GLClosureInvalidDeleteException(latestGLClosure.getOffice()
|
||||
.getId(), latestGLClosure.getOffice().getName(), latestGLClosure.getClosingDate()); }
|
||||
|
||||
this.glClosureRepository.delete(glClosure);
|
||||
|
||||
return new CommandProcessingResultBuilder().withOfficeId(glClosure.getOffice().getId()).withEntityId(glClosure.getId()).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param command
|
||||
* @param dve
|
||||
*/
|
||||
private void handleGLClosureIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
|
||||
final Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("office_id_closing_date")) { throw new GLClosureDuplicateException(
|
||||
command.longValueOfParameterNamed(GLClosureJsonInputParams.OFFICE_ID.getValue()), new LocalDate(
|
||||
command.DateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue()))); }
|
||||
|
||||
logger.error(dve.getMessage(), dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.glClosure.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource GL Closure: " + realCause.getMessage());
|
||||
}
|
||||
}
|
||||
Executable
+301
@@ -0,0 +1,301 @@
|
||||
/**
|
||||
* 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.accounting.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.accounting.financialactivityaccount.data.FinancialActivityData;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
|
||||
public class AccountingConstants {
|
||||
|
||||
/*** Accounting placeholders for cash based accounting for loan products ***/
|
||||
public static enum CASH_ACCOUNTS_FOR_LOAN {
|
||||
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(6), TRANSFERS_SUSPENSE(
|
||||
10), OVERPAYMENT(11), INCOME_FROM_RECOVERY(12);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private CASH_ACCOUNTS_FOR_LOAN(final Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private static final Map<Integer, CASH_ACCOUNTS_FOR_LOAN> intToEnumMap = new HashMap<>();
|
||||
static {
|
||||
for (final CASH_ACCOUNTS_FOR_LOAN type : CASH_ACCOUNTS_FOR_LOAN.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static CASH_ACCOUNTS_FOR_LOAN fromInt(final int i) {
|
||||
final CASH_ACCOUNTS_FOR_LOAN type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/*** Accounting placeholders for accrual based accounting for loan products ***/
|
||||
public static enum ACCRUAL_ACCOUNTS_FOR_LOAN {
|
||||
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(6), INTEREST_RECEIVABLE(
|
||||
7), FEES_RECEIVABLE(8), PENALTIES_RECEIVABLE(9), TRANSFERS_SUSPENSE(10), OVERPAYMENT(11), INCOME_FROM_RECOVERY(12);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private ACCRUAL_ACCOUNTS_FOR_LOAN(final Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private static final Map<Integer, ACCRUAL_ACCOUNTS_FOR_LOAN> intToEnumMap = new HashMap<>();
|
||||
static {
|
||||
for (final ACCRUAL_ACCOUNTS_FOR_LOAN type : ACCRUAL_ACCOUNTS_FOR_LOAN.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static ACCRUAL_ACCOUNTS_FOR_LOAN fromInt(final int i) {
|
||||
final ACCRUAL_ACCOUNTS_FOR_LOAN type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***
|
||||
* Enum of all accounting related input parameter names used while
|
||||
* creating/updating a loan product
|
||||
***/
|
||||
public static enum LOAN_PRODUCT_ACCOUNTING_PARAMS {
|
||||
FUND_SOURCE("fundSourceAccountId"), LOAN_PORTFOLIO("loanPortfolioAccountId"), INTEREST_ON_LOANS("interestOnLoanAccountId"), INCOME_FROM_FEES(
|
||||
"incomeFromFeeAccountId"), INCOME_FROM_PENALTIES("incomeFromPenaltyAccountId"), LOSSES_WRITTEN_OFF("writeOffAccountId"), OVERPAYMENT(
|
||||
"overpaymentLiabilityAccountId"), INTEREST_RECEIVABLE("receivableInterestAccountId"), FEES_RECEIVABLE(
|
||||
"receivableFeeAccountId"), PENALTIES_RECEIVABLE("receivablePenaltyAccountId"), TRANSFERS_SUSPENSE(
|
||||
"transfersInSuspenseAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING("paymentChannelToFundSourceMappings"), PAYMENT_TYPE(
|
||||
"paymentTypeId"), FEE_INCOME_ACCOUNT_MAPPING("feeToIncomeAccountMappings"), PENALTY_INCOME_ACCOUNT_MAPPING(
|
||||
"penaltyToIncomeAccountMappings"), CHARGE_ID("chargeId"), INCOME_ACCOUNT_ID("incomeAccountId"), INCOME_FROM_RECOVERY(
|
||||
"incomeFromRecoveryAccountId");
|
||||
|
||||
private final String value;
|
||||
|
||||
private LOAN_PRODUCT_ACCOUNTING_PARAMS(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS {
|
||||
FUND_SOURCE("fundSourceAccount"), LOAN_PORTFOLIO("loanPortfolioAccount"), INTEREST_ON_LOANS("interestOnLoanAccount"), INCOME_FROM_FEES(
|
||||
"incomeFromFeeAccount"), INCOME_FROM_PENALTIES("incomeFromPenaltyAccount"), LOSSES_WRITTEN_OFF("writeOffAccount"), OVERPAYMENT(
|
||||
"overpaymentLiabilityAccount"), INTEREST_RECEIVABLE("receivableInterestAccount"), FEES_RECEIVABLE("receivableFeeAccount"), PENALTIES_RECEIVABLE(
|
||||
"receivablePenaltyAccount"), TRANSFERS_SUSPENSE("transfersInSuspenseAccount"), INCOME_ACCOUNT_ID("incomeAccount"), INCOME_FROM_RECOVERY(
|
||||
"incomeFromRecoveryAccount"), LIABILITY_TRANSFER_SUSPENSE("liabilityTransferInSuspenseAccount");
|
||||
|
||||
private final String value;
|
||||
|
||||
private LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
/*** Accounting placeholders for cash based accounting for savings products ***/
|
||||
public static enum CASH_ACCOUNTS_FOR_SAVINGS {
|
||||
SAVINGS_REFERENCE(1), SAVINGS_CONTROL(2), INTEREST_ON_SAVINGS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), TRANSFERS_SUSPENSE(
|
||||
10), OVERDRAFT_PORTFOLIO_CONTROL(11), INCOME_FROM_INTEREST(12), LOSSES_WRITTEN_OFF(13);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private CASH_ACCOUNTS_FOR_SAVINGS(final Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private static final Map<Integer, CASH_ACCOUNTS_FOR_SAVINGS> intToEnumMap = new HashMap<>();
|
||||
static {
|
||||
for (final CASH_ACCOUNTS_FOR_SAVINGS type : CASH_ACCOUNTS_FOR_SAVINGS.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static CASH_ACCOUNTS_FOR_SAVINGS fromInt(final int i) {
|
||||
final CASH_ACCOUNTS_FOR_SAVINGS type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Enum of all accounting related input parameter names used while
|
||||
* creating/updating a savings product
|
||||
***/
|
||||
public static enum SAVINGS_PRODUCT_ACCOUNTING_PARAMS {
|
||||
SAVINGS_REFERENCE("savingsReferenceAccountId"), SAVINGS_CONTROL("savingsControlAccountId"), INCOME_FROM_FEES(
|
||||
"incomeFromFeeAccountId"), INCOME_FROM_PENALTIES("incomeFromPenaltyAccountId"), INTEREST_ON_SAVINGS(
|
||||
"interestOnSavingsAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING("paymentChannelToFundSourceMappings"), PAYMENT_TYPE(
|
||||
"paymentTypeId"), FUND_SOURCE("fundSourceAccountId"), TRANSFERS_SUSPENSE("transfersInSuspenseAccountId"), FEE_INCOME_ACCOUNT_MAPPING(
|
||||
"feeToIncomeAccountMappings"), PENALTY_INCOME_ACCOUNT_MAPPING("penaltyToIncomeAccountMappings"), CHARGE_ID("chargeId"), INCOME_ACCOUNT_ID(
|
||||
"incomeAccountId"), OVERDRAFT_PORTFOLIO_CONTROL("overdraftPortfolioControlId"), INCOME_FROM_INTEREST("incomeFromInterestId"), LOSSES_WRITTEN_OFF(
|
||||
"writeOffAccountId");
|
||||
|
||||
private final String value;
|
||||
|
||||
private SAVINGS_PRODUCT_ACCOUNTING_PARAMS(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS {
|
||||
SAVINGS_REFERENCE("savingsReferenceAccount"), SAVINGS_CONTROL("savingsControlAccount"), INCOME_FROM_FEES("incomeFromFeeAccount"), INCOME_FROM_PENALTIES(
|
||||
"incomeFromPenaltyAccount"), INTEREST_ON_SAVINGS("interestOnSavingsAccount"), PAYMENT_TYPE("paymentType"), FUND_SOURCE(
|
||||
"fundSourceAccount"), TRANSFERS_SUSPENSE("transfersInSuspenseAccount"), PENALTY_INCOME_ACCOUNT_MAPPING(
|
||||
"penaltyToIncomeAccountMappings"), CHARGE_ID("charge"), INCOME_ACCOUNT_ID("incomeAccount"), OVERDRAFT_PORTFOLIO_CONTROL(
|
||||
"overdraftPortfolioControl"), INCOME_FROM_INTEREST("incomeFromInterest"), LOSSES_WRITTEN_OFF("writeOffAccount");
|
||||
|
||||
private final String value;
|
||||
|
||||
private SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum FINANCIAL_ACTIVITY {
|
||||
ASSET_TRANSFER(100, "assetTransfer", GLAccountType.ASSET), LIABILITY_TRANSFER(200, "liabilityTransfer", GLAccountType.LIABILITY),
|
||||
CASH_AT_MAINVAULT (101, "cashAtMainVault", GLAccountType.ASSET),
|
||||
CASH_AT_TELLER (102, "cashAtTeller", GLAccountType.ASSET),OPENING_BALANCES_TRANSFER_CONTRA (300,"openingBalancesTransferContra",GLAccountType.EQUITY),
|
||||
ASSET_FUND_SOURCE(103, "fundSource", GLAccountType.ASSET);
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
private final GLAccountType mappedGLAccountType;
|
||||
private static List<FinancialActivityData> financialActivities;
|
||||
|
||||
private FINANCIAL_ACTIVITY(final Integer value, final String code, final GLAccountType mappedGLAccountType) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
this.mappedGLAccountType = mappedGLAccountType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public GLAccountType getMappedGLAccountType() {
|
||||
return mappedGLAccountType;
|
||||
}
|
||||
|
||||
public String getValueAsString() {
|
||||
return this.value.toString();
|
||||
}
|
||||
|
||||
private static final Map<Integer, FINANCIAL_ACTIVITY> intToEnumMap = new HashMap<>();
|
||||
static {
|
||||
for (final FINANCIAL_ACTIVITY type : FINANCIAL_ACTIVITY.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static FINANCIAL_ACTIVITY fromInt(final int financialActivityId) {
|
||||
final FINANCIAL_ACTIVITY type = intToEnumMap.get(Integer.valueOf(financialActivityId));
|
||||
return type;
|
||||
}
|
||||
|
||||
public static FinancialActivityData toFinancialActivityData(final int financialActivityId) {
|
||||
final FINANCIAL_ACTIVITY type = fromInt(financialActivityId);
|
||||
return convertToFinancialActivityData(type);
|
||||
}
|
||||
|
||||
public static List<FinancialActivityData> getAllFinancialActivities() {
|
||||
if (financialActivities == null) {
|
||||
financialActivities = new ArrayList<>();
|
||||
for (final FINANCIAL_ACTIVITY type : FINANCIAL_ACTIVITY.values()) {
|
||||
FinancialActivityData financialActivityData = convertToFinancialActivityData(type);
|
||||
financialActivities.add(financialActivityData);
|
||||
}
|
||||
}
|
||||
return financialActivities;
|
||||
}
|
||||
|
||||
private static FinancialActivityData convertToFinancialActivityData(final FINANCIAL_ACTIVITY type) {
|
||||
FinancialActivityData financialActivityData = new FinancialActivityData(type.value, type.code, type.getMappedGLAccountType());
|
||||
return financialActivityData;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String ASSESTS_TAG_OPTION_CODE_NAME = "AssetAccountTags";
|
||||
public static final String LIABILITIES_TAG_OPTION_CODE_NAME = "LiabilityAccountTags";
|
||||
public static final String EQUITY_TAG_OPTION_CODE_NAME = "EquityAccountTags";
|
||||
public static final String INCOME_TAG_OPTION_CODE_NAME = "IncomeAccountTags";
|
||||
public static final String EXPENSES_TAG_OPTION_CODE_NAME = "ExpenseAccountTags";
|
||||
|
||||
}
|
||||
+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.accounting.common;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
|
||||
public interface AccountingDropdownReadPlatformService {
|
||||
|
||||
public List<EnumOptionData> retrieveGLAccountTypeOptions();
|
||||
|
||||
public List<EnumOptionData> retrieveGLAccountUsageOptions();
|
||||
|
||||
public List<EnumOptionData> retrieveJournalEntryTypeOptions();
|
||||
|
||||
public List<EnumOptionData> retrieveAccountingRuleTypeOptions();
|
||||
|
||||
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForLoanProducts();
|
||||
|
||||
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForSavingsProducts();
|
||||
|
||||
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForCharges();
|
||||
|
||||
public Map<String, List<GLAccountData>> retrieveAccountMappingOptions();
|
||||
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* 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.accounting.common;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage;
|
||||
import org.mifosplatform.accounting.glaccount.service.GLAccountReadPlatformService;
|
||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class AccountingDropdownReadPlatformServiceImpl implements AccountingDropdownReadPlatformService {
|
||||
|
||||
private final GLAccountReadPlatformService accountReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public AccountingDropdownReadPlatformServiceImpl(final GLAccountReadPlatformService accountReadPlatformService) {
|
||||
this.accountReadPlatformService = accountReadPlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EnumOptionData> retrieveGLAccountTypeOptions() {
|
||||
return AccountingEnumerations.gLAccountType(GLAccountType.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EnumOptionData> retrieveGLAccountUsageOptions() {
|
||||
return AccountingEnumerations.gLAccountUsage(GLAccountUsage.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EnumOptionData> retrieveJournalEntryTypeOptions() {
|
||||
return AccountingEnumerations.journalEntryTypes(JournalEntryType.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EnumOptionData> retrieveAccountingRuleTypeOptions() {
|
||||
return AccountingEnumerations.accountingRuleTypes(AccountingRuleType.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForLoanProducts() {
|
||||
return retrieveAccountMappingOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForSavingsProducts() {
|
||||
return retrieveAccountMappingOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForCharges() {
|
||||
// only get income and liability accounts
|
||||
boolean includeIncomeAccounts = true;
|
||||
boolean includeLiabilityAccounts = true;
|
||||
|
||||
boolean includeAssetAccounts = false;
|
||||
boolean includeExpenseAccounts = false;
|
||||
boolean includeEquityAccounts = false;
|
||||
|
||||
return retrieveAccountMappingOptions(includeAssetAccounts, includeIncomeAccounts, includeExpenseAccounts, includeLiabilityAccounts,
|
||||
includeEquityAccounts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<GLAccountData>> retrieveAccountMappingOptions() {
|
||||
boolean includeAssetAccounts = true;
|
||||
boolean includeIncomeAccounts = true;
|
||||
boolean includeExpenseAccounts = true;
|
||||
boolean includeLiabilityAccounts = true;
|
||||
boolean includeEquityAccounts = true;
|
||||
return retrieveAccountMappingOptions(includeAssetAccounts, includeIncomeAccounts, includeExpenseAccounts, includeLiabilityAccounts,
|
||||
includeEquityAccounts);
|
||||
}
|
||||
|
||||
private Map<String, List<GLAccountData>> retrieveAccountMappingOptions(boolean includeAssetAccounts, boolean includeIncomeAccounts,
|
||||
boolean includeExpenseAccounts, boolean includeLiabilityAccounts, boolean includeEquityAccounts) {
|
||||
final Map<String, List<GLAccountData>> accountOptions = new HashMap<>();
|
||||
|
||||
if (includeAssetAccounts) {
|
||||
List<GLAccountData> assetAccountOptions = this.accountReadPlatformService
|
||||
.retrieveAllEnabledDetailGLAccounts(GLAccountType.ASSET);
|
||||
if (assetAccountOptions.isEmpty()) {
|
||||
assetAccountOptions = null;
|
||||
}
|
||||
accountOptions.put("assetAccountOptions", assetAccountOptions);
|
||||
}
|
||||
|
||||
if (includeIncomeAccounts) {
|
||||
List<GLAccountData> incomeAccountOptions = this.accountReadPlatformService
|
||||
.retrieveAllEnabledDetailGLAccounts(GLAccountType.INCOME);
|
||||
if (incomeAccountOptions.isEmpty()) {
|
||||
incomeAccountOptions = null;
|
||||
}
|
||||
accountOptions.put("incomeAccountOptions", incomeAccountOptions);
|
||||
}
|
||||
|
||||
if (includeExpenseAccounts) {
|
||||
List<GLAccountData> expenseAccountOptions = this.accountReadPlatformService
|
||||
.retrieveAllEnabledDetailGLAccounts(GLAccountType.EXPENSE);
|
||||
if (expenseAccountOptions.isEmpty()) {
|
||||
expenseAccountOptions = null;
|
||||
}
|
||||
accountOptions.put("expenseAccountOptions", expenseAccountOptions);
|
||||
}
|
||||
|
||||
if (includeLiabilityAccounts) {
|
||||
List<GLAccountData> liabilityAccountOptions = this.accountReadPlatformService
|
||||
.retrieveAllEnabledDetailGLAccounts(GLAccountType.LIABILITY);
|
||||
if (liabilityAccountOptions.isEmpty()) {
|
||||
liabilityAccountOptions = null;
|
||||
}
|
||||
accountOptions.put("liabilityAccountOptions", liabilityAccountOptions);
|
||||
}
|
||||
|
||||
if (includeEquityAccounts) {
|
||||
List<GLAccountData> equityAccountOptions = this.accountReadPlatformService
|
||||
.retrieveAllEnabledDetailGLAccounts(GLAccountType.EQUITY);
|
||||
if (equityAccountOptions.isEmpty()) {
|
||||
equityAccountOptions = null;
|
||||
}
|
||||
accountOptions.put("equityAccountOptions", equityAccountOptions);
|
||||
}
|
||||
return accountOptions;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+100
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* 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.accounting.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage;
|
||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
|
||||
import org.mifosplatform.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
|
||||
public class AccountingEnumerations {
|
||||
|
||||
public static EnumOptionData gLAccountType(final int id) {
|
||||
return gLAccountType(GLAccountType.fromInt(id));
|
||||
}
|
||||
|
||||
public static EnumOptionData gLAccountType(final GLAccountType accountType) {
|
||||
final EnumOptionData optionData = new EnumOptionData(accountType.getValue().longValue(), accountType.getCode(),
|
||||
accountType.toString());
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static List<EnumOptionData> gLAccountType(final GLAccountType[] accountTypes) {
|
||||
final List<EnumOptionData> optionDatas = new ArrayList<>();
|
||||
for (final GLAccountType accountType : accountTypes) {
|
||||
optionDatas.add(gLAccountType(accountType));
|
||||
}
|
||||
return optionDatas;
|
||||
}
|
||||
|
||||
public static EnumOptionData gLAccountUsage(final int id) {
|
||||
return gLAccountUsage(GLAccountUsage.fromInt(id));
|
||||
}
|
||||
|
||||
public static EnumOptionData gLAccountUsage(final GLAccountUsage accountUsage) {
|
||||
final EnumOptionData optionData = new EnumOptionData(accountUsage.getValue().longValue(), accountUsage.getCode(),
|
||||
accountUsage.toString());
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static List<EnumOptionData> gLAccountUsage(final GLAccountUsage[] accountUsages) {
|
||||
final List<EnumOptionData> optionDatas = new ArrayList<>();
|
||||
for (final GLAccountUsage accountUsage : accountUsages) {
|
||||
optionDatas.add(gLAccountUsage(accountUsage));
|
||||
}
|
||||
return optionDatas;
|
||||
}
|
||||
|
||||
public static EnumOptionData journalEntryType(final int id) {
|
||||
return journalEntryType(JournalEntryType.fromInt(id));
|
||||
}
|
||||
|
||||
public static EnumOptionData journalEntryType(final JournalEntryType journalEntryType) {
|
||||
final EnumOptionData optionData = new EnumOptionData(journalEntryType.getValue().longValue(), journalEntryType.getCode(),
|
||||
journalEntryType.toString());
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static List<EnumOptionData> journalEntryTypes(final JournalEntryType[] journalEntryTypes) {
|
||||
final List<EnumOptionData> optionDatas = new ArrayList<>();
|
||||
for (final JournalEntryType journalEntryType : journalEntryTypes) {
|
||||
optionDatas.add(journalEntryType(journalEntryType));
|
||||
}
|
||||
return optionDatas;
|
||||
}
|
||||
|
||||
public static EnumOptionData portfolioProductType(final int id) {
|
||||
return portfolioProductType(PortfolioProductType.fromInt(id));
|
||||
}
|
||||
|
||||
public static EnumOptionData portfolioProductType(final PortfolioProductType portfolioProductType) {
|
||||
final EnumOptionData optionData = new EnumOptionData(portfolioProductType.getValue().longValue(), portfolioProductType.getCode(),
|
||||
portfolioProductType.toString());
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static EnumOptionData accountingRuleType(final int id) {
|
||||
return accountingRuleType(AccountingRuleType.fromInt(id));
|
||||
}
|
||||
|
||||
public static EnumOptionData accountingRuleType(final AccountingRuleType type) {
|
||||
final EnumOptionData optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), type.toString());
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static List<EnumOptionData> accountingRuleTypes(final AccountingRuleType[] accountingRuleTypes) {
|
||||
final List<EnumOptionData> optionDatas = new ArrayList<>();
|
||||
for (final AccountingRuleType accountingRuleType : accountingRuleTypes) {
|
||||
optionDatas.add(accountingRuleType(accountingRuleType));
|
||||
}
|
||||
return optionDatas;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+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.accounting.common;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum AccountingRuleType {
|
||||
|
||||
NONE(1, "accountingRuleType.none"), //
|
||||
CASH_BASED(2, "accountingRuleType.cash"), //
|
||||
ACCRUAL_PERIODIC(3, "accountingRuleType.accrual.periodic"), //
|
||||
ACCRUAL_UPFRONT(4, "accountingRuleType.accrual.upfront"); //
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private static final Map<Integer, AccountingRuleType> intToEnumMap = new HashMap<>();
|
||||
static {
|
||||
for (final AccountingRuleType type : AccountingRuleType.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static AccountingRuleType fromInt(final Integer ruleTypeValue) {
|
||||
final AccountingRuleType type = intToEnumMap.get(ruleTypeValue);
|
||||
return type;
|
||||
}
|
||||
|
||||
private AccountingRuleType(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return this.code;
|
||||
}
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.mifosplatform.accounting.financialactivityaccount.data.FinancialActivityAccountData;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.service.FinancialActivityAccountReadPlatformService;
|
||||
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.security.service.PlatformSecurityContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/financialactivityaccounts")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class FinancialActivityAccountsApiResource {
|
||||
|
||||
private final FinancialActivityAccountReadPlatformService financialActivityAccountReadPlatformService;
|
||||
private final DefaultToApiJsonSerializer<FinancialActivityAccountData> apiJsonSerializerService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PlatformSecurityContext context;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public FinancialActivityAccountsApiResource(final PlatformSecurityContext context,
|
||||
final FinancialActivityAccountReadPlatformService officeToGLAccountMappingReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<FinancialActivityAccountData> toApiJsonSerializer,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.context = context;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.apiJsonSerializerService = toApiJsonSerializer;
|
||||
this.financialActivityAccountReadPlatformService = officeToGLAccountMappingReadPlatformService;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveTemplate(@Context final UriInfo uriInfo) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
|
||||
|
||||
FinancialActivityAccountData financialActivityAccountData = this.financialActivityAccountReadPlatformService
|
||||
.getFinancialActivityAccountTemplate();
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serialize(settings, financialActivityAccountData,
|
||||
FinancialActivityAccountsConstants.RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAll(@Context final UriInfo uriInfo) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
|
||||
final List<FinancialActivityAccountData> financialActivityAccounts = this.financialActivityAccountReadPlatformService.retrieveAll();
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serialize(settings, financialActivityAccounts,
|
||||
FinancialActivityAccountsConstants.RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{mappingId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retreive(@PathParam("mappingId") final Long mappingId, @Context final UriInfo uriInfo) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
FinancialActivityAccountData financialActivityAccountData = this.financialActivityAccountReadPlatformService.retrieve(mappingId);
|
||||
if (settings.isTemplate()) {
|
||||
financialActivityAccountData = this.financialActivityAccountReadPlatformService
|
||||
.addTemplateDetails(financialActivityAccountData);
|
||||
}
|
||||
|
||||
return this.apiJsonSerializerService.serialize(settings, financialActivityAccountData,
|
||||
FinancialActivityAccountsConstants.RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String createGLAccount(final String jsonRequestBody) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createOfficeToGLAccountMapping().withJson(jsonRequestBody)
|
||||
.build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{mappingId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateGLAccount(@PathParam("mappingId") final Long mappingId, final String jsonRequestBody) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateOfficeToGLAccountMapping(mappingId)
|
||||
.withJson(jsonRequestBody).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{mappingId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteGLAccount(@PathParam("mappingId") final Long mappingId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteOfficeToGLAccountMapping(mappingId).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class FinancialActivityAccountsConstants {
|
||||
|
||||
public static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "financialActivityData",
|
||||
"glAccountData", "glAccountOptions", "financialActivityOptions"));
|
||||
|
||||
public static final String resourceNameForPermission = "FINANCIALACTIVITYACCOUNT";
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.api;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/***
|
||||
* Enum of all parameters passed in while creating/updating a GL Account
|
||||
***/
|
||||
public enum FinancialActivityAccountsJsonInputParams {
|
||||
FINANCIAL_ACTIVITY_ID("financialActivityId"), GL_ACCOUNT_ID("glAccountId");
|
||||
|
||||
private final String value;
|
||||
|
||||
private FinancialActivityAccountsJsonInputParams(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private static final Set<String> values = new HashSet<>();
|
||||
static {
|
||||
for (final FinancialActivityAccountsJsonInputParams type : FinancialActivityAccountsJsonInputParams.values()) {
|
||||
values.add(type.value);
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> getAllValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||
|
||||
public class FinancialActivityAccountData {
|
||||
|
||||
private final Long id;
|
||||
private final FinancialActivityData financialActivityData;
|
||||
private final GLAccountData glAccountData;
|
||||
private Map<String, List<GLAccountData>> glAccountOptions;
|
||||
private List<FinancialActivityData> financialActivityOptions;
|
||||
|
||||
public FinancialActivityAccountData() {
|
||||
this.id = null;
|
||||
this.glAccountData = null;
|
||||
this.financialActivityData = null;
|
||||
this.glAccountOptions = null;
|
||||
this.financialActivityOptions = null;
|
||||
}
|
||||
|
||||
public FinancialActivityAccountData(final Long id, final FinancialActivityData financialActivityData, final GLAccountData glAccountData) {
|
||||
this.id = id;
|
||||
this.glAccountData = glAccountData;
|
||||
this.financialActivityData = financialActivityData;
|
||||
}
|
||||
|
||||
public FinancialActivityAccountData(Map<String, List<GLAccountData>> glAccountOptions,
|
||||
List<FinancialActivityData> financialActivityOptions) {
|
||||
this.id = null;
|
||||
this.glAccountData = null;
|
||||
this.financialActivityData = null;
|
||||
this.glAccountOptions = glAccountOptions;
|
||||
this.financialActivityOptions = financialActivityOptions;
|
||||
|
||||
}
|
||||
|
||||
public List<FinancialActivityData> getFinancialActivityOptions() {
|
||||
return financialActivityOptions;
|
||||
}
|
||||
|
||||
public void setFinancialActivityOptions(List<FinancialActivityData> financialActivityOptions) {
|
||||
this.financialActivityOptions = financialActivityOptions;
|
||||
}
|
||||
|
||||
public Map<String, List<GLAccountData>> getAccountingMappingOptions() {
|
||||
return this.glAccountOptions;
|
||||
}
|
||||
|
||||
public void setAccountingMappingOptions(Map<String, List<GLAccountData>> accountingMappingOptions) {
|
||||
this.glAccountOptions = accountingMappingOptions;
|
||||
}
|
||||
|
||||
public GLAccountData getGlAccountData() {
|
||||
return glAccountData;
|
||||
}
|
||||
|
||||
public FinancialActivityData getFinancialActivityData() {
|
||||
return financialActivityData;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.data;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
|
||||
public class FinancialActivityData {
|
||||
|
||||
private final Integer id;
|
||||
private final String name;
|
||||
private final GLAccountType mappedGLAccountType;
|
||||
|
||||
public Integer getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public GLAccountType getMappedGLAccountType() {
|
||||
return this.mappedGLAccountType;
|
||||
}
|
||||
|
||||
public FinancialActivityData(Integer id, String name, GLAccountType mappedGLAccountType) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.mappedGLAccountType = mappedGLAccountType;
|
||||
}
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.domain;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "acc_gl_financial_activity_account")
|
||||
public class FinancialActivityAccount extends AbstractPersistable<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "gl_account_id")
|
||||
private GLAccount glAccount;
|
||||
|
||||
@Column(name = "financial_activity_type", nullable = false)
|
||||
private Integer financialActivityType;
|
||||
|
||||
public static FinancialActivityAccount createNew(final GLAccount glAccount, final Integer financialAccountType) {
|
||||
return new FinancialActivityAccount(glAccount, financialAccountType);
|
||||
}
|
||||
|
||||
protected FinancialActivityAccount() {
|
||||
//
|
||||
}
|
||||
|
||||
private FinancialActivityAccount(final GLAccount glAccount, final int financialAccountType) {
|
||||
this.glAccount = glAccount;
|
||||
this.financialActivityType = financialAccountType;
|
||||
}
|
||||
|
||||
public GLAccount getGlAccount() {
|
||||
return this.glAccount;
|
||||
}
|
||||
|
||||
public Integer getFinancialActivityType() {
|
||||
return this.financialActivityType;
|
||||
}
|
||||
|
||||
public void updateGlAccount(final GLAccount glAccount) {
|
||||
this.glAccount = glAccount;
|
||||
}
|
||||
|
||||
public void updateFinancialActivityType(final Integer financialActivityType) {
|
||||
this.financialActivityType = financialActivityType;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface FinancialActivityAccountRepository extends JpaRepository<FinancialActivityAccount, Long>,
|
||||
JpaSpecificationExecutor<FinancialActivityAccount> {
|
||||
|
||||
@Query("from FinancialActivityAccount faa where faa.financialActivityType = :financialActivityType")
|
||||
FinancialActivityAccount findByFinancialActivityType(@Param("financialActivityType") int financialAccountType);
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.financialactivityaccount.exception.FinancialActivityAccountNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Wrapper for {@link FinancialActivityAccountRepository} that adds NULL
|
||||
* checking and Error handling capabilities
|
||||
* </p>
|
||||
*/
|
||||
@Service
|
||||
public class FinancialActivityAccountRepositoryWrapper {
|
||||
|
||||
private final FinancialActivityAccountRepository repository;
|
||||
|
||||
@Autowired
|
||||
public FinancialActivityAccountRepositoryWrapper(final FinancialActivityAccountRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public FinancialActivityAccount findOneWithNotFoundDetection(final Long id) {
|
||||
final FinancialActivityAccount financialActivityAccount = this.repository.findOne(id);
|
||||
if (financialActivityAccount == null) { throw new FinancialActivityAccountNotFoundException(id); }
|
||||
return financialActivityAccount;
|
||||
}
|
||||
|
||||
public FinancialActivityAccount findByFinancialActivityTypeWithNotFoundDetection(final int financialActivityType) {
|
||||
FinancialActivityAccount financialActivityAccount = this.repository.findByFinancialActivityType(financialActivityType);
|
||||
if (financialActivityAccount == null) { throw new FinancialActivityAccountNotFoundException(financialActivityType); }
|
||||
return financialActivityAccount;
|
||||
}
|
||||
|
||||
public List<FinancialActivityAccount> findAll() {
|
||||
return this.repository.findAll();
|
||||
}
|
||||
|
||||
public void save(final FinancialActivityAccount entity) {
|
||||
this.repository.save(entity);
|
||||
}
|
||||
|
||||
public void saveAndFlush(final FinancialActivityAccount entity) {
|
||||
this.repository.saveAndFlush(entity);
|
||||
}
|
||||
|
||||
public void delete(final FinancialActivityAccount entity) {
|
||||
this.repository.delete(entity);
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when product to GL account mapping are not
|
||||
* found.
|
||||
*/
|
||||
public class DuplicateFinancialActivityAccountFoundException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
private final static String errorCode = "error.msg.financialActivityAccount.exists";
|
||||
|
||||
public DuplicateFinancialActivityAccountFoundException(final Integer financialActivityType) {
|
||||
super(errorCode, "Mapping for activity already exists " + financialActivityType, financialActivityType);
|
||||
}
|
||||
|
||||
public static String getErrorcode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.exception;
|
||||
|
||||
import org.mifosplatform.accounting.common.AccountingConstants.FINANCIAL_ACTIVITY;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when product to GL account mapping are not
|
||||
* found.
|
||||
*/
|
||||
public class FinancialActivityAccountInvalidException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
private final static String errorCode = "error.msg.financialActivityAccount.invalid";
|
||||
|
||||
public FinancialActivityAccountInvalidException(final FINANCIAL_ACTIVITY financialActivity, final GLAccount glAccount) {
|
||||
super(errorCode, "Financial Activity '" + financialActivity.getCode() + "' with Id :" + financialActivity.getValue()
|
||||
+ "' can only be associated with a Ledger Account of Type " + financialActivity.getMappedGLAccountType().getCode()
|
||||
+ " the provided Ledger Account '" + glAccount.getName() + "(" + glAccount.getGlCode()
|
||||
+ ")' does not of the required type", financialActivity.getCode(), financialActivity.getValue(), financialActivity
|
||||
.getMappedGLAccountType().getCode(), glAccount.getName(), glAccount.getGlCode());
|
||||
}
|
||||
|
||||
public static String getErrorcode() {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when product to GL account mapping are not
|
||||
* found.
|
||||
*/
|
||||
public class FinancialActivityAccountNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public FinancialActivityAccountNotFoundException(final Long id) {
|
||||
super("error.msg.financialActivityAccount.not.found", "Financial Activity account with Id " + id + " does not exist", id);
|
||||
}
|
||||
|
||||
public FinancialActivityAccountNotFoundException(final Integer financialActivityType) {
|
||||
super("error.msg.financialActivityAccount.not.found", "Financial Activity account with for the financial Activity with Id "
|
||||
+ financialActivityType + " does not exist", financialActivityType);
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.handler;
|
||||
|
||||
import org.mifosplatform.accounting.financialactivityaccount.service.FinancialActivityAccountWritePlatformService;
|
||||
import org.mifosplatform.commands.annotation.CommandType;
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "FINANCIALACTIVITYACCOUNT", action = "CREATE")
|
||||
public class CreateFinancialActivityAccountHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final FinancialActivityAccountWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CreateFinancialActivityAccountHandler(final FinancialActivityAccountWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.createFinancialActivityAccountMapping(command);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.handler;
|
||||
|
||||
import org.mifosplatform.accounting.financialactivityaccount.service.FinancialActivityAccountWritePlatformService;
|
||||
import org.mifosplatform.commands.annotation.CommandType;
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "FINANCIALACTIVITYACCOUNT", action = "DELETE")
|
||||
public class DeleteFinancialActivityAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final FinancialActivityAccountWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DeleteFinancialActivityAccountCommandHandler(final FinancialActivityAccountWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.deleteGLAccountActivityMapping(command.entityId(), command);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.handler;
|
||||
|
||||
import org.mifosplatform.accounting.financialactivityaccount.service.FinancialActivityAccountWritePlatformService;
|
||||
import org.mifosplatform.commands.annotation.CommandType;
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "FINANCIALACTIVITYACCOUNT", action = "UPDATE")
|
||||
public class UpdateFinancialActivityAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final FinancialActivityAccountWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public UpdateFinancialActivityAccountCommandHandler(final FinancialActivityAccountWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.updateGLAccountActivityMapping(command.entityId(), command);
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.accounting.common.AccountingConstants.FINANCIAL_ACTIVITY;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.api.FinancialActivityAccountsJsonInputParams;
|
||||
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 final class FinancialActivityAccountDataValidator {
|
||||
|
||||
/**
|
||||
* The parameters supported for this command.
|
||||
*/
|
||||
private final Set<String> supportedParameters = FinancialActivityAccountsJsonInputParams.getAllValues();
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
private final String paramNameForFinancialActivity = FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue();
|
||||
private final String paramNameForGLAccount = FinancialActivityAccountsJsonInputParams.GL_ACCOUNT_ID.getValue();
|
||||
|
||||
@Autowired
|
||||
public FinancialActivityAccountDataValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateForCreate(final String json) {
|
||||
validateJSONAndCheckForUnsupportedParams(json);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = getDataValidator(dataValidationErrors);
|
||||
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final Integer financialActivityId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(paramNameForFinancialActivity, element);
|
||||
baseDataValidator.reset().parameter(paramNameForFinancialActivity).value(financialActivityId).notNull().isOneOfTheseValues(
|
||||
FINANCIAL_ACTIVITY.ASSET_TRANSFER.getValue(), FINANCIAL_ACTIVITY.LIABILITY_TRANSFER.getValue(),
|
||||
FINANCIAL_ACTIVITY.CASH_AT_MAINVAULT.getValue(), FINANCIAL_ACTIVITY.CASH_AT_TELLER.getValue(),
|
||||
FINANCIAL_ACTIVITY.OPENING_BALANCES_TRANSFER_CONTRA.getValue(), FINANCIAL_ACTIVITY.ASSET_FUND_SOURCE.getValue());
|
||||
|
||||
final Long glAccountId = this.fromApiJsonHelper.extractLongNamed(paramNameForGLAccount, element);
|
||||
baseDataValidator.reset().parameter(paramNameForGLAccount).value(glAccountId).notNull().integerGreaterThanZero();
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private DataValidatorBuilder getDataValidator(final List<ApiParameterError> dataValidationErrors) {
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("financialactivityaccount");
|
||||
return baseDataValidator;
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json) {
|
||||
validateJSONAndCheckForUnsupportedParams(json);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = getDataValidator(dataValidationErrors);
|
||||
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(paramNameForFinancialActivity, element)) {
|
||||
final Integer financialActivityId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(paramNameForFinancialActivity,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(paramNameForFinancialActivity).value(financialActivityId).ignoreIfNull().isOneOfTheseValues(
|
||||
FINANCIAL_ACTIVITY.ASSET_TRANSFER.getValue(), FINANCIAL_ACTIVITY.LIABILITY_TRANSFER.getValue(),
|
||||
FINANCIAL_ACTIVITY.OPENING_BALANCES_TRANSFER_CONTRA.getValue(), FINANCIAL_ACTIVITY.ASSET_FUND_SOURCE.getValue());
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(paramNameForGLAccount, element)) {
|
||||
final Long glAccountId = this.fromApiJsonHelper.extractLongNamed(paramNameForGLAccount, element);
|
||||
baseDataValidator.reset().parameter(paramNameForGLAccount).value(glAccountId).ignoreIfNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void validateJSONAndCheckForUnsupportedParams(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.financialactivityaccount.data.FinancialActivityAccountData;
|
||||
|
||||
public interface FinancialActivityAccountReadPlatformService {
|
||||
|
||||
List<FinancialActivityAccountData> retrieveAll();
|
||||
|
||||
FinancialActivityAccountData retrieve(Long mappingId);
|
||||
|
||||
FinancialActivityAccountData addTemplateDetails(FinancialActivityAccountData financialActivityAccountData);
|
||||
|
||||
FinancialActivityAccountData getFinancialActivityAccountTemplate();
|
||||
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.service;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.accounting.common.AccountingConstants.FINANCIAL_ACTIVITY;
|
||||
import org.mifosplatform.accounting.common.AccountingDropdownReadPlatformService;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.data.FinancialActivityAccountData;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.data.FinancialActivityData;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.exception.FinancialActivityAccountNotFoundException;
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||
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 FinancialActivityAccountReadPlatformServiceImpl implements FinancialActivityAccountReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final FinancialActivityAccountMapper financialActivityAccountMapper;
|
||||
private final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public FinancialActivityAccountReadPlatformServiceImpl(final RoutingDataSource dataSource,
|
||||
final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService) {
|
||||
financialActivityAccountMapper = new FinancialActivityAccountMapper();
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.accountingDropdownReadPlatformService = accountingDropdownReadPlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FinancialActivityAccountData> retrieveAll() {
|
||||
String sql = "select " + financialActivityAccountMapper.schema();
|
||||
return this.jdbcTemplate.query(sql, financialActivityAccountMapper, new Object[] {});
|
||||
}
|
||||
|
||||
@Override
|
||||
public FinancialActivityAccountData retrieve(Long financialActivityAccountId) {
|
||||
try {
|
||||
StringBuilder sqlBuilder = new StringBuilder(200);
|
||||
sqlBuilder.append("select ");
|
||||
sqlBuilder.append(this.financialActivityAccountMapper.schema());
|
||||
sqlBuilder.append(" where faa.id=?");
|
||||
return this.jdbcTemplate.queryForObject(sqlBuilder.toString(), this.financialActivityAccountMapper,
|
||||
new Object[] { financialActivityAccountId });
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
throw new FinancialActivityAccountNotFoundException(financialActivityAccountId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FinancialActivityAccountData addTemplateDetails(FinancialActivityAccountData financialActivityAccountData) {
|
||||
final Map<String, List<GLAccountData>> accountOptions = this.accountingDropdownReadPlatformService.retrieveAccountMappingOptions();
|
||||
financialActivityAccountData.setAccountingMappingOptions(accountOptions);
|
||||
financialActivityAccountData.setFinancialActivityOptions(FINANCIAL_ACTIVITY.getAllFinancialActivities());
|
||||
return financialActivityAccountData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FinancialActivityAccountData getFinancialActivityAccountTemplate() {
|
||||
FinancialActivityAccountData financialActivityAccountData = new FinancialActivityAccountData();
|
||||
return addTemplateDetails(financialActivityAccountData);
|
||||
}
|
||||
|
||||
private static final class FinancialActivityAccountMapper implements RowMapper<FinancialActivityAccountData> {
|
||||
|
||||
private final String sql;
|
||||
|
||||
public FinancialActivityAccountMapper() {
|
||||
StringBuilder sb = new StringBuilder(300);
|
||||
sb.append(" faa.id as id, faa.financial_activity_type as financialActivityId, glaccount.id as glAccountId,glaccount.name as glAccountName,glaccount.gl_code as glCode ");
|
||||
sb.append(" from acc_gl_financial_activity_account faa ");
|
||||
sb.append(" join acc_gl_account glaccount on glaccount.id = faa.gl_account_id");
|
||||
sql = sb.toString();
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FinancialActivityAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
final Long id = JdbcSupport.getLong(rs, "id");
|
||||
final Long glAccountId = JdbcSupport.getLong(rs, "glAccountId");
|
||||
final Integer financialActivityId = JdbcSupport.getInteger(rs, "financialActivityId");
|
||||
final String glAccountName = rs.getString("glAccountName");
|
||||
final String glCode = rs.getString("glCode");
|
||||
|
||||
final GLAccountData glAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
|
||||
final FinancialActivityData financialActivityData = FINANCIAL_ACTIVITY.toFinancialActivityData(financialActivityId);
|
||||
|
||||
final FinancialActivityAccountData financialActivityAccountData = new FinancialActivityAccountData(id, financialActivityData,
|
||||
glAccountData);
|
||||
return financialActivityAccountData;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
|
||||
public interface FinancialActivityAccountWritePlatformService {
|
||||
|
||||
CommandProcessingResult createFinancialActivityAccountMapping(JsonCommand command);
|
||||
|
||||
CommandProcessingResult updateGLAccountActivityMapping(Long mappingId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult deleteGLAccountActivityMapping(Long mappingId, JsonCommand command);
|
||||
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* 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.accounting.financialactivityaccount.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.accounting.common.AccountingConstants.FINANCIAL_ACTIVITY;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.api.FinancialActivityAccountsJsonInputParams;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.domain.FinancialActivityAccount;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.exception.DuplicateFinancialActivityAccountFoundException;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.exception.FinancialActivityAccountInvalidException;
|
||||
import org.mifosplatform.accounting.financialactivityaccount.serialization.FinancialActivityAccountDataValidator;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountRepositoryWrapper;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class FinancialActivityAccountWritePlatformServiceImpl implements FinancialActivityAccountWritePlatformService {
|
||||
|
||||
private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepository;
|
||||
private final FinancialActivityAccountDataValidator fromApiJsonDeserializer;
|
||||
private final GLAccountRepositoryWrapper glAccountRepositoryWrapper;
|
||||
private final static Logger logger = LoggerFactory.getLogger(FinancialActivityAccountWritePlatformServiceImpl.class);
|
||||
|
||||
@Autowired
|
||||
public FinancialActivityAccountWritePlatformServiceImpl(
|
||||
final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepository,
|
||||
final FinancialActivityAccountDataValidator fromApiJsonDeserializer, final GLAccountRepositoryWrapper glAccountRepositoryWrapper) {
|
||||
this.financialActivityAccountRepository = financialActivityAccountRepository;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.glAccountRepositoryWrapper = glAccountRepositoryWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult createFinancialActivityAccountMapping(JsonCommand command) {
|
||||
try {
|
||||
|
||||
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
||||
|
||||
final Integer financialActivityId = command
|
||||
.integerValueSansLocaleOfParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue());
|
||||
final Long accountId = command.longValueOfParameterNamed(FinancialActivityAccountsJsonInputParams.GL_ACCOUNT_ID.getValue());
|
||||
final GLAccount glAccount = glAccountRepositoryWrapper.findOneWithNotFoundDetection(accountId);
|
||||
FinancialActivityAccount financialActivityAccount = FinancialActivityAccount.createNew(glAccount, financialActivityId);
|
||||
|
||||
validateFinancialActivityAndAccountMapping(financialActivityAccount);
|
||||
this.financialActivityAccountRepository.save(financialActivityAccount);
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(financialActivityAccount.getId()) //
|
||||
.build();
|
||||
} catch (DataIntegrityViolationException dataIntegrityViolationException) {
|
||||
handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the GL Account is appropriate for the particular Financial
|
||||
* Activity Type
|
||||
**/
|
||||
private void validateFinancialActivityAndAccountMapping(FinancialActivityAccount financialActivityAccount) {
|
||||
FINANCIAL_ACTIVITY financialActivity = FINANCIAL_ACTIVITY.fromInt(financialActivityAccount.getFinancialActivityType());
|
||||
GLAccount glAccount = financialActivityAccount.getGlAccount();
|
||||
if (!financialActivity.getMappedGLAccountType().getValue().equals(glAccount.getType())) { throw new FinancialActivityAccountInvalidException(
|
||||
financialActivity, glAccount); }
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult updateGLAccountActivityMapping(Long financialActivityAccountId, JsonCommand command) {
|
||||
try {
|
||||
this.fromApiJsonDeserializer.validateForUpdate(command.json());
|
||||
final FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository
|
||||
.findOneWithNotFoundDetection(financialActivityAccountId);
|
||||
Map<String, Object> changes = findChanges(command, financialActivityAccount);
|
||||
|
||||
if (changes.containsKey(FinancialActivityAccountsJsonInputParams.GL_ACCOUNT_ID.getValue())) {
|
||||
final Long accountId = command.longValueOfParameterNamed(FinancialActivityAccountsJsonInputParams.GL_ACCOUNT_ID.getValue());
|
||||
final GLAccount glAccount = glAccountRepositoryWrapper.findOneWithNotFoundDetection(accountId);
|
||||
financialActivityAccount.updateGlAccount(glAccount);
|
||||
}
|
||||
|
||||
if (changes.containsKey(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue())) {
|
||||
final Integer financialActivityId = command
|
||||
.integerValueSansLocaleOfParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue());
|
||||
financialActivityAccount.updateFinancialActivityType(financialActivityId);
|
||||
}
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
validateFinancialActivityAndAccountMapping(financialActivityAccount);
|
||||
this.financialActivityAccountRepository.save(financialActivityAccount);
|
||||
}
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(financialActivityAccountId) //
|
||||
.with(changes) //
|
||||
.build();
|
||||
} catch (DataIntegrityViolationException dataIntegrityViolationException) {
|
||||
handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult deleteGLAccountActivityMapping(Long financialActivityAccountId, JsonCommand command) {
|
||||
final FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository
|
||||
.findOneWithNotFoundDetection(financialActivityAccountId);
|
||||
this.financialActivityAccountRepository.delete(financialActivityAccount);
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(financialActivityAccountId) //
|
||||
.build();
|
||||
}
|
||||
|
||||
private void handleFinancialActivityAccountDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
|
||||
final Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("financial_activity_type")) {
|
||||
final Integer financialActivityId = command
|
||||
.integerValueSansLocaleOfParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue());
|
||||
throw new DuplicateFinancialActivityAccountFoundException(financialActivityId);
|
||||
}
|
||||
|
||||
logger.error(dve.getMessage(), dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.glAccount.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource GL Account: " + realCause.getMessage());
|
||||
}
|
||||
|
||||
public Map<String, Object> findChanges(JsonCommand command, FinancialActivityAccount financialActivityAccount) {
|
||||
|
||||
Map<String, Object> changes = new HashMap<>();
|
||||
|
||||
Long existingGLAccountId = financialActivityAccount.getGlAccount().getId();
|
||||
Integer financialActivityType = financialActivityAccount.getFinancialActivityType();
|
||||
|
||||
// is the account Id changed?
|
||||
if (command.isChangeInLongParameterNamed(FinancialActivityAccountsJsonInputParams.GL_ACCOUNT_ID.getValue(), existingGLAccountId)) {
|
||||
final Long newValue = command.longValueOfParameterNamed(FinancialActivityAccountsJsonInputParams.GL_ACCOUNT_ID.getValue());
|
||||
changes.put(FinancialActivityAccountsJsonInputParams.GL_ACCOUNT_ID.getValue(), newValue);
|
||||
}
|
||||
|
||||
// is the financial Activity changed
|
||||
if (command.isChangeInIntegerSansLocaleParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue(),
|
||||
financialActivityType)) {
|
||||
final Integer newValue = command
|
||||
.integerValueSansLocaleOfParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue());
|
||||
changes.put(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue(), newValue);
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.api;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/***
|
||||
* Enum of all parameters passed in while creating/updating a GL Account
|
||||
***/
|
||||
public enum GLAccountJsonInputParams {
|
||||
ID("id"), NAME("name"), PARENT_ID("parentId"), GL_CODE("glCode"), DISABLED("disabled"), MANUAL_ENTRIES_ALLOWED("manualEntriesAllowed"), TYPE(
|
||||
"type"), USAGE("usage"), DESCRIPTION("description"), TAGID("tagId");
|
||||
|
||||
private final String value;
|
||||
|
||||
private GLAccountJsonInputParams(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private static final Set<String> values = new HashSet<>();
|
||||
static {
|
||||
for (final GLAccountJsonInputParams type : GLAccountJsonInputParams.values()) {
|
||||
values.add(type.value);
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> getAllValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
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.accounting.common.AccountingConstants;
|
||||
import org.mifosplatform.accounting.common.AccountingDropdownReadPlatformService;
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
import org.mifosplatform.accounting.glaccount.service.GLAccountReadPlatformService;
|
||||
import org.mifosplatform.accounting.journalentry.data.JournalEntryAssociationParametersData;
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||
import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/glaccounts")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class GLAccountsApiResource {
|
||||
|
||||
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "name", "parentId", "glCode",
|
||||
"disabled", "manualEntriesAllowed", "type", "usage", "description", "assetHeaderAccountOptions",
|
||||
"liabilityHeaderAccountOptions", "equityHeaderAccountOptions", "incomeHeaderAccountOptions", "expenseHeaderAccountOptions",
|
||||
"nameDecorated", "tagId", "allowedAssetsTagOptions", "allowedLiabilitiesTagOptions", "allowedEquityTagOptions",
|
||||
"allowedIncomeTagOptions", "allowedExpensesTagOptions", "creditAccounts", "debitAccounts"));
|
||||
|
||||
private final String resourceNameForPermission = "GLACCOUNT";
|
||||
|
||||
private final GLAccountReadPlatformService glAccountReadPlatformService;
|
||||
private final AccountingDropdownReadPlatformService dropdownReadPlatformService;
|
||||
private final DefaultToApiJsonSerializer<GLAccountData> apiJsonSerializerService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PlatformSecurityContext context;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public GLAccountsApiResource(final PlatformSecurityContext context, final GLAccountReadPlatformService glAccountReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<GLAccountData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||
final AccountingDropdownReadPlatformService dropdownReadPlatformService,
|
||||
final CodeValueReadPlatformService codeValueReadPlatformService) {
|
||||
this.context = context;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.apiJsonSerializerService = toApiJsonSerializer;
|
||||
this.glAccountReadPlatformService = glAccountReadPlatformService;
|
||||
this.dropdownReadPlatformService = dropdownReadPlatformService;
|
||||
this.codeValueReadPlatformService = codeValueReadPlatformService;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveNewAccountDetails(@Context final UriInfo uriInfo, @QueryParam("type") final Integer type) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
|
||||
|
||||
GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveNewGLAccountDetails(type);
|
||||
glAccountData = handleTemplate(glAccountData);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serialize(settings, glAccountData, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAllAccounts(@Context final UriInfo uriInfo, @QueryParam("type") final Integer type,
|
||||
@QueryParam("searchParam") final String searchParam, @QueryParam("usage") final Integer usage,
|
||||
@QueryParam("manualEntriesAllowed") final Boolean manualEntriesAllowed, @QueryParam("disabled") final Boolean disabled,
|
||||
@QueryParam("fetchRunningBalance") final boolean runningBalance) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
|
||||
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance);
|
||||
final List<GLAccountData> glAccountDatas = this.glAccountReadPlatformService.retrieveAllGLAccounts(type, searchParam, usage,
|
||||
manualEntriesAllowed, disabled, associationParametersData);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serialize(settings, glAccountDatas, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{glAccountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retreiveAccount(@PathParam("glAccountId") final Long glAccountId, @Context final UriInfo uriInfo,
|
||||
@QueryParam("fetchRunningBalance") final boolean runningBalance) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance);
|
||||
GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveGLAccountById(glAccountId, associationParametersData);
|
||||
if (settings.isTemplate()) {
|
||||
glAccountData = handleTemplate(glAccountData);
|
||||
}
|
||||
|
||||
return this.apiJsonSerializerService.serialize(settings, glAccountData, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String createGLAccount(final String jsonRequestBody) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLAccount().withJson(jsonRequestBody).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{glAccountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateGLAccount(@PathParam("glAccountId") final Long glAccountId, final String jsonRequestBody) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLAccount(glAccountId).withJson(jsonRequestBody).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{glAccountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteGLAccount(@PathParam("glAccountId") final Long glAccountId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLAccount(glAccountId).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
|
||||
private GLAccountData handleTemplate(final GLAccountData glAccountData) {
|
||||
final List<EnumOptionData> accountTypeOptions = this.dropdownReadPlatformService.retrieveGLAccountTypeOptions();
|
||||
final List<EnumOptionData> usageOptions = this.dropdownReadPlatformService.retrieveGLAccountUsageOptions();
|
||||
final List<GLAccountData> assetHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService
|
||||
.retrieveAllEnabledHeaderGLAccounts(GLAccountType.ASSET));
|
||||
final List<GLAccountData> liabilityHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService
|
||||
.retrieveAllEnabledHeaderGLAccounts(GLAccountType.LIABILITY));
|
||||
final List<GLAccountData> equityHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService
|
||||
.retrieveAllEnabledHeaderGLAccounts(GLAccountType.EQUITY));
|
||||
final List<GLAccountData> incomeHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService
|
||||
.retrieveAllEnabledHeaderGLAccounts(GLAccountType.INCOME));
|
||||
final List<GLAccountData> expenseHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService
|
||||
.retrieveAllEnabledHeaderGLAccounts(GLAccountType.EXPENSE));
|
||||
final Collection<CodeValueData> allowedAssetsTagOptions = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME);
|
||||
final Collection<CodeValueData> allowedLiabilitiesTagOptions = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME);
|
||||
final Collection<CodeValueData> allowedEquityTagOptions = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME);
|
||||
final Collection<CodeValueData> allowedIncomeTagOptions = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(AccountingConstants.INCOME_TAG_OPTION_CODE_NAME);
|
||||
final Collection<CodeValueData> allowedExpensesTagOptions = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(AccountingConstants.EXPENSES_TAG_OPTION_CODE_NAME);
|
||||
|
||||
return new GLAccountData(glAccountData, accountTypeOptions, usageOptions, assetHeaderAccountOptions, liabilityHeaderAccountOptions,
|
||||
equityHeaderAccountOptions, incomeHeaderAccountOptions, expenseHeaderAccountOptions, allowedAssetsTagOptions,
|
||||
allowedLiabilitiesTagOptions, allowedEquityTagOptions, allowedIncomeTagOptions, allowedExpensesTagOptions);
|
||||
}
|
||||
|
||||
private List<GLAccountData> defaultIfEmpty(final List<GLAccountData> list) {
|
||||
List<GLAccountData> returnList = null;
|
||||
if (list != null && !list.isEmpty()) {
|
||||
returnList = list;
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.api.GLAccountJsonInputParams;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
|
||||
/**
|
||||
* Immutable command for adding a general Ledger Account
|
||||
*/
|
||||
public class GLAccountCommand {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Long id;
|
||||
private final String name;
|
||||
private final Long parentId;
|
||||
private final String glCode;
|
||||
private final Boolean disabled;
|
||||
private final Boolean manualEntriesAllowed;
|
||||
private final Integer usage;
|
||||
private final Integer type;
|
||||
private final String description;
|
||||
private final Long tagId;
|
||||
|
||||
public GLAccountCommand(final Long id, final String name, final Long parentId, final String glCode, final Boolean disabled,
|
||||
final Boolean manualEntriesAllowed, final Integer type, final Integer usage, final String description, final Long tagId) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.parentId = parentId;
|
||||
this.glCode = glCode;
|
||||
this.disabled = disabled;
|
||||
this.manualEntriesAllowed = manualEntriesAllowed;
|
||||
this.type = type;
|
||||
this.usage = usage;
|
||||
this.description = description;
|
||||
this.tagId = tagId;
|
||||
}
|
||||
|
||||
public void validateForCreate() {
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("GLAccount");
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.NAME.getValue()).value(this.name).notBlank().notExceedingLengthOf(200);
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.GL_CODE.getValue()).value(this.glCode).notBlank()
|
||||
.notExceedingLengthOf(45);
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.PARENT_ID.getValue()).value(this.parentId).ignoreIfNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.TYPE.getValue()).value(this.type).notNull()
|
||||
.inMinMaxRange(GLAccountType.getMinValue(), GLAccountType.getMaxValue());
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.USAGE.getValue()).value(this.usage)
|
||||
.inMinMaxRange(GLAccountUsage.getMinValue(), GLAccountUsage.getMaxValue());
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.DESCRIPTION.getValue()).value(this.description).ignoreIfNull()
|
||||
.notExceedingLengthOf(500);
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.MANUAL_ENTRIES_ALLOWED.getValue()).value(this.manualEntriesAllowed)
|
||||
.notBlank();
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.TAGID.getValue()).value(this.tagId).ignoreIfNull()
|
||||
.longGreaterThanZero();
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
public void validateForUpdate() {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("GLAccount");
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.NAME.getValue()).value(this.name).ignoreIfNull().notBlank()
|
||||
.notExceedingLengthOf(200);
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.GL_CODE.getValue()).ignoreIfNull().value(this.glCode).notBlank()
|
||||
.notExceedingLengthOf(45);
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.PARENT_ID.getValue()).value(this.parentId).ignoreIfNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.TYPE.getValue()).value(this.type).ignoreIfNull()
|
||||
.inMinMaxRange(GLAccountType.getMinValue(), GLAccountType.getMaxValue());
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.USAGE.getValue()).value(this.usage).ignoreIfNull()
|
||||
.inMinMaxRange(GLAccountUsage.getMinValue(), GLAccountUsage.getMaxValue());
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.DESCRIPTION.getValue()).value(this.description).ignoreIfNull()
|
||||
.notBlank().notExceedingLengthOf(500);
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.DISABLED.getValue()).value(this.disabled).ignoreIfNull();
|
||||
|
||||
baseDataValidator.reset().anyOfNotNull(this.name, this.glCode, this.parentId, this.type, this.description, this.disabled);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.TAGID.getValue()).value(this.tagId).ignoreIfNull()
|
||||
.longGreaterThanZero();
|
||||
}
|
||||
|
||||
public boolean isHeaderAccount() {
|
||||
return GLAccountUsage.HEADER.getValue().equals(this.usage);
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+185
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.data;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.common.AccountingEnumerations;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage;
|
||||
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
|
||||
/**
|
||||
* Immutable object representing a General Ledger Account
|
||||
*
|
||||
* Note: no getter/setters required as google-gson will produce json from fields
|
||||
* of object.
|
||||
*/
|
||||
public class GLAccountData {
|
||||
|
||||
private final Long id;
|
||||
private final String name;
|
||||
private final Long parentId;
|
||||
private final String glCode;
|
||||
private final Boolean disabled;
|
||||
private final Boolean manualEntriesAllowed;
|
||||
private final EnumOptionData type;
|
||||
private final EnumOptionData usage;
|
||||
private final String description;
|
||||
private final String nameDecorated;
|
||||
private final CodeValueData tagId;
|
||||
private final Long organizationRunningBalance;
|
||||
|
||||
// templates
|
||||
final List<EnumOptionData> accountTypeOptions;
|
||||
final List<EnumOptionData> usageOptions;
|
||||
final List<GLAccountData> assetHeaderAccountOptions;
|
||||
final List<GLAccountData> liabilityHeaderAccountOptions;
|
||||
final List<GLAccountData> equityHeaderAccountOptions;
|
||||
final List<GLAccountData> incomeHeaderAccountOptions;
|
||||
final List<GLAccountData> expenseHeaderAccountOptions;
|
||||
final Collection<CodeValueData> allowedAssetsTagOptions;
|
||||
final Collection<CodeValueData> allowedLiabilitiesTagOptions;
|
||||
final Collection<CodeValueData> allowedEquityTagOptions;
|
||||
final Collection<CodeValueData> allowedIncomeTagOptions;
|
||||
final Collection<CodeValueData> allowedExpensesTagOptions;
|
||||
|
||||
public GLAccountData(final Long id, final String name, final Long parentId, final String glCode, final boolean disabled,
|
||||
final boolean manualEntriesAllowed, final EnumOptionData type, final EnumOptionData usage, final String description,
|
||||
final String nameDecorated, final CodeValueData tagId, final Long organizationRunningBalance) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.parentId = parentId;
|
||||
this.glCode = glCode;
|
||||
this.disabled = disabled;
|
||||
this.manualEntriesAllowed = manualEntriesAllowed;
|
||||
this.type = type;
|
||||
this.usage = usage;
|
||||
this.description = description;
|
||||
this.nameDecorated = nameDecorated;
|
||||
this.tagId = tagId;
|
||||
this.organizationRunningBalance = organizationRunningBalance;
|
||||
this.accountTypeOptions = null;
|
||||
this.usageOptions = null;
|
||||
this.assetHeaderAccountOptions = null;
|
||||
this.liabilityHeaderAccountOptions = null;
|
||||
this.equityHeaderAccountOptions = null;
|
||||
this.incomeHeaderAccountOptions = null;
|
||||
this.expenseHeaderAccountOptions = null;
|
||||
this.allowedAssetsTagOptions = null;
|
||||
this.allowedLiabilitiesTagOptions = null;
|
||||
this.allowedEquityTagOptions = null;
|
||||
this.allowedIncomeTagOptions = null;
|
||||
this.allowedExpensesTagOptions = null;
|
||||
}
|
||||
|
||||
public GLAccountData(final GLAccountData accountData, final List<EnumOptionData> accountTypeOptions,
|
||||
final List<EnumOptionData> usageOptions, final List<GLAccountData> assetHeaderAccountOptions,
|
||||
final List<GLAccountData> liabilityHeaderAccountOptions, final List<GLAccountData> equityHeaderAccountOptions,
|
||||
final List<GLAccountData> incomeHeaderAccountOptions, final List<GLAccountData> expenseHeaderAccountOptions,
|
||||
final Collection<CodeValueData> allowedAssetsTagOptions, final Collection<CodeValueData> allowedLiabilitiesTagOptions,
|
||||
final Collection<CodeValueData> allowedEquityTagOptions, final Collection<CodeValueData> allowedIncomeTagOptions,
|
||||
final Collection<CodeValueData> allowedExpensesTagOptions) {
|
||||
this.id = accountData.id;
|
||||
this.name = accountData.name;
|
||||
this.parentId = accountData.parentId;
|
||||
this.glCode = accountData.glCode;
|
||||
this.disabled = accountData.disabled;
|
||||
this.manualEntriesAllowed = accountData.manualEntriesAllowed;
|
||||
this.type = accountData.type;
|
||||
this.usage = accountData.usage;
|
||||
this.description = accountData.description;
|
||||
this.nameDecorated = accountData.nameDecorated;
|
||||
this.tagId = accountData.tagId;
|
||||
this.organizationRunningBalance = accountData.organizationRunningBalance;
|
||||
this.accountTypeOptions = accountTypeOptions;
|
||||
this.usageOptions = usageOptions;
|
||||
this.assetHeaderAccountOptions = assetHeaderAccountOptions;
|
||||
this.liabilityHeaderAccountOptions = liabilityHeaderAccountOptions;
|
||||
this.equityHeaderAccountOptions = equityHeaderAccountOptions;
|
||||
this.incomeHeaderAccountOptions = incomeHeaderAccountOptions;
|
||||
this.expenseHeaderAccountOptions = expenseHeaderAccountOptions;
|
||||
this.allowedAssetsTagOptions = allowedAssetsTagOptions;
|
||||
this.allowedLiabilitiesTagOptions = allowedLiabilitiesTagOptions;
|
||||
this.allowedEquityTagOptions = allowedEquityTagOptions;
|
||||
this.allowedIncomeTagOptions = allowedIncomeTagOptions;
|
||||
this.allowedExpensesTagOptions = allowedExpensesTagOptions;
|
||||
}
|
||||
|
||||
public static GLAccountData sensibleDefaultsForNewGLAccountCreation(final Integer glAccType) {
|
||||
final Long id = null;
|
||||
final String name = null;
|
||||
final Long parentId = null;
|
||||
final String glCode = null;
|
||||
final boolean disabled = false;
|
||||
final boolean manualEntriesAllowed = true;
|
||||
final EnumOptionData type;
|
||||
if (glAccType != null && glAccType >= GLAccountType.getMinValue() && glAccType <= GLAccountType.getMaxValue()) {
|
||||
type = AccountingEnumerations.gLAccountType(glAccType);
|
||||
} else {
|
||||
type = AccountingEnumerations.gLAccountType(GLAccountType.ASSET);
|
||||
}
|
||||
final EnumOptionData usage = AccountingEnumerations.gLAccountUsage(GLAccountUsage.DETAIL);
|
||||
final String description = null;
|
||||
final String nameDecorated = null;
|
||||
final CodeValueData tagId = null;
|
||||
final Long organizationRunningBalance = null;
|
||||
|
||||
return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, type, usage, description, nameDecorated,
|
||||
tagId, organizationRunningBalance);
|
||||
}
|
||||
|
||||
public GLAccountData(final Long id, final String name, final String glCode) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.parentId = null;
|
||||
this.glCode = glCode;
|
||||
this.disabled = null;
|
||||
this.manualEntriesAllowed = null;
|
||||
this.type = null;
|
||||
this.usage = null;
|
||||
this.description = null;
|
||||
this.nameDecorated = null;
|
||||
this.tagId = null;
|
||||
this.organizationRunningBalance = null;
|
||||
this.accountTypeOptions = null;
|
||||
this.usageOptions = null;
|
||||
this.assetHeaderAccountOptions = null;
|
||||
this.liabilityHeaderAccountOptions = null;
|
||||
this.equityHeaderAccountOptions = null;
|
||||
this.incomeHeaderAccountOptions = null;
|
||||
this.expenseHeaderAccountOptions = null;
|
||||
this.allowedAssetsTagOptions = null;
|
||||
this.allowedLiabilitiesTagOptions = null;
|
||||
this.allowedEquityTagOptions = null;
|
||||
this.allowedIncomeTagOptions = null;
|
||||
this.allowedExpensesTagOptions = null;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getGlCode() {
|
||||
return this.glCode;
|
||||
}
|
||||
|
||||
public EnumOptionData getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public Integer getTypeId() {
|
||||
if (this.type != null) { return this.type.getId().intValue(); }
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.data;
|
||||
|
||||
public class GLAccountDataForLookup {
|
||||
|
||||
private final Long id;
|
||||
@SuppressWarnings("unused")
|
||||
private final String name;
|
||||
@SuppressWarnings("unused")
|
||||
private final String glCode;
|
||||
|
||||
public GLAccountDataForLookup(final Long id, final String name, final String glCode) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.glCode = glCode;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.domain;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.accounting.glaccount.api.GLAccountJsonInputParams;
|
||||
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "acc_gl_account", uniqueConstraints = { @UniqueConstraint(columnNames = { "gl_code" }, name = "acc_gl_code") })
|
||||
public class GLAccount extends AbstractPersistable<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "parent_id")
|
||||
private GLAccount parent;
|
||||
|
||||
@Column(name = "hierarchy", nullable = true, length = 50)
|
||||
private String hierarchy;
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "parent_id")
|
||||
private final List<GLAccount> children = new LinkedList<>();
|
||||
|
||||
@Column(name = "name", nullable = false, length = 45)
|
||||
private String name;
|
||||
|
||||
@Column(name = "gl_code", nullable = false, length = 100)
|
||||
private String glCode;
|
||||
|
||||
@Column(name = "disabled", nullable = false)
|
||||
private boolean disabled = false;
|
||||
|
||||
@Column(name = "manual_journal_entries_allowed", nullable = false)
|
||||
private boolean manualEntriesAllowed = true;
|
||||
|
||||
@Column(name = "classification_enum", nullable = false)
|
||||
private Integer type;
|
||||
|
||||
@Column(name = "account_usage", nullable = false)
|
||||
private Integer usage;
|
||||
|
||||
@Column(name = "description", nullable = true, length = 500)
|
||||
private String description;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "tag_id")
|
||||
private CodeValue tagId;
|
||||
|
||||
protected GLAccount() {
|
||||
//
|
||||
}
|
||||
|
||||
private GLAccount(final GLAccount parent, final String name, final String glCode, final boolean disabled,
|
||||
final boolean manualEntriesAllowed, final Integer type, final Integer usage, final String description, final CodeValue tagId) {
|
||||
this.name = StringUtils.defaultIfEmpty(name, null);
|
||||
this.glCode = StringUtils.defaultIfEmpty(glCode, null);
|
||||
this.disabled = BooleanUtils.toBooleanDefaultIfNull(disabled, false);
|
||||
this.manualEntriesAllowed = BooleanUtils.toBooleanDefaultIfNull(manualEntriesAllowed, true);
|
||||
this.usage = usage;
|
||||
this.type = type;
|
||||
this.description = StringUtils.defaultIfEmpty(description, null);
|
||||
this.parent = parent;
|
||||
this.tagId = tagId;
|
||||
}
|
||||
|
||||
public static GLAccount fromJson(final GLAccount parent, final JsonCommand command, final CodeValue glAccountTagType) {
|
||||
final String name = command.stringValueOfParameterNamed(GLAccountJsonInputParams.NAME.getValue());
|
||||
final String glCode = command.stringValueOfParameterNamed(GLAccountJsonInputParams.GL_CODE.getValue());
|
||||
final boolean disabled = command.booleanPrimitiveValueOfParameterNamed(GLAccountJsonInputParams.DISABLED.getValue());
|
||||
final boolean manualEntriesAllowed = command.booleanPrimitiveValueOfParameterNamed(GLAccountJsonInputParams.MANUAL_ENTRIES_ALLOWED
|
||||
.getValue());
|
||||
final Integer usage = command.integerValueSansLocaleOfParameterNamed(GLAccountJsonInputParams.USAGE.getValue());
|
||||
final Integer type = command.integerValueSansLocaleOfParameterNamed(GLAccountJsonInputParams.TYPE.getValue());
|
||||
final String description = command.stringValueOfParameterNamed(GLAccountJsonInputParams.DESCRIPTION.getValue());
|
||||
return new GLAccount(parent, name, glCode, disabled, manualEntriesAllowed, type, usage, description, glAccountTagType);
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(15);
|
||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.DESCRIPTION.getValue(), this.description);
|
||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.DISABLED.getValue(), this.disabled);
|
||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.GL_CODE.getValue(), this.glCode);
|
||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.MANUAL_ENTRIES_ALLOWED.getValue(), this.manualEntriesAllowed);
|
||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.NAME.getValue(), this.name);
|
||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.PARENT_ID.getValue(), 0L);
|
||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.TYPE.getValue(), this.type, true);
|
||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.USAGE.getValue(), this.usage, true);
|
||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.TAGID.getValue(),
|
||||
this.tagId == null ? 0L : this.tagId.getId());
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private void handlePropertyUpdate(final JsonCommand command, final Map<String, Object> actualChanges, final String paramName,
|
||||
final Integer propertyToBeUpdated, final boolean sansLocale) {
|
||||
boolean changeDetected = false;
|
||||
if (sansLocale) {
|
||||
changeDetected = command.isChangeInIntegerSansLocaleParameterNamed(paramName, propertyToBeUpdated);
|
||||
} else {
|
||||
changeDetected = command.isChangeInIntegerParameterNamed(paramName, propertyToBeUpdated);
|
||||
}
|
||||
if (changeDetected) {
|
||||
Integer newValue = null;
|
||||
if (sansLocale) {
|
||||
newValue = command.integerValueSansLocaleOfParameterNamed(paramName);
|
||||
} else {
|
||||
newValue = command.integerValueOfParameterNamed(paramName);
|
||||
}
|
||||
actualChanges.put(paramName, newValue);
|
||||
// now update actual property
|
||||
if (paramName.equals(GLAccountJsonInputParams.TYPE.getValue())) {
|
||||
this.type = newValue;
|
||||
} else if (paramName.equals(GLAccountJsonInputParams.USAGE.getValue())) {
|
||||
this.usage = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePropertyUpdate(final JsonCommand command, final Map<String, Object> actualChanges, final String paramName,
|
||||
final String propertyToBeUpdated) {
|
||||
if (command.isChangeInStringParameterNamed(paramName, propertyToBeUpdated)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(paramName);
|
||||
actualChanges.put(paramName, newValue);
|
||||
// now update actual property
|
||||
if (paramName.equals(GLAccountJsonInputParams.DESCRIPTION.getValue())) {
|
||||
this.description = newValue;
|
||||
} else if (paramName.equals(GLAccountJsonInputParams.GL_CODE.getValue())) {
|
||||
this.glCode = newValue;
|
||||
} else if (paramName.equals(GLAccountJsonInputParams.NAME.getValue())) {
|
||||
this.name = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePropertyUpdate(final JsonCommand command, final Map<String, Object> actualChanges, final String paramName,
|
||||
final Long propertyToBeUpdated) {
|
||||
if (command.isChangeInLongParameterNamed(paramName, propertyToBeUpdated)) {
|
||||
final Long newValue = command.longValueOfParameterNamed(paramName);
|
||||
actualChanges.put(paramName, newValue);
|
||||
// now update actual property
|
||||
if (paramName.equals(GLAccountJsonInputParams.PARENT_ID.getValue())) {
|
||||
// do nothing as this is a nested property
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePropertyUpdate(final JsonCommand command, final Map<String, Object> actualChanges, final String paramName,
|
||||
final boolean propertyToBeUpdated) {
|
||||
if (command.isChangeInBooleanParameterNamed(paramName, propertyToBeUpdated)) {
|
||||
final Boolean newValue = command.booleanObjectValueOfParameterNamed(paramName);
|
||||
actualChanges.put(paramName, newValue);
|
||||
// now update actual property
|
||||
if (paramName.equals(GLAccountJsonInputParams.MANUAL_ENTRIES_ALLOWED.getValue())) {
|
||||
this.manualEntriesAllowed = newValue;
|
||||
} else if (paramName.equals(GLAccountJsonInputParams.DISABLED.getValue())) {
|
||||
this.disabled = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHeaderAccount() {
|
||||
return GLAccountUsage.HEADER.getValue().equals(this.usage);
|
||||
}
|
||||
|
||||
public Integer getUsage() {
|
||||
return this.usage;
|
||||
}
|
||||
|
||||
public List<GLAccount> getChildren() {
|
||||
return this.children;
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
return this.disabled;
|
||||
}
|
||||
|
||||
public boolean isManualEntriesAllowed() {
|
||||
return this.manualEntriesAllowed;
|
||||
}
|
||||
|
||||
public String getGlCode() {
|
||||
return this.glCode;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void generateHierarchy() {
|
||||
|
||||
if (this.parent != null) {
|
||||
this.hierarchy = this.parent.hierarchyOf(getId());
|
||||
} else {
|
||||
this.hierarchy = ".";
|
||||
}
|
||||
}
|
||||
|
||||
private String hierarchyOf(final Long id) {
|
||||
return this.hierarchy + id.toString() + ".";
|
||||
}
|
||||
|
||||
public boolean isDetailAccount() {
|
||||
return GLAccountUsage.DETAIL.getValue().equals(this.usage);
|
||||
}
|
||||
|
||||
public void updateTagId(final CodeValue tagID) {
|
||||
this.tagId = tagID;
|
||||
}
|
||||
|
||||
public void updateParentAccount(final GLAccount parentAccount) {
|
||||
this.parent = parentAccount;
|
||||
generateHierarchy();
|
||||
}
|
||||
}
|
||||
+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.accounting.glaccount.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface GLAccountRepository extends JpaRepository<GLAccount, Long>, JpaSpecificationExecutor<GLAccount> {
|
||||
// no added behaviour
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.domain;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Wrapper for {@link GLAccountRepository} .
|
||||
* </p>
|
||||
*/
|
||||
@Service
|
||||
public class GLAccountRepositoryWrapper {
|
||||
|
||||
private final GLAccountRepository repository;
|
||||
|
||||
@Autowired
|
||||
public GLAccountRepositoryWrapper(final GLAccountRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public GLAccount findOneWithNotFoundDetection(final Long id) {
|
||||
final GLAccount account = this.repository.findOne(id);
|
||||
if (account == null) { throw new GLAccountNotFoundException(id); }
|
||||
return account;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+89
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum GLAccountType {
|
||||
ASSET(1, "accountType.asset"), LIABILITY(2, "accountType.liability"), EQUITY(3, "accountType.equity"), INCOME(4, "accountType.income"), EXPENSE(
|
||||
5, "accountType.expense");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private GLAccountType(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
private static final Map<Integer, GLAccountType> intToEnumMap = new HashMap<>();
|
||||
private static int minValue;
|
||||
private static int maxValue;
|
||||
static {
|
||||
int i = 0;
|
||||
for (final GLAccountType type : GLAccountType.values()) {
|
||||
if (i == 0) {
|
||||
minValue = type.value;
|
||||
}
|
||||
intToEnumMap.put(type.value, type);
|
||||
if (minValue >= type.value) {
|
||||
minValue = type.value;
|
||||
}
|
||||
if (maxValue < type.value) {
|
||||
maxValue = type.value;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static GLAccountType fromInt(final int i) {
|
||||
final GLAccountType type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
|
||||
public static int getMinValue() {
|
||||
return minValue;
|
||||
}
|
||||
|
||||
public static int getMaxValue() {
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString();
|
||||
}
|
||||
|
||||
public boolean isAssetType() {
|
||||
return this.value.equals(GLAccountType.ASSET.getValue());
|
||||
}
|
||||
|
||||
public boolean isLiabilityType() {
|
||||
return this.value.equals(GLAccountType.LIABILITY.getValue());
|
||||
}
|
||||
|
||||
public boolean isEquityType() {
|
||||
return this.value.equals(GLAccountType.EQUITY.getValue());
|
||||
}
|
||||
|
||||
public boolean isIncomeType() {
|
||||
return this.value.equals(GLAccountType.INCOME.getValue());
|
||||
}
|
||||
|
||||
public boolean isExpenseType() {
|
||||
return this.value.equals(GLAccountType.EXPENSE.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum GLAccountUsage {
|
||||
|
||||
DETAIL(1, "accountUsage.detail"), HEADER(2, "accountUsage.header");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private GLAccountUsage(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
private static final Map<Integer, GLAccountUsage> intToEnumMap = new HashMap<>();
|
||||
private static int minValue;
|
||||
private static int maxValue;
|
||||
static {
|
||||
int i = 0;
|
||||
for (final GLAccountUsage type : GLAccountUsage.values()) {
|
||||
if (i == 0) {
|
||||
minValue = type.value;
|
||||
}
|
||||
intToEnumMap.put(type.value, type);
|
||||
if (minValue >= type.value) {
|
||||
minValue = type.value;
|
||||
}
|
||||
if (maxValue < type.value) {
|
||||
maxValue = type.value;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static GLAccountUsage fromInt(final int i) {
|
||||
final GLAccountUsage type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
|
||||
public static int getMinValue() {
|
||||
return minValue;
|
||||
}
|
||||
|
||||
public static int getMaxValue() {
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString();
|
||||
}
|
||||
|
||||
}
|
||||
+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.accounting.glaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when a GL Account with a given GL Code of
|
||||
* the particular type is already present
|
||||
*/
|
||||
public class GLAccountDuplicateException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public GLAccountDuplicateException(final String glCode) {
|
||||
super("error.msg.glaccount.glcode.duplicate", "General Ledger Account with GL code " + glCode + " is already present", glCode);
|
||||
}
|
||||
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when trying to fetch accounts belonging to
|
||||
* an Invalid Usage Type
|
||||
*/
|
||||
public class GLAccountInvalidClassificationException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public GLAccountInvalidClassificationException(final Integer usage) {
|
||||
super("error.msg.glaccount.usage.invalid", "The following COA usage is invalid: " + usage);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when a GL Account with a given GL Code of
|
||||
* the particular type is already present
|
||||
*/
|
||||
public class GLAccountInvalidDeleteException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
/*** Enum of reasons for invalid delete **/
|
||||
public static enum GL_ACCOUNT_INVALID_DELETE_REASON {
|
||||
TRANSANCTIONS_LOGGED, HAS_CHILDREN;
|
||||
|
||||
public String errorMessage() {
|
||||
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) {
|
||||
return "This GL Account cannot be deleted as it has transactions logged against it";
|
||||
} else if (name().toString().equalsIgnoreCase("HAS_CHILDREN")) { return "Cannot delete this Header GL Account without first deleting or reassinging its children"; }
|
||||
return name().toString();
|
||||
}
|
||||
|
||||
public String errorCode() {
|
||||
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) {
|
||||
return "error.msg.glaccount.glcode.invalid.delete.transactions.logged";
|
||||
} else if (name().toString().equalsIgnoreCase("HAS_CHILDREN")) { return "error.msg.glaccount.glcode.invalid.delete.has.children"; }
|
||||
return name().toString();
|
||||
}
|
||||
}
|
||||
|
||||
public GLAccountInvalidDeleteException(final GL_ACCOUNT_INVALID_DELETE_REASON reason, final Long glAccountId) {
|
||||
super(reason.errorCode(), reason.errorMessage(), glAccountId);
|
||||
}
|
||||
}
|
||||
+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.accounting.glaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when trying to map invalid parents to a GL
|
||||
* account
|
||||
*/
|
||||
public class GLAccountInvalidParentException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public GLAccountInvalidParentException(final long glAccountId) {
|
||||
super("error.msg.glaccount.parent.invalid", "The account with id " + glAccountId
|
||||
+ " is a 'Detail' account and cannot be used as a parent", glAccountId);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when an error is encountered during
|
||||
* updating a GL Account
|
||||
*/
|
||||
public class GLAccountInvalidUpdateException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
/*** Enum of reasons for invalid delete **/
|
||||
public static enum GL_ACCOUNT_INVALID_UPDATE_REASON {
|
||||
TRANSANCTIONS_LOGGED;
|
||||
|
||||
public String errorMessage() {
|
||||
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) { return "This Usage of this (detail) GL Account as it already has transactions logged against it"; }
|
||||
return name().toString();
|
||||
}
|
||||
|
||||
public String errorCode() {
|
||||
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) { return "error.msg.glaccount.glcode.invalid.update.transactions.logged"; }
|
||||
return name().toString();
|
||||
}
|
||||
}
|
||||
|
||||
public GLAccountInvalidUpdateException(final GL_ACCOUNT_INVALID_UPDATE_REASON reason, final Long glAccountId) {
|
||||
super(reason.errorCode(), reason.errorMessage(), glAccountId);
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when trying to fetch accounts belonging to
|
||||
* an Invalid Type
|
||||
*/
|
||||
public class GLAccountInvalidUsageException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public GLAccountInvalidUsageException(final Integer type) {
|
||||
super("error.msg.glaccount.classification.invalid", "The following COA type is invalid: " + type);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when GL account resources are not found.
|
||||
*/
|
||||
public class GLAccountNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public GLAccountNotFoundException(final Long id) {
|
||||
super("error.msg.glaccount.id.invalid", "General Ledger account with identifier " + id + " does not exist ", id);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
public class InvalidParentGLAccountHeadException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public InvalidParentGLAccountHeadException(final Long glAccountId, final Long parentId) {
|
||||
super("error.msg.glaccount.id.and.parentid.must.not.same", "parentId:" + parentId + ", id" + glAccountId + " should not be same",
|
||||
glAccountId, parentId);
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.handler;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.service.GLAccountWritePlatformService;
|
||||
import org.mifosplatform.commands.annotation.CommandType;
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "GLACCOUNT", action = "CREATE")
|
||||
public class CreateGLAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final GLAccountWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CreateGLAccountCommandHandler(final GLAccountWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.createGLAccount(command);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.handler;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.service.GLAccountWritePlatformService;
|
||||
import org.mifosplatform.commands.annotation.CommandType;
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "GLACCOUNT", action = "DELETE")
|
||||
public class DeleteGLAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final GLAccountWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DeleteGLAccountCommandHandler(final GLAccountWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.deleteGLAccount(command.entityId());
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.handler;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.service.GLAccountWritePlatformService;
|
||||
import org.mifosplatform.commands.annotation.CommandType;
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "GLACCOUNT", action = "UPDATE")
|
||||
public class UpdateGLAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final GLAccountWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public UpdateGLAccountCommandHandler(final GLAccountWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.updateGLAccount(command.entityId(), command);
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.accounting.glaccount.api.GLAccountJsonInputParams;
|
||||
import org.mifosplatform.accounting.glaccount.command.GLAccountCommand;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.portfolio.loanaccount.guarantor.command.GuarantorCommand;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Implementation of {@link FromApiJsonDeserializer} for
|
||||
* {@link GuarantorCommand}'s.
|
||||
*/
|
||||
@Component
|
||||
public final class GLAccountCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<GLAccountCommand> {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public GLAccountCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonfromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonfromApiJsonHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GLAccountCommand commandFromApiJson(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
final Set<String> supportedParameters = GLAccountJsonInputParams.getAllValues();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
|
||||
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final Long id = this.fromApiJsonHelper.extractLongNamed(GLAccountJsonInputParams.ID.getValue(), element);
|
||||
final String name = this.fromApiJsonHelper.extractStringNamed(GLAccountJsonInputParams.NAME.getValue(), element);
|
||||
final Long parentId = this.fromApiJsonHelper.extractLongNamed(GLAccountJsonInputParams.PARENT_ID.getValue(), element);
|
||||
final String glCode = this.fromApiJsonHelper.extractStringNamed(GLAccountJsonInputParams.GL_CODE.getValue(), element);
|
||||
final Boolean disabled = this.fromApiJsonHelper.extractBooleanNamed(GLAccountJsonInputParams.DISABLED.getValue(), element);
|
||||
final Boolean manualEntriesAllowed = this.fromApiJsonHelper.extractBooleanNamed(
|
||||
GLAccountJsonInputParams.MANUAL_ENTRIES_ALLOWED.getValue(), element);
|
||||
final Integer type = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(GLAccountJsonInputParams.TYPE.getValue(), element);
|
||||
final Integer usage = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(GLAccountJsonInputParams.USAGE.getValue(), element);
|
||||
final String description = this.fromApiJsonHelper.extractStringNamed(GLAccountJsonInputParams.DESCRIPTION.getValue(), element);
|
||||
final Long tagId = this.fromApiJsonHelper.extractLongNamed(GLAccountJsonInputParams.TAGID.getValue(), element);
|
||||
|
||||
return new GLAccountCommand(id, name, parentId, glCode, disabled, manualEntriesAllowed, type, usage, description, tagId);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountDataForLookup;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
import org.mifosplatform.accounting.journalentry.data.JournalEntryAssociationParametersData;
|
||||
|
||||
public interface GLAccountReadPlatformService {
|
||||
|
||||
List<GLAccountData> retrieveAllGLAccounts(Integer accountClassification, String searchParam, Integer usage,
|
||||
Boolean manualTransactionsAllowed, Boolean disabled, JournalEntryAssociationParametersData associationParametersData);
|
||||
|
||||
GLAccountData retrieveGLAccountById(long glAccountId, JournalEntryAssociationParametersData associationParametersData);
|
||||
|
||||
List<GLAccountData> retrieveAllEnabledDetailGLAccounts();
|
||||
|
||||
List<GLAccountData> retrieveAllEnabledDetailGLAccounts(GLAccountType accountType);
|
||||
|
||||
List<GLAccountData> retrieveAllEnabledHeaderGLAccounts(GLAccountType accountType);
|
||||
|
||||
GLAccountData retrieveNewGLAccountDetails(final Integer type);
|
||||
|
||||
List<GLAccountDataForLookup> retrieveAccountsByTagId(final Long ruleId, final Integer transactionType);
|
||||
}
|
||||
+268
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.service;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.accounting.common.AccountingEnumerations;
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountDataForLookup;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage;
|
||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidClassificationException;
|
||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountNotFoundException;
|
||||
import org.mifosplatform.accounting.journalentry.data.JournalEntryAssociationParametersData;
|
||||
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||
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 GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final static String nameDecoratedBaseOnHierarchy = "concat(substring('........................................', 1, ((LENGTH(hierarchy) - LENGTH(REPLACE(hierarchy, '.', '')) - 1) * 4)), name)";
|
||||
|
||||
@Autowired
|
||||
public GLAccountReadPlatformServiceImpl(final RoutingDataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
private static final class GLAccountMapper implements RowMapper<GLAccountData> {
|
||||
|
||||
private final JournalEntryAssociationParametersData associationParametersData;
|
||||
|
||||
public GLAccountMapper(final JournalEntryAssociationParametersData associationParametersData) {
|
||||
if (associationParametersData == null) {
|
||||
this.associationParametersData = new JournalEntryAssociationParametersData();
|
||||
} else {
|
||||
this.associationParametersData = associationParametersData;
|
||||
}
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(
|
||||
" gl.id as id, name as name, parent_id as parentId, gl_code as glCode, disabled as disabled, manual_journal_entries_allowed as manualEntriesAllowed, ")
|
||||
.append("classification_enum as classification, account_usage as accountUsage, gl.description as description, ")
|
||||
.append(nameDecoratedBaseOnHierarchy).append(" as nameDecorated, ")
|
||||
.append("cv.id as codeId, cv.code_value as codeValue ");
|
||||
if (this.associationParametersData.isRunningBalanceRequired()) {
|
||||
sb.append(",gl_j.organization_running_balance as organizationRunningBalance ");
|
||||
}
|
||||
sb.append("from acc_gl_account gl left join m_code_value cv on tag_id=cv.id ");
|
||||
if (this.associationParametersData.isRunningBalanceRequired()) {
|
||||
sb.append("left outer Join acc_gl_journal_entry gl_j on gl_j.account_id = gl.id");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GLAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final String name = rs.getString("name");
|
||||
final Long parentId = JdbcSupport.getLong(rs, "parentId");
|
||||
final String glCode = rs.getString("glCode");
|
||||
final boolean disabled = rs.getBoolean("disabled");
|
||||
final boolean manualEntriesAllowed = rs.getBoolean("manualEntriesAllowed");
|
||||
final int accountTypeId = JdbcSupport.getInteger(rs, "classification");
|
||||
final EnumOptionData accountType = AccountingEnumerations.gLAccountType(accountTypeId);
|
||||
final int usageId = JdbcSupport.getInteger(rs, "accountUsage");
|
||||
final EnumOptionData usage = AccountingEnumerations.gLAccountUsage(usageId);
|
||||
final String description = rs.getString("description");
|
||||
final String nameDecorated = rs.getString("nameDecorated");
|
||||
final Long codeId = rs.wasNull() ? null : rs.getLong("codeId");
|
||||
final String codeValue = rs.getString("codeValue");
|
||||
final CodeValueData tagId = CodeValueData.instance(codeId, codeValue);
|
||||
Long organizationRunningBalance = null;
|
||||
if (associationParametersData.isRunningBalanceRequired()) {
|
||||
organizationRunningBalance = rs.getLong("organizationRunningBalance");
|
||||
}
|
||||
return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, accountType, usage, description,
|
||||
nameDecorated, tagId, organizationRunningBalance);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GLAccountData> retrieveAllGLAccounts(final Integer accountClassification, final String searchParam, final Integer usage,
|
||||
final Boolean manualTransactionsAllowed, final Boolean disabled, JournalEntryAssociationParametersData associationParametersData) {
|
||||
if (accountClassification != null) {
|
||||
if (!checkValidGLAccountType(accountClassification)) { throw new GLAccountInvalidClassificationException(accountClassification); }
|
||||
}
|
||||
|
||||
if (usage != null) {
|
||||
if (!checkValidGLAccountUsage(usage)) { throw new GLAccountInvalidClassificationException(accountClassification); }
|
||||
}
|
||||
|
||||
final GLAccountMapper rm = new GLAccountMapper(associationParametersData);
|
||||
String sql = "select " + rm.schema();
|
||||
// append SQL statement for fetching account totals
|
||||
if (associationParametersData.isRunningBalanceRequired()) {
|
||||
sql = sql + " and gl_j.id in (select t1.id from (select t2.account_id, max(t2.id) as id from "
|
||||
+ "(select id, max(entry_date) as entry_date, account_id from acc_gl_journal_entry where is_running_balance_calculated = 1 "
|
||||
+ "group by account_id desc) t3 inner join acc_gl_journal_entry t2 on t2.account_id = t3.account_id and t2.entry_date = t3.entry_date "
|
||||
+ "group by t2.account_id desc) t1)";
|
||||
}
|
||||
final Object[] paramaterArray = new Object[3];
|
||||
int arrayPos = 0;
|
||||
boolean filtersPresent = false;
|
||||
if ((accountClassification != null) || StringUtils.isNotBlank(searchParam) || (usage != null)
|
||||
|| (manualTransactionsAllowed != null) || (disabled != null)) {
|
||||
filtersPresent = true;
|
||||
sql += " where";
|
||||
}
|
||||
|
||||
if (filtersPresent) {
|
||||
boolean firstWhereConditionAdded = false;
|
||||
if (accountClassification != null) {
|
||||
sql += " classification_enum like ?";
|
||||
paramaterArray[arrayPos] = accountClassification;
|
||||
arrayPos = arrayPos + 1;
|
||||
firstWhereConditionAdded = true;
|
||||
}
|
||||
if (StringUtils.isNotBlank(searchParam)) {
|
||||
if (firstWhereConditionAdded) {
|
||||
sql += " and ";
|
||||
}
|
||||
sql += " ( name like %?% or gl_code like %?% )";
|
||||
paramaterArray[arrayPos] = searchParam;
|
||||
arrayPos = arrayPos + 1;
|
||||
paramaterArray[arrayPos] = searchParam;
|
||||
arrayPos = arrayPos + 1;
|
||||
firstWhereConditionAdded = true;
|
||||
}
|
||||
if (usage != null) {
|
||||
if (firstWhereConditionAdded) {
|
||||
sql += " and ";
|
||||
}
|
||||
if (GLAccountUsage.HEADER.getValue().equals(usage)) {
|
||||
sql += " account_usage = 2 ";
|
||||
} else if (GLAccountUsage.DETAIL.getValue().equals(usage)) {
|
||||
sql += " account_usage = 1 ";
|
||||
}
|
||||
firstWhereConditionAdded = true;
|
||||
}
|
||||
if (manualTransactionsAllowed != null) {
|
||||
if (firstWhereConditionAdded) {
|
||||
sql += " and ";
|
||||
}
|
||||
|
||||
if (manualTransactionsAllowed) {
|
||||
sql += " manual_journal_entries_allowed = 1";
|
||||
} else {
|
||||
sql += " manual_journal_entries_allowed = 0";
|
||||
}
|
||||
firstWhereConditionAdded = true;
|
||||
}
|
||||
if (disabled != null) {
|
||||
if (firstWhereConditionAdded) {
|
||||
sql += " and ";
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
sql += " disabled = 1";
|
||||
} else {
|
||||
sql += " disabled = 0";
|
||||
}
|
||||
firstWhereConditionAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
final Object[] finalObjectArray = Arrays.copyOf(paramaterArray, arrayPos);
|
||||
return this.jdbcTemplate.query(sql, rm, finalObjectArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GLAccountData retrieveGLAccountById(final long glAccountId, JournalEntryAssociationParametersData associationParametersData) {
|
||||
try {
|
||||
|
||||
final GLAccountMapper rm = new GLAccountMapper(associationParametersData);
|
||||
final StringBuilder sql = new StringBuilder();
|
||||
sql.append("select ").append(rm.schema());
|
||||
if (associationParametersData.isRunningBalanceRequired()) {
|
||||
sql.append(" and gl_j.is_running_balance_calculated = 1 ");
|
||||
}
|
||||
sql.append("where gl.id = ?");
|
||||
if (associationParametersData.isRunningBalanceRequired()) {
|
||||
sql.append(" ORDER BY gl_j.entry_date DESC,gl_j.id DESC LIMIT 1");
|
||||
}
|
||||
final GLAccountData glAccountData = this.jdbcTemplate.queryForObject(sql.toString(), rm, new Object[] { glAccountId });
|
||||
|
||||
return glAccountData;
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
throw new GLAccountNotFoundException(glAccountId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GLAccountData> retrieveAllEnabledDetailGLAccounts(final GLAccountType accountType) {
|
||||
return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.DETAIL.getValue(), null, false,
|
||||
new JournalEntryAssociationParametersData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GLAccountData> retrieveAllEnabledDetailGLAccounts() {
|
||||
return retrieveAllGLAccounts(null, null, GLAccountUsage.DETAIL.getValue(), null, false, new JournalEntryAssociationParametersData());
|
||||
}
|
||||
|
||||
private static boolean checkValidGLAccountType(final int type) {
|
||||
for (final GLAccountType accountType : GLAccountType.values()) {
|
||||
if (accountType.getValue().equals(type)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean checkValidGLAccountUsage(final int type) {
|
||||
for (final GLAccountUsage accountUsage : GLAccountUsage.values()) {
|
||||
if (accountUsage.getValue().equals(type)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GLAccountData retrieveNewGLAccountDetails(final Integer type) {
|
||||
return GLAccountData.sensibleDefaultsForNewGLAccountCreation(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GLAccountData> retrieveAllEnabledHeaderGLAccounts(final GLAccountType accountType) {
|
||||
return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.HEADER.getValue(), null, false,
|
||||
new JournalEntryAssociationParametersData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GLAccountDataForLookup> retrieveAccountsByTagId(final Long ruleId, final Integer transactionType) {
|
||||
final GLAccountDataLookUpMapper mapper = new GLAccountDataLookUpMapper();
|
||||
final String sql = "Select " + mapper.schema() + " where rule.id=? and tags.acc_type_enum=?";
|
||||
return this.jdbcTemplate.query(sql, mapper, new Object[] { ruleId, transactionType });
|
||||
}
|
||||
|
||||
private static final class GLAccountDataLookUpMapper implements RowMapper<GLAccountDataForLookup> {
|
||||
|
||||
public String schema() {
|
||||
return " gl.id as id, gl.name as name, gl.gl_code as glCode from acc_accounting_rule rule join acc_rule_tags tags on tags.acc_rule_id = rule.id join acc_gl_account gl on gl.tag_id=tags.tag_id";
|
||||
}
|
||||
|
||||
@Override
|
||||
public GLAccountDataForLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
final Long id = JdbcSupport.getLong(rs, "id");
|
||||
final String name = rs.getString("name");
|
||||
final String glCode = rs.getString("glCode");
|
||||
return new GLAccountDataForLookup(id, name, glCode);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
|
||||
public interface GLAccountWritePlatformService {
|
||||
|
||||
CommandProcessingResult createGLAccount(JsonCommand command);
|
||||
|
||||
CommandProcessingResult updateGLAccount(Long glAccountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult deleteGLAccount(Long glAccountId);
|
||||
|
||||
}
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* 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.accounting.glaccount.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.accounting.common.AccountingConstants;
|
||||
import org.mifosplatform.accounting.glaccount.api.GLAccountJsonInputParams;
|
||||
import org.mifosplatform.accounting.glaccount.command.GLAccountCommand;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountRepository;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountDuplicateException;
|
||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidDeleteException;
|
||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidDeleteException.GL_ACCOUNT_INVALID_DELETE_REASON;
|
||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidParentException;
|
||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidUpdateException;
|
||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidUpdateException.GL_ACCOUNT_INVALID_UPDATE_REASON;
|
||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountNotFoundException;
|
||||
import org.mifosplatform.accounting.glaccount.exception.InvalidParentGLAccountHeadException;
|
||||
import org.mifosplatform.accounting.glaccount.serialization.GLAccountCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntry;
|
||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntryRepository;
|
||||
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
|
||||
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccountWritePlatformService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(GLAccountWritePlatformServiceJpaRepositoryImpl.class);
|
||||
|
||||
private final GLAccountRepository glAccountRepository;
|
||||
private final JournalEntryRepository glJournalEntryRepository;
|
||||
private final GLAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||
private final CodeValueRepositoryWrapper codeValueRepositoryWrapper;
|
||||
|
||||
@Autowired
|
||||
public GLAccountWritePlatformServiceJpaRepositoryImpl(final GLAccountRepository glAccountRepository,
|
||||
final JournalEntryRepository glJournalEntryRepository, final GLAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||
final CodeValueRepositoryWrapper codeValueRepositoryWrapper) {
|
||||
this.glAccountRepository = glAccountRepository;
|
||||
this.glJournalEntryRepository = glJournalEntryRepository;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.codeValueRepositoryWrapper = codeValueRepositoryWrapper;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult createGLAccount(final JsonCommand command) {
|
||||
try {
|
||||
final GLAccountCommand accountCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||
accountCommand.validateForCreate();
|
||||
|
||||
// check parent is valid
|
||||
final Long parentId = command.longValueOfParameterNamed(GLAccountJsonInputParams.PARENT_ID.getValue());
|
||||
GLAccount parentGLAccount = null;
|
||||
if (parentId != null) {
|
||||
parentGLAccount = validateParentGLAccount(parentId);
|
||||
}
|
||||
|
||||
CodeValue glAccountTagType = null;
|
||||
final Long tagId = command.longValueOfParameterNamed(GLAccountJsonInputParams.TAGID.getValue());
|
||||
final Long type = command.longValueOfParameterNamed(GLAccountJsonInputParams.TYPE.getValue());
|
||||
final GLAccountType accountType = GLAccountType.fromInt(type.intValue());
|
||||
|
||||
if (tagId != null) {
|
||||
glAccountTagType = retrieveTagId(tagId, accountType);
|
||||
}
|
||||
|
||||
final GLAccount glAccount = GLAccount.fromJson(parentGLAccount, command, glAccountTagType);
|
||||
|
||||
this.glAccountRepository.saveAndFlush(glAccount);
|
||||
|
||||
glAccount.generateHierarchy();
|
||||
|
||||
this.glAccountRepository.save(glAccount);
|
||||
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(glAccount.getId()).build();
|
||||
} catch (final DataIntegrityViolationException dve) {
|
||||
handleGLAccountDataIntegrityIssues(command, dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult updateGLAccount(final Long glAccountId, final JsonCommand command) {
|
||||
try {
|
||||
final GLAccountCommand accountCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||
accountCommand.validateForUpdate();
|
||||
|
||||
final Long parentId = command.longValueOfParameterNamed(GLAccountJsonInputParams.PARENT_ID.getValue());
|
||||
if (glAccountId.equals(parentId)) { throw new InvalidParentGLAccountHeadException(glAccountId, parentId); }
|
||||
// is the glAccount valid
|
||||
final GLAccount glAccount = this.glAccountRepository.findOne(glAccountId);
|
||||
if (glAccount == null) { throw new GLAccountNotFoundException(glAccountId); }
|
||||
|
||||
final Map<String, Object> changesOnly = glAccount.update(command);
|
||||
|
||||
// is the new parent valid
|
||||
if (changesOnly.containsKey(GLAccountJsonInputParams.PARENT_ID.getValue())) {
|
||||
final GLAccount parentAccount = validateParentGLAccount(parentId);
|
||||
glAccount.updateParentAccount(parentAccount);
|
||||
}
|
||||
|
||||
if (changesOnly.containsKey(GLAccountJsonInputParams.TAGID.getValue())) {
|
||||
final Long tagIdLongValue = command.longValueOfParameterNamed(GLAccountJsonInputParams.TAGID.getValue());
|
||||
final GLAccountType accountType = GLAccountType.fromInt(glAccount.getType());
|
||||
CodeValue tagID = null;
|
||||
if (tagIdLongValue != null) {
|
||||
tagID = retrieveTagId(tagIdLongValue, accountType);
|
||||
}
|
||||
glAccount.updateTagId(tagID);
|
||||
}
|
||||
|
||||
/**
|
||||
* a detail account cannot be changed to a header account if
|
||||
* transactions are already logged against it
|
||||
**/
|
||||
if (changesOnly.containsKey(GLAccountJsonInputParams.USAGE.getValue())) {
|
||||
if (glAccount.isHeaderAccount()) {
|
||||
final List<JournalEntry> journalEntriesForAccount = this.glJournalEntryRepository
|
||||
.findFirstJournalEntryForAccount(glAccountId);
|
||||
if (journalEntriesForAccount.size() > 0) { throw new GLAccountInvalidUpdateException(
|
||||
GL_ACCOUNT_INVALID_UPDATE_REASON.TRANSANCTIONS_LOGGED, glAccountId); }
|
||||
}
|
||||
}
|
||||
|
||||
if (!changesOnly.isEmpty()) {
|
||||
this.glAccountRepository.saveAndFlush(glAccount);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(glAccount.getId())
|
||||
.with(changesOnly).build();
|
||||
} catch (final DataIntegrityViolationException dve) {
|
||||
handleGLAccountDataIntegrityIssues(command, dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult deleteGLAccount(final Long glAccountId) {
|
||||
final GLAccount glAccount = this.glAccountRepository.findOne(glAccountId);
|
||||
|
||||
if (glAccount == null) { throw new GLAccountNotFoundException(glAccountId); }
|
||||
|
||||
// validate this isn't a header account that has children
|
||||
if (glAccount.isHeaderAccount() && glAccount.getChildren().size() > 0) { throw new GLAccountInvalidDeleteException(
|
||||
GL_ACCOUNT_INVALID_DELETE_REASON.HAS_CHILDREN, glAccountId); }
|
||||
|
||||
// does this account have transactions logged against it
|
||||
final List<JournalEntry> journalEntriesForAccount = this.glJournalEntryRepository.findFirstJournalEntryForAccount(glAccountId);
|
||||
if (journalEntriesForAccount.size() > 0) { throw new GLAccountInvalidDeleteException(
|
||||
GL_ACCOUNT_INVALID_DELETE_REASON.TRANSANCTIONS_LOGGED, glAccountId); }
|
||||
this.glAccountRepository.delete(glAccount);
|
||||
|
||||
return new CommandProcessingResultBuilder().withEntityId(glAccountId).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param command
|
||||
* @return
|
||||
*/
|
||||
private GLAccount validateParentGLAccount(final Long parentAccountId) {
|
||||
GLAccount parentGLAccount = null;
|
||||
if (parentAccountId != null) {
|
||||
parentGLAccount = this.glAccountRepository.findOne(parentAccountId);
|
||||
if (parentGLAccount == null) { throw new GLAccountNotFoundException(parentAccountId); }
|
||||
// ensure parent is not a detail account
|
||||
if (parentGLAccount.isDetailAccount()) { throw new GLAccountInvalidParentException(parentAccountId); }
|
||||
}
|
||||
return parentGLAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param command
|
||||
* @param dve
|
||||
*/
|
||||
private void handleGLAccountDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
|
||||
final Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("acc_gl_code")) {
|
||||
final String glCode = command.stringValueOfParameterNamed(GLAccountJsonInputParams.GL_CODE.getValue());
|
||||
throw new GLAccountDuplicateException(glCode);
|
||||
}
|
||||
|
||||
logger.error(dve.getMessage(), dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.glAccount.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource GL Account: " + realCause.getMessage());
|
||||
}
|
||||
|
||||
private CodeValue retrieveTagId(final Long tagId, final GLAccountType accountType) {
|
||||
CodeValue glAccountTagType = null;
|
||||
if (accountType.isAssetType()) {
|
||||
glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
|
||||
AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME, tagId);
|
||||
} else if (accountType.isLiabilityType()) {
|
||||
glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
|
||||
AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME, tagId);
|
||||
} else if (accountType.isEquityType()) {
|
||||
glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
|
||||
AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME, tagId);
|
||||
} else if (accountType.isIncomeType()) {
|
||||
glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
|
||||
AccountingConstants.INCOME_TAG_OPTION_CODE_NAME, tagId);
|
||||
} else if (accountType.isExpenseType()) {
|
||||
glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
|
||||
AccountingConstants.EXPENSES_TAG_OPTION_CODE_NAME, tagId);
|
||||
}
|
||||
return glAccountTagType;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.api;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.serialization.JsonParserHelper;
|
||||
|
||||
/**
|
||||
* Class for parsing dates sent as query parameters
|
||||
*
|
||||
* TODO: Vishwas Should move this class to a more generic package
|
||||
*/
|
||||
public class DateParam {
|
||||
|
||||
private final String dateAsString;
|
||||
|
||||
public DateParam(final String dateStr) throws WebApplicationException {
|
||||
this.dateAsString = dateStr;
|
||||
}
|
||||
|
||||
public Date getDate(final String parameterName, final String dateFormat, final String localeAsString) {
|
||||
final Locale locale = JsonParserHelper.localeFromString(localeAsString);
|
||||
final LocalDate localDate = JsonParserHelper.convertFrom(this.dateAsString, parameterName, dateFormat, locale);
|
||||
return localDate.toDate();
|
||||
}
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
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.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.accounting.journalentry.data.JournalEntryAssociationParametersData;
|
||||
import org.mifosplatform.accounting.journalentry.data.JournalEntryData;
|
||||
import org.mifosplatform.accounting.journalentry.data.OfficeOpeningBalancesData;
|
||||
import org.mifosplatform.accounting.journalentry.service.JournalEntryReadPlatformService;
|
||||
import org.mifosplatform.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||
import org.mifosplatform.accounting.provisioning.constant.ProvisioningEntriesApiConstants;
|
||||
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.exception.UnrecognizedQueryParamException;
|
||||
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.core.service.SearchParameters;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/journalentries")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class JournalEntriesApiResource {
|
||||
|
||||
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "officeId", "officeName",
|
||||
"glAccountName", "glAccountId", "glAccountCode", "glAccountType", "transactionDate", "entryType", "amount", "transactionId",
|
||||
"manualEntry", "entityType", "entityId", "createdByUserId", "createdDate", "createdByUserName", "comments", "reversed",
|
||||
"referenceNumber", "currency", "transactionDetails"));
|
||||
|
||||
private final String resourceNameForPermission = "JOURNALENTRY";
|
||||
|
||||
private final JournalEntryReadPlatformService journalEntryReadPlatformService;
|
||||
private final DefaultToApiJsonSerializer<Object> apiJsonSerializerService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PlatformSecurityContext context;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public JournalEntriesApiResource(final PlatformSecurityContext context,
|
||||
final JournalEntryReadPlatformService journalEntryReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<Object> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.context = context;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.apiJsonSerializerService = toApiJsonSerializer;
|
||||
this.journalEntryReadPlatformService = journalEntryReadPlatformService;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
|
||||
@QueryParam("glAccountId") final Long glAccountId, @QueryParam("manualEntriesOnly") final Boolean onlyManualEntries,
|
||||
@QueryParam("fromDate") final DateParam fromDateParam, @QueryParam("toDate") final DateParam toDateParam,
|
||||
@QueryParam("transactionId") final String transactionId, @QueryParam("entityType") final Integer entityType,
|
||||
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
|
||||
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder,
|
||||
@QueryParam("locale") final String locale, @QueryParam("dateFormat") final String dateFormat,
|
||||
@QueryParam("loanId") final Long loanId, @QueryParam("savingsId") final Long savingsId,
|
||||
@QueryParam("runningBalance") final boolean runningBalance, @QueryParam("transactionDetails") final boolean transactionDetails) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
|
||||
|
||||
Date fromDate = null;
|
||||
if (fromDateParam != null) {
|
||||
fromDate = fromDateParam.getDate("fromDate", dateFormat, locale);
|
||||
}
|
||||
Date toDate = null;
|
||||
if (toDateParam != null) {
|
||||
toDate = toDateParam.getDate("toDate", dateFormat, locale);
|
||||
}
|
||||
|
||||
final SearchParameters searchParameters = SearchParameters.forJournalEntries(officeId, offset, limit, orderBy, sortOrder, loanId,
|
||||
savingsId);
|
||||
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(transactionDetails,
|
||||
runningBalance);
|
||||
|
||||
final Page<JournalEntryData> glJournalEntries = this.journalEntryReadPlatformService.retrieveAll(searchParameters, glAccountId,
|
||||
onlyManualEntries, fromDate, toDate, transactionId, entityType, associationParametersData);
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serialize(settings, glJournalEntries, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{journalEntryId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retreiveJournalEntryById(@PathParam("journalEntryId") final Long journalEntryId, @Context final UriInfo uriInfo,
|
||||
@QueryParam("runningBalance") final boolean runningBalance, @QueryParam("transactionDetails") final boolean transactionDetails) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
|
||||
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(transactionDetails,
|
||||
runningBalance);
|
||||
final JournalEntryData glJournalEntryData = this.journalEntryReadPlatformService.retrieveGLJournalEntryById(journalEntryId,
|
||||
associationParametersData);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serialize(settings, glJournalEntryData, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String createGLJournalEntry(final String jsonRequestBody, @QueryParam("command") final String commandParam) {
|
||||
|
||||
CommandProcessingResult result = null;
|
||||
if (is(commandParam, "updateRunningBalance")) {
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateRunningBalanceForJournalEntry()
|
||||
.withJson(jsonRequestBody).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "defineOpeningBalance")) {
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().defineOpeningBalanceForJournalEntry()
|
||||
.withJson(jsonRequestBody).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else {
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createJournalEntry().withJson(jsonRequestBody).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
}
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{transactionId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String createReversalJournalEntry(final String jsonRequestBody, @PathParam("transactionId") final String transactionId,
|
||||
@QueryParam("command") final String commandParam) {
|
||||
CommandProcessingResult result = null;
|
||||
if (is(commandParam, "reverse")) {
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().reverseJournalEntry(transactionId).withJson(jsonRequestBody)
|
||||
.build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
|
||||
return this.apiJsonSerializerService.serialize(result);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("provisioning")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveJournalEntries(@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
|
||||
@QueryParam("entryId") final Long entryId, @Context final UriInfo uriInfo) {
|
||||
this.context.authenticatedUser();
|
||||
String transactionId = "P"+entryId ;
|
||||
SearchParameters params = SearchParameters.forPagination(offset, limit) ;
|
||||
Page<JournalEntryData> entries = this.journalEntryReadPlatformService.retrieveAll(params, null, null, null, null, transactionId, PortfolioProductType.PROVISIONING.getValue(), null) ;
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serialize(settings, entries, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Path("openingbalance")
|
||||
public String retrieveOpeningBalance(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
|
||||
@QueryParam("currencyCode") final String currencyCode) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
|
||||
final OfficeOpeningBalancesData officeOpeningBalancesData = this.journalEntryReadPlatformService.retrieveOfficeOpeningBalances(
|
||||
officeId, currencyCode);
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.apiJsonSerializerService.serialize(settings, officeOpeningBalancesData);
|
||||
}
|
||||
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.api;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/***
|
||||
* Enum of all parameters passed in while creating/updating a journal Entry
|
||||
***/
|
||||
public enum JournalEntryJsonInputParams {
|
||||
OFFICE_ID("officeId"), TRANSACTION_DATE("transactionDate"), COMMENTS("comments"), CREDITS("credits"), DEBITS("debits"), LOCALE("locale"), DATE_FORMAT(
|
||||
"dateFormat"), REFERENCE_NUMBER("referenceNumber"), USE_ACCOUNTING_RULE("useAccountingRule"), ACCOUNTING_RULE("accountingRule"), AMOUNT(
|
||||
"amount"), CURRENCY_CODE("currencyCode"), PAYMENT_TYPE_ID("paymentTypeId"), ACCOUNT_NUMBER("accountNumber"), CHECK_NUMBER(
|
||||
"checkNumber"), ROUTING_CODE("routingCode"), RECEIPT_NUMBER("receiptNumber"), BANK_NUMBER("bankNumber");
|
||||
|
||||
private final String value;
|
||||
|
||||
private JournalEntryJsonInputParams(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private static final Set<String> values = new HashSet<>();
|
||||
static {
|
||||
for (final JournalEntryJsonInputParams type : JournalEntryJsonInputParams.values()) {
|
||||
values.add(type.value);
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> getAllValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.command;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.accounting.journalentry.api.JournalEntryJsonInputParams;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
|
||||
/**
|
||||
* Immutable command for adding an accounting closure
|
||||
*/
|
||||
public class JournalEntryCommand {
|
||||
|
||||
private final Long officeId;
|
||||
private final LocalDate transactionDate;
|
||||
private final String currencyCode;
|
||||
private final String comments;
|
||||
private final String referenceNumber;
|
||||
private final Long accountingRuleId;
|
||||
private final BigDecimal amount;
|
||||
private final Long paymentTypeId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String accountNumber;
|
||||
@SuppressWarnings("unused")
|
||||
private final String checkNumber;
|
||||
@SuppressWarnings("unused")
|
||||
private final String receiptNumber;
|
||||
@SuppressWarnings("unused")
|
||||
private final String bankNumber;
|
||||
@SuppressWarnings("unused")
|
||||
private final String routingCode;
|
||||
|
||||
private final SingleDebitOrCreditEntryCommand[] credits;
|
||||
private final SingleDebitOrCreditEntryCommand[] debits;
|
||||
|
||||
public JournalEntryCommand(final Long officeId, final String currencyCode, final LocalDate transactionDate, final String comments,
|
||||
final SingleDebitOrCreditEntryCommand[] credits, final SingleDebitOrCreditEntryCommand[] debits, final String referenceNumber,
|
||||
final Long accountingRuleId, final BigDecimal amount, final Long paymentTypeId, final String accountNumber,
|
||||
final String checkNumber, final String receiptNumber, final String bankNumber, final String routingCode) {
|
||||
this.officeId = officeId;
|
||||
this.currencyCode = currencyCode;
|
||||
this.transactionDate = transactionDate;
|
||||
this.comments = comments;
|
||||
this.credits = credits;
|
||||
this.debits = debits;
|
||||
this.referenceNumber = referenceNumber;
|
||||
this.accountingRuleId = accountingRuleId;
|
||||
this.amount = amount;
|
||||
this.paymentTypeId = paymentTypeId;
|
||||
this.accountNumber = accountNumber;
|
||||
this.checkNumber = checkNumber;
|
||||
this.receiptNumber = receiptNumber;
|
||||
this.bankNumber = bankNumber;
|
||||
this.routingCode = routingCode;
|
||||
|
||||
}
|
||||
|
||||
public void validateForCreate() {
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("GLJournalEntry");
|
||||
|
||||
baseDataValidator.reset().parameter("transactionDate").value(this.transactionDate).notBlank();
|
||||
|
||||
baseDataValidator.reset().parameter("officeId").value(this.officeId).notNull().integerGreaterThanZero();
|
||||
|
||||
baseDataValidator.reset().parameter(JournalEntryJsonInputParams.CURRENCY_CODE.getValue()).value(this.currencyCode).notBlank();
|
||||
|
||||
baseDataValidator.reset().parameter("comments").value(this.comments).ignoreIfNull().notExceedingLengthOf(500);
|
||||
|
||||
baseDataValidator.reset().parameter("referenceNumber").value(this.referenceNumber).ignoreIfNull().notExceedingLengthOf(100);
|
||||
|
||||
baseDataValidator.reset().parameter("accountingRule").value(this.accountingRuleId).ignoreIfNull().longGreaterThanZero();
|
||||
|
||||
baseDataValidator.reset().parameter("paymentTypeId").value(this.paymentTypeId).ignoreIfNull().longGreaterThanZero();
|
||||
|
||||
// validation for credit array elements
|
||||
if (this.credits != null) {
|
||||
if (this.credits.length == 0) {
|
||||
validateSingleDebitOrCredit(baseDataValidator, "credits", 0, new SingleDebitOrCreditEntryCommand(null, null, null, null));
|
||||
} else {
|
||||
int i = 0;
|
||||
for (final SingleDebitOrCreditEntryCommand credit : this.credits) {
|
||||
validateSingleDebitOrCredit(baseDataValidator, "credits", i, credit);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// validation for debit array elements
|
||||
if (this.debits != null) {
|
||||
if (this.debits.length == 0) {
|
||||
validateSingleDebitOrCredit(baseDataValidator, "debits", 0, new SingleDebitOrCreditEntryCommand(null, null, null, null));
|
||||
} else {
|
||||
int i = 0;
|
||||
for (final SingleDebitOrCreditEntryCommand debit : this.debits) {
|
||||
validateSingleDebitOrCredit(baseDataValidator, "debits", i, debit);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
baseDataValidator.reset().parameter("amount").value(this.amount).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
/**
|
||||
* @param baseDataValidator
|
||||
* @param i
|
||||
* @param credit
|
||||
*/
|
||||
private void validateSingleDebitOrCredit(final DataValidatorBuilder baseDataValidator, final String paramSuffix, final int arrayPos,
|
||||
final SingleDebitOrCreditEntryCommand credit) {
|
||||
baseDataValidator.reset().parameter(paramSuffix + "[" + arrayPos + "].glAccountId").value(credit.getGlAccountId()).notNull()
|
||||
.integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(paramSuffix + "[" + arrayPos + "].amount").value(credit.getAmount()).notNull()
|
||||
.zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public LocalDate getTransactionDate() {
|
||||
return this.transactionDate;
|
||||
}
|
||||
|
||||
public String getComments() {
|
||||
return this.comments;
|
||||
}
|
||||
|
||||
public SingleDebitOrCreditEntryCommand[] getCredits() {
|
||||
return this.credits;
|
||||
}
|
||||
|
||||
public SingleDebitOrCreditEntryCommand[] getDebits() {
|
||||
return this.debits;
|
||||
}
|
||||
|
||||
public String getReferenceNumber() {
|
||||
return this.referenceNumber;
|
||||
}
|
||||
|
||||
public Long getAccountingRuleId() {
|
||||
return this.accountingRuleId;
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.command;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Immutable command for adding a "Credit" entry to the Journal
|
||||
*/
|
||||
public class SingleDebitOrCreditEntryCommand {
|
||||
|
||||
private final Long glAccountId;
|
||||
private final BigDecimal amount;
|
||||
private final String comments;
|
||||
|
||||
private final Set<String> parametersPassedInRequest;
|
||||
|
||||
public SingleDebitOrCreditEntryCommand(final Set<String> parametersPassedInRequest, final Long glAccountId, final BigDecimal amount,
|
||||
final String comments) {
|
||||
this.parametersPassedInRequest = parametersPassedInRequest;
|
||||
this.glAccountId = glAccountId;
|
||||
this.amount = amount;
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public boolean isGlAccountIdChanged() {
|
||||
return this.parametersPassedInRequest.contains("glAccountId");
|
||||
}
|
||||
|
||||
public boolean isGlAmountChanged() {
|
||||
return this.parametersPassedInRequest.contains("amount");
|
||||
}
|
||||
|
||||
public boolean isCommentsChanged() {
|
||||
return this.parametersPassedInRequest.contains("comments");
|
||||
}
|
||||
|
||||
public Long getGlAccountId() {
|
||||
return this.glAccountId;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public String getComments() {
|
||||
return this.comments;
|
||||
}
|
||||
|
||||
public Set<String> getParametersPassedInRequest() {
|
||||
return this.parametersPassedInRequest;
|
||||
}
|
||||
|
||||
}
|
||||
fineract-provider/src/main/java/org/mifosplatform/accounting/journalentry/data/ChargePaymentDTO.java
Executable
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class ChargePaymentDTO {
|
||||
|
||||
private final Long chargeId;
|
||||
private final BigDecimal amount;
|
||||
private final Long loanChargeId;
|
||||
|
||||
public ChargePaymentDTO(final Long chargeId, final Long loanChargeId, final BigDecimal amount) {
|
||||
this.chargeId = chargeId;
|
||||
this.amount = amount;
|
||||
this.loanChargeId = loanChargeId;
|
||||
}
|
||||
|
||||
public Long getChargeId() {
|
||||
return this.chargeId;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public Long getLoanChargeId() {
|
||||
return this.loanChargeId;
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class ClientChargePaymentDTO {
|
||||
|
||||
private final Long chargeId;
|
||||
private final BigDecimal amount;
|
||||
private final Long clientChargeId;
|
||||
private final boolean isPenalty;
|
||||
private final Long incomeAccountId;
|
||||
|
||||
public ClientChargePaymentDTO(Long chargeId, BigDecimal amount, Long clientChargeId, boolean isPenalty, Long incomeAccountId) {
|
||||
super();
|
||||
this.chargeId = chargeId;
|
||||
this.amount = amount;
|
||||
this.clientChargeId = clientChargeId;
|
||||
this.isPenalty = isPenalty;
|
||||
this.incomeAccountId = incomeAccountId;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public Long getClientChargeId() {
|
||||
return this.clientChargeId;
|
||||
}
|
||||
|
||||
public boolean isPenalty() {
|
||||
return this.isPenalty;
|
||||
}
|
||||
|
||||
public Long getChargeId() {
|
||||
return chargeId;
|
||||
}
|
||||
|
||||
public Long getIncomeAccountId() {
|
||||
return this.incomeAccountId;
|
||||
}
|
||||
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientTransactionType;
|
||||
|
||||
public class ClientTransactionDTO {
|
||||
|
||||
private final Long officeId;
|
||||
private final Long clientId;
|
||||
private String currencyCode;
|
||||
|
||||
private final Long transactionId;
|
||||
private final Date transactionDate;
|
||||
private final Long paymentTypeId;
|
||||
private final EnumOptionData transactionType;
|
||||
|
||||
private final BigDecimal amount;
|
||||
|
||||
private final Boolean accountingEnabled;
|
||||
|
||||
/*** Boolean values determines if the transaction is reversed ***/
|
||||
private final boolean reversed;
|
||||
|
||||
/** Breakdowns of fees this Transaction pays **/
|
||||
private final List<ClientChargePaymentDTO> chargePayments;
|
||||
|
||||
public ClientTransactionDTO(final Long clientId, final Long officeId, final Long paymentTypeId, final Long transactionId,
|
||||
final Date transactionDate, final EnumOptionData transactionType, final String currencyCode, final BigDecimal amount,
|
||||
final boolean reversed, final boolean accountingEnabled, final List<ClientChargePaymentDTO> clientChargePayments) {
|
||||
this.clientId = clientId;
|
||||
this.paymentTypeId = paymentTypeId;
|
||||
this.transactionId = transactionId;
|
||||
this.transactionDate = transactionDate;
|
||||
this.amount = amount;
|
||||
this.reversed = reversed;
|
||||
this.transactionType = transactionType;
|
||||
this.chargePayments = clientChargePayments;
|
||||
this.officeId = officeId;
|
||||
this.accountingEnabled = accountingEnabled;
|
||||
this.currencyCode = currencyCode;
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public Date getTransactionDate() {
|
||||
return this.transactionDate;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public boolean isReversed() {
|
||||
return this.reversed;
|
||||
}
|
||||
|
||||
public Long getPaymentTypeId() {
|
||||
return this.paymentTypeId;
|
||||
}
|
||||
|
||||
public EnumOptionData getTransactionType() {
|
||||
return transactionType;
|
||||
}
|
||||
|
||||
public boolean isChargePayment() {
|
||||
return ClientTransactionType.PAY_CHARGE.getValue().equals(new Integer(this.transactionType.getId().intValue()));
|
||||
}
|
||||
|
||||
public String getCurrencyCode() {
|
||||
return this.currencyCode;
|
||||
}
|
||||
|
||||
public List<ClientChargePaymentDTO> getChargePayments() {
|
||||
return this.chargePayments;
|
||||
}
|
||||
|
||||
public Long getTransactionId() {
|
||||
return this.transactionId;
|
||||
}
|
||||
|
||||
public Boolean getAccountingEnabled() {
|
||||
return this.accountingEnabled;
|
||||
}
|
||||
|
||||
public Long getClientId() {
|
||||
return this.clientId;
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
public class JournalEntryAssociationParametersData {
|
||||
|
||||
private final boolean transactionDetailsRequired;
|
||||
private final boolean runningBalanceRequired;
|
||||
|
||||
public JournalEntryAssociationParametersData() {
|
||||
this.transactionDetailsRequired = false;
|
||||
this.runningBalanceRequired = false;
|
||||
}
|
||||
|
||||
public JournalEntryAssociationParametersData(final boolean transactionDetailsRequired, final boolean runningBalanceRequired) {
|
||||
this.transactionDetailsRequired = transactionDetailsRequired;
|
||||
this.runningBalanceRequired = runningBalanceRequired;
|
||||
}
|
||||
|
||||
public boolean isTransactionDetailsRequired() {
|
||||
return this.transactionDetailsRequired;
|
||||
}
|
||||
|
||||
public boolean isRunningBalanceRequired() {
|
||||
return this.runningBalanceRequired;
|
||||
}
|
||||
}
|
||||
fineract-provider/src/main/java/org/mifosplatform/accounting/journalentry/data/JournalEntryData.java
Executable
+162
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
|
||||
/**
|
||||
* Immutable object representing a General Ledger Account
|
||||
*
|
||||
* Note: no getter/setters required as google will produce json from fields of
|
||||
* object.
|
||||
*/
|
||||
public class JournalEntryData {
|
||||
|
||||
private final Long id;
|
||||
private final Long officeId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String officeName;
|
||||
@SuppressWarnings("unused")
|
||||
private final String glAccountName;
|
||||
private final Long glAccountId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String glAccountCode;
|
||||
private final EnumOptionData glAccountType;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate transactionDate;
|
||||
private final EnumOptionData entryType;
|
||||
private final BigDecimal amount;
|
||||
@SuppressWarnings("unused")
|
||||
private final CurrencyData currency;
|
||||
private final String transactionId;
|
||||
@SuppressWarnings("unused")
|
||||
private final Boolean manualEntry;
|
||||
@SuppressWarnings("unused")
|
||||
private final EnumOptionData entityType;
|
||||
@SuppressWarnings("unused")
|
||||
private final Long entityId;
|
||||
@SuppressWarnings("unused")
|
||||
private final Long createdByUserId;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate createdDate;
|
||||
@SuppressWarnings("unused")
|
||||
private final String createdByUserName;
|
||||
@SuppressWarnings("unused")
|
||||
private final String comments;
|
||||
@SuppressWarnings("unused")
|
||||
private final Boolean reversed;
|
||||
@SuppressWarnings("unused")
|
||||
private final String referenceNumber;
|
||||
@SuppressWarnings("unused")
|
||||
private final BigDecimal officeRunningBalance;
|
||||
@SuppressWarnings("unused")
|
||||
private final BigDecimal organizationRunningBalance;
|
||||
@SuppressWarnings("unused")
|
||||
private final Boolean runningBalanceComputed;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final TransactionDetailData transactionDetails;
|
||||
|
||||
public JournalEntryData(final Long id, final Long officeId, final String officeName, final String glAccountName,
|
||||
final Long glAccountId, final String glAccountCode, final EnumOptionData glAccountClassification,
|
||||
final LocalDate transactionDate, final EnumOptionData entryType, final BigDecimal amount, final String transactionId,
|
||||
final Boolean manualEntry, final EnumOptionData entityType, final Long entityId, final Long createdByUserId,
|
||||
final LocalDate createdDate, final String createdByUserName, final String comments, final Boolean reversed,
|
||||
final String referenceNumber, final BigDecimal officeRunningBalance, final BigDecimal organizationRunningBalance,
|
||||
final Boolean runningBalanceComputed, final TransactionDetailData transactionDetailData, final CurrencyData currency) {
|
||||
this.id = id;
|
||||
this.officeId = officeId;
|
||||
this.officeName = officeName;
|
||||
this.glAccountName = glAccountName;
|
||||
this.glAccountId = glAccountId;
|
||||
this.glAccountCode = glAccountCode;
|
||||
this.glAccountType = glAccountClassification;
|
||||
this.transactionDate = transactionDate;
|
||||
this.entryType = entryType;
|
||||
this.amount = amount;
|
||||
this.transactionId = transactionId;
|
||||
this.manualEntry = manualEntry;
|
||||
this.entityType = entityType;
|
||||
this.entityId = entityId;
|
||||
this.createdByUserId = createdByUserId;
|
||||
this.createdDate = createdDate;
|
||||
this.createdByUserName = createdByUserName;
|
||||
this.comments = comments;
|
||||
this.reversed = reversed;
|
||||
this.referenceNumber = referenceNumber;
|
||||
this.officeRunningBalance = officeRunningBalance;
|
||||
this.organizationRunningBalance = organizationRunningBalance;
|
||||
this.runningBalanceComputed = runningBalanceComputed;
|
||||
this.transactionDetails = transactionDetailData;
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public static JournalEntryData fromGLAccountData(final GLAccountData glAccountData) {
|
||||
|
||||
final Long id = null;
|
||||
final Long officeId = null;
|
||||
final String officeName = null;
|
||||
final String glAccountName = glAccountData.getName();
|
||||
final Long glAccountId = glAccountData.getId();
|
||||
final String glAccountCode = glAccountData.getGlCode();
|
||||
final EnumOptionData glAccountClassification = glAccountData.getType();
|
||||
final LocalDate transactionDate = null;
|
||||
final EnumOptionData entryType = null;
|
||||
final BigDecimal amount = null;
|
||||
final String transactionId = null;
|
||||
final Boolean manualEntry = null;
|
||||
final EnumOptionData entityType = null;
|
||||
final Long entityId = null;
|
||||
final Long createdByUserId = null;
|
||||
final LocalDate createdDate = null;
|
||||
final String createdByUserName = null;
|
||||
final String comments = null;
|
||||
final Boolean reversed = null;
|
||||
final String referenceNumber = null;
|
||||
final BigDecimal officeRunningBalance = null;
|
||||
final BigDecimal organizationRunningBalance = null;
|
||||
final Boolean runningBalanceComputed = null;
|
||||
final TransactionDetailData transactionDetailData = null;
|
||||
final CurrencyData currency = null;
|
||||
return new JournalEntryData(id, officeId, officeName, glAccountName, glAccountId, glAccountCode, glAccountClassification,
|
||||
transactionDate, entryType, amount, transactionId, manualEntry, entityType, entityId, createdByUserId, createdDate,
|
||||
createdByUserName, comments, reversed, referenceNumber, officeRunningBalance, organizationRunningBalance,
|
||||
runningBalanceComputed, transactionDetailData, currency);
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Long getGlAccountId() {
|
||||
return this.glAccountId;
|
||||
}
|
||||
|
||||
public EnumOptionData getGlAccountType() {
|
||||
return this.glAccountType;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public EnumOptionData getEntryType() {
|
||||
return this.entryType;
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mifosplatform.accounting.journalentry.api.JournalEntryJsonInputParams;
|
||||
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.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public class JournalEntryDataValidator {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
public static final Set<String> RUNNING_BALANCE_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<>(
|
||||
Arrays.asList(JournalEntryJsonInputParams.OFFICE_ID.getValue()));
|
||||
|
||||
@Autowired
|
||||
public JournalEntryDataValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateForUpdateRunningbalance(final JsonCommand command) {
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, command.json(), RUNNING_BALANCE_UPDATE_REQUEST_DATA_PARAMETERS);
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("GLJournalEntry");
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(JournalEntryJsonInputParams.OFFICE_ID.getValue(), command.parsedJson())) {
|
||||
final String officeId = this.fromApiJsonHelper.extractStringNamed(JournalEntryJsonInputParams.OFFICE_ID.getValue(),
|
||||
command.parsedJson());
|
||||
baseDataValidator.reset().parameter(JournalEntryJsonInputParams.OFFICE_ID.getValue()).value(officeId).ignoreIfNull()
|
||||
.longGreaterThanZero();
|
||||
}
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
/**
|
||||
* Represents the successful result of an REST API call.
|
||||
*/
|
||||
public class JournalEntryIdentifier {
|
||||
|
||||
private String entityId;
|
||||
|
||||
// TODO - Rename variable to commandId or taskId or something that shows
|
||||
// this is the id of a command in a table/queue for processing.
|
||||
@SuppressWarnings("unused")
|
||||
private Long makerCheckerId;
|
||||
|
||||
public static JournalEntryIdentifier makerChecker(final Long makerCheckerId) {
|
||||
return new JournalEntryIdentifier(null, makerCheckerId);
|
||||
}
|
||||
|
||||
public static JournalEntryIdentifier makerChecker(final String resourceId, final Long makerCheckerId) {
|
||||
return new JournalEntryIdentifier(resourceId, makerCheckerId);
|
||||
}
|
||||
|
||||
public JournalEntryIdentifier() {
|
||||
//
|
||||
}
|
||||
|
||||
public JournalEntryIdentifier(final String entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
private JournalEntryIdentifier(final String entityId, final Long makerCheckerId) {
|
||||
this.entityId = entityId;
|
||||
this.makerCheckerId = makerCheckerId;
|
||||
}
|
||||
|
||||
public String getEntityId() {
|
||||
return this.entityId;
|
||||
}
|
||||
|
||||
public void setEntityId(final String entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
}
|
||||
Executable
+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.accounting.journalentry.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LoanDTO {
|
||||
|
||||
private Long loanId;
|
||||
private Long loanProductId;
|
||||
private Long officeId;
|
||||
|
||||
private String currencyCode;
|
||||
private boolean cashBasedAccountingEnabled;
|
||||
final boolean upfrontAccrualBasedAccountingEnabled;
|
||||
final boolean periodicAccrualBasedAccountingEnabled;
|
||||
private List<LoanTransactionDTO> newLoanTransactions;
|
||||
|
||||
public LoanDTO(final Long loanId, final Long loanProductId, final Long officeId, final String currencyCode,
|
||||
final boolean cashBasedAccountingEnabled, final boolean upfrontAccrualBasedAccountingEnabled,
|
||||
final boolean periodicAccrualBasedAccountingEnabled, final List<LoanTransactionDTO> newLoanTransactions) {
|
||||
this.loanId = loanId;
|
||||
this.loanProductId = loanProductId;
|
||||
this.officeId = officeId;
|
||||
this.cashBasedAccountingEnabled = cashBasedAccountingEnabled;
|
||||
this.newLoanTransactions = newLoanTransactions;
|
||||
this.currencyCode = currencyCode;
|
||||
this.upfrontAccrualBasedAccountingEnabled = upfrontAccrualBasedAccountingEnabled;
|
||||
this.periodicAccrualBasedAccountingEnabled = periodicAccrualBasedAccountingEnabled;
|
||||
}
|
||||
|
||||
public Long getLoanId() {
|
||||
return this.loanId;
|
||||
}
|
||||
|
||||
public void setLoanId(final Long loanId) {
|
||||
this.loanId = loanId;
|
||||
}
|
||||
|
||||
public Long getLoanProductId() {
|
||||
return this.loanProductId;
|
||||
}
|
||||
|
||||
public void setLoanProductId(final Long loanProductId) {
|
||||
this.loanProductId = loanProductId;
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public void setOfficeId(final Long officeId) {
|
||||
this.officeId = officeId;
|
||||
}
|
||||
|
||||
public boolean isCashBasedAccountingEnabled() {
|
||||
return this.cashBasedAccountingEnabled;
|
||||
}
|
||||
|
||||
public void setCashBasedAccountingEnabled(final boolean cashBasedAccountingEnabled) {
|
||||
this.cashBasedAccountingEnabled = cashBasedAccountingEnabled;
|
||||
}
|
||||
|
||||
public boolean isUpfrontAccrualBasedAccountingEnabled() {
|
||||
return this.upfrontAccrualBasedAccountingEnabled;
|
||||
}
|
||||
|
||||
public boolean isPeriodicAccrualBasedAccountingEnabled() {
|
||||
return this.periodicAccrualBasedAccountingEnabled;
|
||||
}
|
||||
|
||||
public List<LoanTransactionDTO> getNewLoanTransactions() {
|
||||
return this.newLoanTransactions;
|
||||
}
|
||||
|
||||
public void setNewLoanTransactions(final List<LoanTransactionDTO> newLoanTransactions) {
|
||||
this.newLoanTransactions = newLoanTransactions;
|
||||
}
|
||||
|
||||
public String getCurrencyCode() {
|
||||
return this.currencyCode;
|
||||
}
|
||||
|
||||
public void setCurrencyCode(final String currencyCode) {
|
||||
this.currencyCode = currencyCode;
|
||||
}
|
||||
|
||||
}
|
||||
+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.accounting.journalentry.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
|
||||
|
||||
public class LoanTransactionDTO {
|
||||
|
||||
private final Long officeId;
|
||||
|
||||
private final String transactionId;
|
||||
private final Date transactionDate;
|
||||
private final Long paymentTypeId;
|
||||
private final LoanTransactionEnumData transactionType;
|
||||
|
||||
private final BigDecimal amount;
|
||||
|
||||
/*** Breakup of amounts in case of repayments **/
|
||||
private final BigDecimal principal;
|
||||
private final BigDecimal interest;
|
||||
private final BigDecimal fees;
|
||||
private final BigDecimal penalties;
|
||||
private final BigDecimal overPayment;
|
||||
|
||||
/*** Boolean values determines if the transaction is reversed ***/
|
||||
private final boolean reversed;
|
||||
|
||||
/** Breakdowns of fees and penalties this Transaction pays **/
|
||||
private final List<ChargePaymentDTO> penaltyPayments;
|
||||
private final List<ChargePaymentDTO> feePayments;
|
||||
|
||||
private final boolean isAccountTransfer;
|
||||
|
||||
public LoanTransactionDTO(final Long officeId, final Long paymentTypeId, final String transactionId, final Date transactionDate,
|
||||
final LoanTransactionEnumData transactionType, final BigDecimal amount, final BigDecimal principal, final BigDecimal interest,
|
||||
final BigDecimal fees, final BigDecimal penalties, final BigDecimal overPayment, final boolean reversed,
|
||||
final List<ChargePaymentDTO> feePayments, final List<ChargePaymentDTO> penaltyPayments, boolean isAccountTransfer) {
|
||||
this.paymentTypeId = paymentTypeId;
|
||||
this.transactionId = transactionId;
|
||||
this.transactionDate = transactionDate;
|
||||
this.amount = amount;
|
||||
this.principal = principal;
|
||||
this.interest = interest;
|
||||
this.fees = fees;
|
||||
this.penalties = penalties;
|
||||
this.reversed = reversed;
|
||||
this.transactionType = transactionType;
|
||||
this.feePayments = feePayments;
|
||||
this.penaltyPayments = penaltyPayments;
|
||||
this.overPayment = overPayment;
|
||||
this.officeId = officeId;
|
||||
this.isAccountTransfer = isAccountTransfer;
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return this.transactionId;
|
||||
}
|
||||
|
||||
public Date getTransactionDate() {
|
||||
return this.transactionDate;
|
||||
}
|
||||
|
||||
public LoanTransactionEnumData getTransactionType() {
|
||||
return this.transactionType;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipal() {
|
||||
return this.principal;
|
||||
}
|
||||
|
||||
public BigDecimal getInterest() {
|
||||
return this.interest;
|
||||
}
|
||||
|
||||
public BigDecimal getFees() {
|
||||
return this.fees;
|
||||
}
|
||||
|
||||
public BigDecimal getPenalties() {
|
||||
return this.penalties;
|
||||
}
|
||||
|
||||
public BigDecimal getOverPayment() {
|
||||
return this.overPayment;
|
||||
}
|
||||
|
||||
public boolean isReversed() {
|
||||
return this.reversed;
|
||||
}
|
||||
|
||||
public Long getPaymentTypeId() {
|
||||
return this.paymentTypeId;
|
||||
}
|
||||
|
||||
public List<ChargePaymentDTO> getPenaltyPayments() {
|
||||
return this.penaltyPayments;
|
||||
}
|
||||
|
||||
public List<ChargePaymentDTO> getFeePayments() {
|
||||
return this.feePayments;
|
||||
}
|
||||
|
||||
public boolean isAccountTransfer() {
|
||||
return this.isAccountTransfer;
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||
|
||||
public class OfficeOpeningBalancesData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Long officeId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String officeName;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate transactionDate;
|
||||
@SuppressWarnings("unused")
|
||||
private final GLAccountData contraAccount;
|
||||
@SuppressWarnings("unused")
|
||||
private final List<JournalEntryData> assetAccountOpeningBalances;
|
||||
@SuppressWarnings("unused")
|
||||
private final List<JournalEntryData> liabityAccountOpeningBalances;
|
||||
@SuppressWarnings("unused")
|
||||
private final List<JournalEntryData> incomeAccountOpeningBalances;
|
||||
@SuppressWarnings("unused")
|
||||
private final List<JournalEntryData> equityAccountOpeningBalances;
|
||||
@SuppressWarnings("unused")
|
||||
private final List<JournalEntryData> expenseAccountOpeningBalances;
|
||||
|
||||
private OfficeOpeningBalancesData(final Long officeId, final String officeName, final LocalDate transactionDate,
|
||||
final GLAccountData contraAccount, final List<JournalEntryData> assetAccountOpeningBalances,
|
||||
final List<JournalEntryData> liabityAccountOpeningBalances, final List<JournalEntryData> incomeAccountOpeningBalances,
|
||||
final List<JournalEntryData> equityAccountOpeningBalances, final List<JournalEntryData> expenseAccountOpeningBalances) {
|
||||
this.officeId = officeId;
|
||||
this.officeName = officeName;
|
||||
this.transactionDate = transactionDate;
|
||||
this.contraAccount = contraAccount;
|
||||
this.assetAccountOpeningBalances = assetAccountOpeningBalances;
|
||||
this.liabityAccountOpeningBalances = liabityAccountOpeningBalances;
|
||||
this.incomeAccountOpeningBalances = incomeAccountOpeningBalances;
|
||||
this.equityAccountOpeningBalances = equityAccountOpeningBalances;
|
||||
this.expenseAccountOpeningBalances = expenseAccountOpeningBalances;
|
||||
}
|
||||
|
||||
public static OfficeOpeningBalancesData createNew(final Long officeId, final String officeName, final LocalDate transactionDate,
|
||||
final GLAccountData contraAccount, final List<JournalEntryData> assetAccountOpeningBalances,
|
||||
final List<JournalEntryData> liabityAccountOpeningBalances, final List<JournalEntryData> incomeAccountOpeningBalances,
|
||||
final List<JournalEntryData> equityAccountOpeningBalances, final List<JournalEntryData> expenseAccountOpeningBalances) {
|
||||
return new OfficeOpeningBalancesData(officeId, officeName, transactionDate, contraAccount, assetAccountOpeningBalances,
|
||||
liabityAccountOpeningBalances, incomeAccountOpeningBalances, equityAccountOpeningBalances, expenseAccountOpeningBalances);
|
||||
}
|
||||
}
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.accounting.journalentry.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SavingsDTO {
|
||||
|
||||
private Long savingsId;
|
||||
private Long savingsProductId;
|
||||
private Long officeId;
|
||||
private String currencyCode;
|
||||
private boolean cashBasedAccountingEnabled;
|
||||
private boolean accrualBasedAccountingEnabled;
|
||||
private List<SavingsTransactionDTO> newSavingsTransactions;
|
||||
|
||||
public SavingsDTO(final Long savingsId, final Long savingsProductId, final Long officeId, final String currencyCode,
|
||||
final boolean cashBasedAccountingEnabled, final boolean accrualBasedAccountingEnabled,
|
||||
final List<SavingsTransactionDTO> newSavingsTransactions) {
|
||||
this.savingsId = savingsId;
|
||||
this.savingsProductId = savingsProductId;
|
||||
this.officeId = officeId;
|
||||
this.cashBasedAccountingEnabled = cashBasedAccountingEnabled;
|
||||
this.accrualBasedAccountingEnabled = accrualBasedAccountingEnabled;
|
||||
this.newSavingsTransactions = newSavingsTransactions;
|
||||
this.currencyCode = currencyCode;
|
||||
}
|
||||
|
||||
public Long getSavingsId() {
|
||||
return this.savingsId;
|
||||
}
|
||||
|
||||
public void setSavingsId(final Long savingsId) {
|
||||
this.savingsId = savingsId;
|
||||
}
|
||||
|
||||
public Long getSavingsProductId() {
|
||||
return this.savingsProductId;
|
||||
}
|
||||
|
||||
public void setSavingsProductId(final Long savingsProductId) {
|
||||
this.savingsProductId = savingsProductId;
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public void setOfficeId(final Long officeId) {
|
||||
this.officeId = officeId;
|
||||
}
|
||||
|
||||
public boolean isCashBasedAccountingEnabled() {
|
||||
return this.cashBasedAccountingEnabled;
|
||||
}
|
||||
|
||||
public void setCashBasedAccountingEnabled(final boolean cashBasedAccountingEnabled) {
|
||||
this.cashBasedAccountingEnabled = cashBasedAccountingEnabled;
|
||||
}
|
||||
|
||||
public boolean isAccrualBasedAccountingEnabled() {
|
||||
return this.accrualBasedAccountingEnabled;
|
||||
}
|
||||
|
||||
public void setAccrualBasedAccountingEnabled(final boolean accrualBasedAccountingEnabled) {
|
||||
this.accrualBasedAccountingEnabled = accrualBasedAccountingEnabled;
|
||||
}
|
||||
|
||||
public List<SavingsTransactionDTO> getNewSavingsTransactions() {
|
||||
return this.newSavingsTransactions;
|
||||
}
|
||||
|
||||
public void setNewSavingsTransactions(final List<SavingsTransactionDTO> newSavingsTransactions) {
|
||||
this.newSavingsTransactions = newSavingsTransactions;
|
||||
}
|
||||
|
||||
public String getCurrencyCode() {
|
||||
return this.currencyCode;
|
||||
}
|
||||
|
||||
public void setCurrencyCode(final String currencyCode) {
|
||||
this.currencyCode = currencyCode;
|
||||
}
|
||||
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionEnumData;
|
||||
|
||||
public class SavingsTransactionDTO {
|
||||
|
||||
private final Long officeId;
|
||||
private final String transactionId;
|
||||
private final Date transactionDate;
|
||||
private final Long paymentTypeId;
|
||||
private final SavingsAccountTransactionEnumData transactionType;
|
||||
|
||||
private final BigDecimal amount;
|
||||
private final BigDecimal overdraftAmount;
|
||||
|
||||
/*** Boolean values determines if the transaction is reversed ***/
|
||||
private final boolean reversed;
|
||||
|
||||
/** Breakdowns of fees and penalties this Transaction pays **/
|
||||
private final List<ChargePaymentDTO> penaltyPayments;
|
||||
private final List<ChargePaymentDTO> feePayments;
|
||||
|
||||
private final boolean isAccountTransfer;
|
||||
|
||||
public SavingsTransactionDTO(final Long officeId, final Long paymentTypeId, final String transactionId, final Date transactionDate,
|
||||
final SavingsAccountTransactionEnumData transactionType, final BigDecimal amount, final boolean reversed,
|
||||
final List<ChargePaymentDTO> feePayments, final List<ChargePaymentDTO> penaltyPayments, final BigDecimal overdraftAmount,
|
||||
boolean isAccountTransfer) {
|
||||
this.paymentTypeId = paymentTypeId;
|
||||
this.transactionId = transactionId;
|
||||
this.transactionDate = transactionDate;
|
||||
this.amount = amount;
|
||||
this.reversed = reversed;
|
||||
this.transactionType = transactionType;
|
||||
this.feePayments = feePayments;
|
||||
this.penaltyPayments = penaltyPayments;
|
||||
this.officeId = officeId;
|
||||
this.overdraftAmount = overdraftAmount;
|
||||
this.isAccountTransfer = isAccountTransfer;
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return this.transactionId;
|
||||
}
|
||||
|
||||
public Date getTransactionDate() {
|
||||
return this.transactionDate;
|
||||
}
|
||||
|
||||
public Long getPaymentTypeId() {
|
||||
return this.paymentTypeId;
|
||||
}
|
||||
|
||||
public SavingsAccountTransactionEnumData getTransactionType() {
|
||||
return this.transactionType;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public boolean isReversed() {
|
||||
return this.reversed;
|
||||
}
|
||||
|
||||
public List<ChargePaymentDTO> getPenaltyPayments() {
|
||||
return this.penaltyPayments;
|
||||
}
|
||||
|
||||
public List<ChargePaymentDTO> getFeePayments() {
|
||||
return this.feePayments;
|
||||
}
|
||||
|
||||
public BigDecimal getOverdraftAmount() {
|
||||
return this.overdraftAmount;
|
||||
}
|
||||
|
||||
public boolean isOverdraftTransaction() {
|
||||
return this.overdraftAmount != null && this.overdraftAmount.doubleValue() > 0;
|
||||
}
|
||||
|
||||
public boolean isAccountTransfer() {
|
||||
return this.isAccountTransfer;
|
||||
}
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
import org.mifosplatform.portfolio.note.data.NoteData;
|
||||
import org.mifosplatform.portfolio.paymentdetail.data.PaymentDetailData;
|
||||
|
||||
public class TransactionDetailData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Long transactionId;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final PaymentDetailData paymentDetails;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final NoteData noteData;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final TransactionTypeEnumData transactionType;
|
||||
|
||||
public TransactionDetailData(final Long transactionId, final PaymentDetailData paymentDetails, final NoteData noteData) {
|
||||
this.transactionId = transactionId;
|
||||
this.paymentDetails = paymentDetails;
|
||||
this.noteData = noteData;
|
||||
this.transactionType = null;
|
||||
|
||||
}
|
||||
|
||||
public TransactionDetailData(final Long transactionId, final PaymentDetailData paymentDetails, final NoteData noteData,
|
||||
final TransactionTypeEnumData transactionType) {
|
||||
this.transactionId = transactionId;
|
||||
this.paymentDetails = paymentDetails;
|
||||
this.noteData = noteData;
|
||||
this.transactionType = transactionType;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.data;
|
||||
|
||||
/**
|
||||
* Immutable data object represent loan and Savings status enumerations.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class TransactionTypeEnumData {
|
||||
|
||||
private final Long id;
|
||||
private final String code;
|
||||
private final String value;
|
||||
|
||||
public TransactionTypeEnumData(final Long id, final String code, final String value) {
|
||||
this.id = id;
|
||||
this.code = code;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Long id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+203
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
||||
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientTransaction;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
|
||||
@Entity
|
||||
@Table(name = "acc_gl_journal_entry")
|
||||
public class JournalEntry extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "office_id", nullable = false)
|
||||
private Office office;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
@JoinColumn(name = "payment_details_id", nullable = true)
|
||||
private PaymentDetail paymentDetail;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "account_id", nullable = false)
|
||||
private GLAccount glAccount;
|
||||
|
||||
@Column(name = "currency_code", length = 3, nullable = false)
|
||||
private String currencyCode;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "reversal_id")
|
||||
private JournalEntry reversalJournalEntry;
|
||||
|
||||
@Column(name = "transaction_id", nullable = false, length = 50)
|
||||
private String transactionId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "loan_transaction_id", nullable = false)
|
||||
private LoanTransaction loanTransaction;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "savings_transaction_id", nullable = false)
|
||||
private SavingsAccountTransaction savingsTransaction;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "client_transaction_id", nullable = false)
|
||||
private ClientTransaction clientTransaction;
|
||||
|
||||
@Column(name = "reversed", nullable = false)
|
||||
private boolean reversed = false;
|
||||
|
||||
@Column(name = "manual_entry", nullable = false)
|
||||
private boolean manualEntry = false;
|
||||
|
||||
@Column(name = "entry_date")
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date transactionDate;
|
||||
|
||||
@Column(name = "type_enum", nullable = false)
|
||||
private Integer type;
|
||||
|
||||
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal amount;
|
||||
|
||||
@Column(name = "description", length = 500)
|
||||
private String description;
|
||||
|
||||
@Column(name = "entity_type_enum", length = 50)
|
||||
private Integer entityType;
|
||||
|
||||
@Column(name = "entity_id")
|
||||
private Long entityId;
|
||||
|
||||
@Column(name = "ref_num")
|
||||
private String referenceNumber;
|
||||
|
||||
public static JournalEntry createNew(final Office office, final PaymentDetail paymentDetail, final GLAccount glAccount,
|
||||
final String currencyCode, final String transactionId, final boolean manualEntry, final Date transactionDate,
|
||||
final JournalEntryType journalEntryType, final BigDecimal amount, final String description, final Integer entityType,
|
||||
final Long entityId, final String referenceNumber, final LoanTransaction loanTransaction,
|
||||
final SavingsAccountTransaction savingsTransaction, final ClientTransaction clientTransaction) {
|
||||
return new JournalEntry(office, paymentDetail, glAccount, currencyCode, transactionId, manualEntry, transactionDate,
|
||||
journalEntryType.getValue(), amount, description, entityType, entityId, referenceNumber, loanTransaction,
|
||||
savingsTransaction, clientTransaction);
|
||||
}
|
||||
|
||||
protected JournalEntry() {
|
||||
//
|
||||
}
|
||||
|
||||
public JournalEntry(final Office office, final PaymentDetail paymentDetail, final GLAccount glAccount, final String currencyCode,
|
||||
final String transactionId, final boolean manualEntry, final Date transactionDate, final Integer type, final BigDecimal amount,
|
||||
final String description, final Integer entityType, final Long entityId, final String referenceNumber,
|
||||
final LoanTransaction loanTransaction, final SavingsAccountTransaction savingsTransaction,
|
||||
final ClientTransaction clientTransaction) {
|
||||
this.office = office;
|
||||
this.glAccount = glAccount;
|
||||
this.reversalJournalEntry = null;
|
||||
this.transactionId = transactionId;
|
||||
this.reversed = false;
|
||||
this.manualEntry = manualEntry;
|
||||
this.transactionDate = transactionDate;
|
||||
this.type = type;
|
||||
this.amount = amount;
|
||||
this.description = StringUtils.defaultIfEmpty(description, null);
|
||||
this.entityType = entityType;
|
||||
this.entityId = entityId;
|
||||
this.referenceNumber = referenceNumber;
|
||||
this.currencyCode = currencyCode;
|
||||
this.loanTransaction = loanTransaction;
|
||||
this.savingsTransaction = savingsTransaction;
|
||||
this.clientTransaction = clientTransaction;
|
||||
this.paymentDetail = paymentDetail;
|
||||
}
|
||||
|
||||
public boolean isDebitEntry() {
|
||||
return JournalEntryType.DEBIT.getValue().equals(this.type);
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public Office getOffice() {
|
||||
return this.office;
|
||||
}
|
||||
|
||||
public GLAccount getGlAccount() {
|
||||
return this.glAccount;
|
||||
}
|
||||
|
||||
public Date getTransactionDate() {
|
||||
return this.transactionDate;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public void setReversalJournalEntry(final JournalEntry reversalJournalEntry) {
|
||||
this.reversalJournalEntry = reversalJournalEntry;
|
||||
}
|
||||
|
||||
public void setReversed(final boolean reversed) {
|
||||
this.reversed = reversed;
|
||||
}
|
||||
|
||||
public String getReferenceNumber() {
|
||||
return this.referenceNumber;
|
||||
}
|
||||
|
||||
public String getCurrencyCode() {
|
||||
return this.currencyCode;
|
||||
}
|
||||
|
||||
public LoanTransaction getLoanTransaction() {
|
||||
return this.loanTransaction;
|
||||
}
|
||||
|
||||
public SavingsAccountTransaction getSavingsTransaction() {
|
||||
return this.savingsTransaction;
|
||||
}
|
||||
|
||||
public PaymentDetail getPaymentDetails() {
|
||||
return this.paymentDetail;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public ClientTransaction getClientTransaction() {
|
||||
return this.clientTransaction;
|
||||
}
|
||||
|
||||
public Long getEntityId() {
|
||||
return this.entityId ;
|
||||
}
|
||||
|
||||
public Integer getEntityType() {
|
||||
return this.entityType ;
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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.accounting.journalentry.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface JournalEntryRepository extends JpaRepository<JournalEntry, Long>, JpaSpecificationExecutor<JournalEntry>,
|
||||
JournalEntryRepositoryCustom {
|
||||
|
||||
@Query("from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed is false and journalEntry.manualEntry is true")
|
||||
List<JournalEntry> findUnReversedManualJournalEntriesByTransactionId(@Param("transactionId") String transactionId);
|
||||
|
||||
@Query("select DISTINCT j.transactionId from JournalEntry j where j.transactionId not in (select DISTINCT je.transactionId from JournalEntry je where je.glAccount.id = :contraId)")
|
||||
List<String> findNonContraTansactionIds(@Param("contraId") Long contraId);
|
||||
|
||||
@Query("select DISTINCT j.transactionId from JournalEntry j where j.office.id = :officeId and j.glAccount.id = :contraId and j.reversed is false and j.transactionId not in (select DISTINCT je.reversalJournalEntry.transactionId from JournalEntry je where je.reversed is true)")
|
||||
List<String> findNonReversedContraTansactionIds(@Param("contraId") Long contraId, @Param("officeId") Long officeId);
|
||||
|
||||
@Query("from JournalEntry journalEntry where journalEntry.entityId= :entityId and journalEntry.entityType = :entityType")
|
||||
List<JournalEntry> findProvisioningJournalEntriesByEntityId(@Param("entityId") Long entityId, @Param("entityType") Integer entityType) ;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user