leadingbridge commited on
Commit
39ee075
·
verified ·
1 Parent(s): 96612f3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +210 -0
app.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ from datetime import datetime
4
+ import pytz
5
+ import openpyxl
6
+
7
+ def process_file(file):
8
+ file_name = file.name.lower()
9
+ try:
10
+ if file_name.endswith('.csv'):
11
+ # CSV files do not have multiple sheets.
12
+ return "Error: Please upload an Excel file with a UPS sheet.", None
13
+ elif file_name.endswith(('.xls', '.xlsx', '.xlsm')):
14
+ # Only read data from the "UPS" sheet.
15
+ df = pd.read_excel(file.name, sheet_name="UPS")
16
+ else:
17
+ return f"Unsupported file format: {file_name}", None
18
+ except Exception as e:
19
+ return f"Error reading file: {str(e)}", None
20
+
21
+ # Define the new header list as specified.
22
+ output_headers = [
23
+ "Contact Name", "Company or Name", "Country", "Address 1", "Address 2", "Address 3",
24
+ "City", "State/Prov/Other", "Postal Code", "Telephone", "Ext", "Residential Ind",
25
+ "Consignee Email", "Packaging Type", "Customs Value", "Weight", "Length", "Width",
26
+ "Height", "Unit of Measure", "Description of Goods", "Documents of No Commercial Value",
27
+ "GNIFC", "Pkg Decl Value", "Service", "Delivery Confirm", "Shipper Release", "Ret of Documents",
28
+ "Saturday Deliver", "Carbon Neutral", "Large Package", "Addl handling", "Reference 1",
29
+ "Reference 2", "Reference 3", "QV Notif 1-Addr", "QV Notif 1-Ship", "QV Notif 1-Excp",
30
+ "QV Notif 1-Delv", "QV Notif 2-Addr", "QV Notif 2-Ship", "QV Notif 2-Excp", "QV Notif 2-Delv",
31
+ "QV Notif 3-Addr", "QV Notif 3-Ship", "QV Notif 3-Excp", "QV Notif 3-Delv", "QV Notif 4-Addr",
32
+ "QV Notif 4-Ship", "QV Notif 4-Excp", "QV Notif 4-Delv", "QV Notif 5-Addr", "QV Notif 5-Ship",
33
+ "QV Notif 5-Excp", "QV Notif 5-Delv", "QV Notif Msg", "QV Failure Addr", "UPS Premium Care",
34
+ "ADL Location ID", "ADL Media Type", "ADL Language", "ADL Notification Addr", "ADL Failure Addr",
35
+ "ADL COD Value", "ADL Deliver to Addressee", "ADL Shipper Media Type", "ADL Shipper Language",
36
+ "ADL Shipper Notification Addr", "ADL Direct Delivery Only", "Electronic Package Release Authentication",
37
+ "Lithium Ion Alone", "Lithium Ion In Equipment", "Lithium Ion With_Equipment", "Lithium Metal Alone",
38
+ "Lithium Metal In Equipment", "Lithium Metal With Equipment", "Weekend Commercial Delivery",
39
+ "Dry Ice Weight", "Merchandise Description", "UPS SurePost®Limited Quantity/Lithium Battery"
40
+ ]
41
+
42
+ # Create an output DataFrame with the new header list.
43
+ output_df = pd.DataFrame("", index=range(len(df)), columns=output_headers)
44
+
45
+ # Mapping from input file to output based on provided rules:
46
+ # 1. Shipping First Name + Shipping Last Name + Shipping Company -> Contact Name and Company or Name
47
+ if {"Shipping First Name", "Shipping Last Name", "Shipping Company"}.issubset(df.columns):
48
+ first_name = df["Shipping First Name"].fillna("").astype(str).str.strip()
49
+ last_name = df["Shipping Last Name"].fillna("").astype(str).str.strip()
50
+ company = df["Shipping Company"].fillna("").astype(str).str.strip()
51
+ combined = (first_name + " " + last_name + " " + company).str.strip()
52
+ output_df["Contact Name"] = combined
53
+ output_df["Company or Name"] = combined
54
+
55
+ # 2. Shipping Country Code -> Country
56
+ if "Shipping Country Code" in df.columns:
57
+ output_df["Country"] = df["Shipping Country Code"].fillna("").astype(str).str.strip()
58
+
59
+ # 3. Shipping Address 1 -> Address 1
60
+ if "Shipping Address 1" in df.columns:
61
+ output_df["Address 1"] = df["Shipping Address 1"].fillna("").astype(str).str.strip()
62
+
63
+ # 4. Shipping Address 2 -> Address 2
64
+ if "Shipping Address 2" in df.columns:
65
+ output_df["Address 2"] = df["Shipping Address 2"].fillna("").astype(str).str.strip()
66
+
67
+ # 5. Shipping City -> City
68
+ if "Shipping City" in df.columns:
69
+ output_df["City"] = df["Shipping City"].fillna("").astype(str).str.strip()
70
+
71
+ # 6. Shipping Province -> State/Prov/Other
72
+ if "Shipping Province" in df.columns:
73
+ output_df["State/Prov/Other"] = df["Shipping Province"].fillna("").astype(str).str.strip()
74
+
75
+ # Convert full US state names to their 2-letter abbreviations if applicable.
76
+ us_states = {
77
+ 'alabama': 'AL',
78
+ 'alaska': 'AK',
79
+ 'arizona': 'AZ',
80
+ 'arkansas': 'AR',
81
+ 'california': 'CA',
82
+ 'colorado': 'CO',
83
+ 'connecticut': 'CT',
84
+ 'delaware': 'DE',
85
+ 'florida': 'FL',
86
+ 'georgia': 'GA',
87
+ 'hawaii': 'HI',
88
+ 'idaho': 'ID',
89
+ 'illinois': 'IL',
90
+ 'indiana': 'IN',
91
+ 'iowa': 'IA',
92
+ 'kansas': 'KS',
93
+ 'kentucky': 'KY',
94
+ 'louisiana': 'LA',
95
+ 'maine': 'ME',
96
+ 'maryland': 'MD',
97
+ 'massachusetts': 'MA',
98
+ 'michigan': 'MI',
99
+ 'minnesota': 'MN',
100
+ 'mississippi': 'MS',
101
+ 'missouri': 'MO',
102
+ 'montana': 'MT',
103
+ 'nebraska': 'NE',
104
+ 'nevada': 'NV',
105
+ 'new hampshire': 'NH',
106
+ 'new jersey': 'NJ',
107
+ 'new mexico': 'NM',
108
+ 'new york': 'NY',
109
+ 'north carolina': 'NC',
110
+ 'north dakota': 'ND',
111
+ 'ohio': 'OH',
112
+ 'oklahoma': 'OK',
113
+ 'oregon': 'OR',
114
+ 'pennsylvania': 'PA',
115
+ 'rhode island': 'RI',
116
+ 'south carolina': 'SC',
117
+ 'south dakota': 'SD',
118
+ 'tennessee': 'TN',
119
+ 'texas': 'TX',
120
+ 'utah': 'UT',
121
+ 'vermont': 'VT',
122
+ 'virginia': 'VA',
123
+ 'washington': 'WA',
124
+ 'west virginia': 'WV',
125
+ 'wisconsin': 'WI',
126
+ 'wyoming': 'WY'
127
+ }
128
+
129
+ def convert_state(state):
130
+ if state:
131
+ state_lower = state.lower()
132
+ return us_states.get(state_lower, state)
133
+ return state
134
+
135
+ output_df["State/Prov/Other"] = output_df["State/Prov/Other"].apply(convert_state)
136
+
137
+ # 7. Shipping ZIP -> Postal Code
138
+ if "Shipping ZIP" in df.columns:
139
+ output_df["Postal Code"] = df["Shipping ZIP"].fillna("").astype(str).str.strip()
140
+
141
+ # 8. Shipping Address Phone -> Telephone
142
+ if "Shipping Address Phone" in df.columns:
143
+ output_df["Telephone"] = df["Shipping Address Phone"].fillna("").astype(str).str.strip()
144
+
145
+ # 9. Email -> Consignee Email
146
+ if "Email" in df.columns:
147
+ output_df["Consignee Email"] = df["Email"].fillna("").astype(str).str.strip()
148
+
149
+ # 10. Total Weight -> Weight (divide by 1000)
150
+ if "Total Weight" in df.columns:
151
+ def convert_weight(x):
152
+ try:
153
+ if pd.isna(x) or x == "":
154
+ return ""
155
+ return float(x) / 1000
156
+ except:
157
+ return ""
158
+ output_df["Weight"] = df["Total Weight"].apply(convert_weight)
159
+
160
+ # Fixed value mapping (applied for rows with data in Contact Name)
161
+ mask = output_df["Contact Name"].notna() & (output_df["Contact Name"] != "")
162
+ output_df.loc[mask, "Packaging Type"] = "2"
163
+ output_df.loc[mask, "Unit of Measure"] = "KG"
164
+ output_df.loc[mask, "Description of Goods"] = "Eyes Beauty Color Cosmetics"
165
+ output_df.loc[mask, "Service"] = "7"
166
+
167
+ # Delete duplicate rows based on "Contact Name", keeping the first occurrence.
168
+ output_df = output_df.drop_duplicates(subset=["Contact Name"], keep="first")
169
+
170
+ # Generate the output file name using the current Hong Kong date.
171
+ hk_timezone = pytz.timezone("Asia/Hong_Kong")
172
+ current_date_hk = datetime.now(hk_timezone).strftime("%y%m%d")
173
+ output_file_name = f"UPS {current_date_hk}.csv"
174
+
175
+ # Save the output DataFrame to a CSV file without the header.
176
+ output_df.to_csv(output_file_name, index=False, header=False)
177
+
178
+ return output_df, output_file_name
179
+
180
+ with gr.Blocks(title="Shipping - UPS") as demo:
181
+ gr.Markdown("# Shipping - UPS")
182
+ with gr.Row():
183
+ file_input = gr.File(label="Upload Excel File with a UPS sheet")
184
+ process_button = gr.Button("Process Data")
185
+ with gr.Row():
186
+ output_data = gr.DataFrame()
187
+ output_file_component = gr.File(label="Download Processed File")
188
+
189
+ process_button.click(fn=process_file, inputs=[file_input], outputs=[output_data, output_file_component])
190
+
191
+ # Updated hyperlink block with separate sections for Shipping Tools and Administration Tools.
192
+ gr.HTML(
193
+ """
194
+ <div style="text-align: center; font-size: 16px; margin-top: 20px;">
195
+ <h3>Shipping Tools</h3>
196
+ <a href="https://huggingface.co/spaces/leadingbridge/shipping-dhl-e-commerce">DHL</a> |
197
+ <a href="https://huggingface.co/spaces/leadingbridge/shipping-ec-ship">EC-Ship</a> |
198
+ <a href="https://huggingface.co/spaces/leadingbridge/shipping-fedex">Fedex</a> |
199
+ <a href="https://huggingface.co/spaces/leadingbridge/shipping-UPS">UPS</a>
200
+ </div>
201
+ <div style="text-align: center; font-size: 16px; margin-top: 20px;">
202
+ <h3>Administration Tools</h3>
203
+ <a href="https://huggingface.co/spaces/leadingbridge/email-template">Email Template</a> |
204
+ <a href="https://huggingface.co/spaces/leadingbridge/product-feed">Google Merchant</a> |
205
+ <a href="https://huggingface.co/spaces/leadingbridge/tss-order">Order Processing</a>
206
+ </div>
207
+ """
208
+ )
209
+
210
+ demo.launch()