From 9813267eff6d04e442494af45c072e687ab98bb7 Mon Sep 17 00:00:00 2001 From: Jawad Khan Date: Wed, 14 Feb 2024 07:57:37 +0500 Subject: [PATCH 1/3] fix: Support create-mobile-skus to run again if we found an error previously --- ecommerce/extensions/iap/api/v1/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ecommerce/extensions/iap/api/v1/views.py b/ecommerce/extensions/iap/api/v1/views.py index bcf4f9a1ebe..7bcae9d690c 100644 --- a/ecommerce/extensions/iap/api/v1/views.py +++ b/ecommerce/extensions/iap/api/v1/views.py @@ -404,7 +404,7 @@ def post(self, request): product_class__name=SEAT_PRODUCT_CLASS_NAME, children__expires__gt=now(), course=course_run, - ) + ).distinct() if not parent_product.exists(): failed_course_runs.append(course_run_key) From 163b554b151d7ad52c90166bd22d87bda9d42927 Mon Sep 17 00:00:00 2001 From: Jawad Khan Date: Wed, 14 Feb 2024 20:50:55 +0500 Subject: [PATCH 2/3] fix: Fix submission flow for already created ios products --- ecommerce/extensions/api/serializers.py | 10 ++++++---- ecommerce/extensions/iap/api/v1/utils.py | 18 +++++++++++++++--- ecommerce/extensions/iap/utils.py | 4 +++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ecommerce/extensions/api/serializers.py b/ecommerce/extensions/api/serializers.py index e00a211ddac..6508607dc93 100644 --- a/ecommerce/extensions/api/serializers.py +++ b/ecommerce/extensions/api/serializers.py @@ -861,11 +861,13 @@ def _update_app_store_product(self, mobile_seat, price): partner_short_code = self.context['request'].site.siteconfiguration.partner.short_code configuration = settings.PAYMENT_PROCESSOR_CONFIG[partner_short_code.lower()][IOSIAP.NAME.lower()] headers = get_auth_headers(configuration) - try: - ios_product_id = mobile_seat.attr.app_store_id - apply_price_of_inapp_purchase(price, ios_product_id, headers) - except AttributeError: + ios_product_id = getattr(mobile_seat.attr, 'app_store_id', None) + if not ios_product_id: logger.error("app_store_id not associated with [%s]", mobile_seat.course) + return + + apply_price_of_inapp_purchase(price, ios_product_id, headers) + def get_partner(self): """Validate partner""" diff --git a/ecommerce/extensions/iap/api/v1/utils.py b/ecommerce/extensions/iap/api/v1/utils.py index 93f536cc1a5..1c82f57770a 100644 --- a/ecommerce/extensions/iap/api/v1/utils.py +++ b/ecommerce/extensions/iap/api/v1/utils.py @@ -36,9 +36,7 @@ def create_ios_product(course, ios_product, configuration): """ headers = get_auth_headers(configuration) try: - in_app_purchase_id = create_inapp_purchase(course, ios_product.partner_sku, configuration['apple_id'], headers) - ios_product.product.attr.app_store_id = in_app_purchase_id - ios_product.product.save() + in_app_purchase_id = get_or_create_inapp_purchase(ios_product, course, configuration, headers) localize_inapp_purchase(in_app_purchase_id, headers) apply_price_of_inapp_purchase(course['price'], in_app_purchase_id, headers) upload_screenshot_of_inapp_purchase(in_app_purchase_id, headers) @@ -50,6 +48,20 @@ def create_ios_product(course, ios_product, configuration): logger.error(error_msg) return error_msg +def get_or_create_inapp_purchase(ios_stock_record, course, configuration, headers): + """ + Returns inapp_purchase_id from product attr + If not present there create a product on ios store and return its inapp_purchase_id + """ + + in_app_purchase_id = getattr(ios_stock_record.product.attr, 'app_store_id', '') + if not in_app_purchase_id: + in_app_purchase_id = create_inapp_purchase(course, ios_stock_record.partner_sku, + configuration['apple_id'], headers) + ios_stock_record.product.attr.app_store_id = in_app_purchase_id + ios_stock_record.product.save() + + return in_app_purchase_id def request_connect_store(url, headers, data=None, method="post"): """ Request the given endpoint with multiple tries and backoff time """ diff --git a/ecommerce/extensions/iap/utils.py b/ecommerce/extensions/iap/utils.py index ecd02d9c3d4..802886f4d6e 100644 --- a/ecommerce/extensions/iap/utils.py +++ b/ecommerce/extensions/iap/utils.py @@ -57,7 +57,9 @@ def create_mobile_seat(sku_prefix, existing_web_seat): if 'ios' in sku_prefix: # We need this attribute defined for ios products # Actual values will be assigned when we create product on appstore - new_mobile_seat.attr.app_store_id = '' + app_store_id = getattr(new_mobile_seat.attr, 'app_store_id', None) + if not app_store_id: + new_mobile_seat.attr.app_store_id = '' new_mobile_seat.attr.save() From a9bff24cd79d63908da710dcba4d2663a7073bee Mon Sep 17 00:00:00 2001 From: Jawad Khan Date: Thu, 15 Feb 2024 11:45:12 +0500 Subject: [PATCH 3/3] fix: fixed blank line issues --- ecommerce/extensions/api/serializers.py | 1 - ecommerce/extensions/iap/api/v1/utils.py | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ecommerce/extensions/api/serializers.py b/ecommerce/extensions/api/serializers.py index 6508607dc93..68a1189bd0a 100644 --- a/ecommerce/extensions/api/serializers.py +++ b/ecommerce/extensions/api/serializers.py @@ -868,7 +868,6 @@ def _update_app_store_product(self, mobile_seat, price): apply_price_of_inapp_purchase(price, ios_product_id, headers) - def get_partner(self): """Validate partner""" if not self.partner: diff --git a/ecommerce/extensions/iap/api/v1/utils.py b/ecommerce/extensions/iap/api/v1/utils.py index 1c82f57770a..6a62ac5a877 100644 --- a/ecommerce/extensions/iap/api/v1/utils.py +++ b/ecommerce/extensions/iap/api/v1/utils.py @@ -48,6 +48,7 @@ def create_ios_product(course, ios_product, configuration): logger.error(error_msg) return error_msg + def get_or_create_inapp_purchase(ios_stock_record, course, configuration, headers): """ Returns inapp_purchase_id from product attr @@ -63,6 +64,7 @@ def get_or_create_inapp_purchase(ios_stock_record, course, configuration, header return in_app_purchase_id + def request_connect_store(url, headers, data=None, method="post"): """ Request the given endpoint with multiple tries and backoff time """ # Adding backoff and retries because of following two reasons