修复订单多项统计和海运快慢报价上下文
This commit is contained in:
@@ -127,6 +127,24 @@ def quantity_number(value,intent):
|
||||
return '约'+number(value,6)
|
||||
|
||||
|
||||
def select_timed_rates(rates,slowest=False):
|
||||
"""Compare numeric day ranges within one region, service kind and billing basis."""
|
||||
ranked=[]
|
||||
best={}
|
||||
for rate in rates:
|
||||
match=re.search(r'(?<![\d.])(\d+(?:\.\d+)?)\s*(?:[-—–~~至]\s*(\d+(?:\.\d+)?))?\s*(?:天|days?)',rate['eta'],re.I)
|
||||
if not match:continue
|
||||
low=Decimal(match[1])
|
||||
high=Decimal(match[2] or match[1])
|
||||
if low<=0 or high<low:continue
|
||||
key=(rate['zone'],rate['kind'],rate['unit'],rate['tax'])
|
||||
timing=(high,low) if slowest else (low,high)
|
||||
ranked.append((rate,key,timing))
|
||||
choose=max if slowest else min
|
||||
best[key]=choose(best.get(key,timing),timing)
|
||||
return [rate for rate,key,timing in ranked if timing==best[key]]
|
||||
|
||||
|
||||
def render_rates(intent, book, destinations, remote_fees):
|
||||
from .quote_fees import charge_details
|
||||
from .quote_language import translate_quote
|
||||
@@ -154,35 +172,42 @@ def render_rates(intent, book, destinations, remote_fees):
|
||||
if part and intent.get('metal_chargeable_weight') is not None:
|
||||
billing.update(metal_chargeable_weight=None,metal_scope='partial')
|
||||
rates = match_rates(billing, book, destination)
|
||||
if intent.get('mode') in ('cheapest','fastest') and rates:
|
||||
if intent['mode']=='cheapest':
|
||||
eligible=[r for r in rates if quantity(billing,r) is not None]
|
||||
best={}
|
||||
for rate in eligible:
|
||||
key=(destination['zone'] or rate['zone'],rate['unit'],rate['tax'])
|
||||
value=quantity(billing,rate)*Decimal(rate['price'])+charge_details(billing,rate,fees,book)['cny']
|
||||
best[key]=min(best.get(key,value),value)
|
||||
rates=[r for r in eligible if quantity(billing,r)*Decimal(r['price'])+charge_details(billing,r,fees,book)['cny']==best[(destination['zone'] or r['zone'],r['unit'],r['tax'])]] or rates
|
||||
lines.append('按相同区域、计费单位及税费方式比较的较低价方案:')
|
||||
else:
|
||||
def eta_key(rate):
|
||||
values=[Decimal(v) for v in re.findall(r'\d+(?:\.\d+)?',rate['eta'])]
|
||||
return tuple(values[:2]) if values else (Decimal('Infinity'),)
|
||||
earliest=min(eta_key(r) for r in rates)
|
||||
rates=[r for r in rates if eta_key(r)==earliest]
|
||||
lines.append('按资料中的参考时效,较快方案如下;提取不等于送达或签收:')
|
||||
if intent.get('mode')=='cheapest' and rates:
|
||||
eligible=[r for r in rates if quantity(billing,r) is not None]
|
||||
best={}
|
||||
for rate in eligible:
|
||||
key=(destination['zone'] or rate['zone'],rate['unit'],rate['tax'])
|
||||
value=quantity(billing,rate)*Decimal(rate['price'])+charge_details(billing,rate,fees,book)['cny']
|
||||
best[key]=min(best.get(key,value),value)
|
||||
rates=[r for r in eligible if quantity(billing,r)*Decimal(r['price'])+charge_details(billing,r,fees,book)['cny']==best[(destination['zone'] or r['zone'],r['unit'],r['tax'])]] or rates
|
||||
lines.append('按相同区域、计费单位及税费方式比较的较低价方案:')
|
||||
if not rates:
|
||||
lines.append(f"{destination['label']}:当前资料没有匹配的线路价格,提供目的仓码或邮编可继续查询。")
|
||||
continue
|
||||
if destination['label'] != '美国':
|
||||
lines.append(destination['label']+':')
|
||||
selections=[('',rates)]
|
||||
if intent.get('mode') in ('fastest','slowest','speed_compare'):
|
||||
selections=[]
|
||||
if intent['mode'] in ('fastest','speed_compare'):
|
||||
selections.append(('最快参考方案',select_timed_rates(rates)))
|
||||
if intent['mode'] in ('slowest','speed_compare'):
|
||||
selections.append(('最慢参考方案',select_timed_rates(rates,slowest=True)))
|
||||
lines.append('按相同区域、运输方式、计费单位及税费方式比较参考时效。最快按天数下限、最慢按天数上限选择。')
|
||||
grouped = {}
|
||||
for rate in rates:
|
||||
key = (rate['service'], rate['origin'], rate['unit'], rate['tax'])
|
||||
grouped.setdefault(key, []).append(rate)
|
||||
for (service, origin, unit, tax), rows in grouped.items():
|
||||
for selection,selected_rates in selections:
|
||||
if selection and not selected_rates:
|
||||
lines.append(selection+'暂时无法确定,匹配线路未列明可比较的天数。')
|
||||
for rate in selected_rates:
|
||||
key = (selection, rate['service'], rate['origin'], rate['unit'], rate['tax'], rate['eta'])
|
||||
grouped.setdefault(key, []).append(rate)
|
||||
last_selection=None
|
||||
for (selection,service, origin, unit, tax,eta_source), rows in grouped.items():
|
||||
if selection and selection!=last_selection:
|
||||
lines.append(selection)
|
||||
last_selection=selection
|
||||
if intent.get('mode')=='time':
|
||||
eta=rows[0]['eta'] or '当前资料未列明时效'
|
||||
eta=eta_source or '当前资料未列明时效'
|
||||
if rows[0]['kind']=='parcel' and '提取' not in eta:eta+='提取'
|
||||
lines.append(f'- {service} · {origin}:{eta}。提取不等于送达或签收。')
|
||||
continue
|
||||
@@ -203,7 +228,7 @@ def render_rates(intent, book, destinations, remote_fees):
|
||||
elif intent.get('cbm') and rate['unit']=='cbm':
|
||||
lines.append('计费体积四舍五入后不足0.01CBM,最低计费体积需人工确认,不能按零费用出价。')
|
||||
parts.append(rate_text)
|
||||
eta = re.sub(r'\s*无时效赔偿', '', rows[0]['eta']).strip()
|
||||
eta = re.sub(r'\s*无时效赔偿', '', eta_source).strip()
|
||||
if rows[0]['kind']=='parcel' and eta and '提取' not in eta:eta+='提取'
|
||||
elif rows[0]['kind']=='truck' and eta and '船开' not in eta:eta='开船后参考'+eta
|
||||
lines.append(f"- {service} · {origin} · {'包税' if tax=='included' else '不包税'}:"+';'.join(parts)
|
||||
|
||||
Reference in New Issue
Block a user