feat(P20T2-1,P20T2-2,P20T2-3): 卡授权/交易/支付标记/发票绑定/ERP出站后端
这个提交包含在:
@@ -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,
|
||||
};
|
||||
|
||||
在新工单中引用
屏蔽一个用户