Fred808 commited on
Commit
3cc043f
·
verified ·
1 Parent(s): d72d1b8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -78
app.py CHANGED
@@ -134,6 +134,17 @@ menu_items = [
134
  {"name": "Banga Soup", "description": "Traditional dish with catfish", "price": 5000, "nutrition": "Calories: 600 kcal, Carbs: 50g, Protein: 35g, Fat: 15g"}
135
  ]
136
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
  class ConversationState:
139
  def __init__(self):
@@ -630,11 +641,10 @@ async def process_order_flow(user_id: str, message: str) -> str:
630
  return (f"Got it. {quantity} serving(s) of {dish}.\n"
631
  "Please provide your phone number and delivery address.")
632
 
633
- # 4) If state.step == 3: parse phone & address
634
  if state and state.flow == "order" and state.step == 3:
635
  phone_pattern = r'(\+?\d{10,15})'
636
  phone_match = re.search(phone_pattern, message)
637
- address = None
638
  if phone_match:
639
  phone_number = phone_match.group(1)
640
  address_start = phone_match.end()
@@ -649,88 +659,26 @@ async def process_order_flow(user_id: str, message: str) -> str:
649
  else:
650
  return ("Please provide both your phone number and address. "
651
  "For example: '09162409591, 1, Iyana Isashi, Isashi, Lagos'.")
652
- if "address" not in state.data:
653
  return "Thank you. Please provide your delivery address."
654
  shipping_cost = calculate_shipping_cost(state.data["address"])
655
  state.data["shipping_cost"] = shipping_cost
656
- state.step = 5
 
 
 
657
  return (f"Thanks! Your phone number is recorded as: {state.data['phone_number']}.\n"
658
  f"Your delivery address is: {state.data['address']}.\n"
659
- f"Your delivery cost is N{shipping_cost}. Would you like extras (yes/no)?")
660
-
661
- # Step 5: Ask about extras.
662
- if state and state.flow == "order" and state.step == 5:
663
- normalized = message.strip().lower()
664
- if normalized in ["yes", "y"]:
665
- state.step = 6
666
- return "Please list the extras you'd like (e.g., drinks, sides)."
667
- elif normalized in ["no", "n"]:
668
- state.data["extras"] = ""
669
- state.step = 7
670
- # Build order summary for confirmation:
671
- if "orders" in state.data: # Multiple-dish order
672
- summary = "\n".join([f"{qty} serving(s) of {dish}" for dish, qty in state.data["orders"].items()])
673
- quantity_total = sum(state.data["orders"].values())
674
- dish_summary = ", ".join(state.data["orders"].keys())
675
- else: # Single-dish order
676
- summary = f"{state.data.get('quantity', 1)} serving(s) of {state.data.get('dish', '')}"
677
- quantity_total = state.data.get("quantity", 1)
678
- dish_summary = state.data.get("dish", "")
679
- # Determine the price correctly
680
- if "dish" in state.data:
681
- price_per_serving = get_dish_price(state.data["dish"])
682
- total_price = (quantity_total * price_per_serving) + state.data.get("shipping_cost", 0)
683
- elif "orders" in state.data:
684
- total_price = 0
685
- for dish, qty in state.data["orders"].items():
686
- total_price += get_dish_price(dish) * qty
687
- total_price += state.data.get("shipping_cost", 0)
688
- else:
689
- total_price = state.data.get("shipping_cost", 0)
690
- confirmation = (
691
- f"Order Summary:\n"
692
- f"Dish(es): {dish_summary}\n"
693
- f"Quantity: {quantity_total}\n"
694
- f"Phone: {state.data.get('phone_number', '')}\n"
695
- f"Address: {state.data.get('address', '')}\n"
696
- f"Shipping Cost: N{state.data.get('shipping_cost', 0)}\n"
697
- f"Total Price: N{total_price}\n"
698
- f"Extras: None\nConfirm order? (yes/no)"
699
- )
700
- return confirmation
701
- else:
702
- return "Please respond with 'yes' or 'no' regarding extras."
703
-
704
-
705
- # 6) Step 6: Process extras list.
706
- if state and state.flow == "order" and state.step == 6:
707
- state.data["extras"] = message
708
- state.step = 7
709
- if "orders" in state.data:
710
- summary = "\n".join([f"{qty} serving(s) of {dish}" for dish, qty in state.data["orders"].items()])
711
- quantity_total = sum(state.data["orders"].values())
712
- dish_summary = ", ".join(state.data["orders"].keys())
713
- else:
714
- summary = f"{state.data.get('quantity', 1)} serving(s) of {state.data.get('dish', '')}"
715
- quantity_total = state.data.get("quantity", 1)
716
- dish_summary = state.data.get("dish", "")
717
- price_per_serving = get_dish_price(state.data.get("dish", "")) if "dish" in state.data else 0
718
- total_price = (quantity_total * price_per_serving) + state.data.get("shipping_cost", 0)
719
- confirmation = (f"Order Summary:\nDish(es): {dish_summary}\nQuantity: {quantity_total}\n"
720
- f"Phone: {state.data.get('phone_number', '')}\n"
721
- f"Address: {state.data.get('address', '')}\n"
722
- f"Shipping Cost: N{state.data.get('shipping_cost', 0)}\n"
723
- f"Total Price: N{total_price}\n"
724
- f"Extras: {state.data.get('extras', 'None')}\nConfirm order? (yes/no)")
725
- return confirmation
726
 
 
727
  # 7) Step 7: Order Confirmation and Payment Link Generation
