lokesh341 commited on
Commit
6283128
·
verified ·
1 Parent(s): d21dd50

Update menu.py

Browse files
Files changed (1) hide show
  1. menu.py +232 -375
menu.py CHANGED
@@ -1,454 +1,311 @@
1
  from flask import Blueprint, render_template, request, session, jsonify, redirect, url_for
2
  from salesforce import get_salesforce_connection
3
  import os
4
- import re
5
- import logging
6
- from urllib.parse import quote
7
- from datetime import datetime, timedelta
8
-
9
- # Initialize logging
10
- logging.basicConfig(level=logging.INFO)
11
- logger = logging.getLogger(__name__)
12
 
13
  menu_blueprint = Blueprint('menu', __name__)
14
 
15
  # Initialize Salesforce connection
16
  sf = get_salesforce_connection()
17
 
18
- # Constants
19
- STATIC_DIR = os.path.join(os.path.dirname(__file__), '..', 'static')
20
  PLACEHOLDER_VIDEO = 'placeholder.mp4'
21
- PLACEHOLDER_IMAGE = 'placeholder.jpg'
22
- PLACEHOLDER_VIDEO_PATH = os.path.join(STATIC_DIR, PLACEHOLDER_VIDEO)
23
- PLACEHOLDER_IMAGE_PATH = os.path.join(STATIC_DIR, PLACEHOLDER_IMAGE)
24
- SECTION_ORDER = ["Best Sellers", "Starters", "Biryanis", "Curries", "Breads",
25
- "Customized Dish", "Appetizer", "Desserts", "Soft Drinks"]
26
- MAX_BEST_SELLERS = 4
27
- DEFAULT_VIDEO_URL = "https://yourdomain.my.salesforce.com/sfc/servlet.shepherd/version/download/"
28
-
29
- # Custom Jinja2 filter
30
- def slugify(text):
31
- """Convert text to a slug format (lowercase, replace spaces with hyphens)"""
32
- if not text:
33
- return ""
34
- text = text.lower()
35
- text = re.sub(r'[^\w\s-]', '', text) # Remove non-alphanumeric chars
36
- text = re.sub(r'[\s-]+', '-', text) # Replace spaces and multiple hyphens with single hyphen
37
- return text
38
-
39
- # Register the filter with the blueprint
40
- @menu_blueprint.app_template_filter('slugify')
41
- def slugify_filter(s):
42
- return slugify(s)
43
-
44
- def initialize_placeholders():
45
- """Create placeholder files if they don't exist"""
46
- try:
47
- if not os.path.exists(PLACEHOLDER_VIDEO_PATH):
48
- with open(PLACEHOLDER_VIDEO_PATH, 'wb') as f:
49
- f.write(b'') # Empty file
50
- logger.info(f"Created placeholder video at {PLACEHOLDER_VIDEO_PATH}")
51
-
52
- if not os.path.exists(PLACEHOLDER_IMAGE_PATH):
53
- with open(PLACEHOLDER_IMAGE_PATH, 'wb') as f:
54
- f.write(b'') # Empty file
55
- logger.info(f"Created placeholder image at {PLACEHOLDER_IMAGE_PATH}")
56
- except Exception as e:
57
- logger.error(f"Error creating placeholder files: {str(e)}")
58
 
59
- initialize_placeholders()
 
 
 
60
 
61
- def get_valid_media_path(media_url=None, media_type='video'):
62
  """
63
- Get valid media path with placeholder fallback
64
- Args:
65
- media_url: URL or ID from Salesforce
66
- media_type: 'video' or 'image'
67
- Returns:
68
- Valid URL for the media
69
  """
70
- # Default placeholders
71
- default_path = f"/static/{PLACEHOLDER_VIDEO if media_type == 'video' else PLACEHOLDER_IMAGE}"
72
-
73
- if not media_url:
74
- return default_path
75
-
76
- # Handle Salesforce File ID (starts with '069')
77
- if media_url.startswith('069'):
78
- return f"{DEFAULT_VIDEO_URL}{media_url}"
79
-
80
- # Handle complete URLs
81
- if media_url.startswith(('http://', 'https://')):
82
- return media_url
83
 
