"""Product Pricing Override logic.""" from oto import response from pricing.constants import error from pricing.logic import change_detection from pricing.models import product_pricing_override from pricing.models import product_pricing_override_store from pricing.models import product_pricing_override_territory def get_by_product_id(product_id): """Get product pricing overrides by product ID. Args: product_id (int): the ID of a product. Returns: response.Response: containing the product pricing overrides. """ return product_pricing_override.get_by_product_id(product_id) def create_product_pricing_override_with_change_detection(product_id, data): """Create a product pricing override. Args: product_id (int): the product id data (dict): dict Returns: response.Response: containing the product pricing override """ result = create_product_pricing_override( product_id, data) if result: change_detection.write_pricing_changes( product_id, data['pricing_family_id']) return result def create_product_pricing_override(product_id, data): """Create a product pricing override. Args: product_id (int): the product id data (dict): dict Returns: response.Response: containing the product pricing override """ territories = [] if 'territories' in data: territories = data['territories'] del data['territories'] stores = [] if 'stores' in data: stores = data['stores'] del data['stores'] try: if has_duplicate(product_id, data, territories, stores): return response.create_error_response( 400, error.ERROR_MESSAGE_DUPLICATE) except Exception: return response.create_error_response( 500, error.ERROR_MESSAGE_DB_ISSUE) create_result = product_pricing_override.create_product_pricing_override( product_id, data) if create_result.status != 200: return create_result if len(territories) == 0 and len(stores) == 0: return create_result product_pricing_override_id = create_result.message[ 'product_pricing_override_id'] if len(territories) > 0: territories_result = \ product_pricing_override_territory.update_territories( product_pricing_override_id, territories) if territories_result.status != 200: return territories_result created_territories = territories_result.message['created'] create_result.message['territories'] = \ [item['territory_code'] for item in created_territories] if len(stores) > 0: stores_result = \ product_pricing_override_store.update_stores( product_pricing_override_id, stores) if stores_result.status != 200: return stores_result created_stores = stores_result.message['created'] create_result.message['stores'] = [item['store_id'] for item in created_stores] return create_result def bulk_create_product_pricing_override(product_id, data): """Create new product pricing overrides. Args: product_id (int): the product id data (dict): dict Returns: response.Response: containing the product pricing overrides """ if 'items' not in data: return response.create_error_response( 400, error.ERROR_MESSAGE_EMPTY_BODY) results = [] pricing_family_ids = set() for item in data['items']: create_result = create_product_pricing_override(product_id, item) pricing_family_ids.add(item['pricing_family_id']) if not create_result: return create_result results.append(create_result.message) for pricing_family_id in pricing_family_ids: change_detection.write_pricing_changes(product_id, pricing_family_id) return response.Response({'items': results}) def bulk_update_create_product_pricing_override(product_id, data): """Update and create new product pricing overrides. Args: product_id (int): the product id data (dict): dict Returns: response.Response: containing the product pricing overrides """ if 'items' not in data: return response.create_error_response( 400, error.ERROR_MESSAGE_EMPTY_BODY) results = [] pricing_family_ids = set() for item in data['items']: pricing_family_ids.add(item['pricing_family_id']) if 'product_pricing_override_id' in item: if 'product_id' in item: del item['product_id'] if 'created_date' in item: del item['created_date'] update_result = update_product_pricing_override( product_id, item['product_pricing_override_id'], item) if not update_result: return update_result results.append(update_result.message) else: create_result = create_product_pricing_override(product_id, item) if not create_result: return create_result results.append(create_result.message) for pricing_family_id in pricing_family_ids: change_detection.write_pricing_changes(product_id, pricing_family_id) return response.Response({'items': results}) def update_product_pricing_override( product_id, product_pricing_override_id, data): """Update a product pricing override. Args: product_id (int): the ID of a product. product_pricing_override_id (int): product pricing override id data (dict): dict Returns: response.Response: containing the updated product pricing override """ if 'product_id' in data: del data['product_id'] if 'created_date' in data: del data['created_date'] territories = [] if 'territories' in data: territories = data['territories'] del data['territories'] stores = [] if 'stores' in data: stores = data['stores'] del data['stores'] update_result = product_pricing_override.update_product_pricing_override( product_id, product_pricing_override_id, data) if update_result.status != 200: return update_result if len(territories) == 0 and len(stores) == 0: change_detection.write_pricing_changes( product_id, data['pricing_family_id']) return update_result if len(territories) > 0: territories_result = \ product_pricing_override_territory.update_territories( product_pricing_override_id, territories) if territories_result.status != 200: return territories_result updated_territories = territories_result.message['created'] update_result.message['territories'] = [item['territory_code'] for item in updated_territories] if len(stores) > 0: stores_result = \ product_pricing_override_store.update_stores( product_pricing_override_id, stores) if stores_result.status != 200: return stores_result updated_stores = stores_result.message['created'] update_result.message['stores'] = [item['store_id'] for item in updated_stores] change_detection.write_pricing_changes( product_id, data['pricing_family_id']) return update_result def has_duplicate(product_id, data, territories, stores): """Try to find an identical store pricing tier code in the DB. Args: product_id (int): the ID of the product. data (dict): the data to use to find the duplicate. territories ([string]): the list of territory codes to use to find the duplicate. stores ([string]): the list of store_ids to use to find the duplicate. Returns: boolean: True if a duplicate was found, False if not. """ find_result = product_pricing_override.find_duplicate( product_id, data) if find_result.status != 200: raise Exception() if find_result.message['found'] is False: return False found = find_result.message['item'] find_territories_result = \ product_pricing_override_territory.get_by_product_pricing_override_id( found['product_pricing_override_id']) if find_territories_result.status != 200: raise Exception() find_stores_result = \ product_pricing_override_store.get_by_product_pricing_override_id( found['product_pricing_override_id']) if find_stores_result.status != 200: raise Exception() found_territories = find_territories_result.message['items'] found_territory_codes = [i['territory_code'] for i in found_territories] found_stores = find_stores_result.message['items'] found_store_ids = [i['store_id'] for i in found_stores] if set(found_territory_codes) == set(territories) and \ set(found_store_ids) == set(stores): return True else: return False def preview_migrate_product_pricing_override_stores(): """Preview Product Pricing Overrides migration to support multiple stores. Returns: response.Response: containing the product pricing override stores to create """ return get_product_pricing_override_stores_to_create() def execute_migrate_product_pricing_override_stores(): """Execute Product Pricing Overrides migration to support multiple stores. Returns: response.Response: containing the created product pricing override stores """ stores_to_create_response = get_product_pricing_override_stores_to_create() if not stores_to_create_response: return stores_to_create_response stores_to_create = stores_to_create_response.message['items'] created_stores = [] for store in stores_to_create: create_response = product_pricing_override_store.create( store['product_pricing_override_id'], store['store_id']) if not create_response: return create_response created_stores.append(create_response.message) return response.Response({'items': created_stores}) def get_product_pricing_override_stores_to_create(): """Get a list of product pricing override stores to create. Returns: response.Response: containing the list of product pricing override stores """ overrides_response = product_pricing_override.get_all_with_store_id() if not overrides_response: return overrides_response overrides = overrides_response.message['items'] stores_to_create = [] for override in overrides: stores_response = product_pricing_override_store.\ get_by_product_pricing_override_id( override['product_pricing_override_id']) if not stores_response: return stores_response stores = stores_response.message['items'] store_ids = [store['store_id'] for store in stores] if override['store_id'] in store_ids: continue stores_to_create.append({ 'product_pricing_override_id': override[ 'product_pricing_override_id'], 'store_id': override['store_id'] }) return response.Response({'items': stores_to_create})