feat(fusion_accounting_ai): add Followup and Assets data adapters
Made-with: Cursor
This commit is contained in:
@@ -3,5 +3,7 @@ from ._registry import get_adapter, register_adapter
|
|||||||
|
|
||||||
from . import bank_rec # noqa: F401
|
from . import bank_rec # noqa: F401
|
||||||
from . import reports # noqa: F401
|
from . import reports # noqa: F401
|
||||||
|
from . import followup # noqa: F401
|
||||||
|
from . import assets # noqa: F401
|
||||||
|
|
||||||
__all__ = ['DataAdapter', 'AdapterMode', 'get_adapter', 'register_adapter']
|
__all__ = ['DataAdapter', 'AdapterMode', 'get_adapter', 'register_adapter']
|
||||||
|
|||||||
42
fusion_accounting_ai/services/data_adapters/assets.py
Normal file
42
fusion_accounting_ai/services/data_adapters/assets.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
"""Assets data adapter."""
|
||||||
|
|
||||||
|
from .base import DataAdapter
|
||||||
|
from ._registry import register_adapter
|
||||||
|
|
||||||
|
|
||||||
|
class AssetsAdapter(DataAdapter):
|
||||||
|
FUSION_MODEL = 'fusion.asset'
|
||||||
|
ENTERPRISE_MODULE = 'account_asset'
|
||||||
|
|
||||||
|
def list_assets(self, state=None):
|
||||||
|
return self._dispatch('list_assets', state=state)
|
||||||
|
|
||||||
|
def list_assets_via_fusion(self, state=None):
|
||||||
|
return self._read_fusion('fusion.asset', state=state)
|
||||||
|
|
||||||
|
def list_assets_via_enterprise(self, state=None):
|
||||||
|
return self._read_fusion('account.asset', state=state)
|
||||||
|
|
||||||
|
def list_assets_via_community(self, state=None):
|
||||||
|
# No assets feature in pure Community — return empty list with a hint.
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _read_fusion(self, model_name, state=None):
|
||||||
|
"""Shared shape between fusion and enterprise (both use account.asset-like API)."""
|
||||||
|
Model = self.env[model_name].sudo()
|
||||||
|
domain = []
|
||||||
|
if state:
|
||||||
|
domain.append(('state', '=', state))
|
||||||
|
records = Model.search(domain, limit=200)
|
||||||
|
out = []
|
||||||
|
for r in records:
|
||||||
|
out.append({
|
||||||
|
'id': r.id,
|
||||||
|
'name': getattr(r, 'name', None),
|
||||||
|
'state': getattr(r, 'state', None),
|
||||||
|
'value': getattr(r, 'original_value', None) or getattr(r, 'acquisition_cost', None),
|
||||||
|
})
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
register_adapter('assets', AssetsAdapter)
|
||||||
47
fusion_accounting_ai/services/data_adapters/followup.py
Normal file
47
fusion_accounting_ai/services/data_adapters/followup.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
"""Follow-up data adapter."""
|
||||||
|
|
||||||
|
from datetime import date, timedelta
|
||||||
|
from .base import DataAdapter
|
||||||
|
from ._registry import register_adapter
|
||||||
|
|
||||||
|
|
||||||
|
class FollowupAdapter(DataAdapter):
|
||||||
|
FUSION_MODEL = 'fusion.followup.line'
|
||||||
|
ENTERPRISE_MODULE = 'account_followup'
|
||||||
|
|
||||||
|
def overdue_invoices(self, days_overdue=30, partner_id=None):
|
||||||
|
return self._dispatch('overdue_invoices', days_overdue=days_overdue, partner_id=partner_id)
|
||||||
|
|
||||||
|
def overdue_invoices_via_fusion(self, days_overdue=30, partner_id=None):
|
||||||
|
return self.overdue_invoices_via_community(days_overdue=days_overdue, partner_id=partner_id)
|
||||||
|
|
||||||
|
def overdue_invoices_via_enterprise(self, days_overdue=30, partner_id=None):
|
||||||
|
return self.overdue_invoices_via_community(days_overdue=days_overdue, partner_id=partner_id)
|
||||||
|
|
||||||
|
def overdue_invoices_via_community(self, days_overdue=30, partner_id=None):
|
||||||
|
cutoff = date.today() - timedelta(days=days_overdue)
|
||||||
|
domain = [
|
||||||
|
('move_type', 'in', ('out_invoice', 'out_refund')),
|
||||||
|
('state', '=', 'posted'),
|
||||||
|
('payment_state', 'in', ('not_paid', 'partial')),
|
||||||
|
('invoice_date_due', '<=', cutoff),
|
||||||
|
]
|
||||||
|
if partner_id:
|
||||||
|
domain.append(('partner_id', '=', partner_id))
|
||||||
|
moves = self.env['account.move'].sudo().search(domain, limit=200, order='invoice_date_due asc')
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'id': m.id,
|
||||||
|
'name': m.name,
|
||||||
|
'partner_id': m.partner_id.id,
|
||||||
|
'partner_name': m.partner_id.name,
|
||||||
|
'invoice_date_due': m.invoice_date_due,
|
||||||
|
'amount_residual': m.amount_residual,
|
||||||
|
'currency_id': m.currency_id.id,
|
||||||
|
'days_overdue': (date.today() - m.invoice_date_due).days,
|
||||||
|
}
|
||||||
|
for m in moves
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
register_adapter('followup', FollowupAdapter)
|
||||||
@@ -74,3 +74,19 @@ class TestReportsAdapter(TransactionCase):
|
|||||||
for row in result:
|
for row in result:
|
||||||
self.assertIn('account_id', row)
|
self.assertIn('account_id', row)
|
||||||
self.assertIn('balance', row)
|
self.assertIn('balance', row)
|
||||||
|
|
||||||
|
|
||||||
|
@tagged('post_install', '-at_install')
|
||||||
|
class TestFollowupAdapter(TransactionCase):
|
||||||
|
def test_overdue_invoices_returns_list(self):
|
||||||
|
adapter = get_adapter(self.env, 'followup')
|
||||||
|
rows = adapter.overdue_invoices(days_overdue=30)
|
||||||
|
self.assertIsInstance(rows, list)
|
||||||
|
|
||||||
|
|
||||||
|
@tagged('post_install', '-at_install')
|
||||||
|
class TestAssetsAdapter(TransactionCase):
|
||||||
|
def test_list_assets_returns_list(self):
|
||||||
|
adapter = get_adapter(self.env, 'assets')
|
||||||
|
rows = adapter.list_assets()
|
||||||
|
self.assertIsInstance(rows, list)
|
||||||
|
|||||||
Reference in New Issue
Block a user