Skip to content
This repository was archived by the owner on Jul 11, 2025. It is now read-only.

Refactor checkout process to handle inventory and errors #32

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 46 additions & 20 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
from flask import Flask, request, json, abort
from flask import Flask, request, json, abort, jsonify
from flask_cors import CORS

import sentry_sdk
Expand Down Expand Up @@ -30,20 +30,33 @@
obj['keyDoesntExist']

Inventory = {
'wrench': 1,
'nails': 1,
'hammer': 1
'wrench': 10,
'nails': 100,
'hammer': 5,
'4': 2 # Botana Voice with ID '4' and 2 in stock
}

def process_order(cart):
class InsufficientInventoryError(Exception):
def __init__(self, message, product_id=None):
super().__init__(message)
self.product_id = product_id

def process_order(cart_items, cart_quantities):
global Inventory
tempInventory = Inventory
for item in cart:
if Inventory[item['id']] <= 0:
raise Exception("Not enough inventory for " + item['id'])
else:
tempInventory[item['id']] -= 1
print 'Success: ' + item['id'] + ' was purchased, remaining stock is ' + str(tempInventory[item['id']])
tempInventory = Inventory.copy()
for item_in_cart in cart_items:
product_id = str(item_in_cart['id'])
if product_id not in tempInventory:
raise ValueError(f"Product ID '{product_id}' not found.")
requested_quantity = cart_quantities.get(product_id)
if not isinstance(requested_quantity, int) or requested_quantity <= 0:
raise ValueError(f"Invalid quantity for product ID '{product_id}'.")
available_stock = tempInventory[product_id]
if available_stock < requested_quantity:
raise InsufficientInventoryError(
f"Not enough inventory for product ID '{product_id}'.", product_id=product_id)
tempInventory[product_id] -= requested_quantity
print(f'Success: {product_id} was purchased, remaining stock is {tempInventory[product_id]}')
Inventory = tempInventory

@app.before_request
Expand All @@ -65,11 +78,24 @@

@app.route('/checkout', methods=['POST'])
def checkout():

order = json.loads(request.data)
print "Processing order for: " + order["email"]
cart = order["cart"]

process_order(cart)

return 'Success'
try:
order_data = request.get_json()
print(f"Processing order for: {order_data['form']['email']}")
cart = order_data["cart"]
cart_items = cart["items"]
cart_quantities = cart["quantities"]

process_order(cart_items, cart_quantities)
return jsonify({"message": "Order successful"}), 200
except InsufficientInventoryError as e:
return jsonify({
"error": "InsufficientInventory",
"message": str(e),
"product_id": e.product_id
}), 409 # Use 409 Conflict

Check warning on line 95 in app.py

View check run for this annotation

GitHub Advanced Security / CodeQL

Information exposure through an exception

[Stack trace information](1) flows to this location and may be exposed to an external user.
Comment on lines +91 to +95

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.
except ValueError as e:
return jsonify({"error": "BadRequest", "message": str(e)}), 400 # Use 400 Bad Request

Check warning on line 97 in app.py

View check run for this annotation

GitHub Advanced Security / CodeQL

Information exposure through an exception

[Stack trace information](1) flows to this location and may be exposed to an external user.

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.
except Exception as e:
# Fallback for unexpected errors
sentry_sdk.capture_exception(e)
return jsonify({"error": "InternalServerError", "message": "An unexpected error occurred."}), 500
Loading