Tell us what’s happening:
I manually tested all the test cases, and they passed, but I can’t seem to pass the last seven test cases when running the automated tests. Appreciate any help!
-
Failed:When
price
is less than the value in the#cash
element, total cash in drawercid
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
is19.5
, the value in the#cash
element is20
,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 drawercid
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
is19.5
, the value in the#cash
element is20
,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 drawercid
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
is19.5
, the value in the#cash
element is20
,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 drawercid
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.
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="stylesheet" href="styles.css" />
<title>Cash Register</title>
</head>
<body>
<h1>Cash Register Project</h1>
<div class="container">
<div id="change-due"></div>
<label for="cash">Enter Cash from Customer:</label>
<input type="number" id="cash" />
<button id="purchase-btn">Purchase</button>
<div class="cash-container">
<div class="wrapper">
<div>
<p id="total">
Total:
<span id="price"></span>
</p>
<img src="https://www.svgrepo.com/show/141588/cash-register.svg" alt="" />
</div>
<div>
<label>Change in Drawer:</label>
<p>
Pennies:
<span></span>
</p>
<p>
Nickels:
<span></span>
</p>
<p>
Dimes:
<span></span>
</p>
<p>
Quarters:
<span></span>
</p>
<p>
Ones:
<span></span>
</p>
<p>
Fives:
<span></span>
</p>
<p>
Tens:
<span></span>
</p>
<p>
Twenties:
<span></span>
</p>
<p>
Hundreds:
<span></span>
</p>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
/* file: script.js */
const changedueElement = document.getElementById("change-due")
const cashInput = document.getElementById("cash")
const purchaseBtn = document.getElementById("purchase-btn")
const priceElement = document.getElementById("price")
const changeInDrawElements = document.querySelectorAll("label ~ p > span")
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 currencyValues = [
["Penny", 0.01],
["Nickel", 0.05],
["Dime", 0.1],
["Quarter", 0.25],
["One", 1],
["Five", 5],
["Ten", 10],
["Twenty", 20],
["One Hundred", 100],
]
class Currency {
constructor(name, amount, faceValue) {
this.name = name
this._faceValue = faceValue
this.amount = amount || 0
}
getFaceValue() {
return this._faceValue
}
hasSufficientAmount() {
return parseFloat((this.amount - this._faceValue).toFixed(2)) > 0
}
}
class CashDrawer {
constructor(cid, currencyValues) {
this.currencies = []
for (let i = 0; i < cid.length; i++) {
this.currencies.push(
new Currency(currencyValues[i][0], cid[i][1], currencyValues[i][1])
)
}
}
getTotalAmount() {
let total = 0
this.currencies.forEach((currency) => {
total += currency.amount
})
return parseFloat(total.toFixed(2))
}
getCurrencyArray() {
return this.currencies
}
calculateChange(cashReceived, itemPrice) {
let changeNeeded = parseFloat((cashReceived - itemPrice).toFixed(2))
console.log("changeNeeded: $", changeNeeded)
//- "Status: INSUFFICIENT_FUNDS" if cash-in-drawer is less than the change due
console.log("total change amount in the drawer: $" + this.getTotalAmount())
if (this.getTotalAmount() < changeNeeded) {
return { canBreakChange: false, status: "INSUFFICIENT_FUNDS" }
}
let changeArray = []
let currencies = this.getCurrencyArray()
for (let i = currencies.length - 1; i >= 0; i--) {
let currency = currencies[i]
let faceValue = currency.getFaceValue()
let currencyName = currency.name
let currencyTotalAmount = 0
while (changeNeeded >= faceValue && currency.amount >= faceValue) {
// console.log(`ChangeNeeded: ${changeNeeded} - ${faceValue}`)
changeNeeded = parseFloat((changeNeeded - faceValue).toFixed(2))
currency.amount = parseFloat((currency.amount - faceValue).toFixed(2))
currencyTotalAmount = parseFloat(
(currencyTotalAmount + faceValue).toFixed(2)
)
}
if (currencyTotalAmount > 0) {
changeArray.push([currencyName, currencyTotalAmount])
}
}
if (changeNeeded > 0) {
return { canBreakChange: false, status: "INSUFFICIENT_FUNDS" }
} else if (this.getTotalAmount() === 0) {
return { canBreakChange: true, status: "CLOSED", changeArray }
} else {
return { canBreakChange: true, status: "OPEN", changeArray }
}
}
}
window.onload = () => init()
const resetCashInput = () => (cashInput.value = "")
const updateChangeInDrawer = () => {
for (let i = 0; i < cid.length; i++) {
changeInDrawElements[i].textContent = `$${
cashDrawer.getCurrencyArray()[i].amount
}`
}
}
const updateStatus = (text) => {
changedueElement.innerHTML = `<p>${text}</p>`
changedueElement.style.display = "block"
}
const updateChangeDue = (changeArray) => {
for (let i = 0; i < changeArray.length; i++) {
changedueElement.innerHTML += `<p>${changeArray[i][0].toUpperCase()}: $${
changeArray[i][1]
}</p>`
}
changedueElement.style.display = "block"
}
const resetChangeDueElement = () => {
changedueElement.innerHTML = ""
changedueElement.style.display = "none"
}
const isCashInputValid = (cash) => {
if (cash === 0) {
alert("Please enter a valid number")
resetCashInput()
return false
} else if (cash < price) {
alert("Customer does not have enough money to purchase the item")
resetCashInput()
return false
} else if (cash === price) {
updateStatus("No change due - customer paid with exact cash")
resetCashInput()
return false
} else {
// console.log(`Cash input: ${cash} is valid`)
return true
}
}
const purchase = (cash) => {
console.log(
"Customer handed $" + Number(cash) + "\nItem price is: $" + price
)
resetChangeDueElement()
cash = Number(cash)
if (!isCashInputValid(cash)) {
return
}
// todo: call your new breakChange function
const result = cashDrawer.calculateChange(cash, price)
console.log(result)
if (!result.canBreakChange) {
updateStatus(`Status: ${result.status}`)
return
}
updateStatus(`Status: ${result.status}`)
updateChangeDue(result.changeArray)
updateChangeInDrawer()
return
}
purchaseBtn.addEventListener("click", () => {
purchase(cashInput.value)
resetCashInput()
})
cashInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
purchase(cashInput.value)
resetCashInput()
}
if (e.key === "Escape") {
resetCashInput()
}
})
const cashDrawer = new CashDrawer(cid, currencyValues)
const init = () => {
// set total price
priceElement.textContent = `$${price}`
// load change in drawer
updateChangeInDrawer()
}
/* file: styles.css */
:root {
--background-color: #9ec8b9;
--input-color: #c8eadf;
--font-color: #092635;
--button-color: #5c8374;
--button-color-hover: #64907f;
--button2-color: #1b4242;
--color: #000000;
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--background-color);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-family: Arial, Helvetica, sans-serif;
color: var(--font-color);
}
/** Title */
h1 {
margin: 36px;
text-align: center;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 400px;
max-width: 800px;
}
.container * {
margin: 0 0 10px 0;
}
#change-due {
display: none;
}
#change-due p {
margin: 6px;
}
/** cash input */
#cash {
border: none;
border-radius: 10px;
padding: 4px 4px 4px 8px;
font-size: 1.1rem;
width: 40%;
background-color: var(--input-color);
color: var(--font-color);
}
#purchase-btn {
padding: 6px 10px 6px 10px;
font-size: 1.1rem;
border: none;
border-radius: 10px;
background-color: var(--button-color);
color: var(--font-color);
cursor: pointer;
}
#purchase-btn:hover {
background-color: var(--button-color-hover);
}
#purchase-btn:active {
background-color: var(--button-color);
}
.cash-container {
margin: 10px 0 0 0;
}
#total {
text-align: center;
font-size: 1.1rem;
}
.wrapper {
display: flex;
}
.wrapper div:first-child {
width: 200px;
margin: 0 20px 0 0;
}
.wrapper div:nth-child(2) {
width: 200px;
}
.wrapper div:nth-child(2) label {
margin: 0;
font-weight: bold;
}
.wrapper div:nth-child(2) p {
margin: 8px 0 0 24px;
}
@media (max-width: 420px) {
img {
display: none;
}
.wrapper {
flex-direction: column;
}
.wrapper div:first-child {
width: 200px;
margin: 0;
}
}
Your browser information:
User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
Challenge Information:
Build a Cash Register Project - Build a Cash Register