import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
aGetPlacedCoupons,
aGetPlacedCouponsShop,
aGetSettledCoupons,
aGetSettledCouponsShop,
aSetCouponToWontpayRequest,
aVoidCouponRequest,
} from '../../reducers/actions';
import {
getCurrency,
getSelectedMenuItem,
getFilterData,
isFetched,
isLastRecord,
hasRecord,
getSelectedTimezone,
getActiveModal,
checkPermisson,
getBetStatus,
} from '../../selectors/common';
import {
getGameStatuses,
getPlacedCoupons,
getSelectedCoupon,
getSettledCoupons,
getPlacedCouponsShop,
getSettledCouponsShop,
getShopGameStatuses,
getCouponStatus,
getOperatorsFilter,
getIsLoadingCoupons,
getCouponSource,
} from '../../selectors/coupons';
import PlacedCoupons from '../../components/MenuItems/Coupons/PlacedCoupons';
import Filter from '../../components/Filter';
import CouponDetails from '../../components/MenuItems/Coupons/CouponDetails';
import { MENU_ITEMS, COUPONS_TYPE, COUPON_PAGES, PERMISSIONS } from '../../constants';
import SettledCoupons from '../../components/MenuItems/Coupons/SettledCoupons';
import { getCountryNewDate, getDateForIntervalFilter, setFilterFromUrl } from '../../utils/common';
import ScrollTable from '../../components/ScrollTable';
import { aClearFilterData } from '../../reducers/cashier';
import { aSetFilters, aSetOpenModal } from '../../reducers/common';
import { aSetSelectedCoupon, aSortSettledCoupons } from '../../reducers/coupons';
import { withRouterHooks } from '../../utils/router';
import { SETTLED_COUPONS_SORT_FIELDS, SORT_DIRECTION } from '../../utils/sort';
import { COUPON_FILTER_KEY_MAPPING, OPERATOR_LABEL_MAPPING } from './constants';
import { aResetExport } from '../../reducers/exporter';
import { getGamesSettings } from '../../selectors/settings';
import { aGetGamesSettings } from '../../reducers/settings';
import Loader from '../../components/Loader';
const mapToProps = (state) => ({
placedCoupons: getPlacedCoupons(state),
placedCouponsShop: getPlacedCouponsShop(state),
settledCoupons: getSettledCoupons(state),
settledCouponsShop: getSettledCouponsShop(state),
currency: getCurrency(state),
selectedMenuItem: getSelectedMenuItem(state),
selectedCoupon: getSelectedCoupon(state),
filters: getFilterData(state),
isFetched: isFetched(state),
isLastRecord: isLastRecord(state),
hasRecord: hasRecord(state),
gameStatuses: getGameStatuses(state),
shopGameStatuses: getShopGameStatuses(state),
selectedTimezone: getSelectedTimezone(state),
activeModal: getActiveModal(state),
checkPermisson: (payload) => checkPermisson(state, payload),
betStatus: getBetStatus(state),
couponStatus: getCouponStatus(state),
gamesSettings: getGamesSettings(state),
operators: getOperatorsFilter(state),
isLoadingCoupons: getIsLoadingCoupons(state),
couponSource: getCouponSource(state),
});
const actionsToProps = (dispatch) => ({
setFilterData: (payload) => dispatch(aSetFilters(payload)),
getPlacedCoupons: (payload) => dispatch(aGetPlacedCoupons(payload)),
getPlacedCouponsShop: (payload) => dispatch(aGetPlacedCouponsShop(payload)),
getSettledCoupons: (payload) => dispatch(aGetSettledCoupons(payload)),
getSettledCouponsShop: (payload) => dispatch(aGetSettledCouponsShop(payload)),
selectCoupon: (payload) => dispatch(aSetSelectedCoupon(payload)),
clearFilterData: (payload) => dispatch(aClearFilterData(payload)),
setOpenModal: (payload) => dispatch(aSetOpenModal(payload)),
voidCoupon: (payload) => dispatch(aVoidCouponRequest(payload)),
setCouponToWontpay: (payload) => dispatch(aSetCouponToWontpayRequest(payload)),
sortSettledCoupons: (payload) => dispatch(aSortSettledCoupons(payload)),
getGamesSettings: (payload) => dispatch(aGetGamesSettings(payload)),
resetExport: () => dispatch(aResetExport()),
});
/**
* @class
* @property {object} props
* @property {Array} props.placedCoupons All placed coupons data
* @property {Array} props.settledCoupons All settled coupons data
* @property {string} props.currency Currency sign
* @property {object} props.selectedMenuItem Placed or settled coupons
* @property {object} props.selectedCoupon Selected coupon data
* @property {object} props.filters Filters data
* @property {boolean} props.isFetched
* @property {Function} props.setFilterData Filter coupons
* @property {Function} props.getPlacedCoupons Get coupons API
* @property {Function} props.selectCoupon Change selected coupon
* @property {Function} props.clearFilterData Clear filter data
*/
class Coupons extends Component {
constructor(props) {
super(props);
/**
* @member {Array}
* @description Filtering fields settings
*/
this.state = {
sort: {
direction: SORT_DIRECTION.DESC,
field: SETTLED_COUPONS_SORT_FIELDS.PLACED_DATE,
},
};
this.filterFields = [
{
className: 'user__username',
text: 'Coupon ID',
field: 'filter.couponId',
},
{
text: 'Client ID',
field: 'filter.clientId',
},
{
text: 'Round ID',
field: 'filter.roundId',
},
{
text: 'Game',
// eslint-disable-next-line sonarjs/no-duplicate-string
field: 'filter.game',
dropdown: props.gameStatuses,
},
{
text: 'Placed date',
// eslint-disable-next-line sonarjs/no-duplicate-string
fields: ['filter.startPlacedDate', 'filter.endPlacedDate'],
dateInterval: true,
},
{
text: 'Bonus',
field: 'filter.isBonus',
bonus: true,
},
];
/**
* @member {boolean}
* @description Is settlet coupons selected
*/
this.isSettled = false;
/**
* @member {object}
*/
this.defaultFilter = {
'filter.startPlacedDate': '',
'filter.endPlacedDate': '',
'filter.couponId': '',
'filter.clientId': '',
'filter.roundId': '',
};
/**
* @member {object}
*/
this.filters = props.filters
? {
...props.filters,
'filter.startPlacedDate': setFilterFromUrl(this.props.location.search, 'filter.startPlacedDate'),
'filter.endPlacedDate': setFilterFromUrl(this.props.location.search, 'filter.endPlacedDate'),
}
: this.defaultFilter;
/**
* @member {boolean}
*/
this.initialApiCall = !!props.filters;
}
componentDidMount() {
const path = this.props.location.pathname;
const isSettledCouponsMobilePage = path === MENU_ITEMS.COUPONS.COUPONS_SETTLED_VIEW.path;
const hasExportCouponPermission = this.props.checkPermisson(PERMISSIONS.EXPORT_COUPONS);
if (isSettledCouponsMobilePage && hasExportCouponPermission) {
this.props.getGamesSettings();
}
}
componentDidUpdate(prevProps) {
if (prevProps.location.pathname !== this.props.location.pathname) {
this.filters = this.defaultFilter;
const path = this.props.location.pathname;
const isSettledCouponsMobilePage = path === MENU_ITEMS.COUPONS.COUPONS_SETTLED_VIEW.path;
const hasExportCouponPermission = this.props.checkPermisson(PERMISSIONS.EXPORT_COUPONS);
if (!isSettledCouponsMobilePage) {
this.filterFields = this.filterFields.filter(
(obj) =>
obj.field !== COUPON_FILTER_KEY_MAPPING.STATUS &&
obj.field !== COUPON_FILTER_KEY_MAPPING.STAKE &&
obj.field !== COUPON_FILTER_KEY_MAPPING.WON_AMOUNT
);
} else if (
hasExportCouponPermission &&
(prevProps.gamesSettings === null || prevProps.gamesSettings !== this.props.gamesSettings)
) {
this.props.getGamesSettings();
}
this.setState({
sort: {
direction: SORT_DIRECTION.DESC,
field: SETTLED_COUPONS_SORT_FIELDS.PLACED_DATE,
},
});
}
}
getValueEndPlacedDate = (endPlacedDateFilter) => {
if (!endPlacedDateFilter) {
const dateWithTimezone = getCountryNewDate(this.props.selectedTimezone, new Date());
return getDateForIntervalFilter(dateWithTimezone).replace(' ', 'T');
}
const endPlacedDate = new Date(endPlacedDateFilter);
const now = getCountryNewDate(this.props.selectedTimezone, new Date());
if (endPlacedDate.getTime() > now.getTime()) {
return getDateForIntervalFilter(now).replace(' ', 'T');
}
return endPlacedDateFilter;
};
/**
* Get coupons API call
*
* @function
* @param {object} payload Filter data
* @returns {void}
*/
getCoupons = (payload) => {
const defaultSort = { direction: SORT_DIRECTION.DESC, field: SETTLED_COUPONS_SORT_FIELDS.PLACED_DATE };
const { sort = defaultSort, ...filters } = payload || {};
if (payload && JSON.stringify(filters) !== JSON.stringify(this.defaultFilter)) {
this.setState({ sort });
filters['filter.endPlacedDate'] = this.getValueEndPlacedDate(filters['filter.endPlacedDate']);
if (this.isSettled && this.couponsPage === COUPON_PAGES.SETTLED_COUPON_MOBILE) {
this.props.getSettledCoupons({
...filters,
sort,
type: COUPONS_TYPE.SETTLED,
});
} else if (this.isSettled && this.couponsPage === COUPON_PAGES.SETTLED_COUPON_SHOP) {
this.props.getSettledCouponsShop({
...filters,
sort,
type: COUPONS_TYPE.SETTLED,
});
} else if (!this.isSettled && this.couponsPage === COUPON_PAGES.PLACED_COUPON_MOBILE) {
this.props.getPlacedCoupons({
...filters,
type: COUPONS_TYPE.PLACED,
});
} else if (!this.isSettled && this.couponsPage === COUPON_PAGES.PLACED_COUPON_SHOP) {
this.props.getPlacedCouponsShop({
...filters,
type: COUPONS_TYPE.PLACED,
});
}
}
};
/**
* Sort table by columns
* @param {string} field sort field
* @param {string} direction direction of sort ASC or DESC
* @function
* @returns {void}
*/
sortColumn = (field, direction) => {
this.setState({ sort: { field, direction } });
this.props.sortSettledCoupons({ field, direction, isShop: this.isShop });
};
getAdditionalFilters = (props) => [
{
text: 'Status',
field: COUPON_FILTER_KEY_MAPPING.STATUS,
dropdown: [
{ id: '', label: 'Any' },
...props.couponStatus.map((s) => {
const label = s.toLowerCase();
const labelWithCapitalizedWord = `${label.charAt(0).toUpperCase()}${label.slice(1)}`;
return { id: s, label: labelWithCapitalizedWord };
}),
],
},
{
text: 'Stake Amount',
field: COUPON_FILTER_KEY_MAPPING.STAKE,
operatorText: 'Stake Condition',
operatorField: COUPON_FILTER_KEY_MAPPING.STAKE_OPERATOR,
inputWithOperator: true,
minimumValue: 1,
maximumValue: this.props.gamesSettings?.couponMaxStake / 100,
operators: [
{ id: 'any-stake-operator', label: 'Any', value: '' },
...props.operators.map((operator, index) => ({
id: index,
label: OPERATOR_LABEL_MAPPING[operator] || operator,
value: operator,
})),
],
formatValue: (value) => (typeof value === 'number' ? value * 100 : 0),
getValue: (value) => (typeof value === 'number' ? value / 100 : 0),
isValid: (filterValue) => {
if (filterValue[COUPON_FILTER_KEY_MAPPING.STAKE]) {
return (
filterValue[COUPON_FILTER_KEY_MAPPING.STAKE_OPERATOR] !== '' &&
filterValue[COUPON_FILTER_KEY_MAPPING.STAKE] >= 1 &&
filterValue[COUPON_FILTER_KEY_MAPPING.STAKE] <= this.props.gamesSettings?.couponMaxStake
);
}
return true;
},
},
{
text: 'Won Amount',
field: COUPON_FILTER_KEY_MAPPING.WON_AMOUNT,
operatorText: 'Won Amount Condition',
operatorField: COUPON_FILTER_KEY_MAPPING.WON_AMOUNT_OPERATOR,
inputWithOperator: true,
minimumValue: 1,
maximumValue: this.props.gamesSettings?.winCap / 100,
operators: [
{ id: 'any-won-amount-operator', label: 'Any', value: '' },
...props.operators.map((operator, index) => ({
id: index,
label: OPERATOR_LABEL_MAPPING[operator] || operator,
value: operator,
})),
],
formatValue: (value) => (typeof value === 'number' ? value * 100 : 0),
getValue: (value) => (typeof value === 'number' ? value / 100 : 0),
isValid: (filterValue) => {
if (filterValue[COUPON_FILTER_KEY_MAPPING.WON_AMOUNT]) {
return (
filterValue[COUPON_FILTER_KEY_MAPPING.WON_AMOUNT_OPERATOR] !== '' &&
filterValue[COUPON_FILTER_KEY_MAPPING.WON_AMOUNT] >= 1 &&
filterValue[COUPON_FILTER_KEY_MAPPING.WON_AMOUNT] <= this.props.gamesSettings?.winCap
);
}
return true;
},
},
];
/**
* Load more coupons
*
* @function
* @returns {void}
*/
loadMore = () => {
const filters = this.props.filters || this.filters;
this.getCoupons({ ...filters, sort: this.state.sort });
};
/**
* Render
*
* @returns {view}
*/
render() {
const path = this.props.location.pathname;
let additionalFilters = [];
const hasExportCouponPermission = this.props.checkPermisson(PERMISSIONS.EXPORT_COUPONS);
this.isSettled =
path === MENU_ITEMS.COUPONS.COUPONS_SETTLED_VIEW.path ||
path === MENU_ITEMS.COUPONS.SHOP_COUPONS_SETTLED_VIEW.path;
if (path === MENU_ITEMS.COUPONS.COUPONS_PLACED_VIEW.path) {
this.placedCouponsData = this.props.placedCoupons;
this.couponsPage = COUPON_PAGES.PLACED_COUPON_MOBILE;
} else if (path === MENU_ITEMS.COUPONS.SHOP_COUPONS_PLACED_VIEW.path) {
this.placedCouponsData = this.props.placedCouponsShop;
this.couponsPage = COUPON_PAGES.PLACED_COUPON_SHOP;
} else if (path === MENU_ITEMS.COUPONS.COUPONS_SETTLED_VIEW.path) {
this.settledCouponsData = this.props.settledCoupons;
this.couponsPage = COUPON_PAGES.SETTLED_COUPON_MOBILE;
if (hasExportCouponPermission) {
additionalFilters = this.getAdditionalFilters(this.props);
}
} else if (path === MENU_ITEMS.COUPONS.SHOP_COUPONS_SETTLED_VIEW.path) {
this.settledCouponsData = this.props.settledCouponsShop;
this.couponsPage = COUPON_PAGES.SETTLED_COUPON_SHOP;
}
const gameField = this.filterFields.find((l) => l.text === 'Game');
if (this.couponsPage === COUPON_PAGES.PLACED_COUPON_SHOP || this.couponsPage === COUPON_PAGES.SETTLED_COUPON_SHOP) {
gameField.dropdown = this.props.shopGameStatuses;
this.isShop = true;
} else {
gameField.dropdown = this.props.gameStatuses;
this.isShop = false;
}
const selectedItem = {
3:
this.props.filters &&
gameField.dropdown.find((x) => parseInt(x.id) === parseInt(this.props.filters['filter.game'])),
};
return (
<>
{this.props.isLoadingCoupons && <Loader />}
<div className="user">
<Filter
filterFields={[...this.filterFields, ...additionalFilters]}
info
setFilterData={this.props.setFilterData}
search={this.getCoupons}
selectedMenuItem={this.props.location.pathname}
filters={this.filters}
defaultFilter={this.defaultFilter}
initialApiCall={this.initialApiCall}
filtersProps={this.props.filters}
selectedItem={selectedItem}
clearFilterData={this.props.clearFilterData}
selectedTimezone={this.props.selectedTimezone}
dateFilterFields={this.filterFields[4]?.fields}
isSettledCouponsForMobile={this.couponsPage === COUPON_PAGES.SETTLED_COUPON_MOBILE}
resetExport={this.props.resetExport}
checkPermission={this.props.checkPermisson}
/>
<ScrollTable
loadMore={this.loadMore}
isFetched={this.props.isFetched || this.props.isLoadingCoupons}
isLastRecord={this.props.isLastRecord}
>
{!this.isSettled ? (
<PlacedCoupons
placedCoupons={this.placedCouponsData}
currency={this.props.currency}
selectedCouponId={this.props.selectedCoupon && this.props.selectedCoupon.id}
selectCoupon={this.props.selectCoupon}
hasRecord={this.props.hasRecord}
selectedTimezone={this.props.selectedTimezone}
gameStatuses={this.props.gameStatuses}
shopGameStatuses={this.props.shopGameStatuses}
isShop={this.isShop}
/>
) : (
<SettledCoupons
placedCoupons={this.settledCouponsData}
currency={this.props.currency}
selectedCouponId={this.props.selectedCoupon && this.props.selectedCoupon.id}
selectCoupon={this.props.selectCoupon}
hasRecord={this.props.hasRecord}
selectedTimezone={this.props.selectedTimezone}
gameStatuses={this.props.gameStatuses}
shopGameStatuses={this.props.shopGameStatuses}
isShop={this.isShop}
setOpenModal={this.props.setOpenModal}
activeModal={this.props.activeModal}
voidCouponRequest={this.props.voidCoupon}
setCouponToWontpayRequest={this.props.setCouponToWontpay}
checkPermisson={this.props.checkPermisson}
betStatus={this.props.betStatus}
sort={this.state.sort}
onSortColumn={this.sortColumn}
/>
)}
</ScrollTable>
</div>
{this.props.selectedCoupon && (
<CouponDetails
selectedCoupon={this.props.selectedCoupon}
currency={this.props.currency}
settled={this.isSettled}
betStatus={this.props.betStatus}
couponSource={this.props.couponSource}
/>
)}
</>
);
}
}
export default connect(mapToProps, actionsToProps)(withRouterHooks(Coupons));