from typing import Type from sqlalchemy import func from db import db from sqlalchemy.dialects import postgresql from models.mixins.searchable import SearchableMixin class CampaignAd(SearchableMixin, db.Model): __tablename__ = "CampaignAd" __searchable__ = { "name": {"type": "text", "analyzer": "autocomplete", "search_analyzer": "standard"}, "platform": {"type": "text", "analyzer": "autocomplete", "search_analyzer": "standard"}, "objective_name": {"type": "text", "analyzer": "autocomplete", "search_analyzer": "standard"}, } id = db.Column(db.BigInteger, primary_key=True) external_id = db.Column(db.String, unique=True, nullable=True) name = db.Column(db.String, nullable=False) start_date = db.Column(db.Date, nullable=False) end_date = db.Column(db.Date, nullable=True) planned_budget = db.Column(db.Numeric(12, 2), nullable=False) budget_spend = db.Column(db.Numeric(12, 2), nullable=True) is_deleted = db.Column(db.Boolean, nullable=False, server_default="FALSE") age_range = db.Column(postgresql.INT4RANGE, nullable=False) objective_id = db.Column(db.Integer, db.ForeignKey("CampaignObjective.id"), nullable=False) campaign_id = db.Column(db.BigInteger, db.ForeignKey("Campaign.id", ondelete="CASCADE"), nullable=True) currency_id = db.Column(db.Integer, db.ForeignKey("Currency.id"), nullable=True) platform = db.Column(db.String, nullable=False) created_at = db.Column(db.TIMESTAMP(timezone=True), nullable=False, server_default=func.current_timestamp()) updated_at = db.Column(db.TIMESTAMP(timezone=True), nullable=False, server_default=func.current_timestamp()) campaign = db.relationship("Campaign", back_populates="ad_set") territories = db.relationship("CampaignAdTerritory", back_populates="campaign_ad") objective = db.relationship("CampaignObjective") genders = db.relationship("Gender", secondary="CampaignAdGender") links = db.relationship("CampaignAdLink", cascade="all, delete-orphan") @property def objective_name(self) -> str: return self.objective.name @property def fallback_end_date(self): return self.end_date or self.campaign.fallback_end_date @classmethod def es_query(cls: Type[db.Model]): return cls.query campaign_ad_gender = db.Table( "CampaignAdGender", db.Model.metadata, db.Column("campaign_ad_id", db.Integer, db.ForeignKey("CampaignAd.id", ondelete="CASCADE"), nullable=False), db.Column("gender_id", db.Integer, db.ForeignKey("Gender.id", ondelete="CASCADE"), nullable=False), ) class CampaignAdTerritory(db.Model): __tablename__ = "CampaignAdTerritory" campaign_ad_id = db.Column( db.BigInteger, db.ForeignKey("CampaignAd.id", ondelete="CASCADE"), nullable=False, primary_key=True ) territory_id = db.Column( db.Integer, db.ForeignKey("Territory.id", ondelete="CASCADE"), nullable=False, primary_key=True ) campaign_ad = db.relationship("CampaignAd", back_populates="territories") territory = db.relationship("Territory") class CampaignAdLink(db.Model): __tablename__ = "CampaignAdLink" id = db.Column(db.Integer, primary_key=True, autoincrement=True) campaign_ad_id = db.Column(db.Integer, db.ForeignKey("CampaignAd.id", ondelete="CASCADE"), nullable=False) link = db.Column(db.String, nullable=False) __table_args__ = (db.UniqueConstraint("campaign_ad_id", "link", name="_campaign_ad_id_link_uc"),) campaign_ad = db.relationship("CampaignAd")