sagas/settings.js

import { takeLatest, put, call, select } from 'redux-saga/effects';

import { requestGet, requestPost, requestPostFormData, requestGetDownloadedFile } from '../utils/request';
import { API_URLS, MODALS, SUCCESS_MODALS, STATUS_CODE_ERROR_MESSAGE, EXTRA_BETS_MARKET_IDS } from '../constants';

import {
  getOddsTemplatesPageToken,
  getOddsTemplateLastId,
  getOddsShopTemplateLastId,
  getOddsTemplate,
  getOddsShopTemplate,
  getStatsTemplateLastId,
  getStatsTemplate,
  getStatsTemplatesPageToken,
  getGoalGaloreSettings,
} from '../selectors/settings';
import { aSetHasRecord, aSetIsFetched, aSetLastRecord, aSetOpenModal } from '../reducers/common';
import {
  aDownloadOddsTemplatesFileSuccess,
  aForceTurboSuccess,
  aGetGamesSettings,
  aGetGamesSettingsSuccess,
  aGetGamesShopSettings,
  aGetGamesShopSettingsSuccess,
  aGetGoalGaloreMarginsSuccess,
  aGetGoalGaloreSettings,
  aGetGoalGaloreSuccess,
  aGetLeaguesSettings,
  aGetLeaguesSettingsSuccess,
  aGetMarketsMarginsSettingsSuccess,
  aGetMarketsSettings,
  aGetMarketsSettingsSuccess,
  aGetMarketsShopSettings,
  aGetMarketsShopSettingsSuccess,
  aGetRoundDurationSettings,
  aGetRoundDurationSettingsFail,
  aGetRoundDurationSettingsSuccess,
  aGetRoundSpecialMarginsSuccess,
  aGetRoundSpecialShopSettings,
  aGetRoundSpecialShopSettingsSuccess,
  aGetStatsTemplateSuccess,
  aGetTemplateExelListSuccess,
  aGetVideoActionSuccess,
  aOddsShopTemplateSuccess,
  aOddsTemplateSuccess,
  aOddsTemplatesFilesSuccess,
  aSaveMatchRoundDurationSettings,
  aSaveMatchRoundDurationSettingsSuccess,
  aStatsTemplatesFilesSuccess,
} from '../reducers/settings';
import {
  aForceTurbo,
  aGetDownloadTemplatesFile,
  aGetGoalGaloreMarginsSettings,
  aGetMarketsMargingSettings,
  aGetOddsTemplatesFiles,
  aGetRoundSpecialMarginsSettings,
  aGetStatsDownloadTemplatesFile,
  aGetStatsTemplate,
  aGetStatsTemplateExelList,
  aGetStatsTemplatesFiles,
  aGetStatsUploadTemplatesFile,
  aGetUploadTemplatesFile,
  aGetVideoAction,
  aOddsShopTemplate,
  aOddsShopTemplateExelList,
  aOddsTemplate,
  aOddsTemplateExelList,
  aSaveGamesSettings,
  aSaveGamesShopSettings,
  aSaveGoalGaloreMarginsSettings,
  aSaveGoalGaloreSettings,
  aSaveLeaguesSettings,
  aSaveMarketsMarginsSettings,
  aSaveMarketsSettings,
  aSaveMarketsShopSettings,
  aSaveNewOddsShopTemplate,
  aSaveNewOddsTemplate,
  aSaveNewStatsTemplate,
  aSaveRoundSpecialMarginsSettings,
  aSaveRoundSpecialShopSettings,
  aSaveVideoAction,
} from '../reducers/actions';

/**
 * @namespace sagas/settings
 */
/**
 * @memberof sagas/settings
 * @typedef Market
 * @type {object}
 * @property {number} id
 * @property {string} name
 * @property {number} status
 */
/**
 * @memberof sagas/settings
 * @typedef "getMarketsSettings/response.data"
 * @type {object}
 * @property {Array<Market>} markets
 */
