File size: 22,029 Bytes
211d39c
375539f
16defa4
 
3f862cb
4e07a43
16defa4
 
 
 
4e07a43
 
621242c
ebdfd29
4e07a43
a399ecf
4e07a43
621242c
6283128
a399ecf
4e07a43
a399ecf
6283128
3f862cb
 
16defa4
4e07a43
6283128
3f862cb
6283128
 
 
 
 
 
3f862cb
a399ecf
3f862cb
 
16defa4
6283128
621242c
6283128
 
 
8fb4c32
a399ecf
6283128
3f862cb
621242c
a399ecf
 
3f862cb
a399ecf
 
 
 
 
 
6283128
621242c
b28006b
ebdfd29
7327577
1fdaee2
 
 
 
 
 
 
 
7327577
1fdaee2
 
 
 
 
7327577
1fdaee2
 
 
 
 
 
 
 
3f862cb
16defa4
 
 
 
 
7327577
1fdaee2
16defa4
 
3f862cb
7327577
3f862cb
1fdaee2
 
 
 
 
 
3f862cb
7327577
3f862cb
 
0f2f884
 
3f862cb
 
1fdaee2
 
 
 
 
 
3f862cb
7327577
3f862cb
 
 
 
 
0f2f884
 
 
b28006b
3f862cb
7327577
3f862cb
 
 
 
 
 
1fdaee2
 
 
 
 
 
3f862cb
7327577
3f862cb
 
 
 
 
b28006b
3f862cb
7327577
3f862cb
 
 
7327577
3f862cb
 
 
 
 
 
 
7327577
3f862cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7327577
3f862cb
 
6283128
 
 
 
a399ecf
6283128
 
 
 
 
701d127
16defa4
8fb4c32
 
6283128
4e07a43
b28006b
 
 
 
 
 
 
 
 
16defa4
b28006b
 
 
 
 
16defa4
b28006b
 
701d127
7327577
b28006b
 
 
 
 
 
16defa4
b28006b
 
 
 
 
16defa4
b28006b
 
 
 
 
 
 
 
 
 
7327577
b28006b
 
 
 
 
 
 
 
 
16defa4
b28006b
 
701d127
b28006b
 
 
 
 
 
a399ecf
b28006b
7e251aa
b28006b
 
 
 
 
 
 
 
ebdfd29
b28006b
 
7327577
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b28006b
 
 
7327577
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b28006b
 
 
7327577
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0140872
 
 
7327577
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
from flask import Blueprint, render_template, request, session, jsonify, redirect, url_for
import os
import base64
import logging
from salesforce import get_salesforce_connection

# Configure logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

menu_blueprint = Blueprint('menu', __name__)

# Initialize Salesforce connection
sf = get_salesforce_connection()

# Constants for video handling
STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')
PLACEHOLDER_VIDEO = 'placeholder.mp4'
PLACEHOLDER_PATH = os.path.join(STATIC_DIR, PLACEHOLDER_VIDEO)
SECTION_ORDER = ["Best Sellers", "Starters", "Biryanis", "Curries", "Breads", "Customized dish", "Apetizer", "Desserts", "Soft Drinks"]

# Create placeholder video at startup if it doesn't exist
if not os.path.exists(PLACEHOLDER_PATH):
    with open(PLACEHOLDER_PATH, 'wb') as f:
        f.close()
    logger.info(f"Created placeholder video at {PLACEHOLDER_PATH}")

def get_valid_video_path(item_name, video_url=None):
    """Get valid video path for item with placeholder fallback."""
    if video_url:
        if video_url.startswith(('http://', 'https://')):
            return video_url
        elif video_url.startswith('/'):
            return video_url
        elif video_url.startswith('069'):
            return f"https://biryanihub-dev-ed.develop.my.salesforce.com/sfc/servlet.shepherd/version/download/{video_url}"
    if not os.path.exists(PLACEHOLDER_PATH):
        with open(PLACEHOLDER_PATH, 'wb') as f:
            f.close()
        logger.info(f"Created missing placeholder video at {PLACEHOLDER_PATH}")
    return f"/static/{PLACEHOLDER_VIDEO}"

@menu_blueprint.route("/menu", methods=["GET", "POST"])
def menu():
    selected_category = request.args.get("category", "All")
    highlight_item = request.args.get("highlight")  # Get item to highlight from query parameter
    user_email = session.get('user_email')

    # Handle user authentication
    if not user_email:
        user_email = request.args.get("email")
        user_name = request.args.get("name")
        if user_email and user_name:
            session['user_email'] = user_email
            session['user_name'] = user_name
        else:
            return redirect(url_for("login"))
    else:
        user_name = session.get('user_name')

    first_letter = user_name[0].upper() if user_name else "A"
    user_image = session.get('user_image')

    # Check if Avatar__c field exists on Customer_Login__c
    try:
        describe_result = sf.Customer_Login__c.describe()
        fields = [field['name'] for field in describe_result['fields']]
        avatar_field_exists = 'Avatar__c' in fields
    except Exception as e:
        logger.error(f"Error describing Customer_Login__c object: {str(e)}")
        avatar_field_exists = False

    # Build the SOQL query dynamically based on field availability
    query_fields = ["Id", "Referral__c", "Reward_Points__c"]
    if avatar_field_exists:
        query_fields.append("Avatar__c")
    user_query = f"SELECT {', '.join(query_fields)} FROM Customer_Login__c WHERE Email__c = '{user_email}'"

    # Fetch user referral and reward points
    try:
        user_result = sf.query(user_query)
        if not user_result.get('records'):
            logger.warning(f"No user found with email: {user_email}")
            return redirect(url_for('login'))
    except Exception as e:
        logger.error(f"Error querying user data: {str(e)}")
        return jsonify({"success": False, "error": "Failed to fetch user data from Salesforce"}), 500

    user_record = user_result['records'][0]
    user_id = user_record['Id']
    referral_code = user_record.get('Referral__c', 'N/A')
    reward_points = user_record.get('Reward_Points__c', 0)

    # If no session image, check Salesforce for stored avatar (if field exists)
    if not user_image and avatar_field_exists and user_record.get('Avatar__c'):
        session['user_image'] = user_record['Avatar__c']
        user_image = session['user_image']

    # Get cart item count
    cart_query = f"SELECT COUNT() FROM Cart_Item__c WHERE Customer_Email__c = '{user_email}'"
    try:
        cart_count_result = sf.query(cart_query)
        cart_item_count = cart_count_result.get('totalSize', 0)
    except Exception as e:
        logger.error(f"Error fetching cart item count: {str(e)}")
        cart_item_count = 0

    # Fetch all Menu_Item__c records with required fields
    menu_query = """
        SELECT Name, Price__c, Description__c, Image1__c, Image2__c, 
               Veg_NonVeg__c, Section__c, Total_Ordered__c, Video1__c,
               IngredientsInfo__c, NutritionalInfo__c, Allergens__c
        FROM Menu_Item__c
    """
    try:
        menu_result = sf.query_all(menu_query)
        food_items = menu_result.get('records', [])
    except Exception as e:
        logger.error(f"Error fetching menu items: {str(e)}")
        food_items = []

    # Process menu items
    for item in food_items:
        item['Total_Ordered__c'] = item.get('Total_Ordered__c', 0) or 0
        item['Video1__c'] = get_valid_video_path(item['Name'], item.get('Video1__c'))
        item['Section__c'] = item.get('Section__c', "Others")
        item['Description__c'] = item.get('Description__c', "No description available")
        item['IngredientsInfo__c'] = item.get('IngredientsInfo__c', "Not specified")
        item['NutritionalInfo__c'] = item.get('NutritionalInfo__c', "Not available")
        item['Allergens__c'] = item.get('Allergens__c', "None listed")
        item['is_menu_item'] = True

    # Fetch all Custom_Dish__c records with only existing fields
    custom_dish_query = """
        SELECT Name, Price__c, Description__c, Image1__c, Image2__c, 
               Veg_NonVeg__c, Section__c, Total_Ordered__c
        FROM Custom_Dish__c
        WHERE CreatedDate >= LAST_N_DAYS:7
    """
    try:
        custom_dish_result = sf.query_all(custom_dish_query)
        custom_dishes = custom_dish_result.get('records', [])
    except Exception as e:
        logger.error(f"Error fetching custom dishes: {str(e)}")
        custom_dishes = []

    # Process custom dishes
    for item in custom_dishes:
        item['Total_Ordered__c'] = item.get('Total_Ordered__c', 0) or 0
        item['Video1__c'] = get_valid_video_path(item['Name'])
        item['Section__c'] = item.get('Section__c', "Customized dish")
        item['Description__c'] = item.get('Description__c', "No description available")
        item['is_menu_item'] = False

    # Merge all items
    all_items = food_items + custom_dishes
    ordered_menu = {section: [] for section in SECTION_ORDER}

    # Process best sellers
    best_sellers = sorted(all_items, key=lambda x: x['Total_Ordered__c'], reverse=True)
    if selected_category == "Veg":
        best_sellers = [item for item in best_sellers if item.get("Veg_NonVeg__c") in ["Veg", "both"]]
    elif selected_category == "Non veg":
        best_sellers = [item for item in best_sellers if item.get("Veg_NonVeg__c") in ["Non veg", "both"]]
    ordered_menu["Best Sellers"] = best_sellers[:4]

    # Organize items into sections
    added_item_names = set()
    for item in all_items:
        section = item['Section__c']
        if section not in ordered_menu:
            ordered_menu[section] = []

        if item['Name'] in added_item_names:
            continue

        veg_nonveg = item.get("Veg_NonVeg__c", "both")
        if selected_category == "Veg" and veg_nonveg not in ["Veg", "both"]:
            continue
        if selected_category == "Non veg" and veg_nonveg not in ["Non veg", "both"]:
            continue

        ordered_menu[section].append(item)
        added_item_names.add(item['Name'])

    # Remove empty sections
    ordered_menu = {section: items for section, items in ordered_menu.items() if items}
    categories = ["All", "Veg", "Non veg"]

    return render_template(
        "menu.html",
        ordered_menu=ordered_menu,
        categories=categories,
        selected_category=selected_category,
        referral_code=referral_code,
        reward_points=reward_points,
        user_name=user_name,
        first_letter=first_letter,
        cart_item_count=cart_item_count,
        user_image=user_image,
        user_id=user_id,
        highlight_item=highlight_item  # Pass the item to highlight to the template
    )

