Dineshpopuri commited on
Commit
cd77c9b
·
verified ·
1 Parent(s): 31c5a4e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -83
app.py CHANGED
@@ -5,6 +5,10 @@ from reportlab.pdfgen import canvas
5
  import bleach
6
  from simple_salesforce import Salesforce, SalesforceError
7
  import os
 
 
 
 
8
 
9
  # Salesforce configuration (loaded from environment variables for security)
10
  SF_USERNAME = os.getenv("SF_USERNAME")
@@ -22,22 +26,23 @@ def init_salesforce():
22
  instance_url=SF_INSTANCE_URL
23
  )
24
  return sf, "Salesforce connected successfully"
25
- except SalesforceError as e:
 
26
  return None, f"Salesforce connection failed: {str(e)}"
27
 
28
  # Create Salesforce record using Case object
29
  def create_salesforce_record(score, checklist_summary, missing_summary, status):
30
- sf, connection_message = init_salesforce()
31
- if not sf:
32
- # Silently handle connection failure since UI feedback is removed
33
- return
 
34
 
35
- # Map app status to Salesforce Case.Status values
36
- sf_status = "New" # Default for Pending and Escalated
37
- if status == "Completed":
38
- sf_status = "Closed"
39
 
40
- try:
41
  # Create a Case record in Salesforce with required fields
42
  record = {
43
  "Subject": "Project Readiness Evaluation",
@@ -47,8 +52,8 @@ def create_salesforce_record(score, checklist_summary, missing_summary, status):
47
  "Priority": "Medium" # Required field in many Salesforce orgs
48
  }
49
  sf.Case.create(record)
50
- except SalesforceError:
51
- # Silently handle errors since UI feedback is removed
52
  pass
53
 
54
  # Clean input to prevent injection attacks
@@ -59,80 +64,88 @@ def sanitize_input(text):
59
 
60
  # Rule-based completeness engine to evaluate readiness and create Salesforce record
61
  def evaluate_readiness_and_save(logs, qa_report, punch_list_text):
62
- # Evaluate readiness
63
- score = 0 # Base score set to 0 for clearer range
64
- missing_items = []
65
- checklist_details = []
66
-
67
- # Sanitize inputs
68
- logs = sanitize_input(logs)
69
- qa_report = sanitize_input(qa_report)
70
- punch_list_text = sanitize_input(punch_list_text)
71
-
72
- # Process Project Logs
73
- log_keywords = r"complete|handover done|finished|closed|successful"
74
- if logs and re.search(log_keywords, logs.lower()):
75
- score += 30
76
- checklist_details.append("Logs: Completed")
77
- else:
78
- missing_items.append("Project Logs Incomplete")
79
- checklist_details.append("Logs: Pending")
80
-
81
- # Process QA Report
82
- qa_keywords = r"approved|passed|cleared"
83
- if qa_report and re.search(qa_keywords, qa_report.lower()):
84
- score += 40
85
- checklist_details.append("QA Report: Approved")
86
- else:
87
- missing_items.append("QA Approval Missing")
88
- checklist_details.append("QA Report: Pending")
89
-
90
- # Process Punch List
91
- punch_keywords = r"none|resolved|closed|no issues"
92
- if punch_list_text and re.search(punch_keywords, punch_list_text.lower()):
93
- score += 30
94
- checklist_details.append("Punch List: Resolved")
95
- else:
96
- missing_items.append("Open Punch Points Detected")
97
- checklist_details.append("Punch List: Pending")
98
-
99
- # Handle critical issues (escalation)
100
- escalated = any("incomplete" in item.lower() or "missing" in item.lower() for item in missing_items)
101
- status = "Escalated" if escalated else ("Completed" if not missing_items else "Pending")
102
-
103
- # Build summaries
104
- checklist_summary = "\n".join(checklist_details)
105
- missing_summary = "None" if not missing_items else ", ".join(missing_items)
106
-
107
- # Generate progress bar HTML (alert indicator)
108
- color = "red" if score < 70 else "yellow" if score < 90 else "green"
109
- progress_bar = f'<progress value="{score}" max="100" style="width:100%;height:20px;background-color:{color}">{score}%</progress>'
110
-
111
- # Automatically create Salesforce record
112
- create_salesforce_record(score, checklist_summary, missing_summary, status)
113
-
114
- return score, checklist_summary, missing_summary, status, progress_bar
 
 
 
 
115
 
116
  # Generate PDF report with signature slots
117
  def generate_pdf(score, checklist_summary, missing_summary, status):
118
- pdf_file = "readiness_report.pdf"
119
- c = canvas.Canvas(pdf_file, pagesize=letter)
120
- c.setFont("Helvetica-Bold", 16)
121
- c.drawString(50, 750, "Project Closure Readiness Report")
122
- c.setFont("Helvetica", 12)
123
- c.drawString(50, 720, f"Readiness Score: {score}%")
124
- c.drawString(50, 700, f"Status: {status}")
125
- c.drawString(50, 680, "Checklist Summary:")
126
- y = 660
127
- for line in checklist_summary.split("\n"):
128
- c.drawString(50, y, line)
129
- y -= 20
130
- c.drawString(50, y-20, "Missing Items:")
131
- c.drawString(50, y-40, missing_summary)
132
- c.drawString(50, y-80, "Stakeholder Signature: ____________________")
133
- c.drawString(50, y-100, "Date: ____________________")
134
- c.save()
135
- return pdf_file
 
 
 
 
136
 
137
  # Gradio interface with updated UI
138
  with gr.Blocks(css="""progress { background-color: #f0f0f0; } .red { background-color: red; }""") as demo:
 
5
  import bleach
6
  from simple_salesforce import Salesforce, SalesforceError
7
  import os
8
+ import logging
9
+
10
+ # Set up logging for debugging
11
+ logging.basicConfig(filename="app_errors.log", level=logging.ERROR, format="%(asctime)s - %(levelname)s - %(message)s")
12
 
13
  # Salesforce configuration (loaded from environment variables for security)
14
  SF_USERNAME = os.getenv("SF_USERNAME")
 
26
  instance_url=SF_INSTANCE_URL
27
  )
28
  return sf, "Salesforce connected successfully"
29
+ except Exception as e:
30
+ logging.error(f"Failed to initialize Salesforce connection: {str(e)}")
31
  return None, f"Salesforce connection failed: {str(e)}"
32
 
33
  # Create Salesforce record using Case object
34
  def create_salesforce_record(score, checklist_summary, missing_summary, status):
35
+ try:
36
+ sf, connection_message = init_salesforce()
37
+ if not sf:
38
+ logging.error(f"Skipping Salesforce record creation due to connection failure: {connection_message}")
39
+ return
40
 
41
+ # Map app status to Salesforce Case.Status values
42
+ sf_status = "New" # Default for Pending and Escalated
43
+ if status == "Completed":
44
+ sf_status = "Closed"
45
 
 
46
  # Create a Case record in Salesforce with required fields
47
  record = {
48
  "Subject": "Project Readiness Evaluation",
 
52
  "Priority": "Medium" # Required field in many Salesforce orgs
53
  }
54
  sf.Case.create(record)
55
+ except Exception as e:
56
+ logging.error(f"Failed to create Salesforce Case record: {str(e)}")
57
  pass
58
 
59
  # Clean input to prevent injection attacks
 
64
 
65
  # Rule-based completeness engine to evaluate readiness and create Salesforce record
66
  def evaluate_readiness_and_save(logs, qa_report, punch_list_text):
67
+ try:
68
+ # Evaluate readiness
69
+ score = 0 # Base score set to 0 for clearer range
70
+ missing_items = []
71
+ checklist_details = []
72
+
73
+ # Sanitize inputs
74
+ logs = sanitize_input(logs)
75
+ qa_report = sanitize_input(qa_report)
76
+ punch_list_text = sanitize_input(punch_list_text)
77
+
78
+ # Process Project Logs
79
+ log_keywords = r"complete|handover done|finished|closed|successful"
80
+ if logs and re.search(log_keywords, logs.lower()):
81
+ score += 30
82
+ checklist_details.append("Logs: Completed")
83
+ else:
84
+ missing_items.append("Project Logs Incomplete")
85
+ checklist_details.append("Logs: Pending")
86
+
87
+ # Process QA Report
88
+ qa_keywords = r"approved|passed|cleared"
89
+ if qa_report and re.search(qa_keywords, qa_report.lower()):
90
+ score += 40
91
+ checklist_details.append("QA Report: Approved")
92
+ else:
93
+ missing_items.append("QA Approval Missing")
94
+ checklist_details.append("QA Report: Pending")
95
+
96
+ # Process Punch List
97
+ punch_keywords = r"none|resolved|closed|no issues"
98
+ if punch_list_text and re.search(punch_keywords, punch_list_text.lower()):
99
+ score += 30
100
+ checklist_details.append("Punch List: Resolved")
101
+ else:
102
+ missing_items.append("Open Punch Points Detected")
103
+ checklist_details.append("Punch List: Pending")
104
+
105
+ # Handle critical issues (escalation)
106
+ escalated = any("incomplete" in item.lower() or "missing" in item.lower() for item in missing_items)
107
+ status = "Escalated" if escalated else ("Completed" if not missing_items else "Pending")
108
+
109
+ # Build summaries
110
+ checklist_summary = "\n".join(checklist_details)
111
+ missing_summary = "None" if not missing_items else ", ".join(missing_items)
112
+
113
+ # Generate progress bar HTML (alert indicator)
114
+ color = "red" if score < 70 else "yellow" if score < 90 else "green"
115
+ progress_bar = f'<progress value="{score}" max="100" style="width:100%;height:20px;background-color:{color}">{score}%</progress>'
116
+
117
+ # Automatically create Salesforce record
118
+ create_salesforce_record(score, checklist_summary, missing_summary, status)
119
+
120
+ return score, checklist_summary, missing_summary, status, progress_bar
121
+ except Exception as e:
122
+ logging.error(f"Error in evaluate_readiness_and_save: {str(e)}")
123
+ raise
124
 
125
  # Generate PDF report with signature slots
126
  def generate_pdf(score, checklist_summary, missing_summary, status):
127
+ try:
128
+ pdf_file = "readiness_report.pdf"
129
+ c = canvas.Canvas(pdf_file, pagesize=letter)
130
+ c.setFont("Helvetica-Bold", 16)
131
+ c.drawString(50, 750, "Project Closure Readiness Report")
132
+ c.setFont("Helvetica", 12)
133
+ c.drawString(50, 720, f"Readiness Score: {score}%")
134
+ c.drawString(50, 700, f"Status: {status}")
135
+ c.drawString(50, 680, "Checklist Summary:")
136
+ y = 660
137
+ for line in checklist_summary.split("\n"):
138
+ c.drawString(50, y, line)
139
+ y -= 20
140
+ c.drawString(50, y-20, "Missing Items:")
141
+ c.drawString(50, y-40, missing_summary)
142
+ c.drawString(50, y-80, "Stakeholder Signature: ____________________")
143
+ c.drawString(50, y-100, "Date: ____________________")
144
+ c.save()
145
+ return pdf_file
146
+ except Exception as e:
147
+ logging.error(f"Error in generate_pdf: {str(e)}")
148
+ raise
149
 
150
  # Gradio interface with updated UI
151
  with gr.Blocks(css="""progress { background-color: #f0f0f0; } .red { background-color: red; }""") as demo: