Dineshpopuri commited on
Commit
223543d
·
verified ·
1 Parent(s): 0ec919f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +164 -17
app.py CHANGED
@@ -1,5 +1,5 @@
1
  import gradio as gr
2
- from simple_salesforce import Salesforce
3
  from dotenv import load_dotenv
4
  import os
5
  import logging
@@ -8,14 +8,14 @@ import logging
8
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
9
  logger = logging.getLogger(__name__)
10
 
11
- # Load environment variables
12
  load_dotenv()
13
 
14
  # Salesforce credentials
15
  SF_USERNAME = os.getenv("SF_USERNAME")
16
  SF_PASSWORD = os.getenv("SF_PASSWORD")
17
  SF_SECURITY_TOKEN = os.getenv("SF_SECURITY_TOKEN")
18
- SF_INSTANCE_URL = os.getenv("SF_INSTANCE_URL", "https://login.salesforce.com")
19
 
20
  # Initialize Salesforce client
21
  sf = None
@@ -29,14 +29,71 @@ try:
29
  )
30
  logger.info("Successfully connected to Salesforce")
31
  else:
32
- logger.error("Salesforce credentials not found")
33
  except Exception as e:
34
  logger.error(f"Failed to connect to Salesforce: {str(e)}")
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  def create_salesforce_record(project_logs, qa_report, punch_list):
37
  """Create a new record in Salesforce."""
38
  if sf is None:
39
- return "Salesforce connection not established."
 
 
40
  try:
41
  data = {
42
  "Project_Logs__c": project_logs,
@@ -44,29 +101,119 @@ def create_salesforce_record(project_logs, qa_report, punch_list):
44
  "Punch_List__c": punch_list
45
  }
46
  result = sf.Project_Closure_Handover__c.create(data)
 
47
  return f"Successfully created record with ID: {result['id']}"
48
  except Exception as e:
 
49
  return f"Error creating record: {str(e)}"
50
 
51
- # Gradio interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  with gr.Blocks() as demo:
53
  gr.Markdown("# Project Closure Readiness Evaluator")
54
 
55
- # Input section
 
 
 
 
 
56
  gr.Markdown("## Enter Project Details")
57
- logs = gr.Textbox(label="Project Logs", placeholder="e.g., Project complete")
 
 
58
  qa_report = gr.Textbox(label="QA Report", placeholder="e.g., Approved")
59
- punch_list = gr.Textbox(label="Punch List", placeholder="e.g., None")
 
 
 
60
 
61
- # Create button
62
- create_button = gr.Button("Create Salesforce Record")
63
- create_output = gr.Textbox(label="Record Creation Status", interactive=False)
 
 
 
 
 
64
 
65
- # Bind create function
66
- create_button.click(
67
- create_salesforce_record,
68
- inputs=[logs, qa_report, punch_list],
69
- outputs=create_output
 
70
  )
71
 
72
  demo.launch()
 
1
  import gradio as gr
2
+ from simple_salesforce import Salesforce, SalesforceResourceNotFound
3
  from dotenv import load_dotenv
4
  import os
5
  import logging
 
8
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
9
  logger = logging.getLogger(__name__)
10
 
11
+ # Load environment variables from .env file (for local development)
12
  load_dotenv()
13
 
14
  # Salesforce credentials
15
  SF_USERNAME = os.getenv("SF_USERNAME")
16
  SF_PASSWORD = os.getenv("SF_PASSWORD")
17
  SF_SECURITY_TOKEN = os.getenv("SF_SECURITY_TOKEN")
18
+ SF_INSTANCE_URL = os.getenv("SF_INSTANCE_URL", "https://login.salesforce.com") # Default to production
19
 
20
  # Initialize Salesforce client
21
  sf = None
 
29
  )
30
  logger.info("Successfully connected to Salesforce")
31
  else:
32
+ logger.error("Salesforce credentials not found in environment variables")
33
  except Exception as e:
34
  logger.error(f"Failed to connect to Salesforce: {str(e)}")
35
 
