rairo commited on
Commit
c75cb71
·
verified ·
1 Parent(s): 14b1751

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +175 -2
main.py CHANGED
@@ -1266,9 +1266,182 @@ def admin_get_all_deals():
1266
  return handle_route_errors(e, uid_context=admin_uid)
1267
  # --- END OF ADMIN ALL LISTINGS/DEALS ---
1268
 
 
1269
 
1270
- # --- (The rest of your script: Admin approval of deals, Chat, Notifications, AI, main block) ---
1271
- # Ensure all these sections are present and use the handle_route_errors and app=db_app pattern.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1272
 
1273
  @app.route('/api/admin/deals/pending', methods=['GET'])
1274
  def admin_get_pending_deals():
 
1266
  return handle_route_errors(e, uid_context=admin_uid)
1267
  # --- END OF ADMIN ALL LISTINGS/DEALS ---
1268
 
1269
+ # --- ADMIN ENDPOINTS FOR WHATSAPP-MANAGED FARMER ACCOUNTS ---
1270
 
1271
+ @app.route('/api/admin/whatsapp-farmers/create', methods=['POST'])
1272
+ def admin_create_whatsapp_farmer():
1273
+ auth_header = request.headers.get('Authorization')
1274
+ admin_uid = None
1275
+ try:
1276
+ admin_uid = verify_admin(auth_header)
1277
+ if not FIREBASE_INITIALIZED:
1278
+ return jsonify({'error': 'Server configuration error: Firebase not ready.'}), 503
1279
+
1280
+ data = request.get_json()
1281
+ name = data.get('name')
1282
+ phone_number = data.get('phone_number') # Expecting E.164 format ideally
1283
+ location = data.get('location', "")
1284
+ initial_notes = data.get('initial_notes', "")
1285
+
1286
+ if not name or not phone_number:
1287
+ return jsonify({'error': 'Farmer name and phone number are required.'}), 400
1288
+
1289
+ # Basic validation for phone number format (can be enhanced)
1290
+ if not re.match(r"^\+?[1-9]\d{1,14}$", phone_number):
1291
+ return jsonify({'error': 'Invalid phone number format. Please use E.164 like +263771234567.'}), 400
1292
+
1293
+ # Check if phone number is already in use by a fully registered webapp user
1294
+ # This query can be slow if you have many users. Consider indexing phone_number.
1295
+ users_ref = db.reference('users', app=db_app)
1296
+ existing_user_query = users_ref.order_by_child('phone_number').equal_to(phone_number).limit_to_first(1).get()
1297
+ if existing_user_query:
1298
+ for existing_uid, existing_user_data in existing_user_query.items():
1299
+ if existing_user_data.get('account_type') == 'webapp_registered':
1300
+ return jsonify({'error': f'This phone number is already registered to a web app user (UID: {existing_uid}).'}), 409
1301
+ # Optionally, handle if already a whatsapp_managed account with this number
1302
+ # if existing_user_data.get('account_type') == 'whatsapp_managed':
1303
+ # return jsonify({'error': f'This phone number is already managed for another WhatsApp farmer (UID: {existing_uid}).'}), 409
1304
+
1305
+
1306
+ # Generate a unique ID for this WhatsApp-managed farmer
1307
+ # This UID will be used in the 'users' node. No Firebase Auth user created at this stage.
1308
+ farmer_uid = f"wpfarmer_{str(uuid.uuid4())}"
1309
+
1310
+ profile_data = {
1311
+ 'uid': farmer_uid, # Store the UID within the profile too for convenience
1312
+ 'name': name,
1313
+ 'phone_number': phone_number,
1314
+ 'email': f"{farmer_uid}@whatsapp.tunasonga.internal", # Placeholder email
1315
+ 'location': location,
1316
+ 'roles': {'farmer': True, 'buyer': False, 'transporter': False},
1317
+ 'account_type': "whatsapp_managed",
1318
+ 'is_placeholder_account': True, # Indicates this was admin-created before web registration
1319
+ 'can_login_webapp': False, # Cannot log in to web app yet
1320
+ 'managed_by_admin_uid': admin_uid,
1321
+ 'created_at': datetime.now(timezone.utc).isoformat(),
1322
+ 'created_by_admin_uid': admin_uid, # Explicitly track creator
1323
+ 'whatsapp_interaction_log': [{ # Start a log
1324
+ 'timestamp': datetime.now(timezone.utc).isoformat(),
1325
+ 'action': 'account_created_by_admin',
1326
+ 'admin_uid': admin_uid,
1327
+ 'notes': f"Initial notes: {initial_notes}" if initial_notes else "Account created."
1328
+ }]
1329
+ }
1330
+
1331
+ db.reference(f'users/{farmer_uid}', app=db_app).set(profile_data)
1332
+
1333
+ return jsonify({
1334
+ 'success': True,
1335
+ 'message': f'WhatsApp-managed farmer account created for {name} ({phone_number}).',
1336
+ 'farmer_uid': farmer_uid,
1337
+ 'profile': profile_data
1338
+ }), 201
1339
+
1340
+ except Exception as e:
1341
+ return handle_route_errors(e, uid_context=admin_uid)
1342
+
1343
+
1344
+ @app.route('/api/admin/whatsapp-farmers', methods=['GET'])
1345
+ def admin_list_whatsapp_farmers():
1346
+ auth_header = request.headers.get('Authorization')
1347
+ admin_uid = None
1348
+ try:
1349
+ admin_uid = verify_admin(auth_header)
1350
+ if not FIREBASE_INITIALIZED:
1351
+ return jsonify({'error': 'Server configuration error: Firebase not ready.'}), 503
1352
+
1353
+ users_ref = db.reference('users', app=db_app)
1354
+ # Querying for account_type. This requires an index on 'account_type' in Firebase rules for performance.
1355
+ # ".indexOn": ["account_type"] under your "users" rules.
1356
+ whatsapp_farmers_query = users_ref.order_by_child('account_type').equal_to('whatsapp_managed').get()
1357
+
1358
+ whatsapp_farmers = whatsapp_farmers_query or {}
1359
+
1360
+ return jsonify(whatsapp_farmers), 200
1361
+
1362
+ except Exception as e:
1363
+ return handle_route_errors(e, uid_context=admin_uid)
1364
+
1365
+ @app.route('/api/admin/whatsapp-farmers/<farmer_uid>', methods=['GET'])
1366
+ def admin_get_whatsapp_farmer(farmer_uid):
1367
+ auth_header = request.headers.get('Authorization')
1368
+ admin_uid = None
1369
+ try:
1370
+ admin_uid = verify_admin(auth_header)
1371
+ if not FIREBASE_INITIALIZED:
1372
+ return jsonify({'error': 'Server configuration error: Firebase not ready.'}), 503
1373
+
1374
+ farmer_ref = db.reference(f'users/{farmer_uid}', app=db_app)
1375
+ farmer_data = farmer_ref.get()
1376
+
1377
+ if not farmer_data or farmer_data.get('account_type') != 'whatsapp_managed':
1378
+ return jsonify({'error': 'WhatsApp-managed farmer not found or not of correct type.'}), 404
1379
+
1380
+ return jsonify(farmer_data), 200
1381
+
1382
+ except Exception as e:
1383
+ return handle_route_errors(e, uid_context=admin_uid)
1384
+
1385
+
1386
+ @app.route('/api/admin/whatsapp-farmers/<farmer_uid>/update', methods=['PUT'])
1387
+ def admin_update_whatsapp_farmer(farmer_uid):
1388
+ auth_header = request.headers.get('Authorization')
1389
+ admin_uid = None
1390
+ try:
1391
+ admin_uid = verify_admin(auth_header)
1392
+ if not FIREBASE_INITIALIZED:
1393
+ return jsonify({'error': 'Server configuration error: Firebase not ready.'}), 503
1394
+
1395
+ farmer_ref = db.reference(f'users/{farmer_uid}', app=db_app)
1396
+ farmer_data = farmer_ref.get()
1397
+
1398
+ if not farmer_data or farmer_data.get('account_type') != 'whatsapp_managed':
1399
+ return jsonify({'error': 'WhatsApp-managed farmer not found or not of correct type.'}), 404
1400
+
1401
+ data = request.get_json()
1402
+ updates = {}
1403
+ allowed_fields_to_update = ['name', 'location', 'phone_number'] # Define what admin can change
1404
+
1405
+ for field in allowed_fields_to_update:
1406
+ if field in data:
1407
+ updates[field] = data[field]
1408
+
1409
+ if not updates and 'additional_notes' not in data : # Check if any valid fields or notes are provided
1410
+ return jsonify({'error': 'No valid fields to update or notes provided.'}), 400
1411
+
1412
+ # Log the update action
1413
+ if data.get('additional_notes'):
1414
+ log_entry_key = db.reference(f'users/{farmer_uid}/whatsapp_interaction_log', app=db_app).push().key
1415
+ log_entry = {
1416
+ 'timestamp': datetime.now(timezone.utc).isoformat(),
1417
+ 'action': 'admin_update_notes',
1418
+ 'admin_uid': admin_uid,
1419
+ 'notes': data.get('additional_notes')
1420
+ }
1421
+ # To add to the log, we need to fetch existing logs or use a transaction if it's critical
1422
+ # For simplicity here, we'll just push a new entry.
1423
+ # If you want to update the main profile and add a log entry atomically,
1424
+ # you'd construct a single update payload for farmer_ref.update()
1425
+ db.reference(f'users/{farmer_uid}/whatsapp_interaction_log/{log_entry_key}', app=db_app).set(log_entry)
1426
+
1427
+
1428
+ if updates: # If there are profile fields to update
1429
+ updates['last_updated_by_admin_uid'] = admin_uid
1430
+ updates['last_updated_at'] = datetime.now(timezone.utc).isoformat()
1431
+ farmer_ref.update(updates)
1432
+
1433
+ updated_farmer_data = farmer_ref.get() # Get the latest data
1434
+
1435
+ return jsonify({
1436
+ 'success': True,
1437
+ 'message': f'WhatsApp-managed farmer {farmer_uid} updated.',
1438
+ 'profile': updated_farmer_data
1439
+ }), 200
1440
+
1441
+ except Exception as e:
1442
+ return handle_route_errors(e, uid_context=admin_uid)
1443
+
1444
+ # --- END OF WHATSAPP-MANAGED FARMER ACCOUNT ENDPOINTS ---
1445
 
1446
  @app.route('/api/admin/deals/pending', methods=['GET'])
1447
  def admin_get_pending_deals():