feat: fix standing instructions GL accounting for current account transfers
- AccountTransfersWritePlatformServiceImpl:
* Direct GL posting for current↔savings/current transfers:
DR debit-side account GL (with correct account entity_id)
CR credit-side account GL (with correct account entity_id)
* Prefix current account txn_id with CA (not C) so
JournalEntryReadPlatformServiceImpl joins m_current_account
and shows correct current account number on GL entries
* Suppress redundant savings deposit/withdrawal GL entries
(skipAccountingPostings=true) when current account handles
the full double-entry directly
* Separate performCurrentWithdrawalForLoan for Current→Loan
transfers (loan domain service handles the other GL leg)
* Reuse existing AccountTransferDetails for SI recurring runs
so transactions appear in list-account-transactions history
- SavingsAccountDomainService / SavingsAccountDomainServiceJpa:
* New handleDeposit overload with skipAccountingPostings flag
* handleWithdrawal respects SavingsTransactionBooleanValues
.isSkipAccountingPostings() to suppress redundant GL entries
- SavingsTransactionBooleanValues:
* Added skipAccountingPostings field + overloaded constructor
- AccountingProcessorHelper:
* New createDirectTransferJournalEntriesForSavings() method
creates DR and CR entries with separate productId/entityId
so each GL line shows the correct account number
- JournalEntryReadPlatformServiceImpl:
* Join both m_savings_account and m_current_account always
* COALESCE(ca.account_no, sa.account_no) to resolve correct
account number regardless of transaction_id prefix
- ExecuteStandingInstructionsTasklet:
* Load existing AccountTransferDetails via repository so
subsequent SI runs link to the same transfer detail record
- ExecuteStandingInstructionsConfig / AccountConfiguration:
* Wire AccountTransferDetailRepository and
AccountingProcessorHelper into the relevant beans
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
2251fd2259
commit
7d4f409202
+70
-59
@@ -1,59 +1,70 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings;
|
||||
|
||||
public class SavingsTransactionBooleanValues {
|
||||
|
||||
private final boolean isAccountTransfer;
|
||||
private final boolean isRegularTransaction;
|
||||
private final boolean isApplyWithdrawFee;
|
||||
private final boolean isInterestTransfer;
|
||||
private final boolean isExceptionForBalanceCheck;
|
||||
|
||||
public SavingsTransactionBooleanValues(final boolean isAccountTransfer, final boolean isRegularTransaction,
|
||||
final boolean isApplyWithdrawFee, final boolean isInterestTransfer, final boolean isExceptionForBalanceCheck) {
|
||||
|
||||
this.isAccountTransfer = isAccountTransfer;
|
||||
this.isRegularTransaction = isRegularTransaction;
|
||||
this.isApplyWithdrawFee = isApplyWithdrawFee;
|
||||
this.isInterestTransfer = isInterestTransfer;
|
||||
this.isExceptionForBalanceCheck = isExceptionForBalanceCheck;
|
||||
}
|
||||
|
||||
public boolean isAccountTransfer() {
|
||||
return this.isAccountTransfer;
|
||||
}
|
||||
|
||||
public boolean isRegularTransaction() {
|
||||
return this.isRegularTransaction;
|
||||
}
|
||||
|
||||
public boolean isApplyWithdrawFee() {
|
||||
return this.isApplyWithdrawFee;
|
||||
}
|
||||
|
||||
public boolean isInterestTransfer() {
|
||||
return this.isInterestTransfer;
|
||||
}
|
||||
|
||||
public boolean isExceptionForBalanceCheck() {
|
||||
return this.isExceptionForBalanceCheck;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings;
|
||||
|
||||
public class SavingsTransactionBooleanValues {
|
||||
|
||||
private final boolean isAccountTransfer;
|
||||
private final boolean isRegularTransaction;
|
||||
private final boolean isApplyWithdrawFee;
|
||||
private final boolean isInterestTransfer;
|
||||
private final boolean isExceptionForBalanceCheck;
|
||||
private final boolean skipAccountingPostings;
|
||||
|
||||
public SavingsTransactionBooleanValues(final boolean isAccountTransfer, final boolean isRegularTransaction,
|
||||
final boolean isApplyWithdrawFee, final boolean isInterestTransfer, final boolean isExceptionForBalanceCheck) {
|
||||
this(isAccountTransfer, isRegularTransaction, isApplyWithdrawFee, isInterestTransfer, isExceptionForBalanceCheck, false);
|
||||
}
|
||||
|
||||
public SavingsTransactionBooleanValues(final boolean isAccountTransfer, final boolean isRegularTransaction,
|
||||
final boolean isApplyWithdrawFee, final boolean isInterestTransfer, final boolean isExceptionForBalanceCheck,
|
||||
final boolean skipAccountingPostings) {
|
||||
this.isAccountTransfer = isAccountTransfer;
|
||||
this.isRegularTransaction = isRegularTransaction;
|
||||
this.isApplyWithdrawFee = isApplyWithdrawFee;
|
||||
this.isInterestTransfer = isInterestTransfer;
|
||||
this.isExceptionForBalanceCheck = isExceptionForBalanceCheck;
|
||||
this.skipAccountingPostings = skipAccountingPostings;
|
||||
}
|
||||
|
||||
public boolean isAccountTransfer() {
|
||||
return this.isAccountTransfer;
|
||||
}
|
||||
|
||||
public boolean isRegularTransaction() {
|
||||
return this.isRegularTransaction;
|
||||
}
|
||||
|
||||
public boolean isApplyWithdrawFee() {
|
||||
return this.isApplyWithdrawFee;
|
||||
}
|
||||
|
||||
public boolean isInterestTransfer() {
|
||||
return this.isInterestTransfer;
|
||||
}
|
||||
|
||||
public boolean isExceptionForBalanceCheck() {
|
||||
return this.isExceptionForBalanceCheck;
|
||||
}
|
||||
|
||||
public boolean isSkipAccountingPostings() {
|
||||
return this.skipAccountingPostings;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+55
-51
@@ -1,51 +1,55 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.apache.fineract.portfolio.savings.SavingsTransactionBooleanValues;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
|
||||
|
||||
public interface SavingsAccountDomainService {
|
||||
|
||||
SavingsAccountTransaction handleWithdrawal(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, SavingsTransactionBooleanValues transactionBooleanValues,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
SavingsAccountTransaction handleDeposit(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean isAccountTransfer, boolean isRegularTransaction,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
void postJournalEntries(SavingsAccount savingsAccount, Set<Long> existingTransactionIds, Set<Long> existingReversedTransactionIds,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
SavingsAccountTransaction handleDividendPayout(SavingsAccount account, LocalDate transactionDate, BigDecimal transactionAmount,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
SavingsAccountTransaction handleReversal(SavingsAccount account, List<SavingsAccountTransaction> savingsAccountTransactions,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
SavingsAccountTransaction handleHold(SavingsAccount account, BigDecimal amount, LocalDate transactionDate, Boolean lienAllowed);
|
||||
}
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.apache.fineract.portfolio.savings.SavingsTransactionBooleanValues;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
|
||||
|
||||
public interface SavingsAccountDomainService {
|
||||
|
||||
SavingsAccountTransaction handleWithdrawal(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, SavingsTransactionBooleanValues transactionBooleanValues,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
SavingsAccountTransaction handleDeposit(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean isAccountTransfer, boolean isRegularTransaction,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
SavingsAccountTransaction handleDeposit(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean isAccountTransfer, boolean isRegularTransaction,
|
||||
boolean backdatedTxnsAllowedTill, boolean skipAccountingPostings);
|
||||
|
||||
void postJournalEntries(SavingsAccount savingsAccount, Set<Long> existingTransactionIds, Set<Long> existingReversedTransactionIds,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
SavingsAccountTransaction handleDividendPayout(SavingsAccount account, LocalDate transactionDate, BigDecimal transactionAmount,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
SavingsAccountTransaction handleReversal(SavingsAccount account, List<SavingsAccountTransaction> savingsAccountTransactions,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
SavingsAccountTransaction handleHold(SavingsAccount account, BigDecimal amount, LocalDate transactionDate, Boolean lienAllowed);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user