satyacode
Background
Back to js-functions

05-dabbawala-tracker.js

JavaScript
1/**
2 * 🚂 Dabbawala Delivery Tracker - Closures
3 *
4 * Mumbai ke famous dabbawala system ka tracker bana! Yahan closure ka
5 * use hoga — ek function ke andar private state rakhna hai jo bahar se
6 * directly access nahi ho sakta. Sirf returned methods se access hoga.
7 *
8 * Function: createDabbawala(name, area)
9 *
10 * Returns an object with these methods (sab ek hi private state share karte hain):
11 *
12 *   - addDelivery(from, to)
13 *     Adds a new delivery. Returns auto-incremented id (starting from 1).
14 *     Each delivery: { id, from, to, status: "pending" }
15 *     Agar from ya to empty/missing, return -1
16 *
17 *   - completeDelivery(id)
18 *     Marks delivery as "completed". Returns true if found and was pending.
19 *     Returns false if not found or already completed.
20 *
21 *   - getActiveDeliveries()
22 *     Returns array of deliveries with status "pending" (copies, not references)
23 *
24 *   - getStats()
25 *     Returns: { name, area, total, completed, pending, successRate }
26 *     successRate = completed/total as percentage string "85.00%" (toFixed(2) + "%")
27 *     Agar total is 0, successRate = "0.00%"
28 *
29 *   - reset()
30 *     Clears all deliveries, resets id counter to 0. Returns true.
31 *
32 * IMPORTANT: Private state (deliveries array, nextId counter) should NOT
33 *   be accessible as properties on the returned object.
34 *   Two instances created with createDabbawala should be completely independent.
35 *
36 * Hint: Use closure to keep variables private. The returned object's methods
37 *   form a closure over those variables.
38 *
39 * @param {string} name - Dabbawala's name
40 * @param {string} area - Delivery area
41 * @returns {object} Object with delivery management methods
42 *
43 * @example
44 *   const ram = createDabbawala("Ram", "Dadar");
45 *   ram.addDelivery("Andheri", "Churchgate"); // => 1
46 *   ram.addDelivery("Bandra", "CST");         // => 2
47 *   ram.completeDelivery(1);                   // => true
48 *   ram.getStats();
49 *   // => { name: "Ram", area: "Dadar", total: 2, completed: 1, pending: 1, successRate: "50.00%" }
50 */
51export function createDabbawala(name, area) {
52  let deliveries = []
53  let id = 1
54
55  return {
56    addDelivery(from, to) {
57      if ( !from || !to) {
58        return -1
59      }
60      const currId = id
61      deliveries.push({ id: currId, from, to, status: "pending" })
62      id++
63      return currId
64    },
65
66    completeDelivery(id) {
67      if (typeof id !== "number") {
68        return -1
69      }
70      for (let deliver of deliveries) {
71        if (deliver.id === id) {
72          if (deliver.status === "pending") {
73            deliver.status = "completed"
74            return true
75          }
76          return false
77        }
78      }
79      return false
80    },
81    getActiveDeliveries() {
82      return deliveries.filter(del => del.status === "pending").map(d => ({ ...d }))
83    },
84
85    getStats() {
86      const total = deliveries.length
87
88      const completed = deliveries.filter(
89        (del) => del.status === "completed",
90      ).length
91
92     const pending = total - completed
93
94      let successRate;
95      if (total === 0) {
96        successRate = "0.00%"
97      } else {
98        successRate = ((completed / total) * 100).toFixed(2) + "%"
99      }
100
101      return { name, area, total, completed, pending, successRate }
102    },
103    reset() {
104      deliveries = []
105      id = 1 
106      return true
107    },
108  }
109}