containers/Betslip/BetslipHandler.js

/* eslint-disable react/no-unused-state */

import { Component } from 'react';

import { SinglesMinMaxWinCalculator } from 'system-manager';
import Constants, { MINIMUM_MULTIPLE_ODDS_LENGTH, NO_BONUS } from '../../constants';
import { SystemMatches, SystemSplitManager, OddsByMatches } from '../../utils/systemManager';
import {
  setupCalc,
  newObjectRef,
  filterDuplicateSelections,
  convertIntoUnits,
} from '../../utils/common';

/**
 * Betslip handler functions
 *
 * @class
 */
class BetslipHandler extends Component {
  /**
   * Setup placebet settings calculate total stake, bonus, potential win (min/max)
   *
   * @function
   * @param {Array} singleStakes
   * @param {Array} combi
   * @param {number} multiple
   * @param {number} other
   * @returns {object} Settings (total stake, potential win (min/max), bonus amount)
   */
  setupPlacebet = (singleStakes, combi, multiple, other) => {
    const selectedType = this.props.selectedBetType;
    const systemManager = this.state.systemManager;
    const lastKey = this.props.numberOfSelections;
    const maxPotWin = this.state.maxPotWin;
    const minPotWin = this.state.minPotWin;
    const odds = this.props.odds;
    const combinations = this.props.combinations?.length > 0
      ? this.props.combinations : this.combinations;
    if (selectedType !== Constants.BET_TYPE.NO_BET) {
      switch (selectedType) {
        case Constants.BET_TYPE.SINGLE: {
          const singlesOdds = OddsByMatches(this.props.selectedOdds, singleStakes);
          const winnings = SinglesMinMaxWinCalculator(singlesOdds, this.props.winCap);
          const totalStake = singleStakes.reduce((accumulator, value) => (
            accumulator + Number(value)
          ), 0);

          return ({
            totalStake,
            potWinMax: convertIntoUnits(winnings.max),
            potWinMin: convertIntoUnits(winnings.min),
            bonusAmt: NO_BONUS,
          });
        }
        case Constants.BET_TYPE.MULTIPLE: {
          if (systemManager) {
            const percentage = systemManager[lastKey].BONUSPERCENTAGE;
            const potWinMax = maxPotWin[maxPotWin.length - 1];
            const rez = this.calcForStakes(
              multiple, potWinMax, potWinMax, null, systemManager[lastKey],
              this.props.betslipSettings.minStake, false,
            );
            return {
              ...rez,
              percentage,
            };
          }
          break;
        }
        case Constants.BET_TYPE.COMBINATION:
          return this.calcForStakes(
            combi, maxPotWin, minPotWin, combinations,
            systemManager, this.props.betslipSettings.minStakePerSelection, true,
          );
        case Constants.BET_TYPE.FREEBET: {
          if (systemManager) {
            const potWin = odds.map((o) => o.odd);
            const potWinMax = systemManager[lastKey]
              ? systemManager[lastKey].POTWINMAX : potWin;
            const potWinMin = systemManager[lastKey]
              ? systemManager[lastKey].POTWINMIN : potWin;
            const bonusAmt = systemManager[lastKey]
              ? systemManager[lastKey].BONUSMAX * other
              : null;
            const percentage = systemManager[lastKey]
              ? systemManager[lastKey].BONUSPERCENTAGE
              : null;
            return ({
              potWinMax: (potWinMax - 1) * other,
              potWinMin: (potWinMin - 1) * other,
              minStake: this.props.betslipSettings.minStake,
              bonusAmt,
              percentage,
            });
          }
          break;
        }
        default:
          return this.calcForStakes(
            other, maxPotWin, minPotWin, combinations[1],
            systemManager, this.props.betslipSettings.minStakePerSelection, false,
          );
      }
    }
    return this.setup;
  }

  /**
   * Calculate settings for selected bet type
   *
   * @function
   * @param {number|Array} stake
   * @param {number|Array} bonusOddMax
   * @param {number|Array} bonusOddMin
   * @param {number|null|Array} numOfBets
   * @param {object|null} manager
   * @param {number} minStake
   * @param {boolean} isArray
   * @returns {object} Settings (total stake, potential win (min/max), bonus amount)
   */
  calcForStakes = (stake, bonusOddMax, bonusOddMin, numOfBets, manager, minStake, isArray) => {
    let calc = newObjectRef(this.setup);
    if (isArray) {
      for (let i = 0; i < stake.length; i += 1) {
        calc = setupCalc(
          calc, stake[i], bonusOddMax[i], bonusOddMin[i],
          numOfBets && numOfBets[i], manager && manager[i + 1], minStake,
        );
      }
    } else {
      calc = setupCalc(calc, stake, bonusOddMax, bonusOddMin, numOfBets, manager, minStake);
    }
    return {
      ...calc,
      minStake,
    };
  }