36
+ def verify_salesforce_object():
37
+ """Verify if Project_Closure_Handover__c exists and contains data."""
38
+ if sf is None:
39
+ logger.error("Salesforce client not initialized")
40
+ return "Salesforce connection not established. Check credentials in Hugging Face Secrets or .env file."
41
+
42
+ try:
43
+ # Check if the object exists
44
+ sf.Project_Closure_Handover__c.describe()
45
+ logger.info("Object Project_Closure_Handover__c exists")
46
+
47
+ # Check if the object has data
48
+ query = "SELECT Id FROM Project_Closure_Handover__c LIMIT 1"
49
+ result = sf.query(query)
50
+ has_data = result["totalSize"] > 0
51
+ data_status = "contains data" if has_data else "is empty"
52
+ logger.info(f"Object Project_Closure_Handover__c {data_status}")
53
+
54
+ return f"Object Project_Closure_Handover__c exists and {data_status}."
55
+ except SalesforceResourceNotFound:
56
+ logger.error("Object Project_Closure_Handover__c does not exist")
57
+ return "Object Project_Closure_Handover__c does not exist in Salesforce."
58
+ except Exception as e:
59
+ logger.error(f"Error verifying object: {str(e)}")
60
+ return f"Error verifying object: {str(e)}"
61
+
62
+ def fetch_salesforce_data(project_id):
63
+ """Fetch project data from Salesforce using the project ID."""
64
+ if not project_id:
65
+ return "Project ID is required for Salesforce data retrieval.", None, None, None, None
66
+
67
+ if sf is None:
68
+ logger.error("Salesforce client not initialized")
69
+ return "Salesforce connection not established. Check credentials in Hugging Face Secrets or .env file.", None, None, None, None
70
+
71
+ try:
72
+ # Query the Project_Closure_Handover__c object
73
+ query = f"SELECT Project_Logs__c, QA_Report__c, Punch_List__c FROM Project_Closure_Handover__c WHERE Id = '{project_id}'"
74
+ logger.info(f"Executing Salesforce query: {query}")
75
+ result = sf.query(query)
76
+
77
+ if result["totalSize"] > 0:
78
+ record = result["records"][0]
79
+ logs = record.get("Project_Logs__c", "") or "" # Fixed field name from Project_ID__c to Project_Logs__c
80
+ qa_report = record.get("QA_Report__c", "") or ""
81
+ punch_list = record.get("Punch_List__c", "") or ""
82
+ logger.info(f"Fetched data for Project ID {project_id}: Logs={logs}, QA={qa_report}, Punch={punch_list}")
83
+ return None, logs, qa_report, punch_list, f"Raw Salesforce Data: Logs='{logs}', QA='{qa_report}', Punch='{punch_list}'"
84
+ else:
85
+ logger.warning(f"No record found for Project ID: {project_id}")
86
+ return "No record found for the provided Project ID.", None, None, None, None
87
+ except Exception as e:
88
+ logger.error(f"Error fetching Salesforce data: {str(e)}")
89
+ return f"Error fetching Salesforce data: {str(e)}", None, None, None, None
90
+
91
  def create_salesforce_record(project_logs, qa_report, punch_list):
92
  """Create a new record in Salesforce."""
93
  if sf is None:
94
+ logger.error("Salesforce client not initialized")
95
+ return "Salesforce connection not established. Check credentials in Hugging Face Secrets or .env file."
96
+
97
  try:
98
  data = {
99
  "Project_Logs__c": project_logs,
 
101
  "Punch_List__c": punch_list
102
  }
103
  result = sf.Project_Closure_Handover__c.create(data)
104
+ logger.info(f"Created record with ID: {result['id']}")
105
  return f"Successfully created record with ID: {result['id']}"
106
  except Exception as e:
107
+ logger.error(f"Error creating record: {str(e)}")
108
  return f"Error creating record: {str(e)}"
109
 
