varshakolanu commited on
Commit
f673d62
·
verified ·
1 Parent(s): f541eee

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -31
app.py CHANGED
@@ -18,27 +18,40 @@ if not API_KEY:
18
  logger.error("HUGGINGFACE_API_KEY environment variable not set")
19
  raise ValueError("HUGGINGFACE_API_KEY environment variable not set")
20
 
 
21
  class VendorLog(BaseModel):
22
  vendorLogId: str
23
  vendorId: str
24
- workCompletionPercentage: float
25
- qualityPercentage: float
26
- incidentSeverity: str
27
- workCompletionDate: str
28
- actualCompletionDate: str
29
- vendorLogName: str
30
- delayDays: int
 
 
 
31
 
32
  def calculate_scores(log: VendorLog):
33
- quality_score = log.qualityPercentage
 
 
 
 
 
34
 
 
35
  timeliness_score = 100.0 if log.delayDays <= 0 else 80.0 if log.delayDays <= 3 else 60.0 if log.delayDays <= 7 else 40.0
36
 
37
- severity_map = {'None': 100.0, 'Low': 80.0, 'Medium': 50.0, 'High': 20.0}
38
- safety_score = severity_map.get(log.incidentSeverity, 100.0)
 
39
 
 
40
  communication_score = (quality_score * 0.33 + timeliness_score * 0.33 + safety_score * 0.33)
41
 
 
42
  final_score = (quality_score + timeliness_score + safety_score + communication_score) / 4
43
 
