"""Amounts come from the active book; explicit customer-approved fee policies live here.""" from decimal import Decimal import re from .pricing import dims_to_cm def document(book,required,service=None): rows=[d for d in book['documents'] if (not service or d['sheet'] in (service,'海派')) and all(term in d['content'] for term in required)] return rows[0]['content'] if rows else '' def amount(text,pattern): match=re.search(pattern,text,re.I) return Decimal(match.group(1)) if match else None def material_fee(book): text=document(book,('铁铝','附加费')) return amount(text,r'铁铝制品[^\n]*?[¥¥]\s*(\d+(?:\.\d+)?)\s*/KG') def specimens(intent): if intent.get('packages'): return [{**p,'dims':p.get('dims') or intent.get('dims'), 'dim_unit':p.get('dim_unit') if p.get('dims') else intent.get('dim_unit','cm')} for p in intent['packages']] if intent.get('boxes')==1 and intent.get('weight'): return [{'count':1,'weight':intent['weight'],'dims':intent.get('dims'),'dim_unit':intent.get('dim_unit','cm')}] return [] def limit_fees(intent,book): """Maximum per-piece limit fee, not the sum of overlapping weight/size charges. The malformed 068 or (dims and (length>270 or girth>419)): result['notes'].append('该件可能超出承运尺寸或重量,需人工确认是否接收。'+(f'原表超大件若接收的附加费为{huge_fee:g}USD/件。' if huge_fee else '')) continue candidates=[] if weight>max_weight:candidates.append(normal_fee) if dims and (length>max_length or second>max_second or girth>max_girth) and size_fee is not None:candidates.append(size_fee) if large_fee is not None and max_weight=243 or girth>=330): result['notes'].append('该件接近大尺寸档,原表有一处长度条件不清,适用档位需人工确认。') if candidates: fee=max(candidates)*count result['cny']+=fee result['items'].append(f'超重/超尺寸按最高项{max(candidates):g}元/件×{count}件={fee:g}元') return result def charge_details(intent,rate,remote,book): from .quote_engine import quantity result={'cny':Decimal(0),'items':[],'notes':[]} charged=quantity(intent,rate) if charged is None:return result if rate['kind']=='parcel' and remote: if remote['fee'] is not None: fee=charged*Decimal(remote['fee']);result['cny']+=fee result['items'].append(f'偏远费{remote["fee"]}元/KG×{charged:g}KG={fee:g}元') else:result['notes'].append('遥远地址的附加费需单独确认,当前金额未包含该项。') if rate['unit']=='kg' and intent.get('material')=='metal': per_kg=material_fee(book) if per_kg is not None: fee=charged*per_kg;result['cny']+=fee result['items'].append(f'铁铝附加费{per_kg:g}元/KG×{charged:g}KG={fee:g}元') if rate['kind']=='parcel': limits=limit_fees(intent,book) result['cny']+=limits['cny'];result['items']+=limits['items'];result['notes']+=limits['notes'] if intent.get('address_type')=='non_fba': result['notes'].append('非亚马逊地址还需核对住宅/商业派送附加费,原表此项需单独询价。') return result