LogicGoInfotechSpaces commited on
Commit
21a5b7f
·
1 Parent(s): 2210c72

Improve check_user_has_category_data to comprehensively search budgets collection and fix logic to prioritize historical data over budget_amount

Browse files
Files changed (2) hide show
  1. app/main.py +32 -35
  2. app/smart_recommendation.py +83 -56
app/main.py CHANGED
@@ -207,32 +207,23 @@ async def check_and_get_recommendations(request: RecommendationRequest, month: O
207
  # Check if user has previous data for this category
208
  has_data = recommender.check_user_has_category_data(request.user_id, request.category_id)
209
 
210
- if has_data or request.budget_amount:
211
- # Get recommendations for this specific category
212
- # Pass budget_amount if provided
213
  recommendations = recommender.get_recommendation_for_category(
214
  request.user_id,
215
  request.category_id,
216
  month,
217
  year,
218
- request.budget_amount
219
  )
220
 
221
  if recommendations:
222
- # Check if this is based on budget_amount only (no real historical data)
223
- # If user doesn't have data but provided budget_amount, set has_previous_data=False
224
- if not has_data and request.budget_amount:
225
- return RecommendationResponse(
226
- has_previous_data=False,
227
- recommendations=recommendations,
228
- message="Recommendation generated based on provided budget amount. User does not have previous spending data for this category."
229
- )
230
- else:
231
- return RecommendationResponse(
232
- has_previous_data=True,
233
- recommendations=recommendations,
234
- message=None
235
- )
236
  else:
237
  # User has data but no recommendations generated (edge case)
238
  return RecommendationResponse(
@@ -240,24 +231,30 @@ async def check_and_get_recommendations(request: RecommendationRequest, month: O
240
  recommendations=[],
241
  message="User has previous data but no recommendations could be generated for this category."
242
  )
243
- else:
244
- # User doesn't have previous data, but if budget_amount is provided, generate recommendation anyway
245
- if request.budget_amount and request.budget_amount > 0:
246
- recommendations = recommender.get_recommendation_for_category(
247
- request.user_id,
248
- request.category_id,
249
- month,
250
- year,
251
- request.budget_amount
252
- )
253
-
254
- if recommendations:
255
- return RecommendationResponse(
256
- has_previous_data=False,
257
- recommendations=recommendations,
258
- message=f"Recommendation generated based on provided budget amount. User does not have previous data for this category."
259
- )
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  # User doesn't have previous data and no budget_amount provided
262
  return RecommendationResponse(
263
  has_previous_data=False,
 
207
  # Check if user has previous data for this category
208
  has_data = recommender.check_user_has_category_data(request.user_id, request.category_id)
209
 
210
+ if has_data:
211
+ # User has previous data - use it for recommendations (ignore budget_amount if provided)
212
+ print(f"✅ User {request.user_id} has previous data for category {request.category_id} - using historical data")
213
  recommendations = recommender.get_recommendation_for_category(
214
  request.user_id,
215
  request.category_id,
216
  month,
217
  year,
218
+ budget_amount=None # Don't use budget_amount if user has historical data
219
  )
220
 
221
  if recommendations:
222
+ return RecommendationResponse(
223
+ has_previous_data=True,
224
+ recommendations=recommendations,
225
+ message=None
226
+ )
 
 
 
 
 
 
 
 
 
227
  else:
228
  # User has data but no recommendations generated (edge case)
229
  return RecommendationResponse(
 
231
  recommendations=[],
232
  message="User has previous data but no recommendations could be generated for this category."
233
  )
234
+ elif request.budget_amount and request.budget_amount > 0:
235
+ # User doesn't have previous data, but provided budget_amount - generate recommendation based on it
236
+ print(f"ℹ️ User {request.user_id} does not have previous data for category {request.category_id} - using provided budget_amount")
237
+ recommendations = recommender.get_recommendation_for_category(
238
+ request.user_id,
239
+ request.category_id,
240
+ month,
241
+ year,
242
+ request.budget_amount
243
+ )
 
 
 
 
 
 
 
244
 
245
+ if recommendations:
246
+ return RecommendationResponse(
247
+ has_previous_data=False,
248
+ recommendations=recommendations,
249
+ message="Recommendation generated based on provided budget amount. User does not have previous spending data for this category."
250
+ )
251
+ else:
252
+ return RecommendationResponse(
253
+ has_previous_data=False,
254
+ recommendations=None,
255
+ message="Could not generate recommendations even with provided budget amount."
256
+ )
257
+ else:
258
  # User doesn't have previous data and no budget_amount provided
259
  return RecommendationResponse(
260
  has_previous_data=False,
app/smart_recommendation.py CHANGED
@@ -125,79 +125,106 @@ class SmartBudgetRecommender:
125
  Returns:
126
  True if user has previous data for this category, False otherwise
127
  """
128
- # Check if user has budgets with this category_id
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  try:
130
- # Try ObjectId format
131
  try:
132
  category_objid = ObjectId(category_id)
133
- budget_query = {
134
  "$or": [
135
- {"createdBy": ObjectId(user_id), "category": category_objid},
136
- {"createdBy": ObjectId(user_id), "categoryId": category_objid},
137
- {"createdBy": ObjectId(user_id), "headCategory": category_objid},
138
- {"createdBy": user_id, "category": category_objid},
139
- {"createdBy": user_id, "categoryId": category_objid},
140
- {"createdBy": user_id, "headCategory": category_objid},
141
  {"user_id": ObjectId(user_id), "category": category_objid},
142
- {"user_id": user_id, "category": category_objid},
143
- ]
144
- }
145
- except (ValueError, TypeError):
146
- # category_id is not a valid ObjectId, try as string
147
- budget_query = {
148
- "$or": [
149
- {"createdBy": ObjectId(user_id), "category": category_id},
150
- {"createdBy": ObjectId(user_id), "categoryId": category_id},
151
- {"createdBy": ObjectId(user_id), "headCategory": category_id},
152
- {"createdBy": user_id, "category": category_id},
153
- {"createdBy": user_id, "categoryId": category_id},
154
- {"createdBy": user_id, "headCategory": category_id},
155
  {"user_id": ObjectId(user_id), "category": category_id},
 
156
  {"user_id": user_id, "category": category_id},
157
  ]
158
  }
159
-
160
- # Check budgets collection
161
- budget_count = self.db.budgets.count_documents(budget_query)
162
- if budget_count > 0:
163
- print(f"✅ Found {budget_count} budget(s) for user {user_id} with category_id {category_id}")
164
- return True
165
-
166
- # Also check if category_id is in headCategories array
167
- head_cat_query = {
168
- "$or": [
169
- {"createdBy": ObjectId(user_id), "headCategories.category": category_id},
170
- {"createdBy": user_id, "headCategories.category": category_id},
171
- {"user_id": ObjectId(user_id), "headCategories.category": category_id},
172
- {"user_id": user_id, "headCategories.category": category_id},
173
- ]
174
- }
175
- head_cat_count = self.db.budgets.count_documents(head_cat_query)
176
- if head_cat_count > 0:
177
- print(f"✅ Found {head_cat_count} budget(s) with category_id {category_id} in headCategories for user {user_id}")
178
- return True
179
-
180
- # Check expenses collection
181
- try:
182
  expense_query = {
183
  "$or": [
184
  {"user_id": ObjectId(user_id), "category": category_id},
185
  {"user_id": user_id, "category": category_id},
186
  ]
187
  }
188
- expense_count = self.db.expenses.count_documents(expense_query)
189
- if expense_count > 0:
190
- print(f"✅ Found {expense_count} expense(s) for user {user_id} with category_id {category_id}")
191
- return True
192
- except Exception as e:
193
- print(f"Error checking expenses: {e}")
194
-
195
- print(f"❌ No previous data found for user {user_id} with category_id {category_id}")
196
- return False
197
 
 
 
 
 
198
  except Exception as e:
199
- print(f"Error checking user category data: {e}")
200
- return False
 
 
201
 
202
  def get_recommendation_for_category(self, user_id: str, category_id: str, month: int, year: int, budget_amount: Optional[float] = None) -> List[BudgetRecommendation]:
203
  """
 
125
  Returns:
126
  True if user has previous data for this category, False otherwise
127
  """
128
+ print(f"🔍 check_user_has_category_data: Checking for user_id={user_id}, category_id={category_id}")
129
+
130
+ # Build comprehensive user query
131
+ user_conditions = []
132
+ try:
133
+ user_objid = ObjectId(user_id)
134
+ user_conditions = [
135
+ {"createdBy": user_objid},
136
+ {"createdBy": user_id},
137
+ {"user_id": user_objid},
138
+ {"user_id": user_id}
139
+ ]
140
+ except (ValueError, TypeError):
141
+ user_conditions = [
142
+ {"createdBy": user_id},
143
+ {"user_id": user_id}
144
+ ]
145
+
146
+ # Build comprehensive category query - check all possible fields
147
+ category_conditions = []
148
+ try:
149
+ category_objid = ObjectId(category_id)
150
+ # Try as ObjectId
151
+ category_conditions = [
152
+ {"category": category_objid},
153
+ {"categoryId": category_objid},
154
+ {"headCategory": category_objid},
155
+ {"headCategories.headCategory": category_objid},
156
+ {"headCategories.categories.category": category_objid},
157
+ # Also try as string
158
+ {"category": category_id},
159
+ {"categoryId": category_id},
160
+ {"headCategory": category_id},
161
+ {"headCategories.headCategory": category_id},
162
+ {"headCategories.categories.category": category_id},
163
+ ]
164
+ except (ValueError, TypeError):
165
+ # category_id is not a valid ObjectId, try as string only
166
+ category_conditions = [
167
+ {"category": category_id},
168
+ {"categoryId": category_id},
169
+ {"headCategory": category_id},
170
+ {"headCategories.headCategory": category_id},
171
+ {"headCategories.categories.category": category_id},
172
+ ]
173
+
174
+ # Combine user and category conditions
175
+ for user_cond in user_conditions:
176
+ for cat_cond in category_conditions:
177
+ budget_query = {**user_cond, **cat_cond}
178
+ budget_count = self.db.budgets.count_documents(budget_query)
179
+ if budget_count > 0:
180
+ print(f"✅ Found {budget_count} budget(s) for user {user_id} with category_id {category_id}")
181
+ print(f" Query that matched: {budget_query}")
182
+ return True
183
+
184
+ # Also try a more comprehensive query using $and and $or
185
+ try:
186
+ comprehensive_query = {
187
+ "$and": [
188
+ {"$or": user_conditions},
189
+ {"$or": category_conditions}
190
+ ]
191
+ }
192
+ budget_count = self.db.budgets.count_documents(comprehensive_query)
193
+ if budget_count > 0:
194
+ print(f"✅ Found {budget_count} budget(s) using comprehensive query for user {user_id} with category_id {category_id}")
195
+ return True
196
+ except Exception as e:
197
+ print(f"⚠️ Error with comprehensive query: {e}")
198
+
199
+ # Check expenses collection as fallback
200
  try:
 
201
  try:
202
  category_objid = ObjectId(category_id)
203
+ expense_query = {
204
  "$or": [
 
 
 
 
 
 
205
  {"user_id": ObjectId(user_id), "category": category_objid},
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  {"user_id": ObjectId(user_id), "category": category_id},
207
+ {"user_id": user_id, "category": category_objid},
208
  {"user_id": user_id, "category": category_id},
209
  ]
210
  }
211
+ except (ValueError, TypeError):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  expense_query = {
213
  "$or": [
214
  {"user_id": ObjectId(user_id), "category": category_id},
215
  {"user_id": user_id, "category": category_id},
216
  ]
217
  }
 
 
 
 
 
 
 
 
 
218
 
219
+ expense_count = self.db.expenses.count_documents(expense_query)
220
+ if expense_count > 0:
221
+ print(f"✅ Found {expense_count} expense(s) for user {user_id} with category_id {category_id}")
222
+ return True
223
  except Exception as e:
224
+ print(f"Error checking expenses: {e}")
225
+
226
+ print(f"❌ No previous data found for user {user_id} with category_id {category_id}")
227
+ return False
228
 
229
  def get_recommendation_for_category(self, user_id: str, category_id: str, month: int, year: int, budget_amount: Optional[float] = None) -> List[BudgetRecommendation]:
230
  """