@menu_blueprint.route('/search', methods=['GET'])
def search():
    user_email = session.get('user_email')
    if not user_email:
        return redirect(url_for("login"))

    user_name = session.get('user_name')
    first_letter = user_name[0].upper() if user_name else "A"
    user_image = session.get('user_image')

    # Get cart item count
    cart_query = f"SELECT COUNT() FROM Cart_Item__c WHERE Customer_Email__c = '{user_email}'"
    try:
        cart_count_result = sf.query(cart_query)
        cart_item_count = cart_count_result.get('totalSize', 0)
    except Exception as e:
        logger.error(f"Error fetching cart item count: {str(e)}")
        cart_item_count = 0

    # Fetch all Menu_Item__c records with required fields
    menu_query = """
        SELECT Name, Price__c, Description__c, Image1__c, Image2__c, 
               Veg_NonVeg__c, Section__c, Total_Ordered__c, Video1__c,
               IngredientsInfo__c, NutritionalInfo__c, Allergens__c
        FROM Menu_Item__c
    """
    try:
        menu_result = sf.query_all(menu_query)
        food_items = menu_result.get('records', [])
    except Exception as e:
        logger.error(f"Error fetching menu items: {str(e)}")
        food_items = []

    for item in food_items:
        item['Total_Ordered__c'] = item.get('Total_Ordered__c', 0) or 0
        item['Video1__c'] = get_valid_video_path(item['Name'], item.get('Video1__c'))
        item['Section__c'] = item.get('Section__c', "Others")
        item['Description__c'] = item.get('Description__c', "No description available")
        item['IngredientsInfo__c'] = item.get('IngredientsInfo__c', "Not specified")
        item['NutritionalInfo__c'] = item.get('NutritionalInfo__c', "Not available")
        item['Allergens__c'] = item.get('Allergens__c', "None listed")
        item['is_menu_item'] = True

    # Fetch all Custom_Dish__c records
    custom_dish_query = """
        SELECT Name, Price__c, Description__c, Image1__c, Image2__c, 
               Veg_NonVeg__c, Section__c, Total_Ordered__c
        FROM Custom_Dish__c
        WHERE CreatedDate >= LAST_N_DAYS:7
    """
    try:
        custom_dish_result = sf.query_all(custom_dish_query)
        custom_dishes = custom_dish_result.get('records', [])
    except Exception as e:
        logger.error(f"Error fetching custom dishes: {str(e)}")
        custom_dishes = []

    for item in custom_dishes:
        item['Total_Ordered__c'] = item.get('Total_Ordered__c', 0) or 0
        item['Video1__c'] = get_valid_video_path(item['Name'])
        item['Section__c'] = item.get('Section__c', "Customized dish")
        item['Description__c'] = item.get('Description__c', "No description available")
        item['is_menu_item'] = False

    all_items = food_items + custom_dishes

    return render_template(
        "search.html",
        all_items=all_items,
        user_name=user_name,
        first_letter=first_letter,
        cart_item_count=cart_item_count,
        user_image=user_image
    )

