空运人工价锁舱现拉补全舱位并拦清缺参;成交/报价填表与工单陆运费率展示同步收紧。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -253,9 +253,88 @@ function parseQuoteFees(q: any): TicketQuoteFee[] {
|
||||
pushRows(asFeeArray(payload[key] || payload[bucket]));
|
||||
}
|
||||
}
|
||||
// 陆运 TMS:燃油附加费率 / 税率挂在线路段上,不是金额费目行。
|
||||
for (const extra of parseLandRateFees(payload)) {
|
||||
if (!out.some((x) => x.name === extra.name && x.amount === extra.amount)) {
|
||||
out.push(extra);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 陆运线路:fuelSurchargeRate=燃油附加费率;rate=税率;rateFlag=是否含税(1是0否)。
|
||||
* 只读 payload,不写库。海运/空运没有这些键则不出行。
|
||||
*/
|
||||
function parseLandRateFees(payload: Record<string, any>): TicketQuoteFee[] {
|
||||
const rows = asFeeArray(payload.route_rows || payload.landSegments || payload.land_segments);
|
||||
const out: TicketQuoteFee[] = [];
|
||||
const seen = new Set<string>();
|
||||
for (const row of rows) {
|
||||
if (!row || typeof row !== "object") continue;
|
||||
const fuel = formatLandPercent(row.fuel_surcharge_rate ?? row.fuelSurchargeRate);
|
||||
const tax = formatLandTaxRate(row.tax_rate ?? row.taxRate ?? row.rate);
|
||||
const included = formatLandTaxIncluded(
|
||||
row.tax_included ?? row.rateFlag ?? row.rate_flag
|
||||
);
|
||||
if (fuel) {
|
||||
const key = `fuel:${fuel}`;
|
||||
if (!seen.has(key)) {
|
||||
seen.add(key);
|
||||
out.push({ name: "燃油附加费率", amount: fuel });
|
||||
}
|
||||
}
|
||||
if (tax) {
|
||||
const key = `tax:${tax}`;
|
||||
if (!seen.has(key)) {
|
||||
seen.add(key);
|
||||
out.push({ name: "税率", amount: tax });
|
||||
}
|
||||
}
|
||||
if (included) {
|
||||
const key = `inc:${included}`;
|
||||
if (!seen.has(key)) {
|
||||
seen.add(key);
|
||||
out.push({ name: "是否含税", amount: included });
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** 燃油附加费率:数字带 %。 */
|
||||
function formatLandPercent(raw: unknown): string {
|
||||
const s = String(raw ?? "").trim();
|
||||
if (!s || s === "-" || s.toLowerCase() === "null") return "";
|
||||
if (s.includes("%")) return s;
|
||||
if (/^-?\d+(\.\d+)?$/.test(s)) {
|
||||
return `${s.replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "")}%`;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/** 税率 rate:0.09→9%;大于 1 按百分点。 */
|
||||
function formatLandTaxRate(raw: unknown): string {
|
||||
const s = String(raw ?? "").trim();
|
||||
if (!s || s === "-" || s.toLowerCase() === "null") return "";
|
||||
if (s.includes("%")) return s;
|
||||
if (!/^-?\d+(\.\d+)?$/.test(s)) return s;
|
||||
const n = Number(s);
|
||||
if (!Number.isFinite(n)) return s;
|
||||
const abs = Math.abs(n);
|
||||
const pct = abs > 0 && abs <= 1 ? n * 100 : n;
|
||||
return `${String(pct).replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "")}%`;
|
||||
}
|
||||
|
||||
/** rateFlag:1=含税,0=不含税。 */
|
||||
function formatLandTaxIncluded(raw: unknown): string {
|
||||
const s = String(raw ?? "").trim();
|
||||
if (!s || s === "-" || s.toLowerCase() === "null") return "";
|
||||
if (s === "1" || s.toLowerCase() === "true" || s === "是" || s === "含税") return "含税";
|
||||
if (s === "0" || s.toLowerCase() === "false" || s === "否" || s === "不含税") return "不含税";
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主账 inq_ticket_status_log.action 是内部码,禁止当备注展示。
|
||||
* transition 与「已报价」等 toStatus 重复,无用户备注时不再跟一段英文。
|
||||
|
||||
Reference in New Issue
Block a user