I’m having a problem with the last scenario:
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.
I thought I had already met the user story by sorting the change array. Excerpt of my code:
if (changeDue === totalCid) {
const sortedCid = cid.slice().sort((a, b) => b[1] - a[1]);
return { status: "CLOSED", change: sortedCid };
}
Full code:
const sale = document.getElementById("purchase-btn");
const change = document.getElementById("change-due");
let price = 10;
document.getElementById("priceDisplay").innerHTML = `I am selling you something that costs $${price}.`;
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 currencyUnits = [
['PENNY', .01],
['NICKEL', .05],
['DIME', .1],
['QUARTER', .25],
['ONE', 1],
['FIVE', 5],
['TEN', 10],
['TWENTY', 20],
['ONE HUNDRED', 100]
];
sale.addEventListener('click', () => {
const cashValue = parseFloat(cash.value); //convert input from sting to number
const changeDue = cashValue - price;
if (cashValue < price) {
alert("Customer does not have enough money to purchase the item");
return;
}
if (cashValue === price) {
change.innerText = "No change due - customer paid with exact cash"
return;
}
const changeResult = getChange(changeDue, cid);
if (changeResult.status === "INSUFFICIENT_FUNDS" || changeResult.status === "CLOSED") {
change.innerText = `Status: ${(changeResult.status)} ${formatChange(changeResult.change)}`
} else {
change.innerText = `Status: OPEN ${formatChange(changeResult.change)}`;
}
});//End of event listener
const getChange = (changeDue, cid) => {
let totalCid = parseFloat(cid.reduce((sum, [_, amount]) => sum + amount, 0).toFixed(2)); //Calculate how much change there is in the cash register, need to convert the string to a number
console.log("Total CID:", totalCid);
if (totalCid < changeDue) {
return {status: "INSUFFICIENT_FUNDS", change: []}
}
let changeArray = [];
let remainingChange = parseFloat(changeDue);
for (let i = currencyUnits.length - 1; i >= 0; i--) {
let unit = currencyUnits[i][0]; // Iterate through cid starting from the largest value
let unitValue = currencyUnits[i][1]; // What is the actual value
let unitInDrawer = cid[i][1]; // How much of this value do i have in the cash register
if (unitValue <= remainingChange && unitInDrawer > 0) {
let amountFromUnit = 0;
while (remainingChange >= unitValue && unitInDrawer > 0) {
remainingChange = (remainingChange - unitValue).toFixed(2);
unitInDrawer -= unitValue;
amountFromUnit += unitValue;
}
if (amountFromUnit > 0) {
changeArray.push([unit, amountFromUnit]);
}
}
} // End of for loop
if (remainingChange > 0) {
return {status: "INSUFFICIENT_FUNDS", change: []}
}
if (changeDue === totalCid) {
const sortedCid = cid.slice().sort((a, b) => b[1] - a[1]);
return { status: "CLOSED", change: sortedCid };
}
return {status: "OPEN", change: changeArray}
};//End of getChange
const formatChange = changeArray => {
return changeArray
.filter(([unit, amount]) => amount > 0) // Filter out denominations with zero amount
.map(([unit, amount]) => {
// Format the amount to remove trailing zeroes after the decimal point
let formattedAmount = amount.toString();
if (formattedAmount.indexOf('.') !== -1) {
formattedAmount = formattedAmount.replace(/\.?0+$/, ''); // Remove trailing zeros
}
return `${unit}: $${formattedAmount}`;
})
.join(" "); // Join them into a single string
};
type or paste code here