@@ -776,6 +776,59 @@ def quote_fee_lines(quote: dict[str, Any] | None) -> list[tuple[str, str]]:
|
||||
return lines
|
||||
|
||||
|
||||
_SEA_FEE_BUCKETS = (
|
||||
("polCostItems", "始发港费用", "始发港费用小计"),
|
||||
("oceanCostItems", "海运费", "海运费小计"),
|
||||
("podCostItems", "目的港费用", "目的港费用小计"),
|
||||
)
|
||||
|
||||
|
||||
def _parse_fee_bucket(quote: dict[str, Any], key: str) -> list[dict[str, Any]]:
|
||||
"""读 polCostItems / fee_rows_polCostItems,字符串 JSON 也认。"""
|
||||
raw = quote.get(key) or quote.get("fee_rows_" + key)
|
||||
if isinstance(raw, str) and raw.strip():
|
||||
try:
|
||||
raw = json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
return []
|
||||
if not isinstance(raw, list):
|
||||
return []
|
||||
return [row for row in raw if isinstance(row, dict)]
|
||||
|
||||
|
||||
def sea_bucket_fee_lines(quote: dict[str, Any] | None) -> list[str]:
|
||||
"""
|
||||
海运三段正文。有任一段桶才用;否则返回空列表,调用方回退扁平 fee_lines。
|
||||
|
||||
费目按该条币种金额原样;小计用 fee_total_* + 表头结算币种。本地不折算。
|
||||
"""
|
||||
src = dict(quote or {})
|
||||
header_ccy = str(src.get("currency") or src.get("currencyCode") or "").strip()
|
||||
sections: list[str] = []
|
||||
any_bucket = False
|
||||
for key, title, subtotal_label in _SEA_FEE_BUCKETS:
|
||||
rows = _parse_fee_bucket(src, key)
|
||||
subtotal = str(src.get("fee_total_" + key) or "").strip()
|
||||
if not rows and not subtotal:
|
||||
continue
|
||||
any_bucket = True
|
||||
sections.append(title)
|
||||
for row in rows:
|
||||
name = str(row.get("name") or row.get("label") or row.get("feeName") or "").strip()
|
||||
amount = str(row.get("amount") or row.get("value") or "").strip()
|
||||
line_ccy = str(row.get("currency") or row.get("currencyCode") or header_ccy).strip()
|
||||
if name and amount and amount != "-":
|
||||
sections.append(f"{name}:{money_text(amount, line_ccy)}")
|
||||
if subtotal and subtotal != "-":
|
||||
sections.append(f"{subtotal_label}:{money_text(subtotal, header_ccy)}")
|
||||
sections.append("")
|
||||
if not any_bucket:
|
||||
return []
|
||||
while sections and sections[-1] == "":
|
||||
sections.pop()
|
||||
return sections
|
||||
|
||||
|
||||
def quote_area_fee_text(
|
||||
quote: dict[str, Any] | None,
|
||||
business_line: str = "",
|
||||
@@ -789,7 +842,11 @@ def quote_area_fee_text(
|
||||
src = dict(quote or {})
|
||||
header_ccy = str(src.get("currency") or src.get("currencyCode") or "").strip()
|
||||
total = money_text(str(src.get("total") or "-").strip() or "-", header_ccy)
|
||||
fee_lines = [f"{name}:{amount}" for name, amount in quote_fee_lines(src)]
|
||||
bucket_lines = sea_bucket_fee_lines(src)
|
||||
if bucket_lines:
|
||||
fee_lines = list(bucket_lines)
|
||||
else:
|
||||
fee_lines = [f"{name}:{amount}" for name, amount in quote_fee_lines(src)]
|
||||
fee_lines.append(f"{_total_label(src, business_line, transport_mode)}:{total}")
|
||||
return "\n".join(fee_lines)
|
||||
|
||||
@@ -920,7 +977,14 @@ def quote_detail_lines(
|
||||
src = dict(quote or {})
|
||||
header_ccy = str(src.get("currency") or src.get("currencyCode") or "").strip()
|
||||
total = money_text(str(src.get("total") or "-").strip() or "-", header_ccy)
|
||||
lines = [f"{name}:{amount}" for name, amount in quote_fee_lines(src)]
|
||||
bucket_lines = sea_bucket_fee_lines(src) if (business_line or "").upper() == "SEA" or (
|
||||
transport_mode or ""
|
||||
).strip() == "海运" else []
|
||||
if bucket_lines:
|
||||
lines = list(bucket_lines)
|
||||
else:
|
||||
lines = [f"{name}:{amount}" for name, amount in quote_fee_lines(src)]
|
||||
lines.append(f"{_total_label(src, business_line, transport_mode)}:{total}")
|
||||
lines.append(f"{_total_label(src, business_line, transport_mode)}:{total}")
|
||||
lines.append(f"时效:{tms_eta_display(src)}")
|
||||
lines.append(f"报价有效期:{tms_valid_until_display(src)}")
|
||||
|
||||
Reference in New Issue
Block a user