Skip to content

Commit

Permalink
Update add product API to allow for a discount to be specified (#196)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkachel authored Jan 15, 2025
1 parent 6fd4a23 commit 94af2c5
Show file tree
Hide file tree
Showing 5 changed files with 355 additions and 14 deletions.
175 changes: 175 additions & 0 deletions frontends/api/src/generated/v0/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4108,6 +4108,74 @@ export const PaymentsApiAxiosParamCreator = function (
configuration?: Configuration,
) {
return {
/**
* Creates or updates a basket for the current user, adding the selected product and discount.
* @param {string} discount_code
* @param {string} sku
* @param {string} system_slug
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
createBasketFromProductWithDiscount: async (
discount_code: string,
sku: string,
system_slug: string,
options: RawAxiosRequestConfig = {},
): Promise<RequestArgs> => {
// verify required parameter 'discount_code' is not null or undefined
assertParamExists(
"createBasketFromProductWithDiscount",
"discount_code",
discount_code,
)
// verify required parameter 'sku' is not null or undefined
assertParamExists("createBasketFromProductWithDiscount", "sku", sku)
// verify required parameter 'system_slug' is not null or undefined
assertParamExists(
"createBasketFromProductWithDiscount",
"system_slug",
system_slug,
)
const localVarPath =
`/api/v0/payments/baskets/create_from_product/{system_slug}/{sku}/{discount_code}/`
.replace(
`{${"discount_code"}}`,
encodeURIComponent(String(discount_code)),
)
.replace(`{${"sku"}}`, encodeURIComponent(String(sku)))
.replace(
`{${"system_slug"}}`,
encodeURIComponent(String(system_slug)),
)
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL)
let baseOptions
if (configuration) {
baseOptions = configuration.baseOptions
}

const localVarRequestOptions = {
method: "POST",
...baseOptions,
...options,
}
const localVarHeaderParameter = {} as any
const localVarQueryParameter = {} as any

setSearchParams(localVarUrlObj, localVarQueryParameter)
let headersFromBaseOptions =
baseOptions && baseOptions.headers ? baseOptions.headers : {}
localVarRequestOptions.headers = {
...localVarHeaderParameter,
...headersFromBaseOptions,
...options.headers,
}

return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
}
},
/**
* Creates or updates a basket for the current user, adding the discount if valid.
* @param {string} discount_code
Expand Down Expand Up @@ -4668,6 +4736,45 @@ export const PaymentsApiAxiosParamCreator = function (
export const PaymentsApiFp = function (configuration?: Configuration) {
const localVarAxiosParamCreator = PaymentsApiAxiosParamCreator(configuration)
return {
/**
* Creates or updates a basket for the current user, adding the selected product and discount.
* @param {string} discount_code
* @param {string} sku
* @param {string} system_slug
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async createBasketFromProductWithDiscount(
discount_code: string,
sku: string,
system_slug: string,
options?: RawAxiosRequestConfig,
): Promise<
(
axios?: AxiosInstance,
basePath?: string,
) => AxiosPromise<BasketWithProduct>
> {
const localVarAxiosArgs =
await localVarAxiosParamCreator.createBasketFromProductWithDiscount(
discount_code,
sku,
system_slug,
options,
)
const index = configuration?.serverIndex ?? 0
const operationBasePath =
operationServerMap["PaymentsApi.createBasketFromProductWithDiscount"]?.[
index
]?.url
return (axios, basePath) =>
createRequestFunction(
localVarAxiosArgs,
globalAxios,
BASE_PATH,
configuration,
)(axios, operationBasePath || basePath)
},
/**
* Creates or updates a basket for the current user, adding the discount if valid.
* @param {string} discount_code
Expand Down Expand Up @@ -5032,6 +5139,25 @@ export const PaymentsApiFactory = function (
) {
const localVarFp = PaymentsApiFp(configuration)
return {
/**
* Creates or updates a basket for the current user, adding the selected product and discount.
* @param {PaymentsApiCreateBasketFromProductWithDiscountRequest} requestParameters Request parameters.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
createBasketFromProductWithDiscount(
requestParameters: PaymentsApiCreateBasketFromProductWithDiscountRequest,
options?: RawAxiosRequestConfig,
): AxiosPromise<BasketWithProduct> {
return localVarFp
.createBasketFromProductWithDiscount(
requestParameters.discount_code,
requestParameters.sku,
requestParameters.system_slug,
options,
)
.then((request) => request(axios, basePath))
},
/**
* Creates or updates a basket for the current user, adding the discount if valid.
* @param {PaymentsApiPaymentsBasketsAddDiscountCreateRequest} requestParameters Request parameters.
Expand Down Expand Up @@ -5210,6 +5336,34 @@ export const PaymentsApiFactory = function (
}
}

/**
* Request parameters for createBasketFromProductWithDiscount operation in PaymentsApi.
* @export
* @interface PaymentsApiCreateBasketFromProductWithDiscountRequest
*/
export interface PaymentsApiCreateBasketFromProductWithDiscountRequest {
/**
*
* @type {string}
* @memberof PaymentsApiCreateBasketFromProductWithDiscount
*/
readonly discount_code: string

/**
*
* @type {string}
* @memberof PaymentsApiCreateBasketFromProductWithDiscount
*/
readonly sku: string

/**
*
* @type {string}
* @memberof PaymentsApiCreateBasketFromProductWithDiscount
*/
readonly system_slug: string
}

/**
* Request parameters for paymentsBasketsAddDiscountCreate operation in PaymentsApi.
* @export
Expand Down Expand Up @@ -5392,6 +5546,27 @@ export interface PaymentsApiPaymentsOrdersHistoryRetrieveRequest {
* @extends {BaseAPI}
*/
export class PaymentsApi extends BaseAPI {
/**
* Creates or updates a basket for the current user, adding the selected product and discount.
* @param {PaymentsApiCreateBasketFromProductWithDiscountRequest} requestParameters Request parameters.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof PaymentsApi
*/
public createBasketFromProductWithDiscount(
requestParameters: PaymentsApiCreateBasketFromProductWithDiscountRequest,
options?: RawAxiosRequestConfig,
) {
return PaymentsApiFp(this.configuration)
.createBasketFromProductWithDiscount(
requestParameters.discount_code,
requestParameters.sku,
requestParameters.system_slug,
options,
)
.then((request) => request(this.axios, this.basePath))
}

/**
* Creates or updates a basket for the current user, adding the discount if valid.
* @param {PaymentsApiPaymentsBasketsAddDiscountCreateRequest} requestParameters Request parameters.
Expand Down
30 changes: 30 additions & 0 deletions openapi/specs/v0.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,36 @@ paths:
schema:
$ref: '#/components/schemas/BasketWithProduct'
description: ''
/api/v0/payments/baskets/create_from_product/{system_slug}/{sku}/{discount_code}/:
post:
operationId: create_basket_from_product_with_discount
description: Creates or updates a basket for the current user, adding the selected
product and discount.
parameters:
- in: path
name: discount_code
schema:
type: string
required: true
- in: path
name: sku
schema:
type: string
required: true
- in: path
name: system_slug
schema:
type: string
required: true
tags:
- payments
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/BasketWithProduct'
description: ''
/api/v0/payments/baskets/create_with_products/:
post:
operationId: payments_baskets_create_with_products_create
Expand Down
82 changes: 69 additions & 13 deletions payments/views/v0/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Views for the REST API for payments."""

import logging
from typing import Optional

from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
Expand Down Expand Up @@ -124,18 +125,9 @@ def get_user_basket_for_system(request, system_slug: str):
)


@extend_schema(
description=(
"Creates or updates a basket for the current user, "
"adding the selected product."
),
methods=["POST"],
request=None,
responses=BasketWithProductSerializer,
)
@api_view(["POST"])
@permission_classes((IsAuthenticated,))
def create_basket_from_product(request, system_slug: str, sku: str):
def _create_basket_from_product(
request, system_slug: str, sku: str, discount_code: Optional[str] = None
):
"""
Create a new basket item from a product for the currently logged in user. Reuse
the existing basket object if it exists.
Expand All @@ -144,10 +136,14 @@ def create_basket_from_product(request, system_slug: str, sku: str):
basket, then immediately flip the user to the checkout interstitial (which
then redirects to the payment gateway).
If the discount code is provided, then it will be applied to the basket. If
the discount isn't found or doesn't apply, then it will be ignored.
Args:
request (Request): The request object.
system_slug (str): system slug
sku (str): product slug
discount_code (str): discount code
POST Args:
quantity (int): quantity of the product to add to the basket (defaults to 1)
checkout (bool): redirect to checkout interstitial (defaults to False)
Expand Down Expand Up @@ -181,6 +177,14 @@ def create_basket_from_product(request, system_slug: str, sku: str):
auto_apply_discount_discounts = api.get_auto_apply_discounts_for_basket(basket.id)
for discount in auto_apply_discount_discounts:
basket.apply_discount_to_basket(discount)

if discount_code:
try:
discount = Discount.objects.get(discount_code=discount_code)
basket.apply_discount_to_basket(discount)
except Discount.DoesNotExist:
pass

basket.refresh_from_db()

if checkout:
Expand All @@ -192,6 +196,58 @@ def create_basket_from_product(request, system_slug: str, sku: str):
)


@extend_schema(
description=(
"Creates or updates a basket for the current user, "
"adding the selected product."
),
methods=["POST"],
request=None,
responses=BasketWithProductSerializer,
parameters=[
OpenApiParameter(
"system_slug", OpenApiTypes.STR, OpenApiParameter.PATH, required=True
),
OpenApiParameter("sku", OpenApiTypes.STR, OpenApiParameter.PATH, required=True),
],
)
@api_view(["POST"])
@permission_classes((IsAuthenticated,))
def create_basket_from_product(request, system_slug: str, sku: str):
"""Run _create_basket_from_product."""

return _create_basket_from_product(request, system_slug, sku)


@extend_schema(
operation_id="create_basket_from_product_with_discount",
description=(
"Creates or updates a basket for the current user, "
"adding the selected product and discount."
),
methods=["POST"],
request=None,
responses=BasketWithProductSerializer,
parameters=[
OpenApiParameter(
"system_slug", OpenApiTypes.STR, OpenApiParameter.PATH, required=True
),
OpenApiParameter("sku", OpenApiTypes.STR, OpenApiParameter.PATH, required=True),
OpenApiParameter(
"discount_code", OpenApiTypes.STR, OpenApiParameter.PATH, required=True
),
],
)
@api_view(["POST"])
@permission_classes((IsAuthenticated,))
def create_basket_from_product_with_discount(
request, system_slug: str, sku: str, discount_code: Optional[str] = None
):
"""Run _create_basket_from_product with the discount code."""

return _create_basket_from_product(request, system_slug, sku, discount_code)


@extend_schema(
description=(
"Creates or updates a basket for the current user, "
Expand Down
6 changes: 6 additions & 0 deletions payments/views/v0/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
add_discount_to_basket,
clear_basket,
create_basket_from_product,
create_basket_from_product_with_discount,
create_basket_with_products,
get_user_basket_for_system,
start_checkout,
Expand All @@ -34,6 +35,11 @@
create_basket_from_product,
name="create_from_product",
),
path(
"baskets/create_from_product/<str:system_slug>/<str:sku>/<str:discount_code>/",
create_basket_from_product_with_discount,
name="create_from_product_with_discount",
),
path(
"baskets/create_with_products/",
create_basket_with_products,
Expand Down
Loading

0 comments on commit 94af2c5

Please sign in to comment.