gopichandra commited on
Commit
b0dc34b
Β·
verified Β·
1 Parent(s): 78c5c14

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -70
app.py CHANGED
@@ -9,7 +9,6 @@ import pandas as pd
9
  import matplotlib.pyplot as plt
10
  from io import BytesIO
11
  from fuzzywuzzy import process
12
- import plotly.graph_objects as go
13
  import kaleido # Ensure kaleido is imported
14
 
15
  # Attribute mappings: readable names to Salesforce API names
@@ -82,7 +81,7 @@ PRODUCT_NAMES = [
82
  "Openwell Submersible Pumpset", "Electric Motor", "Self Priming Pump",
83
  "Control panel for single phase submersible pumps", "MOTOR", "Submersible pump set",
84
  "Fusion submersible pump set", "DCT", "Shock proof water proof", "CG COMMERCIAL MOTORS", "Fusion",
85
- "control panel for single phase submersible pumps",
86
  "single phase digital starter dry run and timer panel", "5HP AV1 XL Kirloskar Pump",
87
  "Phase stainless steel submersible pump", "Submersible pump", "WB15X",
88
  "Vtype self priming pump", "SP SHINE DISC", "havells submersible pump",
@@ -150,7 +149,7 @@ def extract_attributes(extracted_text):
150
  def filter_valid_attributes(attributes, valid_fields):
151
  return {ATTRIBUTE_MAPPING[key]: value for key, value in attributes.items() if ATTRIBUTE_MAPPING[key] in valid_fields}
152
 
153
- # Function to interact with Salesforce based on mode and type
154
  def interact_with_salesforce(mode, entry_type, quantity, extracted_text):
155
  try:
156
  sf = Salesforce(
@@ -159,11 +158,11 @@ def interact_with_salesforce(mode, entry_type, quantity, extracted_text):
159
  security_token=SALESFORCE_SECURITY_TOKEN
160
  )
161
 
162
- # Mapping mode and entry_type to Salesforce object and field
163
  object_name = None
 
 
164
  field_name = None
165
- product_field_name = "Product_Name__c" # Correct field for product name in the object
166
- model_field_name = "Modal_Name__c" # Correct field for model name in the object
167
 
168
  if mode == "Entry":
169
  if entry_type == "Sales":
@@ -175,79 +174,52 @@ def interact_with_salesforce(mode, entry_type, quantity, extracted_text):
175
  elif mode == "Exit":
176
  if entry_type == "Sales":
177
  object_name = "Inventory_Management__c"
178
- product_field_name = "Product_Name__c"
179
- model_field_name = "Modal_Name__c"
180
  field_name = "Quantity_Sold__c"
181
  elif entry_type == "Non-Sales":
182
  object_name = "Un_Billable__c"
183
- product_field_name = "Product_Name__c"
184
- model_field_name = "Model_Name__c"
185
  field_name = "Sold_Out__c"
186
 
187
  if not object_name or not field_name:
188
  return "Invalid mode or entry type."
189
 
190
- # Get valid fields for the specified Salesforce object
191
- sf_object = sf.__getattr__(object_name)
192
- schema = sf_object.describe()
193
- valid_fields = {field["name"] for field in schema["fields"]}
194
-
195
- # Extract product name or model number
196
  product_name = match_product_name(extracted_text)
197
  attributes = extract_attributes(extracted_text)
 
198
 
199
- if not product_name:
200
- return "Product name could not be matched from the extracted text."
201
 
202
- attributes["Product name"] = product_name
 
 
 
 
 
 
 
 
 
 
203
 
204
- # If in "Exit" mode, we check if the product name or model name is already in Salesforce
205
- if mode == "Exit":
206
- # Build query based on product name or model name
207
- query = f"SELECT Id, {field_name} FROM {object_name} WHERE {product_field_name} = '{product_name}' OR {model_field_name} = '{attributes.get('Model Name', '')}' LIMIT 1"
208
- response = sf.query(query)
209
-
210
- if response["records"]:
211
- record_id = response["records"][0]["Id"]
212
- updated_quantity = quantity # Overwrite the quantity, don't add
213
- sf_object.update(record_id, {field_name: updated_quantity})
214
- return f"Updated record for product '{product_name}' in {object_name}. New {field_name}: {updated_quantity}."
215
  else:
216
- return f"No matching record found for product '{product_name}' in {object_name}."
 
 
 
217
  else:
218
- filtered_attributes = filter_valid_attributes(attributes, valid_fields)
219
- filtered_attributes[field_name] = quantity
220
- sf_object.create(filtered_attributes)
221
- return f"βœ… Data successfully exported to Salesforce object {object_name}."
222
 
223
  except Exception as e:
224
  return f"❌ Error interacting with Salesforce: {str(e)}"
225
 
226
- # Function to generate a simple bar graph from the DataFrame
227
- def generate_bar_graph(df):
228
- fig = go.Figure()
229
-
230
- # Create a simple bar graph from the data
231
- fig.add_trace(go.Bar(
232
- x=df['Product Name'], # X-axis: Product Name
233
- y=df['Current Stocks'], # Y-axis: Current Stocks
234
- marker=dict(color='skyblue'), # Basic color for the bars
235
- text=df['Current Stocks'], # Show current stock as text on the bars
236
- textposition='outside', # Position text outside the bars
237
- ))
238
-
239
- # Update layout for cleaner styling
240
- fig.update_layout(
241
- title="Current Stocks of Products", # Title of the chart
242
- xaxis=dict(title="Product Name", tickangle=-45), # X-axis label
243
- yaxis=dict(title="Stock Quantity"), # Y-axis label
244
- showlegend=False, # Hide legend
245
- plot_bgcolor='white', # White background for the plot
246
- margin=dict(l=50, r=50, t=50, b=150), # Adjust margins for better visibility
247
- )
248
-
249
- return fig
250
-
251
  # Function to pull structured data from Salesforce and display as a table
252
  def pull_data_from_salesforce():
253
  try:
@@ -277,10 +249,20 @@ def pull_data_from_salesforce():
277
  excel_path = "salesforce_data.xlsx"
278
  df.to_excel(excel_path, index=False)
279
 
280
- # Call the function to generate the bar graph
281
- fig = generate_bar_graph(df)
 
 
 
 
 
 
 
 
 
 
282
 
283
- return "Data successfully retrieved.", df, excel_path, fig
284
  except Exception as e:
285
  return f"Error fetching data: {str(e)}", None, None, None
286
 
@@ -303,16 +285,16 @@ def process_image(image, mode, entry_type, quantity):
303
 
304
  # Gradio Interface
305
  def app():
306
- return gr.TabbedInterface([
307
  gr.Interface(
308
  fn=process_image,
309
- inputs=[
310
  gr.Image(type="numpy", label="πŸ“„ Upload Image"),
311
  gr.Dropdown(label="πŸ“Œ Mode", choices=["Entry", "Exit"], value="Entry"),
312
- gr.Radio(label="Entry Type", choices=["Sales", "Non-Sales"], value="Sales"),
313
  gr.Number(label="πŸ”’ Quantity", value=1, interactive=True),
314
  ],
315
- outputs=[
316
  gr.Text(label="πŸ“ Extracted Image Data"),
317
  gr.Text(label="πŸš€ Result")
318
  ],
@@ -322,11 +304,11 @@ def app():
322
  gr.Interface(
323
  fn=pull_data_from_salesforce,
324
  inputs=[],
325
- outputs=[
326
  gr.Text(label="Status"),
327
  gr.Dataframe(label="πŸ“¦ Salesforce Data Table"),
328
  gr.File(label="Download Salesforce Data"),
329
- gr.Plot(label="πŸ“‰ Stock Distribution Bar Graph")
330
  ],
331
  title="πŸ“Š Salesforce Data Export",
332
  description="View, visualize (zoom-in/out), and download Salesforce data (Product Name, Model Name, Current Stocks)."
@@ -334,4 +316,4 @@ def app():
334
  ], ["πŸ“₯ OCR Processing", "πŸ“Š Salesforce Data Export"])
335
 
336
  if __name__ == "__main__":
337
- app().launch(share=True)
 
9
  import matplotlib.pyplot as plt
10
  from io import BytesIO
11
  from fuzzywuzzy import process
 
12
  import kaleido # Ensure kaleido is imported
13
 
14
  # Attribute mappings: readable names to Salesforce API names
 
81
  "Openwell Submersible Pumpset", "Electric Motor", "Self Priming Pump",
82
  "Control panel for single phase submersible pumps", "MOTOR", "Submersible pump set",
83
  "Fusion submersible pump set", "DCT", "Shock proof water proof", "CG COMMERCIAL MOTORS", "Fusion",
84
+ "control panel for single phase submerisible pumps",
85
  "single phase digital starter dry run and timer panel", "5HP AV1 XL Kirloskar Pump",
86
  "Phase stainless steel submersible pump", "Submersible pump", "WB15X",
87
  "Vtype self priming pump", "SP SHINE DISC", "havells submersible pump",
 
149
  def filter_valid_attributes(attributes, valid_fields):
150
  return {ATTRIBUTE_MAPPING[key]: value for key, value in attributes.items() if ATTRIBUTE_MAPPING[key] in valid_fields}
151
 
152
+ #πŸ“Š Function to interact with Salesforce based on mode and type
153
  def interact_with_salesforce(mode, entry_type, quantity, extracted_text):
154
  try:
155
  sf = Salesforce(
 
158
  security_token=SALESFORCE_SECURITY_TOKEN
159
  )
160
 
161
+ # Determine Salesforce Object and Fields
162
  object_name = None
163
+ product_field_name = "Product_Name__c"
164
+ model_field_name = "Modal_Name__c"
165
  field_name = None
 
 
166
 
167
  if mode == "Entry":
168
  if entry_type == "Sales":
 
174
  elif mode == "Exit":
175
  if entry_type == "Sales":
176
  object_name = "Inventory_Management__c"
 
 
177
  field_name = "Quantity_Sold__c"
178
  elif entry_type == "Non-Sales":
179
  object_name = "Un_Billable__c"
 
 
180
  field_name = "Sold_Out__c"
181
 
182
  if not object_name or not field_name:
183
  return "Invalid mode or entry type."
184
 
185
+ # Extract product name and attributes from the OCR result
 
 
 
 
 
186
  product_name = match_product_name(extracted_text)
187
  attributes = extract_attributes(extracted_text)
188
+ model_name = attributes.get("Model Name", "").strip()
189
 
190
+ if not product_name and not model_name:
191
+ return "Product name or Model name could not be matched from the extracted text."
192
 
193
+ # Build strict query to match either Product Name or Model Name
194
+ query_conditions = []
195
+ if product_name:
196
+ query_conditions.append(f"{product_field_name} = '{product_name}'")
197
+ if model_name:
198
+ query_conditions.append(f"{model_field_name} = '{model_name}'")
199
+
200
+ query_condition_string = " OR ".join(query_conditions)
201
+
202
+ query = f"SELECT Id, {field_name} FROM {object_name} WHERE {query_condition_string} LIMIT 1"
203
+ response = sf.query(query)
204
 
205
+ if response["records"]:
206
+ record_id = response["records"][0]["Id"]
207
+ existing_quantity = response["records"][0].get(field_name, 0)
208
+
209
+ # Ensure quantity is subtracted correctly in Exit Mode
210
+ if mode == "Exit":
211
+ updated_quantity = max(0, existing_quantity - quantity)
 
 
 
 
212
  else:
213
+ updated_quantity = existing_quantity + quantity
214
+
215
+ sf.__getattr__(object_name).update(record_id, {field_name: updated_quantity})
216
+ return f"βœ… Successfully updated product '{product_name or model_name}' in {object_name}. New {field_name}: {updated_quantity}."
217
  else:
218
+ return f"❌ No matching record found for '{product_name or model_name}' in {object_name}."
 
 
 
219
 
220
  except Exception as e:
221
  return f"❌ Error interacting with Salesforce: {str(e)}"
222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  # Function to pull structured data from Salesforce and display as a table
224
  def pull_data_from_salesforce():
225
  try:
 
249
  excel_path = "salesforce_data.xlsx"
250
  df.to_excel(excel_path, index=False)
251
 
252
+ # Generate interactive vertical bar graph using Matplotlib
253
+ fig, ax = plt.subplots(figsize=(12, 8))
254
+ df.plot(kind='bar', x="Product Name", y="Current Stocks", ax=ax, legend=False)
255
+ ax.set_title("Stock Distribution by Product Name")
256
+ ax.set_xlabel("Product Name")
257
+ ax.set_ylabel("Current Stocks")
258
+ plt.xticks(rotation=45, ha="right", fontsize=10)
259
+ plt.tight_layout()
260
+ buffer = BytesIO()
261
+ plt.savefig(buffer, format="png")
262
+ buffer.seek(0)
263
+ img = Image.open(buffer)
264
 
265
+ return "Data successfully retrieved.", df, excel_path, img
266
  except Exception as e:
267
  return f"Error fetching data: {str(e)}", None, None, None
268
 
 
285
 
286
  # Gradio Interface
287
  def app():
288
+ return gr.TabbedInterface([
289
  gr.Interface(
290
  fn=process_image,
291
+ inputs=[
292
  gr.Image(type="numpy", label="πŸ“„ Upload Image"),
293
  gr.Dropdown(label="πŸ“Œ Mode", choices=["Entry", "Exit"], value="Entry"),
294
+ gr.Radio(label="πŸ“¦ Entry Type", choices=["Sales", "Non-Sales"], value="Sales"),
295
  gr.Number(label="πŸ”’ Quantity", value=1, interactive=True),
296
  ],
297
+ outputs=[
298
  gr.Text(label="πŸ“ Extracted Image Data"),
299
  gr.Text(label="πŸš€ Result")
300
  ],
 
304
  gr.Interface(
305
  fn=pull_data_from_salesforce,
306
  inputs=[],
307
+ outputs=[
308
  gr.Text(label="Status"),
309
  gr.Dataframe(label="πŸ“¦ Salesforce Data Table"),
310
  gr.File(label="Download Salesforce Data"),
311
+ gr.Image(label="πŸ“‰ Stock Distribution Bar Graph")
312
  ],
313
  title="πŸ“Š Salesforce Data Export",
314
  description="View, visualize (zoom-in/out), and download Salesforce data (Product Name, Model Name, Current Stocks)."
 
316
  ], ["πŸ“₯ OCR Processing", "πŸ“Š Salesforce Data Export"])
317
 
318
  if __name__ == "__main__":
319
+ app().launch(share=True)