Build a Cash Register Project - Build a Cash Register

Tell us what’s happening:

Change-due element is showing the expected output in accordance with the tests but the tests are still failing. I have manually checked the output of each test by entering the values into the price and cash fields and the output is perfectly in accordance withe tests . Why my tests are failing?

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">
  <title>Cash Register</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 20px;
    }
    .container {
      max-width: 600px;
      margin: 0 auto;
      padding: 20px;
      border: 1px solid #ccc;
      border-radius: 10px;
    }
    input, button {
      padding: 10px;
      margin: 5px 0;
      width: 100%;
    }
    /* #change-due {
      margin-top: 20px;
      font-weight: bold;
    } */
  </style>
</head>
<body>
  <div class="container">
    <h1>Cash Register</h1>
    <label for="price">Price of Item:</label>
    <input type="number" id="price" step="0.01" placeholder="Enter price">
    <label for="cash">Cash Provided:</label>
    <input type="number" id="cash" step="0.01" placeholder="Enter cash provided">
    <button id="purchase-btn">Purchase</button>
    <p id="change-due"></p>
  </div>
  <script src="script.js"></script>
</body>
</html>

/* file: script.js */
// Predefined variables for testing
let price = 0;
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]];

// Currency unit values
const currencyUnit = {
  "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
};

document.getElementById('purchase-btn').addEventListener('click', function() {
  price = parseFloat(document.getElementById('price').value);
  let cash = parseFloat(document.getElementById('cash').value);

  if (isNaN(price) || isNaN(cash)) {
    alert("Please enter valid numbers for price and cash.");
    return;
  }

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

  if (cash === price) {
    document.getElementById('change-due').innerHTML = "No change due - customer paid with exact cash";
    return;
  }

  let changeDue = cash - price;
  let changeArray = getChange(changeDue, cid);

  if (changeArray.status === "INSUFFICIENT_FUNDS") {
    document.getElementById('change-due').innerHTML = "Status: INSUFFICIENT_FUNDS";
  } else if (changeArray.status === "CLOSED") {
    document.getElementById('change-due').innerHTML = `Status: CLOSED ${formatChangeArray(changeArray.change)}`;
  } else {
    document.getElementById('change-due').innerHTML = `Status: OPEN ${formatChangeArray(changeArray.change)}`;
  }
});

function getTotalCid(cid) {
  return cid.reduce((acc, curr) => acc + curr[1], 0);
}

function getChange(changeDue, cid) {
  let changeArray = [];
  let totalCid = getTotalCid(cid);
  
  if (totalCid < changeDue) {
    return { status: "INSUFFICIENT_FUNDS", change: [] };
  }

  if (totalCid === changeDue) {
    return { status: "CLOSED", change: cid };
  }

  for (let i = cid.length - 1; i >= 0; i--) {
    let currencyName = cid[i][0];
    let currencyTotal = cid[i][1];
    let currencyValue = currencyUnit[currencyName];
    let amountNeeded = 0;

    while (changeDue >= currencyValue && currencyTotal > 0) {
      changeDue -= currencyValue;
      currencyTotal -= currencyValue;
      amountNeeded += currencyValue;
      changeDue = Math.round(changeDue * 100) / 100;
    }

    if (amountNeeded > 0) {
      changeArray.push([currencyName, amountNeeded]);
    }
  }

  if (changeDue > 0) {
    return { status: "INSUFFICIENT_FUNDS", change: [] };
  }

  return { status: "OPEN", change: changeArray };
}

function formatChangeArray(changeArray) {
  if (changeArray.length === 0) {
    return "";
  }
  return changeArray.map(item => `${item[0]}: $${formatAmount(item[1])}`).join(" ");
}

function formatAmount(amount) {
  if (amount % 1 === 0) {
    return amount.toString();
  } else if (amount * 10 % 1 === 0) {
    return amount.toFixed(1);
  } else {
    return amount.toFixed(2);
  }
}

/* file: styles.css */

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/17.4 Safari/605.1.15

Challenge Information:

Build a Cash Register Project - Build a Cash Register

hi there, your app doesn’t work without requiring that we enter the price.
The app is supposed to rely on the global price value only.

I didn’t understand. Do I need to give the option to the user to enter the price or not?

you can do that if you want but the tests need you to use the global price value they set.
So maybe you can write some logic that says that if the global variable price is not null, then use it, otherwise use the one given by the user. (and do not give any alert if the user doesn’t give you a value)

Thanks for that. Implemented it but still the last two cases are failing

can you post new code?

/ file: script.js /

**// Predefined variables for testing**

**let price = 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]];**

**// Currency unit values**

**let currencyUnit = {**

**"PENNY": 0.01,**

**"NICKEL": 0.05,**

**"DIME": 0.1,**

**"QUARTER": 0.25,**

**"ONE": 1,**

**"FIVE": 5,**

**"TEN": 10,**

**"TWENTY": 20,**

**"ONE HUNDRED": 100**

**};**