44
  return {
@@ -79,11 +92,12 @@ def generate_pdf(vendor_id: str, vendor_log_name: str, scores: dict):
79
  c.setFont('Helvetica', 12)
80
  c.drawString(100, 750, 'Subcontractor Performance Report')
81
  c.drawString(100, 730, f'Vendor ID: {vendor_id}')
82
- c.drawString(100, 710, f'Quality Score: {scores["qualityScore"]}% ({get_feedback(scores["qualityScore"], "Quality")})')
83
- c.drawString(100, 690, f'Timeliness Score: {scores["timelinessScore"]}% ({get_feedback(scores["timelinessScore"], "Timeliness")})')
84
- c.drawString(100, 670, f'Safety Score: {scores["safetyScore"]}% ({get_feedback(scores["safetyScore"], "Safety")})')
85
- c.drawString(100, 650, f'Communication Score: {scores["communicationScore"]}% ({get_feedback(scores["communicationScore"], "Communication")})')
86
- c.drawString(100, 630, f'Final Score: {scores["finalScore"]}%')
 
87
  c.save()
88
 
89
  with open(filename, 'rb') as f:
@@ -91,27 +105,32 @@ def generate_pdf(vendor_id: str, vendor_log_name: str, scores: dict):
91
  os.remove(filename)
92
  return pdf_content
93
 
94
- def determine_alert_flag(final_score: float, all_scores: list):
 
 
 
95
  if final_score < 50:
96
  return True
97
- above_50 = any(score['scores']['finalScore'] >= 50 for score in all_scores)
98
- if not above_50:
99
- lowest_score = min([score['scores']['finalScore'] for score in all_scores])
100
- return final_score == lowest_score
101
- return False
102
-
103
- vendor_logs = []
104
 
105
  @app.post('/score')
106
  async def score_vendor(log: VendorLog, authorization: str = Header(...)):
107
  if authorization != f'Bearer {API_KEY}':
108
  raise HTTPException(status_code=401, detail='Invalid API key')
109
 
 
110
  scores = calculate_scores(log)
 
 
111
  pdf_content = generate_pdf(log.vendorId, log.vendorLogName, scores)
112
  pdf_base64 = base64.b64encode(pdf_content).decode('utf-8')
 
 
113
  alert_flag = determine_alert_flag(scores['finalScore'], vendor_logs)
114
 
 
115
  vendor_logs.append({
116
  'vendorLogId': log.vendorLogId,
117
  'vendorId': log.vendorId,
@@ -120,6 +139,7 @@ async def score_vendor(log: VendorLog, authorization: str = Header(...)):
120
  'extracted': True
121
  })
122
 
 
123
  return {
124
  'vendorLogId': log.vendorLogId,
125
  'vendorId': log.vendorId,
@@ -130,8 +150,7 @@ async def score_vendor(log: VendorLog, authorization: str = Header(...)):
130
  'communicationScore': scores['communicationScore'],
131
  'finalScore': scores['finalScore'],
132
  'pdfContent': pdf_base64,
133
- 'pdfUrl': f'/files/report_{log.vendorId}.pdf',
134
- 'alertFlag': alert_flag
135
  }
136
 
137
  @app.get('/', response_class=HTMLResponse)
@@ -149,15 +168,16 @@ async def get_dashboard():
149
  </style>
150
  </head>
151
  <body>
152
- <h1>Subcontractor Performance Score App Generator</h1>
153
- <h2>Vendor Logs</h2>
154
  <table>
155
  <tr>
156
- <th>Vendor ID</th>
157
- <th>Details Extracted</th>
158
- <th>Final Score</th>
159
  </tr>
160
  """
 
161
  for log in vendor_logs:
162
  html_content += f"""
163
  <tr>
@@ -166,9 +186,10 @@ async def get_dashboard():
166
  <td>{log['scores']['finalScore'] if log['extracted'] else 'NOT CALCULATED'}</td>
167
  </tr>
168
  """
 
169
  html_content += """
170
  </table>
171
- <h2>Subcontractor Performance Scores</h2>
172
  <table>
173
  <tr>
174
  <th>Vendor ID</th>
@@ -181,6 +202,7 @@ async def get_dashboard():
181
  <th>Alert Flag</th>
182
  </tr>
183
  """
 
184
  for log in vendor_logs:
185
  scores = log['scores']
186
  alert_flag = determine_alert_flag(scores['finalScore'], vendor_logs)
@@ -196,6 +218,7 @@ async def get_dashboard():
196
  <td>{'Checked' if alert_flag else 'Unchecked'}</td>
197
  </tr>
198
  """
 
199
  html_content += """
200
  </table>
201
  </body>
 
18
  logger.error("HUGGINGFACE_API_KEY environment variable not set")
19
  raise ValueError("HUGGINGFACE_API_KEY environment variable not set")
20
 
21
+ # Model to match the incoming Vendor Log data from Salesforce
22
  class VendorLog(BaseModel):
23
  vendorLogId: str
24
  vendorId: str
25
+ workDetails: str # e.g., "90% completed"
26
+ qualityReport: str # e.g., "60% quality"
27
+ incidentLog: str # e.g., "Minor"
28
+ workCompletionDate: str # e.g., "2025-05-12"
29
+ actualCompletionDate: str # e.g., "2025-05-10"
30
+ vendorLogName: str # e.g., "abhi"
31
+ delayDays: int # e.g., 2
32
+
33
+ # Store vendor logs for display in the dashboard
34
+ vendor_logs = []
35
 
36
  def calculate_scores(log: VendorLog):
37
+ # Extract percentages from the string fields
38
+ work_completion_percentage = float(log.workDetails.replace('% completed', ''))
39
+ quality_percentage = float(log.qualityReport.replace('% quality', ''))
40
+
41
+ # Quality Score: Directly use the quality percentage
42
+ quality_score = quality_percentage
43
 
44
+ # Timeliness Score: Based on delay days
45
  timeliness_score = 100.0 if log.delayDays <= 0 else 80.0 if log.delayDays <= 3 else 60.0 if log.delayDays <= 7 else 40.0
46
 
47
+ # Safety Score: Based on incident severity
48
+ severity_map = {'None': 100.0, 'Low': 80.0, 'Minor': 80.0, 'Medium': 50.0, 'High': 20.0}
49
+ safety_score = severity_map.get(log.incidentLog, 100.0)
50
 
51
+ # Communication Score: Weighted average of other scores
52
  communication_score = (quality_score * 0.33 + timeliness_score * 0.33 + safety_score * 0.33)
53
 
54
+ # Final Score: Average of all scores
55
  final_score = (quality_score + timeliness_score + safety_score + communication_score) / 4
56
 
57
  return {
 
92
  c.setFont('Helvetica', 12)
93
  c.drawString(100, 750, 'Subcontractor Performance Report')
94
  c.drawString(100, 730, f'Vendor ID: {vendor_id}')
95
+ c.drawString(100, 710, f'Vendor Log Name: {vendor_log_name}')
96
+ c.drawString(100, 690, f'Quality Score: {scores["qualityScore"]}% ({get_feedback(scores["qualityScore"], "Quality")})')
97
+ c.drawString(100, 670, f'Timeliness Score: {scores["timelinessScore"]}% ({get_feedback(scores["timelinessScore"], "Timeliness")})')
98
+ c.drawString(100, 650, f'Safety Score: {scores["safetyScore"]}% ({get_feedback(scores["safetyScore"], "Safety")})')
99
+ c.drawString(100, 630, f'Communication Score: {scores["communicationScore"]}% ({get_feedback(scores["communicationScore"], "Communication")})')
100
+ c.drawString(100, 610, f'Final Score: {scores["finalScore"]}%')
101
  c.save()
102
 
103
  with open(filename, 'rb') as f:
 
105
  os.remove(filename)
106
  return pdf_content
107
 
108
+ def determine_alert_flag(final_score: float, all_logs: list):
109
+ if not all_logs:
110
+ return False
111
+ # If final score is less than 50, flag an alert
112
  if final_score < 50:
113
  return True
114
+ # Otherwise, flag the vendor with the lowest final score
115
+ lowest_score = min([log['scores']['finalScore'] for log in all_logs])
116
+ return final_score == lowest_score
 
 
 
 
117
 
118
  @app.post('/score')
119
  async def score_vendor(log: VendorLog, authorization: str = Header(...)):
120
  if authorization != f'Bearer {API_KEY}':
121
  raise HTTPException(status_code=401, detail='Invalid API key')
122
 
123
+ # Calculate scores
124
  scores = calculate_scores(log)
125
+
126
+ # Generate PDF
127
  pdf_content = generate_pdf(log.vendorId, log.vendorLogName, scores)
128
  pdf_base64 = base64.b64encode(pdf_content).decode('utf-8')
129
+
130
+ # Determine alert flag
131
  alert_flag = determine_alert_flag(scores['finalScore'], vendor_logs)
132
 
133
+ # Store the log and scores
134
  vendor_logs.append({
135
  'vendorLogId': log.vendorLogId,
136
  'vendorId': log.vendorId,
 
139
  'extracted': True
140
  })
141
 
142
+ # Return the response to Salesforce
143
  return {
144
  'vendorLogId': log.vendorLogId,
145
  'vendorId': log.vendorId,
 
150
  'communicationScore': scores['communicationScore'],
151
  'finalScore': scores['finalScore'],
152
  'pdfContent': pdf_base64,
153
+ 'alert': alert_flag
 
154
  }
155
 
156
  @app.get('/', response_class=HTMLResponse)
 
168
  </style>
169
  </head>
170
  <body>
171
+ <h1>SUBCONTRACTOR PERFORMANCE SCORE APP GENERATOR</h1>
172
+ <h2>VENDOR LOGS</h2>
173
  <table>
174
  <tr>
175
+ <th>VENDOR ID</th>
176
+ <th>DETAILS EXTRACTED FROM SALESFORCE FROM VENDOR LOG OBJECT</th>
177
+ <th>FINAL SCORE CALCULATED BY APP</th>
178
  </tr>
179
  """
180
+
181
  for log in vendor_logs:
182
  html_content += f"""
183
  <tr>
 
186
  <td>{log['scores']['finalScore'] if log['extracted'] else 'NOT CALCULATED'}</td>
187
  </tr>
188
  """
189
+
190
  html_content += """
191
  </table>
192
+ <h2>SUBCONTRACTOR PERFORMANCE SCORES</h2>
193
  <table>
194
  <tr>
195
  <th>Vendor ID</th>
 
202
  <th>Alert Flag</th>
203
  </tr>
204
  """
205
+
206
  for log in vendor_logs:
207
  scores = log['scores']
208
  alert_flag = determine_alert_flag(scores['finalScore'], vendor_logs)
 
218
  <td>{'Checked' if alert_flag else 'Unchecked'}</td>
219
  </tr>
220
  """
221
+
222
  html_content += """
223
  </table>
224
  </body>