diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 53bee542d..175a8f51b 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -9494,6 +9494,30 @@ Content-Type: application/json Credit account for creating accounting rule + + debitTags + + + Debit tags for creating accounting rule, These tags fetches the all chart of accounts that are tagged with these tagIds + + + creditTags + + + Credit tags for creating accounting rule, These tags fetches the all chart of accounts that are tagged with these tagIds + + + allowMultipleDebitEntries + + + Allows to add multiple debits if the value is true, while creating journal entries with this rule + + + allowMultipleCreditEntries + + + Allows to add multiple credits if the value is true, while creating journal entries with this rule + @@ -9605,6 +9629,64 @@ Request Body: { "officeId":1, "resourceId":1 +} + + +POST accountingrules +Content-Type: application/json +Request Body: +{ + "name": "fordocs", + "officeId": "1", + "debitTags": ["10","11"], + "allowMultipleDebitEntries": "true", + "creditTags": ["12","13"], + "allowMultipleCreditEntries": "true", + "description": "for api docs" +} + + +{ + "officeId":1, + "resourceId":2 +} + + +POST accountingrules +Content-Type: application/json +Request Body: +{ + "name": "test123", + "officeId": "1", + "debitAccountHead": "21", + "creditTags": ["12", "13"], + "allowMultipleCreditEntries": "false", + "description": "Employee salary" +} + + +{ + "officeId":1, + "resourceId":3 +} + + +POST accountingrules +Content-Type: application/json +Request Body: +{ + "name": "fordocstest", + "officeId": "1", + "debitTags": ["10", "11"], + "allowMultipleDebitEntries": "false", + "creditAccountHead": "9", + "description": "for api docs" +} + + +{ + "officeId":1, + "resourceId":4 } @@ -14890,6 +14972,68 @@ Request Body: { "officeId":1, "transactionId":"RS9MCISID4WK1ZM" +} + + +POST https://DomainName/api/v1/journalentries + + +POST journalentries +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "officeId": "1", + "transactionDate": "23 May 2013", + "referenceNumber": "547", + "comments": "asdf", + "accountingRule": "2", + "credits":[{"glAccountId":1, + "amount":5000}, + {"glAccountId":2, + "amount":5000} + ], + "debits":[{"glAccountId":3, + "amount":5000}, + {"glAccountId":4, + "amount":5000} + ] +} + + +{ + "officeId":1, + "transactionId":"RS9MCISID4WK1ZM" +} + + +POST https://DomainName/api/v1/journalentries + + +POST journalentries +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "officeId": "1", + "transactionDate": "23 May 2013", + "referenceNumber": "547", + "comments": "asdf", + "accountingRule": "3", + "credits":[{"glAccountId":1, + "amount":5000}, + {"glAccountId":2, + "amount":5000} + ], + "amount": "10000" +} + + +{ + "officeId":1, + "transactionId":"RS9MCISID4WK1ZM" } diff --git a/mifosng-db/migrations/core_db/V52__add_boolean_support_cols_to_acc_accounting_rule.sql b/mifosng-db/migrations/core_db/V52__add_boolean_support_cols_to_acc_accounting_rule.sql new file mode 100644 index 000000000..55041d7d2 --- /dev/null +++ b/mifosng-db/migrations/core_db/V52__add_boolean_support_cols_to_acc_accounting_rule.sql @@ -0,0 +1,6 @@ +ALTER TABLE `acc_accounting_rule` + ADD COLUMN `allow_multiple_debits` TINYINT(1) NOT NULL DEFAULT '0' AFTER `debit_account_id`, + ADD COLUMN `allow_multiple_credits` TINYINT(1) NOT NULL DEFAULT '0' AFTER `credit_account_id`; + +ALTER TABLE acc_rule_tags + ADD UNIQUE KEY `UNIQUE_ACCOUNT_RULE_TAGS` (`acc_rule_id`,`tag_id`,`acc_type_enum`); \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/data/GLAccountData.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/data/GLAccountData.java index 004431078..8fd608ebd 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/data/GLAccountData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/data/GLAccountData.java @@ -48,10 +48,6 @@ public class GLAccountData { final Collection allowedIncomeTagOptions; final Collection allowedExpensesTagOptions; - // for predefined journal entry template - private final List creditAccounts; - private final List debitAccounts; - public GLAccountData(final Long id, final String name, final Long parentId, final String glCode, final boolean disabled, final boolean manualEntriesAllowed, final EnumOptionData type, final EnumOptionData usage, final String description, final String nameDecorated, final CodeValueData tagId) { @@ -78,8 +74,6 @@ public class GLAccountData { this.allowedEquityTagOptions = null; this.allowedIncomeTagOptions = null; this.allowedExpensesTagOptions = null; - this.creditAccounts = null; - this.debitAccounts = null; } public GLAccountData(final GLAccountData accountData, final List accountTypeOptions, @@ -112,8 +106,6 @@ public class GLAccountData { this.allowedEquityTagOptions = allowedEquityTagOptions; this.allowedIncomeTagOptions = allowedIncomeTagOptions; this.allowedExpensesTagOptions = allowedExpensesTagOptions; - this.creditAccounts = accountData.creditAccounts; - this.debitAccounts = accountData.debitAccounts; } public static GLAccountData sensibleDefaultsForNewGLAccountCreation(final Integer glAccType) { @@ -160,8 +152,6 @@ public class GLAccountData { this.allowedEquityTagOptions = null; this.allowedIncomeTagOptions = null; this.allowedExpensesTagOptions = null; - this.creditAccounts = null; - this.debitAccounts = null; } public Long getId() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/domain/JournalEntry.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/domain/JournalEntry.java index 32e462a78..e5298504c 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/domain/JournalEntry.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/domain/JournalEntry.java @@ -73,7 +73,7 @@ public class JournalEntry extends AbstractAuditableCustom { @SuppressWarnings("unused") @Column(name = "entity_id") private Long entityId; - + @Column(name = "ref_num") private String referenceNumber; @@ -104,7 +104,7 @@ public class JournalEntry extends AbstractAuditableCustom { this.entityType = entityType; this.entityId = entityId; this.referenceNumber = referenceNumber; - + } public boolean isDebitEntry() { @@ -139,8 +139,8 @@ public class JournalEntry extends AbstractAuditableCustom { this.reversed = reversed; } - public String getReferenceNumber() { - return this.referenceNumber; - } + public String getReferenceNumber() { + return this.referenceNumber; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/domain/JournalEntryType.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/domain/JournalEntryType.java index 4d6842f85..6c316f5af 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/domain/JournalEntryType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/domain/JournalEntryType.java @@ -45,4 +45,12 @@ public enum JournalEntryType { return name().toString(); } + public boolean isDebitType() { + return this.value.equals(JournalEntryType.DEBIT.getValue()); + } + + public boolean isCreditType() { + return this.value.equals(JournalEntryType.CREDIT.getValue()); + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/api/AccountingRuleApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/api/AccountingRuleApiResource.java index 57c8746b5..6aabbd0c1 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/api/AccountingRuleApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/api/AccountingRuleApiResource.java @@ -5,10 +5,13 @@ */ package org.mifosplatform.accounting.rule.api; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import javax.ws.rs.Consumes; @@ -19,7 +22,6 @@ 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; @@ -28,12 +30,14 @@ 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; +import org.mifosplatform.accounting.rule.data.AccountingTagRuleData; 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.codes.data.CodeValueData; import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService; +import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; @@ -51,9 +55,9 @@ import org.springframework.stereotype.Component; public class AccountingRuleApiResource { private static final Set RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "officeId", "officeName", - "accountToDebitId", "accountToCreditId", "name", "description", "systemDefined", "allowedAssetsTagOptions", - "allowedLiabilitiesTagOptions", "allowedEquityTagOptions", "allowedIncomeTagOptions", "allowedExpensesTagOptions", "debitTags", - "creditTags", "creditAccounts", "debitAccounts")); + "accountToDebitId", "accountToCreditId", "name", "description", "systemDefined", "allowedCreditTagOptions", + "allowedDebitTagOptions", "debitTags", "creditTags", "creditAccounts", "debitAccounts", "allowMultipleCreditEntries", + "allowMultipleDebitEntries", "tag")); private final String resourceNameForPermission = "ACCOUNTINGRULE"; @@ -101,10 +105,19 @@ public class AccountingRuleApiResource { @GET @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveAllAccountingRules(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId) { + public String retrieveAllAccountingRules(@Context final UriInfo uriInfo) { this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission); - final List accountingRuleDatas = this.accountingRuleReadPlatformService.retrieveAllAccountingRules(officeId); + final Set associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); + final Long officeId = this.context.authenticatedUser().getOffice().getId(); + boolean isAssociationParametersExists = false; + if (!associationParameters.isEmpty()) { + if (associationParameters.contains("all")) { + isAssociationParametersExists = true; // If true, retrieve additional fields for journal entry form. + } + } + final List accountingRuleDatas = this.accountingRuleReadPlatformService.retrieveAllAccountingRules(officeId, + isAssociationParametersExists); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.apiJsonSerializerService.serialize(settings, accountingRuleDatas, RESPONSE_DATA_PARAMETERS); @@ -117,7 +130,6 @@ public class AccountingRuleApiResource { 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()); AccountingRuleData accountingRuleData = this.accountingRuleReadPlatformService.retrieveAccountingRuleById(accountingRuleId); @@ -166,30 +178,47 @@ public class AccountingRuleApiResource { return this.apiJsonSerializerService.serialize(result); } - private AccountingRuleData handleTemplate(final AccountingRuleData accountingRuleData) { + private AccountingRuleData handleTemplate(AccountingRuleData accountingRuleData) { final List allowedAccounts = this.accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(); final List allowedOffices = (List) this.officeReadPlatformService.retrieveAllOfficesForDropdown(); - final Collection allowedAssetsTagOptions = defaultIfEmpty(this.codeValueReadPlatformService - .retrieveCodeValuesByCode(AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME)); - final Collection allowedLiabilitiesTagOptions = defaultIfEmpty(this.codeValueReadPlatformService - .retrieveCodeValuesByCode(AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME)); - final Collection allowedEquityTagOptions = defaultIfEmpty(this.codeValueReadPlatformService - .retrieveCodeValuesByCode(AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME)); - final Collection allowedIncomeTagOptions = defaultIfEmpty(this.codeValueReadPlatformService - .retrieveCodeValuesByCode(AccountingConstants.INCOME_TAG_OPTION_CODE_NAME)); - final Collection 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); + final Collection allowedTagOptions = this.codeValueReadPlatformService + .retrieveCodeValuesByCode(AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME); + + allowedTagOptions.addAll(this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME)); + allowedTagOptions.addAll(this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME)); + allowedTagOptions.addAll(this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.INCOME_TAG_OPTION_CODE_NAME)); + allowedTagOptions.addAll(this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.EXPENSES_TAG_OPTION_CODE_NAME)); + + if (accountingRuleData == null) { + + final Collection allowedCreditTagOptions = allowedTagOptions; + final Collection allowedDebitTagOptions = allowedTagOptions; + + accountingRuleData = new AccountingRuleData(allowedAccounts, allowedOffices, allowedCreditTagOptions, allowedDebitTagOptions); + + } else { + + final Collection allowedCreditTagOptions = retrieveSelectedTags(allowedTagOptions, accountingRuleData.getCreditTags()); + final Collection allowedDebitTagOptions = retrieveSelectedTags(allowedTagOptions, accountingRuleData.getDebitTags()); + + accountingRuleData = new AccountingRuleData(accountingRuleData, allowedAccounts, allowedOffices, allowedCreditTagOptions, + allowedDebitTagOptions); + } + return accountingRuleData; } - private Collection defaultIfEmpty(final Collection collection) { - Collection returnCollection = null; - if (collection != null && !collection.isEmpty()) { - returnCollection = collection; + private Collection retrieveSelectedTags(final Collection allowedTagOptions, + final List existedTags) { + final Collection tempOptions = new ArrayList(allowedTagOptions); + final Map selectedTags = new HashMap(); + for (final AccountingTagRuleData accountingTagRuleData : existedTags) { + for (final CodeValueData codeValueData : tempOptions) { + if (codeValueData.getId().equals(accountingTagRuleData.getTag().getId())) { + selectedTags.put(codeValueData.getId(), codeValueData); + } + } } - return returnCollection; + tempOptions.removeAll(selectedTags.values()); + return tempOptions; } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/api/AccountingRuleJsonInputParams.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/api/AccountingRuleJsonInputParams.java index 161638bbe..795b6e2d4 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/api/AccountingRuleJsonInputParams.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/api/AccountingRuleJsonInputParams.java @@ -13,7 +13,8 @@ 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"), DEBIT_ACCOUNT_TAGS("debitTags"), CREDIT_ACCOUNT_TAGS("creditTags"); + "description"), SYSTEM_DEFINED("systemDefined"), DEBIT_ACCOUNT_TAGS("debitTags"), CREDIT_ACCOUNT_TAGS("creditTags"), ALLOW_MULTIPLE_CREDIT_ENTRIES( + "allowMultipleCreditEntries"), ALLOW_MULTIPLE_DEBIT_ENTRIES("allowMultipleDebitEntries"); private final String value; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/command/AccountingRuleCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/command/AccountingRuleCommand.java deleted file mode 100755 index b3f3f45af..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/command/AccountingRuleCommand.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 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 dataValidationErrors = new ArrayList(); - - 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 dataValidationErrors = new ArrayList(); - - final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("AccountingRule"); - - baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue()).value(this.accountToDebitId) - .ignoreIfNull().notBlank().integerGreaterThanZero(); - baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue()).value(this.accountToCreditId) - .ignoreIfNull().notBlank().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); } - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/data/AccountingRuleData.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/data/AccountingRuleData.java index 42aca2773..908f7fe85 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/data/AccountingRuleData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/data/AccountingRuleData.java @@ -28,6 +28,8 @@ public class AccountingRuleData { private final String name; private final String description; private final boolean systemDefined; + private final boolean allowMultipleDebitEntries; + private final boolean allowMultipleCreditEntries; private final GLAccountData debitAccountHead; private final GLAccountData creditAccountHead; private final List creditTags; @@ -36,33 +38,28 @@ public class AccountingRuleData { // template private List allowedOffices = new ArrayList(); private List allowedAccounts = new ArrayList(); - private final Collection allowedAssetsTagOptions; - private final Collection allowedLiabilitiesTagOptions; - private final Collection allowedEquityTagOptions; - private final Collection allowedIncomeTagOptions; - private final Collection allowedExpensesTagOptions; + private final Collection allowedCreditTagOptions; + private final Collection allowedDebitTagOptions; private final List creditAccounts; private final List debitAccounts; public AccountingRuleData(final AccountingRuleData accountingRuleData, final List allowedAccounts, - final List allowedOffices, final Collection allowedAssetsTagOptions, - final Collection allowedLiabilitiesTagOptions, final Collection allowedEquityTagOptions, - final Collection allowedIncomeTagOptions, final Collection allowedExpensesTagOptions) { + final List allowedOffices, final Collection allowedCreditTagOptions, + final Collection allowedDebitTagOptions) { 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.allowMultipleDebitEntries = accountingRuleData.allowMultipleDebitEntries; + this.allowMultipleCreditEntries = accountingRuleData.allowMultipleCreditEntries; 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.allowedCreditTagOptions = allowedCreditTagOptions; + this.allowedDebitTagOptions = allowedDebitTagOptions; this.creditTags = accountingRuleData.creditTags; this.debitTags = accountingRuleData.debitTags; this.creditAccounts = accountingRuleData.creditAccounts; @@ -70,24 +67,21 @@ public class AccountingRuleData { } public AccountingRuleData(final List allowedAccounts, final List allowedOffices, - final Collection allowedAssetsTagOptions, final Collection allowedLiabilitiesTagOptions, - final Collection allowedEquityTagOptions, final Collection allowedIncomeTagOptions, - final Collection allowedExpensesTagOptions) { + final Collection allowedCreditTagOptions, final Collection allowedDebitTagOptions) { this.id = null; this.officeId = null; this.officeName = null; this.name = null; this.description = null; this.systemDefined = false; + this.allowMultipleDebitEntries = false; + this.allowMultipleCreditEntries = 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.allowedCreditTagOptions = allowedCreditTagOptions; + this.allowedDebitTagOptions = allowedDebitTagOptions; this.creditTags = null; this.debitTags = null; this.creditAccounts = null; @@ -95,22 +89,22 @@ public class AccountingRuleData { } 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) { + final boolean systemDefined, final boolean allowMultipleDebitEntries, final boolean allowMultipleCreditEntries, + 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.allowMultipleDebitEntries = allowMultipleDebitEntries; + this.allowMultipleCreditEntries = allowMultipleCreditEntries; 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.allowedCreditTagOptions = null; + this.allowedDebitTagOptions = null; this.creditTags = null; this.debitTags = null; this.creditAccounts = new ArrayList(); @@ -126,15 +120,14 @@ public class AccountingRuleData { this.name = accountingRuleData.name; this.description = accountingRuleData.description; this.systemDefined = accountingRuleData.systemDefined; + this.allowMultipleDebitEntries = accountingRuleData.allowMultipleDebitEntries; + this.allowMultipleCreditEntries = accountingRuleData.allowMultipleCreditEntries; 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.allowedCreditTagOptions = accountingRuleData.allowedCreditTagOptions; + this.allowedDebitTagOptions = accountingRuleData.allowedDebitTagOptions; this.creditTags = creditTags; this.creditAccounts = creditAccounts; this.debitTags = debitTags; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/data/AccountingTagRuleData.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/data/AccountingTagRuleData.java index f1d985caf..6185f8970 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/data/AccountingTagRuleData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/data/AccountingTagRuleData.java @@ -5,21 +5,25 @@ */ package org.mifosplatform.accounting.rule.data; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.core.data.EnumOptionData; public class AccountingTagRuleData { @SuppressWarnings("unused") private final Long id; - @SuppressWarnings("unused") - private final Long tagId; + private final CodeValueData tag; @SuppressWarnings("unused") private final EnumOptionData transactionType; - public AccountingTagRuleData(final Long id, final Long tagId, final EnumOptionData transactionType) { + public AccountingTagRuleData(final Long id, final CodeValueData tag, final EnumOptionData transactionType) { this.id = id; - this.tagId = tagId; + this.tag = tag; this.transactionType = transactionType; } + public CodeValueData getTag() { + return tag; + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/domain/AccountingRule.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/domain/AccountingRule.java index 1b30eb02e..0f2f6e67e 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/domain/AccountingRule.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/domain/AccountingRule.java @@ -6,9 +6,11 @@ package org.mifosplatform.accounting.rule.domain; import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -23,6 +25,7 @@ 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.journalentry.domain.JournalEntryType; import org.mifosplatform.accounting.rule.api.AccountingRuleJsonInputParams; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.organisation.office.domain.Office; @@ -52,16 +55,22 @@ public class AccountingRule extends AbstractPersistable { @Column(name = "system_defined", nullable = false) private Boolean systemDefined; - + @LazyCollection(LazyCollectionOption.FALSE) @OneToMany(cascade = CascadeType.ALL, mappedBy = "accountingRule", orphanRemoval = true) - private List accountingTagRules = new ArrayList(); - + private final List accountingTagRules = new ArrayList(); + + @Column(name = "allow_multiple_credits", nullable = false) + private boolean allowMultipleCreditEntries; + + @Column(name = "allow_multiple_debits", nullable = false) + private boolean allowMultipleDebitEntries; protected AccountingRule() {} - private AccountingRule(Office office, GLAccount accountToDebit, GLAccount accountToCredit, String name, String description, - boolean systemDefined) { + private AccountingRule(final Office office, final GLAccount accountToDebit, final GLAccount accountToCredit, final String name, + final String description, final boolean systemDefined, final boolean allowMultipleCreditEntries, + final boolean allowMultipleDebitEntries) { this.accountToDebit = accountToDebit; this.accountToCredit = accountToCredit; this.name = name; @@ -71,24 +80,34 @@ public class AccountingRule extends AbstractPersistable { this.description = this.description.trim(); } this.systemDefined = systemDefined; + this.allowMultipleCreditEntries = allowMultipleCreditEntries; + this.allowMultipleDebitEntries = allowMultipleDebitEntries; } public static AccountingRule fromJson(final Office office, final GLAccount accountToDebit, final GLAccount accountToCredit, - JsonCommand command) { + final JsonCommand command, final boolean allowMultipleCreditEntries, final boolean allowMultipleDebitEntries) { 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); + return new AccountingRule(office, accountToDebit, accountToCredit, name, description, systemDefined, allowMultipleCreditEntries, + allowMultipleDebitEntries); } public Map update(final JsonCommand command) { - final Map actualChanges = new LinkedHashMap(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); + final Map actualChanges = new LinkedHashMap(10); + handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.OFFICE_ID.getValue(), this.office == null ? 0L + : this.office.getId()); + handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue(), + this.accountToDebit == null ? 0L : this.accountToDebit.getId()); + handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue(), + this.accountToCredit == null ? 0L : this.accountToCredit.getId()); 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); + handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue(), + this.allowMultipleCreditEntries); + handlePropertyUpdate(command, actualChanges, AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue(), + this.allowMultipleDebitEntries); return actualChanges; } @@ -114,6 +133,14 @@ public class AccountingRule extends AbstractPersistable { // now update actual property if (paramName.equals(AccountingRuleJsonInputParams.SYSTEM_DEFINED.getValue())) { this.systemDefined = newValue; + } else if (paramName.equals(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue())) { + if (this.accountToCredit == null) { + this.allowMultipleCreditEntries = newValue; + } + } else if (paramName.equals(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue())) { + if (this.accountToDebit == null) { + this.allowMultipleDebitEntries = newValue; + } } } } @@ -134,7 +161,7 @@ public class AccountingRule extends AbstractPersistable { } } - public void setOffice(Office office) { + public void setOffice(final Office office) { this.office = office; } @@ -150,11 +177,11 @@ public class AccountingRule extends AbstractPersistable { return this.accountToCredit; } - public void setAccountToDebit(GLAccount accountToDebit) { + public void setAccountToDebit(final GLAccount accountToDebit) { this.accountToDebit = accountToDebit; } - public void setAccountToCredit(GLAccount accountToCredit) { + public void setAccountToCredit(final GLAccount accountToCredit) { this.accountToCredit = accountToCredit; } @@ -162,12 +189,66 @@ public class AccountingRule extends AbstractPersistable { return this.description; } - public List updateAccountingRuleForTags(List debitAccountingTagRules) { - for(AccountingTagRule accountingTagRule : debitAccountingTagRules){ - accountingTagRule.updateAccountingTagRule(this); - this.accountingTagRules.add(accountingTagRule); - } - return debitAccountingTagRules; - } + public List getAccountingTagRules() { + return this.accountingTagRules; + } + + public void updateAccountingRuleForTags(final List debitAccountingTagRules) { + for (final AccountingTagRule accountingTagRule : debitAccountingTagRules) { + accountingTagRule.updateAccountingTagRule(this); + this.accountingTagRules.add(accountingTagRule); + } + } + + public void updateDebitAccount(final GLAccount accountToDebit) { + this.accountToDebit = accountToDebit; + this.allowMultipleDebitEntries = false; + } + + public void updateCreditAccount(final GLAccount accountToCredit) { + this.accountToCredit = accountToCredit; + this.allowMultipleCreditEntries = false; + } + + public void updateAllowMultipleCreditEntries(final boolean allowMultipleCreditEntries) { + this.allowMultipleCreditEntries = allowMultipleCreditEntries; + } + + public void updateAllowMultipleDebitEntries(final boolean allowMultipleDebitEntries) { + this.allowMultipleDebitEntries = allowMultipleDebitEntries; + } + + public void updateTags(final JournalEntryType type) { + final Set existedCreditTags = new HashSet(); + final Set existedDebitTags = new HashSet(); + for (final AccountingTagRule accountingTagRule : this.accountingTagRules) { + if (accountingTagRule.isCreditAccount()) { + existedCreditTags.add(accountingTagRule); + } else if (accountingTagRule.isDebitAccount()) { + existedDebitTags.add(accountingTagRule); + } + } + + if (type.isCreditType()) { + this.accountingTagRules.retainAll(existedCreditTags); + } else if (type.isDebitType()) { + this.accountingTagRules.retainAll(existedDebitTags); + } + + } + + public Set getAccountingTagRulesByType(final JournalEntryType type) { + final Set existedTags = new HashSet(); + for (final AccountingTagRule accountingTagRule : this.accountingTagRules) { + if (accountingTagRule.getAccountType().equals(type.getValue())) { + existedTags.add(accountingTagRule); + } + } + return existedTags; + } + + public void removeOldTags(final List accountsToRemove) { + this.accountingTagRules.removeAll(accountsToRemove); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/domain/AccountingTagRule.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/domain/AccountingTagRule.java index 18bc38349..f43a99cef 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/domain/AccountingTagRule.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/domain/AccountingTagRule.java @@ -10,20 +10,20 @@ import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import javax.persistence.UniqueConstraint; +import org.mifosplatform.accounting.journalentry.domain.JournalEntryType; import org.mifosplatform.infrastructure.codes.domain.CodeValue; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity -@Table(name = "acc_rule_tags") +@Table(name = "acc_rule_tags", uniqueConstraints = { @UniqueConstraint(columnNames = { "acc_rule_id", "tag_id", "acc_type_enum" }, name = "UNIQUE_ACCOUNT_RULE_TAGS") }) public class AccountingTagRule extends AbstractPersistable { - @SuppressWarnings("unused") @ManyToOne @JoinColumn(name = "acc_rule_id", nullable = false) private AccountingRule accountingRule; - @SuppressWarnings("unused") @ManyToOne @JoinColumn(name = "tag_id", nullable = false) private CodeValue tagId; @@ -52,4 +52,16 @@ public class AccountingTagRule extends AbstractPersistable { return this.accountType; } + public boolean isDebitAccount() { + return JournalEntryType.fromInt(this.accountType).isDebitType(); + } + + public boolean isCreditAccount() { + return JournalEntryType.fromInt(this.accountType).isCreditType(); + } + + public Long getTagId() { + return this.tagId.getId(); + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/exception/AccountingRuleDataException.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/exception/AccountingRuleDataException.java new file mode 100644 index 000000000..f94df017b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/exception/AccountingRuleDataException.java @@ -0,0 +1,12 @@ +package org.mifosplatform.accounting.rule.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +public class AccountingRuleDataException extends AbstractPlatformDomainRuleException { + + public AccountingRuleDataException(final String debitOrCreditAccount, final String debitOrCreditTags) { + super("error.msg.accounting.rule." + debitOrCreditAccount + ".or." + debitOrCreditTags + ".required", debitOrCreditAccount + " or " + + debitOrCreditTags + " required", debitOrCreditAccount, debitOrCreditTags); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/exception/AccountingRuleDuplicateException.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/exception/AccountingRuleDuplicateException.java index a5023731f..90b443820 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/exception/AccountingRuleDuplicateException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/exception/AccountingRuleDuplicateException.java @@ -16,5 +16,9 @@ public class AccountingRuleDuplicateException extends AbstractPlatformDomainRule public AccountingRuleDuplicateException(String name) { super("error.msg.accounting.rule.duplicate", "An accounting rule with the name " + name + " already exists" + name); } + + public AccountingRuleDuplicateException() { + super("error.msg.accounting.rule.tag.duplicate", "The accounting rule already have the tags which you defined"); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/serialization/AccountingRuleCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/serialization/AccountingRuleCommandFromApiJsonDeserializer.java index fb1101b94..4bdcfcc5e 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/serialization/AccountingRuleCommandFromApiJsonDeserializer.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/serialization/AccountingRuleCommandFromApiJsonDeserializer.java @@ -6,55 +6,182 @@ package org.mifosplatform.accounting.rule.serialization; import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.mifosplatform.accounting.rule.api.AccountingRuleJsonInputParams; -import org.mifosplatform.accounting.rule.command.AccountingRuleCommand; +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.serialization.AbstractFromApiJsonDeserializer; +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 final class AccountingRuleCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer { +public class AccountingRuleCommandFromApiJsonDeserializer { + + /** + * The parameters supported for this command. + */ + private final Set supportedParameters = AccountingRuleJsonInputParams.getAllValues(); private final FromJsonHelper fromApiJsonHelper; @Autowired - public AccountingRuleCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonfromApiJsonHelper) { - this.fromApiJsonHelper = fromApiJsonfromApiJsonHelper; + public AccountingRuleCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; } - @Override - public AccountingRuleCommand commandFromApiJson(final String json) { + public void validateForCreate(final String json) { + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } final Type typeOfMap = new TypeToken>() {}.getType(); - final Set supportedParameters = AccountingRuleJsonInputParams.getAllValues(); - this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters); + + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("AccountingRule"); 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); + 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()); + + final String allowMultipleCredits = this.fromApiJsonHelper.extractStringNamed( + AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue(), element); + baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue()) + .value(allowMultipleCredits).ignoreIfNull().notBlank(); + final Boolean allowMultipleCreditEntries = this.fromApiJsonHelper.extractBooleanNamed( + AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue(), element); + baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue()) + .value(allowMultipleCreditEntries).ignoreIfNull(); + final String allowMultipleDebits = this.fromApiJsonHelper.extractStringNamed( + AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue(), element); + baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue()) + .value(allowMultipleDebits).ignoreIfNull().notBlank(); + final Boolean allowMultipleDebitEntries = this.fromApiJsonHelper.extractBooleanNamed( + AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue(), element); + baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue()) + .value(allowMultipleDebitEntries).ignoreIfNull(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + private void throwExceptionIfValidationWarningsExist(final List 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>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters); + + final List dataValidationErrors = new ArrayList(); + 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); - // final String[] creditTags = - this.fromApiJsonHelper.extractArrayNamed(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue(), element); - // final String[] debitTags = - this.fromApiJsonHelper.extractArrayNamed(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue(), element); + baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.DESCRIPTION.getValue()).value(description).ignoreIfNull() + .notExceedingLengthOf(500); - return new AccountingRuleCommand(id, officeId, accountToDebitId, accountToCreditId, name, description); + 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()); + + final String allowMultipleCredits = this.fromApiJsonHelper.extractStringNamed( + AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue(), element); + baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue()) + .value(allowMultipleCredits).ignoreIfNull().notBlank(); + final Boolean allowMultipleCreditEntries = this.fromApiJsonHelper.extractBooleanNamed( + AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue(), element); + baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue()) + .value(allowMultipleCreditEntries).ignoreIfNull(); + final String allowMultipleDebits = this.fromApiJsonHelper.extractStringNamed( + AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue(), element); + baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue()) + .value(allowMultipleDebits).ignoreIfNull().notBlank(); + final Boolean allowMultipleDebitEntries = this.fromApiJsonHelper.extractBooleanNamed( + AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue(), element); + baseDataValidator.reset().parameter(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue()) + .value(allowMultipleDebitEntries).ignoreIfNull(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); } -} \ No newline at end of file +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleDataValidator.java deleted file mode 100644 index 83b89af41..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleDataValidator.java +++ /dev/null @@ -1,152 +0,0 @@ -/** - * 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.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 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>() {}.getType(); - this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters); - - final List dataValidationErrors = new ArrayList(); - 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 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>() {}.getType(); - this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters); - - final List dataValidationErrors = new ArrayList(); - 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); - } -} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleReadPlatformService.java index 1ea43a58d..d8d6ab4dd 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleReadPlatformService.java @@ -11,7 +11,7 @@ import org.mifosplatform.accounting.rule.data.AccountingRuleData; public interface AccountingRuleReadPlatformService { - List retrieveAllAccountingRules(Long OfficeId); + List retrieveAllAccountingRules(Long OfficeId, boolean isAssociationParametersExists); AccountingRuleData retrieveAccountingRuleById(Long accountingRuleId); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleReadPlatformServiceImpl.java index e87499023..6546a4b84 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleReadPlatformServiceImpl.java @@ -20,6 +20,7 @@ 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.codes.data.CodeValueData; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; @@ -44,68 +45,22 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead this.glAccountReadPlatformService = glAccountReadPlatformService; } - // Will remove the old one if everything goes well. -/* private static final class AccountingRuleMapper implements RowMapper { - - 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,") - .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,") - .append("creditAccount.glName as creditAccountName, creditAccount.glCode as creditAccountGLCode ") - .append("from (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.debit_account_id ) as debitAccount,") - .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"); - 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"); - 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); - - return new AccountingRuleData(id, officeId, officeName, name, description, systemDefined, debitAccountData, creditAccountData); - } - }*/ - private static final class AccountingRuleDataExtractor implements ResultSetExtractor> { private final String schemaSql; private final JdbcTemplate jdbcTemplate; private final GLAccountReadPlatformService glAccountReadPlatformService; + private final boolean isAssociationParametersExists; - public AccountingRuleDataExtractor(final JdbcTemplate jdbcTemplate, final GLAccountReadPlatformService glAccountReadPlatformService) { + public AccountingRuleDataExtractor(final JdbcTemplate jdbcTemplate, + final GLAccountReadPlatformService glAccountReadPlatformService, final boolean isAssociationParametersExists) { this.jdbcTemplate = jdbcTemplate; this.glAccountReadPlatformService = glAccountReadPlatformService; + this.isAssociationParametersExists = isAssociationParametersExists; 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(" rule.description as description, rule.system_defined as systemDefined, rule.allow_multiple_debits as allowMultipleDebitEntries, rule.allow_multiple_credits as allowMultipleCreditEntries, ") .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 ") @@ -134,6 +89,8 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead final Long accountToDebitId = JdbcSupport.getLong(rs, "debitAccountId"); final Long accountToCreditId = JdbcSupport.getLong(rs, "creditAccountId"); final boolean systemDefined = rs.getBoolean("systemDefined"); + final boolean allowMultipleDebitEntries = rs.getBoolean("allowMultipleDebitEntries"); + final boolean allowMultipleCreditEntries = rs.getBoolean("allowMultipleCreditEntries"); final String debitAccountName = rs.getString("debitAccountName"); final String creditAccountName = rs.getString("creditAccountName"); final String debitAccountGLCode = rs.getString("debitAccountGLCode"); @@ -144,19 +101,21 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead final GLAccountData creditAccountData = accountToCreditId == null ? null : new GLAccountData(accountToCreditId, creditAccountName, creditAccountGLCode); accountingRuleData = new AccountingRuleData(id, officeId, officeName, name, description, systemDefined, - debitAccountData, creditAccountData); + allowMultipleDebitEntries, allowMultipleCreditEntries, debitAccountData, creditAccountData); } if (accountingRuleData.getCreditAccountHead() == null) { - final List creditTags = getCreditOrDebitTags(id, JournalEntryType.CREDIT.getValue()); - final List creditAccounts = this.glAccountReadPlatformService.retrieveAccountsByTagId(id, - JournalEntryType.CREDIT.getValue()); + final List creditTags = !this.isAssociationParametersExists ? getCreditOrDebitTags(id, + JournalEntryType.CREDIT.getValue()) : null; + final List creditAccounts = this.isAssociationParametersExists ? this.glAccountReadPlatformService + .retrieveAccountsByTagId(id, JournalEntryType.CREDIT.getValue()) : null; accountingRuleData = new AccountingRuleData(accountingRuleData, creditTags, creditAccounts, accountingRuleData.getDebitTags(), accountingRuleData.getDebitAccounts()); } if (accountingRuleData.getDebitAccountHead() == null) { - final List debitTags = getCreditOrDebitTags(id, JournalEntryType.DEBIT.getValue()); - final List debitAccounts = this.glAccountReadPlatformService.retrieveAccountsByTagId(id, - JournalEntryType.DEBIT.getValue()); + final List debitTags = !this.isAssociationParametersExists ? getCreditOrDebitTags(id, + JournalEntryType.DEBIT.getValue()) : null; + final List debitAccounts = this.isAssociationParametersExists ? this.glAccountReadPlatformService + .retrieveAccountsByTagId(id, JournalEntryType.DEBIT.getValue()) : null; accountingRuleData = new AccountingRuleData(accountingRuleData, accountingRuleData.getCreditTags(), accountingRuleData.getCreditAccounts(), debitTags, debitAccounts); } @@ -174,9 +133,9 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead } @Override - public List retrieveAllAccountingRules(final Long officeId) { + public List retrieveAllAccountingRules(final Long officeId, final boolean isAssociationParametersExists) { final AccountingRuleDataExtractor resultSetExtractor = new AccountingRuleDataExtractor(this.jdbcTemplate, - this.glAccountReadPlatformService); + this.glAccountReadPlatformService, isAssociationParametersExists); Object[] arguments = new Object[] {}; String sql = "select " + resultSetExtractor.schema() + " and system_defined=0 "; if (officeId != null) { @@ -192,7 +151,7 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead public AccountingRuleData retrieveAccountingRuleById(final Long accountingRuleId) { try { final AccountingRuleDataExtractor resultSetExtractor = new AccountingRuleDataExtractor(this.jdbcTemplate, - this.glAccountReadPlatformService); + this.glAccountReadPlatformService, false); final String sql = "select " + resultSetExtractor.schema() + " and rule.id = ?"; final Map extractedData = this.jdbcTemplate.query(sql, resultSetExtractor, @@ -208,7 +167,7 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead private static final class AccountingTagRuleDataMapper implements RowMapper { public String taggedAccountSchema() { - return " tag.id as id,tag.tag_id as tagId, tag.acc_type_enum as transactionType from acc_rule_tags tag " + return " tag.id as id,tag.tag_id as tagId, tag.acc_type_enum as transactionType, cv.code_value as tagName from m_code_value cv join acc_rule_tags tag on tag.tag_id=cv.id " + "join acc_accounting_rule rule on tag.acc_rule_id=rule.id "; } @@ -217,8 +176,10 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead final Long id = rs.getLong("id"); final Long tagId = rs.getLong("tagId"); final Integer transactionType = JdbcSupport.getInteger(rs, "transactionType"); + final String tagName = rs.getString("tagName"); + final CodeValueData tag = CodeValueData.instance(tagId, tagName); final EnumOptionData transactionTypeEnum = AccountingEnumerations.journalEntryType(transactionType); - return new AccountingTagRuleData(id, tagId, transactionTypeEnum); + return new AccountingTagRuleData(id, tag, transactionTypeEnum); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleWritePlatformServiceJpaRepositoryImpl.java index 483b8a6a2..ba2b3916f 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/rule/service/AccountingRuleWritePlatformServiceJpaRepositoryImpl.java @@ -6,9 +6,14 @@ package org.mifosplatform.accounting.rule.service; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; 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.glaccount.domain.GLAccount; import org.mifosplatform.accounting.glaccount.domain.GLAccountRepositoryWrapper; @@ -18,7 +23,9 @@ 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.AccountingRuleDataException; 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.codes.exception.CodeValueNotFoundException; @@ -45,13 +52,13 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco private final AccountingRuleRepository accountingRuleRepository; private final GLAccountRepositoryWrapper accountRepositoryWrapper; private final OfficeRepository officeRepository; - private final AccountingRuleDataValidator fromApiJsonDeserializer; + private final AccountingRuleCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final CodeValueRepository codeValueRepository; @Autowired public AccountingRuleWritePlatformServiceJpaRepositoryImpl(final AccountingRuleRepositoryWrapper accountingRuleRepositoryWrapper, final GLAccountRepositoryWrapper accountRepositoryWrapper, final OfficeRepository officeRepository, - final AccountingRuleRepository ruleRepository, final AccountingRuleDataValidator fromApiJsonDeserializer, + final AccountingRuleRepository ruleRepository, final AccountingRuleCommandFromApiJsonDeserializer fromApiJsonDeserializer, final CodeValueRepository codeValueRepository) { this.accountRepositoryWrapper = accountRepositoryWrapper; this.officeRepository = officeRepository; @@ -67,8 +74,9 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco */ 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())); } + if (realCause.getMessage().contains("accounting_rule_name_unique")) { + throw new AccountingRuleDuplicateException(command.stringValueOfParameterNamed(AccountingRuleJsonInputParams.NAME.getValue())); + } else if (realCause.getMessage().contains("UNIQUE_ACCOUNT_RULE_TAGS")) { throw new AccountingRuleDuplicateException(); } logger.error(dve.getMessage(), dve); throw new PlatformDataIntegrityException("error.msg.accounting.rule.unknown.data.integrity.issue", @@ -104,84 +112,204 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco // 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 Set incomingDebitTags = new HashSet(Arrays.asList(debitTags)); + final Set incomingCreditTags = new HashSet(Arrays.asList(creditTags)); final Long accountToDebitId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue()); final Long accountToCreditId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue()); + + boolean allowMultipleCreditEntries = false; + boolean allowMultipleDebitEntries = false; GLAccount debitAccount = null; GLAccount creditAccount = null; List accountingTagRules = new ArrayList(); if ((accountToDebitId != null && debitTags != null) || (accountToDebitId == null && debitTags == null)) { - // TODO- Throw Appropriate exception - throw new RuntimeException("Please Specify debitTags or accountToDebitId"); + throw new AccountingRuleDataException(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue(), + AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue()); } else if (accountToDebitId != null) { debitAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToDebitId); } else if (debitTags != null) { - accountingTagRules = saveDebitOrCreditTags(debitTags, JournalEntryType.DEBIT, accountingTagRules); + accountingTagRules = saveDebitOrCreditTags(incomingDebitTags, JournalEntryType.DEBIT, accountingTagRules); + allowMultipleDebitEntries = command + .booleanPrimitiveValueOfParameterNamed(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue()); } if ((accountToCreditId != null && creditTags != null) || (accountToCreditId == null && creditTags == null)) { - // TODO- Throw Appropriate exception - throw new RuntimeException("Please Specify debitTags or accountToDebitId"); + throw new AccountingRuleDataException(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue(), + AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue()); } else if (accountToCreditId != null) { creditAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToCreditId); } else if (creditTags != null) { - accountingTagRules = saveDebitOrCreditTags(creditTags, JournalEntryType.CREDIT, accountingTagRules); + accountingTagRules = saveDebitOrCreditTags(incomingCreditTags, JournalEntryType.CREDIT, accountingTagRules); + allowMultipleCreditEntries = command + .booleanPrimitiveValueOfParameterNamed(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue()); } - final AccountingRule accountingRule = AccountingRule.fromJson(office, debitAccount, creditAccount, command); - accountingTagRules = accountingRule.updateAccountingRuleForTags(accountingTagRules); + final AccountingRule accountingRule = AccountingRule.fromJson(office, debitAccount, creditAccount, command, + allowMultipleCreditEntries, allowMultipleDebitEntries); + accountingRule.updateAccountingRuleForTags(accountingTagRules); return accountingRule; } - // TODO- This update mehtod should update based on new changes made for - // createAccountingRule. @Transactional @Override public CommandProcessingResult updateAccountingRule(final Long accountingRuleId, final JsonCommand command) { - this.fromApiJsonDeserializer.validateForUpdate(command.json()); + try { - Long officeId = null; - if (command.parameterExists(AccountingRuleJsonInputParams.OFFICE_ID.getValue())) { - officeId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.OFFICE_ID.getValue()); + this.fromApiJsonDeserializer.validateForUpdate(command.json()); + + 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()); + } + + String[] debitTags = null; + if (command.parameterExists(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue())) { + debitTags = command.arrayValueOfParameterNamed(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue()); + } + + String[] creditTags = null; + if (command.parameterExists(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue())) { + creditTags = command.arrayValueOfParameterNamed(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue()); + } + + if (accountToDebitId != null && debitTags != null) { throw new AccountingRuleDataException( + AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue(), AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue()); } + + if (accountToCreditId != null && creditTags != null) { throw new AccountingRuleDataException( + AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue(), + AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue()); } + + boolean allowMultipleCreditEntries = false; + if (command.parameterExists(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue())) { + allowMultipleCreditEntries = command + .booleanPrimitiveValueOfParameterNamed(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_CREDIT_ENTRIES.getValue()); + } + + boolean allowMultipleDebitEntries = false; + if (command.parameterExists(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue())) { + allowMultipleDebitEntries = command + .booleanPrimitiveValueOfParameterNamed(AccountingRuleJsonInputParams.ALLOW_MULTIPLE_DEBIT_ENTRIES.getValue()); + } + + final AccountingRule accountingRule = this.accountingRuleRepositoryWrapper.findOneWithNotFoundDetection(accountingRuleId); + final Map changesOnly = accountingRule.update(command); + + if (accountToDebitId != null && changesOnly.containsKey(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue())) { + final GLAccount accountToDebit = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToDebitId); + accountingRule.updateDebitAccount(accountToDebit); + accountingRule.updateTags(JournalEntryType.CREDIT); + } + + if (accountToCreditId != null && changesOnly.containsKey(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue())) { + final GLAccount accountToCredit = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToCreditId); + accountingRule.updateCreditAccount(accountToCredit); + accountingRule.updateTags(JournalEntryType.DEBIT); + } + + if (creditTags != null && creditTags.length > 0 + && command.parameterExists(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue())) { + + final Set creditTagsToAdd = determineCreditTagToAddAndRemoveOldTags(creditTags, JournalEntryType.CREDIT, + accountingRule); + + if (!creditTagsToAdd.isEmpty()) { + List accountingTagRules = new ArrayList(); + accountingTagRules = saveDebitOrCreditTags(creditTagsToAdd, JournalEntryType.CREDIT, accountingTagRules); + accountingRule.updateAccountingRuleForTags(accountingTagRules); + accountingRule.updateCreditAccount(null); + if (allowMultipleCreditEntries) { + accountingRule.updateAllowMultipleCreditEntries(allowMultipleCreditEntries); + } + changesOnly.put(AccountingRuleJsonInputParams.CREDIT_ACCOUNT_TAGS.getValue(), creditTagsToAdd); + } + + } + + if (debitTags != null && debitTags.length > 0 + && command.parameterExists(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue())) { + final Set debitTagsToAdd = determineCreditTagToAddAndRemoveOldTags(debitTags, JournalEntryType.DEBIT, + accountingRule); + if (!debitTagsToAdd.isEmpty()) { + List accountingTagRules = new ArrayList(); + accountingTagRules = saveDebitOrCreditTags(debitTagsToAdd, JournalEntryType.DEBIT, accountingTagRules); + accountingRule.updateAccountingRuleForTags(accountingTagRules); + accountingRule.updateDebitAccount(null); + if (allowMultipleDebitEntries) { + accountingRule.updateAllowMultipleDebitEntries(allowMultipleDebitEntries); + } + changesOnly.put(AccountingRuleJsonInputParams.DEBIT_ACCOUNT_TAGS.getValue(), debitTagsToAdd); + } + } + + if (officeId != null && 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(); + } catch (final DataIntegrityViolationException dve) { + handleAccountingRuleIntegrityIssues(command, dve); + return CommandProcessingResult.empty(); } - Long accountToDebitId = null; - if (command.parameterExists(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue())) { - accountToDebitId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue()); + } + + private Set determineCreditTagToAddAndRemoveOldTags(final String[] creditOrDebitTags, final JournalEntryType type, + final AccountingRule accountingRule) { + + final Set incomingTags = new HashSet(Arrays.asList(creditOrDebitTags)); + final Set existingTags = accountingRule.getAccountingTagRulesByType(type); + final Set existingTagIds = retrieveExistingTagIds(existingTags); + final Set tagsToAdd = new HashSet(); + final Set tagsToRemove = existingTagIds; + final Map accountsToRemove = new HashMap(); + + for (final String tagId : incomingTags) { + if (existingTagIds.contains(tagId)) { + tagsToRemove.remove(tagId); + } else { + tagsToAdd.add(tagId); + } } - Long accountToCreditId = null; - if (command.parameterExists(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue())) { - accountToCreditId = command.longValueOfParameterNamed(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue()); + if (!tagsToRemove.isEmpty()) { + for (final String tagId : tagsToRemove) { + for (final AccountingTagRule accountingTagRule : existingTags) { + if (tagId.equals(accountingTagRule.getTagId().toString())) { + accountsToRemove.put(accountingTagRule.getId(), accountingTagRule); + } + } + } + accountingRule.removeOldTags(new ArrayList(accountsToRemove.values())); } + return tagsToAdd; + } - final AccountingRule accountingRule = this.accountingRuleRepositoryWrapper.findOneWithNotFoundDetection(accountingRuleId); - final Map changesOnly = accountingRule.update(command); - - if (accountToDebitId != null && changesOnly.containsKey(AccountingRuleJsonInputParams.ACCOUNT_TO_DEBIT.getValue())) { - final GLAccount accountToDebit = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToDebitId); - accountingRule.setAccountToDebit(accountToDebit); + private Set retrieveExistingTagIds(final Set existingCreditTags) { + final Set existingCreditTagIds = new HashSet(); + for (final AccountingTagRule accountingTagRule : existingCreditTags) { + existingCreditTagIds.add(accountingTagRule.getTagId().toString()); } - - if (accountToCreditId != null && changesOnly.containsKey(AccountingRuleJsonInputParams.ACCOUNT_TO_CREDIT.getValue())) { - final GLAccount accountToCredit = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToCreditId); - accountingRule.setAccountToCredit(accountToCredit); - } - - if (officeId != null && 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(); + return existingCreditTagIds; } @Transactional @@ -192,27 +320,16 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco 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 accountingTagRules = saveDebitOrCreditTags(creditOrDebitTagArray, transactionType); - } else { - throw new RuntimeException("Please Specify debitTags or accountToDebitId"); - } - return creditOrDebitAccount; - }*/ - - private List saveDebitOrCreditTags(final String[] creditOrDebitTagArray, final JournalEntryType transactionType, + private List saveDebitOrCreditTags(final Set creditOrDebitTagArray, final JournalEntryType transactionType, final List accountingTagRules) { for (final String creditOrDebitTag : creditOrDebitTagArray) { - final Long creditOrDebitTagIdLongValue = Long.valueOf(creditOrDebitTag); - final CodeValue creditOrDebitAccount = this.codeValueRepository.findOne(creditOrDebitTagIdLongValue); - if (creditOrDebitAccount == null) { throw new CodeValueNotFoundException(creditOrDebitTagIdLongValue); } - final AccountingTagRule accountingTagRule = AccountingTagRule.create(creditOrDebitAccount, transactionType.getValue()); - accountingTagRules.add(accountingTagRule); + if (creditOrDebitTag != null && StringUtils.isNotBlank(creditOrDebitTag)) { + final Long creditOrDebitTagIdLongValue = Long.valueOf(creditOrDebitTag); + final CodeValue creditOrDebitAccount = this.codeValueRepository.findOne(creditOrDebitTagIdLongValue); + if (creditOrDebitAccount == null) { throw new CodeValueNotFoundException(creditOrDebitTagIdLongValue); } + final AccountingTagRule accountingTagRule = AccountingTagRule.create(creditOrDebitAccount, transactionType.getValue()); + accountingTagRules.add(accountingTagRule); + } } return accountingTagRules; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java index f9a23c779..6517087e8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java @@ -10,7 +10,6 @@ package org.mifosplatform.infrastructure.codes.data; */ public class CodeValueData { - @SuppressWarnings("unused") private final Long id; @SuppressWarnings("unused") @@ -32,4 +31,8 @@ public class CodeValueData { this.name = name; this.position = position; } + + public Long getId() { + return id; + } } \ No newline at end of file