"""Interface to the ows-product microservice.""" from flask import g from oto import response from owsrequest import request from product_digital.connectors.sentry import send_to_sentry from product_digital.constants import account from product_digital.constants import error from product_digital.constants import services def check_upc_available(upc): """Check is upc is available for use. Make call to ows-product to test if upc is in use at the orchard. Args: upc (int): the upc to be checked Returns: response.Response: status code 200 if available, 403 if taken """ resource = '/upc/available/{upc}'.format(upc=upc) ows_product_response = request.head(services.OWS_PRODUCT, resource) if ows_product_response.status_code == 200: return response.Response() if ows_product_response.status_code == 403: return response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_UPC_NOT_AVAILABLE, status=400) if ows_product_response.status_code == 404: return response.create_error_response( code=error.ERROR_CODE_BAD_REQUEST, message=error.ERROR_MESSAGE_UPC_NOT_VALID, status=400) error_message = 'ows-product returns {} status'.format( ows_product_response.status_code) g.ows.log.error(error_message) send_to_sentry('check_upc_error', {}, ows_product_response.status_code, error_message) return response.create_fatal_response() def check_ownership(product_id, account_type, account_id): """Check if product is owned by the given account. Args: product_id (int): the id of the product to check account_type (str): type of account (vendor or subaccount) account_id (int): id of the account to check Returns: response.Response: status code 200 if owner, 403 if not owner """ if account_type not in [account.VENDOR_TYPE, account.SUBACCOUNT_TYPE]: return response.create_error_response( code=error.ERROR_CODE_BAD_REQUEST, message='Invalid account type', status=400) resource = '/{account_type}/{account_id}/product/{product_id}'.format( account_type=account_type, account_id=account_id, product_id=product_id) ows_product_response = request.head(services.OWS_PRODUCT, resource) if ows_product_response.status_code == 403: return response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_NOT_PRODUCT_OWNER, status=403) # @todo: handle unexpected status codes return response.Response(status=ows_product_response.status_code) def is_product_code_available(product_code, account_type, account_id): """Check if product_code is available for an account. Arguments: product_code (str): the product code to check account_type (str): one of vendor or subaccount account_id (int): the account id for checking product code Returns: response.Response: 200 if available 403 if not """ product_code_found_response = request.head( services.OWS_PRODUCT, '/{}/{}/product_code/{}'.format( account_type, account_id, product_code)) if product_code_found_response.status_code == 404: return response.Response() if product_code_found_response.status_code == 200: return response.create_error_response( 'validation_error', 'product_code is not available') error_message = 'ows-product returns {} status'.format( product_code_found_response.status_code) g.ows.log.error(error_message) send_to_sentry('product_code_error', {}, product_code_found_response.status_code, error_message) return response.create_fatal_response() def get_product(product_id): """Return information for a product. Arguments: product_id (int): the id of a product Returns: response.Response: get product result """ product_response = request.get(services.OWS_PRODUCT, '/product/{}'.format(product_id)) message = product_response.json() if product_response.status_code != 200: return response.Response(errors=message, status=product_response.status_code) return response.Response(message=product_response.json()) def get_provisioned_upc(mark_used=False): """Retrieve a provisioned UPC. Args: mark_used (boolean): default is False but when True UPC status updates to used. Returns: response.Response: upc value or errors """ upc_response = request.post( services.OWS_PRODUCT, '/upc/provision', json={'mark_used': mark_used} ) if upc_response.status_code != 200: error_response = response.create_error_response( code=error.INTERNAL_ERROR, message='Error fetching UPC', status=500 ) return error_response provisioned_upc = upc_response.json().get('upc') return response.Response(message=provisioned_upc) def get_product_by_upc(upc): """Get product by UPC. Args: upc (str): Returns: response.Response: upc value or errors """ upc_response = request.get( services.OWS_PRODUCT, f'/product/upc/{upc}' ) if upc_response.status_code != 200: error_response = response.create_error_response( code=error.INTERNAL_ERROR, message='Error fetching UPC', status=500 ) return error_response upc_response = upc_response.json() return response.Response(message=upc_response)