  /**
   * Change stake value
   *
   * @function
   * @param {numer} val
   * @returns {void}
   */
  updateStakeValue = (val) => {
    const value = val <= this.props.betslipSettings.maxStake
      ? val
      : this.props.betslipSettings.maxStake;
    const {
      singleStakes, combiStakes,
    } = this.props;
    const selectedBetType = this.props.selectedBetType;
    let multipleStake = this.props.multipleStake;
    let otherStake = this.props.otherStake;
    if (selectedBetType === Constants.BET_TYPE.SINGLE) {
      singleStakes[this.state.stakeInFocus] = value || '';
    } else if (selectedBetType === Constants.BET_TYPE.COMBINATION) {
      combiStakes[this.state.stakeInFocus] = value || '';
    } else if (selectedBetType === Constants.BET_TYPE.MULTIPLE) {
      multipleStake = value || '';
    } else {
      otherStake = value || '';
    }
    this.props.setStakes({
      singleStakes,
      multipleStake,
      combiStakes,
      otherStake,
    });

    const settings = this.setupPlacebet(singleStakes, combiStakes, multipleStake, otherStake);

    this.setState({
      settings,
      rerender: !this.state.rerender,
      stakeHasChanges: true,
      maxPotWinPayoutErr: this.checkMaximumWinningPayoutErr(settings.potWinMax),
    });
  }

  /**
   * Change stake value
   *
   * @function
   * @returns {void}
   */
  updateCalc = () => {
    const {
      singleStakes, combiStakes,
    } = this.props;
    const multipleStake = this.props.multipleStake;
    const otherStake = this.props.otherStake;
    this.props.setStakes({
      singleStakes,
      multipleStake,
      combiStakes,
      otherStake,
    });

    const settings = this.setupPlacebet(singleStakes, combiStakes, multipleStake, otherStake);

    this.setState({
      settings,
      rerender: !this.state.rerender,
      stakeHasChanges: true,
      maxPotWinPayoutErr: this.checkMaximumWinningPayoutErr(settings.potWinMax),
    });
  }

  /**
   * Change stake value inserted in input
   *
   * @function
   * @param {Event} e
   * @returns {void}
   */
  changeStakeInput = (e) => {
    let stake = e && e.target.value;
    stake = stake === 0 || stake === '' ? 0 : parseInt(stake.split(',').join(''));
    if ((this.props.selectedBetType !== Constants.BET_TYPE.FREEBET
      && stake) || stake === 0) {
      const value = stake > 0 ? stake : 0;
      // eslint-disable-next-line no-restricted-globals
      if (!isNaN(value)) {
        this.updateStakeValue(value);
      } else {
        this.updateStakeValue(0);
      }
    }
  }

  /**
   * Change stake value by clicking on stake buttons
   *
   * @function
   * @param {Event} e
   * @returns {void}
   */
  addButton = (e) => {
    const selectedType = this.props.selectedBetType;
    const value = e.target.id;
    if (selectedType === Constants.BET_TYPE.FREEBET) {
      this.updateStakeValue(parseInt(value));
    } else {
      const newState = selectedType === Constants.BET_TYPE.SINGLE
        ? this.props.singleStakes[this.state.stakeInFocus] || 0
        : selectedType === Constants.BET_TYPE.MULTIPLE
          ? this.props.multipleStake || 0
          : selectedType === Constants.BET_TYPE.COMBINATION
            ? this.props.combiStakes[this.state.stakeInFocus] || 0
            : this.props.otherStake || 0;
      this.updateStakeValue(parseInt(newState) + parseInt(value));
    }
  }

  /**
   * Change stake value to 0
   *
   * @function
   * @returns {void}
   */
  clearStake = () => {
    this.updateStakeValue(0);
  }

  /**
   * Initialize split bet tab
   *
   * @function
   * @param {number} num
   * @param {number} numOfSplitBets
   * @returns {void}
   */
  initSplitBetTab = (num, numOfSplitBets) => {
    this.combinationTypes = [];
    this.combinations = [num, numOfSplitBets];
    this.combinationTypes.push(`${num < 4 ? Constants.DIGITS[num - 1] : `${Constants.DIGITS[num - 1]} Folds`} (${numOfSplitBets})`);
  }

