Fred808 commited on
Commit
ab89947
·
verified ·
1 Parent(s): b3f38b0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -107
app.py CHANGED
@@ -510,55 +510,56 @@ async def process_order_flow(user_id: str, message: str) -> str:
510
 
511
  # 2) If we are not already in the order flow, detect dish(es) from the message.
512
  if not state or state.flow != "order":
513
- matched = match_dishes(message)
514
- if matched:
515
- if len(matched) == 1:
516
- # Single dish: store in state.data["dish"]
517
- found_dish = matched[0]
518
- state = ConversationState()
519
- state.flow = "order"
520
- state.update_last_active()
521
- user_state[user_id] = state
522
- state.data["dish"] = found_dish
523
- # Try to parse quantity, phone, address from the same message.
524
- single_parse = _parse_single_dish_line(message, found_dish)
525
- if single_parse["quantity"]:
526
- state.data["quantity"] = single_parse["quantity"]
527
- state.step = 3
528
- else:
529
- state.step = 2
530
- if single_parse["phone"]:
531
- state.data["phone_number"] = single_parse["phone"]
532
- if single_parse["address"]:
533
- state.data["address"] = single_parse["address"]
534
- if state.step == 2 and not state.data.get("quantity"):
535
- return f"You selected {found_dish}. How many servings would you like?"
536
- elif state.step == 3:
537
- if state.data.get("phone_number") and state.data.get("address"):
538
- shipping_cost = calculate_shipping_cost(state.data["address"])
539
- state.data["shipping_cost"] = shipping_cost
540
- state.step = 5
541
- return (f"Thanks! Your phone number is recorded as: {state.data['phone_number']}.\n"
542
- f"Your delivery address is: {state.data['address']}.\n"
543
- f"Your delivery cost is N{shipping_cost}. Would you like extras (yes/no)?")
544
- elif state.data.get("phone_number") and not state.data.get("address"):
545
- return "Thank you. Please provide your delivery address."
546
- else:
547
- return "Please provide your phone number and address."
548
  else:
549
- # Multiple dishes detected—allow unlimited dishes.
550
- state = ConversationState()
551
- state.flow = "order"
552
- state.update_last_active()
553
- user_state[user_id] = state
554
- state.data["dishes"] = matched # Store all matched dishes
555
  state.step = 2
556
- dish_options = ", ".join(matched)
557
- return (f"You have selected the following dishes: {dish_options}.\n"
558
- "How many servings of each would you like? "
559
- "For example: '2 for Jollof Rice, 3 for Chicken Wings, 1 for Fish'")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
560
  else:
561
- return "I couldn't identify the dish. Please type the dish name from our menu."
 
 
 
 
 
 
 
 
 
 
 
 
 
562
 
563
  # 3) If state exists and we're at step 2: parse quantity details.
564
  if state and state.flow == "order" and state.step == 2:
@@ -692,68 +693,68 @@ async def process_order_flow(user_id: str, message: str) -> str:
692
 
693
  # 7) Step 7: Order Confirmation and Payment Link Generation
694
  if state and state.flow == "order" and state.step == 7:
