168 lines
5.9 KiB
JavaScript
168 lines
5.9 KiB
JavaScript
const args = Object.fromEntries(
|
|
process.argv.slice(2)
|
|
.map((arg) => arg.replace(/^--/, "").split("="))
|
|
.map(([k, v]) => [k, v ?? "true"])
|
|
);
|
|
|
|
const BASE_URL = args.baseUrl || process.env.BASE_URL || "http://localhost:5000/api";
|
|
const PASSWORD = "Admin@123";
|
|
const STEP_DELAY_MS = Number(args.delayMs || 500);
|
|
|
|
const EMAILS = {
|
|
DD_ADMIN: args.ddAdminEmail || "lince@royalenfield.com",
|
|
DEALER: args.dealerEmail,
|
|
ASM: args.asmEmail || "abhishek@royalenfield.com",
|
|
RBM: args.rbmEmail || "manish@royalenfield.com",
|
|
DD_ZM: args.ddZmEmail || "piyush@royalenfield.com",
|
|
ZBH: args.zbhEmail || "manav@royalenfield.com",
|
|
DD_LEAD: args.ddLeadEmail || "jaya@royalenfield.com",
|
|
DD_HEAD: args.ddHeadEmail || "ganesh@royalenfield.com",
|
|
NBH: args.nbhEmail || "yashwin@royalenfield.com",
|
|
LEGAL: args.legalEmail || "legal@royalenfield.com",
|
|
};
|
|
|
|
const ROLE_BY_STAGE = {
|
|
"ASM Review": ["ASM"],
|
|
"RBM Review": ["RBM"],
|
|
"DD ZM Review": ["DD_ZM"],
|
|
"ZBH Review": ["ZBH"],
|
|
"DD Lead Review": ["DD_LEAD"],
|
|
"DD Head Approval": ["DD_HEAD"],
|
|
"NBH Approval": ["NBH"],
|
|
"Legal Clearance": ["LEGAL"],
|
|
"NBH Clearance with EOR": ["NBH"],
|
|
};
|
|
|
|
const delay = (ms = STEP_DELAY_MS) => new Promise((r) => setTimeout(r, ms));
|
|
|
|
async function apiRequest(endpoint, method = "GET", body = null, token = null) {
|
|
const headers = { "Content-Type": "application/json" };
|
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
const config = { method, headers };
|
|
if (body) config.body = JSON.stringify(body);
|
|
|
|
const response = await fetch(`${BASE_URL}${endpoint}`, config);
|
|
const data = await response.json();
|
|
if (!response.ok) {
|
|
throw new Error(`API Error ${method} ${endpoint}: ${JSON.stringify(data)}`);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
async function login(email) {
|
|
if (!login.cache) login.cache = {};
|
|
if (login.cache[email]) return login.cache[email];
|
|
const data = await apiRequest("/auth/login", "POST", { email, password: PASSWORD });
|
|
login.cache[email] = data.token;
|
|
return data.token;
|
|
}
|
|
|
|
async function getRelocationByAnyId(id, token) {
|
|
return apiRequest(`/self-service/relocation/${id}`, "GET", null, token);
|
|
}
|
|
|
|
async function approveCurrentStage(requestId, stageName) {
|
|
const candidateRoles = ROLE_BY_STAGE[stageName] || [];
|
|
if (!candidateRoles.length) {
|
|
throw new Error(`No actor mapping found for stage: ${stageName}`);
|
|
}
|
|
|
|
let lastError = null;
|
|
const attempts = [];
|
|
for (const roleKey of candidateRoles) {
|
|
const email = EMAILS[roleKey];
|
|
if (!email) {
|
|
attempts.push(`${roleKey}:missing-email`);
|
|
continue;
|
|
}
|
|
try {
|
|
const token = await login(email);
|
|
const res = await apiRequest(`/self-service/relocation/${requestId}/action`, "POST", {
|
|
action: "APPROVE",
|
|
comments: `${roleKey} approved relocation request.`,
|
|
}, token);
|
|
return { roleKey, email, message: res.message || "Approved" };
|
|
} catch (error) {
|
|
lastError = error;
|
|
attempts.push(`${roleKey}:${error.message}`);
|
|
}
|
|
}
|
|
throw new Error(
|
|
`Approval failed for stage: ${stageName}. Attempts -> ${attempts.join(" | ")}`
|
|
+ (lastError ? ` | Last error: ${lastError.message}` : "")
|
|
);
|
|
}
|
|
|
|
async function resolveDealerOutlet(dealerToken) {
|
|
const dashboard = await apiRequest("/dealer/dashboard", "GET", null, dealerToken);
|
|
const outlet = dashboard?.data?.outlets?.[0];
|
|
if (!outlet) throw new Error("No dealer outlet found to create relocation request.");
|
|
return outlet;
|
|
}
|
|
|
|
async function run() {
|
|
try {
|
|
console.log("--- STARTING RELOCATION E2E FLOW ---");
|
|
if (!EMAILS.DEALER) {
|
|
throw new Error("Missing --dealerEmail. This script requires an existing dealer user email.");
|
|
}
|
|
const adminToken = await login(EMAILS.DD_ADMIN);
|
|
const dealerToken = await login(EMAILS.DEALER);
|
|
|
|
let requestId = args.requestId;
|
|
if (!requestId) {
|
|
const outlet = await resolveDealerOutlet(dealerToken);
|
|
console.log(`[STEP 1] Submitting relocation for outlet: ${outlet.name} (${outlet.id})`);
|
|
const createRes = await apiRequest("/self-service/relocation", "POST", {
|
|
outletId: args.outletId || outlet.id,
|
|
relocationType: args.relocationType || "Intercity",
|
|
newAddress: args.newAddress || "Sector 21, New Premises",
|
|
newCity: args.newCity || "Gurugram",
|
|
newState: args.newState || "Haryana",
|
|
reason: args.reason || "Business expansion and better customer access",
|
|
proposedDate: args.proposedDate || new Date().toISOString().split("T")[0],
|
|
}, dealerToken);
|
|
requestId = createRes.requestId;
|
|
console.log(`[STEP 1] Request Created: ${requestId}`);
|
|
await delay();
|
|
} else {
|
|
console.log(`[STEP 1] Resuming request: ${requestId}`);
|
|
}
|
|
|
|
let step = 2;
|
|
while (true) {
|
|
const detailsRes = await getRelocationByAnyId(requestId, adminToken);
|
|
const request = detailsRes.request;
|
|
const stage = request.currentStage;
|
|
const status = request.status;
|
|
|
|
if (stage === "Completed" || status === "Completed") {
|
|
console.log(`[STEP ${step}] SUCCESS: Relocation request is completed.`);
|
|
break;
|
|
}
|
|
if (stage === "Rejected" || status === "Rejected") {
|
|
throw new Error(`Relocation request is rejected at stage: ${stage}`);
|
|
}
|
|
|
|
console.log(`[STEP ${step}] Current Stage: ${stage} | Status: ${status}`);
|
|
const actor = await approveCurrentStage(requestId, stage);
|
|
console.log(`[STEP ${step}] ${actor.roleKey} (${actor.email}) -> ${actor.message}`);
|
|
step++;
|
|
await delay();
|
|
}
|
|
|
|
const finalRes = await getRelocationByAnyId(requestId, adminToken);
|
|
console.log("--- VERIFICATION RESULTS ---");
|
|
console.log(`RequestId: ${finalRes.request.requestId || requestId}`);
|
|
console.log(`Final Stage: ${finalRes.request.currentStage}`);
|
|
console.log(`Final Status: ${finalRes.request.status}`);
|
|
console.log("Outcome: RELOCATION FLOW COMPLETED SUCCESSFULLY");
|
|
process.exit(0);
|
|
} catch (error) {
|
|
console.error("Workflow failed:", error.message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
run();
|