accounting wip: addressing review comments

This commit is contained in:
Vishwas Babu AJ
2013-01-22 03:08:44 +05:30
parent 0a30e4e08c
commit 72e712de24
29 changed files with 700 additions and 214 deletions
+45
View File
@@ -0,0 +1,45 @@
-- Make classification an enumeration for GL Account table
update acc_gl_account
set acc_gl_account.classification=1 where acc_gl_account.classification="ASSET";
update acc_gl_account
set acc_gl_account.classification=2 where acc_gl_account.classification="LIABILITY";
update acc_gl_account
set acc_gl_account.classification=3 where acc_gl_account.classification="EQUITY";
update acc_gl_account
set acc_gl_account.classification=4 where acc_gl_account.classification="INCOME";
update acc_gl_account
set acc_gl_account.classification=5 where acc_gl_account.classification="EXPENSE";
ALTER TABLE `acc_gl_account`
ALTER `classification` DROP DEFAULT;
ALTER TABLE `acc_gl_account`
CHANGE COLUMN `classification` `classification_enum` SMALLINT(5) NOT NULL AFTER `header_account`;
-- Rename is header account to usage in GL Account Table
update acc_gl_account
set acc_gl_account.header_account=2 where acc_gl_account.header_account=1;
update acc_gl_account
set acc_gl_account.header_account=1 where acc_gl_account.header_account=0;
ALTER TABLE `acc_gl_account`
CHANGE COLUMN `header_account` `account_usage` TINYINT(1) NOT NULL DEFAULT '2' AFTER `manual_journal_entries_allowed`;
-- Update Type in journal entries table
update acc_gl_journal_entry
set acc_gl_journal_entry.type=1 where acc_gl_journal_entry.type="CREDIT";
update acc_gl_journal_entry
set acc_gl_journal_entry.type=2 where acc_gl_journal_entry.type="DEBIT";
ALTER TABLE `acc_gl_journal_entry`
ALTER `type` DROP DEFAULT;
ALTER TABLE `acc_gl_journal_entry`
CHANGE COLUMN `type` `type_enum` SMALLINT(50) NOT NULL AFTER `entry_date`;
@@ -5,68 +5,6 @@ import java.util.Map;
public class AccountingConstants { public class AccountingConstants {
/*** Categories for Accounting **/
public static enum GL_ACCOUNT_CLASSIFICATION {
ASSET, LIABILITY, INCOME, EXPENSE, EQUITY;
@Override
public String toString() {
return name().toString();
}
}
/** Types of Journal Entries **/
public static enum JOURNAL_ENTRY_TYPE {
DEBIT, CREDIT;
@Override
public String toString() {
return name().toString();
}
}
/** USAGES of Accounts **/
public static enum GL_ACCOUNT_USAGE {
HEADER, DETAIL;
@Override
public String toString() {
return name().toString();
}
}
/*** Types of portfolio products ***/
public static enum PORTFOLIO_PRODUCT_TYPE {
LOAN(1), SAVING(2);
private final Integer value;
private PORTFOLIO_PRODUCT_TYPE(final Integer value) {
this.value = value;
}
@Override
public String toString() {
return name().toString().replaceAll("_", " ");
}
public Integer getValue() {
return this.value;
}
private static final Map<Integer, PORTFOLIO_PRODUCT_TYPE> intToEnumMap = new HashMap<Integer, PORTFOLIO_PRODUCT_TYPE>();
static {
for (PORTFOLIO_PRODUCT_TYPE type : PORTFOLIO_PRODUCT_TYPE.values()) {
intToEnumMap.put(type.value, type);
}
}
public static PORTFOLIO_PRODUCT_TYPE fromInt(int i) {
PORTFOLIO_PRODUCT_TYPE type = intToEnumMap.get(Integer.valueOf(i));
return type;
}
}
/*** Accounting placeholders for cash based accounting for loan products ***/ /*** Accounting placeholders for cash based accounting for loan products ***/
public static enum CASH_ACCOUNTS_FOR_LOAN { public static enum CASH_ACCOUNTS_FOR_LOAN {
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(6); FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(6);
@@ -21,10 +21,12 @@ import org.mifosplatform.accounting.api.commands.GLAccountCommand;
import org.mifosplatform.accounting.api.data.GLAccountData; import org.mifosplatform.accounting.api.data.GLAccountData;
import org.mifosplatform.accounting.api.infrastructure.AccountingApiDataConversionService; import org.mifosplatform.accounting.api.infrastructure.AccountingApiDataConversionService;
import org.mifosplatform.accounting.api.infrastructure.AccountingApiJsonSerializerService; import org.mifosplatform.accounting.api.infrastructure.AccountingApiJsonSerializerService;
import org.mifosplatform.accounting.service.AccountingDropdownReadPlatformService;
import org.mifosplatform.accounting.service.GLAccountReadPlatformService; import org.mifosplatform.accounting.service.GLAccountReadPlatformService;
import org.mifosplatform.accounting.service.GLAccountWritePlatformService; import org.mifosplatform.accounting.service.GLAccountWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@@ -47,6 +49,9 @@ public class GLAccountsApiResource {
@Autowired @Autowired
private AccountingApiJsonSerializerService apiJsonSerializerService; private AccountingApiJsonSerializerService apiJsonSerializerService;
@Autowired
private AccountingDropdownReadPlatformService dropdownReadPlatformService;
private final String entityType = "GL_ACCOUNT"; private final String entityType = "GL_ACCOUNT";
@Autowired @Autowired
@@ -65,8 +70,8 @@ public class GLAccountsApiResource {
@GET @GET
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllAccounts(@Context final UriInfo uriInfo, @QueryParam("classification") final String classification, public String retrieveAllAccounts(@Context final UriInfo uriInfo, @QueryParam("classification") final Integer classification,
@QueryParam("searchParam") final String searchParam, @QueryParam("usage") final String usage, @QueryParam("searchParam") final String searchParam, @QueryParam("usage") final Integer usage,
@QueryParam("manualAdjustmentsAllowed") final Boolean manualTransactionsAllowed, @QueryParam("disabled") final Boolean disabled) { @QueryParam("manualAdjustmentsAllowed") final Boolean manualTransactionsAllowed, @QueryParam("disabled") final Boolean disabled) {
context.authenticatedUser().validateHasReadPermission(entityType); context.authenticatedUser().validateHasReadPermission(entityType);
@@ -79,6 +84,22 @@ public class GLAccountsApiResource {
return this.apiJsonSerializerService.serializeGLAccountDataToJson(prettyPrint, responseParameters, glAccountDatas); return this.apiJsonSerializerService.serializeGLAccountDataToJson(prettyPrint, responseParameters, glAccountDatas);
} }
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveNewLoanProductDetails(@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(entityType);
GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveNewGLAccountDetails();
glAccountData = handleTemplate(glAccountData);
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
return this.apiJsonSerializerService.serializeGLAccountDataToJson(prettyPrint, responseParameters, glAccountData);
}
@GET @GET
@Path("{glAccountId}") @Path("{glAccountId}")
@@ -92,9 +113,9 @@ public class GLAccountsApiResource {
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
final GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveGLAccountById(glAccountId); GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveGLAccountById(glAccountId);
if (template) { if (template) {
// TODO: define templates glAccountData = handleTemplate(glAccountData);
} }
return this.apiJsonSerializerService.serializeGLAccountDataToJson(prettyPrint, responseParameters, glAccountData); return this.apiJsonSerializerService.serializeGLAccountDataToJson(prettyPrint, responseParameters, glAccountData);
@@ -135,4 +156,10 @@ public class GLAccountsApiResource {
return Response.ok(new CommandProcessingResult(glAccountId)).build(); return Response.ok(new CommandProcessingResult(glAccountId)).build();
} }
private GLAccountData handleTemplate(GLAccountData glAccountData) {
List<EnumOptionData> accountTypeOptions = dropdownReadPlatformService.retrieveGLAccountTypeOptions();
List<EnumOptionData> usageOptions = dropdownReadPlatformService.retrieveGLAccountUsageOptions();
return new GLAccountData(glAccountData, accountTypeOptions, usageOptions);
}
} }
@@ -2,6 +2,8 @@ package org.mifosplatform.accounting.api.commands;
import java.util.Set; import java.util.Set;
import org.mifosplatform.accounting.domain.GLAccountUsage;
/** /**
* Immutable command for adding a general Ledger Account * Immutable command for adding a general Ledger Account
*/ */
@@ -13,15 +15,15 @@ public class GLAccountCommand {
private final String glCode; private final String glCode;
private final Boolean disabled; private final Boolean disabled;
private final Boolean manualEntriesAllowed; private final Boolean manualEntriesAllowed;
private final Boolean headerAccount; private final Integer usage;
private final String classification; private final Integer classification;
private final String description; private final String description;
private final Set<String> parametersPassedInRequest; private final Set<String> parametersPassedInRequest;
public GLAccountCommand(final Set<String> modifiedParameters, final Long id, final String name, final Long parentId, public GLAccountCommand(final Set<String> modifiedParameters, final Long id, final String name, final Long parentId,
final String glCode, final Boolean disabled, final Boolean manualEntriesAllowed, final String classification, final String glCode, final Boolean disabled, final Boolean manualEntriesAllowed, final Integer classification,
final Boolean headerAccount, final String description) { final Integer usage, final String description) {
this.parametersPassedInRequest = modifiedParameters; this.parametersPassedInRequest = modifiedParameters;
this.id = id; this.id = id;
this.name = name; this.name = name;
@@ -30,10 +32,14 @@ public class GLAccountCommand {
this.disabled = disabled; this.disabled = disabled;
this.manualEntriesAllowed = manualEntriesAllowed; this.manualEntriesAllowed = manualEntriesAllowed;
this.classification = classification; this.classification = classification;
this.headerAccount = headerAccount; this.usage = usage;
this.description = description; this.description = description;
} }
public boolean isHeaderAccount() {
return GLAccountUsage.HEADER.getValue().equals(this.usage);
}
public boolean isNameChanged() { public boolean isNameChanged() {
return this.parametersPassedInRequest.contains("name"); return this.parametersPassedInRequest.contains("name");
} }
@@ -58,8 +64,8 @@ public class GLAccountCommand {
return this.parametersPassedInRequest.contains("classification"); return this.parametersPassedInRequest.contains("classification");
} }
public boolean isHeaderAccountFlagChanged() { public boolean isUsageChanged() {
return this.parametersPassedInRequest.contains("headerAccount"); return this.parametersPassedInRequest.contains("usage");
} }
public boolean isDescriptionChanged() { public boolean isDescriptionChanged() {
@@ -90,15 +96,15 @@ public class GLAccountCommand {
return manualEntriesAllowed; return manualEntriesAllowed;
} }
public Boolean getHeaderAccount() { public Integer getUsage() {
return headerAccount; return this.usage;
} }
public String getDescription() { public String getDescription() {
return description; return description;
} }
public String getClassification() { public Integer getClassification() {
return classification; return classification;
} }
} }
@@ -1,5 +1,12 @@
package org.mifosplatform.accounting.api.data; package org.mifosplatform.accounting.api.data;
import java.util.List;
import org.mifosplatform.accounting.domain.GLAccountType;
import org.mifosplatform.accounting.domain.GLAccountUsage;
import org.mifosplatform.accounting.service.AccountingEnumerations;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
/** /**
* Immutable object representing a General Ledger Account * Immutable object representing a General Ledger Account
* *
@@ -8,35 +15,59 @@ package org.mifosplatform.accounting.api.data;
*/ */
public class GLAccountData { public class GLAccountData {
@SuppressWarnings("unused")
private final Long id; private final Long id;
@SuppressWarnings("unused")
private final String name; private final String name;
@SuppressWarnings("unused")
private final Long parentId; private final Long parentId;
@SuppressWarnings("unused")
private final String glCode; private final String glCode;
@SuppressWarnings("unused")
private final boolean disabled; private final boolean disabled;
@SuppressWarnings("unused")
private final boolean manualEntriesAllowed; private final boolean manualEntriesAllowed;
@SuppressWarnings("unused") private final EnumOptionData type;
private final String classification; private final EnumOptionData usage;
@SuppressWarnings("unused")
private final Boolean headerAccount;
@SuppressWarnings("unused")
private final String description; private final String description;
// templates
final List<EnumOptionData> accountTypeOptions;
final List<EnumOptionData> usageOptions;
public GLAccountData(final Long id, final String name, final Long parentId, final String glCode, final boolean disabled, public GLAccountData(final Long id, final String name, final Long parentId, final String glCode, final boolean disabled,
final boolean manualEntriesAllowed, final String classification, final boolean headerAccount, final String description) { final boolean manualEntriesAllowed, final EnumOptionData type, final EnumOptionData usage, final String description) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.parentId = parentId; this.parentId = parentId;
this.glCode = glCode; this.glCode = glCode;
this.disabled = disabled; this.disabled = disabled;
this.manualEntriesAllowed = manualEntriesAllowed; this.manualEntriesAllowed = manualEntriesAllowed;
this.classification = classification; this.type = type;
this.headerAccount = headerAccount; this.usage = usage;
this.description = description; this.description = description;
this.accountTypeOptions = null;
this.usageOptions = null;
}
public GLAccountData(GLAccountData accountData, List<EnumOptionData> accountTypeOptions, List<EnumOptionData> usageOptions) {
this.id = accountData.id;
this.name = accountData.name;
this.parentId = accountData.parentId;
this.glCode = accountData.glCode;
this.disabled = accountData.disabled;
this.manualEntriesAllowed = accountData.manualEntriesAllowed;
this.type = accountData.type;
this.usage = accountData.usage;
this.description = accountData.description;
this.accountTypeOptions = accountTypeOptions;
this.usageOptions = usageOptions;
}
public static GLAccountData sensibleDefaultsForNewGLAccountCreation() {
final Long id = null;
final String name = null;
final Long parentId = null;
final String glCode = null;
final boolean disabled = false;
final boolean manualEntriesAllowed = true;
final EnumOptionData type = 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);
} }
} }
@@ -3,6 +3,7 @@ package org.mifosplatform.accounting.api.data;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
/** /**
* Immutable object representing a General Ledger Account * Immutable object representing a General Ledger Account
@@ -23,11 +24,11 @@ public class GLJournalEntryData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Long glAccountId; private final Long glAccountId;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String glAccountClassification; private final EnumOptionData glAccountClassification;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final LocalDate entryDate; private final LocalDate entryDate;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String entryType; private final EnumOptionData entryType;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final BigDecimal amount; private final BigDecimal amount;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@@ -50,7 +51,7 @@ public class GLJournalEntryData {
private final Boolean reversed; private final Boolean reversed;
public GLJournalEntryData(Long id, Long officeId, String officeName, String glAccountName, Long glAccountId, public GLJournalEntryData(Long id, Long officeId, String officeName, String glAccountName, Long glAccountId,
String glAccountClassification, LocalDate entryDate, String entryType, BigDecimal amount, String transactionId, EnumOptionData glAccountClassification, LocalDate entryDate, EnumOptionData entryType, BigDecimal amount, String transactionId,
Boolean portfolioGenerated, String entityType, Long entityId, Long createdByUserId, LocalDate createdDate, Boolean portfolioGenerated, String entityType, Long entityId, Long createdByUserId, LocalDate createdDate,
String createdByUserName, String comments, Boolean reversed) { String createdByUserName, String comments, Boolean reversed) {
this.id = id; this.id = id;
@@ -61,7 +61,7 @@ public class AccountingApiDataConversionServiceImpl implements AccountingApiData
final Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap); final Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
final Set<String> supportedParams = new HashSet<String>(Arrays.asList("name", "parentId", "glCode", "disabled", final Set<String> supportedParams = new HashSet<String>(Arrays.asList("name", "parentId", "glCode", "disabled",
"manualEntriesAllowed", "classification", "headerAccount", "description", "locale", "dateFormat")); "manualEntriesAllowed", "classification", "usage", "description", "locale", "dateFormat"));
checkForUnsupportedParameters(requestMap, supportedParams); checkForUnsupportedParameters(requestMap, supportedParams);
@@ -75,16 +75,18 @@ public class AccountingApiDataConversionServiceImpl implements AccountingApiData
final String glCode = helper.extractStringNamed("glCode", element, requestParamatersDetected); final String glCode = helper.extractStringNamed("glCode", element, requestParamatersDetected);
final Boolean disabled = helper.extractBooleanNamed("disabled", element, requestParamatersDetected); final Boolean disabled = helper.extractBooleanNamed("disabled", element, requestParamatersDetected);
final Boolean manualEntriesAllowed = helper.extractBooleanNamed("manualEntriesAllowed", element, requestParamatersDetected); final Boolean manualEntriesAllowed = helper.extractBooleanNamed("manualEntriesAllowed", element, requestParamatersDetected);
final String category = helper.extractStringNamed("classification", element, requestParamatersDetected); final Integer category = helper.extractIntegerFromUnFormattedStringNamed("classification", element, requestParamatersDetected);
final Boolean headerAccount = helper.extractBooleanNamed("headerAccount", element, requestParamatersDetected); final Integer usage = helper.extractIntegerFromUnFormattedStringNamed("usage", element, requestParamatersDetected);
final String description = helper.extractStringNamed("description", element, requestParamatersDetected); final String description = helper.extractStringNamed("description", element, requestParamatersDetected);
return new GLAccountCommand(requestParamatersDetected, resourceIdentifier, name, parentId, glCode, disabled, manualEntriesAllowed, return new GLAccountCommand(requestParamatersDetected, resourceIdentifier, name, parentId, glCode, disabled, manualEntriesAllowed,
category, headerAccount, description); category, usage, description);
} }
@Override @Override
public GLClosureCommand convertJsonToGLClosureCommand(Long resourceIdentifier, String json) { public GLClosureCommand convertJsonToGLClosureCommand(Long resourceIdentifier, String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
final Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap); final Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
@@ -107,6 +109,8 @@ public class AccountingApiDataConversionServiceImpl implements AccountingApiData
@Override @Override
public GLJournalEntryCommand convertJsonToGLJournalEntryCommand(String json) { public GLJournalEntryCommand convertJsonToGLJournalEntryCommand(String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
final Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap); final Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
@@ -43,19 +43,19 @@ public class GLAccount extends AbstractPersistable<Long> {
private boolean manualEntriesAllowed = true; private boolean manualEntriesAllowed = true;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "classification", nullable = false, length = 45) @Column(name = "classification_enum", nullable = false)
private String classification; private Integer classification;
@Column(name = "header_account", nullable = false) @Column(name = "account_usage", nullable = false)
private boolean headerAccount; private Integer usage;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "description", nullable = true, length = 500) @Column(name = "description", nullable = true, length = 500)
private String description; private String description;
public static GLAccount createNew(final GLAccount parent, final String name, final String glCode, final boolean disabled, public static GLAccount createNew(final GLAccount parent, final String name, final String glCode, final boolean disabled,
final boolean manualEntriesAllowed, final String classification, final boolean headerAccount, final String description) { final boolean manualEntriesAllowed, final Integer classification, final Integer usage, final String description) {
return new GLAccount(parent, name, glCode, disabled, manualEntriesAllowed, classification, headerAccount, description); return new GLAccount(parent, name, glCode, disabled, manualEntriesAllowed, classification, usage, description);
} }
protected GLAccount() { protected GLAccount() {
@@ -63,13 +63,13 @@ public class GLAccount extends AbstractPersistable<Long> {
} }
private GLAccount(final GLAccount parent, final String name, final String glCode, final boolean disabled, private GLAccount(final GLAccount parent, final String name, final String glCode, final boolean disabled,
final boolean manualEntriesAllowed, final String classification, final boolean headerAccount, final String description) { final boolean manualEntriesAllowed, final Integer classification, final Integer usage, final String description) {
this.parent = parent; this.parent = parent;
this.name = StringUtils.defaultIfEmpty(name, null); this.name = StringUtils.defaultIfEmpty(name, null);
this.glCode = StringUtils.defaultIfEmpty(glCode, null); this.glCode = StringUtils.defaultIfEmpty(glCode, null);
this.disabled = BooleanUtils.toBooleanDefaultIfNull(disabled, false); this.disabled = BooleanUtils.toBooleanDefaultIfNull(disabled, false);
this.manualEntriesAllowed = BooleanUtils.toBooleanDefaultIfNull(manualEntriesAllowed, true); this.manualEntriesAllowed = BooleanUtils.toBooleanDefaultIfNull(manualEntriesAllowed, true);
this.headerAccount = BooleanUtils.toBooleanDefaultIfNull(headerAccount, false); this.usage = usage;
this.classification = classification; this.classification = classification;
this.description = StringUtils.defaultIfEmpty(description, null); this.description = StringUtils.defaultIfEmpty(description, null);
} }
@@ -87,8 +87,8 @@ public class GLAccount extends AbstractPersistable<Long> {
if (command.isGLCodeChanged()) { if (command.isGLCodeChanged()) {
this.glCode = command.getGlCode(); this.glCode = command.getGlCode();
} }
if (command.isHeaderAccountFlagChanged()) { if (command.isUsageChanged()) {
this.headerAccount = command.getHeaderAccount(); this.usage = command.getUsage();
} }
if (command.isManualEntriesAllowedFlagChanged()) { if (command.isManualEntriesAllowedFlagChanged()) {
this.manualEntriesAllowed = command.getManualEntriesAllowed(); this.manualEntriesAllowed = command.getManualEntriesAllowed();
@@ -102,7 +102,11 @@ public class GLAccount extends AbstractPersistable<Long> {
} }
public boolean isHeaderAccount() { public boolean isHeaderAccount() {
return headerAccount; return GLAccountUsage.HEADER.getValue().equals(this.usage);
}
public Integer getUsage() {
return this.usage;
} }
public List<GLAccount> getChildren() { public List<GLAccount> getChildren() {
@@ -0,0 +1,64 @@
package org.mifosplatform.accounting.domain;
import java.util.HashMap;
import java.util.Map;
public enum GLAccountType {
ASSET(1, "accountType.asset"), LIABILITY(2, "accountType.liability"), EQUITY(3, "accountType.equity"), INCOME(4, "accountType.income"), EXPENSE(
5, "accountType.expense"), ;
private final Integer value;
private final String code;
private GLAccountType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return code;
}
private static final Map<Integer, GLAccountType> intToEnumMap = new HashMap<Integer, GLAccountType>();
private static int minValue;
private static int maxValue;
static {
int i = 0;
for (GLAccountType type : GLAccountType.values()) {
if (i == 0) {
minValue = type.value;
}
intToEnumMap.put(type.value, type);
if (minValue >= type.value) {
minValue = type.value;
}
if (maxValue < type.value) {
maxValue = type.value;
}
i = i + 1;
}
}
public static GLAccountType fromInt(int i) {
GLAccountType type = intToEnumMap.get(Integer.valueOf(i));
return type;
}
public static int getMinValue() {
return minValue;
}
public static int getMaxValue() {
return maxValue;
}
@Override
public String toString() {
return name().toString();
}
}
@@ -0,0 +1,64 @@
package org.mifosplatform.accounting.domain;
import java.util.HashMap;
import java.util.Map;
public enum GLAccountUsage {
DETAIL(1, "accountUsage.detail"), HEADER(2, "accountUsage.header");
private final Integer value;
private final String code;
private GLAccountUsage(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return code;
}
private static final Map<Integer, GLAccountUsage> intToEnumMap = new HashMap<Integer, GLAccountUsage>();
private static int minValue;
private static int maxValue;
static {
int i = 0;
for (GLAccountUsage type : GLAccountUsage.values()) {
if (i == 0) {
minValue = type.value;
}
intToEnumMap.put(type.value, type);
if (minValue >= type.value) {
minValue = type.value;
}
if (maxValue < type.value) {
maxValue = type.value;
}
i = i + 1;
}
}
public static GLAccountUsage fromInt(int i) {
GLAccountUsage type = intToEnumMap.get(Integer.valueOf(i));
return type;
}
public static int getMinValue() {
return minValue;
}
public static int getMaxValue() {
return maxValue;
}
@Override
public String toString() {
return name().toString();
}
}
@@ -50,8 +50,8 @@ public class GLJournalEntry extends AbstractAuditableCustom<AppUser, Long> {
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
private Date entryDate; private Date entryDate;
@Column(name = "type", nullable = false, length = 50) @Column(name = "type_enum", nullable = false, length = 50)
private String type; private Integer type;
@Column(name = "amount", scale = 6, precision = 19, nullable = false) @Column(name = "amount", scale = 6, precision = 19, nullable = false)
private BigDecimal amount; private BigDecimal amount;
@@ -69,9 +69,9 @@ public class GLJournalEntry extends AbstractAuditableCustom<AppUser, Long> {
private Long entityId; private Long entityId;
public static GLJournalEntry createNew(Office office, GLAccount glAccount, String transactionId, boolean portfolioGenerated, public static GLJournalEntry createNew(Office office, GLAccount glAccount, String transactionId, boolean portfolioGenerated,
Date entryDate, String type, BigDecimal amount, String description, String entityType, Long entityId) { Date entryDate, JournalEntryType journalEntryType, BigDecimal amount, String description, String entityType, Long entityId) {
return new GLJournalEntry(office, glAccount, transactionId, portfolioGenerated, entryDate, type, amount, description, entityType, return new GLJournalEntry(office, glAccount, transactionId, portfolioGenerated, entryDate, journalEntryType.getValue(), amount,
entityId); description, entityType, entityId);
} }
protected GLJournalEntry() { protected GLJournalEntry() {
@@ -79,7 +79,7 @@ public class GLJournalEntry extends AbstractAuditableCustom<AppUser, Long> {
} }
public GLJournalEntry(Office office, GLAccount glAccount, String transactionId, boolean portfolioGenerated, Date entryDate, public GLJournalEntry(Office office, GLAccount glAccount, String transactionId, boolean portfolioGenerated, Date entryDate,
String type, BigDecimal amount, String description, String entityType, Long entityId) { Integer type, BigDecimal amount, String description, String entityType, Long entityId) {
this.office = office; this.office = office;
this.glAccount = glAccount; this.glAccount = glAccount;
this.reversalJournalEntry = null; this.reversalJournalEntry = null;
@@ -94,7 +94,11 @@ public class GLJournalEntry extends AbstractAuditableCustom<AppUser, Long> {
this.entityId = entityId; this.entityId = entityId;
} }
public String getType() { public boolean isDebitEntry() {
return JournalEntryType.DEBIT.getValue().equals(type);
}
public Integer getType() {
return this.type; return this.type;
} }
@@ -0,0 +1,44 @@
package org.mifosplatform.accounting.domain;
import java.util.HashMap;
import java.util.Map;
public enum JournalEntryType {
CREDIT(1, "journalEntryType.credit"), DEBIT(2, "journalEntrytType.debit");
private final Integer value;
private final String code;
private JournalEntryType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return code;
}
private static final Map<Integer, JournalEntryType> intToEnumMap = new HashMap<Integer, JournalEntryType>();
static {
for (JournalEntryType type : JournalEntryType.values()) {
intToEnumMap.put(type.value, type);
}
}
public static JournalEntryType fromInt(int i) {
JournalEntryType type = intToEnumMap.get(Integer.valueOf(i));
return type;
}
@Override
public String toString() {
return name().toString();
}
}
@@ -0,0 +1,42 @@
package org.mifosplatform.accounting.domain;
import java.util.HashMap;
import java.util.Map;
public enum PortfolioProductType {
LOAN(1, "productType.loan"), SAVING(2, "productType.saving");
private final Integer value;
private final String code;
private PortfolioProductType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
@Override
public String toString() {
return name().toString().replaceAll("_", " ");
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return code;
}
private static final Map<Integer, PortfolioProductType> intToEnumMap = new HashMap<Integer, PortfolioProductType>();
static {
for (PortfolioProductType type : PortfolioProductType.values()) {
intToEnumMap.put(type.value, type);
}
}
public static PortfolioProductType fromInt(int i) {
PortfolioProductType type = intToEnumMap.get(Integer.valueOf(i));
return type;
}
}
@@ -4,11 +4,11 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRul
/** /**
* A {@link RuntimeException} thrown when trying to fetch accounts belonging to * A {@link RuntimeException} thrown when trying to fetch accounts belonging to
* an Invalid Type * an Invalid Usage Type
*/ */
public class GLAccountInvalidClassificationException extends AbstractPlatformDomainRuleException { public class GLAccountInvalidClassificationException extends AbstractPlatformDomainRuleException {
public GLAccountInvalidClassificationException(final String classification) { public GLAccountInvalidClassificationException(final Integer usage) {
super("error.msg.glaccount.classification.invalid", "The following COA classification is invalid: " + classification); super("error.msg.glaccount.usage.invalid", "The following COA usage is invalid: " + usage);
} }
} }
@@ -0,0 +1,14 @@
package org.mifosplatform.accounting.exceptions;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when trying to fetch accounts belonging to
* an Invalid Type
*/
public class GLAccountInvalidUsageException extends AbstractPlatformDomainRuleException {
public GLAccountInvalidUsageException(final Integer type) {
super("error.msg.glaccount.classification.invalid", "The following COA type is invalid: " + type);
}
}
@@ -1,6 +1,6 @@
package org.mifosplatform.accounting.exceptions; package org.mifosplatform.accounting.exceptions;
import org.mifosplatform.accounting.AccountingConstants.PORTFOLIO_PRODUCT_TYPE; import org.mifosplatform.accounting.domain.PortfolioProductType;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
/** /**
@@ -9,7 +9,7 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
*/ */
public class ProductToGLAccountMappingNotFoundException extends AbstractPlatformResourceNotFoundException { public class ProductToGLAccountMappingNotFoundException extends AbstractPlatformResourceNotFoundException {
public ProductToGLAccountMappingNotFoundException(final PORTFOLIO_PRODUCT_TYPE type, final Long productId, String accountType) { public ProductToGLAccountMappingNotFoundException(final PortfolioProductType type, final Long productId, String accountType) {
super("error.msg.productTyAccountMapping.not.found", "Mapping for product of type" + type.toString() + " with Id " + productId super("error.msg.productTyAccountMapping.not.found", "Mapping for product of type" + type.toString() + " with Id " + productId
+ " does not exist for an account of type " + accountType, type.toString(), productId, accountType); + " does not exist for an account of type " + accountType, type.toString(), productId, accountType);
} }
@@ -0,0 +1,14 @@
package org.mifosplatform.accounting.service;
import java.util.List;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
public interface AccountingDropdownReadPlatformService {
public List<EnumOptionData> retrieveGLAccountTypeOptions();
public List<EnumOptionData> retrieveGLAccountUsageOptions();
public List<EnumOptionData> retrieveJournalEntryTypeOptions();
}
@@ -0,0 +1,76 @@
package org.mifosplatform.accounting.service;
import java.util.ArrayList;
import java.util.List;
import org.mifosplatform.accounting.domain.GLAccountType;
import org.mifosplatform.accounting.domain.GLAccountUsage;
import org.mifosplatform.accounting.domain.JournalEntryType;
import org.mifosplatform.accounting.domain.PortfolioProductType;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
public class AccountingEnumerations {
public static EnumOptionData gLAccountType(final int id) {
return gLAccountType(GLAccountType.fromInt(id));
}
public static EnumOptionData gLAccountType(final GLAccountType accountType) {
EnumOptionData optionData = new EnumOptionData(accountType.getValue().longValue(), accountType.getCode(), accountType.toString());
return optionData;
}
public static List<EnumOptionData> gLAccountType(GLAccountType[] accountTypes) {
List<EnumOptionData> optionDatas = new ArrayList<EnumOptionData>();
for (GLAccountType accountType : accountTypes) {
optionDatas.add(gLAccountType(accountType));
}
return optionDatas;
}
public static EnumOptionData gLAccountUsage(final int id) {
return gLAccountUsage(GLAccountUsage.fromInt(id));
}
public static EnumOptionData gLAccountUsage(final GLAccountUsage accountUsage) {
EnumOptionData optionData = new EnumOptionData(accountUsage.getValue().longValue(), accountUsage.getCode(), accountUsage.toString());
return optionData;
}
public static List<EnumOptionData> gLAccountUsage(GLAccountUsage[] accountUsages) {
List<EnumOptionData> optionDatas = new ArrayList<EnumOptionData>();
for (GLAccountUsage accountUsage : accountUsages) {
optionDatas.add(gLAccountUsage(accountUsage));
}
return optionDatas;
}
public static EnumOptionData journalEntryType(final int id) {
return journalEntryType(JournalEntryType.fromInt(id));
}
public static EnumOptionData journalEntryType(final JournalEntryType journalEntryType) {
EnumOptionData optionData = new EnumOptionData(journalEntryType.getValue().longValue(), journalEntryType.getCode(),
journalEntryType.toString());
return optionData;
}
public static List<EnumOptionData> journalEntryTypes(JournalEntryType[] journalEntryTypes) {
List<EnumOptionData> optionDatas = new ArrayList<EnumOptionData>();
for (JournalEntryType journalEntryType : journalEntryTypes) {
optionDatas.add(journalEntryType(journalEntryType));
}
return optionDatas;
}
public static EnumOptionData portfolioProductType(final int id) {
return portfolioProductType(PortfolioProductType.fromInt(id));
}
public static EnumOptionData portfolioProductType(final PortfolioProductType portfolioProductType) {
EnumOptionData optionData = new EnumOptionData(portfolioProductType.getValue().longValue(), portfolioProductType.getCode(),
portfolioProductType.toString());
return optionData;
}
}
@@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.mifosplatform.accounting.api.commands.GLAccountCommand; import org.mifosplatform.accounting.api.commands.GLAccountCommand;
import org.mifosplatform.accounting.domain.GLAccountType;
import org.mifosplatform.accounting.domain.GLAccountUsage;
import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
@@ -28,7 +30,11 @@ public class GLAccountCommandValidator {
baseDataValidator.reset().parameter("parentId").value(command.getParentId()).ignoreIfNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("parentId").value(command.getParentId()).ignoreIfNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("classification").value(command.getClassification()).notBlank().notExceedingLengthOf(45); baseDataValidator.reset().parameter("classification").value(command.getClassification())
.inMinMaxRange(GLAccountType.getMinValue(), GLAccountType.getMaxValue());
baseDataValidator.reset().parameter("usage").value(command.getUsage())
.inMinMaxRange(GLAccountUsage.getMinValue(), GLAccountUsage.getMaxValue());
baseDataValidator.reset().parameter("description").value(command.getDescription()).ignoreIfNull().notExceedingLengthOf(500); baseDataValidator.reset().parameter("description").value(command.getDescription()).ignoreIfNull().notExceedingLengthOf(500);
@@ -49,8 +55,10 @@ public class GLAccountCommandValidator {
baseDataValidator.reset().parameter("parentId").value(command.getParentId()).ignoreIfNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("parentId").value(command.getParentId()).ignoreIfNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("classification").value(command.getClassification()).ignoreIfNull().notBlank() baseDataValidator.reset().parameter("classification").value(command.getClassification()).ignoreIfNull()
.notExceedingLengthOf(45); .inMinMaxRange(GLAccountType.getMinValue(), GLAccountType.getMaxValue());
baseDataValidator.reset().parameter("usage").value(command.getUsage()).ignoreIfNull()
.inMinMaxRange(GLAccountUsage.getMinValue(), GLAccountUsage.getMaxValue());
baseDataValidator.reset().parameter("description").value(command.getDescription()).ignoreIfNull().notBlank() baseDataValidator.reset().parameter("description").value(command.getDescription()).ignoreIfNull().notBlank()
.notExceedingLengthOf(500); .notExceedingLengthOf(500);
@@ -2,16 +2,18 @@ package org.mifosplatform.accounting.service;
import java.util.List; import java.util.List;
import org.mifosplatform.accounting.AccountingConstants;
import org.mifosplatform.accounting.api.data.GLAccountData; import org.mifosplatform.accounting.api.data.GLAccountData;
import org.mifosplatform.accounting.domain.GLAccountType;
public interface GLAccountReadPlatformService { public interface GLAccountReadPlatformService {
List<GLAccountData> retrieveAllGLAccounts(String accountClassification, String searchParam, String usage, List<GLAccountData> retrieveAllGLAccounts(Integer accountClassification, String searchParam, Integer usage,
Boolean manualTransactionsAllowed, Boolean disabled); Boolean manualTransactionsAllowed, Boolean disabled);
GLAccountData retrieveGLAccountById(long glAccountId); GLAccountData retrieveGLAccountById(long glAccountId);
List<GLAccountData> retrieveAllEnabledDetailGLAccounts(AccountingConstants.GL_ACCOUNT_CLASSIFICATION classification); List<GLAccountData> retrieveAllEnabledDetailGLAccounts(GLAccountType accountType);
GLAccountData retrieveNewGLAccountDetails();
} }
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.mifosplatform.accounting.api.commands.GLJournalEntryCommand; import org.mifosplatform.accounting.api.commands.GLJournalEntryCommand;
import org.mifosplatform.accounting.api.commands.SingleDebitOrCreditEntryCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
@@ -28,8 +29,50 @@ public class GLJournalEntryCommandValidator {
baseDataValidator.reset().parameter("comments").value(command.getComments()).ignoreIfNull().notExceedingLengthOf(500); baseDataValidator.reset().parameter("comments").value(command.getComments()).ignoreIfNull().notExceedingLengthOf(500);
baseDataValidator.reset().parameter("credits").value(command.getCredits()).notNull();
baseDataValidator.reset().parameter("debits").value(command.getDebits()).notNull();
// validation for credit array elements
if (command.getCredits() != null) {
if (command.getCredits().length == 0) {
validateSingleDebitOrCredit(baseDataValidator, "credits", 0, new SingleDebitOrCreditEntryCommand(null, null, null, null));
} else {
int i = 0;
for (SingleDebitOrCreditEntryCommand credit : command.getCredits()) {
validateSingleDebitOrCredit(baseDataValidator, "credits", i, credit);
i++;
}
}
}
// validation for debit array elements
if (command.getDebits() != null) {
if (command.getDebits().length == 0) {
validateSingleDebitOrCredit(baseDataValidator, "credits", 0, new SingleDebitOrCreditEntryCommand(null, null, null, null));
} else {
int i = 0;
for (SingleDebitOrCreditEntryCommand debit : command.getDebits()) {
validateSingleDebitOrCredit(baseDataValidator, "debits", i, debit);
i++;
}
}
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); } "Validation errors exist.", dataValidationErrors); }
} }
/**
* @param baseDataValidator
* @param i
* @param credit
*/
private void validateSingleDebitOrCredit(DataValidatorBuilder baseDataValidator, String paramSuffix, int arrayPos,
SingleDebitOrCreditEntryCommand credit) {
baseDataValidator.reset().parameter(paramSuffix + "[" + arrayPos + "].glAccountId").value(credit.getGlAccountId()).notNull()
.integerGreaterThanZero();
baseDataValidator.reset().parameter(paramSuffix + "[" + arrayPos + "].amount").value(credit.getAmount()).notNull()
.zeroOrPositiveAmount();
}
} }
@@ -0,0 +1,31 @@
package org.mifosplatform.accounting.service.impl;
import java.util.List;
import org.mifosplatform.accounting.domain.GLAccountType;
import org.mifosplatform.accounting.domain.GLAccountUsage;
import org.mifosplatform.accounting.domain.JournalEntryType;
import org.mifosplatform.accounting.service.AccountingDropdownReadPlatformService;
import org.mifosplatform.accounting.service.AccountingEnumerations;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.springframework.stereotype.Service;
@Service
public class AccountingDropdownReadPlatformServiceImpl implements AccountingDropdownReadPlatformService {
@Override
public List<EnumOptionData> retrieveGLAccountTypeOptions() {
return AccountingEnumerations.gLAccountType(GLAccountType.values());
}
@Override
public List<EnumOptionData> retrieveGLAccountUsageOptions() {
return AccountingEnumerations.gLAccountUsage(GLAccountUsage.values());
}
@Override
public List<EnumOptionData> retrieveJournalEntryTypeOptions() {
return AccountingEnumerations.journalEntryTypes(JournalEntryType.values());
}
}
@@ -6,13 +6,15 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosplatform.accounting.AccountingConstants;
import org.mifosplatform.accounting.AccountingConstants.GL_ACCOUNT_CLASSIFICATION;
import org.mifosplatform.accounting.AccountingConstants.GL_ACCOUNT_USAGE;
import org.mifosplatform.accounting.api.data.GLAccountData; import org.mifosplatform.accounting.api.data.GLAccountData;
import org.mifosplatform.accounting.domain.GLAccountType;
import org.mifosplatform.accounting.domain.GLAccountUsage;
import org.mifosplatform.accounting.exceptions.GLAccountInvalidClassificationException; import org.mifosplatform.accounting.exceptions.GLAccountInvalidClassificationException;
import org.mifosplatform.accounting.exceptions.GLAccountNotFoundException; import org.mifosplatform.accounting.exceptions.GLAccountNotFoundException;
import org.mifosplatform.accounting.service.AccountingEnumerations;
import org.mifosplatform.accounting.service.GLAccountReadPlatformService; import org.mifosplatform.accounting.service.GLAccountReadPlatformService;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.EmptyResultDataAccessException;
@@ -34,7 +36,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
public String schema() { 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, " 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 as classification, header_account as headerAccount, description as description " + "classification_enum as classification, account_usage as accountUsage, description as description "
+ "from acc_gl_account"; + "from acc_gl_account";
} }
@@ -47,20 +49,25 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
String glCode = rs.getString("glCode"); String glCode = rs.getString("glCode");
boolean disabled = rs.getBoolean("disabled"); boolean disabled = rs.getBoolean("disabled");
boolean manualEntriesAllowed = rs.getBoolean("manualEntriesAllowed"); boolean manualEntriesAllowed = rs.getBoolean("manualEntriesAllowed");
String classification = rs.getString("classification"); final int accountTypeId = JdbcSupport.getInteger(rs, "classification");
boolean headerAccount = rs.getBoolean("headerAccount"); final EnumOptionData accountType = AccountingEnumerations.gLAccountType(accountTypeId);
final int usageId = JdbcSupport.getInteger(rs, "accountUsage");
final EnumOptionData usage = AccountingEnumerations.gLAccountUsage(usageId);
String description = rs.getString("description"); String description = rs.getString("description");
return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, classification, headerAccount, description); return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, accountType, usage, description);
} }
} }
@Override @Override
public List<GLAccountData> retrieveAllGLAccounts(String accountClassification, String searchParam, String usage, public List<GLAccountData> retrieveAllGLAccounts(Integer accountClassification, String searchParam, Integer usage,
Boolean manualTransactionsAllowed, Boolean disabled) { Boolean manualTransactionsAllowed, Boolean disabled) {
if (StringUtils.isNotBlank(accountClassification)) { if (accountClassification != null) {
if (!checkValidGLAccountClassification(accountClassification)) { throw new GLAccountInvalidClassificationException( if (!checkValidGLAccountType(accountClassification)) { throw new GLAccountInvalidClassificationException(accountClassification); }
accountClassification); } }
if (usage != null) {
if (!checkValidGLAccountUsage(usage)) { throw new GLAccountInvalidClassificationException(accountClassification); }
} }
GLAccountMapper rm = new GLAccountMapper(); GLAccountMapper rm = new GLAccountMapper();
@@ -68,7 +75,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
Object[] paramaterArray = new Object[3]; Object[] paramaterArray = new Object[3];
int arrayPos = 0; int arrayPos = 0;
boolean filtersPresent = false; boolean filtersPresent = false;
if (StringUtils.isNotBlank(accountClassification) || StringUtils.isNotBlank(searchParam) || StringUtils.isNotBlank(usage) if ((accountClassification != null) || StringUtils.isNotBlank(searchParam) || (usage != null)
|| (manualTransactionsAllowed != null) || (disabled != null)) { || (manualTransactionsAllowed != null) || (disabled != null)) {
filtersPresent = true; filtersPresent = true;
sql += " where"; sql += " where";
@@ -76,8 +83,8 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
if (filtersPresent) { if (filtersPresent) {
boolean firstWhereConditionAdded = false; boolean firstWhereConditionAdded = false;
if (StringUtils.isNotBlank(accountClassification)) { if (accountClassification != null) {
sql += " classification like ?"; sql += " classification_enum like ?";
paramaterArray[arrayPos] = accountClassification; paramaterArray[arrayPos] = accountClassification;
arrayPos = arrayPos + 1; arrayPos = arrayPos + 1;
firstWhereConditionAdded = true; firstWhereConditionAdded = true;
@@ -93,16 +100,14 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
arrayPos = arrayPos + 1; arrayPos = arrayPos + 1;
firstWhereConditionAdded = true; firstWhereConditionAdded = true;
} }
if (StringUtils.isNotBlank(usage)) { if (usage != null) {
if (firstWhereConditionAdded) { if (firstWhereConditionAdded) {
sql += " and "; sql += " and ";
} }
if (usage.equalsIgnoreCase(GL_ACCOUNT_USAGE.HEADER.toString())) { if (GLAccountUsage.HEADER.getValue().equals(usage)) {
sql += " header_account = 1 "; sql += " account_usage = 2 ";
} else if (usage.equalsIgnoreCase(GL_ACCOUNT_USAGE.DETAIL.toString())) { } else if (GLAccountUsage.DETAIL.getValue().equals(usage)) {
sql += " header_account = 0 "; sql += " account_usage = 1 ";
} else {
} }
firstWhereConditionAdded = true; firstWhereConditionAdded = true;
} }
@@ -153,15 +158,27 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
} }
@Override @Override
public List<GLAccountData> retrieveAllEnabledDetailGLAccounts(GL_ACCOUNT_CLASSIFICATION classification) { public List<GLAccountData> retrieveAllEnabledDetailGLAccounts(GLAccountType accountType) {
return retrieveAllGLAccounts(classification.toString(), null, AccountingConstants.GL_ACCOUNT_USAGE.DETAIL.toString(), null, false); return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.DETAIL.getValue(), null, false);
} }
private static boolean checkValidGLAccountClassification(final String entityType) { private static boolean checkValidGLAccountType(final int type) {
for (GL_ACCOUNT_CLASSIFICATION classification : GL_ACCOUNT_CLASSIFICATION.values()) { for (GLAccountType accountType : GLAccountType.values()) {
if (classification.name().toString().equalsIgnoreCase(entityType)) { return true; } if (accountType.getValue().equals(type)) { return true; }
} }
return false; return false;
} }
private static boolean checkValidGLAccountUsage(final int type) {
for (GLAccountUsage accountUsage : GLAccountUsage.values()) {
if (accountUsage.getValue().equals(type)) { return true; }
}
return false;
}
@Override
public GLAccountData retrieveNewGLAccountDetails() {
return GLAccountData.sensibleDefaultsForNewGLAccountCreation();
}
} }
@@ -2,20 +2,17 @@ package org.mifosplatform.accounting.service.impl;
import java.util.List; import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.accounting.AccountingConstants.GL_ACCOUNT_CLASSIFICATION;
import org.mifosplatform.accounting.api.commands.GLAccountCommand; import org.mifosplatform.accounting.api.commands.GLAccountCommand;
import org.mifosplatform.accounting.domain.GLAccount; import org.mifosplatform.accounting.domain.GLAccount;
import org.mifosplatform.accounting.domain.GLAccountRepository; import org.mifosplatform.accounting.domain.GLAccountRepository;
import org.mifosplatform.accounting.domain.GLJournalEntry; import org.mifosplatform.accounting.domain.GLJournalEntry;
import org.mifosplatform.accounting.domain.GLJournalEntryRepository; import org.mifosplatform.accounting.domain.GLJournalEntryRepository;
import org.mifosplatform.accounting.exceptions.GLAccountDuplicateException; import org.mifosplatform.accounting.exceptions.GLAccountDuplicateException;
import org.mifosplatform.accounting.exceptions.GLAccountInvalidClassificationException;
import org.mifosplatform.accounting.exceptions.GLAccountInvalidDeleteException; import org.mifosplatform.accounting.exceptions.GLAccountInvalidDeleteException;
import org.mifosplatform.accounting.exceptions.GLAccountInvalidDeleteException.GL_ACCOUNT_INVALID_DELETE_REASON; import org.mifosplatform.accounting.exceptions.GLAccountInvalidDeleteException.GL_ACCOUNT_INVALID_DELETE_REASON;
import org.mifosplatform.accounting.exceptions.GLAccountInvalidUpdateException.GL_ACCOUNT_INVALID_UPDATE_REASON;
import org.mifosplatform.accounting.exceptions.GLAccountInvalidParentException; import org.mifosplatform.accounting.exceptions.GLAccountInvalidParentException;
import org.mifosplatform.accounting.exceptions.GLAccountInvalidUpdateException; import org.mifosplatform.accounting.exceptions.GLAccountInvalidUpdateException;
import org.mifosplatform.accounting.exceptions.GLAccountInvalidUpdateException.GL_ACCOUNT_INVALID_UPDATE_REASON;
import org.mifosplatform.accounting.exceptions.GLAccountNotFoundException; import org.mifosplatform.accounting.exceptions.GLAccountNotFoundException;
import org.mifosplatform.accounting.service.GLAccountCommandValidator; import org.mifosplatform.accounting.service.GLAccountCommandValidator;
import org.mifosplatform.accounting.service.GLAccountWritePlatformService; import org.mifosplatform.accounting.service.GLAccountWritePlatformService;
@@ -49,18 +46,13 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
GLAccountCommandValidator validator = new GLAccountCommandValidator(command); GLAccountCommandValidator validator = new GLAccountCommandValidator(command);
validator.validateForCreate(); validator.validateForCreate();
if (StringUtils.isNotBlank(command.getClassification())) {
if (!checkValidGLAccountClassification(command.getClassification())) { throw new GLAccountInvalidClassificationException(
command.getClassification()); }
}
// check parent is valid // check parent is valid
GLAccount parentGLAccount = null; GLAccount parentGLAccount = null;
if (command.getParentId() != null) { if (command.getParentId() != null) {
parentGLAccount = validateParentGLAccount(command); parentGLAccount = validateParentGLAccount(command);
} }
GLAccount glAccount = GLAccount.createNew(parentGLAccount, command.getName(), command.getGlCode(), false, GLAccount glAccount = GLAccount.createNew(parentGLAccount, command.getName(), command.getGlCode(), false,
command.getManualEntriesAllowed(), command.getClassification(), command.getHeaderAccount(), command.getDescription()); command.getManualEntriesAllowed(), command.getClassification(), command.getUsage(), command.getDescription());
this.glAccountRepository.saveAndFlush(glAccount); this.glAccountRepository.saveAndFlush(glAccount);
@@ -87,18 +79,12 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
parentGLAccount = validateParentGLAccount(command); parentGLAccount = validateParentGLAccount(command);
} }
// validate new classification
if (command.isClassificationChanged()) {
if (!checkValidGLAccountClassification(command.getClassification())) { throw new GLAccountInvalidClassificationException(
command.getClassification()); }
}
/** /**
* a detail account cannot be changed to a header account if * a detail account cannot be changed to a header account if
* transactions are already logged against it * transactions are already logged against it
**/ **/
if (command.isHeaderAccountFlagChanged()) { if (command.isUsageChanged()) {
if (command.getHeaderAccount() == true) { if (command.isHeaderAccount()) {
List<GLJournalEntry> journalEntriesForAccount = glJournalEntryRepository.findFirstJournalEntryForAccount(glAccountId); List<GLJournalEntry> journalEntriesForAccount = glJournalEntryRepository.findFirstJournalEntryForAccount(glAccountId);
if (journalEntriesForAccount.size() > 0) { throw new GLAccountInvalidUpdateException( if (journalEntriesForAccount.size() > 0) { throw new GLAccountInvalidUpdateException(
GL_ACCOUNT_INVALID_UPDATE_REASON.TRANSANCTIONS_LOGGED, glAccountId); } GL_ACCOUNT_INVALID_UPDATE_REASON.TRANSANCTIONS_LOGGED, glAccountId); }
@@ -161,10 +147,4 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
"Unknown data integrity issue with resource GL Account: " + realCause.getMessage()); "Unknown data integrity issue with resource GL Account: " + realCause.getMessage());
} }
private static boolean checkValidGLAccountClassification(final String entityType) {
for (GL_ACCOUNT_CLASSIFICATION classification : GL_ACCOUNT_CLASSIFICATION.values()) {
if (classification.name().toString().equalsIgnoreCase(entityType)) { return true; }
}
return false;
}
} }
@@ -12,7 +12,9 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.accounting.api.data.GLJournalEntryData; import org.mifosplatform.accounting.api.data.GLJournalEntryData;
import org.mifosplatform.accounting.exceptions.GLJournalEntriesNotFoundException; import org.mifosplatform.accounting.exceptions.GLJournalEntriesNotFoundException;
import org.mifosplatform.accounting.service.AccountingEnumerations;
import org.mifosplatform.accounting.service.GLJournalEntryReadPlatformService; import org.mifosplatform.accounting.service.GLJournalEntryReadPlatformService;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -34,11 +36,11 @@ public class GLJournalEntryReadPlatformServiceImpl implements GLJournalEntryRead
private static final class GLJournalEntryMapper implements RowMapper<GLJournalEntryData> { private static final class GLJournalEntryMapper implements RowMapper<GLJournalEntryData> {
public String schema() { public String schema() {
return " journalEntry.id as journalEntryId, glAccount.classification as classification ," return " journalEntry.id as journalEntryId, glAccount.classification_enum as classification ,"
+ " glAccount.name as glAccountName, journalEntry.account_id as glAccountId," + " glAccount.name as glAccountName, journalEntry.account_id as glAccountId,"
+ " journalEntry.office_id as officeId, office.name as officeName, " + " journalEntry.office_id as officeId, office.name as officeName, "
+ " journalEntry.portfolio_generated as portfolioGenerated,journalEntry.entry_date as entryDate, " + " journalEntry.portfolio_generated as portfolioGenerated,journalEntry.entry_date as entryDate, "
+ " journalEntry.type as entryType,journalEntry.amount as amount, journalEntry.transaction_id as transactionId," + " journalEntry.type_enum as entryType,journalEntry.amount as amount, journalEntry.transaction_id as transactionId,"
+ " journalEntry.entity_type as entityType, journalEntry.entity_id as entityId, creatingUser.id as createdByUserId, " + " journalEntry.entity_type as entityType, journalEntry.entity_id as entityId, creatingUser.id as createdByUserId, "
+ " creatingUser.username as createdByUserName, journalEntry.description as comments, " + " creatingUser.username as createdByUserName, journalEntry.description as comments, "
+ " journalEntry.created_date as createdDate, journalEntry.reversed as reversed " + " journalEntry.created_date as createdDate, journalEntry.reversed as reversed "
@@ -55,22 +57,24 @@ public class GLJournalEntryReadPlatformServiceImpl implements GLJournalEntryRead
String officeName = rs.getString("officeName"); String officeName = rs.getString("officeName");
String glAccountName = rs.getString("glAccountName"); String glAccountName = rs.getString("glAccountName");
Long glAccountId = rs.getLong("glAccountId"); Long glAccountId = rs.getLong("glAccountId");
String glAccountClassification = rs.getString("classification"); final int accountTypeId = JdbcSupport.getInteger(rs, "classification");
final EnumOptionData accountType = AccountingEnumerations.gLAccountType(accountTypeId);
LocalDate entryDate = JdbcSupport.getLocalDate(rs, "entryDate"); LocalDate entryDate = JdbcSupport.getLocalDate(rs, "entryDate");
Boolean portfolioGenerated = rs.getBoolean("portfolioGenerated"); Boolean portfolioGenerated = rs.getBoolean("portfolioGenerated");
BigDecimal amount = rs.getBigDecimal("amount"); BigDecimal amount = rs.getBigDecimal("amount");
String entryType = rs.getString("entryType"); int entryTypeId = JdbcSupport.getInteger(rs, "entryType");
final EnumOptionData entryType = AccountingEnumerations.journalEntryType(entryTypeId);
String transactionId = rs.getString("transactionId"); String transactionId = rs.getString("transactionId");
String entityType = rs.getString("entityType"); String entityType = rs.getString("entityType");
Long entityId = rs.getLong("entityId"); Long entityId = JdbcSupport.getLong(rs, "entityId");
Long createdByUserId = rs.getLong("createdByUserId"); Long createdByUserId = rs.getLong("createdByUserId");
LocalDate createdDate = JdbcSupport.getLocalDate(rs, "createdDate"); LocalDate createdDate = JdbcSupport.getLocalDate(rs, "createdDate");
String createdByUserName = rs.getString("createdByUserName"); String createdByUserName = rs.getString("createdByUserName");
String comments = rs.getString("comments"); String comments = rs.getString("comments");
Boolean reversed = rs.getBoolean("reversed"); Boolean reversed = rs.getBoolean("reversed");
return new GLJournalEntryData(journalEntryId, officeId, officeName, glAccountName, glAccountId, glAccountClassification, return new GLJournalEntryData(journalEntryId, officeId, officeName, glAccountName, glAccountId, accountType, entryDate,
entryDate, entryType, amount, transactionId, portfolioGenerated, entityType, entityId, createdByUserId, createdDate, entryType, amount, transactionId, portfolioGenerated, entityType, entityId, createdByUserId, createdDate,
createdByUserName, comments, reversed); createdByUserName, comments, reversed);
} }
} }
@@ -8,8 +8,6 @@ import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.accounting.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN; import org.mifosplatform.accounting.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
import org.mifosplatform.accounting.AccountingConstants.JOURNAL_ENTRY_TYPE;
import org.mifosplatform.accounting.AccountingConstants.PORTFOLIO_PRODUCT_TYPE;
import org.mifosplatform.accounting.api.commands.GLJournalEntryCommand; import org.mifosplatform.accounting.api.commands.GLJournalEntryCommand;
import org.mifosplatform.accounting.api.commands.SingleDebitOrCreditEntryCommand; import org.mifosplatform.accounting.api.commands.SingleDebitOrCreditEntryCommand;
import org.mifosplatform.accounting.api.data.LoanDTO; import org.mifosplatform.accounting.api.data.LoanDTO;
@@ -20,6 +18,8 @@ import org.mifosplatform.accounting.domain.GLClosure;
import org.mifosplatform.accounting.domain.GLClosureRepository; import org.mifosplatform.accounting.domain.GLClosureRepository;
import org.mifosplatform.accounting.domain.GLJournalEntry; import org.mifosplatform.accounting.domain.GLJournalEntry;
import org.mifosplatform.accounting.domain.GLJournalEntryRepository; import org.mifosplatform.accounting.domain.GLJournalEntryRepository;
import org.mifosplatform.accounting.domain.JournalEntryType;
import org.mifosplatform.accounting.domain.PortfolioProductType;
import org.mifosplatform.accounting.domain.ProductToGLAccountMapping; import org.mifosplatform.accounting.domain.ProductToGLAccountMapping;
import org.mifosplatform.accounting.domain.ProductToGLAccountMappingRepository; import org.mifosplatform.accounting.domain.ProductToGLAccountMappingRepository;
import org.mifosplatform.accounting.exceptions.GLAccountNotFoundException; import org.mifosplatform.accounting.exceptions.GLAccountNotFoundException;
@@ -78,9 +78,9 @@ public class GLJournalEntryWritePlatformServiceJpaRepositoryImpl implements GLJo
Date entryDate = command.getEntryDate().toDateMidnight().toDate(); Date entryDate = command.getEntryDate().toDateMidnight().toDate();
String transactionId = generateTransactionId(); String transactionId = generateTransactionId();
saveAllDebitOrCreditEntries(command, office, entryDate, command.getDebits(), transactionId, JOURNAL_ENTRY_TYPE.DEBIT); saveAllDebitOrCreditEntries(command, office, entryDate, command.getDebits(), transactionId, JournalEntryType.DEBIT);
saveAllDebitOrCreditEntries(command, office, entryDate, command.getCredits(), transactionId, JOURNAL_ENTRY_TYPE.CREDIT); saveAllDebitOrCreditEntries(command, office, entryDate, command.getCredits(), transactionId, JournalEntryType.CREDIT);
return transactionId; return transactionId;
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
@@ -104,14 +104,14 @@ public class GLJournalEntryWritePlatformServiceJpaRepositoryImpl implements GLJo
GLJournalEntry reversalJournalEntry; GLJournalEntry reversalJournalEntry;
String reversalComment = "Reversal entry for Journal Entry with Entry Id :" + journalEntry.getId() + " and transaction Id " String reversalComment = "Reversal entry for Journal Entry with Entry Id :" + journalEntry.getId() + " and transaction Id "
+ transactionId; + transactionId;
if (journalEntry.getType().equalsIgnoreCase(JOURNAL_ENTRY_TYPE.DEBIT.toString())) { if (journalEntry.isDebitEntry()) {
reversalJournalEntry = GLJournalEntry.createNew(journalEntry.getOffice(), journalEntry.getGlAccount(), reversalJournalEntry = GLJournalEntry.createNew(journalEntry.getOffice(), journalEntry.getGlAccount(),
reversalTransactionId, false, journalEntry.getEntryDate(), JOURNAL_ENTRY_TYPE.CREDIT.toString(), reversalTransactionId, false, journalEntry.getEntryDate(), JournalEntryType.CREDIT, journalEntry.getAmount(),
journalEntry.getAmount(), reversalComment, null, null); reversalComment, null, null);
} else { } else {
reversalJournalEntry = GLJournalEntry.createNew(journalEntry.getOffice(), journalEntry.getGlAccount(), reversalJournalEntry = GLJournalEntry.createNew(journalEntry.getOffice(), journalEntry.getGlAccount(),
reversalTransactionId, false, journalEntry.getEntryDate(), JOURNAL_ENTRY_TYPE.DEBIT.toString(), reversalTransactionId, false, journalEntry.getEntryDate(), JournalEntryType.DEBIT, journalEntry.getAmount(),
journalEntry.getAmount(), reversalComment, null, null); reversalComment, null, null);
} }
// save the reversal entry // save the reversal entry
this.glJournalEntryRepository.saveAndFlush(reversalJournalEntry); this.glJournalEntryRepository.saveAndFlush(reversalJournalEntry);
@@ -267,21 +267,21 @@ public class GLJournalEntryWritePlatformServiceJpaRepositoryImpl implements GLJo
private GLAccount getLinkedFinAccountForLoanProduct(Long loanProductId, CASH_ACCOUNTS_FOR_LOAN finAccountType) { private GLAccount getLinkedFinAccountForLoanProduct(Long loanProductId, CASH_ACCOUNTS_FOR_LOAN finAccountType) {
ProductToGLAccountMapping accountMapping = accountMappingRepository.findByProductIdAndProductTypeAndFinancialAccountType( ProductToGLAccountMapping accountMapping = accountMappingRepository.findByProductIdAndProductTypeAndFinancialAccountType(
loanProductId, PORTFOLIO_PRODUCT_TYPE.LOAN.getValue(), finAccountType.getValue()); loanProductId, PortfolioProductType.LOAN.getValue(), finAccountType.getValue());
return accountMapping.getGlAccount(); return accountMapping.getGlAccount();
} }
private void createCreditJournalEntryForLoanProduct(Office office, GLAccount account, Long loanId, String transactionId, private void createCreditJournalEntryForLoanProduct(Office office, GLAccount account, Long loanId, String transactionId,
Date entryDate, BigDecimal amount) { Date entryDate, BigDecimal amount) {
GLJournalEntry journalEntry = GLJournalEntry.createNew(office, account, transactionId, true, entryDate, GLJournalEntry journalEntry = GLJournalEntry.createNew(office, account, transactionId, true, entryDate, JournalEntryType.CREDIT,
JOURNAL_ENTRY_TYPE.CREDIT.toString(), amount, null, PORTFOLIO_PRODUCT_TYPE.LOAN.toString(), loanId); amount, null, PortfolioProductType.LOAN.toString(), loanId);
glJournalEntryRepository.saveAndFlush(journalEntry); glJournalEntryRepository.saveAndFlush(journalEntry);
} }
private void createDebitJournalEntryForLoanProduct(Office office, GLAccount account, Long loanId, String transactionId, Date entryDate, private void createDebitJournalEntryForLoanProduct(Office office, GLAccount account, Long loanId, String transactionId, Date entryDate,
BigDecimal amount) { BigDecimal amount) {
GLJournalEntry journalEntry = GLJournalEntry.createNew(office, account, transactionId, true, entryDate, GLJournalEntry journalEntry = GLJournalEntry.createNew(office, account, transactionId, true, entryDate, JournalEntryType.DEBIT,
JOURNAL_ENTRY_TYPE.DEBIT.toString(), amount, null, PORTFOLIO_PRODUCT_TYPE.LOAN.toString(), loanId); amount, null, PortfolioProductType.LOAN.toString(), loanId);
glJournalEntryRepository.saveAndFlush(journalEntry); glJournalEntryRepository.saveAndFlush(journalEntry);
} }
@@ -336,7 +336,7 @@ public class GLJournalEntryWritePlatformServiceJpaRepositoryImpl implements GLJo
* @param transactionId * @param transactionId
*/ */
private void saveAllDebitOrCreditEntries(GLJournalEntryCommand command, final Office office, Date entryDate, private void saveAllDebitOrCreditEntries(GLJournalEntryCommand command, final Office office, Date entryDate,
SingleDebitOrCreditEntryCommand[] singleDebitOrCreditEntryCommands, String transactionId, JOURNAL_ENTRY_TYPE type) { SingleDebitOrCreditEntryCommand[] singleDebitOrCreditEntryCommands, String transactionId, JournalEntryType type) {
for (SingleDebitOrCreditEntryCommand singleDebitOrCreditEntryCommand : singleDebitOrCreditEntryCommands) { for (SingleDebitOrCreditEntryCommand singleDebitOrCreditEntryCommand : singleDebitOrCreditEntryCommands) {
GLAccount glAccount = glAccountRepository.findOne(singleDebitOrCreditEntryCommand.getGlAccountId()); GLAccount glAccount = glAccountRepository.findOne(singleDebitOrCreditEntryCommand.getGlAccountId());
if (glAccount == null) { throw new GLAccountNotFoundException(singleDebitOrCreditEntryCommand.getGlAccountId()); } if (glAccount == null) { throw new GLAccountNotFoundException(singleDebitOrCreditEntryCommand.getGlAccountId()); }
@@ -356,7 +356,7 @@ public class GLJournalEntryWritePlatformServiceJpaRepositoryImpl implements GLJo
if (!StringUtils.isBlank(singleDebitOrCreditEntryCommand.getComments())) { if (!StringUtils.isBlank(singleDebitOrCreditEntryCommand.getComments())) {
comments = singleDebitOrCreditEntryCommand.getComments(); comments = singleDebitOrCreditEntryCommand.getComments();
} }
GLJournalEntry glJournalEntry = GLJournalEntry.createNew(office, glAccount, transactionId, false, entryDate, type.toString(), GLJournalEntry glJournalEntry = GLJournalEntry.createNew(office, glAccount, transactionId, false, entryDate, type,
singleDebitOrCreditEntryCommand.getAmount(), comments, null, null); singleDebitOrCreditEntryCommand.getAmount(), comments, null, null);
glJournalEntryRepository.saveAndFlush(glJournalEntry); glJournalEntryRepository.saveAndFlush(glJournalEntry);
} }
@@ -4,13 +4,12 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.mifosplatform.accounting.AccountingConstants;
import org.mifosplatform.accounting.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN; import org.mifosplatform.accounting.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
import org.mifosplatform.accounting.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN; import org.mifosplatform.accounting.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
import org.mifosplatform.accounting.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS; import org.mifosplatform.accounting.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
import org.mifosplatform.accounting.AccountingConstants.PORTFOLIO_PRODUCT_TYPE;
import org.mifosplatform.accounting.domain.GLAccount; import org.mifosplatform.accounting.domain.GLAccount;
import org.mifosplatform.accounting.domain.GLAccountRepository; import org.mifosplatform.accounting.domain.GLAccountRepository;
import org.mifosplatform.accounting.domain.PortfolioProductType;
import org.mifosplatform.accounting.domain.ProductToGLAccountMapping; import org.mifosplatform.accounting.domain.ProductToGLAccountMapping;
import org.mifosplatform.accounting.domain.ProductToGLAccountMappingRepository; import org.mifosplatform.accounting.domain.ProductToGLAccountMappingRepository;
import org.mifosplatform.accounting.exceptions.GLAccountNotFoundException; import org.mifosplatform.accounting.exceptions.GLAccountNotFoundException;
@@ -181,7 +180,7 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
GLAccount glAccount = accountRepository.findOne(glAccountId); GLAccount glAccount = accountRepository.findOne(glAccountId);
if (glAccount == null) { throw new GLAccountNotFoundException(glAccountId); } if (glAccount == null) { throw new GLAccountNotFoundException(glAccountId); }
ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping(glAccount, productId, ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping(glAccount, productId,
AccountingConstants.PORTFOLIO_PRODUCT_TYPE.LOAN.getValue(), accountTypeId); PortfolioProductType.LOAN.getValue(), accountTypeId);
accountMappingRepository.save(accountMapping); accountMappingRepository.save(accountMapping);
} }
@@ -189,8 +188,8 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
String accountParamValue, Map<String, Object> changes) { String accountParamValue, Map<String, Object> changes) {
// get the existing product // get the existing product
ProductToGLAccountMapping accountMapping = accountMappingRepository.findByProductIdAndProductTypeAndFinancialAccountType(productId, ProductToGLAccountMapping accountMapping = accountMappingRepository.findByProductIdAndProductTypeAndFinancialAccountType(productId,
PORTFOLIO_PRODUCT_TYPE.LOAN.getValue(), accountTypeId); PortfolioProductType.LOAN.getValue(), accountTypeId);
if (accountMapping == null) { throw new ProductToGLAccountMappingNotFoundException(PORTFOLIO_PRODUCT_TYPE.LOAN, productId, if (accountMapping == null) { throw new ProductToGLAccountMappingNotFoundException(PortfolioProductType.LOAN, productId,
accountTypeName); } accountTypeName); }
if (accountMapping.getGlAccount().getId() != glAccountId) { if (accountMapping.getGlAccount().getId() != glAccountId) {
GLAccount glAccount = accountRepository.findOne(glAccountId); GLAccount glAccount = accountRepository.findOne(glAccountId);
@@ -204,7 +203,7 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
@Override @Override
public void deleteLoanProductToGLAccountMapping(Long loanProductId) { public void deleteLoanProductToGLAccountMapping(Long loanProductId) {
List<ProductToGLAccountMapping> productToGLAccountMappings = accountMappingRepository.findByProductIdAndProductType(loanProductId, List<ProductToGLAccountMapping> productToGLAccountMappings = accountMappingRepository.findByProductIdAndProductType(loanProductId,
PORTFOLIO_PRODUCT_TYPE.LOAN.getValue()); PortfolioProductType.LOAN.getValue());
if (productToGLAccountMappings != null && productToGLAccountMappings.size() > 0) { if (productToGLAccountMappings != null && productToGLAccountMappings.size() > 0) {
accountMappingRepository.deleteInBatch(productToGLAccountMappings); accountMappingRepository.deleteInBatch(productToGLAccountMappings);
} }
@@ -132,6 +132,33 @@ public class JsonParserHelper {
} }
return value; return value;
} }
/** Method used to extract integers from unformatted strings.
* Ex: "1" , "100002" etc
*
* Please note that this method does not support extracting Integers from locale
* specific formatted strings Ex "1,000" etc
*
* @param parameterName
* @param element
* @param parametersPassedInRequest
* @return
*/
public Integer extractIntegerFromUnFormattedStringNamed(final String parameterName, final JsonElement element, final Set<String> parametersPassedInRequest) {
Integer intValue = null;
if (element.isJsonObject()) {
JsonObject object = element.getAsJsonObject();
if (object.has(parameterName) && object.get(parameterName).isJsonPrimitive()) {
parametersPassedInRequest.add(parameterName);
JsonPrimitive primitive = object.get(parameterName).getAsJsonPrimitive();
final String stringValue = primitive.getAsString();
if (StringUtils.isNotBlank(stringValue)) {
intValue = Integer.valueOf(stringValue);
}
}
}
return intValue;
}
public String extractDateFormatParameter(final JsonObject element) { public String extractDateFormatParameter(final JsonObject element) {
String value = null; String value = null;
@@ -17,16 +17,13 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.accounting.AccountingConstants.GL_ACCOUNT_CLASSIFICATION;
import org.mifosplatform.accounting.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS; import org.mifosplatform.accounting.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
import org.mifosplatform.accounting.api.data.GLAccountData; import org.mifosplatform.accounting.api.data.GLAccountData;
import org.mifosplatform.accounting.domain.GLAccountType;
import org.mifosplatform.accounting.service.GLAccountReadPlatformService; import org.mifosplatform.accounting.service.GLAccountReadPlatformService;
import org.mifosplatform.accounting.service.ProductToGLAccountMappingReadPlatformService; import org.mifosplatform.accounting.service.ProductToGLAccountMappingReadPlatformService;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
@@ -194,9 +191,9 @@ public class LoanProductsApiResource {
final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions = this.dropdownReadPlatformService final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions = this.dropdownReadPlatformService
.retreiveTransactionProcessingStrategies(); .retreiveTransactionProcessingStrategies();
final List<GLAccountData> assetAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GL_ACCOUNT_CLASSIFICATION.ASSET); final List<GLAccountData> assetAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GLAccountType.ASSET);
final List<GLAccountData> incomeAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GL_ACCOUNT_CLASSIFICATION.INCOME);; final List<GLAccountData> incomeAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GLAccountType.INCOME);;
final List<GLAccountData> expenseAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GL_ACCOUNT_CLASSIFICATION.EXPENSE);; final List<GLAccountData> expenseAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GLAccountType.EXPENSE);;
return new LoanProductData(productData, chargeOptions, currencyOptions, amortizationTypeOptions, interestTypeOptions, return new LoanProductData(productData, chargeOptions, currencyOptions, amortizationTypeOptions, interestTypeOptions,
interestCalculationPeriodTypeOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions, interestCalculationPeriodTypeOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,