Build a Cash Register Project

I’m really stuck. I have no idea what’s going on and all the rounding of the numbers is really throwing me off. I’ve been trying to solve this for 2 days. Please help me out with the findExactChange function.

HTML:

<!DOCTYPE html>
<html lang="en">

  <head>
    <title>Cash Register</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Outputs the exact change that needs to be given from the cash register" />
    <link rel="stylesheet" href="./styles.css" />
    <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cutive+Mono&display=swap" rel="stylesheet">
  </head>


  <body>
    <main>
      <h1>Cash Register Project</h1>
        <div id="due-div">
          <p id="change-status"></p>
          <p id="change-due">  
          </p>
        </div>

        <label for="input-btn"> Enter cash from customer: <input type="number" id="cash"/> </label>

        <button id="purchase-btn">Purchase</button>

      <div id="register">
          <div id="big-block"><p>Total:</p></div>
          <div id="small-block"></div>
        <div id="main-body">
          <div class="key">
            <div class="keys"></div>
            <div class="keys"></div>
            <div class="keys"></div>
            <div class="keys"></div>
            <div class="keys"></div>
            <div class="keys"></div>
            <div class="keys"></div>
            <div class="keys"></div>
            <div class="keys"></div>
          </div>
          <div id="cash-in-drawer">Change in drawer:
            <br>
            <ul id="cash-in-draw-ul">
              
            </ul>
          </div>
        </div>
        <div id="drawer">
          <div id="handle"></div>
        </div>
      </div>
    </main>
    <script src="./script.js"></script>
  </body>

</html>

CSS:

:root {
  --grey: #f2f2f2;
  --navy: #152238;
  --cream: #FCFBF4;
  --black: #1C1C1C;
}

* {
  background-color: var(--navy);
  color: var(--cream);
  font-family: "Cutive Mono";
  font-size: 20px;
  text-align: center;
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  overflow-x: hidden;
}

h1 {
  font-size: 38px;
  padding: 10px;
  margin-bottom: 10px;
  margin-top: 10px;
}

.hidden {
  display: none;
}

#change-ul {
  padding-bottom: 50px;
}

input {
  background-color: var(--grey);
  color: var(--black);
  display: block;
  margin: 10 auto;
  padding: 5px;
  margin-top: 10px;
}

button {
  background-color: var(--black); 
  padding: 5px;
  font-size: 18px;
  margin-top: 10px;
}

div {
  background-color: var(--grey); 
  color: var(--black);
}

#register {
  background-color: var(--navy); 
  margin: 0 auto;
  margin-top: 40px; 
  width: 370px;
}

#big-block {
  width: 180px;
  height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-left: 15%;
}

#big-block p {
  background-color: var(--navy); 
  color: var(--cream);
  width: 90%;
  padding: 2px;
}

#small-block {
  width: 40px;
  height: 30px;
  margin-left: 20%;
}

#main-body {
  width: 370px;
  height: 300px;
  margin: 0 auto;
  border-radius: 50px 50px 0 0;
  display: grid;
}

.key {
  display: inline-grid;
  margin-left: 30px;
  margin-top: 30px;
  grid-template-columns: repeat(3, 25px);
  grid-template-rows: repeat(3, 25px);
}

.keys {
  background-color: var(--navy); 
  width: 10px;
  height: 10px;
}

#cash-in-drawer {
  background-color: var(--black);
  color: var(--cream);
  margin-bottom: 5px;
  width: 90%;
  margin: 10 auto;
  height: 170px;
  padding: 5px;
}

#drawer {
  width: 370px;
  height: 50px;
  margin: 10px auto;
  margin-bottom: 80px;
  display: flex;
  justify-content: center;
  align-items: center;
}

#handle {
  background-color: var(--navy);
  width: 15px;
  height: 15px;
  border-radius: 100%;
  border: 1px solid var(--black);
}

JS:

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]
];

let cashToReturn = [
  ['PENNY', 0],
  ['NICKEL', 0],
  ['DIME', 0],
  ['QUARTER', 0],
  ['ONE', 0],
  ['FIVE', 0],
  ['TEN', 0],
  ['TWENTY', 0],
  ['ONE HUNDRED', 0]
];

const totalDisplay = document.querySelector("#big-block p");
const inputCash = document.getElementById("cash");
const purchaseBtn = document.getElementById("purchase-btn"); 
const changeDueText = document.getElementById("change-due");
const changeDueDiv = document.getElementById("due-div");
const cidList = document.getElementById("cash-in-draw-ul");
const statusP = document.getElementById("change-status");

function evaluateChange() {
  const customerCash = Number(Number(inputCash.value).toFixed(2));
  inputCash.value = "";

  defaultScreen();

  price = Number(price.toFixed(2));
  
  if (customerCash < price) {
    alert("Customer does not have enough money to purchase the item");
  } else if (customerCash === price) {
    changeDueDiv.classList.remove("hidden");
    changeDueText.textContent = "No change due - customer paid with exact cash";
  } else {
    changeDueDiv.classList.remove("hidden");
    calculateChange(customerCash);
    displayCID();
  }
}