695
- if message.lower() in ["yes", "y"]:
696
- order_id = f"ORD-{int(time.time())}"
697
- state.data["order_id"] = order_id
698
- # Handle both single-dish and multi-dish orders:
699
- if "orders" in state.data:
700
- total_price = 0
701
- for dish, qty in state.data["orders"].items():
702
- total_price += get_dish_price(dish) * qty
703
- # Add shipping cost once.
704
- total_price += state.data.get("shipping_cost", 0)
705
- dish_summary = ", ".join(state.data["orders"].keys())
706
- quantity_total = sum(state.data["orders"].values())
707
- else:
708
- dish_summary = state.data.get("dish", "")
709
- quantity_total = state.data.get("quantity", 1)
710
- total_price = (quantity_total * get_dish_price(dish_summary)) + state.data.get("shipping_cost", 0)
711
- state.data["price"] = str(total_price)
712
-
713
- async def save_order():
714
- async with async_session() as session:
715
- order = Order(
716
- order_id=order_id,
717
- user_id=user_id,
718
- dish=dish_summary,
719
- quantity=str(quantity_total),
720
- price=str(total_price),
721
- status="Pending Payment",
722
- delivery_address=state.data.get("address", "")
723
- )
724
- session.add(order)
725
- await session.commit()
726
- asyncio.create_task(save_order())
727
- asyncio.create_task(log_order_tracking(order_id, "Order Placed", "Order placed and awaiting payment."))
728
-
729
- email_for_paystack = "customer@example.com" # Replace with actual email if available
730
- payment_data = create_paystack_payment_link(email_for_paystack, total_price * 100, order_id)
731
- state.reset()
732
- if user_id in user_state:
733
- del user_state[user_id]
734
- if payment_data.get("status"):
735
- payment_link = payment_data["data"]["authorization_url"]
736
- return (f"Thank you for your order of {quantity_total} serving(s) of {dish_summary}! "
737
- f"Your Order ID is {order_id}.\n\n"
738
- "Please complete your payment using one of the following options:\n"
739
- f"1. Pay online via our Paystack link: {payment_link}\n"
740
- "2. Alternatively, you can make a bank transfer to the following account:\n"
741
- " Account Number: 1433042821\n"
742
- " Bank: Access Bank\n"
743
- " Account Name: Angelo Food Court 2\n\n"
744
- "If you choose the bank transfer option, please send a screenshot of your payment confirmation to this chatbot.\n\n"
745
- "You can track your order status using your Order ID.\n"
746
- "Is there anything else you'd like to order?")
747
- else:
748
- return (f"Your order has been placed with Order ID {order_id}, "
749
- "but we could not initialize online payment. Please try again later, or "
750
- "you may opt to pay via bank transfer to Account Number 1433042821, Access Bank, Angelo Food Court 2 "
751
- "and send your payment screenshot to this chatbot.")
752
  else:
753
- state.reset()
754
- if user_id in user_state:
755
- del user_state[user_id]
756
- return "Order canceled. Let me know if you'd like to try again."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
757
 
758
  # Final fallback
759
  return ""
 
510
 
511
  # 2) If we are not already in the order flow, detect dish(es) from the message.
512
  if not state or state.flow != "order":
513
+ matched = match_dishes(message)
514
+ if matched:
515
+ if len(matched) == 1:
516
+ # Single dish order
517
+ found_dish = matched[0]
518
+ state = ConversationState()
519
+ state.flow = "order"
520
+ state.update_last_active()
521
+ user_state[user_id] = state
522
+ state.data["dish"] = found_dish
523
+ # Try to parse quantity, phone, address from the same message.
524
+ single_parse = _parse_single_dish_line(message, found_dish)
525
+ if single_parse["quantity"]:
526
+ state.data["quantity"] = single_parse["quantity"]
527
+ state.step = 3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
  else:
 
 
 
 
 
 
529
  state.step = 2
530
+ if single_parse["phone"]:
531
+ state.data["phone_number"] = single_parse["phone"]
532
+ if single_parse["address"]:
533
+ state.data["address"] = single_parse["address"]
534
+ if state.step == 2 and not state.data.get("quantity"):
535
+ return f"You selected {found_dish}. How many servings would you like?"
536
+ elif state.step == 3:
537
+ if state.data.get("phone_number") and state.data.get("address"):
538
+ shipping_cost = calculate_shipping_cost(state.data["address"])
539
+ state.data["shipping_cost"] = shipping_cost
540
+ state.step = 5
541
+ return (f"Thanks! Your phone number is recorded as: {state.data['phone_number']}.\n"
542
+ f"Your delivery address is: {state.data['address']}.\n"
543
+ f"Your delivery cost is N{shipping_cost}. Would you like extras (yes/no)?")
544
+ elif state.data.get("phone_number") and not state.data.get("address"):
545
+ return "Thank you. Please provide your delivery address."
546
+ else:
547
+ return "Please provide your phone number and address."
548
  else:
549
+ # Multiple dishes detected support unlimited dishes.
550
+ state = ConversationState()
551
+ state.flow = "order"
552
+ state.update_last_active()
553
+ user_state[user_id] = state
554
+ state.data["dishes"] = matched # Store all matched dishes
555
+ state.step = 2
556
+ dish_options = ", ".join(matched)
557
+ return (f"You have selected the following dishes: {dish_options}.\n"
558
+ "How many servings of each would you like? "
559
+ "For example: '2 for Jollof Rice, 3 for Chicken, 1 for Fish'")
560
+ else:
561
+ return "I couldn't identify the dish. Please type the dish name from our menu."
562
+
563
 
564
  # 3) If state exists and we're at step 2: parse quantity details.
565
  if state and state.flow == "order" and state.step == 2:
 
693
 
694
  # 7) Step 7: Order Confirmation and Payment Link Generation
695
  if state and state.flow == "order" and state.step == 7:
696
+ if message.lower() in ["yes", "y"]:
697
+ order_id = f"ORD-{int(time.time())}"
698
+ state.data["order_id"] = order_id
699
+ # Calculate total price differently for multi-dish orders:
700
+ if "orders" in state.data:
701
+ total_price = 0
702
+ for dish, qty in state.data["orders"].items():
703
+ total_price += get_dish_price(dish) * qty
704
+ total_price += state.data.get("shipping_cost", 0)
705
+ dish_summary = ", ".join(state.data["orders"].keys())
706
+ quantity_total = sum(state.data["orders"].values())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
707
  else:
708
+ dish_summary = state.data.get("dish", "")
709
+ quantity_total = state.data.get("quantity", 1)
710
+ total_price = (quantity_total * get_dish_price(dish_summary)) + state.data.get("shipping_cost", 0)
711
+ state.data["price"] = str(total_price)
712
+
713
+ async def save_order():
714
+ async with async_session() as session:
715
+ order = Order(
716
+ order_id=order_id,
717
+ user_id=user_id,
718
+ dish=dish_summary,
719
+ quantity=str(quantity_total),
720
+ price=str(total_price),
721
+ status="Pending Payment",
722
+ delivery_address=state.data.get("address", "")
723
+ )
724
+ session.add(order)
725
+ await session.commit()
726
+ asyncio.create_task(save_order())
727
+ asyncio.create_task(log_order_tracking(order_id, "Order Placed", "Order placed and awaiting payment."))
728
+
729
+ # Email notification and payment link code here (omitted for brevity)
730
+ email_for_paystack = "customer@example.com"
731
+ payment_data = create_paystack_payment_link(email_for_paystack, total_price * 100, order_id)
732
+ state.reset()
733
+ if user_id in user_state:
734
+ del user_state[user_id]
735
+ if payment_data.get("status"):
736
+ payment_link = payment_data["data"]["authorization_url"]
737
+ return (f"Thank you for your order of {quantity_total} serving(s) of {dish_summary}! "
738
+ f"Your Order ID is {order_id}.\n\n"
739
+ "Please complete your payment using one of the following options:\n"
740
+ f"1. Pay online via our Paystack link: {payment_link}\n"
741
+ "2. Alternatively, you can make a bank transfer to the following account:\n"
742
+ " Account Number: 1433042821\n"
743
+ " Bank: Access Bank\n"
744
+ " Account Name: Angelo Food Court 2\n\n"
745
+ "If you choose the bank transfer option, please send a screenshot of your payment confirmation to this chatbot.\n\n"
746
+ "You can track your order status using your Order ID.\n"
747
+ "Is there anything else you'd like to order?")
748
+ else:
749
+ return (f"Your order has been placed with Order ID {order_id}, "
750
+ "but we could not initialize online payment. Please try again later, or "
751
+ "you may opt to pay via bank transfer to Account Number 1433042821, Access Bank, Angelo Food Court 2 "
752
+ "and send your payment screenshot to this chatbot.")
753
+ elif message.lower() in ["no", "n"]:
754
+ state.reset()
755
+ if user_id in user_state:
756
+ del user_state[user_id]
757
+ return "Order canceled. Let me know if you'd like to try again."
758
 
759
  # Final fallback
760
  return ""