diff --git a/Backend/main.py b/Backend/main.py index c522ca22243f571180aca3185524dddeec1d67d1..29014f4573b8b631d4c4d206ac5ccb146bfffacb 100644 --- a/Backend/main.py +++ b/Backend/main.py @@ -1,7 +1,7 @@ from utils.application import app from routes.category import get_category -#from routes.order import get_order from routes.home import get_home +from routes.order import post_pay_products #from routes.cart import get_cart from routes.login import post_login, post_logout, post_register from routes.product import get_product_by_id, get_product_all, get_products_by_search @@ -23,9 +23,9 @@ def home(): def category(category_name=None): return get_category(category_name) -#@app.route('/cart', methods=['GET']) -#def cart(): -# return get_cart() +@app.route('/order/', methods=['POST']) +def pay_products(): + return post_pay_products() @app.route('/logout/', methods=['POST']) def logout(): diff --git a/Backend/routes/order.py b/Backend/routes/order.py index c2c1583010f3803dcc84459d644ddcfc97a26119..c251d73bad11da53338db47617b04fc0c8b33834 100644 --- a/Backend/routes/order.py +++ b/Backend/routes/order.py @@ -1,14 +1,78 @@ -from main import mysql, jsonify +from utils.application import mysql +from flask import jsonify, request +from threading import Lock -def get_order(order_id): - if order_id is None: - return jsonify({"message": "Order not found"}), 404 - else: +# Create a lock to avoid a race condition when getting and setting stock quantity +mutex_lock = Lock() + +def post_create_order(): + # Get user from logged in cookie + userId = request.cookies.get('logged_in') + if userId is None: + return jsonify({"message": "You are not logged in"}), 401 + + data = request.json + # Products is array of {product_id, quantity} + products = data["products"] + payment_method = data["payment_method"] + + productIds = [] + for product in products: + productIds.append(product["product_id"]) + + if (len(products) == 0): + return jsonify({"message": "No products in order"}), 400 + + # Acquire the mutex lock + mutex_lock.acquire() + + try: + # Check if all products exist and get their price cur = mysql.connection.cursor() - cur.execute('') # TODO Add SQL query here - data = cur.fetchall() + cur.execute('''SELECT price, stock_quantity FROM product WHERE product_id IN %s''', (productIds,)) + productsData = cur.fetchall() cur.close() - return jsonify(data) # TODO Return the data as JSON - - \ No newline at end of file + if len(productsData) != len(products): + return jsonify({"message": "A product you are attempting to purchase does not exist"}), 400 + + # Check if all products are in stock + for i in range(len(productsData)): + if productsData[i][1] < products[i]["quantity"]: + return jsonify({"message": "A product you are attempting to purchase is out of stock"}), 400 + + totalAmount = 0 + for i in range(len(productsData)): + totalAmount += productsData[i][0] * products[i]["quantity"] + + # Create user_order, it has order_date, total_amount, status, user_id + cur = mysql.connection.cursor() + cur.execute('''INSERT INTO user_order (order_date, total_amount, status, user_id) VALUES (NOW(), %s, "Pending", %s)''', (totalAmount, userId)) + mysql.connection.commit() + cur.close() + + # Get the order_id + cur = mysql.connection.cursor() + cur.execute('''SELECT order_id FROM user_order WHERE user_id = %s ORDER BY order_id DESC LIMIT 1''', (userId,)) + order_id = cur.fetchall()[0][0] + cur.close() + + # Create order_item for each product + for i in range(len(products)): + cur = mysql.connection.cursor() + cur.execute('''INSERT INTO order_item (quantity, product_id, order_id) VALUES (%s, %s, %s)''', (products[i]["quantity"], products[i]["product_id"], order_id)) + mysql.connection.commit() + cur.close() + + # Reduce stock_quantity for each product + for i in range(len(products)): + cur = mysql.connection.cursor() + cur.execute('''UPDATE product SET stock_quantity = stock_quantity - %s WHERE product_id = %s''', (products[i]["quantity"], products[i]["product_id"])) + mysql.connection.commit() + cur.close() + + finally: + # Release the lock even if the try-block fails + mutex_lock.release() + + return jsonify({"message": "Order placed"}), 201 \ No newline at end of file