/**
 * Get markets settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getMarketsSettings() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGet, API_URLS.MARKETS_SETTINGS, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetMarketsSettingsSuccess({
          marketsSettings: response.data.markets,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get goal galore settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getGoalGaloreSettingsRequest() {
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const response = yield call(requestGet, API_URLS.GOAL_GALORE_SETTINGS, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetGoalGaloreSuccess({
          goalGaloreSettings: response.data.markets,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get special round settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getRoundSpecialShopSettings() {
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const response = yield call(requestGet, API_URLS.ROUND_SPECIAL_SETTINGS, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetRoundSpecialShopSettingsSuccess({
          roundSpecialShopSettings: response.data.markets,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get markets margins settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getMarketsMarginsSettings() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGet, API_URLS.MARKETS_MARGINS_SETTINGS, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetMarketsMarginsSettingsSuccess({
          marketsMarginsSettings: response.data.margins,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get round special margins settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getRoundSpecialMarginsSettings() {
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const response = yield call(requestGet, API_URLS.ROUND_SPECIAL_MARGINS_SETTINGS, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetRoundSpecialMarginsSuccess({
          roundSpecialMarginsSettings: response.data.margins,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get goal galore margins settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getGoalGaloreMarginsSettings() {
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const response = yield call(requestGet, API_URLS.GOAL_GALORE_MARGINS_SETTINGS, true);

    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetGoalGaloreMarginsSuccess({
          goalGaloreMarginsSettings: response.data.margins,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * @namespace sagas/settings
 */
/**
 * @memberof sagas/settings
 * @typedef Market Shop
 * @type {object}
 * @property {number} id
 * @property {string} name
 * @property {number} status
 */
/**
 * @memberof sagas/settings
 * @typedef "getMarketsShopSettings/response.data"
 * @type {object}
 * @property {Array<Market>} markets
 */
/**
 * Get markets shop settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getMarketsShopSettings() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGet, API_URLS.MARKETS_SHOP_SETTINGS, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetMarketsShopSettingsSuccess({
          marketsShopSettings: response.data.markets,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}
/**
 * @memberof sagas/settings
 * @typedef League
 * @type {object}
 * @property {string} emblem
 * @property {number} leagueID
 * @property {string} name
 * @property {number} status
 */
/**
 * @memberof sagas/settings
 * @typedef "getLeaguesSettings/response.data"
 * @type {object}
 * @property {Array<League>} leagues
 */
/**
 * Get league settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getLeaguesSettings() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGet, API_URLS.LEAGUES_SETTINGS, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetLeaguesSettingsSuccess({
          leaguesSettings: response.data.leagues,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Save market settings changes
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {Array} action.payload.marketsSettings
 */
