Tell us what’s happening:
Struggling with test cases 12 and 11:
11. 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”.
Waiting: 12. 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”.
My goal was to loop through the 2D array cid backwards looking at the big bills first, deconstruct inner arrays into variables for amount and unit/denomination. Check if money of that specific denomination is available in drawer and that there is still change to be given back. And only then subtract that amount from cash in drawer. Create an array to keep track of the amount to be given back and in what units, convert that array into a string and output it with the status.
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">
<link rel="stylesheets" href="styles.css">
<title>Cash Register</title>
</head>
<body>
<div class="container">
<h1>Cash Register</h1>
<form>
<label for="cash"></label>
<input id="cash" name="cash" type="number">
<button type="submit" id="purchase-btn">Buy</button>
</form>
<div id="change-due">Change Due: </div>
</div>
<script src="script.js"></script>
</body>
</html>
/* file: script.js */
let price = 19.5; //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]
];
const cashInput = document.getElementById("cash");
const purchaseBtn = document.getElementById("purchase-btn");
const changeDue = document.getElementById("change-due");
const calculateChange = (cashGiven, price) => {
let change = (Number(cashGiven) * 100 - price * 100) / 100;
//console.log(`Price in dollars: ${price}`);
//console.log(`Price in cents: ${100*price}`);
//console.log(`Cash Given in dollars: ${cashGiven}`);
console.log(`Cash Given in cents: ${100*cashGiven}`);
console.log(`Change: ${change}`);
//"Status: OPEN TWENTY: $60 TEN: $20 FIVE: $15 ONE: $1 QUARTER: $0.5 DIME: $0.2 PENNY: $0.04"
return change;
}
//console.log(`Change due (cents): ${change}`);
//console.log(`Cash in drawer total (cents): ${cidTotal}`);
//console.log(`cidTotal < change? ${cidTotal < change}`);
//console.log(`cidTotal: ${cidTotal}`)
purchaseBtn.addEventListener("click", (event) => {
event.preventDefault();
const cashInputVal = Number(cashInput.value);
let status = "";
let change = 0;
let changeArr = [];
// cash in drawer as cents = 33541 or $335.41
const cidTotal = cid.reduce((acc, el)=> acc + Math.round(el[1] * 100), 0) / 100;
if (cashInputVal < price) {
alert("Customer does not have enough money to purchase the item");
return;
}
if (cashInputVal === price) {
changeDue.innerText = "No change due - customer paid with exact cash";
return;
}
change = calculateChange(cashInputVal, price);
if (cashInputVal > price) {
if(cidTotal < change){
status = "INSUFFICIENT_FUNDS";
changeDue.innerText =`Status: ${status}`;
}
else if(cidTotal === change){
status = "CLOSED";
changeDue.innerText =`Status: ${status}`;
}
//if(cidTotal > change)
else{
status = "OPEN";
// IRL I would start with the largest bills and remove them from the register by subtracting,
// like if I had $17.34 I would see how many tens I need, then how many fives, then ones, then quarters and dimes etc.
// and subtracting my change from each unit/denomination and updating the array
const unitValues = {
"PENNY": 0.01,
"NICKEL": 0.05,
"DIME": 0.10,
"QUARTER": 0.25,
"ONE": 1.00,
"FIVE": 5.00,
"TEN": 10.00,
"TWENTY": 20.00,
"ONE HUNDRED": 100.00
};
// loop backwards thru the 2d array cid array big numbers/bills are first
for (let i = cid.length - 1; i >= 0; i--){
// destructure inner array to break it up into units/denominations and cash
let [unit, amount] = cid[i];
let unitValue = unitValues[unit];
let amountToGive = 0;
// while money of that denomination is available in draw
// and still change to be given back
while (amount >= unitValue && unitValue <= change) {
//update change
change = parseFloat((change - unitValue).toFixed(2));
//update amount of cash in drawer
amount = parseFloat((amount - unitValue).toFixed(2));
//update amount to give
amountToGive = parseFloat((amountToGive + unitValue).toFixed(2));
}
//populate the change array
if (amountToGive > 0) {
changeArray.push([unit, amountToGive]);
}
}
const formattedChangeStr = changeArray.map(([unit, amount]) => `${unit}: $${amount.toFixed(2)}`).join(' ')
changeDue.innerText = `Status: ${status} ${formattedChangeStr}`;
}
}
})
/* file: styles.css */
* {
box-sizing: border-box;
margin: 0;
padding: 0
}
html, body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #fff;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: start;
background-color: rgb(124, 228, 124);
width: 25rem;
height: 25rem;
border-radius: 10px;
margin-top: 40px;
}
h1 {
margin-top: 40px;
margin-bottom: 20px;
}
form{
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 0.75rem;
}
input {
height: 20px;
}
#purchase-btn {
width: 40px;
height: 20px;
font-size: 15px;
}
#change-due {
margin-top: 20px;
display: flex;
align-items: center;
}
Your browser information:
User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.2 Safari/605.1.15
Challenge Information:
Build a Cash Register Project - Build a Cash Register