Build a Cash Register Project - Build a Cash Register

Tell us what’s happening:

Hello Everyone! I’m having trouble here. My app passes all of the tests successfully when running them manually, as far as I can tell. I already had to make a bunch of changes to appease the test conditions, but the last 7 conditions continue to fail.

Not sure what to fix, or do I need to scrap it all and start with hitting conditions true manually so I can build the app backwards exactly how the course expects it?

Your code so far

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Cash Register</title>
    <link rel="stylesheet" href="styles.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <main>
      <header>
        <h1>Cash Register Project</h1>
      </header>
      <section id="change-container">
        <div id="change-due">
          <!--Text will be inserted here by script.js-->
        </div>
      </section>
      <form>
        <label for="cash">Enter cash from customer</label>
        <input id="cash" type="number" inputmode="decimal" min="0" max="400" step="0.01">
        <button type="submit" id="purchase-btn">Purchase</button>
      </form>
      <section id="reg-container">
        <div id="reg-price-sign-box">
          <span id="total-container">Total: <span id="total"></span></span>
        </div>
        <div id="reg-post"></div>
        <div id="reg-main-body">
          <div id="reg-btns-container">
            <div class="reg-btns"></div>
            <div class="reg-btns"></div>
            <div class="reg-btns"></div>
            <div class="reg-btns"></div>
            <div class="reg-btns"></div>
            <div class="reg-btns"></div>
            <div class="reg-btns"></div>
            <div class="reg-btns"></div>
            <div class="reg-btns"></div>
          </div>
          <div id="reg-change-container"></div>
        </div>
        <div id="reg-drawer">
          <div id="reg-key-hole"</div>
        </div>
      </section>
    </main>


    <script src="script.js"></script>
  </body>
</html>

const changeDue = document.getElementById("change-due");
const cash = document.getElementById("cash");
const purchaseBtn = document.getElementById("purchase-btn");
const totalDisplay = document.getElementById("total");
const regChangeContainer = document.getElementById("reg-change-container")

let price = 19.5;
let cid = [
  ['PENNY', 1.01, .01, 0],
  ['NICKEL', 2.05, .05, 0],
  ['DIME', 3.1, .1, 0],
  ['QUARTER', 4.25, .25, 0],
  ['ONE', 90, 1, 0],
  ['FIVE', 55, 5, 0],
  ['TEN', 20, 10, 0],
  ['TWENTY', 60, 20, 0],
  ['ONE HUNDRED', 100, 100, 0]
];

// let cid = [
//   ['PENNY', .01, .01, 0],
//   ['NICKEL', 0, .05, 0],
//   ['DIME', 0, .1, 0],
//   ['QUARTER', 0, .25, 0],
//   ['ONE', 1, 1, 0],
//   ['FIVE', 0, 5, 0],
//   ['TEN', 0, 10, 0],
//   ['TWENTY', 0, 20, 0],
//   ['ONE HUNDRED', 0, 100, 0]
// ];

//duplicating cid as i want to adjust values and it interfers with project tests. 
let workingCid = [
  [cid[0][0], cid[0][1], .01, 0],
  [cid[1][0], cid[1][1], .05, 0],
  [cid[2][0], cid[2][1], .1, 0],
  [cid[3][0], cid[3][1], .25, 0],
  [cid[4][0], cid[4][1], 1, 0],
  [cid[5][0], cid[5][1], 5, 0],
  [cid[6][0], cid[6][1], 10, 0],
  [cid[7][0], cid[7][1], 20, 0],
  [cid[8][0], cid[8][1], 100, 0]
];

const updatePrice = (currentPrice) => {
  total.innerText = `$${currentPrice}`;
}

