Add Predefined Journal Entries with optional tag fields

This commit is contained in:
mifoscontributer
2013-05-29 12:07:43 +05:30
parent 42a2428774
commit 96789be7ad
8 changed files with 232 additions and 86 deletions
@@ -0,0 +1,15 @@
package org.mifosplatform.accounting.glaccount.data;
public class GLAccountDataForLookup {
private final Long id;
public GLAccountDataForLookup(final Long id) {
this.id = id;
}
public Long getId() {
return this.id;
}
}
@@ -8,6 +8,7 @@ package org.mifosplatform.accounting.glaccount.service;
import java.util.List;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.glaccount.data.GLAccountDataForLookup;
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
public interface GLAccountReadPlatformService {
@@ -24,4 +25,6 @@ public interface GLAccountReadPlatformService {
List<GLAccountData> retrieveAllEnabledHeaderGLAccounts(GLAccountType accountType);
GLAccountData retrieveNewGLAccountDetails(final Integer type);
List<GLAccountDataForLookup> retrieveAccountsByTagId(final Long ruleId, final Integer transactionType);
}
@@ -13,6 +13,7 @@ import java.util.List;
import org.apache.commons.lang.StringUtils;
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.domain.GLAccountType;
import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage;
import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidClassificationException;
@@ -65,7 +66,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
final String nameDecorated = rs.getString("nameDecorated");
final Long codeId = rs.wasNull() ? null : rs.getLong("codeId");
final String codeValue = rs.getString("codeValue");
CodeValueData tagId = CodeValueData.instance(codeId, codeValue);
final CodeValueData tagId = CodeValueData.instance(codeId, codeValue);
return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, accountType, usage, description,
nameDecorated, tagId);
}
@@ -202,4 +203,25 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
public List<GLAccountData> retrieveAllEnabledHeaderGLAccounts(final GLAccountType accountType) {
return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.HEADER.getValue(), null, false);
}
@Override
public List<GLAccountDataForLookup> retrieveAccountsByTagId(final Long ruleId, final Integer transactionType) {
final GLAccountDataLookUpMapper mapper = new GLAccountDataLookUpMapper();
final String sql = "Select " + mapper.schema() + " where rule.id=? and tags.acc_type_enum=?";
return this.jdbcTemplate.query(sql, mapper, new Object[] { ruleId, transactionType });
}
private static final class GLAccountDataLookUpMapper implements RowMapper<GLAccountDataForLookup> {
public String schema() {
return " gl.id as id from acc_accounting_rule rule join acc_rule_tags tags on tags.acc_rule_id = rule.id join acc_gl_account gl on gl.tag_id=tags.tag_id";
}
@Override
public GLAccountDataForLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long id = JdbcSupport.getLong(rs, "id");
return new GLAccountDataForLookup(id);
}
}
}
@@ -30,8 +30,8 @@ public class JournalEntryCommand {
private final SingleDebitOrCreditEntryCommand[] debits;
public JournalEntryCommand(final Long officeId, final LocalDate transactionDate, final String comments,
final SingleDebitOrCreditEntryCommand[] credits, final SingleDebitOrCreditEntryCommand[] debits,
final String referenceNumber, final Long accountingRuleId, final BigDecimal amount) {
final SingleDebitOrCreditEntryCommand[] credits, final SingleDebitOrCreditEntryCommand[] debits, final String referenceNumber,
final Long accountingRuleId, final BigDecimal amount) {
this.officeId = officeId;
this.transactionDate = transactionDate;
this.comments = comments;
@@ -53,46 +53,42 @@ public class JournalEntryCommand {
baseDataValidator.reset().parameter("officeId").value(this.officeId).notNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("comments").value(this.comments).ignoreIfNull().notExceedingLengthOf(500);
baseDataValidator.reset().parameter("referenceNumber").value(this.referenceNumber).ignoreIfNull().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("accountingRule").value(this.accountingRuleId).ignoreIfNull().longGreaterThanZero();
if (this.accountingRuleId == null) {
baseDataValidator.reset().parameter("credits").value(this.credits).notNull();
baseDataValidator.reset().parameter("debits").value(this.debits).notNull();
// validation for credit array elements
if (this.credits != null) {
if (this.credits.length == 0) {
validateSingleDebitOrCredit(baseDataValidator, "credits", 0, new SingleDebitOrCreditEntryCommand(null, null, null, null));
} else {
int i = 0;
for (final SingleDebitOrCreditEntryCommand credit : this.credits) {
validateSingleDebitOrCredit(baseDataValidator, "credits", i, credit);
i++;
}
baseDataValidator.reset().parameter("credits").value(this.credits).ignoreIfNull();
baseDataValidator.reset().parameter("debits").value(this.debits).ignoreIfNull();
// validation for credit array elements
if (this.credits != null) {
if (this.credits.length == 0) {
validateSingleDebitOrCredit(baseDataValidator, "credits", 0, new SingleDebitOrCreditEntryCommand(null, null, null, null));
} else {
int i = 0;
for (final SingleDebitOrCreditEntryCommand credit : this.credits) {
validateSingleDebitOrCredit(baseDataValidator, "credits", i, credit);
i++;
}
}
// validation for debit array elements
if (this.debits != null) {
if (this.debits.length == 0) {
validateSingleDebitOrCredit(baseDataValidator, "credits", 0, new SingleDebitOrCreditEntryCommand(null, null, null, null));
} else {
int i = 0;
for (final SingleDebitOrCreditEntryCommand debit : this.debits) {
validateSingleDebitOrCredit(baseDataValidator, "debits", i, debit);
i++;
}
}
}
} else {
baseDataValidator.reset().parameter("amount").value(this.amount).notNull().zeroOrPositiveAmount();
}
// validation for debit array elements
if (this.debits != null) {
if (this.debits.length == 0) {
validateSingleDebitOrCredit(baseDataValidator, "credits", 0, new SingleDebitOrCreditEntryCommand(null, null, null, null));
} else {
int i = 0;
for (final SingleDebitOrCreditEntryCommand debit : this.debits) {
validateSingleDebitOrCredit(baseDataValidator, "debits", i, debit);
i++;
}
}
}
baseDataValidator.reset().parameter("amount").value(this.amount).ignoreIfNull().zeroOrPositiveAmount();
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
@@ -134,8 +130,8 @@ public class JournalEntryCommand {
return this.referenceNumber;
}
public Long getAccountingRuleId() {
return this.accountingRuleId;
}
public Long getAccountingRuleId() {
return this.accountingRuleId;
}
}
@@ -16,7 +16,7 @@ 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, 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;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
@@ -25,6 +25,8 @@ public class JournalEntryInvalidException extends AbstractPlatformDomainRuleExce
return "Journal entry cannot be made prior to last account closing date for the branch";
} else if (name().toString().equalsIgnoreCase("NO_DEBITS_OR_CREDITS")) {
return "Journal Entry must have atleast one Debit and one Credit";
} else if (name().toString().equalsIgnoreCase("DEBIT_CREDIT_SUM_MISMATCH_WITH_AMOUNT")) {
return "Sum of All Debits OR Credits must equal the Amount for a Journal Entry";
} else if (name().toString().equalsIgnoreCase("DEBIT_CREDIT_SUM_MISMATCH")) {
return "Sum of All Debits must equal the sum of all Credits for a Journal Entry";
} else if (name().toString().equalsIgnoreCase("DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY")) {
@@ -6,6 +6,7 @@
package org.mifosplatform.accounting.journalentry.service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -15,9 +16,11 @@ import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.accounting.closure.domain.GLClosure;
import org.mifosplatform.accounting.closure.domain.GLClosureRepository;
import org.mifosplatform.accounting.glaccount.data.GLAccountDataForLookup;
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
import org.mifosplatform.accounting.glaccount.domain.GLAccountRepository;
import org.mifosplatform.accounting.glaccount.exception.GLAccountNotFoundException;
import org.mifosplatform.accounting.glaccount.service.GLAccountReadPlatformService;
import org.mifosplatform.accounting.journalentry.api.JournalEntryJsonInputParams;
import org.mifosplatform.accounting.journalentry.command.JournalEntryCommand;
import org.mifosplatform.accounting.journalentry.command.SingleDebitOrCreditEntryCommand;
@@ -61,6 +64,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
private final AccountingProcessorHelper helper;
private final JournalEntryCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final AccountingRuleRepository accountingRuleRepository;
private final GLAccountReadPlatformService glAccountReadPlatformService;
@Autowired
public JournalEntryWritePlatformServiceJpaRepositoryImpl(final GLClosureRepository glClosureRepository,
@@ -68,7 +72,8 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
final GLAccountRepository glAccountRepository, final JournalEntryCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final AccountingProcessorHelper accountingProcessorHelper, final AccountingRuleRepository accountingRuleRepository,
final AccountingProcessorForLoanFactory accountingProcessorForLoanFactory,
final AccountingProcessorForSavingsFactory accountingProcessorForSavingsFactory) {
final AccountingProcessorForSavingsFactory accountingProcessorForSavingsFactory,
final GLAccountReadPlatformService glAccountReadPlatformService) {
this.glClosureRepository = glClosureRepository;
this.officeRepository = officeRepository;
this.glJournalEntryRepository = glJournalEntryRepository;
@@ -78,6 +83,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
this.accountingProcessorForSavingsFactory = accountingProcessorForSavingsFactory;
this.helper = accountingProcessorHelper;
this.accountingRuleRepository = accountingRuleRepository;
this.glAccountReadPlatformService = glAccountReadPlatformService;
}
@Transactional
@@ -99,32 +105,65 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
/** Set a transaction Id and save these Journal entries **/
final Date transactionDate = command.DateValueOfParameterNamed(JournalEntryJsonInputParams.TRANSACTION_DATE.getValue());
final String transactionId = generateTransactionId();
final String referenceNumber = journalEntryCommand.getReferenceNumber();
final String referenceNumber = command.stringValueOfParameterNamed(JournalEntryJsonInputParams.REFERENCE_NUMBER.getValue());
final boolean manualEntry = true;
if (accountRuleId != null) {
final Long accountingRuleId = command.longValueOfParameterNamed(JournalEntryJsonInputParams.ACCOUNTING_RULE.getValue());
final BigDecimal amount = command.bigDecimalValueOfParameterNamed(JournalEntryJsonInputParams.AMOUNT.getValue());
final AccountingRule accountingRule = this.accountingRuleRepository.findOne(accountingRuleId);
if (accountingRule == null) { throw new AccountingRuleNotFoundException(accountingRuleId); }
final GLAccount creditAccountHead = accountingRule.getAccountToCredit();
validateGLAccountForTransaction(creditAccountHead);
final GLAccount debitAccountHead = accountingRule.getAccountToDebit();
validateGLAccountForTransaction(debitAccountHead);
String description = null;
if (StringUtils.isNotBlank(journalEntryCommand.getComments())) {
description = journalEntryCommand.getComments();
}
JournalEntry creditEntry = JournalEntry.createNew(office, creditAccountHead, transactionId, manualEntry, transactionDate,
JournalEntryType.CREDIT, amount, description, null, null, referenceNumber);
this.glJournalEntryRepository.saveAndFlush(creditEntry);
final AccountingRule accountingRule = this.accountingRuleRepository.findOne(accountRuleId);
if (accountingRule == null) { throw new AccountingRuleNotFoundException(accountRuleId); }
JournalEntry debitEntry = JournalEntry.createNew(office, debitAccountHead, transactionId, manualEntry, transactionDate,
JournalEntryType.DEBIT, amount, description, null, null, referenceNumber);
this.glJournalEntryRepository.saveAndFlush(debitEntry);
if (accountingRule.getAccountToCredit() == null) {
if (journalEntryCommand.getCredits() == null) { throw new RuntimeException(
"You have to pass atleast one value for credits"); }
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);
}
if (accountingRule.getAccountToDebit() == null) {
if (journalEntryCommand.getDebits() == null) { throw new RuntimeException(
"You have to pass atleast one parameter for debits"); }
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);
}
} else {
saveAllDebitOrCreditEntries(journalEntryCommand, office, transactionDate, journalEntryCommand.getDebits(), transactionId,
@@ -143,7 +182,76 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
}
}
private void validateGLAccountForTransaction(GLAccount creditOrDebitAccountHead) {
@SuppressWarnings("null")
private void checkDebitOrCreditAccountsAreValid(final AccountingRule accountingRule, final SingleDebitOrCreditEntryCommand[] credits,
final SingleDebitOrCreditEntryCommand[] debits) {
// Validate the debit and credit arrays are appropriate accounts
List<GLAccountDataForLookup> allowedCreditGLAccounts = new ArrayList<GLAccountDataForLookup>();
List<GLAccountDataForLookup> allowedDebitGLAccounts = new ArrayList<GLAccountDataForLookup>();
final SingleDebitOrCreditEntryCommand[] validCredits = new SingleDebitOrCreditEntryCommand[credits.length];
final SingleDebitOrCreditEntryCommand[] validDebits = new SingleDebitOrCreditEntryCommand[debits.length];
if (credits != null && credits.length > 0) {
allowedCreditGLAccounts = this.glAccountReadPlatformService.retrieveAccountsByTagId(accountingRule.getId(),
JournalEntryType.CREDIT.getValue());
for (final GLAccountDataForLookup accountDataForLookup : allowedCreditGLAccounts) {
for (int i = 0; i < credits.length; i++) {
final SingleDebitOrCreditEntryCommand credit = credits[i];
if (credit.getGlAccountId().equals(accountDataForLookup.getId())) {
validCredits[i] = credit;
}
}
}
if (credits.length != validCredits.length) { throw new RuntimeException("Invalid credits"); }
}
if (debits != null && debits.length > 0) {
allowedDebitGLAccounts = this.glAccountReadPlatformService.retrieveAccountsByTagId(accountingRule.getId(),
JournalEntryType.DEBIT.getValue());
for (final GLAccountDataForLookup accountDataForLookup : allowedDebitGLAccounts) {
for (int i = 0; i < debits.length; i++) {
final SingleDebitOrCreditEntryCommand debit = debits[i];
if (debit.getGlAccountId().equals(accountDataForLookup.getId())) {
validDebits[i] = debit;
}
}
}
if (debits.length != validDebits.length) { throw new RuntimeException("Invalid debits"); }
}
}
private void checkDebitAndCreditAmounts(final SingleDebitOrCreditEntryCommand[] credits, final SingleDebitOrCreditEntryCommand[] debits) {
// sum of all debits must be = sum of all credits
BigDecimal creditsSum = BigDecimal.ZERO;
BigDecimal debitsSum = BigDecimal.ZERO;
for (final SingleDebitOrCreditEntryCommand creditEntryCommand : credits) {
if (creditEntryCommand.getAmount() == null || creditEntryCommand.getGlAccountId() == null) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, null, null, null); }
creditsSum = creditsSum.add(creditEntryCommand.getAmount());
}
for (final SingleDebitOrCreditEntryCommand debitEntryCommand : debits) {
if (debitEntryCommand.getAmount() == null || debitEntryCommand.getGlAccountId() == null) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, null, null, null); }
debitsSum = debitsSum.add(debitEntryCommand.getAmount());
}
if (creditsSum.compareTo(debitsSum) != 0) { throw new JournalEntryInvalidException(
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
* disabled
@@ -199,7 +307,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
final boolean accrualBasedAccountingEnabled = (Boolean) accountingBridgeData.get("accrualBasedAccountingEnabled");
if (cashBasedAccountingEnabled || accrualBasedAccountingEnabled) {
final LoanDTO loanDTO = helper.populateLoanDtoFromMap(accountingBridgeData, cashBasedAccountingEnabled,
final LoanDTO loanDTO = this.helper.populateLoanDtoFromMap(accountingBridgeData, cashBasedAccountingEnabled,
accrualBasedAccountingEnabled);
final AccountingProcessorForLoan accountingProcessorForLoan = this.accountingProcessorForLoanFactory
.determineProcessor(loanDTO);
@@ -209,13 +317,13 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
@Transactional
@Override
public void createJournalEntriesForSavings(Map<String, Object> accountingBridgeData) {
public void createJournalEntriesForSavings(final Map<String, Object> accountingBridgeData) {
final boolean cashBasedAccountingEnabled = (Boolean) accountingBridgeData.get("cashBasedAccountingEnabled");
final boolean accrualBasedAccountingEnabled = (Boolean) accountingBridgeData.get("accrualBasedAccountingEnabled");
if (cashBasedAccountingEnabled || accrualBasedAccountingEnabled) {
final SavingsDTO savingsDTO = helper.populateSavingsDtoFromMap(accountingBridgeData, cashBasedAccountingEnabled,
final SavingsDTO savingsDTO = this.helper.populateSavingsDtoFromMap(accountingBridgeData, cashBasedAccountingEnabled,
accrualBasedAccountingEnabled);
final AccountingProcessorForSavings accountingProcessorForSavings = this.accountingProcessorForSavingsFactory
.determineProcessor(savingsDTO);
@@ -247,21 +355,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
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); }
// sum of all debits must be = sum of all credits
BigDecimal creditsSum = BigDecimal.ZERO;
BigDecimal debitsSum = BigDecimal.ZERO;
for (final SingleDebitOrCreditEntryCommand creditEntryCommand : credits) {
if (creditEntryCommand.getAmount() == null || creditEntryCommand.getGlAccountId() == null) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, null, null, null); }
creditsSum = creditsSum.add(creditEntryCommand.getAmount());
}
for (final SingleDebitOrCreditEntryCommand debitEntryCommand : debits) {
if (debitEntryCommand.getAmount() == null || debitEntryCommand.getGlAccountId() == null) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, null, null, null); }
debitsSum = debitsSum.add(debitEntryCommand.getAmount());
}
if (creditsSum.compareTo(debitsSum) != 0) { throw new JournalEntryInvalidException(
GL_JOURNAL_ENTRY_INVALID_REASON.DEBIT_CREDIT_SUM_MISMATCH, null, null, null); }
checkDebitAndCreditAmounts(credits, debits);
}
}
@@ -24,10 +24,10 @@ public class AccountingTagRule extends AbstractPersistable<Long> {
@ManyToOne
@JoinColumn(name = "tag_id", nullable = false)
private final CodeValue tagId;
private CodeValue tagId;
@Column(name = "acc_type_enum", nullable = false)
private final Integer accountType;
private Integer accountType;
public static AccountingTagRule create(final CodeValue tagId, final Integer accountType) {
return new AccountingTagRule(tagId, accountType);
@@ -42,4 +42,12 @@ public class AccountingTagRule extends AbstractPersistable<Long> {
this.accountingRule = accountingRule;
}
public AccountingTagRule() {
// TODO Auto-generated constructor stub
}
public Integer getAccountType() {
return this.accountType;
}
}
@@ -21,6 +21,7 @@ import org.mifosplatform.accounting.rule.domain.AccountingTagRule;
import org.mifosplatform.accounting.rule.exception.AccountingRuleDuplicateException;
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepository;
import org.mifosplatform.infrastructure.codes.exception.CodeValueNotFoundException;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -109,20 +110,22 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco
GLAccount creditAccount = null;
List<AccountingTagRule> accountingTagRules = new ArrayList<AccountingTagRule>();
if (accountToDebitId != null) {
if ((accountToDebitId != null && debitTags != null) || (accountToDebitId == null && debitTags == null)) {
// TODO- Throw Appropriate exception
throw new RuntimeException("Please Specify debitTags or accountToDebitId");
} else if (accountToDebitId != null) {
debitAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToDebitId);
} else if (debitTags != null) {
accountingTagRules = saveDebitOrCreditTags(debitTags, JournalEntryType.DEBIT, accountingTagRules);
} else {
throw new RuntimeException("Please Specify debitTags or accountToDebitId");
}
if (accountToCreditId != null) {
creditAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToCreditId);
} else if (debitTags != null) {
accountingTagRules = saveDebitOrCreditTags(creditTags, JournalEntryType.CREDIT, accountingTagRules);
} else {
if ((accountToCreditId != null && creditTags != null) || (accountToCreditId == null && creditTags == null)) {
// TODO- Throw Appropriate exception
throw new RuntimeException("Please Specify debitTags or accountToDebitId");
} else if (accountToCreditId != null) {
creditAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountToCreditId);
} else if (creditTags != null) {
accountingTagRules = saveDebitOrCreditTags(creditTags, JournalEntryType.CREDIT, accountingTagRules);
}
final AccountingRule accountingRule = AccountingRule.fromJson(office, debitAccount, creditAccount, command);
@@ -131,6 +134,8 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco
return accountingRule;
}
// TODO- This update mehtod should update based on new changes made for
// createAccountingRule.
@Transactional
@Override
public CommandProcessingResult updateAccountingRule(final Long accountingRuleId, final JsonCommand command) {
@@ -205,6 +210,7 @@ public class AccountingRuleWritePlatformServiceJpaRepositoryImpl implements Acco
for (final String creditOrDebitTag : creditOrDebitTagArray) {
final Long creditOrDebitTagIdLongValue = Long.valueOf(creditOrDebitTag);
final CodeValue creditOrDebitAccount = this.codeValueRepository.findOne(creditOrDebitTagIdLongValue);
if (creditOrDebitAccount == null) { throw new CodeValueNotFoundException(creditOrDebitTagIdLongValue); }
final AccountingTagRule accountingTagRule = AccountingTagRule.create(creditOrDebitAccount, transactionType.getValue());
accountingTagRules.add(accountingTagRule);
}