gopichandra commited on
Commit
537155f
Β·
verified Β·
1 Parent(s): 7b8704f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -143
app.py CHANGED
@@ -78,7 +78,7 @@ ATTRIBUTE_MAPPING = {
78
 
79
  # List of product names to match
80
  PRODUCT_NAMES = [
81
- "Fusion", "Agroking", "openwell", "CG commercial motors", "Jaguar", "Submersible pumps", "Gaurav"
82
  ]
83
 
84
  # Salesforce credentials
@@ -98,7 +98,7 @@ def extract_text(image):
98
  return "\n".join(extracted_text)
99
 
100
  # Function to match product name using fuzzy matching
101
- def match_product_name(extracted_text, threshold=70):
102
  best_match = None
103
  best_score = 0
104
 
@@ -108,7 +108,7 @@ def match_product_name(extracted_text, threshold=70):
108
  best_match = match
109
  best_score = score
110
 
111
- return best_match if best_score >= threshold else None # Adjustable threshold for a match
112
 
113
  # Function to extract attributes and their values
114
  def extract_attributes(extracted_text):
@@ -167,25 +167,19 @@ def interact_with_salesforce(mode, entry_type, quantity, attributes):
167
  schema = sf_object.describe()
168
  valid_fields = {field["name"] for field in schema["fields"]}
169
 
170
- # Extract product name and attributes
171
- product_name = attributes.get("Product name", "").strip()
172
- model_name = attributes.get("Model Name", "").strip()
173
- stage = attributes.get("Stage", "").strip()
174
- hp = attributes.get("H.P.", "").strip()
175
-
176
- if not product_name:
177
- return "Product name could not be matched from the extracted text."
178
 
179
  # Handling "Exit" Mode (Updating Records)
180
  if mode == "Exit":
181
  # Query should match exact product name, model name, stage, and hp if available
182
- query_conditions = [f"{product_field_name} = '{product_name}'"]
183
- if model_name:
184
- query_conditions.append(f"{model_field_name} = '{model_name}'")
185
- if stage:
186
- query_conditions.append(f"{stage_field_name} = '{stage}'")
187
- if hp:
188
- query_conditions.append(f"{hp_field_name} = '{hp}'")
189
 
190
  query = f"SELECT Id, {', '.join(field_names)} FROM {object_name} WHERE {' AND '.join(query_conditions)} LIMIT 1"
191
  response = sf.query(query)
@@ -194,23 +188,12 @@ def interact_with_salesforce(mode, entry_type, quantity, attributes):
194
  record_id = response["records"][0]["Id"]
195
  updated_fields = {field: quantity for field in field_names}
196
  sf_object.update(record_id, updated_fields)
197
- return f"βœ… Updated record for product '{product_name}' ({model_name}) in {object_name}. Updated fields: {updated_fields}."
198
  else:
199
- # If no matching record found with all conditions, try with only product name
200
- query_conditions = [f"{product_field_name} = '{product_name}'"]
201
- query = f"SELECT Id, {', '.join(field_names)} FROM {object_name} WHERE {' AND '.join(query_conditions)} LIMIT 1"
202
- response = sf.query(query)
203
- if response["records"]:
204
- record_id = response["records"][0]["Id"]
205
- updated_fields = {field: quantity for field in field_names}
206
- sf_object.update(record_id, updated_fields)
207
- return f"βœ… Updated record for product '{product_name}' in {object_name}. Updated fields: {updated_fields}."
208
- else:
209
- return f"❌ No matching record found for product '{product_name}' in {object_name}."
210
 
211
  # Handling "Entry" Mode (Creating Records)
212
  else:
213
- filtered_attributes = filter_valid_attributes(attributes, valid_fields)
214
  filtered_attributes[field_name] = quantity
215
  sf_object.create(filtered_attributes)
216
  return f"βœ… Data successfully exported to Salesforce object {object_name}."
@@ -218,129 +201,67 @@ def interact_with_salesforce(mode, entry_type, quantity, attributes):
218
  except Exception as e:
219
  return f"❌ Error interacting with Salesforce: {str(e)}"
220
 
221
- # Function to pull structured data from Salesforce and display as a table
222
- def pull_data_from_salesforce(selected_object):
223
- try:
224
- sf = Salesforce(
225
- username=SALESFORCE_USERNAME,
226
- password=SALESFORCE_PASSWORD,
227
- security_token=SALESFORCE_SECURITY_TOKEN
228
- )
229
-
230
- if selected_object == "Inventory_Management__c":
231
- query = "SELECT Productname__c, Current_Stocks__c, soldstock__c FROM Inventory_Management__c LIMIT 100"
232
- elif selected_object == "Un_Billable__c":
233
- query = "SELECT Productname__c, Current_Stock__c, soldstock__c FROM Un_Billable__c LIMIT 100"
234
- else:
235
- return "Invalid object selected.", None, None, None
236
-
237
- response = sf.query_all(query)
238
- records = response.get("records", [])
239
-
240
- if not records:
241
- return "No data found in Salesforce.", None, None, None
242
-
243
- df = pd.DataFrame(records)
244
- df = df.drop(columns=['attributes'], errors='ignore')
245
-
246
- # Rename columns for better readability
247
- df.rename(columns={
248
- "Productname__c": "Product Name",
249
- "Current_Stocks__c": "Current Stocks",
250
- "Current_Stock__c": "Current Stocks",
251
- "soldstock__c": "Sold Stock"
252
- }, inplace=True)
253
-
254
- excel_path = "salesforce_data.xlsx"
255
- df.to_excel(excel_path, index=False)
256
-
257
- # Generate interactive vertical bar graph using Matplotlib
258
- fig, ax = plt.subplots(figsize=(12, 8))
259
- df.plot(kind='bar', x="Product Name", y="Current Stocks", ax=ax, legend=False)
260
- ax.set_title("Stock Distribution by Product Name")
261
- ax.set_xlabel("Product Name")
262
- ax.set_ylabel("Current Stocks")
263
- plt.xticks(rotation=45, ha="right", fontsize=10)
264
- plt.tight_layout()
265
- buffer = BytesIO()
266
- plt.savefig(buffer, format="png")
267
- buffer.seek(0)
268
- img = Image.open(buffer)
269
-
270
- return "Data successfully retrieved.", df, excel_path, img
271
- except Exception as e:
272
- return f"Error fetching data: {str(e)}", None, None, None
273
-
274
- # Unified function to handle image processing and Salesforce interaction
275
- def process_image(image, mode, entry_type, quantity, threshold=70):
276
  extracted_text = extract_text(image)
277
  if not extracted_text:
278
  return "No text detected in the image.", None, None
279
 
280
- product_name = match_product_name(extracted_text, threshold)
281
  attributes = extract_attributes(extracted_text)
282
  if product_name:
283
  attributes["Product name"] = product_name
284
- else:
285
- attributes["Product name"] = "Unknown"
286
 
287
- # Combine extracted text and attributes for display
288
- combined_text = extracted_text + "\n\nExtracted Attributes:\n"
289
- for key, value in attributes.items():
290
- combined_text += f"{key}: {value}\n"
291
 
292
- return combined_text, attributes
293
-
294
- # Function to export edited attributes to Salesforce
295
- def export_to_salesforce(mode, entry_type, quantity, attributes):
296
- message = interact_with_salesforce(mode, entry_type, quantity, attributes)
297
- return message
 
 
 
 
 
298
 
299
  # Gradio Interface
300
  def app():
301
- with gr.Blocks() as demo:
302
- with gr.Tab("πŸ“₯ OCR Processing"):
303
- image_input = gr.Image(type="numpy", label="πŸ“„ Upload Image")
304
- mode_input = gr.Dropdown(label="πŸ“Œ Mode", choices=["Entry", "Exit"], value="Entry")
305
- entry_type_input = gr.Radio(label="πŸ“¦ Entry Type", choices=["Sales", "Non-Sales"], value="Sales")
306
- quantity_input = gr.Number(label="πŸ”’ Quantity", value=1, interactive=True)
307
- threshold_input = gr.Slider(label="πŸ” Matching Threshold", minimum=0, maximum=100, value=70, step=1)
308
- extracted_text_output = gr.Text(label="πŸ“ Extracted Image Data")
309
- attributes_output = gr.Dataframe(label="✏️ Edit Attributes", headers=["Attribute", "Value"], interactive=True)
310
- process_button = gr.Button("Process Image")
311
-
312
- def process_image_and_display(image, mode, entry_type, quantity, threshold):
313
- combined_text, attributes = process_image(image, mode, entry_type, quantity, threshold)
314
- attributes_list = [[key, value] for key, value in attributes.items()]
315
- return combined_text, attributes_list
316
-
317
- process_button.click(process_image_and_display, inputs=[image_input, mode_input, entry_type_input, quantity_input, threshold_input], outputs=[extracted_text_output, attributes_output])
318
-
319
- export_button = gr.Button("OK")
320
- result_output = gr.Text(label="πŸš€ Result")
321
-
322
- def export_attributes(mode, entry_type, quantity, attributes_list):
323
- attributes = {item[0]: item[1] for item in attributes_list}
324
- message = export_to_salesforce(mode, entry_type, quantity, attributes)
325
- return message
326
-
327
- export_button.click(export_attributes, inputs=[mode_input, entry_type_input, quantity_input, attributes_output], outputs=[result_output])
328
-
329
- with gr.Tab("πŸ“Š Salesforce Data Export"):
330
- selected_object_input = gr.Dropdown(label="Select Salesforce Object", choices=["Inventory_Management__c", "Un_Billable__c"], value="Inventory_Management__c")
331
- status_output = gr.Text(label="Status")
332
- data_table_output = gr.Dataframe(label="πŸ“¦ Salesforce Data Table")
333
- download_link_output = gr.File(label="Download Salesforce Data")
334
- bar_graph_output = gr.Image(label="πŸ“‰ Stock Distribution Bar Graph")
335
- pull_data_button = gr.Button("Pull Data")
336
-
337
- def pull_data(selected_object):
338
- status, df, excel_path, img = pull_data_from_salesforce(selected_object)
339
- return status, df, excel_path, img
340
-
341
- pull_data_button.click(pull_data, inputs=[selected_object_input], outputs=[status_output, data_table_output, download_link_output, bar_graph_output])
342
-
343
- demo.launch(share=True)
344
 
345
  if __name__ == "__main__":
346
- app()
 
78
 
79
  # List of product names to match
80
  PRODUCT_NAMES = [
81
+ "Fusion", "Agroking", "openwell", "CG commercial motors", "Jaguar", "Submersible pumps", "Gaurav"
82
  ]
83
 
84
  # Salesforce credentials
 
98
  return "\n".join(extracted_text)
99
 
100
  # Function to match product name using fuzzy matching
101
+ def match_product_name(extracted_text):
102
  best_match = None
103
  best_score = 0
104
 
 
108
  best_match = match
109
  best_score = score
110
 
111
+ return best_match if best_score >= 70 else None # Threshold of 70 for a match
112
 
113
  # Function to extract attributes and their values
114
  def extract_attributes(extracted_text):
 
167
  schema = sf_object.describe()
168
  valid_fields = {field["name"] for field in schema["fields"]}
169
 
170
+ # Filter attributes for valid Salesforce fields
171
+ filtered_attributes = filter_valid_attributes(attributes, valid_fields)
 
 
 
 
 
 
172
 
173
  # Handling "Exit" Mode (Updating Records)
174
  if mode == "Exit":
175
  # Query should match exact product name, model name, stage, and hp if available
176
+ query_conditions = [f"{product_field_name} = '{attributes['Product name']}'"]
177
+ if "Model Name" in attributes:
178
+ query_conditions.append(f"{model_field_name} = '{attributes['Model Name']}'")
179
+ if "Stage" in attributes:
180
+ query_conditions.append(f"{stage_field_name} = '{attributes['Stage']}'")
181
+ if "H.P." in attributes:
182
+ query_conditions.append(f"{hp_field_name} = '{attributes['H.P.']}'")
183
 
184
  query = f"SELECT Id, {', '.join(field_names)} FROM {object_name} WHERE {' AND '.join(query_conditions)} LIMIT 1"
185
  response = sf.query(query)
 
188
  record_id = response["records"][0]["Id"]
189
  updated_fields = {field: quantity for field in field_names}
190
  sf_object.update(record_id, updated_fields)
191
+ return f"βœ… Updated record for product '{attributes['Product name']}' in {object_name}. Updated fields: {updated_fields}."
192
  else:
193
+ return f"❌ No matching record found for product '{attributes['Product name']}' in {object_name}."
 
 
 
 
 
 
 
 
 
 
194
 
195
  # Handling "Entry" Mode (Creating Records)
196
  else:
 
197
  filtered_attributes[field_name] = quantity
198
  sf_object.create(filtered_attributes)
199
  return f"βœ… Data successfully exported to Salesforce object {object_name}."
 
201
  except Exception as e:
202
  return f"❌ Error interacting with Salesforce: {str(e)}"
203
 
204
+ # Function to process image, extract attributes, and allow editing
205
+ def process_image(image, mode, entry_type, quantity):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  extracted_text = extract_text(image)
207
  if not extracted_text:
208
  return "No text detected in the image.", None, None
209
 
210
+ product_name = match_product_name(extracted_text)
211
  attributes = extract_attributes(extracted_text)
212
  if product_name:
213
  attributes["Product name"] = product_name
 
 
214
 
215
+ # Convert attributes to DataFrame for editing
216
+ df = pd.DataFrame(list(attributes.items()), columns=["Attribute", "Value"])
217
+ return f"Extracted Text:\n{extracted_text}", df, None
 
218
 
219
+ # Function to handle edited attributes and export to Salesforce
220
+ def export_to_salesforce(mode, entry_type, quantity, edited_df):
221
+ try:
222
+ # Convert edited DataFrame back to dictionary
223
+ edited_attributes = dict(zip(edited_df["Attribute"], edited_df["Value"]))
224
+
225
+ # Export to Salesforce
226
+ message = interact_with_salesforce(mode, entry_type, quantity, edited_attributes)
227
+ return message
228
+ except Exception as e:
229
+ return f"❌ Error exporting to Salesforce: {str(e)}"
230
 
231
  # Gradio Interface
232
  def app():
233
+ return gr.TabbedInterface([
234
+ gr.Interface(
235
+ fn=process_image,
236
+ inputs=[
237
+ gr.Image(type="numpy", label="πŸ“„ Upload Image"),
238
+ gr.Dropdown(label="πŸ“Œ Mode", choices=["Entry", "Exit"], value="Entry"),
239
+ gr.Radio(label="πŸ“¦ Entry Type", choices=["Sales", "Non-Sales"], value="Sales"),
240
+ gr.Number(label="πŸ”’ Quantity", value=1, interactive=True),
241
+ ],
242
+ outputs=[
243
+ gr.Text(label="πŸ“ Extracted Image Data"),
244
+ gr.Dataframe(label="✏️ Edit Attributes (Key-Value Pairs)"),
245
+ gr.Text(label="πŸš€ Result")
246
+ ],
247
+ title="🏒 𝑽𝑬𝑡𝑲𝑨𝑻𝑨𝑹𝑨𝑴𝑨𝑡𝑨 𝑴𝑢𝑻𝑢𝑹𝑺",
248
+ description="πŸ“¦ πˆππ•π„ππ“πŽπ‘π˜ πŒπ€ππ€π†π„πŒπ„ππ“"
249
+ ),
250
+ gr.Interface(
251
+ fn=export_to_salesforce,
252
+ inputs=[
253
+ gr.Dropdown(label="πŸ“Œ Mode", choices=["Entry", "Exit"], value="Entry"),
254
+ gr.Radio(label="πŸ“¦ Entry Type", choices=["Sales", "Non-Sales"], value="Sales"),
255
+ gr.Number(label="πŸ”’ Quantity", value=1, interactive=True),
256
+ gr.Dataframe(label="✏️ Edited Attributes (Key-Value Pairs)")
257
+ ],
258
+ outputs=[
259
+ gr.Text(label="πŸš€ Result")
260
+ ],
261
+ title="πŸ“€ Export to Salesforce",
262
+ description="Edit attributes and export to Salesforce."
263
+ )
264
+ ], ["πŸ“₯ OCR Processing", "πŸ“€ Export to Salesforce"])
 
 
 
 
 
 
 
 
 
 
 
265
 
266
  if __name__ == "__main__":
267
+ app().launch(share=True)