function* saveMarketsSettings(action) {
  let response;
  try {
    const body = {
      markets: action.payload.marketsSettings,
    };
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPost, API_URLS.MARKETS_SETTINGS, body, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetMarketsSettingsSuccess({
          marketsSettings: action.payload.marketsSettings,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_MARKET_SETTTINGS,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_MARKET_SETTTINGS,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}
/**
 * Save market settings changes
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {Array} action.payload.goalGaloreSettings
 */
function* saveGoalGaloreSettings(action) {
  try {
    const goalGaloreSettings = action.payload.goalGaloreSettings.filter(
      (goalGalore) => goalGalore.id !== EXTRA_BETS_MARKET_IDS.MEGADRAW
    );
    const isSameStatus = goalGaloreSettings.every(
      (goalGalore) => goalGalore.status === action.payload.goalGaloreSettings[0]?.status
    );
    if (!isSameStatus) {
      const goalGaloreList = yield select(getGoalGaloreSettings);
      yield put(
        aGetGoalGaloreSuccess({
          goalGaloreSettings: goalGaloreList,
        })
      );
      const e = new Error('Both Goal Galore markets should be enabled/disabled at the same time');
      e.modal = MODALS.ERROR;
      throw e;
    }

    yield put(aSetIsFetched({ isFetched: false }));
    const body = {
      markets: action.payload.goalGaloreSettings,
    };
    const response = yield call(requestPost, API_URLS.GOAL_GALORE_SETTINGS, body, true);

    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetGoalGaloreSuccess({
          goalGaloreSettings: action.payload.goalGaloreSettings,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_MARKET_SETTTINGS,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_MARKET_SETTTINGS,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Save round special settings changes
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {Array} action.payload.roundSpecialSettings
 */
function* saveRoundSpecialShopSettings(action) {
  try {
    const body = {
      markets: action.payload.roundSpecialSettings,
    };
    yield put(aSetIsFetched({ isFetched: false }));
    const response = yield call(requestPost, API_URLS.ROUND_SPECIAL_SETTINGS, body, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetRoundSpecialShopSettingsSuccess({
          roundSpecialShopSettings: action.payload.roundSpecialSettings,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_MARKET_SETTTINGS,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_MARKET_SETTTINGS,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Save round special settings changes
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {Array} action.payload.roundSpecialSettings
 */
function* saveGoalGaloreMarginsSettings(action) {
  try {
    const body = {
      margins: action.payload.marketsMarginsSettings,
    };
    yield put(aSetIsFetched({ isFetched: false }));
    const response = yield call(requestPost, API_URLS.GOAL_GALORE_MARGINS_SETTINGS, body, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetRoundSpecialShopSettingsSuccess({
          roundSpecialShopSettings: action.payload.roundSpecialSettings,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_MARKET_MARGINS_SETTTINGS,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_MARKET_MARGINS_SETTTINGS,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Save market shop settings changes
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {Array} action.payload.marketsShopSettings
 */
function* saveMarketsShopSettings(action) {
  try {
    const body = {
      markets: action.payload.marketsShopSettings,
    };
    const hasEnabledMarkets = body.markets.some((market) => market.status === 1);
    if (!hasEnabledMarkets) {
      const e = new Error(MODALS.MARKET_SETTINGS_ALL_DISABLED_ERROR);
      e.modal = MODALS.ERROR;
      throw e;
    }
    yield put(aSetIsFetched({ isFetched: false }));
    const response = yield call(requestPost, API_URLS.MARKETS_SHOP_SETTINGS, body, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetMarketsShopSettingsSuccess({
          marketsShopSettings: action.payload.marketsShopSettings,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_MARKET_SHOP_SETTTINGS,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_MARKET_SETTTINGS,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Save marketMargins settings changes
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {object} action.payload.marketsMarginsSettings
 */
function* saveMarketsMargins(action) {
  let response;
  try {
    const body = {
      margins: action.payload.marketsMarginsSettings,
    };
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPost, API_URLS.MARKETS_MARGINS_SETTINGS, body, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetMarketsMarginsSettingsSuccess({
          marketsMarginsSettings: action.payload.marketsMarginsSettings,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_MARKET_MARGINS_SETTTINGS,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_MARKET_MARGINS_SETTTINGS,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Save round special Margins settings changes
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {object} action.payload.marketsMarginsSettings
 */
function* saveRoundSpecialMargins(action) {
  try {
    const body = {
      margins: action.payload.marketsMarginsSettings,
    };
    yield put(aSetIsFetched({ isFetched: false }));
    const response = yield call(requestPost, API_URLS.ROUND_SPECIAL_MARGINS_SETTINGS, body, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetRoundSpecialMarginsSuccess({
          roundSpecialMarginsSettings: action.payload.marketsMarginsSettings,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_MARKET_MARGINS_SETTTINGS,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_MARKET_MARGINS_SETTTINGS,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}
/**
 * Save league settings changes
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {Array} action.payload.leaguesSettings
 */
function* saveLeaguesSettings(action) {
  let response;
  try {
    const body = {
      leagues: action.payload.leaguesSettings,
    };
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPost, API_URLS.SAVE_LEAGUES_SETTINGS, body, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetLeaguesSettingsSuccess({
          leaguesSettings: action.payload.leaguesSettings,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_LEAGUES_SETTTINGS,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_LEAGUES_SETTTINGS,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Edit video action settings
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {Array<VideoAction>} action.payload.videoAction
 */
function* saveVideoAction(action) {
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const body = action.payload.videoActionList.map((videoAction) => ({
      id: videoAction.id,
      status: videoAction.status,
    }));
    const response = yield call(requestPost, API_URLS.SAVE_VIDEO_ACTION, body, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetVideoActionSuccess({
          videoActionList: action.payload.videoActionList,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_VIDEO_ACTION,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_VIDEO_ACTION,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}
/**
 * @memberof sagas/settings
 * @typedef "getGamesSettings/response.data"
 * @type {object}
 * @property {number} couponMaxStake
 * @property {number} couponMinStake
 * @property {number} matchLength
 * @property {Array<number>} multipleBonusPercentages
 * @property {number} multipleBonusThreshold
 * @property {number} noPlaceBetInterval
 * @property {number} roundInterval
 * @property {number} winCap
 */
/**
 * Get league settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getGamesSettings() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGet, API_URLS.GAMES_SETTINGS, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetGamesSettingsSuccess({
          gamesSettings: response.data,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * @memberof sagas/settings
 * @typedef "getGamesShopSettings/response.data"
 * @type {object}
 * @property {number} couponMaxStake
 * @property {number} couponMinStake
 * @property {number} matchLength
 * @property {Array<number>} multipleBonusPercentages
 * @property {number} multipleBonusThreshold
 * @property {number} noPlaceBetInterval
 * @property {number} roundInterval
 * @property {number} winCap
 */
/**
 * Get game shop settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getGamesShopSettings() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGet, API_URLS.GAMES_SHOP_SETTINGS, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetGamesShopSettingsSuccess({
          gamesShopSettings: response.data,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get round duration settings data
 *
 * @memberof sagas/settings
 * @async
 */
function* getRoundDurationSettings() {
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const response = yield call(requestGet, API_URLS.ROUND_DURATION_SETTTINGS, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      e.code = response.error.code;
      throw e;
    }
    yield put(
      aGetRoundDurationSettingsSuccess({
        roundDurationSettings: response.data,
      })
    );
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    const insufficientPrivilegeErrorCode = 15104;
    if (error.code === insufficientPrivilegeErrorCode) {
      yield put(aSetIsFetched({ isFetched: true }));
      return;
    }

    yield put(
      aGetRoundDurationSettingsFail({
        roundDurationSettings: null,
      })
    );
    yield put(aSetIsFetched({ isFetched: true }));
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Save games settings changes
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {Array} action.payload.gamesSettings
 */
function* saveGamesSettings(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPost, API_URLS.SAVE_GAMES_SETTTINGS, action.payload, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetGamesSettingsSuccess({
          gamesSettings: action.payload,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_GAMES_SETTTINGS,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_GAMES_SETTTINGS,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Save games settings SHOP changes
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {Array} action.payload.gamesShopSettings
 */
function* saveGamesShopSettings(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPost, API_URLS.SAVE_GAMES_SHOP_SETTTINGS, action.payload, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetGamesShopSettingsSuccess({
          gamesShopSettings: action.payload,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_GAMES_SETTTINGS,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.SAVE_GAMES_SETTTINGS,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

function* saveMatchRoundDurationSettings(action) {
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const response = yield call(requestPost, API_URLS.ROUND_DURATION_SETTTINGS, action.payload, true);

    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    }

    yield put(
      aSaveMatchRoundDurationSettingsSuccess({
        roundDurationSettings: action.payload,
      })
    );
    yield put(
      aSetOpenModal({
        modal: MODALS.SUCCESS,
        modalData: {
          message: SUCCESS_MODALS.SAVE_GAMES_SETTTINGS,
          additionalMessage: 'successfully',
          modal: SUCCESS_MODALS.SAVE_GAMES_SETTTINGS,
        },
      })
    );

    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(aSetIsFetched({ isFetched: false }));
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get odds templates files data
 *
 * @memberof sagas/settings
 * @async
 */
function* getOddsTemplates() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));

    const pageToken = yield select(getOddsTemplatesPageToken);
    const params = `?${new URLSearchParams({ pageToken }).toString()}`;

    response = yield call(requestGet, API_URLS.ODDS_TEMPLATES_FILES + params, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aOddsTemplatesFilesSuccess({
          oddsTemplatesFiles: response.data.oddsFiles,
          oddsTemplatesPageToken: response.data.pageToken,
        })
      );
      if (!response.data.pageToken) {
        yield put(aSetLastRecord(true));
      }
      yield put({
        type: aSetHasRecord.type,
        payload: {
          hasRecord: !!Object.entries(response.data.oddsFiles).length,
        },
      });
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * download odds templates file
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 */
function* getDownloadOddsTemplatesFile(action) {
  let response;
  const params = `?fileName=${action.payload}`;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGetDownloadedFile, API_URLS.DOWNLOAD_ODDS_TEMPLATES_FILE + params, true);
    if (response) {
      yield put(
        aDownloadOddsTemplatesFileSuccess({
          downloadedFile: response,
        })
      );
      yield put(aSetIsFetched({ isFetched: true }));
    } else {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Upload odds templates files
 *
 * @memberof oddstemplatefiles/upload
 * @async
 * @param {object} action
 */
function* getUploadOddsTemplatesFile(action) {
  let response;
  const params = new FormData();
  params.append('file', action.payload);
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPostFormData, API_URLS.UPLOAD_ODDS_TEMPLATES_FILE, params, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(aGetOddsTemplatesFiles());
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.UPLOAD_ODDS_TEMPLATES_FILE,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.UPLOAD_ODDS_TEMPLATES_FILE,
          },
        })
      );
      yield put(aSetIsFetched({ isFetched: true }));
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get odds template data
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 */
function* getOddsTemplateList(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const lastId = action.payload && action.payload.refreshData ? '' : yield select(getOddsTemplateLastId);
    const params = `?${new URLSearchParams({ lastId }).toString()}`;

    response = yield call(requestGet, API_URLS.GET_ODDS_TEMPLATE + params, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      const previousOddsTemplate = action.payload && action.payload.refreshData ? [] : yield select(getOddsTemplate);
      yield put(
        aOddsTemplateSuccess({
          oddsTemplate: [...previousOddsTemplate, ...response.data.oddsTemplate],
          oddsTemplateLastId: response.data.lastId,
        })
      );

      if (!response.data.lastId) {
        yield put(aSetLastRecord(true));
      }
      yield put({
        type: aSetHasRecord.type,
        payload: {
          hasRecord: !!Object.entries(response.data.oddsTemplate).length,
        },
      });
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get odds shop template data
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 */
function* getOddsShopTemplateList(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const lastId = action.payload && action.payload.refreshData ? '' : yield select(getOddsShopTemplateLastId);
    const params = `?${new URLSearchParams({ lastId }).toString()}`;

    response = yield call(requestGet, API_URLS.GET_ODDS_SHOP_TEMPLATE + params, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      const previousOddsTemplate =
        action.payload && action.payload.refreshData ? [] : yield select(getOddsShopTemplate);
      yield put(
        aOddsShopTemplateSuccess({
          oddsShopTemplate: [...previousOddsTemplate, ...response.data.oddsTemplate],
          oddsShopTemplateLastId: response.data.lastId,
        })
      );

      if (!response.data.lastId) {
        yield put(aSetLastRecord(true));
      }
      yield put({
        type: aSetHasRecord.type,
        payload: {
          hasRecord: !!Object.entries(response.data.oddsTemplate).length,
        },
      });
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get odds template exel list data
 *
 * @memberof sagas/settings
 * @async
 */
function* getOddsTemplateExelList() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGet, API_URLS.GET_ODDS_TEMPLATE_LIST_EXEL, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetTemplateExelListSuccess({
          templateExelList: response.data.fileNames,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get odds shop template excel list data
 *
 * @memberof sagas/settings
 * @async
 */
function* getOddsShopTemplateExelList() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGet, API_URLS.GET_ODDS_SHOP_TEMPLATE_LIST_EXEL, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetTemplateExelListSuccess({
          templateExelList: response.data.fileNames,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Save new odds template
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 */
function* saveNewOddsTemplate(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPost, API_URLS.SAVE_NEW_ODDS_TEMPLATE, action.payload, true);
    if (response.status === -1) {
      let errorMgs;
      switch (response.error.code) {
        case 19107:
          errorMgs = STATUS_CODE_ERROR_MESSAGE.completelyFailed;
          break;
        case 19108:
          errorMgs = STATUS_CODE_ERROR_MESSAGE.partlyFailed;
          break;
        default:
          errorMgs = response.error.message;
          break;
      }
      const e = new Error(errorMgs);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aOddsTemplate({
          refreshData: true,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_NEW_ODDS_TEMPLATE,
            modal: SUCCESS_MODALS.SAVE_NEW_ODDS_TEMPLATE,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  } finally {
    yield put(aSetLastRecord(false));
  }
}

/**
 * Save new odds shop template
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 */
function* saveNewOddsShopTemplate(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPost, API_URLS.SAVE_NEW_ODDS_SHOP_TEMPLATE, action.payload, true);
    if (response.status === -1) {
      let errorMgs;
      switch (response.error.code) {
        case 19107:
          errorMgs = STATUS_CODE_ERROR_MESSAGE.completelyFailed;
          break;
        case 19108:
          errorMgs = STATUS_CODE_ERROR_MESSAGE.partlyFailed;
          break;
        default:
          errorMgs = response.error.message;
          break;
      }
      const e = new Error(errorMgs);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aOddsShopTemplate({
          refreshData: true,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_NEW_ODDS_TEMPLATE,
            modal: SUCCESS_MODALS.SAVE_NEW_ODDS_TEMPLATE,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  } finally {
    yield put(aSetLastRecord(false));
  }
}

/**
 * Post request to force Turbo for odds template
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 */
function* forceTurbo(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(
      requestPost,
      `${API_URLS.FORCE_TURBO}/${action.payload?.templateId}/forceTurbo`,
      { forceTurbo: action.payload?.forceTurbo },
      true
    );

    if (response?.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      const oddsTemplate = structuredClone(yield select(getOddsTemplate));
      const modifiedTemplate = oddsTemplate?.find((member) => member.id === action.payload?.templateId);
      if (modifiedTemplate) {
        modifiedTemplate.forceTurbo = !modifiedTemplate.forceTurbo;
      }

      yield put(
        aForceTurboSuccess({
          oddsTemplate,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get stats template data
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 */
function* getStatsTemplateList(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const lastId = action.payload && action.payload.refreshData ? '' : yield select(getStatsTemplateLastId);
    const params = `?${new URLSearchParams({ lastId }).toString()}`;

    response = yield call(requestGet, API_URLS.GET_STATS_TEMPLATE + params, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      const previousStatsTemplate = action.payload && action.payload.refreshData ? [] : yield select(getStatsTemplate);
      yield put(
        aGetStatsTemplateSuccess({
          statsTemplate: [...previousStatsTemplate, ...(response.data?.statsTemplates || [])],
          statsTemplateLastId: response.data?.lastId,
        })
      );

      if (!response.data.lastId) {
        yield put(aSetLastRecord(true));
      }
      yield put({
        type: aSetHasRecord.type,
        payload: {
          hasRecord: !!Object.entries(response.data?.statsTemplates || [])?.length,
        },
      });
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}
/**
 * Get stats  template excel list data
 *
 * @memberof sagas/settings
 * @async
 */
function* getStatsTemplateExelList() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGet, API_URLS.GET_STATS_TEMPLATE_LIST_EXEL, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetTemplateExelListSuccess({
          templateExelList: response.data.fileNames,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Save new stats template
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 */
function* saveNewStatsTemplate(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPost, API_URLS.SAVE_NEW_STATS_TEMPLATE, action.payload, true);
    if (response.status === -1) {
      let errorMgs;
      switch (response.error.code) {
        case 19206:
          errorMgs = STATUS_CODE_ERROR_MESSAGE.completelyFailed;
          break;
        case 19207:
          errorMgs = STATUS_CODE_ERROR_MESSAGE.partlyFailed;
          break;
        default:
          errorMgs = response.error.message;
          break;
      }
      const e = new Error(errorMgs);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetStatsTemplate({
          refreshData: true,
        })
      );
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.SAVE_NEW_STATS_TEMPLATE,
            modal: SUCCESS_MODALS.SAVE_NEW_STATS_TEMPLATE,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  } finally {
    yield put(aSetLastRecord(false));
  }
}

/**
 * Get stats templates files data
 *
 * @memberof sagas/settings
 * @async
 */
function* getStatsTemplates() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));

    const pageToken = yield select(getStatsTemplatesPageToken);
    const params = `?${new URLSearchParams({ pageToken }).toString()}`;

    response = yield call(requestGet, API_URLS.STATS_TEMPLATES_FILES + params, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aStatsTemplatesFilesSuccess({
          statsTemplatesFiles: response.data.statsFiles,
          statsTemplatesPageToken: response.data.pageToken,
        })
      );
      if (!response.data.pageToken) {
        yield put(aSetLastRecord(true));
      }
      yield put({
        type: aSetHasRecord.type,
        payload: {
          hasRecord: !!Object.entries(response.data.statsFiles).length,
        },
      });
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * download stats templates file
 *
 * @memberof sagas/settings
 * @async
 * @param {object} action
 */
function* getStatsDownloadTemplates(action) {
  let response;
  const params = `?fileName=${action.payload}`;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGetDownloadedFile, API_URLS.DOWNLOAD_STATS_TEMPLATES_FILE + params, true);
    if (response) {
      yield put(
        aDownloadOddsTemplatesFileSuccess({
          downloadedFile: response,
        })
      );
      yield put(aSetIsFetched({ isFetched: true }));
    } else {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Upload stats templates files
 *
 * @memberof oddstemplatefiles/upload
 * @async
 * @param {object} action
 */
function* getStatsUploadTemplates(action) {
  let response;
  const params = new FormData();
  params.append('file', action.payload);
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPostFormData, API_URLS.UPLOAD_STATS_TEMPLATES_FILE, params, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(aGetStatsTemplatesFiles());
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: SUCCESS_MODALS.UPLOAD_ODDS_TEMPLATES_FILE,
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.UPLOAD_ODDS_TEMPLATES_FILE,
          },
        })
      );
      yield put(aSetIsFetched({ isFetched: true }));
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Get video action for shop
 * @param {object} action
 * @memberof sagas/settings
 * @async
 */
function* getVideoActionList(action) {
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    const params = `?${new URLSearchParams(action.payload).toString()}`;
    const response = yield call(requestGet, API_URLS.VIDEO_ACTION_LIST + params, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetVideoActionSuccess({
          videoActionList: response.data.videoActionList,
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}
/**
 * @memberof sagas/settings
 * @async
 */
export default function* settingsSaga() {
  yield takeLatest(aGetMarketsMargingSettings, getMarketsMarginsSettings);
  yield takeLatest(aGetRoundSpecialMarginsSettings, getRoundSpecialMarginsSettings);
  yield takeLatest(aGetGoalGaloreMarginsSettings, getGoalGaloreMarginsSettings);
  yield takeLatest(aGetMarketsSettings, getMarketsSettings);
  yield takeLatest(aGetRoundSpecialShopSettings, getRoundSpecialShopSettings);
  yield takeLatest(aGetMarketsShopSettings, getMarketsShopSettings);
  yield takeLatest(aSaveMarketsSettings, saveMarketsSettings);
  yield takeLatest(aSaveRoundSpecialShopSettings, saveRoundSpecialShopSettings);
  yield takeLatest(aSaveGoalGaloreMarginsSettings, saveGoalGaloreMarginsSettings);
  yield takeLatest(aSaveMarketsShopSettings, saveMarketsShopSettings);
  yield takeLatest(aSaveMarketsMarginsSettings, saveMarketsMargins);
  yield takeLatest(aSaveRoundSpecialMarginsSettings, saveRoundSpecialMargins);
  yield takeLatest(aGetLeaguesSettings, getLeaguesSettings);
  yield takeLatest(aSaveLeaguesSettings, saveLeaguesSettings);
  yield takeLatest(aGetGamesSettings, getGamesSettings);
  yield takeLatest(aGetGamesShopSettings, getGamesShopSettings);
  yield takeLatest(aGetRoundDurationSettings, getRoundDurationSettings);
  yield takeLatest(aSaveGamesSettings, saveGamesSettings);
  yield takeLatest(aSaveMatchRoundDurationSettings, saveMatchRoundDurationSettings);
  yield takeLatest(aSaveGamesShopSettings, saveGamesShopSettings);
  yield takeLatest(aGetOddsTemplatesFiles, getOddsTemplates);
  yield takeLatest(aGetDownloadTemplatesFile, getDownloadOddsTemplatesFile);
  yield takeLatest(aGetUploadTemplatesFile, getUploadOddsTemplatesFile);
  yield takeLatest(aOddsTemplate, getOddsTemplateList);
  yield takeLatest(aOddsShopTemplate, getOddsShopTemplateList);
  yield takeLatest(aOddsTemplateExelList, getOddsTemplateExelList);
  yield takeLatest(aOddsShopTemplateExelList, getOddsShopTemplateExelList);
  yield takeLatest(aGetStatsTemplateExelList, getStatsTemplateExelList);
  yield takeLatest(aSaveNewOddsTemplate, saveNewOddsTemplate);
  yield takeLatest(aSaveNewOddsShopTemplate, saveNewOddsShopTemplate);
  yield takeLatest(aSaveNewStatsTemplate, saveNewStatsTemplate);
  yield takeLatest(aGetStatsTemplatesFiles, getStatsTemplates);
  yield takeLatest(aGetStatsDownloadTemplatesFile, getStatsDownloadTemplates);
  yield takeLatest(aGetStatsUploadTemplatesFile, getStatsUploadTemplates);
  yield takeLatest(aForceTurbo, forceTurbo);
  yield takeLatest(aGetStatsTemplate, getStatsTemplateList);
  yield takeLatest(aGetVideoAction, getVideoActionList);
  yield takeLatest(aSaveVideoAction, saveVideoAction);
  yield takeLatest(aGetGoalGaloreSettings, getGoalGaloreSettingsRequest);
  yield takeLatest(aSaveGoalGaloreSettings, saveGoalGaloreSettings);
}