"""Asset operations shared by web forms and the REST API.""" from fastapi import HTTPException from database import connect, ensure_asset, validate_asset from models import name_key def list_assets(active=None): with connect() as db: if active is None: rows = db.execute('SELECT * FROM assets ORDER BY name COLLATE NOCASE').fetchall() else: rows = db.execute('SELECT * FROM assets WHERE active=? ORDER BY name COLLATE NOCASE', (active,)).fetchall() return [dict(row) for row in rows] def _get_asset(db, asset_id): if not 1 <= asset_id <= 9223372036854775807: raise HTTPException(404, 'Position nicht gefunden.') row = db.execute('SELECT * FROM assets WHERE id=?', (asset_id,)).fetchone() if row is None: raise HTTPException(404, 'Position nicht gefunden.') return dict(row) def get_asset(asset_id): with connect() as db: return _get_asset(db, asset_id) def create_asset(name, asset_type='other', ticker=None, active=True, reuse=False): name, ticker = validate_asset(name, asset_type, ticker) with connect() as db: db.execute('BEGIN IMMEDIATE') existing = db.execute('SELECT * FROM assets WHERE normalized_name=?', (name_key(name),)).fetchone() if existing: if reuse: return dict(existing) raise HTTPException(409, 'Diese Position existiert bereits.') asset_id = ensure_asset(db, name, asset_type, ticker) db.execute('UPDATE assets SET active=? WHERE id=?', (bool(active), asset_id)) return _get_asset(db, asset_id) def update_asset(asset_id, changes): with connect() as db: db.execute('BEGIN IMMEDIATE') data = _get_asset(db, asset_id) data.update(changes) name, ticker = validate_asset(data['name'], data['asset_type'], data['ticker']) if db.execute('SELECT 1 FROM assets WHERE normalized_name=? AND id<>?', (name_key(name), asset_id)).fetchone(): raise HTTPException(409, 'Diese Position existiert bereits.') db.execute('UPDATE assets SET name=?, normalized_name=?, ticker=?, asset_type=?, active=? WHERE id=?', (name, name_key(name), ticker, data['asset_type'], bool(data['active']), asset_id)) return _get_asset(db, asset_id) def deactivate_asset(asset_id): # Preserve references and history even when an asset has no payments yet. return update_asset(asset_id, {'active': False})