UNPKG

sportsbet-mobile

Version:
497 lines (445 loc) 12.3 kB
/// <reference path=".#ts/client.d.ts" /> module Betting { export interface BetSlipState { type: string; message?: string; positive?: boolean; } export interface BetSlipBet { id: string; time: Date; eventId: string; eventName: string; marketId: string; marketName: string; selection: string; selectionId: number; selectionName: string; specialBetValue: string; odds: number; state: BetSlipState stake: number; oldOdds?: number; changed?: boolean; } Tracker.autorun(function () { var bets = getBetSlip(); bets.forEach(function (bet: BetSlipBet) { if (bet.state && ['closing', 'success', 'processing'].indexOf(bet.state.type) !== -1) { if (bet.state.type === 'processing') { var selection = Betting.Selection.db.findOne(bet.selection); if (selection.backOddsMultiplied() !== bet.odds) { bet.odds = selection.backOddsMultiplied(); setBetSlip(bets); } } return; } // status change var event = Betting.Event.db.findOne(bet.eventId); var market = Betting.Market.db.findOne(bet.marketId); var selection = Betting.Selection.db.findOne(bet.selection); if ((!event || !market || !market.active || !selection || !selection.active)) { var subject: string; if (!event || event.status !== EventStatus.OPEN) { subject = 'event'; } else if (!market || !market.active) { subject = 'market' } else if (!selection || !selection.active) { subject = 'selection' } var message = `This ${subject} is suspended`; if (!bet.state || bet.state.type !== 'suspended' || bet.state.message !== message) { bet.state = { type: 'suspended', message: message }; setBetSlip(bets); } } else if (selection && selection.active && (bet.state && bet.state.type === 'suspended')) { bet.state = null; setBetSlip(bets); } // odds change if (!selection) { return; } //if (selection.backOdds !== bet.odds) { if (selection.backOddsMultiplied() !== bet.odds) { if (!bet.state || bet.state.type !== 'suspended') { bet.state = { type: 'changed', //positive: selection.backOdds > bet.odds positive: selection.backOddsMultiplied() > bet.odds }; } bet.oldOdds = bet.odds; //bet.odds = selection.backOdds; bet.odds = selection.backOddsMultiplied(); setBetSlip(bets); } }); }); export function addToRejectedBets(selections, betId) { var rejectedBets = Session.get('rejectedBets'); if (!rejectedBets) { rejectedBets = {}; } var matchedBetIndex = ''; var matchedBet = _.find(rejectedBets, function (betSelections: any, rejectedBet: any) { matchedBetIndex = rejectedBet; var compared = compareSelections(selections, betSelections); return compared; }); if (matchedBet) { delete rejectedBets[matchedBetIndex]; } if (!rejectedBets[betId]) { rejectedBets[betId] = selections; } Session.set('rejectedBets', rejectedBets); } export function getBetSlip(): BetSlipBet[] { return Session.get('sportsBetSlip') || []; } export function setBetSlip(bets: BetSlipBet[]) { Session.set('sportsBetSlip', bets); } export function isMultibet(): boolean { return Session.get('sportsIsMultiBet'); } export function setMultibet(value: boolean) { Session.set('sportsIsMultiBet', value); } export function getMultiStake(): number { return Session.get('sportsMultiStake') || 0; } export function setMultiStake(stake: number) { stake = +(stake / 1000).toFixed(5); Session.set('sportsMultiStake', stake || ''); } export function getBetSlipState(): BetSlipState { return Session.get('sportsBetSlipState'); } export function setBetSlipState(value: BetSlipState) { Session.set('sportsBetSlipState', value); } export function setBetSlipBetState(value: string) { var bets = getBetSlip(); bets.forEach(function(bet){ bet.state.type = value; }); setBetSlip(bets); } export function addToBetSlip(selection: Selection) { var event = selection.event.fetch(); var market = selection.market.fetch(); var bets = getBetSlip(); // user cant set two bets in one market when selected multiple type for (let betItem of bets) { if (isMultibet() && market._id === betItem.marketId) { closeBet(betItem.selection); } if (isMultibet() && event._id === betItem.eventId) { closeBet(betItem.selection); } } var bet = <BetSlipBet>{ time: event.startTime, eventId: event._id, eventName: event.name, marketId: market._id, marketName: market.name, selection: selection._id, selectionId: selection.id, selectionName: selection.text(), specialBetValue: selection.specialBetValueText(), odds: selection.backOddsMultiplied(), state: { type: 'opening' }, stake: null }; bets.unshift(bet); setBetSlip(bets); selection.select(); // disabling alert message on more than one bet when switched to "multiple" type from "single" if (isMultibet() && bets.length > 1) { setBetSlipState(null); } var selectionId = bet.selection; Meteor.setTimeout(function () { var bets = getBetSlip(); var bet = _.find(bets, (bet: any) => { return bet.selection === selectionId; }); if (!bet) { return; } bet.state = null; setBetSlip(bets); }, 430); } export function acceptOdds(selectionId: string) { var bets = getBetSlip(); var bet = _.find(bets, (bet: any) => { return bet.selection === selectionId; }); bet.state = null; setBetSlip(bets); } export function deleteBet(selectionId: string): boolean { var bets = getBetSlip(); return !!_.find(bets, (bet: any) => { var found = bet.selection === selectionId; if (found) { bets.splice(bets.indexOf(bet), 1); setBetSlip(bets); Selection.db.unSelect(selectionId); //validateBets(); } return found; }); } export function getBet(selectionId: string) { return _.find(getBetSlip(), (bet: any) => { return bet.selection === selectionId; }); } export function closeBet(selectionId: string): boolean { var bets = getBetSlip(); var bet = _.find(bets, (bet: any) => { return bet.selection === selectionId; }); if (!bet) { return false; } Selection.db.unSelect(selectionId); bet.state = { type: 'closing' }; setBetSlip(bets); Meteor.setTimeout(function () { deleteBet(selectionId); }, 430); return true; } export function clearBetSlip() { setBetSlip([]); setBetSlipState(null); Selection.db.clearSelection(); } export function toggleBet(selection: Selection) { if (!closeBet(selection._id)) { addToBetSlip(selection); } } export function setBetStake(selectionId: string, stake: number) { stake = +(stake / 1000).toFixed(5); var bets = getBetSlip(); var bet = _.find(bets, (bet: any) => bet.selection === selectionId); if (!bet) { throw new Error('Bet not found from betslip: ' + selectionId); } bet.stake = stake; setBetSlip(bets); } export function getTotalStake() { var isMulti = isMultibet(); if (isMulti) { return getMultiStake(); } else { return getBetSlip().reduce((prev, cur) => prev + cur.stake, 0); } } export function placeBetAllowed() { if (!Meteor.userId()) { return false; } if (Session.get('clientCountry') == 'GB' || Session.get('clientCountry') == 'AU') { return false; } var state = getBetSlipState(); if (state && ['processing', 'closing', 'success', 'changed', 'suspended'].indexOf(state.type) !== -1) { return false; } var bets = getBetSlip(); if (!bets.length) { return false; } var isMulti = isMultibet(); var allStakesOk = !_.find(bets, function (bet: BetSlipBet) { return bet.stake > 0 && bet.stake < 0.0001; }); if (!isMulti && !allStakesOk) { return false; } if (isMulti && (getTotalStake() < 0.0001 || bets.length < 2)) { return false; } else { var last = !_.find(bets, function (bet: BetSlipBet) { if (!isMulti && !(bet.stake > 0)) { return true; } if (!bet.state) { return false; } return ['processing', 'closing', 'success', 'changed', 'pending'].indexOf(bet.state.type) !== -1; }); return last; } } export function clearAllowed() { var bets = getBetSlip(); if (!bets.length) { return false; } var state = getBetSlipState(); return (!state || state.type !== 'processing') || getBetSlip().length > 0; } export function getPotentialPayout() { var isMulti = isMultibet(); if (isMulti) { return getTotalOdds() * getMultiStake(); } else { return getBetSlip().reduce((prev, cur) => prev + cur.stake * cur.odds, 0) } } export function getTotalOdds() { return getBetSlip().reduce((prev, cur) => prev * cur.odds, 1); } function isFatal(err) { return ['odds_changed', 'over_limit', 'under_limit'].indexOf(err.reason) === -1; } export function placeBet() { if (!placeBetAllowed()) { return; } var isMulti = isMultibet(); var bets = getBetSlip(); if (!bets.length) { return; } setBetSlipState({ type: 'processing' }); bets.forEach(function (bet: BetSlipBet) { bet.state = {type: 'processing'}; }); setBetSlip(bets); if (isMulti) { var selectionIds = bets.map((x) => x.selectionId); Betting.Ticket.placeBetClient( { selectionIds, odds: bets.reduce((prev, cur) => prev * cur.odds, 1), stake: getMultiStake(), isMulti, altStakeRefTicketId: getAltStakeRefTicketId(selectionIds) }, function callback(err, res) { if (err) { localeError(err, 'betting'); bets.forEach(function (bet: BetSlipBet) { bet.state = null; }); setBetSlip(bets); setBetSlipState({ type: isFatal(err) ? 'error' : 'warning', message: err.localeMessage || removeErrCode(err.message) }); return; } bets.forEach(function (bet: BetSlipBet) { bet.id = res; bet.state = {type: 'success'}; }); setBetSlip(bets); $('.bet-done').show('slow', 'swing'); Meteor.setTimeout(function () { $('.bet-done').hide('slow', 'swing'); }, 6000); Meteor.setTimeout(function () { bets.forEach(function (bet: BetSlipBet) { closeBet(bet.selection); }); setMultiStake(0); clearBetSlip(); }, 100); } ); } else { var count = bets.length; bets.forEach(function (bet: BetSlipBet) { var selectionIds = [bet.selectionId]; Betting.Ticket.placeBetClient( { selectionIds, odds: bet.odds, stake: bet.stake, isMulti, altStakeRefTicketId: getAltStakeRefTicketId(selectionIds) }, function (err, res) { if (!--count) { setBetSlipState(null); } if (err) { localeError(err, 'betting'); setBetSlipState({ // type: isFatal(err) ? 'error' : 'warning', type: 'error', message: err.localeMessage || removeErrCode(err.message) }); bet.state = { // type: isFatal(err) ? 'error' : 'warning', type: 'error', message: err.localeMessage || removeErrCode(err.message) }; } else { bet.id = res; bet.state = { type: 'pending' }; $('.bet-done').show('slow', 'swing'); Meteor.setTimeout(function () { $('.bet-done').hide('slow', 'swing'); }, 6000); Meteor.setTimeout(function () { closeBet(bet.selection); clearBetSlip(); }, 100); } setBetSlip(bets); } ) ; }); } } function getAltStakeRefTicketId(selectionIds) { var rejectedBets = Session.get('rejectedBets'); var matchedBetIndex = ''; var matchedBet = _.find(rejectedBets, function (betSelections: any, rejectedBet: any) { matchedBetIndex = rejectedBet; return compareSelections(betSelections, selectionIds); }); return matchedBet ? matchedBetIndex.toString() : undefined; } function compareSelections(selections1, selections2) { return selections1.length === selections2.length && _.every(selections1, function (selection: any) { return selections2.indexOf(selection) !== -1; }); } function removeErrCode(message) { return message.replace(/\s+\[[45][0-9]{2}\]/, ''); } }