Hi!
I’m stuck with this project, when I run the tests, I get the following wrong:
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"
As shown in the image, my program gets that status, so I don’t know what’s going on.
This is my code:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta
name="vewport"
content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./styles.css">
<title>Cash register project</title>
</head>
<body>
<div class="container">
<input value="20" type="number" id="cash">
<div id="change-due"></div>
<button id="purchase-btn">Purchase</button>
</div>
<script src="./script.js"></script>
</body>
</html>
JavaScript
const cashInput = document.getElementById("cash");
const purchaseBtn = document.getElementById("purchase-btn");
const changeDueElement = document.getElementById("change-due");
/*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]
];*/
let price = 19.5;
let cid = [
['PENNY', 0],
['NICKEL', 0],
['DIME', 0],
['QUARTER', 0],
['ONE', 90],
['FIVE', 55],
['TEN', 20],
['TWENTY', 60],
['ONE HUNDRED', 100]
];
// function to update html element with needed change
const updateChangeDueElement = (change) => {
if (change.every((noteOrCoin) => noteOrCoin === 0)) {
changeDueElement.innerHTML =
`<p>Status: INSUFFICIENT_FUNDS</p>`;
return;
}
for (let i = cid.length - 1; i >= 0; i--) {
if (change[i] > 0) {
changeDueElement.innerHTML += `<p>${cid[i][0]}: $${change[i]}</p>`
}
}
}
const isChangePossible = (changeDue, change) => {
const c1 = change.reduce((acc, el) => acc + el, 0);
return c1 >= changeDue;
}
// function to calculate change due
const getChange = (changeDue) => {
// array with values per note/coin
const notesAndCoins = [0.01, 0.05, 0.1, 0.25, 1, 5, 10, 20, 100]
// array with needed change
const change = [];
for (let i = cid.length - 1; i >= 0; i--) {
// how many of each do we have?
let available = Number((cid[i][1] / notesAndCoins[i]).toFixed(2));
// how many would we need?
let needed = parseInt((changeDue / notesAndCoins[i]).toFixed(2))
// calculate how many we need according with availability
if (changeDue >= notesAndCoins[i] && available) {
let toPush = 0;
while (available > 0 && needed > 0) {
cid[i][1] -= notesAndCoins[i];
needed--;
available--;
toPush++;
}
// update change due
changeDue -= notesAndCoins[i] * toPush;
// push the number of notes/coins we need into the array
change.unshift(Number((toPush * notesAndCoins[i]).toFixed(2)));
} else {
// if change is less than note/coin or there is not
change.unshift(0);
}
}
if (!isChangePossible(changeDue, change)) {
changeDueElement.innerHTML =
`<p>Status: INSUFFICIENT_FUNDS</p>`;
} else {
updateChangeDueElement(change);
}
}
purchaseBtn.addEventListener("click", () => {
// check if #cash input is empty
if (!cashInput.value) { return; }
// use 2 digit precission in variables
const cash = Number(cashInput.value).toFixed(2);
const changeDue = Number(cash - price).toFixed(2);
const cashInDrawer = Number(cid.reduce(
(acc, elem) => acc + elem[1], 0
).toFixed(2));
if (cash < price) {
alert("Customer does not have enough money to purchase the item");
// check why condition does not work with ===
} else if (cash == price) {
changeDueElement.innerHTML =
`<p>No change due - customer paid with exact cash</p>`;
} else if (cashInDrawer < changeDue) {
changeDueElement.innerHTML =
`<p>Status: INSUFFICIENT_FUNDS</p>`;
} else if (cashInDrawer == changeDue) {
changeDueElement.innerHTML =
`<p>Status: CLOSED</p>`;
getChange(changeDue);
} else {
changeDueElement.innerHTML =
`<p>Status: OPEN</p>`;
getChange(changeDue);
}
});
Also, I would like to comment that the last test
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.
at first I got it wrong, but next, whithout changing the code (just the cid array values) changed to “correct”.
I’m quite lost and would appreciate some insight.
Cheers
EDIT:
Funny, I just copied the code from the provided example (as an experiment) and it randomly fails at some tests… Now I’m completely lost