文件
hyb-oa/server/src/services/integrations/travel.js
T

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,
};