空运成交后可在本群继续锁舱;调价同步舱位费用桶;出单按空运段骨架落费并保留陆运车型尺寸;导出文件名乱码修复。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+12
-1
@@ -12,6 +12,7 @@ import java.util.Set;
|
||||
* 空运群「当前工单」能不能激活。纯内存规则,不写库。
|
||||
* <p>
|
||||
* 可激活:业务线 AIR,且六态询价中 / 已报价 / 协商中。
|
||||
* 已成交只在锁舱补参数(allowDeal)时允许记到本群。
|
||||
* 一张单同时只跟一个群;已经绑了别的群就 occupied。
|
||||
*/
|
||||
public final class AirGroupActivateRule {
|
||||
@@ -27,13 +28,23 @@ public final class AirGroupActivateRule {
|
||||
* @return 空串表示可以激活;否则是给智能体的错误码
|
||||
*/
|
||||
public static String rejectReason(InquiryTicket ticket, String chatId) {
|
||||
return rejectReason(ticket, chatId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 锁舱补参数时允许把已成交单记在本群,方便下一句不再带工单号。
|
||||
* 未成交、已关闭、转人工仍然不能激活。普通激活不要传 allowDeal。
|
||||
*/
|
||||
public static String rejectReason(InquiryTicket ticket, String chatId, boolean allowDeal) {
|
||||
if (ticket == null) {
|
||||
return "ticket_not_found";
|
||||
}
|
||||
if (!"AIR".equalsIgnoreCase(StringUtils.trimToEmpty(ticket.getBusinessLine()))) {
|
||||
return "not_air";
|
||||
}
|
||||
if (!OPEN.contains(StringUtils.trimToEmpty(ticket.getStatus()))) {
|
||||
String status = StringUtils.trimToEmpty(ticket.getStatus());
|
||||
boolean dealBind = allowDeal && TicketStatuses.DEAL.equals(status);
|
||||
if (!OPEN.contains(status) && !dealBind) {
|
||||
return "terminal";
|
||||
}
|
||||
String bound = StringUtils.trimToEmpty(ticket.getCollabChatId());
|
||||
|
||||
+31
-4
@@ -1043,6 +1043,22 @@ public class InquiryQuoteTemplateServiceImpl extends ServiceImpl<InquiryQuoteTem
|
||||
}
|
||||
out.put("customer_name", customer);
|
||||
out.put("客户名称", customer);
|
||||
// 陆运/中港表头「联系人」「电话」映射码是 contact_*;事实里常是中文键,必须投影否则格子只剩标签
|
||||
String contactName = first(src, "联系人", "contact_name", "联系人姓名", "客户联系人", "contactName");
|
||||
if (StringUtils.isNotBlank(contactName)) {
|
||||
out.put("contact_name", contactName);
|
||||
out.put("联系人", contactName);
|
||||
}
|
||||
String contactPhone = first(src, "电话", "联系电话", "contact_phone", "手机", "手机号", "contactPhone");
|
||||
if (StringUtils.isNotBlank(contactPhone)) {
|
||||
out.put("contact_phone", contactPhone);
|
||||
out.put("电话", contactPhone);
|
||||
}
|
||||
String cargoValue = first(src, "货值", "货物价值", "cargo_value", "货值(元)", "cargoValue");
|
||||
if (StringUtils.isNotBlank(cargoValue)) {
|
||||
out.put("cargo_value", cargoValue);
|
||||
out.put("货值", cargoValue);
|
||||
}
|
||||
boolean hideAirEta = looksAirInquiry(src, q, businessLine);
|
||||
String eta = first(q, "eta", "transit_days", "transitDays");
|
||||
if (!hideAirEta && StringUtils.isNotBlank(eta) && !"-".equals(eta)) {
|
||||
@@ -1077,12 +1093,18 @@ public class InquiryQuoteTemplateServiceImpl extends ServiceImpl<InquiryQuoteTem
|
||||
if (rows.isEmpty()) {
|
||||
rows = QuoteTemplateExcelSupport.parseFeeRows(q.get("fee_rows"));
|
||||
}
|
||||
// 空运:已落库 quote 常只有一条 fee_lines,完整明细在 airOptions.departureCharges。
|
||||
// 行数相同也优先 departureCharges(fee_lines 常把单价误当金额,缺单位)。
|
||||
// 空运:完整明细在 airOptions 分桶 + 顶层 feeItems(空运段)。
|
||||
// 行数相同也优先分桶解析(fee_lines 常把单价误当金额,缺单位/项目列)。
|
||||
Object quoteFeeItems = q.get("feeItems");
|
||||
if (quoteFeeItems == null) {
|
||||
quoteFeeItems = q.get("fee_items");
|
||||
}
|
||||
JSONArray fromAir = QuoteTemplateExcelSupport.parseAirDepartureChargeRows(
|
||||
q.get("airOptions"), q.get("air_options"), chargeable, currency);
|
||||
q.get("airOptions"), q.get("air_options"), quoteFeeItems, chargeable, currency);
|
||||
if (!fromAir.isEmpty()) {
|
||||
rows = fromAir;
|
||||
// 分桶优先,但 flat fee_lines 里多出来的人工调价(如「增值费」)必须并进模板,
|
||||
// 禁止整表替换后把群摘要已展示的费用丢掉(WO202610140006)。
|
||||
rows = QuoteTemplateExcelSupport.mergeAirBucketRowsWithFlatManualFees(fromAir, rows);
|
||||
}
|
||||
if (rows.isEmpty()) {
|
||||
String freight = first(q, "freight");
|
||||
@@ -1104,6 +1126,11 @@ public class InquiryQuoteTemplateServiceImpl extends ServiceImpl<InquiryQuoteTem
|
||||
}
|
||||
}
|
||||
}
|
||||
// 旧 payload 常丢 unit:从 raw_text 回填后再走默认「票」补全
|
||||
if (!rows.isEmpty()) {
|
||||
QuoteTemplateExcelSupport.backfillMissingFeeUnitsFromRawText(
|
||||
rows, first(q, "raw_text", "rawText", "text"));
|
||||
}
|
||||
// 空运:补单位/数量/单价(手工常只有金额,WO020 空运费与增点费)
|
||||
if (!rows.isEmpty()) {
|
||||
List<Map<String, String>> lineMaps = new ArrayList<>();
|
||||
|
||||
+9
-1
@@ -1307,7 +1307,15 @@ public class InquiryWorkOrderServiceImpl extends ServiceImpl<InquiryTicketMapper
|
||||
String room = text(body, "chatId", "chat_id");
|
||||
InquiryTicket ticket = findByWorkOrderNo(no);
|
||||
Map<String, Object> out = new LinkedHashMap<>();
|
||||
String reject = AirGroupActivateRule.rejectReason(ticket, room);
|
||||
Object rawAllow = body == null ? null : body.get("allowDeal");
|
||||
if (rawAllow == null && body != null) {
|
||||
rawAllow = body.get("allow_deal");
|
||||
}
|
||||
// 只有锁舱补参数才带这个标记。普通激活仍拒绝已成交。
|
||||
boolean allowDeal = Boolean.TRUE.equals(rawAllow)
|
||||
|| "true".equalsIgnoreCase(String.valueOf(rawAllow))
|
||||
|| "1".equals(String.valueOf(rawAllow));
|
||||
String reject = AirGroupActivateRule.rejectReason(ticket, room, allowDeal);
|
||||
if (StringUtils.isNotBlank(reject)) {
|
||||
out.put("ok", false);
|
||||
out.put("error", reject);
|
||||
|
||||
+23
@@ -32,11 +32,18 @@ public final class LandQuoteTemplateFields {
|
||||
add("land_freight", "陆运费", "landFreight");
|
||||
add("vehicle_42_fee", "4.2米/3T费用", "vehicle42Fee");
|
||||
add("vehicle_50_fee", "5米/5T费用", "vehicle50Fee");
|
||||
add("vehicle_68_fee", "6.8/5T费用", "vehicle68Fee");
|
||||
add("vehicle_65_fee", "6.5米/8T费用", "vehicle65Fee");
|
||||
add("vehicle_76_fee", "7.6米/8T费用", "vehicle76Fee");
|
||||
add("vehicle_78_fee", "7.8米/10T费用", "vehicle78Fee");
|
||||
add("vehicle_82_fee", "8.2米/10T费用", "vehicle82Fee");
|
||||
add("vehicle_82_12_fee", "8.2米/12T费用", "vehicle8212Fee");
|
||||
add("vehicle_96_fee", "9.6米/10T费用", "vehicle96Fee");
|
||||
add("vehicle_59_fee", "5.9米/20尺费用", "vehicle59Fee");
|
||||
add("vehicle_12_fee", "12米/40尺费用", "vehicle12Fee");
|
||||
add("vehicle_125_fee", "12.5米/40尺费用", "vehicle125Fee");
|
||||
add("vehicle_135_fee", "13.5米/45尺费用", "vehicle135Fee");
|
||||
add("vehicle_15_reefer_fee", "15米/冷柜费用", "vehicle15ReeferFee");
|
||||
add("vehicle_165_fee", "16.5米/53尺费用", "vehicle165Fee");
|
||||
add("vehicle_3t_fee", "4.1*2.1*2.3M/3T费用", "vehicle3TFee");
|
||||
add("vehicle_5t_fee", "6.5*2.4*2.5M/5T费用", "vehicle5TFee");
|
||||
@@ -51,9 +58,25 @@ public final class LandQuoteTemplateFields {
|
||||
LABEL_TO_CODE.put("时效", "transit_days");
|
||||
LABEL_TO_CODE.put("干线费", "land_freight");
|
||||
LABEL_TO_CODE.put("运费", "land_freight");
|
||||
// 20261012 国内整车 / 中港:短表头(无「费用」后缀)也要能对上填表码
|
||||
LABEL_TO_CODE.put("4.2米/3T", "vehicle_42_fee");
|
||||
LABEL_TO_CODE.put("5米/5T", "vehicle_50_fee");
|
||||
LABEL_TO_CODE.put("6.8/5T", "vehicle_68_fee");
|
||||
LABEL_TO_CODE.put("6.8米/5T", "vehicle_68_fee");
|
||||
LABEL_TO_CODE.put("6.5米/8T", "vehicle_65_fee");
|
||||
LABEL_TO_CODE.put("7.6米/8T", "vehicle_76_fee");
|
||||
LABEL_TO_CODE.put("7.8米/10T", "vehicle_78_fee");
|
||||
LABEL_TO_CODE.put("8.2米/10T", "vehicle_82_fee");
|
||||
LABEL_TO_CODE.put("8.2米/12T", "vehicle_82_12_fee");
|
||||
LABEL_TO_CODE.put("9.6米/10T", "vehicle_96_fee");
|
||||
LABEL_TO_CODE.put("5.9米/20尺", "vehicle_59_fee");
|
||||
LABEL_TO_CODE.put("12米/40尺", "vehicle_12_fee");
|
||||
LABEL_TO_CODE.put("12.5米/40尺", "vehicle_125_fee");
|
||||
LABEL_TO_CODE.put("13.5米/45尺", "vehicle_135_fee");
|
||||
LABEL_TO_CODE.put("15米/冷柜", "vehicle_15_reefer_fee");
|
||||
LABEL_TO_CODE.put("16.5米/53尺", "vehicle_165_fee");
|
||||
LABEL_TO_CODE.put("13.75米平板", "vehicle_1375_fee");
|
||||
LABEL_TO_CODE.put("17.5米平板", "vehicle_175_fee");
|
||||
LABEL_TO_CODE.put("元/KG", "price_per_kg");
|
||||
}
|
||||
|
||||
|
||||
+725
-75
File diff suppressed because it is too large
Load Diff
+39
-8
@@ -32,7 +32,7 @@ import java.util.Map;
|
||||
* 有真实 TMS 编号才带 quoteId。有值才出站,缺航班不拦。
|
||||
* SYSTEM 出站精简(quoteId + 航班等标量,不带 validUntil/feeItems);
|
||||
* MANUAL 费用名按 TMS 查价回包原样带回,有效期必须带时区 ISO8601。
|
||||
* 已成交再释放:本地拦住。测服打开 TMS_V2_LOCK_ENABLED;现网验收期保持关闭。
|
||||
* 只有已成交才能锁舱。成交并锁上之后仍可释放。测服打开 TMS_V2_LOCK_ENABLED;现网验收期保持关闭。
|
||||
* 禁止:按 userid 伪造报价;单测打真实 TMS。
|
||||
*/
|
||||
@Slf4j
|
||||
@@ -55,6 +55,27 @@ public class InquiryTmsCabinService {
|
||||
/** 多段询价锁舱的产品口径。智能体群回复与主账拒绝用同一句。 */
|
||||
public static final String MULTI_LOCK_UNSUPPORTED = "多段询价,暂时不支持锁舱";
|
||||
|
||||
/**
|
||||
* 锁舱成交门禁。已成交返回空串,表示可以继续拼锁舱正文。
|
||||
* 协商中、未成交、已关闭/转人工、以及还没回复成交,各自一个错误码。
|
||||
*/
|
||||
static String lockDealGate(String status) {
|
||||
String st = StringUtils.trimToEmpty(status);
|
||||
if (TicketStatuses.DEAL.equals(st)) {
|
||||
return "";
|
||||
}
|
||||
if (TicketStatuses.NEGOTIATING.equals(st)) {
|
||||
return "lock_negotiating";
|
||||
}
|
||||
if (TicketStatuses.LOST.equals(st)) {
|
||||
return "lock_lost";
|
||||
}
|
||||
if (TicketStatuses.CLOSED.equals(st) || TicketStatuses.HANDOFF.equals(st)) {
|
||||
return "ticket_closed";
|
||||
}
|
||||
return "lock_need_deal";
|
||||
}
|
||||
|
||||
/**
|
||||
* 还没到 TMS 之前的拒绝原因。空运单返回空,表示可以继续锁。
|
||||
* 多段整单不是 AIR,但航线会按空运段来锁,单独说明暂不支持。
|
||||
@@ -86,9 +107,18 @@ public class InquiryTmsCabinService {
|
||||
String code = MULTI_LOCK_UNSUPPORTED.equals(lockReject) ? "multi_no_lock" : "not_air";
|
||||
return fail(code, lockReject);
|
||||
}
|
||||
if (TicketStatuses.DEAL.equals(ticket.getStatus())
|
||||
|| TicketStatuses.CLOSED.equals(ticket.getStatus())) {
|
||||
return fail("ticket_closed", "工单已是「" + ticket.getStatus() + "」,不能锁舱");
|
||||
String dealGate = lockDealGate(ticket.getStatus());
|
||||
if ("lock_negotiating".equals(dealGate)) {
|
||||
return fail(dealGate, "工单还在协商中,成交后才能锁舱");
|
||||
}
|
||||
if ("lock_lost".equals(dealGate)) {
|
||||
return fail(dealGate, "工单已是「未成交」,不能锁舱");
|
||||
}
|
||||
if ("ticket_closed".equals(dealGate)) {
|
||||
return fail(dealGate, "工单已是「" + ticket.getStatus() + "」,不能锁舱");
|
||||
}
|
||||
if ("lock_need_deal".equals(dealGate)) {
|
||||
return fail(dealGate, "请销售先确认工单「已成交」");
|
||||
}
|
||||
List<InquiryQuote> rows = quoteRows(no);
|
||||
if (rows.isEmpty()) {
|
||||
@@ -279,7 +309,7 @@ public class InquiryTmsCabinService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能体释放入口。已成交不调 TMS。
|
||||
* 智能体释放入口。已成交仍可取消已锁舱位。没有成功锁舱记录则不调 TMS。
|
||||
*/
|
||||
public Map<String, Object> releaseCabin(Map<String, Object> body) {
|
||||
String no = text(body, "workOrderNo", "work_order_no");
|
||||
@@ -288,9 +318,6 @@ public class InquiryTmsCabinService {
|
||||
if (ticket == null) {
|
||||
return fail("ticket_not_found", "找不到工单");
|
||||
}
|
||||
if (TicketStatuses.DEAL.equals(ticket.getStatus())) {
|
||||
return fail("deal_blocked", "工单已成交");
|
||||
}
|
||||
if (StringUtils.isBlank(lockId)) {
|
||||
return fail("release_need_lock", "本单还没有成功锁舱记录");
|
||||
}
|
||||
@@ -1442,6 +1469,10 @@ public class InquiryTmsCabinService {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调试会话 3ba460:手工报价锁舱死循环取证。写 NDJSON,不含密钥。
|
||||
*/
|
||||
|
||||
private static String text(Map<String, Object> body, String... keys) {
|
||||
if (body == null || keys == null) {
|
||||
return "";
|
||||
|
||||
+68
-21
@@ -786,8 +786,9 @@ public class InquiryTmsQueryService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 空运舱位选项上的 departureCharges → 扁平费用行。
|
||||
* TMS 字段:chargeName / unitPrice / unit / currency;行金额出单时再按计费重补。
|
||||
* 空运舱位分桶费用 → 扁平费用行。
|
||||
* TMS:feeItems=空运段,departureCharges=起运港,destinationCharges=目的地;
|
||||
* 行金额出单时再按计费重补(仅空运段)。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static List<Map<String, String>> extractAirDepartureCharges(Map<String, Object> data, String headerCurrency) {
|
||||
@@ -806,15 +807,21 @@ public class InquiryTmsQueryService {
|
||||
if (!(raw instanceof List)) {
|
||||
return out;
|
||||
}
|
||||
Object topFeeItems = first(data.get("feeItems"), data.get("fee_items"));
|
||||
for (Object optObj : (List<?>) raw) {
|
||||
if (!(optObj instanceof Map)) {
|
||||
continue;
|
||||
}
|
||||
Map<?, ?> opt = (Map<?, ?>) optObj;
|
||||
// 合并 departureCharges + feeItems,避免只取附加费丢掉空运费
|
||||
List<Map<?, ?>> charges = mergeAirOptionChargeMaps(opt);
|
||||
Map<Object, Object> opt = new LinkedHashMap<>((Map<?, ?>) optObj);
|
||||
// 舱位缺 feeItems 时补整单顶层(TMS 常把空运费放在 data.feeItems)
|
||||
if (topFeeItems instanceof List
|
||||
&& !(opt.get("feeItems") instanceof List)
|
||||
&& !(opt.get("fee_items") instanceof List)) {
|
||||
opt.put("feeItems", topFeeItems);
|
||||
}
|
||||
List<Map<String, Object>> charges = mergeAirOptionChargeMaps(opt);
|
||||
String optCcy = firstText(opt.get("currency"), headerCurrency);
|
||||
for (Map<?, ?> ch : charges) {
|
||||
for (Map<String, Object> ch : charges) {
|
||||
if (ch == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -823,18 +830,24 @@ public class InquiryTmsQueryService {
|
||||
if (StringUtils.isBlank(name) || StringUtils.isBlank(unitPrice)) {
|
||||
continue;
|
||||
}
|
||||
String project = firstText(ch.get("project"), "其它");
|
||||
String amountRaw = firstText(ch.get("amount"), unitPrice);
|
||||
String lineCcy = firstText(ch.get("currency"), optCcy, headerCurrency);
|
||||
Map<String, String> extras = new LinkedHashMap<>();
|
||||
putExtra(extras, "unit", firstText(ch.get("unit"), ch.get("unitName")));
|
||||
putExtra(extras, "unit_price", unitPrice);
|
||||
// 固定费无数量时默认 1;运输费 enrich 会改成计费重
|
||||
putExtra(extras, "project", project);
|
||||
String qty = firstText(ch.get("quantity"), ch.get("chargeQuantity"), ch.get("charge_quantity"));
|
||||
putExtra(extras, "quantity", StringUtils.isBlank(qty) ? "1" : qty);
|
||||
putExtra(extras, "project", isAirWeightFeeName(name) ? "空运段" : "起运港");
|
||||
// 先把单价写入 amount;运输费会在 enrich 里改成 单价×计费重
|
||||
addFeeLine(out, name, unitPrice, lineCcy, extras);
|
||||
boolean airSeg = "空运段".equals(project) && isAirWeightFeeName(name);
|
||||
if (StringUtils.isNotBlank(qty)) {
|
||||
putExtra(extras, "quantity", qty);
|
||||
} else if (!airSeg) {
|
||||
putExtra(extras, "quantity", "1");
|
||||
}
|
||||
// 空运段先写金额原文(或单价);enrich 再按计费重重算
|
||||
addFeeLine(out, name, amountRaw, lineCcy, extras);
|
||||
}
|
||||
// departureCharges 只有附加费时,用舱位 salePrice 补空运费(与出单 parse 对齐)
|
||||
// 无空运段运费时,用舱位 salePrice 补空运费(与出单 parse 对齐)
|
||||
injectAirFreightFeeLineIfMissing(out, opt, headerCurrency);
|
||||
// 通常只用首个舱位选项的费用明细
|
||||
if (!out.isEmpty()) {
|
||||
@@ -844,15 +857,31 @@ public class InquiryTmsQueryService {
|
||||
return out;
|
||||
}
|
||||
|
||||
/** 合并舱位 departureCharges / feeItems,同名去重。 */
|
||||
/**
|
||||
* 按 TMS 桶合并:feeItems→空运段,departureCharges→起运港,destinationCharges→目的地。
|
||||
* 同名去重,先出现的桶优先。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static List<Map<?, ?>> mergeAirOptionChargeMaps(Map<?, ?> opt) {
|
||||
List<Map<?, ?>> out = new ArrayList<>();
|
||||
static List<Map<String, Object>> mergeAirOptionChargeMaps(Map<?, ?> opt) {
|
||||
List<Map<String, Object>> out = new ArrayList<>();
|
||||
if (opt == null) {
|
||||
return out;
|
||||
}
|
||||
Set<String> seen = new HashSet<>();
|
||||
for (Object key : new Object[]{"departureCharges", "departure_charges", "charges", "feeItems", "fee_items"}) {
|
||||
appendAirBucketMaps(out, seen, opt, "空运段", "feeItems", "fee_items");
|
||||
appendAirBucketMaps(out, seen, opt, "起运港", "departureCharges", "departure_charges", "charges");
|
||||
appendAirBucketMaps(out, seen, opt, "目的地",
|
||||
"destinationCharges", "destination_charges", "arrivalCharges", "destCharges");
|
||||
return out;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void appendAirBucketMaps(List<Map<String, Object>> out, Set<String> seen,
|
||||
Map<?, ?> opt, String project, String... keys) {
|
||||
if (out == null || opt == null || keys == null) {
|
||||
return;
|
||||
}
|
||||
for (String key : keys) {
|
||||
Object raw = opt.get(key);
|
||||
if (!(raw instanceof List)) {
|
||||
continue;
|
||||
@@ -870,22 +899,34 @@ public class InquiryTmsQueryService {
|
||||
if (!seen.add(dedupe)) {
|
||||
continue;
|
||||
}
|
||||
out.add(ch);
|
||||
Map<String, Object> copy = new LinkedHashMap<>();
|
||||
for (Map.Entry<?, ?> e : ch.entrySet()) {
|
||||
if (e.getKey() != null) {
|
||||
copy.put(String.valueOf(e.getKey()), e.getValue());
|
||||
}
|
||||
}
|
||||
copy.put("project", project);
|
||||
out.add(copy);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查价投影 fee_lines:明细无运输/空运费时,用舱位 salePrice/unitPrice 注入。
|
||||
* 查价投影 fee_lines:明细无空运段运费时,用舱位 salePrice/unitPrice 注入。
|
||||
* 与 QuoteTemplateExcelSupport.injectAirFreightLineIfMissing 口径一致。
|
||||
* 起运港「运输费」不算已有空运段。
|
||||
*/
|
||||
static void injectAirFreightFeeLineIfMissing(List<Map<String, String>> lines, Map<?, ?> opt, String headerCurrency) {
|
||||
if (lines == null || opt == null) {
|
||||
return;
|
||||
}
|
||||
for (Map<String, String> line : lines) {
|
||||
if (line != null && isAirWeightFeeName(line.get("name"))) {
|
||||
if (line == null) {
|
||||
continue;
|
||||
}
|
||||
String project = StringUtils.trimToEmpty(line.get("project"));
|
||||
if ((project.isEmpty() || "空运段".equals(project) || "空运".equals(project))
|
||||
&& isAirWeightFeeName(line.get("name"))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -950,16 +991,22 @@ public class InquiryTmsQueryService {
|
||||
if (line == null || !isAirWeightFeeName(line.get("name"))) {
|
||||
continue;
|
||||
}
|
||||
// 已标明非空运段(起运港「运输费」等)禁止乘计费重
|
||||
String project = StringUtils.trimToEmpty(line.get("project"));
|
||||
if (StringUtils.isNotBlank(project)
|
||||
&& !"空运段".equals(project) && !"空运".equals(project)) {
|
||||
continue;
|
||||
}
|
||||
String unitPrice = firstText(line.get("unit_price"), line.get("unitPrice"));
|
||||
String qty = firstText(line.get("quantity"));
|
||||
String amount = firstText(line.get("amount"));
|
||||
String unit = firstText(line.get("unit"));
|
||||
if (StringUtils.isBlank(qty)) {
|
||||
line.put("quantity", chargeable);
|
||||
qty = chargeable;
|
||||
}
|
||||
// TMS 常给单位「板数」;按计费重计价时统一写成 KG
|
||||
line.put("unit", "KG");
|
||||
line.put("project", "空运段");
|
||||
// 有数量、无单价:当前 amount 当作单价(TMS 把费率塞进 salePrice/amount)
|
||||
if (StringUtils.isBlank(unitPrice) && StringUtils.isNotBlank(amount)) {
|
||||
line.put("unit_price", amount);
|
||||
|
||||
Reference in New Issue
Block a user