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
85 lines
3.8 KiB
Python
85 lines
3.8 KiB
Python
"""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)
|