From 0d18ddc034e3223d7ccea5e3efac21ad2864c472 Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Wed, 8 May 2013 14:42:57 +0100 Subject: [PATCH 1/2] MIFOSX-343: update quick typo --- .../commands/service/AuditReadPlatformServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/AuditReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/AuditReadPlatformServiceImpl.java index 0d81aac5a..5a5ce6482 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/AuditReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/AuditReadPlatformServiceImpl.java @@ -221,7 +221,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService { if (commandAsJsonMap.containsKey("clientId")) { commandAsJsonMap.remove("clientId"); - final Long clientId = auditObject.get("officeId").getAsLong(); + final Long clientId = auditObject.get("clientId").getAsLong(); if (clientId != null) { ClientData client = this.clientReadPlatformService.retrieveOne(clientId); commandAsJsonMap.put("clientName", client.displayName()); From 8b4de075a2cd7a6caf7dcf9e984fdfd7f64864c2 Mon Sep 17 00:00:00 2001 From: goutham-M Date: Mon, 6 May 2013 18:09:40 +0530 Subject: [PATCH 2/2] SQL Retrievals for Hierarchical ChartofAccounts Fixing Naming Convention for COA options Tag ID for GLAccounts --- ...dd_hierarchy_column_for_acc_gl_account.sql | 1 + ...__add_tag_id_column_for_acc_gl_account.sql | 5 ++ .../common/AccountingConstants.java | 6 +++ .../api/GLAccountJsonInputParams.java | 2 +- .../glaccount/api/GLAccountsApiResource.java | 38 +++++++++++-- .../glaccount/command/GLAccountCommand.java | 7 ++- .../glaccount/data/GLAccountData.java | 53 +++++++++++++++++-- .../glaccount/domain/GLAccount.java | 35 ++++++++++-- .../glaccount/domain/GLAccountType.java | 20 +++++++ ...AccountCommandFromApiJsonDeserializer.java | 5 +- .../service/GLAccountReadPlatformService.java | 2 + .../GLAccountReadPlatformServiceImpl.java | 22 +++++--- ...WritePlatformServiceJpaRepositoryImpl.java | 45 ++++++++++++++-- 13 files changed, 216 insertions(+), 25 deletions(-) create mode 100644 mifosng-db/migrations/core_db/V35__add_hierarchy_column_for_acc_gl_account.sql create mode 100644 mifosng-db/migrations/core_db/V36__add_tag_id_column_for_acc_gl_account.sql diff --git a/mifosng-db/migrations/core_db/V35__add_hierarchy_column_for_acc_gl_account.sql b/mifosng-db/migrations/core_db/V35__add_hierarchy_column_for_acc_gl_account.sql new file mode 100644 index 000000000..f84fceb5c --- /dev/null +++ b/mifosng-db/migrations/core_db/V35__add_hierarchy_column_for_acc_gl_account.sql @@ -0,0 +1 @@ +ALTER TABLE `acc_gl_account` ADD COLUMN `hierarchy` varchar(50) AFTER `parent_id`; \ No newline at end of file diff --git a/mifosng-db/migrations/core_db/V36__add_tag_id_column_for_acc_gl_account.sql b/mifosng-db/migrations/core_db/V36__add_tag_id_column_for_acc_gl_account.sql new file mode 100644 index 000000000..9dadf2fbe --- /dev/null +++ b/mifosng-db/migrations/core_db/V36__add_tag_id_column_for_acc_gl_account.sql @@ -0,0 +1,5 @@ +ALTER TABLE `acc_gl_account` +ADD COLUMN `tag_id` INT(11) NULL DEFAULT NULL AFTER `classification_enum`, +ADD INDEX `FKGLACC000000002` (`tag_id`), +ADD CONSTRAINT `FKGLACC000000002` FOREIGN KEY (`tag_id`) REFERENCES `m_code_value` (`id`); +INSERT into m_code(`code_name`,`is_system_defined`) values ('AssetAccountTags',1),('LiabilityAccountTags',1),('EquityAccountTags',1),('IncomeAccountTags',1),('ExpenseAccountTags',1); \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/common/AccountingConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/common/AccountingConstants.java index 2353c00d9..14dd6904b 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/common/AccountingConstants.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/common/AccountingConstants.java @@ -101,5 +101,11 @@ public class AccountingConstants { return this.value; } } + + public static final String ASSESTS_TAG_OPTION_CODE_NAME = "AssetAccountTags"; + public static final String LIABILITIES_TAG_OPTION_CODE_NAME = "LiabilityAccountTags"; + public static final String EQUITY_TAG_OPTION_CODE_NAME = "EquityAccountTags"; + public static final String INCOME_TAG_OPTION_CODE_NAME = "IncomeAccountTags"; + public static final String EXPENSES_TAG_OPTION_CODE_NAME = "ExpenseAccountTags"; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountJsonInputParams.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountJsonInputParams.java index acbfc820a..83d0c0b58 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountJsonInputParams.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountJsonInputParams.java @@ -13,7 +13,7 @@ import java.util.Set; ***/ public enum GLAccountJsonInputParams { ID("id"), NAME("name"), PARENT_ID("parentId"), GL_CODE("glCode"), DISABLED("disabled"), MANUAL_ENTRIES_ALLOWED("manualEntriesAllowed"), TYPE( - "type"), USAGE("usage"), DESCRIPTION("description"); + "type"), USAGE("usage"), DESCRIPTION("description"), TAGID("tagId"); private final String value; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountsApiResource.java index ce6d5a91a..d3f1dd9bc 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountsApiResource.java @@ -6,6 +6,7 @@ package org.mifosplatform.accounting.glaccount.api; import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -23,12 +24,16 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; +import org.mifosplatform.accounting.common.AccountingConstants; import org.mifosplatform.accounting.common.AccountingDropdownReadPlatformService; import org.mifosplatform.accounting.glaccount.data.GLAccountData; +import org.mifosplatform.accounting.glaccount.domain.GLAccountType; import org.mifosplatform.accounting.glaccount.service.GLAccountReadPlatformService; import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.service.CommandWrapperBuilder; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; +import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.EnumOptionData; @@ -45,7 +50,9 @@ import org.springframework.stereotype.Component; public class GLAccountsApiResource { private static final Set RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "name", "parentId", "glCode", - "disabled", "manualEntriesAllowed", "type", "usage", "description")); + "disabled", "manualEntriesAllowed", "type", "usage", "description", "assetHeaderAccountOptions", "liabilityHeaderAccountOptions", + "equityHeaderAccountOptions", "incomeHeaderAccountOptions", "expenseHeaderAccountOptions", "nameDecorated", "tagId", + "allowedAssetsTagOptions", "allowedLiabilitiesTagOptions", "allowedEquityTagOptions", "allowedIncomeTagOptions", "allowedExpensesTagOptions")); private final String resourceNameForPermission = "GLACCOUNT"; @@ -55,18 +62,20 @@ public class GLAccountsApiResource { private final ApiRequestParameterHelper apiRequestParameterHelper; private final PlatformSecurityContext context; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; - + private final CodeValueReadPlatformService codeValueReadPlatformService; + @Autowired public GLAccountsApiResource(final PlatformSecurityContext context, final GLAccountReadPlatformService glAccountReadPlatformService, final DefaultToApiJsonSerializer toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, - final AccountingDropdownReadPlatformService dropdownReadPlatformService) { + final AccountingDropdownReadPlatformService dropdownReadPlatformService, final CodeValueReadPlatformService codeValueReadPlatformService) { this.context = context; this.apiRequestParameterHelper = apiRequestParameterHelper; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.apiJsonSerializerService = toApiJsonSerializer; this.glAccountReadPlatformService = glAccountReadPlatformService; this.dropdownReadPlatformService = dropdownReadPlatformService; + this.codeValueReadPlatformService = codeValueReadPlatformService; } @GET @@ -158,6 +167,27 @@ public class GLAccountsApiResource { private GLAccountData handleTemplate(final GLAccountData glAccountData) { final List accountTypeOptions = this.dropdownReadPlatformService.retrieveGLAccountTypeOptions(); final List usageOptions = this.dropdownReadPlatformService.retrieveGLAccountUsageOptions(); - return new GLAccountData(glAccountData, accountTypeOptions, usageOptions); + final List assetHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService.retrieveAllEnabledHeaderGLAccounts(GLAccountType.ASSET)); + final List liabilityHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService.retrieveAllEnabledHeaderGLAccounts(GLAccountType.LIABILITY)); + final List equityHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService.retrieveAllEnabledHeaderGLAccounts(GLAccountType.EQUITY)); + final List incomeHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService.retrieveAllEnabledHeaderGLAccounts(GLAccountType.INCOME)); + final List expenseHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService.retrieveAllEnabledHeaderGLAccounts(GLAccountType.EXPENSE)); + final Collection allowedAssetsTagOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME); + final Collection allowedLiabilitiesTagOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME); + final Collection allowedEquityTagOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME); + final Collection allowedIncomeTagOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.INCOME_TAG_OPTION_CODE_NAME); + final Collection allowedExpensesTagOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode(AccountingConstants.EXPENSES_TAG_OPTION_CODE_NAME); + + return new GLAccountData(glAccountData, accountTypeOptions, usageOptions, assetHeaderAccountOptions, liabilityHeaderAccountOptions, + equityHeaderAccountOptions, incomeHeaderAccountOptions, expenseHeaderAccountOptions, allowedAssetsTagOptions, + allowedLiabilitiesTagOptions, allowedEquityTagOptions, allowedIncomeTagOptions, allowedExpensesTagOptions); + } + + private List defaultIfEmpty(final List list) { + List returnList = null; + if (list != null && !list.isEmpty()) { + returnList = list; + } + return returnList; } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/command/GLAccountCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/command/GLAccountCommand.java index f279ed9b9..1f498228a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/command/GLAccountCommand.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/command/GLAccountCommand.java @@ -30,9 +30,10 @@ public class GLAccountCommand { private final Integer usage; private final Integer type; private final String description; + private final Long tagId; public GLAccountCommand(final Long id, final String name, final Long parentId, final String glCode, final Boolean disabled, - final Boolean manualEntriesAllowed, final Integer type, final Integer usage, final String description) { + final Boolean manualEntriesAllowed, final Integer type, final Integer usage, final String description, final Long tagId) { this.id = id; this.name = name; this.parentId = parentId; @@ -42,6 +43,7 @@ public class GLAccountCommand { this.type = type; this.usage = usage; this.description = description; + this.tagId = tagId; } public void validateForCreate() { @@ -69,6 +71,8 @@ public class GLAccountCommand { baseDataValidator.reset().parameter(GLAccountJsonInputParams.MANUAL_ENTRIES_ALLOWED.getValue()).value(this.manualEntriesAllowed) .notBlank(); + + baseDataValidator.reset().parameter(GLAccountJsonInputParams.TAGID.getValue()).value(this.tagId).ignoreIfNull().longGreaterThanZero(); if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); } @@ -102,6 +106,7 @@ public class GLAccountCommand { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); } + baseDataValidator.reset().parameter(GLAccountJsonInputParams.TAGID.getValue()).value(this.tagId).ignoreIfNull().longGreaterThanZero(); } public boolean isHeaderAccount() { 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 e3368f80b..e427fc263 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 @@ -5,11 +5,13 @@ */ package org.mifosplatform.accounting.glaccount.data; +import java.util.Collection; import java.util.List; import org.mifosplatform.accounting.common.AccountingEnumerations; import org.mifosplatform.accounting.glaccount.domain.GLAccountType; import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.core.data.EnumOptionData; /** @@ -29,13 +31,26 @@ public class GLAccountData { private final EnumOptionData type; private final EnumOptionData usage; private final String description; + private final String nameDecorated; + private final CodeValueData tagId; // templates final List accountTypeOptions; final List usageOptions; + final List assetHeaderAccountOptions; + final List liabilityHeaderAccountOptions; + final List equityHeaderAccountOptions; + final List incomeHeaderAccountOptions; + final List expenseHeaderAccountOptions; + final Collection allowedAssetsTagOptions; + final Collection allowedLiabilitiesTagOptions; + final Collection allowedEquityTagOptions; + final Collection allowedIncomeTagOptions; + final Collection allowedExpensesTagOptions; public GLAccountData(final Long id, final String name, final Long parentId, final String glCode, final boolean disabled, - final boolean manualEntriesAllowed, final EnumOptionData type, final EnumOptionData usage, final String description) { + final boolean manualEntriesAllowed, final EnumOptionData type, final EnumOptionData usage, final String description, + final String nameDecorated, final CodeValueData tagId) { this.id = id; this.name = name; this.parentId = parentId; @@ -45,12 +60,29 @@ public class GLAccountData { this.type = type; this.usage = usage; this.description = description; + this.nameDecorated = nameDecorated; + this.tagId = tagId; this.accountTypeOptions = null; this.usageOptions = null; + this.assetHeaderAccountOptions = null; + this.liabilityHeaderAccountOptions = null; + this.equityHeaderAccountOptions = null; + this.incomeHeaderAccountOptions = null; + this.expenseHeaderAccountOptions = null; + this.allowedAssetsTagOptions = null; + this.allowedLiabilitiesTagOptions = null; + this.allowedEquityTagOptions=null; + this.allowedIncomeTagOptions=null; + this.allowedExpensesTagOptions=null; } public GLAccountData(final GLAccountData accountData, final List accountTypeOptions, - final List usageOptions) { + final List usageOptions, final List assetHeaderAccountOptions, + final List liabilityHeaderAccountOptions, final List equityHeaderAccountOptions, + final List incomeHeaderAccountOptions, final List expenseHeaderAccountOptions, + final Collection allowedAssetsTagOptions, final Collection allowedLiabilitiesTagOptions, + final Collection allowedEquityTagOptions, final Collection allowedIncomeTagOptions, + final Collection allowedExpensesTagOptions) { this.id = accountData.id; this.name = accountData.name; this.parentId = accountData.parentId; @@ -60,8 +92,20 @@ public class GLAccountData { this.type = accountData.type; this.usage = accountData.usage; this.description = accountData.description; + this.nameDecorated = accountData.nameDecorated; + this.tagId = accountData.tagId; this.accountTypeOptions = accountTypeOptions; this.usageOptions = usageOptions; + this.assetHeaderAccountOptions = assetHeaderAccountOptions; + this.liabilityHeaderAccountOptions = liabilityHeaderAccountOptions; + this.equityHeaderAccountOptions = equityHeaderAccountOptions; + this.incomeHeaderAccountOptions = incomeHeaderAccountOptions; + this.expenseHeaderAccountOptions = expenseHeaderAccountOptions; + this.allowedAssetsTagOptions = allowedAssetsTagOptions; + this.allowedLiabilitiesTagOptions = allowedLiabilitiesTagOptions; + this.allowedEquityTagOptions = allowedEquityTagOptions; + this.allowedIncomeTagOptions = allowedIncomeTagOptions; + this.allowedExpensesTagOptions = allowedExpensesTagOptions; } public static GLAccountData sensibleDefaultsForNewGLAccountCreation() { @@ -74,6 +118,9 @@ public class GLAccountData { final EnumOptionData type = AccountingEnumerations.gLAccountType(GLAccountType.ASSET); final EnumOptionData usage = AccountingEnumerations.gLAccountUsage(GLAccountUsage.DETAIL); final String description = null; - return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, type, usage, description); + final String nameDecorated = null; + final CodeValueData tagId = null; + return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, type, usage, description, nameDecorated, tagId); } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccount.java index 812692b15..527564160 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccount.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccount.java @@ -22,6 +22,7 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; import org.mifosplatform.accounting.glaccount.api.GLAccountJsonInputParams; +import org.mifosplatform.infrastructure.codes.domain.CodeValue; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -29,10 +30,12 @@ import org.springframework.data.jpa.domain.AbstractPersistable; @Table(name = "acc_gl_account", uniqueConstraints = { @UniqueConstraint(columnNames = { "gl_code" }, name = "acc_gl_code") }) public class GLAccount extends AbstractPersistable { - @SuppressWarnings("unused") - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") private GLAccount parent; + + @Column(name = "hierarchy", nullable = true, length = 50) + private String hierarchy; @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") @@ -58,13 +61,18 @@ public class GLAccount extends AbstractPersistable { @Column(name = "description", nullable = true, length = 500) private String description; + + @SuppressWarnings("unused") + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "tag_id") + private CodeValue tagId; protected GLAccount() { // } private GLAccount(final GLAccount parent, final String name, final String glCode, final boolean disabled, - final boolean manualEntriesAllowed, final Integer type, final Integer usage, final String description) { + final boolean manualEntriesAllowed, final Integer type, final Integer usage, final String description, final CodeValue tagId) { this.name = StringUtils.defaultIfEmpty(name, null); this.glCode = StringUtils.defaultIfEmpty(glCode, null); this.disabled = BooleanUtils.toBooleanDefaultIfNull(disabled, false); @@ -73,9 +81,10 @@ public class GLAccount extends AbstractPersistable { this.type = type; this.description = StringUtils.defaultIfEmpty(description, null); this.parent = parent; + this.tagId = tagId; } - public static GLAccount fromJson(final GLAccount parent, final JsonCommand command) { + public static GLAccount fromJson(final GLAccount parent, final JsonCommand command, CodeValue glAccountTagType) { final String name = command.stringValueOfParameterNamed(GLAccountJsonInputParams.NAME.getValue()); final String glCode = command.stringValueOfParameterNamed(GLAccountJsonInputParams.GL_CODE.getValue()); final boolean disabled = command.booleanPrimitiveValueOfParameterNamed(GLAccountJsonInputParams.DISABLED.getValue()); @@ -84,7 +93,7 @@ public class GLAccount extends AbstractPersistable { final Integer usage = command.integerValueSansLocaleOfParameterNamed(GLAccountJsonInputParams.USAGE.getValue()); final Integer type = command.integerValueSansLocaleOfParameterNamed(GLAccountJsonInputParams.TYPE.getValue()); final String description = command.stringValueOfParameterNamed(GLAccountJsonInputParams.DESCRIPTION.getValue()); - return new GLAccount(parent, name, glCode, disabled, manualEntriesAllowed, type, usage, description); + return new GLAccount(parent, name, glCode, disabled, manualEntriesAllowed, type, usage, description, glAccountTagType); } public Map update(final JsonCommand command) { @@ -198,5 +207,21 @@ public class GLAccount extends AbstractPersistable { public Integer getType() { return this.type; } + + public void generateHierarchy() { + if (parent != null) { + this.hierarchy = this.parent.hierarchyOf(this.getId()); + } else { + this.hierarchy = "."; + } + } + + private String hierarchyOf(final Long id) { + return this.hierarchy + id.toString() + "."; + } + + public boolean isDetailAccount() { + return GLAccountUsage.DETAIL.getValue().equals(this.usage); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccountType.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccountType.java index 57275e1b5..07dbe5258 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccountType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccountType.java @@ -66,4 +66,24 @@ public enum GLAccountType { return name().toString(); } + public boolean isAssetType() { + return this.value.equals(GLAccountType.ASSET.getValue()); + } + + public boolean isLiabilityType() { + return this.value.equals(GLAccountType.LIABILITY.getValue()); + } + + public boolean isEquityType() { + return this.value.equals(GLAccountType.EQUITY.getValue()); + } + + public boolean isIncomeType() { + return this.value.equals(GLAccountType.INCOME.getValue()); + } + + public boolean isExpenseType() { + return this.value.equals(GLAccountType.EXPENSE.getValue()); + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/serialization/GLAccountCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/serialization/GLAccountCommandFromApiJsonDeserializer.java index e8b147ab3..ac9301a79 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/serialization/GLAccountCommandFromApiJsonDeserializer.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/serialization/GLAccountCommandFromApiJsonDeserializer.java @@ -57,7 +57,8 @@ public final class GLAccountCommandFromApiJsonDeserializer extends AbstractFromA final Integer type = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(GLAccountJsonInputParams.TYPE.getValue(), element); final Integer usage = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(GLAccountJsonInputParams.USAGE.getValue(), element); final String description = this.fromApiJsonHelper.extractStringNamed(GLAccountJsonInputParams.DESCRIPTION.getValue(), element); - - return new GLAccountCommand(id, name, parentId, glCode, disabled, manualEntriesAllowed, type, usage, description); + final Long tagId = this.fromApiJsonHelper.extractLongNamed(GLAccountJsonInputParams.TAGID.getValue(), element); + + return new GLAccountCommand(id, name, parentId, glCode, disabled, manualEntriesAllowed, type, usage, description, tagId); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformService.java index 5f51428f6..3e118df5e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformService.java @@ -22,4 +22,6 @@ public interface GLAccountReadPlatformService { List retrieveAllEnabledDetailGLAccounts(GLAccountType accountType); GLAccountData retrieveNewGLAccountDetails(); + + List retrieveAllEnabledHeaderGLAccounts(GLAccountType accountType); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java index 52ea07020..9f3d9ab85 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java @@ -17,6 +17,7 @@ import org.mifosplatform.accounting.glaccount.domain.GLAccountType; import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage; import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidClassificationException; import org.mifosplatform.accounting.glaccount.exception.GLAccountNotFoundException; +import org.mifosplatform.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; @@ -30,6 +31,7 @@ import org.springframework.stereotype.Service; public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformService { private final JdbcTemplate jdbcTemplate; + private final static String nameDecoratedBaseOnHierarchy = "concat(substring('........................................', 1, ((LENGTH(hierarchy) - LENGTH(REPLACE(hierarchy, '.', '')) - 1) * 4)), name)"; @Autowired public GLAccountReadPlatformServiceImpl(final TenantAwareRoutingDataSource dataSource) { @@ -39,9 +41,9 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe private static final class GLAccountMapper implements RowMapper { public String schema() { - return " id as id, name as name, parent_id as parentId, gl_code as glCode, disabled as disabled, manual_journal_entries_allowed as manualEntriesAllowed, " - + "classification_enum as classification, account_usage as accountUsage, description as description " - + "from acc_gl_account"; + return " gl.id as id, name as name, parent_id as parentId, gl_code as glCode, disabled as disabled, manual_journal_entries_allowed as manualEntriesAllowed, " + + "classification_enum as classification, account_usage as accountUsage, description as description, "+nameDecoratedBaseOnHierarchy +"as nameDecorated, " + + "cv.id as codeId, cv.code_value as codeValue from acc_gl_account gl left join m_code_value cv on tag_id=cv.id"; } @Override @@ -58,8 +60,11 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe final int usageId = JdbcSupport.getInteger(rs, "accountUsage"); final EnumOptionData usage = AccountingEnumerations.gLAccountUsage(usageId); final String description = rs.getString("description"); - - return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, accountType, usage, description); + final String nameDecorated = rs.getString("nameDecorated"); + final Long codeId = rs.getLong("codeId"); + final String codeValue = rs.getString("codeValue"); + CodeValueData tagId = CodeValueData.instance(codeId, codeValue); + return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, accountType, usage, description, nameDecorated, tagId); } } @@ -151,7 +156,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe try { final GLAccountMapper rm = new GLAccountMapper(); - final String sql = "select " + rm.schema() + " where id = ?"; + final String sql = "select " + rm.schema() + " where gl.id = ?"; final GLAccountData glAccountData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { glAccountId }); @@ -190,4 +195,9 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe return GLAccountData.sensibleDefaultsForNewGLAccountCreation(); } + @Override + public List retrieveAllEnabledHeaderGLAccounts(GLAccountType accountType) { + return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.HEADER.getValue(), null, false); + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java index c66c483bc..6aee906b6 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java @@ -8,10 +8,12 @@ package org.mifosplatform.accounting.glaccount.service; import java.util.List; import java.util.Map; +import org.mifosplatform.accounting.common.AccountingConstants; import org.mifosplatform.accounting.glaccount.api.GLAccountJsonInputParams; import org.mifosplatform.accounting.glaccount.command.GLAccountCommand; import org.mifosplatform.accounting.glaccount.domain.GLAccount; import org.mifosplatform.accounting.glaccount.domain.GLAccountRepository; +import org.mifosplatform.accounting.glaccount.domain.GLAccountType; import org.mifosplatform.accounting.glaccount.exception.GLAccountDuplicateException; import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidDeleteException; import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidDeleteException.GL_ACCOUNT_INVALID_DELETE_REASON; @@ -22,6 +24,8 @@ import org.mifosplatform.accounting.glaccount.exception.GLAccountNotFoundExcepti import org.mifosplatform.accounting.glaccount.serialization.GLAccountCommandFromApiJsonDeserializer; import org.mifosplatform.accounting.journalentry.domain.JournalEntry; import org.mifosplatform.accounting.journalentry.domain.JournalEntryRepository; +import org.mifosplatform.infrastructure.codes.domain.CodeValue; +import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; @@ -41,13 +45,16 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount private final GLAccountRepository glAccountRepository; private final JournalEntryRepository glJournalEntryRepository; private final GLAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer; + private final CodeValueRepositoryWrapper codeValueRepositoryWrapper; @Autowired public GLAccountWritePlatformServiceJpaRepositoryImpl(final GLAccountRepository glAccountRepository, - final JournalEntryRepository glJournalEntryRepository, final GLAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer) { + final JournalEntryRepository glJournalEntryRepository, final GLAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer, + final CodeValueRepositoryWrapper codeValueRepositoryWrapper) { this.glAccountRepository = glAccountRepository; this.glJournalEntryRepository = glJournalEntryRepository; this.fromApiJsonDeserializer = fromApiJsonDeserializer; + this.codeValueRepositoryWrapper = codeValueRepositoryWrapper; } @Transactional @@ -63,9 +70,41 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount if (parentId != null) { parentGLAccount = validateParentGLAccount(parentId); } - final GLAccount glAccount = GLAccount.fromJson(parentGLAccount, command); + + CodeValue glAccountTagType = null; + Long tagId = command.longValueOfParameterNamed(GLAccountJsonInputParams.TAGID.getValue()); + Long type = command.longValueOfParameterNamed(GLAccountJsonInputParams.TYPE.getValue()); + GLAccountType accountType = GLAccountType.fromInt(type.intValue()); + if (accountType == null) { + // TODO:generate an appropriate exception type. + throw new RuntimeException("Invalid GLAccount Type"); + } + + if (accountType.isAssetType()) { + glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection( + AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME, tagId); + } else if (accountType.isLiabilityType()) { + glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection( + AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME, tagId); + } else if (accountType.isEquityType()) { + glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection( + AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME, tagId); + } else if (accountType.isIncomeType()) { + glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection( + AccountingConstants.INCOME_TAG_OPTION_CODE_NAME, tagId); + } else if (accountType.isExpenseType()) { + glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection( + AccountingConstants.EXPENSES_TAG_OPTION_CODE_NAME, tagId); + } + + + final GLAccount glAccount = GLAccount.fromJson(parentGLAccount, command, glAccountTagType); this.glAccountRepository.saveAndFlush(glAccount); + + glAccount.generateHierarchy(); + + this.glAccountRepository.save(glAccount); return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(glAccount.getId()).build(); } catch (final DataIntegrityViolationException dve) { @@ -147,7 +186,7 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount parentGLAccount = this.glAccountRepository.findOne(parentAccountId); if (parentGLAccount == null) { throw new GLAccountNotFoundException(parentAccountId); } // ensure parent is not a detail account - if (parentGLAccount.isHeaderAccount()) { throw new GLAccountInvalidParentException(parentAccountId); } + if (parentGLAccount.isDetailAccount()) { throw new GLAccountInvalidParentException(parentAccountId); } return parentGLAccount; }