Defining accounting rule with Tagged Accounts

Formatting the white spaces
This commit is contained in:
mifoscontributer
2013-05-28 11:52:16 +05:30
parent 94150b91ad
commit 2d4050de12
13 changed files with 624 additions and 153 deletions
@@ -0,0 +1,11 @@
create table `acc_rule_tags` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`acc_rule_id` BIGINT(20) NOT NULL,
`tag_id` INT(11) NOT NULL,
`acc_type_enum` SMALLINT(5) NOT NULL,
primary key(`id`),
INDEX `FK_acc_accounting_rule_id` (`acc_rule_id`),
INDEX `FK_m_code_value_id` (`tag_id`),
CONSTRAINT `FK_acc_accounting_rule_id` FOREIGN KEY (`acc_rule_id`) REFERENCES `acc_accounting_rule` (`id`),
CONSTRAINT `FK_m_code_value_id` FOREIGN KEY (`tag_id`) REFERENCES `m_code_value` (`id`)
);
@@ -112,7 +112,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
validateGLAccountForTransaction(creditAccountHead);
final GLAccount debitAccountHead = accountingRule.getAccountToDebit();
validateGLAccountForTransaction(debitAccountHead);
String description = accountingRule.getDescription();
String description = null;
if (StringUtils.isNotBlank(journalEntryCommand.getComments())) {
description = journalEntryCommand.getComments();
}
@@ -6,6 +6,7 @@
package org.mifosplatform.accounting.rule.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -23,6 +24,7 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.mifosplatform.accounting.common.AccountingConstants;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.glaccount.service.GLAccountReadPlatformService;
import org.mifosplatform.accounting.rule.data.AccountingRuleData;
@@ -30,6 +32,8 @@ import org.mifosplatform.accounting.rule.service.AccountingRuleReadPlatformServi
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
@@ -47,7 +51,9 @@ import org.springframework.stereotype.Component;
public class AccountingRuleApiResource {
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "officeId", "officeName",
"accountToDebitId", "accountToCreditId", "name", "description", "systemDefined"));
"accountToDebitId", "accountToCreditId", "name", "description", "systemDefined", "allowedAssetsTagOptions",
"allowedLiabilitiesTagOptions", "allowedEquityTagOptions", "allowedIncomeTagOptions", "allowedExpensesTagOptions", "debitTags",
"creditTags"));
private final String resourceNameForPermission = "ACCOUNTINGRULE";
@@ -58,6 +64,7 @@ public class AccountingRuleApiResource {
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PlatformSecurityContext context;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
@Autowired
public AccountingRuleApiResource(final PlatformSecurityContext context,
@@ -65,7 +72,7 @@ public class AccountingRuleApiResource {
final DefaultToApiJsonSerializer<AccountingRuleData> toApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper, final GLAccountReadPlatformService accountReadPlatformService,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final OfficeReadPlatformService officeReadPlatformService) {
final OfficeReadPlatformService officeReadPlatformService, final CodeValueReadPlatformService codeValueReadPlatformService) {
this.context = context;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -73,22 +80,23 @@ public class AccountingRuleApiResource {
this.accountingRuleReadPlatformService = accountingRuleReadPlatformService;
this.officeReadPlatformService = officeReadPlatformService;
this.accountReadPlatformService = accountReadPlatformService;
this.codeValueReadPlatformService = codeValueReadPlatformService;
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermission);
AccountingRuleData accountingRuleData = null;
accountingRuleData = handleTemplate(accountingRuleData);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.apiJsonSerializerService.serialize(settings, accountingRuleData, RESPONSE_DATA_PARAMETERS);
}
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
AccountingRuleData accountingRuleData = null;
accountingRuleData = handleTemplate(accountingRuleData);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.apiJsonSerializerService.serialize(settings, accountingRuleData, RESPONSE_DATA_PARAMETERS);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@@ -114,7 +122,7 @@ public class AccountingRuleApiResource {
AccountingRuleData accountingRuleData = this.accountingRuleReadPlatformService.retrieveAccountingRuleById(accountingRuleId);
if (settings.isTemplate()) {
accountingRuleData = handleTemplate(accountingRuleData);
accountingRuleData = handleTemplate(accountingRuleData);
}
return this.apiJsonSerializerService.serialize(settings, accountingRuleData, RESPONSE_DATA_PARAMETERS);
@@ -157,13 +165,31 @@ public class AccountingRuleApiResource {
return this.apiJsonSerializerService.serialize(result);
}
private AccountingRuleData handleTemplate(AccountingRuleData accountingRuleData) {
List<GLAccountData> allowedAccounts = this.accountReadPlatformService.retrieveAllEnabledDetailGLAccounts();
List<OfficeData> allowedOffices = (List<OfficeData>) this.officeReadPlatformService.retrieveAllOfficesForDropdown();
if (accountingRuleData == null) {
return new AccountingRuleData(allowedAccounts, allowedOffices);
}
return new AccountingRuleData(accountingRuleData, allowedAccounts, allowedOffices);
}
private AccountingRuleData handleTemplate(final AccountingRuleData accountingRuleData) {
final List<GLAccountData> allowedAccounts = this.accountReadPlatformService.retrieveAllEnabledDetailGLAccounts();
final List<OfficeData> allowedOffices = (List<OfficeData>) this.officeReadPlatformService.retrieveAllOfficesForDropdown();
final Collection<CodeValueData> allowedAssetsTagOptions = defaultIfEmpty(this.codeValueReadPlatformService
.retrieveCodeValuesByCode(AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME));
final Collection<CodeValueData> allowedLiabilitiesTagOptions = defaultIfEmpty(this.codeValueReadPlatformService
.retrieveCodeValuesByCode(AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME));
final Collection<CodeValueData> allowedEquityTagOptions = defaultIfEmpty(this.codeValueReadPlatformService
.retrieveCodeValuesByCode(AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME));
final Collection<CodeValueData> allowedIncomeTagOptions = defaultIfEmpty(this.codeValueReadPlatformService
.retrieveCodeValuesByCode(AccountingConstants.INCOME_TAG_OPTION_CODE_NAME));
final Collection<CodeValueData> allowedExpensesTagOptions = defaultIfEmpty(this.codeValueReadPlatformService
.retrieveCodeValuesByCode(AccountingConstants.EXPENSES_TAG_OPTION_CODE_NAME));
if (accountingRuleData == null) { return new AccountingRuleData(allowedAccounts, allowedOffices, allowedAssetsTagOptions,
allowedLiabilitiesTagOptions, allowedEquityTagOptions, allowedIncomeTagOptions, allowedExpensesTagOptions); }
return new AccountingRuleData(accountingRuleData, allowedAccounts, allowedOffices, allowedAssetsTagOptions,
allowedLiabilitiesTagOptions, allowedEquityTagOptions, allowedIncomeTagOptions, allowedExpensesTagOptions);
}
private Collection<CodeValueData> defaultIfEmpty(final Collection<CodeValueData> collection) {
Collection<CodeValueData> returnCollection = null;
if (collection != null && !collection.isEmpty()) {
returnCollection = collection;
}
return returnCollection;
}
}
@@ -13,7 +13,7 @@ import java.util.Set;
***/
public enum AccountingRuleJsonInputParams {
ID("id"), OFFICE_ID("officeId"), ACCOUNT_TO_DEBIT("debitAccountHead"), ACCOUNT_TO_CREDIT("creditAccountHead"), NAME("name"), DESCRIPTION(
"description"), SYSTEM_DEFINED("systemDefined");
"description"), SYSTEM_DEFINED("systemDefined"), DEBIT_ACCOUNT_TAGS("debitTags"), CREDIT_ACCOUNT_TAGS("creditTags");
private final String value;
@@ -6,9 +6,11 @@
package org.mifosplatform.accounting.rule.data;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
import org.mifosplatform.organisation.office.data.OfficeData;
/**
@@ -19,85 +21,127 @@ import org.mifosplatform.organisation.office.data.OfficeData;
*/
public class AccountingRuleData {
private final Long id;
private final Long officeId;
private final String officeName;
private final String name;
private final String description;
private final boolean systemDefined;
private final GLAccountData debitAccountHead;
private final GLAccountData creditAccountHead;
private final Long id;
private final Long officeId;
private final String officeName;
private final String name;
private final String description;
private final boolean systemDefined;
private final GLAccountData debitAccountHead;
private final GLAccountData creditAccountHead;
private final List<AccountingTagRuleData> creditTags;
private final List<AccountingTagRuleData> debitTags;
// template
@SuppressWarnings("unused")
private List<OfficeData> allowedOffices = new ArrayList<OfficeData>();
@SuppressWarnings("unused")
private List<GLAccountData> allowedAccounts = new ArrayList<GLAccountData>();
// template
private List<OfficeData> allowedOffices = new ArrayList<OfficeData>();
private List<GLAccountData> allowedAccounts = new ArrayList<GLAccountData>();
private final Collection<CodeValueData> allowedAssetsTagOptions;
private final Collection<CodeValueData> allowedLiabilitiesTagOptions;
private final Collection<CodeValueData> allowedEquityTagOptions;
private final Collection<CodeValueData> allowedIncomeTagOptions;
private final Collection<CodeValueData> allowedExpensesTagOptions;
/*public AccountingRuleData(final Long id, final Long accountToDebitId, final Long accountToCreditId) {
this(id, null, null, accountToDebitId, accountToCreditId, null, null, true, null, null, null, null, null, null);
}*/
public AccountingRuleData(final AccountingRuleData accountingRuleData, final List<GLAccountData> allowedAccounts,
final List<OfficeData> allowedOffices, final Collection<CodeValueData> allowedAssetsTagOptions,
final Collection<CodeValueData> allowedLiabilitiesTagOptions, final Collection<CodeValueData> allowedEquityTagOptions,
final Collection<CodeValueData> allowedIncomeTagOptions, final Collection<CodeValueData> allowedExpensesTagOptions) {
this.id = accountingRuleData.id;
this.officeId = accountingRuleData.officeId;
this.officeName = accountingRuleData.officeName;
this.name = accountingRuleData.name;
this.description = accountingRuleData.description;
this.systemDefined = accountingRuleData.systemDefined;
this.allowedOffices = allowedOffices;
this.allowedAccounts = allowedAccounts;
this.debitAccountHead = accountingRuleData.debitAccountHead;
this.creditAccountHead = accountingRuleData.creditAccountHead;
this.allowedAssetsTagOptions = allowedAssetsTagOptions;
this.allowedLiabilitiesTagOptions = allowedLiabilitiesTagOptions;
this.allowedEquityTagOptions = allowedEquityTagOptions;
this.allowedIncomeTagOptions = allowedIncomeTagOptions;
this.allowedExpensesTagOptions = allowedExpensesTagOptions;
this.creditTags = accountingRuleData.creditTags;
this.debitTags = accountingRuleData.debitTags;
}
/*public AccountingRuleData(final Long id, final Long officeId, final String officeName, final Long accountToDebitId,
final Long accountToCreditId, final String name, final String description, final boolean systemDefined,
final String debitAccountName, final String creditAccountName, final String debitAccountGLCode,
final String creditAccountGLCode) {
this(id, officeId, officeName, accountToDebitId, accountToCreditId, name, description, systemDefined, debitAccountName,
creditAccountName, debitAccountGLCode, creditAccountGLCode, null, null);
}*/
public AccountingRuleData(final List<GLAccountData> allowedAccounts, final List<OfficeData> allowedOffices,
final Collection<CodeValueData> allowedAssetsTagOptions, final Collection<CodeValueData> allowedLiabilitiesTagOptions,
final Collection<CodeValueData> allowedEquityTagOptions, final Collection<CodeValueData> allowedIncomeTagOptions,
final Collection<CodeValueData> allowedExpensesTagOptions) {
this.id = null;
this.officeId = null;
this.officeName = null;
this.name = null;
this.description = null;
this.systemDefined = false;
this.allowedOffices = allowedOffices;
this.allowedAccounts = allowedAccounts;
this.debitAccountHead = null;
this.creditAccountHead = null;
this.allowedAssetsTagOptions = allowedAssetsTagOptions;
this.allowedLiabilitiesTagOptions = allowedLiabilitiesTagOptions;
this.allowedEquityTagOptions = allowedEquityTagOptions;
this.allowedIncomeTagOptions = allowedIncomeTagOptions;
this.allowedExpensesTagOptions = allowedExpensesTagOptions;
this.creditTags = null;
this.debitTags = null;
}
public AccountingRuleData(final Long id, final Long officeId, final String officeName, final String name, final String description,
final boolean systemDefined, final List<OfficeData> allowedOffices, final List<GLAccountData> allowedAccounts) {
this.id = id;
this.officeId = officeId;
this.officeName = officeName;
this.name = name;
this.description = description;
this.systemDefined = systemDefined;
this.allowedOffices = allowedOffices;
this.allowedAccounts = allowedAccounts;
this.debitAccountHead = null;
this.creditAccountHead = null;
}
public AccountingRuleData(final Long id, final Long officeId, final String officeName, final String name, final String description,
final boolean systemDefined, final GLAccountData debitAccountData, final GLAccountData creditAccountData) {
this.id = id;
this.officeId = officeId;
this.officeName = officeName;
this.name = name;
this.description = description;
this.systemDefined = systemDefined;
this.allowedOffices = null;
this.allowedAccounts = null;
this.debitAccountHead = debitAccountData;
this.creditAccountHead = creditAccountData;
this.allowedAssetsTagOptions = null;
this.allowedLiabilitiesTagOptions = null;
this.allowedEquityTagOptions = null;
this.allowedIncomeTagOptions = null;
this.allowedExpensesTagOptions = null;
this.creditTags = null;
this.debitTags = null;
}
public AccountingRuleData(final AccountingRuleData accountingRuleData,
final List<GLAccountData> allowedAccounts, final List<OfficeData> allowedOffices) {
this.id = accountingRuleData.id;
this.officeId = accountingRuleData.officeId;
this.officeName = accountingRuleData.officeName;
this.name = accountingRuleData.name;
this.description = accountingRuleData.description;
this.systemDefined = accountingRuleData.systemDefined;
this.allowedOffices = allowedOffices;
this.allowedAccounts = allowedAccounts;
this.debitAccountHead = accountingRuleData.debitAccountHead;
this.creditAccountHead = accountingRuleData.creditAccountHead;
}
public AccountingRuleData(final AccountingRuleData accountingRuleData, final List<AccountingTagRuleData> creditTags,
final List<AccountingTagRuleData> debitTags) {
this.id = accountingRuleData.id;
this.officeId = accountingRuleData.officeId;
this.officeName = accountingRuleData.officeName;
this.name = accountingRuleData.name;
this.description = accountingRuleData.description;
this.systemDefined = accountingRuleData.systemDefined;
this.allowedOffices = accountingRuleData.allowedOffices;
this.allowedAccounts = accountingRuleData.allowedAccounts;
this.debitAccountHead = accountingRuleData.debitAccountHead;
this.creditAccountHead = accountingRuleData.creditAccountHead;
this.allowedAssetsTagOptions = accountingRuleData.allowedAssetsTagOptions;
this.allowedLiabilitiesTagOptions = accountingRuleData.allowedLiabilitiesTagOptions;
this.allowedEquityTagOptions = accountingRuleData.allowedEquityTagOptions;
this.allowedIncomeTagOptions = accountingRuleData.allowedIncomeTagOptions;
this.allowedExpensesTagOptions = accountingRuleData.allowedExpensesTagOptions;
this.creditTags = creditTags;
this.debitTags = debitTags;
}
public AccountingRuleData(final List<GLAccountData> allowedAccounts, final List<OfficeData> allowedOffices) {
this.id = null;
this.officeId = null;
this.officeName = null;
this.name = null;
this.description = null;
this.systemDefined = false;
this.allowedOffices = allowedOffices;
this.allowedAccounts = allowedAccounts;
this.debitAccountHead = null;
this.creditAccountHead = null;
}
public GLAccountData getDebitAccountHead() {
return this.debitAccountHead;
}
public AccountingRuleData(Long id, Long officeId, String officeName, String name, String description,
boolean systemDefined, GLAccountData debitAccountData, GLAccountData creditAccountData) {
this.id = id;
this.officeId = officeId;
this.officeName = officeName;
this.name = name;
this.description = description;
this.systemDefined = systemDefined;
this.allowedOffices = null;
this.allowedAccounts = null;
this.debitAccountHead = debitAccountData;
this.creditAccountHead = creditAccountData;
}
public GLAccountData getCreditAccountHead() {
return this.creditAccountHead;
}
public List<AccountingTagRuleData> getCreditTags() {
return this.creditTags;
}
public List<AccountingTagRuleData> getDebitTags() {
return this.debitTags;
}
}
@@ -0,0 +1,20 @@
package org.mifosplatform.accounting.rule.data;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
public class AccountingTagRuleData {
@SuppressWarnings("unused")
private final Long id;
@SuppressWarnings("unused")
private final Long tagId;
@SuppressWarnings("unused")
private final EnumOptionData transactionType;
public AccountingTagRuleData(final Long id, final Long tagId, final EnumOptionData transactionType) {
this.id = id;
this.tagId = tagId;
this.transactionType = transactionType;
}
}
@@ -5,17 +5,23 @@
*/
package org.mifosplatform.accounting.rule.domain;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
import org.mifosplatform.accounting.rule.api.AccountingRuleJsonInputParams;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
@@ -34,11 +40,11 @@ public class AccountingRule extends AbstractPersistable<Long> {
private Office office;
@ManyToOne
@JoinColumn(name = "debit_account_id", nullable = false)
@JoinColumn(name = "debit_account_id", nullable = true)
private GLAccount accountToDebit;
@ManyToOne
@JoinColumn(name = "credit_account_id", nullable = false)
@JoinColumn(name = "credit_account_id", nullable = true)
private GLAccount accountToCredit;
@Column(name = "description", nullable = true, length = 500)
@@ -46,6 +52,11 @@ public class AccountingRule extends AbstractPersistable<Long> {
@Column(name = "system_defined", nullable = false)
private Boolean systemDefined;
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "accountingRule", orphanRemoval = true)
private List<AccountingTagRule> accountingTagRules = new ArrayList<AccountingTagRule>();
protected AccountingRule() {}
@@ -151,4 +162,12 @@ public class AccountingRule extends AbstractPersistable<Long> {
return this.description;
}
public List<AccountingTagRule> updateAccountingRuleForTags(List<AccountingTagRule> debitAccountingTagRules) {
for(AccountingTagRule accountingTagRule : debitAccountingTagRules){
accountingTagRule.updateAccountingTagRule(this);
this.accountingTagRules.add(accountingTagRule);
}
return debitAccountingTagRules;
}
}
@@ -0,0 +1,40 @@
package org.mifosplatform.accounting.rule.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "acc_rule_tags")
public class AccountingTagRule extends AbstractPersistable<Long> {
@ManyToOne
@JoinColumn(name = "acc_rule_id", nullable = false)
private AccountingRule accountingRule;
@ManyToOne
@JoinColumn(name = "tag_id", nullable = false)
private final CodeValue tagId;
@Column(name = "acc_type_enum", nullable = false)
private final Integer accountType;
public static AccountingTagRule create(final CodeValue tagId, final Integer accountType) {
return new AccountingTagRule(tagId, accountType);
}
public AccountingTagRule(final CodeValue tagId, final Integer accountType) {
this.tagId = tagId;
this.accountType = accountType;
}
public void updateAccountingTagRule(final AccountingRule accountingRule) {
this.accountingRule = accountingRule;
}
}
@@ -55,7 +55,8 @@ public final class AccountingRuleCommandFromApiJsonDeserializer extends Abstract
element);
final String name = this.fromApiJsonHelper.extractStringNamed(AccountingRuleJsonInputParams.NAME.getValue(), element);
final String description = this.fromApiJsonHelper.extractStringNamed(AccountingRuleJsonInputParams.DESCRIPTION.getValue(), element);
final String[] creditTags = this.fromApiJsonHelper.extractArrayNamed(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue(), element);
final String[] debitTags = this.fromApiJsonHelper.extractArrayNamed(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue(), element);
return new AccountingRuleCommand(id, officeId, accountToDebitId, accountToCreditId, name, description);
}
}
@@ -0,0 +1,147 @@
package org.mifosplatform.accounting.rule.service;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.accounting.rule.api.AccountingRuleJsonInputParams;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
@Component
public class AccountingRuleDataValidator {
/**
* The parameters supported for this command.
*/
private final Set<String> supportedParameters = AccountingRuleJsonInputParams.getAllValues();
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public AccountingRuleDataValidator(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateForCreate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("AccountingRule");
final JsonElement element = this.fromApiJsonHelper.parse(json);
final Long accountToDebitId = this.fromApiJsonHelper.extractLongNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue(),
element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue()).value(accountToDebitId)
.ignoreIfNull().integerGreaterThanZero();
final Long accountToCreditId = this.fromApiJsonHelper.extractLongNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue(),
element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue()).value(accountToCreditId)
.ignoreIfNull().integerGreaterThanZero();
final Long officeId = this.fromApiJsonHelper.extractLongNamed(AccountingRuleJsonInputParams.OFFICE_ID.getValue(), element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.OFFICE_ID.getValue()).value(officeId).ignoreIfNull()
.integerGreaterThanZero();
final String name = this.fromApiJsonHelper.extractStringNamed(AccountingRuleJsonInputParams.NAME.getValue(), element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.NAME.getValue()).value(name).notBlank().notExceedingLengthOf(100);
final String description = this.fromApiJsonHelper.extractStringNamed(AccountingRuleJsonInputParams.DESCRIPTION.getValue(), element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.DESCRIPTION.getValue()).value(description).ignoreIfNull()
.notExceedingLengthOf(500);
final String[] creditTags = this.fromApiJsonHelper.extractArrayNamed(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue(),
element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue()).value(creditTags).ignoreIfNull()
.arrayNotEmpty();
validateCreditOrDebitTagArray(creditTags, baseDataValidator, AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue());
final String[] debitTags = this.fromApiJsonHelper.extractArrayNamed(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue(),
element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue()).value(debitTags).ignoreIfNull()
.arrayNotEmpty();
validateCreditOrDebitTagArray(debitTags, baseDataValidator, AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue());
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
public void validateCreditOrDebitTagArray(final String[] creditOrDebitTagArray, final DataValidatorBuilder baseDataValidator,
final String parameter) {
if (creditOrDebitTagArray != null && !ObjectUtils.isEmpty(creditOrDebitTagArray)) {
for (final String tag : creditOrDebitTagArray) {
baseDataValidator.reset().parameter(parameter).value(tag).ignoreIfNull().notBlank().longGreaterThanZero();
}
}
}
public void validateForUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("AccountingRule");
final JsonElement element = this.fromApiJsonHelper.parse(json);
final Long accountToDebitId = this.fromApiJsonHelper.extractLongNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue(),
element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue()).value(accountToDebitId)
.ignoreIfNull().notBlank().integerGreaterThanZero();
final Long accountToCreditId = this.fromApiJsonHelper.extractLongNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue(),
element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue()).value(accountToCreditId)
.ignoreIfNull().notBlank().integerGreaterThanZero();
final Long officeId = this.fromApiJsonHelper.extractLongNamed(AccountingRuleJsonInputParams.OFFICE_ID.getValue(), element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.OFFICE_ID.getValue()).value(officeId).ignoreIfNull()
.integerGreaterThanZero();
final String name = this.fromApiJsonHelper.extractStringNamed(AccountingRuleJsonInputParams.NAME.getValue(), element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.NAME.getValue()).value(name).ignoreIfNull().notBlank()
.notExceedingLengthOf(100);
final String description = this.fromApiJsonHelper.extractStringNamed(AccountingRuleJsonInputParams.DESCRIPTION.getValue(), element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.DESCRIPTION.getValue()).value(description).ignoreIfNull()
.notExceedingLengthOf(500);
final String[] creditTags = this.fromApiJsonHelper.extractArrayNamed(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue(),
element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue()).value(creditTags).ignoreIfNull()
.arrayNotEmpty();
validateCreditOrDebitTagArray(creditTags, baseDataValidator, AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue());
final String[] debitTags = this.fromApiJsonHelper.extractArrayNamed(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue(),
element);
baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue()).value(debitTags).ignoreIfNull()
.arrayNotEmpty();
validateCreditOrDebitTagArray(debitTags, baseDataValidator, AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue());
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
}
@@ -13,6 +13,6 @@ public interface AccountingRuleReadPlatformService {
List<AccountingRuleData> retrieveAllAccountingRules(Long OfficeId);
AccountingRuleData retrieveAccountingRuleById(long accountingRuleId);
AccountingRuleData retrieveAccountingRuleById(Long accountingRuleId);
}
@@ -7,16 +7,25 @@ package org.mifosplatform.accounting.rule.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.mifosplatform.accounting.common.AccountingEnumerations;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
import org.mifosplatform.accounting.rule.data.AccountingRuleData;
import org.mifosplatform.accounting.rule.data.AccountingTagRuleData;
import org.mifosplatform.accounting.rule.exception.AccountingRuleNotFoundException;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
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.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@@ -30,13 +39,15 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
private static final class AccountingRuleMapper implements RowMapper<AccountingRuleData> {
// Will remove the old one if everything goes well.
/* private static final class AccountingRuleMapper implements RowMapper<AccountingRuleData> {
private final String schemaSql;
public AccountingRuleMapper() {
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder.append("distinct rule.id as id,rule.name as name, rule.office_id as officeId,office.name as officeName,")
sqlBuilder
.append("distinct 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("debitAccount.glName as debitAccountName, debitAccount.glCode as debitAccountGLCode,")
@@ -46,7 +57,7 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead
.append("(Select gl.id as id,gl.name as glName, gl.gl_code as glCode from acc_gl_account gl,acc_accounting_rule rule ")
.append("where gl.id=rule.credit_account_id ) as creditAccount,")
.append("acc_accounting_rule rule left join m_office office on rule.office_id=office.id ")
.append("where debitAccount.id=rule.debit_account_id and creditAccount.id = rule.credit_account_id");
.append("where debitAccount.id=rule.debit_account_id and creditAccount.id = rule.credit_account_id");
this.schemaSql = sqlBuilder.toString();
}
@@ -66,41 +77,137 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead
final Long accountToCreditId = rs.getLong("creditAccountId");
final boolean systemDefined = rs.getBoolean("systemDefined");
final String debitAccountName = rs.getString("debitAccountName");
final String creditAccountName = rs.getString("creditAccountName");
final String debitAccountGLCode = rs.getString("debitAccountGLCode");
final String creditAccountGLCode = rs.getString("creditAccountGLCode");
final GLAccountData debitAccountData = new GLAccountData(accountToDebitId, debitAccountName, debitAccountGLCode);
final GLAccountData creditAccountData = new GLAccountData(accountToCreditId, creditAccountName, creditAccountGLCode);
final String creditAccountName = rs.getString("creditAccountName");
final String debitAccountGLCode = rs.getString("debitAccountGLCode");
final String creditAccountGLCode = rs.getString("creditAccountGLCode");
final GLAccountData debitAccountData = new GLAccountData(accountToDebitId, debitAccountName, debitAccountGLCode);
final GLAccountData creditAccountData = new GLAccountData(accountToCreditId, creditAccountName, creditAccountGLCode);
return new AccountingRuleData(id, officeId, officeName, name, description, systemDefined, debitAccountData, creditAccountData);
}
}
}*/
@Override
public List<AccountingRuleData> retrieveAllAccountingRules(Long officeId) {
final AccountingRuleMapper rm = new AccountingRuleMapper();
Object[] arguments = new Object[]{};
String sql = "select " + rm.schema() +" and system_defined=0 ";
if(officeId != null) {
sql = sql +" and office.id = ?";
arguments = new Object[] { officeId };
private static final class AccountingRuleDataExtractor implements ResultSetExtractor<Object> {
private final String schemaSql;
private final JdbcTemplate jdbcTemplate;
public AccountingRuleDataExtractor(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder
.append(" rule.id as id,rule.name as name, rule.office_id as officeId,office.name as officeName,")
.append(" rule.description as description, rule.system_defined as systemDefined, ")
.append("debitAccount.id AS debitAccountId, debitAccount.name as debitAccountName, debitAccount.gl_code as debitAccountGLCode, ")
.append("creditAccount.id AS creditAccountId, creditAccount.name as creditAccountName, creditAccount.gl_code as creditAccountGLCode")
.append(" from m_office AS office, acc_accounting_rule AS rule ")
.append(" LEFT JOIN acc_gl_account AS creditAccount ON rule.credit_account_id = creditAccount.id ")
.append(" LEFT JOIN acc_gl_account AS debitAccount ON rule.debit_account_id = debitAccount.id ")
.append("WHERE office.id=rule.office_id ");
this.schemaSql = sqlBuilder.toString();
}
sql = sql + " order by rule.id asc";
return this.jdbcTemplate.query(sql, rm, arguments);
public String schema() {
return this.schemaSql;
}
@Override
public Map<Long, AccountingRuleData> extractData(final ResultSet rs) throws SQLException, DataAccessException {
final Map<Long, AccountingRuleData> extractedData = new HashMap<Long, AccountingRuleData>();
while (rs.next()) {
final Long id = rs.getLong("id");
AccountingRuleData accountingRuleData = extractedData.get(id);
if (accountingRuleData == null) {
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 = JdbcSupport.getLong(rs, "debitAccountId");
final Long accountToCreditId = JdbcSupport.getLong(rs, "creditAccountId");
final boolean systemDefined = rs.getBoolean("systemDefined");
final String debitAccountName = rs.getString("debitAccountName");
final String creditAccountName = rs.getString("creditAccountName");
final String debitAccountGLCode = rs.getString("debitAccountGLCode");
final String creditAccountGLCode = rs.getString("creditAccountGLCode");
final GLAccountData debitAccountData = accountToDebitId == null ? null : new GLAccountData(accountToDebitId,
debitAccountName, debitAccountGLCode);
final GLAccountData creditAccountData = accountToCreditId == null ? null : new GLAccountData(accountToCreditId,
creditAccountName, creditAccountGLCode);
accountingRuleData = new AccountingRuleData(id, officeId, officeName, name, description, systemDefined,
debitAccountData, creditAccountData);
}
if (accountingRuleData.getCreditAccountHead() == null) {
final List<AccountingTagRuleData> creditTags = getCreditOrDebitTags(id, JournalEntryType.CREDIT.getValue());
accountingRuleData = new AccountingRuleData(accountingRuleData, creditTags, accountingRuleData.getDebitTags());
}
if (accountingRuleData.getDebitAccountHead() == null) {
final List<AccountingTagRuleData> debitTags = getCreditOrDebitTags(id, JournalEntryType.DEBIT.getValue());
accountingRuleData = new AccountingRuleData(accountingRuleData, accountingRuleData.getCreditTags(), debitTags);
}
extractedData.put(id, accountingRuleData);
}
return extractedData;
}
private List<AccountingTagRuleData> getCreditOrDebitTags(final Long creditOrDebitAccount, final Integer transactionType) {
final AccountingTagRuleDataMapper mapper = new AccountingTagRuleDataMapper();
final String taggedAccountsSchema = "Select " + mapper.taggedAccountSchema() + " where rule.id = ? and tag.acc_type_enum=?";
return this.jdbcTemplate.query(taggedAccountsSchema, mapper, new Object[] { creditOrDebitAccount, transactionType });
}
}
@Override
public AccountingRuleData retrieveAccountingRuleById(long accountingRuleId) {
public List<AccountingRuleData> retrieveAllAccountingRules(final Long officeId) {
final AccountingRuleDataExtractor resultSetExtractor = new AccountingRuleDataExtractor(this.jdbcTemplate);
Object[] arguments = new Object[] {};
String sql = "select " + resultSetExtractor.schema() + " and system_defined=0 ";
if (officeId != null) {
sql = sql + " and office.id = ?";
arguments = new Object[] { officeId };
}
sql = sql + " order by rule.id asc";
@SuppressWarnings("unchecked")
final Map<Long, AccountingRuleData> extractedData = (Map<Long, AccountingRuleData>) this.jdbcTemplate.query(sql,
resultSetExtractor, arguments);
return new ArrayList<AccountingRuleData>(extractedData.values());
}
@Override
public AccountingRuleData retrieveAccountingRuleById(final Long accountingRuleId) {
try {
final AccountingRuleDataExtractor resultSetExtractor = new AccountingRuleDataExtractor(this.jdbcTemplate);
final String sql = "select " + resultSetExtractor.schema() + " and rule.id = ?";
final AccountingRuleMapper rm = new AccountingRuleMapper();
final String sql = "select " + rm.schema() + " and rule.id = ?";
final AccountingRuleData accountingRuleData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { accountingRuleId });
@SuppressWarnings("unchecked")
final Map<Long, AccountingRuleData> extractedData = (Map<Long, AccountingRuleData>) this.jdbcTemplate.query(sql,
resultSetExtractor, new Object[] { accountingRuleId });
final AccountingRuleData accountingRuleData = extractedData.get(accountingRuleId);
if (accountingRuleData == null) { throw new AccountingRuleNotFoundException(accountingRuleId); }
return accountingRuleData;
} catch (final EmptyResultDataAccessException e) {
throw new AccountingRuleNotFoundException(accountingRuleId);
}
}
private static final class AccountingTagRuleDataMapper implements RowMapper<AccountingTagRuleData> {
public String taggedAccountSchema() {
return " tag.id as id,tag.tag_id as tagId, tag.acc_type_enum as transactionType from acc_rule_tags tag "
+ "join acc_accounting_rule rule on tag.acc_rule_id=rule.id ";
}
@Override
public AccountingTagRuleData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long id = rs.getLong("id");
final Long tagId = rs.getLong("tagId");
final Integer transactionType = JdbcSupport.getInteger(rs, "transactionType");
final EnumOptionData transactionTypeEnum = AccountingEnumerations.journalEntryType(transactionType);
return new AccountingTagRuleData(id, tagId, transactionTypeEnum);
}
}
}
@@ -5,18 +5,22 @@
*/
package org.mifosplatform.accounting.rule.service;
import java.util.ArrayList;
import java.util.List;
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.journalentry.domain.JournalEntryType;
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.domain.AccountingTagRule;
import org.mifosplatform.accounting.rule.exception.AccountingRuleDuplicateException;
import org.mifosplatform.accounting.rule.serialization.AccountingRuleCommandFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepository;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -40,17 +44,20 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco
private final AccountingRuleRepository accountingRuleRepository;
private final GLAccountRepositoryWrapper accountRepositoryWrapper;
private final OfficeRepository officeRepository;
private final AccountingRuleCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final AccountingRuleDataValidator fromApiJsonDeserializer;
private final CodeValueRepository codeValueRepository;
@Autowired
public AccountingRuleWritePlatformServiceJpaRepositoryImpl(final AccountingRuleRepositoryWrapper accountingRuleRepositoryWrapper,
final GLAccountRepositoryWrapper accountRepositoryWrapper, final OfficeRepository officeRepository,
final AccountingRuleCommandFromApiJsonDeserializer fromApiJsonDeserializer, final AccountingRuleRepository ruleRepository) {
final AccountingRuleRepository ruleRepository, final AccountingRuleDataValidator fromApiJsonDeserializer,
final CodeValueRepository codeValueRepository) {
this.accountRepositoryWrapper = accountRepositoryWrapper;
this.officeRepository = officeRepository;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.accountingRuleRepository = ruleRepository;
this.accountingRuleRepositoryWrapper = accountingRuleRepositoryWrapper;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.codeValueRepository = codeValueRepository;
}
/**
@@ -69,10 +76,10 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco
@Transactional
@Override
public CommandProcessingResult createAccountingRule(JsonCommand command) {
public CommandProcessingResult createAccountingRule(final JsonCommand command) {
try {
final AccountingRuleCommand accountingRuleCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
accountingRuleCommand.validateForCreate();
this.fromApiJsonDeserializer.validateForCreate(command.json());
// check office is valid
final Long officeId = command.longValueOfParameterNamed(GLClosureJsonInputParams.OFFICE_ID.getValue());
@@ -82,15 +89,8 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco
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);
final AccountingRule accountingRule = assembleAccountingRuleAndTags(office, command);
this.accountingRuleRepository.saveAndFlush(accountingRule);
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(officeId)
.withEntityId(accountingRule.getId()).build();
} catch (final DataIntegrityViolationException dve) {
@@ -99,11 +99,43 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco
}
}
private AccountingRule assembleAccountingRuleAndTags(final Office office, final JsonCommand command) {
// get the GL Accounts or tags to Debit and Credit
final String[] debitTags = command.arrayValueOfParameterNamed(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue());
final String[] creditTags = command.arrayValueOfParameterNamed(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue());
final Long accountToDebitId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue());
final Long accountToCreditId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue());
GLAccount debitAccount = null;
GLAccount creditAccount = null;
List<AccountingTagRule> accountingTagRules = new ArrayList<AccountingTagRule>();
if (accountToDebitId != null) {
debitAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToDebitId);
} else if (debitTags != null) {
accountingTagRules = saveDebitOrCreditTags(debitTags, JournalEntryType.DEBIT, accountingTagRules);
} else {
throw new RuntimeException("Please Specify debitTags or accountToDebitId");
}
if (accountToCreditId != null) {
creditAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToCreditId);
} else if (debitTags != null) {
accountingTagRules = saveDebitOrCreditTags(creditTags, JournalEntryType.CREDIT, accountingTagRules);
} else {
throw new RuntimeException("Please Specify debitTags or accountToDebitId");
}
final AccountingRule accountingRule = AccountingRule.fromJson(office, debitAccount, creditAccount, command);
accountingTagRules = accountingRule.updateAccountingRuleForTags(accountingTagRules);
return accountingRule;
}
@Transactional
@Override
public CommandProcessingResult updateAccountingRule(Long accountingRuleId, JsonCommand command) {
final AccountingRuleCommand accountingRuleCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
accountingRuleCommand.validateForUpdate();
public CommandProcessingResult updateAccountingRule(final Long accountingRuleId, final JsonCommand command) {
this.fromApiJsonDeserializer.validateForUpdate(command.json());
Long officeId = null;
if (command.parameterExists(AccountingRuleJsonInputParams.OFFICE_ID.getValue())) {
@@ -124,12 +156,12 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco
final Map<String, Object> changesOnly = accountingRule.update(command);
if (accountToDebitId != null && changesOnly.containsKey(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue())) {
final GLAccount accountToDebit = accountRepositoryWrapper.findOneWithNotFoundDetection(accountToDebitId);
final GLAccount accountToDebit = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToDebitId);
accountingRule.setAccountToDebit(accountToDebit);
}
if (accountToCreditId != null && changesOnly.containsKey(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue())) {
final GLAccount accountToCredit = accountRepositoryWrapper.findOneWithNotFoundDetection(accountToCreditId);
final GLAccount accountToCredit = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToCreditId);
accountingRule.setAccountToCredit(accountToCredit);
}
@@ -149,9 +181,33 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco
@Transactional
@Override
public CommandProcessingResult deleteAccountingRule(Long accountingRuleId) {
public CommandProcessingResult deleteAccountingRule(final Long accountingRuleId) {
final AccountingRule accountingRule = this.accountingRuleRepositoryWrapper.findOneWithNotFoundDetection(accountingRuleId);
this.accountingRuleRepository.delete(accountingRule);
return new CommandProcessingResultBuilder().withEntityId(accountingRule.getId()).build();
}
/* private GLAccount saveDebitOrCreditTagsOrGetDebitORCreditAccount(final String[] creditOrDebitTagArray, final Long creditOrDebitId,
final JournalEntryType transactionType) {
GLAccount creditOrDebitAccount = null;
if (creditOrDebitId != null) {
creditOrDebitAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(creditOrDebitId);
} else if (creditOrDebitTagArray != null) {
final List<AccountingTagRule> accountingTagRules = saveDebitOrCreditTags(creditOrDebitTagArray, transactionType);
} else {
throw new RuntimeException("Please Specify debitTags or accountToDebitId");
}
return creditOrDebitAccount;
}*/
private List<AccountingTagRule> saveDebitOrCreditTags(final String[] creditOrDebitTagArray, final JournalEntryType transactionType,
final List<AccountingTagRule> accountingTagRules) {
for (final String creditOrDebitTag : creditOrDebitTagArray) {
final Long creditOrDebitTagIdLongValue = Long.valueOf(creditOrDebitTag);
final CodeValue creditOrDebitAccount = this.codeValueRepository.findOne(creditOrDebitTagIdLongValue);
final AccountingTagRule accountingTagRule = AccountingTagRule.create(creditOrDebitAccount, transactionType.getValue());
accountingTagRules.add(accountingTagRule);
}
return accountingTagRules;
}
}