Build a Cash Register Project

This is my code

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Cash Register</title>
  <meta name="viewport" content="width=device.width,initial-scale=1:0">
  <meta charset="utf-8">
  <link rel="stylesheet" href="styles.css">
  </head>
<body>
  <h1>Cash Register</h1>
  <div id="change">

    <h2>Enter cash from customer:</h2>
    <input id="cash" type="number" DOM=""  />
    <button id="purchase-btn">Confirm</button>
    <p id="change-due"></p>
  </div>
  <div id="cash-register">
    <div id="total"><p class="total"></p></div>
    <div id="thing"></div>
    <div id="register-body">
      <div id="buttons">
        <div id="button">1</div>
        <div id="button">2</div>
        <div id="button">3</div>
        <div id="button">4</div>
        <div id="button">5</div>
        <div id="button">6</div>
        <div id="button">7</div>
        <div id="button">8</div>
        <div id="button">0</div>
        <div id="button">+</div>
        <div id="button">-</div>
        <div id="button">*</div>
        <div id="button"class="equals">=</div>
      </div>
      <div id="change-counter">
        <p id="units">Available change:</p>
        <p id="unit"></p>
        <p id="unit"></p>
        <p id="unit"></p>
        <p id="unit"></p>
        <p id="unit"></p>
        <p id="unit"></p>
        <p id="unit"></p>
        <p id="unit"></p>
        <p id="unit"></p>
      </div>
    </div>
    <div id="drawer"><div id="knob"></div></div>
  </div>

<script src="script.js"></script>
</body>
  </html>
let price = 19.5;
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 total = document.querySelector(".total")
const cidName = cid.map(subArr=>subArr[0])
const cidVal = cid.map(subArr=>subArr[1])
const cash = document.querySelector("#cash");
const btn = document.getElementById("purchase-btn");
const units = document.querySelectorAll("#unit");
const changeDue = document.getElementById("change-due");
 cash.addEventListener('input', () => {
    });
for (let i=0;i<9;i++){
  units[i].textContent += `${cidName[i]}: $${cidVal[i]}`
}
total.textContent = price
const reset = () =>{ 
  changeDue.textContent = ""
}


const getChange = () => {
  reset()
  let cidRev = cid.reverse()
  let changeMap = {}
  let cid2 = [...cid]
  let denoms = [100,20,10,5,1,0.25,0.10,0.05,0.01]
  const totalCid = cid.reduce((acc, curr) => acc + curr[1], 0);
  let denomNames = ["ONE HUNDRED","TWENTY","TEN","FIVE","ONE","QUARTER","DIME","NICKEL","PENNY"]
  let totalChange = Number(cash.value) - price

  if (price > Number(cash.value)) {
    alert("Customer does not have enough money to purchase the item")
  } else if (price === Number(cash.value)) {
    if (totalChange === totalCid) {
      changeDue.textContent = `Status: CLOSED ${cidName[0]}: $${cidVal[0].toFixed(2)}`;
    } else {
      changeDue.textContent = "No change due - customer paid with exact cash"
    }
  } else {
    if (price > totalCid){ 
      changeDue.textContent = "Status: INSUFFICIENT_FUNDS"
    } else {
      for (let i = 0; i < denoms.length; i++) {
        if (totalChange >= denoms[i]) {
          let amountGiven = 0;
          while (totalChange >= denoms[i] && cid[i][1] > 0) {
            totalChange -= denoms[i];
            totalChange = Math.round(totalChange * 100) / 100;
            cid[i][1] -= denoms[i];
            amountGiven += denoms[i];

            if (cid[i][1] < denoms[i]) break;
          }

          if (amountGiven > 0) {
            if (changeMap[denomNames[i]]) {
              changeMap[denomNames[i]] += amountGiven;
            } else {
              changeMap[denomNames[i]] = amountGiven;
            }
          }
        }
      }

      if (totalChange > 0) {
        changeDue.textContent = "Status: INSUFFICIENT_FUNDS";
        return;
      }

      let formattedChange = Object.entries(changeMap).map(([key, value]) => `${key}: $${parseFloat(value).toFixed(value % 1 === 0 ? 0 : 2)}`).join(' ');
      changeDue.textContent = `Status: OPEN ${formattedChange}`
    }
  }
}
btn.addEventListener("click",()=>getChange(cash.value))

it passes every test except for tests 18 and 19 on this project: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures-v8/build-a-cash-register-project/build-a-cash-register

I’ve been slaving away at this for hours but can’t get to understand why would it not pass, i tried searching the freecodecamp forum and even asked chatgpt for help but im stuck so I thought I’ll just create a post myself. Thanks for help in advance. (my thesis is it’s caused by the fact some of my things have more than 2 decimals but in some places when i put .toFixed(2) it just breaks the code so i’m lost)

