rairo commited on
Commit
2cebcff
·
verified ·
1 Parent(s): ea21e37

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +50 -17
main.py CHANGED
@@ -228,8 +228,7 @@ def get_user_profile():
228
  def get_user_dashboard():
229
  """
230
  Retrieves and aggregates data for the user's dashboard.
231
- **FIXED**: Now normalizes currency codes to prevent fragmentation (e.g., '$' and 'USD'
232
- are treated as the same currency).
233
  """
234
  uid = verify_token(request.headers.get('Authorization'))
235
  if not uid: return jsonify({'error': 'Invalid or expired token'}), 401
@@ -245,36 +244,51 @@ def get_user_dashboard():
245
  if not phone_number: return jsonify({'error': 'No phone number is associated with your account.'}), 404
246
 
247
  try:
 
 
 
 
 
 
 
 
 
248
  bot_data_id = phone_number.lstrip('+')
249
  bot_user_ref = db.collection('users').document(bot_data_id)
250
 
251
  sales_revenue_by_currency, cogs_by_currency, expenses_by_currency = {}, {}, {}
252
  sales_count = 0
253
 
254
- # --- THE FIX IS HERE ---
255
- # Establish the user's default currency as the initial fallback
256
  default_currency_code = normalize_currency_code(user_data.get('defaultCurrency'), 'USD')
257
  last_seen_currency_code = default_currency_code
258
 
259
  # Process Sales
260
- for doc in bot_user_ref.collection('sales').stream():
 
 
 
 
 
 
261
  details = doc.to_dict().get('details', {})
262
-
263
- # Normalize the currency code using the helper function
264
  currency_code = normalize_currency_code(details.get('currency'), last_seen_currency_code)
265
- last_seen_currency_code = currency_code # Update for the next transaction
266
-
267
  quantity, price, cost = int(details.get('quantity', 1)), float(details.get('price', 0)), float(details.get('cost', 0))
268
  sales_revenue_by_currency[currency_code] = sales_revenue_by_currency.get(currency_code, 0) + (price * quantity)
269
  cogs_by_currency[currency_code] = cogs_by_currency.get(currency_code, 0) + (cost * quantity)
270
  sales_count += 1
271
 
272
  # Process Expenses
273
- for doc in bot_user_ref.collection('expenses').stream():
 
 
 
 
 
 
274
  details = doc.to_dict().get('details', {})
275
  currency_code = normalize_currency_code(details.get('currency'), last_seen_currency_code)
276
  last_seen_currency_code = currency_code
277
-
278
  amount = float(details.get('amount', 0))
279
  expenses_by_currency[currency_code] = expenses_by_currency.get(currency_code, 0) + amount
280
 
@@ -788,10 +802,20 @@ def get_admin_dashboard_stats():
788
  """
789
  Retrieves complete global statistics, including an accurate total user count
790
  and separate Top 5 leaderboards for each currency.
 
791
  """
792
  try:
793
  verify_admin_and_get_uid(request.headers.get('Authorization'))
794
 
 
 
 
 
 
 
 
 
 
795
  # --- Initialization ---
796
  all_users_docs = list(db.collection('users').stream())
797
  all_orgs_docs = list(db.collection('organizations').stream())
@@ -820,17 +844,14 @@ def get_admin_dashboard_stats():
820
  if user_data.get('isAdmin', False):
821
  admin_count += 1
822
 
823
- # --- THE FIX IS HERE: Create a filtered list of only user profiles for an accurate count ---
824
  user_profile_docs = [doc for doc in all_users_docs if doc.to_dict().get('email')]
825
 
826
- # Assemble the accurate user stats
827
  user_stats = {
828
- 'total': len(user_profile_docs), # Use the length of the filtered list
829
  'admins': admin_count,
830
  'approvedForBot': approved_users,
831
  'pendingApproval': pending_approvals
832
  }
833
- # --- END OF FIX ---
834
 
835
  org_stats = {'total': len(all_orgs_docs)}
836
 
@@ -844,7 +865,13 @@ def get_admin_dashboard_stats():
844
  user_sales_data[phone] = {'total_revenue_by_currency': {}, 'item_sales': {}}
845
  last_seen_currency_code = normalize_currency_code(phone_to_user_map.get(phone, {}).get('defaultCurrency'), 'USD')
846
 
847
- for sale_doc in bot_user_ref.collection('sales').stream():
 
 
 
 
 
 
848
  details = sale_doc.to_dict().get('details', {})
849
  currency_code = normalize_currency_code(details.get('currency'), last_seen_currency_code)
850
  last_seen_currency_code = currency_code
@@ -861,7 +888,13 @@ def get_admin_dashboard_stats():
861
  if item_name not in global_item_revenue: global_item_revenue[item_name] = {}
862
  global_item_revenue[item_name][currency_code] = global_item_revenue[item_name].get(currency_code, 0) + sale_revenue
863
 
864
- for expense_doc in bot_user_ref.collection('expenses').stream():
 
 
 
 
 
 
865
  details = expense_doc.to_dict().get('details', {})
866
  currency_code = normalize_currency_code(details.get('currency'), last_seen_currency_code)
867
  last_seen_currency_code = currency_code
 
228
  def get_user_dashboard():
229
  """
230
  Retrieves and aggregates data for the user's dashboard.
231
+ **MODIFIED**: Now filters by a date range if provided.
 
232
  """
233
  uid = verify_token(request.headers.get('Authorization'))
234
  if not uid: return jsonify({'error': 'Invalid or expired token'}), 401
 
