import sys import os import argparse from datetime import date, datetime def main(): parser = argparse.ArgumentParser(description="Post Draft Depreciation Entries in Odoo") 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") parser.add_argument("--date", help="Post entries up to this date (YYYY-MM-DD). Defaults to today.", default=None) 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 if args.date: try: post_up_to_date = datetime.strptime(args.date, '%Y-%m-%d').date() except ValueError: print("Error: Date must be in YYYY-MM-DD format.") sys.exit(1) else: post_up_to_date = date.today() # 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 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) post_depreciation(db_name, conf_path, post_up_to_date) def post_depreciation(db_name, conf_file, post_up_to_date): print(f"Initializing Odoo Environment for database: {db_name}...") try: import odoo from odoo import api, SUPERUSER_ID odoo.tools.config.parse_config(['-c', conf_file]) 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.") # Search for Draft Depreciation MOVES (account.move) # Linked to an asset, in draft state, date <= target date moves_to_post = env['account.move'].search([ ('asset_id', '!=', False), ('state', '=', 'draft'), ('date', '<=', post_up_to_date) ]) if not moves_to_post: print(f"No draft depreciation entries found on or before {post_up_to_date}.") return print(f"Found {len(moves_to_post)} moves to post up to {post_up_to_date}.") # Group by date for nicer logging moves_by_date = {} for move in moves_to_post: d = move.date if d not in moves_by_date: moves_by_date[d] = [] moves_by_date[d].append(move) count = 0 try: for d in sorted(moves_by_date.keys()): batch = moves_by_date[d] batch_moves = env['account.move'].browse([m.id for m in batch]) print(f"Posting {len(batch)} entries for date {d}...") batch_moves.action_post() count += len(batch) cr.commit() print(f"Successfully posted {count} depreciation entries.") except Exception as e: cr.rollback() print(f"An error occurred. Transaction rolled back.\nError: {e}") import traceback traceback.print_exc() if __name__ == "__main__": main()