落地转人工:三次补问或明确接管后出入口,真正转人工后冻结本票并允许新开询价。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -37,7 +37,9 @@ _COLLAB_FILL_ALIASES = {
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
TERMINAL = {"已成交", "未成交", "已关闭"}
|
||||
TERMINAL = {"已成交", "未成交", "已关闭", "转人工"}
|
||||
CLOSED = {"已成交", "未成交", "已关闭"}
|
||||
HANDOFF_STATUS = "转人工"
|
||||
OPEN_EDIT = {"询价中", "已报价", "协商中"}
|
||||
EXCEL_PDF = {".xlsx", ".xls", ".xlsm", ".pdf"}
|
||||
|
||||
@@ -126,6 +128,57 @@ def is_terminal(ticket: object) -> bool:
|
||||
return ticket_status(ticket) in TERMINAL
|
||||
|
||||
|
||||
def is_handoff_ticket(ticket: object, sess: Any = None) -> bool:
|
||||
"""这一票已经真正转人工:群里不再跟、也不回锁定话术。"""
|
||||
if ticket_status(ticket) == HANDOFF_STATUS:
|
||||
return True
|
||||
if sess is None:
|
||||
return False
|
||||
if str(getattr(sess, "status", "") or "").strip() == HANDOFF_STATUS:
|
||||
return True
|
||||
return bool(getattr(sess, "handoff_committed", False))
|
||||
|
||||
|
||||
def halt_closed_group(
|
||||
*,
|
||||
flow: Any,
|
||||
ticket: object,
|
||||
sess: Any = None,
|
||||
chat_id: str = "",
|
||||
file: bool = False,
|
||||
) -> str:
|
||||
"""
|
||||
转人工:静默。已成交/未成交/已关闭:回不能改/不能传附件。
|
||||
返回空表示可以继续跟。
|
||||
"""
|
||||
no = ticket_no(ticket)
|
||||
room = (chat_id or "").strip() or str(
|
||||
(sess.collab_chat_id if sess else "")
|
||||
or ticket_view(ticket).get("collab_chat_id")
|
||||
or ""
|
||||
)
|
||||
if is_handoff_ticket(ticket, sess):
|
||||
logger.info("group.handoff_ignore wo=%s chat=%s", no or "-", room or "-")
|
||||
return "handoff_ignore"
|
||||
st = ticket_status(ticket) or (
|
||||
str(getattr(sess, "status", "") or "").strip() if sess is not None else ""
|
||||
)
|
||||
if st in CLOSED or is_terminal(ticket) or (
|
||||
sess is not None and str(getattr(sess, "status", "") or "").strip() in CLOSED
|
||||
):
|
||||
client = group_client_of(flow)
|
||||
if file:
|
||||
send_group_text(
|
||||
client, room, copy.ticket_locked_file(work_order_no=no, status=st or "已关闭")
|
||||
)
|
||||
return "ticket_locked_file"
|
||||
send_group_text(
|
||||
client, room, copy.ticket_locked(work_order_no=no, status=st or "已关闭")
|
||||
)
|
||||
return "ticket_locked"
|
||||
return ""
|
||||
|
||||
|
||||
def is_sales(ticket: object, sender_id: str) -> bool:
|
||||
uid = (sender_id or "").strip()
|
||||
view = ticket_view(ticket)
|
||||
@@ -612,9 +665,9 @@ def apply_collab_update(
|
||||
no = ticket_no(ticket)
|
||||
chat_id = str((sess.collab_chat_id if sess else "") or ticket_view(ticket).get("collab_chat_id") or "")
|
||||
client = group_client_of(flow)
|
||||
if is_terminal(ticket):
|
||||
send_group_text(client, chat_id, copy.ticket_locked(work_order_no=no, status=ticket_status(ticket)))
|
||||
return "ticket_locked"
|
||||
stopped = halt_closed_group(flow=flow, ticket=ticket, sess=sess, chat_id=chat_id)
|
||||
if stopped:
|
||||
return stopped
|
||||
line, keys = _collab_keys_of(ticket, sess)
|
||||
fields = extract_collab_fields(text, allow_b=True, allowed_keys=keys)
|
||||
if not fields:
|
||||
@@ -665,9 +718,9 @@ def apply_product_quote(
|
||||
view = ticket_view(ticket)
|
||||
chat_id = str((sess.collab_chat_id if sess else "") or view.get("collab_chat_id") or "")
|
||||
client = group_client_of(flow)
|
||||
if is_terminal(ticket):
|
||||
send_group_text(client, chat_id, copy.ticket_locked(work_order_no=no, status=ticket_status(ticket)))
|
||||
return "ticket_locked"
|
||||
stopped = halt_closed_group(flow=flow, ticket=ticket, sess=sess, chat_id=chat_id)
|
||||
if stopped:
|
||||
return stopped
|
||||
if not is_product(ticket, sender_id, flow=flow):
|
||||
send_group_text(client, chat_id, copy.group_only_product_can_quote())
|
||||
return "quote_not_product"
|
||||
@@ -728,9 +781,9 @@ def apply_tms_quote_choice(
|
||||
view = ticket_view(ticket)
|
||||
chat_id = str((sess.collab_chat_id if sess else "") or view.get("collab_chat_id") or "")
|
||||
client = group_client_of(flow)
|
||||
if is_terminal(ticket):
|
||||
send_group_text(client, chat_id, copy.ticket_locked(work_order_no=no, status=ticket_status(ticket)))
|
||||
return "ticket_locked"
|
||||
stopped = halt_closed_group(flow=flow, ticket=ticket, sess=sess, chat_id=chat_id)
|
||||
if stopped:
|
||||
return stopped
|
||||
if not is_product(ticket, sender_id, flow=flow):
|
||||
send_group_text(client, chat_id, copy.group_only_product_can_quote())
|
||||
return "quote_not_product"
|
||||
@@ -777,9 +830,9 @@ def apply_confirm_tms_quote(
|
||||
view = ticket_view(ticket)
|
||||
chat_id = str((sess.collab_chat_id if sess else "") or view.get("collab_chat_id") or "")
|
||||
client = group_client_of(flow)
|
||||
if is_terminal(ticket):
|
||||
send_group_text(client, chat_id, copy.ticket_locked(work_order_no=no, status=ticket_status(ticket)))
|
||||
return "ticket_locked"
|
||||
stopped = halt_closed_group(flow=flow, ticket=ticket, sess=sess, chat_id=chat_id)
|
||||
if stopped:
|
||||
return stopped
|
||||
if not is_product(ticket, sender_id, flow=flow):
|
||||
send_group_text(client, chat_id, copy.group_only_product_can_quote())
|
||||
return "quote_not_product"
|
||||
@@ -881,9 +934,11 @@ def handle_group_file(
|
||||
view = ticket_view(ticket)
|
||||
chat_id = str((sess.collab_chat_id if sess else "") or view.get("collab_chat_id") or "")
|
||||
client = group_client_of(flow)
|
||||
if is_terminal(ticket):
|
||||
send_group_text(client, chat_id, copy.ticket_locked_file(work_order_no=no, status=ticket_status(ticket)))
|
||||
return "ticket_locked_file"
|
||||
stopped = halt_closed_group(
|
||||
flow=flow, ticket=ticket, sess=sess, chat_id=chat_id, file=True
|
||||
)
|
||||
if stopped:
|
||||
return stopped
|
||||
if not filename_is_excel_pdf(filename):
|
||||
send_group_text(client, chat_id, copy.group_only_excel_pdf())
|
||||
return "file_type_rejected"
|
||||
@@ -993,10 +1048,9 @@ def apply_group_deal(
|
||||
view = ticket_view(ticket)
|
||||
chat_id = str((sess.collab_chat_id if sess else "") or view.get("collab_chat_id") or "")
|
||||
client = group_client_of(flow)
|
||||
if is_terminal(ticket) or (sess is not None and getattr(sess, "status", "") in TERMINAL):
|
||||
status = ticket_status(ticket) or (sess.status if sess else "")
|
||||
send_group_text(client, chat_id, copy.ticket_locked(work_order_no=no, status=status))
|
||||
return "ticket_locked"
|
||||
stopped = halt_closed_group(flow=flow, ticket=ticket, sess=sess, chat_id=chat_id)
|
||||
if stopped:
|
||||
return stopped
|
||||
if not is_sales(ticket, sender_id):
|
||||
send_group_text(client, chat_id, copy.group_deal_sales_only())
|
||||
return "not_sales"
|
||||
@@ -1097,9 +1151,14 @@ def explain_deal_click(
|
||||
chat_id = (sess.collab_chat_id or "").strip()
|
||||
client = group_client_of(flow)
|
||||
no = sess.work_order_no
|
||||
if sess.status in TERMINAL:
|
||||
send_group_text(client, chat_id, copy.ticket_locked(work_order_no=no, status=sess.status))
|
||||
return "ticket_locked"
|
||||
stopped = halt_closed_group(
|
||||
flow=flow,
|
||||
ticket={"work_order_no": no, "status": sess.status, "collab_chat_id": chat_id},
|
||||
sess=sess,
|
||||
chat_id=chat_id,
|
||||
)
|
||||
if stopped:
|
||||
return stopped
|
||||
if sender_id != sess.sender_id:
|
||||
send_group_text(client, chat_id, copy.group_deal_sales_only())
|
||||
return "not_sales"
|
||||
|
||||
Reference in New Issue
Block a user