Build a Cash Register

The code works but it doesn’t with case #7 and #10

I tested with the values it provides but for some reason doesn’t pass it. I attached the images that shows the input.

These are the only cases, the others work perfectly well.

My code

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Cash Register</title>
  <link rel="stylesheet" href="./styles.css" />
</head>

<body>
  <div class="input-div">
    <label for="cash">Please enter cash from customer:</label>
  <input type="number" id="cash" value />
  <button class="check-btn-styles" id="purchase-btn">Purchase</button>
  </div>
  <div id="change-due">
  </div>
  <script src="./script.js"></script>
</body>

</html>
/* file: script.js */
let price = 19.5;
let cid = [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]];
let moneyProvided = [
  ["ONE HUNDRED", 0],
  ["TWENTY", 0],
  ["TEN", 0],
  ["FIVE", 0],
  ["ONE", 0],
  ["QUARTER", 0],
  ["DIME", 0],
  ["NICKEL", 0],
  ["PENNY", 0],
];
const denom = [100, 20, 10, 5, 1, 0.25, 0.1, 0.05, 0.01];
const inputDiv = document.getElementById("input-div");
const cash = document.getElementById("cash");
const purchaseBtn = document.getElementById("purchase-btn");
const changeDiv = document.getElementById('change-due');
let total = [];
let totalSum = 0;
let change = 0;
let status = "";

class CashRegister {

  getTotals() {
    total = [...cid].reverse().map(el => [el[0], this.formatQuantities(el[1])]);
    totalSum = this.formatQuantities(total.reduce((acc, curr) => acc + curr[1], 0));
  };

  transaction(cash) {
    change = this.formatQuantities(this.formatQuantities(cash) - price);
    this.getTotals();

    // cash < price - No money
    if (this.formatQuantities(cash) < price || cash.length === 0) {
      alert("Customer does not have enough money to purchase the item");
      return;
    }
    // cid < change - insufficiente funds
    if (this.formatQuantities(cash) === price) {
      changeDiv.textContent = "No change due - customer paid with exact cash";
      status = "Status: CLOSED";
      // cid > change
    }
    else if (totalSum < change) {
      status = "Status: INSUFFICIENT_FUNDS";
      changeDiv.innerHTML = `<p>${status} </p>`;
      // cid == change - closed
    } else {
      if (change === totalSum) {
        status = "Status: CLOSED";
      } else {
        status = "Status: OPEN";
      }
      this.calculateChange();
    }

  };

  calculateChange() {
    const tempChange = change;

    for (let i = 0; i < total.length; i++) {
      while (denom[i] <= this.formatQuantities(change) && total[i][1] > 0) {
        moneyProvided[i][1] += denom[i];
        change -= denom[i];
        total[i][1] -= denom[i];
      }
    }

    change = moneyProvided.filter(el => el[1] !== 0);
    const totalChange = this.formatQuantities(change.reduce((acc, curr) => acc + curr[1], 0))
    changeDiv.innerHTML = `<p>${status} </p>`;

    if (tempChange !== totalChange) {
      status = "Status: INSUFFICIENT_FUNDS";
      changeDiv.innerHTML = `<p>${status} </p>`;
      return;
    }

    for (let i = 0; i < change.length; i++) {
      changeDiv.innerHTML += `<p>${change[i][0]}:  $${this.formatQuantities(change[i][1])}</p>`;
    }
    return;
  };

  formatQuantities(number) {
    return Number(Math.round(number + 'e2') + 'e-2');
  };
}

const cashRegister = new CashRegister();
purchaseBtn.addEventListener('click', () => {
  changeDiv.textContent = "";
  cash.textContent = "";
  cashRegister.transaction(cash.value);
});

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 OPR/107.0.0.0 (Edition std-1)

Challenge Information:

  1. When price is 3.26, the value in the #cash element is 100, cid is [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]], and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: OPEN TWENTY: $60 TEN: $20 FIVE: $15 ONE: $1 QUARTER: $0.5 DIME: $0.2 PENNY: $0.04"

  2. When price is 19.5 , the value in the #cash element is 20 , cid is [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]] , and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: CLOSED PENNY: $0.5" .

You shouldn’t use these global variables

Hey Jeremy, thanks for reply and sorry for the late response.

So I took your advice and declared the 4 varibles in their respective functions, but I still have the same problem.

Only those two cases, maybe is something on how freeCodeCamp checks the outputs? Because i display the answers they’re looking up

class CashRegister {

  getTotals() {
    let total = [];

    total = [...cid].reverse().map(el => [el[0], this.formatQuantities(el[1])]);
    let totalSum = this.formatQuantities(total.reduce((acc, curr) => acc + curr[1], 0));

    return {
      total: total,
      totalSum: totalSum
    };
  };

  transaction(cash) {
    let change = this.formatQuantities(this.formatQuantities(cash) - price);
    let status = "";
    let totals = this.getTotals();
    console.log(totals);
    // cash < price - No money
    if (this.formatQuantities(cash) < price || cash.length === 0) {
      alert("Customer does not have enough money to purchase the item");
      return;
    }
    // cid < change - insufficiente funds
    if (this.formatQuantities(cash) === price) {
      changeDiv.textContent = "No change due - customer paid with exact cash";
      /*
      status = "Status: CLOSED";
      changeDiv.innerHTML = `<p>${status} </p>`;
      */
      // cid > change
    }
    else if (totals.totalSum < change) {
      status = "Status: INSUFFICIENT_FUNDS";
      changeDiv.innerHTML = `<p>${status} </p>`;
      // cid == change - closed
    } else {
      if (change === totals.totalSum) {
        status = "Status: CLOSED";
      } else {
        status = "Status: OPEN";
      }
      this.calculateChange(change, totals, status);
    }

  };

  calculateChange(change, totals, status) {
    const tempChange = change;

    for (let i = 0; i < totals.total.length; i++) {
      while (denom[i] <= this.formatQuantities(change) && totals.total[i][1] > 0) {
        moneyProvided[i][1] += denom[i];
        change -= denom[i];
        totals.total[i][1] -= denom[i];
      }
    }

    change = moneyProvided.filter(el => el[1] !== 0);
    const totalChange = this.formatQuantities(change.reduce((acc, curr) => acc + curr[1], 0))

    if (tempChange !== totalChange) {
      status = "Status: INSUFFICIENT_FUNDS";
      changeDiv.innerHTML = `<p>${status} </p>`;
      return;
    }

    changeDiv.innerHTML = `<p>${status} </p>`;

    for (let i = 0; i < change.length; i++) {
      changeDiv.innerHTML += `<p>${change[i][0]}:  $${this.formatQuantities(change[i][1])}</p>`;
    }
    return;
  };

  formatQuantities(number) {
    return Number(Math.round(number + 'e2') + 'e-2');
  };
}

You’re also reusing this global moneyProvided variable. I’d really not have anything like this in the global space.

1 Like

What? it really worked!!

Thank you so much Jeremy!

1 Like