  /**
   * Initialize combination bet tab
   *
   * @function
   * @param {object} systemManager
   * @param {boolean} isDeleting
   * @returns {object} Odds (min/max), potential win (min/max)
   */
  initSystemTab = (systemManager, isDeleting) => {
    const maxOdd = [];
    const minOdd = [];
    const maxPotWin = [];
    const minPotWin = [];
    this.combinationTypes = [];
    this.combinations = [];
    let combiStakes = this.props.combiStakes || [];
    let singleStakes = this.props.singleStakes || [];
    let multipleStake = this.props.multipleStake || '';
    let otherStake = this.props.otherStake || '';
    for (let i = 0, j = 1; i < this.props.numberOfSelections; i += 1, j += 1) {
      const {
        POTWINMAX, POTWINMIN, ODDMAX, ODDMIN, NUM,
      } = systemManager[j];
      this.combinationTypes.push(`${i < 3 ? Constants.DIGITS[i] : `${Constants.DIGITS[i]} Folds`} (${NUM})`);
      this.combinations.push(NUM);
      maxOdd.push(ODDMAX);
      minOdd.push(ODDMIN);
      maxPotWin.push(POTWINMAX);
      minPotWin.push(POTWINMIN);
      if (isDeleting || this.props.placebetAfterLogin) {
        combiStakes = [];
        singleStakes = [];
        multipleStake = '';
        otherStake = '';
        this.setState({
          maxPotWin: [],
          minPotWin: [],
          settings: {
            totalStake: 0,
            potWinMax: 0,
            potWinMin: 0,
            bonusAmt: 0,
          },
        });
      }
    }
    if (this.props.placebetBackupLogin !== true) {
      this.props.setStakes({
        multipleStake,
        combiStakes,
        singleStakes,
        otherStake,
      });
    }

    return {
      minOdd, maxOdd, maxPotWin, minPotWin,
    };
  }

  /**
   * Change tab from bottom navigation
   *
   * @function
   * @param {string} [betType]
   * @param {boolean} [isDeleting]
   * @returns {void}
   */
  changeBetType = (betType, isDeleting) => {
    const propOdds = this.props.odds;
    if (this.props.numberOfSelections === 0) {
      this.props.setSelectedBetType({
        selectedBetType: Constants.BET_TYPE.NO_BET,
      });
    } else {
      const { numOfMatchesForSys, oddsPerMatch } = SystemMatches(propOdds);
      if (numOfMatchesForSys === 1
        && betType !== Constants.BET_TYPE.FREEBET) {
        this.props.setSelectedBetType({
          selectedBetType: Constants.BET_TYPE.SINGLE,
        });
      } else if (numOfMatchesForSys === this.props.numberOfSelections
        && parseInt(this.props.numberOfSelections) > 0) {
        const odds = propOdds.map((o) => o.odd);
        const systemManager = SystemSplitManager(
          odds,
          this.props.bonusPercentages,
          this.props.bonusOddsThreshold,
          false,
          this.props.winCap,
        );
        const selectedType = betType && betType !== Constants.BET_TYPE.SPLIT_COLUMN
          && betType !== Constants.BET_TYPE.NO_BET
          ? betType : Constants.BET_TYPE.MULTIPLE;
        const {
          minOdd, maxOdd, minPotWin, maxPotWin,
        } = this.initSystemTab(systemManager, isDeleting);
        this.props.setSelectedBetType({
          selectedBetType: selectedType,
        });
        this.setState({
          minOdd,
          maxOdd,
          maxPotWin,
          minPotWin,
          stakeInFocus: 0,
          systemManager,
        });
      } else {
        const splitManager = SystemSplitManager(
          oddsPerMatch,
          this.props.bonusPercentages,
          this.props.bonusOddsThreshold,
          true,
          this.props.winCap,
        );
        const selectedType = betType && betType !== Constants.BET_TYPE.NO_BET
          ? betType : Constants.BET_TYPE.SPLIT_COLUMN;
        for (let i = 0; i < this.props.combiStakes.length; i += 1) {
          this.props.combiStakes[i] = '';
        }
        this.props.setSelectedBetType({
          selectedBetType: selectedType,
        });
        this.initSplitBetTab(numOfMatchesForSys, splitManager.NUM);
        this.setState({
          numOfMatchesForSys,
          numOfSplitBets: splitManager.NUM,
          minOdd: [splitManager.ODDMIN],
          maxOdd: [splitManager.ODDMAX],
          maxPotWin: [splitManager.POTWINMAX],
          minPotWin: [splitManager.POTWINMIN],
          stakeInFocus: 0,
          systemManager: splitManager,
        });
      }
    }
  }

