feat(fusion_accounting_ai): 5 new asset management AI tools
Made-with: Cursor
This commit is contained in:
@@ -10,11 +10,13 @@ from .adp import TOOLS as ADP_TOOLS
|
||||
from .reporting import TOOLS as REPORTING_TOOLS
|
||||
from .audit import TOOLS as AUDIT_TOOLS
|
||||
from .financial_reports import TOOLS as FINANCIAL_REPORTS_TOOLS
|
||||
from .asset_management import TOOLS as ASSET_MANAGEMENT_TOOLS
|
||||
|
||||
TOOL_DISPATCH = {}
|
||||
for tools_dict in [
|
||||
BANK_RECON_TOOLS, HST_TOOLS, AR_TOOLS, AP_TOOLS, JOURNAL_TOOLS,
|
||||
MONTH_END_TOOLS, PAYROLL_TOOLS, INVENTORY_TOOLS, ADP_TOOLS,
|
||||
REPORTING_TOOLS, AUDIT_TOOLS, FINANCIAL_REPORTS_TOOLS,
|
||||
ASSET_MANAGEMENT_TOOLS,
|
||||
]:
|
||||
TOOL_DISPATCH.update(tools_dict)
|
||||
|
||||
77
fusion_accounting_ai/services/tools/asset_management.py
Normal file
77
fusion_accounting_ai/services/tools/asset_management.py
Normal file
@@ -0,0 +1,77 @@
|
||||
"""Fusion-engine-routed AI tools for asset management."""
|
||||
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def fusion_list_assets(env, params):
|
||||
if 'fusion.asset.engine' not in env.registry:
|
||||
return {'error': 'fusion_accounting_assets not installed'}
|
||||
from ..data_adapters import get_adapter
|
||||
adapter = get_adapter(env, 'assets')
|
||||
return adapter.list_assets(
|
||||
state=params.get('state'),
|
||||
limit=int(params.get('limit', 50)),
|
||||
company_id=int(params['company_id']) if params.get('company_id') else env.company.id,
|
||||
)
|
||||
|
||||
|
||||
def fusion_get_asset_detail(env, params):
|
||||
if 'fusion.asset.engine' not in env.registry:
|
||||
return {'error': 'fusion_accounting_assets not installed'}
|
||||
Asset = env['fusion.asset']
|
||||
asset = Asset.browse(int(params['asset_id']))
|
||||
if not asset.exists():
|
||||
return {'error': 'Asset not found'}
|
||||
return {
|
||||
'asset': {
|
||||
'id': asset.id, 'name': asset.name, 'state': asset.state,
|
||||
'cost': asset.cost, 'book_value': asset.book_value,
|
||||
'total_depreciated': asset.total_depreciated,
|
||||
'method': asset.method, 'useful_life_years': asset.useful_life_years,
|
||||
},
|
||||
'depreciation_count': len(asset.depreciation_line_ids),
|
||||
}
|
||||
|
||||
|
||||
def fusion_compute_asset_schedule(env, params):
|
||||
if 'fusion.asset.engine' not in env.registry:
|
||||
return {'error': 'fusion_accounting_assets not installed'}
|
||||
asset = env['fusion.asset'].browse(int(params['asset_id']))
|
||||
return env['fusion.asset.engine'].compute_depreciation_schedule(
|
||||
asset, recompute=bool(params.get('recompute', False)),
|
||||
)
|
||||
|
||||
|
||||
def fusion_dispose_asset(env, params):
|
||||
if 'fusion.asset.engine' not in env.registry:
|
||||
return {'error': 'fusion_accounting_assets not installed'}
|
||||
from ..data_adapters import get_adapter
|
||||
adapter = get_adapter(env, 'assets')
|
||||
return adapter.dispose_asset(
|
||||
asset_id=int(params['asset_id']),
|
||||
sale_amount=float(params.get('sale_amount', 0)),
|
||||
disposal_type=params.get('disposal_type', 'sale'),
|
||||
)
|
||||
|
||||
|
||||
def fusion_suggest_asset_useful_life(env, params):
|
||||
if 'fusion.asset.engine' not in env.registry:
|
||||
return {'error': 'fusion_accounting_assets not installed'}
|
||||
from ..data_adapters import get_adapter
|
||||
adapter = get_adapter(env, 'assets')
|
||||
return adapter.suggest_useful_life(
|
||||
description=params.get('description', ''),
|
||||
amount=float(params['amount']) if params.get('amount') else None,
|
||||
partner_name=params.get('partner_name'),
|
||||
)
|
||||
|
||||
|
||||
TOOLS = {
|
||||
'fusion_list_assets': fusion_list_assets,
|
||||
'fusion_get_asset_detail': fusion_get_asset_detail,
|
||||
'fusion_compute_asset_schedule': fusion_compute_asset_schedule,
|
||||
'fusion_dispose_asset': fusion_dispose_asset,
|
||||
'fusion_suggest_asset_useful_life': fusion_suggest_asset_useful_life,
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
'name': 'Fusion Accounting Assets',
|
||||
'version': '19.0.1.0.15',
|
||||
'version': '19.0.1.0.16',
|
||||
'category': 'Accounting/Accounting',
|
||||
'summary': 'AI-augmented asset management with depreciation schedules.',
|
||||
'description': """
|
||||
|
||||
@@ -13,3 +13,4 @@ from . import test_fusion_asset_engine
|
||||
from . import test_engine_integration
|
||||
from . import test_assets_controller
|
||||
from . import test_assets_adapter
|
||||
from . import test_asset_tools
|
||||
|
||||
56
fusion_accounting_assets/tests/test_asset_tools.py
Normal file
56
fusion_accounting_assets/tests/test_asset_tools.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""Tests for the 5 fusion-asset AI tools."""
|
||||
|
||||
from datetime import date
|
||||
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
from odoo.addons.fusion_accounting_ai.services.tools import asset_management as tools
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestFusionAssetTools(TransactionCase):
|
||||
|
||||
def test_fusion_list_assets(self):
|
||||
self.env['fusion.asset'].create({
|
||||
'name': 'Tool Test', 'cost': 1000,
|
||||
'acquisition_date': date(2026, 1, 1),
|
||||
'method': 'straight_line', 'useful_life_years': 4,
|
||||
})
|
||||
result = tools.fusion_list_assets(self.env, {'company_id': self.env.company.id})
|
||||
self.assertGreaterEqual(result.get('count', 0), 1)
|
||||
|
||||
def test_fusion_get_asset_detail(self):
|
||||
asset = self.env['fusion.asset'].create({
|
||||
'name': 'Detail Test', 'cost': 1500,
|
||||
'acquisition_date': date(2026, 1, 1),
|
||||
'method': 'straight_line', 'useful_life_years': 4,
|
||||
})
|
||||
result = tools.fusion_get_asset_detail(self.env, {'asset_id': asset.id})
|
||||
self.assertEqual(result['asset']['name'], 'Detail Test')
|
||||
|
||||
def test_fusion_compute_schedule(self):
|
||||
asset = self.env['fusion.asset'].create({
|
||||
'name': 'Schedule Test', 'cost': 2000,
|
||||
'acquisition_date': date(2026, 1, 1),
|
||||
'method': 'straight_line', 'useful_life_years': 4,
|
||||
})
|
||||
result = tools.fusion_compute_asset_schedule(self.env, {'asset_id': asset.id})
|
||||
self.assertEqual(result['lines_created'], 4)
|
||||
|
||||
def test_fusion_suggest_useful_life(self):
|
||||
self.env['ir.config_parameter'].sudo().search([
|
||||
('key', 'in', ['fusion_accounting.provider.asset_useful_life',
|
||||
'fusion_accounting.provider.default'])
|
||||
]).unlink()
|
||||
result = tools.fusion_suggest_asset_useful_life(self.env, {
|
||||
'description': 'desk',
|
||||
})
|
||||
self.assertEqual(result['useful_life_years'], 7)
|
||||
|
||||
def test_tools_registered_in_dispatch(self):
|
||||
from odoo.addons.fusion_accounting_ai.services.tools import TOOL_DISPATCH
|
||||
for tool_name in ['fusion_list_assets', 'fusion_get_asset_detail',
|
||||
'fusion_compute_asset_schedule', 'fusion_dispose_asset',
|
||||
'fusion_suggest_asset_useful_life']:
|
||||
self.assertIn(tool_name, TOOL_DISPATCH)
|
||||
Reference in New Issue
Block a user