gopichandra commited on
Commit
8f1417a
Β·
verified Β·
1 Parent(s): 92b1f49

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -162
app.py CHANGED
@@ -1,4 +1,3 @@
1
-
2
  import os
3
  from paddleocr import PaddleOCR
4
  from PIL import Image
@@ -13,9 +12,9 @@ from fuzzywuzzy import process
13
  import plotly.graph_objects as go
14
  import kaleido # Ensure kaleido is imported
15
 
16
- #πŸ“Œ Attribute mappings: readable names to Salesforce API names
17
  ATTRIBUTE_MAPPING = {
18
- "Product name": "Productname__c",
19
  "Colour": "Colour__c",
20
  "Motortype": "Motortype__c",
21
  "Frequency": "Frequency__c",
@@ -74,43 +73,15 @@ ATTRIBUTE_MAPPING = {
74
  "SRnumber": "SRnumber__c",
75
  "TypeOfEndUse": "TypeOfEndUse__c",
76
  "Model Name": "Model_Name_Number__c",
77
- "coolingmethod": "coolingmethod__c"
78
  }
79
-
80
- # List of product names to match
81
- PRODUCT_NAMES = ["Centrifugal mono block pump", "SINGLE PHASE MOTOR STARTER", "EasyPact EZC 100",
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 submerisible 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",
89
- "Havells open well Submersible pump", "Bertolini pump CK3 90pp",
90
- "WPA 772 Water Pump Assy", "bertolini TTL triplex high pressure plunger pumps",
91
- "Generic plunger high pressure pump", "Apple Normal, Banana",
92
- "Cast Iron KSb centrifugal pump", "5.5kw Water Pump",
93
- "KSB reliable i line centrifuged pumps", "Apple Normal, Orange, Banana",
94
- "Positive API 6745 hydraulic diaphragm pump", "1/2 inch Fuel Hose Pipe", "Kirloskar Water Pump",
95
- "Rotodel motor pump", "PVC Electrical Insulation Materials",
96
- "Electric kirloskar domestic water pump", "Electrical Insulation Materials",
97
- "sellowell motor pump", "bhupathi submersible pump set",
98
- "Flowshine Submersible pump set", "Index submersible pump",
99
- "Wintoss Plastic Electric Switch Board", "Electric 18 watt ujagar cooler pump",
100
- "Generator Service", "LG WM FHT1207ZWL, LG REF GL-S292RSCY",
101
- "Water tank, Filters, Water Pump", "MS Control Submersible Panel",
102
- "Centrifugal Monoblock Pumps", "Electric Motor with Pump BodyBlue and White",
103
- "Various Repair and Maintenance Parts", "Earthmax Pump",
104
- "Water Tank, Filters, Water Pump", "Centrifugal Water Pump for Agriculture",
105
- "mono block pumps"
106
- ]
107
 
108
- #πŸ“Œ Salesforce credentials
109
  SALESFORCE_USERNAME = "venkatramana@sandbox.com"
110
  SALESFORCE_PASSWORD = "Venkat12345@"
111
  SALESFORCE_SECURITY_TOKEN = "GhcJJmjBEefdnukJoz4CAQlR"
112
 
113
- #🧠 Initialize PaddleOCR
114
  ocr = PaddleOCR(use_angle_cls=True, lang='en')
115
 
116
  # Function to extract text using PaddleOCR
@@ -150,90 +121,6 @@ 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(
157
- username=SALESFORCE_USERNAME,
158
- password=SALESFORCE_PASSWORD,
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":
170
- object_name = "VENKATA_RAMANA_MOTORS__c"
171
- field_name = "Quantity__c"
172
- elif entry_type == "Non-Sales":
173
- object_name = "UNBILLING_DATA__c"
174
- field_name = "TotalQuantity__c"
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 mode == "Exit":
205
- 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"
206
- response = sf.query(query)
207
-
208
- if response["records"]:
209
- record_id = response["records"][0]["Id"]
210
- updated_quantity = quantity # Overwrite the quantity, don't add
211
- sf_object.update(record_id, {field_name: updated_quantity})
212
- return f"Updated record for product '{product_name}' in {object_name}. New {field_name}: {updated_quantity}."
213
- else:
214
- return f"No matching record found for product '{product_name}' in {object_name}."
215
- else:
216
- filtered_attributes = filter_valid_attributes(attributes, valid_fields)
217
- filtered_attributes[field_name] = quantity
218
- sf_object.create(filtered_attributes)
219
- return f"βœ… Data successfully exported to Salesforce object {object_name}."
220
-
221
- except Exception as e:
222
- return f"❌ Error interacting with Salesforce: {str(e)}"
223
-
224
- # Function to pull data from Salesforce MotorDataAPI
225
- def pull_data_from_motor_api():
226
- try:
227
- sf = Salesforce(
228
- username=SALESFORCE_USERNAME,
229
- password=SALESFORCE_PASSWORD,
230
- security_token=SALESFORCE_SECURITY_TOKEN
231
- )
232
- motor_data = sf.apexecute("MotorDataAPI/", method="GET")
233
- return motor_data # API returns the list of records
234
- except Exception as e:
235
- return f"Error pulling data from MotorDataAPI: {str(e)}"
236
-
237
  # Function to pull structured data from Salesforce and display as a table
238
  def pull_data_from_salesforce():
239
  try:
@@ -242,29 +129,34 @@ def pull_data_from_salesforce():
242
  password=SALESFORCE_PASSWORD,
243
  security_token=SALESFORCE_SECURITY_TOKEN
244
  )
245
-
246
  query = "SELECT Product_Name__c, Modal_Name__c, Current_Stocks__c FROM Inventory_Management__c LIMIT 100"
247
  response = sf.query_all(query)
248
-
249
  records = response.get("records", [])
250
  if not records:
251
- return "No data found in Salesforce.", None, None, None
252
-
253
  df = pd.DataFrame(records)
254
  df = df.drop(columns=['attributes'], errors='ignore')
255
-
256
  # Rename columns for better readability
257
  df.rename(columns={
258
  "Product_Name__c": "Product Name",
259
  "Modal_Name__c": "Model Name",
260
  "Current_Stocks__c": "Current Stocks"
261
  }, inplace=True)
262
-
263
- excel_path = "salesforce_data.xlsx"
264
- df.to_excel(excel_path, index=False)
265
-
266
- # Generate interactive bar graph using Plotly with Tooltip, Hover Effect, and Zooming
 
 
 
267
  fig = go.Figure()
 
 
268
  fig.add_trace(go.Bar(
269
  x=df['Product Name'],
270
  y=df['Current Stocks'],
@@ -274,7 +166,7 @@ def pull_data_from_salesforce():
274
  text=df['Current Stocks'],
275
  textposition='outside'
276
  ))
277
-
278
  fig.update_layout(
279
  title="Current Stocks of Products",
280
  xaxis=dict(title="Product Name", tickangle=-45),
@@ -283,61 +175,90 @@ def pull_data_from_salesforce():
283
  dragmode='zoom',
284
  showlegend=False
285
  )
286
-
287
- return "Data successfully retrieved.", df, excel_path, fig
288
- except Exception as e:
289
- return f"Error fetching data: {str(e)}", None, None, None
290
 
291
- # Unified function to handle image processing and Salesforce interaction
292
- def process_image(image, mode, entry_type, quantity):
293
- extracted_text = extract_text(image)
294
- if not extracted_text:
295
- return "No text detected in the image.", None
 
 
 
296
 
297
- product_name = match_product_name(extracted_text)
298
- attributes = extract_attributes(extracted_text)
299
- if product_name:
300
- attributes["Product name"] = product_name
 
 
 
 
 
 
 
 
 
 
 
301
 
302
- # Interact with Salesforce
303
- message = interact_with_salesforce(mode, entry_type, quantity, extracted_text)
 
304
 
305
- numbered_output = "\n".join([f"{key}: {value}" for key, value in attributes.items()])
306
- return f"Extracted Text:\n{extracted_text}\n\nAttributes and Values:\n{numbered_output}", message
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
 
308
  # Gradio Interface
309
  def app():
 
 
 
310
  return gr.TabbedInterface([
311
  gr.Interface(
312
  fn=process_image,
313
  inputs=[
314
- gr.Image(type="numpy", label="πŸ“„α΄œα΄˜ΚŸα΄α΄€α΄… Ιͺᴍᴀɒᴇ"),
315
- gr.Radio(label="πŸ“ŒMode", choices=["ᴇɴᴛʀʏ", "ᴇxΙͺα΄›"], value="Entry"),
316
- gr.Radio(label="πŸ“¦α΄‡Ι΄α΄›Κ€Κ α΄›Κα΄˜α΄‡", choices=["κœ±α΄€ΚŸα΄‡κœ±", "ɴᴏɴ-κœ±α΄€ΚŸα΄‡κœ±"], value="Sales"),
317
- gr.Number(label="πŸ”’Quantity", value=1, interactive=False),
318
  ],
319
  outputs=[
320
- gr.Text(label="Ιͺᴍᴀɒᴇ α΄…α΄€α΄›α΄€ α΄ Ιͺᴇᴑᴇʀ"),
321
- gr.Text(label="πŸ“οΌ²οΌ₯οΌ³οΌ΅οΌ¬οΌ΄")
322
  ],
323
- title="πŸ’π‘½π‘¬π‘΅π‘²π‘¨π‘»π‘¨π‘Ήπ‘¨π‘΄π‘¨π‘΅π‘¨ 𝑴𝑢𝑻𝑢𝑹𝑺",
324
- description="πŸ“¦πˆππ•π„ππ“πŽπ‘π˜ πŒπ€ππ€π†π„πŒπ„ππ“"
325
  ),
326
  gr.Interface(
327
- fn=pull_data_from_salesforce,
328
  inputs=[],
329
  outputs=[
330
  gr.Text(label="Status"),
331
- gr.Dataframe(label="πŸ“¦κœ±α΄€ΚŸα΄‡κœ±κœ°α΄Κ€α΄„α΄‡ α΄…α΄€α΄›α΄€ α΄›α΄€Κ™ΚŸα΄‡"),
332
- gr.File(label="α΄…α΄α΄‘Ι΄ΚŸα΄α΄€α΄… κœ±α΄€ΚŸα΄‡κœ±κœ°α΄Κ€α΄„α΄‡ α΄…α΄€α΄›α΄€"),
333
- gr.Plot(label="πŸ“‰κœ±α΄›α΄α΄„α΄‹ α΄…Ιͺκœ±α΄›Κ€ΙͺΚ™α΄œα΄›Ιͺᴏɴ Κ™α΄€Κ€ Ι’Κ€α΄€α΄˜Κœ")
334
-
335
  ],
336
- title="πŸ“ˆκœ±α΄€ΚŸα΄‡κœ±κœ°α΄Κ€α΄„α΄‡ α΄…α΄€α΄›α΄€ ᴇxα΄˜α΄Κ€α΄›",
337
  description="View, visualize (zoom-in/out), and download Salesforce data (Product Name, Model Name, Current Stocks)."
338
  )
339
- ], ["πŸ“₯OCR Processing", "πŸ“ŠSalesforce Data Export"])
340
 
341
  if __name__ == "__main__":
342
  app().launch(share=True)
343
-
 
 
1
  import os
2
  from paddleocr import PaddleOCR
3
  from PIL import Image
 
12
  import plotly.graph_objects as go
13
  import kaleido # Ensure kaleido is imported
14
 
15
+ # Attribute mappings: readable names to Salesforce API names
16
  ATTRIBUTE_MAPPING = {
17
+ "Product name": "Productname__c",
18
  "Colour": "Colour__c",
19
  "Motortype": "Motortype__c",
20
  "Frequency": "Frequency__c",
 
73
  "SRnumber": "SRnumber__c",
74
  "TypeOfEndUse": "TypeOfEndUse__c",
75
  "Model Name": "Model_Name_Number__c",
76
+ "coolingmethod": "coolingmethod__c"
77
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
+ # Salesforce credentials
80
  SALESFORCE_USERNAME = "venkatramana@sandbox.com"
81
  SALESFORCE_PASSWORD = "Venkat12345@"
82
  SALESFORCE_SECURITY_TOKEN = "GhcJJmjBEefdnukJoz4CAQlR"
83
 
84
+ # Initialize PaddleOCR
85
  ocr = PaddleOCR(use_angle_cls=True, lang='en')
86
 
87
  # Function to extract text using PaddleOCR
 
121
  def filter_valid_attributes(attributes, valid_fields):
122
  return {ATTRIBUTE_MAPPING[key]: value for key, value in attributes.items() if ATTRIBUTE_MAPPING[key] in valid_fields}
123
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  # Function to pull structured data from Salesforce and display as a table
125
  def pull_data_from_salesforce():
126
  try:
 
129
  password=SALESFORCE_PASSWORD,
130
  security_token=SALESFORCE_SECURITY_TOKEN
131
  )
132
+
133
  query = "SELECT Product_Name__c, Modal_Name__c, Current_Stocks__c FROM Inventory_Management__c LIMIT 100"
134
  response = sf.query_all(query)
135
+
136
  records = response.get("records", [])
137
  if not records:
138
+ return "No data found in Salesforce.", None
139
+
140
  df = pd.DataFrame(records)
141
  df = df.drop(columns=['attributes'], errors='ignore')
142
+
143
  # Rename columns for better readability
144
  df.rename(columns={
145
  "Product_Name__c": "Product Name",
146
  "Modal_Name__c": "Model Name",
147
  "Current_Stocks__c": "Current Stocks"
148
  }, inplace=True)
149
+
150
+ return "Data successfully retrieved.", df
151
+ except Exception as e:
152
+ return f"Error fetching data: {str(e)}", None
153
+
154
+ # Function to generate the graph from the table data
155
+ def generate_graph_from_table(df):
156
+ if df is not None:
157
  fig = go.Figure()
158
+
159
+ # Create the bar graph using the table data
160
  fig.add_trace(go.Bar(
161
  x=df['Product Name'],
162
  y=df['Current Stocks'],
 
166
  text=df['Current Stocks'],
167
  textposition='outside'
168
  ))
169
+
170
  fig.update_layout(
171
  title="Current Stocks of Products",
172
  xaxis=dict(title="Product Name", tickangle=-45),
 
175
  dragmode='zoom',
176
  showlegend=False
177
  )
178
+ return fig
179
+ else:
180
+ return None
 
181
 
182
+ # Function to update Salesforce records based on mode (Entry/Exit) and type (Sales/Non-Sales)
183
+ def interact_with_salesforce(mode, entry_type, quantity, product_name):
184
+ try:
185
+ sf = Salesforce(
186
+ username=SALESFORCE_USERNAME,
187
+ password=SALESFORCE_PASSWORD,
188
+ security_token=SALESFORCE_SECURITY_TOKEN
189
+ )
190
 
191
+ # Define the object and field names based on mode and entry type
192
+ if mode == "Entry":
193
+ if entry_type == "Sales":
194
+ object_name = "VENKATA_RAMANA_MOTORS__c"
195
+ field_name = "Quantity__c"
196
+ elif entry_type == "Non-Sales":
197
+ object_name = "UNBILLING_DATA__c"
198
+ field_name = "TotalQuantity__c"
199
+ elif mode == "Exit":
200
+ if entry_type == "Sales":
201
+ object_name = "Inventory_Management__c"
202
+ field_name = "Quantity_Sold__c"
203
+ elif entry_type == "Non-Sales":
204
+ object_name = "Un_Billable__c"
205
+ field_name = "Sold_Out__c"
206
 
207
+ # Query the product in Salesforce
208
+ query = f"SELECT Id, {field_name} FROM {object_name} WHERE Product_Name__c = '{product_name}' LIMIT 1"
209
+ response = sf.query(query)
210
 
211
+ if response["records"]:
212
+ record_id = response["records"][0]["Id"]
213
+ current_quantity = response["records"][0].get(field_name, 0) or 0
214
+
215
+ # Update or add the quantity based on mode
216
+ if mode == "Exit" and entry_type == "Sales":
217
+ updated_quantity = max(0, current_quantity - quantity) # Subtract quantity on sales exit
218
+ else:
219
+ updated_quantity = current_quantity + quantity # Add quantity on entry
220
+
221
+ # Update or create record in Salesforce
222
+ sf.__getattr__(object_name).update(record_id, {field_name: updated_quantity})
223
+ return f"Updated record for {product_name}. New {field_name}: {updated_quantity}."
224
+ else:
225
+ return f"No matching record found for product '{product_name}'."
226
+ except Exception as e:
227
+ return f"Error interacting with Salesforce: {str(e)}"
228
 
229
  # Gradio Interface
230
  def app():
231
+ status, df = pull_data_from_salesforce()
232
+ graph = generate_graph_from_table(df) if df is not None else None
233
+
234
  return gr.TabbedInterface([
235
  gr.Interface(
236
  fn=process_image,
237
  inputs=[
238
+ gr.Image(type="numpy", label="πŸ“„ Upload Image"),
239
+ gr.Dropdown(label="πŸ“Œ Mode", choices=["Entry", "Exit"], value="Entry"),
240
+ gr.Radio(label="Entry Type", choices=["Sales", "Non-Sales"], value="Sales"),
241
+ gr.Number(label="πŸ”’ Quantity", value=1, interactive=True),
242
  ],
243
  outputs=[
244
+ gr.Text(label="πŸ“ Extracted Image Data"),
245
+ gr.Text(label="πŸš€ Result")
246
  ],
247
+ title="🏒 Inventory Management",
248
+ description="πŸ“¦ Inventory Management System"
249
  ),
250
  gr.Interface(
251
+ fn=lambda: (status, df, graph),
252
  inputs=[],
253
  outputs=[
254
  gr.Text(label="Status"),
255
+ gr.Dataframe(label="πŸ“¦ Salesforce Data Table"),
256
+ gr.Plot(label="πŸ“‰ Stock Distribution Bar Graph")
 
 
257
  ],
258
+ title="πŸ“Š Salesforce Data Export",
259
  description="View, visualize (zoom-in/out), and download Salesforce data (Product Name, Model Name, Current Stocks)."
260
  )
261
+ ], ["πŸ“₯ OCR Processing", "πŸ“Š Salesforce Data Export"])
262
 
263
  if __name__ == "__main__":
264
  app().launch(share=True)