Add Predefined Journal Entries with optional tag fields
This commit is contained in:
+15
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+3
@@ -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);
|
||||
}
|
||||
+23
-1
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+35
-39
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -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")) {
|
||||
|
||||
+129
-35
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-2
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
-8
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user