import sys import os import argparse from datetime import date def main(): parser = argparse.ArgumentParser(description="Post Missing Depreciation Entries for Running Assets") 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 # The odoo package is located inside the directory containing odoo-bin odoo_dir = os.path.dirname(odoo_bin_path) if odoo_dir not in sys.path: sys.path.insert(0, odoo_dir) # Change CWD to config directory to handle relative paths in config 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_dir}. 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.") process_assets(env) # Determine if we should commit # (For safety, we could add a --dry-run flag, but for now we commit) cr.commit() print("Changes committed to database.") def process_assets(env): # Find all OPEN (Running) assets assets = env['account.asset'].search([('state', '=', 'open')]) print(f"Found {len(assets)} running assets.") count_assets_fixed = 0 count_moves_posted = 0 for asset in assets: # Find draft moves for this asset UP TO TODAY # Future moves are handled by Odoo's auto_post cron today = date.today() moves_to_post = asset.depreciation_move_ids.filtered(lambda m: m.state == 'draft' and m.date <= today) if not moves_to_post: continue print(f"Asset '{asset.name}' has {len(moves_to_post)} draft moves. Posting...") # Post them moves_to_post._post() count_assets_fixed += 1 count_moves_posted += len(moves_to_post) # Also ensure FUTURE draft moves are set to auto_post='at_date' future_moves = asset.depreciation_move_ids.filtered(lambda m: m.state == 'draft' and m.date > today) if future_moves: future_moves.write({'auto_post': 'at_date'}) print(f"\nSummary:") print(f" Assets processed: {len(assets)}") print(f" Assets updated: {count_assets_fixed}") print(f" Moves posted: {count_moves_posted}") if __name__ == "__main__": main()