logistics/utils/countryOperator.py

171 lines
7.8 KiB
Python
Raw Permalink Normal View History

2025-06-17 13:40:20 +08:00
from logisticsClass.logisticsBaseClass import HeadLogistics, PortType, TailLogistics,BaseLogistics
from logisticsClass.logisticsTail_EUR import *
from logisticsClass.logisticsHead_EUR import *
from logisticsClass.logisticsTail_US import *
from logisticsClass.logisticsHead_US import *
from logisticsClass.logisticsTail_AU import *
from logisticsClass.logisticsHead_AU import *
from logisticsClass.logisticsTail_UK import *
from logisticsClass.logisticsHead_UK import *
from utils.apply_active_config import apply_active_config
class OperateCountry:
"""操作国家"""
def __init__(self, country_name,port = PortType.DEFAULT,packeges = None, postcode = None):
# head表示头程方式默认海运0为空运
self.country_name = country_name
self.port = port
self.packages = packeges
self.postcode = postcode
self.companies = self.get_tail_subclasses()
def set_packages_and_postcode(self,packages,postcode):
self.packages = packages
self.postcode = postcode
def set_parameter(self,parameter,self_parameter):
"""设置参数,优先考虑函数参数,其次考虑类属性"""
return parameter if parameter is not None else self_parameter
def get_head_class(self,port=None,head_type=None):
"""获取头程类,头程与港口的关联更密切,所以可能一个头程类包含多个国家"""
port = self.set_parameter(port, self.port)
headclass = None
apply_active_config()
subclasses = HeadLogistics.get_open_subclasses()
for cls in subclasses:
if hasattr(cls, "country") and self.country_name in cls.country and cls.port == port and cls.logistics_type.value == head_type:
headclass = cls()
elif hasattr(cls, "country") and self.country_name in cls.country_code and cls.port ==port and cls.logistics_type.value == head_type:
headclass = cls()
if headclass is None:
raise ValueError(f"No head class found for port {port}")
return headclass
def get_air_fee(self, packages=None,port=None):
"""获取空运头程费用"""
packages = self.set_parameter(packages, self.packages)
if packages is None:
raise ValueError("No packages or port provided")
air_class = self.get_head_class(port,"空运")
air_head_fee = air_class.calculate_fee(packages)
return air_head_fee
def get_ocean_fee(self, packages=None,port=None):
"""获取海运头程费用"""
packages = self.set_parameter(packages, self.packages)
if packages is None:
raise ValueError("No packages or port provided")
ocean_class = self.get_head_class(port,"海运")
ocean_head_fee = ocean_class.calculate_fee(packages)
return ocean_head_fee
def get_tail_subclasses(self):
"""获取该国家对应港口的尾端物流实现类列表"""
# 如果没有指定 port, 则返回默认港口的物流公司及其实例
companies = {}
apply_active_config()
subclasses = TailLogistics.get_open_subclasses()
for cls in subclasses:
# 获取符合条件的公司,国家名相等且港口名相等
if hasattr(cls, "country") and self.country_name == cls.country and cls.port == self.port:
if hasattr(cls, "company"):
companies[cls.company] = cls()
else:
continue
elif hasattr(cls, "country") and self.country_name == cls.country_code and cls.port ==self.port:
if hasattr(cls, "company"):
companies[cls.company] = cls()
else:
continue
return companies
def get_all_tail_info(self, packages=None,postcode=None):
"""计算所有物流公司尾端费用"""
packages = self.set_parameter(packages, self.packages)
postcode = self.set_parameter(postcode, self.postcode)
if packages is None or postcode is None:
raise ValueError("No packages or postcode provided")
results = {}
# 存储物流公司及其对应的实例
for company, fee_instance in self.companies.items():
results[company] = self.get_tail_amount(company,packages,postcode)
return results
def get_min_company(self, packages=None,postcode=None):
"""获取最低尾端费用公司"""
packages = self.set_parameter(packages, self.packages)
postcode = self.set_parameter(postcode, self.postcode)
if packages is None or postcode is None:
raise ValueError("No packages or postcode provided")
all_fees = self.get_all_tail_info(packages,postcode)
min_company = min(all_fees, key=all_fees.get)
return min_company
def get_company_class(self, company_name):
"""获取指定物流公司的物流类"""
if company_name not in self.companies:
raise ValueError(f"No such company: {company_name}")
company_class = self.companies[company_name]
return company_class
def get_tail_amount(self, company_name, packages=None,postcode=None):
"""获取指定物流公司的费用"""
packages = self.set_parameter(packages, self.packages)
postcode = self.set_parameter(postcode, self.postcode)
if packages is None or postcode is None:
raise ValueError("No packages or postcode provided")
if company_name not in self.companies:
raise ValueError(f"No such company: {company_name}")
detail_amount = self.get_detail_amount(company_name, packages,postcode)
return round(detail_amount['tail_amount'], 2)
def get_tail_currency(self, company_name):
"""获取指定物流公司的货币"""
company = self.get_company_class(company_name)
return company.currency
def get_logistic_type(self, company_name):
"""获取指定物流公司的物流类型"""
company = self.get_company_class(company_name)
return company.logistics_type.value
def get_detail_amount(self, company_name, packages=None,postcode=None):
"""获取指定物流公司的费用明细"""
packages = self.set_parameter(packages, self.packages)
postcode = self.set_parameter(postcode, self.postcode)
if packages is None or postcode is None:
raise ValueError("No packages or postcode provided")
company_class = self.get_company_class(company_name)
detail_amount = company_class.calculate_fee(packages,postcode)
return detail_amount
def convert_to_usd(self,amount,currency):
"""将货币转换为美元"""
if currency == "USD":
return amount
elif currency == "EUR": # 欧元
return amount * 1.12
elif currency == "GBP": # 英镑
return amount * 1.3
elif currency == "AUD": # 澳元
return amount * 0.7
elif currency == "CAD": # 加元
return amount * 0.75
elif currency == "JPY": # 日元
return amount * 0.007
elif currency == "CNY": # 人民币
return amount * 0.14
elif currency == "HKD": # 港币
return amount * 0.13
def usd_to_currency(self,amount,currency):
"""将美元转换为指定货币"""
if currency == "USD":
return amount
else:
return amount / self.convert_to_usd(1,currency)
def convert_currency(self,amount,current_currency,target_currency):
"""先转美元,再转目标货币"""
if current_currency == "USD":
return self.usd_to_currency(amount,target_currency)
else:
return self.usd_to_currency(self.convert_to_usd(amount,current_currency),target_currency)