from datetime import date from typing import Optional, List from dataclasses import dataclass, field from marshmallow import validate from campaign_ads.constants import PAGE_LIMIT_DEFAULT from campaigns.schemas import ( TerritoryResponseSchema, CampaignDetailsObjectiveResponseSchema, CampaignDetailsGenderResponseSchema, CampaignDetailsAudienceAgeResponseSchema, ) from config import TIMEZONE from constants.currency import DEFAULT_CURRENCY from models.campaign_ad import CampaignAd @dataclass class CampaignAdsQueryParams: freeText: Optional[str] = field(metadata={"validate": validate.Length(min=1, max=500)}) limit: Optional[int] = field(default=PAGE_LIMIT_DEFAULT, metadata={"validate": validate.Range(min=1)}) offset: Optional[int] = field(default=0, metadata={"validate": validate.Range(min=0)}) sort: Optional[str] = field(default="name") @dataclass class CampaignAdsExportParams(CampaignAdsQueryParams): timeZone: Optional[str] = field(default=TIMEZONE) @dataclass class CampaignAdsSchema: id: int name: str budgetSpend: float plannedBudget: float currency: str startDate: date endDate: Optional[date] territories: List[TerritoryResponseSchema] objective: CampaignDetailsObjectiveResponseSchema genders: List[CampaignDetailsGenderResponseSchema] platform: str destinationLinks: List[str] audienceAge: CampaignDetailsAudienceAgeResponseSchema def __init__(self, campaign_ad: CampaignAd, currency: str): self.id = campaign_ad.id self.name = campaign_ad.name self.budgetSpend = campaign_ad.budget_spend self.plannedBudget = campaign_ad.planned_budget self.startDate = campaign_ad.start_date self.endDate = campaign_ad.fallback_end_date self.platform = campaign_ad.platform self.territories = [ TerritoryResponseSchema(at.territory.id, at.territory.name) for at in campaign_ad.territories ] self.objective = CampaignDetailsObjectiveResponseSchema(campaign_ad.objective.id, campaign_ad.objective.name) self.genders = [CampaignDetailsGenderResponseSchema(gender.id, gender.name) for gender in campaign_ad.genders] self.audienceAge = CampaignDetailsAudienceAgeResponseSchema( campaign_ad.age_range.lower, campaign_ad.age_range.upper - 1 ) self.destinationLinks = [destination.link for destination in campaign_ad.links] if currency is not None: self.currency = currency else: self.currency = DEFAULT_CURRENCY @dataclass class CampaignAdsResponse: items: List[CampaignAdsSchema] limit: int offset: int total: int