sagas/reports.js

import { takeLatest, put, call, select } from 'redux-saga/effects';
import { requestPost, requestGet } from '../utils/request';
import { API_URLS, MODALS } from '../constants';
import { getReports, getReportsShop, getLastRoundStartDate } from '../selectors/reports';
import {
  aGetFreeBetShopReportsSuccess,
  aGetRoundReportsShopSuccess,
  aGetRoundReportsSuccess,
  aGetTurnoverReports,
  aGetTurnoverReportsSuccess,
} from '../reducers/reports';
import { aSetHasRecord, aSetIsFetched, aSetLastRecord, aSetOpenModal } from '../reducers/common';
import { aGetFreeBetShopReports, aGetRoundReports, aGetRoundReportsShop } from '../reducers/actions';

/**
 * @namespace sagas/reports
 */

/**
 * @memberof sagas/reports
 * @typedef Round
 * @type {object}
 * @property {number} roundId
 * @property {string} roundStartDate
 * @property {string} roundEndDate
 * @property {number} roundStatus
 * @property {number} placedCoupons
 * @property {number} settledCoupons
 * @property {number} winningCoupons
 * @property {number} totalPlacedStake
 * @property {number} totalWonAmount
 * @property {number} paidCoupons
 * @property {number} wontPayCoupons
 */

/**
 * @memberof sagas/reports
 * @typedef "getRounds/response.data"
 * @type {object}
 * @property {Array<Round>} roundStats
 * @property {number} totalPage
 */
/**
 * Get round reports list
 *
 * @memberof sagas/reports
 * @async
 * @param {object} action Filtering data
 */
function* getRoundReports(action) {
  let response;
  try {
    if (action.payload) {
      let filters = action.payload || {};
      const lastRoundStartDate = yield select(getLastRoundStartDate);
      filters = {
        ...filters,
        lastRoundStartDate,
      };
      const params = `?${new URLSearchParams(filters).toString()}`;

      yield put(aSetIsFetched({ isFetched: false }));
      response = yield call(requestGet, API_URLS.ROUND_REPORTS + params, true);
      if (response.status === -1) {
        const e = Error(response.error.message);
        e.modal = MODALS.ERROR;
        throw e;
      } else {
        const roundsReport = yield select(getReports);
        yield put(
          aGetRoundReportsSuccess({
            roundStats: [...roundsReport, ...response.data.roundStats],
            lastRoundStartDate: response.data.lastRoundStartDate,
          })
        );
        if (!response.data.lastRoundStartDate) {
          yield put(aSetLastRecord(true));
        }
        yield put({
          type: aSetHasRecord.type,
          payload: {
            hasRecord: response.data.roundStats.length > 0,
          },
        });
      }
    }
    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/reportsShop
 */

/**
 * @memberof sagas/reportsShop
 * @typedef Round
 * @type {object}
 * @property {number} roundId
 * @property {string} roundStartDate
 * @property {string} roundEndDate
 * @property {number} roundStatus
 * @property {number} placedCoupons
 * @property {number} settledCoupons
 * @property {number} winningCoupons
 * @property {number} totalPlacedStake
 * @property {number} totalWonAmount
 * @property {number} paidCoupons
 * @property {number} wontPayCoupons
 */

/**
 * @memberof sagas/reportsShop
 * @typedef "getRoundsShop/response.data"
 * @type {object}
 * @property {Array<RoundShop>} roundStats
 * @property {number} totalPage
 */
/**
 * Get round reports shop list
 *
 * @memberof sagas/reportsShop
 * @async
 * @param {object} action Filtering data
 */
function* getRoundReportsShop(action) {
  let response;
  try {
    if (action.payload) {
      let filters = action.payload || {};
      const lastRoundStartDate = yield select(getLastRoundStartDate);
      filters = {
        ...filters,
        lastRoundStartDate,
      };
      const params = `?${new URLSearchParams(filters).toString()}`;

      yield put(aSetIsFetched({ isFetched: false }));
      response = yield call(requestGet, API_URLS.ROUND_REPORTS_SHOP + params, true);
      if (response.status === -1) {
        const e = Error(response.error.message);
        e.modal = MODALS.ERROR;
        throw e;
      } else {
        const roundsReportShop = yield select(getReportsShop);
        yield put(
          aGetRoundReportsShopSuccess({
            roundStats: [...roundsReportShop, ...response.data.roundStats],
            lastRoundStartDate: response.data.lastRoundStartDate,
          })
        );
        if (!response.data.lastRoundStartDate) {
          yield put(aSetLastRecord(true));
        }
        yield put({
          type: aSetHasRecord.type,
          payload: {
            hasRecord: response.data.roundStats.length > 0,
          },
        });
      }
    }
    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/reports
 * @typedef "getTurnoverReports/response.data"
 * @type {object}
 * @property {number} numberOfBets
 * @property {number} totalStake
 * @property {number} numberOfWinningBets
 * @property {number} totalWin
 * @property {number} profit
 * @property {string} currencySymbol
 */
/**
 * Get turover reports list
 *
 * @memberof sagas/reports
 * @async
 * @param {object} action Filtering data
 */
function* getTurnoverReports(action) {
  let response;
  try {
    if (action.payload) {
      const filters = action.payload;
      yield put(aSetIsFetched({ isFetched: false }));
      response = yield call(requestPost, API_URLS.TURNOVER_REPORTS, filters, true);
      if (response.status === -1) {
        const e = Error(response.error.message);
        e.modal = MODALS.ERROR;
        throw e;
      } else {
        yield put(
          aGetTurnoverReportsSuccess({
            turnover: response.data,
          })
        );
        yield put({
          type: aSetHasRecord.type,
          payload: {
            hasRecord: Object.entries(response.data).length > 0,
          },
        });
      }
    }
    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 free bet reports list
 *
 * @memberof sagas/reports
 * @async
 * @param {object} action Filtering data
 */
function* getFreeBetShopReports(action) {
  try {
    if (action.payload) {
      yield put(aSetIsFetched({ isFetched: false }));
      const response = yield call(requestPost, API_URLS.FREE_BET_SHOP_REPORTS, action.payload, true);
      if (response.status === -1) {
        const e = Error(response.error.message);
        e.modal = MODALS.ERROR;
        throw e;
      } else {
        yield put(
          aGetFreeBetShopReportsSuccess({
            freeBetShopReports: 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/reports
 * @async
 * @returns {void}
 */
export default function* reportsSaga() {
  yield takeLatest(aGetRoundReports, getRoundReports);
  yield takeLatest(aGetRoundReportsShop, getRoundReportsShop);
  yield takeLatest(aGetTurnoverReports, getTurnoverReports);
  yield takeLatest(aGetFreeBetShopReports, getFreeBetShopReports);
}