|
import gradio as gr |
|
import pandas as pd |
|
from datetime import datetime |
|
import pytz |
|
import re |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def process_file(file): |
|
file_name = file.name.lower() |
|
try: |
|
if file_name.endswith(('.xls', '.xlsx', '.xlsm')): |
|
|
|
df = pd.read_excel(file, sheet_name="YunExpress") |
|
else: |
|
return f"Unsupported file format: {file_name}", None |
|
except Exception as e: |
|
return f"Error reading file: {e}", None |
|
|
|
|
|
output_headers = [ |
|
"CustomerOrderNo.", "RoutingCode", "Trackingnumber", "AdditionalServices", |
|
"ShipmentProtectionPlusService", "CustomDeclaredValue", "SignatureService", |
|
"VatNumber", "EoriNumber", "IossCode", "ManufactureSalesName", |
|
"UnifiedSocialCreditCode", "CountryCode", "Name", "CertificateCode", "Company", |
|
"Street", "City", "Province/State", "ZipCode", "phone", "HouseNumber", "Email", |
|
"PackageNumber", "PackageWeight", "SenderFiastName", "SenderCompany", |
|
"SenderStreet", "SenderCity", "SenderProvince", "SenderPostalCode", |
|
"SenderCountry", "SenderTelephone", "SenderEmail", "SenderUSCI", "PlatformName", |
|
"PlatformProvince", "PlatformAddress", "PlatformPostalCode", "PlatformPhoneNumber", |
|
"PlatformEmail", "EcommercePlatformCode", "SalesPlatformLink", "CurrencyCode", |
|
"SKU1", "ItemDescription1", "ForeignItemDescription1", "DeclaredQuantity1", |
|
"FOBPrice1", "SellingPrice1", "UnitWeight1", "HsCode1", "Remarks1", "SalesLink1", |
|
"Materials1", "Use1", "Brand1", "ModelType1", "Specs1", "FabricCreationMethod1", |
|
"ManufacturerID1", "ManufacturerName1", "ManufacturerCountry1", |
|
"ManufacturerState1", "ManufacturerCity1", "ManufacturerPostalCode1", |
|
"ManufacturerAddress1", "CargoCategory", "PaymentPlatform", "PaymentAccount", |
|
"PaymentTransactionNumber" |
|
] |
|
|
|
|
|
output_df = pd.DataFrame("", index=range(len(df)), columns=output_headers) |
|
|
|
|
|
if "Order Number" in df.columns: |
|
output_df["CustomerOrderNo."] = "LB" + df["Order Number"].astype(str) |
|
|
|
|
|
if {"Shipping First Name", "Shipping Last Name", "Shipping Company"}.issubset(df.columns): |
|
first = df["Shipping First Name"].fillna("").astype(str).str.strip() |
|
last = df["Shipping Last Name"].fillna("").astype(str).str.strip() |
|
comp = df["Shipping Company"].fillna("").astype(str).str.strip() |
|
output_df["Name"] = (first + " " + last + " " + comp).str.replace(r"\s+", " ", regex=True).str.strip() |
|
|
|
|
|
addr1 = df.get("Shipping Address 1", pd.Series([""] * len(df), index=df.index)).fillna("").astype(str).str.strip() |
|
addr2 = df.get("Shipping Address 2", pd.Series([""] * len(df), index=df.index)).fillna("").astype(str).str.strip() |
|
output_df["Street"] = (addr1 + " " + addr2).str.replace(r"\s+", " ", regex=True).str.strip() |
|
|
|
|
|
if "Shipping City" in df.columns: |
|
output_df["City"] = df["Shipping City"] |
|
|
|
|
|
if "Shipping Province" in df.columns: |
|
output_df["Province/State"] = df["Shipping Province"] |
|
|
|
|
|
if "Shipping Country Code" in df.columns: |
|
output_df["CountryCode"] = df["Shipping Country Code"] |
|
|
|
|
|
if "Shipping ZIP" in df.columns: |
|
zip_raw = ( |
|
df["Shipping ZIP"] |
|
.astype(str) |
|
.str.strip() |
|
.str.replace(r"\.0$", "", regex=True) |
|
) |
|
|
|
zip_clean = zip_raw.str.replace(r"[^A-Za-z0-9 ]+", "", regex=True) |
|
|
|
mask_us = output_df["CountryCode"].eq("US") |
|
|
|
mask_3_4_digits = zip_clean.str.fullmatch(r"\d{3,4}") |
|
zip_padded = zip_clean.where(~(mask_us & mask_3_4_digits), zip_clean.str.zfill(5)) |
|
|
|
|
|
output_df["ZipCode"] = zip_padded |
|
|
|
|
|
if "Shipping Address Phone" in df.columns: |
|
output_df["phone"] = df["Shipping Address Phone"] |
|
|
|
|
|
if "Email" in df.columns: |
|
output_df["Email"] = df["Email"] |
|
|
|
|
|
if "Total Weight" in df.columns: |
|
output_df["PackageWeight"] = df["Total Weight"] / 1000 |
|
|
|
|
|
if "Order Number" in df.columns and "Quantity" in df.columns: |
|
output_df["DeclaredQuantity1"] = df.groupby("Order Number")["Quantity"].transform("sum") |
|
|
|
|
|
mask = output_df["CustomerOrderNo."].astype(str).str.len() > 0 |
|
|
|
|
|
mask_us_no_fr = mask & output_df["CountryCode"].isin(["US", "NO", "FR"]) |
|
mask_other = mask & ~output_df["CountryCode"].isin(["US", "NO", "FR"]) |
|
output_df.loc[mask_us_no_fr, "RoutingCode"] = "HK-ASS-PF" |
|
output_df.loc[mask_other, "RoutingCode"] = "HKTHZXR" |
|
|
|
|
|
output_df.loc[mask, "FOBPrice1"] = 2 |
|
output_df.loc[mask, "CurrencyCode"] = "USD" |
|
output_df.loc[mask, "ItemDescription1"] = "Eye Cosmetic Accessories" |
|
output_df.loc[mask, "ForeignItemDescription1"] = "Eye Cosmetic Accessories" |
|
output_df.loc[mask, "UnitWeight1"] = 0.02 |
|
|
|
|
|
EU_COUNTRIES = {"AT","BE","BG","CY","CZ","DE","DK","EE","ES","FI", |
|
"FR","HR","HU","IE","IT","LT","LU","LV","MT","NL", |
|
"PL","PT","RO","SE","SI","SK","GR"} |
|
mask_eu = mask & output_df["CountryCode"].isin(EU_COUNTRIES) |
|
output_df.loc[mask_eu, "AdditionalServices"] = "v1" |
|
|
|
|
|
output_df = output_df.drop_duplicates(subset=["CustomerOrderNo."], keep="first") |
|
|
|
|
|
hk_tz = pytz.timezone("Asia/Hong_Kong") |
|
today_hk = datetime.now(hk_tz).strftime("%y%m%d") |
|
output_file_name = f"yunexpress {today_hk}.xlsx" |
|
|
|
|
|
try: |
|
import xlsxwriter |
|
from xlsxwriter.utility import xl_col_to_name |
|
|
|
with pd.ExcelWriter(output_file_name, engine="xlsxwriter") as writer: |
|
output_df.to_excel(writer, index=False, sheet_name="Sheet1") |
|
workbook = writer.book |
|
worksheet = writer.sheets["Sheet1"] |
|
|
|
|
|
text_fmt = workbook.add_format({"num_format": "@"}) |
|
|
|
|
|
zip_col_idx = output_df.columns.get_loc("ZipCode") |
|
col_letter = xl_col_to_name(zip_col_idx) |
|
worksheet.set_column(f"{col_letter}:{col_letter}", None, text_fmt) |
|
except Exception: |
|
|
|
output_df.to_excel(output_file_name, index=False) |
|
|
|
return output_df, output_file_name |
|
|
|
|
|
|
|
with gr.Blocks(title="Shipping - YunExpress") as demo: |
|
gr.Markdown("# Shipping - YunExpress") |
|
with gr.Row(): |
|
file_input = gr.File(label="Upload Excel File with a YunExpress sheet") |
|
process_button = gr.Button("Process Data") |
|
with gr.Row(): |
|
output_data = gr.DataFrame() |
|
output_file_component = gr.File(label="Download Processed File") |
|
process_button.click(fn=process_file, inputs=[file_input], outputs=[output_data, output_file_component]) |
|
|
|
|
|
gr.HTML( |
|
""" |
|
<div style="text-align: center; font-size: 16px; margin-top: 20px;"> |
|
<h3>Shipping Tools</h3> |
|
<a href="https://huggingface.co/spaces/leadingbridge/shipping-dhl-e-commerce">DHL</a> | |
|
<a href="https://huggingface.co/spaces/leadingbridge/shipping-ec-ship">EC-Ship</a> | |
|
<a href="https://huggingface.co/spaces/leadingbridge/shipping-fedex">Fedex</a> | |
|
<a href="https://huggingface.co/spaces/leadingbridge/shipping-UPS">UPS</a><br> | |
|
<a href="https://huggingface.co/spaces/leadingbridge/shipping-yunexpress">Yunexpress</a> |
|
</div> |
|
<div style="text-align: center; font-size: 16px; margin-top: 20px;"> |
|
<h3>Administration Tools</h3> |
|
<a href="https://huggingface.co/spaces/leadingbridge/email-template">Email Template</a> | |
|
<a href="https://huggingface.co/spaces/leadingbridge/product-feeding">Google Merchant</a> | |
|
<a href="https://huggingface.co/spaces/leadingbridge/tss">Order Processing</a> |
|
</div> |
|
""" |
|
) |
|
|
|
demo.launch() |
|
|