728
  if state and state.flow == "order" and state.step == 7:
729
  if message.lower() in ["yes", "y"]:
730
  order_id = f"ORD-{int(time.time())}"
731
  state.data["order_id"] = order_id
732
-
733
- # Calculate total price based on whether it's a single-dish or multi-dish order.
734
  if "orders" in state.data:
735
  total_price = 0
736
  for dish, qty in state.data["orders"].items():
@@ -742,7 +690,6 @@ async def process_order_flow(user_id: str, message: str) -> str:
742
  dish_summary = state.data.get("dish", "")
743
  quantity_total = state.data.get("quantity", 1)
744
  total_price = (quantity_total * get_dish_price(dish_summary)) + state.data.get("shipping_cost", 0)
745
-
746
  state.data["price"] = str(total_price)
747
 
748
  async def save_order():
@@ -761,6 +708,9 @@ async def process_order_flow(user_id: str, message: str) -> str:
761
  asyncio.create_task(save_order())
762
  asyncio.create_task(log_order_tracking(order_id, "Order Placed", "Order placed and awaiting payment."))
763
 
 
 
 
764
  # Prepare order details as a dictionary for the email notification.
765
  order_details = {
766
  "order_id": order_id,
@@ -778,7 +728,7 @@ async def process_order_flow(user_id: str, message: str) -> str:
778
  print("Failed to send email notification.")
779
 
780
  # Generate Paystack payment link (amount in kobo)
781
- email_for_paystack = "customer@example.com" # Replace as needed
782
  payment_data = create_paystack_payment_link(email_for_paystack, total_price * 100, order_id)
783
  state.reset()
784
  if user_id in user_state:
@@ -799,11 +749,13 @@ async def process_order_flow(user_id: str, message: str) -> str:
799
  else:
800
  return (f"Your order has been placed with Order ID {order_id}, "
801
  "but we could not initialize online payment. Please try again later, or "
802
- "you may opt to pay via bank transfer to Account Number 1433042821, Access Bank, Angelo Food Court 2 "
803
  "and send your payment screenshot to this chatbot.")
804
  elif message.lower() in ["no", "n"]:
805
- # Instead of canceling immediately, re-prompt for confirmation.
806
- return "Please confirm your order by typing 'yes' to confirm your order or 'no' to cancel it."
 
 
807
  else:
808
  return "I didn't understand that. Please type 'yes' to confirm your order or 'no' to cancel it."
809
 
 
134
  {"name": "Banga Soup", "description": "Traditional dish with catfish", "price": 5000, "nutrition": "Calories: 600 kcal, Carbs: 50g, Protein: 35g, Fat: 15g"}
135
  ]
136
 
137
+ nigerian_drinks = [
138
+ {"name": "Chapman", "description": "Popular Nigerian cocktail with a fruity, fizzy taste", "price": 1500, "nutrition": "Calories: 180 kcal, Carbs: 40g, Protein: 1g, Fat: 0g"},
139
+ {"name": "VitaMilk", "description": "Healthy, protein-rich plant-based milk", "price": 1000, "nutrition": "Calories: 180 kcal, Carbs: 20g, Protein: 8g, Fat: 6g"},
140
+ {"name": "Malt Drink", "description": "Non-alcoholic malt-based drink", "price": 1000, "nutrition": "Calories: 200 kcal, Carbs: 50g, Protein: 2g, Fat: 0g"},
141
+ {"name": "Soft Drinks", "description": "Carbonated sodas like Coke, Fanta, and Sprite", "price": 800, "nutrition": "Calories: 150 kcal, Carbs: 39g, Protein: 0g, Fat: 0g"},
142
+ {"name": "Bottled Water", "description": "Pure, refreshing drinking water", "price": 500, "nutrition": "Calories: 0 kcal, Carbs: 0g, Protein: 0g, Fat: 0g"},
143
+ {"name": "Energy Drink", "description": "Boost of energy with caffeine and vitamins", "price": 1500, "nutrition": "Calories: 200 kcal, Carbs: 50g, Protein: 1g, Fat: 0g"}
144
+ ]
145
+
146
+ menu_items.extend(nigerian_drinks)
147
+
148
 
149
  class ConversationState:
150
  def __init__(self):
 
641
  return (f"Got it. {quantity} serving(s) of {dish}.\n"
642
  "Please provide your phone number and delivery address.")
643
 
644
+ # Step 4: Parse phone & address (for single or multi-dish orders), then skip extras.
645
  if state and state.flow == "order" and state.step == 3:
646
  phone_pattern = r'(\+?\d{10,15})'
647
  phone_match = re.search(phone_pattern, message)
 
648
  if phone_match:
649
  phone_number = phone_match.group(1)
650
  address_start = phone_match.end()
 
659
  else:
660
  return ("Please provide both your phone number and address. "
661
  "For example: '09162409591, 1, Iyana Isashi, Isashi, Lagos'.")
662
+ if not state.data.get("address"):
663
  return "Thank you. Please provide your delivery address."
664
  shipping_cost = calculate_shipping_cost(state.data["address"])
665
  state.data["shipping_cost"] = shipping_cost
666
+ # Automatically set extras to empty since we're not using extras anymore.
667
+ state.data["extras"] = ""
668
+ # Skip extras prompt and jump directly to confirmation (Step 7)
669
+ state.step = 7
670
  return (f"Thanks! Your phone number is recorded as: {state.data['phone_number']}.\n"
671
  f"Your delivery address is: {state.data['address']}.\n"
672
+ f"Your delivery cost is N{shipping_cost}.\n"
673
+ "Here is your order summary. Please confirm your order? (yes/no)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674
 
675
+
676
  # 7) Step 7: Order Confirmation and Payment Link Generation
677
  if state and state.flow == "order" and state.step == 7:
678
  if message.lower() in ["yes", "y"]:
679
  order_id = f"ORD-{int(time.time())}"
680
  state.data["order_id"] = order_id
681
+ # Calculate total price:
 
682
  if "orders" in state.data:
683
  total_price = 0
684
  for dish, qty in state.data["orders"].items():
 
690
  dish_summary = state.data.get("dish", "")
691
  quantity_total = state.data.get("quantity", 1)
692
  total_price = (quantity_total * get_dish_price(dish_summary)) + state.data.get("shipping_cost", 0)
 
693
  state.data["price"] = str(total_price)
694
 
695
  async def save_order():
 
708
  asyncio.create_task(save_order())
709
  asyncio.create_task(log_order_tracking(order_id, "Order Placed", "Order placed and awaiting payment."))
710
 
711
+ # Automatically set extras to empty
712
+ state.data["extras"] = ""
713
+
714
  # Prepare order details as a dictionary for the email notification.
715
  order_details = {
716
  "order_id": order_id,
 
728
  print("Failed to send email notification.")
729
 
730
  # Generate Paystack payment link (amount in kobo)
731
+ email_for_paystack = "customer@example.com"
732
  payment_data = create_paystack_payment_link(email_for_paystack, total_price * 100, order_id)
733
  state.reset()
734
  if user_id in user_state:
 
749
  else:
750
  return (f"Your order has been placed with Order ID {order_id}, "
751
  "but we could not initialize online payment. Please try again later, or "
752
+ "you may opt to pay via bank transfer to Account Number: 1433042821, Access Bank, Angelo Food Court 2 "
753
  "and send your payment screenshot to this chatbot.")
754
  elif message.lower() in ["no", "n"]:
755
+ state.reset()
756
+ if user_id in user_state:
757
+ del user_state[user_id]
758
+ return "Order canceled. Let me know if you'd like to try again."
759
  else:
760
  return "I didn't understand that. Please type 'yes' to confirm your order or 'no' to cancel it."
761