diff --git a/booking_service/main.py b/booking_service/main.py index 1bfe1cc51dbbc797f27b27e93750720e14892c71..579510f6a4561288ec371ab9c84b00b2a7dade0a 100644 --- a/booking_service/main.py +++ b/booking_service/main.py @@ -10,7 +10,7 @@ from pathlib import Path from typing import List import mysql.connector from dotenv import load_dotenv -from decimal import Decimal +from decimal import Decimal, getcontext import os @@ -37,6 +37,7 @@ db_connection = mysql.connector.connect( ) cursor = db_connection.cursor() +getcontext().prec = 10 class Booking(BaseModel): user_id: int @@ -165,16 +166,6 @@ async def book_bike(booking: Booking): @app.put("/bookings/") async def update_booking(update: UpdateBooking): - # Establish a database connection - db_connection = mysql.connector.connect( - host='database-1.cz0ucmk42cu5.us-east-1.rds.amazonaws.com', - port='3306', - user='admin', - password='Test#321', - database='cycle_connect' - ) - cursor = db_connection.cursor() - # Check if the booking with provided booking_id, user_id, and bike_id exists cursor.execute(""" SELECT @@ -189,42 +180,37 @@ async def update_booking(update: UpdateBooking): booking = cursor.fetchone() if not booking: - raise HTTPException(status_code=404, detail="No matching booking found.") + raise HTTPException(status_code=404, detail="Booking not found") # Unpack fetched details - start_time, blocked_amount, price_per_hour, current_wallet_balance = booking + start_time, blocked_amount, price_per_hour, wallet_balance = booking + start_time = datetime.fromisoformat(start_time) if isinstance(start_time, str) else start_time - # Handle start_time type appropriately - if not isinstance(start_time, datetime): - start_time = datetime.fromisoformat(start_time) - - # Calculate total runtime in hours + # Calculate the duration in hours and the final price end_time = datetime.now() - total_runtime = (end_time - start_time).total_seconds() / 3600 - - # Determine final price based on total runtime - if total_runtime <= 5: - final_price = blocked_amount - (total_runtime * price_per_hour) - else: - final_price = blocked_amount - - # Update wallet balance - new_wallet_balance = current_wallet_balance + final_price - - # Update Booking and Users records - cursor.execute("UPDATE Bookings SET end_time = %s, payment_state = 'Ride Completed' WHERE booking_id = %s", (end_time.strftime('%Y-%m-%d %H:%M:%S'), update.booking_id)) - cursor.execute("UPDATE Users SET wallet_balance = %s WHERE user_id = %s", (new_wallet_balance, update.user_id)) - - db_connection.commit() - db_connection.close() + duration_hours = (end_time - start_time).total_seconds() / 3600 + duration_hours_decimal = Decimal(str(duration_hours)) # Convert float to Decimal via string for accuracy + + final_price = Decimal(blocked_amount) - (duration_hours_decimal * Decimal(price_per_hour)) + new_wallet_balance = Decimal(wallet_balance) + final_price + + # Perform database updates within a transaction + try: + cursor.execute("UPDATE Bookings SET end_time = %s, payment_state = 'Completed' WHERE booking_id = %s", + (end_time.strftime('%Y-%m-%d %H:%M:%S'), update.booking_id)) + cursor.execute("UPDATE Users SET wallet_balance = %s WHERE user_id = %s", + (new_wallet_balance, update.user_id)) + db_connection.commit() + except Exception as e: + db_connection.rollback() + raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") return { - "message": "Booking updated and charges applied successfully", - "booking_id": update.booking_id, - "user_id": update.user_id, - "bike_id": update.bike_id, - "end_time": end_time.strftime('%Y-%m-%d %H:%M:%S'), - "final_price": final_price, - "new_wallet_balance": new_wallet_balance, - "payment_state": "Ride Completed" - } \ No newline at end of file + "message": "Booking updated successfully", + "details": { + "booking_id": update.booking_id, + "final_price": float(final_price), # Convert Decimal back to float for JSON serialization + "new_wallet_balance": float(new_wallet_balance), + "end_time": end_time.strftime('%Y-%m-%d %H:%M:%S') + } + }