确定运输方式前的多句询价带到所选方式并按该方式抽字段;成交已定后放舱不再推跟进,未成交原因不再被当成新询价。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -516,6 +516,36 @@ def harvest_oral_collab(text: str) -> dict[str, str]:
|
||||
return out
|
||||
|
||||
|
||||
# 原话里单独出现才收下。举例行「(如:DDP、DAP、CIF、CIP)」整行跳过,避免示例被当成已填。
|
||||
_TRADE_TERM_CODES = ("DDP", "DAP", "DDU", "CIF", "CIP", "CPT", "CFR", "FOB", "FCA", "EXW")
|
||||
_TRADE_TERM_RE = re.compile(
|
||||
r"(?i)(?<![A-Za-z])(" + "|".join(_TRADE_TERM_CODES) + r")(?![A-Za-z])"
|
||||
)
|
||||
_TRADE_TERM_EXAMPLE_LINE = re.compile(r"^\s*[((]如\s*[::]")
|
||||
|
||||
|
||||
def harvest_spoken_trade_term(text: str) -> dict[str, str]:
|
||||
"""
|
||||
原话里单独写出的 DAP、DDP、CIF 等记成贸易条款。
|
||||
|
||||
只认这一组术语本身,不从「门到门」猜。同一句出现两个不同术语时不选。
|
||||
补问举例行整行不看。已有「贸易条款」标签值的,由调用方决定不覆盖。
|
||||
"""
|
||||
kept: list[str] = []
|
||||
for line in (text or "").splitlines() or [""]:
|
||||
if _TRADE_TERM_EXAMPLE_LINE.match((line or "").strip()):
|
||||
continue
|
||||
kept.append(line)
|
||||
found: list[str] = []
|
||||
for match in _TRADE_TERM_RE.finditer("\n".join(kept)):
|
||||
code = match.group(1).upper()
|
||||
if code not in found:
|
||||
found.append(code)
|
||||
if len(found) != 1:
|
||||
return {}
|
||||
return {"贸易条款": found[0]}
|
||||
|
||||
|
||||
# 箱型原文:40HQ*1、1x40HQ、40尺高柜。货物数量不能收这种串。
|
||||
_CONTAINER_SPEC = re.compile(
|
||||
r"(?i)(20|40|45)\s*['\"′尺]?\s*(HQ|GP|NOR|RH|HC|高柜|平柜|柜)"
|
||||
@@ -549,6 +579,39 @@ def project_sea_cargo_qty(facts: dict[str, str] | None) -> dict[str, str]:
|
||||
return merged
|
||||
|
||||
|
||||
# 选定方式后,不属于该方式首次询价的键拿掉。海运件数先投影成货量再删。
|
||||
_SEA_DROP_AFTER_PROJECT = ("件数", "毛重", "体积", "包装方式", "包装类型")
|
||||
_LAND_DROP_FOREIGN = ("件数", "货量", "货物数量", "整柜或拼柜", "箱型箱量", "贸易条款")
|
||||
_AIR_DROP_FOREIGN = ("货量", "货物数量", "整柜或拼柜", "箱型箱量")
|
||||
|
||||
|
||||
def shape_facts_for_chosen_mode(facts: dict[str, str] | None, business_line: str) -> dict[str, str]:
|
||||
"""
|
||||
运输方式刚定下来时,按该方式的询价字段收口。
|
||||
|
||||
海运留下货物数量、整柜或拼柜、箱型箱量、贸易条款、运输分类;件数里的数量先写入货量。
|
||||
陆运留下运输类型、线路类别、运输分类和重量体积或车型,不留海运箱型、空运件数。
|
||||
空运留下件数、毛重、体积、包装方式,不留海运箱型。
|
||||
不猜新值,只删不属于本方式的键。返回新 dict。
|
||||
"""
|
||||
line = (business_line or "").strip().upper()
|
||||
merged = {str(k): str(v).strip() for k, v in dict(facts or {}).items() if str(v).strip()}
|
||||
if line == "SEA":
|
||||
merged = project_sea_cargo_qty(merged)
|
||||
for key in _SEA_DROP_AFTER_PROJECT:
|
||||
merged.pop(key, None)
|
||||
return merged
|
||||
if line == "LAND":
|
||||
for key in _LAND_DROP_FOREIGN:
|
||||
merged.pop(key, None)
|
||||
return merged
|
||||
if line == "AIR":
|
||||
for key in _AIR_DROP_FOREIGN:
|
||||
merged.pop(key, None)
|
||||
return merged
|
||||
return merged
|
||||
|
||||
|
||||
def apply_quote_date_default(facts: dict[str, str]) -> dict[str, str]:
|
||||
"""销售未提供报价日期时填当天;已有则不覆盖。"""
|
||||
merged = dict(facts)
|
||||
|
||||
Reference in New Issue
Block a user