Ajay98 commited on
Commit
7e60323
·
verified ·
1 Parent(s): 41f6ff4

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +227 -0
app.py ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from paddleocr import PaddleOCR
3
+ from PIL import Image, ImageEnhance
4
+ import gradio as gr
5
+ import pandas as pd
6
+ import re
7
+ from simple_salesforce import Salesforce
8
+
9
+ # Attributes to match in the image
10
+ ATTRIBUTES = [
11
+ "Product name", "Colour", "Motortype", "Frequency", "Grossweight", "Ratio",
12
+ "MotorFrame", "Model", "Speed", "Quantity", "Voltage", "Material", "Type",
13
+ "Horsepower", "Consignee", "LOT", "Stage", "Outlet", "Serialnumber", "HeadSize",
14
+ "Deliverysize", "Phase", "Size", "MRP", "Usebefore", "Height",
15
+ "MaximumDischarge Flow", "DischargeRange", "Assembledby", "Manufacturedate",
16
+ "Companyname", "Customercarenumber", "SellerAddress", "Selleremail", "GSTIN",
17
+ "Totalamount", "Paymentstatus", "Paymentmethod", "Invoicedate", "Warranty",
18
+ "Brand", "Motorhorsepower", "Power", "Motorphase", "Enginetype", "Tankcapacity",
19
+ "Head", "Usage/Application", "Volts", "Hertz", "Frame", "Mounting", "Tollfreenumber",
20
+ "Pipesize", "Manufacturer", "Office", "Size", "Ratio", "SRnumber", "volts", "weight",
21
+ "frame", "TypeOfEndUse", "Model Name", "cooling method",
22
+ ]
23
+
24
+ # Salesforce credentials
25
+ SALESFORCE_USERNAME = "venkatramana@sandbox.com"
26
+ SALESFORCE_PASSWORD = "Venkat12345@"
27
+ SALESFORCE_SECURITY_TOKEN = "GhcJJmjBEefdnukJoz4CAQlR"
28
+
29
+ # Initialize PaddleOCR
30
+ ocr = PaddleOCR(use_angle_cls=True, lang='en')
31
+
32
+ # Environment variable for the Excel file path
33
+ EXCEL_FILE_PATH = os.getenv("EXCEL_FILE_PATH", "DataStorage.xlsx")
34
+
35
+ # Function to extract text using PaddleOCR
36
+ def extract_text(image):
37
+ result = ocr.ocr(image)
38
+ extracted_text = []
39
+ for line in result[0]:
40
+ extracted_text.append(line[1][0])
41
+ return "\n".join(extracted_text)
42
+
43
+ # Function to find attributes and their values
44
+ def find_attributes(text):
45
+ structured_data = {}
46
+ for attr in ATTRIBUTES:
47
+ pattern = rf"{re.escape(attr)}[:\-]?\s*(.+)" # Match the attribute and capture its value
48
+ match = re.search(pattern, text, re.IGNORECASE)
49
+ if match:
50
+ structured_data[attr] = match.group(1).strip()
51
+ return structured_data
52
+
53
+ # Function to sanitize numeric values
54
+ def sanitize_numeric(value):
55
+ try:
56
+ # If the value is already numeric, return it as-is
57
+ if isinstance(value, (int, float)):
58
+ return value
59
+ if '/' in value: # Handle fraction strings like "1/2"
60
+ numerator, denominator = value.split('/')
61
+ return float(numerator) / float(denominator)
62
+ sanitized = re.sub(r'[^\d\.\-]', '', value) # Remove non-numeric characters
63
+ return float(sanitized) if sanitized else None
64
+ except (ValueError, ZeroDivisionError):
65
+ return None
66
+
67
+ # Function to save structured data to the constant Excel file
68
+ def save_to_excel(data):
69
+ if not data:
70
+ return "No data to save."
71
+
72
+ if not os.path.exists(EXCEL_FILE_PATH):
73
+ df = pd.DataFrame([data])
74
+ df.to_excel(EXCEL_FILE_PATH, index=False, engine="openpyxl")
75
+ else:
76
+ existing_df = pd.read_excel(EXCEL_FILE_PATH, engine="openpyxl")
77
+ new_data_df = pd.DataFrame([data])
78
+ updated_df = pd.concat([existing_df, new_data_df], ignore_index=True)
79
+ updated_df.to_excel(EXCEL_FILE_PATH, index=False, engine="openpyxl")
80
+
81
+ return EXCEL_FILE_PATH
82
+
83
+ # Function to update stock in Inventory Management
84
+ def update_stock_in_inventory_management(data, quantity):
85
+ try:
86
+ # Initialize Salesforce connection
87
+ sf = Salesforce(
88
+ username=SALESFORCE_USERNAME,
89
+ password=SALESFORCE_PASSWORD,
90
+ security_token=SALESFORCE_SECURITY_TOKEN,
91
+ )
92
+
93
+ # Query the existing stock for the product
94
+ product_name = data.get("Product name")
95
+ query = f"SELECT Id, Current_Stocks__c FROM Inventory_Management__c WHERE Product_Name__c = '{product_name}' LIMIT 1"
96
+ result = sf.query(query)
97
+
98
+ if result["totalSize"] == 0:
99
+ return f"Product '{product_name}' not found in Inventory Management."
100
+
101
+ product_id = result["records"][0]["Id"]
102
+ current_stock = result["records"][0].get("Current_Stocks__c", 0)
103
+
104
+ # Ensure current_stock is not None
105
+ current_stock = current_stock or 0
106
+
107
+ # Deduct stock by the quantity
108
+ updated_stock = max(0, current_stock - quantity) # Ensure stock doesn't go negative
109
+
110
+ # Update the stock in Salesforce
111
+ sf.Inventory_Management__c.update(product_id, {"Current_Stocks__c": updated_stock})
112
+
113
+ return f"Stock updated successfully. {quantity} units deducted from '{product_name}'. Remaining stock: {updated_stock}."
114
+ except Exception as e:
115
+ return f"Error updating stock in Inventory Management: {str(e)}"
116
+
117
+ # Function to add stock in VENKATA_RAMANA_MOTORS__c
118
+ def add_stock_to_venkataramana(data, quantity):
119
+ try:
120
+ # Initialize Salesforce connection
121
+ sf = Salesforce(
122
+ username=SALESFORCE_USERNAME,
123
+ password=SALESFORCE_PASSWORD,
124
+ security_token=SALESFORCE_SECURITY_TOKEN,
125
+ )
126
+
127
+ # Target Salesforce object
128
+ object_name = "VENKATA_RAMANA_MOTORS__c"
129
+ sf_object = sf.__getattr__(object_name)
130
+
131
+ # Fetch valid field names from the object schema
132
+ schema = sf_object.describe()
133
+ valid_fields = {field["name"] for field in schema["fields"]}
134
+
135
+ # Prepare the record with valid fields
136
+ record = {
137
+ "Productname__c": data.get("Product name"),
138
+ "Quantity__c": sanitize_numeric(quantity),
139
+ }
140
+
141
+ # Filter record to include only valid fields
142
+ filtered_record = {k: v for k, v in record.items() if k in valid_fields and v is not None}
143
+
144
+ # Add stock to Salesforce
145
+ sf_object.create(filtered_record)
146
+ return f"Data successfully added to {object_name}."
147
+ except Exception as e:
148
+ return f"Error adding stock to VENKATA_RAMANA_MOTORS__c: {str(e)}"
149
+
150
+ # Function to process image for the entry interface
151
+ def process_entry_image(image, quantity):
152
+ try:
153
+ extracted_text = extract_text(image)
154
+ attributes = find_attributes(extracted_text)
155
+ attributes["Quantity"] = quantity # Include quantity in attributes
156
+
157
+ if attributes:
158
+ numbered_output = "\n".join(
159
+ [f"{i + 1}. {key}: {value}" for i, (key, value) in enumerate(attributes.items())]
160
+ )
161
+ # Save to Excel
162
+ file_path = save_to_excel(attributes)
163
+
164
+ # Add stock to VENKATA_RAMANA_MOTORS__c
165
+ salesforce_message = add_stock_to_venkataramana(attributes, quantity)
166
+
167
+ return f"{numbered_output}\n\n{salesforce_message}", file_path
168
+ else:
169
+ return "No attributes found with values in the image.", None
170
+ except Exception as e:
171
+ return f"Error during processing: {str(e)}", None
172
+
173
+ # Function to process image for the exit interface
174
+ def process_exit_image(image, quantity):
175
+ try:
176
+ extracted_text = extract_text(image)
177
+ attributes = find_attributes(extracted_text)
178
+ attributes["Quantity"] = quantity # Include quantity in attributes
179
+
180
+ if attributes:
181
+ numbered_output = "\n".join(
182
+ [f"{i + 1}. {key}: {value}" for i, (key, value) in enumerate(attributes.items())]
183
+ )
184
+ # Save to Excel
185
+ file_path = save_to_excel(attributes)
186
+
187
+ # Deduct stock in Inventory Management
188
+ stock_message = update_stock_in_inventory_management(attributes, quantity)
189
+
190
+ return f"{numbered_output}\n\n{stock_message}", file_path
191
+ else:
192
+ return "No attributes found with values in the image.", None
193
+ except Exception as e:
194
+ return f"Error during processing: {str(e)}", None
195
+
196
+ # Gradio Interfaces
197
+ entry_interface = gr.Interface(
198
+ fn=process_entry_image,
199
+ inputs=[
200
+ gr.Image(type="numpy"),
201
+ gr.Number(label="Quantity", value=1, interactive=True),
202
+ ],
203
+ outputs=[
204
+ gr.Text(label="Image Data Viewer"),
205
+ gr.File(label="Data Storage Manager")
206
+ ],
207
+ title="Entry Interface - VENKATARAMANA MOTORS",
208
+ description="Process images and add stock to VENKATA_RAMANA_MOTORS__c."
209
+ )
210
+
211
+ exit_interface = gr.Interface(
212
+ fn=process_exit_image,
213
+ inputs=[
214
+ gr.Image(type="numpy"),
215
+ gr.Number(label="Quantity", value=1, interactive=True),
216
+ ],
217
+ outputs=[
218
+ gr.Text(label="Image Data Viewer"),
219
+ gr.File(label="Data Storage Manager")
220
+ ],
221
+ title="Exit Interface - VENKATARAMANA MOTORS",
222
+ description="Process images and deduct stock from Inventory Management."
223
+ )
224
+
225
+ if __name__ == "__main__":
226
+ gr.TabbedInterface([entry_interface, exit_interface], ["Entry", "Exit"]).launch(share=True)
227
+