AjaykumarPilla commited on
Commit
61f69c5
·
verified ·
1 Parent(s): 8712241

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -15
app.py CHANGED
@@ -108,21 +108,41 @@ def validate_usage_series(usage_str):
108
 
109
  def generate_forecast_pdf(forecast_data: dict, daily_forecasts: pd.DataFrame, alert_status: list, current_stock: int, forecast_7: int, forecast_14: int, forecast_30: int, fig_daily: go.Figure, fig_alerts: go.Figure, usage_series: str) -> BytesIO:
110
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  pdf_file = BytesIO()
112
  c = canvas.Canvas(pdf_file, pagesize=letter)
113
  c.setFont("Helvetica", 12)
114
  c.drawString(1 * inch, 10 * inch, "Consumables Forecast Report")
115
  c.setFont("Helvetica", 10)
116
  y_position = 9.5 * inch
 
117
 
118
- # Basic Forecast Data (Consumable Type, Current Stock, Forecast Results, Order Suggestions, Reorder Information)
 
119
  for key, value in forecast_data.items():
120
  display_key = key.replace('_', ' ').title()
121
  value_str = str(value)
122
  c.drawString(1 * inch, y_position, f"{display_key}: {value_str}")
123
  y_position -= 0.3 * inch
124
 
125
- # Add Last 60 Days Usage (comma-separated)
126
  y_position -= 0.3 * inch
127
  c.drawString(1 * inch, y_position, "Last 60 Days Usage (comma-separated):")
128
  y_position -= 0.3 * inch
