Build a Cash Register Project

Okay, so currently I’ve gotten to the point where when I handle each of the example tests individually by testing each cid and price test, they work, but it’s also causing the other tests where the test values are different to fail. I’m not sure what’s the cause for it. (I haven’t cleaned the code up yet from all the console logs.)

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

const currencyIndex = [
  ['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]
]; 

const floatPrecision = number => parseFloat((number).toFixed(2));

const cashInput = document.getElementById('cash');
const purchaseBtn = document.getElementById('purchase-btn');

cashInput.addEventListener("keydown", (e) => {
  if (e.key === "Enter"){
    const cash = cashInput.value;
    checkCashInput(cash);
  }
})

const checkCashInput = cash => {
    if (!cash){
      return;
    } else {
      register.updateChangeDisplay(floatPrecision(Number(cash)));  
    }
  }

purchaseBtn.addEventListener("click", () => {
  const cash = cashInput.value;
  checkCashInput(cash);
});



class CashRegister{
  constructor(changeArr){
    
    // Data Attributes
    this.change = changeArr;
    this.difference;
    this.totalChange = parseFloat(this.change.reduce((acc, el) => acc + el[1], 0).toFixed(2));

    // Display of change in drawer.
    this.changeDisplayContent = `
      <p><strong>Change in Drawer:</strong></p>
      <p>Pennies: $${this.change[0][1]}</p>
      <p>Nickels: $${this.change[1][1]}</p>
      <p>Dimes: $${this.change[2][1]}</p>
      <p>Quarters: $${this.change[3][1]}</p>
      <p>Ones: $${this.change[4][1]}</p>
      <p>Fives: $${this.change[5][1]}</p>
      <p>Tens: $${this.change[6][1]}</p>
      <p>Twenties: $${this.change[7][1]}</p>
      <p>Hundreds: $${this.change[8][1]}</p>
    `;

    // DOM Attributes
    this.priceDisplay = document.getElementById('price');
    this.changeInRegister = document.getElementById('change-in-register');
    this.statusDisplay = document.getElementById('change-due');

    // DOM Initializations
    this.priceDisplay.textContent = `$${price}`;
    this.changeInRegister.innerHTML = this.changeDisplayContent;
    this.changeDue = ``;
  }

    // DOM Methods
  showPrice(){
    priceDisplay.textContent = `$${price}`;
  }
  // Updates the Amount of Change in the Drawer Display.
  updateChangeinDrawer(){
    this.changeInRegister.innerHTML = `
      <p><strong>Change in Drawer:</strong></p>
      <p>Pennies: $${this.change[0][1]}</p>
      <p>Nickels: $${this.change[1][1]}</p>
      <p>Dimes: $${this.change[2][1]}</p>
      <p>Quarters: $${this.change[3][1]}</p>
      <p>Ones: $${this.change[4][1]}</p>
      <p>Fives: $${this.change[5][1]}</p>
      <p>Tens: $${this.change[6][1]}</p>
      <p>Twenties: $${this.change[7][1]}</p>
      <p>Hundreds: $${this.change[8][1]}</p>
    `;
    
  }

  // Update Change Values
  updateChangeValues(change){
    this.changeDue = ``;
    console.log("Change to count: ", change);

    // Locate the highest unit that is lower or equal to the change due.
    let startingIndex = currencyIndex.length - 1;
    while (change < currencyIndex[startingIndex][1]){
      startingIndex -= 1;
    }

    // Overall sum of change obtained from cash register drawer.
    let totalSum = 0;
    console.log("Total sum so far: ", totalSum);
    console.log("Starting Index ID: ", this.change[startingIndex][0]);
    console.log("Starting loop...");
    for (let i = startingIndex; i >= 0; i--){
      console.log("Looping.");
      let changeToTakeFromUnit = 0; // Note: Within the loop.
      console.log("CURRENT INDEX: ", currencyIndex[i][0]);
      console.log("Initial Change to take: ", changeToTakeFromUnit);

      console.log("Initial Change plus additional unit: ", floatPrecision(changeToTakeFromUnit + currencyIndex[i][1]));
      console.log(`Amount of ${this.change[i][0]} in drawer: ${this.change[i][1]}`);
      console.log("Total Sum so far initially: ", totalSum);
      while (floatPrecision(changeToTakeFromUnit + currencyIndex[i][1]) <= this.change[i][1] && floatPrecision(changeToTakeFromUnit + currencyIndex[i][1] + totalSum) <= change){
        changeToTakeFromUnit = floatPrecision(changeToTakeFromUnit + currencyIndex[i][1]);
        console.log("Checking--");
        console.log(`Change to take from ${currencyIndex[i][0]}: ${changeToTakeFromUnit}`);
        console.log("Current Change By Unit plus additional unit: ", floatPrecision(changeToTakeFromUnit + currencyIndex[i][1]));
        console.log(`Amount of ${this.change[i][0]} in drawer: ${this.change[i][1]}`);
        console.log("Current change to take + total sum:",floatPrecision(changeToTakeFromUnit + totalSum));
        console.log("REMINDER - Change: ", change);
      } 
      
      console.log(`Final change to take from ${currencyIndex[i][0]}: ${changeToTakeFromUnit}`);
      console.log(`${this.change[i][0]} in drawer before: ${this.change[i][1]}`);
      this.change[i][1] = floatPrecision(this.change[i][1] - changeToTakeFromUnit);
      console.log(`${this.change[i][0]} in drawer now: ${this.change[i][1]}`);

      totalSum = floatPrecision(totalSum + changeToTakeFromUnit);
      console.log("Total Sum so far after change: ", totalSum);

      console.log("Total change left: ", floatPrecision(change - totalSum));
      if (changeToTakeFromUnit !== 0){
        this.changeDue += `<p>${this.change[i][0]}: $${changeToTakeFromUnit}</p>`;
      }
    }

    cid = this.change;
    this.updateChangeinDrawer();
    this.totalChange = this.change.reduce((acc, el) => acc + el[1], 0);
    console.log("Total Change in drawer after transaction: ", this.totalChange);
  }

  // Checks if the amount of change is enough to pay the EXACT amount.
  isEnoughChangeinDrawer(changeDue){

    let currentSum = 0;

    // Finds the highest unit lower than the change value.
    let startingIndex = currencyIndex.length - 1;
    while (changeDue < currencyIndex[startingIndex][1]){
      startingIndex -= 1;
    }

    for (let i = startingIndex; i >= 0 ;i--){
      let currentValueInDrawer = this.change[i][1];
      const currencyIndexValue = currencyIndex[i][1];

      while (floatPrecision(currentSum + currencyIndexValue) <= changeDue && floatPrecision(currentValueInDrawer - currencyIndexValue) >= 0){
        currentSum = floatPrecision(currentSum + currencyIndexValue);
        currentValueInDrawer = floatPrecision(currentValueInDrawer - currencyIndexValue);
      }
    }
    if (currentSum !== changeDue){
      return false; 
    }else {
      return true;
    }
    
  } 
  updateChangeDisplay(cashValue){
    if (cashValue < price){
      alert("Customer does not have enough money to purchase the item");
    } else{ 
    
      if (cashValue === price){
        this.statusDisplay.innerHTML = "<p>No change due - customer paid with exact cash</p>";
      } else {
          this.difference = floatPrecision(cashValue - price);

        if (cashValue > price && !this.isEnoughChangeinDrawer(this.difference)){
          console.log("INSUFFICIENT.");
          this.statusDisplay.innerHTML = "<p>Status: INSUFFICIENT_FUNDS</p>";
        } else if (cashValue > price && this.isEnoughChangeinDrawer(this.difference)){
          this.changeDue = "";
          this.updateChangeValues(parseFloat(this.difference.toFixed(2)));
          
          if (this.totalChange === 0){  
            this.statusDisplay.innerHTML = `<p>Status: CLOSED </p>`;
          } else {
            this.statusDisplay.innerHTML = `<p>Status: OPEN </p>`;
          }
          
          
          this.statusDisplay.innerHTML += this.changeDue;
        }
      }
    }
  }
}

const register = new CashRegister(cid);


  
  

What happens when cid changes during testing?

Like literally during testing as cid changes as change is removed from the drawer or when I adjust the cid values before testing the program?

Every test uses a different cid value. The tests run back to back after updating the cid variable.

Ah…I see. I just checked the console for how the tests are done. I see now.

Got it! Solution works now. Thanks for the help.

1 Like

Also, to anyone who sees this post wondering about what’s going on, what’s happening in the code is that the cid is changed mid-test. It’s basically the equivalent of finishing a transaction and then taking change out or adding change into the drawer before going into the next transaction.

1 Like

It’s not changing cid inside of a single test. Cid is changed in between tests executing

2 Likes