logistics/logisticsClass/logisticsTail_EUR.py

970 lines
37 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

""" 欧洲国家尾端物流模块实现类"""
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.92,8.53,10.3]
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 = [11.27,11.72,13.73]
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.8,13.37,15.16]
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 = [14.19,14.95,16.97]
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.98,9.53,11.32]
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.31,8.97,10.68]
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.82,9.42,11.21]
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_IR(DPDZGLogistics):
country_code = 'IR'
country = 'Ireland'
def __init__(self):
super().__init__()
self.base_fee = [14.1,14.74,16.74]
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 = None
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
self.fuel_rate = 0.0125
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]
self.fuel_rate = 0.0325
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
self.fuel_rate = 0.06
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
self.fuel_rate = 0
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
self.fuel_rate = 0.01
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
class EURZGLogistics_IR(EURZGLogistics):
country_code = 'IR'
country = 'Ireland'
def __init__(self):
super().__init__()
self.per_item = 3.92
self.per_kg = 1.58
self.limit_kg = 30
self.remote = 999999
self.fuel_rate = 0.01
def is_remote(self,postcode):
return 0
# DPD-NV德国始发
class DPDNVLogistics(TailLogistics):
"""DPD-NV"""
currency = "EUR"
company = "DPD-NV"
def __init__(self):
super().__init__()
self.base_20 = None
self.base_31= None
self.oversize = 4.62
self.big_package = 40.15
self.remote = 0
def is_remote(self,postcode):
"""判断是否偏远,1偏远0非偏远"""
raise NotImplementedError("Subclasses must implement remote calculation.")
def calculate_fee(self,packages,postcode):
"""计算快递费用,40kg,250cm长,330cm围长"""
detail_amount = {
"base":0.00,
"oversize":0.00,
"big_package":0.00,
"remote":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.fst_size >= 250 or package.weight >= 40000 or package.girth>=330:
detail_amount['tail_amount'] = 99999
return detail_amount
detail_amount['base'] += self.base_31 if package.weight >= 20000 else self.base_20
if package.fst_size >= 175 or package.weight >= 31500 or package.girth>=300:
detail_amount['big_package'] = self.big_package
elif package.fst_size >= 120 or package.sed_size>=60 or package.volume>=150000:
detail_amount['oversize'] = self.oversize
for key in detail_amount:
if key != 'tail_amount':
detail_amount['tail_amount'] += detail_amount[key]
return detail_amount
class DPDNVLogistics_DE(DPDNVLogistics):
country_code = 'DE'
country = 'Germany'
def __init__(self):
super().__init__()
self.base_20 = 4.3625
self.base_31= 4.6125
def is_remote(self,postcode):
return 0
class DPDNVLogistics_FR(DPDNVLogistics):
country_code = 'FR'
country = 'France'
def __init__(self):
super().__init__()
self.base_20 = 12.2375
self.base_31= 12.4875
def is_remote(self,postcode):
return 0
class DPDNVLogistics_IT(DPDNVLogistics):
country_code = 'IT'
country = 'Italy'
def __init__(self):
super().__init__()
self.base_20 = 14.0375
self.base_31= 14.7375
def is_remote(self,postcode):
return 0
class DPDNVLogistics_PT(DPDNVLogistics):
country_code = 'PT'
country = 'Portugal'
def __init__(self):
super().__init__()
self.base_20 = 18.45
self.base_31= 22.375
def is_remote(self,postcode):
return 0
class DPDNVLogistics_ES(DPDNVLogistics):
country_code = 'ES'
country = 'Spain'
def __init__(self):
super().__init__()
self.base_20 = 14.0375
self.base_31=14.7375
def is_remote(self,postcode):
return 0
class DPDNVLogistics_IR(DPDNVLogistics):
country_code = 'IR'
country = 'Ireland'
def __init__(self):
super().__init__()
self.base_20 = 18.45
self.base_31= 22.375
def is_remote(self,postcode):
return 0