@@ -133,8 +153,9 @@ def generate_forecast_pdf(forecast_data: dict, daily_forecasts: pd.DataFrame, al
133
  text_object.textLine(line)
134
  y_position -= 0.3 * inch
135
  c.drawText(text_object)
 
136
 
137
- # Add Daily Forecast Values (Next 30 Days) / Comma-separated daily forecasts
138
  y_position -= 0.3 * inch
139
  c.drawString(1 * inch, y_position, "Daily Forecast Values (Next 30 Days):")
140
  y_position -= 0.3 * inch
@@ -146,8 +167,9 @@ def generate_forecast_pdf(forecast_data: dict, daily_forecasts: pd.DataFrame, al
146
  text_object.textLine(line)
147
  y_position -= 0.3 * inch
148
  c.drawText(text_object)
 
149
 
150
- # Add Threshold Alerts (with flag indicator as text)
151
  y_position -= 0.3 * inch
152
  c.drawString(1 * inch, y_position, "Threshold Alerts:")
153
  y_position -= 0.3 * inch
@@ -159,8 +181,9 @@ def generate_forecast_pdf(forecast_data: dict, daily_forecasts: pd.DataFrame, al
159
  alert_text = f"No alert for {period} forecast."
160
  c.drawString(1 * inch, y_position, alert_text)
161
  y_position -= 0.3 * inch
 
162
 
163
- # Add Daily Forecast Visualization Data (Next 30 Days)
164
  y_position -= 0.3 * inch
165
  c.drawString(1 * inch, y_position, "Daily Forecast Visualization Data (Next 30 Days):")
166
  y_position -= 0.3 * inch
@@ -173,19 +196,25 @@ def generate_forecast_pdf(forecast_data: dict, daily_forecasts: pd.DataFrame, al
173
  c.showPage()
174
  c.setFont("Helvetica", 10)
175
  y_position = 10 * inch
 
176
 
177
  # Add Daily Forecast Visualization Image
178
  y_position -= 0.3 * inch
179
- if y_position < 4 * inch: # Ensure enough space for the image
180
  c.showPage()
181
  y_position = 10 * inch
182
  c.drawString(1 * inch, y_position, "Daily Forecast Visualization (Next 30 Days):")
183
  y_position -= 0.3 * inch
184
  daily_chart_img = BytesIO()
185
- pio.write_image(fig_daily, daily_chart_img, format='png', width=600, height=400)
186
- daily_chart_img.seek(0)
187
- img = Image(daily_chart_img, width=6 * inch, height=4 * inch)
188
- img.drawOn(c, 1 * inch, y_position - 4 * inch)
 
 
 
 
 
189
  y_position -= 4.5 * inch
190
 
191
  # Add Threshold Alerts Visualization Data
@@ -208,6 +237,7 @@ def generate_forecast_pdf(forecast_data: dict, daily_forecasts: pd.DataFrame, al
208
  c.showPage()
209
  c.setFont("Helvetica", 10)
210
  y_position = 10 * inch
 
211
 
212
  # Add Threshold Alerts Visualization Image
213
  y_position -= 0.3 * inch
@@ -217,14 +247,20 @@ def generate_forecast_pdf(forecast_data: dict, daily_forecasts: pd.DataFrame, al
217
  c.drawString(1 * inch, y_position, "Threshold Alerts Visualization:")
218
  y_position -= 0.3 * inch
219
  alerts_chart_img = BytesIO()
220
- pio.write_image(fig_alerts, alerts_chart_img, format='png', width=600, height=400)
221
- alerts_chart_img.seek(0)
222
- img = Image(alerts_chart_img, width=6 * inch, height=4 * inch)
223
- img.drawOn(c, 1 * inch, y_position - 4 * inch)
 
 
 
 
 
224
 
225
  c.showPage()
226
  c.save()
227
  pdf_file.seek(0)
 
228
  return pdf_file
229
  except Exception as e:
230
  logger.error(f"Error generating PDF: {str(e)}")
@@ -403,7 +439,7 @@ def main():
403
  {"Pdf_report__c": pdf_url}
404
  )
405
  logger.info(f"PDF uploaded to Salesforce: {pdf_url}")
406
- st.success(f"PDF Report generated and uploaded to Salesforce: {pdf_url}")
407
  else:
408
  logger.error("Failed to upload PDF to Salesforce")
409
  st.error("Failed to upload PDF to Salesforce")
 
108
 
109
  def generate_forecast_pdf(forecast_data: dict, daily_forecasts: pd.DataFrame, alert_status: list, current_stock: int, forecast_7: int, forecast_14: int, forecast_30: int, fig_daily: go.Figure, fig_alerts: go.Figure, usage_series: str) -> BytesIO:
110
  try:
111
+ logger.info("Starting PDF generation")
112
+ # Validate inputs
113
+ if not isinstance(forecast_data, dict) or not forecast_data:
114
+ logger.error("Invalid forecast_data: Must be a non-empty dictionary")
115
+ return None
116
+ if not isinstance(daily_forecasts, pd.DataFrame) or daily_forecasts.empty:
117
+ logger.error("Invalid daily_forecasts: Must be a non-empty DataFrame")
118
+ return None
119
+ if not isinstance(alert_status, list) or len(alert_status) != 3:
120
+ logger.error("Invalid alert_status: Must be a list of 3 booleans")
121
+ return None
122
+ if not isinstance(usage_series, str) or not usage_series:
123
+ logger.error("Invalid usage_series: Must be a non-empty string")
124
+ return None
125
+ if not isinstance(fig_daily, go.Figure) or not isinstance(fig_alerts, go.Figure):
126
+ logger.error("Invalid Plotly figures: fig_daily and fig_alerts must be valid go.Figure objects")
127
+ return None
128
+
129
  pdf_file = BytesIO()
130
  c = canvas.Canvas(pdf_file, pagesize=letter)
131
  c.setFont("Helvetica", 12)
132
  c.drawString(1 * inch, 10 * inch, "Consumables Forecast Report")
133
  c.setFont("Helvetica", 10)
134
  y_position = 9.5 * inch
135
+ logger.info("Initialized PDF canvas")
136
 
137
+ # Basic Forecast Data
138
+ logger.info("Writing forecast data")
139
  for key, value in forecast_data.items():
140
  display_key = key.replace('_', ' ').title()
141
  value_str = str(value)
142
  c.drawString(1 * inch, y_position, f"{display_key}: {value_str}")
143
  y_position -= 0.3 * inch
144
 
145
+ # Add Last 60 Days Usage
146
  y_position -= 0.3 * inch
147
  c.drawString(1 * inch, y_position, "Last 60 Days Usage (comma-separated):")
148
  y_position -= 0.3 * inch
 
153
  text_object.textLine(line)
154
  y_position -= 0.3 * inch
155
  c.drawText(text_object)
156
+ logger.info("Added usage series")
157
 
158
+ # Add Daily Forecast Values
159
  y_position -= 0.3 * inch
160
  c.drawString(1 * inch, y_position, "Daily Forecast Values (Next 30 Days):")
161
  y_position -= 0.3 * inch
 
167
  text_object.textLine(line)
168
  y_position -= 0.3 * inch
169
  c.drawText(text_object)
170
+ logger.info("Added daily forecast values")
171
 
172
+ # Add Threshold Alerts
173
  y_position -= 0.3 * inch
174
  c.drawString(1 * inch, y_position, "Threshold Alerts:")
175
  y_position -= 0.3 * inch
 
181
  alert_text = f"No alert for {period} forecast."
182
  c.drawString(1 * inch, y_position, alert_text)
183
  y_position -= 0.3 * inch
184
+ logger.info("Added threshold alerts")
185
 
186
+ # Add Daily Forecast Visualization Data
187
  y_position -= 0.3 * inch
188
  c.drawString(1 * inch, y_position, "Daily Forecast Visualization Data (Next 30 Days):")
189
  y_position -= 0.3 * inch
 
196
  c.showPage()
197
  c.setFont("Helvetica", 10)
198
  y_position = 10 * inch
199
+ logger.info("Added daily forecast visualization data")
200
 
201
  # Add Daily Forecast Visualization Image
202
  y_position -= 0.3 * inch
203
+ if y_position < 4 * inch:
204
  c.showPage()
205
  y_position = 10 * inch
206
  c.drawString(1 * inch, y_position, "Daily Forecast Visualization (Next 30 Days):")
207
  y_position -= 0.3 * inch
208
  daily_chart_img = BytesIO()
209
+ try:
210
+ pio.write_image(fig_daily, daily_chart_img, format='png', width=600, height=400)
211
+ daily_chart_img.seek(0)
212
+ img = Image(daily_chart_img, width=6 * inch, height=4 * inch)
213
+ img.drawOn(c, 1 * inch, y_position - 4 * inch)
214
+ logger.info("Added daily forecast visualization image")
215
+ except Exception as e:
216
+ logger.error(f"Failed to export daily forecast image: {str(e)}")
217
+ c.drawString(1 * inch, y_position - 0.3 * inch, "Error: Could not include daily forecast visualization.")
218
  y_position -= 4.5 * inch
219
 
220
  # Add Threshold Alerts Visualization Data
 
237
  c.showPage()
238
  c.setFont("Helvetica", 10)
239
  y_position = 10 * inch
240
+ logger.info("Added threshold alerts visualization data")
241
 
242
  # Add Threshold Alerts Visualization Image
243
  y_position -= 0.3 * inch
 
247
  c.drawString(1 * inch, y_position, "Threshold Alerts Visualization:")
248
  y_position -= 0.3 * inch
249
  alerts_chart_img = BytesIO()
250
+ try:
251
+ pio.write_image(fig_alerts, alerts_chart_img, format='png', width=600, height=400)
252
+ alerts_chart_img.seek(0)
253
+ img = Image(alerts_chart_img, width=6 * inch, height=4 * inch)
254
+ img.drawOn(c, 1 * inch, y_position - 4 * inch)
255
+ logger.info("Added threshold alerts visualization image")
256
+ except Exception as e:
257
+ logger.error(f"Failed to export alerts visualization image: {str(e)}")
258
+ c.drawString(1 * inch, y_position - 0.3 * inch, "Error: Could not include threshold alerts visualization.")
259
 
260
  c.showPage()
261
  c.save()
262
  pdf_file.seek(0)
263
+ logger.info("PDF generation completed successfully")
264
  return pdf_file
265
  except Exception as e:
266
  logger.error(f"Error generating PDF: {str(e)}")
 
439
  {"Pdf_report__c": pdf_url}
440
  )
441
  logger.info(f"PDF uploaded to Salesforce: {pdf_url}")
442
+ logger.info(f"PDF Report generated and uploaded to Salesforce: {pdf_url}")
443
  else:
444
  logger.error("Failed to upload PDF to Salesforce")
445
  st.error("Failed to upload PDF to Salesforce")