244
  if not phone_number: return jsonify({'error': 'No phone number is associated with your account.'}), 404
245
 
246
  try:
247
+ start_date_str = request.args.get('start_date')
248
+ end_date_str = request.args.get('end_date')
249
+
250
+ start_date, end_date = None, None
251
+ if start_date_str:
252
+ start_date = datetime.fromisoformat(start_date_str.replace('Z', '+00:00'))
253
+ if end_date_str:
254
+ end_date = datetime.fromisoformat(end_date_str.replace('Z', '+00:00'))
255
+
256
  bot_data_id = phone_number.lstrip('+')
257
  bot_user_ref = db.collection('users').document(bot_data_id)
258
 
259
  sales_revenue_by_currency, cogs_by_currency, expenses_by_currency = {}, {}, {}
260
  sales_count = 0
261
 
 
 
262
  default_currency_code = normalize_currency_code(user_data.get('defaultCurrency'), 'USD')
263
  last_seen_currency_code = default_currency_code
264
 
265
  # Process Sales
266
+ sales_query = bot_user_ref.collection('sales')
267
+ if start_date:
268
+ sales_query = sales_query.where('createdAt', '>=', start_date)
269
+ if end_date:
270
+ sales_query = sales_query.where('createdAt', '<=', end_date)
271
+
272
+ for doc in sales_query.stream():
273
  details = doc.to_dict().get('details', {})
 
 
274
  currency_code = normalize_currency_code(details.get('currency'), last_seen_currency_code)
275
+ last_seen_currency_code = currency_code
 
276
  quantity, price, cost = int(details.get('quantity', 1)), float(details.get('price', 0)), float(details.get('cost', 0))
277
  sales_revenue_by_currency[currency_code] = sales_revenue_by_currency.get(currency_code, 0) + (price * quantity)
278
  cogs_by_currency[currency_code] = cogs_by_currency.get(currency_code, 0) + (cost * quantity)
279
  sales_count += 1
280
 
281
  # Process Expenses
282
+ expenses_query = bot_user_ref.collection('expenses')
283
+ if start_date:
284
+ expenses_query = expenses_query.where('createdAt', '>=', start_date)
285
+ if end_date:
286
+ expenses_query = expenses_query.where('createdAt', '<=', end_date)
287
+
288
+ for doc in expenses_query.stream():
289
  details = doc.to_dict().get('details', {})
290
  currency_code = normalize_currency_code(details.get('currency'), last_seen_currency_code)
291
  last_seen_currency_code = currency_code
 
292
  amount = float(details.get('amount', 0))
293
  expenses_by_currency[currency_code] = expenses_by_currency.get(currency_code, 0) + amount
294
 
 
802
  """
803
  Retrieves complete global statistics, including an accurate total user count
804
  and separate Top 5 leaderboards for each currency.
805
+ **MODIFIED**: Now filters by a date range if provided.
806
  """
807
  try:
808
  verify_admin_and_get_uid(request.headers.get('Authorization'))
809
 
810
+ start_date_str = request.args.get('start_date')
811
+ end_date_str = request.args.get('end_date')
812
+
813
+ start_date, end_date = None, None
814
+ if start_date_str:
815
+ start_date = datetime.fromisoformat(start_date_str.replace('Z', '+00:00'))
816
+ if end_date_str:
817
+ end_date = datetime.fromisoformat(end_date_str.replace('Z', '+00:00'))
818
+
819
  # --- Initialization ---
820
  all_users_docs = list(db.collection('users').stream())
821
  all_orgs_docs = list(db.collection('organizations').stream())
 
844
  if user_data.get('isAdmin', False):
845
  admin_count += 1
846
 
 
847
  user_profile_docs = [doc for doc in all_users_docs if doc.to_dict().get('email')]
848
 
 
849
  user_stats = {
850
+ 'total': len(user_profile_docs),
851
  'admins': admin_count,
852
  'approvedForBot': approved_users,
853
  'pendingApproval': pending_approvals
854
  }
 
855
 
856
  org_stats = {'total': len(all_orgs_docs)}
857
 
 
865
  user_sales_data[phone] = {'total_revenue_by_currency': {}, 'item_sales': {}}
866
  last_seen_currency_code = normalize_currency_code(phone_to_user_map.get(phone, {}).get('defaultCurrency'), 'USD')
867
 
868
+ sales_query = bot_user_ref.collection('sales')
869
+ if start_date:
870
+ sales_query = sales_query.where('createdAt', '>=', start_date)
871
+ if end_date:
872
+ sales_query = sales_query.where('createdAt', '<=', end_date)
873
+
874
+ for sale_doc in sales_query.stream():
875
  details = sale_doc.to_dict().get('details', {})
876
  currency_code = normalize_currency_code(details.get('currency'), last_seen_currency_code)
877
  last_seen_currency_code = currency_code
 
888
  if item_name not in global_item_revenue: global_item_revenue[item_name] = {}
889
  global_item_revenue[item_name][currency_code] = global_item_revenue[item_name].get(currency_code, 0) + sale_revenue
890
 
891
+ expenses_query = bot_user_ref.collection('expenses')
892
+ if start_date:
893
+ expenses_query = expenses_query.where('createdAt', '>=', start_date)
894
+ if end_date:
895
+ expenses_query = expenses_query.where('createdAt', '<=', end_date)
896
+
897
+ for expense_doc in expenses_query.stream():
898
  details = expense_doc.to_dict().get('details', {})
899
  currency_code = normalize_currency_code(details.get('currency'), last_seen_currency_code)
900
  last_seen_currency_code = currency_code