"""Template renderer. Renders jinja templates with the given data """ from datetime import timedelta from jinja2 import Environment from jinja2 import FileSystemLoader from jinja2.exceptions import TemplateNotFound from oto import response from salessheets import config from salessheets.connectors.sentry import sentry_capture_exception from salessheets.constants import errors from salessheets.constants import field_const from salessheets.constants import localized_template from salessheets.constants import pdf from salessheets.utils import misc class TemplateNotFoundException(Exception): """Raise when Jinja template was not found.""" def render_template(template_name, data_from_db): """ Provide rendering of jinja-template. Args: template_name (str): template name with extension data_from_db (dict): all the data from database which will be used for template rendering Returns: Response: Response with rendered template which is of type str. """ try: env = Environment(loader=FileSystemLoader(config.TEMPLATE_PATH)) template = env.get_template(template_name) rendered_template = template.render(**data_from_db) return response.Response(rendered_template) except TemplateNotFound as e: error = response.create_error_response( code=errors.ERROR_FINDING_TEMPLATE, message=e.message ) if sentry_capture_exception: sentry_capture_exception() return error def compose_artist_name(artist_name_list): """ Compose name of artist depending on the number of names in it. Args: artist_name_list (list): list of strings, i.e. artist names Returns: str: name of the artist """ artist_name = '' if len(artist_name_list) > 1: for name in artist_name_list: artist_name += name + ', ' artist_name = artist_name[:-2] elif len(artist_name_list) == 1: artist_name = artist_name_list[0] return artist_name def extract_global_sync_highlights(marketing_highlights): """ Extract global sync highlights from marketing highlights. Args: marketing_highlights (list): list of dict Returns: str: global sync highlights description """ global_sync_highlights = '' for marketing_highlight in marketing_highlights: if marketing_highlight['subject'] == 'Project Sync Highlights': global_sync_highlights = marketing_highlight['description'] return global_sync_highlights def prepare_template_data(data_from_db): """ Prepare db data for rendering template. Extends data from db with hardcoded data, format dates and text fields. Args: data_from_db (dict): data from db. Returns: Response: prepared data. """ try: patch_data_for_non_redessent_vendor(data_from_db) data_from_db[field_const.ARTIST_NAME] = compose_artist_name( data_from_db[field_const.ARTIST_LIST]) data_from_db[field_const.SALE_START_DATE] = misc.datetime_to_str( data_from_db[field_const.SALE_START_DATE]) if ( data_from_db[field_const.SALE_START_DATE]) else '' data_from_db[field_const.DESCRIPTION] = misc.split_text_in_paragraphs( data_from_db[field_const.DESCRIPTION]) track_count = 0 for disc, sides in data_from_db['track_list'].items(): for side, tracks in sides.items(): track_count = track_count + len(tracks) data_from_db['track_count'] = track_count template_details_data = data_from_db[field_const.TEMPLATE_DETAILS_DATA] template_details_id = template_details_data[ field_const.LOCALIZED_TEMPLATE_TYPE_ID] if template_details_id == ( localized_template.TEMPLATE_DETAILS_IDS[ localized_template.SME_CAN]): data_from_db.pop(field_const.ORDER_DUE_DATE, None) data_from_db.pop(field_const.BOX_LOT, None) data_from_db.pop(field_const.PRODUCT_CODE, None) edition = data_from_db.get(field_const.EDITION) if edition: data_from_db[field_const.EDITION] = \ field_const.EDITION_DISPLAY_VALUES[edition] mkt_highlights = data_from_db.get(field_const.MARKETING_HIGHLIGHTS) if mkt_highlights: data_from_db[field_const.GLOBAL_SYNC_HIGHLIGHTS] = \ extract_global_sync_highlights(mkt_highlights) sales_goals = data_from_db.get(field_const.SALES_GOALS) if sales_goals: data_from_db[field_const.JAPAN_SLOGAN] = find_japan_slogan( sales_goals) return response.Response(misc.cleanup_dict(data_from_db)) except misc.EmptyDateException as e: error = response.create_error_response( code=errors.ERROR_CONVERTING_DATE, message=e.message ) if sentry_capture_exception: sentry_capture_exception() return error except (TypeError, KeyError) as e: error = response.create_error_response( code=errors.ERROR_PDF_GENERATION_CODE, message=e.message ) if sentry_capture_exception: sentry_capture_exception() return error def patch_data_for_non_redessent_vendor(data_from_db): """ Update data when sales sheets 2.0 feature flag == True. When feature flag is enabled, data_from_db should be patched with additional fields if vendor owner is not Red Essential. Args: data_from_db (dict): contains data form db. """ product_info_sale_start_date = '' order_due_date = '' if data_from_db.get(field_const.SALE_START_DATE, ''): product_info_sale_start_date = misc.datetime_to_str( data_from_db[field_const.SALE_START_DATE], pdf.ORCHARD_DATE_FORMAT) order_due_date = ( misc.datetime_to_str(( data_from_db[field_const.SALE_START_DATE] - timedelta(days=config.ORDER_DUE_DATE_TIMEDELTA)), pdf.ORCHARD_DATE_FORMAT)) data_from_db[field_const.PRODUCT_INFO_SALE_START_DATE] = ( product_info_sale_start_date) data_from_db[field_const.ORDER_DUE_DATE] = order_due_date def find_japan_slogan(sales_goals): """Find the slogan for Japan if present. Args: sales_goals ([dict]): The highlights by country. Returns: str or None: The Japan slogan or None. """ for sg in sales_goals: if sg['country']['country_id'] == field_const.JAPAN_COUNTRY_ID: return sg['marketing_drivers']['slogan'] return None