空运人工价锁舱现拉补全舱位并拦清缺参;成交/报价填表与工单陆运费率展示同步收紧。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -906,12 +906,14 @@ def apply_product_quote(
|
||||
logger.info("产品报价未识别 wo=%s text=%s", no, (text or "")[:200])
|
||||
send_group_text(client, chat_id, copy.group_quote_not_recognized())
|
||||
return "quote_not_recognized"
|
||||
quote = _attach_land_weight_band_segment(quote, view)
|
||||
base = _current_quote(view, sess)
|
||||
if _has_tms_quote(base):
|
||||
_park_pending_quote(no, quote, sess, flow)
|
||||
send_group_text(client, chat_id, copy.group_ask_tms_or_product())
|
||||
return "wait_tms_choice"
|
||||
if _quote_fee_rows(base):
|
||||
# 分档单价是完整人工价(含费率),禁止和旧错误行(如燃油附加费=2)相加。
|
||||
if _quote_fee_rows(base) and not (quote.get("weightPrices") or []):
|
||||
quote = merge_quote_fees(base, quote)
|
||||
_save_product_quote(flow, no, quote, sess)
|
||||
ticket2 = _reload(flow, chat_id, no) or ticket
|
||||
@@ -1231,8 +1233,11 @@ def apply_group_deal(
|
||||
return "not_sales"
|
||||
quote = _current_quote(view, sess)
|
||||
status_now = ticket_status(ticket) or (sess.status if sess else "")
|
||||
if not (quote.get("total") or _quote_fee_rows(quote) or status_now in {"已报价", "协商中"}):
|
||||
send_group_text(client, chat_id, copy.group_deal_need_quote())
|
||||
usable_total = str(quote.get("total") or "").strip()
|
||||
if usable_total in {"", "-"}:
|
||||
usable_total = ""
|
||||
if not (usable_total or _quote_fee_rows(quote) or status_now in {"已报价", "协商中"}):
|
||||
send_group_text(client, chat_id, copy.group_deal_need_quote(work_order_no=no))
|
||||
return "deal_need_quote"
|
||||
from agent.policy.deal_outcome import finish_deal_outcome, harvest_inline_lost_reason
|
||||
|
||||
@@ -1309,7 +1314,14 @@ def capture_group_lost_reason(
|
||||
sess.phase = "done"
|
||||
sess.allowed = ()
|
||||
flow._save(sess)
|
||||
send_group_text(client, chat_id, copy.lost_reason_ack(str(result.get("lost_reason") or text)))
|
||||
send_group_text(
|
||||
client,
|
||||
chat_id,
|
||||
copy.lost_reason_ack(
|
||||
str(result.get("lost_reason") or text),
|
||||
work_order_no=no,
|
||||
),
|
||||
)
|
||||
return "done"
|
||||
|
||||
|
||||
@@ -1634,6 +1646,53 @@ def merge_quote_fees(base: dict[str, Any] | None, overlay: dict[str, Any] | None
|
||||
return stamp_prices_for_sheet(out)
|
||||
|
||||
|
||||
def _attach_land_weight_band_segment(
|
||||
quote: dict[str, Any], view: dict[str, Any]
|
||||
) -> dict[str, Any]:
|
||||
"""
|
||||
陆运产品分档价:把 weightPrices / 燃油税率挂到 landSegments,出单才能填「2-500KG」列。
|
||||
|
||||
无分档价时原样返回。OD 取工单询价事实,不另猜城市。
|
||||
"""
|
||||
src = dict(quote or {})
|
||||
tiers = src.get("weightPrices")
|
||||
if not isinstance(tiers, list) or not tiers:
|
||||
return src
|
||||
facts = dict(view.get("facts") or {})
|
||||
origin = str(
|
||||
facts.get("始发地")
|
||||
or facts.get("起运地")
|
||||
or facts.get("origin")
|
||||
or view.get("origin")
|
||||
or ""
|
||||
).strip()
|
||||
dest = str(
|
||||
facts.get("目的地")
|
||||
or facts.get("destination")
|
||||
or view.get("destination")
|
||||
or ""
|
||||
).strip()
|
||||
seg: dict[str, Any] = {
|
||||
"origin": origin,
|
||||
"destination": dest,
|
||||
"weightPrices": list(tiers),
|
||||
"currency": str(src.get("currency") or "CNY"),
|
||||
"salePrice": str(src.get("total") or tiers[0].get("price") or ""),
|
||||
"price_per_kg": str(src.get("price_per_kg") or tiers[0].get("price") or ""),
|
||||
}
|
||||
fuel = str(src.get("fuel_surcharge_rate") or src.get("fuelSurchargeRate") or "").strip()
|
||||
tax = str(src.get("tax_rate") or src.get("taxRate") or "").strip()
|
||||
if fuel:
|
||||
seg["fuel_surcharge_rate"] = fuel
|
||||
seg["fuelSurchargeRate"] = fuel
|
||||
if tax:
|
||||
seg["tax_rate"] = tax
|
||||
seg["taxRate"] = tax
|
||||
src["landSegments"] = [seg]
|
||||
src["route_rows"] = [seg]
|
||||
return src
|
||||
|
||||
|
||||
def _save_product_quote(
|
||||
flow: Any,
|
||||
no: str,
|
||||
|
||||
Reference in New Issue
Block a user