EDIT: I probably should add that the main issue is, when cid runs out to all 0’s what happens is “No change due…” goes to work instead of “Status:CLOSED…”

can you also provide the html please?

done, a lot of it is just for css though

I see that your app returns INSUFFICIENT_FUNDS for test 18, not the No change due thing

are you sure you are nesting things correctly? if price is equal to the cash value doesn’t seem a good prerequisitive for totalChange equal to totalCid

if price is equal to cash, there is no change to be given

i guess a language barrier doesn’t allow me to understand what you’re trying to tell me, so please put it in different words
but you pointed it out and i guess i can see some kind of issue with it, but i can’t exactly figure out where :confused:

if this is true means that the client payed with the exact amount

in this case you do not need to calculate change

so it is not correct that

is under this condition, because when price is equal to cash.value there is no change

oh my god you’re so right, i’ll try to get the code to work but it’s possible i’ll come back to this thread if I fail
but thanks so much for pointing this out

ok, so I’ve done some tweaks and I feel like i’m on the right track, but i’m not sure
what seems to be an issue is that if you look at the 4 console logs in the code, totalChange is not the same as Number(cash.value)-price
and so maybe that’s the issue im running into here?

Actually I’ve ran into another idea that makes even more sense
shouldn’t I just add an if statement that checks if totalChange=totalCid before i start looping?

let price = 19.5;
let cid = [
  ['PENNY', 0.5],
  ['NICKEL', 0],
  ['DIME', 0],
  ['QUARTER', 0],
  ['ONE', 0],
  ['FIVE', 0],
  ['TEN', 0],
  ['TWENTY', 0],
  ['ONE HUNDRED', 0]
];
const total = document.querySelector(".total")
const cidName = cid.map(subArr=>subArr[0])
const cidVal = cid.map(subArr=>subArr[1])
const cash = document.querySelector("#cash");
const btn = document.getElementById("purchase-btn");
const units = document.querySelectorAll("#unit");
const changeDue = document.getElementById("change-due");
 cash.addEventListener('input', () => {
    });
for (let i=0;i<9;i++){
  units[i].textContent += `${cidName[i]}: $${cidVal[i]}`
}
total.textContent = price
const reset = () =>{ 
  changeDue.textContent = ""
}


const getChange = () => {
  reset()
  let cidRev = cid.reverse()
  let changeMap = {}
  let cid2 = [...cid]
  let denoms = [100,20,10,5,1,0.25,0.10,0.05,0.01]
  const totalCid = cid.reduce((acc, curr) => acc + curr[1], 0);
  let denomNames = ["ONE HUNDRED","TWENTY","TEN","FIVE","ONE","QUARTER","DIME","NICKEL","PENNY"]
  let totalChange = Number(cash.value) - price

  if (price > Number(cash.value)) {
    alert("Customer does not have enough money to purchase the item")
  } else if (price === Number(cash.value)) {
      changeDue.textContent = "No change due - customer paid with exact cash"
  } else {
      for (let i = 0; i < denoms.length; i++) {
        if (totalChange >= denoms[i]) {
          let amountGiven = 0;
          while (totalChange >= denoms[i] && cid[i][1] > 0) {
            totalChange -= denoms[i];
            totalChange = Math.round(totalChange * 100) / 100;
            cid[i][1] -= denoms[i];
            amountGiven += denoms[i];

            if (cid[i][1] < denoms[i]) break;
          }

          if (amountGiven > 0) {
            if (changeMap[denomNames[i]]) {
              changeMap[denomNames[i]] += amountGiven;
            } else {
              changeMap[denomNames[i]] = amountGiven;
            }
          }
        }
      }
      console.log(Number(cash.value))
      console.log(price)
      console.log(Number(cash.value)-price)
      console.log(totalChange)
      if (totalChange > 0) {
        if (totalChange = totalCid){
      changeDue.textContent = `Status: CLOSED ${cidName[0]}: $${cidVal[0].toFixed(2)}`
      } else{
        changeDue.textContent = "Status: INSUFFICIENT_FUNDS";       // <--- i added this instead to check for 18.
        return;}
      }
      

      let formattedChange = Object.entries(changeMap).map(([key, value]) => `${key}: $${parseFloat(value).toFixed(value % 1 === 0 ? 0 : 2)}`).join(' ');
      changeDue.textContent = `Status: OPEN ${formattedChange}`
    }
  }

btn.addEventListener("click",()=>getChange(cash.value))

are you sure this is a comparison?

okay yeah I’ve given this code a few more hours and apart from fixing this one mistake I also started making progress and finished it like a minute ago, having your initial tip in mind actually did push me in the right direction so thanks a lot <3