This commit is contained in:
Wenxixi 2025-06-23 16:08:03 +08:00
parent 180b4fda1d
commit 7178520862
13 changed files with 1524 additions and 146 deletions

File diff suppressed because it is too large Load Diff

BIN
data/售价尾端价格.xlsx (Stored with Git LFS)

Binary file not shown.

View File

@ -3,7 +3,7 @@ from enum import Enum
class LogisticsType(Enum): class LogisticsType(Enum):
EXPRESS = '快递' EXPRESS = '快递'
COURIER = '卡派' LTL = '卡派'
OCEAN = '海运' OCEAN = '海运'
AIR = '空运' AIR = '空运'
class PortType(Enum): class PortType(Enum):

View File

@ -239,7 +239,7 @@ class KPASLLogistics(TailLogistics):
"""卡派—ASL""" """卡派—ASL"""
company = "卡派-ASL" # 欧洲国家的卡派 company = "卡派-ASL" # 欧洲国家的卡派
currency = "EUR" currency = "EUR"
logistics_type = LogisticsType.COURIER logistics_type = LogisticsType.LTL
parent_current_directory = Path(__file__).parent.parent parent_current_directory = Path(__file__).parent.parent
price_path = parent_current_directory.joinpath("data") price_path = parent_current_directory.joinpath("data")
@ -304,7 +304,7 @@ class KPGELLogistics(TailLogistics):
""" """
company = "卡派-GEL" # 欧洲国家的卡派 company = "卡派-GEL" # 欧洲国家的卡派
currency = "EUR" currency = "EUR"
logistics_type = LogisticsType.COURIER logistics_type = LogisticsType.LTL
parent_current_directory = Path(__file__).parent.parent parent_current_directory = Path(__file__).parent.parent
price_path = parent_current_directory.joinpath("data") price_path = parent_current_directory.joinpath("data")

View File

