feat(P20T2-1,P20T2-2,P20T2-3): 卡授权/交易/支付标记/发票绑定/ERP出站后端

这个提交包含在:
2026-03-11 06:41:11 +08:00
父节点 539c2cc4dd
当前提交 dc74d9e53f
共修改 23 个文件,包含 4265 行新增和 218 行删除
+106 -8
查看文件
@@ -1,3 +1,30 @@
function toDateOnly(value) {
if (!value) {
return null;
}
const date = new Date(`${String(value).slice(0, 10)}T00:00:00.000Z`);
return Number.isNaN(date.getTime()) ? null : date;
}
function toDateTime(value) {
if (!value) {
return null;
}
const date = new Date(value);
return Number.isNaN(date.getTime()) ? null : date;
}
function toMoneyString(value) {
if (value == null || value === "") {
return null;
}
const numeric = Number(value);
return Number.isFinite(numeric) ? numeric.toFixed(2) : null;
}
function normalizeTravelImportRows(rows) {
if (!Array.isArray(rows)) {
return [];
@@ -12,12 +39,6 @@ function normalizeTravelImportRows(rows) {
return null;
}
const amountRaw = item?.amount;
const amount = amountRaw == null || amountRaw === "" ? null : Number(amountRaw);
const occurredAt = item?.occurredAt
? new Date(`${String(item.occurredAt).slice(0, 10)}T00:00:00.000Z`)
: null;
const hasTravelRequestId = Object.prototype.hasOwnProperty.call(item ?? {}, "travelRequestId");
const rawTravelRequestId = String(item?.travelRequestId ?? "").trim();
@@ -31,9 +52,84 @@ function normalizeTravelImportRows(rows) {
: null,
travelRequestId: rawTravelRequestId || null,
hasTravelRequestId,
amount: Number.isFinite(amount) ? amount.toFixed(2) : null,
amount: toMoneyString(item?.amount),
currency: String(item?.currency ?? "CNY").trim().toUpperCase() || "CNY",
occurredAt,
occurredAt: toDateOnly(item?.occurredAt),
rawPayload: item ?? null,
};
})
.filter(Boolean);
}
function normalizeTravelAuthorizationRows(rows) {
if (!Array.isArray(rows)) {
return [];
}
return rows
.map((item) => {
const source = String(item?.source ?? "manual").trim().toLowerCase();
const externalAuthNo = String(item?.externalAuthNo ?? item?.externalAuthNumber ?? "").trim();
const employeeId = String(item?.employeeId ?? "").trim();
const travelRequestId = String(item?.travelRequestId ?? "").trim();
if (!externalAuthNo || !employeeId || !travelRequestId) {
return null;
}
return {
source,
externalAuthNo,
employeeId,
travelRequestId,
budgetPoolId:
item?.budgetPoolId && String(item.budgetPoolId).trim()
? String(item.budgetPoolId).trim()
: null,
authorizedAmount: toMoneyString(item?.authorizedAmount),
settledAmount: toMoneyString(item?.settledAmount) ?? "0.00",
reversedAmount: toMoneyString(item?.reversedAmount) ?? "0.00",
currency: String(item?.currency ?? "CNY").trim().toUpperCase() || "CNY",
occurredAt: toDateTime(item?.occurredAt),
expiresAt: toDateTime(item?.expiresAt),
status: String(item?.status ?? "authorized").trim().toLowerCase() || "authorized",
rawPayload: item ?? null,
};
})
.filter(Boolean);
}
function normalizeTravelTransactionRows(rows) {
if (!Array.isArray(rows)) {
return [];
}
return rows
.map((item) => {
const source = String(item?.source ?? "manual").trim().toLowerCase();
const externalTxnId = String(item?.externalTxnId ?? item?.externalTransactionId ?? "").trim();
const employeeId = String(item?.employeeId ?? "").trim();
const travelRequestId = String(item?.travelRequestId ?? "").trim();
if (!externalTxnId || !employeeId || !travelRequestId) {
return null;
}
const rawCardAuthorizationId = String(item?.cardAuthorizationId ?? "").trim();
const rawTravelOrderId = String(item?.travelOrderId ?? "").trim();
return {
source,
externalTxnId,
employeeId,
travelRequestId,
cardAuthorizationId: rawCardAuthorizationId || null,
hasCardAuthorizationId: Object.prototype.hasOwnProperty.call(item ?? {}, "cardAuthorizationId"),
travelOrderId: rawTravelOrderId || null,
hasTravelOrderId: Object.prototype.hasOwnProperty.call(item ?? {}, "travelOrderId"),
amount: toMoneyString(item?.amount),
currency: String(item?.currency ?? "CNY").trim().toUpperCase() || "CNY",
txnType: String(item?.txnType ?? "charge").trim().toLowerCase() || "charge",
status: String(item?.status ?? "pending").trim().toLowerCase() || "pending",
occurredAt: toDateTime(item?.occurredAt),
rawPayload: item ?? null,
};
})
@@ -42,4 +138,6 @@ function normalizeTravelImportRows(rows) {
module.exports = {
normalizeTravelImportRows,
normalizeTravelAuthorizationRows,
normalizeTravelTransactionRows,
};