空运人工价锁舱现拉补全舱位并拦清缺参;成交/报价填表与工单陆运费率展示同步收紧。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -144,10 +144,75 @@ class TestDealOutcome(unittest.TestCase):
|
||||
view = self.ledger.get_for_agent(work_order_no=self.wo, sender_id="sales1")
|
||||
self.assertEqual(view.get("wait_phase"), "done")
|
||||
|
||||
def test_lost_from_inquiring_promotes_quoted_first(self) -> None:
|
||||
"""主账仍询价中时点未成交:先补已报价再入未成交,禁止直接失败。"""
|
||||
|
||||
class _StrictSix:
|
||||
def __init__(self) -> None:
|
||||
self.status = "询价中"
|
||||
self.lost_reason = ""
|
||||
self.event_wait_kind = ""
|
||||
|
||||
def transition(self, *, work_order_no, to_status, **kwargs):
|
||||
_ = work_order_no
|
||||
allowed = {
|
||||
"询价中": {"已报价", "协商中", "已关闭"},
|
||||
"已报价": {"协商中", "已成交", "未成交", "已关闭"},
|
||||
}
|
||||
if to_status not in allowed.get(self.status, set()):
|
||||
# 模拟 http_ledger 在 500 时只回 http_500(丢失正文)
|
||||
return {"ok": False, "error": "http_500"}
|
||||
self.status = to_status
|
||||
if to_status == "未成交" and kwargs.get("lost_reason"):
|
||||
self.lost_reason = str(kwargs.get("lost_reason") or "")
|
||||
return {"ok": True, "status": self.status}
|
||||
|
||||
def patch_lost_reason(self, *, work_order_no, lost_reason):
|
||||
_ = work_order_no
|
||||
self.lost_reason = lost_reason
|
||||
return {"ok": True}
|
||||
|
||||
def get_for_agent(self, *, work_order_no, sender_id):
|
||||
_ = (work_order_no, sender_id)
|
||||
return {"status": self.status, "lost_reason": self.lost_reason}
|
||||
|
||||
ledger = _StrictSix()
|
||||
out = finish_deal_outcome(
|
||||
ledger=ledger,
|
||||
work_order_no="WO202610070023",
|
||||
outcome="未成交",
|
||||
facts={},
|
||||
quote={},
|
||||
business_line="AIR",
|
||||
)
|
||||
self.assertTrue(out.get("ok"), out)
|
||||
self.assertEqual(ledger.status, "未成交")
|
||||
self.assertEqual(out.get("phase"), "wait_lost_reason")
|
||||
|
||||
def test_lost_reason_ack_repeats_user_text(self) -> None:
|
||||
self.assertEqual(copy.lost_reason_ack("客户不要了"), "已记下未成交原因:客户不要了。")
|
||||
self.assertEqual(copy.lost_reason_ack("价格高。"), "已记下未成交原因:价格高。")
|
||||
|
||||
def test_lost_reason_ack_fills_ticket_no_from_bot_reply(self) -> None:
|
||||
"""后台文案带 {{ticket_no}} 时必须填实值,禁止原样打出占位符。"""
|
||||
from agent.policy import bot_reply
|
||||
|
||||
bot_reply.override_catalog(
|
||||
{
|
||||
"lost.reason_ack": (
|
||||
"已将未成交原因“{{lost_reason}}”记录在后台,"
|
||||
"工单{{ticket_no}}已关闭,智能体不再跟进该工单,请悉知。"
|
||||
)
|
||||
}
|
||||
)
|
||||
try:
|
||||
text = copy.lost_reason_ack("换时间", work_order_no="WO202610070018")
|
||||
self.assertIn("WO202610070018", text)
|
||||
self.assertNotIn("{{ticket_no}}", text)
|
||||
self.assertIn("换时间", text)
|
||||
finally:
|
||||
bot_reply.override_catalog(None)
|
||||
|
||||
def test_harvest_inline_lost_reason(self) -> None:
|
||||
self.assertEqual(harvest_inline_lost_reason("未成交,原因客户不想要了"), "客户不想要了")
|
||||
self.assertEqual(
|
||||
|
||||
Reference in New Issue
Block a user