空运协同里手工改费用、有起运地、锁舱失败或缺参会被误判,报价单已出后再激活又重发模板。按销售侧口径收紧这些分支,并让价格卡和未成交回执带上真实工单号。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -45,10 +45,55 @@ def parse_air_options(quote: dict[str, Any] | None) -> list[dict[str, Any]]:
|
||||
|
||||
|
||||
def needs_route_pick(quote: dict[str, Any] | None) -> bool:
|
||||
"""多于一条线路才进 H5 选。"""
|
||||
"""没写起运地、且多于一条线路,才进 H5 选。有起运地时由调用方先按起运地收口。"""
|
||||
return len(parse_air_options(quote)) > 1
|
||||
|
||||
|
||||
def options_matching_origin(
|
||||
options: list[dict[str, Any]],
|
||||
origin_text: str,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""
|
||||
销售已经写了起运地时,只留起运机场对得上的线路。
|
||||
|
||||
杭州对 HGH,珠海对 ZUH。回包里的南京/深圳/郑州不能拿来给这张单选。
|
||||
对不上返回空列表。不改入参。
|
||||
"""
|
||||
text = (origin_text or "").strip()
|
||||
if not text:
|
||||
return list(options)
|
||||
code = resolve_airport_code(text).upper()
|
||||
raw = text.upper()
|
||||
matched: list[dict[str, Any]] = []
|
||||
for opt in options:
|
||||
origin = str(opt.get("originAirportCode") or opt.get("origin") or "").strip().upper()
|
||||
if not origin:
|
||||
continue
|
||||
if code and origin == code:
|
||||
matched.append(opt)
|
||||
elif origin == raw:
|
||||
matched.append(opt)
|
||||
return matched
|
||||
|
||||
|
||||
def choose_stated_origin_option(
|
||||
options: list[dict[str, Any]],
|
||||
quote: dict[str, Any] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""
|
||||
起运地已指定时直接用一条,不再让销售选线。
|
||||
|
||||
只有一条就用它。多条时优先和报价总价相同的那条,否则用第一条。
|
||||
"""
|
||||
if len(options) == 1:
|
||||
return options[0]
|
||||
total = (quote or {}).get("total")
|
||||
for opt in options:
|
||||
if _same_amount(opt.get("salePrice"), total):
|
||||
return opt
|
||||
return options[0]
|
||||
|
||||
|
||||
def _place_name(code: str, fallback: str = "") -> str:
|
||||
"""三字码能对上就用中文,否则用原文或 fallback。"""
|
||||
raw = (code or "").strip()
|
||||
@@ -331,14 +376,14 @@ def _same_amount(left: Any, right: Any) -> bool:
|
||||
|
||||
def drop_air_freight_total_alias(quote: dict[str, Any] | None) -> dict[str, Any]:
|
||||
"""
|
||||
整单兜底「空运费=总价」不是线路分项,群摘要禁止再写。
|
||||
已经有其它费用分项时,去掉「空运费=总价」这一行兜底。
|
||||
|
||||
真有空运费且金额不等于总价(例如另有附加费)则保留。
|
||||
舱位上有运输费、提送货费时,主账快照常再塞一行空运费,金额就是总价,不能和分项叠在一起。
|
||||
只有空运费这一项时必须留下:TMS 经常只回这一项,金额自然等于总价,群里仍要写出费用名。
|
||||
不写库。群摘要投影之后调用。
|
||||
"""
|
||||
src = dict(quote or {})
|
||||
total = src.get("total")
|
||||
if _same_amount(src.get("freight"), total):
|
||||
src["freight"] = "-"
|
||||
raw = src.get("fee_lines") or src.get("fee_rows")
|
||||
parsed: Any = raw
|
||||
if isinstance(raw, str) and raw.strip():
|
||||
@@ -348,17 +393,26 @@ def drop_air_freight_total_alias(quote: dict[str, Any] | None) -> dict[str, Any]
|
||||
parsed = None
|
||||
if not isinstance(parsed, list):
|
||||
return src
|
||||
kept: list[Any] = []
|
||||
others: list[Any] = []
|
||||
alias: list[Any] = []
|
||||
for item in parsed:
|
||||
if not isinstance(item, dict):
|
||||
kept.append(item)
|
||||
others.append(item)
|
||||
continue
|
||||
name = str(item.get("name") or item.get("label") or "").strip()
|
||||
name = str(item.get("name") or item.get("label") or item.get("feeName") or "").strip()
|
||||
amount = item.get("amount") or item.get("value")
|
||||
if name == "空运费" and _same_amount(amount, total):
|
||||
alias.append(item)
|
||||
continue
|
||||
kept.append(item)
|
||||
src["fee_lines"] = kept
|
||||
others.append(item)
|
||||
if others:
|
||||
# 分项已经在,空运费=总价是重复兜底。运费字段同值也不再补一行。
|
||||
src["fee_lines"] = others
|
||||
if _same_amount(src.get("freight"), total):
|
||||
src["freight"] = "-"
|
||||
return src
|
||||
# 明细就是这一条空运费,群摘要要显示费用名,不能只剩费用合计。
|
||||
src["fee_lines"] = alias
|
||||
return src
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user