yoursdvniel commited on
Commit
1989702
·
verified ·
1 Parent(s): c33867e

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +106 -84
main.py CHANGED
@@ -97,105 +97,127 @@ def marketing_rec():
97
  @app.route("/predict_metric", methods=["POST"])
98
  @cross_origin()
99
  def predict_metric():
100
- request_data = request.json
101
- user_id = request_data.get("user_id")
102
- interval = request_data.get("interval", 30)
103
- metric_type = request_data.get("metric_type", "Profit") # "Profit" or "Customer Engagement"
104
-
105
- transactions_ref = db.collection("system_users").document(user_id).collection("transactions")
106
-
107
- data = []
108
-
109
- if metric_type == "Profit":
110
- # Fetch both Income and Expense transactions for Profit calculation
111
- income_query = transactions_ref.where("transactionType", "==", "Income").stream()
112
- expense_query = transactions_ref.where("transactionType", "==", "Expense").stream()
113
-
114
- income_data = {}
115
- expense_data = {}
116
-
117
- for doc in income_query:
118
- transaction = doc.to_dict()
119
- date_str = transaction["date"].toDate() # Convert Firestore Timestamp to DateTime
120
- amount = transaction["amountDue"]
121
- income_data[date_str] = income_data.get(date_str, 0) + amount
122
- print(f"Income transaction - Date: {date_str}, Amount: {amount}")
123
-
124
- for doc in expense_query:
125
- transaction = doc.to_dict()
126
- date_str = transaction["date"].toDate() # Convert Firestore Timestamp to DateTime
127
- amount = transaction["amountDue"]
128
- expense_data[date_str] = expense_data.get(date_str, 0) + amount
129
- print(f"Expense transaction - Date: {date_str}, Amount: {amount}")
130
-
131
- # Calculate net profit for each date
132
- for date, income in income_data.items():
133
- expense = expense_data.get(date, 0)
134
- data.append({"date": date, "amountDue": income - expense})
135
-
136
- elif metric_type == "Customer Engagement":
137
- # Use count of Income transactions per day as Customer Engagement
138
- income_query = transactions_ref.where("transactionType", "==", "Income").stream()
139
-
140
- engagement_data = {}
141
- for doc in income_query:
142
- transaction = doc.to_dict()
143
- date_str = transaction["date"].toDate() # Convert Firestore Timestamp to DateTime
144
- engagement_data[date_str] = engagement_data.get(date_str, 0) + 1
145
- print(f"Engagement transaction - Date: {date_str}")
146
-
147
- for date, count in engagement_data.items():
148
- data.append({"date": date, "amountDue": count})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
150
- # Create DataFrame from the aggregated data
151
- df = pd.DataFrame(data)
 
152
 
153
- # Log the DataFrame before further processing
154
- print("Data before processing:", df)
155
 
156
- # Ensure 'date' column is datetime
157
- df['date'] = pd.to_datetime(df['date'], errors='coerce')
158
- df['date'] = df['date'].dt.tz_localize(None)
159
 
160
- # Log DataFrame after date conversion
161
- print("Data after date conversion:", df)
 
162
 
163
- # Drop rows where 'date' could not be parsed
164
- df = df.dropna(subset=['date'])
165
 
166
- # Set 'date' as index
167
- df = df.sort_values("date").set_index("date")
 
 
168
 
169
- # Resample daily to ensure regular intervals (fill missing dates)
170
- df = df.resample("D").sum().reset_index()
 
171
 
172
- # Log DataFrame after resampling
173
- print("Data after resampling:", df)
 
 
 
174
 
175
- df.columns = ["ds", "y"] # ds: date, y: target
 
 
176
 
177
- # Check if there's enough data to train the model
178
- if df.shape[0] < 10:
179
- print("Not enough data for prediction")
180
- return jsonify({"error": "Not enough data for prediction"})
181
 
182
- # Initialize and fit the Prophet model
183
- model = Prophet(daily_seasonality=True, yearly_seasonality=True)
184
- model.fit(df)
185
 
186
- # DataFrame for future predictions
187
- future_dates = model.make_future_dataframe(periods=interval)
188
- forecast = model.predict(future_dates)
189
 
190
- # Extract the forecast for the requested interval
191
- forecast_data = forecast[['ds', 'yhat']].tail(interval)
192
- predictions = [{"date": row['ds'].strftime('%Y-%m-%d'), "value": row['yhat']} for _, row in forecast_data.iterrows()]
193
 
194
- # Log the predictions before returning
195
- print("Predictions:", predictions)
 
196
 
197
- # Return predictions in JSON format
198
- return jsonify({"predictedData": predictions})
199
 
200
 
201
 
 
97
  @app.route("/predict_metric", methods=["POST"])
98
  @cross_origin()
99
  def predict_metric():
