AIEmailAutomationUtility 0.0.24__py3-none-any.whl → 0.0.26__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- AIEmailAutomationUtility/Email_Classification.py +1 -1
- AIEmailAutomationUtility/Email_DocumentUploader.py +2 -1
- AIEmailAutomationUtility/Process_Category.py +60 -29
- {AIEmailAutomationUtility-0.0.24.dist-info → AIEmailAutomationUtility-0.0.26.dist-info}/METADATA +3 -3
- {AIEmailAutomationUtility-0.0.24.dist-info → AIEmailAutomationUtility-0.0.26.dist-info}/RECORD +8 -8
- {AIEmailAutomationUtility-0.0.24.dist-info → AIEmailAutomationUtility-0.0.26.dist-info}/LICENCE.txt +0 -0
- {AIEmailAutomationUtility-0.0.24.dist-info → AIEmailAutomationUtility-0.0.26.dist-info}/WHEEL +0 -0
- {AIEmailAutomationUtility-0.0.24.dist-info → AIEmailAutomationUtility-0.0.26.dist-info}/top_level.txt +0 -0
@@ -18,7 +18,7 @@ class Email_Classification:
|
|
18
18
|
logger.log(f"Final GPT message for detecting category::: {message}")
|
19
19
|
client = OpenAI(api_key=openai_api_key)
|
20
20
|
result = client.chat.completions.create(
|
21
|
-
model="gpt-4.1",
|
21
|
+
model="gpt-4.1-mini",
|
22
22
|
messages=message,
|
23
23
|
temperature=0,
|
24
24
|
max_tokens=1800,
|
@@ -9,11 +9,12 @@ from datetime import datetime
|
|
9
9
|
|
10
10
|
class Email_DocumentUploader:
|
11
11
|
def upload_document(self, upload_config, file_data):
|
12
|
+
document_type = upload_config['document_type']
|
12
13
|
# try:
|
13
14
|
logger.log("inside function" )
|
14
15
|
# Create temp directory if needed
|
15
16
|
today_date = datetime.today().strftime('%Y-%m-%d')
|
16
|
-
temp_dir = os.path.join(
|
17
|
+
temp_dir = os.path.join(document_type, today_date)
|
17
18
|
|
18
19
|
# Save file temporarily
|
19
20
|
file_path = os.path.join(temp_dir, file_data['filename'])
|
@@ -8,6 +8,7 @@ import loggerutility as logger
|
|
8
8
|
from datetime import datetime
|
9
9
|
from openai import OpenAI
|
10
10
|
from fpdf import FPDF
|
11
|
+
import mimetypes
|
11
12
|
import sqlite3
|
12
13
|
import openai
|
13
14
|
import json
|
@@ -102,24 +103,36 @@ class Process_Category:
|
|
102
103
|
logger.log(f"parameters ::: {parameters}")
|
103
104
|
|
104
105
|
# Download the attachment
|
105
|
-
fileName = self.download_attachment(msg)
|
106
|
-
|
107
|
-
|
108
|
-
today_date = datetime.today().strftime('%Y-%m-%d')
|
109
|
-
order_folder = os.path.join("ORDERS", today_date)
|
106
|
+
fileName, document_type = self.download_attachment(msg)
|
107
|
+
logger.log(f"fileName 107::: {fileName}")
|
108
|
+
logger.log(f"document_type 108::: {document_type}")
|
110
109
|
|
111
110
|
if responseMethod == "Upload_Document":
|
111
|
+
# Get today's date folder path
|
112
|
+
today_date = datetime.today().strftime('%Y-%m-%d')
|
113
|
+
order_folder = os.path.join(document_type, today_date)
|
114
|
+
|
112
115
|
email_upload_document = Email_DocumentUploader()
|
113
116
|
if len(fileName) != 0:
|
114
117
|
file_path = os.path.join(order_folder, fileName) # Correct file path
|
115
118
|
|
116
119
|
with open(file_path, "rb") as file:
|
120
|
+
parameters["DOCUMENT_TYPE"] = document_type
|
121
|
+
|
122
|
+
logger.log(f"Updated Parameters ::: {parameters}")
|
117
123
|
response_status, restAPI_Result = email_upload_document.email_document_upload(file, parameters)
|
118
124
|
logger.log(f"email_upload_document_response ::: {restAPI_Result}")
|
119
125
|
else:
|
126
|
+
document_type = "Order Email"
|
127
|
+
# Get today's date folder path
|
128
|
+
today_date = datetime.today().strftime('%Y-%m-%d')
|
129
|
+
order_folder = os.path.join(document_type, today_date)
|
130
|
+
|
131
|
+
parameters["DOCUMENT_TYPE"] = document_type
|
132
|
+
logger.log(f"Updated Parameters ::: {parameters}")
|
120
133
|
new_fileName = self.create_file_from_emailBody(email_body, sender_email_addr, parameters)
|
121
134
|
new_file_path = os.path.join(order_folder, new_fileName)
|
122
|
-
|
135
|
+
|
123
136
|
with open(new_file_path, "rb") as file:
|
124
137
|
response_status, restAPI_Result = email_upload_document.email_document_upload(file, parameters)
|
125
138
|
logger.log(f"email_upload_document_response ::: {restAPI_Result}")
|
@@ -144,13 +157,13 @@ class Process_Category:
|
|
144
157
|
# Step 4: Identify customer from email using AI
|
145
158
|
customer_data = self.identify_customer(email_body, subject, Model_Name, openai_api_key, geminiAI_APIKey, localAIURL, parameters["Customer_Assistant_Id"])
|
146
159
|
logger.log(f"Identified customer: {customer_data}")
|
147
|
-
logger.log(f'
|
160
|
+
logger.log(f'This is the customer data we are getting ::: {customer_data}')
|
148
161
|
# Extract customer code once
|
149
162
|
customer_code = customer_data.get("customer_code", "")
|
150
163
|
|
151
164
|
# Step 5: Identify product from email using AI
|
152
165
|
products = self.identify_products(email_body, subject, Model_Name, openai_api_key, geminiAI_APIKey, localAIURL, parameters["Product_Assistant_Id"])
|
153
|
-
logger.log(f'this is the products data we are getting'
|
166
|
+
logger.log(f'this is the products data we are getting ::: {products}')
|
154
167
|
|
155
168
|
db_connection = sqlite3.connect('/home/base/git/ai-email-automation/AI_Email/database/fetchprice.db')
|
156
169
|
for product in products:
|
@@ -219,7 +232,7 @@ class Process_Category:
|
|
219
232
|
|
220
233
|
if discount_result:
|
221
234
|
discount_percent = discount_result[0]
|
222
|
-
rate = raw_price * (1 - discount_percent / 100)
|
235
|
+
rate = raw_price * (1 - int(discount_percent) / 100)
|
223
236
|
rate = round(rate, 2)
|
224
237
|
found_rate = True
|
225
238
|
logger.log(f"[2] Discounted rate for '{make}' ({discount_percent}%) on price {raw_price}: {rate}")
|
@@ -241,7 +254,7 @@ class Process_Category:
|
|
241
254
|
if past_sales_result:
|
242
255
|
most_common_make, past_discount = past_sales_result
|
243
256
|
if isinstance(raw_price, (int, float)):
|
244
|
-
rate = raw_price * (1 - past_discount / 100)
|
257
|
+
rate = raw_price * (1 - int(past_discount) / 100)
|
245
258
|
rate = round(rate, 2)
|
246
259
|
found_rate = True
|
247
260
|
logger.log(f"[3] Fallback: Most used make '{most_common_make}' for customer '{customer_code}' got {past_discount}% discount. Rate: {rate}")
|
@@ -262,7 +275,7 @@ class Process_Category:
|
|
262
275
|
|
263
276
|
if general_discount_result:
|
264
277
|
general_discount_percent = general_discount_result[0]
|
265
|
-
rate = raw_price * (1 - general_discount_percent / 100)
|
278
|
+
rate = raw_price * (1 - int(general_discount_percent) / 100)
|
266
279
|
rate = round(rate, 2)
|
267
280
|
found_rate = True
|
268
281
|
logger.log(f"[4] General Discount for '{make}' ({general_discount_percent}%) on price {raw_price}: {rate}")
|
@@ -320,10 +333,11 @@ class Process_Category:
|
|
320
333
|
mail.expunge()
|
321
334
|
logger.log(f"Mail removed from inbox and added to '{LABEL}' label.")
|
322
335
|
|
323
|
-
|
336
|
+
current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
337
|
+
filename = f'{uid}{current_timestamp}'
|
324
338
|
logger.log(f"the file name is ---------------- {filename}")
|
325
339
|
self.store_email_details_to_csv(
|
326
|
-
email_id=uid,
|
340
|
+
email_id=f'{uid}{current_timestamp}',
|
327
341
|
to_email=parseaddr(to_email_addr)[1],
|
328
342
|
from_email=parseaddr(sender_email_addr)[1],
|
329
343
|
cc_email=parseaddr(cc_email_addr)[1] if cc_email_addr else '',
|
@@ -334,11 +348,11 @@ class Process_Category:
|
|
334
348
|
filename=filename,
|
335
349
|
user_id=user_id,
|
336
350
|
status=csv_data_status,
|
337
|
-
response=csv_data_response
|
338
|
-
|
351
|
+
response=csv_data_response,
|
352
|
+
current_timestamp=current_timestamp
|
339
353
|
)
|
340
354
|
self.store_email_as_eml(
|
341
|
-
uid=uid,
|
355
|
+
uid=f'{uid}{current_timestamp}',
|
342
356
|
from_email=sender_email_addr,
|
343
357
|
to_email=to_email_addr,
|
344
358
|
cc_email=cc_email_addr,
|
@@ -363,21 +377,37 @@ class Process_Category:
|
|
363
377
|
return responseMethod, parameters
|
364
378
|
|
365
379
|
def download_attachment(self, msg):
|
366
|
-
base_folder = "ORDERS" # Main folder for storing orders
|
367
|
-
today_date = datetime.today().strftime('%Y-%m-%d') # Format: YYYY-MM-DD
|
368
|
-
date_folder = os.path.join(base_folder, today_date) # Path: ORDERS/YYYY-MM-DD
|
369
|
-
|
370
|
-
# Ensure folders exist
|
371
|
-
os.makedirs(date_folder, exist_ok=True)
|
372
380
|
|
373
381
|
filename = ""
|
382
|
+
mime_type = ""
|
383
|
+
document_type = "Orders"
|
374
384
|
|
375
385
|
for part in msg.walk():
|
376
386
|
if part.get_content_maintype() == 'multipart':
|
377
387
|
continue
|
378
388
|
if part.get('Content-Disposition') is None:
|
379
389
|
continue
|
390
|
+
|
380
391
|
filename = part.get_filename()
|
392
|
+
mime_type = part.get_content_type().lower()
|
393
|
+
|
394
|
+
if "pdf" in mime_type:
|
395
|
+
document_type = "Orders"
|
396
|
+
elif "msword" in mime_type or "wordprocessingml" in mime_type or filename.lower().endswith(".docx"):
|
397
|
+
document_type = "Order Excel"
|
398
|
+
elif "excel" in mime_type or "spreadsheetml" in mime_type or filename.lower().endswith((".xls", ".xlsx")):
|
399
|
+
document_type = "Order Excel"
|
400
|
+
elif "csv" in mime_type or filename.lower().endswith(".csv"):
|
401
|
+
document_type = "Order Excel"
|
402
|
+
elif "plain" in mime_type or filename.lower().endswith(".txt"):
|
403
|
+
document_type = "Order Email"
|
404
|
+
elif "rtf" in mime_type or filename.lower().endswith(".rtf"):
|
405
|
+
document_type = "Order Excel"
|
406
|
+
|
407
|
+
today_date = datetime.today().strftime('%Y-%m-%d') # Format: YYYY-MM-DD
|
408
|
+
date_folder = os.path.join(document_type, today_date) # Path: ORDERS/YYYY-MM-DD
|
409
|
+
os.makedirs(date_folder, exist_ok=True)
|
410
|
+
|
381
411
|
if filename:
|
382
412
|
filepath = os.path.join(date_folder, filename) # Save inside date-wise folder
|
383
413
|
|
@@ -386,10 +416,10 @@ class Process_Category:
|
|
386
416
|
logger.log(f"\nAttachment saved: '{filepath}'")
|
387
417
|
else:
|
388
418
|
logger.log("\nNo Attachment found.")
|
389
|
-
return filename
|
419
|
+
return filename, document_type
|
390
420
|
|
391
421
|
def create_file_from_emailBody(self, text, sender_email_addr, parameters):
|
392
|
-
base_folder =
|
422
|
+
base_folder = parameters.get('DOCUMENT_TYPE', '')
|
393
423
|
today_date = datetime.today().strftime('%Y-%m-%d') # Format: YYYY-MM-DD
|
394
424
|
order_folder = os.path.join(base_folder, today_date)
|
395
425
|
|
@@ -720,7 +750,7 @@ class Process_Category:
|
|
720
750
|
logger.log(f"Error with Gemini AI detection/generation: {str(e)}")
|
721
751
|
return {"success": "Failed", "message": f"Error with Gemini AI detection/generation: {str(e)}"}
|
722
752
|
|
723
|
-
def store_email_details_to_csv(self, email_id, to_email, from_email, cc_email, subject, body, email_type, action_performed, filename, user_id,status,response):
|
753
|
+
def store_email_details_to_csv(self, email_id, to_email, from_email, cc_email, subject, body, email_type, action_performed, filename, user_id,status,response,current_timestamp):
|
724
754
|
"""
|
725
755
|
Stores the extracted email details to a CSV file inside 'Mail_log/mail_log_user_id' folder
|
726
756
|
with the name user_id.csv.
|
@@ -734,9 +764,10 @@ class Process_Category:
|
|
734
764
|
user_folder = os.path.join(log_folder, f"{user_id}")
|
735
765
|
os.makedirs(user_folder, exist_ok=True)
|
736
766
|
|
767
|
+
filename = filename.lstrip()
|
768
|
+
logger.log(f"filename ::: [{filename}]")
|
737
769
|
full_csv_path = os.path.join(user_folder, f"{filename}.csv")
|
738
|
-
|
739
|
-
current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
770
|
+
logger.log(f"full_csv_path ::: {full_csv_path}")
|
740
771
|
|
741
772
|
# Prepare the data to write
|
742
773
|
csv_data = [{
|
@@ -786,6 +817,7 @@ class Process_Category:
|
|
786
817
|
user_folder = os.path.join(archive_folder, f"{user_id}")
|
787
818
|
os.makedirs(user_folder, exist_ok=True)
|
788
819
|
|
820
|
+
filename = filename.lstrip()
|
789
821
|
# Define the full path for the CSV file (csv_filename.csv inside the mail_log_user_id folder)
|
790
822
|
eml_file_path = os.path.join(user_folder, f"{filename}.eml")
|
791
823
|
|
@@ -820,5 +852,4 @@ class Process_Category:
|
|
820
852
|
if user_id:
|
821
853
|
return user_id.value
|
822
854
|
return None
|
823
|
-
|
824
|
-
|
855
|
+
|
{AIEmailAutomationUtility-0.0.24.dist-info → AIEmailAutomationUtility-0.0.26.dist-info}/METADATA
RENAMED
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: AIEmailAutomationUtility
|
3
|
-
Version: 0.0.
|
4
|
-
Summary:
|
3
|
+
Version: 0.0.26
|
4
|
+
Summary: Resolve the issue of email and excel file uploading on orders
|
5
5
|
Author: Proteus Technology PVT. LTD.
|
6
6
|
Author-email: <apps@baseinformation.com>
|
7
7
|
Keywords: python,first package
|
@@ -13,4 +13,4 @@ Classifier: Operating System :: MacOS :: MacOS X
|
|
13
13
|
Classifier: Operating System :: Microsoft :: Windows
|
14
14
|
License-File: LICENCE.txt
|
15
15
|
|
16
|
-
|
16
|
+
Resolve the issue of email and excel file uploading on orders
|
{AIEmailAutomationUtility-0.0.24.dist-info → AIEmailAutomationUtility-0.0.26.dist-info}/RECORD
RENAMED
@@ -1,15 +1,15 @@
|
|
1
1
|
AIEmailAutomationUtility/EmailReplyAssistant.py,sha256=oRobM6C1AwiRA3lQ2Sh51m-FaH2PpbUEidbkOG7O9Ww,6339
|
2
|
-
AIEmailAutomationUtility/Email_Classification.py,sha256=
|
3
|
-
AIEmailAutomationUtility/Email_DocumentUploader.py,sha256=
|
2
|
+
AIEmailAutomationUtility/Email_Classification.py,sha256=Ar0g4Ff8HOT7xICktd3nP_C_vCyeY-xCpUjVCVRWAyc,9417
|
3
|
+
AIEmailAutomationUtility/Email_DocumentUploader.py,sha256=YJu4tuTHr0K-5vuds9gZfj-Hwsgm4MuAOP39Lmu_t98,3219
|
4
4
|
AIEmailAutomationUtility/Email_Draft.py,sha256=DcyBeDaE8CReKHnHxLiz-o2tDxuUgwy91c4k0qhQbVw,7749
|
5
5
|
AIEmailAutomationUtility/Email_Read.py,sha256=UJDHdsr5RN_GG5OsOvUKbKziaw0a-kR3TT0iUv0oRmI,27795
|
6
6
|
AIEmailAutomationUtility/Email_Upload_Document.py,sha256=3bdkxfDlwoeRp-46KPw2Gs1dqBhEIoA1yE5GCudpdV8,1320
|
7
|
-
AIEmailAutomationUtility/Process_Category.py,sha256=
|
7
|
+
AIEmailAutomationUtility/Process_Category.py,sha256=EojfyGAN7U6NIBqinikJIauEgzz-ZQhHpzcjNr1No9M,41234
|
8
8
|
AIEmailAutomationUtility/Save_Draft.py,sha256=yzLgFN14I_lXE6qL0I3tKNduvcnWdbsY9i2mKdTtio4,5348
|
9
9
|
AIEmailAutomationUtility/Save_Transaction.py,sha256=Gg1w6hhzHmEFjsuzYvkq-3-EsWReetjLHsYSv5YIGgM,3816
|
10
10
|
AIEmailAutomationUtility/__init__.py,sha256=Jad3IdPRsVMeLqEEh-FbCrc1lE2tzJO2DTG5Hgmxh5g,391
|
11
|
-
AIEmailAutomationUtility-0.0.
|
12
|
-
AIEmailAutomationUtility-0.0.
|
13
|
-
AIEmailAutomationUtility-0.0.
|
14
|
-
AIEmailAutomationUtility-0.0.
|
15
|
-
AIEmailAutomationUtility-0.0.
|
11
|
+
AIEmailAutomationUtility-0.0.26.dist-info/LICENCE.txt,sha256=2qX9IkEUBx0VJp1Vh9O2dsRwE-IpYId0lXDyn7OVsJ8,1073
|
12
|
+
AIEmailAutomationUtility-0.0.26.dist-info/METADATA,sha256=8n0W1uGzS7F2kkzHYPYi32axicmcCOapZ-LK8ql7fKs,623
|
13
|
+
AIEmailAutomationUtility-0.0.26.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
14
|
+
AIEmailAutomationUtility-0.0.26.dist-info/top_level.txt,sha256=3jTWrTUblVkaP7mpwY2UBSnrlfot5Ykpfsehyke-Uzw,25
|
15
|
+
AIEmailAutomationUtility-0.0.26.dist-info/RECORD,,
|
{AIEmailAutomationUtility-0.0.24.dist-info → AIEmailAutomationUtility-0.0.26.dist-info}/LICENCE.txt
RENAMED
File without changes
|
{AIEmailAutomationUtility-0.0.24.dist-info → AIEmailAutomationUtility-0.0.26.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|