"""Model for marketing_driver table in sales_goals database.""" from datetime import datetime from oto import response from sqlalchemy import Column from sqlalchemy import DateTime from sqlalchemy import ForeignKey from sqlalchemy import func from sqlalchemy import Integer from sqlalchemy import String from sqlalchemy import Text from sales_goals.connectors import mysql from sales_goals.constants import error from sales_goals.constants import models from sales_goals.logic import countries from sales_goals.models import error_handlers class MarketingDriver(mysql.BaseModel): """Class representing the sales goal's marketing driver entity.""" __tablename__ = 'marketing_driver' marketing_driver_id = Column( 'id', Integer, primary_key=True, autoincrement=True) project_id = Column(Integer, nullable=False) value = Column(Text) slogan = Column(Text) country_id = Column(Integer, nullable=False) country_name = Column(String, nullable=False) def to_dict(self): """Return object as dict. Returns: dict: Dictionary representation of object """ marketing_driver_dict = { 'marketing_driver_id': self.marketing_driver_id, 'project_id': self.project_id, 'value': self.value, 'slogan': self.slogan, 'country_id': self.country_id, 'country_name': self.country_name } return marketing_driver_dict class DigitalStore(mysql.BaseModel): """Class representing the digital stores.""" __tablename__ = 'digital_stores' digital_store_id = Column( 'id', Integer, primary_key=True, autoincrement=True) store = Column(String, nullable=False) customer_master_master_id = Column(Integer, nullable=False) def to_dict(self): """Return object as dict. Returns: dict: Dictionary representation of object """ return { 'id': self.digital_store_id, 'store': self.store, 'customer_master_master_id': self.customer_master_master_id } class DigitalStoreHighlight(mysql.BaseModel): """Class representing the digital stores.""" __tablename__ = 'digital_store_highlights' highlight_id = Column( 'id', Integer, primary_key=True, autoincrement=True) project_id = Column(Integer, nullable=False) store_id = Column( Integer, ForeignKey('digital_stores.id'), nullable=False) value = Column(String, nullable=False) def to_dict(self): """Return object as dict. Returns: dict: Dictionary representation of object """ return { 'id': self.highlight_id, 'project_id': self.project_id, 'store_id': self.store_id, 'value': self.value, } class GlobalMarketingDriver(mysql.BaseModel): """Class representing the sales goal's marketing driver entity.""" __tablename__ = 'mkt_program_info' mkt_program_info_id = Column( Integer, primary_key=True, autoincrement=True) description = Column(Text) info_for = Column(String, nullable=False) mkt_program_id = Column(Integer, nullable=False) info_for_id = Column(Integer, nullable=False) subject = Column(String, nullable=False) client = Column(String, nullable=False) attachment = Column(String, nullable=False) scope = Column(String, nullable=False) date_added = Column(DateTime, nullable=False) last_updated = Column(DateTime, nullable=False) def to_dict(self): """Return object as dict. Returns: dict: Dictionary representation of object """ return { 'mkt_program_info_id': self.mkt_program_info_id, 'description': self.description, 'info_for': self.info_for, 'mkt_program_id': self.mkt_program_id, 'info_for_id': self.info_for_id, 'subject': self.subject, 'client': self.client, 'attachment': self.attachment, 'scope': self.scope, 'date_added': self.date_added.isoformat() if self.date_added else None, 'last_updated': self.last_updated.isoformat() if self.last_updated else None, } @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def fetch_global_marketing_driver(project_id, program_id): """Get marketing drivers data from art relations by project id. Args: project_id (int): project id of marketing driver. program_id (int): mkt_program_id to use for the marketing driver. Returns: GlobalMarketingDriver: marketing driver """ with mysql.art_relations_session_scope() as session: return session.query(GlobalMarketingDriver).filter_by( mkt_program_id=program_id, info_for_id=project_id, info_for=models.INFO_FOR_PROJECT ).first() @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def fetch_marketing_drivers(project_id): """Get marketing drivers data by project id. Args: project_id (int): project id of marketing driver. """ with mysql.sales_goals_session_scope() as session: return session.query(MarketingDriver).filter_by( project_id=project_id, ).all() @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def fetch_marketing_driver(project_id, territory_id): """Get marketing drivers data by project id. Args: project_id (int): project id of marketing driver. """ with mysql.sales_goals_session_scope() as session: return session.query(MarketingDriver).filter_by( project_id=project_id, country_id=territory_id, ).first() @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def fetch_digital_marketing_driver(project_id, store_id): """Get marketing drivers data by project id. Args: project_id (int): project id of marketing driver. """ with mysql.sales_goals_session_scope() as session: return session.query(DigitalStoreHighlight).filter_by( project_id=project_id, store_id=store_id, ).first() @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def fetch_digital_marketing_drivers(project_id): """Get marketing drivers data by project id. Args: project_id (int): project id of marketing driver. """ with mysql.sales_goals_session_scope() as session: return session.query(DigitalStoreHighlight, DigitalStore).filter_by( project_id=project_id, ).join(DigitalStore).all() @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def fetch_digital_store_by_name(store): """Get store by store name. Args: store (str): Store name """ with mysql.sales_goals_session_scope() as session: return session.query(DigitalStore).filter( func.lower(DigitalStore.store) == store, ).first() @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def upsert_global_marketing_driver(project_id, highlight_text): """Create or update global marketing driver. Args: project_id (int): project id of marketing driver. highlight_text (str): the marketing text Returns: None """ marketing_driver = fetch_global_marketing_driver( project_id, models.MARKETING_HIGHLIGHTS_ID) with mysql.art_relations_session_scope() as session: now = datetime.utcnow() if not marketing_driver: marketing_driver = GlobalMarketingDriver( subject=models.MARKETING_HIGHLIGHT_SUBJECT, client=models.CLIENT, date_added=now, last_updated=now, description=highlight_text, mkt_program_id=models.MARKETING_HIGHLIGHTS_ID, info_for_id=project_id, info_for=models.INFO_FOR_PROJECT, attachment=models.NO_ATTACHMENT, scope=models.PUBLIC_SCOPE, ) else: marketing_driver.description = highlight_text marketing_driver.last_updated = now session.add(marketing_driver) @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def upsert_global_sync_driver(project_id, sync_highlight_text): """Create or update global marketing driver. Args: project_id (int): project id of marketing driver. sync_highlight_text (str): the marketing text Returns: None """ marketing_driver = fetch_global_marketing_driver( project_id, models.SYNC_HIGHLIGHTS_ID) with mysql.art_relations_session_scope() as session: now = datetime.utcnow() if not marketing_driver: marketing_driver = GlobalMarketingDriver( subject=models.SYNC_HIGHLIGHT_SUBJECT, client=models.CLIENT, date_added=now, last_updated=now, description=sync_highlight_text, mkt_program_id=models.SYNC_HIGHLIGHTS_ID, info_for_id=project_id, info_for=models.INFO_FOR_PROJECT, attachment=models.NO_ATTACHMENT, scope=models.PUBLIC_SCOPE, ) else: marketing_driver.description = sync_highlight_text marketing_driver.last_updated = now session.add(marketing_driver) @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def upsert_marketing_driver( project_id, territory_id, highlight_text, slogan=None): """Create or update territory marketing driver. Args: project_id (int): project id of marketing driver. territory_id (int): territory id of marketing driver. highlight_text (str): the marketing text. slogan (str): The marketing slogan. Returns: None """ marketing_driver = fetch_marketing_driver(project_id, territory_id) with mysql.sales_goals_session_scope() as session: if not marketing_driver: country_name = countries.get_country_name_from_id(territory_id) marketing_driver = MarketingDriver( project_id=project_id, value=highlight_text, slogan=slogan, country_id=territory_id, country_name=country_name, ) else: marketing_driver.value = highlight_text marketing_driver.slogan = slogan session.add(marketing_driver) @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def delete_marketing_driver(project_id, territory_id): """Delet marketing driver data. Args: project_id (int): project id of marketing driver. territory_id (int): territory id of marketing driver. """ with mysql.sales_goals_session_scope() as session: driver = session.query(MarketingDriver).filter_by( project_id=project_id, country_id=territory_id ).first() if not driver: return response.create_not_found_response() session.delete(driver) return response.Response() @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def bulk_delete_marketing_drivers(project_id, country_ids): """Bulk Delete marketing driver data. Args: project_id (int): project id of marketing driver. country_ids (list): list of territory ids of marketing drivers. """ with mysql.sales_goals_session_scope() as session: session.query( MarketingDriver ).filter( MarketingDriver.project_id == int(project_id) ).filter( MarketingDriver.country_id.in_(country_ids) ).delete() @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def upsert_digital_marketing_driver(project_id, store, highlight_text): """Create or update territory marketing driver. Args: project_id (int): project id of marketing driver. store (str): store of marketing driver. highlight_text (str): the marketing text Returns: None """ store = fetch_digital_store_by_name(store) marketing_driver = fetch_digital_marketing_driver( project_id, store.digital_store_id) with mysql.sales_goals_session_scope() as session: if not marketing_driver: marketing_driver = DigitalStoreHighlight( project_id=project_id, value=highlight_text, store_id=store.digital_store_id, ) else: marketing_driver.value = highlight_text session.add(marketing_driver) @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def create_marketing_program_info(data): """Create marketing program info.""" result = None with mysql.art_relations_session_scope() as session: now = datetime.utcnow() marketing_driver = GlobalMarketingDriver( subject=data.get('subject'), client=data['client'], date_added=now, last_updated=now, description=data['description'], mkt_program_id=data['mkt_program_id'], info_for_id=data['info_for_id'], info_for=data['info_for'], attachment=data.get('attachment') or models.NO_ATTACHMENT, scope=data.get('scope') or models.PUBLIC_SCOPE, ) session.add(marketing_driver) result = marketing_driver return result.to_dict() if result else None @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def get_marketing_program_info(**kwargs): """Get marketing program info.""" if not kwargs.get('info_for') and not kwargs.get('info_for_id'): raise IndexError('Marketing program info entity ID and type required.') with mysql.art_relations_session_scope() as session: filters = { 'info_for': kwargs.get('info_for'), 'info_for_id': kwargs.get('info_for_id'), } if kwargs.get('mkt_program_id'): filters['mkt_program_id'] = kwargs.get('mkt_program_id') result = session.query( GlobalMarketingDriver).filter_by(**filters).all() return [row.to_dict() for row in result] @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def update_marketing_program_info(marketing_program_info_id, data): """Update marketing program info. Args: marketing_program_info_id (int): Marketing program info ID data (dict): Marketing program info data Returns: bool """ result = None with mysql.art_relations_session_scope() as session: marketing_program_info = session.query( GlobalMarketingDriver).filter_by( mkt_program_info_id=marketing_program_info_id).first() if not marketing_program_info: raise LookupError( f'Marketing program info ' f'{marketing_program_info_id} not found.') marketing_program_info.description = data['description'] marketing_program_info.subject = data.get('subject') marketing_program_info.client = data['client'] marketing_program_info.mkt_program_id = data['mkt_program_id'] marketing_program_info.info_for = data['info_for'] marketing_program_info.info_for_id = data['info_for_id'] marketing_program_info.attachment = data.get('attachment') or models.NO_ATTACHMENT marketing_program_info.scope = data.get('scope') or models.PUBLIC_SCOPE session.add(marketing_program_info) result = marketing_program_info return result.to_dict() if result else None @error_handlers.sqlalchemy_error_handler @error_handlers.integrity_error_handler( error_code=error.ERROR_CODE_MODEL_VALIDATION) def delete_marketing_program_infos(marketing_program_info_ids): """Delete marketing program info. Args: marketing_program_info_ids (list): ids to delete. """ with mysql.art_relations_session_scope() as session: session.query( GlobalMarketingDriver ).filter( GlobalMarketingDriver.mkt_program_info_id.in_( marketing_program_info_ids ) ).delete()