""" Event Calendar Models Database models for tracking local events, promotions, and special occasions """ from sqlalchemy import Column, Integer, String, DateTime, Text, Boolean, Float, Date from sqlalchemy.dialects.postgresql import UUID from shared.database.base import Base from datetime import datetime, timezone import uuid class Event(Base): """ Table to track events that affect bakery demand. Events include: - Local events (festivals, markets, concerts) - Promotions and sales - Weather events (heat waves, storms) - School holidays and breaks - Special occasions """ __tablename__ = "events" # Primary identification id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True) # Event information event_name = Column(String(500), nullable=False) event_type = Column(String(100), nullable=False, index=True) # promotion, festival, holiday, weather, school_break, sport_event, etc. description = Column(Text, nullable=True) # Date and time event_date = Column(Date, nullable=False, index=True) start_time = Column(DateTime(timezone=True), nullable=True) end_time = Column(DateTime(timezone=True), nullable=True) is_all_day = Column(Boolean, default=True) # Impact estimation expected_impact = Column(String(50), nullable=True) # low, medium, high, very_high impact_multiplier = Column(Float, nullable=True) # Expected demand multiplier (e.g., 1.5 = 50% increase) affected_product_categories = Column(String(500), nullable=True) # Comma-separated categories # Location location = Column(String(500), nullable=True) is_local = Column(Boolean, default=True) # True if event is near bakery # Status is_confirmed = Column(Boolean, default=False) is_recurring = Column(Boolean, default=False) recurrence_pattern = Column(String(200), nullable=True) # e.g., "weekly:monday", "monthly:first_saturday" # Actual impact (filled after event) actual_impact_multiplier = Column(Float, nullable=True) actual_sales_increase_percent = Column(Float, nullable=True) # Metadata created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) created_by = Column(String(255), nullable=True) notes = Column(Text, nullable=True) def to_dict(self): return { "id": str(self.id), "tenant_id": str(self.tenant_id), "event_name": self.event_name, "event_type": self.event_type, "description": self.description, "event_date": self.event_date.isoformat() if self.event_date else None, "start_time": self.start_time.isoformat() if self.start_time else None, "end_time": self.end_time.isoformat() if self.end_time else None, "is_all_day": self.is_all_day, "expected_impact": self.expected_impact, "impact_multiplier": self.impact_multiplier, "affected_product_categories": self.affected_product_categories, "location": self.location, "is_local": self.is_local, "is_confirmed": self.is_confirmed, "is_recurring": self.is_recurring, "recurrence_pattern": self.recurrence_pattern, "actual_impact_multiplier": self.actual_impact_multiplier, "actual_sales_increase_percent": self.actual_sales_increase_percent, "created_at": self.created_at.isoformat() if self.created_at else None, "updated_at": self.updated_at.isoformat() if self.updated_at else None, "created_by": self.created_by, "notes": self.notes } class EventTemplate(Base): """ Template for recurring events. Allows easy creation of events based on patterns. """ __tablename__ = "event_templates" # Primary identification id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True) # Template information template_name = Column(String(500), nullable=False) event_type = Column(String(100), nullable=False) description = Column(Text, nullable=True) # Default values default_impact = Column(String(50), nullable=True) default_impact_multiplier = Column(Float, nullable=True) default_affected_categories = Column(String(500), nullable=True) # Recurrence recurrence_pattern = Column(String(200), nullable=False) # e.g., "weekly:saturday", "monthly:last_sunday" is_active = Column(Boolean, default=True) # Metadata created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) def to_dict(self): return { "id": str(self.id), "tenant_id": str(self.tenant_id), "template_name": self.template_name, "event_type": self.event_type, "description": self.description, "default_impact": self.default_impact, "default_impact_multiplier": self.default_impact_multiplier, "default_affected_categories": self.default_affected_categories, "recurrence_pattern": self.recurrence_pattern, "is_active": self.is_active, "created_at": self.created_at.isoformat() if self.created_at else None, "updated_at": self.updated_at.isoformat() if self.updated_at else None }