18 KiB
18 KiB
In [ ]:
from utils.gtools import MySQLconnect import pandas as pd ads = MySQLconnect('ads') engine = ads.engine() conn = ads.connect() # sql = """ SELECT # sku.SKU, # 包裹数据, # 成本价 # FROM # ods.`stg_bayshop_litfad_sku` sku # LEFT JOIN ads.new_erp_sku_size size ON sku.SKU=size.SKU # WHERE sku.状态 = "启用" # AND EXISTS (SELECT 1 FROM ods.stg_bayshop_litfad_spu s1 where s1.`产品PID` = sku.`产品PID` AND s1.状态 = "正常销售" and s1.`产品分类` regexp "light") AND sku.添加时间 >="2024-01-01" # """ # df = pd.read_sql(sql, conn)
In [ ]:
# 计算售价 from sell.sell_price import call_sell_and_order_price import json import pandas as pd DATE_LIST = ["2024-01-01","2024-02-01","2024-03-01","2024-04-01","2024-05-01","2024-06-01","2024-07-01","2024-08-01","2024-09-01","2024-10-01","2024-11-01","2024-12-01","2025-01-01","2025-02-01","2025-03-01"] def cal_sell_price(df): """ 计算所有SKU的售价,物流分摊费 """ for index, row in df.iterrows(): try: package_dict = json.loads(row['包裹数据']) sell_price,order_price,order_type = call_sell_and_order_price(row['成本价'], package_dict) except Exception as e: print(f" {row['SKU']} 报错: {e}") continue df.loc[index, '售价'] = sell_price df.loc[index, '物流分摊费'] = order_price df.loc[index, '物流类型'] = order_type # print(f"sku:{row['SKU']},售价:{sell_price},物流分摊费:{order_price},物流类型:{order_type}") return df for date in DATE_LIST: sql = f""" SELECT sku.SKU, 包裹数据, 成本价, 产品售价, `产品品类`, `产品分类` FROM ods.`stg_bayshop_litfad_sku` sku LEFT JOIN ads.new_erp_sku_size size ON sku.SKU = size.SKU LEFT JOIN ods.stg_bayshop_litfad_spu spu ON sku.`产品PID` =spu.`产品PID` WHERE sku.状态 = "启用" AND spu.`产品品类` REGEXP "66" AND spu.`状态` ="正常销售" AND DATE_FORMAT( sku.添加时间, "%Y-%m-01" )= "{date}" """ df = pd.read_sql(sql, conn) df1 = cal_sell_price(df) df1.to_excel(f'售价_{date}.xlsx', index=False) print(f"日期:{date}, 售价计算完成")
美国2025版订单物流费
In [ ]:
import math import pandas as pd from utils.gtools import MySQLconnect mat = MySQLconnect('mat') engine = mat.engine() df1 = pd.read_sql('select * from fedex2_0814', engine) import math # 美国海运订单费用,返回单个sku的订单费用和订单类型 def us_ocean_order_price(packages): return ocean_order_price(packages)
英国2024版订单物流费
In [ ]:
# 英国海运订单费用,返回单个sku的订单费用和订单类型 def uk_ocean_order_price(packages): # 计算uk经济直达费用 order_fee = 0 express_fee = 0 order_type1 = '' # 订单类型 ltl_fee = 0 if packages is None or len(packages) == 0: return 0, '包裹数为0' num = len(packages) if num > 30: return 0, '包裹数超过30' for package in packages: base_fee = 0 other_fee1 = 0 other_fee2 = 0 girth = package.girth if package.fst_size <= 90 and package.sed_size <= 50 and package.trd_size <= 50 and package.weight <= 29000: base_fee = 2.5 elif package.fst_size <= 165 and package.weight <= 39000: base_fee = 4.5 if package.weight >= 29000: other_fee1 = 17.8 # 超重费 order_type1 += '超重' if package.fst_size > 95 or package.sed_size > 55 or package.trd_size > 55: other_fee2 = 12.7 # 超长费 order_type1 += '超长' elif package.fst_size <= 290 and package.weight <= 69000 and girth <= 410: if package.weight <= 29000: base_fee = (7 * 9 / 7) / 0.45 elif 29000 < package.weight <= 49000: base_fee = (17.5 * 9 / 7) / 0.45 elif 49000 < package.weight <= 69000: base_fee = (28 * 9 / 7) / 0.45 order_type1 += '大包裹' else: base_fee = 999999 express_fee += (base_fee + other_fee1 + other_fee2) express_fee = round(express_fee, 2) # 卡派 主计费实重,辅计费抛重 order_type2 = '卡派' sku_total_cubic_feet = 0 for package in packages: cubic_feet= package.length * package.width * package.height / 6000 sku_total_cubic_feet += cubic_feet if package.length >310: return 999999,'包裹超尺寸' ltl_fee = max(151/0.45 - 2.4 /7 * sku_total_cubic_feet,2.5) if express_fee <= ltl_fee: order_fee = express_fee order_type = order_type1 else: order_fee = ltl_fee order_type = order_type2 return round(order_fee,2), order_type
计算2024版本售价
In [ ]:
from utils.Package import Package, Package_group from sell.base_sell_price import SellPriceBase import re import json def call_sell_price(price, packages): if packages is None: return 0 litfad = SellPriceBase.litfad(packages, price,1) # 修改版本,网站售价 sell_price = litfad.cal_sell_price() return sell_price[0]
In [ ]:
from utils.gtools import MySQLconnect from tqdm import tqdm import pandas as pd from utils.Package import Package, Package_group import json import re from concurrent.futures import ThreadPoolExecutor def to_package(package_data): 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 package_dict = json.loads(package_data) for key, package in package_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 None packages.add_package(Package(key,package['长'], package['宽'], package['高'], package['重量'])) return package_dict from utils.countryOperator import OperateCountry from utils.logisticsBill import Billing from sell.sell_price import call_sell_price_2025, ocean_order_price from sell.logistic_price.uk_price import uk_ocean_order_price from sell.logistic_price.jp_price import jp_order_yamato if __name__ == '__main__': sql = """SELECT * , sku.`成本价` FROM dwd.dim_erp_sku_package_vol_info t1 LEFT JOIN ods.stg_bayshop_litfad_sku sku ON t1.erp_sku = sku.SKU WHERE NOT EXISTS ( SELECT 1 FROM ads.sku_order_compare t2 WHERE t1.erp_sku = t2.SKU ) AND id >= %s AND id <= %s AND `状态` = '启用'""" au_opCountry = OperateCountry("AU") fr_opCountry = OperateCountry('FR') de_opCountry = OperateCountry('DE') es_opCountry = OperateCountry('ES') it_opCountry = OperateCountry('IT') with MySQLconnect('ads') as db: for i in tqdm(range(0,150)): print(i,"开始") dfsql = sql % (i*100000, (i+1)*100000-1) df = pd.read_sql(dfsql, db.engine()) if len(df) == 0: continue # 包裹数据格式化 df['erp_package_vol'] = df.apply(lambda x: to_package(x['erp_package_vol']), axis=1) # df['售价'] = df.apply(lambda x: call_sell_and_order_price(x['成本价'], x['erp_package_vol'], "海运")[0], axis=1) # df[['美国海运','美国海运类型']] = df.apply(lambda x: us_ocean_order_price(x['erp_package_vol']), axis=1, result_type='expand') # df[['英国海运','英国海运类型']] = df.apply(lambda x: uk_ocean_order_price(x['erp_package_vol']), axis=1, result_type='expand') def process_row(x): # 单行处理逻辑 try: sell_price=x['产品售价'] logitcs = x['物流分摊'] # print("售价计算完成") us_price, us_type = ocean_order_price(x['erp_package_vol']) # print("美国海运计算完成") uk_price, uk_type = uk_ocean_order_price(x['erp_package_vol'],logitcs) jp_price,jp_type = jp_order_yamato(x['erp_package_vol'], sell_price) # print("英国海运计算完成") if x['erp_sku'] =="2207384162": au_price2 = Billing("1",au_opCountry,x['erp_package_vol'],"2911",company_name=None,head_type=1,beizhu='1').tail_amount[0] print(au_price2) au_price = Billing("1",au_opCountry,x['erp_package_vol'],"2911",company_name=None,head_type=1,beizhu='1').tail_amount[0] fr_price = Billing("1",fr_opCountry,x['erp_package_vol'],"75000",company_name=None,head_type=1,beizhu='1').tail_amount[0] de_price = Billing("1",de_opCountry,x['erp_package_vol'],"12489",company_name=None,head_type=1,beizhu='1').tail_amount[0] es_price = Billing("1",es_opCountry,x['erp_package_vol'],"28002",company_name=None,head_type=1,beizhu='1').tail_amount[0] it_price = Billing("1",it_opCountry,x['erp_package_vol'],"20143",company_name=None,head_type=1,beizhu='1').tail_amount[0] return [round(sell_price, 2), us_price, us_type, uk_price, uk_type,jp_price,jp_type,au_price,fr_price,de_price,es_price,it_price] except Exception as e: return [None, None, None, None, None,None, None, None, None, None,None, None] # 用 dict 更稳妥 rows = df.to_dict(orient='records') # 转为 list of dict with ThreadPoolExecutor(max_workers=50) as executor: results = list(executor.map(process_row, rows)) # 组装结果 result_df = pd.DataFrame(results, columns=['售价', '美国海运', '美国海运类型', '英国海运', '英国海运类型','日本','日本类型','澳洲','法国Zone4','德国Zone2','西班牙','意大利']) df = pd.concat([df.reset_index(drop=True), result_df], axis=1) # 清空临时表 db.cur.execute("TRUNCATE TABLE ads.temp_sku_order_compare;") print("临时表清空完成") # 组装需要输出的字段 df = df.rename(columns={ 'erp_package_vol':'包裹数据' }) columns_needed = ['SKU', '售价','包裹数据', '美国海运', '美国海运类型', '英国海运', '英国海运类型','日本','日本类型','澳洲','法国Zone4','德国Zone2','西班牙','意大利'] df_out = df[columns_needed] # 写入当前批次数据 df_out.to_sql( "temp_sku_order_compare", db.eng, if_exists='append', index=False, method='multi', chunksize=500 # 分批写入 ) print("当前批次数据写入完成") # 更新主表 update_sql = """ REPLACE INTO ads.sku_order_compare SELECT * FROM ads.temp_sku_order_compare """ db.cur.execute(update_sql) print("主表更新完成") db.con.commit() print(i,"结束")
In [2]:
from utils.countryOperator import OperateCountry from utils.logisticsBill import Billing,BillFactory from utils.gtools import MySQLconnect from tqdm import tqdm import pandas as pd from utils.Package import Package, Package_group sql = """ SELECT order_id, postcode, package, length, width, hight, weight FROM order_list ol LEFT JOIN parcel ON ol.order_id = parcel.订单号 LEFT JOIN package_vol_info pvi ON parcel.`包裹号` = pvi.package WHERE site_name = "Litfad" AND delivery_country REGEXP "United Kingdom" AND order_date >="2025-03-01" AND fund_status NOT REGEXP "等待" AND length>0 AND weight>0 """ with MySQLconnect('ods') as db: conn = db.connect() df = pd.read_sql(sql, conn) df_group = df.groupby(['order_id']) opCountry = OperateCountry("UK") bills = BillFactory() index = 0 for order_id, group in df_group: index+=1 packages = Package_group() postcode= group['postcode'].iloc[0] for i, row in group.iterrows(): package = Package(row['package'], row['length'], row['width'], row['hight'], row['weight']) packages.add_package(package) bill = bills.create_bill("1",opCountry,packages,postcode,company_name="智谷-DPD",head_type=1,beizhu=index) bills.add_bill(bill) df_bill = bills.bills_to_df() df_bill.to_excel("英国账单.xlsx")
C:\Users\Admin\AppData\Local\Temp\ipykernel_27996\1408839972.py:30: UserWarning: pandas only supports SQLAlchemy connectable (engine/connection) or database string URI or sqlite3 DBAPI2 connection. Other DBAPI2 objects are not tested. Please consider using SQLAlchemy. df = pd.read_sql(sql, conn)