  /**
   * Parse stake string for placebet API
   *
   * @function
   * @returns {object} Stake, bet type, and free bet id if it is free bet
   */
  parsePlacebetStake = () => {
    const selectedType = this.props.selectedBetType;
    const combinations = this.props.prevCombinations?.length > 0
      ? this.props.prevCombinations : this.combinations;
    let type;
    let stake = '';
    let selectedStake = null;
    let freeBetId = null;
    switch (selectedType) {
      case Constants.BET_TYPE.FREEBET: {
        stake = this.props.otherStake * 100;
        freeBetId = this.props.freeBets.find((bet) => (
          parseInt(bet.stake / 100) === this.props.otherStake)).id;
        if (this.props.numberOfSelections === 1) {
          type = Constants.BET_TYPE_VALUES.SINGLE;
          stake = `1:${stake}&T:${stake}`;
        } else {
          type = Constants.BET_TYPE_VALUES.MULTIPLE;
        }
        break;
      }
      case Constants.BET_TYPE.SINGLE: {
        selectedStake = this.props.singleStakes;
        type = Constants.BET_TYPE_VALUES.SINGLE;
        break;
      }
      case Constants.BET_TYPE.MULTIPLE: {
        stake = this.props.multipleStake * 100;
        type = Constants.BET_TYPE_VALUES.MULTIPLE;
        break;
      }
      case Constants.BET_TYPE.SPLIT_COLUMN: {
        stake = `${combinations[0]}:${this.props.otherStake * 100}&T:${this.props.otherStake * 100 * combinations[1]}`;
        type = Constants.BET_TYPE_VALUES.SPLIT_COLUMN;
        break;
      }
      default: {
        selectedStake = this.props.combiStakes;
        type = Constants.BET_TYPE_VALUES.COMBINATION;
      }
    }
    if (selectedStake) {
      for (let s = 0; s < selectedStake.length; s += 1) {
        if (selectedStake[s]) { stake += `${s + 1}:${selectedStake[s] * 100}&`; }
      }
      stake += `T:${this.state.settings.totalStake * 100}`;
    }
    return {
      stake, type, freeBetId,
    };
  }

  /**
   * Validate max stakes before placebet
   *
   * @function
   * @returns {boolean}
   */
  checkMaxStakeError = () => {
    if (this.props.selectedBetType === Constants.BET_TYPE.SINGLE
      || this.props.selectedBetType === Constants.BET_TYPE.COMBINATION
      || this.props.selectedBetType === Constants.BET_TYPE.SPLIT_COLUMN) {
      return this.state.settings.totalStake > this.props.betslipSettings.maxStake;
    }
    return false;
  }

  /**
   * Validate min stakes before placebet
   *
   * @function
   * @returns {boolean}
   */
  checkMinStakeError = () => {
    let flag = true;
    switch (this.props.selectedBetType) {
      case Constants.BET_TYPE.SINGLE:
        return this.props.singleStakes.findIndex((stake) => {
          if (stake) flag = false;
          return parseInt(stake) < this.props.betslipSettings.minStake;
        }) !== -1 || flag;
      case Constants.BET_TYPE.COMBINATION:
        return this.props.combiStakes.findIndex((stake) => {
          if (stake) flag = false;
          return parseInt(stake) < this.props.betslipSettings.minStakePerSelection;
        }) !== -1 || flag;
      case Constants.BET_TYPE.MULTIPLE:
        return !this.props.multipleStake
          || parseInt(this.props.multipleStake) < this.props.betslipSettings.minStake;
      case Constants.BET_TYPE.FREEBET:
      case Constants.BET_TYPE.SPLIT_COLUMN:
        return !this.props.otherStake
          || parseInt(this.props.otherStake) < this.props.betslipSettings.minStakePerSelection;
      default:
        return false;
    }
  }

  /**
   * Validate maximum winning payout before placebet
   *
   * @function
   * @param {number} potWinMax
   * @returns {boolean}
   */
  checkMaximumWinningPayoutErr = (potWinMax) => {
    const win = potWinMax || this.state.settings.potWinMax;
    return win > (this.props.winCap / 100);
  };

  /**
   * Validate inputs fields before placebet action
   *
   * @function
   * @returns {boolean}
   */
  checkError = () => ({
    minStakeErr: this.checkMinStakeError(),
    maxStakeErr: this.checkMaxStakeError(),
    maxPotWinPayoutErr: this.checkMaximumWinningPayoutErr(null),
  });

  /**
   * Select single bet type from bottom navigation
   *
   * @function
   * @returns {void}
   */
  selectSingleBet = () => {
    if (this.props.selectedBetType !== Constants.BET_TYPE.NO_BET) {
      this.props.setSelectedBetType({ selectedBetType: Constants.BET_TYPE.SINGLE });
      this.setState({
        stakeInFocus: 0,
      });
    }
    this.changeBetType(Constants.BET_TYPE.SINGLE);
  }

  /**
   * Select multiple bet type from bottom navigation
   *
   * @function
   * @returns {void}
   */
  selectMultipleBet = () => {
    if ((this.props.selectedBetType !== Constants.BET_TYPE.NO_BET
      && this.props.selectedOdds?.length >= MINIMUM_MULTIPLE_ODDS_LENGTH)) {
      this.props.setSelectedBetType({ selectedBetType: Constants.BET_TYPE.MULTIPLE });
    }
    this.changeBetType(Constants.BET_TYPE.MULTIPLE);
  }

  /**
   * Select combination bet type from bottom navigation (Can be combinations or split bet)
   *
   * @function
   * @returns {void}
   */
  openOtherTypes = () => {
    const type = this.props.selectedBetType;
    if (type !== Constants.BET_TYPE.NO_BET) {
      const uniqueSelectedOddsArr = filterDuplicateSelections(this.props.selectedOdds);
      const newSelectedType = uniqueSelectedOddsArr.length !== this.props.selectedOdds.length
        ? Constants.BET_TYPE.SPLIT_COLUMN
        : Constants.BET_TYPE.COMBINATION;
      this.props.setSelectedBetType({
        selectedBetType: newSelectedType,
      });
      this.setState({
        stakeInFocus: 0,
      });
    }
  }

  /**
   * Select free bet dtype from bottom navigation
   *
   * @function
   * @returns {void}
   */
  openFreeBetType = () => {
    if ((this.props.selectedBetType !== Constants.BET_TYPE.NO_BET
      && this.props.selectedBetType !== Constants.BET_TYPE.SPLIT_COLUMN)) {
      this.props.setSelectedBetType({ selectedBetType: Constants.BET_TYPE.FREEBET });
      this.setState({
        stakeInFocus: 0,
      });
    }
  }

  /**
   * Return first 5 bets amount
   *
   * @function
   * @returns {Array}
   */
  getFreeBetsAmount = () => {
    const freeBetsAmounts = [];
    this.props.freeBets.map((bet) => {
      const stake = parseInt(bet.stake / 100);
      if (freeBetsAmounts.findIndex((b) => b === stake) === -1 && freeBetsAmounts.length < 5) {
        freeBetsAmounts.push(stake);
      }
    });
    freeBetsAmounts.sort((a, b) => (a > b ? 1 : -1));

    return freeBetsAmounts;
  }

  /**
   * Set input in focus by input index
   *
   * @function
   * @param {number} index
   * @returns {void}
   */
  setInputInFocus = (index) => {
    this.tid1 = setTimeout(() => {
      this.setState({
        stakeInFocus: index,
        showButtons: true,
      });
    }, 100);

    if (this.state.error === true || this.props.placeBetErrorMgs) {
      this.closeError();
    }
  }

  /**
   * Set input out of focus and hide buttons
   *
   * @function
   * @param {Event} e
   * @returns {void}
   */
  setInputOutOfFocus = (e) => {
    if (e) {
      const targetIsButton = e.relatedTarget != null && e.relatedTarget.classList.contains('chip-button');
      if ((!targetIsButton) || e.relatedTarget === null) {
        this.tid2 = setTimeout(() => {
          this.setState({ showButtons: false });
        }, 100);
      } else if (targetIsButton) {
        e.target.focus();
      }
    }
  }

  /**
   * Clear all timeouts
   *
   * @function
   * @returns {void}
   */
  clearAllTimeouts = () => {
    clearTimeout(this.tid1);
    clearTimeout(this.tid2);
  }

