Build a Cash Register Project

Good morning, please, could you help me, I’ve been trying to understand my mistake for days and I didn’t find the solution on the forum, mainly because it’s a private project, I searched on the internet and when I correct one error, I find another, and in the end, I stay with these 2 errors
I appreciate the super help

ERROR:

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”.

When price is less than the value in the #cash element, total cash in drawer cid is equal to change due, and the #purchase-btn element is clicked, the value in the #change-due element should be “Status: CLOSED” with change due in coins and bills sorted in highest to lowest order.

const cashInput = document.getElementById("cash");
const changeText = document.getElementById("change-due");
const button = document.getElementById("purchase-btn");

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]
];

const conversion = {
  "PENNY": 0.01,
  "NICKEL": 0.05,
  "DIME": 0.1,
  "QUARTER": 0.25,
  "ONE": 1,
  "FIVE": 5,
  "TEN": 10,
  "TWENTY": 20,
  "ONE HUNDRED": 100,
};

const totalCash = Number(cid.reduce((acc, cur) => acc + cur[1], 0).toFixed(2));

const moneyChecker = (changeDue, statusCheck) => {
  let results = {
    status: statusCheck,
    change: []
  };

  for (let i = cid.length - 1; i >= 0; i--) {
    if (changeDue >= conversion[cid[i][0]] && changeDue > 0) {
      const timesInto = Math.floor(changeDue / conversion[cid[i][0]]);
      const amount = timesInto * conversion[cid[i][0]];

      if (amount > cid[i][1]) {
        changeDue -= cid[i][1];
        results.change.push([cid[i][0], cid[i][1]]);
      } else {
        changeDue -= amount;
        results.change.push([cid[i][0], amount]);
      }
      changeDue = changeDue.toFixed(2);
    }
  }

  if (changeDue > 0) {
    changeText.textContent = "Status: INSUFFICIENT_FUNDS";
    return;
  }


  results.change.sort((a, b) => conversion[b[0]] - conversion[a[0]]);

  let changeOutput = results.change.map(item => `${item[0]}: $${item[1].toFixed(2)}`);

  changeText.textContent = `Status: ${results.status} ${changeOutput.join(" ")}`;
};

button.addEventListener("click", () => {
  const cash = Number(cashInput.value);
  let changeDue = (cash - price).toFixed(2);

  if (totalCash < changeDue) {
    changeText.textContent = "Status: INSUFFICIENT_FUNDS";
  } else if (cash < price) {
    alert("Customer does not have enough money to purchase the item");
  } else if (cash === price) {
    changeText.textContent = "No change due - customer paid with exact cash";
  } else if (totalCash === changeDue) {
    moneyChecker(changeDue, "CLOSED");
  } else {
    moneyChecker(changeDue, "OPEN");
  }
});

first thing you should do is get rid of all the logic in the global scope.
Example:

This logic will only run once when the page is loaded but you want to run it everytime the tests change the cid (they do not reload the page they probably just issue a new purchase button click event)

when removing the code on demand, it had several errors

I had already corrected it

where did you put the logic? (i didn’t mean to delete it, I just meant to move it out of the global scope into a function that runs when purchase is clicked).

Please post your newest code.

const cashInput = document.getElementById("cash");
const changeText = document.getElementById("change-due");
const button = document.getElementById("purchase-btn");

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]
];

const conversion = {
  "PENNY": 0.01,
  "NICKEL": 0.05,
  "DIME": 0.1,
  "QUARTER": 0.25,
  "ONE": 1,
  "FIVE": 5,
  "TEN": 10,
  "TWENTY": 20,
  "ONE HUNDRED": 100,
};

const moneyChecker = (changeDue, statusCheck) => {
  let results = {
    status: statusCheck,
    change: []
  };

  for (let i = cid.length - 1; i >= 0; i--) {
    if (changeDue >= conversion[cid[i][0]] && changeDue > 0) {
      const timesInto = Math.floor(changeDue / conversion[cid[i][0]]);
      const amount = timesInto * conversion[cid[i][0]];

      if (amount > cid[i][1]) {
        changeDue -= cid[i][1];
        results.change.push([cid[i][0], cid[i][1]]);
      } else {
        changeDue -= amount;
        results.change.push([cid[i][0], amount]);
      }
      changeDue = changeDue.toFixed(2);
    }
  }

  if (changeDue > 0) {
    changeText.textContent = "Status: INSUFFICIENT_FUNDS";
    return;
  }

  results.change.sort((a, b) => conversion[b[0]] - conversion[a[0]]);
  let changeOutput = results.change.map(item => `${item[0]}: $${item[1].toFixed(2)}`);
  changeText.textContent = `Status: ${results.status} ${changeOutput.join(" ")}`;
};

button.addEventListener("click", () => {
  const cash = Number(cashInput.value);
  let changeDue = (cash - price).toFixed(2);

  if (cash < price) {
    alert("Customer does not have enough money to purchase the item");
    return;
  }

  if (cash === price) {
    changeText.textContent = "No change due - customer paid with exact cash";
    return;
  }

  moneyChecker(changeDue, "OPEN");
});






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".
Falhou:When price is less than the value in the #cash element, total cash in drawer cid is equal to change due, and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: CLOSED" with change due in coins and bills sorted in highest to lowest order.

