sagas/rounds.js

import { takeLatest, put, call, select } from 'redux-saga/effects';
import { requestGet } from '../utils/request';
import { API_URLS, MODALS } from '../constants';
import { parseRoundDetails } from '../utils/common';
import { getRounds, getLastStartDate, getRoundsTurbo, getTurboLastStartDate, getRoundsShop } from '../selectors/rounds';
import { aSetHasRecord, aSetIsFetched, aSetLastRecord, aSetOpenModal } from '../reducers/common';
import {
  aGetRoundDetailsSuccess,
  aGetRoundShopSuccess,
  aGetRoundsSuccess,
  aGetRoundsTurboSuccess,
} from '../reducers/rounds';
import { aGetRounds, aGetRoundsShop, aGetRoundsTurbo, aSetSelectedRound } from '../reducers/actions';

/**
 * @namespace sagas/rounds
 */

/**
 * @memberof sagas/rounds
 * @typedef Round
 * @type {object}
 * @property {number} roundId
 * @property {string} roundStartDate
 * @property {string} roundEndDate
 * @property {number} roundStatus
 */

/**
 * @memberof sagas/rounds
 * @typedef "getRounds/response.data"
 * @type {object}
 * @property {Array<Round>} rounds
 * @property {number} totalPage
 */
/**
 * Get rounds list
 *
 * @memberof sagas/rounds
 * @async
 * @param {object} action Filtering data
 */
function* getRoundsSaga(action) {
  let response;
  try {
    if (action.payload) {
      const lastStartDate = yield select(getLastStartDate);
      const filters = {
        ...action.payload,
        lastStartDate,
      };

      const params = `?${new URLSearchParams(filters).toString()}`;

      yield put(aSetIsFetched({ isFetched: false }));
      response = yield call(requestGet, API_URLS.ROUNDS_LIST + params, true);
      if (response.status === -1) {
        const e = new Error(response.error.message);
        e.modal = MODALS.ERROR;
        throw e;
      } else {
        const rounds = yield select(getRounds);

        yield put(
          aGetRoundsSuccess({
            rounds: [...rounds, ...response.data.rounds],
            lastStartDate: response.data.lastStartDate,
          })
        );
        if (!response.data.lastStartDate) {
          yield put(aSetLastRecord(true));
        }
        yield put({
          type: aSetHasRecord.type,
          payload: {
            hasRecord: response.data.rounds.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/roundsTurbo
 * @typedef RoundTurbo
 * @type {object}
 * @property {number} roundId
 * @property {number} clientId
 * @property {string} roundStartDate
 * @property {string} roundEndDate
 */

/**
 * @memberof sagas/roundsTurbo
 * @typedef "getRoundsTurbo/response.data"
 * @type {object}
 * @property {Array<RoundTurbo>} roundsTurbo
 * @property {number} totalPage
 */
/**
 * Get Rounds Turbo List
 *
 * @memberof sagas/roundsTurbo
 * @async
 * @param {object} action Filtering data
 */
function* getRoundsTurboSaga(action) {
  let response;
  try {
    if (action.payload) {
      const turboLastStartDate = yield select(getTurboLastStartDate);
      const filters = {
        ...action.payload,
        turboLastStartDate,
      };
      const params = `?${new URLSearchParams(filters).toString()}`;
      yield put(aSetIsFetched({ isFetched: false }));
      response = yield call(requestGet, API_URLS.ROUNDS_TURBO_LIST + params, true);
      if (response.status === -1) {
        const e = new Error(response.error.message);
        e.modal = MODALS.ERROR;
        throw e;
      } else {
        const roundsTurbo = yield select(getRoundsTurbo);

        yield put(
          aGetRoundsTurboSuccess({
            roundsTurbo: [...roundsTurbo, ...response.data.rounds],
            turboLastStartDate: response.data.turboLastStartDate,
          })
        );
        if (!response.data.turboLastStartDate) {
          yield put(aSetLastRecord(true));
        }
        yield put({
          type: aSetHasRecord.type,
          payload: {
            hasRecord: response.data.rounds.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/roundsShop
 * @typedef RoundsShop
 * @type {object}
 * @property {number} roundId
 * @property {string} roundStartDate
 * @property {string} roundEndDate
 * @property {number} roundStatus
 */

/**
 * @memberof sagas/roundsShop
 * @typedef "getRoundsShop/response.data"
 * @type {object}
 * @property {Array<RoundsShop>} roundsShop
 * @property {number} totalPage
 */
/**
 * Get rounds SHOP list
 *
 * @memberof sagas/roundsShop
 * @async
 * @param {object} action Filtering data
 */
function* getRoundsShopSaga(action) {
  let response;
  try {
    if (action.payload) {
      const lastStartDate = yield select(getLastStartDate);
      const filters = {
        ...action.payload,
        lastStartDate,
      };
      const params = `?${new URLSearchParams(filters).toString()}`;

      yield put(aSetIsFetched({ isFetched: false }));
      response = yield call(requestGet, API_URLS.ROUNDS_SHOP_LIST + params, true);
      if (response.status === -1) {
        const e = new Error(response.error.message);
        e.modal = MODALS.ERROR;
        throw e;
      } else {
        const roundsShop = yield select(getRoundsShop);

        yield put(
          aGetRoundShopSuccess({
            roundsShop: [...roundsShop, ...response.data.rounds],
            lastStartDate: response.data.lastStartDate,
          })
        );
        if (!response.data.lastStartDate) {
          yield put(aSetLastRecord(true));
        }
        yield put({
          type: aSetHasRecord.type,
          payload: {
            hasRecord: response.data.rounds.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/rounds
 * @typedef "getRoundDetails/response.data"
 * @type {object}
 * @property {number} roundId
 * @property {string} roundStartDate
 * @property {string} roundEndDate
 * @property {number} roundStatus
 */
/**
 * Get round details
 *
 * @memberof sagas/rounds
 * @async
 * @param {object} action
 * @property {object} action
 * @property {number} action.roundId
 */
function* getRoundDetails(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    if (action.payload.isShop) {
      response = yield call(
        requestGet,
        `${API_URLS.ROUND_DETAILS_SHOP}/${action.payload.turbo}/${action.payload.roundId}`,
        true
      );
    } else {
      response = yield call(
        requestGet,
        `${API_URLS.ROUND_DETAILS}/${action.payload.turbo}/${action.payload.roundId}`,
        true
      );
    }
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetRoundDetailsSuccess({
          selectedRound: parseRoundDetails(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/rounds
 * @async
 * @returns {void}
 */
export default function* roundsSaga() {
  yield takeLatest(aGetRounds, getRoundsSaga);
  yield takeLatest(aSetSelectedRound, getRoundDetails);
  yield takeLatest(aGetRoundsTurbo, getRoundsTurboSaga);
  yield takeLatest(aGetRoundsShop, getRoundsShopSaga);
}