diff --git a/fusion_accounting_assets/__manifest__.py b/fusion_accounting_assets/__manifest__.py index 8ed58fc1..5131b40b 100644 --- a/fusion_accounting_assets/__manifest__.py +++ b/fusion_accounting_assets/__manifest__.py @@ -1,6 +1,6 @@ { 'name': 'Fusion Accounting Assets', - 'version': '19.0.1.0.7', + 'version': '19.0.1.0.8', 'category': 'Accounting/Accounting', 'summary': 'AI-augmented asset management with depreciation schedules.', 'description': """ diff --git a/fusion_accounting_assets/models/fusion_asset_category.py b/fusion_accounting_assets/models/fusion_asset_category.py index eecade1b..1f3ad7c1 100644 --- a/fusion_accounting_assets/models/fusion_asset_category.py +++ b/fusion_accounting_assets/models/fusion_asset_category.py @@ -1,10 +1,6 @@ -"""Asset categories with default settings (used as templates). +"""Asset categories with default settings (used as templates).""" -Stub created with Task 8 (so fusion.asset.category_id Many2one resolves). -Fully elaborated in Task 10. -""" - -from odoo import fields, models +from odoo import api, fields, models class FusionAssetCategory(models.Model): @@ -14,3 +10,44 @@ class FusionAssetCategory(models.Model): name = fields.Char(required=True, translate=True) sequence = fields.Integer(default=10) + company_id = fields.Many2one( + 'res.company', default=lambda self: self.env.company, + ) + + method = fields.Selection([ + ('straight_line', 'Straight Line'), + ('declining_balance', 'Declining Balance'), + ('units_of_production', 'Units of Production'), + ], default='straight_line', required=True) + useful_life_years = fields.Integer(default=5) + declining_rate_pct = fields.Float(default=20.0) + salvage_value_pct = fields.Float( + default=0.0, + help="% of cost (used for new assets in this category).", + ) + prorate_convention = fields.Selection([ + ('full_month', 'Full Month'), + ('days_365', 'Days / 365'), + ('days_period', 'Days in Period'), + ], default='days_period', required=True) + + asset_account_id = fields.Many2one( + 'account.account', string='Asset Account', + domain="[('account_type', 'in', ('asset_fixed', 'asset_non_current'))]", + ) + depreciation_account_id = fields.Many2one( + 'account.account', string='Depreciation Account', + domain="[('account_type', '=', 'asset_fixed')]", + ) + expense_account_id = fields.Many2one( + 'account.account', string='Expense Account', + domain="[('account_type', '=', 'expense_depreciation')]", + ) + + asset_count = fields.Integer(compute='_compute_asset_count') + + def _compute_asset_count(self): + for cat in self: + cat.asset_count = self.env['fusion.asset'].search_count([ + ('category_id', '=', cat.id), + ]) diff --git a/fusion_accounting_assets/tests/__init__.py b/fusion_accounting_assets/tests/__init__.py index 5104fc18..b5ea6f5f 100644 --- a/fusion_accounting_assets/tests/__init__.py +++ b/fusion_accounting_assets/tests/__init__.py @@ -5,3 +5,4 @@ from . import test_asset_anomaly_detection from . import test_useful_life_predictor from . import test_fusion_asset from . import test_fusion_asset_depreciation_line +from . import test_fusion_asset_category diff --git a/fusion_accounting_assets/tests/test_fusion_asset_category.py b/fusion_accounting_assets/tests/test_fusion_asset_category.py new file mode 100644 index 00000000..a7bc36c8 --- /dev/null +++ b/fusion_accounting_assets/tests/test_fusion_asset_category.py @@ -0,0 +1,35 @@ +from datetime import date + +from odoo.tests.common import TransactionCase +from odoo.tests import tagged + + +@tagged('post_install', '-at_install') +class TestFusionAssetCategory(TransactionCase): + + def test_create_with_defaults(self): + cat = self.env['fusion.asset.category'].create({'name': 'Computers'}) + self.assertEqual(cat.method, 'straight_line') + self.assertEqual(cat.useful_life_years, 5) + self.assertEqual(cat.prorate_convention, 'days_period') + self.assertEqual(cat.asset_count, 0) + + def test_asset_count_reflects_linked_assets(self): + cat = self.env['fusion.asset.category'].create({'name': 'Vehicles'}) + for i in range(3): + self.env['fusion.asset'].create({ + 'name': f'Truck {i}', + 'cost': 50000, + 'acquisition_date': date(2026, 1, 1), + 'method': 'declining_balance', + 'category_id': cat.id, + }) + cat.invalidate_recordset(['asset_count']) + self.assertEqual(cat.asset_count, 3) + + def test_method_must_be_in_selection(self): + with self.assertRaises(Exception): + self.env['fusion.asset.category'].create({ + 'name': 'Bogus', + 'method': 'not_a_method', + })