Merge pull request #547 from mifoscontributer/mifox-predefinedAR

Changing predefined posting json for consistenxy
This commit is contained in:
Vishwas Babu A J
2013-08-28 00:31:44 -07:00
4 changed files with 74 additions and 118 deletions
@@ -16,7 +16,8 @@ public class JournalEntryInvalidException extends AbstractPlatformDomainRuleExce
/*** enum of reasons for invalid Journal Entry **/
public static enum GL_JOURNAL_ENTRY_INVALID_REASON {
FUTURE_DATE, ACCOUNTING_CLOSED, NO_DEBITS_OR_CREDITS, DEBIT_CREDIT_SUM_MISMATCH_WITH_AMOUNT, DEBIT_CREDIT_SUM_MISMATCH, DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, GL_ACCOUNT_DISABLED, GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED;
FUTURE_DATE, ACCOUNTING_CLOSED, NO_DEBITS_OR_CREDITS, DEBIT_CREDIT_SUM_MISMATCH_WITH_AMOUNT, DEBIT_CREDIT_SUM_MISMATCH, DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, GL_ACCOUNT_DISABLED, GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED,
INVALID_DEBIT_OR_CREDIT_ACCOUNTS;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
@@ -33,6 +34,8 @@ public class JournalEntryInvalidException extends AbstractPlatformDomainRuleExce
return "Both account and amount must be specified for all Debits and Credits";
} else if (name().toString().equalsIgnoreCase("GL_ACCOUNT_DISABLED")) {
return "Target account has been disabled";
} else if (name().toString().equalsIgnoreCase("INVALID_DEBIT_OR_CREDIT_ACCOUNTS")) {
return "Invalid debit or credit accounts are passed";
} else if (name().toString().equalsIgnoreCase("GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED")) { return "Target account does not allow maual adjustments"; }
return name().toString();
}
@@ -50,6 +53,8 @@ public class JournalEntryInvalidException extends AbstractPlatformDomainRuleExce
return "error.msg.glJournalEntry.invalid.empty.account.or.amount";
} else if (name().toString().equalsIgnoreCase("GL_ACCOUNT_DISABLED")) {
return "error.msg.glJournalEntry.invalid.account.disabled";
} else if (name().toString().equalsIgnoreCase("INVALID_DEBIT_OR_CREDIT_ACCOUNTS")) {
return "error.msg.glJournalEntry.invalid.debit.or.credit.accounts";
} else if (name().toString().equalsIgnoreCase("GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED")) { return "error.msg.glJournalEntry.invalid.account.manual.adjustments.not.permitted"; }
return name().toString();
}
@@ -106,63 +106,48 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
final Date transactionDate = command.DateValueOfParameterNamed(JournalEntryJsonInputParams.TRANSACTION_DATE.getValue());
final String transactionId = generateTransactionId();
final String referenceNumber = command.stringValueOfParameterNamed(JournalEntryJsonInputParams.REFERENCE_NUMBER.getValue());
final boolean manualEntry = true;
if (accountRuleId != null) {
final BigDecimal amount = command.bigDecimalValueOfParameterNamed(JournalEntryJsonInputParams.AMOUNT.getValue());
String description = null;
if (StringUtils.isNotBlank(journalEntryCommand.getComments())) {
description = journalEntryCommand.getComments();
}
final AccountingRule accountingRule = this.accountingRuleRepository.findOne(accountRuleId);
if (accountingRule == null) { throw new AccountingRuleNotFoundException(accountRuleId); }
if (accountingRule.getAccountToCredit() == null) {
if (journalEntryCommand.getCredits() == null) { throw new RuntimeException(
"You have to pass atleast one value for credits"); }
if (journalEntryCommand.getCredits() == null) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.NO_DEBITS_OR_CREDITS, null, null, null); }
if (journalEntryCommand.getDebits() != null) {
checkDebitOrCreditAccountsAreValid(accountingRule, journalEntryCommand.getCredits(),
journalEntryCommand.getDebits());
checkDebitAndCreditAmounts(journalEntryCommand.getCredits(), journalEntryCommand.getDebits());
} else {
checkDebitAndCreditAmounts(journalEntryCommand.getCredits(), amount);
}
saveAllDebitOrCreditEntries(journalEntryCommand, office, transactionDate, journalEntryCommand.getCredits(),
transactionId, JournalEntryType.CREDIT, referenceNumber);
} else {
if (journalEntryCommand.getCredits() != null) { throw new RuntimeException(
"You can not pass credits for this rule please verify your rule"); }
final GLAccount creditAccountHead = accountingRule.getAccountToCredit();
validateGLAccountForTransaction(creditAccountHead);
final JournalEntry creditEntry = JournalEntry.createNew(office, creditAccountHead, transactionId, manualEntry,
transactionDate, JournalEntryType.CREDIT, amount, description, null, null, referenceNumber);
this.glJournalEntryRepository.saveAndFlush(creditEntry);
validateDebitOrCreditArrayForExistingGLAccount(creditAccountHead,journalEntryCommand.getCredits());
saveAllDebitOrCreditEntries(journalEntryCommand, office, transactionDate, journalEntryCommand.getCredits(),
transactionId, JournalEntryType.CREDIT, referenceNumber);
}
if (accountingRule.getAccountToDebit() == null) {
if (journalEntryCommand.getDebits() == null) { throw new RuntimeException(
"You have to pass atleast one parameter for debits"); }
if (journalEntryCommand.getDebits() == null) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.NO_DEBITS_OR_CREDITS, null, null, null); }
if (journalEntryCommand.getCredits() != null) {
checkDebitOrCreditAccountsAreValid(accountingRule, journalEntryCommand.getCredits(),
journalEntryCommand.getDebits());
checkDebitAndCreditAmounts(journalEntryCommand.getCredits(), journalEntryCommand.getDebits());
} else {
checkDebitAndCreditAmounts(journalEntryCommand.getDebits(), amount);
}
saveAllDebitOrCreditEntries(journalEntryCommand, office, transactionDate, journalEntryCommand.getDebits(),
transactionId, JournalEntryType.DEBIT, referenceNumber);
} else {
if (journalEntryCommand.getDebits() != null) { throw new RuntimeException(
"You can not pass debits for this rule please verify your rule"); }
final GLAccount debitAccountHead = accountingRule.getAccountToDebit();
validateGLAccountForTransaction(debitAccountHead);
final JournalEntry debitEntry = JournalEntry.createNew(office, debitAccountHead, transactionId, manualEntry,
transactionDate, JournalEntryType.DEBIT, amount, description, null, null, referenceNumber);
this.glJournalEntryRepository.saveAndFlush(debitEntry);
validateDebitOrCreditArrayForExistingGLAccount(debitAccountHead,journalEntryCommand.getDebits());
saveAllDebitOrCreditEntries(journalEntryCommand, office, transactionDate, journalEntryCommand.getDebits(),
transactionId, JournalEntryType.DEBIT, referenceNumber);
}
} else {
@@ -182,6 +167,19 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
}
}
private void validateDebitOrCreditArrayForExistingGLAccount(GLAccount glaccount, SingleDebitOrCreditEntryCommand[] creditOrDebits) {
/**
* If a glaccount is assigned for a rule the credits or debits array
* should have only one entry and it must be same as existing account
*/
if (creditOrDebits.length != 1) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.INVALID_DEBIT_OR_CREDIT_ACCOUNTS, null, null, null); }
for (SingleDebitOrCreditEntryCommand creditOrDebit : creditOrDebits) {
if (!glaccount.getId().equals(creditOrDebit.getGlAccountId())) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.INVALID_DEBIT_OR_CREDIT_ACCOUNTS, null, null, null); }
}
}
@SuppressWarnings("null")
private void checkDebitOrCreditAccountsAreValid(final AccountingRule accountingRule, final SingleDebitOrCreditEntryCommand[] credits,
final SingleDebitOrCreditEntryCommand[] debits) {
@@ -238,19 +236,6 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
GL_JOURNAL_ENTRY_INVALID_REASON.DEBIT_CREDIT_SUM_MISMATCH, null, null, null); }
}
private void checkDebitAndCreditAmounts(final SingleDebitOrCreditEntryCommand[] creditOrDebits, final BigDecimal amount) {
if (amount == null) { throw new JournalEntryInvalidException(GL_JOURNAL_ENTRY_INVALID_REASON.DEBIT_CREDIT_SUM_MISMATCH_WITH_AMOUNT,
null, null, null); }
BigDecimal creditOrDebitSum = BigDecimal.ZERO;
for (final SingleDebitOrCreditEntryCommand creditEntryCommand : creditOrDebits) {
if (creditEntryCommand.getAmount() == null || creditEntryCommand.getGlAccountId() == null) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, null, null, null); }
creditOrDebitSum = creditOrDebitSum.add(creditEntryCommand.getAmount());
}
if (creditOrDebitSum.compareTo(amount) != 0) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.DEBIT_CREDIT_SUM_MISMATCH, null, null, null); }
}
private void validateGLAccountForTransaction(final GLAccount creditOrDebitAccountHead) {
/***
* validate that the account allows manual adjustments and is not
@@ -346,17 +331,16 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
if (latestGLClosure.getClosingDate().after(transactionDate) || latestGLClosure.getClosingDate().equals(transactionDate)) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate(), null, null); }
}
if (command.getAccountingRuleId() == null) {
/*** check if credits and debits are valid **/
final SingleDebitOrCreditEntryCommand[] credits = command.getCredits();
final SingleDebitOrCreditEntryCommand[] debits = command.getDebits();
// atleast one debit or credit must be present
if ((credits == null || credits.length <= 0) || (debits == null || debits.length <= 0)) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.NO_DEBITS_OR_CREDITS, null, null, null); }
/*** check if credits and debits are valid **/
final SingleDebitOrCreditEntryCommand[] credits = command.getCredits();
final SingleDebitOrCreditEntryCommand[] debits = command.getDebits();
checkDebitAndCreditAmounts(credits, debits);
}
// atleast one debit or credit must be present
if ((credits == null || credits.length <= 0) || (debits == null || debits.length <= 0)) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.NO_DEBITS_OR_CREDITS, null, null, null); }
checkDebitAndCreditAmounts(credits, debits);
}
private void saveAllDebitOrCreditEntries(final JournalEntryCommand command, final Office office, final Date transactionDate,
@@ -30,15 +30,17 @@ public class AccountingRuleData {
private final boolean systemDefined;
private final boolean allowMultipleDebitEntries;
private final boolean allowMultipleCreditEntries;
private final GLAccountData debitAccountHead;
private final GLAccountData creditAccountHead;
private final List<AccountingTagRuleData> creditTags;
private final List<AccountingTagRuleData> debitTags;
// template
@SuppressWarnings("unused")
private List<OfficeData> allowedOffices = new ArrayList<OfficeData>();
@SuppressWarnings("unused")
private List<GLAccountData> allowedAccounts = new ArrayList<GLAccountData>();
@SuppressWarnings("unused")
private final Collection<CodeValueData> allowedCreditTagOptions;
@SuppressWarnings("unused")
private final Collection<CodeValueData> allowedDebitTagOptions;
private final List<GLAccountDataForLookup> creditAccounts;
private final List<GLAccountDataForLookup> debitAccounts;
@@ -56,8 +58,6 @@ public class AccountingRuleData {
this.allowMultipleCreditEntries = accountingRuleData.allowMultipleCreditEntries;
this.allowedOffices = allowedOffices;
this.allowedAccounts = allowedAccounts;
this.debitAccountHead = accountingRuleData.debitAccountHead;
this.creditAccountHead = accountingRuleData.creditAccountHead;
this.allowedCreditTagOptions = allowedCreditTagOptions;
this.allowedDebitTagOptions = allowedDebitTagOptions;
this.creditTags = accountingRuleData.creditTags;
@@ -78,8 +78,6 @@ public class AccountingRuleData {
this.allowMultipleCreditEntries = false;
this.allowedOffices = allowedOffices;
this.allowedAccounts = allowedAccounts;
this.debitAccountHead = null;
this.creditAccountHead = null;
this.allowedCreditTagOptions = allowedCreditTagOptions;
this.allowedDebitTagOptions = allowedDebitTagOptions;
this.creditTags = null;
@@ -90,7 +88,8 @@ public class AccountingRuleData {
public AccountingRuleData(final Long id, final Long officeId, final String officeName, final String name, final String description,
final boolean systemDefined, final boolean allowMultipleDebitEntries, final boolean allowMultipleCreditEntries,
final GLAccountData debitAccountData, final GLAccountData creditAccountData) {
final List<AccountingTagRuleData> creditTags, final List<AccountingTagRuleData> debitTags,
final List<GLAccountDataForLookup> creditAccounts, final List<GLAccountDataForLookup> debitAccounts) {
this.id = id;
this.officeId = officeId;
this.officeName = officeName;
@@ -101,47 +100,14 @@ public class AccountingRuleData {
this.allowMultipleCreditEntries = allowMultipleCreditEntries;
this.allowedOffices = null;
this.allowedAccounts = null;
this.debitAccountHead = debitAccountData;
this.creditAccountHead = creditAccountData;
this.allowedCreditTagOptions = null;
this.allowedDebitTagOptions = null;
this.creditTags = null;
this.debitTags = null;
this.creditAccounts = new ArrayList<GLAccountDataForLookup>();
this.debitAccounts = new ArrayList<GLAccountDataForLookup>();
}
public AccountingRuleData(final AccountingRuleData accountingRuleData, final List<AccountingTagRuleData> creditTags,
final List<GLAccountDataForLookup> creditAccounts, final List<AccountingTagRuleData> debitTags,
final List<GLAccountDataForLookup> debitAccounts) {
this.id = accountingRuleData.id;
this.officeId = accountingRuleData.officeId;
this.officeName = accountingRuleData.officeName;
this.name = accountingRuleData.name;
this.description = accountingRuleData.description;
this.systemDefined = accountingRuleData.systemDefined;
this.allowMultipleDebitEntries = accountingRuleData.allowMultipleDebitEntries;
this.allowMultipleCreditEntries = accountingRuleData.allowMultipleCreditEntries;
this.allowedOffices = accountingRuleData.allowedOffices;
this.allowedAccounts = accountingRuleData.allowedAccounts;
this.debitAccountHead = accountingRuleData.debitAccountHead;
this.creditAccountHead = accountingRuleData.creditAccountHead;
this.allowedCreditTagOptions = accountingRuleData.allowedCreditTagOptions;
this.allowedDebitTagOptions = accountingRuleData.allowedDebitTagOptions;
this.creditTags = creditTags;
this.creditAccounts = creditAccounts;
this.debitTags = debitTags;
this.creditAccounts = creditAccounts;
this.debitAccounts = debitAccounts;
}
public GLAccountData getDebitAccountHead() {
return this.debitAccountHead;
}
public GLAccountData getCreditAccountHead() {
return this.creditAccountHead;
}
public List<AccountingTagRuleData> getCreditTags() {
return this.creditTags;
}
@@ -150,11 +116,4 @@ public class AccountingRuleData {
return this.debitTags;
}
public List<GLAccountDataForLookup> getCreditAccounts() {
return this.creditAccounts;
}
public List<GLAccountDataForLookup> getDebitAccounts() {
return this.debitAccounts;
}
}
@@ -8,12 +8,12 @@ package org.mifosplatform.accounting.rule.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.mifosplatform.accounting.common.AccountingEnumerations;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.glaccount.data.GLAccountDataForLookup;
import org.mifosplatform.accounting.glaccount.service.GLAccountReadPlatformService;
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
@@ -96,29 +96,37 @@ public class AccountingRuleReadPlatformServiceImpl implements AccountingRuleRead
final String debitAccountGLCode = rs.getString("debitAccountGLCode");
final String creditAccountGLCode = rs.getString("creditAccountGLCode");
final GLAccountData debitAccountData = accountToDebitId == null ? null : new GLAccountData(accountToDebitId,
debitAccountName, debitAccountGLCode);
final GLAccountData creditAccountData = accountToCreditId == null ? null : new GLAccountData(accountToCreditId,
creditAccountName, creditAccountGLCode);
final List<AccountingTagRuleData> creditTags;
final List<AccountingTagRuleData> debitTags;
final List<GLAccountDataForLookup> creditAccounts;
final List<GLAccountDataForLookup> debitAccounts;
if (accountToCreditId == null) {
creditTags = !this.isAssociationParametersExists ? getCreditOrDebitTags(id, JournalEntryType.CREDIT.getValue())
: null;
creditAccounts = this.isAssociationParametersExists ? this.glAccountReadPlatformService.retrieveAccountsByTagId(id,
JournalEntryType.CREDIT.getValue()) : null;
} else {
creditTags = null;
final GLAccountDataForLookup creditAccount = new GLAccountDataForLookup(accountToCreditId, creditAccountName,
creditAccountGLCode);
creditAccounts = new ArrayList<GLAccountDataForLookup>(Arrays.asList(creditAccount));
}
if (accountToDebitId == null) {
debitTags = !this.isAssociationParametersExists ? getCreditOrDebitTags(id, JournalEntryType.DEBIT.getValue())
: null;
debitAccounts = this.isAssociationParametersExists ? this.glAccountReadPlatformService.retrieveAccountsByTagId(id,
JournalEntryType.DEBIT.getValue()) : null;
} else {
debitTags = null;
final GLAccountDataForLookup debitAccount = new GLAccountDataForLookup(accountToDebitId, debitAccountName,
debitAccountGLCode);
debitAccounts = new ArrayList<GLAccountDataForLookup>(Arrays.asList(debitAccount));
}
accountingRuleData = new AccountingRuleData(id, officeId, officeName, name, description, systemDefined,
allowMultipleDebitEntries, allowMultipleCreditEntries, debitAccountData, creditAccountData);
}
if (accountingRuleData.getCreditAccountHead() == null) {
final List<AccountingTagRuleData> creditTags = !this.isAssociationParametersExists ? getCreditOrDebitTags(id,
JournalEntryType.CREDIT.getValue()) : null;
final List<GLAccountDataForLookup> creditAccounts = this.isAssociationParametersExists ? this.glAccountReadPlatformService
.retrieveAccountsByTagId(id, JournalEntryType.CREDIT.getValue()) : null;
accountingRuleData = new AccountingRuleData(accountingRuleData, creditTags, creditAccounts,
accountingRuleData.getDebitTags(), accountingRuleData.getDebitAccounts());
}
if (accountingRuleData.getDebitAccountHead() == null) {
final List<AccountingTagRuleData> debitTags = !this.isAssociationParametersExists ? getCreditOrDebitTags(id,
JournalEntryType.DEBIT.getValue()) : null;
final List<GLAccountDataForLookup> debitAccounts = this.isAssociationParametersExists ? this.glAccountReadPlatformService
.retrieveAccountsByTagId(id, JournalEntryType.DEBIT.getValue()) : null;
accountingRuleData = new AccountingRuleData(accountingRuleData, accountingRuleData.getCreditTags(),
accountingRuleData.getCreditAccounts(), debitTags, debitAccounts);
allowMultipleDebitEntries, allowMultipleCreditEntries, creditTags, debitTags, creditAccounts, debitAccounts);
}
extractedData.put(id, accountingRuleData);
}
return extractedData;