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');
- }
-}