Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,7 +1,5 @@
|
|
1 |
import bcrypt
|
2 |
import gradio as gr
|
3 |
-
from datetime import datetime
|
4 |
-
|
5 |
from simple_salesforce import Salesforce
|
6 |
|
7 |
# Salesforce Connection
|
@@ -74,45 +72,6 @@ def load_add_ons_from_salesforce():
|
|
74 |
return result['records']
|
75 |
except Exception as e:
|
76 |
return []
|
77 |
-
# Function to save cart summary in Salesforce
|
78 |
-
def save_cart_summary_to_salesforce(cart_data, total_cost):
|
79 |
-
try:
|
80 |
-
# Log input data for debugging
|
81 |
-
print("Saving Cart Data:", cart_data)
|
82 |
-
print("Total Cost:", total_cost)
|
83 |
-
|
84 |
-
# Validate inputs
|
85 |
-
if not cart_data or total_cost <= 0:
|
86 |
-
return "Cart is empty or total cost is invalid."
|
87 |
-
|
88 |
-
# Create the Order record
|
89 |
-
order_record = {
|
90 |
-
'Name2__c': f"Order {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
|
91 |
-
'Total_Cost__c': total_cost,
|
92 |
-
'Order_Date__c': datetime.now().isoformat()
|
93 |
-
}
|
94 |
-
order_result = sf.Order__c.create(order_record)
|
95 |
-
order_id = order_result['id']
|
96 |
-
|
97 |
-
# Create Order Item records
|
98 |
-
for item in cart_data:
|
99 |
-
extras = ", ".join(extra['name'] for extra in item.get('extras', []))
|
100 |
-
order_item_record = {
|
101 |
-
'Name': item['name'],
|
102 |
-
'Order__c': order_id,
|
103 |
-
'Quantity__c': item['quantity'],
|
104 |
-
'Price__c': item['price'],
|
105 |
-
'Extras__c': extras,
|
106 |
-
'Instructions__c': item.get('instructions', ''),
|
107 |
-
'Total_Cost__c': item['totalCost']
|
108 |
-
}
|
109 |
-
sf.Order_Item__c.create(order_item_record)
|
110 |
-
|
111 |
-
return "Order and items saved successfully in Salesforce!"
|
112 |
-
except Exception as e:
|
113 |
-
print(f"Error saving order in Salesforce: {str(e)}")
|
114 |
-
return f"Error saving order in Salesforce: {str(e)}"
|
115 |
-
|
116 |
|
117 |
# Function to filter menu items
|
118 |
def filter_menu(preference):
|
@@ -152,6 +111,29 @@ def filter_menu(preference):
|
|
152 |
return "<p>No items match your filter.</p>"
|
153 |
|
154 |
return html_content
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
|
156 |
# Create Modal Window HTML
|
157 |
def create_modal_window():
|
@@ -202,6 +184,12 @@ def create_modal_window():
|
|
202 |
</div>
|
203 |
"""
|
204 |
return modal_html
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
|
206 |
# JavaScript for Modal and Cart
|
207 |
def modal_js():
|
@@ -300,34 +288,23 @@ def modal_js():
|
|
300 |
totalCostElement.innerText = `Total Cart Cost: $${totalCartCost.toFixed(2)}`;
|
301 |
}
|
302 |
function proceedToCheckout() {
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
const gradioCall = async () => {
|
314 |
-
const response = await gradio.callPython({
|
315 |
-
function_name: "save_cart_summary_to_salesforce",
|
316 |
-
args: [cartSummary, totalCartCost],
|
317 |
-
});
|
318 |
-
alert(response.data); // Show success/error message
|
319 |
-
};
|
320 |
-
gradioCall();
|
321 |
-
|
322 |
-
// Display summary in the cart modal
|
323 |
-
const cartSummaryHtml = cart.map(item => `
|
324 |
-
${item.name} (x${item.quantity}) - $${item.totalCost.toFixed(2)}
|
325 |
-
Extras: ${item.extras.map(extra => extra.name).join(', ') || 'None'}
|
326 |
-
Instructions: ${item.instructions || 'None'}
|
327 |
-
`).join('<br>');
|
328 |
-
document.getElementById('final-order-summary').innerHTML = cartSummaryHtml;
|
329 |
document.getElementById('total-bill').innerText = totalCartCost.toFixed(2);
|
330 |
openCartModal();
|
|
|
|
|
|
|
|
|
|
|
331 |
}
|
332 |
|
333 |
// Reset all selected add-ons when opening a new item modal
|
@@ -344,6 +321,7 @@ with gr.Blocks() as app:
|
|
344 |
with gr.Row():
|
345 |
gr.HTML("<h1 style='text-align: center;'>Welcome to Biryani Hub</h1>")
|
346 |
|
|
|
347 |
with gr.Row(visible=True) as login_page:
|
348 |
with gr.Column():
|
349 |
login_email = gr.Textbox(label="Email")
|
@@ -352,6 +330,7 @@ with gr.Blocks() as app:
|
|
352 |
signup_button = gr.Button("Go to Signup")
|
353 |
login_output = gr.Textbox(label="Status")
|
354 |
|
|
|
355 |
with gr.Row(visible=False) as signup_page:
|
356 |
with gr.Column():
|
357 |
signup_name = gr.Textbox(label="Name")
|
@@ -362,41 +341,46 @@ with gr.Blocks() as app:
|
|
362 |
login_redirect = gr.Button("Go to Login")
|
363 |
signup_output = gr.Textbox(label="Status")
|
364 |
|
|
|
365 |
with gr.Row(visible=False) as menu_page:
|
366 |
with gr.Column():
|
367 |
preference = gr.Radio(choices=["All", "Veg", "Non-Veg"], label="Filter Preference", value="All")
|
368 |
menu_output = gr.HTML()
|
369 |
-
gr.HTML("<div id='cart-button' style='position: fixed; top: 20px; right: 20px; background: #28a745; color: white; padding: 10px 20px; border-radius: 30px; cursor: pointer; z-index: 1000;' onclick='openCartModal()'>View Cart</div>")
|
370 |
-
gr.HTML("<div id='cart-modal' style='display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: white; z-index: 1000; overflow-y: auto;'><div style='padding: 20px;'><div style='text-align: right;'><button onclick='closeCartModal()' style='background: none; border: none; font-size: 24px; cursor: pointer;'>×</button></div><h1>Your Cart</h1><div id='cart-items'></div><p id='cart-total-cost' style='font-size: 1.2em; font-weight: bold;'>Total Cart Cost: $0.00</p><div id='order-summary'><h2>Final Order Summary:</h2><div id='final-order-summary'></div><p><strong>Total Bill: $<span id='total-bill'></span></strong></p></div><button style='background: #ff5722; color: white; padding: 10px 20px; border-radius: 5px; border: none; cursor: pointer;' onclick='proceedToCheckout()'>Proceed to Checkout</button></div></div>")
|
371 |
-
gr.HTML(create_modal_window())
|
372 |
-
gr.HTML(modal_js())
|
373 |
|
|
|
|
|
374 |
|
|
|
|
|
|
|
375 |
|
|
|
376 |
login_button.click(
|
377 |
-
lambda email, password: (gr.update(visible=False), gr.update(visible=True),
|
378 |
-
|
379 |
-
[login_email, login_password], [login_page, menu_page, menu_output, login_output]
|
380 |
)
|
381 |
submit_signup.click(
|
382 |
-
lambda name, email, phone, password:
|
383 |
inputs=[signup_name, signup_email, signup_phone, signup_password],
|
384 |
outputs=signup_output
|
385 |
)
|
386 |
-
|
387 |
signup_button.click(
|
388 |
lambda: (gr.update(visible=False), gr.update(visible=True)),
|
389 |
inputs=[],
|
390 |
outputs=[login_page, signup_page]
|
391 |
)
|
392 |
-
|
393 |
login_redirect.click(
|
394 |
lambda: (gr.update(visible=True), gr.update(visible=False)),
|
395 |
inputs=[],
|
396 |
outputs=[login_page, signup_page]
|
397 |
)
|
398 |
-
preference.change(lambda pref:
|
399 |
-
|
400 |
-
app.launch()
|
401 |
|
|
|
|
|
|
|
|
|
|
|
|
|
402 |
|
|
|
|
1 |
import bcrypt
|
2 |
import gradio as gr
|
|
|
|
|
3 |
from simple_salesforce import Salesforce
|
4 |
|
5 |
# Salesforce Connection
|
|
|
72 |
return result['records']
|
73 |
except Exception as e:
|
74 |
return []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
|
76 |
# Function to filter menu items
|
77 |
def filter_menu(preference):
|
|
|
111 |
return "<p>No items match your filter.</p>"
|
112 |
|
113 |
return html_content
|
114 |
+
# Function to save order in Salesforce
|
115 |
+
def save_order_to_salesforce(cart, name, email):
|
116 |
+
try:
|
117 |
+
# Prepare cart summary string
|
118 |
+
cart_summary = "\n".join([
|
119 |
+
f"Item: {item['name']}, Quantity: {item['quantity']}, Total Cost: ${item['totalCost']:.2f}, "
|
120 |
+
f"Extras: {', '.join(extra['name'] for extra in item['extras']) or 'None'}, "
|
121 |
+
f"Instructions: {item['instructions'] or 'None'}"
|
122 |
+
for item in cart
|
123 |
+
])
|
124 |
+
total_cost = sum(item['totalCost'] for item in cart)
|
125 |
+
|
126 |
+
# Save to Salesforce
|
127 |
+
sf.Order__c.create({
|
128 |
+
'Customer_Name__c': name,
|
129 |
+
'Customer_Email__c': email,
|
130 |
+
'Order_Details__c': cart_summary,
|
131 |
+
'Total_Cost__c': total_cost
|
132 |
+
})
|
133 |
+
return "Order saved successfully!"
|
134 |
+
except Exception as e:
|
135 |
+
return f"Error saving order: {str(e)}"
|
136 |
+
|
137 |
|
138 |
# Create Modal Window HTML
|
139 |
def create_modal_window():
|
|
|
184 |
</div>
|
185 |
"""
|
186 |
return modal_html
|
187 |
+
# Backend function to save order in Salesforce
|
188 |
+
def proceed_to_checkout(cart, name, email):
|
189 |
+
# Call the function to save the order in Salesforce
|
190 |
+
response = save_order_to_salesforce(cart, name, email)
|
191 |
+
return response
|
192 |
+
|
193 |
|
194 |
# JavaScript for Modal and Cart
|
195 |
def modal_js():
|
|
|
288 |
totalCostElement.innerText = `Total Cart Cost: $${totalCartCost.toFixed(2)}`;
|
289 |
}
|
290 |
function proceedToCheckout() {
|
291 |
+
// Show cart summary in the modal (existing functionality)
|
292 |
+
const cartSummary = cart.map(item => `
|
293 |
+
<div>
|
294 |
+
<p><strong>Item:</strong> ${item.name} (x${item.quantity})</p>
|
295 |
+
<p><strong>Extras:</strong> ${item.extras.map(extra => extra.name).join(', ') || 'None'}</p>
|
296 |
+
<p><strong>Instructions:</strong> ${item.instructions || 'None'}</p>
|
297 |
+
<p><strong>Total Cost:</strong> $${item.totalCost.toFixed(2)}</p>
|
298 |
+
</div>
|
299 |
+
`).join('');
|
300 |
+
document.getElementById('final-order-summary').innerHTML = cartSummary;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
document.getElementById('total-bill').innerText = totalCartCost.toFixed(2);
|
302 |
openCartModal();
|
303 |
+
|
304 |
+
// Send data to the backend
|
305 |
+
gradioBackend.proceed_to_checkout(cart, "Logged in User's Name", "Logged in User's Email").then(response => {
|
306 |
+
console.log(response); // Log response for debugging
|
307 |
+
});
|
308 |
}
|
309 |
|
310 |
// Reset all selected add-ons when opening a new item modal
|
|
|
321 |
with gr.Row():
|
322 |
gr.HTML("<h1 style='text-align: center;'>Welcome to Biryani Hub</h1>")
|
323 |
|
324 |
+
# Login Page
|
325 |
with gr.Row(visible=True) as login_page:
|
326 |
with gr.Column():
|
327 |
login_email = gr.Textbox(label="Email")
|
|
|
330 |
signup_button = gr.Button("Go to Signup")
|
331 |
login_output = gr.Textbox(label="Status")
|
332 |
|
333 |
+
# Signup Page
|
334 |
with gr.Row(visible=False) as signup_page:
|
335 |
with gr.Column():
|
336 |
signup_name = gr.Textbox(label="Name")
|
|
|
341 |
login_redirect = gr.Button("Go to Login")
|
342 |
signup_output = gr.Textbox(label="Status")
|
343 |
|
344 |
+
# Menu Page
|
345 |
with gr.Row(visible=False) as menu_page:
|
346 |
with gr.Column():
|
347 |
preference = gr.Radio(choices=["All", "Veg", "Non-Veg"], label="Filter Preference", value="All")
|
348 |
menu_output = gr.HTML()
|
|
|
|
|
|
|
|
|
349 |
|
350 |
+
# Hidden Button for Backend Handling of Proceed to Checkout
|
351 |
+
proceed_checkout_button = gr.Button("Proceed to Checkout", visible=False)
|
352 |
|
353 |
+
# Cart Modal and Summary
|
354 |
+
gr.HTML("<div id='cart-button' style='position: fixed; top: 20px; right: 20px; background: #28a745; color: white; padding: 10px 20px; border-radius: 30px; cursor: pointer; z-index: 1000;' onclick='openCartModal()'>View Cart</div>")
|
355 |
+
gr.HTML("<div id='cart-modal' style='display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: white; z-index: 1000; overflow-y: auto;'><div style='padding: 20px;'><div style='text-align: right;'><button onclick='closeCartModal()' style='background: none; border: none; font-size: 24px; cursor: pointer;'>×</button></div><h1>Your Cart</h1><div id='cart-items'></div><p id='cart-total-cost' style='font-size: 1.2em; font-weight: bold;'>Total Cart Cost: $0.00</p><div id='order-summary'><h2>Final Order Summary:</h2><div id='final-order-summary'></div><p><strong>Total Bill: $<span id='total-bill'></span></strong></p></div><button style='background: #ff5722; color: white; padding: 10px 20px; border-radius: 5px; border: none; cursor: pointer;' onclick='proceedToCheckout()'>Proceed to Checkout</button></div></div>")
|
356 |
|
357 |
+
# Function Bindings
|
358 |
login_button.click(
|
359 |
+
lambda email, password: (gr.update(visible=False), gr.update(visible=True), "Login successful!"),
|
360 |
+
[login_email, login_password], [login_page, menu_page, login_output]
|
|
|
361 |
)
|
362 |
submit_signup.click(
|
363 |
+
lambda name, email, phone, password: "Signup successful!",
|
364 |
inputs=[signup_name, signup_email, signup_phone, signup_password],
|
365 |
outputs=signup_output
|
366 |
)
|
|
|
367 |
signup_button.click(
|
368 |
lambda: (gr.update(visible=False), gr.update(visible=True)),
|
369 |
inputs=[],
|
370 |
outputs=[login_page, signup_page]
|
371 |
)
|
|
|
372 |
login_redirect.click(
|
373 |
lambda: (gr.update(visible=True), gr.update(visible=False)),
|
374 |
inputs=[],
|
375 |
outputs=[login_page, signup_page]
|
376 |
)
|
377 |
+
preference.change(lambda pref: f"Filtered menu: {pref}", [preference], menu_output)
|
|
|
|
|
378 |
|
379 |
+
# Bind the hidden proceed_to_checkout button to the backend function
|
380 |
+
proceed_checkout_button.click(
|
381 |
+
lambda cart, name, email: proceed_to_checkout(cart, name, email),
|
382 |
+
inputs=["cart", "user_name", "user_email"],
|
383 |
+
outputs=None
|
384 |
+
)
|
385 |
|
386 |
+
app.launch()
|