84
- # Handle relative paths
85
- if media_url.startswith('/'):
86
- return media_url
 
87
 
88
- return default_path
89
 
90
- def validate_user_session():
91
- """Validate and return user session data or redirect to login"""
 
92
  user_email = session.get('user_email')
93
- user_name = session.get('user_name')
94
-
95
  if not user_email:
96
- user_email = request.args.get('email')
97
- user_name = request.args.get('name')
98
-
99
  if user_email:
100
  session['user_email'] = user_email
101
  session['user_name'] = user_name
102
  else:
103
- return None, None, redirect(url_for("login"))
104
-
 
 
105
  first_letter = user_name[0].upper() if user_name else "A"
106
- return user_email, first_letter, None
107
 
108
- def get_user_details(sf_connection, email):
109
- """Fetch user details from Salesforce"""
110
  try:
111
- query = f"""
112
- SELECT Id, Referral__c, Reward_Points__c
113
- FROM Customer_Login__c
114
- WHERE Email__c = '{email}'
115
- """
116
- result = sf_connection.query(query)
117
-
118
- if not result['records']:
119
- return None
120
-
121
- return {
122
- 'referral_code': result['records'][0].get('Referral__c', 'N/A'),
123
- 'reward_points': result['records'][0].get('Reward_Points__c', 0)
124
- }
125
- except Exception as e:
126
- logger.error(f"Error fetching user details: {str(e)}")
127
- return None
128
 
129
- def get_cart_count(sf_connection, email):
130
- """Get cart item count for user"""
131
- try:
132
- query = f"SELECT COUNT() FROM Cart_Item__c WHERE Customer_Email__c = '{email}'"
133
- result = sf_connection.query(query)
134
- return result['totalSize']
135
- except Exception as e:
136
- logger.error(f"Error fetching cart count: {str(e)}")
137
- return 0
138
 
139
- def fetch_menu_items(sf_connection, selected_category):
140
- """Fetch and process menu items from Salesforce"""
141
- try:
142
- # Query for standard menu items
 
 
 
 
 
143
  menu_query = """
144
- SELECT Id, Name, Price__c, Description__c, Image1__c, Image2__c,
145
- Veg_NonVeg__c, Section__c, Total_Ordered__c, Video1__c,
146
- Is_Available__c, Spice_Level__c, Preparation_Time__c
147
  FROM Menu_Item__c
148
- WHERE Is_Available__c = true
149
  """
150
- menu_result = sf_connection.query(menu_query)
151
- food_items = menu_result.get('records', [])
152
-
153
- # Query for custom dishes (last 7 days)
 
 
 
 
 
 
154
  custom_dish_query = """
155
- SELECT Id, Name, Price__c, Description__c, Image1__c, Image2__c,
156
- Veg_NonVeg__c, Section__c, Total_Ordered__c, Is_Available__c
157
  FROM Custom_Dish__c
158
- WHERE CreatedDate >= LAST_N_DAYS:7 AND Is_Available__c = true
159
  """
160
- custom_dish_result = sf_connection.query(custom_dish_query)
161
  custom_dishes = custom_dish_result.get('records', [])
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
- # Process and merge items
164
- all_items = []
165
-
166
- for item in food_items + custom_dishes:
167
- processed_item = {
168
- 'id': item.get('Id'),
169
- 'name': item.get('Name', 'Unnamed Item'),
170
- 'price': item.get('Price__c', 0),
171
- 'description': item.get('Description__c', 'No description available'),
172
- 'image1': get_valid_media_path(item.get('Image1__c'), 'image'),
173
- 'image2': get_valid_media_path(item.get('Image2__c'), 'image'),
174
- 'video': get_valid_media_path(item.get('Video1__c'), 'video'),
175
- 'veg_non_veg': item.get('Veg_NonVeg__c', 'Unknown'),
176
- 'section': item.get('Section__c', 'Others'),
177
- 'total_ordered': item.get('Total_Ordered__c', 0),
178
- 'is_available': item.get('Is_Available__c', True),
179
- 'spice_level': item.get('Spice_Level__c', 'Medium'),
180
- 'prep_time': item.get('Preparation_Time__c', 20)
181
- }
182
-
183
- # Apply category filter
184
- if selected_category == "Veg" and processed_item['veg_non_veg'] not in ["Veg", "both"]:
185
  continue