That would be the code now
help, please

when I run your code with the failing testcase, the output shown in the #change-due is

Status: OPEN QUARTER: $0.00 DIME: $0.00 NICKEL: $0.00 PENNY: $0.50

But the testcase is quite clear when they said that #change-due should have this instead:

"Status: CLOSED PENNY: $0.5" .

So fix the code so only the change that is not 0 is shown

I’m in a loop of errors, when I correct something, other errors appear

okay, so the above code you shared failed exactly 2 testcases.
one of those was because you were printing out too much stuff as I mentioned earlier.

What code fix did you do for that one? Please show me the function you changed and highlight the change.

Edit: also pls share your html code in case there is some other issue I am not seeing.

Now I’ve found other errors and increased them

const cashInput = document.getElementById("cash");
const changeText = document.getElementById("change-due");
const button = document.getElementById("purchase-btn");

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]
];

const conversion = {
  "PENNY": 0.01,
  "NICKEL": 0.05,
  "DIME": 0.1,
  "QUARTER": 0.25,
  "ONE": 1,
  "FIVE": 5,
  "TEN": 10,
  "TWENTY": 20,
  "ONE HUNDRED": 100,
};

const moneyChecker = (changeDue, statusCheck) => {
  let results = {
    status: statusCheck,
    change: []
  };

  let cidObj = {};
  for (let [name, amount] of cid) {
    cidObj[name] = amount;
  }

  for (let i = cid.length - 1; i >= 0; i--) {
    const denomination = cid[i][0];
    const denomValue = conversion[denomination];

    if (changeDue >= denomValue && cidObj[denomination] > 0) {
      const maxAmount = Math.min(Math.floor(changeDue / denomValue), cidObj[denomination]);
      const amount = maxAmount * denomValue;

      changeDue -= amount;
      cidObj[denomination] -= amount;
      results.change.push([denomination, amount]);
      changeDue = changeDue.toFixed(2);
    }
  }

  if (changeDue > 0) {
    changeText.textContent = "Status: INSUFFICIENT_FUNDS";
    return;
  }

  // Filter out denominations with zero amount
  results.change = results.change.filter(item => item[1] !== 0);

  // Sort change in descending order based on denomination value
  results.change.sort((a, b) => conversion[b[0]] - conversion[a[0]]);

  let changeOutput = results.change.map(item => `${item[0]}: $${item[1].toFixed(2)}`);
  changeText.textContent = `Status: ${results.status} ${changeOutput.join(" ")}`;
};

button.addEventListener("click", () => {
  const cash = Number(cashInput.value);

  if (cash < price) {
    alert("Customer does not have enough money to purchase the item");
    return;
  }

  let changeDue = (cash - price).toFixed(2);

  if (cash === price) {
    changeText.textContent = "No change due - customer paid with exact cash";
    return;
  }

  moneyChecker(changeDue, "CLOSED");
});

please tell me which lines you changed first.

I don’t know how to fix these mistakes, I didn’t understand

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" .

When price is less than the value in the #cash element, total cash in drawer cid is equal to change due, and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: CLOSED" with change due in coins and bills sorted in highest to lowest order.

so when the total cash in the drawer is exactly equal to the change, then the status has to be CLOSED not OPEN.

const moneyChecker = (changeDue, statusCheck) => {
  let results = {
    status: statusCheck,
    change: []
  };

  let totalCID = cid.reduce((acc, curr) => acc + curr[1], 0); // Calculate total cash in drawer

  if (changeDue == 0 && totalCID == cash) {
    results.status = "CLOSED";
    changeText.textContent = `Status: ${results.status}`;
    return;
  }

  for (let i = cid.length - 1; i >= 0; i--) {
    if (changeDue >= conversion[cid[i][0]] && changeDue > 0) {
      const timesInto = Math.floor(changeDue / conversion[cid[i][0]]);
      const amount = timesInto * conversion[cid[i][0]];

      if (amount > cid[i][1]) {
        changeDue -= cid[i][1];
        results.change.push([cid[i][0], cid[i][1]]);
      } else {
        changeDue -= amount;
        results.change.push([cid[i][0], amount]);
      }
      changeDue = changeDue.toFixed(2);
    }
  }

  if (changeDue > 0) {
    changeText.textContent = "Status: INSUFFICIENT_FUNDS";
    return;
  }

  results.change.sort((a, b) => conversion[b[0]] - conversion[a[0]]);
  let changeOutput = results.change.map(item => `${item[0]}: $${item[1].toFixed(2)}`);
  changeText.textContent = `Status: ${results.status} ${changeOutput.join(" ")}`;
};

If I put this code, all the other errors that were already solved appear

try to explain to me what you changed (and why).

const cashInput = document.getElementById("cash");
const changeText = document.getElementById("change-due");
const button = document.getElementById("purchase-btn");

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]
];