const purchase = () => {
  //clear change due
  changeDue.innerHTML = "";
  const cashPaid = parseFloat(cash.value);

  if (!cashPaid){
    alert("Please enter cash from customer");
    return;
  } else if(cashPaid < price){
    changeDue.innerHTML += `<p>Customer does not have enough money to purchase the item</p>`;
    alert("Customer does not have enough money to purchase the item")
    return;
  }  
  //add all cash values in cid for drawer total
  let drawerTotal = 0;
  let change = cashPaid - price;
  change = Math.round(change * 100) / 100;
    workingCid.forEach((cash) => {
    drawerTotal += cash[1]
  })
  drawerTotal = Math.round(drawerTotal * 100) / 100;

  if(drawerTotal < cash){
    changeDue.innerText += `Status: INSUFFICIENT_FUNDS`;
  }

  //action per change values
  if(change === 0){
    changeDue.innerHTML += `<p>No change due - customer paid with exact cash</p>`;
    return
  } else if (change > drawerTotal){
    changeDue.innerText += `Status: INSUFFICIENT_FUNDS`;
    return
  }

  //reset bill tracker in multi dimensional arr
  workingCid.forEach((bill) => {
    bill[3] = 0;
  });

  //calculating number of each bill needed, and if it's available
  let cidReverse = workingCid.slice().reverse()
  cidReverse.forEach((bill) => {
    while(change >= bill[2] && bill[1] >= bill[2]){
      change -= bill[2];
      bill[1] -= bill[2];
      bill[3] += 1;
      change = Math.round(change * 100) / 100;
      bill[1] = Math.round(bill[1] * 100) / 100;
    };
    updateDrawer()
  });

  //update Drawer Total
  drawerTotal = 0;
  workingCid.forEach((cash) => {
    drawerTotal += cash[1]
  })
  drawerTotal = Math.round(drawerTotal * 100) / 100;

  //verify all bills were available
  if(change !== 0){
    changeDue.innerText += `Status: INSUFFICIENT_FUNDS`;
    //If all bills are not available, put them all back (re add the number of bills taken * bill value to the amount of bill in drawer)
    cidReverse.forEach((bill) => {
      bill[1] += bill[2] * bill[3]
    })
    updateDrawer()
    return
  };
  
  console.log(drawerTotal)
  if(drawerTotal === 0){
    changeDue.innerText += "Status: Closed"
  } else {
    changeDue.innerText += "Status: OPEN"
  }
    
  //build changeDue HTML
  cidReverse.forEach((bill) => {
    if(bill[3] !== 0){
      let total = bill[3] * bill[2];
      total = Math.round(total * 100) / 100;
      changeDue.innerText += `\n${bill[0]}: $${total}`
    };

    
  // changeDue.innerHTML += `<p>Status: OPEN</p>`
  // //build changeDue HTML
  // cidReverse.forEach((bill) => {
  //   if(bill[3] !== 0){
  //     let total = bill[3] * bill[2];
  //     total = Math.round(total * 100) / 100;
  //     changeDue.innerHTML += `<p>${bill[0]}: $${total}</p>`
  //   };
  
  });
};

const updateDrawer = () => { 

  workingCid.forEach((bill) => {
    bill[1] = (bill[1] * 100) / 100;
  })

  regChangeContainer.innerHTML = ''
  regChangeContainer.innerHTML += `
  <p><strong>Change in drawer:</strong></p>
  <p>Pennies: $${workingCid[0][1]}</p>
  <p>Nickels: $${workingCid[1][1]}</p>
  <p>Dimes: $${workingCid[2][1]}</p>
  <p>Quarters: $${workingCid[3][1]}</p>
  <p>Ones: $${workingCid[4][1]}</p>
  <p>Fives: $${workingCid[5][1]}</p>
  <p>Tens: $${workingCid[6][1]}</p>
  <p>Twenties: $${workingCid[7][1]}</p>
  <p>Hundreds: $${workingCid[8][1]}</p>
  `
}

window.onload = () => {
  window.resizeTo(700,750)
}

updatePrice(price) //allows price change on backed
updateDrawer() //updates starting change to drawer container
purchaseBtn.addEventListener("click", purchase)







* {
  box-sizing: border-box;
  /* border: 1px solid black; */
}

:root {
  --background-color: #373e4a;
  --register-color: #4eb598;
  --text-color: white;
  --register-accent-color: black;
}

body {
  background-color: var(--background-color);
  color: white;
}
body, main, form{
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

h1{
  font-size: 3em;
  margin-bottom: 20px;
  min-width: 450px;
}

#change-due{
  font-size: 1.2em;
}

#change-due p{
  margin: 0
}

