feat(fusion_accounting_ai): 5 new bank-rec AI tools wrapping engine
Adds fusion_suggest_matches, fusion_accept_suggestion, fusion_reconcile_bank_line, fusion_unreconcile, and fusion_get_pending_suggestions. All route through the BankRecAdapter (or direct engine for ones the adapter doesn't expose), giving the AI chat the same reconciliation surface a human operator gets in the OWL UI. Made-with: Cursor
This commit is contained in:
@@ -11,3 +11,4 @@ from . import test_factories
|
||||
from . import test_reconcile_engine_integration
|
||||
from . import test_bank_rec_prompt
|
||||
from . import test_bank_rec_adapter
|
||||
from . import test_bank_rec_tools
|
||||
|
||||
84
fusion_accounting_bank_rec/tests/test_bank_rec_tools.py
Normal file
84
fusion_accounting_bank_rec/tests/test_bank_rec_tools.py
Normal file
@@ -0,0 +1,84 @@
|
||||
"""Smoke tests for the 5 new fusion bank-rec AI tools."""
|
||||
|
||||
from odoo.tests.common import TransactionCase, tagged
|
||||
from odoo.addons.fusion_accounting_ai.services.tools import bank_reconciliation as tools
|
||||
from . import _factories as f
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestFusionBankRecTools(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.partner = self.env['res.partner'].create({'name': 'Tools Test Partner'})
|
||||
|
||||
def test_fusion_suggest_matches_returns_suggestions(self):
|
||||
invoice = f.make_invoice(self.env, partner=self.partner, amount=550.00)
|
||||
bank_line = f.make_bank_line(
|
||||
self.env, amount=550.00, partner=self.partner, memo='Tool test')
|
||||
result = tools.fusion_suggest_matches(self.env, {
|
||||
'statement_line_ids': [bank_line.id],
|
||||
'limit_per_line': 3,
|
||||
})
|
||||
self.assertIn('suggestions', result)
|
||||
self.assertIn('count', result)
|
||||
self.assertGreater(result['count'], 0)
|
||||
|
||||
def test_fusion_accept_suggestion_reconciles(self):
|
||||
invoice = f.make_invoice(self.env, partner=self.partner, amount=625.00)
|
||||
recv_lines = invoice.line_ids.filtered(
|
||||
lambda l: l.account_id.account_type == 'asset_receivable')
|
||||
bank_line = f.make_bank_line(self.env, amount=625.00, partner=self.partner)
|
||||
sug = f.make_suggestion(
|
||||
self.env, statement_line=bank_line,
|
||||
candidate_move_lines=recv_lines, confidence=0.94)
|
||||
result = tools.fusion_accept_suggestion(self.env, {'suggestion_id': sug.id})
|
||||
self.assertEqual(result['status'], 'accepted')
|
||||
self.assertGreater(len(result['partial_ids']), 0)
|
||||
|
||||
def test_fusion_reconcile_bank_line(self):
|
||||
bank_line, recv_lines = f.make_reconcileable_pair(
|
||||
self.env, amount=375.00, partner=self.partner)
|
||||
result = tools.fusion_reconcile_bank_line(self.env, {
|
||||
'statement_line_id': bank_line.id,
|
||||
'against_move_line_ids': recv_lines.ids,
|
||||
})
|
||||
self.assertEqual(result['status'], 'reconciled')
|
||||
self.assertTrue(result['is_reconciled'])
|
||||
|
||||
def test_fusion_unreconcile(self):
|
||||
bank_line, recv_lines = f.make_reconcileable_pair(
|
||||
self.env, amount=275.00, partner=self.partner)
|
||||
rec = self.env['fusion.reconcile.engine'].reconcile_one(
|
||||
bank_line, against_lines=recv_lines)
|
||||
partial_ids = rec['partial_ids']
|
||||
result = tools.fusion_unreconcile(self.env, {
|
||||
'partial_reconcile_ids': partial_ids,
|
||||
})
|
||||
self.assertEqual(result['status'], 'unreconciled')
|
||||
self.assertGreater(result['count'], 0)
|
||||
|
||||
def test_fusion_get_pending_suggestions(self):
|
||||
bank_line = f.make_bank_line(self.env, amount=100.00, partner=self.partner)
|
||||
sug = f.make_suggestion(
|
||||
self.env, statement_line=bank_line,
|
||||
candidate_move_lines=self.env['account.move.line'],
|
||||
confidence=0.88, state='pending')
|
||||
result = tools.fusion_get_pending_suggestions(self.env, {})
|
||||
self.assertIn('count', result)
|
||||
self.assertGreater(result['count'], 0)
|
||||
ids = [s['id'] for s in result['suggestions']]
|
||||
self.assertIn(sug.id, ids)
|
||||
|
||||
def test_fusion_get_pending_suggestions_filters_by_min_confidence(self):
|
||||
bank_line = f.make_bank_line(self.env, amount=100.00, partner=self.partner)
|
||||
# One low-confidence suggestion
|
||||
f.make_suggestion(self.env, statement_line=bank_line,
|
||||
confidence=0.30, state='pending')
|
||||
# One high-confidence
|
||||
high = f.make_suggestion(self.env, statement_line=bank_line,
|
||||
confidence=0.95, state='pending')
|
||||
result = tools.fusion_get_pending_suggestions(
|
||||
self.env, {'min_confidence': 0.80})
|
||||
ids = [s['id'] for s in result['suggestions']]
|
||||
self.assertIn(high.id, ids)
|
||||
Reference in New Issue
Block a user