Cash Register Solution

Hello there!

I would like to post here my solution to the cash register algorithm hoping for someone to give me some feedback.

This time I have placed a lot of verbose and kept a bunch o console logs for whoever wants to see how the function builds upon every call.

I left comments as well in the code.

Thanks in advance =)

function checkCashRegister(price, cash, cid) {
    const currencyRef = [
      ["PENNY", 0.01],
      ["NICKEL", 0.05],
      ["DIME", 0.1],
      ["QUARTER", 0.25],
      ["ONE", 1],
      ["FIVE", 5],
      ["TEN", 10],
      ["TWENTY", 20],
      ["ONE HUNDRED", 100]
    ];
    //create an object to manage the register
    const managedStock = currencyRef.map(val => ({
      id: val[0],
      unitaryValue: val[1],
      stockValue: cid.find(stockItem => stockItem[0] === val[0])[1] / val[1],
      changeApplied: 0
    }));
    const change = (cash - price)
    const bankNoteFinder = (change, array, cidStatus) => {
      let fixedChange;
    //small hack to ensure that we will not get floating initial numbers  
      if (change.toString().match(/[0-9]{3,}/g)) {
        fixedChange = change.toFixed(2);
        console.log("fixed change", fixedChange);
      } else { fixedChange = change; }
      //if the change is not 0 exec logic
      if (fixedChange !== 0) {
        console.log("change", fixedChange);
        //check for the closest bank note / coin
        const closestBankNote = array.reduce((a, b) => {
          return {
            unitaryValue:
                b.unitaryValue > fixedChange ? a.unitaryValue : b.unitaryValue
          };
        });
        console.log("result of bank note finder", closestBankNote);
        //do we have funds for the closest bank note / coin?
        const closestBankNoteHasFunds =
          array.find(
            stock => stock.unitaryValue === closestBankNote.unitaryValue
          ).stockValue > 0;
        console.log("check if we have funds", closestBankNoteHasFunds);
        //in case we do not have funds for the given bank note / coin
        if (!closestBankNoteHasFunds) {
          //let´s slice the array of notes for the next recursion, excluding the note we tried to use
          const indexOfClosestBankNote = array.indexOf(
            array.find(v => v.unitaryValue === closestBankNote.unitaryValue)
          );
          //slice and call the recursion while the index is higher then 0
          if (indexOfClosestBankNote - 1 >= 0) {
            const slicedArrayForRecursion = array.slice(
              0,
              indexOfClosestBankNote
            );
            return bankNoteFinder(
              fixedChange,
              slicedArrayForRecursion,
              cidStatus
            );
         //stop slicing once we get to Index 0 and still have change to give   
          } else {
            cidStatus = { status: "INSUFFICIENT_FUNDS", change: [] };
          }
        }
        //if we have funds for the given bank note
        if (closestBankNoteHasFunds) {
          //how many notes do we need? 
          const numberOfNotesNeeded = Math.trunc(
            fixedChange / closestBankNote.unitaryValue
            );
          console.log("number of notes needed", numberOfNotesNeeded);
          //how many notes can we use?
          const howManyNotesAvailable = array.find(
            note => note.unitaryValue === closestBankNote.unitaryValue
          ).stockValue;
          //Oh, this is the amount of notes that will be used
          const amountOfNotesThatWillBeUsed =
            numberOfNotesNeeded > howManyNotesAvailable
              ? howManyNotesAvailable
              : numberOfNotesNeeded;
          console.log("amount of notes that will be used",amountOfNotesThatWillBeUsed);
         // get the desired note info and total deduction to prepare array of change 
          const getNeededNote = array.find(
            note => note.unitaryValue === closestBankNote.unitaryValue
          ); 
          const totalDedution = amountOfNotesThatWillBeUsed * getNeededNote.unitaryValue;
         //start building the array of the change 
          cidStatus.push([getNeededNote.id, totalDedution]);
          const noteToBeMutatedInstance = array.indexOf(
            array.find(note => note.id === getNeededNote.id)
          );
          //deduce the amount of available bank notes / coins and it´s total deduction 
          //from the total in the management control
          array[noteToBeMutatedInstance].stockValue = howManyNotesAvailable - amountOfNotesThatWillBeUsed;
          array[noteToBeMutatedInstance].changeApplied = totalDedution;
          return bankNoteFinder(fixedChange - totalDedution, array, cidStatus);
        }
      }
      //managed to give out all of the needed change
      if (fixedChange === 0) {
        console.log("change is ZERO!");
        console.log("we've used all of our money?", managedStock.every(note => note.stockValue === 0));
        //in case there is no money left in the register
        if (managedStock.every(note => note.stockValue === 0)) {
          cidStatus = {
            status: "CLOSED",
            change: [...managedStock.map(note => [note.id, note.changeApplied])]
          };
        }
        //in case there is still some money left
        if (managedStock.some(note => note.stockValue > 0)) {
          cidStatus = { status: "OPEN", change: [...cidStatus] };
        }
      }
      return cidStatus;
    };
    return bankNoteFinder(change, managedStock, [], {});
  }
  console.log( checkCashRegister(19.5, 20, [
      ["PENNY", 0.5],
      ["NICKEL", 0],
      ["DIME", 0],
      ["QUARTER", 0],
      ["ONE", 0],
      ["FIVE", 0],
      ["TEN", 0],
      ["TWENTY", 0],
      ["ONE HUNDRED", 0]
    ])
  );