form label{
  font-size: 1.3em;
  margin-top: 10px;
}

#cash, #purchase-btn{
  font-size: 1.2em;
}

#cash {
  margin-top: 10px;
  margin-bottom: 15px;
  width: 215px;
}

#purchase-btn{
  margin-bottom: 20px;
  background-image: linear-gradient(#18c4c9, #287dde);
  color: var(--text-color);
  border: 2px solid #18c4c9;
}

#purchase-btn:active{
  background-image: linear-gradient(#287dde, #18c4c9);
}

#reg-container{
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 450px;
  height: 450px;
}

#reg-price-sign-box{
  width: 45%;
  height: 50px;
  background-color: var(--register-color);
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-right: 70px;
  border-radius: 3px;

}

#total-container{
  font-size: 1.2em;
  margin: auto;
  background-color: var(--register-accent-color);
  padding: 4px 40px;
  width: 180px;
  border-radius: 3px;
}

#reg-post{
  height: 30px;
  width: 40px;
  margin-right: 170px;
  background-color: var(--register-color)
}

#reg-main-body{
  height: 275px;
  width: 75%;
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
  background-color: var(--register-color);
  padding-top: 15px;
  display: flex;
}

#reg-btns-container {
  width: 75px;
  height: 75px;
  background-color: var(--register-color);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  margin-left: 20px;
}

.reg-btns {
  height: 18px;
  width: 18px;
  background-color: var(--register-accent-color);
  margin: auto;
  border-radius: 3px
}

#reg-change-container {
  width: 200px;
  height: 95%;
  margin-left: 28px;
  background-color: white;
  color: black;
  text-align: left;
  padding-left: 5px;
  font-size: 1.1em;
}

#reg-change-container p{
  margin: 3px 0;
}

#reg-change-container p:first-of-type{
  margin: 5px 0;
}

#reg-drawer{
  width: 75%;
  height: 50px;
  margin-top: 8px;
  background-color: var(--register-color)
}

#reg-key-hole{
  width: 15px;
  height: 15px;
  background-color: var(--register-accent-color);
  border-radius: 17px;
  margin: 15px auto auto auto;
}

Your browser information:

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

Challenge Information:

Build a Cash Register Project - Build a Cash Register

Oof woops found 1 issue, I had a 1 added to the end to an Insufficient_Funds message for tracking and forgot to remove it. :sweat_smile:. However I’m still failing tests 11, 12, 13, 18, 19.

We can’t see your code, unfortunately. Please add it

Ah embarrassing sorry! First time posting. I’ve updated the post with my code so far.

This will break the tests for you (and wreck the re-usability of your functions)

Oh bummer. In what way does that break the tests and reusability?

What happens if you try to re-run the function again with a new price and cid without changing your workingCid?

Generally, global state variables like that are really hard to reason about. When possible, your functions should only use their inputs.

Oh it ran fine using the commented out cid as written in my post, and with any price I put there.

I must be missing something. I’m going to re-write without relying on manipulating the cid variable at all.

I had built in functionality to reduce the value of the cid[n][1] values so I could keep running transactions accurately - but I guess with the scope of this project having not included the types of bills the customer is using, it wasn’t really fully fleshed out anyways.

Thank you for the advice! I’ll re-work it this evening

Your code contains global variables that are changed each time the function is run. This means that after each function call completes, subsequent function calls start with the previous value. To fix this, make sure your function doesn’t change any global variables, and declare/assign variables within the function if they need to be changed.

Example:

var myGlobal = [1];
function returnGlobal(arg) {
  myGlobal.push(arg);
  return myGlobal;
} // unreliable - array gets longer each time the function is run

function returnLocal(arg) {
  var myLocal = [1];
  myLocal.push(arg);
  return myLocal;
} // reliable - always returns an array of length 2

You can try to simulate the tests in this way:

add at the bottom of your code

cid = [] // add here new value of cid
price = 0 // add here new value of price
cash.value = 0 // add here new value in the input
purchaseBtn.click(); // this clicks the button
console.log(changeDue.innerText); // this shows the value inside `changeDue` in the console

you can add it multiple times to see how your app behave with being used multiple times in a row