214 lines
8.0 KiB
Python
214 lines
8.0 KiB
Python
import sys
|
|
import os
|
|
import argparse
|
|
from datetime import datetime, date
|
|
from dateutil.relativedelta import relativedelta
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Deep Test Depreciation Logic")
|
|
parser.add_argument("odoo_bin_path", help="Path to odoo-bin executable")
|
|
parser.add_argument("conf_path", help="Path to odoo.conf")
|
|
parser.add_argument("db_name", help="Database name")
|
|
|
|
args = parser.parse_args()
|
|
|
|
odoo_bin_path = os.path.abspath(args.odoo_bin_path)
|
|
conf_path = os.path.abspath(args.conf_path)
|
|
db_name = args.db_name
|
|
|
|
# Add Odoo to sys.path
|
|
odoo_root = os.path.dirname(odoo_bin_path)
|
|
if odoo_root not in sys.path:
|
|
sys.path.append(odoo_root)
|
|
|
|
# Change CWD to config directory to handle relative paths in config (like addons_path)
|
|
os.chdir(os.path.dirname(conf_path))
|
|
|
|
try:
|
|
import odoo
|
|
from odoo import api, SUPERUSER_ID
|
|
except ImportError:
|
|
print(f"Error: Could not import 'odoo' module from {odoo_root}. Make sure odoo-bin path is correct.")
|
|
sys.exit(1)
|
|
|
|
print(f"Initializing Odoo Environment for database: {db_name}...")
|
|
try:
|
|
odoo.tools.config.parse_config(['-c', conf_path])
|
|
registry = odoo.registry(db_name)
|
|
except Exception as e:
|
|
print(f"Error initializing Odoo: {e}")
|
|
return
|
|
|
|
with registry.cursor() as cr:
|
|
env = api.Environment(cr, SUPERUSER_ID, {})
|
|
print("Connected to Odoo.")
|
|
|
|
try:
|
|
test_different_scenarios(env)
|
|
cr.commit()
|
|
print("Test completed successfully.")
|
|
except Exception as e:
|
|
cr.rollback()
|
|
print(f"Test failed: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
def test_different_scenarios(env):
|
|
# Find an asset model to use
|
|
model = env['account.asset'].search([('state', '=', 'model')], limit=1)
|
|
if not model:
|
|
print("No asset model found!")
|
|
return
|
|
|
|
print(f"Using asset model: {model.name}")
|
|
print(f"Model settings: method={model.method}, method_number={model.method_number}, method_period={model.method_period}")
|
|
|
|
# Test different acquisition dates
|
|
test_cases = [
|
|
{
|
|
'name': 'Future Acquisition (2025-11-01)',
|
|
'acquisition_date': date(2025, 11, 1),
|
|
'description': 'Asset acquired after cutoff date'
|
|
},
|
|
{
|
|
'name': 'Recent Acquisition (2024-11-01)',
|
|
'acquisition_date': date(2024, 11, 1),
|
|
'description': 'Asset acquired before cutoff date'
|
|
},
|
|
{
|
|
'name': 'Old Acquisition (2020-01-01)',
|
|
'acquisition_date': date(2020, 1, 1),
|
|
'description': 'Very old asset'
|
|
}
|
|
]
|
|
|
|
for i, test_case in enumerate(test_cases):
|
|
print(f"\n{'='*60}")
|
|
print(f"TEST {i+1}: {test_case['name']}")
|
|
print(f"Description: {test_case['description']}")
|
|
print(f"{'='*60}")
|
|
|
|
acquisition_date = test_case['acquisition_date']
|
|
original_value = 48500000.0
|
|
|
|
vals = {
|
|
'name': f'TEST Asset - {test_case["name"]}',
|
|
'original_value': original_value,
|
|
'acquisition_date': acquisition_date,
|
|
'model_id': model.id,
|
|
'method': model.method,
|
|
'method_number': 60, # Force 60 months
|
|
'method_period': '1', # Force monthly
|
|
'prorata_computation_type': model.prorata_computation_type,
|
|
'state': 'draft',
|
|
'account_asset_id': model.account_asset_id.id,
|
|
'account_depreciation_id': model.account_depreciation_id.id,
|
|
'account_depreciation_expense_id': model.account_depreciation_expense_id.id,
|
|
'journal_id': model.journal_id.id,
|
|
'method_progress_factor': model.method_progress_factor,
|
|
'analytic_distribution': model.analytic_distribution,
|
|
}
|
|
|
|
asset = env['account.asset'].create(vals)
|
|
|
|
print(f"Created asset: {asset.name}")
|
|
print(f" Acquisition Date: {asset.acquisition_date}")
|
|
print(f" Method Number: {asset.method_number}")
|
|
print(f" Method Period: {asset.method_period}")
|
|
|
|
# Compute depreciation board
|
|
asset.compute_depreciation_board()
|
|
|
|
moves = asset.depreciation_move_ids.sorted('date')
|
|
print(f" Moves created: {len(moves)}")
|
|
|
|
if moves:
|
|
print(f" First move: {moves[0].date}")
|
|
print(f" Last move: {moves[-1].date}")
|
|
|
|
# Calculate expected end date
|
|
expected_end = acquisition_date + relativedelta(months=59) # 60 months = 0 to 59
|
|
print(f" Expected last move around: {expected_end}")
|
|
|
|
# Check if complete
|
|
if len(moves) >= 60:
|
|
print(f" ✅ Complete: {len(moves)} moves")
|
|
else:
|
|
print(f" ❌ Incomplete: Only {len(moves)} moves (expected 60)")
|
|
|
|
# Show first few and last few moves
|
|
print(f" First 3 moves:")
|
|
for move in moves[:3]:
|
|
amount = sum(line.debit for line in move.line_ids if line.account_id == asset.account_depreciation_expense_id)
|
|
print(f" {move.date}: {amount:,.2f}")
|
|
|
|
print(f" Last 3 moves:")
|
|
for move in moves[-3:]:
|
|
amount = sum(line.debit for line in move.line_ids if line.account_id == asset.account_depreciation_expense_id)
|
|
print(f" {move.date}: {amount:,.2f}")
|
|
|
|
# Cleanup
|
|
asset.unlink()
|
|
|
|
# Test with different prorata settings
|
|
print(f"\n{'='*60}")
|
|
print(f"TEST: Different Prorata Settings")
|
|
print(f"{'='*60}")
|
|
|
|
prorata_options = ['constant_periods', 'daily_computation', 'none']
|
|
|
|
for prorata in prorata_options:
|
|
print(f"\nTesting prorata_computation_type: {prorata}")
|
|
|
|
vals = {
|
|
'name': f'TEST Asset - Prorata {prorata}',
|
|
'original_value': 48500000.0,
|
|
'acquisition_date': date(2024, 11, 1),
|
|
'model_id': model.id,
|
|
'method': 'linear',
|
|
'method_number': 60,
|
|
'method_period': '1',
|
|
'prorata_computation_type': prorata,
|
|
'state': 'draft',
|
|
'account_asset_id': model.account_asset_id.id,
|
|
'account_depreciation_id': model.account_depreciation_id.id,
|
|
'account_depreciation_expense_id': model.account_depreciation_expense_id.id,
|
|
'journal_id': model.journal_id.id,
|
|
'method_progress_factor': model.method_progress_factor,
|
|
'analytic_distribution': model.analytic_distribution,
|
|
}
|
|
|
|
asset = env['account.asset'].create(vals)
|
|
asset.compute_depreciation_board()
|
|
|
|
moves = asset.depreciation_move_ids.sorted('date')
|
|
print(f" Moves: {len(moves)}, Last: {moves[-1].date if moves else 'None'}, Prorata Date: {asset.prorata_date}")
|
|
|
|
asset.unlink()
|
|
|
|
# Manual Test for 'none' with forced date
|
|
print(f"\nTesting prorata_computation_type: none (FORCED prorata_date)")
|
|
vals = {
|
|
'name': f'TEST Asset - Forced None',
|
|
'original_value': 48500000.0,
|
|
'acquisition_date': date(2024, 11, 1),
|
|
'prorata_date': date(2024, 11, 1), # Explicitly set
|
|
'model_id': model.id,
|
|
'method': 'linear',
|
|
'method_number': 60,
|
|
'method_period': '1',
|
|
'prorata_computation_type': 'none',
|
|
'state': 'draft',
|
|
'account_asset_id': model.account_asset_id.id,
|
|
'account_depreciation_id': model.account_depreciation_id.id,
|
|
'account_depreciation_expense_id': model.account_depreciation_expense_id.id,
|
|
'journal_id': model.journal_id.id,
|
|
}
|
|
asset = env['account.asset'].create(vals)
|
|
asset.compute_depreciation_board()
|
|
moves = asset.depreciation_move_ids.sorted('date')
|
|
print(f" Moves: {len(moves)}, Last: {moves[-1].date if moves else 'None'}, Prorata Date: {asset.prorata_date}")
|
|
asset.unlink()
|
|
|
|
if __name__ == "__main__":
|
|
main() |