Cash Register Working in Preview but not passing tests

Hello,

So, my code here is working in the preview fine, but not passing any tests except the first three checking for the HTML elements. I figure maybe I have made it too complicated, but I have been trying to cover all the cases possible. One thing I have noticed is that when I console.log(changeDue.innerText), nothing shows in the console until the second time I click the ‘make purchase’ button, so maybe that has something to do with why the tests arent running properly, but I dont know why that might be. I know there is a delay perhaps between the JS and the browser, but how can I try and fix that?

Here is the 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="style.css">
  </head>
  <body>
    <h1>Cash Register</h1>
    <input type="number" id="cash"></input>
    <button id="purchase-btn">Make Purchase</button>
    <div id="change-due"></div>
	<script src="script.js"></script>
  </body>
</html>

Here is the JS:

document.addEventListener("DOMContentLoaded", () => {
  const cash = document.getElementById("cash");
  const purchaseBtn = document.getElementById("purchase-btn");
  const changeDue = document.getElementById("change-due");
  
  let price = 19.5;
  let cid = [
    ["PENNY", 0.01],
    ["NICKEL", 0],
    ["DIME", 0],
    ["QUARTER", 0],
    ["ONE", 1],
    ["FIVE", 0],
    ["TEN", 0],
    ["TWENTY", 0],
    ["ONE HUNDRED", 0]
  ];

  const checkChange = () => {
    const inputValue = parseFloat(cash.value).toFixed(2);
    const parsedPrice = parseFloat(price).toFixed(2)
    const cidTotal = parseFloat(cid.reduce((acc, curr) => acc + (curr[1] || 0), 0).toFixed(2));

    
    const toBeChanged = parseFloat(inputValue - parsedPrice).toFixed(2)

    console.log(inputValue)
    console.log(parsedPrice)
    console.log(toBeChanged)
    console.log(cidTotal)
    
    
    if (toBeChanged < 0.00) {
      alert("Customer does not have enough money to purchase the item");
    } else if (Math.abs(toBeChanged) < 0.01) {
      changeDue.innerText = "No change due - customer paid with exact cash";
    } else if (cidTotal < toBeChanged) {
      changeDue.innerText = "Status: INSUFFICIENT_FUNDS"
    } else {
      const allTheChange = changeBack(toBeChanged, cid);
      const allTheChangeTotal = parseFloat(allTheChange.reduce((acc, curr) => acc + (curr[1] || 0), 0)).toFixed(2);

      const formattedChange = allTheChange.length > 0 ? allTheChange.map(([denomination, amount]) => `${denomination}: $${amount}\n`).join(' ') : '';

      if (allTheChange.length === 0 || allTheChangeTotal === cidTotal) {
        changeDue.innerText = `Status: CLOSED\n${formattedChange}`
      } else {
      changeDue.innerText = `Status: OPEN\n${formattedChange}`;
      }
    }
  } 

  const changeBack = (difference, cid) => {
    let allTheChange =[ ]

    const denominations = [
      ["PENNY", 0.01],
      ["NICKEL", 0.05],
      ["DIME", 0.1],
      ["QUARTER", 0.25],
      ["ONE", 1],
      ["FIVE", 5],
      ["TEN", 10],
      ["TWENTY", 20],
      ["ONE HUNDRED", 100]
    ];

    let index = denominations.length - 1;

    while (index >= 0 && cid.length > 0 && cid[index]) {
      const [denom, value] = denominations[index];
      let available = cid[index] ? cid[index][1] : 0;

      if (value <= difference && available > 0) {
        const amountNeeded = Math.floor(difference / value);
        const amountToUse = Math.min(amountNeeded * value, available);

        difference = parseFloat(difference - amountToUse).toFixed(2);
        available -= amountToUse;
        console.log(difference);
        
        if (amountToUse > 0) {
          allTheChange.push([denom, amountToUse]);
        }

        if (difference === 0) {
          return allTheChange;
        }
      }
      index--;
    }
    if (difference > 0) {
      changeDue.innerText = "Status: INSUFFICIENT_FUNDS"
      return
    }
    return allTheChange;
  }
  purchaseBtn.addEventListener("click", checkChange);
});

The cid and price variables needs to be in the global scope, otherwise it won’t be possible to change them to specific cases values when tests are running.

2 Likes

Good lord… Thank you so much!