Build a Cash Register Project - Last test failing

Tell us what’s happening:

Last test failing:
" When price is 19.5 , the value in the #cash element is 20 , 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 QUARTER: $0 DIME: $0 NICKEL: $0 PENNY: $0.5 ."

Q: Why. It seems I am meeting all the requirements and passing every other test. What am I doing wrong?

Your code so far

let cid = [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]];

let price = 19.5

const change_tracker = [
    { name: 'ONE HUNDRED', value: 10000, outStr: 0 },
    { name: 'TWENTY', value: 2000, outStr: 0 },
    { name: 'TEN', value: 1000, outStr: 0 },
    { name: 'FIVE', value: 500, outStr: 0 },
    { name: 'ONE', value: 100, outStr: 0 },
    { name: 'QUARTER', value: 25, outStr: 0 },
    { name: 'DIME', value: 10, outStr: 0 },
    { name: 'NICKEL', value: 5, outStr: 0 },
    { name: 'PENNY', value: 1, outStr: 0 }
];
const change_due = document.getElementById("change-due")
const changeElement = document.getElementById("change")
const CENT_IN_DOLLAR = 100

let [cash, converted_cash, total_cid, reg_status, missed_change] = [null, null, null, null, ''];

//Upon load, add the price and drawer change
document.addEventListener('DOMContentLoaded', function () {
    const totalElement = document.getElementById('total')
    totalElement.innerHTML = `$${price.toFixed(2)}`
    drawer_change()
})

//Handles purchase button, updating change information and drawer status.
const purchase = () => {
    //clear any elements in change_due
    clear_change_div()

    cash = document.getElementById("cash").value

    //get total cash in drawer
    for (let i = 0; i < cid.length; i++) {
        total_cid = floatFixer(total_cid) + floatFixer(cid[i][1]);
    }
    total_cid = floatFixer(total_cid);

    if (cash.length == 0) {
        alert('Invalid input')
    } else if (cash < price) {
        alert("Customer does not have enough money to purchase the item")
        return
    } else if (cash == price) {
        change_due.innerHTML = 'No change due - customer paid with exact cash'
        return
    } else if (cash - price > total_cid) {
        reg_status = 'INSUFFICIENT_FUNDS'
    } else {
        console.log(cash - price, total_cid)
        if (cash - price == total_cid) {
            reg_status = 'CLOSED'
        } else {
            reg_status = 'OPEN'
        }
        converted_cash = parseInt((cash - price) * CENT_IN_DOLLAR)
        calculateChange(converted_cash)
    }
    changeUpdate()
    drawer_change()
}


/*
Calculates the change breakdown for a given amount 'num'.
Iterates through elements in 'change_tracker' and updates values in the 'cid' array accordingly.
Updates 'outStr' property in 'change_tracker'.
*/
const calculateChange = (num) => {

    //slowly breaks down the change to 0
    //for each element of change_tracker
    for (const element of change_tracker) {

        //find the matching element in CID array (PENNY find PENNY)
        let matching_cid = cid.find((index) => index[0] === element.name)

        //find index of matching element
        let index = cid.indexOf(matching_cid)

        //to accomodate for the final test, adding html elements > value but = 0. 
        if (num >= element.value && cid[index][1] == 0) {
            missed_change += `<p>${element.name}: $0</p><br />`
        } else {
            //while num is greater than the elements value
            while (num >= element.value && cid[index][1] > 0) {
                //decrease num by elements value
                num -= element.value;

                //convert element value to dollar amount
                let convert_dollar = element.value / CENT_IN_DOLLAR

                //decrease matching element in cid array by element value
                cid[index][1] = floatFixer(parseFloat(cid[index][1] - convert_dollar))

                //add element value to the outstr value
                element.outStr += convert_dollar
            }
        }
    }
    if (num != 0) {
        reg_status = 'INSUFFICIENT_FUNDS'
    }
}

//Updates the HTML content of 'change_due' element with register status and possible change.
const changeUpdate = () => {
    change_due.innerHTML += `<h3>Status: ${reg_status}</h3><br />`
    if (reg_status !== 'INSUFFICIENT_FUNDS') {
        //find all elements in change_tracker where outStr is not 0 (base value)
        let filtered_items = change_tracker.filter((element) => element.outStr !== 0)
        change_due.innerHTML += missed_change
        filtered_items.forEach(element => {
            change_due.innerHTML += `<p>${element.name}: $${floatFixer(element.outStr)}</p><br />`
        })
    }
}

