fix(accounting,branchday): 3-stage FD interest posting in scheduler, fix branch day close business date validation
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Canceled after 0s
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Canceled after 0s
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Canceled after 0s
Fineract Documentation build / build (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Canceled after 0s
Fineract Liquibase Only mode - PostgreSQL / test (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Canceled after 0s
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Canceled after 0s
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Canceled after 0s
Fineract Documentation build / build (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Canceled after 0s
Fineract Liquibase Only mode - PostgreSQL / test (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Canceled after 0s
This commit is contained in:
+19
@@ -58,6 +58,9 @@ public class DepositProductData {
|
||||
|
||||
// accounting
|
||||
protected final EnumOptionData accountingRule;
|
||||
|
||||
private List<Map<String, Object>> otherGlMappings;
|
||||
private Map<String, List<Map<String, Object>>> otherGlMappingsMap;
|
||||
protected final Map<String, Object> accountingMappings;
|
||||
protected final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings;
|
||||
protected final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings;
|
||||
@@ -453,4 +456,20 @@ public class DepositProductData {
|
||||
public EnumOptionData getInterestCompoundingPeriodType() {
|
||||
return interestCompoundingPeriodType;
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getOtherGlMappings() {
|
||||
return this.otherGlMappings;
|
||||
}
|
||||
|
||||
public void setOtherGlMappings(List<Map<String, Object>> otherGlMappings) {
|
||||
this.otherGlMappings = otherGlMappings;
|
||||
}
|
||||
|
||||
public Map<String, List<Map<String, Object>>> getOtherGlMappingsMap() {
|
||||
return this.otherGlMappingsMap;
|
||||
}
|
||||
|
||||
public void setOtherGlMappingsMap(Map<String, List<Map<String, Object>>> otherGlMappingsMap) {
|
||||
this.otherGlMappingsMap = otherGlMappingsMap;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -244,7 +244,7 @@ public final class FixedDepositProductData extends DepositProductData {
|
||||
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
|
||||
final Collection<TaxGroupData> taxGroupOptions = null;
|
||||
|
||||
return new FixedDepositProductData(depositProductData.id, depositProductData.name, depositProductData.shortName,
|
||||
final FixedDepositProductData result = new FixedDepositProductData(depositProductData.id, depositProductData.name, depositProductData.shortName,
|
||||
depositProductData.description, depositProductData.currency, depositProductData.nominalAnnualInterestRate,
|
||||
depositProductData.interestCompoundingPeriodType, depositProductData.interestPostingPeriodType,
|
||||
depositProductData.interestCalculationType, depositProductData.interestCalculationDaysInYearType,
|
||||
@@ -258,6 +258,9 @@ public final class FixedDepositProductData extends DepositProductData {
|
||||
minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm,
|
||||
inMultiplesOfDepositTermType, minDepositAmount, depositAmount, maxDepositAmount, periodFrequencyTypeOptions,
|
||||
depositProductData.withHoldTax, depositProductData.taxGroup, taxGroupOptions);
|
||||
result.setOtherGlMappings(depositProductData.getOtherGlMappings());
|
||||
result.setOtherGlMappingsMap(depositProductData.getOtherGlMappingsMap());
|
||||
return result;
|
||||
}
|
||||
|
||||
public static FixedDepositProductData lookup(final Long id, final String name) {
|
||||
@@ -609,6 +612,8 @@ public final class FixedDepositProductData extends DepositProductData {
|
||||
this.balanceFrequency = src.balanceFrequency;
|
||||
this.withdrawalFeeForTransfers = src.withdrawalFeeForTransfers;
|
||||
this.renewalGracePeriodDays = src.renewalGracePeriodDays;
|
||||
this.setOtherGlMappings(src.getOtherGlMappings());
|
||||
this.setOtherGlMappingsMap(src.getOtherGlMappingsMap());
|
||||
}
|
||||
|
||||
private Boolean withdrawalFeeForTransfers;
|
||||
|
||||
+9
@@ -52,6 +52,7 @@ import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPe
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minBalanceForInterestCalculationParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nameParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.otherGlMappingsParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.shortNameParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.taxGroupIdParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName;
|
||||
@@ -247,6 +248,10 @@ public class DepositProductAssembler {
|
||||
fixedDepositProduct.setWithdrawalFeeApplicableForTransfer(command.booleanPrimitiveValueOfParameterNamed("withdrawalFeeForTransfers"));
|
||||
}
|
||||
|
||||
if (command.hasParameter(otherGlMappingsParamName)) {
|
||||
fixedDepositProduct.setOtherGlMappings(command.jsonFragment(otherGlMappingsParamName));
|
||||
}
|
||||
|
||||
fixedDepositProduct.validateDomainRules();
|
||||
|
||||
return fixedDepositProduct;
|
||||
@@ -402,6 +407,10 @@ public class DepositProductAssembler {
|
||||
recurringDepositProduct.setWithdrawalFeeApplicableForTransfer(command.booleanPrimitiveValueOfParameterNamed("withdrawalFeeForTransfers"));
|
||||
}
|
||||
|
||||
if (command.hasParameter(otherGlMappingsParamName)) {
|
||||
recurringDepositProduct.setOtherGlMappings(command.jsonFragment(otherGlMappingsParamName));
|
||||
}
|
||||
|
||||
recurringDepositProduct.validateDomainRules();
|
||||
|
||||
return recurringDepositProduct;
|
||||
|
||||
+4
@@ -1123,6 +1123,10 @@ public class SavingsProduct extends AbstractPersistableCustom<Long> {
|
||||
return this.otherGlMappings;
|
||||
}
|
||||
|
||||
public void setOtherGlMappings(final String otherGlMappings) {
|
||||
this.otherGlMappings = otherGlMappings;
|
||||
}
|
||||
|
||||
// Enhanced Savings Product Getters and Setters
|
||||
public String getAccountType() {
|
||||
return accountType;
|
||||
|
||||
+137
-19
@@ -30,6 +30,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
@@ -96,6 +97,63 @@ public class SavingsSchedularInterestPoster {
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<String, Long> namedGlAccountCache = new HashMap<>();
|
||||
|
||||
private Long findNamedGlAccount(final Long savingsProductId, final String... accountNames) {
|
||||
if (savingsProductId == null || accountNames == null || accountNames.length == 0) {
|
||||
return null;
|
||||
}
|
||||
for (final String accountName : accountNames) {
|
||||
if (accountName == null) {
|
||||
continue;
|
||||
}
|
||||
final String cacheKey = savingsProductId + ":" + accountName.trim().toLowerCase();
|
||||
if (this.namedGlAccountCache.containsKey(cacheKey)) {
|
||||
final Long cached = this.namedGlAccountCache.get(cacheKey);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
final List<Long> found = this.jdbcTemplate.queryForList("""
|
||||
SELECT gl.id
|
||||
FROM (SELECT other_gl_mappings::jsonb AS doc
|
||||
FROM m_savings_product
|
||||
WHERE id = ?
|
||||
AND other_gl_mappings IS NOT NULL
|
||||
AND other_gl_mappings <> ''
|
||||
AND other_gl_mappings LIKE '{%') sp
|
||||
CROSS JOIN LATERAL jsonb_array_elements(
|
||||
COALESCE(sp.doc -> 'assets', '[]'::jsonb)
|
||||
|| COALESCE(sp.doc -> 'liabilities', '[]'::jsonb)
|
||||
|| COALESCE(sp.doc -> 'expenses', '[]'::jsonb)
|
||||
|| COALESCE(sp.doc -> 'income', '[]'::jsonb)
|
||||
) AS m(entry)
|
||||
JOIN acc_gl_account gl ON gl.gl_code = m.entry ->> 'glCode'
|
||||
WHERE lower(trim(m.entry ->> 'accountName')) = lower(trim(?))
|
||||
LIMIT 1
|
||||
""", Long.class, savingsProductId, accountName);
|
||||
if (!found.isEmpty()) {
|
||||
this.namedGlAccountCache.put(cacheKey, found.get(0));
|
||||
return found.get(0);
|
||||
} else {
|
||||
this.namedGlAccountCache.put(cacheKey, null);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addJournalEntryLeg(final List<Object[]> params, final Long accountId, final Long officeId,
|
||||
final String currencyCode, final String transactionId, final Long savingsTransactionId,
|
||||
final LocalDate transactionDate, final JournalEntryType entryType, final BigDecimal amount,
|
||||
final Long savingsAccountId, final OffsetDateTime auditDatetime, final Long userId,
|
||||
final LocalDate businessDate) {
|
||||
params.add(new Object[] { accountId, officeId, null, currencyCode, transactionId,
|
||||
savingsTransactionId, null, false, null, false, transactionDate, entryType.getValue().longValue(),
|
||||
amount, null, entryType.getValue().longValue(), savingsAccountId, auditDatetime, auditDatetime, false,
|
||||
BigDecimal.ZERO, BigDecimal.ZERO, null, transactionDate, null, userId, userId, businessDate });
|
||||
}
|
||||
|
||||
private void batchUpdateJournalEntries(final List<SavingsAccountData> savingsAccountDataList,
|
||||
final HashMap<String, SavingsAccountTransactionData> savingsAccountTransactionDataHashMap)
|
||||
throws DataAccessException, NullPointerException {
|
||||
@@ -114,26 +172,86 @@ public class SavingsSchedularInterestPoster {
|
||||
savingsAccountTransactionData.setId(dataFromFetch.getId());
|
||||
if (savingsAccountData.getGlAccountIdForSavingsControl() != 0
|
||||
&& savingsAccountData.getGlAccountIdForInterestOnSavings() != 0) {
|
||||
OffsetDateTime auditDatetime = DateUtils.getAuditOffsetDateTime();
|
||||
paramsForGLInsertion.add(
|
||||
new Object[] { savingsAccountTransactionData.getAccountCredit(), savingsAccountData.getOfficeId(), null,
|
||||
currencyCode, SAVINGS_TRANSACTION_IDENTIFIER + savingsAccountTransactionData.getId().toString(),
|
||||
savingsAccountTransactionData.getId(), null, false, null, false,
|
||||
savingsAccountTransactionData.getTransactionDate(), JournalEntryType.CREDIT.getValue().longValue(),
|
||||
savingsAccountTransactionData.getAmount(), null, JournalEntryType.CREDIT.getValue().longValue(),
|
||||
savingsAccountData.getId(), auditDatetime, auditDatetime, false, BigDecimal.ZERO, BigDecimal.ZERO,
|
||||
null, savingsAccountTransactionData.getTransactionDate(), null, userId, userId,
|
||||
DateUtils.getBusinessLocalDate() });
|
||||
final OffsetDateTime auditDatetime = DateUtils.getAuditOffsetDateTime();
|
||||
final LocalDate businessDate = DateUtils.getBusinessLocalDate();
|
||||
final String txnIdentifier = SAVINGS_TRANSACTION_IDENTIFIER + savingsAccountTransactionData.getId().toString();
|
||||
final Long savingsTxnId = savingsAccountTransactionData.getId();
|
||||
final LocalDate txnDate = savingsAccountTransactionData.getTransactionDate();
|
||||
final BigDecimal amount = savingsAccountTransactionData.getAmount();
|
||||
final Long savingsAccountId = savingsAccountData.getId();
|
||||
final Long officeId = savingsAccountData.getOfficeId();
|
||||
|
||||
paramsForGLInsertion
|
||||
.add(new Object[] { savingsAccountTransactionData.getAccountDebit(), savingsAccountData.getOfficeId(), null,
|
||||
currencyCode, SAVINGS_TRANSACTION_IDENTIFIER + savingsAccountTransactionData.getId().toString(),
|
||||
savingsAccountTransactionData.getId(), null, false, null, false,
|
||||
savingsAccountTransactionData.getTransactionDate(), JournalEntryType.DEBIT.getValue().longValue(),
|
||||
savingsAccountTransactionData.getAmount(), null, JournalEntryType.DEBIT.getValue().longValue(),
|
||||
savingsAccountData.getId(), auditDatetime, auditDatetime, false, BigDecimal.ZERO, BigDecimal.ZERO,
|
||||
null, savingsAccountTransactionData.getTransactionDate(), null, userId, userId,
|
||||
DateUtils.getBusinessLocalDate() });
|
||||
if (Boolean.TRUE.equals(isOverdraft)) {
|
||||
addJournalEntryLeg(paramsForGLInsertion, savingsAccountTransactionData.getAccountCredit(), officeId,
|
||||
currencyCode, txnIdentifier, savingsTxnId, txnDate, JournalEntryType.CREDIT, amount,
|
||||
savingsAccountId, auditDatetime, userId, businessDate);
|
||||
addJournalEntryLeg(paramsForGLInsertion, savingsAccountTransactionData.getAccountDebit(), officeId,
|
||||
currencyCode, txnIdentifier, savingsTxnId, txnDate, JournalEntryType.DEBIT, amount,
|
||||
savingsAccountId, auditDatetime, userId, businessDate);
|
||||
} else {
|
||||
final Long expenseAccountId = savingsAccountData.getGlAccountIdForInterestOnSavings();
|
||||
final Long controlAccountId = savingsAccountData.getGlAccountIdForSavingsControl();
|
||||
Long payableAccountId = savingsAccountData.getGlAccountIdForInterestPayable();
|
||||
final Long productId = savingsAccountData.getSavingsProductId() != null
|
||||
? savingsAccountData.getSavingsProductId()
|
||||
: savingsAccountData.getProductId();
|
||||
|
||||
if (payableAccountId == null || payableAccountId == 0) {
|
||||
payableAccountId = findNamedGlAccount(productId,
|
||||
"Fixed Deposit Interest Payable", "Savings Interest Payable", "Recurring Deposit Interest Payable",
|
||||
"Interest Payable", "Interest Payable Account");
|
||||
}
|
||||
|
||||
final Long paidAccountId = findNamedGlAccount(productId,
|
||||
"Fixed Deposit Interest Paid", "Savings Interest Paid", "Recurring Deposit Interest Paid",
|
||||
"Interest Paid", "Interest Paid Account");
|
||||
|
||||
final boolean hasPayable = payableAccountId != null && payableAccountId != 0 && !payableAccountId.equals(controlAccountId);
|
||||
final boolean hasPaid = paidAccountId != null && paidAccountId != 0 && !paidAccountId.equals(payableAccountId);
|
||||
|
||||
log.info("SavingsSchedularInterestPoster: accountId={}, productId={}, expense={}, payable={}, paid={}, control={}, amount={}",
|
||||
savingsAccountId, productId, expenseAccountId, payableAccountId, paidAccountId, controlAccountId, amount);
|
||||
|
||||
if (hasPayable && hasPaid) {
|
||||
// Stage 1: Dr Interest Expense / Cr Interest Payable
|
||||
addJournalEntryLeg(paramsForGLInsertion, expenseAccountId, officeId, currencyCode, txnIdentifier,
|
||||
savingsTxnId, txnDate, JournalEntryType.DEBIT, amount, savingsAccountId, auditDatetime, userId, businessDate);
|
||||
addJournalEntryLeg(paramsForGLInsertion, payableAccountId, officeId, currencyCode, txnIdentifier,
|
||||
savingsTxnId, txnDate, JournalEntryType.CREDIT, amount, savingsAccountId, auditDatetime, userId, businessDate);
|
||||
|
||||
// Stage 2: Dr Interest Payable / Cr Interest Paid
|
||||
addJournalEntryLeg(paramsForGLInsertion, payableAccountId, officeId, currencyCode, txnIdentifier,
|
||||
savingsTxnId, txnDate, JournalEntryType.DEBIT, amount, savingsAccountId, auditDatetime, userId, businessDate);
|
||||
addJournalEntryLeg(paramsForGLInsertion, paidAccountId, officeId, currencyCode, txnIdentifier,
|
||||
savingsTxnId, txnDate, JournalEntryType.CREDIT, amount, savingsAccountId, auditDatetime, userId, businessDate);
|
||||
|
||||
// Stage 3: Dr Interest Paid / Cr Savings Control
|
||||
addJournalEntryLeg(paramsForGLInsertion, paidAccountId, officeId, currencyCode, txnIdentifier,
|
||||
savingsTxnId, txnDate, JournalEntryType.DEBIT, amount, savingsAccountId, auditDatetime, userId, businessDate);
|
||||
addJournalEntryLeg(paramsForGLInsertion, controlAccountId, officeId, currencyCode, txnIdentifier,
|
||||
savingsTxnId, txnDate, JournalEntryType.CREDIT, amount, savingsAccountId, auditDatetime, userId, businessDate);
|
||||
} else if (hasPayable) {
|
||||
// Stage 1: Dr Interest Expense / Cr Interest Payable
|
||||
addJournalEntryLeg(paramsForGLInsertion, expenseAccountId, officeId, currencyCode, txnIdentifier,
|
||||
savingsTxnId, txnDate, JournalEntryType.DEBIT, amount, savingsAccountId, auditDatetime, userId, businessDate);
|
||||
addJournalEntryLeg(paramsForGLInsertion, payableAccountId, officeId, currencyCode, txnIdentifier,
|
||||
savingsTxnId, txnDate, JournalEntryType.CREDIT, amount, savingsAccountId, auditDatetime, userId, businessDate);
|
||||
|
||||
// Stage 2: Dr Interest Payable / Cr Savings Control
|
||||
addJournalEntryLeg(paramsForGLInsertion, payableAccountId, officeId, currencyCode, txnIdentifier,
|
||||
savingsTxnId, txnDate, JournalEntryType.DEBIT, amount, savingsAccountId, auditDatetime, userId, businessDate);
|
||||
addJournalEntryLeg(paramsForGLInsertion, controlAccountId, officeId, currencyCode, txnIdentifier,
|
||||
savingsTxnId, txnDate, JournalEntryType.CREDIT, amount, savingsAccountId, auditDatetime, userId, businessDate);
|
||||
} else {
|
||||
// Standard 2-leg entry: Dr Interest Expense / Cr Savings Control
|
||||
addJournalEntryLeg(paramsForGLInsertion, savingsAccountTransactionData.getAccountCredit(), officeId,
|
||||
currencyCode, txnIdentifier, savingsTxnId, txnDate, JournalEntryType.CREDIT, amount,
|
||||
savingsAccountId, auditDatetime, userId, businessDate);
|
||||
addJournalEntryLeg(paramsForGLInsertion, savingsAccountTransactionData.getAccountDebit(), officeId,
|
||||
currencyCode, txnIdentifier, savingsTxnId, txnDate, JournalEntryType.DEBIT, amount,
|
||||
savingsAccountId, auditDatetime, userId, businessDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user