Build a Cash Register Project - Build a Cash Register

Tell us what’s happening:

I’ve been stuck in this project for several days. The code seems to work for me, and when I try using the values for price, cid (cash-in-drawer) and the input that they’re testing with, it seemingly works, but the tests just don’t pass.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./styles.css">
  </head>
  <body>
    <main>
      <h1>Cash Register Project</h1>
      <div id="change-due">
        <p id="change-status"></p>
        <ul id="change-list"></ul>
      </div>
      <div id="input-area">
        <form>
          <label for="cash">Enter cash from customer:</label>
          <input id="cash" type="number" required />
          <button id="purchase-btn" type="button">Purchase</button>
        </form>
      </div>
      <div id="output-area">
        <p class="total"></p>
        <p>Change in drawer:</p>
        <ul id="cid-output"></ul>
      </div>
    </main>
    <script src="./script.js"></script>
  </body>
</html>
/* file: script.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]
];
//deno holds the value of all denominations
const deno = [
  ['PENNY', 0.01],
  ['NICKEL', 0.05],
  ['DIME', 0.1],
  ['QUARTER', 0.25],
  ['ONE', 1],
  ['FIVE', 5],
  ['TEN', 10],
  ['TWENTY', 20],
  ['ONE HUNDRED', 100]
  ];

const purchaseBtn = document.getElementById("purchase-btn");
const cashInput = document.getElementById("cash");
const cidOutput = document.getElementById("cid-output");
const changeList = document.getElementById("change-list");
const changeStatus = document.getElementById("change-status");

document.querySelector(".total").textContent = `Total: ${price}`;

const cashExpand = (num) => {
    let wholeCash = num;
    const calcArr = [];
    for (let i = deno.length - 1; i >= 4; i--) {
        const calc = parseInt(wholeCash / deno[i][1]) * deno[i][1];
        calcArr.unshift([deno[i][0], calc]);
        wholeCash = Number((wholeCash % deno[i][1]).toFixed(2));
    } 
    for (let i = 3; i >= 0; i--) {
        const timesHun = wholeCash * 100;
        const denoTimesHun = deno[i][1] * 100;
        const calc = parseInt(timesHun / denoTimesHun) * denoTimesHun;
        const calcFinal = Number((calc / 100).toFixed(2));
        const modCalc = Number((timesHun % denoTimesHun).toFixed(2));
        calcArr.unshift([deno[i][0], calcFinal]);
        wholeCash = Number((modCalc / 100).toFixed(2));
    }
    return calcArr;
}

const changeOutput = (num) => {
    let changeExpanded = cashExpand(num);
    for (let i = changeExpanded.length - 1; i >= 0; i--) {
        if (changeExpanded[i][1] > cid[i][1]) {
            changeExpanded[i-1][1] += Number(changeExpanded[i][1].toFixed(2)) - Number(cid[i][1].toFixed(2));
            changeExpanded[i][1] = cid[i][1];
        }
    }
    const finalArr = changeExpanded.toReversed();
    return finalArr;
}

const remainingCid = (num) => {
    let changeExpanded = cashExpand(num);
    const priceExpanded = cashExpand(price);
    let cidRemains = [];
    for (let i = cid.length - 1; i >= 0; i--) {
        const updated = Number((cid[i][1]).toFixed(2)) - Number((changeExpanded[i][1]).toFixed(2)) + Number((priceExpanded[i][1]).toFixed(2));
        if (updated >= 0) {
            cidRemains.unshift([cid[i][0], updated]);
        } else if (updated < 0) {
            cidRemains.unshift([cid[i][0], 0]);
            changeExpanded[i-1][1] -= updated;
        }
    }
    return cidRemains;
} 

const btnFn = () => {
    changeList.innerHTML = "";
    changeStatus.textContent = "";
    cidOutput.innerHTML = "";
    let givenCash = Number(cashInput.value);
    let change = Number(givenCash.toFixed(2)) - Number(price.toFixed(2));
    const totalCidVals = [];
    cid.forEach(x => totalCidVals.push(x[1]));
    let totalCid = Number(totalCidVals.reduce((acc, cur) => acc + cur).toFixed(2));

    if (givenCash < price) {
        alert("Customer does not have enough money to purchase the item");
        return;
    } else if (givenCash === price) {
        changeStatus.textContent += "No change due - customer paid with exact cash";
        return;
    }

    if (totalCid < change) {
       changeStatus.textContent += "Status: INSUFFICIENT_FUNDS";
       return;
   } else if (totalCid === change) {
       changeStatus.textContent += "Status: CLOSED";        
   } else if (totalCid > change) {
       changeStatus.textContent += "Status: OPEN";
   }

   const changeDetails = changeOutput(change);
   const cidRemains = remainingCid(givenCash);
   const cidReversed = cid.toReversed();

   changeDetails.forEach((el, i) => {
      if (el[1] !== 0) {
      changeList.innerHTML += `<li>${cidReversed[i][0]} : $${Number(el[1].toFixed(2))}</li>`; }
  })
   cidRemains.forEach((el, i) => {
      cidOutput.innerHTML += `<li>${cid[i][0]} : $${Number(el[1].toFixed(2))}</li>`;
  })
   cid.forEach((el, i) => {
      el[1] = cidRemains[i][1];
  })

  givenCash = 0;
  change = 0;
}

purchaseBtn.addEventListener("click", (e) => {
  e.preventDefault();
  btnFn();
});
cashInput.addEventListener("keydown", (e) => {
    if (e.key === "Enter") {
        btnFn();
    }
})


/* file: styles.css */

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

Challenge Information:

Build a Cash Register Project - Build a Cash Register

you have a couple of issues.
1- the format of the statement with the change due has an extra space to the left of the colon character. So remove that.
2- when I test your code for testcases 15 and 16, your code throws an error to the console:
Uncaught TypeError: Cannot read properties of undefined (reading '1')

To recreate the error, just set price and cid like below:

let price = 19.5;
let cid = [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]];

then type in 30 first as the cash after that type in 20 (both of these should give insufficient funds, but only the first one does).

Edit: also I noticed your cash input does not accept the value of $20.56 as cash and it should accept that as a valid value.

1 Like

okay, doing the fix from your 1st point automatically caused most of the tests to pass, and I also noticed that entering decimal numbers causes an alert, so I’ll have to find a fix to stop that in HTML I think?

Decimals are allowed so you should not stop that.