Build a Cash Register Project - Build a Cash Register

Tell us what’s happening:

Hi, hope some one can help. I have been doing this project, but tests 7-13, 18 and 19 keep failing. It seems to me to be functioning properly and I just can’t figure it out.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Cash Register</title>
    <link rel="stylesheet" href="./styles.css">
  </head>
  <body>
    <h1>Cash Register</h1>
    <div class="register">
        <label for="price">Item Price: $</label>
        <input type="number" id="price" step="0.01" value="2.45">
    </div>
    <div class="register">
        <label for="cash">Cash Provided: $</label>
        <input type="number" id="cash" step="0.01">
    </div>
    <button id="purchase-btn">Purchase</button>
    <p id="change-due">Change Due: </p>
    <p id="cid">Cash In Drawer:</p>


    <script src="./script.js"></script>
  </body>
</html>
/* file: script.js */
let price = 0;
let cash = 0;

let cid = [
  ["PENNY", 1.01],
  ["NICKEL", 2.05],
  ["DIME", 3.1],
  ["QUARTER", 4.25],
  ["ONE", 90],
  ["FIVE", 55],
  ["TEN", 20],
  ["TWENTY", 60],
  ["ONE HUNDRED", 100],
];

const currencyValues = {
  "PENNY": 0.01,
  "NICKEL": 0.05,
  "DIME": 0.10,
  "QUARTER": 0.25,
  "ONE": 1,
  "FIVE": 5,
  "TEN": 10,
  "TWENTY": 20,
  "ONE HUNDRED": 100,
};

const purchaseBtn = document.getElementById("purchase-btn");
const changeDueElement = document.getElementById("change-due");
const cidElement = document.getElementById("cid");

const updateCidElement = (cidArr) => {
  return 'Cash In Drawer: $' + calculateTotalCid(cidArr) +
    cidArr.map(([denom, val]) => `<p>${denom}: ${val.toFixed(2)}</p>`).join('');
};
cidElement.innerHTML = updateCidElement(cid);

function calculateTotalCid(cidArr) {
  return parseFloat(cidArr.reduce((sum, [_, val]) => sum + val, 0).toFixed(2));
}

function calculateChangeDue(changeValueDue, cashInDrawer) {
  let change = [];
  let remaining = changeValueDue;
  const drawer = [...cashInDrawer].reverse();
  const totalCid = calculateTotalCid(cashInDrawer);

  for (let [denom, amount] of drawer) {
    const unit = currencyValues[denom];
    let given = 0;

    while (remaining >= unit && amount >= unit) {
      given += unit;
      amount -= unit;
      remaining -= unit;
      remaining = parseFloat(remaining.toFixed(2));
    }

    if (given > 0) {
      change.push([denom, parseFloat(given.toFixed(2))]);
    }
  }

  const totalGiven = calculateTotalCid(change);

  if (remaining > 0 || totalGiven < changeValueDue) {
    return { status: "INSUFFICIENT_FUNDS", change: [] };
  } else if (totalGiven === totalCid) {
    return { status: "CLOSED", change: [...cashInDrawer].filter(([, amt]) => amt > 0).sort((a, b) => currencyValues[b[0]] - currencyValues[a[0]]) };
  } else {
    return { status: "OPEN", change };
  }
}

function updateCid(changeArr) {
  for (let [denom, amount] of changeArr) {
    for (let i = 0; i < cid.length; i++) {
      if (cid[i][0] === denom) {
        cid[i][1] = parseFloat((cid[i][1] - amount).toFixed(2));
      }
    }
  }
  cidElement.innerHTML = updateCidElement(cid);
}

const formatValue = (val) => val % 1 === 0 ? val.toFixed(0) : parseFloat(val.toFixed(2)).toString();

const processPayment = () => {
  const priceInput = document.getElementById("price");
  const cashInput = document.getElementById("cash");
  price = parseFloat(priceInput.value);
  cash = parseFloat(cashInput.value);

  if (isNaN(price) || isNaN(cash)) {
    alert("Please enter valid numbers for price and cash.");
    return;
  }

  if (cash < price) {
    setTimeout(() => alert("Customer does not have enough money to purchase the item"), 0);
    return;
  }

  if (cash === price) {
    changeDueElement.innerText = "No change due - customer paid with exact cash";
    return;
  }

  const changeDue = parseFloat((cash - price).toFixed(2));
  const result = calculateChangeDue(changeDue, cid);
  const { status, change } = result;

  const sortedChange = [...change].sort((a, b) => currencyValues[b[0]] - currencyValues[a[0]]);
  const output = sortedChange.map(([denom, val]) => `${denom}: $${formatValue(val)}`).join(" ");

  if (status === "INSUFFICIENT_FUNDS") {
    changeDueElement.innerText = "Status: INSUFFICIENT_FUNDS";
  } else {
    changeDueElement.innerText = `Status: ${status} ${output}`;
    if (status === "OPEN" || status === "CLOSED") {
      updateCid(change);
    }
  }
};

purchaseBtn.addEventListener("click", processPayment);

/* file: styles.css */
* {
  padding: 0;
  margin: 0;
  line-height: 1.6em;
  font-size: 20px;
}

h1 {
  line-height: 1.1em;
  width: 600px;
  margin: 10px auto;
  font-size: 30px;
}
label {
  font-weight: bold;
}
.register {
  display: flex;
  justify-content: space-between;
  margin: 20px auto;
  width: 100%;
  max-width: 600px;
  border: solid 2px black;
  padding: 10px;
  border-radius: 5px;
}

#purchase-btn {
  display: block;
  margin: auto;
  width: 100%;
  max-width: 600px;
  font-weight: bold;
  border: solid 2px black;
  padding: 10px;
  border-radius: 5px;
  background-color: black;
  color: white;
  font-size: 20px;
  transition: background-color 0.5s, color 0.5s;
}

#purchase-btn:hover {
  background-color: white;
  color: black;
}

#change-due, #cid {
  display: block;
  margin: 20px auto;
  width: 100%;
  max-width: 600px;
  font-weight: bold;
  border: solid 2px black;
  padding: 10px;
  border-radius: 5px;
}

input {
  max-width: 400px;
  width: 100%;
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36

Challenge Information:

Build a Cash Register Project - Build a Cash Register

when do these two get a value?

Hi, thanks for responding. The price and cash variables are initially declared and set to 0, but they’re only assigned actual values when the “Purchase” button is clicked. Until then, they stay at their default values of 0.

are you sure that is what you should do based on the user stories?

Thank you for your help. I made a faulty assumption that I would have to get the item price from an input. Fixing that allowed me to work out the other issues with the code and complete the project.