feat(Bank Transaction): auto-book included bank fees#346
feat(Bank Transaction): auto-book included bank fees#346barredterra wants to merge 23 commits intoversion-15-hotfixfrom
Conversation
Add bank fee account configuration and create fee Journal Entries on bank transaction submission so included fees are recognized immediately and reconciled correctly. Co-authored-by: Cursor <cursoragent@cursor.com>
Guard included-fee Journal Entry creation behind a Banking Settings flag so existing sites without bank fee account setup continue to work until the feature is explicitly enabled. Co-authored-by: Cursor <cursoragent@cursor.com>
Update the DocType JSON modified timestamp so the controller change is picked up reliably during model sync. Co-authored-by: Cursor <cursoragent@cursor.com>
…included-bank-fees
Reject withdrawal transactions where included fee exceeds withdrawal amount, while still allowing fee handling when deposit is not set. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as resolved.
This comment was marked as resolved.
…included-bank-fees
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Ensure a Bank Transaction can be submitted without a bank fee account when automatic bank fee journal entries are disabled, and assert that no linked fee Journal Entry is created.
Prevent automatic bank fee journal entries from being enabled until every company Bank Account has a bank fee account, and reject company bank accounts without one while the feature is enabled.
…concile the fee JE
Create fee Journal Entries for deposit Bank Transactions with included fees, but do not add them to payment entries because the fee is already deducted before the bank credits the deposit. Semantically, a row in Bank Transaction would say "this JE is allocatable against the bank amount later", which is exactly what we don’t want for a deposit fee. Add regression coverage for included-fee deposit and withdrawal flows.
Keep cheque_no-linked custom journal entries hidden from matching while excluding standard fee journal entries only for deposit transactions. This lets unreconciled withdrawal fee journal entries be offered again.
This comment was marked as resolved.
This comment was marked as resolved.
Recompute `allocated_amount` and `unallocated_amount` from `payment_entries` after appending the fee journal entry, so prior allocations are not lost. Add a regression test covering fee entry creation when an allocation already exists.
This comment was marked as resolved.
This comment was marked as resolved.
Since we no longer create fee JEs for deposits, there's nothing to exclude from matching. The test was validating behavior that no longer exists.
This test now creates its own GL account (_Test Bank Fee Reco GL) instead of reusing self.gl_account, avoiding the "account already used by another bank account" error.
| def get_deposit_included_fee(bt: "CustomBankTransaction") -> float: | ||
| """Return the included fee amount when deposit-side fee handling is enabled. | ||
|
|
||
| Deposit-side fees are only settled during reconciliation when the global | ||
| feature flag is enabled and the bank account provides a fee account. | ||
| Returns 0.0 when the legacy pre-feature behavior should be preserved. | ||
| """ | ||
| if not (flt(bt.deposit) > 0 and flt(bt.included_fee) > 0): | ||
| return 0.0 | ||
|
|
||
| if not flt( | ||
| frappe.db.get_single_value("Banking Settings", "enable_automatic_journal_entries_for_bank_fees") | ||
| ): | ||
| return 0.0 | ||
|
|
There was a problem hiding this comment.
Fee double-booked on sequential partial reconciliation
get_deposit_included_fee always returns the full bt.included_fee regardless of how many times the deposit has already been partially reconciled. If a user reconciles a deposit of 75 with included_fee=5 against two invoices in separate steps, the fee account is debited twice (2×5=10 instead of 5), and the BT can never be fully reconciled because 5 remains permanently unallocated.
Concretely: step 1 creates JE Dr Bank 45 / Dr Fee 5 / Cr SI1 50, allocating 45 against the BT (unallocated→30). Step 2 again sees included_fee=5, creates JE Dr Bank 25 / Dr Fee 5 / Cr SI2 30, allocating 25 (unallocated→5). The BT remains 5 short and the fee expense is overstated by 5.
A guard is needed before returning included_fee to check whether a fee JE was already booked for this BT — for example by checking whether a JE already exists where is_system_generated=1 and JEA.reference_name = bt.name AND has a bank_fee_account row, or alternatively by only returning the fee when bt.unallocated_amount == bt.deposit (i.e., the first reconciliation step).
Summary
Auto-book included bank fees on Bank Transaction submit (withdrawals) and at reconciliation time (deposits).
Withdrawals: On submit, a Journal Entry is created (
Dr Bank Fees / Cr Bank) and allocated against the Bank Transaction, partially reconciling the fee portion.Deposits: Fee booking is deferred to reconciliation, where the correct counter-account (e.g. receivable) is known. The reconciliation tool matches deposits using
deposit + included_feeas the target amount, so the right vouchers are found. At reconciliation:Dr Bank, Dr Bank Fees / Cr Receivable)Configuration
Bank Fee Accountfield on Bank Account (Link to Expense account, same currency)Enable Automatic Journal Entries for Bank Feescheckbox in Banking SettingsDepends on
unallocated_amountfordeposit=0 + included_feetransactions)Test plan