logistics/utils/countryOperator.py

171 lines
7.8 KiB
Python
Raw 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 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)