from typing import List from models.campaign_provider import Providers from db import db from campaigns.schemas import CampaignEditableFields, CampaignMetadata from services.users_repository import UsersRepository from utils.json_encoder import DataclassDictionaryEncoder as Encoder from utils import list_utils from utils.snowflake.google_data.models import GoogleCampaignModel from utils.snowflake.google_data.utils import GoogleWorkerUtils from utils.reporting.worker_logger import WorkerLogger from models import Campaign from models.projects import ProjectCampaign from campaigns.repositories.campaigns_repository import CampaignsRepository from campaigns.services.campaigns_history_service import CampaignHistoryService from projects.repositories.projects_repository import ProjectsRepository from linkfire.linkfire_repository import LinkfireRepository from workers.base_worker import BaseWorker from workers import helpers class GoogleCampaignsWorker(BaseWorker): campaigns_repository: CampaignsRepository = CampaignsRepository() projects_repository: ProjectsRepository = ProjectsRepository() users_repository: UsersRepository = UsersRepository() linkfire_repository: LinkfireRepository = LinkfireRepository() history_service: CampaignHistoryService = CampaignHistoryService() utils: GoogleWorkerUtils = GoogleWorkerUtils() logger: WorkerLogger = WorkerLogger() def execute(self, campaigns: List[GoogleCampaignModel]): mapped_campaigns = [] for campaign in campaigns: mapped_campaigns.append(self.process_campaign(campaign)) db.session.commit() Campaign.index_models(mapped_campaigns) db.session.close() def process_campaign(self, campaign: GoogleCampaignModel) -> Campaign: gras_user_id = self.users_repository.get_gras_user_id() projects = self.get_possible_projects(campaign) google_campaign = self.campaigns_repository.get_campaign_by_external_id(str(campaign.id)) links = self.utils.build_campaign_links(campaign.links) genders = self.utils.build_gender_ids(campaign.genders) fields_object = CampaignEditableFields() fields_object.countries = campaign.territories == [self.utils.global_territory_id] fields_object.audienceAge = campaign.ages is None fields_object.startDate = campaign.start_date is None fields_object.endDate = campaign.end_date is None fields_object.destinations = len(campaign.links) == 0 fields_object.budget = not bool(campaign.budget) fields_object.spend = False fields_object.genders = genders is None fields_object.notes = True fields_object.name = False fields_object.provider = False fields_object.objective = False fields_object.campaignTypes = False is_new = False state = None if not google_campaign: google_campaign = Campaign() google_campaign.external_id = campaign.id is_new = True else: state = self.history_service.get_campaign_state(google_campaign) if campaign.linkfire_links: self.linkfire_repository.import_linkfire_campaign_links(google_campaign, campaign.linkfire_links) if not google_campaign.project_id: for project in projects: already_assigned = list_utils.exists( project.project_campaigns, lambda x: x.campaign.external_id == str(campaign.id) ) if not already_assigned: project_campaign = ProjectCampaign() project_campaign.project = project project_campaign.campaign = google_campaign project.project_campaigns.append(project_campaign) provider_id = self.campaigns_repository.provider_id_for_account(campaign.account) campaign_type, platform_names = self.utils.get_campaign_platforms(campaign.types) platforms = self.campaigns_repository.get_campaign_platforms_by_names(platform_names) budget = campaign.budget or 0 google_campaign.name = campaign.name google_campaign.start_date = campaign.start_date google_campaign.end_date = campaign.end_date google_campaign.planned_budget = budget google_campaign.budget_spend = campaign.spend google_campaign.external_marketing_account_id = campaign.account google_campaign.objective_id = self.utils.build_objective(campaign.bidding_type) google_campaign.provider_id = provider_id or Providers.GuptaMedia.value google_campaign.age_range = self.utils.build_age_range(campaign.ages) google_campaign.genders = self.campaigns_repository.get_campaign_genders_by_ids( genders or self.utils.all_genders ) google_campaign.source = self.utils.source_name google_campaign.metainfo = Encoder.convert_to_dict(CampaignMetadata(fields=fields_object)) google_campaign.platforms.extend(platforms) google_campaign.gratis = False google_campaign.type = self.campaigns_repository.get_campaign_type_by_name(campaign_type) self.campaigns_repository.safe_update_campaign_links(google_campaign, links) self.campaigns_repository.update_campaign_territories( campaign=google_campaign, territories=self.utils.map_territories(campaign.territories), budget_spend=budget ) db.session.flush() db.session.refresh(google_campaign) if is_new: self.history_service.log_campaign_created(google_campaign, None, gras_user_id) else: self.history_service.log_campaign_changes(google_campaign, state, gras_user_id) return google_campaign def get_possible_projects(self, campaign: GoogleCampaignModel): projects = [] currency = self.campaigns_repository.get_currency_for_marketing_account(campaign.account) prs_code = helpers.prs_id_from_campaign_name(campaign.name) if prs_code is not None: prs_project = self.projects_repository.get_project_by_PRS_id(prs_code, currency) projects.append(prs_project) elif helpers.is_name_includes_external_id(campaign.name): external_id = helpers.get_campaign_name_first_part(campaign.name) projects = self.projects_repository.get_projects_by_GRAS_id(external_id, currency) if len(projects) == 0: projects = self.projects_repository.get_projects_with_artists( campaign.artists, campaign.start_date, str(campaign.account), currency ) return projects