wip:accounting stubs for autoposting and abstractions
This commit is contained in:
+47
@@ -0,0 +1,47 @@
|
|||||||
|
CREATE TABLE `acc_accounting_rule` (
|
||||||
|
`id` BIGINT(20) NOT NULL,
|
||||||
|
`name` VARCHAR(100) NULL DEFAULT NULL,
|
||||||
|
`office_id` BIGINT(20) NULL DEFAULT NULL,
|
||||||
|
`debit_account_id` BIGINT(20) NOT NULL,
|
||||||
|
`credit_account_id` BIGINT(20) NOT NULL,
|
||||||
|
`description` VARCHAR(500) NULL DEFAULT NULL,
|
||||||
|
`system_defined` TINYINT(1) NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE INDEX `accounting_rule_name_unique` (`name`),
|
||||||
|
INDEX `FK_acc_accounting_rule_acc_gl_account_debit` (`debit_account_id`),
|
||||||
|
INDEX `FK_acc_accounting_rule_acc_gl_account_credit` (`credit_account_id`),
|
||||||
|
INDEX `FK_acc_accounting_rule_m_office` (`office_id`),
|
||||||
|
CONSTRAINT `FK_acc_accounting_rule_acc_gl_account_credit` FOREIGN KEY (`credit_account_id`) REFERENCES `acc_gl_account` (`id`),
|
||||||
|
CONSTRAINT `FK_acc_accounting_rule_acc_gl_account_debit` FOREIGN KEY (`debit_account_id`) REFERENCES `acc_gl_account` (`id`),
|
||||||
|
CONSTRAINT `FK_acc_accounting_rule_m_office` FOREIGN KEY (`office_id`) REFERENCES `m_office` (`id`)
|
||||||
|
)
|
||||||
|
COLLATE='utf8_general_ci'
|
||||||
|
ENGINE=InnoDB;
|
||||||
|
|
||||||
|
CREATE TABLE `acc_auto_posting` (
|
||||||
|
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` VARCHAR(100) NOT NULL,
|
||||||
|
`description` VARCHAR(500) NULL DEFAULT NULL,
|
||||||
|
`office_id` BIGINT(20) NULL DEFAULT NULL,
|
||||||
|
`product_type_enum` SMALLINT(5) NOT NULL,
|
||||||
|
`product_id` BIGINT(20) NULL DEFAULT NULL,
|
||||||
|
`charge_id` BIGINT(20) NULL DEFAULT NULL,
|
||||||
|
`event` INT(11) NOT NULL,
|
||||||
|
`event_attribute` INT(11) NULL DEFAULT NULL,
|
||||||
|
`accounting_rule_id` BIGINT(20) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE INDEX `auto_posting_name_unique` (`name`),
|
||||||
|
INDEX `FK_acc_auto_posting_m_office` (`office_id`),
|
||||||
|
INDEX `FK_acc_auto_posting_acc_accounting_rule` (`accounting_rule_id`),
|
||||||
|
INDEX `FK_acc_auto_posting_m_code` (`event`),
|
||||||
|
INDEX `FK_acc_auto_posting_m_charge` (`charge_id`),
|
||||||
|
INDEX `FK_acc_auto_posting_m_code_value` (`event_attribute`),
|
||||||
|
CONSTRAINT `FK_acc_auto_posting_acc_accounting_rule` FOREIGN KEY (`accounting_rule_id`) REFERENCES `acc_accounting_rule` (`id`),
|
||||||
|
CONSTRAINT `FK_acc_auto_posting_m_charge` FOREIGN KEY (`charge_id`) REFERENCES `m_charge` (`id`),
|
||||||
|
CONSTRAINT `FK_acc_auto_posting_m_code` FOREIGN KEY (`event`) REFERENCES `m_code` (`id`),
|
||||||
|
CONSTRAINT `FK_acc_auto_posting_m_code_value` FOREIGN KEY (`event_attribute`) REFERENCES `m_code_value` (`id`),
|
||||||
|
CONSTRAINT `FK_acc_auto_posting_m_office` FOREIGN KEY (`office_id`) REFERENCES `m_office` (`id`)
|
||||||
|
)
|
||||||
|
COLLATE='utf8_general_ci'
|
||||||
|
ENGINE=InnoDB;
|
||||||
|
|
||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
* 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.autoposting.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("/autopostingrules")
|
||||||
|
@Component
|
||||||
|
@Scope("singleton")
|
||||||
|
public class AutoPostingApiResource {
|
||||||
|
|
||||||
|
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(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 AutoPostingApiResource(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(new
|
||||||
|
// ArrayList<OfficeLookup>(this.officeReadPlatformService.retrieveAllOfficesForLookup()));
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package org.mifosplatform.accounting.autoposting.api;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Enum of all parameters passed in while creating/updating a loan product
|
||||||
|
***/
|
||||||
|
public enum AutoPostingJsonInputParams {
|
||||||
|
ID("id"), OFFICE_ID("officeId"), NAME("name"), DESCRIPTION("description"), PRODUCT_TYPE_ENUM("productTypeEnum"), PRODUCT_ID("productId"), CHARGE_ID(
|
||||||
|
"chargeId"), EVENT_ID("eventCodeId"), EVENT_ATTRIBUTE_ID("eventAttributeId"), ACCOUNTING_RULE_ID("accountingRuleId");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
private AutoPostingJsonInputParams(final String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Set<String> values = new HashSet<String>();
|
||||||
|
static {
|
||||||
|
for (final AutoPostingJsonInputParams type : AutoPostingJsonInputParams.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
+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.autoposting.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 AutoPostingCommand {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long id;
|
||||||
|
private final Long officeId;
|
||||||
|
private final LocalDate closingDate;
|
||||||
|
private final String comments;
|
||||||
|
|
||||||
|
public AutoPostingCommand(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<ApiParameterError>();
|
||||||
|
|
||||||
|
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<ApiParameterError>();
|
||||||
|
|
||||||
|
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
+113
@@ -0,0 +1,113 @@
|
|||||||
|
/**
|
||||||
|
* 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.autoposting.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.rule.data.AccountingRuleData;
|
||||||
|
import org.mifosplatform.infrastructure.codes.data.CodeData;
|
||||||
|
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||||
|
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
|
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||||
|
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||||
|
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||||
|
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable object representing a Auto posting rule
|
||||||
|
*
|
||||||
|
* Note: no getter/setters required as google-gson will produce json from fields
|
||||||
|
* of object.
|
||||||
|
*/
|
||||||
|
public class AutoPostingData {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long id;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String name;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private String description;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private OfficeData officeData;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private EnumOptionData productType;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private LoanProductData loanProductData;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private SavingsProductData savingProductData;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private ChargeData charge;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private CodeData event;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private CodeValueData eventAttribute;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private AccountingRuleData accountingRule;
|
||||||
|
|
||||||
|
// template
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private List<EnumOptionData> allowedProductTypes = new ArrayList<EnumOptionData>();
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private List<OfficeData> allowedOffices = new ArrayList<OfficeData>();
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private List<SavingsProductData> allowedSavingProducts = new ArrayList<SavingsProductData>();
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private List<LoanProductData> allowedLoanProducts = new ArrayList<LoanProductData>();
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private List<CodeValue> allowedEventAttributes = new ArrayList<CodeValue>();
|
||||||
|
|
||||||
|
public AutoPostingData(Long id, String name, String description, OfficeData officeData, EnumOptionData productType,
|
||||||
|
LoanProductData loanProductData, SavingsProductData savingsProductData, ChargeData charge, CodeData event,
|
||||||
|
CodeValueData eventAttribute, AccountingRuleData accountingRule) {
|
||||||
|
this(id, name, description, officeData, productType, loanProductData, savingsProductData, charge, event, eventAttribute,
|
||||||
|
accountingRule, null, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AutoPostingData(Long id, String name, String description, OfficeData officeData, EnumOptionData productType,
|
||||||
|
LoanProductData loanProductData, SavingsProductData savingsProductData, ChargeData charge, CodeData event,
|
||||||
|
CodeValueData eventAttribute, AccountingRuleData accountingRule, List<EnumOptionData> allowedProductTypes,
|
||||||
|
List<OfficeData> allowedOffices, List<SavingsProductData> allowedSavingProducts, List<LoanProductData> allowedLoanProducts,
|
||||||
|
List<CodeValue> allowedEventAttributes) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.officeData = officeData;
|
||||||
|
this.productType = productType;
|
||||||
|
this.loanProductData = loanProductData;
|
||||||
|
this.savingProductData = savingsProductData;
|
||||||
|
this.charge = charge;
|
||||||
|
this.event = event;
|
||||||
|
this.eventAttribute = eventAttribute;
|
||||||
|
this.accountingRule = accountingRule;
|
||||||
|
this.allowedProductTypes = allowedProductTypes;
|
||||||
|
this.allowedOffices = allowedOffices;
|
||||||
|
this.allowedSavingProducts = allowedSavingProducts;
|
||||||
|
this.allowedLoanProducts = allowedLoanProducts;
|
||||||
|
this.allowedEventAttributes = allowedEventAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedProductTypes(List<EnumOptionData> allowedProductTypes) {
|
||||||
|
this.allowedProductTypes = allowedProductTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedOffices(List<OfficeData> allowedOffices) {
|
||||||
|
this.allowedOffices = allowedOffices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedSavingProducts(List<SavingsProductData> allowedSavingProducts) {
|
||||||
|
this.allowedSavingProducts = allowedSavingProducts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedLoanProducts(List<LoanProductData> allowedLoanProducts) {
|
||||||
|
this.allowedLoanProducts = allowedLoanProducts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedEventAttributes(List<CodeValue> allowedEventAttributes) {
|
||||||
|
this.allowedEventAttributes = allowedEventAttributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+197
@@ -0,0 +1,197 @@
|
|||||||
|
/**
|
||||||
|
* 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.autoposting.domain;
|
||||||
|
|
||||||
|
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.UniqueConstraint;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.autoposting.api.AutoPostingJsonInputParams;
|
||||||
|
import org.mifosplatform.accounting.rule.domain.AccountingRule;
|
||||||
|
import org.mifosplatform.infrastructure.codes.domain.Code;
|
||||||
|
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
|
import org.mifosplatform.portfolio.charge.domain.Charge;
|
||||||
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "acc_auto_posting", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "auto_posting_name_unique") })
|
||||||
|
public class AutoPosting extends AbstractPersistable<Long> {
|
||||||
|
|
||||||
|
@Column(name = "name", nullable = true, length = 100)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(name = "description", nullable = true, length = 500)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "office_id", nullable = true)
|
||||||
|
private Office office;
|
||||||
|
|
||||||
|
@Column(name = "type_enum", nullable = false)
|
||||||
|
private Integer productTypeEnum;
|
||||||
|
|
||||||
|
@Column(name = "product_id", nullable = true)
|
||||||
|
private Long productId;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "charge_id", nullable = true)
|
||||||
|
private Charge charge;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "event", nullable = false)
|
||||||
|
private Code event;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "event_attribute", nullable = true)
|
||||||
|
private CodeValue eventAttribute;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "accounting_rule_id", nullable = true)
|
||||||
|
private AccountingRule accountingRule;
|
||||||
|
|
||||||
|
protected AutoPosting() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
private AutoPosting(Office office, Charge charge, Code event, CodeValue eventAttribute, AccountingRule accountingRule, String name,
|
||||||
|
String description, Integer productTypeEnum, Long productId) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.office = office;
|
||||||
|
this.productTypeEnum = productTypeEnum;
|
||||||
|
this.productId = productId;
|
||||||
|
this.charge = charge;
|
||||||
|
this.event = event;
|
||||||
|
this.eventAttribute = eventAttribute;
|
||||||
|
this.accountingRule = accountingRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AutoPosting fromJson(Office office, Charge charge, Code event, CodeValue eventAttribute, AccountingRule accountingRule,
|
||||||
|
JsonCommand command) {
|
||||||
|
final String name = command.stringValueOfParameterNamed(AutoPostingJsonInputParams.NAME.getValue());
|
||||||
|
final String description = command.stringValueOfParameterNamed(AutoPostingJsonInputParams.DESCRIPTION.getValue());
|
||||||
|
final Integer productTypeEnum = command.integerValueSansLocaleOfParameterNamed(AutoPostingJsonInputParams.PRODUCT_TYPE_ENUM
|
||||||
|
.getValue());
|
||||||
|
final Long productId = command.longValueOfParameterNamed(AutoPostingJsonInputParams.PRODUCT_ID.getValue());
|
||||||
|
return new AutoPosting(office, charge, event, eventAttribute, accountingRule, name, description, productTypeEnum, productId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> update(final JsonCommand command) {
|
||||||
|
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(5);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AutoPostingJsonInputParams.OFFICE_ID.getValue(), 0L);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AutoPostingJsonInputParams.CHARGE_ID.getValue(), 0L);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AutoPostingJsonInputParams.EVENT_ID.getValue(), 0L);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AutoPostingJsonInputParams.EVENT_ATTRIBUTE_ID.getValue(), 0L);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AutoPostingJsonInputParams.ACCOUNTING_RULE_ID.getValue(), 0L);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AutoPostingJsonInputParams.NAME.getValue(), this.name);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AutoPostingJsonInputParams.DESCRIPTION.getValue(), this.description);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AutoPostingJsonInputParams.PRODUCT_TYPE_ENUM.getValue(), this.productTypeEnum, true);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AutoPostingJsonInputParams.PRODUCT_ID.getValue(), this.productId);
|
||||||
|
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(AutoPostingJsonInputParams.DESCRIPTION.getValue())) {
|
||||||
|
this.description = newValue;
|
||||||
|
} else if (paramName.equals(AutoPostingJsonInputParams.NAME.getValue())) {
|
||||||
|
this.name = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePropertyUpdate(final JsonCommand command, final Map<String, Object> actualChanges, final String paramName,
|
||||||
|
Integer propertyToBeUpdated, boolean sansLocale) {
|
||||||
|
if (command.isChangeInIntegerParameterNamed(paramName, propertyToBeUpdated)) {
|
||||||
|
Integer newValue = null;
|
||||||
|
if (sansLocale) {
|
||||||
|
newValue = command.integerValueSansLocaleOfParameterNamed(paramName);
|
||||||
|
} else {
|
||||||
|
newValue = command.integerValueOfParameterNamed(paramName);
|
||||||
|
}
|
||||||
|
actualChanges.put(paramName, newValue);
|
||||||
|
propertyToBeUpdated = newValue;
|
||||||
|
|
||||||
|
// now update actual property
|
||||||
|
if (paramName.equals(AutoPostingJsonInputParams.PRODUCT_TYPE_ENUM.getValue())) {
|
||||||
|
this.productTypeEnum = 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(AutoPostingJsonInputParams.OFFICE_ID.getValue())) {
|
||||||
|
// do nothing as this is a nested property
|
||||||
|
} else if (paramName.equals(AutoPostingJsonInputParams.CHARGE_ID.getValue())) {
|
||||||
|
// do nothing as this is a nested property
|
||||||
|
} else if (paramName.equals(AutoPostingJsonInputParams.EVENT_ID.getValue())) {
|
||||||
|
// do nothing as this is a nested property
|
||||||
|
} else if (paramName.equals(AutoPostingJsonInputParams.EVENT_ATTRIBUTE_ID.getValue())) {
|
||||||
|
// do nothing as this is a nested property
|
||||||
|
} else if (paramName.equals(AutoPostingJsonInputParams.ACCOUNTING_RULE_ID.getValue())) {
|
||||||
|
// do nothing as this is a nested property
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Office getOffice() {
|
||||||
|
return this.office;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffice(Office office) {
|
||||||
|
this.office = office;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Charge getCharge() {
|
||||||
|
return this.charge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCharge(Charge charge) {
|
||||||
|
this.charge = charge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Code getEvent() {
|
||||||
|
return this.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEvent(Code event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeValue getEventAttribute() {
|
||||||
|
return this.eventAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventAttribute(CodeValue eventAttribute) {
|
||||||
|
this.eventAttribute = eventAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountingRule getAccountingRule() {
|
||||||
|
return this.accountingRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountingRule(AccountingRule accountingRule) {
|
||||||
|
this.accountingRule = accountingRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+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.autoposting.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 AutoPostingRepository extends JpaRepository<AutoPosting, Long>, JpaSpecificationExecutor<AutoPosting> {
|
||||||
|
|
||||||
|
@Query("from GLClosure closure where closure.closingDate = (select max(closure1.closingDate) from GLClosure closure1 where closure1.office.id=:officeId) and closure.office.id= :officeId")
|
||||||
|
AutoPosting getLatestGLClosureByBranch(@Param("officeId") Long officeId);
|
||||||
|
}
|
||||||
+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.autoposting.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link RuntimeException} thrown when a Auto posting rule is already present
|
||||||
|
*/
|
||||||
|
public class AutoPostingDuplicateException extends AbstractPlatformDomainRuleException {
|
||||||
|
|
||||||
|
public AutoPostingDuplicateException(final String autoPostingName) {
|
||||||
|
super("error.msg.auto.posting.duplicate", "An autoposting rule with the name " + autoPostingName + " already exists",
|
||||||
|
autoPostingName);
|
||||||
|
}
|
||||||
|
}
|
||||||
+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.autoposting.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 AutoPostingInvalidDeleteException extends AbstractPlatformDomainRuleException {
|
||||||
|
|
||||||
|
public AutoPostingInvalidDeleteException(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.autoposting.exception;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link RuntimeException} thrown when a GL Closure is Invalid
|
||||||
|
*/
|
||||||
|
public class AutoPostingInvalidException 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 AutoPostingInvalidException(final GL_CLOSURE_INVALID_REASON reason, final Date date) {
|
||||||
|
super(reason.errorCode(), reason.errorMessage(), date);
|
||||||
|
}
|
||||||
|
}
|
||||||
+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.autoposting.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link RuntimeException} thrown when Auto posting rule is not found.
|
||||||
|
*/
|
||||||
|
public class AutoPostingNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
|
public AutoPostingNotFoundException(final Long id) {
|
||||||
|
super("error.msg.autoposting.id.invalid", "Autoposting rule with identifier " + id + " does not exist", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.accounting.autoposting.handler;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.autoposting.service.AutoPostingWritePlatformService;
|
||||||
|
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
|
||||||
|
public class CreateAutoPostingCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final AutoPostingWritePlatformService writePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CreateAutoPostingCommandHandler(final AutoPostingWritePlatformService writePlatformService) {
|
||||||
|
this.writePlatformService = writePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
|
||||||
|
return this.writePlatformService.createAutoPostingRule(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
+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.autoposting.handler;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.autoposting.service.AutoPostingWritePlatformService;
|
||||||
|
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
|
||||||
|
public class DeleteAutoPostingCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final AutoPostingWritePlatformService writePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public DeleteAutoPostingCommandHandler(final AutoPostingWritePlatformService writePlatformService) {
|
||||||
|
this.writePlatformService = writePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
return this.writePlatformService.deleteAutoPostingRule(command.entityId());
|
||||||
|
}
|
||||||
|
}
|
||||||
+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.autoposting.handler;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.autoposting.service.AutoPostingWritePlatformService;
|
||||||
|
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
|
||||||
|
public class UpdateAutoPostingCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final AutoPostingWritePlatformService writePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UpdateAutoPostingCommandHandler(final AutoPostingWritePlatformService writePlatformService) {
|
||||||
|
this.writePlatformService = writePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
return this.writePlatformService.updateAutoPostingRule(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.autoposting.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 AutoPostingCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<GLClosureCommand> {
|
||||||
|
|
||||||
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AutoPostingCommandFromApiJsonDeserializer(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.autoposting.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.autoposting.data.AutoPostingData;
|
||||||
|
|
||||||
|
public interface AutoPostingReadPlatformService {
|
||||||
|
|
||||||
|
List<AutoPostingData> retrieveAllAutoPostingRules();
|
||||||
|
|
||||||
|
AutoPostingData retrieveAutoPostingRuleById(long autopostingId);
|
||||||
|
|
||||||
|
}
|
||||||
+152
@@ -0,0 +1,152 @@
|
|||||||
|
/**
|
||||||
|
* 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.autoposting.service;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.autoposting.data.AutoPostingData;
|
||||||
|
import org.mifosplatform.accounting.closure.exception.GLClosureNotFoundException;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingEnumerations;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||||
|
import org.mifosplatform.accounting.rule.data.AccountingRuleData;
|
||||||
|
import org.mifosplatform.infrastructure.codes.data.CodeData;
|
||||||
|
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.TenantAwareRoutingDataSource;
|
||||||
|
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||||
|
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||||
|
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||||
|
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||||
|
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 AutoPostingReadPlatformServiceImpl implements AutoPostingReadPlatformService {
|
||||||
|
|
||||||
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AutoPostingReadPlatformServiceImpl(final TenantAwareRoutingDataSource dataSource) {
|
||||||
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class AutoPostingMapper implements RowMapper<AutoPostingData> {
|
||||||
|
|
||||||
|
private final String schemaSql;
|
||||||
|
|
||||||
|
public AutoPostingMapper() {
|
||||||
|
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||||
|
sqlBuilder
|
||||||
|
.append("select autoposting.id as id, autoposting.name as name, autoposting.description as description,")
|
||||||
|
.append(" autoposting.office_id as officeId, office.name as officeName, autoposting.product_type_enum as productTypeEnum,")
|
||||||
|
.append(" autoposting.product_id as productId, autoposting.charge_id as chargeId, autoposting.event as event,")
|
||||||
|
.append(" autoposting.event_attribute as eventAttribute, autoposting.accounting_rule_id as accountingRuleId,")
|
||||||
|
.append(" savingsproduct.name as savingProductName, loanproduct.name as loanProductName,")
|
||||||
|
.append(" charge.name as chargeName, charge.is_penalty as isPenalty,")
|
||||||
|
.append(" event.code_name as eventName, eventAttribute.code_value as eventAttributeName")
|
||||||
|
.append(" accountingRule.debit_account_id as debitAccountId, accountingRule.credit_account_id as creditAccountId")
|
||||||
|
.append(" from acc_auto_posting autoposting left join m_office office on autoposting.office_id=office.id")
|
||||||
|
.append(" left join m_savings_product savingsproduct on autoposting.product_id=savingsproduct.id")
|
||||||
|
.append(" left join m_product_loan loanproduct on autoposting.product_id=loanproduct.id")
|
||||||
|
.append(" left join m_charge charge on autoposting.charge_id=charge.id")
|
||||||
|
.append(" left join m_code event on autoposting.event=event.id")
|
||||||
|
.append(" left join m_code_value eventAttribute on autoposting.event_attribute=eventAttribute.id")
|
||||||
|
.append(" left join acc_accounting_rule accountingRule on autoposting.accounting_rule_id= accountingRule.id");
|
||||||
|
this.schemaSql = sqlBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String schema() {
|
||||||
|
return this.schemaSql;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AutoPostingData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||||
|
|
||||||
|
final Long id = rs.getLong("id");
|
||||||
|
final String name = rs.getString("name");
|
||||||
|
final String description = rs.getString("description");
|
||||||
|
final Long officeId = JdbcSupport.getLong(rs, "officeId");
|
||||||
|
final String officeName = rs.getString("officeName");
|
||||||
|
final int productTypeEnum = rs.getInt("productTypeEnum");
|
||||||
|
final Long productId = JdbcSupport.getLong(rs, "productId");
|
||||||
|
final Long chargeId = JdbcSupport.getLong(rs, "chargeId");
|
||||||
|
final Long accountingRuleId = JdbcSupport.getLong(rs, "accountingRuleId");
|
||||||
|
final Long eventId = JdbcSupport.getLong(rs, "eventId");
|
||||||
|
final Long eventAttributeId = JdbcSupport.getLong(rs, "eventAttributeId");
|
||||||
|
final Long debitAccountId = JdbcSupport.getLong(rs, "debitAccountId");
|
||||||
|
final Long creditAccountId = JdbcSupport.getLong(rs, "creditAccountId");
|
||||||
|
final String savingProductName = rs.getString("savingProductName");
|
||||||
|
final String loanProductName = rs.getString("loanProductName");
|
||||||
|
final String chargeName = rs.getString("chargeName");
|
||||||
|
final String eventName = rs.getString("eventName");
|
||||||
|
final String eventAttributeName = rs.getString("eventAttributeName");
|
||||||
|
final boolean chargeIsPenalty = rs.getBoolean("isPenalty");
|
||||||
|
|
||||||
|
OfficeData officeData = null;
|
||||||
|
if (officeId != null) {
|
||||||
|
officeData = OfficeData.dropdown(officeId, officeName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
SavingsProductData savingsProductData = null;
|
||||||
|
LoanProductData loanProductData = null;
|
||||||
|
|
||||||
|
PortfolioProductType portfolioProductType = PortfolioProductType.fromInt(productTypeEnum);
|
||||||
|
EnumOptionData productType = AccountingEnumerations.portfolioProductType(portfolioProductType);
|
||||||
|
if (portfolioProductType.isLoanProduct() && productId != null) {
|
||||||
|
savingsProductData = SavingsProductData.lookup(productId, savingProductName);
|
||||||
|
} else if (portfolioProductType.isSavingProduct() && productId != null) {
|
||||||
|
loanProductData = LoanProductData.lookup(productId, loanProductName);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChargeData chargeData = null;
|
||||||
|
if (chargeId != null) {
|
||||||
|
chargeData = ChargeData.lookup(chargeId, chargeName, chargeIsPenalty);
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeData event = CodeData.instance(eventId, eventName, true);
|
||||||
|
|
||||||
|
CodeValueData eventAttribute = null;
|
||||||
|
if (eventAttributeId != null) {
|
||||||
|
eventAttribute = CodeValueData.instance(eventAttributeId, eventAttributeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountingRuleData accountingRuleData = new AccountingRuleData(accountingRuleId, debitAccountId, creditAccountId);
|
||||||
|
|
||||||
|
return new AutoPostingData(id, name, description, officeData, productType, loanProductData, savingsProductData, chargeData,
|
||||||
|
event, eventAttribute, accountingRuleData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AutoPostingData> retrieveAllAutoPostingRules() {
|
||||||
|
final AutoPostingMapper rm = new AutoPostingMapper();
|
||||||
|
|
||||||
|
String sql = "select " + rm.schema();
|
||||||
|
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AutoPostingData retrieveAutoPostingRuleById(final long autopostingId) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
final AutoPostingMapper rm = new AutoPostingMapper();
|
||||||
|
final String sql = "select " + rm.schema() + " and glClosure.id = ?";
|
||||||
|
|
||||||
|
final AutoPostingData autoPostingData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { autopostingId });
|
||||||
|
|
||||||
|
return autoPostingData;
|
||||||
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
|
throw new GLClosureNotFoundException(autopostingId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+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.autoposting.service;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
|
||||||
|
public interface AutoPostingWritePlatformService {
|
||||||
|
|
||||||
|
CommandProcessingResult createAutoPostingRule(JsonCommand command);
|
||||||
|
|
||||||
|
CommandProcessingResult updateAutoPostingRule(Long autoPostingId, JsonCommand command);
|
||||||
|
|
||||||
|
CommandProcessingResult deleteAutoPostingRule(Long autoPostingId);
|
||||||
|
|
||||||
|
}
|
||||||
+142
@@ -0,0 +1,142 @@
|
|||||||
|
/**
|
||||||
|
* 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.autoposting.service;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.autoposting.api.AutoPostingJsonInputParams;
|
||||||
|
import org.mifosplatform.accounting.autoposting.exception.AutoPostingDuplicateException;
|
||||||
|
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.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 AutoPostingWritePlatformServiceJpaRepositoryImpl implements AutoPostingWritePlatformService {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(AutoPostingWritePlatformServiceJpaRepositoryImpl.class);
|
||||||
|
|
||||||
|
private final GLClosureRepository glClosureRepository;
|
||||||
|
private final OfficeRepository officeRepository;
|
||||||
|
private final GLClosureCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AutoPostingWritePlatformServiceJpaRepositoryImpl(final GLClosureRepository glClosureRepository,
|
||||||
|
final OfficeRepository officeRepository, final GLClosureCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
|
||||||
|
this.glClosureRepository = glClosureRepository;
|
||||||
|
this.officeRepository = officeRepository;
|
||||||
|
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult createAutoPostingRule(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) {
|
||||||
|
handleAutoPostingIntegrityIssues(command, dve);
|
||||||
|
return CommandProcessingResult.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult updateAutoPostingRule(final Long autoPostingId, final JsonCommand command) {
|
||||||
|
final GLClosureCommand closureCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||||
|
closureCommand.validateForUpdate();
|
||||||
|
|
||||||
|
// is the glClosure valid
|
||||||
|
final GLClosure glClosure = this.glClosureRepository.findOne(autoPostingId);
|
||||||
|
if (glClosure == null) { throw new GLClosureNotFoundException(autoPostingId); }
|
||||||
|
|
||||||
|
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 deleteAutoPostingRule(final Long autoPostingId) {
|
||||||
|
final GLClosure glClosure = this.glClosureRepository.findOne(autoPostingId);
|
||||||
|
|
||||||
|
if (glClosure == null) { throw new GLClosureNotFoundException(autoPostingId); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 handleAutoPostingIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
|
||||||
|
final Throwable realCause = dve.getMostSpecificCause();
|
||||||
|
if (realCause.getMessage().contains("auto_posting_name_unique")) { throw new AutoPostingDuplicateException(
|
||||||
|
command.stringValueOfParameterNamed(AutoPostingJsonInputParams.NAME.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());
|
||||||
|
}
|
||||||
|
}
|
||||||
-4
@@ -44,10 +44,6 @@ public class GLClosure extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
@Column(name = "comments", nullable = true, length = 500)
|
@Column(name = "comments", nullable = true, length = 500)
|
||||||
private String comments;
|
private String comments;
|
||||||
|
|
||||||
public static GLClosure createNew(final Office office, final Date closingDate, final String comments) {
|
|
||||||
return new GLClosure(office, closingDate, comments);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected GLClosure() {
|
protected GLClosure() {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|||||||
-5
@@ -59,11 +59,6 @@ public class GLAccount extends AbstractPersistable<Long> {
|
|||||||
@Column(name = "description", nullable = true, length = 500)
|
@Column(name = "description", nullable = true, length = 500)
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
public static GLAccount createNew(final GLAccount parent, final String name, final String glCode, final boolean disabled,
|
|
||||||
final boolean manualEntriesAllowed, final Integer type, final Integer usage, final String description) {
|
|
||||||
return new GLAccount(parent, name, glCode, disabled, manualEntriesAllowed, type, usage, description);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected GLAccount() {
|
protected GLAccount() {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|||||||
+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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-1
@@ -17,8 +17,9 @@ public interface GLAccountReadPlatformService {
|
|||||||
|
|
||||||
GLAccountData retrieveGLAccountById(long glAccountId);
|
GLAccountData retrieveGLAccountById(long glAccountId);
|
||||||
|
|
||||||
|
List<GLAccountData> retrieveAllEnabledDetailGLAccounts();
|
||||||
|
|
||||||
List<GLAccountData> retrieveAllEnabledDetailGLAccounts(GLAccountType accountType);
|
List<GLAccountData> retrieveAllEnabledDetailGLAccounts(GLAccountType accountType);
|
||||||
|
|
||||||
GLAccountData retrieveNewGLAccountDetails();
|
GLAccountData retrieveNewGLAccountDetails();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -166,6 +166,11 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
|
|||||||
return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.DETAIL.getValue(), null, false);
|
return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.DETAIL.getValue(), null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GLAccountData> retrieveAllEnabledDetailGLAccounts() {
|
||||||
|
return retrieveAllGLAccounts(null, null, GLAccountUsage.DETAIL.getValue(), null, false);
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean checkValidGLAccountType(final int type) {
|
private static boolean checkValidGLAccountType(final int type) {
|
||||||
for (final GLAccountType accountType : GLAccountType.values()) {
|
for (final GLAccountType accountType : GLAccountType.values()) {
|
||||||
if (accountType.getValue().equals(type)) { return true; }
|
if (accountType.getValue().equals(type)) { return true; }
|
||||||
|
|||||||
+1
-1
@@ -56,7 +56,7 @@ public class JournalEntry extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
@Temporal(TemporalType.DATE)
|
@Temporal(TemporalType.DATE)
|
||||||
private Date transactionDate;
|
private Date transactionDate;
|
||||||
|
|
||||||
@Column(name = "type_enum", nullable = false, length = 50)
|
@Column(name = "type_enum", nullable = false)
|
||||||
private Integer type;
|
private Integer type;
|
||||||
|
|
||||||
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
||||||
|
|||||||
+8
@@ -44,4 +44,12 @@ public enum PortfolioProductType {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSavingProduct() {
|
||||||
|
return this.value.equals(PortfolioProductType.SAVING.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLoanProduct() {
|
||||||
|
return this.value.equals(PortfolioProductType.LOAN.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
+148
@@ -0,0 +1,148 @@
|
|||||||
|
/**
|
||||||
|
* 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.rule.api;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
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.glaccount.data.GLAccountData;
|
||||||
|
import org.mifosplatform.accounting.glaccount.service.GLAccountReadPlatformService;
|
||||||
|
import org.mifosplatform.accounting.rule.data.AccountingRuleData;
|
||||||
|
import org.mifosplatform.accounting.rule.service.AccountingRuleReadPlatformService;
|
||||||
|
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.data.OfficeData;
|
||||||
|
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("/accountingrules")
|
||||||
|
@Component
|
||||||
|
@Scope("singleton")
|
||||||
|
public class AccountingRuleApiResource {
|
||||||
|
|
||||||
|
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "officeId", "officeName",
|
||||||
|
"accountToDebitId", "accountToCreditId", "name", "description", "systemDefined"));
|
||||||
|
|
||||||
|
private final String resourceNameForPermission = "ACCOUNTINGRULE";
|
||||||
|
|
||||||
|
private final AccountingRuleReadPlatformService accountingRuleReadPlatformService;
|
||||||
|
private final GLAccountReadPlatformService accountReadPlatformService;
|
||||||
|
private final OfficeReadPlatformService officeReadPlatformService;
|
||||||
|
private final DefaultToApiJsonSerializer<AccountingRuleData> apiJsonSerializerService;
|
||||||
|
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountingRuleApiResource(final PlatformSecurityContext context,
|
||||||
|
final AccountingRuleReadPlatformService accountingRuleReadPlatformService,
|
||||||
|
final DefaultToApiJsonSerializer<AccountingRuleData> toApiJsonSerializer,
|
||||||
|
final ApiRequestParameterHelper apiRequestParameterHelper, final GLAccountReadPlatformService accountReadPlatformService,
|
||||||
|
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||||
|
final OfficeReadPlatformService officeReadPlatformService) {
|
||||||
|
this.context = context;
|
||||||
|
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||||
|
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||||
|
this.apiJsonSerializerService = toApiJsonSerializer;
|
||||||
|
this.accountingRuleReadPlatformService = accountingRuleReadPlatformService;
|
||||||
|
this.officeReadPlatformService = officeReadPlatformService;
|
||||||
|
this.accountReadPlatformService = accountReadPlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String retrieveAllAccountingRules(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId) {
|
||||||
|
|
||||||
|
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
|
||||||
|
final List<AccountingRuleData> accountingRuleDatas = this.accountingRuleReadPlatformService.retrieveAllAccountingRules(officeId);
|
||||||
|
|
||||||
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
|
return this.apiJsonSerializerService.serialize(settings, accountingRuleDatas, RESPONSE_DATA_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{accountingRuleId}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String retreiveAccountingRule(@PathParam("accountingRuleId") final Long accountingRuleId, @Context final UriInfo uriInfo) {
|
||||||
|
|
||||||
|
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
|
||||||
|
|
||||||
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
|
final AccountingRuleData accountingRuleData = this.accountingRuleReadPlatformService.retrieveAccountingRuleById(accountingRuleId);
|
||||||
|
if (settings.isTemplate()) {
|
||||||
|
accountingRuleData.setAllowedOffices(new ArrayList<OfficeData>(this.officeReadPlatformService.retrieveAllOfficesForDropdown()));
|
||||||
|
accountingRuleData.setAllowedAccounts(new ArrayList<GLAccountData>(this.accountReadPlatformService
|
||||||
|
.retrieveAllEnabledDetailGLAccounts()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.apiJsonSerializerService.serialize(settings, accountingRuleData, RESPONSE_DATA_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String createAccountingRule(final String jsonRequestBody) {
|
||||||
|
|
||||||
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().createAccountingRule().withJson(jsonRequestBody).build();
|
||||||
|
|
||||||
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
|
return this.apiJsonSerializerService.serialize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{accountingRuleId}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String updateAccountingRule(@PathParam("accountingRuleId") final Long accountingRuleId, final String jsonRequestBody) {
|
||||||
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateAccountingRule(accountingRuleId).withJson(jsonRequestBody)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
|
return this.apiJsonSerializerService.serialize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{accountingRuleId}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String deleteAccountingRule(@PathParam("accountingRuleId") final Long accountingRuleId) {
|
||||||
|
|
||||||
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteAccountingRule(accountingRuleId).build();
|
||||||
|
|
||||||
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
|
return this.apiJsonSerializerService.serialize(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package org.mifosplatform.accounting.rule.api;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Enum of all parameters passed in while creating/updating a loan product
|
||||||
|
***/
|
||||||
|
public enum AccountingRuleJsonInputParams {
|
||||||
|
ID("id"), OFFICE_ID("officeId"), ACCOUNT_TO_DEBIT("accountToDebitId"), ACCOUNT_TO_CREDIT("accountToCreditId"), NAME("name"), DESCRIPTION(
|
||||||
|
"description"), SYSTEM_DEFINED("systemDefined");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
private AccountingRuleJsonInputParams(final String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Set<String> values = new HashSet<String>();
|
||||||
|
static {
|
||||||
|
for (final AccountingRuleJsonInputParams type : AccountingRuleJsonInputParams.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
+79
@@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* 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.rule.command;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.rule.api.AccountingRuleJsonInputParams;
|
||||||
|
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 AccountingRuleCommand {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long id;
|
||||||
|
private final Long officeId;
|
||||||
|
private final Long accountToDebitId;
|
||||||
|
private final Long accountToCreditId;
|
||||||
|
private final String name;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
public AccountingRuleCommand(Long id, Long officeId, Long accountToDebitId, Long accountToCreditId, String name, String description) {
|
||||||
|
this.id = id;
|
||||||
|
this.officeId = officeId;
|
||||||
|
this.accountToDebitId = accountToDebitId;
|
||||||
|
this.accountToCreditId = accountToCreditId;
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateForCreate() {
|
||||||
|
|
||||||
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
|
|
||||||
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("AccountingRule");
|
||||||
|
|
||||||
|
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue()).value(this.accountToDebitId)
|
||||||
|
.notNull().integerGreaterThanZero();
|
||||||
|
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue()).value(this.accountToCreditId)
|
||||||
|
.notNull().integerGreaterThanZero();
|
||||||
|
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.OFFICE_ID.getValue()).value(this.officeId).ignoreIfNull()
|
||||||
|
.integerGreaterThanZero();
|
||||||
|
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.NAME.getValue()).value(this.name).notBlank()
|
||||||
|
.notExceedingLengthOf(100);
|
||||||
|
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.DESCRIPTION.getValue()).value(this.description).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<ApiParameterError>();
|
||||||
|
|
||||||
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("AccountingRule");
|
||||||
|
|
||||||
|
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue()).value(this.accountToDebitId)
|
||||||
|
.ignoreIfNull().integerGreaterThanZero();
|
||||||
|
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue()).value(this.accountToCreditId)
|
||||||
|
.ignoreIfNull().integerGreaterThanZero();
|
||||||
|
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.OFFICE_ID.getValue()).value(this.officeId).ignoreIfNull()
|
||||||
|
.integerGreaterThanZero();
|
||||||
|
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.NAME.getValue()).value(this.name).ignoreIfNull().notBlank()
|
||||||
|
.notExceedingLengthOf(100);
|
||||||
|
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.DESCRIPTION.getValue()).value(this.description).ignoreIfNull()
|
||||||
|
.notExceedingLengthOf(500);
|
||||||
|
|
||||||
|
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||||
|
"Validation errors exist.", dataValidationErrors); }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Executable
+76
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* 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.rule.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||||
|
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 AccountingRuleData {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long id;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long officeId;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String officeName;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long accountToDebitId;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long accountToCreditId;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String name;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String description;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final boolean systemDefined;
|
||||||
|
|
||||||
|
// template
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private List<OfficeData> allowedOffices = new ArrayList<OfficeData>();
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private List<GLAccountData> allowedAccounts = new ArrayList<GLAccountData>();
|
||||||
|
|
||||||
|
public AccountingRuleData(Long id, Long accountToDebitId, Long accountToCreditId) {
|
||||||
|
this(id, null, null, accountToDebitId, accountToCreditId, null, null, true, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountingRuleData(Long id, Long officeId, String officeName, Long accountToDebitId, Long accountToCreditId, String name,
|
||||||
|
String description, boolean systemDefined) {
|
||||||
|
this(id, officeId, officeName, accountToDebitId, accountToCreditId, name, description, systemDefined, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountingRuleData(Long id, Long officeId, String officeName, Long accountToDebitId, Long accountToCreditId, String name,
|
||||||
|
String description, boolean systemDefined, List<OfficeData> allowedOffices, List<GLAccountData> allowedAccounts) {
|
||||||
|
this.id = id;
|
||||||
|
this.officeId = officeId;
|
||||||
|
this.officeName = officeName;
|
||||||
|
this.accountToDebitId = accountToDebitId;
|
||||||
|
this.accountToCreditId = accountToCreditId;
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.systemDefined = systemDefined;
|
||||||
|
this.allowedOffices = allowedOffices;
|
||||||
|
this.allowedAccounts = allowedAccounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedOffices(List<OfficeData> allowedOffices) {
|
||||||
|
this.allowedOffices = allowedOffices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedAccounts(List<GLAccountData> allowedAccounts) {
|
||||||
|
this.allowedAccounts = allowedAccounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Executable
+150
@@ -0,0 +1,150 @@
|
|||||||
|
/**
|
||||||
|
* 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.rule.domain;
|
||||||
|
|
||||||
|
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.UniqueConstraint;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
||||||
|
import org.mifosplatform.accounting.rule.api.AccountingRuleJsonInputParams;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "acc_accounting_rule", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "accounting_rule_name_unique") })
|
||||||
|
public class AccountingRule extends AbstractPersistable<Long> {
|
||||||
|
|
||||||
|
@Column(name = "name", nullable = false, length = 500)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "office_id", nullable = true)
|
||||||
|
private Office office;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "debit_account_id", nullable = false)
|
||||||
|
private GLAccount accountToDebit;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "credit_account_id", nullable = false)
|
||||||
|
private GLAccount accountToCredit;
|
||||||
|
|
||||||
|
@Column(name = "description", nullable = true, length = 500)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Column(name = "system_defined", nullable = false)
|
||||||
|
private Boolean systemDefined;
|
||||||
|
|
||||||
|
protected AccountingRule() {}
|
||||||
|
|
||||||
|
private AccountingRule(Office office, GLAccount accountToDebit, GLAccount accountToCredit, String name, String description,
|
||||||
|
boolean systemDefined) {
|
||||||
|
this.accountToDebit = accountToDebit;
|
||||||
|
this.accountToCredit = accountToCredit;
|
||||||
|
this.name = name;
|
||||||
|
this.office = office;
|
||||||
|
this.description = StringUtils.defaultIfEmpty(description, null);
|
||||||
|
if (this.description != null) {
|
||||||
|
this.description = this.description.trim();
|
||||||
|
}
|
||||||
|
this.systemDefined = systemDefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AccountingRule fromJson(final Office office, final GLAccount accountToDebit, final GLAccount accountToCredit,
|
||||||
|
JsonCommand command) {
|
||||||
|
final String name = command.stringValueOfParameterNamed(AccountingRuleJsonInputParams.NAME.getValue());
|
||||||
|
final String description = command.stringValueOfParameterNamed(AccountingRuleJsonInputParams.DESCRIPTION.getValue());
|
||||||
|
final boolean systemDefined = false;
|
||||||
|
return new AccountingRule(office, accountToDebit, accountToCredit, name, description, systemDefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> update(final JsonCommand command) {
|
||||||
|
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(5);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.OFFICE_ID.getValue(), 0L);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue(), 0L);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue(), 0L);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.NAME.getValue(), this.name);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.DESCRIPTION.getValue(), this.description);
|
||||||
|
handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.SYSTEM_DEFINED.getValue(), this.systemDefined);
|
||||||
|
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(AccountingRuleJsonInputParams.DESCRIPTION.getValue())) {
|
||||||
|
this.description = newValue;
|
||||||
|
} else if (paramName.equals(AccountingRuleJsonInputParams.NAME.getValue())) {
|
||||||
|
this.name = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(AccountingRuleJsonInputParams.SYSTEM_DEFINED.getValue())) {
|
||||||
|
this.systemDefined = 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(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue())) {
|
||||||
|
// do nothing as this is a nested property
|
||||||
|
} else if (paramName.equals(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue())) {
|
||||||
|
// do nothing as this is a nested property
|
||||||
|
} else if (paramName.equals(AccountingRuleJsonInputParams.OFFICE_ID.getValue())) {
|
||||||
|
// do nothing as this is a nested property
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffice(Office office) {
|
||||||
|
this.office = office;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Office getOffice() {
|
||||||
|
return this.office;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GLAccount getAccountToDebit() {
|
||||||
|
return this.accountToDebit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GLAccount getAccountToCredit() {
|
||||||
|
return this.accountToCredit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountToDebit(GLAccount accountToDebit) {
|
||||||
|
this.accountToDebit = accountToDebit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountToCredit(GLAccount accountToCredit) {
|
||||||
|
this.accountToCredit = accountToCredit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+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.rule.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 AccountingRuleRepository extends JpaRepository<AccountingRule, Long>, JpaSpecificationExecutor<AccountingRule> {
|
||||||
|
|
||||||
|
@Query("from AccountingRule accountingRule where accountingRule.office is null or accountingRule.office.id =:officeId")
|
||||||
|
AccountingRule getAccountingRuleByOfficeId(@Param("officeId") Long officeId);
|
||||||
|
}
|
||||||
+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.rule.domain;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.rule.exception.AccountingRuleNotFoundException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Wrapper for {@link AccountingRuleRepository} .
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class AccountingRuleRepositoryWrapper {
|
||||||
|
|
||||||
|
private final AccountingRuleRepository repository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountingRuleRepositoryWrapper(final AccountingRuleRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountingRule findOneWithNotFoundDetection(final Long id) {
|
||||||
|
final AccountingRule accountingRule = this.repository.findOne(id);
|
||||||
|
if (accountingRule == null) { throw new AccountingRuleNotFoundException(id); }
|
||||||
|
return accountingRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+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.rule.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link RuntimeException} thrown when an Accounting rule with a given name
|
||||||
|
* already exists
|
||||||
|
*/
|
||||||
|
public class AccountingRuleDuplicateException extends AbstractPlatformDomainRuleException {
|
||||||
|
|
||||||
|
public AccountingRuleDuplicateException(String name) {
|
||||||
|
super("error.msg.accounting.rule.duplicate", "An accounting rule with the name " + name + " already exists" + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+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.rule.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 AccountingRuleInvalidDeleteException extends AbstractPlatformDomainRuleException {
|
||||||
|
|
||||||
|
public AccountingRuleInvalidDeleteException(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.rule.exception;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link RuntimeException} thrown when a GL Closure is Invalid
|
||||||
|
*/
|
||||||
|
public class AccountingRuleInvalidException 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 AccountingRuleInvalidException(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.rule.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link RuntimeException} thrown when Accounting rule resources are not
|
||||||
|
* found.
|
||||||
|
*/
|
||||||
|
public class AccountingRuleNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
|
public AccountingRuleNotFoundException(final Long id) {
|
||||||
|
super("error.msg.accounting.rule.id.invalid", "Accounting Rule with identifier " + id + " does not exist", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
+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.rule.handler;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.rule.service.AccountingRuleWritePlatformService;
|
||||||
|
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
|
||||||
|
public class CreateAccountingRuleCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final AccountingRuleWritePlatformService writePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CreateAccountingRuleCommandHandler(final AccountingRuleWritePlatformService writePlatformService) {
|
||||||
|
this.writePlatformService = writePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
return this.writePlatformService.createAccountingRule(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
+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.rule.handler;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.rule.service.AccountingRuleWritePlatformService;
|
||||||
|
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
|
||||||
|
public class DeleteAccountingRuleCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final AccountingRuleWritePlatformService writePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public DeleteAccountingRuleCommandHandler(final AccountingRuleWritePlatformService writePlatformService) {
|
||||||
|
this.writePlatformService = writePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
return this.writePlatformService.deleteAccountingRule(command.entityId());
|
||||||
|
}
|
||||||
|
}
|
||||||
+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.rule.handler;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.rule.service.AccountingRuleWritePlatformService;
|
||||||
|
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
|
||||||
|
public class UpdateAccountingRuleCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final AccountingRuleWritePlatformService writePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UpdateAccountingRuleCommandHandler(final AccountingRuleWritePlatformService writePlatformService) {
|
||||||
|
this.writePlatformService = writePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
return this.writePlatformService.updateAccountingRule(command.entityId(), command);
|
||||||
|
}
|
||||||
|
}
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* 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.rule.serialization;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.mifosplatform.accounting.closure.api.GLClosureJsonInputParams;
|
||||||
|
import org.mifosplatform.accounting.rule.api.AccountingRuleJsonInputParams;
|
||||||
|
import org.mifosplatform.accounting.rule.command.AccountingRuleCommand;
|
||||||
|
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 AccountingRuleCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<AccountingRuleCommand> {
|
||||||
|
|
||||||
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountingRuleCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonfromApiJsonHelper) {
|
||||||
|
this.fromApiJsonHelper = fromApiJsonfromApiJsonHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccountingRuleCommand 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(AccountingRuleJsonInputParams.ID.getValue(), element);
|
||||||
|
final Long officeId = this.fromApiJsonHelper.extractLongNamed(AccountingRuleJsonInputParams.OFFICE_ID.getValue(), element);
|
||||||
|
final Long accountToDebitId = this.fromApiJsonHelper.extractLongNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue(),
|
||||||
|
element);
|
||||||
|
final Long accountToCreditId = this.fromApiJsonHelper.extractLongNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue(),
|
||||||
|
element);
|
||||||
|
final String name = this.fromApiJsonHelper.extractStringNamed(AccountingRuleJsonInputParams.NAME.getValue(), element);
|
||||||
|
final String description = this.fromApiJsonHelper.extractStringNamed(AccountingRuleJsonInputParams.DESCRIPTION.getValue(), element);
|
||||||
|
|
||||||
|
return new AccountingRuleCommand(id, officeId, accountToDebitId, accountToCreditId, name, description);
|
||||||
|
}
|
||||||
|
}
|
||||||
+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.rule.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.rule.data.AccountingRuleData;
|
||||||
|
|
||||||
|
public interface AccountingRuleReadPlatformService {
|
||||||
|
|
||||||
|
List<AccountingRuleData> retrieveAllAccountingRules(Long OfficeId);
|
||||||
|
|
||||||
|
AccountingRuleData retrieveAccountingRuleById(long accountingRuleId);
|
||||||
|
|
||||||
|
}
|
||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* 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.rule.service;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.rule.data.AccountingRuleData;
|
||||||
|
import org.mifosplatform.accounting.rule.exception.AccountingRuleNotFoundException;
|
||||||
|
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||||
|
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||||
|
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 AccountingRuleReadPlatformServiceImpl implements AccountingRuleReadPlatformService {
|
||||||
|
|
||||||
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountingRuleReadPlatformServiceImpl(final TenantAwareRoutingDataSource dataSource) {
|
||||||
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class AccountingRuleMapper implements RowMapper<AccountingRuleData> {
|
||||||
|
|
||||||
|
private final String schemaSql;
|
||||||
|
|
||||||
|
public AccountingRuleMapper() {
|
||||||
|
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||||
|
sqlBuilder.append("select rule.id as id,rule.name as name, rule.office_id as officeId,office.name as officeName,")
|
||||||
|
.append(" rule.debit_account_id as debitAccountId,rule.credit_account_id as creditAccountId,")
|
||||||
|
.append(" rule.description as description, rule.system_defined as systemDefined ").append("from ")
|
||||||
|
.append(" acc_accounting_rule rule left join m_office office on rule.office_id=office.id");
|
||||||
|
this.schemaSql = sqlBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String schema() {
|
||||||
|
return this.schemaSql;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccountingRuleData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||||
|
|
||||||
|
final Long id = rs.getLong("id");
|
||||||
|
final Long officeId = JdbcSupport.getLong(rs, "officeId");
|
||||||
|
final String officeName = rs.getString("officeName");
|
||||||
|
final String name = rs.getString("name");
|
||||||
|
final String description = rs.getString("description");
|
||||||
|
final Long accountToDebitId = rs.getLong("debitAccountId");
|
||||||
|
final Long accountToCreditId = rs.getLong("creditAccountId");
|
||||||
|
final boolean systemDefined = rs.getBoolean("systemDefined");
|
||||||
|
|
||||||
|
return new AccountingRuleData(id, officeId, officeName, accountToDebitId, accountToCreditId, name, description, systemDefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AccountingRuleData> retrieveAllAccountingRules(Long officeId) {
|
||||||
|
final AccountingRuleMapper rm = new AccountingRuleMapper();
|
||||||
|
String sql = "select " + rm.schema() + " where system_defined=0 and office.id = ?";
|
||||||
|
sql = sql + " order by rule.id asc";
|
||||||
|
return this.jdbcTemplate.query(sql, rm, new Object[] { officeId });
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccountingRuleData retrieveAccountingRuleById(long accountingRuleId) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
final AccountingRuleMapper rm = new AccountingRuleMapper();
|
||||||
|
final String sql = "select " + rm.schema() + " and glClosure.id = ?";
|
||||||
|
|
||||||
|
final AccountingRuleData accountingRuleData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { accountingRuleId });
|
||||||
|
return accountingRuleData;
|
||||||
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
|
throw new AccountingRuleNotFoundException(accountingRuleId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+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.rule.service;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
|
||||||
|
public interface AccountingRuleWritePlatformService {
|
||||||
|
|
||||||
|
CommandProcessingResult createAccountingRule(JsonCommand command);
|
||||||
|
|
||||||
|
CommandProcessingResult updateAccountingRule(Long accountingRuleId, JsonCommand command);
|
||||||
|
|
||||||
|
CommandProcessingResult deleteAccountingRule(Long accountingRuleId);
|
||||||
|
|
||||||
|
}
|
||||||
+157
@@ -0,0 +1,157 @@
|
|||||||
|
/**
|
||||||
|
* 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.rule.service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.closure.api.GLClosureJsonInputParams;
|
||||||
|
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
||||||
|
import org.mifosplatform.accounting.glaccount.domain.GLAccountRepositoryWrapper;
|
||||||
|
import org.mifosplatform.accounting.rule.api.AccountingRuleJsonInputParams;
|
||||||
|
import org.mifosplatform.accounting.rule.command.AccountingRuleCommand;
|
||||||
|
import org.mifosplatform.accounting.rule.domain.AccountingRule;
|
||||||
|
import org.mifosplatform.accounting.rule.domain.AccountingRuleRepository;
|
||||||
|
import org.mifosplatform.accounting.rule.domain.AccountingRuleRepositoryWrapper;
|
||||||
|
import org.mifosplatform.accounting.rule.exception.AccountingRuleDuplicateException;
|
||||||
|
import org.mifosplatform.accounting.rule.serialization.AccountingRuleCommandFromApiJsonDeserializer;
|
||||||
|
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 AccountingRuleWritePlatformServiceJpaRepositoryImpl implements AccountingRuleWritePlatformService {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(AccountingRuleWritePlatformServiceJpaRepositoryImpl.class);
|
||||||
|
|
||||||
|
private final AccountingRuleRepositoryWrapper accountingRuleRepositoryWrapper;
|
||||||
|
private final AccountingRuleRepository accountingRuleRepository;
|
||||||
|
private final GLAccountRepositoryWrapper accountRepositoryWrapper;
|
||||||
|
private final OfficeRepository officeRepository;
|
||||||
|
private final AccountingRuleCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountingRuleWritePlatformServiceJpaRepositoryImpl(final AccountingRuleRepositoryWrapper accountingRuleRepositoryWrapper,
|
||||||
|
final GLAccountRepositoryWrapper accountRepositoryWrapper, final OfficeRepository officeRepository,
|
||||||
|
final AccountingRuleCommandFromApiJsonDeserializer fromApiJsonDeserializer, final AccountingRuleRepository ruleRepository) {
|
||||||
|
this.accountRepositoryWrapper = accountRepositoryWrapper;
|
||||||
|
this.officeRepository = officeRepository;
|
||||||
|
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||||
|
this.accountingRuleRepository = ruleRepository;
|
||||||
|
this.accountingRuleRepositoryWrapper = accountingRuleRepositoryWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param command
|
||||||
|
* @param dve
|
||||||
|
*/
|
||||||
|
private void handleAccountingRuleIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
|
||||||
|
final Throwable realCause = dve.getMostSpecificCause();
|
||||||
|
if (realCause.getMessage().contains("accounting_rule_name_unique")) { throw new AccountingRuleDuplicateException(
|
||||||
|
command.stringValueOfParameterNamed(AccountingRuleJsonInputParams.NAME.getValue())); }
|
||||||
|
|
||||||
|
logger.error(dve.getMessage(), dve);
|
||||||
|
throw new PlatformDataIntegrityException("error.msg.accounting.rule.unknown.data.integrity.issue",
|
||||||
|
"Unknown data integrity issue with resource Accounting Rule: " + realCause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult createAccountingRule(JsonCommand command) {
|
||||||
|
try {
|
||||||
|
final AccountingRuleCommand accountingRuleCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||||
|
accountingRuleCommand.validateForCreate();
|
||||||
|
|
||||||
|
// check office is valid
|
||||||
|
final Long officeId = command.longValueOfParameterNamed(GLClosureJsonInputParams.OFFICE_ID.getValue());
|
||||||
|
Office office = null;
|
||||||
|
if (officeId != null) {
|
||||||
|
office = this.officeRepository.findOne(officeId);
|
||||||
|
if (office == null) { throw new OfficeNotFoundException(officeId); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the GL Accounts to Debit and Credit
|
||||||
|
final Long accountToDebitId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue());
|
||||||
|
final Long accountToCreditId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue());
|
||||||
|
final GLAccount accountToDebit = accountRepositoryWrapper.findOneWithNotFoundDetection(accountToDebitId);
|
||||||
|
final GLAccount accountToCredit = accountRepositoryWrapper.findOneWithNotFoundDetection(accountToCreditId);
|
||||||
|
|
||||||
|
final AccountingRule accountingRule = AccountingRule.fromJson(office, accountToDebit, accountToCredit, command);
|
||||||
|
this.accountingRuleRepository.saveAndFlush(accountingRule);
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(officeId)
|
||||||
|
.withEntityId(accountingRule.getId()).build();
|
||||||
|
} catch (final DataIntegrityViolationException dve) {
|
||||||
|
handleAccountingRuleIntegrityIssues(command, dve);
|
||||||
|
return CommandProcessingResult.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult updateAccountingRule(Long accountingRuleId, JsonCommand command) {
|
||||||
|
final AccountingRuleCommand accountingRuleCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||||
|
accountingRuleCommand.validateForUpdate();
|
||||||
|
|
||||||
|
Long officeId = null;
|
||||||
|
if (command.parameterExists(AccountingRuleJsonInputParams.OFFICE_ID.getValue())) {
|
||||||
|
officeId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.OFFICE_ID.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
Long accountToDebitId = null;
|
||||||
|
if (command.parameterExists(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue())) {
|
||||||
|
accountToDebitId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
Long accountToCreditId = null;
|
||||||
|
if (command.parameterExists(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue())) {
|
||||||
|
accountToCreditId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
final AccountingRule accountingRule = this.accountingRuleRepositoryWrapper.findOneWithNotFoundDetection(accountingRuleId);
|
||||||
|
final Map<String, Object> changesOnly = accountingRule.update(command);
|
||||||
|
|
||||||
|
if (changesOnly.containsKey(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue())) {
|
||||||
|
final GLAccount accountToDebit = accountRepositoryWrapper.findOneWithNotFoundDetection(accountToDebitId);
|
||||||
|
accountingRule.setAccountToDebit(accountToDebit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changesOnly.containsKey(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue())) {
|
||||||
|
final GLAccount accountToCredit = accountRepositoryWrapper.findOneWithNotFoundDetection(accountToCreditId);
|
||||||
|
accountingRule.setAccountToCredit(accountToCredit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changesOnly.containsKey(AccountingRuleJsonInputParams.OFFICE_ID.getValue())) {
|
||||||
|
final Office userOffice = this.officeRepository.findOne(officeId);
|
||||||
|
if (userOffice == null) { throw new OfficeNotFoundException(officeId); }
|
||||||
|
accountingRule.setOffice(userOffice);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!changesOnly.isEmpty()) {
|
||||||
|
this.accountingRuleRepository.saveAndFlush(accountingRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(accountingRule.getId())
|
||||||
|
.with(changesOnly).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult deleteAccountingRule(Long accountingRuleId) {
|
||||||
|
final AccountingRule accountingRule = this.accountingRuleRepositoryWrapper.findOneWithNotFoundDetection(accountingRuleId);
|
||||||
|
this.accountingRuleRepository.delete(accountingRule);
|
||||||
|
return new CommandProcessingResultBuilder().withEntityId(accountingRule.getId()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
@@ -932,4 +932,28 @@ public class CommandWrapperBuilder {
|
|||||||
this.href = "/centers/" + centerId + "?command=activate";
|
this.href = "/centers/" + centerId + "?command=activate";
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder createAccountingRule() {
|
||||||
|
this.actionName = "CREATE";
|
||||||
|
this.entityName = "ACCOUNTINGRULE";
|
||||||
|
this.entityId = null;
|
||||||
|
this.href = "/accountingrules/template";
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder updateAccountingRule(final Long accountingRuleId) {
|
||||||
|
this.actionName = "UPDATE";
|
||||||
|
this.entityName = "ACCOUNTINGRULE";
|
||||||
|
this.entityId = accountingRuleId;
|
||||||
|
this.href = "/accountingrules/" + accountingRuleId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder deleteAccountingRule(final Long accountingRuleId) {
|
||||||
|
this.actionName = "DELETE";
|
||||||
|
this.entityName = "ACCOUNTINGRULE";
|
||||||
|
this.entityId = accountingRuleId;
|
||||||
|
this.href = "/accountingrules/" + accountingRuleId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+16
@@ -53,6 +53,22 @@ public class ChargeData implements Comparable<ChargeData> {
|
|||||||
null, null, null);
|
null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ChargeData lookup(final Long id, final String name, final boolean isPenalty) {
|
||||||
|
BigDecimal amount = null;
|
||||||
|
CurrencyData currency = null;
|
||||||
|
EnumOptionData chargeTimeType = null;
|
||||||
|
EnumOptionData chargeAppliesTo = null;
|
||||||
|
EnumOptionData chargeCalculationType = null;
|
||||||
|
Boolean penalty = isPenalty;
|
||||||
|
Boolean active = false;
|
||||||
|
Collection<CurrencyData> currencyOptions = null;
|
||||||
|
List<EnumOptionData> chargeCalculationTypeOptions = null;
|
||||||
|
List<EnumOptionData> chargeAppliesToOptions = null;
|
||||||
|
List<EnumOptionData> chargeTimeTypeOptions = null;
|
||||||
|
return new ChargeData(id, name, amount, currency, chargeTimeType, chargeAppliesTo, chargeCalculationType, penalty, active,
|
||||||
|
currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions, chargeTimeTypeOptions);
|
||||||
|
}
|
||||||
|
|
||||||
private ChargeData(final Long id, final String name, final BigDecimal amount, final CurrencyData currency,
|
private ChargeData(final Long id, final String name, final BigDecimal amount, final CurrencyData currency,
|
||||||
final EnumOptionData chargeTimeType, final EnumOptionData chargeAppliesTo, final EnumOptionData chargeCalculationType,
|
final EnumOptionData chargeTimeType, final EnumOptionData chargeAppliesTo, final EnumOptionData chargeCalculationType,
|
||||||
final boolean penalty, final boolean active, final Collection<CurrencyData> currencyOptions,
|
final boolean penalty, final boolean active, final Collection<CurrencyData> currencyOptions,
|
||||||
|
|||||||
Reference in New Issue
Block a user