- cron_suggest (every 30min): warm AI suggestions for unreconciled lines that don't have a recent pending one - cron_pattern_refresh (daily 02:00): recompute fusion.reconcile.pattern for each (company, partner) pair with precedents - cron_mv_refresh (every 5min): REFRESH MATERIALIZED VIEW CONCURRENTLY using a dedicated autocommit cursor (REFRESH CONCURRENTLY can't run inside a regular Odoo transaction) V19 note: ir.cron dropped the numbercall field, so the data XML omits it (cron now repeats indefinitely as long as active=True). Tests: 5 new TestFusionBankRecCron tests pass; full module suite is 0 failed / 0 errors of 123 logical tests on westin-v19. Made-with: Cursor
86 lines
3.3 KiB
Python
86 lines
3.3 KiB
Python
"""Smoke tests for the cron handler methods.
|
|
|
|
We don't test the Odoo cron scheduler itself (it works) — we test that
|
|
calling the cron methods directly does what they're supposed to do."""
|
|
|
|
from odoo.tests.common import TransactionCase, tagged
|
|
from . import _factories as f
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestFusionBankRecCron(TransactionCase):
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.partner = self.env['res.partner'].create({'name': 'Cron Test Partner'})
|
|
self.cron = self.env['fusion.bank.rec.cron']
|
|
|
|
def test_cron_suggest_pending_creates_suggestions_for_new_line(self):
|
|
f.make_invoice(self.env, partner=self.partner, amount=420.00)
|
|
bank_line = f.make_bank_line(
|
|
self.env, amount=420.00, partner=self.partner)
|
|
|
|
Sug = self.env['fusion.reconcile.suggestion']
|
|
self.assertEqual(
|
|
Sug.search_count([('statement_line_id', '=', bank_line.id)]), 0)
|
|
|
|
self.cron._cron_suggest_pending(batch_size=10)
|
|
|
|
self.assertGreater(
|
|
Sug.search_count([('statement_line_id', '=', bank_line.id)]), 0)
|
|
|
|
def test_cron_suggest_pending_skips_lines_with_recent_suggestions(self):
|
|
f.make_invoice(self.env, partner=self.partner, amount=510.00)
|
|
bank_line = f.make_bank_line(
|
|
self.env, amount=510.00, partner=self.partner)
|
|
f.make_suggestion(
|
|
self.env, statement_line=bank_line, confidence=0.5)
|
|
|
|
Sug = self.env['fusion.reconcile.suggestion']
|
|
before = Sug.search_count(
|
|
[('statement_line_id', '=', bank_line.id)])
|
|
self.cron._cron_suggest_pending(batch_size=10)
|
|
after = Sug.search_count(
|
|
[('statement_line_id', '=', bank_line.id)])
|
|
self.assertEqual(
|
|
before, after,
|
|
"Cron should skip lines with a recent pending suggestion")
|
|
|
|
def test_cron_refresh_patterns_creates_pattern_for_partner_with_precedents(self):
|
|
for d in [10, 24, 38]:
|
|
f.make_precedent(
|
|
self.env, partner=self.partner, days_ago=d, amount=1000)
|
|
|
|
Pattern = self.env['fusion.reconcile.pattern']
|
|
Pattern.search([('partner_id', '=', self.partner.id)]).unlink()
|
|
|
|
self.cron._cron_refresh_patterns()
|
|
|
|
pattern = Pattern.search(
|
|
[('partner_id', '=', self.partner.id)], limit=1)
|
|
self.assertTrue(
|
|
pattern, "Cron should create pattern for partner with precedents")
|
|
self.assertEqual(pattern.reconcile_count, 3)
|
|
|
|
def test_cron_refresh_patterns_updates_existing_pattern(self):
|
|
Pattern = self.env['fusion.reconcile.pattern']
|
|
Pattern.search([('partner_id', '=', self.partner.id)]).unlink()
|
|
f.make_pattern(
|
|
self.env, partner=self.partner, reconcile_count=99)
|
|
|
|
for d in [5, 15]:
|
|
f.make_precedent(
|
|
self.env, partner=self.partner, days_ago=d, amount=500)
|
|
|
|
self.cron._cron_refresh_patterns()
|
|
|
|
pattern = Pattern.search(
|
|
[('partner_id', '=', self.partner.id)], limit=1)
|
|
self.assertEqual(
|
|
pattern.reconcile_count, 2,
|
|
"Cron should update existing pattern with fresh precedent count")
|
|
|
|
def test_cron_refresh_mv_does_not_raise(self):
|
|
# Just verify it runs — full MV behaviour is tested in Task 24
|
|
self.cron._cron_refresh_mv()
|