Implemented the feature to identify and update estimates based on the ACR value, consumption start date, and ramp-up
This commit is contained in:
79
src/services/spa/workloads.js
Normal file
79
src/services/spa/workloads.js
Normal file
@@ -0,0 +1,79 @@
|
||||
function createSpaWorkloads({ fetchJson, getCachedWorkloads, normalizeCacheMaxAge, invalidateWorkloadsCache }) {
|
||||
async function requestWorkloadForecastUpdate(message) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
const id = String(message.workloadId ?? "");
|
||||
const token = message.authorization?.value;
|
||||
if (!/^\d+$/.test(id)) throw new Error("A numeric workload ID is required.");
|
||||
if (typeof token !== "string" || !token.trim()) throw new Error("WWB-TS uiaasHeader.value is unavailable.");
|
||||
if (!Array.isArray(message.payload) || !message.payload.length) throw new Error("Monthly estimates are required.");
|
||||
const periods = new Set();
|
||||
const payload = message.payload.map(({ year, month, amount, updatedBy }) => {
|
||||
if (!Number.isInteger(year) || year < 1000 || year > 9999 || !Number.isInteger(month) || month < 1 || month > 12
|
||||
|| typeof amount !== "number" || !Number.isFinite(amount) || amount < 0
|
||||
|| typeof updatedBy !== "string" || !updatedBy.trim()) throw new Error("Invalid monthly estimate.");
|
||||
const period = `${year}-${month}`;
|
||||
if (periods.has(period)) throw new Error("Duplicate forecast month.");
|
||||
periods.add(period);
|
||||
return { year, month, amount, updatedBy: updatedBy.trim() };
|
||||
});
|
||||
const result = await fetchJson(`https://spa.oracle.com/oalcrm/web/api/provider-proxy/wwb-provider/service/workbench-proxy/wwb/mgmt/workloads/${id}/forecast`, {
|
||||
method: "PATCH", credentials: "include",
|
||||
headers: { Accept: "application/json", "Content-Type": "application/json", "wwb-provider-authorization": token.trim() },
|
||||
body: JSON.stringify(payload)
|
||||
}, "requestWorkloadForecastUpdate", debugRequests, { allowEmpty: true });
|
||||
await invalidateWorkloadsCache().catch(() => {});
|
||||
return { ok: true, result, debugRequests };
|
||||
} catch (error) {
|
||||
error.debugRequests = debugRequests;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async function requestWorkloads(message) {
|
||||
const customerId = String(message.customerId ?? "").trim();
|
||||
const token = message.authorization?.value;
|
||||
if (!/^\d+$/.test(customerId)) throw new Error("A numeric CustomerAccount.PartyId is required.");
|
||||
if (typeof token !== "string" || !token.trim()) throw new Error("WWB-TS uiaasHeader.value is unavailable.");
|
||||
const result = await getCachedWorkloads(customerId, token.trim(), normalizeCacheMaxAge(message.cacheMaxAgeMs), message.principal);
|
||||
return { ok: true, customerId, ...result };
|
||||
}
|
||||
|
||||
async function fetchAllWorkloads(customerId, token) {
|
||||
const debugRequests = [];
|
||||
const workloads = new Map();
|
||||
let offset = 0;
|
||||
let limit = 500;
|
||||
try {
|
||||
for (let page = 0; page < 1000; page += 1) {
|
||||
const url = new URL(`https://spa.oracle.com/oalcrm/web/api/provider-proxy/wwb-provider/service/workbench-proxy/wwb/mgmt/customers/${customerId}/workloads`);
|
||||
for (const [name, value] of Object.entries({ workloadStatus: "Pipeline,Implementation,Live", opportunityForecastType: "All",
|
||||
includeForEstimates: "ALL", financialYear: "ROLLING_4_QTRS", offset, limit })) url.searchParams.set(name, String(value));
|
||||
const result = await fetchJson(url.toString(), {
|
||||
method: "GET", credentials: "include",
|
||||
headers: { Accept: "application/json", "wwb-provider-authorization": token }
|
||||
}, "requestWorkloads", debugRequests);
|
||||
if (!result || !Array.isArray(result.workloads) || typeof result.hasNext !== "boolean"
|
||||
|| result.workloads.some(item => !item || !/^\d+$/.test(String(item.id ?? "")))) {
|
||||
throw new Error("requestWorkloads returned an invalid collection.");
|
||||
}
|
||||
const countBefore = workloads.size;
|
||||
for (const item of result.workloads) workloads.set(String(item.id), item);
|
||||
if (!result.hasNext) return { workloads: [...workloads.values()], debugRequests };
|
||||
const responseOffset = Number(result.offset ?? offset);
|
||||
const responseLimit = Number(result.limit ?? limit);
|
||||
if (workloads.size === countBefore || !Number.isSafeInteger(responseOffset) || responseOffset !== offset
|
||||
|| !Number.isSafeInteger(responseLimit) || responseLimit <= 0 || !Number.isSafeInteger(responseOffset + responseLimit)) {
|
||||
throw new Error("requestWorkloads pagination did not advance.");
|
||||
}
|
||||
offset = responseOffset + responseLimit;
|
||||
limit = responseLimit;
|
||||
}
|
||||
throw new Error("requestWorkloads exceeded the pagination limit.");
|
||||
} catch (error) {
|
||||
error.debugRequests = debugRequests;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return { requestWorkloads, fetchAllWorkloads, requestWorkloadForecastUpdate };
|
||||
}
|
||||
Reference in New Issue
Block a user