Cash register help

Hello, I’m having problems with the last two steps of the “Cash Register” project. Below is my JS code, if anyone can help me I would appreciate it:

let price = 19.5; // Exemplo de preço
let cid = [
    ["PENNY", 0.5],
    ["NICKEL", 0],
    ["DIME", 0],
    ["QUARTER", 0],
    ["ONE", 0],
    ["FIVE", 0],
    ["TEN", 0],
    ["TWENTY", 0],
    ["ONE HUNDRED", 0]
];

const purchaseBtn = document.getElementById('purchase-btn');
const cashInput = document.getElementById('cash');
const priceInput = document.getElementById('price');
const changeDueDiv = document.getElementById('change-due');

// Atualiza o preço com base na entrada do usuário
priceInput.addEventListener('change', () => {
    price = parseFloat(priceInput.value);
});

purchaseBtn.addEventListener('click', () => {
    let cash = parseFloat(cashInput.value);

    if (cash < price) {
        alert("Customer does not have enough money to purchase the item");
        return;
    }

    let changeDue = cash - price;

    if (Math.abs(changeDue) < 0.01) {
        changeDueDiv.textContent = "No change due - customer paid with exact cash";
        return; 
    }

    let result = checkCashRegister(price, cash, cid);
    changeDueDiv.innerHTML = result;
});

function checkCashRegister(price, cash, cid) {
    let change = calculateChange(price, cash, cid);

    if (change.status === "INSUFFICIENT_FUNDS") {
        return "Status: INSUFFICIENT_FUNDS";
    } else if (change.status === "CLOSED") {
        return "Status: CLOSED " + formatChange(change.change);
    } else if (change.status === "OPEN") {
        return "Status: OPEN " + formatChange(change.change);
    }
}

function calculateChange(price, cash, cid) {
    let changeDue = cash - price;
    let totalCid = cid.reduce((sum, [_, amount]) => sum + amount, 0);
    let change = [];
    let status = "OPEN";

    // Se o total em cid é igual ao troco
    if (Math.abs(changeDue - totalCid) < 0.01) {
        status = "CLOSED";
        change = cid.map(([denom, amount]) => [denom, amount]); // Usa todo o cid como troco
    } else if (changeDue > totalCid) { // Se o troco devido é maior que o total na gaveta
        status = "INSUFFICIENT_FUNDS";
        change = [];
    } else {
        let denominations = [
            ["ONE HUNDRED", 100],
            ["TWENTY", 20],
            ["TEN", 10],
            ["FIVE", 5],
            ["ONE", 1],
            ["QUARTER", 0.25],
            ["DIME", 0.1],
            ["NICKEL", 0.05],
            ["PENNY", 0.01]
        ];

        for (let [denom, value] of denominations) {
            let amount = 0;

            while (changeDue >= value) {
                for (let [cidDenom, cidAmount] of cid) {
                    if (cidDenom === denom && cidAmount >= value) {
                        amount += value;
                        changeDue = (changeDue - value).toFixed(2);
                        cid[cid.findIndex(([d]) => d === denom)][1] -= value;
                        break;
                    }
                }
                if (amount > 0) {
                    change.push([denom, parseFloat(amount.toFixed(2))]);
                }
            }
        }

        // Verifica se ainda precisamos de troco
        if (Math.abs(changeDue) > 0.01 || change.length === 0) {
            status = "INSUFFICIENT_FUNDS";
            change = [];
        }
    }

    return { status, change };
}

function formatChange(change) {
    return change.map(([denom, amount]) => `${denom}: $${amount.toFixed(2)}`).join(" ");
}

What’s happening? What have you tried to fix it? Where did you get stuck?

Greetings, my problem was with change but I have already solved it, when I put 20 in the amount paid by the customer the program put 0.05 when it should have been 0.5
Thanks.

In short, it was “Rounding Accuracy and Change Logic” problems!

1 Like