rairo commited on
Commit
8934e96
·
verified ·
1 Parent(s): 7f3cb6f

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +14 -15
main.py CHANGED
@@ -749,8 +749,8 @@ def admin_remove_member_from_org(org_id, member_uid):
749
  @app.route('/api/admin/dashboard/stats', methods=['GET'])
750
  def get_admin_dashboard_stats():
751
  """
752
- Retrieves global statistics for the admin dashboard, including leaderboards
753
- for top users, items, and expenses.
754
  """
755
  try:
756
  verify_admin_and_get_uid(request.headers.get('Authorization'))
@@ -759,11 +759,10 @@ def get_admin_dashboard_stats():
759
  all_users_docs = list(db.collection('users').stream())
760
  all_orgs_docs = list(db.collection('organizations').stream())
761
 
762
- # Data structures for leaderboards
763
- user_sales_data = {} # {phone: {'total_revenue': X, 'item_sales': {item: revenue}}}
764
- global_item_revenue = {} # {item_name: total_revenue}
765
- global_expense_totals = {} # {category: total_amount}
766
- phone_to_user_map = {} # Helper to get user info from phone
767
 
768
  # --- First Pass: Get user info and list of approved phones ---
769
  pending_approvals, approved_users, admin_count = 0, 0, 0
@@ -787,7 +786,7 @@ def get_admin_dashboard_stats():
787
  user_stats = {'total': len(all_users_docs), 'admins': admin_count, 'approvedForBot': approved_users, 'pendingApproval': pending_approvals}
788
  org_stats = {'total': len(all_orgs_docs)}
789
 
790
- # --- Second Pass: Aggregate financial data for all approved users ---
791
  total_sales_revenue, total_cogs, total_expenses, sales_count = 0, 0, 0, 0
792
 
793
  for phone in approved_phone_numbers:
@@ -795,7 +794,6 @@ def get_admin_dashboard_stats():
795
  bot_data_id = phone.lstrip('+')
796
  bot_user_ref = db.collection('users').document(bot_data_id)
797
 
798
- # Initialize user's entry for leaderboard tracking
799
  user_sales_data[phone] = {'total_revenue': 0, 'item_sales': {}}
800
 
801
  # Process Sales
@@ -808,12 +806,10 @@ def get_admin_dashboard_stats():
808
  item_name = details.get('item', 'Unknown Item')
809
  sale_revenue = price * quantity
810
 
811
- # Aggregate for global system stats
812
  total_sales_revenue += sale_revenue
813
  total_cogs += cost * quantity
814
  sales_count += 1
815
 
816
- # Aggregate for leaderboards
817
  user_sales_data[phone]['total_revenue'] += sale_revenue
818
  user_sales_data[phone]['item_sales'][item_name] = user_sales_data[phone]['item_sales'].get(item_name, 0) + sale_revenue
819
  global_item_revenue[item_name] = global_item_revenue.get(item_name, 0) + sale_revenue
@@ -823,7 +819,11 @@ def get_admin_dashboard_stats():
823
  for expense_doc in expenses_docs:
824
  details = expense_doc.to_dict().get('details', {})
825
  amount = float(details.get('amount', 0))
826
- category = details.get('category', 'Uncategorized')
 
 
 
 
827
 
828
  total_expenses += amount
829
  global_expense_totals[category] = global_expense_totals.get(category, 0) + amount
@@ -839,7 +839,6 @@ def get_admin_dashboard_stats():
839
  top_users_by_revenue = []
840
  for phone, data in sorted_users[:5]:
841
  user_info = phone_to_user_map.get(phone, {})
842
- # Find this user's top selling item
843
  top_item = max(data['item_sales'], key=data['item_sales'].get) if data['item_sales'] else 'N/A'
844
  top_users_by_revenue.append({
845
  'displayName': user_info.get('displayName'),
@@ -852,7 +851,7 @@ def get_admin_dashboard_stats():
852
  sorted_items = sorted(global_item_revenue.items(), key=lambda item: item[1], reverse=True)
853
  top_selling_items = [{'item': name, 'totalRevenue': round(revenue, 2)} for name, revenue in sorted_items[:5]]
854
 
855
- # Rank Top Expenses Globally
856
  sorted_expenses = sorted(global_expense_totals.items(), key=lambda item: item[1], reverse=True)
857
  top_expenses = [{'category': name, 'totalAmount': round(amount, 2)} for name, amount in sorted_expenses[:5]]
858
 
@@ -872,7 +871,7 @@ def get_admin_dashboard_stats():
872
  'userStats': user_stats,
873
  'organizationStats': org_stats,
874
  'systemStats': system_stats,
875
- 'leaderboards': { # Add the new leaderboards to the response
876
  'topUsersByRevenue': top_users_by_revenue,
877
  'topSellingItems': top_selling_items,
878
  'topExpenses': top_expenses
 
749
  @app.route('/api/admin/dashboard/stats', methods=['GET'])
750
  def get_admin_dashboard_stats():
751
  """
752
+ Retrieves global statistics for the admin dashboard, including leaderboards.
753
+ **FIXED**: Correctly groups expenses by the 'description' field for the leaderboard.
754
  """
755
  try:
756
  verify_admin_and_get_uid(request.headers.get('Authorization'))
 
759
  all_users_docs = list(db.collection('users').stream())
760
  all_orgs_docs = list(db.collection('organizations').stream())
761
 
762
+ user_sales_data = {}
763
+ global_item_revenue = {}
764
+ global_expense_totals = {} # This will be populated correctly now
765
+ phone_to_user_map = {}
 
766
 
767
  # --- First Pass: Get user info and list of approved phones ---
768
  pending_approvals, approved_users, admin_count = 0, 0, 0
 
786
  user_stats = {'total': len(all_users_docs), 'admins': admin_count, 'approvedForBot': approved_users, 'pendingApproval': pending_approvals}
787
  org_stats = {'total': len(all_orgs_docs)}
788
 
789
+ # --- Second Pass: Aggregate financial data ---
790
  total_sales_revenue, total_cogs, total_expenses, sales_count = 0, 0, 0, 0
791
 
792
  for phone in approved_phone_numbers:
 
794
  bot_data_id = phone.lstrip('+')
795
  bot_user_ref = db.collection('users').document(bot_data_id)
796
 
 
797
  user_sales_data[phone] = {'total_revenue': 0, 'item_sales': {}}
798
 
799
  # Process Sales
 
806
  item_name = details.get('item', 'Unknown Item')
807
  sale_revenue = price * quantity
808
 
 
809
  total_sales_revenue += sale_revenue
810
  total_cogs += cost * quantity
811
  sales_count += 1
812
 
 
813
  user_sales_data[phone]['total_revenue'] += sale_revenue
814
  user_sales_data[phone]['item_sales'][item_name] = user_sales_data[phone]['item_sales'].get(item_name, 0) + sale_revenue
815
  global_item_revenue[item_name] = global_item_revenue.get(item_name, 0) + sale_revenue
 
819
  for expense_doc in expenses_docs:
820
  details = expense_doc.to_dict().get('details', {})
821
  amount = float(details.get('amount', 0))
822
+
823
+ # --- THE FIX IS HERE ---
824
+ # Use the 'description' field for grouping, as seen in Firestore.
825
+ category = details.get('description', 'Uncategorized')
826
+ # --- END OF FIX ---
827
 
828
  total_expenses += amount
829
  global_expense_totals[category] = global_expense_totals.get(category, 0) + amount
 
839
  top_users_by_revenue = []
840
  for phone, data in sorted_users[:5]:
841
  user_info = phone_to_user_map.get(phone, {})
 
842
  top_item = max(data['item_sales'], key=data['item_sales'].get) if data['item_sales'] else 'N/A'
843
  top_users_by_revenue.append({
844
  'displayName': user_info.get('displayName'),
 
851
  sorted_items = sorted(global_item_revenue.items(), key=lambda item: item[1], reverse=True)
852
  top_selling_items = [{'item': name, 'totalRevenue': round(revenue, 2)} for name, revenue in sorted_items[:5]]
853
 
854
+ # Rank Top Expenses Globally (This will now be correct)
855
  sorted_expenses = sorted(global_expense_totals.items(), key=lambda item: item[1], reverse=True)
856
  top_expenses = [{'category': name, 'totalAmount': round(amount, 2)} for name, amount in sorted_expenses[:5]]
857
 
 
871
  'userStats': user_stats,
872
  'organizationStats': org_stats,
873
  'systemStats': system_stats,
874
+ 'leaderboards': {
875
  'topUsersByRevenue': top_users_by_revenue,
876
  'topSellingItems': top_selling_items,
877
  'topExpenses': top_expenses