const conversion = {
  "PENNY": 0.01,
  "NICKEL": 0.05,
  "DIME": 0.1,
  "QUARTER": 0.25,
  "ONE": 1,
  "FIVE": 5,
  "TEN": 10,
  "TWENTY": 20,
  "ONE HUNDRED": 100,
};

const moneyChecker = (changeDue, statusCheck) => {
  let results = {
    status: statusCheck,
    change: []
  };

  for (let i = cid.length - 1; i >= 0; i--) {
    if (changeDue >= conversion[cid[i][0]] && changeDue > 0) {
      const timesInto = Math.floor(changeDue / conversion[cid[i][0]]);
      const amount = timesInto * conversion[cid[i][0]];

      if (amount > cid[i][1]) {
        changeDue -= cid[i][1];
        results.change.push([cid[i][0], cid[i][1]]);
      } else {
        changeDue -= amount;
        results.change.push([cid[i][0], amount]);
      }
      changeDue = changeDue.toFixed(2);
    }
  }

  if (changeDue > 0) {
    changeText.textContent = "Status: INSUFFICIENT_FUNDS";
    return;
  }

  results.change.sort((a, b) => conversion[b[0]] - conversion[a[0]]);
  let changeOutput = results.change.map(item => `${item[0]}: $${item[1].toFixed(2)}`);
  changeText.textContent = `Status: ${results.status} ${changeOutput.join(" ")}`;
};

button.addEventListener("click", () => {
  const cash = Number(cashInput.value);
  let changeDue = (cash - price).toFixed(2);

  if (cash < price) {
    alert("Customer does not have enough money to purchase the item");
    return;
  }

  if (cash === price) {
    changeText.textContent = "No change due - customer paid with exact cash";
    return;
  }

  moneyChecker(changeDue, "OPEN");
});




this was the code that failed 2 testcases.

You need to focus in on why the testcase failed.
1- you were printing the wrong status
2- you were printing too many things in the #change-due

Edit: fix one problem at a time. If you fix one problem and other things degrade, you need to identify why.

Okay, I’ll do it, just a moment

1 Like

At the moment I correct and leave the code like this:

const moneyChecker = (changeDue) => {
  let remainingChange = changeDue;
  let results = {
    status: "OPEN",
    change: []
  };

  for (let i = cid.length - 1; i >= 0; i--) {
    const denomination = cid[i][0];
    const amountInDrawer = cid[i][1];
    const value = conversion[denomination];

    if (remainingChange >= value && amountInDrawer > 0) {
      let maxToUse = Math.min(Math.floor(remainingChange / value) * value, amountInDrawer);
      results.change.push([denomination, maxToUse]);
      remainingChange -= maxToUse;
      remainingChange = remainingChange.toFixed(2);
    }
  }

  if (remainingChange > 0) {
    results.status = "INSUFFICIENT_FUNDS";
  } else if (changeDue === 0) {
    results.status = "EXACT";
  }

  if (results.status === "INSUFFICIENT_FUNDS") {
    changeText.textContent = "Status: INSUFFICIENT_FUNDS";
  } else if (results.status === "EXACT") {
    changeText.textContent = "No change due - customer paid with exact cash";
  } else {
    results.change.sort((a, b) => conversion[b[0]] - conversion[a[0]]);
    let changeOutput = results.change.map(item => `${item[0]}: $${item[1].toFixed(2)}`);
    changeText.textContent = `Status: OPEN ${changeOutput.join(" ")}`;
  }
};

presents these errors

  • When price is 20 and the value in the #cash element is 10, an alert should appear with the text "Customer does not have enough money to purchase the item".

  • Failed:When the value in the #cash element is less than price, an alert should appear with the text "Customer does not have enough money to purchase the item".

  • Failed:When price is 11.95 and the value in the #cash element is 11.95, the value in the #change-due element should be "No change due - customer paid with exact cash".

  • Failed:When the value in the #cash element is equal to price, the value in the #change-due element should be "No change due - customer paid with exact cash".

  • Failed:When price is 19.5, the value in the #cash element is 20, 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 QUARTER: $0.5".

  • Failed: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".

  • Failed:When price is less than the value in the #cash element, total cash in drawer cid is greater than the change due, individual denomination amounts allows for returning change due, and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: OPEN" with required change due in coins and bills sorted in highest to lowest order.

  • Failed:When price is 19.5, the value in the #cash element is 20, cid is [["PENNY", 0.01], ["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: INSUFFICIENT_FUNDS"

  • Failed:When price is less than the value in the #cash element, total cash in drawer cid is greater than change due, individual denomination amounts make impossible to return needed change, and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: INSUFFICIENT_FUNDS"

  • Failed:When price is 19.5, the value in the #cash element is 20, cid is [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["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: INSUFFICIENT_FUNDS".

  • Failed:When price is less than the value in the #cash element, total cash in drawer cid is less than the change due, and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: INSUFFICIENT_FUNDS".

  • Failed: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".

  • Failed:When price is less than the value in the #cash element, total cash in drawer cid is equal to change due, and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: CLOSED" with change due in coins and bills sorted in highest to lowest order.

tell me which line(s) of code you changed to fix the issue:

We want to make very limited changes. One fix at a time.