sportsbet-mobile
Version:
Sportsbet mobile
497 lines (445 loc) • 12.3 kB
text/typescript
/// <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}\]/, '');
}
}