Tell us what’s happening:
Hey guys,
I have trouble finishing this project. The tests keep failing and I dont know exactly. For instance: There is a test case where the price is set to 19.5, the cash given is supposed to be 20 but the Cash-in-Drawer is insufficient . The test says that the text in the output element should be: “Status: INSUFFICIENT_FUNDS”. So I assigned the cid and the price to the values mentioned above and my website returns the wanted text. I dont get why the test case fails if both strings are equal.
Your code so far
<!-- 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>CashRegister</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>Cash Register</h1>
<p id="change-due"></p>
<label for="cash">Enter cash from customer: </label>
<input type="number" id="cash" />
<button id="purchase-btn">Change</button>
<p id="price"></p>
</div>
<script src="script.js"></script>
</body>
</html>
/* file: script.js */
const priceElement = document.getElementById("price");
const cash = document.getElementById("cash");
const changeBtn = document.getElementById("purchase-btn");
const changeDue = document.getElementById("change-due");
let price = 19.5;
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]];
window.addEventListener("load", () => (priceElement.innerText = price));
const determineValue = (currencyName) => {
switch (currencyName) {
case "PENNY":
return 0.01;
case "NICKEL":
return 0.05;
case "DIME":
return 0.1;
case "QUARTER":
return 0.25;
case "ONE":
return 1;
case "FIVE":
return 5;
case "TEN":
return 10;
case "TWENTY":
return 20;
case "ONE HUNDRED":
return 100;
default:
return 1;
}
};
class CashRegister {
constructor(cid) {
this.register = cid;
this.status = "OPEN";
this.hand = {};
}
getAmount(currency) {
const entry = this.register.find((el) => el[0] === currency);
return Number((entry[1] / determineValue(entry[0])).toFixed(2));
}
getFunds() {
return Number(
this.register.reduce((acc, el) => (acc += el[1]), 0).toFixed(2)
);
}
isEmpty() {
return this.getFunds() === 0;
}
putHandBack() {
for (const [currency, amount] of Object.entries(this.hand)) {
if (["QUARTER", "DIME", "NICKEL", "PENNY"].includes(currency)) {
this.register.find((el) => el[0] === currency)[1] += Number(
(amount * determineValue(currency)).toFixed(2)
);
} else {
this.register.find((el) => el[0] === currency)[1] +=
amount * determineValue(currency);
}
}
this.hand = {};
}
formatHand() {
let returnArray = [`Status: ${this.status}`];
for (const [key, value] of Object.entries(this.hand)) {
if (value === 0) {
continue;
}
if (["QUARTER", "DIME", "NICKEL", "PENNY"].includes(key)) {
returnArray.push(
`${key}: $${Number((value * determineValue(key)).toFixed(2))}`
);
} else {
returnArray.push(`${key}: $${value * determineValue(key)}`);
}
}
this.hand = {};
return returnArray.join(" ");
}
takeCash(currency, amount) {
switch (currency) {
case "ONE HUNDRED":
this.register[8][1] -= amount;
break;
case "TWENTY":
this.register[7][1] -= amount;
break;
case "TEN":
this.register[6][1] -= amount;
break;
case "FIVE":
this.register[5][1] -= amount;
break;
case "ONE":
this.register[4][1] -= amount;
break;
case "QUARTER":
this.register[3][1] -= amount;
break;
case "DIME":
this.register[2][1] -= amount;
break;
case "NICKEL":
this.register[1][1] -= amount;
break;
case "PENNY":
this.register[0][1] -= amount;
break;
default:
return;
}
}
computeCurrency(money, currency) {
const value = determineValue(currency);
const currentAmount = this.getAmount(currency);
const requiredAmount = Math.floor(money / value);
let leftover = money;
if (leftover >= value) {
const amount =
requiredAmount <= currentAmount ? requiredAmount : currentAmount;
leftover -= amount * value;
this.takeCash(currency, amount * value);
this.hand[currency] = amount;
}
return leftover;
}
change(receivedMoney) {
this.status = this.status === "CLOSED" ? "CLOSED" : "OPEN";
if (this.status === "CLOSED") {
changeDue.innerText = "Status: CLOSED";
return;
}
if (receivedMoney < 0) {
alert("Cannot process negative cash");
return;
}
if (receivedMoney < price) {
alert("Customer does not have enough money to purchase the item");
return;
}
if (receivedMoney === price) {
changeDue.innerText = "No change due - customer paid with exact cash";
return;
}
// calculation
const difference = Number((receivedMoney - price).toFixed(2));
let leftover = difference;
const register = this.register.slice();
register
.reverse()
.map((el) => el[0])
.forEach((el) => {
leftover = Number(this.computeCurrency(leftover, el).toFixed(2));
console.log("leftover", leftover);
});
if (leftover === 0 && this.isEmpty()) {
this.status = "CLOSED";
} else if (leftover === 0) {
this.status = "OPEN";
} else {
this.status = "INSUFFICIENT_FUNDS";
}
console.log("hand", this.hand);
// output
if (this.status === "INSUFFICIENT_FUNDS") {
changeDue.innerText = "Status: INSUFFICIENT_FUNDS";
this.putHandBack();
return;
} else {
changeDue.innerText = this.formatHand();
}
return;
}
}
const cashRegister = new CashRegister(cid);
changeBtn.addEventListener("click", () => {
const money = Number(cash.value);
cashRegister.change(money);
});
/* file: styles.css */
* {
padding: 0;
margin: 0;
}
.container {
margin: 0 auto;
width: min(80%, 1000px);
background-color: rgb(10, 10, 77);
color: white;
padding: 10px;
text-align: center;
}
label {
display: block;
padding: 5px;
}
input {
display: block;
margin: 10px auto 10px;
}
button {
background-color: rgb(238, 202, 84);
border: 2px solid orange;
padding: 5px;
}
#price::before {
content: "Price: $";
}
#price {
padding: 10px;
color: rgb(224, 47, 47);
}
#output {
padding: 5px;
}
Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.0
Challenge Information:
Build a Cash Register Project - Build a Cash Register