Implemented the customer installed-base view
This commit is contained in:
60
src/services/spa/install-base.js
Normal file
60
src/services/spa/install-base.js
Normal file
@@ -0,0 +1,60 @@
|
||||
function createSpaInstallBase({ ACCOUNT_SUMMARY_URL, fetchJson, findNestedObject, normalizeMessageAuthorization }) {
|
||||
const endpoint = "https://spa.oracle.com/oalcrm/web/api/provider-proxy/g2m-installbase-provider/service/account/";
|
||||
async function requestInstallBase(message) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
const partyNumber = String(message.partyNumber || "").trim();
|
||||
const summaryAuth = normalizeMessageAuthorization(message.authorizations?.accountSummary, "account-ti-authorization");
|
||||
const installAuth = normalizeMessageAuthorization(message.authorizations?.installBase, "");
|
||||
if (!partyNumber) throw new Error("Customer Party Number is required.");
|
||||
if (!summaryAuth.value) throw new Error("ACCP-TS authorization is unavailable.");
|
||||
if (!installAuth.name || !installAuth.value) throw new Error("SAIB-TS uiaasHeader.label/value is unavailable.");
|
||||
const summary = await fetchJson(ACCOUNT_SUMMARY_URL, {
|
||||
method: "POST", credentials: "include",
|
||||
headers: { Accept: "application/json", "Content-Type": "application/json", [summaryAuth.name]: summaryAuth.value },
|
||||
body: JSON.stringify([{ key: "regId", value: partyNumber }])
|
||||
}, "requestAccountSummary", debugRequests);
|
||||
const account = findNestedObject(summary, value =>
|
||||
(typeof value.registryId === "string" || typeof value.registryId === "number") && String(value.registryId).trim() !== "");
|
||||
if (!account) throw new Error("registryId was not found in requestAccountSummary.");
|
||||
const payload = {
|
||||
text: "", accountHierarchy: "single", accountScope: "all", productScope: "all",
|
||||
installStatus: ["active", "inactive", "unsupported"], productIds: null,
|
||||
contractEndDate: { to: null, from: null }, contractStartDate: { to: null, from: null },
|
||||
purchaseStartDate: { to: null, from: null }, registryIds: [], gecPartyNumbers: null
|
||||
};
|
||||
const items = [];
|
||||
let offset = 0;
|
||||
// Bound malformed pagination without silently returning a partial result.
|
||||
for (let page = 0; page < 1000; page += 1) {
|
||||
const url = `${endpoint}${encodeURIComponent(String(account.registryId).trim())}?orderBy=currentSupport%3Adesc&limit=25&offset=${offset}`;
|
||||
const result = await fetchJson(url, {
|
||||
method: "POST", credentials: "include",
|
||||
headers: { Accept: "application/json", "Content-Type": "application/json", [installAuth.name]: installAuth.value },
|
||||
body: JSON.stringify(payload)
|
||||
}, "requestInstallBase", debugRequests);
|
||||
if (!result || !Array.isArray(result.items) || typeof result.hasMore !== "boolean"
|
||||
|| result.items.some(item => !item || typeof item !== "object" || Array.isArray(item))) {
|
||||
throw new Error("requestInstallBase returned an invalid collection.");
|
||||
}
|
||||
if (result.offset !== undefined && result.offset !== offset) throw new Error("requestInstallBase returned an unexpected offset.");
|
||||
items.push(...result.items);
|
||||
if (!result.hasMore) return { ok: true, items, debugRequests };
|
||||
if (!result.items.length) throw new Error("requestInstallBase pagination made no progress.");
|
||||
offset += result.items.length;
|
||||
}
|
||||
throw new Error("requestInstallBase pagination limit reached.");
|
||||
} catch (error) {
|
||||
error.debugRequests = debugRequests;
|
||||
throw error;
|
||||
} finally {
|
||||
// The provider chooses the credential header name; never rely on its spelling for redaction.
|
||||
for (const entry of debugRequests) {
|
||||
for (const key of Object.keys(entry.requestHeaders || {})) {
|
||||
if (!/^(accept|content-type)$/i.test(key)) entry.requestHeaders[key] = "(present)";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return { requestInstallBase };
|
||||
}
|
||||
Reference in New Issue
Block a user