@ -152,7 +152,7 @@ class KPZGLogistics_UK(TailLogistics):
country = 'United Kingdom' country = 'United Kingdom'
company = '海GB-卡派' company = '海GB-卡派'
currency = 'GBP' currency = 'GBP'
logistics_type = LogisticsType.COURIER logistics_type = LogisticsType.LTL
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.base_dice = { self.base_dice = {
@ -218,7 +218,7 @@ class KPNVlogistics_UK(TailLogistics):
country = 'United Kingdom' country = 'United Kingdom'
company = '卡派-NV' company = '卡派-NV'
currency = 'GBP' currency = 'GBP'
logistics_type = LogisticsType.COURIER logistics_type = LogisticsType.LTL
parent_current_directory = Path(__file__).parent.parent parent_current_directory = Path(__file__).parent.parent
price_path = parent_current_directory.joinpath("data") price_path = parent_current_directory.joinpath("data")
@ -272,7 +272,7 @@ class KPNVlogistics_UK(TailLogistics):
# country = 'United Kingdom' # country = 'United Kingdom'
# company = 'DX-EL' # company = 'DX-EL'
# currency = 'GBP' # currency = 'GBP'
# logistics_type = LogisticsType.COURIER # logistics_type = LogisticsType.LTL
# def __init__(self): # def __init__(self):
# super().__init__() # super().__init__()
# self.base_fee = 0 # self.base_fee = 0

View File

@ -362,7 +362,7 @@ class GIGALogistics_US(TailLogistics):
country = "United States" country = "United States"
country_code = "US" country_code = "US"
company = "大健-GIGA" company = "大健-GIGA"
logistics_type = LogisticsType.COURIER logistics_type = LogisticsType.LTL
parent_current_directory = Path(__file__).parent.parent parent_current_directory = Path(__file__).parent.parent
data_path = parent_current_directory.joinpath("data") data_path = parent_current_directory.joinpath("data")
@ -410,7 +410,7 @@ class CEVALogistics_US(TailLogistics):
country = "United States" country = "United States"
country_code = "US" country_code = "US"
company = "大健-CEVA" company = "大健-CEVA"
logistics_type = LogisticsType.COURIER logistics_type = LogisticsType.LTL
parent_current_directory = Path(__file__).parent.parent parent_current_directory = Path(__file__).parent.parent
data_path = parent_current_directory.joinpath("data") data_path = parent_current_directory.joinpath("data")
@ -503,7 +503,7 @@ class MetroLogistics_US(TailLogistics):
country = "United States" country = "United States"
country_code = "US" country_code = "US"
company = "Metro-SAIR" company = "Metro-SAIR"
logistics_type = LogisticsType.COURIER logistics_type = LogisticsType.LTL
parent_current_directory = Path(__file__).parent.parent parent_current_directory = Path(__file__).parent.parent
data_path = parent_current_directory.joinpath("data") data_path = parent_current_directory.joinpath("data")
@ -617,7 +617,7 @@ class XmilesLogistics_US(TailLogistics):
country = "United States" country = "United States"
country_code = "US" country_code = "US"
company = "XMILES-SAIR" company = "XMILES-SAIR"
logistics_type = LogisticsType.COURIER logistics_type = LogisticsType.LTL
parent_current_directory = Path(__file__).parent.parent parent_current_directory = Path(__file__).parent.parent
data_path = parent_current_directory.joinpath("data") data_path = parent_current_directory.joinpath("data")
@ -700,7 +700,7 @@ class AMWestLogistics_US(TailLogistics):
country = "United States" country = "United States"
country_code = "US" country_code = "US"
company = "AM-美西" company = "AM-美西"
logistics_type = LogisticsType.COURIER logistics_type = LogisticsType.LTL
parent_current_directory = Path(__file__).parent.parent parent_current_directory = Path(__file__).parent.parent
data_path = parent_current_directory.joinpath("data") data_path = parent_current_directory.joinpath("data")
@ -779,7 +779,7 @@ class AMEastLogistics_US(TailLogistics):
country = "United States" country = "United States"
country_code = "US" country_code = "US"
company = "AM-美东" company = "AM-美东"
logistics_type = LogisticsType.COURIER logistics_type = LogisticsType.LTL
parent_current_directory = Path(__file__).parent.parent parent_current_directory = Path(__file__).parent.parent
data_path = parent_current_directory.joinpath("data") data_path = parent_current_directory.joinpath("data")

View File

@ -65,10 +65,13 @@ class SellPriceBase:
price_path = parent_current_directory.joinpath("data") price_path = parent_current_directory.joinpath("data")
_price_files = price_path.joinpath("售价尾端价格.xlsx") _price_files = price_path.joinpath("售价尾端价格.xlsx")
df_2025 = None df_2025 = None
df_2024 = None
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
"""实现单例模式,只加载一次文件""" """实现单例模式,只加载一次文件"""
if cls.df_2024 is None:
cls.df_2024 = pd.read_excel(cls._price_files,sheet_name="2024")
if cls.df_2025 is None: if cls.df_2025 is None:
cls.df_2025 = pd.read_excel(cls._price_files,sheet_name="Sheet1") cls.df_2025 = pd.read_excel(cls._price_files,sheet_name="2025")
return super().__new__(cls) return super().__new__(cls)
def __init__(self, packages, purchase_price, shipping_type, ocean_first_cny, ocean_first_usd, air_first_usd, def __init__(self, packages, purchase_price, shipping_type, ocean_first_cny, ocean_first_usd, air_first_usd,
air_cny_type, air_first_fix, exchange_rate, profit_rate, air_rate,tax_rate): air_cny_type, air_first_fix, exchange_rate, profit_rate, air_rate,tax_rate):
@ -85,26 +88,35 @@ class SellPriceBase:
self.shipping_type = shipping_type # 1为海运0为空运由spu定好的 self.shipping_type = shipping_type # 1为海运0为空运由spu定好的
self.tax_rate = tax_rate # 税率 self.tax_rate = tax_rate # 税率
# 获取对应价格表
def get_fee(self, head_type): # def get_fee_df(self):
mat = MySQLconnect('mat') # if self.df_status == 0:
engine = mat.engine() # self.df_status = 1
# self.mat = MySQLconnect('mat')
# self.engine = self.mat.engine()
# self.adf = pd.read_sql('SELECT * FROM `usps_0814`', self.engine)
# self.bdf = pd.read_sql('SELECT * FROM `uandf_0814`', self.engine)
# self.cdf = pd.read_sql('SELECT * FROM `fedex_2504`', self.engine)
# # 获取对应价格表
# def get_fee(self, head_type,adf,bdf,cdf):
# mat = MySQLconnect('mat')
# engine = mat.engine()
try: # try:
if head_type == 0: # if head_type == 0:
df = pd.read_sql('SELECT * FROM `usps_0814`', engine) # df = self.adf
elif head_type == 1: # elif head_type == 1:
df = pd.read_sql('SELECT * FROM `uandf_0814`', engine) # df = self.bdf
elif head_type == 2: # elif head_type == 2:
df = pd.read_sql('SELECT * FROM `fedex_2504`', engine) # df = self.cdf
else: # else:
df = pd.DataFrame([99999], columns=['错误']) # df = pd.DataFrame([99999], columns=['错误'])
except Exception as e: # except Exception as e:
print(f"发生错误: {e}") # print(f"发生错误: {e}")
df = pd.DataFrame() # df = pd.DataFrame()
finally: # finally:
engine.dispose() # engine.dispose()
return df # return df
# 计算快递费用 # 计算快递费用
def cal_express_fee(self): def cal_express_fee(self):
@ -136,22 +148,19 @@ class SellPriceBase:
ahs_dimension = 0 ahs_dimension = 0
if head_type == 0: if head_type == 0:
try: try:
df = self.get_fee(head_type) express_base_fee = self.df_2024[self.df_2024['oz'] == oz_weight]['最终费用'].iloc[0] / self.profit_rate
express_base_fee = df[df['oz'] == oz_weight]['最终费用'].iloc[0] / self.profit_rate
except: except:
head_type = 1 head_type = 1
# USPSA2/FEDEXA1 # USPSA2/FEDEXA1
if head_type == 1: if head_type == 1:
try: try:
df = self.get_fee(head_type) express_base_fee = self.df_2024[self.df_2024['lbs小'] == lbs_weight]['加权价格'].iloc[0] / self.profit_rate
express_base_fee = df[df['lbs'] == lbs_weight]['加权价格'].iloc[0] / self.profit_rate
except: except:
head_type = 2 head_type = 2
# FEDEX # FEDEX
if head_type == 2: if head_type == 2:
try: try:
df = self.get_fee(head_type) express_base_fee = self.df_2024[self.df_2024['lbs大'] == lbs_weight]['售价尾端价格'].iloc[0]
express_base_fee = df[df['lbs'] == lbs_weight]['售价尾端价格'].iloc[0]
except: except:
express_base_fee = 99999 express_base_fee = 99999
head_type = 3 head_type = 3
@ -358,6 +367,22 @@ class SellPriceBase:
@classmethod @classmethod
def litfad(cls, packages, purchase_price, shipping_type): def litfad(cls, packages, purchase_price, shipping_type):
return cls(
packages, # 单sku包裹数据
purchase_price, # 采购价/成本价
shipping_type, # 1为海运0为空运由spu定好的
ocean_first_cny=1.077, #1.077, # 海运头程单价CNY
ocean_first_usd=1.06, #1.06, # 海运头程单价USD
air_first_usd=0.65, # 空运头程单价USD
air_cny_type=0.093, # 空运头程货型单价CNY
air_first_fix=27.7, # 空运头程固定单价CNY
exchange_rate=7, # 汇率
profit_rate=0.45, #0.45, # 利润系数
air_rate=0.7, # 空运分配占比
tax_rate = 0 # 税率
)
@classmethod
def litfad_2025(cls, packages, purchase_price, shipping_type):
return cls( return cls(
packages, # 单sku包裹数据 packages, # 单sku包裹数据
purchase_price, # 采购价/成本价 purchase_price, # 采购价/成本价

View File

View File

@ -20,7 +20,7 @@ def uk_ocean_order_price(packages,k):
base_fee = 3.7/0.359*1.3-k-0.8*package.get_volume_weight(6000) base_fee = 3.7/0.359*1.3-k-0.8*package.get_volume_weight(6000)
else: else:
base_fee = 999999 base_fee = 999999
if package.fst_size >=100 and package.sed_size >=60 and package.weight >=30000: if package.fst_size >=100 or package.sed_size >=60 or package.weight >=30000:
other_fee1 =45 other_fee1 =45
order_type1 += '大包裹' order_type1 += '大包裹'

View File

@ -19,7 +19,7 @@ def ocean_order_price(packages):
express_type_length = '' express_type_length = ''
for package in packages: for package in packages:
for key, value in ocean_price_dict.items(): for key, value in ocean_price_dict.items():
if package.weight <=key: if max(package.get_volume_weight(8.5), package.weight) <=key:
express_fee+=value express_fee+=value
break break
if package.fst_size>=116 or package.sed_size>=71 or package.girth>=251: if package.fst_size>=116 or package.sed_size>=71 or package.girth>=251:

View File

@ -1,3 +1,4 @@
import json
import math import math
import sys import sys
sys.path.append(r'D:\test\logistics\sell') sys.path.append(r'D:\test\logistics\sell')
@ -26,7 +27,7 @@ def ocean_order_price(packages):
express_type_length = '' express_type_length = ''
for package in packages: for package in packages:
for key, value in ocean_price_dict.items(): for key, value in ocean_price_dict.items():
if package.weight <=key: if max(package.get_volume_weight(8500)*1000, package.weight) <=key:
express_fee+=value express_fee+=value
break break
if package.fst_size>=116 or package.sed_size>=71 or package.girth>=251: if package.fst_size>=116 or package.sed_size>=71 or package.girth>=251:
@ -148,7 +149,7 @@ def call_sell_and_order_price(price, package_dict,head_type):
# 提取字符串中的第一个数字 # 提取字符串中的第一个数字
match = re.search(r"[-+]?\d*\.\d+|\d+", str(value)) match = re.search(r"[-+]?\d*\.\d+|\d+", str(value))
return float(match.group()) if match else 0.0 return float(match.group()) if match else 0.0
package_dict = json.loads(package_dict)
for key, package in package_dict.items(): for key, package in package_dict.items():
package[''] = extract_number(package['']) package[''] = extract_number(package[''])
package[''] = extract_number(package['']) package[''] = extract_number(package[''])
@ -163,7 +164,7 @@ def call_sell_and_order_price(price, package_dict,head_type):
return (0,0,0,0),0,0 return (0,0,0,0),0,0
litfad = SellPriceBase.litfad(packages, price,1) litfad = SellPriceBase.litfad(packages, price,1)
# 修改版本,网站售价 # 修改版本,网站售价
sell_price = litfad.cal_sell_price_2025() sell_price = litfad.cal_sell_price()
# 订单物流费 # 订单物流费
if "" in head_type: if "" in head_type:
order_price, order_type = ocean_order_price(packages) order_price, order_type = ocean_order_price(packages)

View File

@ -259646,7 +259646,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": null,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
@ -259966,8 +259966,7 @@
], ],
"source": [ "source": [
"import pandas as pd\n", "import pandas as pd\n",
"df=pd.read_clipboard()\n", "df=pd.read_clipboard()"
"df"
] ]
}, },
{ {
@ -259975,7 +259974,23 @@
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [] "source": [
"\n",
"D, E, F = [], [], []\n",
"temp_sum = 0\n",
"\n",
"for i in range(len(df)):\n",
" temp_sum += df.loc[i, '未售出']\n",
" if df.loc[i, '已售出'] != 0:\n",
" D.append(df.loc[i, '价格'])\n",
" E.append(temp_sum)\n",
" F.append(df.loc[i, '已售出'])\n",
" temp_sum = 0 # 重置\n",
"\n",
"# 结果\n",
"result = pd.DataFrame({'D': D, 'E': E, 'F': F})\n",
"result.to_clipboard(index=False)"
]
} }
], ],
"metadata": { "metadata": {

View File

@ -30,8 +30,10 @@ class Billing:
self.items: List[BillItem] = [] # 存储账单项 self.items: List[BillItem] = [] # 存储账单项
self.volume_weight = 0 self.volume_weight = 0
self.head_per = 0 self.head_per = 0
self.logistic_type = None
self.add_items_from_operator() self.add_items_from_operator()
def add_item(self, item: BillItem): def add_item(self, item: BillItem):
"""添加账单项""" """添加账单项"""
self.items.append(item) self.items.append(item)
@ -41,7 +43,9 @@ class Billing:
if self.packages is not None or self.postcode is not None: if self.packages is not None or self.postcode is not None:
self.operator.set_packages_and_postcode(self.packages, self.postcode) # 设置包裹信息 self.operator.set_packages_and_postcode(self.packages, self.postcode) # 设置包裹信息
company_name = self.company_name if self.company_name is not None else self.operator.get_min_company() company_name = self.company_name if self.company_name is not None else self.operator.get_min_company()
logistic_type = self.logistic_type if self.logistic_type is not None else self.operator.get_logistic_type(company_name)
self.company_name = company_name self.company_name = company_name
self.logistic_type = logistic_type
# 获取头程费用 # 获取头程费用
head_detail = self.operator.get_ocean_fee() if self.head_type == 1 else self.operator.get_air_fee() head_detail = self.operator.get_ocean_fee() if self.head_type == 1 else self.operator.get_air_fee()
@ -87,7 +91,7 @@ class Billing:
if item.item_type == "尾程" and item.item_detail == "tail_amount": if item.item_type == "尾程" and item.item_detail == "tail_amount":
tailfee = item.amount_usd tailfee = item.amount_usd
return headfee + tailfee return headfee + tailfee
def bill_dict(self): def bill_dict(self):
"""返回账单字典""" """返回账单字典"""
result = {} result = {}