class Api::V1::BetsController < Api::AuthenticatedApiController include ApplicationHelper include Pagy::Backend skip_before_action :authenticate_user!, only: %i[add_placed_bet tips] skip_before_action :verify_authenticity_token, only: %i[add_placed_bet tips] def index exchange_account = params[:exchange_account_id].blank? ? ExchangeAccount.mounted_account : ExchangeAccount.find(params[:exchange_account_id]) bets = filter_by_date_range(exchange_account.my_bets, 'created_at') bets = bets.where(outcome: params[:outcome]) unless params[:outcome].blank? bets = bets.where("exchange_event_name ILIKE '%%#{params[:event_name]}%%'") unless params[:event_name].blank? ev_range = params[:expected_value] if ev_range.present? v_symbolize = JSON.parse(ev_range).symbolize_keys bets = bets.where("expected_value >= #{v_symbolize[:min]} AND expected_value <= #{v_symbolize[:max]}") end # add additional filters later # summary = summary_dashboard(exchange_account, bets) pagy, bets = pagy(bets) pagy_json = pagy_metadata(pagy) render json: { summary: summary, pagy: pagy_json, bets: bets.order(created_at: :desc).map(&:json_payload) } end def add_placed_bet # push a placed bet from an authenticated client wpb = 'WEB_PLACED_BETS' ex = ExchangeAccount.find_by(id: wpb) stake = (params['stake'] || 0).to_f executed_odds = (params['odds_accepted'] || 0).to_f record = { tip_provider_id: 'betburger', tip_provider_bet_id: params['betburger_bet_id'], tip_provider_percent: (params['value_bet_ev_percent'] || 0).to_f, tip_provider_odds: (params['original_odds'] || 0).to_f, team1: "Not Set", team2: "Not Set", exchange_id: params['bookmaker'], exchange_event_name: params['match'], exchange_market_details: {market: params['market'], selection: params['selection']}, stake: stake, executed_odds: executed_odds, expected_value: Bet.calculate_expected_value(stake, executed_odds), original_json: params.to_json, outcome: {'Bet placed': 'open', 'Odds changed': 'expired'}[params['placer_result']] || 'skipped', log: [params['placer_result']], } ex.my_bets.create(record) render json: { success: true } end def tips id = params[:id] resp = { success: false } ts = id.nil? ? nil : TipSource.find_by(id: id) if ts resp[:success] = true latest_source_data = ts.tip_source_data.latest resp[:data] = latest_source_data.blank? ? {} : latest_source_data.data else resp[:message] = 'Unknown tip source requested' end render json: resp end def summary_dashboard(exchange_account, bets) { exchange_account: exchange_account.json_payload, total_win_amount: exchange_account.total_won(bets), total_lost_amount: exchange_account.total_lost(bets), total_risked_amount: exchange_account.total_open(bets), total_tips: bets.count, total_tips_skipped: bets.skipped.count, total_tips_processing: bets.processing.count, total_tips_expired: bets.expired.count, total_tips_ignored: bets.ignored.count, total_tips_voided: bets.voided.count, total_placed_bets: bets.placed_bets.count, total_placed_bets_won: bets.won.count, total_placed_bets_lost: bets.lost.count, total_placed_bets_open: bets.open.count, average_odds_won: odd_averages(bets.won), average_odds_lost: odd_averages(bets.lost), average_odds: odd_averages(bets), running_since: exchange_account.my_bets.minimum(:created_at) || exchange_account.created_at, } end def odd_averages(bets) return 0 if bets.count.zero? total_odds = 0 bets.map { |b| total_odds += b.tip_provider_odds.to_f } (total_odds / bets.count).round(2) end end