100
+ try:
101
+ request_data = request.json
102
+ user_id = request_data.get("user_id")
103
+ interval = request_data.get("interval", 30)
104
+ metric_type = request_data.get("metric_type", "Profit") # "Profit" or "Customer Engagement"
105
+
106
+ # Log received request data
107
+ print("Received request:", request_data)
108
+
109
+ transactions_ref = db.collection("system_users").document(user_id).collection("transactions")
110
+ data = []
111
+
112
+ if metric_type == "Profit":
113
+ try:
114
+ # Fetch both Income and Expense transactions for Profit calculation
115
+ income_query = transactions_ref.where("transactionType", "==", "Income").stream()
116
+ expense_query = transactions_ref.where("transactionType", "==", "Expense").stream()
117
+
118
+ income_data = {}
119
+ expense_data = {}
120
+
121
+ for doc in income_query:
122
+ transaction = doc.to_dict()
123
+ date_str = transaction["date"].toDate() # Convert Firestore Timestamp to DateTime
124
+ amount = transaction["amountDue"]
125
+ income_data[date_str] = income_data.get(date_str, 0) + amount
126
+ print(f"Income transaction - Date: {date_str}, Amount: {amount}")
127
+
128
+ for doc in expense_query:
129
+ transaction = doc.to_dict()
130
+ date_str = transaction["date"].toDate() # Convert Firestore Timestamp to DateTime
131
+ amount = transaction["amountDue"]
132
+ expense_data[date_str] = expense_data.get(date_str, 0) + amount
133
+ print(f"Expense transaction - Date: {date_str}, Amount: {amount}")
134
+
135
+ # Calculate net profit for each date
136
+ for date, income in income_data.items():
137
+ expense = expense_data.get(date, 0)
138
+ data.append({"date": date, "amountDue": income - expense})
139
+
140
+ except Exception as e:
141
+ print("Error processing Profit data:", str(e))
142
+ return jsonify({"error": "Error processing Profit data"}), 500
143
+
144
+ elif metric_type == "Customer Engagement":
145
+ try:
146
+ # Use count of Income transactions per day as Customer Engagement
147
+ income_query = transactions_ref.where("transactionType", "==", "Income").stream()
148
+
149
+ engagement_data = {}
150
+ for doc in income_query:
151
+ transaction = doc.to_dict()
152
+ date_str = transaction["date"].toDate() # Convert Firestore Timestamp to DateTime
153
+ engagement_data[date_str] = engagement_data.get(date_str, 0) + 1
154
+ print(f"Engagement transaction - Date: {date_str}")
155
+
156
+ for date, count in engagement_data.items():
157
+ data.append({"date": date, "amountDue": count})
158
+
159
+ except Exception as e:
160
+ print("Error processing Customer Engagement data:", str(e))
161
+ return jsonify({"error": "Error processing Customer Engagement data"}), 500
162
+
163
+ # Create DataFrame from the aggregated data
164
+ try:
165
+ df = pd.DataFrame(data)
166
+ print("Data before processing:", df)
167
 
168
+ # Ensure 'date' column is datetime
169
+ df['date'] = pd.to_datetime(df['date'], errors='coerce')
170
+ df['date'] = df['date'].dt.tz_localize(None)
171
 
172
+ # Drop rows where 'date' could not be parsed
173
+ df = df.dropna(subset=['date'])
174
 
175
+ # Set 'date' as index
176
+ df = df.sort_values("date").set_index("date")
 
177
 
178
+ # Resample daily to ensure regular intervals (fill missing dates)
179
+ df = df.resample("D").sum().reset_index()
180
+ print("Data after resampling:", df)
181
 
182
+ df.columns = ["ds", "y"] # ds: date, y: target
 
183
 
184
+ # Check if there's enough data to train the model
185
+ if df.shape[0] < 10:
186
+ print("Not enough data for prediction")
187
+ return jsonify({"error": "Not enough data for prediction"}), 400
188
 
189
+ except Exception as e:
190
+ print("Error processing DataFrame:", str(e))
191
+ return jsonify({"error": "Error processing DataFrame"}), 500
192
 
193
+ # Prophet prediction
194
+ try:
195
+ # Initialize and fit the Prophet model
196
+ model = Prophet(daily_seasonality=True, yearly_seasonality=True)
197
+ model.fit(df)
198
 
199
+ # DataFrame for future predictions
200
+ future_dates = model.make_future_dataframe(periods=interval)
201
+ forecast = model.predict(future_dates)
202
 
203
+ # Extract the forecast for the requested interval
204
+ forecast_data = forecast[['ds', 'yhat']].tail(interval)
205
+ predictions = [{"date": row['ds'].strftime('%Y-%m-%d'), "value": row['yhat']} for _, row in forecast_data.iterrows()]
 
206
 
207
+ # Log the predictions before returning
208
+ print("Predictions:", predictions)
 
209
 
210
+ # Return predictions in JSON format
211
+ return jsonify({"predictedData": predictions})
 
212
 
213
+ except Exception as e:
214
+ print("Error in Prophet prediction:", str(e))
215
+ return jsonify({"error": "Error in Prophet prediction"}), 500
216
 
217
+ except Exception as e:
218
+ print("General error:", str(e))
219
+ return jsonify({"error": "Internal server error"}), 500
220
 
 
 
221
 
222
 
223