{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from utils.gtools import MySQLconnect\n", "import pandas as pd\n", "ads = MySQLconnect('ads')\n", "engine = ads.engine()\n", "conn = ads.connect()\n", "# sql = \"\"\" SELECT\n", "# sku.SKU,\n", "# 包裹数据,\n", "# 成本价\n", "# FROM\n", "# ods.`stg_bayshop_litfad_sku` sku\n", "# LEFT JOIN ads.new_erp_sku_size size ON sku.SKU=size.SKU\n", "# \t\t\t\t\t\t\t WHERE sku.状态 = \"启用\"\n", "# \t\t\t\t\t\t\t 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\"\n", "# \"\"\"\n", "# df = pd.read_sql(sql, conn)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 计算售价\n", "\n", "\n", "from sell.sell_price import call_sell_and_order_price\n", "import json\n", "import pandas as pd\n", "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\"]\n", "\n", "def cal_sell_price(df):\n", " \"\"\"\n", " 计算所有SKU的售价,物流分摊费\n", " \"\"\"\n", " for index, row in df.iterrows():\n", " try:\n", " package_dict = json.loads(row['包裹数据'])\n", " sell_price,order_price,order_type = call_sell_and_order_price(row['成本价'], package_dict)\n", " except Exception as e:\n", " print(f\" {row['SKU']} 报错: {e}\")\n", " continue\n", " df.loc[index, '售价'] = sell_price\n", " df.loc[index, '物流分摊费'] = order_price\n", " df.loc[index, '物流类型'] = order_type\n", " # print(f\"sku:{row['SKU']},售价:{sell_price},物流分摊费:{order_price},物流类型:{order_type}\")\n", " return df\n", "for date in DATE_LIST:\n", " sql = f\"\"\" SELECT\n", "\tsku.SKU,\n", "\t包裹数据,\n", "\t成本价,\n", "\t产品售价,\n", "\t`产品品类`,\n", "\t`产品分类` \n", "FROM\n", "\tods.`stg_bayshop_litfad_sku` sku\n", "\tLEFT JOIN ads.new_erp_sku_size size ON sku.SKU = size.SKU \n", "\tLEFT JOIN ods.stg_bayshop_litfad_spu spu ON sku.`产品PID` =spu.`产品PID`\n", "WHERE\n", "\tsku.状态 = \"启用\" \n", "\tAND spu.`产品品类` REGEXP \"66\"\n", "\tAND spu.`状态` =\"正常销售\"\n", "\tAND DATE_FORMAT( sku.添加时间, \"%Y-%m-01\" )= \"{date}\"\n", " \"\"\"\n", " df = pd.read_sql(sql, conn)\n", " df1 = cal_sell_price(df)\n", " df1.to_excel(f'售价_{date}.xlsx', index=False)\n", " print(f\"日期:{date}, 售价计算完成\")\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "美国2025版订单物流费\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\n", "\n", "import math\n", "\n", "import pandas as pd\n", "\n", "from utils.gtools import MySQLconnect\n", "mat = MySQLconnect('mat')\n", "engine = mat.engine()\n", "df1 = pd.read_sql('select * from fedex2_0814', engine)\n", "import math\n", "# 美国海运订单费用,返回单个sku的订单费用和订单类型\n", "def us_ocean_order_price(packages):\n", " return ocean_order_price(packages)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "英国2024版订单物流费" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 英国海运订单费用,返回单个sku的订单费用和订单类型\n", "def uk_ocean_order_price(packages):\n", " # 计算uk经济直达费用\n", " order_fee = 0\n", " express_fee = 0\n", " order_type1 = '' # 订单类型\n", " ltl_fee = 0\n", " if packages is None or len(packages) == 0:\n", " return 0, '包裹数为0'\n", " num = len(packages)\n", " if num > 30:\n", " return 0, '包裹数超过30'\n", " for package in packages:\n", " base_fee = 0\n", " other_fee1 = 0\n", " other_fee2 = 0\n", " girth = package.girth\n", " if package.fst_size <= 90 and package.sed_size <= 50 and package.trd_size <= 50 and package.weight <= 29000:\n", " base_fee = 2.5\n", " elif package.fst_size <= 165 and package.weight <= 39000:\n", " base_fee = 4.5\n", " if package.weight >= 29000:\n", " other_fee1 = 17.8 # 超重费\n", " order_type1 += '超重'\n", " if package.fst_size > 95 or package.sed_size > 55 or package.trd_size > 55:\n", " other_fee2 = 12.7 # 超长费\n", " order_type1 += '超长'\n", " elif package.fst_size <= 290 and package.weight <= 69000 and girth <= 410:\n", " if package.weight <= 29000:\n", " base_fee = (7 * 9 / 7) / 0.45\n", " elif 29000 < package.weight <= 49000:\n", " base_fee = (17.5 * 9 / 7) / 0.45\n", " elif 49000 < package.weight <= 69000:\n", " base_fee = (28 * 9 / 7) / 0.45\n", " order_type1 += '大包裹'\n", " else:\n", " base_fee = 999999\n", " express_fee += (base_fee + other_fee1 + other_fee2)\n", " express_fee = round(express_fee, 2)\n", "\n", " # 卡派 主计费实重,辅计费抛重\n", " order_type2 = '卡派'\n", " sku_total_cubic_feet = 0\n", " for package in packages:\n", " cubic_feet= package.length * package.width * package.height / 6000\n", " sku_total_cubic_feet += cubic_feet\n", " if package.length >310:\n", " return 999999,'包裹超尺寸'\n", " ltl_fee = max(151/0.45 - 2.4 /7 * sku_total_cubic_feet,2.5) \n", "\n", " if express_fee <= ltl_fee:\n", " order_fee = express_fee\n", " order_type = order_type1\n", " else:\n", " order_fee = ltl_fee\n", " order_type = order_type2\n", " return round(order_fee,2), order_type\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "计算2024版本售价" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from utils.Package import Package, Package_group\n", "from sell.base_sell_price import SellPriceBase\n", "import re\n", "import json\n", "def call_sell_price(price, packages):\n", " if packages is None:\n", " return 0\n", " litfad = SellPriceBase.litfad(packages, price,1)\n", " # 修改版本,网站售价\n", " sell_price = litfad.cal_sell_price()\n", " return sell_price[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from utils.gtools import MySQLconnect\n", "from tqdm import tqdm\n", "import pandas as pd\n", "from utils.Package import Package, Package_group\n", "import json\n", "import re\n", "from concurrent.futures import ThreadPoolExecutor\n", "def to_package(package_data):\n", " packages = Package_group()\n", " def extract_number(value):\n", " # 提取字符串中的第一个数字\n", " match = re.search(r\"[-+]?\\d*\\.\\d+|\\d+\", str(value))\n", " return float(match.group()) if match else 0.0\n", " package_dict = json.loads(package_data)\n", " for key, package in package_dict.items():\n", " package['长'] = extract_number(package['长'])\n", " package['宽'] = extract_number(package['宽'])\n", " package['高'] = extract_number(package['高'])\n", " package['重量'] = extract_number(package['重量'])\n", " \n", " if package['长'] == 0 or package['宽'] == 0 or package['高'] == 0 or package['重量'] == 0:\n", " return None\n", " packages.add_package(Package(key,package['长'], package['宽'], package['高'], package['重量']))\n", " return package_dict\n", "\n", "from utils.countryOperator import OperateCountry\n", "from utils.logisticsBill import Billing\n", "from sell.sell_price import call_sell_price_2025, ocean_order_price\n", "from sell.logistic_price.uk_price import uk_ocean_order_price\n", "from sell.logistic_price.jp_price import jp_order_yamato\n", "\n", "if __name__ == '__main__':\n", " sql = \"\"\"SELECT\n", "\t* ,\n", "\tsku.`成本价`\n", " FROM\n", " dwd.dim_erp_sku_package_vol_info t1 \n", " LEFT JOIN ods.stg_bayshop_litfad_sku sku ON t1.erp_sku = sku.SKU\n", " WHERE\n", " NOT EXISTS ( SELECT 1 FROM ads.sku_order_compare t2 WHERE t1.erp_sku = t2.SKU ) \n", " AND id >= %s \n", " AND id <= %s\n", " AND `状态` = '启用'\"\"\"\n", " au_opCountry = OperateCountry(\"AU\")\n", " fr_opCountry = OperateCountry('FR')\n", " de_opCountry = OperateCountry('DE')\n", " es_opCountry = OperateCountry('ES')\n", " it_opCountry = OperateCountry('IT')\n", " with MySQLconnect('ads') as db:\n", " for i in tqdm(range(0,150)):\n", " print(i,\"开始\")\n", " dfsql = sql % (i*100000, (i+1)*100000-1)\n", " df = pd.read_sql(dfsql, db.engine())\n", " if len(df) == 0:\n", " continue\n", " # 包裹数据格式化\n", " df['erp_package_vol'] = df.apply(lambda x: to_package(x['erp_package_vol']), axis=1)\n", " # df['售价'] = df.apply(lambda x: call_sell_and_order_price(x['成本价'], x['erp_package_vol'], \"海运\")[0], axis=1)\n", " # df[['美国海运','美国海运类型']] = df.apply(lambda x: us_ocean_order_price(x['erp_package_vol']), axis=1, result_type='expand')\n", " # df[['英国海运','英国海运类型']] = df.apply(lambda x: uk_ocean_order_price(x['erp_package_vol']), axis=1, result_type='expand')\n", " \n", " \n", " def process_row(x):\n", " # 单行处理逻辑\n", " try:\n", "\n", " sell_price=x['产品售价']\n", " logitcs = x['物流分摊']\n", " # print(\"售价计算完成\")\n", " us_price, us_type = ocean_order_price(x['erp_package_vol'])\n", " # print(\"美国海运计算完成\")\n", " uk_price, uk_type = uk_ocean_order_price(x['erp_package_vol'],logitcs)\n", " jp_price,jp_type = jp_order_yamato(x['erp_package_vol'], sell_price)\n", " # print(\"英国海运计算完成\")\n", " if x['erp_sku'] ==\"2207384162\":\n", " au_price2 = Billing(\"1\",au_opCountry,x['erp_package_vol'],\"2911\",company_name=None,head_type=1,beizhu='1').tail_amount[0]\n", " print(au_price2)\n", " au_price = Billing(\"1\",au_opCountry,x['erp_package_vol'],\"2911\",company_name=None,head_type=1,beizhu='1').tail_amount[0]\n", " fr_price = Billing(\"1\",fr_opCountry,x['erp_package_vol'],\"75000\",company_name=None,head_type=1,beizhu='1').tail_amount[0]\n", " de_price = Billing(\"1\",de_opCountry,x['erp_package_vol'],\"12489\",company_name=None,head_type=1,beizhu='1').tail_amount[0]\n", " es_price = Billing(\"1\",es_opCountry,x['erp_package_vol'],\"28002\",company_name=None,head_type=1,beizhu='1').tail_amount[0]\n", " it_price = Billing(\"1\",it_opCountry,x['erp_package_vol'],\"20143\",company_name=None,head_type=1,beizhu='1').tail_amount[0]\n", " 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]\n", " except Exception as e:\n", " return [None, None, None, None, None,None, None, None, None, None,None, None]\n", "\n", " # 用 dict 更稳妥\n", " rows = df.to_dict(orient='records') # 转为 list of dict\n", " with ThreadPoolExecutor(max_workers=50) as executor:\n", " results = list(executor.map(process_row, rows))\n", " # 组装结果\n", " result_df = pd.DataFrame(results, columns=['售价', '美国海运', '美国海运类型', '英国海运', '英国海运类型','日本','日本类型','澳洲','法国Zone4','德国Zone2','西班牙','意大利'])\n", " df = pd.concat([df.reset_index(drop=True), result_df], axis=1)\n", "\n", " # 清空临时表\n", " db.cur.execute(\"TRUNCATE TABLE ads.temp_sku_order_compare;\")\n", " print(\"临时表清空完成\")\n", "\n", " # 组装需要输出的字段\n", " df = df.rename(columns={\n", " 'erp_package_vol':'包裹数据'\n", " })\n", "\n", " columns_needed = ['SKU', '售价','包裹数据', '美国海运', '美国海运类型', '英国海运', '英国海运类型','日本','日本类型','澳洲','法国Zone4','德国Zone2','西班牙','意大利']\n", " df_out = df[columns_needed]\n", " # 写入当前批次数据\n", " df_out.to_sql(\n", " \"temp_sku_order_compare\",\n", " db.eng,\n", " if_exists='append',\n", " index=False,\n", " method='multi',\n", " chunksize=500 # 分批写入\n", " )\n", "\n", " print(\"当前批次数据写入完成\")\n", " # 更新主表\n", " update_sql = \"\"\"\n", " REPLACE INTO ads.sku_order_compare SELECT * FROM ads.temp_sku_order_compare\n", " \"\"\"\n", " db.cur.execute(update_sql)\n", " print(\"主表更新完成\")\n", " db.con.commit()\n", " print(i,\"结束\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "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.\n", " df = pd.read_sql(sql, conn)\n" ] } ], "source": [ "from utils.countryOperator import OperateCountry\n", "from utils.logisticsBill import Billing,BillFactory\n", "from utils.gtools import MySQLconnect\n", "from tqdm import tqdm\n", "import pandas as pd\n", "from utils.Package import Package, Package_group\n", "sql = \"\"\"\n", "SELECT\n", "\torder_id,\n", "\tpostcode,\n", "\tpackage,\n", "\tlength,\n", "\twidth,\n", "\thight,\n", "\tweight\n", "FROM\n", "\torder_list ol LEFT JOIN parcel ON ol.order_id = parcel.订单号\n", "\tLEFT JOIN package_vol_info pvi ON parcel.`包裹号` = pvi.package\n", "WHERE\n", "site_name = \"Litfad\"\n", "AND delivery_country REGEXP \"United Kingdom\"\n", "AND order_date >=\"2025-03-01\"\n", "AND fund_status NOT REGEXP \"等待\"\n", "AND length>0\n", "AND weight>0\n", "\n", "\"\"\"\n", "with MySQLconnect('ods') as db:\n", " conn = db.connect()\n", " df = pd.read_sql(sql, conn)\n", "\n", "df_group = df.groupby(['order_id'])\n", "opCountry = OperateCountry(\"UK\")\n", "bills = BillFactory()\n", "index = 0\n", "for order_id, group in df_group:\n", " index+=1\n", " packages = Package_group()\n", " postcode= group['postcode'].iloc[0]\n", " for i, row in group.iterrows():\n", " package = Package(row['package'], row['length'], row['width'], row['hight'], row['weight'])\n", " packages.add_package(package)\n", " bill = bills.create_bill(\"1\",opCountry,packages,postcode,company_name=\"智谷-DPD\",head_type=1,beizhu=index)\n", " bills.add_bill(bill)\n", "df_bill = bills.bills_to_df()\n", " \n", "df_bill.to_excel(\"英国账单.xlsx\")\n", " " ] } ], "metadata": { "kernelspec": { "display_name": "base", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.5" } }, "nbformat": 4, "nbformat_minor": 2 }