gopichandra commited on
Commit
2f73ecf
Β·
verified Β·
1 Parent(s): 4094608

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +232 -43
app.py CHANGED
@@ -2,18 +2,78 @@ import os
2
  from paddleocr import PaddleOCR
3
  from PIL import Image
4
  import gradio as gr
 
5
  import re
6
  from simple_salesforce import Salesforce
7
  import pandas as pd
 
 
8
  from fuzzywuzzy import process
 
9
 
10
  # Attribute mappings: readable names to Salesforce API names
11
  ATTRIBUTE_MAPPING = {
12
  "Product name": "Productname__c",
 
 
 
 
 
 
13
  "Model": "Model__c",
 
 
 
 
 
 
 
 
14
  "Stage": "Stage__c",
15
- "H.P.": "H_p__c",
16
- "Price": "Price__c"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
  # List of product names to match
@@ -62,8 +122,12 @@ def extract_attributes(extracted_text):
62
 
63
  return attributes
64
 
65
- # Function to interact with Salesforce and fetch details
66
- def fetch_salesforce_details(attributes):
 
 
 
 
67
  try:
68
  sf = Salesforce(
69
  username=SALESFORCE_USERNAME,
@@ -71,48 +135,65 @@ def fetch_salesforce_details(attributes):
71
  security_token=SALESFORCE_SECURITY_TOKEN
72
  )
73
 
74
- object_name = "Inventory_Management__c"
 
 
75
  product_field_name = "Productname__c"
76
  model_field_name = "Model__c"
77
  stage_field_name = "Stage__c"
78
  hp_field_name = "H_p__c"
79
- price_field_name = "Price__c"
80
-
81
- # Build query conditions
82
- query_conditions = [f"{product_field_name} = '{attributes.get('Product name', '')}'"]
83
- if "Model" in attributes and attributes["Model"]:
84
- query_conditions.append(f"{model_field_name} = '{attributes['Model']}'")
85
- if "Stage" in attributes and attributes["Stage"]:
86
- query_conditions.append(f"{stage_field_name} = '{attributes['Stage']}'")
87
- if "H.P." in attributes and attributes["H.P."]:
88
- query_conditions.append(f"{hp_field_name} = '{attributes['H.P.']}'")
89
-
90
- # Query Salesforce
91
- query = f"SELECT {product_field_name}, {model_field_name}, {stage_field_name}, {hp_field_name}, {price_field_name} FROM {object_name} WHERE {' AND '.join(query_conditions)} LIMIT 1"
92
- response = sf.query(query)
93
-
94
- if response["records"]:
95
- record = response["records"][0]
96
- product_name = record.get(product_field_name, "N/A")
97
- model = record.get(model_field_name, "N/A")
98
- stage = record.get(stage_field_name, "N/A")
99
- hp = record.get(hp_field_name, "N/A")
100
- price = record.get(price_field_name, "N/A")
101
-
102
- # Return details as a formatted string
103
- return (
104
- f"Details:\n"
105
- f"Product Name: {product_name}\n"
106
- f"Model: {model}\n"
107
- f"Stage: {stage}\n"
108
- f"H.P.: {hp}\n"
109
- f"Price: {price}"
110
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  else:
112
- return "❌ No matching record found in Salesforce."
 
 
113
 
114
  except Exception as e:
115
- return f"❌ Error fetching data from Salesforce: {str(e)}"
116
 
117
  # Function to process image, extract attributes, and allow editing
118
  def process_image(image, mode, entry_type, quantity):
@@ -134,18 +215,114 @@ def process_image(image, mode, entry_type, quantity):
134
  df = pd.DataFrame(list(attributes.items()), columns=["Attribute", "Value"])
135
  return f"Extracted Text:\n{extracted_text}", df, None
136
 
137
- # Function to handle edited attributes and fetch Salesforce details
138
  def export_to_salesforce(mode, entry_type, quantity, edited_df):
139
  try:
140
  # Convert edited DataFrame back to dictionary
141
  edited_attributes = dict(zip(edited_df["Attribute"], edited_df["Value"]))
142
 
143
- # Fetch details from Salesforce
144
- details = fetch_salesforce_details(edited_attributes)
145
- return details
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  except Exception as e:
147
  return f"❌ Error exporting to Salesforce: {str(e)}"
148
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  # Gradio Interface
150
  def app():
151
  with gr.Blocks() as demo:
@@ -161,6 +338,13 @@ def app():
161
  ok_button = gr.Button("OK")
162
  result_output = gr.Text(label="πŸš€ Result")
163
 
 
 
 
 
 
 
 
164
  # Define button actions
165
  extract_button.click(
166
  fn=process_image,
@@ -172,6 +356,11 @@ def app():
172
  inputs=[mode_input, entry_type_input, quantity_input, editable_df_output],
173
  outputs=[result_output]
174
  )
 
 
 
 
 
175
 
176
  return demo
177
 
 
2
  from paddleocr import PaddleOCR
3
  from PIL import Image
4
  import gradio as gr
5
+ import requests
6
  import re
7
  from simple_salesforce import Salesforce
8
  import pandas as pd
9
+ import matplotlib.pyplot as plt
10
+ from io import BytesIO
11
  from fuzzywuzzy import process
12
+ import kaleido
13
 
14
  # Attribute mappings: readable names to Salesforce API names
15
  ATTRIBUTE_MAPPING = {
16
  "Product name": "Productname__c",
17
+ "Colour": "Colour__c",
18
+ "Motortype": "Motortype__c",
19
+ "Frequency": "Frequency__c",
20
+ "Grossweight": "Grossweight__c",
21
+ "Ratio": "Ratio__c",
22
+ "MotorFrame": "Motorframe__c",
23
  "Model": "Model__c",
24
+ "Speed": "Speed__c",
25
+ "Quantity": "Quantity__c",
26
+ "Voltage": "Voltage__c",
27
+ "Material": "Material__c",
28
+ "Type": "Type__c",
29
+ "Horsepower": "Horsepower__c",
30
+ "Consignee": "Consignee__c",
31
+ "LOT": "LOT__c",
32
  "Stage": "Stage__c",
33
+ "Outlet": "Outlet__c",
34
+ "Serialnumber": "Serialnumber__c",
35
+ "HeadSize": "Headsize__c",
36
+ "Deliverysize": "Deliverysize__c",
37
+ "Phase": "Phase__c",
38
+ "Size": "Size__c",
39
+ "MRP": "MRP__c",
40
+ "Usebefore": "Usebefore__c",
41
+ "Height": "Height__c",
42
+ "MaximumDischarge Flow": "Maximumdischargeflow__c",
43
+ "DischargeRange": "Dischargeflow__c",
44
+ "Assembledby": "Manufacturer__c",
45
+ "Manufacturedate": "Manufacturedate__c",
46
+ "Companyname": "Companyname__c",
47
+ "Customercarenumber": "Customercarenumber__c",
48
+ "SellerAddress": "Selleraddress__c",
49
+ "Selleremail": "Selleremail__c",
50
+ "GSTIN": "GSTIN__c",
51
+ "Totalamount": "Totalamount__c",
52
+ "Paymentstatus": "Paymentstatus__c",
53
+ "Paymentmethod": "Paymentstatus__c",
54
+ "Invoicedate": "Manufacturedate__c",
55
+ "Warranty": "Warranty__c",
56
+ "Brand": "Brand__c",
57
+ "Motorhorsepower": "Motorhorsepower__c",
58
+ "Power": "Power__c",
59
+ "Motorphase": "Motorphase__c",
60
+ "Enginetype": "Enginetype__c",
61
+ "Tankcapacity": "Tankcapacity__c",
62
+ "Head": "Head__c",
63
+ "Usage/Application": "Usage_Application__c",
64
+ "Volts": "volts__c",
65
+ "Hertz": "Hertz__c",
66
+ "Frame": "frame__c",
67
+ "Mounting": "Mounting__c",
68
+ "Tollfreenumber": "Tollfreenumber__c",
69
+ "Pipesize": "Pipesize__c",
70
+ "Manufacturer": "Manufacturer__c",
71
+ "Office": "Office__c",
72
+ "SRnumber": "SRnumber__c",
73
+ "TypeOfEndUse": "TypeOfEndUse__c",
74
+ "Model Name": "Model_Name_Number__c",
75
+ "coolingmethod": "coolingmethod__c",
76
+ "H.P.": "H_p__c"
77
  }
78
 
79
  # List of product names to match
 
122
 
123
  return attributes
124
 
125
+ # Function to filter attributes for valid Salesforce fields
126
+ def filter_valid_attributes(attributes, valid_fields):
127
+ return {ATTRIBUTE_MAPPING[key]: value for key, value in attributes.items() if ATTRIBUTE_MAPPING[key] in valid_fields}
128
+
129
+ # Function to interact with Salesforce based on mode and type
130
+ def interact_with_salesforce(mode, entry_type, quantity, attributes):
131
  try:
132
  sf = Salesforce(
133
  username=SALESFORCE_USERNAME,
 
135
  security_token=SALESFORCE_SECURITY_TOKEN
136
  )
137
 
138
+ object_name = None
139
+ field_name = None
140
+ field_names = []
141
  product_field_name = "Productname__c"
142
  model_field_name = "Model__c"
143
  stage_field_name = "Stage__c"
144
  hp_field_name = "H_p__c"
145
+
146
+ if mode == "Entry":
147
+ if entry_type == "Sales":
148
+ object_name = "VENKATA_RAMANA_MOTORS__c"
149
+ field_name = "Quantity__c"
150
+ elif entry_type == "Non-Sales":
151
+ object_name = "UNBILLING_DATA__c"
152
+ field_name = "TotalQuantity__c"
153
+ elif mode == "Exit":
154
+ if entry_type == "Sales":
155
+ object_name = "Inventory_Management__c"
156
+ field_names = ["Quantity_Sold__c", "soldstock__c"]
157
+ elif entry_type == "Non-Sales":
158
+ object_name = "Un_Billable__c"
159
+ field_names = ["Sold_Out__c", "soldstock__c"]
160
+
161
+ if not object_name or (not field_name and not field_names):
162
+ return "Invalid mode or entry type."
163
+
164
+ sf_object = sf.__getattr__(object_name)
165
+ schema = sf_object.describe()
166
+ valid_fields = {field["name"] for field in schema["fields"]}
167
+
168
+ filtered_attributes = filter_valid_attributes(attributes, valid_fields)
169
+
170
+ if mode == "Exit":
171
+ query_conditions = [f"{product_field_name} = '{attributes['Product name']}'"]
172
+ if "Model Name" in attributes and attributes["Model Name"]:
173
+ query_conditions.append(f"{model_field_name} = '{attributes['Model Name']}'")
174
+ if "Stage" in attributes and attributes["Stage"] != "":
175
+ query_conditions.append(f"{stage_field_name} = '{attributes['Stage']}'")
176
+ if "H.P." in attributes and attributes["H.P."]:
177
+ query_conditions.append(f"{hp_field_name} = '{attributes['H.P.']}'")
178
+
179
+ query = f"SELECT Id, {', '.join(field_names)} FROM {object_name} WHERE {' AND '.join(query_conditions)} LIMIT 1"
180
+ response = sf.query(query)
181
+
182
+ if response["records"]:
183
+ record_id = response["records"][0]["Id"]
184
+ updated_fields = {field: quantity for field in field_names}
185
+ sf_object.update(record_id, updated_fields)
186
+ return f"βœ… Updated record for product '{attributes['Product name']}' in {object_name}. Updated fields: {updated_fields}."
187
+ else:
188
+ return f"❌ No matching record found for product '{attributes['Product name']}' in {object_name}."
189
+
190
  else:
191
+ filtered_attributes[field_name] = quantity
192
+ sf_object.create(filtered_attributes)
193
+ return f"βœ… Data successfully exported to Salesforce object {object_name}."
194
 
195
  except Exception as e:
196
+ return f"❌ Error interacting with Salesforce: {str(e)}"
197
 
198
  # Function to process image, extract attributes, and allow editing
199
  def process_image(image, mode, entry_type, quantity):
 
215
  df = pd.DataFrame(list(attributes.items()), columns=["Attribute", "Value"])
216
  return f"Extracted Text:\n{extracted_text}", df, None
217
 
218
+ # Function to handle edited attributes and export to Salesforce
219
  def export_to_salesforce(mode, entry_type, quantity, edited_df):
220
  try:
221
  # Convert edited DataFrame back to dictionary
222
  edited_attributes = dict(zip(edited_df["Attribute"], edited_df["Value"]))
223
 
224
+ # Export to Salesforce
225
+ message = interact_with_salesforce(mode, entry_type, quantity, edited_attributes)
226
+
227
+ # Fetch the price from Inventory_Management__c based on attributes
228
+ try:
229
+ sf = Salesforce(
230
+ username=SALESFORCE_USERNAME,
231
+ password=SALESFORCE_PASSWORD,
232
+ security_token=SALESFORCE_SECURITY_TOKEN
233
+ )
234
+ product_name = edited_attributes.get("Product name", "")
235
+ model_name = edited_attributes.get("Model Name", "")
236
+ stage = edited_attributes.get("Stage", "")
237
+
238
+ # Build the query
239
+ query_conditions = []
240
+ if product_name:
241
+ query_conditions.append(f"Productname__c = '{product_name}'")
242
+ if model_name:
243
+ query_conditions.append(f"Model__c = '{model_name}'")
244
+ if stage:
245
+ query_conditions.append(f"Stage__c = '{stage}'")
246
+
247
+ if query_conditions:
248
+ query = f"SELECT Price__c FROM Inventory_Management__c WHERE {' AND '.join(query_conditions)} LIMIT 1"
249
+ response = sf.query(query)
250
+
251
+ if response["records"]:
252
+ price = response["records"][0].get("Price__c", None)
253
+ if price:
254
+ price_message = f"The estimated price for the {product_name} with {model_name} at {stage} is β‚Ή{price:,}."
255
+ return f"{message}\n\n{price_message}"
256
+ else:
257
+ return f"{message}\n\nPrice information not available for the specified product."
258
+ else:
259
+ return f"{message}\n\nNo matching record found for the specified product."
260
+ else:
261
+ return f"{message}\n\nInsufficient data to fetch price information."
262
+
263
+ except Exception as e:
264
+ return f"{message}\n\nError fetching price information: {str(e)}"
265
+
266
  except Exception as e:
267
  return f"❌ Error exporting to Salesforce: {str(e)}"
268
 
269
+ import pytz
270
+
271
+ # Function to pull structured data from Salesforce and display as a table
272
+ def pull_data_from_salesforce(data_type):
273
+ try:
274
+ sf = Salesforce(
275
+ username=SALESFORCE_USERNAME,
276
+ password=SALESFORCE_PASSWORD,
277
+ security_token=SALESFORCE_SECURITY_TOKEN
278
+ )
279
+
280
+ if data_type == "Inventory":
281
+ query = "SELECT Productname__c, Model__c, H_p__c, Stage__c, Current_Stocks__c, soldstock__c, Price__c FROM Inventory_Management__c LIMIT 100"
282
+ else:
283
+ query = "SELECT Productname__c, Model__c, H_p__c, Stage__c, Current_Stock__c, soldstock__c, Price__c FROM Un_Billable__c LIMIT 100"
284
+
285
+ response = sf.query_all(query)
286
+ records = response.get("records", [])
287
+
288
+ if not records:
289
+ return "No data found in Salesforce.", None, None, None
290
+
291
+ df = pd.DataFrame(records)
292
+ df = df.drop(columns=['attributes'], errors='ignore')
293
+
294
+ # Rename columns for better readability
295
+ df.rename(columns={
296
+ "Productname__c": "Product Name",
297
+ "Model__c": "Model",
298
+ "H_p__c": "H.P",
299
+ "Stage__c": "Stage",
300
+ "Current_Stocks__c": "Current Stocks",
301
+ "Current_Stock__c": "Current Stocks",
302
+ "soldstock__c": "Sold Stock",
303
+ "Price__c": "Price"
304
+ }, inplace=True)
305
+
306
+ excel_path = "salesforce_data.xlsx"
307
+ df.to_excel(excel_path, index=False)
308
+
309
+ # Generate interactive vertical bar graph using Matplotlib
310
+ fig, ax = plt.subplots(figsize=(12, 8))
311
+ df.plot(kind='bar', x="Product Name", y="Current Stocks", ax=ax, legend=False)
312
+ ax.set_title("Stock Distribution by Product Name")
313
+ ax.set_xlabel("Product Name")
314
+ ax.set_ylabel("Current Stocks")
315
+ plt.xticks(rotation=45, ha="right", fontsize=10)
316
+ plt.tight_layout()
317
+ buffer = BytesIO()
318
+ plt.savefig(buffer, format="png")
319
+ buffer.seek(0)
320
+ img = Image.open(buffer)
321
+
322
+ return df, excel_path, img
323
+ except Exception as e:
324
+ return f"Error fetching data: {str(e)}", None, None, None
325
+
326
  # Gradio Interface
327
  def app():
328
  with gr.Blocks() as demo:
 
338
  ok_button = gr.Button("OK")
339
  result_output = gr.Text(label="πŸš€ Result")
340
 
341
+ with gr.Tab("πŸ“Š Salesforce Data"):
342
+ data_type_input = gr.Dropdown(label="Select Data Type", choices=["Inventory", "Unbilling"], value="Inventory")
343
+ pull_button = gr.Button("Pull Data from Salesforce")
344
+ salesforce_data_output = gr.Dataframe(label="πŸ“Š Salesforce Data")
345
+ excel_download_output = gr.File(label="πŸ“₯ Download Excel")
346
+ graph_output = gr.Image(label="πŸ“ˆ Stock Distribution Graph")
347
+
348
  # Define button actions
349
  extract_button.click(
350
  fn=process_image,
 
356
  inputs=[mode_input, entry_type_input, quantity_input, editable_df_output],
357
  outputs=[result_output]
358
  )
359
+ pull_button.click(
360
+ fn=pull_data_from_salesforce,
361
+ inputs=[data_type_input],
362
+ outputs=[salesforce_data_output, excel_download_output, graph_output]
363
+ )
364
 
365
  return demo
366