**document.getElementById('purchase-btn').addEventListener('click', function() {**

**let cash = Number(document.getElementById('cash').value);**

**if (isNaN(cash)) {**

**alert("Please enter valid numbers for price and cash.");**

**return;**

**}**

**if (cash < price) {**

**alert("Customer does not have enough money to purchase the item");**

**return;**

**}**

**if (cash === price) {**

**document.getElementById('change-due').innerHTML = "No change due - customer paid with exact cash";**

**return;**

**}**

**let changeDue = cash - price;**

**let changeArray = getChange(changeDue, cid);**

**if (changeArray.status === "INSUFFICIENT_FUNDS") {**

**document.getElementById('change-due').innerHTML = "Status: INSUFFICIENT_FUNDS";**

**} else if (changeArray.status === "CLOSED") {**

**document.getElementById('change-due').innerHTML = `Status: CLOSED ${formatChangeArray(changeArray.change)}`;**

**} else {**

**document.getElementById('change-due').innerHTML = `Status: OPEN ${formatChangeArray(changeArray.change)}`;**

**}**

**});**

**function getTotalCid(cid) {**

**return cid.reduce((acc, curr) => acc + curr[1], 0);**

**}**

**function getChange(changeDue, cid) {**

**let changeArray = [];**

**let totalCid = getTotalCid(cid);**

**if (totalCid < changeDue) {**

**return { status: "INSUFFICIENT_FUNDS", change: [] };**

**}**

**if (totalCid === changeDue) {**

**return { status: "CLOSED", change: cid };**

**}**

**for (let i = cid.length - 1; i >= 0; i--) {**

**let currencyName = cid[i][0];**

**let currencyTotal = cid[i][1];**

**let currencyValue = currencyUnit[currencyName];**

**let amountNeeded = 0;**

**while (changeDue >= currencyValue && currencyTotal > 0) {**

**changeDue -= currencyValue;**

**currencyTotal -= currencyValue;**

**amountNeeded += currencyValue;**

**changeDue = Math.round(changeDue * 100) / 100;**

**}**

**if (amountNeeded > 0) {**

**changeArray.push([currencyName, amountNeeded]);**

**}**

**}**

**if (changeDue > 0) {**

**return { status: "INSUFFICIENT_FUNDS", change: [] };**

**}**

**return { status: "OPEN", change: changeArray };**

**}**

**function formatChangeArray(changeArray) {**

**if (changeArray.length === 0) {**

**return "";**

**}**

**return changeArray.map(item => `${item[0]}: $${formatAmount(item[1])}`).join(" ");**

**}**

**function formatAmount(amount) {**

**if (amount % 1 === 0) {**

**return amount.toString();**

**} else if (amount * 10 % 1 === 0) {**

**return amount.toFixed(1);**

**} else {**

**return amount.toFixed(2);**

**}**

**}**

I’ve edited your code for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

hi, please post again as the code is not usable with all the ** everywhere

/* file: script.js */
// Predefined variables for testing
let price = 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]];


// Currency unit values
let currencyUnit = {
  "PENNY": 0.01,
  "NICKEL": 0.05,
  "DIME": 0.1,
  "QUARTER": 0.25,
  "ONE": 1,
  "FIVE": 5,
  "TEN": 10,
  "TWENTY": 20,
  "ONE HUNDRED": 100
};


document.getElementById('purchase-btn').addEventListener('click', function() {

  let cash = Number(document.getElementById('cash').value);


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

  if (cash === price) {
    document.getElementById('change-due').innerHTML = "No change due - customer paid with exact cash";
    return;
  }

  let changeDue = cash - price;
  let changeArray = getChange(changeDue, cid);

  if (changeArray.status === "INSUFFICIENT_FUNDS") {
    document.getElementById('change-due').innerHTML = "Status: INSUFFICIENT_FUNDS";
  } else if (changeArray.status === "CLOSED") {
    document.getElementById('change-due').innerHTML = `Status: CLOSED ${formatChangeArray(changeArray.change)}`;
  } else {
    document.getElementById('change-due').innerHTML = `Status: OPEN ${formatChangeArray(changeArray.change)}`;
  }
});

function getTotalCid(cid) {
  return cid.reduce((acc, curr) => acc + curr[1], 0);
}

function getChange(changeDue, cid) {
  let changeArray = [];
  let totalCid = getTotalCid(cid);
  
  if (totalCid < changeDue) {
    return { status: "INSUFFICIENT_FUNDS", change: [] };
  }

  if (totalCid === changeDue) {
   
     return { status: "CLOSED", change: cid };
  }

    

  for (let i = cid.length - 1; i >= 0; i--) {
    let currencyName = cid[i][0];
    let currencyTotal = cid[i][1];
    let currencyValue = currencyUnit[currencyName];
    let amountNeeded = 0;

    while (changeDue >= currencyValue && currencyTotal > 0) {
      changeDue -= currencyValue;
      currencyTotal -= currencyValue;
      amountNeeded += currencyValue;
      changeDue = Math.round(changeDue * 100) / 100;
    }

    if (amountNeeded > 0) {
      changeArray.push([currencyName, amountNeeded]);
    }
  }

  if (changeDue > 0) {
    return { status: "INSUFFICIENT_FUNDS", change: [] };
  }
  

  return { status: "OPEN", change: changeArray };
}

function formatChangeArray(changeArray) {
  if (changeArray.length === 0) {
    return "";
  }
  return changeArray.map(item => `${item[0]}: $${formatAmount(item[1])}`).join(" ");
}

function formatAmount(amount) {
  if (amount % 1 === 0) {
    return amount.toString();
  } else if (amount * 10 % 1 === 0) {
    return amount.toFixed(1);
  } else {
    return amount.toFixed(2);
  }
}

Hey @hbar1st , thanks for the help. I got it. The problem is with these lines:
if (totalCid === changeDue) {

 return { status: "CLOSED", change: cid };

}

For the last two cases but my initial problem solved because of your suggestion only

1 Like

just curious, why was the if a problem?