function calculateChange(customerCash) {
  let returnAmt = Number((customerCash - price).toFixed(2));
  let moneyInDraw = Number((cid.reduce((acc, ele) => acc + ele[1], 0)).toFixed(2));

  console.log("The return amt is " + returnAmt + " and the money in draw is: " + moneyInDraw);
  
  if (moneyInDraw < returnAmt) {
    statusP.textContent = "Status: INSUFFICIENT_FUNDS";
  } else if (moneyInDraw === returnAmt) {
    statusP.textContent = "Status: CLOSED";
    
    cashToReturn = [];
    cid.forEach((ele) => {
      cashToReturn.push([ele[0], ele[1]]);
    })

    cid = [
      ['PENNY', 0],
      ['NICKEL', 0],
      ['DIME', 0],
      ['QUARTER', 0],
      ['ONE', 0],
      ['FIVE', 0],
      ['TEN', 0],
      ['TWENTY', 0],
      ['ONE HUNDRED', 0]
    ];

    displayChange();
  } else {
    const isSufficient = findExactChange(returnAmt);
    if (isSufficient) {
      displayChange();
    }
  }
}

function findExactChange(returnAmt) {
  returnAmt = Number(returnAmt.toFixed(2)); // Ensure returnAmt is a number with 2 decimal places

  if (returnAmt >= 100 && cid[8][1] >= 100) {
    returnAmt -= 100;
    cid[8][1] -= 100;
    cashToReturn[8][1] += 100;
    findExactChange(returnAmt);
  } else if (returnAmt >= 20 && cid[7][1] >= 20) {
    returnAmt -= 20;
    cid[7][1] -= 20;
    cashToReturn[7][1] += 20;
    findExactChange(returnAmt);
  } else if (returnAmt >= 10 && cid[6][1] >= 10) {
    returnAmt -= 10;
    cid[6][1] -= 10;
    cashToReturn[6][1] += 10;
    findExactChange(returnAmt);
  } else if (returnAmt >= 5 && cid[5][1] >= 5) {
    returnAmt -= 5;
    cid[5][1] -= 5;
    cashToReturn[5][1] += 5;
    findExactChange(returnAmt);
  } else if (returnAmt >= 1 && cid[4][1] >= 1) {
    returnAmt -= 1;
    cid[4][1] -= 1;
    cashToReturn[4][1] += 1;
    findExactChange(returnAmt);
  } else if (returnAmt >= 0.25 && cid[3][1] >= 0.25) {
    returnAmt -= 0.25;
    cid[3][1] -= 0.25;
    cashToReturn[3][1] += 0.25;
    findExactChange(returnAmt);
  } else if (returnAmt >= 0.10 && cid[2][1] >= 0.10) {
    returnAmt -= 0.10;
    cid[2][1] -= 0.10;
    cashToReturn[2][1] += 0.10;
    findExactChange(returnAmt);
  } else if (returnAmt >= 0.05 && cid[1][1] >= 0.05) {
    returnAmt -= 0.05;
    cid[1][1] -= 0.05;
    cashToReturn[1][1] += 0.05;
    findExactChange(returnAmt);
  } else if (returnAmt >= 0.01 && cid[0][1] >= 0.01) {
    returnAmt -= 0.01;
    cid[0][1] -= 0.01;
    cashToReturn[0][1] += 0.01;
    findExactChange(returnAmt);
  } else if (returnAmt === 0) {
    statusP.textContent = "Status: OPEN";
    return true;
  } else {
    statusP.textContent = "Status: INSUFFICIENT_FUNDS";
    return false;
  }
}

function displayChange() {
  for (let i = cashToReturn.length - 1; i >= 0; i--) {
    cashToReturn[i][1] = Number(cashToReturn[i][1]).toFixed(2);
    if (cashToReturn[i][1] != 0) {
      changeDueText.innerHTML += `${cashToReturn[i][0]}: $${cashToReturn[i][1]}<br>`;
    }
  }
}

function displayCID() {
  cidList.innerHTML = "";
  cid.forEach((element) => {
    element[1] = Number(element[1]).toFixed(2)
    cidList.innerHTML += `<li>${element[0]}: $${element[1]}</li>`;
  })
}

inputCash.addEventListener("keydown", (e) => {
  if (e.key === "Enter") {
    evaluateChange();
  }
});

function defaultScreen() {
  changeDueText.textContent = "";
  statusP.textContent = "";
  changeDueDiv.classList.add("hidden");

  totalDisplay.innerText = `Price: $${price}`;

  inputCash.value = "";

  cashToReturn = [
  ['PENNY', 0],
  ['NICKEL', 0],
  ['DIME', 0],
  ['QUARTER', 0],
  ['ONE', 0],
  ['FIVE', 0],
  ['TEN', 0],
  ['TWENTY', 0],
  ['ONE HUNDRED', 0]
];

  displayCID();

}

purchaseBtn.addEventListener("click", evaluateChange);

window.onload = defaultScreen;

You can change all the dollar values to cents and just calculate everything in cents to avoid having to round anything.