"""Label Details model. This model returns all label details for the label ids passed. """ from oto import response from prs.connectors import mysql from prs.constants import error from prs.constants import tools from prs.models import country from prs.models import label_territory_exception from prs.models import label_blacklist from prs.models import rome_convention from prs.utils import shared_utils def get_label_details(label_filter_args): """Return the label details for a given list of labels. Args: label_filter_args (Dict): Dictionary with arguments to filter label details. Returns: response.Response: Vendor details as a dict for passed vendor_ids. """ vendor_details_query, query_placeholder_values = \ _generate_label_details_query(label_filter_args) vendor_details_result = mysql.raw_sql_execute_query( mysql.ar_db_engine, vendor_details_query, query_placeholder_values) for key in query_placeholder_values: vendor_details_query = vendor_details_query.replace( ':'+key, str(query_placeholder_values[key])) shared_utils.log_info_to_loggly(vendor_details_query) if not vendor_details_result: return response.create_not_found_response( message=error.ERROR_MESSAGE_VENDOR_NOT_FOUND) return response.Response(message=vendor_details_result) def _generate_label_details_query(label_filter_args): """Return the query to get label details. Args: label_filter_args (Dict): Dictionary with arguments to filter label details. Returns: vendor_details_query (String): Query to get vendor details. query_placeholder_values (Dict): Dict having query placeholder values to be replaced in the vendor details query. """ country_id = label_filter_args['country_id'] include_local_labels = label_filter_args['include_local_labels'] ignore_rome = label_filter_args['ignore_rome'] check_blacklist = label_filter_args['check_blacklist'] vendor_list = {'vendor_list': label_filter_args['eligible_vendor_list']} country_details = _get_country_and_its_labels(country_id) bad_labels = _get_bad_labels(country_id, check_blacklist) rome_convention_unsigned = _get_rome_unsigned() kwargs = { 'territory_labels': country_details['territory_labels'], 'vendor_list': vendor_list['vendor_list']} vendor_details_query = \ '''select v.vendor_id, v.vendor_name, v.owner, v.country, v.label_country, vsub.id AS split_id, vsub.vendor_id AS split_vendor_id, vsub.cont_start, vsub.cont_end, vsub.digital_split, vsub.currency_id, cur.`ISO_4217_code` AS 'currency_code', vsub.royalty_collection_territory AS collection_territory, vsub.territory_carve_out AS territory_carve_out, vsub.royalty_collection_commission AS collection_split, vsub.sx_royalty_collection_commission AS sx_split, v.is_signed as 'Signed?', CASE WHEN (vw.vendor_contract_id IS NULL) THEN 'N' ELSE 'Y' END AS 'Active Contract?', {dynamic_select_clause}, v.is_owned_and_operated as 'Owned and Operated?', v.assigned_to, v.email, 'NONE' as last_delivery_date, v.contact_email, v.is_distributor AS 'Is Distributor?' FROM vw_label_details v INNER JOIN (select * from vw_all_vendor_contracts) vsub ON v.vendor_id = vsub.vendor_id LEFT JOIN vw_active_vendor_contract vw ON vw.`vendor_id` = vsub.`vendor_id` LEFT JOIN currencies cur ON cur.id = vsub.currency_id WHERE vsub.vcc2id IS NULL AND vsub.cont_start <= NOW() AND vw.vendor_contract_id IS NOT NULL AND v.api_vendor_id IS NULL AND '''.format(dynamic_select_clause=_get_select_clause( country_id, include_local_labels, **kwargs)) where_clause = _get_where_clause( country_id, include_local_labels, ignore_rome, **kwargs) if where_clause: vendor_details_query += ' {}'.format(where_clause) vendor_details_query += ' GROUP BY v.vendor_id' vendor_details_query += _get_having_clause_sql( country_id, label_filter_args['eligible_vendor_list']) query_placeholder_values = {} query_placeholder_values.update(country_details) query_placeholder_values.update(bad_labels) query_placeholder_values.update(rome_convention_unsigned) query_placeholder_values.update(vendor_list) return vendor_details_query, query_placeholder_values def _get_country_and_its_labels(country_id): """Return country id,name and territory labels for country_id. Args: country_id (int): Country id to get respective country name and labels. Returns: Dict: Dict having country id,country name and territory_labels. """ if not country_id: return { 'country_id': 0, 'country_name': tools.WORLDWIDE_COUNTRY_NAME, 'territory_labels': []} country_name = country.get_country_name_by_id(country_id).message['name'] territory_labels_response = \ label_territory_exception.get_label_id_by_country_id(country_id) territory_labels = territory_labels_response.message['label_ids'] return {'country_id': country_id, 'country_name': country_name, 'territory_labels': territory_labels} def _get_bad_labels(country_id, check_blacklist): """Return label ids for blacklist_type_id. Args: country_id (int): Country id condition to add to blacklist_type_list check_blacklist (int): Flag for check_blacklist. Returns: Dict: Dictionary having list of bad labels. """ bad_label_type_with_id = { tools.ROYALTY_BAD: 1, tools.TEST: 2, tools.BROWN: 3, tools.WW: 4, tools.ROW: 5, tools.US: 6} blacklist_type_list = [bad_label_type_with_id[tools.TEST]] if check_blacklist: blacklist_type_list.append(bad_label_type_with_id[tools.WW]) if country_id > tools.US_COUNTRY_ID and \ country_id < tools.MYANMAR_COUNTRY_ID: blacklist_type_list.append(bad_label_type_with_id[tools.ROW]) bad_labels = label_blacklist.get_bad_label_ids_by_blacklist_type_id( blacklist_type_list).message['label_ids'] return {'bad_labels': bad_labels} def _get_rome_territories(): """Return list of Rome Convention mandatory territories. Returns: List: List of Rome Convention mandatory territories. """ rome_convention_territories = \ rome_convention.get_rome_convention_countries().message['country_ids'] rome_convention_territories = [ country.country_id for country in rome_convention_territories] return rome_convention_territories def _get_rome_unsigned(): """Return territories that disregard the Rome Conventions. Returns: Dict: Dictionary having list of territories that disregard the Rome Conventions. """ rome_unsigned_territories = \ rome_convention.get_rome_convention_unsigned().message['country_ids'] rome_unsigned_territories = [ country.country_id for country in rome_unsigned_territories] return {'rome_convention_unsigned': rome_unsigned_territories} def _get_select_clause(country_id, include_local_labels, **kwargs): """Return SELECT clause for the label_details query. Args: country_id (int): Country ID to be used in the query. include_local_labels (Int): Flag to include local labels or not. kwargs (Dict): Additional conditional columns and its values Returns: String: SELECT clause for get_label_details query. """ def _get_country_check_sql(): """Return query_country_checks SQL snippet for country_id. Returns: String: query_country_checks SQL snippet part of SELECT clause. """ query_country_checks = ''' CASE WHEN (vsub.royalty_collection_territory IS NOT NULL AND vsub.royalty_collection_territory <> '') THEN 'Y' ELSE 'N' END as `Collection Eligible` ''' if country_id: query_country_checks = ''' CASE WHEN ( FIND_IN_SET(:country_id, vsub.royalty_collection_territory)''' if country_id != tools.US_COUNTRY_ID and not include_local_labels: query_country_checks += ''' AND (v.country <> :country_id ''' if kwargs.get('territory_labels'): query_country_checks += ''' OR v.vendor_id IN :territory_labels''' query_country_checks += ') ' query_country_checks += ''' ) THEN 'Y' ELSE 'N' END AS `Can Collect in :country_name`, CASE WHEN FIND_IN_SET(:country_id, territory_carve_out) THEN 'N' ELSE 'Y' END AS `Can Distribute in :country_name` ''' return query_country_checks select_clause_columns = [] select_clause_columns.append(_get_country_check_sql()) return ','.join(select_clause_columns) def _get_where_clause( country_id, include_local_labels, ignore_rome, **kwargs): """Return WHERE clause for the label_details query. Args: country_id (int): Country ID to be used in the query. include_local_labels (Boolean): Flag to include local labels or not. kwargs (Dict): Additional conditional columns and its values Returns: String: WHERE clause for get_label_details query. """ def _get_vendor_list_sql(): """Return eligible vendor SQL snippet. Returns: String: eligible vendor SQL snippet part for WHERE clause. """ query_vendor_list = " AND is_signed='Y' AND vw.vendor_contract_id \ IS NOT NULL" if kwargs.get('vendor_list'): query_vendor_list = ' AND v.vendor_id IN :vendor_list' return query_vendor_list def _get_rome_convention_sql(): """Return rome conventions SQL snippet. Returns: String: rome conventions SQL snippet part for WHERE clause. """ query_rome_convention = '' if country_id in _get_rome_territories(): query_rome_convention = '\ AND v.country NOT IN :rome_convention_unsigned' return query_rome_convention def _get_bad_labels_sql(): """Return bad_labels SQL snippet. Returns: String: bad_labels SQL snippet part for WHERE clause. """ query_bad_labels = ' v.vendor_id NOT IN :bad_labels' return query_bad_labels def _get_local_label_sql(): """Return local_label SQL snippet for country_id . Returns: String: local_label SQL snippet part for WHERE clause. """ query_local_labels = ' AND v.country <> :country_id' if kwargs.get('territory_labels'): query_local_labels = ''' AND (v.vendor_id IN :territory_labels OR v.country <> :country_id)''' return query_local_labels where_clause_members = [] where_clause_members.append(_get_bad_labels_sql()) if country_id != tools.US_COUNTRY_ID and not include_local_labels: where_clause_members.append(_get_local_label_sql()) if country_id != tools.US_COUNTRY_ID and not ignore_rome: where_clause_members.append(_get_rome_convention_sql()) where_clause_members.append(_get_vendor_list_sql()) return ''.join(where_clause_members) def _get_having_clause_sql(country_id, vendor_list): """Return HAVING clause for the label_details query. Args: country_id (int): Country ID to be used in the query. vendor_list (list): List of required vendor ids. """ query_having_clause = '' if country_id and not vendor_list: query_having_clause = ''' HAVING FIND_IN_SET(:country_id, collection_territory) > 0 AND FIND_IN_SET(:country_id, territory_carve_out) = 0''' return query_having_clause