陆运选项不全时改为复制填空清单,方便销售按编号回填。
停发填写样例图,同群只跟当前工单,重量体积统一为 KG/CBM。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -94,6 +94,13 @@ def operator_name(flow: Any, sender_id: str) -> str:
|
||||
return (sender_id or "").strip() or "航线"
|
||||
|
||||
|
||||
def is_air_ticket(ticket: object) -> bool:
|
||||
"""按群找回的工单必须是空运。陆运旧单不能当空运当前单补含电含磁。"""
|
||||
view = ticket_view(ticket)
|
||||
line = str(view.get("business_line") or view.get("businessLine") or "").strip().upper()
|
||||
return not line or line == "AIR"
|
||||
|
||||
|
||||
def can_fill_fields(flow: Any, ticket: object, sender_id: str) -> bool:
|
||||
return is_sales(ticket, sender_id) or is_airline(flow, sender_id)
|
||||
|
||||
@@ -147,6 +154,8 @@ def activate_ticket(
|
||||
ticket = hydrate_ticket(flow, _ticket_from_activate(book, no, out))
|
||||
if is_handoff_ticket(ticket):
|
||||
return None, "handoff_ignore"
|
||||
# 先落默认协同,再决定要不要发摘要。发文件切单不说话,工单上仍要有含电/含磁。
|
||||
_seed_air_activate_collab(flow, ticket)
|
||||
if speak:
|
||||
send_air_brief_and_sheet(flow=flow, ticket=ticket, chat_id=chat_id)
|
||||
_watch_archive_room(chat_id, no)
|
||||
@@ -156,6 +165,54 @@ def activate_ticket(
|
||||
return ticket, "activated"
|
||||
|
||||
|
||||
def _collab_slot_empty(val: object) -> bool:
|
||||
"""协同项没写,或只写了横杠。横杠是摘要占位,不能当成已经填过。"""
|
||||
return str(val or "").strip() in {"", "-", "—", "-"}
|
||||
|
||||
|
||||
def _seed_air_activate_collab(flow: Any, ticket: object) -> dict[str, str]:
|
||||
"""
|
||||
空运群激活时预填协同,并记到主账。
|
||||
|
||||
私聊已经写过的含电/含磁先带上。
|
||||
货物品名正好是「普货」、该项还空着,默认否。
|
||||
群里已经记下的值不覆盖。只补空项。
|
||||
"""
|
||||
from agent.schema.field_validate import (
|
||||
AIR_COLLAB_FIELDS,
|
||||
air_general_cargo_collab_defaults,
|
||||
pick_collab_from_facts,
|
||||
)
|
||||
|
||||
view = ticket_view(ticket)
|
||||
no = ticket_no(ticket)
|
||||
facts = dict(view.get("facts") or {})
|
||||
# 主账有时品名在货物名称列,事实里没带「品名」。群摘要仍能看到普货。
|
||||
if not str(facts.get("品名") or facts.get("货物品名") or "").strip():
|
||||
cargo = str(view.get("goodsName") or view.get("goods_name") or "").strip()
|
||||
if cargo:
|
||||
facts["品名"] = cargo
|
||||
seeded = pick_collab_from_facts(facts, AIR_COLLAB_FIELDS)
|
||||
for key, val in air_general_cargo_collab_defaults(facts).items():
|
||||
if _collab_slot_empty(seeded.get(key)):
|
||||
seeded[key] = val
|
||||
collab = dict(view.get("collab_facts") or {})
|
||||
to_write: dict[str, str] = {}
|
||||
for key, val in seeded.items():
|
||||
if val and _collab_slot_empty(collab.get(key)):
|
||||
collab[key] = val
|
||||
to_write[key] = val
|
||||
if to_write:
|
||||
patcher = getattr(getattr(flow, "ledger", None), "patch_collab_facts", None)
|
||||
if callable(patcher):
|
||||
patcher(
|
||||
work_order_no=no,
|
||||
facts=to_write,
|
||||
sender_id=str(view.get("sales_wecom_id") or view.get("salesWecomId") or ""),
|
||||
)
|
||||
return collab
|
||||
|
||||
|
||||
def send_air_brief_and_sheet(
|
||||
*,
|
||||
flow: Any,
|
||||
@@ -177,25 +234,7 @@ def send_air_brief_and_sheet(
|
||||
if room and not view.get("collab_chat_id"):
|
||||
view["collab_chat_id"] = room
|
||||
facts = dict(view.get("facts") or {})
|
||||
from agent.schema.field_validate import AIR_COLLAB_FIELDS, pick_collab_from_facts
|
||||
|
||||
seeded = pick_collab_from_facts(facts, AIR_COLLAB_FIELDS)
|
||||
collab = dict(view.get("collab_facts") or {})
|
||||
if seeded:
|
||||
changed = False
|
||||
for k, v in seeded.items():
|
||||
if v and not str(collab.get(k) or "").strip():
|
||||
collab[k] = v
|
||||
changed = True
|
||||
if changed:
|
||||
view["collab_facts"] = collab
|
||||
patcher = getattr(getattr(flow, "ledger", None), "patch_collab_facts", None)
|
||||
if callable(patcher):
|
||||
patcher(
|
||||
work_order_no=no,
|
||||
facts=seeded,
|
||||
sender_id=str(view.get("sales_wecom_id") or view.get("salesWecomId") or ""),
|
||||
)
|
||||
collab = _seed_air_activate_collab(flow, view)
|
||||
view["collab_facts"] = collab
|
||||
view_q = dict(view.get("quote") or {})
|
||||
override = dict(quote_override or {})
|
||||
@@ -358,6 +397,9 @@ def apply_air_fields(*, flow: Any, ticket: object, text: str, sender_id: str, ch
|
||||
ticket = hydrate_ticket(flow, ticket)
|
||||
no = ticket_no(ticket)
|
||||
client = group_client_of(flow)
|
||||
if not is_air_ticket(ticket):
|
||||
send_group_text(client, chat_id, copy.air_need_work_order())
|
||||
return "need_work_order"
|
||||
stopped = halt_closed_group(flow=flow, ticket=ticket, chat_id=chat_id)
|
||||
if stopped:
|
||||
return stopped
|
||||
@@ -369,7 +411,10 @@ def apply_air_fields(*, flow: Any, ticket: object, text: str, sender_id: str, ch
|
||||
send_group_text(client, chat_id, copy.air_fields_not_recognized())
|
||||
return "fields_empty"
|
||||
flow.ledger.patch_collab_facts(work_order_no=no, facts=fields, sender_id=sender_id)
|
||||
ticket2 = current_ticket(flow, chat_id) or ticket
|
||||
# 必须回读本单。按群再查会拿到同群更早的陆运/海运旧单(测服 WO202609230007)。
|
||||
getter = getattr(flow.ledger, "get_ticket", None)
|
||||
reloaded = getter(work_order_no=no) if callable(getter) else None
|
||||
ticket2 = hydrate_ticket(flow, reloaded or ticket)
|
||||
view = ticket_view(ticket2)
|
||||
collab = dict(view.get("collab_facts") or {})
|
||||
collab.update(fields)
|
||||
|
||||
Reference in New Issue
Block a user