"""Base model class with common fields.""" from datetime import datetime, timezone from shopdb.extensions import db def _utcnow(): # naive UTC for DB columns (stored without tzinfo) return datetime.now(timezone.utc).replace(tzinfo=None) class BaseModel(db.Model): """ Abstract base model with common fields. All models should inherit from this. """ __abstract__ = True createddate = db.Column( db.DateTime, default=_utcnow, nullable=False ) modifieddate = db.Column( db.DateTime, default=_utcnow, onupdate=_utcnow, nullable=False ) isactive = db.Column(db.Boolean, default=True, nullable=False) def to_dict(self): """Convert model to dictionary.""" result = {} for c in self.__table__.columns: value = getattr(self, c.name) if isinstance(value, datetime): value = value.isoformat() + 'Z' result[c.name] = value return result def update(self, **kwargs): """Update model attributes.""" for key, value in kwargs.items(): if hasattr(self, key): setattr(self, key, value) @classmethod def get_active(cls): """Return query for active records only.""" return cls.query.filter_by(isactive=True) class SoftDeleteMixin: """Mixin for soft delete functionality.""" deleteddate = db.Column(db.DateTime, nullable=True) deletedby = db.Column(db.String(100), nullable=True) def soft_delete(self, deleted_by: str = None): """Mark record as deleted.""" self.isactive = False self.deleteddate = datetime.now(timezone.utc).replace(tzinfo=None) self.deletedby = deleted_by class AuditMixin: """Mixin for audit fields.""" createdby = db.Column(db.String(100), nullable=True) modifiedby = db.Column(db.String(100), nullable=True)