Build a Cash Register Project - Build a Cash Register

Tell us what’s happening:

I’m passing all but test cases 18 & 19 requiring "“Status: CLOSED PENNY: $0.5” as the output. I am getting that exact output when running my code but the test cases are failing.
Thanks in advance for any help!

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
    <title>Cash Register</title>
</head>
<body>
    <h1>Cash Register</h1>

    <label for="cash">Cash</label>
    <input type="number" id="cash">

    <div id="change-due"></div>
    
    <button id="purchase-btn">Purchase</button>

<script src="script.js"></script>
</body>
</html>
/* file: script.js */
const cash = document.getElementById('cash');
const changeTotalElement = document.getElementById("change-total");
const purchaseBtn = document.getElementById('purchase-btn');
const changeDueElement = document.getElementById('change-due');

let price = '19.5';

const statUs = {
  open: "OPEN",
  closed: "CLOSED",
  insuff: "INSUFFICIENT_FUNDS"
};

let registerStatus = '';

let changeDue = [];

const messages = {
  insufficientMessage: "Customer does not have enough money to purchase the item",
  exactCash: "No change due - customer paid with exact cash"
};

let registerMessage = ``;

// 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 cid = [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]];

//Denomination names to simplify calling/assignment
const denominationNames = ["ONE HUNDRED","TWENTY","TEN","FIVE","ONE","QUARTER","DIME","NICKLE","PENNY"];

//Denominations to cents to avoid floating-point precision issues
const denominations = [10000, 2000, 1000, 500, 100, 25, 10, 5, 1];

// updating register status
const updateStatus = (registerStatus) => {
  if (registerStatus === "insuff") {
    return statUs.insuff;
  } else if (registerStatus === "closed") {
    return statUs.closed;
  } else {
    return statUs.open;
  }
}

// using registerStatus() to update UI after button clicked/transaction complete
const updateUI = (registerStatus) => {
  if(registerStatus) {
    changeDueElement.textContent = `Status: ${updateStatus(registerStatus)}`;
    if(!exactChangeNotAvailable) {
      changeDue.map(([denominationName, amount]) => {
      changeDueElement.textContent += ` ${denominationName}: $${amount}`;
      });
    }
  } else {
    changeDueElement.textContent = "No change due - customer paid with exact cash";
  }
}

let exactChangeNotAvailable = false;

const register = (price, cash) => {

  // reversing cid to place larger values first
  let cidReversed = cid.reverse();
  // changed dollars to cents to avoid floating-point precision issues
  for(const element of cidReversed) {
    element[1] = Math.round(element[1] * 100);
  }

  const cidTotal = () => {
    return cidReversed.reduce((a, b) => a + Number(b[1]), 0);
  }
  
  if(!price) {
    alert("Enter amount due");
    return;
  }

  if(!cash) {
    alert("Enter cash from customer");
    return;
  }

  let change = (cash * 100) - (price * 100);
  
  if (price === cash) {
    registerMessage = messages.exactCash;
    return;
  }

  if (cidTotal() < change) {
        registerStatus = 'insuff';
        return;
      } else {
        // making change
          while(change > 0 && !exactChangeNotAvailable) {
            let denominationUsed = false;
            for (let i = 0; i < denominations.length; i++) {
              
              if(cidReversed[i][1] <= 0) {
                continue;
              }
              if(denominations[i] <= change) {
                change -= denominations[i];
                cidReversed[i][1] -= denominations[i];
                
                if (changeDue.some(subArray => subArray.includes(denominationNames[i]))) {
                  for(const denomination of changeDue) {
                      if(denomination[0] === denominationNames[i]) {
                        denomination[1] += denominations[i];
                      }
                  }
                } else {
                changeDue.push([denominationNames[i], denominations[i]]);
                }
                denominationUsed = true;
                break;
              }
            }
            if(!denominationUsed){
              exactChangeNotAvailable = true;
            }
          }
    registerStatus = 'open';
  }
  
  // changing denominations of changeDue to dollars
  for(const element of changeDue) {
    element[1] = element[1] / 100;
  }
  // changing denominations of cidReversed back to dollars
  for(const element of cidReversed) {
    element[1] = element[1] / 100;
  }

  if(exactChangeNotAvailable) {
    registerStatus = 'insuff';
  }

  if (cidReversed.reduce((a, b) => a + b[1], 0) === 0) {
    registerStatus = 'closed';
  }
  
  console.log("changeDue: ", changeDue);
  console.log("cidReversed: ", cidReversed);
  return ;
};

purchaseBtn.addEventListener('click', () => {
  if (price > Number(cash.value)) {
    alert("Customer does not have enough money to purchase the item");
    return;
  } else {
    register(price, Number(cash.value));
    updateUI(registerStatus);
    console.log(changeDueElement.innerText);
  }
  changeDue = [];
});
/* file: styles.css */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

body {
  background-color: black;
  color: lightgray;
}

Your browser information:

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

Challenge Information:

Build a Cash Register Project - Build a Cash Register

Update: upon further troubleshooting I’ve updated my code and have discovered that testing each case myself manually is different than how the test cases run - one after the other - without executing all the code. I now see that after test case 10 runs my “for of” loop that converts the cid to cents stops executing within the register function. I’m now trying to figure out why test case 10 (No change due - customer paid with exact cash) output would cause this.

do not use global variables, the only global variables you should have are cid and price, everything else needs to go inside a function

Thank you! One of my variables set outside of the main function was not being reset during the consecutive run of test cases. Now all test cases passed :tada: