后台成本价、销售价、利润点按费用逐行展示,费用合计用报价官方总价。选完线路只关页面。报价单文件名带上模板名,空运起运地和转人工跟对应工单走。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-05 12:33:34 +08:00
co-authored by Cursor
parent 7c77e45e03
commit e95e8869a6
30 changed files with 1926 additions and 75 deletions
+27 -3
View File
@@ -31,7 +31,7 @@ AIR_REQUIRED_FIELDS = (
)
# 空运询价非必填:有值收下;贸易条款只记工单,不挡查价。
AIR_OPTIONAL_FIELDS = (
("起运港", "起运港"),
("起运港", "起运地"),
("货源地", "货源地"),
("货好时间", "货好时间"),
("提货地址", "提货地址"),
@@ -40,7 +40,7 @@ AIR_OPTIONAL_FIELDS = (
)
AIR_DISPLAY = {key: label for key, label in AIR_REQUIRED_FIELDS}
AIR_DISPLAY.update({key: label for key, label in AIR_OPTIONAL_FIELDS})
# 补问回显仍用「起运地」,与历史卡片一致。
# 内部键仍是起运港(主账/TMS)。销售侧一律写起运地。
AIR_DISPLAY["起运港"] = "起运地"
# 海运询价必填 10 项(销售侧含运输方式):内部键「货量」对外叫「货物数量」。
@@ -235,6 +235,7 @@ _ALIASES = {
"收货地址(非必填)": "收货地址",
"贸易条款(非必填)": "贸易条款",
"起运港(非必填)": "起运港",
"起运地(非必填)": "起运港",
}
for _quote_alias in QUOTE_DATE_SYNONYMS:
_ALIASES[_quote_alias] = "报价日期"
@@ -327,7 +328,30 @@ def _quote_date_labeled_value(raw: str) -> str:
best_val = hit.group(1).strip().strip(",,。;;、")
if not best_val:
return ""
return _harvest_quote_date(best_val) or best_val
return _harvest_quote_date(best_val) or _excel_serial_date(best_val) or best_val
def _excel_serial_date(token: str) -> str:
"""
Excel 把日期存成序列号时(如 46307),收成 yyyy-MM-dd。
只认整段就是 5 位数字。件数、重量不走这里。
"""
from datetime import datetime, timedelta
text = (token or "").strip()
if text.endswith(".0"):
text = text[:-2]
if not re.fullmatch(r"\d{5}", text):
return ""
serial = int(text)
# 约 1982–2064。再外的 5 位数不当日期。
if serial < 30000 or serial > 60000:
return ""
try:
return (datetime(1899, 12, 30) + timedelta(days=serial)).date().isoformat()
except OverflowError:
return ""
def _harvest_quote_date(raw: str) -> str: