2026-03-16 23:36:00 +08:00
|
|
|
|
import sys
|
|
|
|
|
|
sys.path.append(r'D:\workspace\dags\logistics')
|
2025-06-17 18:44:31 +08:00
|
|
|
|
import pandas as pd
|
2026-03-16 23:36:00 +08:00
|
|
|
|
|
2025-06-17 18:44:31 +08:00
|
|
|
|
import math
|
2026-03-16 23:36:00 +08:00
|
|
|
|
from utils.Package import Package, Package_group
|
|
|
|
|
|
import re
|
|
|
|
|
|
express_price = pd.read_excel(r'D:\workspace\dags\logistics\data\售价尾端价格.xlsx', sheet_name='Sheet1')
|
2025-06-17 18:44:31 +08:00
|
|
|
|
key_column = express_price.iloc[:, 8] # 第 I 列
|
|
|
|
|
|
value_column = express_price.iloc[:, 9] # 第 J 列
|
|
|
|
|
|
small_column = express_price.iloc[:, 10] # 第 K 列
|
|
|
|
|
|
big_column = express_price.iloc[:, 11] # 第 L 列
|
|
|
|
|
|
air_small_dict = dict(zip(key_column, small_column))
|
|
|
|
|
|
air_big_dict = dict(zip(key_column, big_column))
|
|
|
|
|
|
# 转换成字典
|
|
|
|
|
|
ocean_price_dict = dict(zip(key_column, value_column))
|
2026-03-16 23:36:00 +08:00
|
|
|
|
def ocean_order_price(packages_dict_str):
|
|
|
|
|
|
|
|
|
|
|
|
packages = Package_group()
|
|
|
|
|
|
def extract_number(value):
|
|
|
|
|
|
# 提取字符串中的第一个数字
|
|
|
|
|
|
match = re.search(r"[-+]?\d*\.\d+|\d+", str(value))
|
|
|
|
|
|
return float(match.group()) if match else 0.0
|
|
|
|
|
|
packages_dict = eval(packages_dict_str)
|
|
|
|
|
|
if len(packages_dict) == 0:
|
|
|
|
|
|
return (0,0)
|
|
|
|
|
|
for key, package in packages_dict.items():
|
|
|
|
|
|
package['长'] = extract_number(package['长'])
|
|
|
|
|
|
package['宽'] = extract_number(package['宽'])
|
|
|
|
|
|
package['高'] = extract_number(package['高'])
|
|
|
|
|
|
package['重量'] = extract_number(package['重量'])
|
|
|
|
|
|
|
|
|
|
|
|
if package['长'] == 0 or package['宽'] == 0 or package['高'] == 0 or package['重量'] == 0:
|
|
|
|
|
|
return (0,0)
|
|
|
|
|
|
packages.add_package(Package(key,package['长'], package['宽'], package['高'], package['重量']))
|
|
|
|
|
|
|
2025-06-17 18:44:31 +08:00
|
|
|
|
express_fee = 0 # 快递基础费
|
|
|
|
|
|
long_fee = 0 # 超长费
|
|
|
|
|
|
weight_fee = 0 # 超重费
|
|
|
|
|
|
big_fee = 0 # 大包裹费
|
|
|
|
|
|
express_type = ''
|
|
|
|
|
|
express_type_weight = ''
|
|
|
|
|
|
express_type_length = ''
|
|
|
|
|
|
for package in packages:
|
|
|
|
|
|
for key, value in ocean_price_dict.items():
|
2026-03-16 23:36:00 +08:00
|
|
|
|
|
|
|
|
|
|
if max(package.get_volume_weight(8500)*1000, package.weight) <=key:
|
2025-06-17 18:44:31 +08:00
|
|
|
|
express_fee+=value
|
|
|
|
|
|
break
|
|
|
|
|
|
if package.fst_size>=116 or package.sed_size>=71 or package.girth>=251:
|
|
|
|
|
|
long_fee += 16.3
|
|
|
|
|
|
if express_type_length == '':
|
|
|
|
|
|
express_type_length ="超长"
|
|
|
|
|
|
if package.weight>=21000 and package.fst_size<238 and package.girth<315:
|
|
|
|
|
|
weight_fee+=25.5
|
|
|
|
|
|
express_type_weight ="超重"
|
|
|
|
|
|
if package.fst_size>=238 or package.girth>=315:
|
|
|
|
|
|
big_fee+=61.6
|
|
|
|
|
|
express_type_length ="大包裹"
|
2026-03-16 23:36:00 +08:00
|
|
|
|
express_fee = 9999999 if express_fee ==0 else express_fee
|
2025-06-17 18:44:31 +08:00
|
|
|
|
express_fee = express_fee + long_fee + weight_fee + big_fee
|
|
|
|
|
|
express_type = express_type_length + express_type_weight
|
|
|
|
|
|
|
|
|
|
|
|
# 卡派(步长为3)
|
|
|
|
|
|
ltl_base = 0
|
|
|
|
|
|
ltl_fee = 0
|
|
|
|
|
|
count1 = 0
|
|
|
|
|
|
count2 = 0
|
|
|
|
|
|
count3 = 0
|
|
|
|
|
|
count4 = 0
|
|
|
|
|
|
ltl_type = '卡派'
|
|
|
|
|
|
order_type_length=''
|
|
|
|
|
|
order_type_weight=''
|
|
|
|
|
|
order_ltl_oversize = 0
|
|
|
|
|
|
order_ltl_overweight1 = 0
|
|
|
|
|
|
order_ltl_overweight2 = 0
|
|
|
|
|
|
order_ltl_overpackage = 0
|
|
|
|
|
|
sku_total_cubic_feet = 0
|
|
|
|
|
|
for package in packages:
|
|
|
|
|
|
cubic_feet= package.length * package.width * package.height / 1000000 * 35.3
|
|
|
|
|
|
sku_total_cubic_feet += cubic_feet
|
|
|
|
|
|
# 卡派额外费用
|
|
|
|
|
|
if package.fst_size>= 250:
|
|
|
|
|
|
count1 += 1
|
|
|
|
|
|
order_ltl_oversize = 118
|
|
|
|
|
|
if order_type_length == '':
|
|
|
|
|
|
order_type_length = '超长'
|
|
|
|
|
|
if package.weight >= 111000:
|
|
|
|
|
|
count2 += 1
|
|
|
|
|
|
order_ltl_overweight1 = 78
|
|
|
|
|
|
order_type_weight = '超重'
|
|
|
|
|
|
if package.weight >= 130000:
|
|
|
|
|
|
count3 += 1
|
|
|
|
|
|
order_ltl_overweight2 = 30
|
|
|
|
|
|
if package.fst_size >= 310:
|
|
|
|
|
|
count4 += 1
|
|
|
|
|
|
order_ltl_overpackage = 30
|
|
|
|
|
|
order_type_length = '大包裹'
|
|
|
|
|
|
order_type2 = ltl_type +order_type_length+ order_type_weight
|
|
|
|
|
|
|
|
|
|
|
|
# 卡派基础费用 体积/1000000 *35.3
|
|
|
|
|
|
if sku_total_cubic_feet < 25:
|
|
|
|
|
|
ltl_base = round(163 / 0.45 / 2, 2) # 181.11
|
|
|
|
|
|
|
|
|
|
|
|
elif sku_total_cubic_feet < 35:
|
|
|
|
|
|
ltl_base = round(180 / 0.45 / 2, 2) # 200
|
|
|
|
|
|
else:
|
|
|
|
|
|
# 大于一个立方的(35立方英尺) 按照每立方英尺*5美金
|
|
|
|
|
|
# 最低为190美金
|
|
|
|
|
|
ltl_base = round(max(190, 5 * sku_total_cubic_feet) / 0.359 / 2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ltl_fee = math.ceil(count1 / 3) * order_ltl_oversize + math.ceil(count2 / 3) * order_ltl_overweight1 + math.ceil(
|
|
|
|
|
|
count3 / 3) * order_ltl_overweight2 + math.ceil(count4 / 3) * order_ltl_overpackage + ltl_base
|
|
|
|
|
|
|
|
|
|
|
|
if ltl_fee < express_fee:
|
|
|
|
|
|
ocean_fee = ltl_fee
|
|
|
|
|
|
order_type = order_type2
|
|
|
|
|
|
else:
|
|
|
|
|
|
ocean_fee = express_fee
|
|
|
|
|
|
order_type = express_type
|
|
|
|
|
|
return ocean_fee, order_type
|
|
|
|
|
|
|
|
|
|
|
|
def air_order_price(packages):
|
|
|
|
|
|
express_fee = 0
|
|
|
|
|
|
express_type = ''
|
|
|
|
|
|
for package in packages:
|
|
|
|
|
|
price=0
|
|
|
|
|
|
bill_weight = max(package.weight, package.get_volume_weight(8500))
|
|
|
|
|
|
if package.weight<=420 and package.fst_size<=50 and package.sed_size<=40 and package.trd_size<=30:
|
|
|
|
|
|
for key, value in air_small_dict.items():
|
|
|
|
|
|
if package.weight <=key:
|
|
|
|
|
|
price =value
|
|
|
|
|
|
break
|
|
|
|
|
|
elif package.weight<=2718 and package.fst_size<=50 and package.sed_size<=40 and package.trd_size<=30:
|
|
|
|
|
|
for key, value in air_small_dict.items():
|
|
|
|
|
|
if bill_weight <=key:
|
|
|
|
|
|
price =value
|
|
|
|
|
|
break
|
|
|
|
|
|
else:
|
|
|
|
|
|
for key, value in air_big_dict.items():
|
|
|
|
|
|
if bill_weight <=key:
|
|
|
|
|
|
price =value
|
|
|
|
|
|
break
|
|
|
|
|
|
if package.weight<=420:
|
|
|
|
|
|
express_fee+=((((min(max(package.density,37),337)*0.093+27.7)/6+0.65)*package.get_volume_weight(6000))*0.3+price)/0.45
|
|
|
|
|
|
if express_type == '':
|
|
|
|
|
|
express_type='USPS'
|
|
|
|
|
|
elif package.weight<=2718:
|
|
|
|
|
|
express_fee+=(((min(max(package.density,37),337)*0.093+27.7)/6+0.65)*package.get_volume_weight(8500)*0.3+price)/0.45
|
|
|
|
|
|
if express_type == '' or express_type == 'USPS':
|
|
|
|
|
|
express_type='UandF'
|
|
|
|
|
|
else:
|
|
|
|
|
|
express_fee+=(((min(max(package.density,37),337)*0.093+27.7-1.08)/6+0.65-1.06)*package.get_volume_weight(8500))/0.45+price
|
|
|
|
|
|
express_type='FEDEX'
|
2026-03-16 23:36:00 +08:00
|
|
|
|
return express_fee, express_type
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
sql = "SELECT * FROM `dim_erp_sku_package_vol_info` where id >=%s AND id <=%s AND logis_type IS NULL"
|
|
|
|
|
|
from utils.gtools import MySQLconnect
|
|
|
|
|
|
from tqdm import tqdm
|
|
|
|
|
|
with MySQLconnect('dwd') as db:
|
|
|
|
|
|
for i in tqdm(range(1,150)):
|
|
|
|
|
|
# count=0
|
|
|
|
|
|
print(i,"开始")
|
|
|
|
|
|
dfsql = sql % (i*100000, (i+1)*100000-1)
|
|
|
|
|
|
df = pd.read_sql(dfsql, db.engine())
|
|
|
|
|
|
if len(df) == 0:
|
|
|
|
|
|
continue
|
|
|
|
|
|
df[['us_price','logitcs_type']] = df.apply(lambda x: ocean_order_price(x['erp_package_vol']), axis=1, result_type='expand')
|
|
|
|
|
|
pd.io.sql.to_sql(df, "temp_update",db.eng, if_exists='replace', index=False )
|
|
|
|
|
|
#添加主键ID
|
|
|
|
|
|
modifysql = """ALTER TABLE `temp_update` ADD PRIMARY KEY (`id`)
|
|
|
|
|
|
"""
|
|
|
|
|
|
db.cur.execute(modifysql)
|
|
|
|
|
|
|
|
|
|
|
|
# se = [tuple([round(x['us_price'],2),x['id']]) for y,x in df.iterrows()]
|
|
|
|
|
|
update_sql = """
|
|
|
|
|
|
UPDATE dim_erp_sku_package_vol_info AS target
|
|
|
|
|
|
JOIN temp_update AS src
|
|
|
|
|
|
ON target.id = src.id -- 根据主键关联
|
|
|
|
|
|
SET target.logis_type = src.logitcs_type;"""
|
|
|
|
|
|
# db.cur.executemany(update_sql, se)
|
|
|
|
|
|
db.cur.execute(update_sql)
|
|
|
|
|
|
db.con.commit()
|
|
|
|
|
|
print(i,"结束")
|