/* eslint-disable no-param-reassign */
/**
* @namespace utils/parsers
*/
import { newObjectRef, getSelectionName, calulatePlacedSelection } from './common';
import Constants, { COUNTRY_TIMEZONE, COUNTRY_OFFSET, ROUNDING_DECIMAL_VALUE } from '../constants';
/**
* Adding index as market.id in markets array
*
* @memberof utils/parsers
* @param {Array} markets
* @param {number} correctScoreIndex
* @returns {Array}
*/
export function parseMarkets(markets, correctScoreIndex) {
return markets.map((m, _i) => {
if (_i === correctScoreIndex) {
m.correctScore = true;
}
m.enabled = 1; return m;
});
}
/**
* Parse odds
*
* @memberof utils/parsers
* @param {Array} odds
* @param {Array<string>} activeSelections
* @returns {object}
*/
export function parseOdds(odds, activeSelections) {
const odds4D = [];
odds.forEach((oddsString, i) => {
const selections = activeSelections[i].split('-');
const oddsPerMatches = oddsString.split('|');
const oddsPerMatch = [];
oddsPerMatches.map((o) => {
const matchOdds = o.split('-');
const oddsPerSelections = {};
matchOdds.map((odd, index) => {
// check existation of selections[index]
oddsPerSelections[selections[index]] = odd;
});
oddsPerMatch.push(oddsPerSelections);
});
odds4D.push(oddsPerMatch);
});
return odds4D;
}
/**
* Parse matches
*
* @memberof utils/parsers
* @param {string} matchesString
* @returns {Array}
*/
export function parseMatches(matchesString) {
const matches = matchesString.split ? matchesString.split('|') : [];
return matches[0] !== '' ? matches : [];
}
/**
* Get team names from match
*
* @memberof utils/parsers
* @param {string} matchString
* @returns {Array}
*/
export function parseCompetitors(matchString) {
return matchString.split('-');
}
/**
* Parse number as currency. For example 9,999,999
*
* @memberof utils/parsers
* @function
* @param {number} value
* @returns {string}
*/
export const parseNum = (value) => (
(value / 100).toFixed(0).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')
);
/**
* Round number up and add 0.000001 to avoid js errors
*
* @memberof utils/parsers
* @function
* @param {number} value
* @returns {string}
*/
export const roundNum = (value) => (
(Math.round(value + ROUNDING_DECIMAL_VALUE))
);
/**
* Parse date in format DD/MM/YYYY, time in format hh:mm and seconds in format ss
*
* @memberof utils/parsers
* @param {Time} dateString
* @example 2020-04-27T09:18:02Z
* parsed to {
* date: "27/04/2020"
* time: "09:18"
* seconds: "02"
* }
* @returns {object} Parsed date and time
*/
export function getDateTime(dateString) {
const dateTime = dateString.split('T');
const date = dateTime[0].split('-');
const time = dateTime[1].replace('Z', '').split(':');
return ({
date: `${date[2]}/${date[1]}/${date[0]}`,
time: `${time[0]}:${time[1]}`,
seconds: time[2],
});
}
/**
* Parse date in format DD/MM/YYYY, time in format hh:mm:ss with selected country time zone
*
* @memberof utils/common
* @param {Time} dateString
* @example 2020-04-27T09:18:02Z
* parsed to "27/04/2020 09:18:02"
* @returns {string} Parsed date and time
*/
export function getCountryDateTime(dateString) {
if (dateString) {
const timezone = COUNTRY_TIMEZONE[process.env.BUNDLE_SKIN];
const offset = new Date().getTimezoneOffset();
const localDateTime = new Date(dateString.replace(/z/gi, ''))
.setMinutes(new Date(dateString).getMinutes() - offset);
const dateTime = new Date(localDateTime).toLocaleString('en-GB', { timeZone: timezone });
const dateTimeArr = dateTime.split(',');
const date = dateTimeArr[0].split('/');
const time = dateTimeArr[1].split(':');
return ({
date: `${date[2]}/${date[1]}/${date[0]}`,
time: `${time[0]}:${time[1]}`,
seconds: time[2],
});
}
return '';
}
/**
* get javascript date object in nigeria time
*
* @memberof utils/common
* @param {string} country
* @param {Time} date
* @returns {string} Parsed date and time
*/
export function getCountryNewDate(country, date) {
if (!country) {
return '';
}
const offset = new Date().getTimezoneOffset();
const countryOffset = offset + COUNTRY_OFFSET[country].OFFSET;
const countryDate = date ? new Date(date) : new Date();
return new Date(Date.UTC(countryDate.getUTCFullYear(),
countryDate.getUTCMonth(), countryDate.getUTCDate(),
countryDate.getUTCHours(), countryDate.getUTCMinutes()
+ countryOffset, countryDate.getUTCSeconds()));
}
/**
* get javascript date object in country time from utc time
*
* @memberof utils/common
* @param {string} countryOffset
* @param {Time} date
* @example 2020-04-27T09:18:02Z
* parsed to "27/04/2020 09:18:02"
* @returns {string} Parsed date and time
*/
export function getCountryDateFromUTC(countryOffset, date) {
return new Date(date)
.setMinutes(new Date(date).getMinutes() + countryOffset);
}
/**
* Parse League Table statistic
*
* @memberof utils/parsers
* @param {string} teamsTableString
* @returns {Array}
*/
export function parseTeamStatistic(teamsTableString) {
const teamsArray = parseMatches(teamsTableString);
const teams = [];
teamsArray.map((team) => {
const dataPerTeam = parseCompetitors(team);
teams.push({
name: dataPerTeam[0],
points: dataPerTeam[1],
lastFive: dataPerTeam[2].split(''),
});
});
return teams;
}
/**
* Parse placed bets.
* One selection code skelet leagueId:matchIndex:selectionId:oddValue
*
* @memberof utils/parsers
* @param {Array} selections
* @param {Array} markets
* @returns {object}
*/
export function getPlacedBetsResults(selections, markets) {
if (selections.length === 0) return null;
const placedSelections = {};
selections.map((sel) => {
const s = sel.split(':');
const leagueId = s[0];
const matchId = parseInt(s[1]) - 1;
const selectionId = s[2];
const odd = s[3];
if (!placedSelections[leagueId]) {
placedSelections[leagueId] = {};
}
if (!placedSelections[leagueId][matchId]) {
placedSelections[leagueId][matchId] = [];
}
const selection = getSelectionName(selectionId, markets);
selection.id = selectionId;
if (placedSelections[leagueId][matchId].findIndex((e) => (
e.selection.id === selectionId)) === -1) {
placedSelections[leagueId][matchId].push({
colorId: Constants.COLOR_IDS.LOSE,
selection,
odd,
});
}
});
return placedSelections;
}
/**
* Adding new placed selection in object of placed selections
*
* @memberof utils/parsers
* @param {object} currentSelections
* @param {object} newPlacedSelections
* @param {Array} markets
* @returns {object}
*/
export function parsePlacedSelections(currentSelections, newPlacedSelections, markets) {
const placedSelections = newPlacedSelections;
const newPlacedBets = getPlacedBetsResults(currentSelections, markets);
Object.keys(newPlacedBets).map((league) => {
Object.keys(newPlacedBets[league]).map((match) => {
if (placedSelections[league]) {
if (placedSelections[league][match]) {
let current = placedSelections[league][match];
const unique = newPlacedBets[league][match].filter((e) => (
current.findIndex((c) => c.selection.name === e.selection.name)) === -1);
current = current.concat(unique);
placedSelections[league][match] = current;
} else {
placedSelections[league][match] = newPlacedBets[league][match];
}
} else {
placedSelections[league] = {
[match]: newPlacedBets[league][match],
};
}
});
});
return placedSelections;
}
/**
* Parse timeline into minutes for one league
*
* @memberof utils/parsers
* @param {string} timelineString
* @returns {object}
*/
export function parseTimeline(timelineString) {
const timelineArray = timelineString.split('|');
const timeline = {};
timelineArray.map((t) => {
const minutes = t.split(':');
timeline[minutes[0]] = minutes[1];
});
return timeline;
}
/**
* Parse timeline into minutes for one league
* 0: "0:0&3:1&0:6&1:1&1:0&0:0&1:2&1:2&2:1&1:0"
*
* @memberof utils/parsers
* @param {string} timelineString
* @returns {object}
*/
export function parseTurboTimeline(timelineString) {
const timelineArray = timelineString.split('&');
const timeline = [];
timelineArray.map((t) => {
const scores = t.split(':');
timeline.push(scores[0]);
timeline.push(scores[1]);
});
return timeline;
}
/**
* Seting placed selection changes, scores and blink data
*
* @memberof utils/parsers
* @param {string} minuteString
* @param {number} leagueIndex
* @param {boolean} showBlink
* @param {object} placedSelectionsLive
* @param {object} blink
* @param {object} scores
* @param {Array} blinksForRemove
* @returns {object}
*/
export function parseTimelineResults(
minuteString,
leagueIndex,
showBlink,
placedSelectionsLive,
blink,
scores,
blinksForRemove,
) {
if (minuteString) {
const teams = minuteString.split('-');
for (let j = 0; j < teams.length; j += 1) {
const teamObj = teams[j].split('^');
const team = parseInt(teamObj[0]) - 1;
let otherTeam;
let score;
const matchId = Math.floor(parseInt(team) / 2);
if (team % 2 === 0) {
otherTeam = team + 1;
score = `${scores[leagueIndex][team] + 1}:${scores[leagueIndex][otherTeam]}`;
} else {
otherTeam = team - 1;
score = `${scores[leagueIndex][otherTeam]}:${scores[leagueIndex][team] + 1}`;
}
if (placedSelectionsLive) {
placedSelectionsLive = calulatePlacedSelection(
placedSelectionsLive,
leagueIndex,
matchId,
score,
);
}
if (showBlink) {
blink[leagueIndex][team] = true;
blinksForRemove.push({ l: leagueIndex, t: team });
}
scores[leagueIndex][team] += 1;
}
}
return {
placedSelectionsLive,
blink,
scores,
blinksForRemove,
};
}
/**
* Parse ticket bets.
*
* @memberof utils/parsers
* @param {string} betData [bet_type|leagueId:matchIndex:selectionId|stake -ex:
* "2|2:6:133$3:1:128|20000" ],
* combination stake [ -ex: "3|1:3:102$1:4:102$1:5:102|2:200&3:500&4:1000&T:310000" ]
* @param {string} betDetail [match:odd:score:win/lost$another_match|minOdd-maxOdd|winnings -ex:
* "ABC-DEF:2.15:0-1:1$GHI-JKL:1.85:2-1:1|1.85-11.63|1:64000&2:380000" ],
* @param {Array} markets
* @see {@link https://docs.google.com/document/d/1NZAkDBrMDwEZvmUvc3eee3rebHHzuVYARWeHzoKwJ0E/edit#heading=h.f5gov45epmd1}
* @returns {object}
*/
function parseBets(betData, betDetail, markets) {
const detail = betDetail.split('|');
let minOdd;
let maxOdd;
const matches = detail[0].split('$');
if (detail[1]) {
const odds = detail[1].split('-');
minOdd = odds[0] ? parseFloat(odds[0]).toFixed(2) : odds[0];
maxOdd = odds[1] ? parseFloat(odds[1]).toFixed(2) : odds[1];
}
let winningString;
const winningData = {};
if (detail[2]) {
winningString = detail[2].split('&');
winningString.map((win) => {
const winData = win.split(':');
winningData[winData[0]] = winData[1];
});
}
const bData = betData.split('|');
const type = bData[0];
const selectionsString = bData[1];
const selections = selectionsString.split('$');
const stakeString = bData[2].split('&');
const combinations = {};
stakeString.map((stake, i) => {
if (i < stakeString.length - 1) {
const s = stake.split(':');
combinations[s[0]] = s[1];
}
});
const bets = [];
matches.map((matchString, i) => {
const match = matchString.split(':');
const selection = selections[i].split(':');
bets.push({
match: match[0],
selection: getSelectionName(selection[2], markets),
matchId: selection[1],
odd: match[1] ? parseFloat(match[1]).toFixed(2) : match[1],
score: match[2],
status: match[3],
league: selection[0],
});
});
return {
type,
minOdd,
maxOdd,
numberOfBets: matches.length,
bets,
combinations,
winningData,
winningString,
};
}
/**
* Parsed tickets list per date
*
* @memberof utils/parsers
* @param {Array} bets
* @param {Array} markets
* @param {object} prevBets
* @param {object} selectedTicket
* @param {Array} prevDates
* @param {boolean} updTickets
* @returns {object}
*/
export function parseTicketData(bets, markets, prevBets, selectedTicket, prevDates, updTickets) {
const newBets = prevBets;
const dates = prevDates;
let newSelectedTicket = selectedTicket;
bets.map((bet) => {
const dateTime = getCountryDateTime(bet.placed);
if (!newBets[dateTime.date]) {
newBets[dateTime.date] = [];
dates.push(dateTime.date);
}
const parsedBets = parseBets(bet.betdata, bet.betdetails, markets);
const betData = {};
Object.assign(
betData,
bet,
parsedBets,
{
date: dateTime.date,
time: dateTime.time,
},
);
if (newSelectedTicket && betData.id === newSelectedTicket.id) {
newSelectedTicket = betData;
}
if (updTickets) {
const index = newBets[dateTime.date].findIndex((b) => b.id === betData.id);
if (index !== -1) {
newBets[dateTime.date][index] = betData;
} else {
newBets[dateTime.date].push(betData);
}
} else {
newBets[dateTime.date].push(betData);
}
});
return { tickets: newObjectRef(newBets), selectedTicket: newSelectedTicket, dates };
}
/**
* Parse selected market
*
* @memberof utils/parsers
* @param {Array} market
* @returns {object}
*/
export function parseSelectedMarket(market) {
const selectedMarket = newObjectRef(market);
selectedMarket.selections = market.submarkets
? Object.keys(market.submarkets[0].selections)
: Object.keys(market.selections);
return selectedMarket;
}
/**
* Check if any selection exist in odds
*
* @memberof utils/parsers
* @param {object} selections
* @param {object} odds
* @returns {boolean}
*/
function findSelection(selections, odds) {
let enabled = 0;
Object.keys(selections).map((s) => {
if (odds[s]) {
enabled = 1;
}
});
return enabled;
}
/**
* Set flag enable on markets
*
* @memberof utils/parsers
* @param {Array} markets
* @param {object} odds Odds of first match of selected league
* @returns {object}
*/
export function setActiveMarkets(markets, odds) {
markets.map((m) => {
if (!m.submarkets) {
m.enabled = findSelection(m.selections, odds);
} else {
m.enabled = 0;
m.submarkets.map((sm) => {
sm.enabled = findSelection(sm.selections, odds);
m.enabled = m.enabled || sm.enabled;
});
}
});
const activeMarkets = markets.filter((m) => (m.enabled === 1));
return ({
markets,
activeMarkets,
selectedMarket: parseSelectedMarket(activeMarkets[0]),
});
}
/**
* Set flag enable on markets
*
* @memberof utils/parsers
* @param {number} bigNum
* @returns {string}
*/
export function parseBigNums(bigNum) {
if (bigNum.toString().indexOf('e') === -1) {
return bigNum;
}
// take everything before 'e', split with '.' and join with '' to remove decimal dot
return `${(bigNum.toString().split('e')[0]).split('.').join('')}...`;
}