gopichandra commited on
Commit
fba3ec7
Β·
verified Β·
1 Parent(s): e962551

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +175 -277
app.py CHANGED
@@ -13,72 +13,72 @@ 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
80
  PRODUCT_NAMES = [
81
- "Fusion", "Agroking", "CG commercial motors", "Jaguar", "Gaurav"
82
  ]
83
 
84
  # Salesforce credentials
@@ -91,239 +91,137 @@ ocr = PaddleOCR(use_angle_cls=True, lang='en')
91
 
92
  # Function to extract text using PaddleOCR
93
  def extract_text(image):
94
- result = ocr.ocr(image)
95
- extracted_text = []
96
- for line in result[0]:
97
- extracted_text.append(line[1][0])
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
 
105
- for line in extracted_text.split("\n"):
106
- match, score = process.extractOne(line, PRODUCT_NAMES)
107
- if score > best_score:
108
- best_match = match
109
- best_score = score
110
 
111
- return best_match if best_score >= 70 else None
112
 
113
  # Function to extract attributes and their values
114
  def extract_attributes(extracted_text):
115
- attributes = {}
116
 
117
- for readable_attr, sf_attr in ATTRIBUTE_MAPPING.items():
118
- pattern = rf"{re.escape(readable_attr)}[:\-]?\s*(.+)"
119
- match = re.search(pattern, extracted_text, re.IGNORECASE)
120
- if match:
121
- attributes[readable_attr] = match.group(1).strip()
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,
134
- password=SALESFORCE_PASSWORD,
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):
200
- extracted_text = extract_text(image)
201
- if not extracted_text:
202
- return "No text detected in the image.", None, None
203
-
204
- product_name = match_product_name(extracted_text)
205
- attributes = extract_attributes(extracted_text)
206
- if product_name:
207
- attributes["Product name"] = product_name
208
-
209
- # Ensure fixed attributes are present
210
- for fixed_attr in ["Stage", "H.P.", "Product name", "Model"]:
211
- if fixed_attr not in attributes:
212
- attributes[fixed_attr] = ""
213
-
214
- # Convert attributes to DataFrame for editing
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
- return message
227
- except Exception as e:
228
- return f"❌ Error exporting to Salesforce: {str(e)}"
229
-
230
- import pytz
231
 
232
  # Function to pull structured data from Salesforce and display as a table
233
  def pull_data_from_salesforce(data_type):
234
- try:
235
- sf = Salesforce(
236
- username=SALESFORCE_USERNAME,
237
- password=SALESFORCE_PASSWORD,
238
- security_token=SALESFORCE_SECURITY_TOKEN
239
- )
240
-
241
- if data_type == "Inventory":
242
- query = "SELECT Productname__c, Model__c, H_p__c, Stage__c, Current_Stocks__c, soldstock__c, Price__c FROM Inventory_Management__c LIMIT 100"
243
- else:
244
- query = "SELECT Productname__c, Model__c, H_p__c, Stage__c, Current_Stock__c, soldstock__c, Price__c FROM Un_Billable__c LIMIT 100"
245
-
246
- response = sf.query_all(query)
247
- records = response.get("records", [])
248
-
249
- if not records:
250
- return "No data found in Salesforce.", None, None, None
251
-
252
- df = pd.DataFrame(records)
253
- df = df.drop(columns=['attributes'], errors='ignore')
254
-
255
- # Rename columns for better readability
256
- df.rename(columns={
257
- "Productname__c": "Product Name",
258
- "Model__c": "Model",
259
- "H_p__c": "H.P",
260
- "Stage__c": "Stage",
261
- "Current_Stocks__c": "Current Stocks",
262
- "Current_Stock__c": "Current Stocks",
263
- "soldstock__c": "Sold Stock",
264
- "Price__c": "Price"
265
- }, inplace=True)
266
-
267
- excel_path = "salesforce_data.xlsx"
268
- df.to_excel(excel_path, index=False)
269
-
270
- # Generate interactive vertical bar graph using Matplotlib
271
- fig, ax = plt.subplots(figsize=(12, 8))
272
- df.plot(kind='bar', x="Product Name", y="Current Stocks", ax=ax, legend=False)
273
- ax.set_title("Stock Distribution by Product Name")
274
- ax.set_xlabel("Product Name")
275
- ax.set_ylabel("Current Stocks")
276
- plt.xticks(rotation=45, ha="right", fontsize=10)
277
- plt.tight_layout()
278
- buffer = BytesIO()
279
- plt.savefig(buffer, format="png")
280
- buffer.seek(0)
281
- img = Image.open(buffer)
282
-
283
- return df, excel_path, img
284
- except Exception as e:
285
- return f"Error fetching data: {str(e)}", None, None, None
 
286
 
287
  # Gradio Interface
288
  def app():
289
- with gr.Blocks() as demo:
290
- with gr.Tab("πŸ“₯ OCR Processing"):
291
- with gr.Row():
292
- image_input = gr.Image(type="numpy", label="πŸ“„ Upload Image")
293
- mode_input = gr.Dropdown(label="πŸ“Œ Mode", choices=["Entry", "Exit"], value="Entry")
294
- entry_type_input = gr.Radio(label="πŸ“¦ Entry Type", choices=["Sales", "Non-Sales"], value="Sales")
295
- quantity_input = gr.Number(label="πŸ”’ Quantity", value=1, interactive=True)
296
- extract_button = gr.Button("Extract Text and Attributes")
297
- extracted_text_output = gr.Text(label="πŸ“ Extracted Image Data")
298
- editable_df_output = gr.Dataframe(label="✏️ Edit Attributes (Key-Value Pairs)", interactive=True)
299
- ok_button = gr.Button("OK")
300
- result_output = gr.Text(label="πŸš€ Result")
301
-
302
- with gr.Tab("πŸ“Š Salesforce Data"):
303
- data_type_input = gr.Dropdown(label="Select Data Type", choices=["Inventory", "Unbilling"], value="Inventory")
304
- pull_button = gr.Button("Pull Data from Salesforce")
305
- salesforce_data_output = gr.Dataframe(label="πŸ“Š Salesforce Data")
306
- excel_download_output = gr.File(label="πŸ“₯ Download Excel")
307
- graph_output = gr.Image(label="πŸ“ˆ Stock Distribution Graph")
308
-
309
- # Define button actions
310
- extract_button.click(
311
- fn=process_image,
312
- inputs=[image_input, mode_input, entry_type_input, quantity_input],
313
- outputs=[extracted_text_output, editable_df_output, result_output]
314
- )
315
- ok_button.click(
316
- fn=export_to_salesforce,
317
- inputs=[mode_input, entry_type_input, quantity_input, editable_df_output],
318
- outputs=[result_output]
319
- )
320
- pull_button.click(
321
- fn=pull_data_from_salesforce,
322
- inputs=[data_type_input],
323
- outputs=[salesforce_data_output, excel_download_output, graph_output]
324
- )
325
-
326
- return demo
327
 
328
  if __name__ == "__main__":
329
- app().launch(share=True)
 
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
80
  PRODUCT_NAMES = [
81
+ "Fusion", "Agroking", "CG commercial motors", "Jaguar", "Gaurav"
82
  ]
83
 
84
  # Salesforce credentials
 
91
 
92
  # Function to extract text using PaddleOCR
93
  def extract_text(image):
94
+ result = ocr.ocr(image)
95
+ extracted_text = []
96
+ for line in result[0]:
97
+ extracted_text.append(line[1][0])
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
 
105
+ for line in extracted_text.split("\n"):
106
+ match, score = process.extractOne(line, PRODUCT_NAMES)
107
+ if score > best_score:
108
+ best_match = match
109
+ best_score = score
110
 
111
+ return best_match if best_score >= 70 else None
112
 
113
  # Function to extract attributes and their values
114
  def extract_attributes(extracted_text):
115
+ attributes = {}
116
 
117
+ for readable_attr, sf_attr in ATTRIBUTE_MAPPING.items():
118
+ pattern = rf"{re.escape(readable_attr)}[:\-]?\s*(.+)"
119
+ match = re.search(pattern, extracted_text, re.IGNORECASE)
120
+ if match:
121
+ attributes[readable_attr] = match.group(1).strip()
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 pull structured data from Salesforce and display as a table
130
  def pull_data_from_salesforce(data_type):
131
+ try:
132
+ sf = Salesforce(
133
+ username=SALESFORCE_USERNAME,
134
+ password=SALESFORCE_PASSWORD,
135
+ security_token=SALESFORCE_SECURITY_TOKEN
136
+ )
137
+
138
+ if data_type == "Inventory":
139
+ query = "SELECT Productname__c, Model__c, H_p__c, Stage__c, Current_Stocks__c, soldstock__c, Price__c, Last_Modified_Date__c FROM Inventory_Management__c LIMIT 100"
140
+ else:
141
+ query = "SELECT Productname__c, Model__c, H_p__c, Stage__c, Current_Stock__c, soldstock__c, Price__c, Last_Modified_Date__c FROM Un_Billable__c LIMIT 100"
142
+
143
+ response = sf.query_all(query)
144
+ records = response.get("records", [])
145
+
146
+ if not records:
147
+ return "No data found in Salesforce.", None, None, None
148
+
149
+ df = pd.DataFrame(records)
150
+ df = df.drop(columns=['attributes'], errors='ignore')
151
+
152
+ # Rename columns for better readability
153
+ df.rename(columns={
154
+ "Productname__c": "Product Name",
155
+ "Model__c": "Model",
156
+ "H_p__c": "H.P",
157
+ "Stage__c": "Stage",
158
+ "Current_Stocks__c": "Current Stocks",
159
+ "Current_Stock__c": "Current Stocks",
160
+ "soldstock__c": "Sold Stock",
161
+ "Price__c": "Price",
162
+ "Last_Modified_Date__c": "Last Modified Date"
163
+ }, inplace=True)
164
+
165
+ excel_path = "salesforce_data.xlsx"
166
+ df.to_excel(excel_path, index=False)
167
+
168
+ # Generate interactive vertical bar graph using Matplotlib
169
+ fig, ax = plt.subplots(figsize=(12, 8))
170
+ df.plot(kind='bar', x="Product Name", y="Current Stocks", ax=ax, legend=False)
171
+ ax.set_title("Stock Distribution by Product Name")
172
+ ax.set_xlabel("Product Name")
173
+ ax.set_ylabel("Current Stocks")
174
+ plt.xticks(rotation=45, ha="right", fontsize=10)
175
+ plt.tight_layout()
176
+ buffer = BytesIO()
177
+ plt.savefig(buffer, format="png")
178
+ buffer.seek(0)
179
+ img = Image.open(buffer)
180
+
181
+ return df, excel_path, img
182
+ except Exception as e:
183
+ return f"Error fetching data: {str(e)}", None, None, None
184
 
185
  # Gradio Interface
186
  def app():
187
+ with gr.Blocks() as demo:
188
+ with gr.Tab("πŸ“₯ OCR Processing"):
189
+ with gr.Row():
190
+ image_input = gr.Image(type="numpy", label="πŸ“„ Upload Image")
191
+ mode_input = gr.Dropdown(label="πŸ“Œ Mode", choices=["Entry", "Exit"], value="Entry")
192
+ entry_type_input = gr.Radio(label="πŸ“¦ Entry Type", choices=["Sales", "Non-Sales"], value="Sales")
193
+ quantity_input = gr.Number(label="πŸ”’ Quantity", value=1, interactive=True)
194
+ extract_button = gr.Button("Extract Text and Attributes")
195
+ extracted_text_output = gr.Text(label="πŸ“ Extracted Image Data")
196
+ editable_df_output = gr.Dataframe(label="✏️ Edit Attributes (Key-Value Pairs)", interactive=True)
197
+ ok_button = gr.Button("OK")
198
+ result_output = gr.Text(label="πŸš€ Result")
199
+
200
+ with gr.Tab("πŸ“Š Salesforce Data"):
201
+ data_type_input = gr.Dropdown(label="Select Data Type", choices=["Inventory", "Unbilling"], value="Inventory")
202
+ pull_button = gr.Button("Pull Data from Salesforce")
203
+ salesforce_data_output = gr.Dataframe(label="πŸ“Š Salesforce Data")
204
+ excel_download_output = gr.File(label="πŸ“₯ Download Excel")
205
+ graph_output = gr.Image(label="πŸ“ˆ Stock Distribution Graph")
206
+
207
+ # Define button actions
208
+ extract_button.click(
209
+ fn=process_image,
210
+ inputs=[image_input, mode_input, entry_type_input, quantity_input],
211
+ outputs=[extracted_text_output, editable_df_output, result_output]
212
+ )
213
+ ok_button.click(
214
+ fn=export_to_salesforce,
215
+ inputs=[mode_input, entry_type_input, quantity_input, editable_df_output],
216
+ outputs=[result_output]
217
+ )
218
+ pull_button.click(
219
+ fn=pull_data_from_salesforce,
220
+ inputs=[data_type_input],
221
+ outputs=[salesforce_data_output, excel_download_output, graph_output]
222
+ )
223
+
224
+ return demo
225
 
226
  if __name__ == "__main__":
227
+ app().launch(share=True)