@menu_blueprint.route('/upload_avatar', methods=['POST'])
def upload_avatar():
    try:
        data = request.get_json()
        if not data or 'image' not in data:
            logger.error("No image data provided in request")
            return jsonify({'success': False, 'error': 'No image data provided'}), 400

        image_data = data['image']
        logger.debug(f"Received image data with length: {len(image_data)}")

        # Validate base64 image
        if not image_data.startswith('data:image/'):
            logger.error("Invalid image format: does not start with 'data:image/'")
            return jsonify({'success': False, 'error': 'Invalid image format'}), 400

        # Check size limit (~1.5MB for base64, roughly 1MB actual image)
        if len(image_data) > 2_000_000:
            logger.error(f"Image too large: {len(image_data)} characters (max 2,000,000)")
            return jsonify({'success': False, 'error': 'Image too large (max ~1.5MB)'}), 400

        # Validate base64 decoding
        try:
            base64_string = image_data.split(',')[1]
            base64.b64decode(base64_string)
        except Exception as e:
            logger.error(f"Invalid base64 data: {str(e)}")
            return jsonify({'success': False, 'error': 'Invalid base64 data'}), 400

        # Store in session
        session['user_image'] = image_data
        logger.info("Image stored in session successfully")

        # Store in Salesforce (if Avatar__c field exists)
        user_email = session.get('user_email')
        if user_email:
            try:
                user_query = f"SELECT Id FROM Customer_Login__c WHERE Email__c = '{user_email}'"
                user_result = sf.query(user_query)
                if user_result.get('records'):
                    user_id = user_result['records'][0]['Id']
                    describe_result = sf.Customer_Login__c.describe()
                    fields = [field['name'] for field in describe_result['fields']]
                    if 'Avatar__c' in fields:
                        sf.Customer_Login__c.update(user_id, {'Avatar__c': image_data})
                        logger.info(f"Image stored in Salesforce for user {user_email}")
                    else:
                        logger.warning("Avatar__c field does not exist; skipping Salesforce update")
                else:
                    logger.warning(f"User not found in Salesforce: {user_email}")
            except Exception as e:
                logger.error(f"Failed to store image in Salesforce: {str(e)}")

        return jsonify({'success': True, 'image': image_data})

    except Exception as e:
        logger.error(f"Error in upload_avatar: {str(e)}", exc_info=True)
        return jsonify({'success': False, 'error': f'Server error: {str(e)}'}), 500

@menu_blueprint.route('/delete_avatar', methods=['POST'])
def delete_avatar():
    try:
        user_email = session.get('user_email')
        if not user_email:
            logger.error("No user email in session")
            return jsonify({'success': False, 'error': 'User not authenticated'}), 401

        if 'user_image' in session:
            session.pop('user_image', None)
            logger.info("Image removed from session")

        try:
            user_query = f"SELECT Id FROM Customer_Login__c WHERE Email__c = '{user_email}'"
            user_result = sf.query(user_query)
            if user_result.get('records'):
                user_id = user_result['records'][0]['Id']
                describe_result = sf.Customer_Login__c.describe()
                fields = [field['name'] for field in describe_result['fields']]
                if 'Avatar__c' in fields:
                    sf.Customer_Login__c.update(user_id, {'Avatar__c': None})
                    logger.info(f"Image removed from Salesforce for user {user_email}")
                else:
                    logger.warning("Avatar__c field does not exist; skipping Salesforce update")
            else:
                logger.warning(f"User not found in Salesforce: {user_email}")
        except Exception as e:
            logger.error(f"Failed to remove image from Salesforce: {str(e)}")

        return jsonify({'success': True})

    except Exception as e:
        logger.error(f"Error in delete_avatar: {str(e)}", exc_info=True)
        return jsonify({'success': False, 'error': f'Server error: {str(e)}'}), 500

@menu_blueprint.route('/api/addons', methods=['GET'])
def get_addons():
    item_name = request.args.get('item_name')
    item_section = request.args.get('item_section')

    if not item_name or not item_section:
        return jsonify({"success": False, "error": "Item name and section are required."}), 400

    try:
        query = f"""
            SELECT Name, Customization_Type__c, Options__c, Max_Selections__c, Extra_Charge__c, Extra_Charge_Amount__c
            FROM Customization_Options__c
            WHERE Section__c = '{item_section}'
        """
        result = sf.query_all(query)
        addons = result.get('records', [])

        if not addons:
            return jsonify({"success": False, "error": "No customization options found for the given section."}), 404

        formatted_addons = []
        for addon in addons:
            options = addon.get("Options__c", "")
            options = options.split(", ") if options else []
            formatted_addons.append({
                "name": addon.get("Name", ""),
                "type": addon.get("Customization_Type__c", ""),
                "options": options,
                "max_selections": addon.get("Max_Selections__c", 1),
                "extra_charge": addon.get("Extra_Charge__c", False),
                "extra_charge_amount": addon.get("Extra_Charge_Amount__c", 0)
            })

        return jsonify({"success": True, "addons": formatted_addons})

    except Exception as e:
        logger.error(f"Error fetching addons: {str(e)}")
        return jsonify({"success": False, "error": "An error occurred while fetching customization options."}), 500