  /**
   * Clear all selections
   *
   * @function
   * @returns {void}
   */
  clearAllSelections = () => {
    this.props.toggleSelectedOdds({ selectedOdds: [], index: null });
    this.props.clearAllSelections();
  }

  /**
   * Clear selected row
   *
   * @function
   * @param {number} index
   * @returns {void}
   */
  clearSelection = (index) => {
    const odds = this.props.odds;
    if (odds.length > 1) {
      const selectedOdds = Array.from(odds);
      selectedOdds.splice(index, 1);
      this.props.toggleSelectedOdds({ selectedOdds, index });
    } else {
      this.clearAllSelections();
    }
    this.updateStakeValue(0);
    this.setState({
      stakeInFocus: 0,
      settings: {
        totalStake: 0,
        potWinMax: 0,
        potWinMin: 0,
        bonusAmt: 0,
      },
    });
    this.props.setStakes({
      singleStakes: [],
      multipleStake: '',
      combiStakes: [],
      otherStake: '',
    });
  }

  /**
   * Close error modal
   *
   * @function
   * @returns {void}
   */
  closeError = () => {
    this.setState({
      minStakeErr: false,
      maxStakeErr: false,
      maxPotWinPayoutErr: false,
    });
    this.props.closePlaceBetErrorMessage();
  }

  /**
   * Close confirmation modal
   *
   * @function
   * @returns {void}
   */
  closeSlipConfirmation = () => {
    this.setState({ openNewPlacedBetsModal: true });
    this.props.closeSlipConfirmation();
    /* if in freebets and no free bets */
    if (this.props.freeBets.length === 0
      && this.props.selectedBetType === Constants.BET_TYPE.FREEBET) {
      if (this.props.numberOfSelections === 1) {
        this.props.setSelectedBetType({ selectedBetType: Constants.BET_TYPE.SINGLE });
      } else {
        this.props.setSelectedBetType({ selectedBetType: Constants.BET_TYPE.MULTIPLE });
      }
    }
  }

  /**
   * Toggle betslip modal
   *
   * @function
   * @returns {void}
   */
  toggleBetslipModal = () => {
    if (this.props.betSlipConfimation) {
      this.clearAllSelections();
    } else {
      this.props.toggleBetslip();
    }
  }

  /**
   * Place bet action
   *
   * @function
   * @returns {void}
   */
  placebet = () => {
    const propOdds = this.props.odds;
    const { minStakeErr, maxStakeErr, maxPotWinPayoutErr } = this.checkError();
    if (minStakeErr === false && maxStakeErr === false) {
      const odds = propOdds.map((odd) => `${odd.league}:${odd.matchId + 1}:${odd.selectionId}`).join('$');
      const placedSelection = propOdds.map((odd) => `${odd.league}:${odd.matchId + 1}:${odd.selectionId}:${odd.odd}`);
      const payload = this.parsePlacebetStake();
      const maxPotWin = Math.round(this.state.settings.potWinMax * 100 + 0.0001).toFixed(0);

      let cappedMaxPotWin = parseInt(maxPotWin) > this.props.winCap
        ? this.props.winCap.toFixed(0) : maxPotWin;

      // handle case when win is super big and contains e+. example 1.5623e+22
      if (typeof cappedMaxPotWin === 'string' && cappedMaxPotWin.indexOf('e+') !== -1) {
        cappedMaxPotWin = this.props.winCap.toFixed(0);
      }

      if (!this.props.user && this.props.selectedBetType) {
        this.props.setSelectedBetType({
          selectedBetType: this.props.selectedBetType,
        });
        this.props.setBackUpLoginProps({
          selectedOdds: this.props.selectedOdds,
          stakes: {
            multipleStake: this.props.multipleStake,
            combiStakes: this.props.combiStakes,
            singleStakes: this.props.singleStakes,
          },
          numberOfSelections: this.props.numberOfSelections,
          placebetPayload: payload,
          prevCombinationTypes: this.combinationTypes,
          prevCombinations: this.combinations,
        });
      }
      this.props.placebetRequest({
        odds,
        placedSelection,
        maxPotWin: cappedMaxPotWin,
        roundId: this.props.roundId,
        ...payload,
      });
      this.setState({
        minStakeErr: false,
        maxStakeErr: false,
        stakeHasChanges: false,
      });
    } else {
      this.setState({
        minStakeErr,
        maxStakeErr,
        maxPotWinPayoutErr,
      });
    }
  }
}
export default BetslipHandler;