833 lines
33 KiB
Python
833 lines
33 KiB
Python
""" 欧洲国家尾端物流模块实现类"""
|
||
from pathlib import Path
|
||
import re
|
||
|
||
import pandas
|
||
from logisticsClass.logisticsBaseClass import LogisticsType, TailLogistics
|
||
"""
|
||
port:NL(default)
|
||
currency:str = 'EUR'
|
||
logistics_type:LogisticsType (快递,卡派)
|
||
"""
|
||
|
||
# DPD-ASL 欧洲国家逻辑基类
|
||
class DPDASLLogistics(TailLogistics):
|
||
"""DPD-ASL"""
|
||
company = "DPD-ASL" # DPD_ASL,荷兰发件,欧洲地区默认港口
|
||
currency = "EUR"
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = None
|
||
self.overweight = 2.89
|
||
self.bigpackage = 44.5
|
||
self.remote_fee = None
|
||
self.fuel_rate = 0.13
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
raise NotImplementedError("Subclasses must implement remote calculation.")
|
||
def calculate_fee(self,packages,postcode):
|
||
"""计算快递费用"""
|
||
detail_amount = {
|
||
"base":0.00,
|
||
"overweight":0.00,
|
||
"bigpackage":0.00,
|
||
"remote":0.00,
|
||
"fuel":0.00,
|
||
"tail_amount":0.00
|
||
}
|
||
isremote = self.is_remote(postcode)
|
||
if isremote == "邮编格式不合法":
|
||
detail_amount['tail_amount'] = 99999
|
||
return detail_amount
|
||
for package in packages: # 逐个处理列表中的每个包裹
|
||
# if package.weight > 31500 or package.girth > 350 or package.fst_size > 200:
|
||
# detail_amount['tail_amount'] = 99999
|
||
# return detail_amount
|
||
detail_amount['base'] += self.base_fee
|
||
detail_amount['remote'] +=self.remote_fee* isremote
|
||
detail_amount['overweight'] += self.overweight if package.weight >= 20000 else 0
|
||
if package.fst_size >=175 or package.weight >= 30000 or package.girth >= 300:
|
||
detail_amount['bigpackage'] += self.bigpackage
|
||
for key in detail_amount:
|
||
if key != 'tail_amount' and key != 'fuel':
|
||
detail_amount['fuel'] += detail_amount[key] * self.fuel_rate
|
||
detail_amount['tail_amount'] += detail_amount[key]
|
||
detail_amount['tail_amount'] +=detail_amount['fuel']
|
||
return detail_amount
|
||
# DPDASL 德国实现
|
||
class DPDASLLogistics_DE(DPDASLLogistics):
|
||
country_code = 'DE'
|
||
country = 'Germany'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = 7.1
|
||
self.remote_fee = 12
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
if not re.match(r'^\d{5}$', postcode):
|
||
return "邮编格式不合法"
|
||
remote_postcodes = ["18565","25845-25847","25849","25859","25863","25869","25929-25933","25938-25942",
|
||
"25946-25949","25952-25955","25980","25961-25970","25985-25986","25988-25990","25992-25994",
|
||
"25996-25999","26465","26474","26486","26548","26571","26579","26757","27498","83256"
|
||
]
|
||
postcodes = []
|
||
for code in remote_postcodes:
|
||
if '-' in code:
|
||
start,end = code.split('-')
|
||
postcodes.extend(list(range(int(start),int(end)+1)))
|
||
else:
|
||
postcodes.append(int(code))
|
||
return 1 if postcode in postcodes else 0
|
||
# DPDASL 法国实现
|
||
class DPDASLLogistics_FR(DPDASLLogistics):
|
||
country_code = 'FR'
|
||
country = 'France'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = 10.2
|
||
self.remote_fee = 22.5
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
if not re.match(r'^\d{5}$', postcode):
|
||
return "邮编格式不合法"
|
||
if postcode.startswith("20"):
|
||
return 1
|
||
remove_postcodes = ["17111","17123","17190","17310","17370","17410","17480","17550","17580","17590","17630","17650",
|
||
"17670","17740","17840","17880","17940","56360","56590","56780","56840","85330","85350"]
|
||
return 1 if postcode in remove_postcodes else 0
|
||
# DPDASL 西班牙实现
|
||
class DPDASLLogistics_ES(DPDASLLogistics):
|
||
country_code = 'ES'
|
||
country = 'Spain'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = 11.9
|
||
self.remote_fee = 34
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
if not re.match(r'^\d{5}$', postcode):
|
||
return "邮编格式不合法"
|
||
if postcode.startswith("07") or postcode.startswith("35") or postcode.startswith("38"):
|
||
return 1
|
||
else:
|
||
return 0
|
||
# DPDASL 荷兰实现
|
||
class DPDASLLogistics_NL(DPDASLLogistics):
|
||
country_code = 'NL'
|
||
country = 'Netherlands'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = 6.9
|
||
self.remote_fee = 7.5
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
postcode_str = postcode[:4]
|
||
postcode_str = int(postcode_str)
|
||
remote_postcodes = ["1156","1791-1797","8881-8884","8891-8897","8899","9161-9164","9166"]
|
||
postcodes = []
|
||
for code in remote_postcodes:
|
||
if '-' in code:
|
||
start,end = code.split('-')
|
||
postcodes.extend(list(range(int(start),int(end)+1)))
|
||
else:
|
||
postcodes.append(int(code))
|
||
return 1 if postcode_str in postcodes else 0
|
||
# DPDASL 意大利实现
|
||
class DPDASLLogistics_IT(DPDASLLogistics):
|
||
country_code = 'IT'
|
||
country = 'Italy'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = 11.3
|
||
self.remote_fee=20.65
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
if not re.match(r'^\d{5}$', postcode):
|
||
return "邮编格式不合法"
|
||
remote_postcodes = ["04020","04027","07024","07042","07046","09014",
|
||
"25050","30010","30012","30100","30121-30126","30131-30133","30135", "30141","57030-57039","58010","58012-58013","58018-58019","71040","80070-80071",
|
||
"80073-80077","80079","90010","91017", "91023","92010","98050", "98052","98055", "90010-90151","91010-91100","92010-92100","93010-93100",
|
||
"94010-94100","95010-95127","96010-96100", "97010-97100", "98020-98168","08010-08100","09010-09049","09070-09099","09100","09124","09126","09170"
|
||
]
|
||
postcodes = []
|
||
for code in remote_postcodes:
|
||
if '-' in code:
|
||
start,end = code.split('-')
|
||
postcodes.extend(list(range(int(start),int(end)+1)))
|
||
else:
|
||
postcodes.append(int(code))
|
||
return 1 if postcode in postcodes else 0
|
||
# DPDASL 葡萄牙实现
|
||
class DPDASLLogistics_PT(DPDASLLogistics):
|
||
country_code = 'PT'
|
||
country = 'Portugal'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = 13.1
|
||
self.remote_fee=52
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
postcode_str = postcode[:4]
|
||
postcode_str = int(postcode_str)
|
||
remote_postcodes = ["9500-9999","9000-9499"]
|
||
postcodes = []
|
||
for code in remote_postcodes:
|
||
if '-' in code:
|
||
start,end = code.split('-')
|
||
postcodes.extend(list(range(int(start),int(end)+1)))
|
||
else:
|
||
postcodes.append(int(code))
|
||
return 1 if postcode_str in postcodes else 0
|
||
# DPDASL 比利时实现
|
||
class DPDASLLogistics_BE(DPDASLLogistics):
|
||
country_code = 'BE'
|
||
country = 'Belgium'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = 8.1
|
||
self.remote_fee=0
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
if not re.match(r'^\d{4}$', postcode):
|
||
return "邮编格式不合法"
|
||
return 0
|
||
|
||
|
||
# DPD-ZG 欧洲国家逻辑基类
|
||
class DPDZGLogistics(TailLogistics):
|
||
"""DPD-智谷"""
|
||
company = "DPD-ZG" # DPD-ZG,可以海运可以空运,海运港口NL,空运港口AMS
|
||
currency = "EUR"
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee:list #[5,10,30]
|
||
self.operate_rate = 0.18
|
||
self.fuel_rate = 0.125
|
||
self.remote_fee:float
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
raise NotImplementedError("Subclasses must implement remote calculation.")
|
||
def calculate_fee(self,packages,postcode):
|
||
"""计算快递费用"""
|
||
detail_amount = {
|
||
"base":0.00,
|
||
"operate":0.00,
|
||
"remote":0.00,
|
||
"fuel":0.00,
|
||
"tail_amount":0.00
|
||
}
|
||
isremote = self.is_remote(postcode)
|
||
if isremote == "邮编格式不合法":
|
||
detail_amount['tail_amount'] = 99999
|
||
return detail_amount
|
||
for package in packages: # 逐个处理列表中的每个包裹
|
||
# if package.weight > 31500 or package.girth > 300 or package.fst_size >175:
|
||
# detail_amount['tail_amount'] = 99999
|
||
# return detail_amount
|
||
if package.weight <5000:
|
||
detail_amount['base'] += self.base_fee[0]
|
||
elif package.weight < 10000:
|
||
detail_amount['base'] += self.base_fee[1]
|
||
else:
|
||
detail_amount['base'] += self.base_fee[2]
|
||
detail_amount['remote'] += float(self.remote_fee) * float(isremote)
|
||
detail_amount['operate'] += package.weight/1000 * self.operate_rate
|
||
for key in detail_amount:
|
||
if key != 'tail_amount' and key != 'fuel':
|
||
detail_amount['fuel'] += detail_amount[key] * self.fuel_rate
|
||
detail_amount['tail_amount'] += detail_amount[key]
|
||
detail_amount['tail_amount'] +=detail_amount['fuel']
|
||
return detail_amount
|
||
# DPD-ZG 德国实现
|
||
class DPDZGLogistics_DE(DPDZGLogistics):
|
||
country_code = 'DE'
|
||
country = 'Germany'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = [7.72,8.83,11.67]
|
||
self.remote_fee=11.5
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
if not re.match(r'^\d{5}$', postcode):
|
||
return "邮编格式不合法"
|
||
remote_postcodes = ["18565","25845-25847","25849","25859","25863","25869","25929-25933","25938-25942",
|
||
"25946-25949","25952-25955","25980","25961-25970","25985-25986","25988-25990","25992-25994",
|
||
"25996-25999","26465","26474","26486","26548","26571","26579","26757","27498","83256"
|
||
]
|
||
postcodes = []
|
||
for code in remote_postcodes:
|
||
if '-' in code:
|
||
start,end = code.split('-')
|
||
postcodes.extend(list(range(int(start),int(end)+1)))
|
||
else:
|
||
postcodes.append(int(code))
|
||
return 1 if postcode in postcodes else 0
|
||
# DPD-ZG 法国实现
|
||
class DPDZGLogistics_FR(DPDZGLogistics):
|
||
country_code = 'FR'
|
||
country = 'France'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = [10.77,11.92,14.03]
|
||
self.remote_fee= 18.5
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
if not re.match(r'^\d{5}$', postcode):
|
||
return "邮编格式不合法"
|
||
if postcode.startswith("20"):
|
||
return 1
|
||
remove_postcodes = ["17111","17123","17190","17310","17370","17410","17480","17550","17580","17590","17630","17650",
|
||
"17670","17740","17840","17880","17940","56360","56590","56780","56840","85330","85350"]
|
||
return 1 if postcode in remove_postcodes else 0
|
||
# DPD-ZG 西班牙实现
|
||
class DPDZGLogistics_SP(DPDZGLogistics):
|
||
country_code = 'ES'
|
||
country = 'Spain'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = [12.1,13.17,15.46]
|
||
self.remote_fee= 32
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
if not re.match(r'^\d{5}$', postcode):
|
||
return "邮编格式不合法"
|
||
if postcode.startswith("07") or postcode.startswith("35") or postcode.startswith("38"):
|
||
return 1
|
||
else:
|
||
return 0
|
||
# DPD-ZG 意大利实现
|
||
class DPDZGLogistics_IT(DPDZGLogistics):
|
||
country_code = 'IT'
|
||
country = 'Italy'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = [13.69,14.75,17.27]
|
||
self.remote_fee=19.5
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
if not re.match(r'^\d{5}$', postcode):
|
||
return "邮编格式不合法"
|
||
remote_postcodes = ["04020","04027","07024","07042","07046","09014",
|
||
"25050","30010","30012","30100","30121-30126","30131-30133","30135", "30141","57030-57039","58010","58012-58013","58018-58019","71040","80070-80071",
|
||
"80073-80077","80079","90010","91017", "91023","92010","98050", "98052","98055", "90010-90151","91010-91100","92010-92100","93010-93100",
|
||
"94010-94100","95010-95127","96010-96100", "97010-97100", "98020-98168","08010-08100","09010-09049","09070-09099","09100","09124","09126","09170"
|
||
]
|
||
postcodes = []
|
||
for code in remote_postcodes:
|
||
if '-' in code:
|
||
start,end = code.split('-')
|
||
postcodes.extend(list(range(int(start),int(end)+1)))
|
||
else:
|
||
postcodes.append(int(code))
|
||
return 1 if postcode in postcodes else 0
|
||
# DPD-ZG 荷兰实现
|
||
class DPDZGLogistics_NL(DPDZGLogistics):
|
||
country_code = 'NL'
|
||
country = 'Netherlands'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = [8.88,9.83,11.62]
|
||
self.remote_fee=7.5
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
postcode_str = postcode[:4]
|
||
postcode_str = int(postcode_str)
|
||
remote_postcodes = ["1156","1791-1797","8881-8884","8891-8897","8899","9161-9164","9166"]
|
||
postcodes = []
|
||
for code in remote_postcodes:
|
||
if '-' in code:
|
||
start,end = code.split('-')
|
||
postcodes.extend(list(range(int(start),int(end)+1)))
|
||
else:
|
||
postcodes.append(int(code))
|
||
return 1 if postcode_str in postcodes else 0
|
||
# DPD-ZG 葡萄牙实现
|
||
class DPDZGLogistics_PT(DPDZGLogistics):
|
||
country_code = 'PT'
|
||
country = 'Portugal'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = [8.11,9.27,10.98]
|
||
self.remote_fee=49
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
postcode_str = postcode[:4]
|
||
postcode_str = int(postcode_str)
|
||
remote_postcodes = ["9500-9999","9000-9499"]
|
||
postcodes = []
|
||
for code in remote_postcodes:
|
||
if '-' in code:
|
||
start,end = code.split('-')
|
||
postcodes.extend(list(range(int(start),int(end)+1)))
|
||
else:
|
||
postcodes.append(int(code))
|
||
return 1 if postcode_str in postcodes else 0
|
||
# DPD-ZG 比利时实现
|
||
class DPDZGLogistics_BE(DPDZGLogistics):
|
||
country_code = 'BE'
|
||
country = 'Belgium'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.base_fee = [8.62,9.72,11.51]
|
||
self.remote_fee=0
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
# 先判断邮编是否合法
|
||
if not re.match(r'^\d{4}$', postcode):
|
||
return "邮编格式不合法"
|
||
return 0
|
||
|
||
|
||
# 卡派-ASL 欧洲各国基类
|
||
class KPASLLogistics(TailLogistics):
|
||
"""卡派—ASL"""
|
||
company = "卡派-ASL" # 欧洲国家的卡派
|
||
currency = "EUR"
|
||
logistics_type = LogisticsType.LTL
|
||
|
||
parent_current_directory = Path(__file__).parent.parent
|
||
price_path = parent_current_directory.joinpath("data")
|
||
_price_files = price_path.joinpath("欧洲卡派.xlsx")
|
||
ltl_cost = None
|
||
def __new__(cls):
|
||
"""实现单例模式,只加载一次文件"""
|
||
if cls.ltl_cost is None:
|
||
cls.ltl_cost = pandas.read_excel(cls._price_files,sheet_name="DHL卡派IP报价")
|
||
return super().__new__(cls)
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.fuel_rate = 0.08
|
||
def calculate_fee(self,packages,postcode):
|
||
detail_amount = {
|
||
"base":0.00,
|
||
"fuel":0.00,
|
||
"tail_amount":0.00
|
||
}
|
||
postcode = str(postcode)
|
||
postcode_str = postcode[:2]
|
||
bill_weight = 0
|
||
for package in packages:
|
||
bill_weight +=package.weight/1000
|
||
base_df = self.ltl_cost[(self.ltl_cost['Country']==self.country_code)&(self.ltl_cost['Postalcode']==postcode_str)]
|
||
if base_df.empty:
|
||
detail_amount['tail_amount'] = 99999
|
||
return detail_amount
|
||
detail_amount['base'] = base_df['1 IP'].iloc[0]
|
||
detail_amount['fuel'] = detail_amount['base'] * self.fuel_rate
|
||
detail_amount['tail_amount'] = detail_amount['base'] + detail_amount['fuel']
|
||
return detail_amount
|
||
# ASL卡派德国
|
||
class KPASLLogistics_DE(KPASLLogistics):
|
||
country_code = 'DE'
|
||
country = 'Germany'
|
||
def __init__(self):
|
||
super().__init__()
|
||
def calculate_fee(self,packages,postcode):
|
||
return super().calculate_fee(packages,postcode)
|
||
# ASL卡派法国
|
||
class KPASLLogistics_FR(KPASLLogistics):
|
||
country_code = 'FR'
|
||
country = 'France'
|
||
def __init__(self):
|
||
super().__init__()
|
||
def calculate_fee(self,packages,postcode):
|
||
return super().calculate_fee(packages,postcode)
|
||
# ASL卡派西班牙
|
||
class KPASLLogistics_SP(KPASLLogistics):
|
||
country_code = 'ES'
|
||
country = 'Spain'
|
||
def __init__(self):
|
||
super().__init__()
|
||
def calculate_fee(self,packages,postcode):
|
||
return super().calculate_fee(packages,postcode)
|
||
|
||
# 卡派-GEL 欧洲各国基类
|
||
class KPGELLogistics(TailLogistics):
|
||
"""卡派—GEL
|
||
6000抛重,计费重
|
||
"""
|
||
company = "卡派-GEL" # 欧洲国家的卡派
|
||
currency = "EUR"
|
||
logistics_type = LogisticsType.LTL
|
||
|
||
parent_current_directory = Path(__file__).parent.parent
|
||
price_path = parent_current_directory.joinpath("data")
|
||
_price_files = price_path.joinpath("欧洲卡派-GEL.xlsx")
|
||
base_cost = None
|
||
def __new__(cls):
|
||
"""实现单例模式,只加载一次文件"""
|
||
if cls.base_cost is None:
|
||
cls.base_cost = pandas.read_excel(cls._price_files,sheet_name="基础费用")
|
||
return super().__new__(cls)
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.notify = 5 # 预约通知费,必收
|
||
self.remote_fee = 9 # 德国偏远费,17/18/19
|
||
self.multiple_package = 2.5 # 多包裹附加费,超过三个包裹的,每个包裹2.5EUR
|
||
self.responsibility = 1.85 # 责任保险,必收
|
||
self.management = 2 # 订单管理费,必收
|
||
self.toll = 0.024 # 过路过桥费,0.024*分段最大kg
|
||
|
||
def is_remote(self,postcode):
|
||
"""判断分区,德国只有1,法国有123,"""
|
||
raise NotImplementedError("Subclasses must implement remote calculation.")
|
||
|
||
def calculate_fee(self,packages,postcode):
|
||
# 6000计费重
|
||
detail_amount = {
|
||
"base":0.00,
|
||
"notify":0.00,
|
||
"multiple_package":0.00,
|
||
"responsibility":0.00,
|
||
"management":0.00,
|
||
"toll" :0.00,
|
||
"remote":0.00,
|
||
"tail_amount":0.00
|
||
}
|
||
postcode = str(postcode)
|
||
zone = self.is_remote(postcode)
|
||
# 德国偏远费
|
||
if postcode[:2] in ['17','18','19'] and self.country_code =='DE':
|
||
detail_amount['remote'] = self.remote_fee
|
||
|
||
base_df = self.base_cost[(self.base_cost['国家'] == self.country_code) & (self.base_cost['分区'] == zone)]
|
||
if base_df.empty:
|
||
detail_amount['tail_amount'] = 99999
|
||
return detail_amount
|
||
|
||
total_weight = 0
|
||
for package in packages:
|
||
# if (package.fst_size > 320 or package.sed_size>170 or package.trd_size>120) and (self.country_code != "DE"):
|
||
# detail_amount['tail_amount'] = 99999
|
||
# return detail_amount
|
||
# if package.fst_size > 320 or package.sed_size>200 or package.trd_size>120:
|
||
# detail_amount['tail_amount'] = 99999
|
||
# return detail_amount
|
||
billing_weight = max(package.weight/1000,package.get_volume_weight(6000))
|
||
total_weight += billing_weight
|
||
# 基础费用
|
||
weight_limit =[col for col in base_df.columns if isinstance(col, (int, float))]
|
||
for weight in weight_limit:
|
||
if total_weight <= weight:
|
||
detail_amount['base'] = base_df[weight].iloc[0]
|
||
detail_amount['toll'] = self.toll * int(weight)
|
||
break
|
||
if total_weight > 300:
|
||
detail_amount['base'] = detail_amount['base'] * total_weight
|
||
|
||
detail_amount['notify'] = self.notify
|
||
detail_amount['multiple_package'] = self.multiple_package * len(packages) if len(packages) > 3 else 0
|
||
detail_amount['responsibility'] = self.responsibility
|
||
detail_amount['management'] = self.management
|
||
for key in detail_amount:
|
||
if key != 'tail_amount':
|
||
detail_amount['tail_amount'] += detail_amount[key]
|
||
return detail_amount
|
||
# GEL卡派德国
|
||
class KPGELLogistics_DE(KPGELLogistics):
|
||
country_code = 'DE'
|
||
country = 'Germany'
|
||
def __init__(self):
|
||
super().__init__()
|
||
def is_remote(self,postcode):
|
||
return 1
|
||
def calculate_fee(self,packages,postcode):
|
||
return super().calculate_fee(packages,postcode)
|
||
# GEL卡派法国
|
||
class KPGELLogistics_FR(KPGELLogistics):
|
||
country_code = 'FR'
|
||
country = 'France'
|
||
def __init__(self):
|
||
super().__init__()
|
||
def is_remote(self, postcode):
|
||
postcode = str(postcode)
|
||
postcode_str = postcode[:2]
|
||
if postcode_str in ["75","78","91","92","93","94","95",]:
|
||
return 1
|
||
elif postcode_str in [
|
||
"01", "02", "03", "08", "10", "14", "16", "17", "18","21", "22", "23", "25", "27", "28", "29",
|
||
"35", "36", "37", "39", "41", "42", "44", "45","49", "50", "51", "52", "53", "54", "55", "56",
|
||
"57","58", "59", "60", "61", "62", "63","67", "68", "69", "70", "71", "72", "73", "74",
|
||
"76", "77", "79", "80","85", "86", "87", "88", "89", "90"
|
||
]:
|
||
return 2
|
||
elif postcode_str in [
|
||
"04", "05", "06", "07", "09", "11", "12", "13", "15", "19", "24", "26",
|
||
"30", "31", "32", "33", "34", "38", "40", "43", "46", "47", "48",
|
||
"64", "65", "66", "81", "82", "83", "84"
|
||
]:
|
||
return 3
|
||
|
||
def calculate_fee(self,packages,postcode):
|
||
return super().calculate_fee(packages,postcode)
|
||
# GEL卡派西班牙
|
||
class KPGELLogistics_SP(KPGELLogistics):
|
||
country_code = 'ES'
|
||
country = 'Spain'
|
||
def __init__(self):
|
||
super().__init__()
|
||
|
||
def is_remote(self, postcode):
|
||
postcode = str(postcode)
|
||
if postcode.startswith("07"):
|
||
return 2
|
||
else:
|
||
return 1
|
||
def calculate_fee(self,packages,postcode):
|
||
return super().calculate_fee(packages,postcode)
|
||
# GEL卡派意大利
|
||
class KPGELLogistics_IT(KPGELLogistics):
|
||
country_code = 'IT'
|
||
country = 'Italy'
|
||
def __init__(self):
|
||
super().__init__()
|
||
def is_remote(self, postcode):
|
||
postcode = str(postcode)
|
||
postcode_str = postcode[:2]
|
||
if 10<=int(postcode_str)<=59:
|
||
return 1
|
||
elif 0<=int(postcode_str)<=6 or postcode =="6086":
|
||
return 2
|
||
elif 7<=int(postcode_str)<=9 or postcode =="8798":
|
||
return 3
|
||
|
||
def calculate_fee(self,packages,postcode):
|
||
return super().calculate_fee(packages,postcode)
|
||
# GEL卡派葡萄牙
|
||
class KPGELLogistics_PT(KPGELLogistics):
|
||
country_code = 'PT'
|
||
country = 'Portugal'
|
||
def __init__(self):
|
||
super().__init__()
|
||
def is_remote(self, postcode):
|
||
return 1
|
||
def calculate_fee(self,packages,postcode):
|
||
return super().calculate_fee(packages,postcode)
|
||
# GEL卡派荷兰
|
||
class KPGELLogistics_NL(KPGELLogistics):
|
||
country_code = 'NL'
|
||
country = 'Netherlands'
|
||
def __init__(self):
|
||
super().__init__()
|
||
def is_remote(self, postcode):
|
||
return 1
|
||
def calculate_fee(self,packages,postcode):
|
||
return super().calculate_fee(packages,postcode)
|
||
# GEL卡派比利时
|
||
class KPGELLogistics_BE(KPGELLogistics):
|
||
country_code = 'BE'
|
||
country = 'Belgium'
|
||
def __init__(self):
|
||
super().__init__()
|
||
def is_remote(self, postcode):
|
||
postcode = int(postcode)
|
||
if 1000<=postcode<=1299:
|
||
return 1
|
||
elif 1300<=postcode<=9999:
|
||
return 2
|
||
def calculate_fee(self,packages,postcode):
|
||
return super().calculate_fee(packages,postcode)
|
||
|
||
# 欧洲商务报价-智谷
|
||
class EURZGLogistics(TailLogistics):
|
||
"""欧洲商务报价-智谷"""
|
||
currency = "EUR"
|
||
company = "EUR-ZG"
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.per_item = None
|
||
self.per_kg = None
|
||
self.limit_kg = None
|
||
self.remote = None
|
||
self.fuel_rate = 0.13
|
||
def is_remote(self,postcode):
|
||
"""判断是否偏远,1偏远0非偏远"""
|
||
raise NotImplementedError("Subclasses must implement remote calculation.")
|
||
def calculate_fee(self,packages,postcode):
|
||
"""计算快递费用"""
|
||
detail_amount = {
|
||
"base":0.00,
|
||
"remote":0.00,
|
||
"fuel":0.00,
|
||
"tail_amount":0.00
|
||
}
|
||
isremote = self.is_remote(postcode)
|
||
if isremote == "邮编格式不合法":
|
||
detail_amount['tail_amount'] = 99999
|
||
return detail_amount
|
||
if isremote == 1:
|
||
detail_amount['remote'] = self.remote
|
||
|
||
for package in packages: # 逐个处理列表中的每个包裹
|
||
# if package.length+package.width+package.height > 150 or package.weight > self.limit_kg*1000:
|
||
# detail_amount['tail_amount'] = 99999
|
||
# return detail_amount
|
||
detail_amount['base'] += self.per_item+self.per_kg*package.weight/1000
|
||
|
||
for key in detail_amount:
|
||
if key != 'tail_amount' and key != 'fuel':
|
||
detail_amount['fuel'] += detail_amount[key] * self.fuel_rate
|
||
detail_amount['tail_amount'] += detail_amount[key]
|
||
detail_amount['tail_amount'] +=detail_amount['fuel']
|
||
return detail_amount
|
||
class EURZGLogistics_DE(EURZGLogistics):
|
||
country_code = 'DE'
|
||
country = 'Germany'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.per_item = 3.71
|
||
self.per_kg = 0.87
|
||
self.limit_kg = 30
|
||
self.remote = 0
|
||
def is_remote(self,postcode):
|
||
return 0
|
||
|
||
class EURZGLogistics_FR(EURZGLogistics):
|
||
country_code = 'FR'
|
||
country = 'France'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.per_item = [3.8,5.08,5.99,7.66]
|
||
self.per_kg = 1.07
|
||
self.limit_kg = 30
|
||
self.remote = [5.5,14]
|
||
def calculate_fee(self,packages,postcode):
|
||
"""计算快递费用"""
|
||
detail_amount = {
|
||
"base":0.00,
|
||
"remote":0.00,
|
||
"fuel":0.00,
|
||
"tail_amount":0.00
|
||
}
|
||
isremote = self.is_remote(postcode)
|
||
if isremote == "邮编格式不合法":
|
||
detail_amount['tail_amount'] = 99999
|
||
return detail_amount
|
||
|
||
for package in packages: # 逐个处理列表中的每个包裹
|
||
# if package.length+package.width+package.height > 150 or package.weight > self.limit_kg*1000:
|
||
# detail_amount['tail_amount'] = 99999
|
||
# return detail_amount
|
||
if package.weight <=500:
|
||
per_item = self.per_item[0]
|
||
elif package.weight <=2000:
|
||
per_item = self.per_item[1]
|
||
elif package.weight <=1500:
|
||
per_item = self.per_item[2]
|
||
else:
|
||
per_item = self.per_item[3]
|
||
detail_amount['base'] += per_item+self.per_kg*package.weight/1000
|
||
if isremote == 1:
|
||
detail_amount['remote'] += self.remote[0]*package.weight/1000+9.5
|
||
elif isremote == 2:
|
||
detail_amount['remote'] += self.remote[1]*package.weight/1000+9.5
|
||
|
||
for key in detail_amount:
|
||
if key != 'tail_amount' and key != 'fuel':
|
||
detail_amount['fuel'] += detail_amount[key] * self.fuel_rate
|
||
detail_amount['tail_amount'] += detail_amount[key]
|
||
detail_amount['tail_amount'] +=detail_amount['fuel']
|
||
return detail_amount
|
||
def is_remote(self,postcode):
|
||
postcode = str(postcode)
|
||
postcode_str = int(postcode[:3])
|
||
if 971<=postcode_str <= 976:
|
||
return 1
|
||
elif 984<=postcode_str <= 988:
|
||
return 2
|
||
return 0
|
||
|
||
class EURZGLogistics_IT(EURZGLogistics):
|
||
country_code = 'IT'
|
||
country = 'Italy'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.per_item = 5.74
|
||
self.per_kg = 1.38
|
||
self.limit_kg = 30
|
||
self.remote = 6
|
||
def is_remote(self,postcode):
|
||
remote_list = ["51024","67020", "67030", "67013", "67049","39030", "39032", "39040", "39043", "39054", "39058","98050", "98055","85046","89030", "89040", "89012", "89049", "89043",
|
||
"80051", "80071", "80072", "80073", "80074", "80075", "80076", "80077", "80079", "80081",
|
||
"38041", "38089", "38095", "38036", "38037", "38077", "38048", "38029", "38010", "38071",
|
||
"87070", "87051", "87035", "87020", "87066", "87073", "87059", "87035", "87014", "87015", "57034", "57031", "57032", "57037", "57038",
|
||
"64020","64031", "64033", "64030", "64037", "64042", "64043", "64010", "64010", "64010", "64010","9014","86021", "86027", "86043", "86029", "86016","50034","23031", "23020", "23010", "23023", "23029", "23030", "23041","30142", "30133", "30141", "30124", "30126","16048", "16046", "16032", "16039","63096","91023", "91017",
|
||
"48013","62024", "62025","65010","33040", "33020", "33090", "33014", "33080","88822", "88823", "88825","17030", "17034", "17046", "17037", "17048","07046", "07024","15060", "15056", "15050","71023", "71051","42035","82024", "82028",
|
||
"41045","13010", "13019", "13028", "13030","32041", "32010", "32030","58019", "58012", "58044","43025","45010","19025", "19020","30124", "30133", "30141", "30142","90051","13888", "13884","04025", "04027", "04031",
|
||
"29031","53030", "53024","66040", "24014", "84050", "58019", "58012","62024", "62025","04025", "04027", "04031","87035", "87020", "16048", "16046","98050","51024","67020", "67030"]
|
||
if postcode in remote_list:
|
||
return 1
|
||
else:
|
||
return 0
|
||
|
||
class EURZGLogistics_PT(EURZGLogistics):
|
||
country_code = 'PT'
|
||
country = 'Portugal'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.per_item = 3.71
|
||
self.per_kg = 1.95
|
||
self.limit_kg = 30
|
||
self.remote = 5
|
||
def is_remote(self,postcode):
|
||
postcode = str(postcode)
|
||
if postcode.startswith("9"):
|
||
return 1
|
||
else:
|
||
return 0
|
||
def calculate_fee(self,packages,postcode):
|
||
"""计算快递费用"""
|
||
detail_amount = {
|
||
"base":0.00,
|
||
"remote":0.00,
|
||
"fuel":0.00,
|
||
"tail_amount":0.00
|
||
}
|
||
isremote = self.is_remote(postcode)
|
||
if isremote == "邮编格式不合法":
|
||
detail_amount['tail_amount'] = 99999
|
||
return detail_amount
|
||
|
||
for package in packages: # 逐个处理列表中的每个包裹
|
||
# if package.length+package.width+package.height > 150 or package.weight > self.limit_kg*1000:
|
||
# detail_amount['tail_amount'] = 99999
|
||
# return detail_amount
|
||
detail_amount['base'] += self.per_item+self.per_kg*package.weight/1000
|
||
if isremote == 1:
|
||
detail_amount['remote'] += self.remote*package.weight/1000+15
|
||
for key in detail_amount:
|
||
if key != 'tail_amount' and key != 'fuel':
|
||
detail_amount['fuel'] += detail_amount[key] * self.fuel_rate
|
||
detail_amount['tail_amount'] += detail_amount[key]
|
||
detail_amount['tail_amount'] +=detail_amount['fuel']
|
||
return detail_amount
|
||
|
||
class EURZGLogistics_ES(EURZGLogistics):
|
||
country_code = 'ES'
|
||
country = 'Spain'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.per_item = 3.93
|
||
self.per_kg = 1.85
|
||
self.limit_kg = 30
|
||
self.remote = 99999
|
||
def is_remote(self,postcode):
|
||
postcode = str(postcode)
|
||
postcode_str = postcode[:2]
|
||
if postcode_str in ['07','51','52','35','38']:
|
||
return 1
|
||
else:
|
||
return 0 |