Update app.py
Browse files
app.py
CHANGED
|
@@ -94,6 +94,21 @@ class OrderTracking(Base):
|
|
| 94 |
message = Column(Text, nullable=True)
|
| 95 |
timestamp = Column(DateTime, default=datetime.utcnow)
|
| 96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
engine = create_async_engine(DATABASE_URL, echo=True)
|
| 98 |
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
| 99 |
|
|
@@ -167,6 +182,37 @@ class ConversationState:
|
|
| 167 |
|
| 168 |
SESSION_TIMEOUT = timedelta(minutes=5)
|
| 169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
async def log_chat_to_db(user_id: str, direction: str, message: str):
|
| 171 |
async with async_session() as session:
|
| 172 |
entry = ChatHistory(user_id=user_id, direction=direction, message=message)
|
|
@@ -337,6 +383,22 @@ def is_order_intent(message: str) -> bool:
|
|
| 337 |
return True
|
| 338 |
return False
|
| 339 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 340 |
async def track_order(user_id: str, order_id: str) -> str:
|
| 341 |
async with async_session() as session:
|
| 342 |
order_result = await session.execute(
|
|
@@ -445,6 +507,29 @@ def get_dish_price(dish: str) -> int:
|
|
| 445 |
return item["price"]
|
| 446 |
return 0 # or raise an error if dish not found
|
| 447 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 448 |
def send_email_notification(order_details):
|
| 449 |
# Construct the email payload. Adjust values as needed.
|
| 450 |
payload = {
|
|
@@ -845,6 +930,8 @@ app = FastAPI()
|
|
| 845 |
@app.on_event("startup")
|
| 846 |
async def on_startup():
|
| 847 |
await init_db()
|
|
|
|
|
|
|
| 848 |
|
| 849 |
@app.post("/chatbot")
|
| 850 |
async def chatbot_response(request: Request, background_tasks: BackgroundTasks):
|
|
|
|
| 94 |
message = Column(Text, nullable=True)
|
| 95 |
timestamp = Column(DateTime, default=datetime.utcnow)
|
| 96 |
|
| 97 |
+
class MenuItem(Base):
|
| 98 |
+
__tablename__ = "menu_items"
|
| 99 |
+
id = Column(Integer, primary_key=True, index=True)
|
| 100 |
+
name = Column(String, unique=True, index=True)
|
| 101 |
+
description = Column(Text)
|
| 102 |
+
price = Column(Integer) # Price as an integer (in Naira)
|
| 103 |
+
nutrition = Column(Text)
|
| 104 |
+
|
| 105 |
+
class TownShippingCost(Base):
|
| 106 |
+
__tablename__ = "town_shipping_costs"
|
| 107 |
+
id = Column(Integer, primary_key=True, index=True)
|
| 108 |
+
town = Column(String, unique=True, index=True)
|
| 109 |
+
cost = Column(Integer)
|
| 110 |
+
|
| 111 |
+
|
| 112 |
engine = create_async_engine(DATABASE_URL, echo=True)
|
| 113 |
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
| 114 |
|
|
|
|
| 182 |
|
| 183 |
SESSION_TIMEOUT = timedelta(minutes=5)
|
| 184 |
|
| 185 |
+
async def populate_menu_items():
|
| 186 |
+
async with async_session() as session:
|
| 187 |
+
for item in menu_items:
|
| 188 |
+
# Check if this menu item already exists to avoid duplicates.
|
| 189 |
+
result = await session.execute(select(MenuItem).where(MenuItem.name == item["name"]))
|
| 190 |
+
existing = result.scalars().first()
|
| 191 |
+
if not existing:
|
| 192 |
+
new_item = MenuItem(
|
| 193 |
+
name=item["name"],
|
| 194 |
+
description=item["description"],
|
| 195 |
+
price=item["price"],
|
| 196 |
+
nutrition=item["nutrition"]
|
| 197 |
+
)
|
| 198 |
+
session.add(new_item)
|
| 199 |
+
await session.commit()
|
| 200 |
+
|
| 201 |
+
async def populate_shipping_costs():
|
| 202 |
+
async with async_session() as session:
|
| 203 |
+
for town, cost in TOWN_SHIPPING_COSTS.items():
|
| 204 |
+
# Check if the shipping cost entry for this town already exists.
|
| 205 |
+
result = await session.execute(select(TownShippingCost).where(TownShippingCost.town == town))
|
| 206 |
+
existing = result.scalars().first()
|
| 207 |
+
if not existing:
|
| 208 |
+
new_cost = TownShippingCost(
|
| 209 |
+
town=town,
|
| 210 |
+
cost=cost
|
| 211 |
+
)
|
| 212 |
+
session.add(new_cost)
|
| 213 |
+
await session.commit()
|
| 214 |
+
|
| 215 |
+
|
| 216 |
async def log_chat_to_db(user_id: str, direction: str, message: str):
|
| 217 |
async with async_session() as session:
|
| 218 |
entry = ChatHistory(user_id=user_id, direction=direction, message=message)
|
|
|
|
| 383 |
return True
|
| 384 |
return False
|
| 385 |
|
| 386 |
+
async def get_menu_items():
|
| 387 |
+
async with async_session() as session:
|
| 388 |
+
result = await session.execute(select(MenuItem))
|
| 389 |
+
items = result.scalars().all()
|
| 390 |
+
# Build a list of dictionaries to send as a response.
|
| 391 |
+
return [
|
| 392 |
+
{
|
| 393 |
+
"name": item.name,
|
| 394 |
+
"description": item.description,
|
| 395 |
+
"price": item.price,
|
| 396 |
+
"nutrition": item.nutrition
|
| 397 |
+
}
|
| 398 |
+
for item in items
|
| 399 |
+
]
|
| 400 |
+
|
| 401 |
+
|
| 402 |
async def track_order(user_id: str, order_id: str) -> str:
|
| 403 |
async with async_session() as session:
|
| 404 |
order_result = await session.execute(
|
|
|
|
| 507 |
return item["price"]
|
| 508 |
return 0 # or raise an error if dish not found
|
| 509 |
|
| 510 |
+
# Fetch dish price from the MenuItem table
|
| 511 |
+
async def get_dish_price_two(dish: str) -> int:
|
| 512 |
+
async with async_session() as session:
|
| 513 |
+
# Using ilike() for case-insensitive matching
|
| 514 |
+
result = await session.execute(select(MenuItem).where(MenuItem.name.ilike(dish)))
|
| 515 |
+
menu_item = result.scalars().first()
|
| 516 |
+
return menu_item.price if menu_item else 0
|
| 517 |
+
|
| 518 |
+
# Fetch shipping cost from the TownShippingCost table based on the address.
|
| 519 |
+
async def get_shipping_cost(address: str) -> int:
|
| 520 |
+
async with async_session() as session:
|
| 521 |
+
result = await session.execute(select(TownShippingCost))
|
| 522 |
+
costs = result.scalars().all()
|
| 523 |
+
address_lower = address.lower()
|
| 524 |
+
# Look for a matching town in the address.
|
| 525 |
+
for cost in costs:
|
| 526 |
+
if cost.town in address_lower:
|
| 527 |
+
return cost.cost
|
| 528 |
+
# Fallback: return the default cost.
|
| 529 |
+
default_cost = next((c for c in costs if c.town == "default"), None)
|
| 530 |
+
return default_cost.cost if default_cost else 1000
|
| 531 |
+
|
| 532 |
+
|
| 533 |
def send_email_notification(order_details):
|
| 534 |
# Construct the email payload. Adjust values as needed.
|
| 535 |
payload = {
|
|
|
|
| 930 |
@app.on_event("startup")
|
| 931 |
async def on_startup():
|
| 932 |
await init_db()
|
| 933 |
+
await populate_menu_items()
|
| 934 |
+
await populate_shipping_costs()
|
| 935 |
|
| 936 |
@app.post("/chatbot")
|
| 937 |
async def chatbot_response(request: Request, background_tasks: BackgroundTasks):
|