logistics/物流渠道测算.ipynb

9.4 KiB

取订单包裹数据,计算它打单的费用,和理论最小费用

In [ ]:
import pandas as pd
from utils.gtools import MySQLconnect

# 读取需要计算的包裹信息
with MySQLconnect('ods') as db:
    sql = r"""  
WITH
t1 AS (
SELECT
order_id,
spu.`产品品类`,
spu.`产品分类`,
SUM(as_value_amount) AS 销售额,
sum(CASE WHEN opl.order_product_id LIKE '%\_%' ESCAPE '\\' 
         AND opl.order_product_id NOT LIKE '%\_%\_%' ESCAPE '\\' THEN product_num END) AS product_num,
order_date,
count(opl.SKU) AS 产品数
FROM
dws.fact_order_product_list opl
LEFT JOIN stg_bayshop_litfad_sku sku ON opl.SKU=sku.SKU
LEFT JOIN stg_bayshop_litfad_spu spu ON sku.产品PID = spu.`产品PID`
WHERE
  NOT EXISTS (
    SELECT 1 
    FROM dws.log_order_reissue_detail AS r 
    WHERE r.order_product_id = opl.order_product_id
  )
	AND order_date >= "20250501"
AND order_date < "20250612"
GROUP BY order_id
)
-- ,
-- t2 AS (
SELECT			t1.`产品品类`,
						t1.`产品分类`,
            t1.order_id,
						t1.销售额,
						t1.order_date,
            a.包裹号,
            a.快递公司,
            a.运输方式,
						a.`目的国`,
            d.postcode,
            b.length AS `长`,
            b.width AS `宽`,
            b.hight AS `高`,
            b.weight AS `重量`
        FROM
				t1
            LEFT JOIN order_express a ON t1.order_id = a.单号
            JOIN package_vol_info b ON a.`包裹号` = b.package
            JOIN order_list d ON a.`单号` = d.order_id 
        WHERE
            a.`包裹状态` not IN ( '已作废') 
            AND b.hight > 0 
            AND b.length > 0 
            AND b.width > 0 
            AND b.hight > 0 
            AND b.weight > 0
            AND a.`目的国` = "United States"
AND `快递公司` NOT REGEXP "易可达|USPS|XMILES|WWEX|美西卡派|美东卡派|大包"
AND `运输方式` REGEXP "海运"
AND a.`投递时间` >= '2025-05-17'
AND a.`投递时间` < '2025-06-12'
ORDER BY order_date
-- )
-- SELECT
-- `快递公司`,
-- count(*)
-- FROM
-- t2
-- GROUP BY 快递公司
-- 

    """
    df=pd.read_sql(sql,db.con)
    print(df)
    df.to_clipboard(index=False)

计算实际物流渠道打单的预估费用,以订单为单位计算,然后价格给每个订单的每个包裹

In [ ]:
for index,row in df.iterrows():
    if "METRO-SAIR" in row['快递公司']:
        df.loc[index,'类型'] = "Metro-SAIR"
    elif "海MS-AMT-SAIR" in row['快递公司']:
        df.loc[index,'类型'] = "AM-美西"
    elif "海NY-AMT-SAIR" in row['快递公司']:
        df.loc[index,'类型'] = "AM-美东"
    elif any(x in row['快递公司'] for x in ["FEDEX-SAIR-G", "FEDEX-SAIR-H", "FEDEX"]):
        df.loc[index,'类型'] = "快递"
df
In [ ]:
import pandas as pd
# 取数据源
df = pd.read_excel(r'C:\Users\Admin\Desktop\订单利润率分析1.1.xlsx', sheet_name='包裹详情')
df = df[df['尾端费用'] == None]
# 快递公司映射
company_mapping =pd.read_excel(r'C:\Users\Admin\Desktop\订单利润率分析1.1.xlsx', sheet_name='快递公司',usecols=[0, 1])
company_mapping = dict(zip(company_mapping['快递公司'], company_mapping['company']))
df
In [ ]:
from utils.countryOperator import OperateCountry
from utils.logisticsBill import BillFactory
from utils.Package import Package, Package_group
import pandas as pd
import json
import re
# 美国 
from utils.logisticsBill import Billing
# opCountry = OperateCountry('US')
df_grouped= df.groupby('快递跟踪号')
for order_num, group in df_grouped:
    postcode = group['postcode'].iloc[0]
    if pd.isna(postcode) or str(postcode).lower() == "nan":
        continue

    packages= Package_group() # Metro-SAIR
    company_name = company_mapping[group['快递公司'].iloc[0]]
    if company_name == "无" or company_name == "可补":
        continue
    opCountry = OperateCountry(group['目的国'].iloc[0])
    total_weight=0 # 按体积重分费用
    for index,row in group.iterrows():
        if row['length'] == 0 or row['width'] == 0 or row['hight'] == 0 or row['weight'] == 0:
            continue
        total_weight = row['体积重']
        package = Package(row['包裹号'],row['length'],row['width'],row['hight'],row['weight'])
        packages.add_package(package)
    try:
        bill1 = Billing(str(index),opCountry,packages,postcode,company_name=company_name,head_type=1,beizhu='1')
        for index,row in group.iterrows():
            propertion = row['体积重']/total_weight
            df.loc[df['包裹号']==row['包裹号'],'尾端费用'] = bill1.tail_amount[0]*propertion
        df.loc[df['快递跟踪号']==order_num,'账单详情'] = bill1.bill_dict()
    except:
        continue
    print(index,bill1.bill_dict())
In [ ]:
df.to_excel(r'C:\Users\Admin\Desktop\订单利润率分析1.xlsx',index=False)

计算最优渠道费用

In [ ]:
from utils.countryOperator import OperateCountry
from utils.logisticsBill import BillFactory
from utils.Package import Package, Package_group
import pandas as pd
import json
import re
# 美国 
from utils.logisticsBill import Billing
import requests
opCountry = OperateCountry('US')
for order_num, group in df_grouped:
    postcode = group['postcode'].iloc[0]
    if pd.isna(postcode) or str(postcode).lower() == "nan":
        continue
    
    
    if "海运" in row['运输方式']:
        head_type = 1
    else:
        head_type = 0
    # 包裹打包
    packages = Package_group()
    for index,row in group.iterrows():
        package = Package(row['包裹号'],row['长'],row['宽'],row['高'],row['重量'])
        packages.add_package(package)
    if packages is None:
        continue

    bill = Billing(str(order_num),opCountry,packages,postcode,company_name=None,head_type=head_type,beizhu='1')
    head_price = bill.head_amount[0]
    tail_price = bill.tail_amount[0]
    if "USPS" in row['快递公司']:
        tail_price = tail_price/2
    df.loc[df['order_id']==order_num,'最优尾端费用'] = tail_price/len(packages)
    # df.loc[index,"尾端货币"] = bill.tail_amount[1]
    df.loc[df['order_id']==order_num,'最优渠道'] = bill.company_name
    print(f"order_num:{order_num},最优尾端费用:{tail_price/len(packages)},最优渠道:{bill.company_name}")
df.to_clipboard(index=False)
In [ ]:
df.to_clipboard(index=False)
In [ ]:

In [ ]: