Pilot refactor per Task 13 Step 2 of phase-0 plan: route the bank-rec AI tool function through the data adapter so it works identically whether the install profile is fusion-native, Enterprise, or pure Community. Extends BankRecAdapter.list_unreconciled() with optional filter params (date_from, date_to, min_amount, company_id, and optional journal_id) and adds partner_name / journal_id / journal_name to the returned shape so the tool wrapper can preserve its existing outward return dict. All 6 data-adapter tests pass against westin-v19 (TestDataAdapterBase, TestBankRecAdapter, TestReportsAdapter, TestFollowupAdapter, TestAssetsAdapter). Made-with: Cursor
88 lines
3.8 KiB
Python
88 lines
3.8 KiB
Python
"""Bank reconciliation data adapter.
|
|
|
|
Routes bank-rec data lookups across:
|
|
- FUSION: fusion.bank.rec.widget (added by fusion_accounting_bank_rec, Phase 1)
|
|
- ENTERPRISE: account_accountant's bank_rec_widget JS service
|
|
- COMMUNITY: pure search on account.bank.statement.line
|
|
"""
|
|
|
|
from .base import DataAdapter
|
|
from ._registry import register_adapter
|
|
|
|
|
|
class BankRecAdapter(DataAdapter):
|
|
FUSION_MODEL = 'fusion.bank.rec.widget'
|
|
ENTERPRISE_MODULE = 'account_accountant'
|
|
|
|
def list_unreconciled(self, journal_id=None, limit=100, date_from=None,
|
|
date_to=None, min_amount=None, company_id=None):
|
|
"""Return unreconciled bank statement lines.
|
|
|
|
All filter params are optional; pass company_id to restrict results to
|
|
a single company (the AI tools always do this).
|
|
"""
|
|
return self._dispatch(
|
|
'list_unreconciled',
|
|
journal_id=journal_id, limit=limit,
|
|
date_from=date_from, date_to=date_to,
|
|
min_amount=min_amount, company_id=company_id,
|
|
)
|
|
|
|
def list_unreconciled_via_fusion(self, journal_id=None, limit=100,
|
|
date_from=None, date_to=None,
|
|
min_amount=None, company_id=None):
|
|
# Phase 1 will add fusion.bank.rec.widget; this method becomes the primary path.
|
|
# For now: even when the model exists, delegate to community read shape.
|
|
return self.list_unreconciled_via_community(
|
|
journal_id=journal_id, limit=limit,
|
|
date_from=date_from, date_to=date_to,
|
|
min_amount=min_amount, company_id=company_id,
|
|
)
|
|
|
|
def list_unreconciled_via_enterprise(self, journal_id=None, limit=100,
|
|
date_from=None, date_to=None,
|
|
min_amount=None, company_id=None):
|
|
# Enterprise's bank rec uses a JS-side service; from Python the cleanest
|
|
# backend access is the same Community search (the data lives in
|
|
# account.bank.statement.line either way). This adapter's purpose is
|
|
# to expose a stable shape to AI tools regardless of which UI the user has.
|
|
return self.list_unreconciled_via_community(
|
|
journal_id=journal_id, limit=limit,
|
|
date_from=date_from, date_to=date_to,
|
|
min_amount=min_amount, company_id=company_id,
|
|
)
|
|
|
|
def list_unreconciled_via_community(self, journal_id=None, limit=100,
|
|
date_from=None, date_to=None,
|
|
min_amount=None, company_id=None):
|
|
Line = self.env['account.bank.statement.line'].sudo()
|
|
domain = [('is_reconciled', '=', False)]
|
|
if journal_id is not None:
|
|
domain.append(('journal_id', '=', journal_id))
|
|
if company_id is not None:
|
|
domain.append(('company_id', '=', company_id))
|
|
if date_from:
|
|
domain.append(('date', '>=', date_from))
|
|
if date_to:
|
|
domain.append(('date', '<=', date_to))
|
|
if min_amount is not None:
|
|
domain.append(('amount', '>=', min_amount))
|
|
records = Line.search(domain, limit=limit, order='date desc, id desc')
|
|
return [
|
|
{
|
|
'id': r.id,
|
|
'date': r.date,
|
|
'payment_ref': r.payment_ref,
|
|
'amount': r.amount,
|
|
'partner_id': r.partner_id.id if r.partner_id else None,
|
|
'partner_name': r.partner_name or (r.partner_id.name if r.partner_id else None),
|
|
'currency_id': r.currency_id.id if r.currency_id else None,
|
|
'journal_id': r.journal_id.id,
|
|
'journal_name': r.journal_id.name,
|
|
}
|
|
for r in records
|
|
]
|
|
|
|
|
|
register_adapter('bank_rec', BankRecAdapter)
|