diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java index 93f8d9e80..f3e13716e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java @@ -687,6 +687,16 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa } private void validateBusinessRulesForJournalEntries(final JournalEntryCommand command) { + validateBusinessRulesForJournalEntries(command, true); + } + + /** + * @param requireBalanced + * false for opening balances: every leg is posted against the contra account, so the books always + * balance, and the submitted legs legitimately differ by the locked (denomination-managed) cash + * account's opening balance that is already posted and can never be part of this request. + */ + private void validateBusinessRulesForJournalEntries(final JournalEntryCommand command, final boolean requireBalanced) { // check if date of Journal entry is valid final LocalDate transactionDate = command.getTransactionDate(); // shouldn't be in the future @@ -706,6 +716,26 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa final SingleDebitOrCreditEntryCommand[] credits = command.getCredits(); final SingleDebitOrCreditEntryCommand[] debits = command.getDebits(); + if (!requireBalanced) { + final List entries = new ArrayList<>(); + if (credits != null) { + entries.addAll(Arrays.asList(credits)); + } + if (debits != null) { + entries.addAll(Arrays.asList(debits)); + } + if (entries.isEmpty()) { + throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.NO_DEBITS_OR_CREDITS, null, null, null); + } + for (final SingleDebitOrCreditEntryCommand entry : entries) { + if (entry.getAmount() == null || entry.getGlAccountId() == null) { + throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, null, null, + null); + } + } + return; + } + // atleast one debit or credit must be present if (credits == null || credits.length == 0 || debits == null || debits.length == 0) { throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.NO_DEBITS_OR_CREDITS, null, null, null); @@ -783,7 +813,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa final Office office = this.officeRepositoryWrapper.findOneWithNotFoundDetection(officeId); final String currencyCode = command.stringValueOfParameterNamed(JournalEntryJsonInputParams.CURRENCY_CODE.getValue()); - validateBusinessRulesForJournalEntries(journalEntryCommand); + validateBusinessRulesForJournalEntries(journalEntryCommand, false); validateNoDenominationManagedCashAccounts(journalEntryCommand); /**