144 行
4.6 KiB
JavaScript
144 行
4.6 KiB
JavaScript
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 [];
|
|
}
|
|
|
|
return rows
|
|
.map((item) => {
|
|
const source = String(item?.source ?? "manual").trim().toLowerCase();
|
|
const externalOrderNo = String(item?.externalOrderNo ?? "").trim();
|
|
const employeeId = String(item?.employeeId ?? "").trim();
|
|
if (!externalOrderNo || !employeeId) {
|
|
return null;
|
|
}
|
|
|
|
const hasTravelRequestId = Object.prototype.hasOwnProperty.call(item ?? {}, "travelRequestId");
|
|
const rawTravelRequestId = String(item?.travelRequestId ?? "").trim();
|
|
|
|
return {
|
|
source,
|
|
externalOrderNo,
|
|
employeeId,
|
|
linkedReimbursementId:
|
|
item?.linkedReimbursementId && String(item.linkedReimbursementId).trim()
|
|
? String(item.linkedReimbursementId).trim()
|
|
: null,
|
|
travelRequestId: rawTravelRequestId || null,
|
|
hasTravelRequestId,
|
|
amount: toMoneyString(item?.amount),
|
|
currency: String(item?.currency ?? "CNY").trim().toUpperCase() || "CNY",
|
|
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,
|
|
};
|
|
})
|
|
.filter(Boolean);
|
|
}
|
|
|
|
module.exports = {
|
|
normalizeTravelImportRows,
|
|
normalizeTravelAuthorizationRows,
|
|
normalizeTravelTransactionRows,
|
|
};
|