refactor(fusion_accounting_ai): route get_unreconciled_bank_lines through BankRecAdapter (pilot)
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
This commit is contained in:
@@ -14,28 +14,60 @@ class BankRecAdapter(DataAdapter):
|
||||
FUSION_MODEL = 'fusion.bank.rec.widget'
|
||||
ENTERPRISE_MODULE = 'account_accountant'
|
||||
|
||||
def list_unreconciled(self, journal_id, limit=100):
|
||||
"""Return unreconciled bank statement lines for a journal."""
|
||||
return self._dispatch('list_unreconciled', journal_id=journal_id, limit=limit)
|
||||
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.
|
||||
|
||||
def list_unreconciled_via_fusion(self, journal_id, limit=100):
|
||||
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)
|
||||
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, limit=100):
|
||||
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)
|
||||
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, limit=100):
|
||||
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()
|
||||
records = Line.search([
|
||||
('journal_id', '=', journal_id),
|
||||
('is_reconciled', '=', False),
|
||||
], limit=limit, order='date desc, id desc')
|
||||
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,
|
||||
@@ -43,8 +75,10 @@ class BankRecAdapter(DataAdapter):
|
||||
'payment_ref': r.payment_ref,
|
||||
'amount': r.amount,
|
||||
'partner_id': r.partner_id.id if r.partner_id else None,
|
||||
'partner_name': r.partner_id.name 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
|
||||
]
|
||||
|
||||
@@ -6,28 +6,32 @@ _logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_unreconciled_bank_lines(env, params):
|
||||
domain = [('is_reconciled', '=', False), ('company_id', '=', env.company.id)]
|
||||
if params.get('journal_id'):
|
||||
domain.append(('journal_id', '=', int(params['journal_id'])))
|
||||
if params.get('date_from'):
|
||||
domain.append(('date', '>=', params['date_from']))
|
||||
if params.get('date_to'):
|
||||
domain.append(('date', '<=', params['date_to']))
|
||||
if params.get('min_amount'):
|
||||
domain.append(('amount', '>=', float(params['min_amount'])))
|
||||
limit = int(params.get('limit', 50))
|
||||
lines = env['account.bank.statement.line'].search(domain, limit=limit, order='date desc')
|
||||
"""Return unreconciled bank lines for a journal/company.
|
||||
|
||||
Routed through the bank_rec data adapter so the result shape is identical
|
||||
whether the install profile is fusion-native, Enterprise, or pure Community.
|
||||
"""
|
||||
from ..data_adapters import get_adapter
|
||||
adapter = get_adapter(env, 'bank_rec')
|
||||
rows = adapter.list_unreconciled(
|
||||
journal_id=int(params['journal_id']) if params.get('journal_id') else None,
|
||||
limit=int(params.get('limit', 50)),
|
||||
date_from=params.get('date_from'),
|
||||
date_to=params.get('date_to'),
|
||||
min_amount=float(params['min_amount']) if params.get('min_amount') else None,
|
||||
company_id=env.company.id,
|
||||
)
|
||||
return {
|
||||
'count': len(lines),
|
||||
'total_amount': sum(abs(l.amount) for l in lines),
|
||||
'count': len(rows),
|
||||
'total_amount': sum(abs(r['amount']) for r in rows),
|
||||
'lines': [{
|
||||
'id': l.id,
|
||||
'date': str(l.date),
|
||||
'payment_ref': l.payment_ref or '',
|
||||
'partner_name': l.partner_name or (l.partner_id.name if l.partner_id else ''),
|
||||
'amount': l.amount,
|
||||
'journal': l.journal_id.name,
|
||||
} for l in lines],
|
||||
'id': r['id'],
|
||||
'date': str(r['date']) if r['date'] else '',
|
||||
'payment_ref': r['payment_ref'] or '',
|
||||
'partner_name': r['partner_name'] or '',
|
||||
'amount': r['amount'],
|
||||
'journal': r['journal_name'],
|
||||
} for r in rows],
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user