Build a Cash Register Project - Build a Cash Register

Hello everybody!
I have been stuck on the javascript cash register project for a long time now and simply cannot manage to get it working. My problem is calculating the change I need to return in case of the open status. Thus I fail two tests. The rest of my code (albeit very long) seems to work or at least pass the tests.

Your code so far

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Cash Register</title>
    <link rel="stylesheet" href="./styles.css" />
  </head>
  <body>
    <main>
      <h1>Cash Register Project</h1>
      <div id="change-due"></div>
      <div class="input-div">
        <label for="cash">Enter customer's cash:</label>
        <input type="number" id="cash" class="user-input" value="" />
        <button class="check-btn-styles" id="purchase-btn">Purchase</button>
      </div>
      <div class="checkout">
        <div class="top-display">
          <p id="price-screen" class="price-screen"></p>
        </div>
        <div class="top-register">
          <div class="keypad">
            <button class="key"></button>
            <button class="key"></button>
            <button class="key"></button>
            <button class="key"></button>
            <button class="key"></button>
            <button class="key"></button>
            <button class="key"></button>
            <button class="key"></button>
            <button class="key"></button>
            <button class="key"></button>
            <button class="key"></button>
            <button class="key"></button>
          </div>
          <div id="cash-display" class="cash-display"></div>
        </div>
      </div>
    </main>
    <script src="./script.js"></script>
  </body>
</html>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  --dark-blue: #152636;
  --light-blue: #57b8bc;
  --turquoise: #b4d2d3;
  --beige: #f3cfa4;
}

body {
  background: var(--dark-blue);
  color: var(--turquoise);
}

main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  padding: 40px, 10px;
}

h1 {
  font-size: 3rem;
  margin: 20px 0;
  text-align: center;
}

#change-due {
  text-align: left;
  font-size: 1.2rem;
}

.checkout {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.input-div {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  margin: 10px 0 20px;
}

label {
  font-size: 22px;
}

.user-input {
  height: 30px;
  padding: 10px;
  margin: 10px;
  font-size: 15px;
  background: var(--beige);
}

.price-screen {
  border: 10px solid var(--light-blue);
  background: black;
  height: 60px;
  width: 200px;
  color: white;
  font-size: 1.2rem;
  text-align: center;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
}

#price {
  font-size: 1.5rem;
  text-align: center;
}

.top-register {
  display: flex;
  justify-content: space-around;
  border-radius: 35px 35px 0 0;
  padding-top: 20px;
  background: var(--light-blue);
  height: 270px;
  width: 335px;
}

.keypad {
  width: 25%;
  margin-left: 15px;
  margin-top: 30px;
}

.key {
  border-radius: 10%;
  border: none;
  width: 20px;
  height: 20px;
  background: linear-gradient(to bottom, red,orange,yellow,green,blue,indigo,violet);
}

.check-btn-styles {
  cursor: pointer;
  width: 120px;
  height: 35px;
  margin: 10px;
  color: black;
  font-size: 18px;
  font-weight: bold;
  background-color: var(--beige);
  background-image: linear-gradient(#d9cfbc, #cdbbad);
  border-color: var(--beige);
  border-width: 3px;
}

.cash-display {
  font-size: 1.1rem;
  background-color: var(--beige);
  width: 55%;
  height: 95%;
  color: black;
  padding: 10px;
  margin-right: 10px;
  border-radius: 8px;
}
let price = 1.87;
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 cash = document.getElementById('cash');
const displayChangeDue = document.getElementById('change-due');
const purchaseBtn = document.getElementById('purchase-btn');

const checkCashRegister = (price, cash, cid) => {
  const currencyUnit = [
    { name: "ONE HUNDRED", val: 100 },
    { name: "TWENTY", val: 20 },
    { name: "TEN", val: 10 },
    { name: "FIVE", val: 5 },
    { name: "ONE", val: 1 },
    { name: "QUARTER", val: 0.25 },
    { name: "DIME", val: 0.1 },
    { name: "NICKEL", val: 0.05 },
    { name: "PENNY", val: 0.01 }
  ];

  const changeDue = Number(cash - price).toFixed(2);

  if (cash === price) {
    displayChangeDue.innerHTML = '<p>No change due - customer paid with exact cash</p>';
    return;
  } else if (cash < price) {
    alert('Customer does not have enough money to purchase the item');
    return;
  } else {
    const reversedCid = [...cid].reverse();
    const totalDrawer = reversedCid.reduce((sum, category) => sum + category[1], 0).toFixed(2);

    if (totalDrawer < changeDue) {
      displayChangeDue.innerHTML = '<p>Status: INSUFFICIENT_FUNDS</p>';
      return;
    } else if (totalDrawer === changeDue) {
      const formatter = (status, change) => {
        displayChangeDue.innerHTML = `<p>Status: ${status}</p>`;
        change.map(
          dollars => (displayChangeDue.innerHTML += `<p>${dollars[0]}: $${dollars[1]}</p>`)
        );
        return;
      };
      formatter('CLOSED', reversedCid);
      return;
    } else {
      const changeCoins = calculateChange(changeDue, cid);
      displayChangeDue.innerHTML = `<p>Status: OPEN<br>${changeCoins.map(([name, value]) => `${name}: $${value}`).join('<br>')}</p>`;
    }
  }
};

const calculateChange = (changeDue, cid) => {
  const changeCoins = [];

  const changeArr = currencyUnit.reduce((acc, curr) => {
    let value = 0;

    while (cid[curr.name] > 0 && changeDue >= curr.val) {
      changeDue -= curr.val;
      cid[curr.name] -= curr.val;
      value += curr.val;
      changeDue = Math.round(changeDue * 100) / 100;
    }

    if (value > 0) {
      acc.push([curr.name, value]);
    }

    return acc;
  }, []);

  return changeArr;
};

purchaseBtn.addEventListener('click', () => {
  const cashValue = parseFloat(cash.value);
  checkCashRegister(price, cashValue, cid);
});

cash.addEventListener('keydown', e => {
  if (e.key === 'Enter') {
    const cashValue = parseFloat(cash.value);
    checkCashRegister(price, cashValue, cid);
  }
});

I think the problem is in my calculateChange function or in how I return the result in the else-clause within the else-clause.

Any help/hints/advice would be greatly appreciated.
Thank you in advance and happy coding!

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3 Safari/605.1.15

Challenge Information:

Build a Cash Register Project - Build a Cash Register

I’ve edited your code for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

Thank you for that ilenia! I tried to do that, but obviously wasn’t successful. I didn’t use backticks, but quotation marks.