186
- if selected_category == "Non veg" and processed_item['veg_non_veg'] not in ["Non veg", "both"]:
187
  continue
188
-
189
- all_items.append(processed_item)
190
-
191
- return all_items
192
-
193
- except Exception as e:
194
- logger.error(f"Error fetching menu items: {str(e)}")
195
- return []
196
 
197
- def organize_menu_items(items, selected_category):
198
- """Organize menu items into sections"""
199
- ordered_menu = {section: [] for section in SECTION_ORDER}
200
- added_item_ids = set()
201
-
202
- # Process best sellers
203
- best_sellers = sorted(
204
- [item for item in items if item['total_ordered'] > 0],
205
- key=lambda x: x['total_ordered'],
206
- reverse=True
207
- )[:MAX_BEST_SELLERS]
208
-
209
- if best_sellers:
210
- ordered_menu["Best Sellers"] = best_sellers
211
- added_item_ids.update(item['id'] for item in best_sellers)
212
-
213
- # Organize other sections
214
- for item in items:
215
- if item['id'] in added_item_ids:
216
- continue
217
-
218
- section = item['section']
219
- if section not in ordered_menu:
220
- section = "Others" # Fallback section
221
-
222
- ordered_menu[section].append(item)
223
- added_item_ids.add(item['id'])
224
-
225
- # Remove empty sections
226
- return {section: items for section, items in ordered_menu.items() if items}
227
 
228
- @menu_blueprint.route("/menu", methods=["GET"])
229
- def menu():
230
- # Validate session
231
- user_email, first_letter, redirect_response = validate_user_session()
232
- if redirect_response:
233
- return redirect_response
234
-
235
- selected_category = request.args.get("category", "All")
236
-
237
- try:
238
- # Get user details
239
- user_details = get_user_details(sf, user_email)
240
- if not user_details:
241
- return redirect(url_for('login'))
242
-
243
- # Get cart count
244
- cart_item_count = get_cart_count(sf, user_email)
245
-
246
- # Fetch and organize menu items
247
- all_items = fetch_menu_items(sf, selected_category)
248
- ordered_menu = organize_menu_items(all_items, selected_category)
249
-
250
- # Prepare categories
251
  categories = ["All", "Veg", "Non veg"]
252
-
253
- return render_template(
254
- "menu.html",
255
- ordered_menu=ordered_menu,
256
- categories=categories,
257
- selected_category=selected_category,
258
- referral_code=user_details['referral_code'],
259
- reward_points=user_details['reward_points'],
260
- user_name=session.get('user_name'),
261
- first_letter=first_letter,
262
- cart_item_count=cart_item_count
263
- )
264
-
265
  except Exception as e:
266
- logger.error(f"Error in menu route: {str(e)}")
267
- # Fallback data
268
- return render_template(
269
- "menu.html",
270
- ordered_menu={},
271
- categories=["All", "Veg", "Non veg"],
272
- selected_category=selected_category,
273
- referral_code='N/A',
274
- reward_points=0,
275
- user_name=session.get('user_name'),
276
- first_letter=first_letter,
277
- cart_item_count=0,
278
- error_message="We're experiencing technical difficulties. Please try again later."
279
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
 
281
  @menu_blueprint.route('/api/addons', methods=['GET'])
282
  def get_addons():
 
 
 
 
 
 
283
  try:
284
- item_name = request.args.get('item_name', '').strip()
285
- item_section = request.args.get('item_section', '').strip()
286
-
287
- if not item_name or not item_section:
288
- return jsonify({
289
- "success": False,
290
- "error": "Item name and section are required."
291
- }), 400
292
-
293
- # Query customization options
294
  query = f"""
295
- SELECT Id, Name, Customization_Type__c, Options__c,
296
- Max_Selections__c, Extra_Charge__c, Extra_Charge_Amount__c,
297
- Is_Active__c
298
  FROM Customization_Options__c
299
  WHERE Section__c = '{item_section}'
300
- AND Is_Active__c = true
301
- ORDER BY Display_Order__c NULLS LAST
302
  """
303
  result = sf.query(query)
304
  addons = result.get('records', [])
305
-
306
  if not addons:
307
- return jsonify({
308
- "success": False,
309
- "error": "No customization options found."
310
- }), 404
311
-
312
- # Format response
313
  formatted_addons = []
314
  for addon in addons:
315
  options = addon.get("Options__c", "")
316
- options = [opt.strip() for opt in options.split(",")] if options else []
317
-
 
 
 
318
  formatted_addons.append({
319
- "id": addon.get("Id"),
320
- "name": addon.get("Name"),
321
- "type": addon.get("Customization_Type__c", "checkbox"),
322
  "options": options,
323
  "max_selections": addon.get("Max_Selections__c", 1),
324
  "extra_charge": addon.get("Extra_Charge__c", False),
325
- "extra_charge_amount": float(addon.get("Extra_Charge_Amount__c", 0))
326
  })
327
-
328
- return jsonify({
329
- "success": True,
330
- "addons": formatted_addons
331
- })
332
-
333
  except Exception as e:
334
- logger.error(f"Error in get_addons: {str(e)}")
335
- return jsonify({
336
- "success": False,
337
- "error": "An error occurred while fetching options."
338
- }), 500
339
 
340
  @menu_blueprint.route('/cart/add', methods=['POST'])
341
  def add_to_cart():
342
  try:
343
- # Validate session
344
- if 'user_email' not in session:
345
- return jsonify({
346
- "success": False,
347
- "error": "Authentication required."
348
- }), 401
349
-
350
- # Validate input
351
- data = request.get_json()
352
- if not data:
353
- return jsonify({
354
- "success": False,
355
- "error": "Invalid JSON data."
356
- }), 400
357
-
358
- required_fields = ['itemName', 'itemPrice', 'itemImage', 'section']
359
- for field in required_fields:
360
- if field not in data or not data[field]:
361
- return jsonify({
362
- "success": False,
363
- "error": f"Missing required field: {field}"
364
- }), 400
365
-
366
- # Prepare data
367
- item_data = {
368
- 'name': data['itemName'].strip(),
369
- 'price': float(data['itemPrice']),
370
- 'image': data['itemImage'].strip(),
371
- 'section': data['section'].strip(),
372
- 'category': data.get('category', ''),
373
- 'addons': data.get('addons', []),
374
- 'instructions': data.get('instructions', '').strip(),
375
- 'quantity': int(data.get('quantity', 1)),
376
- 'customer_email': session['user_email']
377
- }
378
-
379
- # Calculate addons
380
- addons_price = sum(float(addon.get('price', 0)) for addon in item_data['addons'])
381
- addons_string = "; ".join(
382
- f"{addon.get('name', '')} (${addon.get('price', 0):.2f})"
383
- for addon in item_data['addons']
384
- ) if item_data['addons'] else "None"
385
-
386
- total_price = (item_data['price'] * item_data['quantity']) + addons_price
387
-
388
- # Check if item already exists in cart
389
  query = f"""
390
  SELECT Id, Quantity__c, Add_Ons__c, Add_Ons_Price__c, Instructions__c
391
  FROM Cart_Item__c
392
- WHERE Customer_Email__c = '{item_data['customer_email']}'
393
- AND Name = '{item_data['name']}'
394
- LIMIT 1
395
  """
396
  result = sf.query(query)
397
- existing_items = result.get('records', [])
398
-
399
- if existing_items:
400
- # Update existing item
401
- existing_item = existing_items[0]
402
- new_quantity = existing_item['Quantity__c'] + item_data['quantity']
403
-
404
- # Merge addons
405
- existing_addons = existing_item.get('Add_Ons__c', "None")
406
- merged_addons = existing_addons if existing_addons == "None" else f"{existing_addons}; {addons_string}"
407
-
408
- # Merge instructions
409
- existing_instructions = existing_item.get('Instructions__c', "")
410
- merged_instructions = existing_instructions if not item_data['instructions'] else \
411
- f"{existing_instructions} | {item_data['instructions']}".strip(" | ")
412
-
413
- # Update in Salesforce
414
- sf.Cart_Item__c.update(existing_item['Id'], {
415
- "Quantity__c": new_quantity,
416
- "Add_Ons__c": merged_addons,
417
- "Add_Ons_Price__c": addons_price + existing_item.get('Add_Ons_Price__c', 0),
418
- "Instructions__c": merged_instructions,
419
- "Price__c": total_price + existing_item.get('Price__c', 0)
 
 
 
 
 
 
 
 
 
 
420
  })
421
  else:
422
- # Create new cart item
 
 
 
 
 
423
  sf.Cart_Item__c.create({
424
- "Name": item_data['name'],
425
  "Price__c": total_price,
426
- "Base_Price__c": item_data['price'],
427
- "Quantity__c": item_data['quantity'],
428
  "Add_Ons_Price__c": addons_price,
429
  "Add_Ons__c": addons_string,
430
- "Image1__c": item_data['image'],
431
- "Customer_Email__c": item_data['customer_email'],
432
- "Instructions__c": item_data['instructions'],
433
- "Category__c": item_data['category'],
434
- "Section__c": item_data['section']
435
  })
436
-
437
- return jsonify({
438
- "success": True,
439
- "message": "Item added to cart successfully."
440
- })
441
-
442
- except ValueError as e:
443
- logger.error(f"Value error in add_to_cart: {str(e)}")
444
- return jsonify({
445
- "success": False,
446
- "error": "Invalid price or quantity format."
447
- }), 400
448
-
449
  except Exception as e:
450
- logger.error(f"Error in add_to_cart: {str(e)}")
451
- return jsonify({
452
- "success": False,
453
- "error": "An error occurred while adding to cart."
454
- }), 500
 
1
  from flask import Blueprint, render_template, request, session, jsonify, redirect, url_for
2
  from salesforce import get_salesforce_connection
3
  import os
 
 
 
 
 
 
 
 
4
 
5
  menu_blueprint = Blueprint('menu', __name__)
6
 
7
  # Initialize Salesforce connection
8
  sf = get_salesforce_connection()
9
 
10
+ # Constants for video handling
11
+ STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')
12
  PLACEHOLDER_VIDEO = 'placeholder.mp4'
13
+ PLACEHOLDER_PATH = os.path.join(STATIC_DIR, PLACEHOLDER_VIDEO)
14
+ SECTION_ORDER = ["Best Sellers", "Starters", "Biryanis", "Curries", "Breads", "Customized dish", "Apetizer", "Desserts", "Soft Drinks"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ # Create placeholder video at startup if it doesn't exist
17
+ if not os.path.exists(PLACEHOLDER_PATH):
18
+ open(PLACEHOLDER_PATH, 'wb').close()
19
+ print(f"Created placeholder video at {PLACEHOLDER_PATH}")
20
 
21
+ def get_valid_video_path(item_name, video_url=None):
22
  """
23
+ Get valid video path for item with placeholder fallback
24
+ Priority: 1. Video1__c from Salesforce 2. placeholder.mp4
 
 
 
 
25
  """
26
+ # First try: Video1__c from Salesforce if provided
27
+ if video_url:
28
+ # If it's a complete URL (http/https)
29
+ if video_url.startswith(('http://', 'https://')):
30
+ return video_url
31
+ # If it's a relative path (/videos/xxx.mp4)
32
+ elif video_url.startswith('/'):
33
+ return video_url
34
+ # If it's a Salesforce File ID (starts with '069')
35
+ elif video_url.startswith('069'):
36
+ return f"https://yourdomain.my.salesforce.com/sfc/servlet.shepherd/version/download/{video_url}"
 
 
37
 
38
+ # Final fallback: placeholder.mp4
39
+ if not os.path.exists(PLACEHOLDER_PATH):
40
+ open(PLACEHOLDER_PATH, 'wb').close()
41
+ print(f"Created missing placeholder video at {PLACEHOLDER_PATH}")
42
 
43
+ return f"/static/{PLACEHOLDER_VIDEO}"
44
 
45
+ @menu_blueprint.route("/menu", methods=["GET", "POST"])
46
+ def menu():
47
+ selected_category = request.args.get("category", "All")
48
  user_email = session.get('user_email')
49
+
 
50
  if not user_email:
51
+ user_email = request.args.get("email")
52
+ user_name = request.args.get("name")
53
+
54
  if user_email:
55
  session['user_email'] = user_email
56
  session['user_name'] = user_name
57
  else:
58
+ return redirect(url_for("login"))
59
+ else:
60
+ user_name = session.get('user_name')
61
+
62
  first_letter = user_name[0].upper() if user_name else "A"
 
63
 
 
 
64
  try:
65
+ # Fetch user referral and reward points
66
+ user_query = f"SELECT Referral__c, Reward_Points__c FROM Customer_Login__c WHERE Email__c = '{user_email}'"
67
+ user_result = sf.query(user_query)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
+ if not user_result['records']:
70
+ return redirect(url_for('login'))
 
 
 
 
 
 
 
71
 
72
+ referral_code = user_result['records'][0].get('Referral__c', 'N/A')
73
+ reward_points = user_result['records'][0].get('Reward_Points__c', 0)
74
+
75
+ # Get cart item count
76
+ cart_query = f"SELECT COUNT() FROM Cart_Item__c WHERE Customer_Email__c = '{user_email}'"
77
+ cart_count_result = sf.query(cart_query)
78
+ cart_item_count = cart_count_result['totalSize']
79
+
80
+ # Query to fetch Menu_Item__c records including Video1__c
81
  menu_query = """
82
+ SELECT Name, Price__c, Description__c, Image1__c, Image2__c,
83
+ Veg_NonVeg__c, Section__c, Total_Ordered__c, Video1__c
 
84
  FROM Menu_Item__c
 
85
  """
86
+ result = sf.query(menu_query)
87
+ food_items = result['records'] if 'records' in result else []
88
+
89
+ # Process items and add video paths
90
+ for item in food_items:
91
+ if 'Total_Ordered__c' not in item or item['Total_Ordered__c'] is None:
92
+ item['Total_Ordered__c'] = 0
93
+ item['Video1__c'] = get_valid_video_path(item['Name'], item.get('Video1__c'))
94
+
95
+ # Query to fetch Custom_Dish__c records
96
  custom_dish_query = """
97
+ SELECT Name, Price__c, Description__c, Image1__c, Image2__c,
98
+ Veg_NonVeg__c, Section__c, Total_Ordered__c
99
  FROM Custom_Dish__c
100
+ WHERE CreatedDate >= LAST_N_DAYS:7
101
  """
102
+ custom_dish_result = sf.query(custom_dish_query)
103
  custom_dishes = custom_dish_result.get('records', [])
104
+
105
+ # Process custom dishes and add video paths
106
+ for item in custom_dishes:
107
+ if 'Total_Ordered__c' not in item or item['Total_Ordered__c'] is None:
108
+ item['Total_Ordered__c'] = 0
109
+ item['Video1__c'] = get_valid_video_path(item['Name'])
110
+
111
+ # Merge both Menu_Item__c and Custom_Dish__c records
112
+ all_items = food_items + custom_dishes
113
+ ordered_menu = {section: [] for section in SECTION_ORDER}
114
+
115
+ # Process best sellers
116
+ best_sellers = sorted(all_items, key=lambda x: x.get("Total_Ordered__c", 0), reverse=True)
117
 
118
+ if selected_category == "Veg":
119
+ best_sellers = [item for item in best_sellers if item.get("Veg_NonVeg__c") in ["Veg", "both"]]
120
+ elif selected_category == "Non veg":
121
+ best_sellers = [item for item in best_sellers if item.get("Veg_NonVeg__c") in ["Non veg", "both"]]
122
+
123
+ best_sellers = best_sellers[:4]
124
+ if best_sellers:
125
+ ordered_menu["Best Sellers"] = best_sellers
126
+
127
+ # Organize other sections
128
+ added_item_names = set()
129
+ for item in all_items:
130
+ section = item.get("Section__c", "Others")
131
+ if section not in ordered_menu:
132
+ ordered_menu[section] = []
133
+
134
+ if item['Name'] in added_item_names:
135
+ continue
136
+
137
+ if selected_category == "Veg" and item.get("Veg_NonVeg__c") not in ["Veg", "both"]:
 
 
138
  continue
139
+ if selected_category == "Non veg" and item.get("Veg_NonVeg__c") not in ["Non veg", "both"]:
140
  continue
 
 
 
 
 
 
 
 
141
 
142
+ ordered_menu[section].append(item)
143
+ added_item_names.add(item['Name'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
+ ordered_menu = {section: items for section, items in ordered_menu.items() if items}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  categories = ["All", "Veg", "Non veg"]
147
+
 
 
 
 
 
 
 
 
 
 
 
 
148
  except Exception as e:
149
+ print(f"Error fetching menu data: {str(e)}")
150
+ # Fallback data with video support
151
+ ordered_menu = {section: [] for section in SECTION_ORDER}
152
+ best_sellers = ["Chicken Biryani", "Paneer Butter Masala", "Veg Manchurian", "Prawn Fry"]
153
+ ordered_menu["Best Sellers"] = [{
154
+ "Name": name,
155
+ "Price__c": "12.99",
156
+ "Description__c": f"Popular {name}",
157
+ "Image1__c": "/static/placeholder.jpg",
158
+ "Video1__c": get_valid_video_path(name),
159
+ "Total_Ordered__c": 100,
160
+ "Veg_NonVeg__c": "Veg" if "Paneer" in name or "Veg" in name else "Non veg"
161
+ } for name in best_sellers]
162
+
163
+ categories = ["All", "Veg", "Non veg"]
164
+ referral_code = 'N/A'
165
+ reward_points = 0
166
+ cart_item_count = 0
167
+
168
+ return render_template(
169
+ "menu.html",
170
+ ordered_menu=ordered_menu,
171
+ categories=categories,
172
+ selected_category=selected_category,
173
+ referral_code=referral_code,
174
+ reward_points=reward_points,
175
+ user_name=user_name,
176
+ first_letter=first_letter,
177
+ cart_item_count=cart_item_count
178
+ )
179
 
180
  @menu_blueprint.route('/api/addons', methods=['GET'])
181
  def get_addons():
182
+ item_name = request.args.get('item_name')
183
+ item_section = request.args.get('item_section')
184
+
185
+ if not item_name or not item_section:
186
+ return jsonify({"success": False, "error": "Item name and section are required."}), 400
187
+
188
  try:
 
 
 
 
 
 
 
 
 
 
189
  query = f"""
190
+ SELECT Name, Customization_Type__c, Options__c, Max_Selections__c, Extra_Charge__c, Extra_Charge_Amount__c
 
 
191
  FROM Customization_Options__c
192
  WHERE Section__c = '{item_section}'
 
 
193
  """
194
  result = sf.query(query)
195
  addons = result.get('records', [])
196
+
197
  if not addons:
198
+ return jsonify({"success": False, "error": "No customization options found for the given section."}), 404
199
+
 
 
 
 
200
  formatted_addons = []
201
  for addon in addons:
202
  options = addon.get("Options__c", "")
203
+ if options:
204
+ options = options.split(", ")
205
+ else:
206
+ options = []
207
+
208
  formatted_addons.append({
209
+ "name": addon["Name"],
210
+ "type": addon["Customization_Type__c"],
 
211
  "options": options,
212
  "max_selections": addon.get("Max_Selections__c", 1),
213
  "extra_charge": addon.get("Extra_Charge__c", False),
214
+ "extra_charge_amount": addon.get("Extra_Charge_Amount__c", 0)
215
  })
216
+
217
+ return jsonify({"success": True, "addons": formatted_addons})
218
+
 
 
 
219
  except Exception as e:
220
+ print(f"Error fetching addons: {str(e)}")
221
+ return jsonify({"success": False, "error": "An error occurred while fetching customization options."}), 500
 
 
 
222
 
223
  @menu_blueprint.route('/cart/add', methods=['POST'])
224
  def add_to_cart():
225
  try:
226
+ data = request.json
227
+ item_name = data.get('itemName', '').strip()
228
+ item_price = data.get('itemPrice')
229
+ item_image = data.get('itemImage')
230
+ addons = data.get('addons', [])
231
+ instructions = data.get('instructions', '')
232
+ category = data.get('category')
233
+ section = data.get('section')
234
+ quantity = data.get('quantity', 1)
235
+ customer_email = session.get('user_email')
236
+
237
+ if not item_name or not item_price:
238
+ return jsonify({"success": False, "error": "Item name and price are required."}), 400
239
+
240
+ if not customer_email:
241
+ return jsonify({"success": False, "error": "User email is required."}), 400
242
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  query = f"""
244
  SELECT Id, Quantity__c, Add_Ons__c, Add_Ons_Price__c, Instructions__c
245
  FROM Cart_Item__c
246
+ WHERE Customer_Email__c = '{customer_email}' AND Name = '{item_name}'
 
 
247
  """
248
  result = sf.query(query)
249
+ cart_items = result.get("records", [])
250
+
251
+ addons_price = sum(addon['price'] for addon in addons)
252
+ new_addons = "; ".join([f"{addon['name']} (${addon['price']})" for addon in addons])
253
+
254
+ if cart_items:
255
+ cart_item_id = cart_items[0]['Id']
256
+ existing_quantity = cart_items[0]['Quantity__c']
257
+ existing_addons = cart_items[0].get('Add_Ons__c', "None")
258
+ existing_addons_price = cart_items[0].get('Add_Ons_Price__c', 0)
259
+ existing_instructions = cart_items[0].get('Instructions__c', "")
260
+
261
+ combined_addons = existing_addons if existing_addons != "None" else ""
262
+ if new_addons:
263
+ combined_addons = f"{combined_addons}; {new_addons}".strip("; ")
264
+
265
+ combined_instructions = existing_instructions
266
+ if instructions:
267
+ combined_instructions = f"{combined_instructions} | {instructions}".strip(" | ")
268
+
269
+ combined_addons_list = combined_addons.split("; ")
270
+ combined_addons_price = sum(
271
+ float(addon.split("($")[1][:-1]) for addon in combined_addons_list if "($" in addon
272
+ )
273
+
274
+ sf.Cart_Item__c.update(cart_item_id, {
275
+ "Quantity__c": existing_quantity + quantity,
276
+ "Add_Ons__c": combined_addons,
277
+ "Add_Ons_Price__c": combined_addons_price,
278
+ "Instructions__c": combined_instructions,
279
+ "Price__c": (existing_quantity + quantity) * item_price + combined_addons_price,
280
+ "Category__c": category,
281
+ "Section__c": section
282
  })
283
  else:
284
+ addons_string = "None"
285
+ if addons:
286
+ addons_string = new_addons
287
+
288
+ total_price = item_price * quantity + addons_price
289
+
290
  sf.Cart_Item__c.create({
291
+ "Name": item_name,
292
  "Price__c": total_price,
293
+ "Base_Price__c": item_price,
294
+ "Quantity__c": quantity,
295
  "Add_Ons_Price__c": addons_price,
296
  "Add_Ons__c": addons_string,
297
+ "Image1__c": item_image,
298
+ "Customer_Email__c": customer_email,
299
+ "Instructions__c": instructions,
300
+ "Category__c": category,
301
+ "Section__c": section
302
  })
303
+
304
+ return jsonify({"success": True, "message": "Item added to cart successfully."})
305
+
306
+ except KeyError as e:
307
+ return jsonify({"success": False, "error": f"Missing required field: {str(e)}"}), 400
308
+
 
 
 
 
 
 
 
309
  except Exception as e:
310
+ print(f"Error adding item to cart: {str(e)}")
311
+ return jsonify({"success": False, "error": "An error occurred while adding the item to the cart."}), 500