Build a Cash Register

Hi! I think i got the logic down for the most part in this project. However, I am struggling with formatting the text I display. I have two main issues right now:

  1. Trailing zeroes after an integer. The test says it expects the number 60 and my solution displays 60.00
  2. Newline. I’m not sure if the test cases allow me to add newlines or if they only want us to add a space between different denominations.

Please let me know if and how to resolve these issues. I would also appreciate it if someone helped me figure out any other bugs in my code that I hadn’t considered.

Thank you!

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></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 = 3.26;

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 defaultScreen() {
  totalDisplay.innerText = "Total: " + price;
  displayDrawer();
  inputCash.innerText= "";
  statusP.innerText = "";
  changeDueText.innerText = "";
  changeDueDiv.classList.add("hidden");
  cashToReturn = [
  ['PENNY', 0],
  ['NICKEL', 0],
  ['DIME', 0],
  ['QUARTER', 0],
  ['ONE', 0],
  ['FIVE', 0],
  ['TEN', 0],
  ['TWENTY', 0],
  ['ONE HUNDRED', 0]
];
}

function displayDrawer() {
  cidList.innerText = "";
  cid.forEach((ele) => cidList.innerText += ele[0] + ": $" + ele[1] + "\n");
}

function inputCashEvaluate() {
  const inputCashCents = Math.floor(inputCash.value * 100);
  const priceCents = Math.floor(price * 100);

  inputCash.value = "";

  defaultScreen();

  if (inputCashCents < priceCents) {
    alert("Customer does not have enough money to purchase the item");
  } else if (inputCashCents === priceCents) {
    changeDueDiv.classList.remove("hidden");
    changeDueText.textContent = "No change due - customer paid with exact cash";
  } else {
    changeDueDiv.classList.remove("hidden");
    initialStatusCheck(inputCashCents, priceCents);
  }
}

function initialStatusCheck(inputCashCents, priceCents) {
  const sumCIDCents = Math.floor((cid.reduce((acc, ele) => acc + ele[1], 0)) * 100);

  const returnAmt = Math.abs(priceCents - inputCashCents);
  if (sumCIDCents < returnAmt) {
    statusP.textContent = "Status: INSUFFICIENT_FUNDS";
  } else if (sumCIDCents === returnAmt) {
    statusP.textContent = "Status: CLOSED";
    displayChange(cid);
    cid = cashToReturn;
    displayDrawer();
  } else {
    evaluateFurther(returnAmt);
  }
}

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

    }
  }
}

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

}

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

purchaseBtn.addEventListener("click", inputCashEvaluate);

window.onload = defaultScreen;

Hi there,

Your numbers has 2 trailing zeroes because you formatted it so with the toFixed(2) methods.

Delete that method will solve this problem.

About newline, I don’t think it’s a problem. But you can always check it yourself by running the test.


There is also one problem with the output message.

Take a look at, for example, test number 11:

the value in the #change-due element should be "Status: OPEN QUARTER: $0.5".

According to your code, you’re currently putting:

  • "Status: OPEN" inside #change-status
  • "QUARTER: $0.5" inside #change-due

while they both should be inside #change-due.

#change-status is unnecessary. You can delete it.

There are maybe more issues, but that’s all I can think of for now.
Happy coding!

1 Like

Delete that method will solve this problem.

Worked. I also had a small typo that I had to fix.

change-status is unnecessary. You can delete it.

Changed this too. I just wanted it for a little more clarity and better formatting.

About newline, I don’t think it’s a problem. But you can always check it yourself by running the test.

It was. I had to change it to just a space, otherwise it didn’t work.

Thank you for your help!

1 Like