@menu_blueprint.route('/cart/add', methods=['POST'])
def add_to_cart():
    try:
        data = request.json
        item_name = data.get('itemName', '').strip()
        item_price = float(data.get('itemPrice', 0))
        item_image = data.get('itemImage', '')
        addons = data.get('addons', [])
        instructions = data.get('instructions', '')
        category = data.get('category', '')
        section = data.get('section', '')
        quantity = int(data.get('quantity', 1))
        customer_email = session.get('user_email')

        if not item_name or not item_price or not customer_email:
            logger.error(f"Missing required fields: item_name={item_name}, item_price={item_price}, customer_email={customer_email}")
            return jsonify({"success": False, "error": "Item name, price, and user email are required."}), 400

        # Sanitize inputs to prevent SOQL injection
        item_name = item_name.replace("'", "''")
        customer_email = customer_email.replace("'", "''")

        query = f"""
            SELECT Id, Quantity__c, Add_Ons__c, Add_Ons_Price__c, Instructions__c, Price__c
            FROM Cart_Item__c
            WHERE Customer_Email__c = '{customer_email}' AND Name = '{item_name}'
        """
        result = sf.query(query)
        cart_items = result.get("records", [])

        addons_price = sum(float(addon.get('price', 0)) for addon in addons)
        new_addons = "; ".join([f"{addon['name']} (${addon['price']})" for addon in addons]) if addons else "None"

        if cart_items:
            cart_item = cart_items[0]
            cart_item_id = cart_item['Id']
            existing_quantity = int(cart_item.get('Quantity__c', 0))
            existing_addons = cart_item.get('Add_Ons__c', "None")
            existing_addons_price = float(cart_item.get('Add_Ons_Price__c', 0))
            existing_instructions = cart_item.get('Instructions__c', "")

            combined_addons = existing_addons if existing_addons != "None" else ""
            if new_addons != "None":
                combined_addons = f"{combined_addons}; {new_addons}".strip("; ")

            combined_instructions = existing_instructions
            if instructions:
                combined_instructions = f"{combined_instructions} | {instructions}".strip(" | ")

            combined_addons_list = combined_addons.split("; ")
            combined_addons_price = sum(
                float(addon.split("($")[1][:-1]) for addon in combined_addons_list if "($" in addon
            )

            total_price = (existing_quantity + quantity) * item_price + combined_addons_price

            sf.Cart_Item__c.update(cart_item_id, {
                "Quantity__c": existing_quantity + quantity,
                "Add_Ons__c": combined_addons,
                "Add_Ons_Price__c": combined_addons_price,
                "Instructions__c": combined_instructions,
                "Price__c": total_price,
                "Category__c": category,
                "Section__c": section
            })
        else:
            total_price = item_price * quantity + addons_price
            sf.Cart_Item__c.create({
                "Name": item_name,
                "Price__c": total_price,
                "Base_Price__c": item_price,
                "Quantity__c": quantity,
                "Add_Ons_Price__c": addons_price,
                "Add_Ons__c": new_addons,
                "Image1__c": item_image,
                "Customer_Email__c": customer_email,
                "Instructions__c": instructions,
                "Category__c": category,
                "Section__c": section
            })

        # Fetch updated cart for UI update
        cart_query = f"SELECT Name, Quantity__c FROM Cart_Item__c WHERE Customer_Email__c = '{customer_email}'"
        cart_result = sf.query_all(cart_query)
        cart = [{"itemName": item["Name"], "quantity": item["Quantity__c"]} for item in cart_result.get("records", [])]
        
        logger.info(f"Item '{item_name}' added to cart for {customer_email}")
        return jsonify({"success": True, "message": "Item added to cart successfully.", "cart": cart})

    except ValueError as e:
        logger.error(f"Invalid data format: {str(e)}")
        return jsonify({"success": False, "error": f"Invalid data format: {str(e)}"}), 400
    except Exception as e:
        logger.error(f"Error adding item to cart: {str(e)}", exc_info=True)
        return jsonify({"success": False, "error": f"An error occurred while adding the item to the cart: {str(e)}"}), 500

# Note: Ensure 'login' route exists in your app or adjust redirect accordingly