//Updates the HTML content of the 'change' element with remaining change in the register
const drawer_change = () => {
    changeElement.innerHTML = `<h3>Change in Drawer</h3>`

    cid.forEach(element => {
        changeElement.innerHTML += `<p>${element[0]}: $${element[1]}</p> `
    })
}

//Resets the total cash in drawer, change_tracker outstr values, and removes all children nodes from the 'change_due' element
const clear_change_div = () => {
    total_cid = 0
    change_tracker.forEach(element => {
        element.outStr = 0
    })
    while (change_due.firstChild) {
        change_due.removeChild(change_due.firstChild);
    }
}

//Fixes floating point numbers
const floatFixer = (num) => {
    return parseFloat(num.toFixed(2))
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36

Challenge Information:

Build a Cash Register Project - Build a Cash Register

Please provide your HTML so we can run it for ourselves.

Heres the HTML and CSS

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Silkscreen:wght@400;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="./styles.css">
</head>

<body>
    <div id="main-content">
        <h1>Virtual Cash Register</h1>
        <div id="wrapper">
            <div id="top-content">
                <h2>Enter cash from customer:</h2>
                <input id="cash" type="number">
                <br />
                <button id="purchase-btn" onclick="purchase()">Purchase</button>
                <div id="change-due">
                </div>
            </div>
            <div id="bottom-wrapper">
                <div id="change-wrapper">
                    <div id="change"></div>
                </div>
                <div id="bottom-content">
                    <h2 id="total"></h2>
                </div>
            </div>
            <div id="extra-shapes">
                <div id="drawer-top"></div>
                <div class="ovals">
                    <div class="oval1"></div>
                    <div class="oval2"></div>
                    <div class="oval3"></div>
                    <div class="oval4"></div>
                    <div class="oval5"></div>
                    <div class="oval6"></div>
                    <div class="oval7"></div>
                    <div class="oval8"></div>
                    <div class="oval9"></div>
                </div>
                <div id="drawer-bottom">
                    <div id="drawer-bottom-inset"></div>
                </div>
                <div class="tape"></div>
                <div class="sticky-note">
                    <h2>Reminders:</h2>
                    <li>Give the customer their change</li>
                    <br />
                    <li>Don't let them ask for the manager</li>
                    <br />
                    <li>Breaks are <strong><i>not</i></strong> allowed</li>
                </div>

            </div>
        </div>
    </div>
    <br />
    <script src="./script.js"></script>
</body>

</html>

CSS:

html {
    height: 100%;
    font-family: system-ui;
    --main-color: #5DB7DE;
    --accent1: #26799d;
    --accent2: #355c7d;
}

body {
    background: linear-gradient(89.7deg, #000000 -10.7%, var(--accent2) 88.8%);
}

#main-content {
    text-align: center;
    margin: auto;
}


#main-content>h1 {
    color: white;
    padding-top: 10px;
    margin: 0;
}

#top-content {
    color: white;
}

#cash {
    text-align: center;
    font-size: 18px;
    font-family: system-ui;
    font-weight: bold;
    background-color: white;
    height: 40px;
    width: 300px;
    margin-top: -10px;
    border-radius: 40px;
    border-width: 3px;
    border-color: #000000;
}

#change-due {
    padding-top: 20px;
    width: auto;
    margin: auto;
    text-align: center;
    font-size: 1.2rem;
    margin-bottom: -5px;
}

#change-due>h3, #change-due>p {
    line-height: 10px;
    font-weight: 300;
    margin: 0;
}

#purchase-btn {
    margin-top: 10px;
    font-family: system-ui;
    font-weight: bold;
    appearance: none;
    background-color: var(--main-color);
    border-radius: 4px;
    border-width: 0;
    box-shadow: rgba(0, 0, 0, 0.4) 0 2px 4px, rgba(0, 0, 0, 0.3) 0 7px 13px -3px, var(--accent1) 0 -3px 0 inset;
    height: 35px;
    width: 150px;
    transition: box-shadow .15s, transform .15s;
    font-size: 18px;
}

#purchase-btn:hover {
    box-shadow: rgba(0, 0, 0, 0.4) 0 4px 8px, rgba(0, 0, 0, 0.3) 0 7px 13px -3px, var(--accent1) 0 -3px 0 inset;
    transform: translateY(-2px);
}

#purchase-btn:active {
    box-shadow: var(--accent1) 0 3px 7px inset;
    transform: translateY(2px);
}


#bottom-wrapper {
    display: inline-flex;
    background-color: var(--main-color);
    border-radius: 20px 20px 0 0;
    height: 135px;
    margin-top: 170px;
}

#bottom-content {
    padding-top: 1%;
}

#total {
    background-color: #1c698a;
    box-shadow: 0 4px 5px rgba(0, 0, 0, 0.5) inset;
    border-radius: 20px;
    margin: 10px 10px 0 100px;
    width: 250px;
    padding-top: 5px;
    padding-bottom: 10px;
    color: white;
    font-family: "Silkscreen", sans-serif;
    font-weight: 500;
    font-size: 2rem;
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 42px #0fa, 0 0 82px #0fa, 0 0 92px #0fa;
}

#change-wrapper {
    padding-left: 40px;
    width: 200px;
    margin-top: -140px;
}

#change-wrapper::before {
    content: "";
    position: absolute;
    width: 220px;
    border-bottom: solid 3px #000000;
    transform: translate(-110px, 198px);
}

#change {
    padding-top: 1%;
    padding-bottom: 1%;
    background-color: white;
    height: 195px;
}

#change>h3 {
    line-height: 1px;
    text-align: left;
    padding-left: 20px;
    padding-bottom: 10px;
    text-decoration: underline;
}

#change>p {
    line-height: 1px;
    text-align: left;
    padding-left: 25px;
}

#extra-shapes {
    text-align: center;
    margin: auto;
}

#drawer-top {
    text-align: center;
    margin: auto;
    margin-top: 2px;
    border-bottom: 130px solid var(--main-color);
    border-left: 70px solid transparent;
    border-right: 70px solid transparent;
    width: 600px;
}

#drawer-bottom {
    text-align: center;
    margin: auto;
    border-bottom: 100px solid var(--main-color);
    width: 740px;
    margin-top: -132px;
}

#drawer-bottom-inset {
    content: "";
    border-bottom: 90px solid var(--accent1);
    width: 725px;
    margin-left: 7px;
    margin-bottom: 10px;
    transform: translate(0, 105px);
}

.oval1,
.oval2,
.oval3,
.oval4,
.oval5,
.oval6,
.oval7,
.oval8,
.oval9 {
    height: 30px;
    width: 50px;
    background-color: white;
    border-radius: 50%;
    box-shadow: 0 6px 2px -2px rgb(0, 0, 0, 0.2);
    display: inline-block;
}

.oval1 {
    transform: translate(-90px, -40px);
}

.oval2 {
    transform: translate(-60px, -40px);
}

.oval3 {
    transform: translate(-30px, -40px);
}

.oval4 {
    transform: translate(-230px, -80px);
}

.oval5 {
    transform: translate(-205px, -80px);
}

.oval6 {
    transform: translate(-180px, -80px);
}

.oval7 {
    transform: translate(-370px, -120px);
}

.oval8 {
    transform: translate(-350px, -120px);
}

.oval9 {
    transform: translate(-330px, -120px);
}

.sticky-note {
    display: inline-block;
    background-color: #fff740;
    text-align: left;
    width: 250px;
    height: 250px;
    padding: 1px 0 1px 20px;
    zoom: 0.4;
    transform: translate(600px, -550px) rotate(0deg) skew(25deg);
    z-index: 1;
}

.tape {
    display: inline-block;
    background-color: rgba(255, 255, 255, 0.5);
    width: 20px;
    height: 35px;
    transform: translate(300px, -270px) rotate(0deg) skew(25deg);
}

I am having also having problem with the last test.
I’ll make a separate issue. Just so you know you are not the only one.
Your visual design looks great BTW!

1 Like

Thanks! And glad to know I’m not alone. This has been driving me crazy. It’s the last project I need to get the certification haha

There is a known bug in the last test that I believe has been fixed in the code but possibly the updated code hasn’t been pushed to production yet. So that could explain your issue. But…

You actually have a bug in your code that will fail the last test even when the updated fix gets pushed to production. I would recommend you verify that for the last test you actually have the values in #change-due that the tests want. (Hint: You have a little extra in there).

Hi, I was wondering if they rolled that fix into production yet? my output in the #change-due element is
Status: CLOSED PENNY: $0.50
when price is 19.5, cash is 20, and there is only 50 pennies left in the drawer, so I think it should pass? I can make a separate topic if the bug fix has already been rolled out.

I’m assuming it has been fixed by now. If you are still having problems then yes, open your own post.

I’m noticing that the test for this one says:

"…element should be `“Status: CLOSED PENNY: $0.5”

Just wondering if that extra 0 you have on the end might be causing an issue? I’m just guessing here, so it may not be a problem.

1 Like