Enhanced bank reconciliation tool for ERPNext with support for bulk operations, unpaid invoice matching, and extensible filtering.
- Enhanced Bank Reconciliation Interface: Improved UX over standard ERPNext bank reconciliation
- Unpaid Invoice Matching: Automatically match bank transactions against unpaid Sales and Purchase Invoices
- Invoice Returns Support: Handle both regular invoices and returns (credit notes/debit notes) with proper sign handling
- Bulk Reconciliation: Process hundreds of invoices in a single operation with configurable sync/async execution
- Real-time Progress Tracking: Live progress updates with animated progress bar during bulk operations
- Custom Filtering: Extensible filter system via hooks (e.g., Customer Group filtering)
- Date-based Filtering: Filter matching invoices by posting date or reference date ranges
- Extended Bank Transaction: Custom fields and enhanced validation for bank transactions
When reconciling multiple unpaid invoices against a bank transaction:
Configurable Execution Modes (via Advance Bank Reconciliation Settings):
-
Background Mode (default): Processes reconciliation asynchronously for large datasets
- Shows real-time progress dialog with percentage completion
- Sends desktop notifications on completion
- Prevents browser freezing with 100s of invoices
- Automatic batching (100 invoices per batch)
-
Synchronous Mode: Immediate execution for small datasets
- Instant completion with success alert
- No progress dialog needed
- Faster for small reconciliations
Key Features:
- ✅ Atomic operations with automatic rollback on errors
- ✅ Duplicate invoice detection and prevention
- ✅ Pre-validation of amounts vs outstanding balances (configurable)
- ✅ Comprehensive error logging and recovery
- ✅ WebSocket-based progress updates
- ✅ Background job monitoring with unique job IDs
- ✅ Concurrent reconciliation prevention via locking
Full support for matching returns/credit notes:
Sales Invoices:
- Positive outstanding → Match with deposit transactions (customer payments)
- Negative outstanding (returns) → Match with withdrawal transactions (customer refunds)
Purchase Invoices:
- Positive outstanding → Match with withdrawal transactions (supplier payments)
- Negative outstanding (returns) → Match with deposit transactions (supplier refunds)
Features:
- Absolute value matching for exact amount comparisons
- Proper payment type determination (Receive vs Pay)
- Accurate payment entry creation with correct signs
Add custom filters via hooks without modifying core code:
# In your custom app's hooks.py
bank_rec_additional_filters = [
{
"dt": "Customer", # Source doctype
"fieldname": "customer_group",
"fieldtype": "Link",
"label": "Customer Group",
"options": "Customer Group"
},
{
"dt": "Customer",
"fieldname": "territory",
"fieldtype": "Link",
"label": "Territory",
"options": "Territory"
}
]The system automatically:
- Fetches related data from the specified doctype
- Applies filters to matching queries
- Updates UI with new filter fields
# Get the app
bench get-app https://github.com/one-highflyer/advanced_bank_reconciliation
# Install on site
bench --site your-site install-app advanced_bank_reconciliation
# Migrate
bench --site your-site migrate
# Build assets
bench build --app advanced_bank_reconciliation
# Restart
bench restart
# Start background worker (required for async bulk reconciliation)
bench worker --queue longNavigate to Advance Bank Reconciliation Settings to configure:
-
Validate selection against unallocated amount (default: unchecked)
- When enabled: Validates that selected invoice amounts match the bank transaction's unallocated amount exactly
- When disabled: Allows flexible selection (useful for partial reconciliations or complex scenarios)
- Applies to both pre-validation and during processing
-
Reconcile unpaid invoices in background (default: checked)
- When enabled: Runs reconciliation as a background job with progress tracking
- When disabled: Runs reconciliation synchronously (immediate completion)
- Recommendation: Keep enabled for operations with 10+ invoices
For production deployments with heavy reconciliation workload:
# In your Procfile or supervisor config
# Increase workers for the long queue
bench worker --queue long --num-workers 2- Navigate to Advance Bank Reconciliation Tool
- Select your Bank Account
- Set Date Range for bank transactions
- Optionally enable Filter by Reference Date for additional date filtering
- Click Get Unreconciled Entries
- Click Actions button on a bank transaction row
- Select Match Against Voucher in the dialog
- Choose document types to search (Payment Entry, Journal Entry, Sales Invoice, etc.)
- Apply filters (date range, customer group, etc.)
- Select vouchers/invoices to reconcile
- Click Submit and confirm
For matching a single bank transaction against multiple unpaid invoices:
- Follow steps 1-7 above
- Enable Unpaid Sales Invoice or Unpaid Purchase Invoice checkboxes
- Optionally apply filters:
- Show Only Exact Amount: Show only invoices matching the transaction amount exactly
- Customer Group: Filter by specific customer group
- Date filters: Limit invoice date ranges
- Custom filters: Use any custom filters added via hooks
- Select multiple invoices (checkbox on each row or use datatable's "Select All")
- Review the selected total shown above the table
- Click Submit and confirm
What happens next:
-
If Background Mode enabled:
- Confirmation dialog appears
- Progress dialog shows with real-time updates
- Click "Run in Background" to minimize dialog
- Desktop notification on completion
- Data table refreshes automatically
-
If Synchronous Mode enabled:
- Confirmation dialog appears
- Immediate processing
- Success alert shows
- Data table refreshes immediately
To create a new payment entry from a bank transaction:
- Click Actions on a bank transaction
- Select Create Voucher → Payment Entry or Journal Entry
- Fill in required details:
- Reference Number
- Posting Date
- Reference Date
- Party Type and Party (for Payment Entry)
- Account (for Journal Entry)
- Mode of Payment
- Click Submit
To update bank transaction metadata:
- Click Actions on a bank transaction
- Select Update Bank Transaction
- Modify:
- Reference Number
- Party Type
- Party
- Click Submit
Backend (Python):
advance_bank_reconciliation_tool.py: Core reconciliation logicget_matching_queries(): Dynamic query builder for matching vouchers/invoicesprocess_bulk_reconciliation(): Background job handler with batchingcreate_payment_entry_for_invoice(): Payment entry creation for unpaid invoices- Extended
Bank Transactiondoctype with custom fields
Frontend (JavaScript):
dialog_manager.js: Reconciliation dialog UI and WebSocket handling- Real-time progress tracking via
frappe.realtime - Debounced row selection for performance with large datasets
Settings:
Advance Bank Reconciliation Settings: Single doctype for global configuration
User selects invoices → Pre-validation checks → Enqueue job → Background worker picks up
↓ ↓
Returns job_id Process in batches
↓ ↓
Frontend subscribes to events Send progress updates
↓ ↓
Shows progress dialog ←───────────────────────────── WebSocket (frappe.publish_realtime)
↓ ↓
Receives completion event Create payment entries
↓ ↓
Hides dialog + refreshes data ←──────────────────────── Reconcile + commit + notify
The tool uses a ranking system to find best matches:
Rank Score Components (higher = better match):
- +1 if party matches
- +1 if amount matches exactly (with ABS for returns)
- +1 if currency matches
- +1 base score
Query Types:
- Payment Entries (paid against reference)
- Journal Entries (bank account entries)
- Sales Invoices (paid via cash/bank)
- Purchase Invoices (paid via cash/bank)
- Unpaid Sales Invoices (with returns support)
- Unpaid Purchase Invoices (with returns support)
Exact Match Mode:
- Uses
ABS(amount)comparisons for returns support - Filters only matching amounts
- Higher ranking precision
Symptoms: Progress dialog stays open forever, showing 0% or partial progress
Causes:
- WebSocket connection lost
- Background worker not running
- Job crashed without sending completion event
Solutions:
- Check background worker status:
bench worker --queue longmust be running - Check browser console for WebSocket errors
- Check
bench logsfor job errors - Try disabling "Reconcile in background" setting for immediate execution
- Refresh the page and check if reconciliation actually completed (check bank transaction)
"Selected allocations differ from unallocated amount":
- Disable "Validate selection against unallocated amount" in settings if intentional
- Or adjust selections to match exactly
"Allocated amount exceeds outstanding":
- Indicates data inconsistency - refresh invoice data
- Check if invoice was partially paid elsewhere
- Disable validation if needed for special cases
Slow selection with 100+ rows:
- Already optimized with debouncing (100ms)
- Avoid using datatable inline filters (slower with large datasets)
- Use the filter fields in the dialog instead
Timeout errors:
- Enable background mode in settings
- Reduce batch size if needed (modify code:
batch_size = 100)
Check:
- SocketIO server running:
bench serveor production webserver config - Browser console for connection errors
- Firewall/proxy allowing WebSocket connections
- Try synchronous mode as fallback
Implement the hook in your custom app:
# custom_app/custom_app/hooks.py
get_matching_queries = [
"custom_app.bank_rec.get_custom_matching_queries"
]
# custom_app/custom_app/bank_rec.py
def get_custom_matching_queries(bank_account, company, transaction, document_types,
from_date, to_date, filter_by_reference_date,
from_reference_date, to_reference_date, exact_match):
queries = []
if "Custom Voucher" in document_types:
queries.append({
"doctype": "Custom Voucher",
"query": get_custom_voucher_query(...),
"filters": {...}
})
return queries# Run all tests
bench --site your-site run-tests --app advanced_bank_reconciliation
# Run specific test
bench --site your-site run-tests --app advanced_bank_reconciliation --module test_reconciliation- Frappe Framework: >= v15.0.0
- ERPNext: >= v15.0.0
- Python: >= 3.10
- Redis: For background jobs and WebSocket
- SocketIO: For real-time progress updates
GPL-3.0
- Documentation: See inline code comments and this README
- Issues: https://github.com/one-highflyer/advanced_bank_reconciliation/issues
- Logs:
bench logsfor detailed error information
Developed by HighFlyer (https://highflyerglobal.com)
For ERPNext v15+ with enhanced bank reconciliation capabilities.