satyacode
Background
Back to js-datatype-intermediate

12-railway-pnr-system.js

JavaScript
1/**
2 * 🚂 Indian Railway PNR Status System
3 *
4 * IRCTC ka PNR status system bana! PNR data milega with train info,
5 * passengers, aur current statuses. Tujhe ek complete status report
6 * generate karna hai with formatted output aur analytics.
7 *
8 * pnrData object:
9 *   {
10 *     pnr: "1234567890",
11 *     train: { number: "12301", name: "Rajdhani Express", from: "NDLS", to: "HWH" },
12 *     classBooked: "3A",
13 *     passengers: [
14 *       { name: "Rahul Kumar", age: 28, gender: "M", booking: "B1", current: "B1" },
15 *       { name: "Priya Sharma", age: 25, gender: "F", booking: "WL5", current: "B3" },
16 *       { name: "Amit Singh", age: 60, gender: "M", booking: "WL12", current: "WL8" }
17 *     ]
18 *   }
19 *
20 * Status rules (based on current field):
21 *   - Starts with "B" or "S" (berth/seat) => status = "CONFIRMED"
22 *   - Starts with "WL" => status = "WAITING"
23 *   - Equals "CAN" => status = "CANCELLED"
24 *   - Starts with "RAC" => status = "RAC"
25 *
26 * For each passenger generate:
27 *   - formattedName: name.padEnd(20) + "(" + age + "/" + gender + ")"
28 *   - bookingStatus: booking field value
29 *   - currentStatus: current field value
30 *   - statusLabel: one of "CONFIRMED", "WAITING", "CANCELLED", "RAC"
31 *   - isConfirmed: boolean (true only if statusLabel === "CONFIRMED")
32 *
33 * Summary (use array methods on processed passengers):
34 *   - totalPassengers: count of passengers
35 *   - confirmed: count of CONFIRMED
36 *   - waiting: count of WAITING
37 *   - cancelled: count of CANCELLED
38 *   - rac: count of RAC
39 *   - allConfirmed: boolean - every passenger confirmed? (use every)
40 *   - anyWaiting: boolean - some passenger waiting? (use some)
41 *
42 * Other fields:
43 *   - chartPrepared: true if every NON-CANCELLED passenger is confirmed
44 *   - pnrFormatted: "123-456-7890" (3-3-4 dash pattern, use slice + join or concatenation)
45 *   - trainInfo: template literal =>
46 *     "Train: {number} - {name} | {from} → {to} | Class: {classBooked}"
47 *
48 * Hint: Use padEnd(), slice(), join(), map(), filter(), every(), some(),
49 *   startsWith(), template literals, typeof, Array.isArray()
50 *
51 * Validation:
52 *   - Agar pnrData object nahi hai ya null hai, return null
53 *   - Agar pnr string nahi hai ya exactly 10 digits nahi hai, return null
54 *   - Agar train object missing hai, return null
55 *   - Agar passengers array nahi hai ya empty hai, return null
56 *
57 * @param {object} pnrData - PNR data object
58 * @returns {{ pnrFormatted: string, trainInfo: string, passengers: Array<{ formattedName: string, bookingStatus: string, currentStatus: string, statusLabel: string, isConfirmed: boolean }>, summary: { totalPassengers: number, confirmed: number, waiting: number, cancelled: number, rac: number, allConfirmed: boolean, anyWaiting: boolean }, chartPrepared: boolean } | null}
59 *
60 * @example
61 *   processRailwayPNR({
62 *     pnr: "1234567890",
63 *     train: { number: "12301", name: "Rajdhani Express", from: "NDLS", to: "HWH" },
64 *     classBooked: "3A",
65 *     passengers: [
66 *       { name: "Rahul", age: 28, gender: "M", booking: "B1", current: "B1" }
67 *     ]
68 *   })
69 *   // => { pnrFormatted: "123-456-7890",
70 *   //      trainInfo: "Train: 12301 - Rajdhani Express | NDLS → HWH | Class: 3A",
71 *   //      passengers: [...], summary: { ..., allConfirmed: true }, chartPrepared: true }
72 */
73export function processRailwayPNR(pnrData) {
74  if (!pnrData || typeof pnrData !== 'object') return null;
75  if (typeof pnrData.pnr !== 'string') return null;
76  if (pnrData.pnr.length !== 10 || !/^\d{10}$/.test(pnrData.pnr)) return null;
77  if (!pnrData.train || typeof pnrData.train !== 'object') return null;
78  if (!Array.isArray(pnrData.passengers) || pnrData.passengers.length === 0) return null;
79
80  const pnrFormatted = pnrData.pnr.slice(0, 3) + "-"
81    + pnrData.pnr.slice(3, 6) + "-"
82    + pnrData.pnr.slice(6);
83
84  const { number, name, from, to } = pnrData.train;
85  const trainInfo = `Train: ${number} - ${name} | ${from} → ${to} | Class: ${pnrData.classBooked}`;
86
87  const passengers = pnrData.passengers.map(p => {
88    let statusLabel;
89    if (p.current === "CAN") statusLabel = "CANCELLED";
90    else if (p.current.startsWith("WL")) statusLabel = "WAITING";
91    else if (p.current.startsWith("RAC")) statusLabel = "RAC";
92    else statusLabel = "CONFIRMED";
93
94    return {
95      formattedName: p.name.padEnd(20) + `(${p.age}/${p.gender})`,
96      bookingStatus: p.booking,
97      currentStatus: p.current,
98      statusLabel,
99      isConfirmed: statusLabel === "CONFIRMED"
100    };
101  });
102
103  const confirmed = passengers.filter(p => p.statusLabel === "CONFIRMED").length;
104  const waiting = passengers.filter(p => p.statusLabel === "WAITING").length;
105  const cancelled = passengers.filter(p => p.statusLabel === "CANCELLED").length;
106  const rac = passengers.filter(p => p.statusLabel === "RAC").length;
107
108  const summary = {
109    totalPassengers: passengers.length,
110    confirmed, waiting, cancelled, rac,
111    allConfirmed: passengers.every(p => p.isConfirmed),
112    anyWaiting: passengers.some(p => p.statusLabel === "WAITING")
113  };
114
115  const nonCancelled = passengers.filter(p => p.statusLabel !== "CANCELLED");
116  const chartPrepared = nonCancelled.every(p => p.isConfirmed);
117
118  return { pnrFormatted, trainInfo, passengers, summary, chartPrepared };
119}
120