diff --git a/app/Filament/Widgets/PlayerPropsDrop.php b/app/Filament/Widgets/PlayerPropsDrop.php index 28a8feed..34e67a0c 100644 --- a/app/Filament/Widgets/PlayerPropsDrop.php +++ b/app/Filament/Widgets/PlayerPropsDrop.php @@ -8,6 +8,7 @@ use App\Models\SofaScorePlayerPosition; use App\Models\SofaScoreRosa; use App\Models\SsLineupMemory; use App\Models\StatisticFixtures; +use App\Models\StatistikoEvent; use Filament\Notifications\Notification; use Filament\Widgets\Widget; use Illuminate\Support\Facades\Auth; @@ -262,9 +263,9 @@ class PlayerPropsDrop extends Widget foreach ($this->calculationVariables as $row) { if ($copystring == '') { $keys = array_keys($row); - $copystring .= implode(';', $keys) . "\n"; + $copystring .= implode(';', $keys)."\n"; } - $copystring .= implode(';', $row) . "\n"; + $copystring .= implode(';', $row)."\n"; } $this->js("navigator.clipboard.writeText(`$copystring`)"); @@ -284,7 +285,7 @@ class PlayerPropsDrop extends Widget return; } $header = ['name', 'foot', 'events', 'average min', 'position', 'on field', 'gls', 'fls', 'ofs', 'snt', 'tsh', 'crd']; - $copystring = implode(';', $header) . "\n"; + $copystring = implode(';', $header)."\n"; foreach ($this->players as $row) { $tmp = []; $tmp[] = $row['name']; @@ -304,7 +305,7 @@ class PlayerPropsDrop extends Widget $tmp[] = $row['tsh']; $tmp[] = $row['crd']; - $copystring .= implode(';', $tmp) . "\n"; + $copystring .= implode(';', $tmp)."\n"; } $this->js("navigator.clipboard.writeText(`$copystring`)"); @@ -357,6 +358,8 @@ class PlayerPropsDrop extends Widget } } + $asp_team_others = $this->loadOthers($count_player, $team_id); + // Aspettativa Team di Riferimento // (ATR) = Aspettativa Team * Numero di Giocatori di Team in Rosters (esclusi i portieri) / 10. // Ad esempio per Remo (supponiamo 24 giocatori nel Roster esclusi i portieri): ATR = 1.2 * 24 / 10 = 2.88 @@ -416,7 +419,6 @@ class PlayerPropsDrop extends Widget // Somma Minuti Giocati da Player (SMG) nel DB $tmp['somma_minuti'] = $val->total_min; - $tmp['shots_on_target'] = $val->shots_on_target; $tmp['shots_off_target'] = $val->shots_off_target; $tmp['shots_blocked'] = $val->shots_blocked; @@ -435,68 +437,68 @@ class PlayerPropsDrop extends Widget $bettypes = ['goals', 'cards', 'fouls', 'offsides', 'total_shots', 'shots_on_target']; foreach ($bettypes as $bettype) { - $asp_statistica = (float) SofaScorePlayerPosition::where('ss_code', $position)->value('exp_' . $bettype); - $tmp['asp_statistica_' . $bettype] = $asp_statistica; + $asp_statistica = (float) SofaScorePlayerPosition::where('ss_code', $position)->value('exp_'.$bettype); + $tmp['asp_statistica_'.$bettype] = $asp_statistica; switch ($bettype) { case 'goals': if ($val->total_min < $this->y_value || $val->goals == 0) { - $tmp['asp_gioco_' . $bettype] = $asp_statistica; - $tmp['asp_teorica_' . $bettype] = $asp_statistica; + $tmp['asp_gioco_'.$bettype] = $asp_statistica; + $tmp['asp_teorica_'.$bettype] = $asp_statistica; } else { $asp_gioco = $val->goals / $val->total_min * 90; - $tmp['asp_gioco_' . $bettype] = $asp_gioco; - $tmp['asp_teorica_' . $bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); + $tmp['asp_gioco_'.$bettype] = $asp_gioco; + $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); } break; case 'cards': if ($val->total_min < $this->y_value || $val->cards == 0) { - $tmp['asp_gioco_' . $bettype] = $asp_statistica; - $tmp['asp_teorica_' . $bettype] = $asp_statistica; + $tmp['asp_gioco_'.$bettype] = $asp_statistica; + $tmp['asp_teorica_'.$bettype] = $asp_statistica; } else { $asp_gioco = $val->cards / $val->total_min * 90; - $tmp['asp_gioco_' . $bettype] = $asp_gioco; - $tmp['asp_teorica_' . $bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); + $tmp['asp_gioco_'.$bettype] = $asp_gioco; + $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); } break; case 'fouls': if ($val->total_min < $this->y_value || $val->fouls == 0) { - $tmp['asp_gioco_' . $bettype] = $asp_statistica; - $tmp['asp_teorica_' . $bettype] = $asp_statistica; + $tmp['asp_gioco_'.$bettype] = $asp_statistica; + $tmp['asp_teorica_'.$bettype] = $asp_statistica; } else { $asp_gioco = $val->fouls / $val->total_min * 90; - $tmp['asp_gioco_' . $bettype] = $asp_gioco; - $tmp['asp_teorica_' . $bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); + $tmp['asp_gioco_'.$bettype] = $asp_gioco; + $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); } break; case 'offsides': if ($val->total_min < $this->y_value || $val->offsides == 0) { - $tmp['asp_gioco_' . $bettype] = $asp_statistica; - $tmp['asp_teorica_' . $bettype] = $asp_statistica; + $tmp['asp_gioco_'.$bettype] = $asp_statistica; + $tmp['asp_teorica_'.$bettype] = $asp_statistica; } else { $asp_gioco = $val->offsides / $val->total_min * 90; - $tmp['asp_gioco_' . $bettype] = $asp_gioco; - $tmp['asp_teorica_' . $bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); + $tmp['asp_gioco_'.$bettype] = $asp_gioco; + $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); } break; case 'total_shots': if ($val->total_min < $this->y_value || $val->total_shots == 0) { - $tmp['asp_gioco_' . $bettype] = $asp_statistica; - $tmp['asp_teorica_' . $bettype] = $asp_statistica; + $tmp['asp_gioco_'.$bettype] = $asp_statistica; + $tmp['asp_teorica_'.$bettype] = $asp_statistica; } else { $asp_gioco = $val->total_shots / $val->total_min * 90; - $tmp['asp_gioco_' . $bettype] = $asp_gioco; - $tmp['asp_teorica_' . $bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); + $tmp['asp_gioco_'.$bettype] = $asp_gioco; + $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); } break; case 'shots_on_target': if ($val->total_min < $this->y_value || $val->shots_on_target == 0) { - $tmp['asp_gioco_' . $bettype] = $asp_statistica; - $tmp['asp_teorica_' . $bettype] = $asp_statistica; + $tmp['asp_gioco_'.$bettype] = $asp_statistica; + $tmp['asp_teorica_'.$bettype] = $asp_statistica; } else { $asp_gioco = $val->shots_on_target / $val->total_min * 90; - $tmp['asp_gioco_' . $bettype] = $asp_gioco; - $tmp['asp_teorica_' . $bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); + $tmp['asp_gioco_'.$bettype] = $asp_gioco; + $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); } break; } @@ -510,17 +512,48 @@ class PlayerPropsDrop extends Widget } // Log::debug('results', $results); + // dd($asp_team_others); + // "asp_riferimento_goals" => 4.4 + // "asp_riferimento_fouls" => 42.2 + // "asp_riferimento_offside" => 2.0 + // "asp_riferimento_card" => 8.8 + // "asp_riferimento_snt" => 15.4 + // "asp_riferimento_tsh" => 42.6 $bettypes = ['goals', 'cards', 'fouls', 'offsides', 'total_shots', 'shots_on_target']; foreach ($bettypes as $bettype) { - $total_bettype = array_sum(array_column($results, 'asp_teorica_' . $bettype)); + $total_bettype = array_sum(array_column($results, 'asp_teorica_'.$bettype)); foreach ($results as $key => $value) { - // Aspettativa per Player: AP = AT * ATR / TOT AT - $results[$key]['asp_total_' . $bettype] = $total_bettype; - // $results[$key]['asp_player_'.$bettype] = ((float) $value['asp_team'] * (float) $value['asp_teorica_'.$bettype]) / $total_bettype; - // $results[$key]['asp_player_'.$bettype] = ($asp_team * $asp_team_riferimento) / $total_bettype; - $results[$key]['asp_player_' . $bettype] = ($value['asp_teorica_' . $bettype] * $asp_team_riferimento) / $total_bettype; + switch ($bettype) { + case 'goals': + // Aspettativa per Player: AP = AT * ATR / TOT AT + $results[$key]['asp_total_'.$bettype] = $total_bettype; + // $results[$key]['asp_player_'.$bettype] = ((float) $value['asp_team'] * (float) $value['asp_teorica_'.$bettype]) / $total_bettype; + // $results[$key]['asp_player_'.$bettype] = ($asp_team * $asp_team_riferimento) / $total_bettype; + $results[$key]['asp_player_'.$bettype] = $value['asp_teorica_'.$bettype] * $asp_team_riferimento / $total_bettype; + break; + case 'cards': + $results[$key]['asp_total_'.$bettype] = $total_bettype; + $results[$key]['asp_player_'.$bettype] = $value['asp_teorica_'.$bettype] * $asp_team_others['asp_riferimento_card'] / $total_bettype; + break; + case 'fouls': + $results[$key]['asp_total_'.$bettype] = $total_bettype; + $results[$key]['asp_player_'.$bettype] = $value['asp_teorica_'.$bettype] * $asp_team_others['asp_riferimento_fouls'] / $total_bettype; + break; + case 'offsides': + $results[$key]['asp_total_'.$bettype] = $total_bettype; + $results[$key]['asp_player_'.$bettype] = $value['asp_teorica_'.$bettype] * $asp_team_others['asp_riferimento_offside'] / $total_bettype; + break; + case 'total_shots': + $results[$key]['asp_total_'.$bettype] = $total_bettype; + $results[$key]['asp_player_'.$bettype] = $value['asp_teorica_'.$bettype] * $asp_team_others['asp_riferimento_tsh'] / $total_bettype; + break; + case 'shots_on_target': + $results[$key]['asp_total_'.$bettype] = $total_bettype; + $results[$key]['asp_player_'.$bettype] = $value['asp_teorica_'.$bettype] * $asp_team_others['asp_riferimento_snt'] / $total_bettype; + break; + } } } @@ -555,6 +588,48 @@ class PlayerPropsDrop extends Widget return false; } + public function loadOthers(int $count_player, int $team_id) + { + $arr = []; + $arr['goals'] = 0; + $arr['fouls'] = 0; + $arr['offside'] = 0; + $arr['card'] = 0; + $arr['snt'] = 0; + $arr['tsh'] = 0; + + $res = StatistikoEvent::where(function ($query) use ($team_id) { + return $query->orWhere('home_id', $team_id) + ->orWhere('away_id', '=', $team_id); + })->get(); + + $count_events = \count($res); + + foreach ($res as $value) { + if ($value->home_id == $team_id) { + $arr['goals'] += $value->gls_h; + $arr['fouls'] += $value->fls_h; + $arr['offside'] += $value->ofs_h; + $arr['card'] += $value->crd_h; + $arr['snt'] += $value->snt_h; + $arr['tsh'] += $value->tsh_h; + } elseif ($value->away_id == $team_id) { + $arr['goals'] += $value->gls_a; + $arr['fouls'] += $value->fls_a; + $arr['offside'] += $value->ofs_a; + $arr['card'] += $value->crd_a; + $arr['snt'] += $value->snt_a; + $arr['tsh'] += $value->tsh_a; + } + } + + foreach ($arr as $name => $value) { + $arr['asp_riferimento_'.$name] = (float) round($value / $count_events * $count_player / 10, 1); + } + + return $arr; + } + private function boxNames(): array { return [2 => 'DR', 4 => 'MR', 6 => 'LW', 9 => 'DC', 10 => 'DM', 11 => 'MC', 12 => 'AM', 15 => 'SW', 16 => 'DC', 17 => 'DM', 18 => 'MC', 19 => 'AM', 20 => 'SM', 21 => 'ST', 23 => 'DC', 24 => 'DM', 25 => 'MC', 26 => 'AM', 30 => 'DL', 32 => 'ML', 34 => 'RW']; diff --git a/app/Livewire/BoardDispatcher.php b/app/Livewire/BoardDispatcher.php deleted file mode 100644 index 61b46f7a..00000000 --- a/app/Livewire/BoardDispatcher.php +++ /dev/null @@ -1,754 +0,0 @@ - 'DR', 4 => 'MR', 6 => 'LW', 9 => 'DC', 10 => 'DM', 11 => 'MC', 12 => 'AM', 15 => 'SW', 16 => 'DC', 17 => 'DM', 18 => 'MC', 19 => 'AM', 20 => 'SM', 21 => 'ST', 23 => 'DC', 24 => 'DM', 25 => 'MC', 26 => 'AM', 30 => 'DL', 32 => 'ML', 34 => 'RW']; - - public bool $calculationDisabled = true; - - public bool $rangeXDisabled = true; - - public string $team_name = ''; - - public array $lineupsMap = [ - '3313' => [9, 16, 23, 11, 18, 25, 19, 6, 34, 21], - '3331' => [9, 16, 23, 17, 11, 25, 12, 19, 26, 21], - '3331-' => [9, 16, 23, 10, 18, 24, 12, 19, 26, 21], - '3331+' => [9, 16, 23, 11, 18, 25, 12, 19, 26, 21], - '3412-' => [9, 16, 23, 4, 10, 24, 32, 19, 20, 21], - '3412+' => [9, 16, 23, 4, 11, 25, 32, 19, 20, 21], - '3421-' => [9, 16, 23, 4, 10, 24, 32, 12, 26, 21], - '3421+' => [9, 16, 23, 4, 11, 25, 32, 12, 26, 21], - '343-' => [9, 16, 23, 4, 10, 24, 32, 6, 34, 21], - '343+' => [9, 16, 23, 4, 11, 25, 32, 6, 34, 21], - '3511' => [9, 16, 23, 4, 11, 17, 25, 32, 19, 21], - '3511-' => [9, 16, 23, 4, 10, 18, 24, 32, 19, 21], - '3511+' => [9, 16, 23, 4, 11, 18, 25, 32, 19, 21], - '352' => [9, 16, 23, 4, 11, 17, 25, 32, 20, 21], - '352-' => [9, 16, 23, 4, 10, 18, 24, 32, 20, 21], - '352+' => [9, 16, 23, 4, 11, 18, 25, 32, 20, 21], - '4132' => [2, 9, 23, 30, 17, 12, 19, 26, 20, 21], - '4213-' => [2, 9, 23, 30, 10, 24, 19, 6, 34, 21], - '4213+' => [2, 9, 23, 30, 11, 25, 19, 6, 34, 21], - '4222' => [2, 9, 23, 30, 10, 24, 12, 26, 20, 21], - '4231' => [2, 9, 23, 30, 10, 24, 12, 19, 26, 21], - '424' => [2, 9, 23, 30, 10, 24, 6, 34, 20, 21], - '4312' => [2, 9, 23, 30, 17, 11, 25, 19, 20, 21], - '4312-' => [2, 9, 23, 30, 10, 18, 24, 19, 20, 21], - '4312+' => [2, 9, 23, 30, 11, 18, 25, 19, 20, 21], - '4321' => [2, 9, 23, 30, 17, 11, 25, 12, 26, 21], - '4321-' => [2, 9, 23, 30, 10, 18, 24, 12, 26, 21], - '4321+' => [2, 9, 23, 30, 11, 18, 25, 12, 26, 21], - '433' => [2, 9, 23, 30, 17, 11, 25, 6, 34, 21], - '433-' => [2, 9, 23, 30, 10, 18, 24, 6, 34, 21], - '433+' => [2, 9, 23, 30, 11, 18, 25, 6, 34, 21], - '4411-' => [2, 9, 23, 30, 4, 10, 24, 32, 19, 21], - '4411+' => [2, 9, 23, 30, 4, 11, 25, 32, 19, 21], - '442' => [2, 9, 23, 30, 4, 17, 18, 32, 20, 21], - '442-' => [2, 9, 23, 30, 4, 10, 24, 32, 20, 21], - '442+' => [2, 9, 23, 30, 4, 11, 25, 32, 20, 21], - '451' => [2, 9, 23, 30, 4, 17, 11, 25, 32, 21], - '451-' => [2, 9, 23, 30, 4, 10, 18, 24, 32, 21], - '451+' => [2, 9, 23, 30, 4, 11, 18, 25, 32, 21], - '523-' => [2, 9, 16, 23, 30, 10, 24, 6, 34, 21], - '523+' => [2, 9, 16, 23, 30, 11, 25, 6, 34, 21], - '5311' => [2, 9, 16, 23, 30, 17, 11, 25, 19, 21], - '5311-' => [2, 9, 16, 23, 30, 10, 18, 24, 19, 21], - '5311+' => [2, 9, 16, 23, 30, 11, 18, 25, 19, 21], - '532' => [2, 9, 16, 23, 30, 17, 11, 25, 20, 21], - '532-' => [2, 9, 16, 23, 30, 10, 18, 24, 20, 21], - '532+' => [2, 9, 16, 23, 30, 11, 18, 25, 20, 21], - '541-' => [2, 9, 16, 23, 30, 4, 10, 24, 32, 21], - '541+' => [2, 9, 16, 23, 30, 4, 11, 25, 32, 21], - ]; - - public array $lineup = []; - - public array $lineup_options = [ - '3313' => '3313', - '3331' => '3331', - '3331-' => '3331-', - '3331+' => '3331+', - '3412-' => '3412-', - '3412+' => '3412+', - '3421-' => '3421-', - '3421+' => '3421+', - '343-' => '343-', - '343+' => '343+', - '3511' => '3511', - '3511-' => '3511-', - '3511+' => '3511+', - '352' => '352', - '352-' => '352-', - '352+' => '352+', - '4132' => '4132', - '4213-' => '4213-', - '4213+' => '4213+', - '4222' => '4222', - '4231' => '4231', - '424' => '424', - '4312' => '4312', - '4312-' => '4312-', - '4312+' => '4312+', - '4321' => '4321', - '4321-' => '4321-', - '4321+' => '4321+', - '433' => '433', - '433-' => '433-', - '433+' => '433+', - '4411-' => '4411-', - '4411+' => '4411+', - '442' => '442', - '442-' => '442-', - '442+' => '442+', - '451' => '451', - '451-' => '451-', - '451+' => '451+', - '523-' => '523-', - '523+' => '523+', - '5311' => '5311', - '5311-' => '5311-', - '5311+' => '5311+', - '532' => '532', - '532-' => '532-', - '532+' => '532+', - '541-' => '541-', - '541+' => '541+', - ]; - - public string $lineup_selected = '3313'; - - public array $boxes = []; - - public array $beschriftung = []; - - public function mount(array $filters) - { - $this->filters = $filters; - - $this->team_name = SofaScoreRosa::where('ss_team_id', $filters['team_id'])->value('ss_team_name'); - - $this->sourceRecords = PlayerCalculator::load($filters); - - $this->lineup = $this->lineupsMap[$this->lineup_selected]; - - for ($i = 1; $i <= 35; $i++) { - $this->boxes[$i] = []; - if (isset($this->activeBoxes[$i])) { - $this->beschriftung[$i] = $this->activeBoxes[$i]; - } else { - $this->beschriftung[$i] = ''; - } - } - - $this->loadPlacement(); - } - - public function getHeadingTable(): HtmlString - { - return new HtmlString('
-
Gls
-
Fls
-
Ofs
-
Snt
-
Tsh
-
Crd
-
Foot
-
Evt
-
Min Ø
-
'); - } - - public function form(Schema $schema): Schema - { - return $schema - ->components([ - Select::make('lineup_selected') - ->label('Lineup') - ->live() - ->prefixIcon('icon-soccerplayer') - ->searchable() - ->options($this->lineup_options) - ->afterStateUpdated(function ($state, $livewire) { - $livewire->updateLineup($state); - }), - ]); - } - - public function table(Table $table): Table - { - return $table - ->headerActions([ - Action::make('close') - ->size(Size::Small) - ->tooltip('Close') - ->color('success') - ->hiddenLabel() - ->icon('phosphor-x') - ->close(), - Action::make('lineups') - ->size(Size::Small) - ->tooltip('Lineups explanation') - ->color('success') - ->hiddenLabel() - ->icon('phosphor-question-mark') - ->slideOver() - ->slideOverPosition(SlideOverPosition::Start) - ->modalWidth(Width::ExtraLarge) - ->modalSubmitAction(false) - ->modalCancelAction(false) - ->modalContent(fn () => view('filament.modals.position-abbreviation')), - Action::make('reset') - ->hiddenLabel() - ->size(Size::Small) - ->tooltip('Remove all') - ->icon('phosphor-arrows-clockwise') - ->action(fn () => $this->clearResultTable()), - Action::make('calculate') - ->tooltip('Calculate') - ->hiddenLabel() - ->size(Size::Small) - ->icon('phosphor-calculator') - ->action(fn () => $this->calculateAspg()), - Action::make('copy_results') - ->tooltip('Copy results for pasting into a spread sheet') - ->hiddenLabel() - ->size(Size::Small) - ->icon('phosphor-copy') - ->action(fn () => $this->copyResult()), - Action::make('copy_development') - ->tooltip('Copy calculation variables') - ->hiddenLabel() - ->size(Size::Small) - ->hidden(fn () => ! in_array(Auth::user()->id, [1, 2])) - ->color('warning') - ->icon('phosphor-copy') - ->action(fn () => $this->copyDevelopment()), - ]) - /** - * WICHTIG: Da Filament v5 zwingend eine Query braucht, nutzen wir ein - * leeres Modell (z.B. ein beliebiges Basis-Modell deines Projekts) NUR als Dummy-Builder. - * Alternativ kannst du ein anonymes Model nutzen. - */ - ->query(User::query()->whereRaw('1 = 0')) // Verhindert DB-Abfragen - ->striped() - ->defaultSort('name') - ->columns([ - ViewColumn::make('drag_card') - ->columnSpanFull() - ->label(fn () => $this->getHeadingTable()) - ->view('filament.tables.columns.drag-card'), - ]) - ->filters([ - SelectFilter::make('area') - ->columnSpanFull() - ->native(false) - ->options([ - // 'attack' => 'Attack', - // 'midfield' => 'Midfield', - // 'defence' => 'Denfence', - // 'goalkeeper' => 'Goalkeeper', - 'attack' => 'Attack', - 'midfield' => 'Midfield', - 'defence' => 'Defence', - 'goalkeeper' => 'Goalkeeper', - ])->modifyFormFieldUsing(fn (Select $component) => $component->allowHtml()) - ->query(function ($query) { - return $query; - })->indicateUsing(function (array $data): array { - // WICHTIG: Ein leeres Array sorgt dafür, dass kein Indicator-Badge erzeugt wird - return []; - }), - ], layout: FiltersLayout::AboveContent) - ->deferFilters(false) - ->records(function () { - $collection = collect($this->sourceRecords); - $selectedPosition = $this->tableFilters['area']['value'] ?? null; - if (! empty($selectedPosition)) { - $collection = $collection->where('area', $selectedPosition); - } - - return $collection; - }); - } - - #[On('element-dropped-in-box')] - public function handleElementDropped(mixed $elementData, mixed $boxNumber): void - { - $boxNumber = (int) $boxNumber; - $player = is_array($elementData) ? $elementData : json_decode($elementData, true); - - if (! $player || ! isset($player['id'])) { - return; - } - - // dd(Auth::user()); - // "client_id" => 1 - // "sport_id" => 1 - - // when drag from field to field remove from prviouse field to prevent doubles - foreach ($this->boxes as $k => $record) { - if (count($record) && $record['id'] == (int) $player['id']) { - $this->clearBox($k); - } - } - - // when drag from source remove from proviuse field - foreach ($this->sourceRecords as $k => $record) { - if ($record['id'] == (int) $player['id']) { - if ($this->boxes[$boxNumber]) { - $this->clearBox($boxNumber); - } - $this->boxes[$boxNumber] = $record; - $this->sourceRecords[$k]['active'] = 1; - $this->sourceRecords[$k]['pos'] = $this->activeBoxes[$boxNumber]; - - $this->player_on_field_counter++; - } - } - - $this->storePlacement(); - - $this->calculateAspg(); - } - - public function loadPlacement() - { - $this->clearResultTable(); - - $res = SsLineupMemory::where('client_id', Auth::user()->client_id)->where('team_id', $this->filters['team_id'])->first(); - - if ($res) { - $placement = json_decode($res->placement, 1); - - foreach ($this->sourceRecords as $k => $record) { - $id = $record['id']; - if (isset($placement[$id])) { - $this->boxes[$placement[$id]] = $record; - $this->sourceRecords[$k]['active'] = 1; - $this->sourceRecords[$k]['pos'] = $record['pos_ori']; - - $this->player_on_field_counter++; - } - } - } - } - - public function storePlacement() - { - $store = []; - foreach ($this->boxes as $pos => $value) { - if ($value) { - $store[$value['id']] = $pos; - } - } - SsLineupMemory::updateOrCreate([ - 'client_id' => Auth::user()->client_id, - 'team_id' => $this->filters['team_id'], - ], [ - 'placement' => json_encode($store), - 'lineup' => $this->lineup_selected, - 'team_name' => $this->team_name, - ]); - } - - public function updateLineup(?string $state) - { - $this->clearResultTable(); - - if (isset($this->lineupsMap[$state])) { - $this->lineup = $this->lineupsMap[$state]; - } else { - $this->lineup = []; - } - } - - public function clearBox(int $boxNumber): void - { - if (isset($this->boxes[$boxNumber])) { - $tmp = $this->boxes[$boxNumber]; - $player_id = 0; - foreach ($tmp as $key => $value) { - if ($key == 'id') { - $player_id = $value; - } - } - foreach ($this->sourceRecords as $k => $record) { - if ($record['id'] == (int) $player_id) { - $this->boxes[$boxNumber] = []; - $this->sourceRecords[$k]['pos'] = ''; - $this->sourceRecords[$k]['active'] = 0; - - $this->player_on_field_counter--; - } - } - - foreach ($this->sourceRecords as $k => $record) { - $this->sourceRecords[$k]['gls'] = ''; - $this->sourceRecords[$k]['fls'] = ''; - $this->sourceRecords[$k]['ofs'] = ''; - $this->sourceRecords[$k]['snt'] = ''; - $this->sourceRecords[$k]['tsh'] = ''; - $this->sourceRecords[$k]['crd'] = ''; - } - - $this->storePlacement(); - } - } - - public function clearResultTable(): void - { - for ($i = 1; $i <= 35; $i++) { - $this->boxes[$i] = []; - } - foreach ($this->sourceRecords as $k => $record) { - $this->sourceRecords[$k]['active'] = 0; - $this->sourceRecords[$k]['gls'] = ''; - $this->sourceRecords[$k]['fls'] = ''; - $this->sourceRecords[$k]['ofs'] = ''; - $this->sourceRecords[$k]['snt'] = ''; - $this->sourceRecords[$k]['tsh'] = ''; - $this->sourceRecords[$k]['crd'] = ''; - } - - $this->player_on_field_counter = 0; - } - - public function copyDevelopment() - { - if ($this->player_on_field_counter < 10) { - return; - } - - $copystring = ''; - foreach ($this->calculationVariables as $row) { - if ($copystring == '') { - $keys = array_keys($row); - $copystring .= implode(';', $keys)."\n"; - } - $copystring .= implode(';', $row)."\n"; - } - $this->js("navigator.clipboard.writeText(`$copystring`)"); - - Notification::make() - ->title('Calculation variables copied') - ->success() - ->send(); - } - - public function copyResult() - { - if ($this->player_on_field_counter < 10) { - return; - } - $header = ['name', 'foot', 'events', 'average min', 'position', 'on field', 'gls', 'fls', 'ofs', 'snt', 'tsh', 'crd']; - $copystring = implode(';', $header)."\n"; - foreach ($this->sourceRecords as $row) { - $tmp = []; - $tmp[] = $row['name']; - $tmp[] = $row['foot']; - $tmp[] = $row['tot_evt']; - $tmp[] = $row['ave_min']; - if ($row['pos']) { - $tmp[] = $row['pos']; - } else { - $tmp[] = $row['pos_ori']; - } - $tmp[] = $row['active']; - $tmp[] = $row['gls']; - $tmp[] = $row['fls']; - $tmp[] = $row['ofs']; - $tmp[] = $row['snt']; - $tmp[] = $row['tsh']; - $tmp[] = $row['crd']; - - $copystring .= implode(',', $tmp)."\n"; - } - $this->js("navigator.clipboard.writeText(`$copystring`)"); - - Notification::make() - ->title('Results copied') - ->success() - ->send(); - } - - public function calculateAspg(): void - { - if ($this->player_on_field_counter < 10) { - foreach ($this->sourceRecords as $k => $record) { - $this->sourceRecords[$k]['gls'] = ''; - $this->sourceRecords[$k]['fls'] = ''; - $this->sourceRecords[$k]['ofs'] = ''; - $this->sourceRecords[$k]['snt'] = ''; - $this->sourceRecords[$k]['tsh'] = ''; - $this->sourceRecords[$k]['crd'] = ''; - } - - return; - } - // Calcolare Aspettativa Team per GOALS - // (il valore che appare quando viene selezionato un Evento): nell' esempio, - // se scegliamo come Team il Remo (Home) il valore di riferimento sarà 1.2 - $team_id = $this->filters['team_id']; - $res = StatisticFixtures::where('id', $this->filters['match_id'])->first(); - $asp_team = 0; - if ((int) $res->home_id == (int) $team_id) { - $asp_team = (float) $res->exp_home; - } elseif ((int) $res->away_id == (int) $team_id) { - $asp_team = (float) $res->exp_away; - } - - $player = StatistikoDetail::where('ss_team_id', (int) $team_id)->where('pos', '!=', 'GK')->where('is_active', 1)->get(); - - // Aspettativa Team di Riferimento - // (ATR) = Aspettativa Team * Numero di Giocatori di Team in Rosters (esclusi i portieri) / 10. - // Ad esempio per Remo (supponiamo 24 giocatori nel Roster esclusi i portieri): ATR = 1.2 * 24 / 10 = 2.88 - - $asp_team_riferimento = (float) $asp_team * $player->count() / 10; - - $player_totals = SofaScorePlayerPerSeason::with('details')->where('season', 'total')->where('ss_team_id', $team_id)->get(); - - /*** - "id" => 35067 - "ss_player_id" => 233856 - "ss_team_id" => 3212 - "season" => "total" - "total_events" => 12 - "total_min" => 667 - "average_min" => 56 - "events_played_home" => 7 - "events_played_away" => 0 - "minutes_played_home" => 398 - "minutes_played_away" => 274 - "goals" => 0 - "fouls" => 5 - "cards" => 2 - "offsides" => 0 - "shots_on_target" => 1 - "shots_off_target" => 0 - */ - $results = []; - $this->calculationVariables = []; - foreach ($player_totals as $val) { - if ($val->details && $val->details->is_active) { - - $ss_player_id = $val->ss_player_id; - $position = $val->details->position; - - $tmp = []; - $tmp['id'] = $ss_player_id; - $tmp['name'] = $val->details->player_name; - - $tmp['asp_team'] = $asp_team; - $tmp['asp_team_riferimento'] = $asp_team_riferimento; - - $position_field = $this->get_position($ss_player_id); - if ($position_field) { - $position = $position_field; - $tmp['active'] = 1; - } else { - $tmp['active'] = 0; - } - $tmp['pos'] = $position; - - // Aspettativa di Gioco (AdG) = Somma Goals fatti da Player nel DB / Somma Minuti Giocati da Player (SMG) nel DB * 90. - // Se la SMG è < Y per quel Player prenderemo in considerazione solo l'Aspettativa Statistica (AS). - // Il valore Y dovrebbe essere configurabile in una interfaccia. Il valore iniziale lo fissiamo a Y = 180 - - // Somma Minuti Giocati da Player (SMG) nel DB - $tmp['somma_minuti'] = $val->total_min; - - // il valore corrispondente al ruolo del Player (esempio un giocatore in Details ha ruolo = RW - // quindi Aspettativa Statistica (AS) per RW = 0.219) - // exp_goals - // exp_assists - // exp_cards - // exp_fouls - // exp_was_fouled - // exp_offsides - // exp_total_shots - // exp_shots_on_target - - $bettypes = ['goals', 'cards', 'fouls', 'offsides', 'total_shots', 'shots_on_target']; - foreach ($bettypes as $bettype) { - - $asp_statistica = (float) SofaScorePlayerPosition::where('ss_code', $position)->value('exp_'.$bettype); - $tmp['asp_statistica_'.$bettype] = $asp_statistica; - - switch ($bettype) { - case 'goals': - if ($val->total_min < $this->y_value || $val->goals == 0) { - $tmp['asp_gioco_'.$bettype] = $asp_statistica; - $tmp['asp_teorica_'.$bettype] = $asp_statistica; - } else { - $asp_gioco = $val->goals / $val->total_min * 90; - $tmp['asp_gioco_'.$bettype] = $asp_gioco; - $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); - } - break; - case 'cards': - if ($val->total_min < $this->y_value || $val->cards == 0) { - $tmp['asp_gioco_'.$bettype] = $asp_statistica; - $tmp['asp_teorica_'.$bettype] = $asp_statistica; - } else { - $asp_gioco = $val->cards / $val->total_min * 90; - $tmp['asp_gioco_'.$bettype] = $asp_gioco; - $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); - } - break; - case 'fouls': - if ($val->total_min < $this->y_value || $val->fouls == 0) { - $tmp['asp_gioco_'.$bettype] = $asp_statistica; - $tmp['asp_teorica_'.$bettype] = $asp_statistica; - } else { - $asp_gioco = $val->fouls / $val->total_min * 90; - $tmp['asp_gioco_'.$bettype] = $asp_gioco; - $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); - } - break; - case 'offsides': - if ($val->total_min < $this->y_value || $val->offsides == 0) { - $tmp['asp_gioco_'.$bettype] = $asp_statistica; - $tmp['asp_teorica_'.$bettype] = $asp_statistica; - } else { - $asp_gioco = $val->offsides / $val->total_min * 90; - $tmp['asp_gioco_'.$bettype] = $asp_gioco; - $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); - } - break; - case 'total_shots': - if ($val->total_min < $this->y_value || $val->total_shots == 0) { - $tmp['asp_gioco_'.$bettype] = $asp_statistica; - $tmp['asp_teorica_'.$bettype] = $asp_statistica; - } else { - $asp_gioco = $val->total_shots / $val->total_min * 90; - $tmp['asp_gioco_'.$bettype] = $asp_gioco; - $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); - } - break; - case 'shots_on_target': - if ($val->total_min < $this->y_value || $val->shots_on_target == 0) { - $tmp['asp_gioco_'.$bettype] = $asp_statistica; - $tmp['asp_teorica_'.$bettype] = $asp_statistica; - } else { - $asp_gioco = $val->shots_on_target / $val->total_min * 90; - $tmp['asp_gioco_'.$bettype] = $asp_gioco; - $tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value); - } - break; - } - } - - // Calcolare la Somma di tutte le AT (colonna G della Tabella) - // Considerare la ATR calcolata allo Step 1 (colonna I della Tabella) - // Aspettativa per Player: AP = AT * ATR / TOT AT - $results[] = $tmp; - - // for dev copy - $this->calculationVariables[] = $tmp; - } - } - - $bettypes = ['goals', 'cards', 'fouls', 'offsides', 'total_shots', 'shots_on_target']; - foreach ($bettypes as $bettype) { - $total_bettype = array_sum(array_column($results, 'asp_teorica_'.$bettype)); - foreach ($results as $key => $value) { - // Aspettativa per Player: AP = AT * ATR / TOT AT - $results[$key]['asp_total_'.$bettype] = $total_bettype; - // $results[$key]['asp_player_'.$bettype] = ((float) $value['asp_team'] * (float) $value['asp_teorica_'.$bettype]) / $total_bettype; - $results[$key]['asp_player_'.$bettype] = ($asp_team * $asp_team_riferimento) / $total_bettype; - } - } - - // dd($results); - - // update frontend - foreach ($this->sourceRecords as $k => $record) { - - foreach ($results as $key => $result) { - if ($record['id'] == $result['id']) { - // dd($result); - $this->sourceRecords[$k]['active'] = $result['active']; - $this->sourceRecords[$k]['gls'] = number_format($result['asp_player_goals'], 3); - $this->sourceRecords[$k]['fls'] = number_format($result['asp_player_fouls'], 3); - $this->sourceRecords[$k]['ofs'] = number_format($result['asp_player_offsides'], 3); - $this->sourceRecords[$k]['snt'] = number_format($result['asp_player_total_shots'], 3); - $this->sourceRecords[$k]['tsh'] = number_format($result['asp_player_shots_on_target'], 3); - $this->sourceRecords[$k]['crd'] = number_format($result['asp_player_cards'], 3); - } - } - } - } - - public function get_position(int $ss_player_id) - { - // see if player is in field and if yes get new position - foreach ($this->sourceRecords as $record) { - if ($record['id'] == $ss_player_id) { - return $record['pos']; - } - } - - return false; - } - - public function render() - { - return view('livewire.board-dispatcher'); - } -}