""" Category Model SQLAlchemy model for transaction categories. Handles categorization of financial transactions. """ from datetime import datetime from app.extensions import db class Category(db.Model): """ Category model for organizing transactions. Attributes: id (int): Primary key name (str): Category name (unique) description (str): Optional description color (str): Hex color code for UI representation is_active (bool): Whether category is active created_at (datetime): Creation timestamp """ __tablename__ = 'categories' # Primary key id = db.Column(db.Integer, primary_key=True) # Category information name = db.Column(db.String(100), nullable=False, unique=True) description = db.Column(db.Text) color = db.Column(db.String(7)) # Hex color code (#FFFFFF) is_active = db.Column(db.Boolean, default=True, nullable=False) # Timestamps created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) # Relationships transactions = db.relationship('Transaction', backref='category', lazy=True) def __repr__(self): """String representation of Category.""" return f'' def to_dict(self): """Convert category to dictionary for JSON serialization.""" return { 'id': self.id, 'name': self.name, 'description': self.description, 'color': self.color, 'is_active': self.is_active, 'created_at': self.created_at.isoformat() if self.created_at else None } def get_transaction_count(self): """Get transaction count without loading all transactions.""" from app.models.transaction import Transaction return db.session.query(Transaction).filter_by(category_id=self.id).count() @classmethod def get_categories_with_counts(cls): """Get categories with transaction counts efficiently.""" from app.models.transaction import Transaction return db.session.query( cls, db.func.count(Transaction.id).label('transaction_count') ).outerjoin(Transaction).group_by(cls.id).all() @classmethod def get_active_categories(cls): """Get all active categories.""" return cls.query.filter_by(is_active=True).all() @classmethod def find_by_name(cls, name): """Find category by name.""" return cls.query.filter_by(name=name).first()