diff --git a/Order_Microservice_Group3/Dockerfile b/Order_Microservice_Group3/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..7e35c01170fc084dde3257e04b4982a1de8f3a8c --- /dev/null +++ b/Order_Microservice_Group3/Dockerfile @@ -0,0 +1,31 @@ +FROM python:3.11.4 + +# Set the working directory in the container to /app +WORKDIR /app + +# Copy the current directory contents into the container at /app +COPY . /app + +# Install any needed packages specified in requirements.txt +RUN pip install --no-cache-dir -r requirements.txt + +RUN apt-get update && apt-get install -y \ + + unixodbc \ + unixodbc-dev \ + freetds-dev \ + tdsodbc \ + && rm -rf /var/lib/apt/lists/* + +# Set environment variables for ODBC configuration if needed +ENV ODBCINI=/etc/odbc.iniS +ENV ODBCSYSINI=/etc + + +# Make port 5000 available to the world outside this container +EXPOSE 5000 + +ENV START_KAFKA_CONSUMER=true + +# Run app.py when the container launches +CMD ["python", "index.py"] \ No newline at end of file diff --git a/Order_Microservice_Group3/__pycache__/config.cpython-311.pyc b/Order_Microservice_Group3/__pycache__/config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..101ebab0c3bf83308915c60456759b6a5076dd5b Binary files /dev/null and b/Order_Microservice_Group3/__pycache__/config.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/__init__.py b/Order_Microservice_Group3/app/__init__.py index bbf16556cd507d0c7345bc46d53928b0bcd0a4b3..ef81f69fdb877670b376b02e7a19f5a43f14dcda 100644 --- a/Order_Microservice_Group3/app/__init__.py +++ b/Order_Microservice_Group3/app/__init__.py @@ -1,14 +1,44 @@ +# from flask import Flask + +# from .controllers.AddToCartController import AddToCart_bp +# from .controllers.CheckOutController import checkout_bp +# from .controllers.DeleteFromItemController import DeleteCart_bp +# from .controllers.FetchCartController import cart_bp + + +# def create_app(): +# app = Flask(__name__) +# app.register_blueprint(AddToCart_bp) +# app.register_blueprint(checkout_bp) +# app.register_blueprint(DeleteCart_bp) +# app.register_blueprint(cart_bp) + + +# return app + from flask import Flask +from flask_cors import CORS +import os -from .controllers.AddToCartController import AddToCart_bp -from .controllers.CheckOutController import checkout_bp +from app.controllers.AddToCartController import AddToCart_bp +from app.controllers.CheckOutController import checkout_bp from .controllers.DeleteFromItemController import DeleteCart_bp from .controllers.FetchCartController import cart_bp +from .subscriber.UpdateProductSubscriber import start_kafka_consumer def create_app(): app = Flask(__name__) + CORS(app) + + app.config.from_object('config') + app.register_blueprint(AddToCart_bp) app.register_blueprint(checkout_bp) app.register_blueprint(DeleteCart_bp) app.register_blueprint(cart_bp) + + # Optionally start Kafka consumer based on configuration + if app.config.get('START_KAFKA_CONSUMER', False): + start_kafka_consumer() + return app \ No newline at end of file diff --git a/Order_Microservice_Group3/app/__pycache__/__init__.cpython-311.pyc b/Order_Microservice_Group3/app/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45f09827829da5b30358373d313d7bf931794085 Binary files /dev/null and b/Order_Microservice_Group3/app/__pycache__/__init__.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/__pycache__/__init__.cpython-312.pyc b/Order_Microservice_Group3/app/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..58ee95c249f77ea8b7a423614344f4c1dee19f9e Binary files /dev/null and b/Order_Microservice_Group3/app/__pycache__/__init__.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/__pycache__/config.cpython-311.pyc b/Order_Microservice_Group3/app/__pycache__/config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3bad8faed0c0ef554720b32d280772a832bc8c8e Binary files /dev/null and b/Order_Microservice_Group3/app/__pycache__/config.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/config.py b/Order_Microservice_Group3/app/config.py index 0092cdd55fa439a9aa50c21a62bce7545eb9c946..4eaa013981886dab1ba49f264540769872a4290a 100644 --- a/Order_Microservice_Group3/app/config.py +++ b/Order_Microservice_Group3/app/config.py @@ -1,8 +1,5 @@ -import os - DEBUG = True -SECRET_KEY = "Group3" - -PORT = 5001 - -KAFKA_SERVER= "localhost:9092" +SECRET_KEY = '' +PORT = 5000 +START_KAFKA_CONSUMER = True +HOST = '127.0.0.1' \ No newline at end of file diff --git a/Order_Microservice_Group3/app/controllers/AddToCartController.py b/Order_Microservice_Group3/app/controllers/AddToCartController.py index fb556c870406cdef863e8ad23adb33ea4f05c33a..ab120a78086d143027799ea0ae49b9eba24fb170 100644 --- a/Order_Microservice_Group3/app/controllers/AddToCartController.py +++ b/Order_Microservice_Group3/app/controllers/AddToCartController.py @@ -1,49 +1,38 @@ from flask import Blueprint, jsonify, request, json, session -from app.models.AddToCart import add_item_shopping_cart -import requests - -AddToCart_bp = Blueprint("AddToCart", __name__) - -# @AddToCart_bp.route("/cart/AddToCart", methods=["POST"]) -# def add_item(): -# user_id = session.get("user_id") - -# if user_id: -# data = request.get_json() -# ProductID = data.get("ProductID") -# CartQuantity = data.get("CartQuantity") -# UnitPrice = data.get("UnitPrice") - -# if not ProductID or not CartQuantity: -# return jsonify({"error": "Product ID and quantity are required."}), 400 -# cart_item_data = { -# "UserID": user_id, -# "ProductID": ProductID, -# "UnitPrice": UnitPrice, -# CartQuantity": CartQuantity -# } +from models.AddToCart import add_item_shopping_cart +from models.CheckPriceAndQuantity import check_availability_and_price -# add_cart_item_message = add_item_shopping_cart(cart_item_data) -# return jsonify(add_cart_item_message) +import requests -# else: -# return jsonify({"error": "You need to be logged in to add items to the cart."}), +AddToCart_bp = Blueprint("AddToCart", __name__) -#This one to test +#user_id = session.get("user_id") @AddToCart_bp.route("/cart/AddToCart", methods=["POST"]) def add_item(): - - user_id = 1 + user_id = 1 # Temporarily bypass authentication for testing + data = request.get_json() ProductID = data.get("ProductID") CartQuantity = data.get("CartQuantity") UnitPrice = data.get("UnitPrice") + # Check for required data if not ProductID or not CartQuantity or UnitPrice is None: return jsonify({"error": "Product ID, quantity, and unit price are required."}), 400 + # Call the CheckPriceAndQuantity function + inventory_check = check_availability_and_price(ProductID, CartQuantity, UnitPrice, user_id) + + # If there's an issue with availability or price, return the message from the inventory check + if not inventory_check.get("available") or not inventory_check.get("price_correct"): + return jsonify({ + "error": inventory_check.get("message"), # Message from inventory check + "available_quantity": inventory_check.get("available_quantity"), + "current_price": inventory_check.get("current_price") + }), 400 + cart_item_data = { "UserID": user_id, "ProductID": ProductID, @@ -51,5 +40,9 @@ def add_item(): "CartQuantity": CartQuantity } + # Update cart item data with the current price + cart_item_data["UnitPrice"] = inventory_check["current_price"] + + # If the checks pass, add the item to the shopping cart add_cart_item_message = add_item_shopping_cart(cart_item_data) return jsonify(add_cart_item_message) diff --git a/Order_Microservice_Group3/app/controllers/CheckOutController.py b/Order_Microservice_Group3/app/controllers/CheckOutController.py index 5f48e6f482e532007e146172ff85369ccf5f4cbb..6aa7dd8da04e7a67be10c7dcddc0188b31fbe446 100644 --- a/Order_Microservice_Group3/app/controllers/CheckOutController.py +++ b/Order_Microservice_Group3/app/controllers/CheckOutController.py @@ -1,29 +1,38 @@ from flask import Blueprint, request, jsonify, session -from app.models.CheckOut import checkout_cart -from app.models.FetchKart import get_user_cart_items +from models.CheckOut import checkout_cart +from publishers.kafkaPublishers import publish_product_updated_event checkout_bp = Blueprint('checkout', __name__) @checkout_bp.route('/cart/checkout', methods=['POST']) def handle_checkout(): - + #user_id = session.get("user_id") # Retrieve the user ID from session; ensure the user is logged in user_id = 1 if not user_id: return jsonify({"error": "User not logged in"}), 401 data = request.get_json() - - if not data or 'cart_items' not in data or 'location' not in data: - return jsonify({"error": "Missing cart items or location"}), 400 + if not data or 'address' not in data: + return jsonify({"error": "Missing required fields: address"}), 400 - cart_items = data['cart_items'] - location = data['location'] - - total_price = data.get('total_price', 0) + address = data['address'] - checkout_result = checkout_cart(user_id, cart_items, location, total_price) + # Call the checkout function with the provided data + checkout_result = checkout_cart(user_id, address) + # Check for errors in the result and return appropriate responses if 'error' in checkout_result: - return jsonify({"error": checkout_result["error"]}), 500 - - return jsonify(checkout_result), 200 \ No newline at end of file + return jsonify({"error": checkout_result["error"]}), 500 # or another appropriate status code + + # If checkout is successful, publish an event to Kafka for each item purchased + for item in checkout_result.get('item_details', []): # Ensure that item_details are included in checkout_result + event_data = { + "ProductID": item['ProductID'], + "QuantityPurchased": item['Quantity'] + } + publish_product_updated_event(event_data) + + return jsonify({ + "message": "Checkout completed successfully", + "TransactionID": checkout_result.get("TransactionID", "Unknown") + }), 200 \ No newline at end of file diff --git a/Order_Microservice_Group3/app/controllers/DeleteFromItemController.py b/Order_Microservice_Group3/app/controllers/DeleteFromItemController.py index 8a824602145ea4b6bf21af57275ae333fffe28a2..1e72cb1d4c33cf289833eccbac422d313660c630 100644 --- a/Order_Microservice_Group3/app/controllers/DeleteFromItemController.py +++ b/Order_Microservice_Group3/app/controllers/DeleteFromItemController.py @@ -1,24 +1,13 @@ -from app.models.DeleteItemCartModel import delete_item_from_cart +from models.DeleteItemCartModel import delete_item_from_cart from flask import Blueprint, jsonify, request, json, session DeleteCart_bp = Blueprint("delete", __name__) -# @DeleteCart_bp.route("/cart/delete", methods=['DELETE']) -# def delete_item(cart_item_id): # user_id = session.get("user_id") -# if not user_id: -# return jsonify({"error": "You need to be logged in to delete items from the cart."}), 401 - -# # Call the function to delete the item from the cart -# result = delete_item_from_cart(user_id, cart_item_id) - -# if "error" in result: -# return jsonify(result), 404 -# return jsonify(result), 200 @DeleteCart_bp.route("/cart/delete/<int:cart_item_id>", methods=['DELETE']) def delete_item(cart_item_id): - user_id = 5 + user_id = 1 if not user_id: return jsonify({"error": "You need to be logged in to delete items from the cart."}), 401 @@ -26,5 +15,5 @@ def delete_item(cart_item_id): result = delete_item_from_cart(user_id, cart_item_id) if "error" in result: - return jsonify(result), 404 + return jsonify(result), 404 # Or another appropriate status code based on the error return jsonify(result), 200 \ No newline at end of file diff --git a/Order_Microservice_Group3/app/controllers/FetchCartController.py b/Order_Microservice_Group3/app/controllers/FetchCartController.py index 242ec04afc6acd85185527596598af74c68f8947..bf9e944a0a858d90d5743d53a94a1bb6ca6d08a8 100644 --- a/Order_Microservice_Group3/app/controllers/FetchCartController.py +++ b/Order_Microservice_Group3/app/controllers/FetchCartController.py @@ -1,5 +1,5 @@ from flask import Blueprint, jsonify, request, json, session -from app.models.FetchKart import get_user_cart_items +from models.FetchKart import get_user_cart_items import requests # cart_bp = Blueprint("cart", __name__) @@ -24,10 +24,10 @@ cart_bp = Blueprint("cart", __name__) @cart_bp.route("/cart", methods=["GET"]) def fetch_user_cart(): - user_id = request.args.get("user_id") + user_id = 5 if not user_id: - return jsonify({"error": "You need to be logged in to view the cart."}), 400 + return jsonify({"error": "User ID is required."}), 400 cart_data = get_user_cart_items(user_id) if "error" in cart_data: diff --git a/Order_Microservice_Group3/app/controllers/OrderHistoryController.py b/Order_Microservice_Group3/app/controllers/OrderHistoryController.py new file mode 100644 index 0000000000000000000000000000000000000000..c2ceb9ea2165c172f7a7d993ef2f3e5bd82a061d --- /dev/null +++ b/Order_Microservice_Group3/app/controllers/OrderHistoryController.py @@ -0,0 +1,18 @@ +from flask import Blueprint, jsonify, session +from models.order_history import fetch_order_history + +order_history_bp = Blueprint('order_history', __name__) + +@order_history_bp.route('/order/history', methods=['GET']) +def order_history(): + #user_id = session.get('user_id') + user_id = 1 + if not user_id: + return jsonify({"error": "Authentication required to view order history."}), 401 + + order_history_data = fetch_order_history(user_id) + + if 'error' in order_history_data: + return jsonify({"error": order_history_data["error"]}), 500 + + return jsonify({"order_history": order_history_data}), 200 \ No newline at end of file diff --git a/Order_Microservice_Group3/app/controllers/UpdateProductController.py b/Order_Microservice_Group3/app/controllers/UpdateProductController.py new file mode 100644 index 0000000000000000000000000000000000000000..fab0307eb1c25c4f16e1499241bc8491698e8ec9 --- /dev/null +++ b/Order_Microservice_Group3/app/controllers/UpdateProductController.py @@ -0,0 +1,7 @@ +from flask import Blueprint, jsonify, request, json, session +from models.UpdateProduct import UpdateProduct +from subscriber.UpdateProductSubscriber import consume_product_updated_event + +import requests + + diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/AddToCart.cpython-312.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/AddToCart.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61f056c0c6c1d44e3037c3caa6a159cbe1c2d4dd Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/AddToCart.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/AddToCartController.cpython-311.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/AddToCartController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1a9e7891fcf777abbfada512843ea4f1a1a85e2a Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/AddToCartController.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/AddToCartController.cpython-312.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/AddToCartController.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f2978378b85343616505d320886ec0171822f64 Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/AddToCartController.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/CheckOutController.cpython-311.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/CheckOutController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe7008f6ac30785c05f77e69cd7f282c9ae06aaf Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/CheckOutController.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/CheckOutController.cpython-312.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/CheckOutController.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e365f5bde611cb80404546ffa04313ef6241fc51 Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/CheckOutController.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/DeleteFromItemController.cpython-311.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/DeleteFromItemController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..407c6a133d5c8e14b1326add91787d330749b3db Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/DeleteFromItemController.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/DeleteFromItemController.cpython-312.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/DeleteFromItemController.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da076fa047163edc36e0bf3b2339a6b74d0b7478 Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/DeleteFromItemController.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/FetchCartController.cpython-311.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/FetchCartController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8896f18ce6b998335120baaf0fb9b52143b25b49 Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/FetchCartController.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/FetchCartController.cpython-312.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/FetchCartController.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfc13a9f5c15cb3c4f0eba233881f4a60cc6c9a3 Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/FetchCartController.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/OrderHistoryController.cpython-311.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/OrderHistoryController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..682e33fc73c2f0820bb50ee49b50fbf9c56790b5 Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/OrderHistoryController.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/controllers/__pycache__/UpdateProductController.cpython-311.pyc b/Order_Microservice_Group3/app/controllers/__pycache__/UpdateProductController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23e96840e525d88b7815e326927bd300b7099792 Binary files /dev/null and b/Order_Microservice_Group3/app/controllers/__pycache__/UpdateProductController.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/index.py b/Order_Microservice_Group3/app/index.py new file mode 100644 index 0000000000000000000000000000000000000000..532d6800faad33cbf4e125da1e44cd5fc84d1812 --- /dev/null +++ b/Order_Microservice_Group3/app/index.py @@ -0,0 +1,121 @@ +from flask import Flask, jsonify, request, render_template, session, abort, redirect, url_for, make_response +import requests +import subscriber +from flask_cors import CORS +from config import DEBUG, SECRET_KEY, PORT, HOST +import os + +# Importing blueprints from the controllers +from controllers.AddToCartController import AddToCart_bp +from controllers.CheckOutController import checkout_bp +from controllers.DeleteFromItemController import DeleteCart_bp +from controllers.FetchCartController import cart_bp +from controllers.OrderHistoryController import order_history_bp + +# Setting up Flask application +app = Flask(__name__) +CORS(app) + +# Handling secret key based on the execution environment +try: + # Checking if running inside a Docker container + with open("/proc/self/cgroup", "r") as cgroup_file: + cgroup_info = cgroup_file.read() + + if 'docker' in cgroup_file.read(): + print("Running inside Docker container") + app.secret_key = os.environ.get('SECRET_KEY', SECRET_KEY) # Fallback to default if env var is missing + +except FileNotFoundError: + print("Running on a non-Linux system or cgroup not found") + app.secret_key = SECRET_KEY # Use the default secret key if the file is not found + + +@app.route('/cart', methods=['POST']) +def get_session_id(): + session_id = session.get('user_id') + if session_id: + return jsonify({'session_id': session_id}) + else: + return jsonify({'message': 'Session ID not found'}) + +# @app.route('/') +# def index(): + +# return render_template("index.html") + + +# Register blueprints for different parts of the application +app.register_blueprint(AddToCart_bp) +app.register_blueprint(checkout_bp) +app.register_blueprint(DeleteCart_bp) +app.register_blueprint(cart_bp) +app.register_blueprint(order_history_bp) + +if __name__ == '__main__': + + subscriber.start_kafka_consumer() + + # Running the Flask application + app.run(debug=DEBUG, port=PORT) + + + + + + + + + +# from flask import Flask, redirect, url_for, request, render_template, make_response, session, abort +# from flask_cors import CORS +# from flask import jsonify +# from config import DEBUG, SECRET_KEY, PORT +# import os +# import requests +# import subscribers + +# from controllers.AddToCartController import AddToCart_bp +# from controllers.CheckOutController import checkout_bp +# from controllers.DeleteFromItemController import DeleteCart_bp +# from controllers.FetchCartController import cart_bp +# from controllers.UpdateProductController import cart_bp + + +# app = Flask(__name__) +# CORS(app) + + +# app.secret_key = SECRET_KEY + + +# # Read user microservice URL from environment variable +# USER_MICROSERVICE_URL = os.getenv('USER_MICROSERVICE_URL', 'http://127.0.0.1:5000') + + +# @app.route('/cart', methods=['POST']) +# def get_session_id(): +# session_id = session.get('user_id') +# if session_id: +# return jsonify({'session_id': session_id}) +# else: +# return jsonify({'message': 'Session ID not found'}) + +# @app.route('/') +# def index(): +# return render_template("index.html") + + + +# # app.register_blueprint(AddToCart_bp) +# # app.register_blueprint(checkout_bp) +# # app.register_blueprint(DeleteCart_bp) +# # app.register_blueprint(cart_bp) + + + +# if __name__ == '__main__': + +# subscribers.start_kafka_consumer() + +# app.run(debug=DEBUG, port=PORT) \ No newline at end of file diff --git a/Order_Microservice_Group3/app/models/AddToCart.py b/Order_Microservice_Group3/app/models/AddToCart.py index 970068e560001529f3a9c4ec62b9a80a4b976d1e..888e4b4aefbecf4e693cdbe4a3a792c41d679745 100644 --- a/Order_Microservice_Group3/app/models/AddToCart.py +++ b/Order_Microservice_Group3/app/models/AddToCart.py @@ -1,10 +1,7 @@ import pyodbc from flask import jsonify - -import sys -sys.path.append("c:/Users/Fin/University of surrey/Advanced Web Technology/advanced-web-project/Orders_Microservice_Group3") - -from app.models.database_connection import connect_db +from decimal import Decimal +from models.database_connection import connect_db def add_item_shopping_cart(data): diff --git a/Order_Microservice_Group3/app/models/CheckOut.py b/Order_Microservice_Group3/app/models/CheckOut.py index 48d6129f2c724f214728f9937df792c23d490dbb..3cda97b93f2b4b6205c25d0559a5efd18ba7acd3 100644 --- a/Order_Microservice_Group3/app/models/CheckOut.py +++ b/Order_Microservice_Group3/app/models/CheckOut.py @@ -1,83 +1,107 @@ -from app.models.database_connection import connect_db +from models.database_connection import connect_db +from flask import Blueprint, request, jsonify, session + +from decimal import Decimal import pyodbc from datetime import datetime -# def checkout_cart(user_id, address, delivery): -# try: -# connection = connect_db() -# # Ensure that all operations are executed as a single transaction -# connection.autocommit = False -# cursor = connection.cursor() -# # Fetch cart items for the user -# cursor.execute("SELECT ProductID, CartQuantity, UnitPrice, CartQuantity * UnitPrice AS TotalItemPrice FROM ShoppingCart WHERE UserID = ?", (user_id,)) -# cart_items = cursor.fetchall() - -# if not cart_items: -# return {"error": "No items in the cart to checkout."} -# # Insert a new order group -# total_price = sum(item.TotalItemPrice for item in cart_items) -# cursor.execute("INSERT INTO OrderGroup (Transaction_date, Address, Delivery, CustomerID, TotalPrice) VALUES (?, ?, ?, ?, ?)", (datetime.now(), address, delivery, user_id, total_price)) -# transaction_id = cursor.lastrowid - -# # Insert cart items into OrderItem table and link to the new order group -# for item in cart_items: -# cursor.execute("INSERT INTO OrderItem (Transaction_ID, StockCode, OrdersStatus, Quantity, TotalItemPrice) VALUES (?, ?, ?, ?, ?)", (transaction_id, item.ProductID, 'Processing', item.CartQuantity, item.TotalItemPrice)) - -# # Delete the cart items -# cursor.execute("DELETE FROM ShoppingCart WHERE UserID = ?", (user_id,)) - -# # Commit the transaction -# connection.commit() - -# return {"success": "Checkout completed successfully.", "TransactionID": transaction_id} - -# except pyodbc.Error as e: -# print(f"Database error during checkout: {e}") -# connection.rollback() # Rollback in case of error -# return {"error": "Database error during checkout"} - -# finally: -# if cursor: -# cursor.close() -# if connection: -# connection.close() - - -def checkout_cart(user_id, cart_items, Location, total_price): +def checkout_cart(user_id, address): try: connection = connect_db() - # Ensures all operations are executed as a single transaction connection.autocommit = False cursor = connection.cursor() - insert_order_group_stmt = """ + # Fetch cart items for the user + cursor.execute(""" + SELECT ProductID, CartQuantity, FORMAT(UnitPrice, 'N2') AS UnitPrice + FROM ShoppingCart + WHERE UserID = ? + """, (user_id,)) + cart_items = cursor.fetchall() + + if not cart_items: + return {"error": "No items in the cart to checkout."} + + total_price = 0 + item_details = [] + + # Verify availability and price for each cart item + for item in cart_items: + ProductID, CartQuantity, UnitPrice = item + UnitPrice_decimal = Decimal(UnitPrice) # Convert string to Decimal for precise calculations + + # Fetch the current availability and unit price from the product data + cursor.execute(""" + SELECT QuantityAvailable, FORMAT(UnitPrice, 'N2') AS UnitPrice + FROM ProductData + WHERE ProductID = ? + """, (ProductID,)) + row = cursor.fetchone() + if row: + available_quantity, current_price = row + current_price_decimal = Decimal(current_price) + + if available_quantity < CartQuantity: + connection.rollback() + return {"error": f"Not enough inventory for ProductID {ProductID}."} + + if current_price_decimal != UnitPrice_decimal: + cursor.execute(""" + UPDATE ShoppingCart + SET UnitPrice = ? + WHERE ProductID = ? AND UserID = ? + """, (current_price, ProductID, user_id)) + connection.commit() + return {"error": f"Price has changed for ProductID {ProductID}. Updated price in cart."} + + + new_quantity = available_quantity - CartQuantity + cursor.execute(""" + UPDATE ProductData + SET QuantityAvailable = ? + WHERE ProductID = ? + """, (new_quantity, ProductID)) + + + TotalItemPrice = CartQuantity * current_price_decimal + total_price += TotalItemPrice + item_details.append({ + "ProductID": ProductID, + "Quantity": CartQuantity, + "UnitPrice": current_price_decimal, + "TotalItemPrice": TotalItemPrice + }) + + # Insert a new order group + cursor.execute(""" INSERT INTO OrderGroup (CustomerID, TotalPrice, TransactionDate, Location, OrdersStatus) OUTPUT INSERTED.OrderGroupID - VALUES (?, ?, ?, ?, ?) - """ - cursor.execute(insert_order_group_stmt, (user_id, total_price, datetime.now(), Location, 'Processing')) - OrderGroupID = cursor.fetchone()[0] + VALUES (?, ?, ?, ?, 'Processing') + """, (user_id, total_price, datetime.now(), address)) + OrderGroupID = cursor.fetchone()[0] - # Insert cart items into the OrderItem table and link them to the new order group - for item in cart_items: + # Insert cart items into OrderItem table + for item in item_details: cursor.execute(""" - INSERT INTO OrderItem (OrderGroupID, ProductID, Quantity, UnitPrice, TotalItemPrice) - VALUES (?, ?, ?, ?, ?) - """, (OrderGroupID, item['ProductID'], item['CartQuantity'], item['UnitPrice'], item['TotalItemPrice'])) + INSERT INTO OrderItem (OrderGroupID, ProductID, Quantity, TotalItemPrice) + VALUES (?, ?, ?, ?) + """, (OrderGroupID, item["ProductID"], item["Quantity"], item["TotalItemPrice"])) - # Delete the cart items from the ShoppingCart table + # Delete the cart items from the ShoppingCart cursor.execute("DELETE FROM ShoppingCart WHERE UserID = ?", (user_id,)) - - # Commit the transaction connection.commit() - return {"success": "Checkout completed successfully.", "OrderID": OrderGroupID} + return { + "success": "Checkout completed successfully.", + "TransactionID": OrderGroupID, + "item_details": item_details # Include item details for post-processing + } except pyodbc.Error as e: print(f"Database error during checkout: {e}") - connection.rollback() # Rollback in case of an error + connection.rollback() return {"error": "Database error during checkout"} finally: @@ -87,3 +111,102 @@ def checkout_cart(user_id, cart_items, Location, total_price): connection.close() + + + + + +# def validate_cart_items(cart_items, user_id, cursor, connection): +# item_details = [] +# for item in cart_items: +# ProductID, CartQuantity, UnitPrice = item +# UnitPrice_decimal = Decimal(UnitPrice) # Convert string to Decimal for precise calculations + +# # Fetch the current availability and unit price from the product data +# cursor.execute(""" +# SELECT QuantityAvailable, FORMAT(UnitPrice, 'N2') AS UnitPrice +# FROM ProductData +# WHERE ProductID = ? +# """, (ProductID,)) +# row = cursor.fetchone() +# if row: +# available_quantity, current_price = row +# current_price_decimal = Decimal(current_price) + +# if available_quantity < CartQuantity: +# return None, {"error": f"Not enough inventory for ProductID {ProductID}."} + +# if current_price_decimal != UnitPrice_decimal: +# cursor.execute(""" +# UPDATE ShoppingCart +# SET UnitPrice = ? +# WHERE ProductID = ? AND UserID = ? +# """, (current_price, ProductID, user_id)) +# connection.commit() +# return None, {"error": f"Price has changed for ProductID {ProductID}. Updated price in cart from {UnitPrice_decimal} to {current_price_decimal}."} + +# item_details.append({ +# "ProductID": ProductID, +# "Quantity": CartQuantity, +# "UnitPrice": current_price_decimal, +# "TotalItemPrice": CartQuantity * current_price_decimal # Calculate total item price here for consistency +# }) + +# return item_details, None + + +# def checkout_cart(user_id, address): +# try: +# connection = connect_db() +# connection.autocommit = False +# cursor = connection.cursor() + +# cursor.execute(""" +# SELECT ProductID, CartQuantity, FORMAT(UnitPrice, 'N2') AS UnitPrice +# FROM ShoppingCart +# WHERE UserID = ? +# """, (user_id,)) +# cart_items = cursor.fetchall() + +# if not cart_items: +# return {"error": "No items in the cart to checkout."} + +# item_details, error = validate_cart_items(cart_items, user_id, cursor, connection) +# if error: +# connection.rollback() +# return error # Return error if validation failed + +# total_price = sum(item['TotalItemPrice'] for item in item_details) # Sum total prices of all items + +# cursor.execute(""" +# INSERT INTO OrderGroup (CustomerID, TotalPrice, TransactionDate, Location, OrdersStatus) +# OUTPUT INSERTED.OrderGroupID +# VALUES (?, ?, ?, ?, 'Processing') +# """, (user_id, total_price, datetime.now(), address)) +# OrderGroupID = cursor.fetchone()[0] + +# for item in item_details: +# cursor.execute(""" +# INSERT INTO OrderItem (OrderGroupID, ProductID, Quantity, TotalItemPrice) +# VALUES (?, ?, ?, ?) +# """, (OrderGroupID, item["ProductID"], item["Quantity"], item["TotalItemPrice"])) + +# cursor.execute("DELETE FROM ShoppingCart WHERE UserID = ?", (user_id,)) +# connection.commit() + +# return { +# "success": "Checkout completed successfully.", +# "TransactionID": OrderGroupID, +# "item_details": item_details +# } + +# except pyodbc.Error as e: +# connection.rollback() +# return {"error": f"Database error during checkout: {str(e)}"} + +# finally: +# cursor.close() +# connection.close() + + + diff --git a/Order_Microservice_Group3/app/models/CheckPriceAndQuantity.py b/Order_Microservice_Group3/app/models/CheckPriceAndQuantity.py new file mode 100644 index 0000000000000000000000000000000000000000..0f21c3aec23d0a1e1c4d655abfcc98a08f9b742a --- /dev/null +++ b/Order_Microservice_Group3/app/models/CheckPriceAndQuantity.py @@ -0,0 +1,240 @@ +from models.database_connection import connect_db +import pyodbc + +from decimal import Decimal + + + +# def check_availability_and_price(product_id, requested_quantity, expected_price): +# connection = connect_db() +# try: +# cursor = connection.cursor() +# cursor.execute(""" +# SELECT QuantityAvailable, FORMAT(UnitPrice, 'N2') AS UnitPrice +# FROM ProductData +# WHERE ProductID = ? +# """, (product_id,)) + +# row = cursor.fetchone() +# if row: +# available_quantity, current_price = row +# current_price_decimal = current_price + +# expected_price_decimal = expected_price + +# response_data = { +# "available_quantity": available_quantity, +# "current_price": current_price_decimal, +# "available": available_quantity >= requested_quantity, +# "price_correct": current_price_decimal == expected_price_decimal +# } + +# messages = [] +# if not response_data["available"]: +# messages.append(f"We apologize, but there are only {available_quantity} items available.") + +# if not response_data["price_correct"]: +# messages.append(f"The price has changed. The current price is now {current_price_decimal}.") + +# if messages: +# response_data["message"] = " ".join(messages) + +# return response_data + +# else: +# return {"available": False, "message": "Product not found."} + +# except pyodbc.Error as e: +# print(f"Database error in check_availability_and_price: {e}") +# return {"available": False, "message": f"Database error: {str(e)}"} + +# finally: +# if cursor: +# cursor.close() +# if connection: +# connection.close() + + + + +# def check_availability_and_price(product_id, requested_quantity, expected_price): +# connection = connect_db() +# try: +# cursor = connection.cursor() +# cursor.execute(""" +# SELECT QuantityAvailable, UnitPrice +# FROM ProductData +# WHERE ProductID = ? +# """, (product_id,)) + +# row = cursor.fetchone() +# if row: +# available_quantity, current_price = row +# current_price_float = current_price # Ensure conversion to float + +# response_data = { +# "available_quantity": available_quantity, +# "current_price": current_price_float, +# "available": available_quantity >= requested_quantity, +# "price_correct": current_price_float == expected_price +# } + +# if not response_data["available"] or not response_data["price_correct"]: +# messages = [] +# if not response_data["available"]: +# messages.append(f"We apologize, but there are only {available_quantity} items available.") +# if not response_data["price_correct"]: +# messages.append(f"The price has changed. The current price is now {current_price_float}.") +# response_data["message"] = " ".join(messages) + +# return response_data + +# else: +# return {"available": False, "message": "Product not found."} + +# except pyodbc.Error as e: +# print(f"Database error in check_availability_and_price: {e}") +# return {"available": False, "message": f"Database error: {str(e)}"} + +# finally: +# if cursor: +# cursor.close() +# if connection: +# connection.close() + + + + + + + + + + + + + + + + + + + + + + + + +def check_availability_and_price(product_id, requested_quantity, expected_price, user_id): + connection = connect_db() + try: + cursor = connection.cursor() + # Fetch the current available quantity and price + cursor.execute(""" + SELECT QuantityAvailable, FORMAT(UnitPrice, 'N2') AS UnitPrice + FROM ProductData + WHERE ProductID = ? + """, (product_id,)) + + row = cursor.fetchone() + if row: + available_quantity, current_price = row + current_pricefloat = float(current_price) # Convert formatted price back to float if necessary for comparisons + + response_data = { + "available_quantity": available_quantity, + "current_price": current_price, + "available": available_quantity >= requested_quantity, + "price_correct": current_pricefloat == expected_price + } + + messages = [] + if not response_data["available"]: + messages.append(f"We apologize, but there are only {available_quantity} items available.") + + # Check if the price has changed + if not response_data["price_correct"]: + messages.append(f"The price has changed. The current price is now {current_pricefloat}.") + # Update the ShoppingCart with the new price + cursor.execute(""" + UPDATE ShoppingCart + SET UnitPrice = ? + WHERE ProductID = ? AND UserID = ? + """, (current_price, product_id, user_id)) + connection.commit() + + if messages: + response_data["message"] = " ".join(messages) + return response_data + else: + # All checks passed + return response_data + + else: + return {"available": False, "message": "Product not found."} + + except pyodbc.Error as e: + print(f"Database error in check_availability_and_price: {e}") + connection.rollback() + return {"available": False, "message": f"Database error: {str(e)}"} + + finally: + if cursor: + cursor.close() + if connection: + connection.close() + + + + + + +# def check_availability_and_price(product_id, requested_quantity, expected_price): +# connection = connect_db() +# try: +# cursor = connection.cursor() +# cursor.execute(""" +# SELECT QuantityAvailable, FORMAT(UnitPrice, 'N2') AS UnitPrice +# FROM ProductData +# WHERE ProductID = ? +# """, product_id) + +# row = cursor.fetchone() +# if row: +# #The price was stored differently, this may not be an issue with full integration +# available_quantity, current_price = row +# current_price = float(current_price) +# response_data = { +# "available_quantity": available_quantity, +# "current_price": current_price, +# "available": available_quantity >= requested_quantity, +# "price_correct": current_price == expected_price +# } + +# # Construct a message based on availability and price correctness +# messages = [] +# if not response_data["available"]: +# messages.append(f"We apologize, but there are only {available_quantity} items available.") + +# if not response_data["price_correct"]: +# messages.append(f"The price has changed. The current price is now {current_price}.") + +# if messages: +# response_data["message"] = " ".join(messages) +# return response_data +# else: +# # All checks passed +# return response_data + +# else: +# return {"available": False, "message": "Product not found."} + +# except pyodbc.Error as e: +# print(f"Database error in check_availability_and_price: {e}") +# return {"available": False, "message": f"Database error: {str(e)}"} + +# finally: +# if cursor: +# cursor.close() +# if connection: +# connection.close() \ No newline at end of file diff --git a/Order_Microservice_Group3/app/models/DeleteItemCartModel.py b/Order_Microservice_Group3/app/models/DeleteItemCartModel.py index 8c65687e23a8d0c315bc3348d6b8d8e4c1d64286..ae08a3e4606bfc4e27d9ef636c7e84c5713f669a 100644 --- a/Order_Microservice_Group3/app/models/DeleteItemCartModel.py +++ b/Order_Microservice_Group3/app/models/DeleteItemCartModel.py @@ -1,5 +1,5 @@ from flask import jsonify -from app.models.database_connection import connect_db +from models.database_connection import connect_db import pyodbc def delete_item_from_cart(user_id, cart_item_id): diff --git a/Order_Microservice_Group3/app/models/FetchKart.py b/Order_Microservice_Group3/app/models/FetchKart.py index 5254b4421680b87fdbb6a8d01004f9a9080dca45..92b856a1e43b2148aecc0de3e75d9ed8330fb961 100644 --- a/Order_Microservice_Group3/app/models/FetchKart.py +++ b/Order_Microservice_Group3/app/models/FetchKart.py @@ -1,62 +1,51 @@ import pyodbc from datetime import datetime -from app.models.database_connection import connect_db - -def checkout_cart(user_id, cart_items, Location, total_price): - try: - connection = connect_db() - # Ensures all operations are executed as a single transaction - connection.autocommit = False - cursor = connection.cursor() - - # Insert a new order group and capture the Transaction_ID - insert_order_group_stmt = """ - INSERT INTO OrderGroup (CustomerID, TotalPrice, TransactionDate, Location) - OUTPUT INSERTED.OrderGroupID - VALUES (?, ?, ?, ?, ?) - """ - cursor.execute(insert_order_group_stmt, (user_id, total_price, datetime.now(), Location)) - OrderGroupID = cursor.fetchone()[0] # Fetch the Transaction_ID - - # Insert cart items into the OrderItem table and link them to the new order group - for item in cart_items: - cursor.execute(""" - INSERT INTO OrderItem (OrderGroupID, StockCode, OrdersStatus, Quantity, TotalItemPrice) - VALUES (?, ?, ?, ?, ?) - """, (OrderGroupID, item['ProductID'], 'Processing', item['CartQuantity'], item['TotalItemPrice'])) - - # Delete the cart items from the ShoppingCart table - cursor.execute("DELETE FROM ShoppingCart WHERE UserID = ?", (user_id,)) - - # Commit the transaction - connection.commit() - - return {"success": "Checkout completed successfully.", "OrderID": OrderGroupID} - - except pyodbc.Error as e: - print(f"Database error during checkout: {e}") - connection.rollback() # Rollback in case of an error - return {"error": "Database error during checkout"} - - finally: - if cursor: - cursor.close() - if connection: - connection.close() - - - +from models.database_connection import connect_db +# def checkout_cart(user_id, cart_items, Location, total_price): +# try: +# connection = connect_db() +# # Ensure that all operations are executed as a single transaction +# connection.autocommit = False +# cursor = connection.cursor() +# # Insert a new order group and capture the Transaction_ID using the OUTPUT clause +# insert_order_group_stmt = """ +# INSERT INTO OrderGroup (CustomerID, TotalPrice, TransactionDate, Location) +# OUTPUT INSERTED.OrderGroupID +# VALUES (?, ?, ?, ?, ?) +# """ +# cursor.execute(insert_order_group_stmt, (user_id, total_price, datetime.now(), Location)) +# OrderGroupID = cursor.fetchone()[0] # Fetch the Transaction_ID returned by the OUTPUT clause +# # Insert cart items into the OrderItem table and link them to the new order group +# for item in cart_items: +# cursor.execute(""" +# INSERT INTO OrderItem (OrderGroupID, StockCode, OrdersStatus, Quantity, TotalItemPrice) +# VALUES (?, ?, ?, ?, ?) +# """, (OrderGroupID, item['ProductID'], 'Processing', item['CartQuantity'], item['TotalItemPrice'])) +# # Delete the cart items from the ShoppingCart table +# cursor.execute("DELETE FROM ShoppingCart WHERE UserID = ?", (user_id,)) +# # Commit the transaction +# connection.commit() +# return {"success": "Checkout completed successfully.", "OrderID": OrderGroupID} +# except pyodbc.Error as e: +# print(f"Database error during checkout: {e}") +# connection.rollback() # Rollback in case of an error +# return {"error": "Database error during checkout"} +# finally: +# if cursor: +# cursor.close() +# if connection: +# connection.close() -from app.models.database_connection import connect_db +from models.database_connection import connect_db from flask import jsonify import pyodbc diff --git a/Order_Microservice_Group3/app/models/UpdateProduct.py b/Order_Microservice_Group3/app/models/UpdateProduct.py index 7de6ba5953023f63a1bb25cd7cb11987cf444e32..641bb7a1a9561df7520b0f65e59ffacd58c09340 100644 --- a/Order_Microservice_Group3/app/models/UpdateProduct.py +++ b/Order_Microservice_Group3/app/models/UpdateProduct.py @@ -1,8 +1,11 @@ #from confluent_kafka import Producer import json import pyodbc +from flask import jsonify #from flask import jsonify -from database_connection import connect_db +from models.database_connection import connect_db + +#subscriber def UpdateProduct(product_id, quantity, price): try: @@ -11,7 +14,7 @@ def UpdateProduct(product_id, quantity, price): cursor = connection.cursor() # SQL MERGE statement to insert or update - sql = """ + sql_product_data = """ MERGE INTO ProductData AS target USING (SELECT ? AS ProductID, ? AS QuantityAvailable, ? AS UnitPrice) AS source ON target.ProductID = source.ProductID @@ -21,7 +24,16 @@ def UpdateProduct(product_id, quantity, price): INSERT (ProductID, QuantityAvailable, UnitPrice) VALUES (source.ProductID, source.QuantityAvailable, source.UnitPrice); """ - cursor.execute(sql, (product_id, quantity, price)) + cursor.execute(sql_product_data, (product_id, quantity, price)) + + # Update ShoppingCart to reflect new prices + sql_shopping_cart = """ + UPDATE ShoppingCart + SET UnitPrice = ? + WHERE ProductID = ? + """ + cursor.execute(sql_shopping_cart, (price, product_id)) + connection.commit() return {"success": "Product information updated successfully."} diff --git a/Order_Microservice_Group3/app/models/__pycache__/AddToCart.cpython-311.pyc b/Order_Microservice_Group3/app/models/__pycache__/AddToCart.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfcf3766997314f265b5765ba2be8285a807866b Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/AddToCart.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/AddToCart.cpython-312.pyc b/Order_Microservice_Group3/app/models/__pycache__/AddToCart.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd1c0a1653bfb72c78ee6c043d7d6b69b87afbd3 Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/AddToCart.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/CheckOut.cpython-311.pyc b/Order_Microservice_Group3/app/models/__pycache__/CheckOut.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..068db0ea825cd6c1ef8d542a66a5e41339032b01 Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/CheckOut.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/CheckOut.cpython-312.pyc b/Order_Microservice_Group3/app/models/__pycache__/CheckOut.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa7bdb081e740a0063e28ae61d22f4e633ced122 Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/CheckOut.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/CheckPriceAndQuantity.cpython-311.pyc b/Order_Microservice_Group3/app/models/__pycache__/CheckPriceAndQuantity.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c18b61dd7a30efc6bba2ea1deb742a13b691637 Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/CheckPriceAndQuantity.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/CheckPriceAndQuantity.cpython-312.pyc b/Order_Microservice_Group3/app/models/__pycache__/CheckPriceAndQuantity.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83a41ba36819661015f476b957f0f91566c55176 Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/CheckPriceAndQuantity.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/DeleteItemCartModel.cpython-311.pyc b/Order_Microservice_Group3/app/models/__pycache__/DeleteItemCartModel.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b50ef983e2b2f16ab5c1032f617e6d044bedf8c Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/DeleteItemCartModel.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/DeleteItemCartModel.cpython-312.pyc b/Order_Microservice_Group3/app/models/__pycache__/DeleteItemCartModel.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2ea66674acb226f5185fc19100366ff091f702e Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/DeleteItemCartModel.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/FetchKart.cpython-311.pyc b/Order_Microservice_Group3/app/models/__pycache__/FetchKart.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49dfe5ad4e4c7b75897d43f9643df855d83590b6 Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/FetchKart.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/FetchKart.cpython-312.pyc b/Order_Microservice_Group3/app/models/__pycache__/FetchKart.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8566e4c71881890ccfe8d200cc358919b41a2a62 Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/FetchKart.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/UpdateProduct.cpython-311.pyc b/Order_Microservice_Group3/app/models/__pycache__/UpdateProduct.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f082f3afffd6d6841c67b79084642a7a9d1ab45 Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/UpdateProduct.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/__init__.cpython-311.pyc b/Order_Microservice_Group3/app/models/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6c0bff2668c74bd38e94cb35526955cdd4b9a6ab Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/__init__.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/__init__.cpython-312.pyc b/Order_Microservice_Group3/app/models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1a6cdeed180b8b57206cfa994f5e6fd4dc67512a Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/database_connection.cpython-311.pyc b/Order_Microservice_Group3/app/models/__pycache__/database_connection.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0182aa2e0e05b5c37bf5393039b145f0aeefb1d1 Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/database_connection.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/database_connection.cpython-312.pyc b/Order_Microservice_Group3/app/models/__pycache__/database_connection.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f93efc54c77937369eb7735c897e3beaf7600747 Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/database_connection.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/models/__pycache__/order_history.cpython-311.pyc b/Order_Microservice_Group3/app/models/__pycache__/order_history.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d67f37847aa86ba827df45fc0307810e84cabcd Binary files /dev/null and b/Order_Microservice_Group3/app/models/__pycache__/order_history.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/models/database_connection.py b/Order_Microservice_Group3/app/models/database_connection.py index 1e836b8fd3ae593c8d880d038ae6f86c29bcd752..5b439259937e23b4b94b3b092402bdb0d39fe65e 100644 --- a/Order_Microservice_Group3/app/models/database_connection.py +++ b/Order_Microservice_Group3/app/models/database_connection.py @@ -1,11 +1,23 @@ import pyodbc +# #Connect to database +# def connect_db(): + +# server = 'DESKTOP-LCN6P4E\\SQLEXPRESS' +# database = 'Orders' + +# connection_string = f'DRIVER={{SQL Server}};SERVER={server};DATABASE={database};Trusted_Connection=yes;' + +# return pyodbc.connect(connection_string) + #Connect to database def connect_db(): + + server = 'DESKTOP-LCN6P4E\\SQLEXPRESS' + database = 'Orders' + username = 'desktop-lcn6p4e\\fin' + password = '' - server = - database = - - connection_string = f'DRIVER={{SQL Server}};SERVER={server};DATABASE={database};Trusted_Connection=yes;' + connection_string = f'DRIVER={{SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password};Trusted_Connection=yes;' - return pyodbc.connect(connection_string) \ No newline at end of file + return pyodbc.connect(connection_string) diff --git a/Order_Microservice_Group3/app/models/order_history.py b/Order_Microservice_Group3/app/models/order_history.py new file mode 100644 index 0000000000000000000000000000000000000000..d8c851a7f5789dcf5f6ccb345657dc2ad4a908f7 --- /dev/null +++ b/Order_Microservice_Group3/app/models/order_history.py @@ -0,0 +1,59 @@ +import pyodbc +from models.database_connection import connect_db + +def fetch_order_history(user_id): + try: + # Open database connection + connection = connect_db() + cursor = connection.cursor() + + # Fetch the order history for the user + cursor.execute(""" + SELECT og.OrderGroupID, og.CustomerID, og.TransactionDate, og.Location, og.OrdersStatus, og.TotalPrice, oi.OrderItemID, oi.ProductID, oi.UnitPrice, oi.Quantity, oi.TotalItemPrice + FROM OrderGroup og + INNER JOIN OrderItem oi ON og.OrderGroupID = oi.OrderGroupID + WHERE og.CustomerID = ? + ORDER BY og.TransactionDate DESC;""", (user_id,)) + + # Fetch all records and close cursor and connection + records = cursor.fetchall() + cursor.close() + connection.close() + + # Process the fetched data into a structured format for the API response + order_history = {} + for record in records: + # Unpack the fetched row + order_group_id, customer_id, transaction_date, location, orders_status, total_price, order_item_id, product_id, unit_price, quantity, total_item_price = record + + + if order_group_id not in order_history: + order_history[order_group_id] = { + "CustomerID": customer_id, + "TransactionDate": transaction_date, + "Location": location, + "OrdersStatus": orders_status, + "TotalPrice": total_price, + "Items": [] + } + + # Append this item to the items list for the order group + order_history[order_group_id]["Items"].append({ + "OrderItemID": order_item_id, + "ProductID": product_id, + "UnitPrice": unit_price, + "Quantity": quantity, + "TotalItemPrice": total_item_price + }) + + # Convert to list of order histories + order_history_list = list(order_history.values()) + return order_history_list + + except pyodbc.Error as e: + # Close cursor and connection in case of error + if cursor: + cursor.close() + if connection: + connection.close() + return {"error": str(e)} diff --git a/Order_Microservice_Group3/app/publishers/__pycache__/kafkaPublishers.cpython-311.pyc b/Order_Microservice_Group3/app/publishers/__pycache__/kafkaPublishers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f29c863d1d38cd3a32b6adbf3b4951e2a9fb749 Binary files /dev/null and b/Order_Microservice_Group3/app/publishers/__pycache__/kafkaPublishers.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/publishers/__pycache__/kafkaPublishers.cpython-312.pyc b/Order_Microservice_Group3/app/publishers/__pycache__/kafkaPublishers.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..432486e9bcb7f12b1184b584251c58df46243066 Binary files /dev/null and b/Order_Microservice_Group3/app/publishers/__pycache__/kafkaPublishers.cpython-312.pyc differ diff --git a/Order_Microservice_Group3/app/publishers/kafkaPublishers.py b/Order_Microservice_Group3/app/publishers/kafkaPublishers.py index ded6930e91aa08da84e3c6fcaa4313856197e51b..6f511acc77db57d70c21560c94d308766bb0eece 100644 --- a/Order_Microservice_Group3/app/publishers/kafkaPublishers.py +++ b/Order_Microservice_Group3/app/publishers/kafkaPublishers.py @@ -27,7 +27,6 @@ def create_Quantity_updated_topic(): admin_client.create_topics(new_topics=[new_topic], validate_only=False) -#Function is called in updateProfileControllers.py def publish_product_updated_event(event_data): # Serialize the event data to JSON event_json = json.dumps(event_data) diff --git a/Order_Microservice_Group3/app/run.py b/Order_Microservice_Group3/app/run.py new file mode 100644 index 0000000000000000000000000000000000000000..b2d6c4fac62115a0e966128d8fd0454bb93bda76 --- /dev/null +++ b/Order_Microservice_Group3/app/run.py @@ -0,0 +1,7 @@ + +from app import create_app + +app = create_app() + +if __name__ == '__main__': + app.run(debug=app.config['DEBUG'], port=app.config['PORT']) \ No newline at end of file diff --git a/Order_Microservice_Group3/app/subscriber/UpdateProductSubscriber.py b/Order_Microservice_Group3/app/subscriber/UpdateProductSubscriber.py index 95bc9963a30f505eae2ae07a3611c327cb25fbc9..5e3829b9dcf6b69f59deb6e7113dc9f493d92d9d 100644 --- a/Order_Microservice_Group3/app/subscriber/UpdateProductSubscriber.py +++ b/Order_Microservice_Group3/app/subscriber/UpdateProductSubscriber.py @@ -1,15 +1,15 @@ - - - import sys print(sys.path) from threading import Thread from kafka import KafkaConsumer import json import logging + KAFKA_SERVER= "localhost:9092" +TOPIC_NAME = "product_update_topic" + -from app.models.UpdateProduct import UpdateProduct +from models.UpdateProduct import UpdateProduct def consume_product_updated_event(): logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') diff --git a/Order_Microservice_Group3/app/subscriber/__init__.py b/Order_Microservice_Group3/app/subscriber/__init__.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ad05085ca45fa3d3de9426d2438b5f0a1a6465db 100644 --- a/Order_Microservice_Group3/app/subscriber/__init__.py +++ b/Order_Microservice_Group3/app/subscriber/__init__.py @@ -0,0 +1,5 @@ +print("Subscribers package initialized") + +from subscriber.UpdateProductSubscriber import consume_product_updated_event + +from subscriber.UpdateProductSubscriber import start_kafka_consumer diff --git a/Order_Microservice_Group3/app/subscriber/__pycache__/UpdateProductSubscriber.cpython-311.pyc b/Order_Microservice_Group3/app/subscriber/__pycache__/UpdateProductSubscriber.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa9e23735f73af113da60264a91d8bd33db9affa Binary files /dev/null and b/Order_Microservice_Group3/app/subscriber/__pycache__/UpdateProductSubscriber.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/app/subscriber/__pycache__/__init__.cpython-311.pyc b/Order_Microservice_Group3/app/subscriber/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a17d63934a1bacf865d25ca4ec5a38cfc5abe46 Binary files /dev/null and b/Order_Microservice_Group3/app/subscriber/__pycache__/__init__.cpython-311.pyc differ diff --git a/Order_Microservice_Group3/config.py b/Order_Microservice_Group3/config.py new file mode 100644 index 0000000000000000000000000000000000000000..0092cdd55fa439a9aa50c21a62bce7545eb9c946 --- /dev/null +++ b/Order_Microservice_Group3/config.py @@ -0,0 +1,8 @@ +import os + +DEBUG = True +SECRET_KEY = "Group3" + +PORT = 5001 + +KAFKA_SERVER= "localhost:9092" diff --git a/Order_Microservice_Group3/docker-compose.yml b/Order_Microservice_Group3/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..b630abf4196c6b115c7f0394fbbedee120f5bb9b --- /dev/null +++ b/Order_Microservice_Group3/docker-compose.yml @@ -0,0 +1,58 @@ +version: '3.2' +services: + zookeeper: + image: wurstmeister/zookeeper + container_name: zookeeper + ports: + - "2181:2181" + networks: + - kafka_network + + kafka: + image: wurstmeister/kafka + depends_on: kafka + ports: + - "9092:9092" + environment: + KAFKA_ADVERTISED_HOST_NAME: kafka + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_BOOTSTRAP_SEVERS: kafka:9092 + networks: + - kafka_network + + Orders-database: + image: mcr.microsoft.com/mssql/server:2019-latest + container_name: Orders-database + ports: + - "1433:1433" + environment: + SA_PASSWORD: "WebTechGroup3" + ACCEPT_EULA: "Y" + networks: + - kafka_network + volumes: + - Orders-database-data:/var/opt/mssql + + Orders-microservice: + image: Orders-microservice:1.0 + container_name: Orders-microservice + ports: + - "5000:5000" + environment: + DATABASE_URL: "DRIVER=ODBC Driver 17 for SQL Server;SERVER=Chiamaka;DATABASE=User_Management;UID=CHIAMAKA\amych;PWD='';Trusted_Connection=yes;" + #- DATABASE_URL: "mssql://sa:Group3!@user-database:1433/User_Management" + KAFKA_SERVER: "kafka:9092" + SECRET_KEY: Group3 + depends_on: + - Orders-database + - kafka + - zookeeper + networks: + - kafka_network + +networks: + kafka_network: + driver: bridge + +volumes: + Orders-database-data: \ No newline at end of file diff --git a/Order_Microservice_Group3/requirements.txt b/Order_Microservice_Group3/requirements.txt index 972ab5e7fdd6ee679425dcc795c2aeaff42f4d25..febc8c0785e81e39e00be7974efa35a3bd39787f 100644 Binary files a/Order_Microservice_Group3/requirements.txt and b/Order_Microservice_Group3/requirements.txt differ diff --git a/Order_Microservice_Group3/run.py b/Order_Microservice_Group3/run.py new file mode 100644 index 0000000000000000000000000000000000000000..417284e20142e395f88624b73af748fad31e48b3 --- /dev/null +++ b/Order_Microservice_Group3/run.py @@ -0,0 +1,36 @@ +# from flask import Flask +# from app.__init__ import create_app +# app = Flask(__name__) + +# # Define the route for the root URL "/" +# @app.route('/') +# def home(): +# # This is the view function that returns a response +# return "Welcome to the Flask App!" + +# # Check if this is the script being run as the main program and start the app +# if __name__ == '__main__': +# app.run(debug=True) + +# from flask import Flask +# from flask_cors import CORS + + +# #from app.models import models + +# app = Flask(__name__) +# CORS(app) + +# #db = sqlAlchemy + +# #from app import routes + +# if __name__ == '__main__': +# app.run(debug=True) + +from app import create_app # Adjusted import to reference the app package + +app = create_app() + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file