110
+ def evaluate_readiness(logs, qa_report, punch_list_text):
111
+ """Evaluate project closure readiness based on input data."""
112
+ score = 60 # Base score
113
+ missing_items = []
114
+
115
+ # Log input values for debugging
116
+ logger.info(f"Evaluating readiness: Logs='{logs}', QA='{qa_report}', Punch='{punch_list_text}'")
117
+
118
+ # Process Project Logs
119
+ if logs and ("complete" in logs.lower() or "handover done" in logs.lower()):
120
+ score += 10
121
+ logger.info("Project Logs valid: Added +10 to score")
122
+ else:
123
+ missing_items.append("Project Logs Incomplete (requires 'complete' or 'handover done')")
124
+ logger.warning("Project Logs invalid or empty")
125
+
126
+ # Process QA Report
127
+ if qa_report and qa_report.strip().lower() in ["approved", "passed"]:
128
+ score += 20
129
+ logger.info("QA Report valid: Added +20 to score")
130
+ else:
131
+ missing_items.append("QA Approval Missing (requires 'approved' or 'passed')")
132
+ logger.warning("QA Report invalid or empty")
133
+
134
+ # Process Punch List
135
+ if punch_list_text and ("none" in punch_list_text.lower() or "resolved" in punch_list_text.lower()):
136
+ score += 10
137
+ logger.info("Punch List valid: Added +10 to score")
138
+ else:
139
+ missing_items.append("Open Punch Points Detected (requires 'none' or 'resolved')")
140
+ logger.warning("Punch List invalid or empty")
141
+
142
+ # Build output summary
143
+ checklist_summary = "All checklist items reviewed." if not missing_items else "Pending: " + ", ".join(missing_items)
144
+ missing_summary = "None" if not missing_items else ", ".join(missing_items)
145
+
146
+ logger.info(f"Readiness evaluation completed. Score: {score}, Missing: {missing_summary}")
147
+ return score, checklist_summary, missing_summary
148
+
149
+ def combined_workflow(project_id, logs, qa_report, punch_list_text):
150
+ """Combine Salesforce data fetching, record creation, and readiness evaluation."""
151
+ error = None
152
+ raw_data = None
153
+ create_status = None
154
+
155
+ # Create record if inputs are provided
156
+ if logs and qa_report and punch_list_text:
157
+ create_status = create_salesforce_record(logs, qa_report, punch_list_text)
158
+ else:
159
+ create_status = "Record not created: All inputs (Project Logs, QA Report, Punch List) are required."
160
+ logger.warning(create_status)
161
+
162
+ # Fetch data if project_id is provided
163
+ if project_id:
164
+ logger.info(f"Fetching Salesforce data for Project ID: {project_id}")
165
+ error, sf_logs, sf_qa, sf_punch, raw_data = fetch_salesforce_data(project_id)
166
+ if error:
167
+ logger.warning(f"Salesforce fetch failed, using manual inputs: {error}")
168
+ else:
169
+ # Use Salesforce data if available, otherwise fall back to manual inputs
170
+ logs = sf_logs if sf_logs is not None else logs
171
+ qa_report = sf_qa if sf_qa is not None else qa_report
172
+ punch_list_text = sf_punch if sf_punch is not None else punch_list_text
173
+
174
+ if not (logs and qa_report and punch_list_text):
175
+ error_msg = "Please provide all inputs manually or a valid Salesforce Project ID."
176
+ logger.error(error_msg)
177
+ return error_msg if not error else f"{error} {error_msg}", None, None, None, raw_data, create_status
178
+
179
+ score, checklist_summary, missing_summary = evaluate_readiness(logs, qa_report, punch_list_text)
180
+ return error, score, checklist_summary, missing_summary, raw_data, create_status
181
+
182
+ # Gradio interface setup
183
  with gr.Blocks() as demo:
184
  gr.Markdown("# Project Closure Readiness Evaluator")
185
 
186
+ # Object verification section
187
+ gr.Markdown("## Verify Salesforce Object")
188
+ verify_button = gr.Button("Check Project_Closure_Handover__c")
189
+ verify_output = gr.Textbox(label="Object Status", interactive=False)
190
+
191
+ # Data input section
192
  gr.Markdown("## Enter Project Details")
193
+ gr.Markdown("Enter a Salesforce Project ID to fetch data or provide inputs manually. Inputs will be used to create a new Salesforce record.")
194
+ project_id = gr.Textbox(label="Salesforce Project ID (Optional)", placeholder="e.g., a0Axxxxxxxxxxxx")
195
+ logs = gr.Textbox(label="Project Logs", placeholder="e.g., Project complete, handover done")
196
  qa_report = gr.Textbox(label="QA Report", placeholder="e.g., Approved")
197
+ punch_list = gr.Textbox(label="Punch List (Plain Text)", placeholder="e.g., None or Resolved")
198
+
199
+ # Submit button
200
+ submit_button = gr.Button("Evaluate Readiness and Create Record")
201
 
202
+ # Output section
203
+ gr.Markdown("## Results")
204
+ error_output = gr.Textbox(label="Error (if any)", interactive=False)
205
+ score_output = gr.Number(label="Readiness Score (%)", interactive=False)
206
+ checklist_output = gr.Textbox(label="Checklist Summary", interactive=False)
207
+ missing_output = gr.Textbox(label="Missing Items", interactive=False)
208
+ raw_data_output = gr.Textbox(label="Raw Salesforce Data (if fetched)", interactive=False)
209
+ create_status_output = gr.Textbox(label="Record Creation Status", interactive=False)
210
 
211
+ # Event handlers
212
+ verify_button.click(verify_salesforce_object, outputs=verify_output)
213
+ submit_button.click(
214
+ combined_workflow,
215
+ inputs=[project_id, logs, qa_report, punch_list],
216
+ outputs=[error_output, score_output, checklist_output, missing_output, raw_data_output, create_status_output]
217
  )
218
 
219
  demo.launch()