Create app,py
Browse files
app,py
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import pandas as pd
|
3 |
+
from datetime import datetime
|
4 |
+
import pytz
|
5 |
+
|
6 |
+
# Updated Gradio app for YunExpress with new header mappings
|
7 |
+
def process_file(file):
|
8 |
+
file_name = file.name.lower()
|
9 |
+
try:
|
10 |
+
if file_name.endswith(('.xls', '.xlsx', '.xlsm')):
|
11 |
+
# Read data from the "DHL" sheet
|
12 |
+
df = pd.read_excel(file.name, sheet_name="DHL")
|
13 |
+
else:
|
14 |
+
return f"Unsupported file format: {file_name}", None
|
15 |
+
except Exception as e:
|
16 |
+
return f"Error reading file: {e}", None
|
17 |
+
|
18 |
+
# New output headers as requested
|
19 |
+
output_headers = [
|
20 |
+
"CustomerOrderNo.", "RoutingCode", "Trackingnumber", "AdditionalServices",
|
21 |
+
"ShipmentProtectionPlusService", "SignatureService", "VatNumber", "EoriNumber",
|
22 |
+
"IossCode", "CountryCode", "Name", "CertificateCode", "Company", "Street", "City",
|
23 |
+
"Province/State", "ZipCode", "phone", "HouseNumber", "Email", "PackageNumber",
|
24 |
+
"PackageWeight", "SenderFiastName", "SenderCompany", "SenderStreet", "SenderCity",
|
25 |
+
"SenderProvince", "SenderPostalCode", "SenderCountry", "SenderTelephone", "SenderEmail",
|
26 |
+
"SenderUSCI", "PlatformName", "PlatformProvince", "PlatformAddress", "PlatformPostalCode",
|
27 |
+
"PlatformPhoneNumber", "PlatformEmail", "SalesPlatformLink", "CurrencyCode", "SKU1",
|
28 |
+
"ItemDescription1", "ForeignItemDescription1", "DeclaredQuantity1", "UnitPrice1",
|
29 |
+
"UnitWeight1", "HsCode1", "Remarks1", "SalesLink1", "Materials1", "Use1", "Brand1",
|
30 |
+
"ModelType1", "Specs1", "FabricCreationMethod1", "ManufacturerID1", "ManufacturerName1",
|
31 |
+
"ManufacturerCountry1", "ManufacturerState1", "ManufacturerCity1", "ManufacturerPostalCode1",
|
32 |
+
"ManufacturerAddress1", "CargoCategory", "PaymentPlatform", "PaymentAccount",
|
33 |
+
"PaymentTransactionNumber"
|
34 |
+
]
|
35 |
+
|
36 |
+
# Initialize empty output DataFrame
|
37 |
+
output_df = pd.DataFrame("", index=range(len(df)), columns=output_headers)
|
38 |
+
|
39 |
+
# 1. Order Number → CustomerOrderNo. (prefix "LB")
|
40 |
+
if "Order Number" in df.columns:
|
41 |
+
output_df["CustomerOrderNo."] = "LB" + df["Order Number"].astype(str)
|
42 |
+
|
43 |
+
# 2. Name mapping: First + Last + Company → Name
|
44 |
+
if {"Shipping First Name", "Shipping Last Name", "Shipping Company"}.issubset(df.columns):
|
45 |
+
first = df["Shipping First Name"].fillna("").astype(str).str.strip()
|
46 |
+
last = df["Shipping Last Name"].fillna("").astype(str).str.strip()
|
47 |
+
comp = df["Shipping Company"].fillna("").astype(str).str.strip()
|
48 |
+
output_df["Name"] = (first + " " + last + " " + comp).str.strip()
|
49 |
+
|
50 |
+
# 3. Street: Address 1 + Address 2 → Street
|
51 |
+
addr1 = df.get("Shipping Address 1", pd.Series([""] * len(df))).fillna("").astype(str).str.strip()
|
52 |
+
addr2 = df.get("Shipping Address 2", pd.Series([""] * len(df))).fillna("").astype(str).str.strip()
|
53 |
+
output_df["Street"] = (addr1 + " " + addr2).str.strip()
|
54 |
+
|
55 |
+
# 4. City
|
56 |
+
if "Shipping City" in df.columns:
|
57 |
+
output_df["City"] = df["Shipping City"]
|
58 |
+
|
59 |
+
# 5. Province/State
|
60 |
+
if "Shipping Province" in df.columns:
|
61 |
+
output_df["Province/State"] = df["Shipping Province"]
|
62 |
+
|
63 |
+
# 6. ZipCode
|
64 |
+
if "Shipping ZIP" in df.columns:
|
65 |
+
output_df["ZipCode"] = df["Shipping ZIP"]
|
66 |
+
|
67 |
+
# 7. CountryCode
|
68 |
+
if "Shipping Country Code" in df.columns:
|
69 |
+
output_df["CountryCode"] = df["Shipping Country Code"]
|
70 |
+
|
71 |
+
# 8. phone
|
72 |
+
if "Shipping Address Phone" in df.columns:
|
73 |
+
output_df["phone"] = df["Shipping Address Phone"]
|
74 |
+
|
75 |
+
# 9. PackageWeight: Total Weight (g) → kg
|
76 |
+
if "Total Weight" in df.columns:
|
77 |
+
output_df["PackageWeight"] = df["Total Weight"] / 1000
|
78 |
+
|
79 |
+
# 10. DeclaredQuantity1: sum of Quantity per Order Number
|
80 |
+
if "Order Number" in df.columns and "Quantity" in df.columns:
|
81 |
+
output_df["DeclaredQuantity1"] = df.groupby("Order Number")["Quantity"].transform("sum")
|
82 |
+
|
83 |
+
# 11. Fixed defaults for every populated CustomerOrderNo.
|
84 |
+
mask = output_df["CustomerOrderNo."].notna() & (output_df["CustomerOrderNo."] != "")
|
85 |
+
output_df.loc[mask, "RoutingCode"] = "HKTHZXR"
|
86 |
+
output_df.loc[mask, "UnitPrice1"] = 2
|
87 |
+
output_df.loc[mask, "CurrencyCode"] = "USD"
|
88 |
+
output_df.loc[mask, "ItemDescription1"] = "Eye Cosmetic Accessories"
|
89 |
+
output_df.loc[mask, "UnitWeight1"] = 0.02
|
90 |
+
|
91 |
+
# 12. Remove duplicate rows based on CustomerOrderNo.
|
92 |
+
output_df = output_df.drop_duplicates(subset=["CustomerOrderNo."], keep="first")
|
93 |
+
|
94 |
+
# 13. Generate output filename using HK date
|
95 |
+
hk_tz = pytz.timezone("Asia/Hong_Kong")
|
96 |
+
today_hk = datetime.now(hk_tz).strftime("%y%m%d")
|
97 |
+
output_file_name = f"yunexpress {today_hk}.xlsx"
|
98 |
+
|
99 |
+
# Save to Excel
|
100 |
+
output_df.to_excel(output_file_name, index=False)
|
101 |
+
|
102 |
+
return output_df, output_file_name
|
103 |
+
|
104 |
+
# Gradio interface
|
105 |
+
with gr.Blocks(title="Shipping - DHL-E-Commerce") as demo:
|
106 |
+
gr.Markdown("# Shipping - YunExpress")
|
107 |
+
with gr.Row():
|
108 |
+
file_input = gr.File(label="Upload Excel File with a DHL sheet")
|
109 |
+
process_button = gr.Button("Process Data")
|
110 |
+
with gr.Row():
|
111 |
+
output_data = gr.DataFrame()
|
112 |
+
output_file_component = gr.File(label="Download Processed File")
|
113 |
+
process_button.click(fn=process_file, inputs=[file_input], outputs=[output_data, output_file_component])
|
114 |
+
|
115 |
+
demo.launch()
|