Build a Cash Register Project - HELP

I don’t know what is going on, everything seems to work fine but when I run the test it fails and when I change the value of cid, those test wich fails before now they pass, the last one never pass

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Build a Cash Register Project</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <main>
      <div class="cash-register">
        <h2 class="cash-register__title">Cash Register Project</h2>

        <div id="change-due"></div>

        <div>
          <label for="cash">Enter cash from customer:</label>
          <input type="number" name="cash" id="cash" />
          <button type="button" id="purchase-btn">Purchase</button>
        </div>

        <div>
          <p>Total: <span id="price"></span></p>
        </div>

        <div>
          <h3>Change in drawer:</h3>
          <div
            id="change-in-drawer"
            class="drawer-grid"
            style="border: 1px solid red"
          ></div>
        </div>

        <div id="total-in-cid"></div>
      </div>
    </main>

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

const changeDue = document.getElementById("change-due");
const cashInput = document.getElementById("cash");
const purchaseBtn = document.getElementById("purchase-btn");
const priceSpanOutput = document.getElementById("price");
const cidOutput = document.getElementById("change-in-drawer");

window.onload = () => {
  updateOutputs();
};

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

let cidObj = {
  status: "",
  totalCid: () =>
    cidObj.cashArr.reduce(
      (acc, item) => Number((acc + item.total).toFixed(2)),
      0
    ),
};
cidObj.cashArr = cid.map((item) => ({
  "unit-name": item[0],
  "unit-value": () => {
    switch (item[0]) {
      case "PENNY":
        return 0.01;
        break;
      case "NICKEL":
        return 0.05;
        break;
      case "DIME":
        return 0.1;
        break;
      case "QUARTER":
        return 0.25;
        break;
      case "ONE":
        return 1;
        break;
      case "FIVE":
        return 5;
        break;
      case "TEN":
        return 10;
        break;
      case "TWENTY":
        return 20;
        break;
      case "ONE HUNDRED":
        return 100;
        break;
    }
  },
  total: item[1],
  counter: 0,
}));

let changeDueArr = [];
console.log(cidObj);

//OUTPUTS
priceSpanOutput.textContent = `$${price}`;

const updateOutputs = () => {
  changeDue.innerHTML += `<p>${changeDueArr.join(" ")}</p>`;

  cidObj.cashArr.forEach((item) => {
    cidOutput.innerHTML += `
    <div>
      <p>${item["unit-name"]}'s ($${item["unit-value"]()})</p>
      <ul>
        <li>Total: $${item.total}</li>
        <li>Counter: ${item.counter}</li>
      </ul>
    </div>
    `;
  });
};

//CALCULATE
const calculateChangeDue = (change, calculateChange, totalCid) => {
  if (totalCid < change || calculateChange !== 0) {
    cidObj.status = "INSUFFICIENT_FUNDS";
    changeDueArr.push(`Status: ${cidObj.status}`);
    return;
  } else if (totalCid === change) {
    cidObj.status = "CLOSED";
    changeDueArr.push(`Status: ${cidObj.status}`);
  } else if (totalCid > change) {
    cidObj.status = "OPEN";
    changeDueArr.push(`Status: ${cidObj.status}`);
  }

  cidObj.cashArr
    .filter((item) => item.counter !== 0)
    .reverse()
    .forEach((item) =>
      changeDueArr.push(`${item["unit-name"]}: $${item.counter}`)
    );
  console.log(change);
};

const calculateCidObj = (cash) => {
  let change = Number((cash - price).toFixed(2));
  let calculateChange = change;
  let validUnitArr = cidObj.cashArr
    .filter((item) => item["unit-value"]() <= calculateChange && item.total > 0)
    .reverse();
  let totalCid = cidObj.totalCid();

  let i = 0;
  while (calculateChange > 0 && i < validUnitArr.length) {
    let index = cidObj.cashArr.indexOf(validUnitArr[i]);

    if (
      Number((calculateChange - validUnitArr[i]["unit-value"]()).toFixed(2)) >=
        0 &&
      validUnitArr[i].total > 0
    ) {
      cidObj.cashArr[index].total = Number(
        (
          cidObj.cashArr[index].total - cidObj.cashArr[index]["unit-value"]()
        ).toFixed(2)
      );
      cidObj.cashArr[index].counter = Number(
        (
          cidObj.cashArr[index].counter + cidObj.cashArr[index]["unit-value"]()
        ).toFixed(2)
      );
      calculateChange = Number(
        (calculateChange - validUnitArr[i]["unit-value"]()).toFixed(2)
      );
    } else {
      i++;
    }
  }

  calculateChangeDue(change, calculateChange, totalCid);
};

const reset = () => {
  cashInput.value = "";
  cidObj.cashArr.forEach((item) => (item.counter = 0));
  changeDue.innerHTML = "";
  cidOutput.innerHTML = "";
  changeDueArr = [];
};

purchaseBtn.addEventListener("click", () => {
  let cash = Number(cashInput.value);

  if (cash < price) {
    alert("Customer does not have enough money to purchase the item");
    return;
  } else if (cash === price) {
    changeDue.innerHTML = `<p>No change due - customer paid with exact cash</p>`;
    return;
  } else {
    reset();
    calculateCidObj(cash);
    updateOutputs();
  }
});

1 Like

hi there, welcome to the forum.
Please consider including a link to the project you’re working on to encourage people to help you.

Hiya! Welcome to our community!

Let me take a look and see if I can find what’s going on.

Aha! I see the issue.

You’re calculating the cidObj.totalCid and cidObj.cashArr only once, when the page initially loads.

This means when the tests modify the value of cid, your code still runs on the old values. When I moved that logic to run on the button click, your code passed all the tests.

1 Like

Thanks for your help, I don’t understand what you mean by you are calculating cidObj.totalCid and cidObj.cashArr only once.

There is a variable called totalCid inside calculateCidObj that calls cidObj.totalCid() then pass to calculateChangeDue() to update the status to: “INSUFFICIENT”, “OPEN” or “CLOSED”.

About cidObj.cashArr I see how it update everytime I press the button.

How is my code still runs on the old values?
The cidObject.cashArr take the values from cid, it should update it.

But it does NOT update if cid is directly changed, which is what the tests do.

Now I see the problem, VScode and the project page, refresh the page every time I save or modify the code.

The tests doesn’t load the entire code again it just change the value of cid, when cid is change I need to initialize cidObj again.

Exactly! Glad you were able to find it. :3

Hello @nhcarrigan . I am having the same problem, can you please help me.

Nevermind, I solved it! :grin: