{"action":"created","comment":{"url":"https://api.github.com/repos/edx/ecommerce/pulls/comments/47124506","id":47124506,"diff_hunk":"@@ -0,0 +1,263 @@\n+from __future__ import unicode_literals\n+\n+import dateutil.parser\n+import logging\n+from decimal import Decimal\n+\n+from django.core.exceptions import ValidationError\n+from django.db import transaction\n+from django.db.utils import IntegrityError\n+from django.utils.decorators import method_decorator\n+from oscar.core.loading import get_model\n+from rest_framework import status, generics\n+from rest_framework.permissions import IsAuthenticated, IsAdminUser\n+from rest_framework.response import Response\n+\n+from ecommerce.core.models import Client\n+from ecommerce.extensions.api import serializers, data as data_api\n+from ecommerce.extensions.api.constants import APIConstants as AC\n+from ecommerce.extensions.api.v2.views import NonDestroyableModelViewSet\n+from ecommerce.extensions.catalogue.utils import generate_sku, get_or_create_catalog, generate_upc\n+from ecommerce.extensions.checkout.mixins import EdxOrderPlacementMixin\n+from ecommerce.extensions.payment.processors.invoice import InvoicePayment\n+from ecommerce.extensions.voucher.models import CouponVouchers\n+from ecommerce.extensions.voucher.utils import create_vouchers\n+\n+Basket = get_model('basket', 'Basket')\n+Catalog = get_model('catalogue', 'Catalog')\n+logger = logging.getLogger(__name__)\n+Order = get_model('order', 'Order')\n+Product = get_model('catalogue', 'Product')\n+ProductClass = get_model('catalogue', 'ProductClass')\n+StockRecord = get_model('partner', 'StockRecord')\n+\n+\n+class CouponOrderCreateView(generics.CreateAPIView, EdxOrderPlacementMixin, NonDestroyableModelViewSet):\n+    \"\"\"Endpoint for creating coupon orders.\n+\n+    Creates a new coupon product, adds it to a basket and creates a\n+    new order from that basket.\n+    \"\"\"\n+    queryset = Product.objects.filter(\n+        product_class=ProductClass.objects.get(name='Coupon')\n+    )\n+    permission_classes = (IsAuthenticated, IsAdminUser)\n+    serializer_class = serializers.CouponSerializer\n+\n+    # Disable atomicity for the view. Otherwise, we'd be unable to commit to the database\n+    # until the request had concluded; Django will refuse to commit when an atomic() block\n+    # is active, since that would break atomicity. Without an order present in the database\n+    # at the time fulfillment is attempted, asynchronous order fulfillment tasks will fail.\n+    @method_decorator(transaction.non_atomic_requests)\n+    def dispatch(self, request, *args, **kwargs):\n+        return super(CouponOrderCreateView, self).dispatch(request, *args, **kwargs)\n+\n+    def create(self, request, *args, **kwargs):\n+        \"\"\"Adds coupon to the user's basket.\n+\n+        Expects request array to contain all the necessary data (listed out below).\n+        This information is then used to create a coupon product, add to a\n+        basket and create an order from it.\n+\n+        Arguments:\n+            request (HttpRequest): With parameters title, client_username,\n+            stock_record_ids, start_date, end_date, code, benefit_type,\n+            benefit_value, voucher_type, quantity and price in the body.\n+\n+        Returns:\n+            200 if the order was created successfully; the basket ID is included in the response\n+                body along with the order ID and payment information.\n+            401 if an unauthenticated request is denied permission to access the endpoint.\n+            429 if the client has made requests at a rate exceeding that allowed by the configured rate limit.\n+            500 if an error occurs when attempting to create a coupon.\n+        \"\"\"\n+        with transaction.atomic():\n+            title = request.data[AC.KEYS.TITLE]\n+            client_username = request.data[AC.KEYS.CLIENT_USERNAME]\n+            stock_record_ids = request.data[AC.KEYS.STOCK_RECORD_IDS]\n+            start_date = dateutil.parser.parse(request.data[AC.KEYS.START_DATE])\n+            end_date = dateutil.parser.parse(request.data[AC.KEYS.END_DATE])\n+            code = request.data[AC.KEYS.CODE]\n+            benefit_type = request.data[AC.KEYS.BENEFIT_TYPE]\n+            benefit_value = request.data[AC.KEYS.BENEFIT_VALUE]\n+            voucher_type = request.data[AC.KEYS.VOUCHER_TYPE]\n+            quantity = request.data[AC.KEYS.QUANTITY]\n+            price = request.data[AC.KEYS.PRICE]\n+            partner = request.site.siteconfiguration.partner\n+\n+            client, __ = Client.objects.get_or_create(username=client_username)\n+\n+            coupon_catalog = get_or_create_catalog(\n+                name='Coupon',  # Catalog classifier.\n+                partner=partner,\n+                stock_record_ids=stock_record_ids\n+            )\n+\n+            data = {\n+                'partner': partner,\n+                'title': title,\n+                'benefit_type': benefit_type,\n+                'benefit_value': benefit_value,\n+                'catalog': coupon_catalog,\n+                'end_date': end_date,\n+                'code': code,\n+                'quantity': quantity,\n+                'start_date': start_date,\n+                'voucher_type': voucher_type\n+            }\n+\n+            coupon_product = self.create_coupon_product(title, price, data)\n+\n+            basket = self.add_product_to_basket(\n+                product=coupon_product,\n+                client=client,\n+                site=request.site\n+            )\n+\n+            response_data = self.create_order_for_invoice(basket)\n+\n+            return Response(response_data, status=status.HTTP_200_OK)\n+\n+    def create_coupon_product(self, title, price, data):\n+        \"\"\"Creates a coupon product and a stock record for it.\n+\n+        Arguments:\n+            title (string): The name of the coupon.\n+            price (integer): The price of the coupon(s).\n+            data (dict): Contains data needed to create vouchers,SKU and UPC:\n+                - partner (User)\n+                - benefit_type (string)\n+                - benefit_value (integer)\n+                - catalog (Catalog)\n+                - end_date (Datetime)\n+                - code (string)\n+                - quantity (integer)\n+                - start_date (Datetime)\n+                - voucher_type (string)\n+\n+        Returns:\n+            A coupon product object.\n+        \"\"\"\n+\n+        upc = generate_upc(\n+            title=title,\n+            catalog=data['catalog'],\n+            partner=data['partner']\n+        )\n+        product_class = ProductClass.objects.get(slug='coupon')\n+        coupon_product, created = Product.objects.get_or_create(\n+            product_class=product_class,\n+            upc=upc\n+        )\n+\n+        sku = generate_sku(\n+            product=coupon_product,\n+            partner=data['partner'],\n+            catalog=data['catalog'],\n+        )\n+\n+        if created:\n+            coupon_product.title = title\n+\n+            stock_record = StockRecord.objects.create(\n+                product=coupon_product,\n+                partner=data['partner'],\n+                partner_sku=sku\n+            )\n+            stock_record.price_currency = 'USD'\n+            stock_record.price_excl_tax = price\n+            stock_record.save()\n+        else:\n+            stock_record = StockRecord.objects.get(\n+                partner=data['partner'],\n+                partner_sku=sku\n+            )\n+            stock_record.price_excl_tax = price\n+            stock_record.save()\n+\n+        # Product validation.\n+        try:\n+            coupon_product.clean()\n+        except ValidationError as ex:\n+            logger.exception(\n+                'Failed to validate [%s] coupon.',\n+                coupon_product.title\n+            )\n+            raise ValidationError(ex)\n+\n+        coupon_product.save()\n+\n+        try:\n+            create_vouchers(\n+                name=title,\n+                benefit_type=data['benefit_type'],\n+                benefit_value=Decimal(data['benefit_value']),\n+                catalog=data['catalog'],\n+                coupon=coupon_product,\n+                end_date=data['end_date'],\n+                code=data['code'],\n+                quantity=int(data['quantity']),\n+                start_date=data['start_date'],\n+                voucher_type=data['voucher_type']\n+            )\n+        except IntegrityError as ex:\n+            logger.exception(\n+                'Failed to create vouchers for [%s] coupon.',\n+                coupon_product.title\n+            )\n+            raise IntegrityError(ex)  # pylint: disable=nonstandard-exception\n+\n+        coupon_vouchers = CouponVouchers.objects.get(coupon=coupon_product)\n+\n+        coupon_product.attr.coupon_vouchers = coupon_vouchers\n+        coupon_product.save()\n+\n+        return coupon_product\n+\n+    def add_product_to_basket(self, product, client, site):\n+        \"\"\"Adds the coupon product to the user's basket.\"\"\"\n+        basket = Basket.get_basket(client, site)\n+        basket.add_product(product)\n+        logger.info(\n+            'Added product with SKU [%s] to basket [%d]',\n+            product.stockrecords.first().partner_sku, basket.id","path":"ecommerce/extensions/api/v2/views/coupons.py","position":223,"original_position":223,"commit_id":"06926121a4f72df916081880739d3568ab8dac5a","original_commit_id":"b4fa76fad7b6362869e0410b32a10b967a89305a","user":{"login":"clintonb","id":910510,"avatar_url":"https://avatars.githubusercontent.com/u/910510?v=3","gravatar_id":"","url":"https://api.github.com/users/clintonb","html_url":"https://github.com/clintonb","followers_url":"https://api.github.com/users/clintonb/followers","following_url":"https://api.github.com/users/clintonb/following{/other_user}","gists_url":"https://api.github.com/users/clintonb/gists{/gist_id}","starred_url":"https://api.github.com/users/clintonb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clintonb/subscriptions","organizations_url":"https://api.github.com/users/clintonb/orgs","repos_url":"https://api.github.com/users/clintonb/repos","events_url":"https://api.github.com/users/clintonb/events{/privacy}","received_events_url":"https://api.github.com/users/clintonb/received_events","type":"User","site_admin":false},"body":"That works.","created_at":"2015-12-09T17:41:19Z","updated_at":"2015-12-09T17:41:19Z","html_url":"https://github.com/edx/ecommerce/pull/453#discussion_r47124506","pull_request_url":"https://api.github.com/repos/edx/ecommerce/pulls/453","_links":{"self":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/comments/47124506"},"html":{"href":"https://github.com/edx/ecommerce/pull/453#discussion_r47124506"},"pull_request":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/453"}}},"pull_request":{"url":"https://api.github.com/repos/edx/ecommerce/pulls/453","id":52669640,"html_url":"https://github.com/edx/ecommerce/pull/453","diff_url":"https://github.com/edx/ecommerce/pull/453.diff","patch_url":"https://github.com/edx/ecommerce/pull/453.patch","issue_url":"https://api.github.com/repos/edx/ecommerce/issues/453","number":453,"state":"open","locked":false,"title":"Created API endpoint for creating Coupon orders.","user":{"login":"vkaracic","id":2808092,"avatar_url":"https://avatars.githubusercontent.com/u/2808092?v=3","gravatar_id":"","url":"https://api.github.com/users/vkaracic","html_url":"https://github.com/vkaracic","followers_url":"https://api.github.com/users/vkaracic/followers","following_url":"https://api.github.com/users/vkaracic/following{/other_user}","gists_url":"https://api.github.com/users/vkaracic/gists{/gist_id}","starred_url":"https://api.github.com/users/vkaracic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vkaracic/subscriptions","organizations_url":"https://api.github.com/users/vkaracic/orgs","repos_url":"https://api.github.com/users/vkaracic/repos","events_url":"https://api.github.com/users/vkaracic/events{/privacy}","received_events_url":"https://api.github.com/users/vkaracic/received_events","type":"User","site_admin":false},"body":"This PR contains the API endpoint for coupon products, creating coupons, adding them to the basket, handling the order, fulfilling the order, with accompanying tests. (the test for the fulfillment module is not yet finished).\r\n\r\n@clintonb can you please take a look at the code? Also note that #450 is a prerequisite for this so there is code that calls some models and methods from that PR, Travis will probably fail because of that too. But for now let's just fix any code issues that there might be. Thanks!\r\n\r\n@mjfrey @marjev @dsego  ","created_at":"2015-12-04T13:36:28Z","updated_at":"2015-12-09T17:41:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0e288a21e50d181382537f3d3088cc338c035a16","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/edx/ecommerce/pulls/453/commits","review_comments_url":"https://api.github.com/repos/edx/ecommerce/pulls/453/comments","review_comment_url":"https://api.github.com/repos/edx/ecommerce/pulls/comments{/number}","comments_url":"https://api.github.com/repos/edx/ecommerce/issues/453/comments","statuses_url":"https://api.github.com/repos/edx/ecommerce/statuses/06926121a4f72df916081880739d3568ab8dac5a","head":{"label":"vkaracic:vkaracic/SOL-1354","ref":"vkaracic/SOL-1354","sha":"06926121a4f72df916081880739d3568ab8dac5a","user":{"login":"vkaracic","id":2808092,"avatar_url":"https://avatars.githubusercontent.com/u/2808092?v=3","gravatar_id":"","url":"https://api.github.com/users/vkaracic","html_url":"https://github.com/vkaracic","followers_url":"https://api.github.com/users/vkaracic/followers","following_url":"https://api.github.com/users/vkaracic/following{/other_user}","gists_url":"https://api.github.com/users/vkaracic/gists{/gist_id}","starred_url":"https://api.github.com/users/vkaracic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vkaracic/subscriptions","organizations_url":"https://api.github.com/users/vkaracic/orgs","repos_url":"https://api.github.com/users/vkaracic/repos","events_url":"https://api.github.com/users/vkaracic/events{/privacy}","received_events_url":"https://api.github.com/users/vkaracic/received_events","type":"User","site_admin":false},"repo":{"id":44113047,"name":"ecommerce","full_name":"vkaracic/ecommerce","owner":{"login":"vkaracic","id":2808092,"avatar_url":"https://avatars.githubusercontent.com/u/2808092?v=3","gravatar_id":"","url":"https://api.github.com/users/vkaracic","html_url":"https://github.com/vkaracic","followers_url":"https://api.github.com/users/vkaracic/followers","following_url":"https://api.github.com/users/vkaracic/following{/other_user}","gists_url":"https://api.github.com/users/vkaracic/gists{/gist_id}","starred_url":"https://api.github.com/users/vkaracic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vkaracic/subscriptions","organizations_url":"https://api.github.com/users/vkaracic/orgs","repos_url":"https://api.github.com/users/vkaracic/repos","events_url":"https://api.github.com/users/vkaracic/events{/privacy}","received_events_url":"https://api.github.com/users/vkaracic/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/vkaracic/ecommerce","description":"Django application used to manage edX's product catalog and handle orders for those products","fork":true,"url":"https://api.github.com/repos/vkaracic/ecommerce","forks_url":"https://api.github.com/repos/vkaracic/ecommerce/forks","keys_url":"https://api.github.com/repos/vkaracic/ecommerce/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vkaracic/ecommerce/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vkaracic/ecommerce/teams","hooks_url":"https://api.github.com/repos/vkaracic/ecommerce/hooks","issue_events_url":"https://api.github.com/repos/vkaracic/ecommerce/issues/events{/number}","events_url":"https://api.github.com/repos/vkaracic/ecommerce/events","assignees_url":"https://api.github.com/repos/vkaracic/ecommerce/assignees{/user}","branches_url":"https://api.github.com/repos/vkaracic/ecommerce/branches{/branch}","tags_url":"https://api.github.com/repos/vkaracic/ecommerce/tags","blobs_url":"https://api.github.com/repos/vkaracic/ecommerce/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vkaracic/ecommerce/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vkaracic/ecommerce/git/refs{/sha}","trees_url":"https://api.github.com/repos/vkaracic/ecommerce/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vkaracic/ecommerce/statuses/{sha}","languages_url":"https://api.github.com/repos/vkaracic/ecommerce/languages","stargazers_url":"https://api.github.com/repos/vkaracic/ecommerce/stargazers","contributors_url":"https://api.github.com/repos/vkaracic/ecommerce/contributors","subscribers_url":"https://api.github.com/repos/vkaracic/ecommerce/subscribers","subscription_url":"https://api.github.com/repos/vkaracic/ecommerce/subscription","commits_url":"https://api.github.com/repos/vkaracic/ecommerce/commits{/sha}","git_commits_url":"https://api.github.com/repos/vkaracic/ecommerce/git/commits{/sha}","comments_url":"https://api.github.com/repos/vkaracic/ecommerce/comments{/number}","issue_comment_url":"https://api.github.com/repos/vkaracic/ecommerce/issues/comments{/number}","contents_url":"https://api.github.com/repos/vkaracic/ecommerce/contents/{+path}","compare_url":"https://api.github.com/repos/vkaracic/ecommerce/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vkaracic/ecommerce/merges","archive_url":"https://api.github.com/repos/vkaracic/ecommerce/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vkaracic/ecommerce/downloads","issues_url":"https://api.github.com/repos/vkaracic/ecommerce/issues{/number}","pulls_url":"https://api.github.com/repos/vkaracic/ecommerce/pulls{/number}","milestones_url":"https://api.github.com/repos/vkaracic/ecommerce/milestones{/number}","notifications_url":"https://api.github.com/repos/vkaracic/ecommerce/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vkaracic/ecommerce/labels{/name}","releases_url":"https://api.github.com/repos/vkaracic/ecommerce/releases{/id}","created_at":"2015-10-12T14:37:27Z","updated_at":"2015-10-12T14:37:29Z","pushed_at":"2015-12-09T15:40:34Z","git_url":"git://github.com/vkaracic/ecommerce.git","ssh_url":"git@github.com:vkaracic/ecommerce.git","clone_url":"https://github.com/vkaracic/ecommerce.git","svn_url":"https://github.com/vkaracic/ecommerce","homepage":"","size":8384,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"edx:master","ref":"master","sha":"87b9d1667d6971d11cc6ed08923c52438c46d10b","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":30175039,"name":"ecommerce","full_name":"edx/ecommerce","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/ecommerce","description":"Django application used to manage edX's product catalog and handle orders for those products","fork":false,"url":"https://api.github.com/repos/edx/ecommerce","forks_url":"https://api.github.com/repos/edx/ecommerce/forks","keys_url":"https://api.github.com/repos/edx/ecommerce/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/ecommerce/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/ecommerce/teams","hooks_url":"https://api.github.com/repos/edx/ecommerce/hooks","issue_events_url":"https://api.github.com/repos/edx/ecommerce/issues/events{/number}","events_url":"https://api.github.com/repos/edx/ecommerce/events","assignees_url":"https://api.github.com/repos/edx/ecommerce/assignees{/user}","branches_url":"https://api.github.com/repos/edx/ecommerce/branches{/branch}","tags_url":"https://api.github.com/repos/edx/ecommerce/tags","blobs_url":"https://api.github.com/repos/edx/ecommerce/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/ecommerce/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/ecommerce/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/ecommerce/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/ecommerce/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/ecommerce/languages","stargazers_url":"https://api.github.com/repos/edx/ecommerce/stargazers","contributors_url":"https://api.github.com/repos/edx/ecommerce/contributors","subscribers_url":"https://api.github.com/repos/edx/ecommerce/subscribers","subscription_url":"https://api.github.com/repos/edx/ecommerce/subscription","commits_url":"https://api.github.com/repos/edx/ecommerce/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/ecommerce/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/ecommerce/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/ecommerce/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/ecommerce/contents/{+path}","compare_url":"https://api.github.com/repos/edx/ecommerce/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/ecommerce/merges","archive_url":"https://api.github.com/repos/edx/ecommerce/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/ecommerce/downloads","issues_url":"https://api.github.com/repos/edx/ecommerce/issues{/number}","pulls_url":"https://api.github.com/repos/edx/ecommerce/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/ecommerce/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/ecommerce/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/ecommerce/labels{/name}","releases_url":"https://api.github.com/repos/edx/ecommerce/releases{/id}","created_at":"2015-02-02T06:55:15Z","updated_at":"2015-12-02T03:06:44Z","pushed_at":"2015-12-09T16:38:03Z","git_url":"git://github.com/edx/ecommerce.git","ssh_url":"git@github.com:edx/ecommerce.git","clone_url":"https://github.com/edx/ecommerce.git","svn_url":"https://github.com/edx/ecommerce","homepage":"http://open-edx-ecommerce-guide.readthedocs.org","size":8531,"stargazers_count":18,"watchers_count":18,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":18,"mirror_url":null,"open_issues_count":9,"forks":18,"open_issues":9,"watchers":18,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/453"},"html":{"href":"https://github.com/edx/ecommerce/pull/453"},"issue":{"href":"https://api.github.com/repos/edx/ecommerce/issues/453"},"comments":{"href":"https://api.github.com/repos/edx/ecommerce/issues/453/comments"},"review_comments":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/453/comments"},"review_comment":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/453/commits"},"statuses":{"href":"https://api.github.com/repos/edx/ecommerce/statuses/06926121a4f72df916081880739d3568ab8dac5a"}}}}