from odoo import models class AccountMove(models.Model): _inherit = 'account.move' def _auto_create_asset(self): # We need to intercept standard behavior if we can link to an existing asset from Stock Move # This method iterates over self (invoices) and creates assets. # We can run the standard method, BUT standard method creates new assets. # We want to PREVENT creating new assets if one was already created by Stock Picking. # The standard method _auto_create_asset loops over invoice lines and creates assets. # It doesn't seem to have a hook to check for existing assets easily. # However, we can check if the invoice line is linked to a PO line, and that PO line linked to a Stock Move. # Strategy: # 1. Let standard create assets? No, duplicate. # 2. Override completely? risky for maintenance. # 3. Pre-process: if we find a link, set the asset_id on the move_line? # If `move_line.asset_ids` is set, `_auto_create_asset` might skip? # Checking standard code: # `and not move_line.asset_ids` -> YES! definition at line 188 of account_move.py. # So strategy is: # Before calling super, try to find existing asset and link it to move_line. for move in self: if move.is_invoice(): for line in move.invoice_line_ids: # check purchase line if line.purchase_line_id: # Find related stock moves # purchase_line_id.move_ids returns stock moves related_stock_moves = line.purchase_line_id.move_ids.filtered(lambda m: m.state == 'done' and m.asset_id) if related_stock_moves: # Link the first found asset asset = related_stock_moves[0].asset_id line.asset_ids = [(4, asset.id)] # Also update asset value if needed? # Usually creation from Stock might lack price if Price Unit was 0 or estimate. # But let's assume standard behavior: Link is enough. # Log connection asset.message_post(body=f"Linked to Vendor Bill: {move.name}") # Call super to generate new assets (if not linked above) created_assets = super(AccountMove, self)._auto_create_asset() # Post-process: Ensure Product ID is set and Asset Code is correct for asset in created_assets: # key: use sudo() to allow system to correct data even if user has no write access to asset # (e.g. Bill Clerk creating asset but not managing it) if not asset.product_id and asset.original_move_line_ids: # Find product from the first line # (Standard logic usually groups lines by account/product context, so one asset usually comes from one product type) product = asset.original_move_line_ids[0].product_id if product: asset.sudo().product_id = product.id # Fix Asset Code if it defaults to AST but product has barcode if asset.asset_code and asset.asset_code.startswith('AST') and product.barcode: # Replace 'AST' prefix with Barcode # Format is expected to be AST/YYYY/SEQ new_code = asset.asset_code.replace('AST', product.barcode, 1) asset.sudo().asset_code = new_code return created_assets