diff --git a/app/Filament/Pages/Selections/Helper/GetSeason.php b/app/Filament/Pages/Selections/Helper/GetSeason.php index 5e275bb5..f1f705ed 100644 --- a/app/Filament/Pages/Selections/Helper/GetSeason.php +++ b/app/Filament/Pages/Selections/Helper/GetSeason.php @@ -6,18 +6,19 @@ use Illuminate\Support\Carbon; class GetSeason { - public static function load(array|null $season, string|null $seasonmode) + public static function load(?array $season, ?string $seasonmode) { - if (!\is_array($season) || !\count($season)) { + if (! \is_array($season) || ! \count($season)) { $date = Carbon::now(); $season = []; if ($seasonmode == 'halfyear') { - if ((int) date('m') > 7) - $season[] = (string) $date->format('y') . '/' . $date->format('y') + 1; - else - $season[] = (string) $date->format('y') - 1 . '/' . $date->format('y'); + if ((int) date('m') > 7) { + $season[] = (string) $date->format('y').'/'.$date->format('y') + 1; + } else { + $season[] = (string) $date->format('y') - 1 .'/'.$date->format('y'); + } } else { $season[] = (string) $date->year; } @@ -25,4 +26,23 @@ class GetSeason return $season; } + + public static function active(?string $seasonmode) + { + + $date = Carbon::now(); + + $active_season = ''; + if ($seasonmode == 'halfyear') { + if ((int) date('m') > 7) { + $active_season = (string) $date->format('y').'/'.$date->format('y') + 1; + } else { + $active_season = (string) $date->format('y') - 1 .'/'.$date->format('y'); + } + } else { + $active_season = (string) $date->year; + } + + return $active_season; + } } diff --git a/app/Filament/Pages/Selections/LoadPlayerSelection.php b/app/Filament/Pages/Selections/LoadPlayerSelection.php index 122f6764..dcad23bb 100644 --- a/app/Filament/Pages/Selections/LoadPlayerSelection.php +++ b/app/Filament/Pages/Selections/LoadPlayerSelection.php @@ -3,7 +3,6 @@ namespace App\Filament\Pages\Selections; use App\Filament\Pages\Selections\Helper\GetSeason; -use App\Models\SofaScorePlayerCache; use App\Models\SofaScorePlayerPerSeason; use App\Models\StatistikoEvent; @@ -13,11 +12,11 @@ class LoadPlayerSelection { $season = GetSeason::load($season, $seasonmode); - $hash = hash('crc32', $team_id.$team_position.$sofascore_category_id.serialize($season)); - $cached_players = SofaScorePlayerCache::where('hash', $hash)->value('players'); - if ($cached_players) { - return $cached_players; - } + // $hash = hash('crc32', $team_id.$team_position.$sofascore_category_id.serialize($season)); + // $cached_players = SofaScorePlayerCache::where('hash', $hash)->value('players'); + // if ($cached_players) { + // return $cached_players; + // } $matches = StatistikoEvent::whereIn('season', $season) ->where(function ($query) use ($team_id, $team_position) { @@ -92,25 +91,28 @@ class LoadPlayerSelection $position = 'NO SPECIFIC POSITION'; } - $infostring = $events_played.' Ev'; - if ($val['preferred_foot']) { - $infostring .= ' - '.$val['preferred_foot']; - } - if ($events_played) { - $infostring .= ' - '.round($minues_played / $events_played).'min'; - } + $infostring = ''; + if ($colorlevel > 1 && $events_played < $colorlevel) { - $result[$position][$player_id] = ''.$val['player_name'].' '.$position.'
'.$infostring.'
'; + $infostring = '
'; } elseif ($events_played < $colorlevel * 2) { - $result[$position][$player_id] = ''.$val['player_name'].' '.$position.'
'.$infostring.'
'; + $infostring = '
'; } else { - $result[$position][$player_id] = ''.$val['player_name'].' '.$position.'
'.$infostring.'
'; + $infostring = '
'; } + $infostring .= '
'.$val['player_name'].' '.$val['player_position'].'
'; + $infostring .= '
'.$events_played.' Events,
'; + $infostring .= '
'.$val['preferred_foot'].' foot,
'; + if ($events_played) { + $infostring .= '
Av. on field '.round($minues_played / $events_played).'min
'; + } + $infostring .= '
'; + $result[$position][$player_id] = $infostring; } - if ($result) { - SofaScorePlayerCache::updateOrCreate(['hash' => $hash], ['players' => $result]); - } + // if ($result) { + // SofaScorePlayerCache::updateOrCreate(['hash' => $hash], ['players' => $result]); + // } return $result; } diff --git a/app/Filament/Pages/Statistic.php b/app/Filament/Pages/Statistic.php index 8053ebcd..9fb2110e 100644 --- a/app/Filament/Pages/Statistic.php +++ b/app/Filament/Pages/Statistic.php @@ -22,9 +22,9 @@ use Filament\Pages\Dashboard\Concerns\HasFiltersForm; use Filament\Schemas\Components\Grid; use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Components\Utilities\Set; -use Filament\Schemas\Schema; // use Filament\Support\Enums\SlideOverPosition; // use Filament\Support\Enums\Width; +use Filament\Schemas\Schema; use Filament\Support\RawJs; use Illuminate\Contracts\Support\Htmlable; use Illuminate\Contracts\View\View; @@ -181,6 +181,14 @@ class Statistic extends BaseDashboard $this->dispatch('reset-tab'); }) ->placeholder('Select Event'), + Action::make('esc') + ->hiddenLabel() + ->visible(fn (Get $get) => $get('similar_past_matches') != 'none') + ->tooltip('Clear all (esc)') + ->icon('phosphor-x-circle') + ->color('gray') + ->keyBindings(['esc']) + ->action('resetFilters'), Select::make('team_id') ->live() @@ -240,7 +248,7 @@ class Statistic extends BaseDashboard Grid::make([ 'default' => 1, 'sm' => 3, - 'md' => 4, + 'md' => 5, ]) ->columnSpanFull() ->schema([ @@ -332,7 +340,9 @@ class Statistic extends BaseDashboard ->live() ->hiddenLabel() ->allowHtml() + ->columnSpan(2) ->placeholder('Player') + ->visible(fn (Get $get) => $get('team_id')) ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') ->prefixIconColor(fn (Get $get): string => $get('similar_past_matches') == 'none' ? 'success' : '') ->prefixIcon('icon-player') @@ -371,9 +381,10 @@ class Statistic extends BaseDashboard ]), ]), Grid::make([ - 'default' => 4, - 'sm' => 4, + 'default' => 7, + 'sm' => 7, ]) + ->columnSpanFull() ->schema([ Radio::make('season_or_date') ->live() @@ -381,10 +392,7 @@ class Statistic extends BaseDashboard 'class' => 'radio-statistic-group', ]) ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') - ->columnSpan([ - 'default' => 4, - 'sm' => 4, - ]) + ->columnSpan(2) ->inline() ->default('season') ->hiddenLabel() @@ -392,86 +400,88 @@ class Statistic extends BaseDashboard 'season' => 'Season', 'date' => 'Date', ]), + /************************ + * SEASON full time + ************************/ + Select::make('season') + ->live() + ->columnSpan(2) + ->hiddenLabel() + ->multiple() + ->placeholder('Current Season') + ->prefixIconColor('success') + ->visible(fn (Get $get) => $get('seasonmode')) + ->hidden(fn (Get $get) => $get('seasonmode') == 'halfyear' || $get('season_or_date') == 'date' || $get('similar_past_matches') != 'none') + ->prefixIcon('phosphor-calendar-star-fill') + ->options([ + '2026' => '2026', + '2025' => '2025', + '2024' => '2024', + ]) + ->afterStateUpdated(function (callable $set, Get $get) { + $set('ss_player_id', null); + }), + /************************ + * SEASON half time + ************************/ + Select::make('season') + ->live() + ->columnSpan(2) + ->hiddenLabel() + ->multiple() + ->placeholder('Current Season') + ->prefixIconColor('success') + ->visible(fn (Get $get) => $get('seasonmode')) + ->hidden(fn (Get $get) => $get('seasonmode') == 'fullyear' || $get('season_or_date') == 'date' || $get('similar_past_matches') != 'none') + ->prefixIcon('phosphor-calendar-star-fill') + ->options([ + '26/27' => '26/27', + '25/26' => '25/26', + '24/25' => '24/25', + ]) + ->afterStateUpdated(function (callable $set) { + $set('ss_player_id', null); + }), + /************************ + * DATE PICKER + ************************/ + DatePicker::make('start_date') + ->live() + ->hiddenLabel() + ->hidden(fn (Get $get) => $get('season_or_date') == 'season') + ->native(false) + ->prefixIconColor(fn (Get $get): string => $get('start_date') ? 'success' : 'primary') + ->prefixIcon('phosphor-calendar-fill') + ->prefix('Start') + ->suffixAction( + Action::make('clear_start') + ->icon('phosphor-x') + ->color('gray') + ->action(fn (Set $set) => $set('start_date', null)) + ), + DatePicker::make('end_date') + ->live() + ->hiddenLabel() + ->hidden(fn (Get $get) => $get('season_or_date') == 'season') + ->native(false) + ->prefixIconColor(fn (Get $get): string => $get('end_date') ? 'success' : 'primary') + ->prefixIcon('phosphor-calendar-fill') + ->prefix('End') + ->suffixAction( + Action::make('clear_end') + ->icon('phosphor-x') + ->color('gray') + ->action(fn (Set $set) => $set('end_date', null)) + ), + Action::make('esc') + ->hiddenLabel() + ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') + ->tooltip('Clear all (esc)') + ->icon('phosphor-x-circle') + ->color('gray') + ->keyBindings(['esc']) + ->action('resetFilters'), ]), - - /************************ - * SEASON fulltime - ************************/ - Select::make('season') - ->live() - ->columns(2) - ->hiddenLabel() - ->multiple() - ->placeholder('Current Season') - ->prefixIconColor('success') - ->hidden(fn (Get $get) => $get('seasonmode') == 'halfyear' || $get('season_or_date') == 'date' || $get('similar_past_matches') != 'none') - ->prefixIcon('phosphor-calendar-star-fill') - ->options([ - '2026' => '2026', - '2025' => '2025', - '2024' => '2024', - ]) - ->afterStateUpdated(function (callable $set, Get $get) { - $set('ss_player_id', null); - }), - /************************ - * SEASON halftime - ************************/ - Select::make('season') - ->live() - ->columns(2) - ->hiddenLabel() - ->multiple() - ->placeholder('Current Season') - ->prefixIconColor('success') - ->hidden(fn (Get $get) => $get('seasonmode') == 'fullyear' || $get('season_or_date') == 'date' || $get('similar_past_matches') != 'none') - ->prefixIcon('phosphor-calendar-star-fill') - ->options([ - '26/27' => '26/27', - '25/26' => '25/26', - '24/25' => '24/25', - ]) - ->afterStateUpdated(function (callable $set) { - $set('ss_player_id', null); - }), - /************************ - * DATE PICKER - ************************/ - DatePicker::make('start_date') - ->live() - ->hiddenLabel() - ->hidden(fn (Get $get) => $get('season_or_date') == 'season') - ->native(false) - ->prefixIconColor(fn (Get $get): string => $get('start_date') ? 'success' : 'primary') - ->prefixIcon('phosphor-calendar-fill') - ->prefix('Start') - ->suffixAction( - Action::make('clear_start') - ->icon('phosphor-x') - ->color('gray') - ->action(fn (Set $set) => $set('start_date', null)) - ), - DatePicker::make('end_date') - ->live() - ->hiddenLabel() - ->hidden(fn (Get $get) => $get('season_or_date') == 'season') - ->native(false) - ->prefixIconColor(fn (Get $get): string => $get('end_date') ? 'success' : 'primary') - ->prefixIcon('phosphor-calendar-fill') - ->prefix('End') - ->suffixAction( - Action::make('clear_end') - ->icon('phosphor-x') - ->color('gray') - ->action(fn (Set $set) => $set('end_date', null)) - ), - Action::make('esc') - ->hiddenLabel() - ->tooltip('Clear all (esc)') - ->icon('phosphor-x-circle') - ->color('gray') - ->keyBindings(['esc']) - ->action('resetFilters'), ]); } diff --git a/app/Filament/Widgets/BoxesBettypeAll.php b/app/Filament/Widgets/BoxesBettypeAll.php new file mode 100644 index 00000000..17f857bb --- /dev/null +++ b/app/Filament/Widgets/BoxesBettypeAll.php @@ -0,0 +1,189 @@ +filters = $filters; + } + + protected function getStats(): array + { + $data = LoadEventsBoxes::load($this->filters, false); + + $similar_past_matches = $this->filters['similar_past_matches']; + $team_position = $this->filters['team_position']; + + $team_position = in_array($this->filters['team_position'], ['home', 'away']) ? ucfirst($this->filters['team_position']) : 'Both Position'; + + if (! $data) { + return []; + } + + // BOX TOTAL + $count_events = $data['count_events']; + $boxes = []; + $boxes[] = Stat::make('Total', self::template_total($count_events)) + ->description(fn () => $similar_past_matches == 'all' ? 'SPM Database' : 'SPM League') + ->extraAttributes(['x-init' => "animate('number-of-events', $count_events);", 'class' => 'box-info justify-center']); + + // BOX 1X2 + $win = $data['win_odd']; + $draw = $data['draw_odd']; + $lost = $data['lost_odd']; + $boxes[] = Stat::make('Odds', self::template_odds($data, $win, $draw, $lost)) + ->description('Expectations') + ->extraAttributes(['x-init' => "animate('win', $win, 2); animate('draw', $draw, 2); animate('lost', $lost, 2)", 'class' => 'box-purple']); + + // BOX EXPECTED + if (isset($data['gls'])) { + $boxes[] = Stat::make('Expected', self::template_tabelle_1($data)) + ->extraAttributes(['class' => 'box-gray']) + ->description('Home - Away'); + } + + // BOX AVERAGE + if (isset($data['gls_team'])) { + $boxes[] = Stat::make('Average '.$data['active_team'], self::template_tabelle_2($data)) + ->extraAttributes(['class' => 'box-success']) + ->description($team_position); + } + + // BOX AVERAGE WITH TEAM FIXED TO ACTIVE SEASON + if (isset($data['gls_team_season'])) { + $boxes[] = Stat::make('Average '.$data['active_team'], self::template_tabelle_3($data)) + ->extraAttributes(['class' => 'box-yellow']) + ->description('Season '.$data['active_season']); + } + // BOX AVERAGE ALL LEAGUE FIXED TO ACTIVE SEASON + if (isset($data['gls_liga_season'])) { + $boxes[] = Stat::make('League Average', self::template_tabelle_4($data)) + ->extraAttributes(['class' => 'box-yellow']) + ->description('Season '.$data['active_season']); + } + + $this->columns = [ + 'default' => 1, + 'sm' => 2, + 'md' => 3, + 'xl' => 6, + ]; + + return $boxes; + } + + // TEAMPLATE TOTAL EVENTS + protected function template_total(float $total_home): HtmlString + { + return new HtmlString('
+ '.$total_home.' + Events +
'); + } + + // TEAMPLATE ODDS + protected function template_odds(array &$data, float $win, float $draw, float $lost): HtmlString + { + if ($this->filters['similar_past_matches'] != 'none') { + $name_win = '1 ('.$data['win_count'].')'; + $name_draw = 'X ('.$data['draw_count'].')'; + $name_lost = '2 ('.$data['lost_count'].')'; + } else { + $name_win = 'Win ('.$data['win_count'].')'; + $name_draw = 'Draw ('.$data['draw_count'].')'; + $name_lost = 'Lost ('.$data['lost_count'].')'; + } + + return new HtmlString('
+ '.number_format($win, 2).' + '.number_format($draw, 2).' + '.number_format($lost, 2).' + '.$name_win.' + '.$name_draw.' + '.$name_lost.' +
'); + } + + // TEAMPLATE BOX 1 + protected function template_tabelle_1(array $data): HtmlString + { + $bets = ['gls', 'fls', 'ofs', 'crd', 'snt', 'tsh']; + $str = '
'; + // $str .= '
Home
Away
'; + foreach ($bets as $name) { + $str .= '
'.$data[$name]['name'].'
'; + $str .= '
'.number_format($data[$name]['home'], 1).'
'; + $str .= '
'.number_format($data[$name]['away'], 1).'
'; + } + $str .= '
'; + + return new HtmlString($str); + } + + protected function template_tabelle_2(array $data): HtmlString + { + $bets = ['gls_team', 'fls_team', 'ofs_team', 'crd_team', 'snt_team', 'tsh_team']; + $str = '
'; + // $str .= '
Home
Away
'; + foreach ($bets as $name) { + $str .= '
'.$data[$name]['name'].'
'; + $str .= '
'.number_format($data[$name]['home'], 1).'
'; + $str .= '
'.number_format($data[$name]['away'], 1).'
'; + } + $str .= '
'; + + return new HtmlString($str); + } + + protected function template_tabelle_3(array $data): HtmlString + { + $bets = ['gls_team_season', 'fls_team_season', 'ofs_team_season', 'crd_team_season', 'snt_team_season', 'tsh_team_season']; + $str = '
'; + // $str .= '
Home
Away
'; + foreach ($bets as $name) { + $str .= '
'.$data[$name]['name'].'
'; + $str .= '
'.number_format($data[$name]['home'], 1).'
'; + $str .= '
'.number_format($data[$name]['away'], 1).'
'; + } + $str .= '
'; + + return new HtmlString($str); + } + + protected function template_tabelle_4(array $data): HtmlString + { + $bets = ['gls_liga_season', 'fls_liga_season', 'ofs_liga_season', 'crd_liga_season', 'snt_liga_season', 'tsh_liga_season']; + $str = '
'; + // $str .= '
Home
Away
'; + foreach ($bets as $name) { + $str .= '
'.$data[$name]['name'].'
'; + $str .= '
'.number_format($data[$name]['home'], 1).'
'; + $str .= '
'.number_format($data[$name]['away'], 1).'
'; + } + $str .= '
'; + + return new HtmlString($str); + } +} diff --git a/app/Filament/Widgets/StatsMedianAverage.php b/app/Filament/Widgets/BoxesBettypeSingle.php similarity index 98% rename from app/Filament/Widgets/StatsMedianAverage.php rename to app/Filament/Widgets/BoxesBettypeSingle.php index 8d1fc70b..d45a8b7b 100644 --- a/app/Filament/Widgets/StatsMedianAverage.php +++ b/app/Filament/Widgets/BoxesBettypeSingle.php @@ -3,7 +3,6 @@ namespace App\Filament\Widgets; use App\Filament\Widgets\Data\HelperStatisticType; -use App\Filament\Widgets\Data\HelperTeamPosition; use App\Filament\Widgets\Data\LoadEvents; use App\Utilities\Round; use Filament\Widgets\Concerns\InteractsWithPageFilters; @@ -15,7 +14,7 @@ use Livewire\Attributes\Reactive; // use Illuminate\Support\Facades\Log; -class StatsMedianAverage extends StatsOverviewWidget +class BoxesBettypeSingle extends StatsOverviewWidget { use InteractsWithPageFilters; @@ -37,8 +36,6 @@ class StatsMedianAverage extends StatsOverviewWidget { $data = LoadEvents::load($this->filters, false); - // dd($data); - $team_id = (int) $this->filters['team_id'] ?? 0; $season = $this->filters['season'] ?? 0; @@ -75,7 +72,7 @@ class StatsMedianAverage extends StatsOverviewWidget break; } - $team_position = HelperTeamPosition::get($this->filters); + $team_position = $this->filters['team_position'] ? ucfirst($this->filters['team_position']) : 'Position Both'; if (! $data) { return []; diff --git a/app/Filament/Widgets/Data/HelperTeamPosition.php b/app/Filament/Widgets/Data/HelperTeamPosition.php deleted file mode 100644 index 3ab7801e..00000000 --- a/app/Filament/Widgets/Data/HelperTeamPosition.php +++ /dev/null @@ -1,13 +0,0 @@ -when($active_season, function ($query) use ($active_season) { + return $query->where('season', $active_season); + })->get(); + + $result = []; + if ($res) { + foreach ($res as $val) { + ExpectationAverage::filter($result, 'liga', 'gls', $val->gls_h, $val->gls_a); + ExpectationAverage::filter($result, 'liga', 'fls', $val->fls_h, $val->fls_a); + ExpectationAverage::filter($result, 'liga', 'ofs', $val->ofs_h, $val->ofs_a); + ExpectationAverage::filter($result, 'liga', 'crd', $val->crd_h, $val->crd_a); + ExpectationAverage::filter($result, 'liga', 'snt', $val->snt_h, $val->snt_a); + ExpectationAverage::filter($result, 'liga', 'tsh', $val->tsh_h, $val->tsh_a); + } + + $bets = ['gls', 'fls', 'ofs', 'crd', 'snt', 'tsh']; + if ($result) { + foreach ($bets as $bet) { + $expectations[$bet.'_liga_season']['home'] = round(array_sum($result['liga'][$bet]['home']) / \count($result['liga'][$bet]['home']), 1); + $expectations[$bet.'_liga_season']['away'] = round(array_sum($result['liga'][$bet]['away']) / \count($result['liga'][$bet]['away']), 1); + } + } else { + foreach ($bets as $bet) { + $expectations[$bet.'_liga_season']['home'] = 0; + $expectations[$bet.'_liga_season']['away'] = 0; + } + } + $expectations['gls_liga_season']['name'] = 'Goals'; + $expectations['fls_liga_season']['name'] = 'Fouls'; + $expectations['ofs_liga_season']['name'] = 'Offsides'; + $expectations['crd_liga_season']['name'] = 'Cards'; + $expectations['snt_liga_season']['name'] = 'Shots on Target'; + $expectations['tsh_liga_season']['name'] = 'Total Shots'; + $expectations['active_season'] = $active_season; + } + } +} diff --git a/app/Filament/Widgets/Data/LoadEvents/AverageTeam.php b/app/Filament/Widgets/Data/LoadEvents/AverageTeam.php new file mode 100644 index 00000000..d05aa4e0 --- /dev/null +++ b/app/Filament/Widgets/Data/LoadEvents/AverageTeam.php @@ -0,0 +1,113 @@ +when($start, function ($query) use ($start) { + return $query->whereDate('starttime', '>=', $start); + })->when($end, function ($query) use ($end) { + return $query->whereDate('starttime', '<=', $end); + })->when($season, function ($query) use ($season) { + return $query->whereIn('season', $season); + })->when($team_id, function ($query) use ($team_position, $team_id) { + switch ($team_position) { + case 'home': + return $query->where('home_id', $team_id); + case 'away': + return $query->where('away_id', $team_id); + default: + return $query->orWhere('home_id', $team_id) + ->orWhere('away_id', '=', $team_id); + } + })->get(); + + $result = []; + if ($res) { + + // 1) la media dei falli di tutte le partite giocate dal Flamengo + // (esempio, giocate 6 partite con falli 17-11-15-14-15-12, la media è 14) + + // 2) la media dei falli di tutte le partite giocate nel campionato Brasiliano + // (esempio 6 giornate giocate = 60 partite quindi 120 squadre, quindi 120 dati tipo 17-12-12-15-8-15-13-21-..., + // quindi la media di questi 120 dati) + + foreach ($res as $val) { + + if ($team_position == 'home' && $team_id == $val->home_id) { + ExpectationAverage::filter($result, 'team', 'gls', $val->gls_h, $val->gls_a); + ExpectationAverage::filter($result, 'team', 'fls', $val->fls_h, $val->fls_a); + ExpectationAverage::filter($result, 'team', 'ofs', $val->ofs_h, $val->ofs_a); + ExpectationAverage::filter($result, 'team', 'crd', $val->crd_h, $val->crd_a); + ExpectationAverage::filter($result, 'team', 'snt', $val->snt_h, $val->snt_a); + ExpectationAverage::filter($result, 'team', 'tsh', $val->tsh_h, $val->tsh_a); + } elseif ($team_position == 'away' && $team_id == $val->away_id) { + ExpectationAverage::filter($result, 'team', 'gls', $val->gls_a, $val->gls_h); + ExpectationAverage::filter($result, 'team', 'fls', $val->fls_a, $val->fls_h); + ExpectationAverage::filter($result, 'team', 'ofs', $val->ofs_a, $val->ofs_h); + ExpectationAverage::filter($result, 'team', 'crd', $val->crd_a, $val->crd_h); + ExpectationAverage::filter($result, 'team', 'snt', $val->snt_a, $val->snt_h); + ExpectationAverage::filter($result, 'team', 'tsh', $val->tsh_a, $val->tsh_h); + } else { + ExpectationAverage::filter($result, 'team', 'gls', $val->gls_a, $val->gls_h); + ExpectationAverage::filter($result, 'team', 'fls', $val->fls_a, $val->fls_h); + ExpectationAverage::filter($result, 'team', 'ofs', $val->ofs_a, $val->ofs_h); + ExpectationAverage::filter($result, 'team', 'crd', $val->crd_a, $val->crd_h); + ExpectationAverage::filter($result, 'team', 'snt', $val->snt_a, $val->snt_h); + ExpectationAverage::filter($result, 'team', 'tsh', $val->tsh_a, $val->tsh_h); + } + } + + $bets = ['gls', 'fls', 'ofs', 'crd', 'snt', 'tsh']; + if ($result) { + foreach ($bets as $bet) { + $expectations[$bet.'_team']['home'] = round(array_sum($result['team'][$bet]['home']) / \count($result['team'][$bet]['home']), 1); + $expectations[$bet.'_team']['away'] = round(array_sum($result['team'][$bet]['away']) / \count($result['team'][$bet]['away']), 1); + } + } else { + foreach ($bets as $bet) { + $expectations[$bet.'_team']['home'] = 0; + $expectations[$bet.'_team']['away'] = 0; + } + } + $expectations['gls_team']['name'] = 'Goals'; + $expectations['fls_team']['name'] = 'Fouls'; + $expectations['ofs_team']['name'] = 'Offsides'; + $expectations['crd_team']['name'] = 'Cards'; + $expectations['snt_team']['name'] = 'Shots on Target'; + $expectations['tsh_team']['name'] = 'Total Shots'; + } + } +} diff --git a/app/Filament/Widgets/Data/LoadEvents/AverageTeamSeason.php b/app/Filament/Widgets/Data/LoadEvents/AverageTeamSeason.php new file mode 100644 index 00000000..447571d6 --- /dev/null +++ b/app/Filament/Widgets/Data/LoadEvents/AverageTeamSeason.php @@ -0,0 +1,93 @@ +when($active_season, function ($query) use ($active_season) { + return $query->where('season', $active_season); + })->when($team_id, function ($query) use ($team_position, $team_id) { + switch ($team_position) { + case 'home': + return $query->where('home_id', $team_id); + case 'away': + return $query->where('away_id', $team_id); + default: + return $query->orWhere('home_id', $team_id) + ->orWhere('away_id', '=', $team_id); + } + })->get(); + + $result = []; + if ($res) { + + // 1) la media dei falli di tutte le partite giocate dal Flamengo + // (esempio, giocate 6 partite con falli 17-11-15-14-15-12, la media è 14) + + // 2) la media dei falli di tutte le partite giocate nel campionato Brasiliano + // (esempio 6 giornate giocate = 60 partite quindi 120 squadre, quindi 120 dati tipo 17-12-12-15-8-15-13-21-..., + // quindi la media di questi 120 dati) + + foreach ($res as $val) { + if ($team_position == 'home' && $team_id == $val->home_id) { + ExpectationAverage::filter($result, 'team', 'gls', $val->gls_h, $val->gls_a); + ExpectationAverage::filter($result, 'team', 'fls', $val->fls_h, $val->fls_a); + ExpectationAverage::filter($result, 'team', 'ofs', $val->ofs_h, $val->ofs_a); + ExpectationAverage::filter($result, 'team', 'crd', $val->crd_h, $val->crd_a); + ExpectationAverage::filter($result, 'team', 'snt', $val->snt_h, $val->snt_a); + ExpectationAverage::filter($result, 'team', 'tsh', $val->tsh_h, $val->tsh_a); + } elseif ($team_position == 'away' && $team_id == $val->away_id) { + ExpectationAverage::filter($result, 'team', 'gls', $val->gls_a, $val->gls_h); + ExpectationAverage::filter($result, 'team', 'fls', $val->fls_a, $val->fls_h); + ExpectationAverage::filter($result, 'team', 'ofs', $val->ofs_a, $val->ofs_h); + ExpectationAverage::filter($result, 'team', 'crd', $val->crd_a, $val->crd_h); + ExpectationAverage::filter($result, 'team', 'snt', $val->snt_a, $val->snt_h); + ExpectationAverage::filter($result, 'team', 'tsh', $val->tsh_a, $val->tsh_h); + } else { + ExpectationAverage::filter($result, 'team', 'gls', $val->gls_a, $val->gls_h); + ExpectationAverage::filter($result, 'team', 'fls', $val->fls_a, $val->fls_h); + ExpectationAverage::filter($result, 'team', 'ofs', $val->ofs_a, $val->ofs_h); + ExpectationAverage::filter($result, 'team', 'crd', $val->crd_a, $val->crd_h); + ExpectationAverage::filter($result, 'team', 'snt', $val->snt_a, $val->snt_h); + ExpectationAverage::filter($result, 'team', 'tsh', $val->tsh_a, $val->tsh_h); + } + } + + $bets = ['gls', 'fls', 'ofs', 'crd', 'snt', 'tsh']; + if ($result) { + foreach ($bets as $bet) { + $expectations[$bet.'_team_season']['home'] = round(array_sum($result['team'][$bet]['home']) / \count($result['team'][$bet]['home']), 1); + $expectations[$bet.'_team_season']['away'] = round(array_sum($result['team'][$bet]['away']) / \count($result['team'][$bet]['away']), 1); + } + } else { + foreach ($bets as $bet) { + $expectations[$bet.'_team_season']['home'] = 0; + $expectations[$bet.'_team_season']['away'] = 0; + } + } + $expectations['gls_team_season']['name'] = 'Goals'; + $expectations['fls_team_season']['name'] = 'Fouls'; + $expectations['ofs_team_season']['name'] = 'Offsides'; + $expectations['crd_team_season']['name'] = 'Cards'; + $expectations['snt_team_season']['name'] = 'Shots on Target'; + $expectations['tsh_team_season']['name'] = 'Total Shots'; + $expectations['active_season'] = $active_season; + } + } +} diff --git a/app/Filament/Widgets/Data/LoadEvents/ExpectationAverage.php b/app/Filament/Widgets/Data/LoadEvents/ExpectationAverage.php new file mode 100644 index 00000000..bba182f1 --- /dev/null +++ b/app/Filament/Widgets/Data/LoadEvents/ExpectationAverage.php @@ -0,0 +1,12 @@ + $value) { + if (isset($expectations[$name])) { + $summen[$name]['sum'] = array_sum($expectations[$name]) * $value; + $summen[$name]['cnt'] = \count($expectations[$name]); + } else { + $summen[$name]['sum'] = 0; + $summen[$name]['cnt'] = 1; + } + } + + $summen2 = []; + $bets = ['gls', 'fls', 'ofs', 'crd', 'snt', 'tsh']; + foreach ($bets as $name) { + $summen2[$name]['home']['sum'] = 0; + $summen2[$name]['home']['cnt'] = 0; + $summen2[$name]['away']['sum'] = 0; + $summen2[$name]['away']['cnt'] = 0; + } + + foreach ($summen as $key => $value) { + foreach ($bets as $name) { + if (strpos($key, $name) !== false) { + if (strpos($key, 'home') !== false) { + $summen2[$name]['home']['sum'] += $value['sum']; + $summen2[$name]['home']['cnt'] += +$value['cnt']; + } + if (strpos($key, 'away') !== false) { + $summen2[$name]['away']['sum'] += $value['sum']; + $summen2[$name]['away']['cnt'] += +$value['cnt']; + } + } + } + } + $asp_result = []; + foreach ($summen2 as $bettype => $value) { + $asp_result[$bettype]['home'] = round($value['home']['sum'] / $value['home']['cnt'], 1); + $asp_result[$bettype]['away'] = round($value['away']['sum'] / $value['away']['cnt'], 1); + } + + return $asp_result; + } +} diff --git a/app/Filament/Widgets/Data/LoadEvents/ExpectationCollecting.php b/app/Filament/Widgets/Data/LoadEvents/ExpectationCollecting.php new file mode 100644 index 00000000..990eeeb4 --- /dev/null +++ b/app/Filament/Widgets/Data/LoadEvents/ExpectationCollecting.php @@ -0,0 +1,46 @@ +home_id) { + $result[$type.'_home_made_total'][] = $val_home; + $result[$type.'_home_made_home'][] = $val_home; + $result[$type.'_home_got_total'][] = $val_away; + $result[$type.'_home_got_home'][] = $val_away; + } elseif ($away_id == $match->home_id) { + $result[$type.'_home_made_total'][] = $val_away; + $result[$type.'_home_got_total'][] = $val_away; + } elseif ($home_id == $match->away_id) { + $result[$type.'_home_made_total'][] = $val_away; + $result[$type.'_home_got_total'][] = $val_away; + } elseif ($away_id == $match->away_id) { + $result[$type.'_home_made_total'][] = $val_home; + $result[$type.'_home_made_home'][] = $val_home; + $result[$type.'_home_got_total'][] = $val_away; + $result[$type.'_home_got_home'][] = $val_home; + } + + if ($away_id == $match->away_id) { + $result[$type.'_away_made_total'][] = $val_away; + $result[$type.'_away_made_home'][] = $val_away; + $result[$type.'_away_got_total'][] = $val_home; + $result[$type.'_away_got_home'][] = $val_home; + } elseif ($home_id == $match->away_id) { + $result[$type.'_away_made_total'][] = $val_home; + $result[$type.'_away_got_total'][] = $val_home; + } elseif ($away_id == $match->home_id) { + $result[$type.'_away_made_total'][] = $val_home; + $result[$type.'_away_got_total'][] = $val_home; + } elseif ($home_id == $match->home_id) { + $result[$type.'_away_made_total'][] = $val_away; + $result[$type.'_away_made_home'][] = $val_away; + $result[$type.'_away_got_total'][] = $val_home; + $result[$type.'_away_got_home'][] = $val_away; + } + } +} diff --git a/app/Filament/Widgets/Data/LoadEvents/LoadEventsQueryAll.php b/app/Filament/Widgets/Data/LoadEvents/LoadEventsQueryAll.php new file mode 100644 index 00000000..1ed68950 --- /dev/null +++ b/app/Filament/Widgets/Data/LoadEvents/LoadEventsQueryAll.php @@ -0,0 +1,143 @@ +home_id; + $away_id = $match->away_id; + + $handicap_range = []; + $total_range = []; + if ($similar_past_matches != 'none') { + $team_id = 0; + $team_position = ''; + $exp_handicap = $match->exp_away - $match->exp_home; + $exp_total = $match->exp_away + $match->exp_home; + $handicap_range = [$exp_handicap - $accuracy, $exp_handicap + $accuracy]; + $total_range = [$exp_total - $accuracy, $exp_total + $accuracy]; + } + + if ($similar_past_matches != 'none') { + $team_position = ''; + $team_id = 0; + $ss_player_id = 0; + } + + // dd($season); + $season = GetSeason::load($season, $seasonmode); + + /** + * IF WITH PLAYER + */ + $matches_played = []; + + if ($ss_player_id) { + $matches_season = StatistikoEvent::where(function ($query) use ($team_id, $team_position) { + switch ($team_position) { + case 'home': + return $query->where('home_id', '=', $team_id); + case 'away': + return $query->where('away_id', '=', $team_id); + default: + return $query->where('home_id', '=', $team_id) + ->orWhere('away_id', '=', $team_id); + } + })->pluck('match_id')->toArray(); + + $matches_played = StatistikoPlayer::query() + ->whereIn('match_id', $matches_season) + ->where('ss_player_id', $ss_player_id) + ->when($player_on_field, function ($query) use ($player_on_field) { + // 'all' => 'All', + // 'lineup' => 'Lineup', + // 'substituted' => 'Substituted', + // 'notplayed' => 'Not Played', + switch ($player_on_field) { + case 'all': + return $query->where('minutes_played', '>', 0); + case 'lineup': + return $query->where('lineup', 'T')->where('minutes_played', '>', 0); + case 'substituted': + return $query->where('lineup', 'P')->where('minutes_played', '>', 0); + default: + return $query->where('minutes_played', '>', 0); + } + }) + ->pluck('match_id')->toArray(); + + if (! $matches_played) { + $matches_played[] = -1; + } + } + + // dd($handicap_range, $total_range); + /** + * STATTISTIC DATA + */ + return StatistikoEvent::with('home')->with('away') + ->where(function ($query) use ($league_id, $similar_past_matches) { + switch ($similar_past_matches) { + case 'none': + case 'league': + return $query->where('league_id', $league_id); + } + }) + ->where(function ($query) use ($team_id, $home_id, $away_id, $similar_past_matches) { + if ($similar_past_matches == 'none') { + if ($team_id) { + return $query->orWhere('home_id', $team_id) + ->orWhere('away_id', '=', $team_id); + } else { + return $query->whereIn('home_id', [$home_id, $away_id])->orWhereIn('away_id', [$home_id, $away_id]); + } + } + }) + ->when($matches_played, function ($query) use ($matches_played, $player_on_field) { + if ($player_on_field == 'notplayed') { + return $query->whereNotIn('match_id', $matches_played); + } else { + return $query->whereIn('match_id', $matches_played); + } + }) + ->when($handicap_range, function ($query) use ($handicap_range) { + return $query->whereBetween('exp_handicap', $handicap_range); + })->when($total_range, function ($query) use ($total_range) { + return $query->whereBetween('exp_total', $total_range); + }) + ->when($start, function ($query) use ($start) { + return $query->whereDate('starttime', '>=', $start); + })->when($end, function ($query) use ($end) { + return $query->whereDate('starttime', '<=', $end); + }) + ->when($season, function ($query) use ($season, $season_or_date, $similar_past_matches) { + if ($similar_past_matches == 'none' && $season_or_date == 'season') { + return $query->whereIn('season', $season); + } + }) + ->orderBy('starttime', 'ASC') + ->get(); + } +} diff --git a/app/Filament/Widgets/Data/LoadEventsBoxes.php b/app/Filament/Widgets/Data/LoadEventsBoxes.php new file mode 100644 index 00000000..0b18a49b --- /dev/null +++ b/app/Filament/Widgets/Data/LoadEventsBoxes.php @@ -0,0 +1,147 @@ +with('away')->where('id', (int) $match_id)->first(); + + if (! $match) { + return []; + } + + if ($similar_past_matches != 'none') { + $team_id = 0; + $team_position = ''; + $home_team = $match->home->ss_team_name; + $away_team = $match->away->ss_team_name; + } else { + $home_team = 'In Favour'; + $away_team = 'Against'; + } + + /** + * STATTISTIC DATA + */ + $res = LoadEventsQueryAll::load($filter, $match); + if (! $res) { + return []; + } + $tmp = []; + foreach ($res as $value) { + ExpectationCollecting::sort($tmp, 'gls', $value->home_id, $value->away_id, $value->gls_h, $value->gls_a, $match); + ExpectationCollecting::sort($tmp, 'fls', $value->home_id, $value->away_id, $value->fls_h, $value->fls_a, $match); + ExpectationCollecting::sort($tmp, 'ofs', $value->home_id, $value->away_id, $value->ofs_h, $value->ofs_a, $match); + ExpectationCollecting::sort($tmp, 'crd', $value->home_id, $value->away_id, $value->crd_h, $value->crd_a, $match); + ExpectationCollecting::sort($tmp, 'snt', $value->home_id, $value->away_id, $value->snt_h, $value->snt_a, $match); + ExpectationCollecting::sort($tmp, 'tsh', $value->home_id, $value->away_id, $value->tsh_h, $value->tsh_a, $match); + ExpectationCollecting::sort($tmp, 'crn', $value->home_id, $value->away_id, $value->crn_h, $value->crn_a, $match); + } + $expectations = ExpectationCalculation::calc($tmp); + $expectations['gls']['name'] = 'Goals'; + $expectations['fls']['name'] = 'Fouls'; + $expectations['ofs']['name'] = 'Offsides'; + $expectations['crd']['name'] = 'Cards'; + $expectations['snt']['name'] = 'Shots on Target'; + $expectations['tsh']['name'] = 'Total Shots'; + $expectations['home'] = $home_team; + $expectations['away'] = $away_team; + + $expectations += ['win_count' => 0, 'draw_count' => 0, 'lost_count' => 0]; + $count_events = 0; + foreach ($res as $value) { + // dd($value); + if ($team_id && $team_position == 'home') { + $count_events++; + switch ($value['result_code']) { + case '1': + $expectations['win_count']++; + break; + case 'X': + $expectations['draw_count']++; + break; + case '2': + $expectations['lost_count']++; + break; + } + + } elseif ($team_id && $team_position == 'away') { + $count_events++; + switch ($value['result_code']) { + case '1': + $expectations['win_count']++; + break; + case 'X': + $expectations['draw_count']++; + break; + case '2': + $expectations['lost_count']++; + break; + } + + } else { + $count_events++; + switch ($value['result_code']) { + case '1': + $expectations['win_count']++; + break; + case 'X': + $expectations['draw_count']++; + break; + case '2': + $expectations['lost_count']++; + break; + } + } + } + + $expectations['win_odd'] = $expectations['win_count'] ? number_format(Round::odd($count_events / $expectations['win_count']), 2) : 0; + $expectations['draw_odd'] = $expectations['draw_count'] ? number_format(Round::odd($count_events / $expectations['draw_count']), 2) : 0; + $expectations['lost_odd'] = $expectations['lost_count'] ? number_format(Round::odd($count_events / $expectations['lost_count']), 2) : 0; + $expectations['count_events'] = $count_events; + + if ($team_id == $match->home_id) { + $expectations['active_team'] = $match->home->ss_team_name; + } else { + $expectations['active_team'] = $match->away->ss_team_name; + } + + /** + * LEAGUE AVERAGES + */ + if ($team_id != 0 && $similar_past_matches == 'none') { + AverageTeam::load($expectations, $filter); + AverageTeamSeason::load($expectations, $filter); + AverageLeagueSeason::load($expectations, $filter); + } + + return $expectations; + } +} diff --git a/resources/css/filament/admin/theme.css b/resources/css/filament/admin/theme.css index 1bac7fc0..fe5f27da 100644 --- a/resources/css/filament/admin/theme.css +++ b/resources/css/filament/admin/theme.css @@ -122,19 +122,23 @@ input[type="radio"].fi-radio-input { Statistiko BOX Widgets */ .box-info { - @apply bg-info-50 dark:bg-info-500/20 border border-info-500/30 dark:border-info-900 drop-shadow-xl p-2 + @apply bg-info-50 dark:bg-info-500/20 border border-info-500/30 dark:border-info-900 drop-shadow-xl p-2 flex justify-center } .box-success { - @apply bg-success-50 dark:bg-success-500/20 border border-success-500/30 dark:border-success-900 drop-shadow-xl p-2 + @apply bg-success-50 dark:bg-success-500/20 border border-success-500/30 dark:border-success-900 drop-shadow-xl p-2 flex justify-center } .box-purple { - @apply bg-purple-50 dark:bg-purple-500/20 border border-purple-500/30 dark:border-purple-900 drop-shadow-xl p-2 + @apply bg-purple-50 dark:bg-purple-500/20 border border-purple-500/30 dark:border-purple-900 drop-shadow-xl p-2 flex justify-center } .box-yellow { - @apply bg-yellow-50 dark:bg-yellow-500/20 border border-yellow-500/30 dark:border-yellow-900 drop-shadow-xl p-2 + @apply bg-yellow-50 dark:bg-yellow-500/20 border border-yellow-500/30 dark:border-yellow-900 drop-shadow-xl p-2 flex justify-center +} + +.box-gray { + @apply bg-gray-50 dark:bg-gray-500/20 border border-gray-500/30 dark:border-gray-900 drop-shadow-xl p-2 flex justify-center } /* diff --git a/resources/views/filament/pages/statistic.blade.php b/resources/views/filament/pages/statistic.blade.php index 511906ab..379dcfca 100644 --- a/resources/views/filament/pages/statistic.blade.php +++ b/resources/views/filament/pages/statistic.blade.php @@ -16,7 +16,8 @@ {{ $this->filtersForm }} - @livewire(\App\Filament\Widgets\StatsMedianAverage::class, ['filters' => $this->filters]) + {{-- @livewire(\App\Filament\Widgets\BoxesBettypeSingle::class, ['filters' => $this->filters]) --}} + @livewire(\App\Filament\Widgets\BoxesBettypeAll::class, ['filters' => $this->filters])