This commit is contained in:
salam committed 2026-09-11 17:32:24 +02:00
1 parent 7708a4a935
commit 43d1c091b3
9 files changed
+165 -344

No files matched your search

+51 -93
View File
@@ -25,7 +25,6 @@ use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Enums\FiltersLayout;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\HtmlString;
use Livewire\Attributes\On;
use Livewire\Component;
@@ -40,6 +39,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
public array $sourceRecords = [];
public array $filters = [];
public int $player_on_field_counter = 0;
// slider
@@ -58,7 +58,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
public bool $rangeXDisabled = true;
public string $ss_team_name = '';
public string $team_name = '';
public array $lineupsMap = [
'3313' => [9, 16, 23, 11, 18, 25, 19, 6, 34, 21],
@@ -176,7 +176,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
{
$this->filters = $filters;
$this->ss_team_name = SofaScoreRosa::where('ss_team_id', $filters['team_id'])->value('ss_team_name');
$this->team_name = SofaScoreRosa::where('ss_team_id', $filters['team_id'])->value('ss_team_name');
$this->sourceRecords = PlayerCalculator::load($filters);
@@ -205,7 +205,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
<div>Crd</div>
<div>Foot</div>
<div>Evt</div>
<div>Ømin</div>
<div>Min Ø</div>
</div>');
}
@@ -245,26 +245,19 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
->modalWidth(Width::ExtraLarge)
->modalSubmitAction(false)
->modalCancelAction(false)
->modalContent(fn() => view('filament.modals.position-abbreviation')),
->modalContent(fn () => view('filament.modals.position-abbreviation')),
Action::make('reset')
->hiddenLabel()
->size(Size::Small)
->tooltip('Remove all players from field')
->icon('phosphor-arrows-clockwise')
->action(fn() => $this->clearResultTable()),
// Action::make('calculate')
// ->hiddenLabel()
// ->tooltip('Calculate expected values')
// ->size(Size::Small)
// ->icon('phosphor-calculator')
// ->disabled($this->calculationDisabled)
// ->action(fn () => $this->calculateAspg()),
->action(fn () => $this->clearResultTable()),
Action::make('copy')
->tooltip('Copy results for pasting into a spread sheet')
->hiddenLabel()
->size(Size::Small)
->icon('phosphor-copy')
->action(fn() => $this->copyResult()),
->action(fn () => $this->copyResult()),
])
/**
* WICHTIG: Da Filament v5 zwingend eine Query braucht, nutzen wir ein
@@ -277,11 +270,11 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
->columns([
ViewColumn::make('drag_card')
->columnSpanFull()
->label(fn() => $this->getHeadingTable())
->label(fn () => $this->getHeadingTable())
->view('filament.tables.columns.drag-card'),
])
->filters([
SelectFilter::make('position_area')
SelectFilter::make('area')
->columnSpanFull()
->native(false)
->options([
@@ -293,7 +286,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
'midfield' => '<span class="text-blue-500">Midfield</span>',
'defence' => '<span class="text-green-500">Defence</span>',
'goalkeeper' => '<span class="text-gray-500">Goalkeeper</span>',
])->modifyFormFieldUsing(fn(Select $component) => $component->allowHtml())
])->modifyFormFieldUsing(fn (Select $component) => $component->allowHtml())
->query(function ($query) {
return $query;
})->indicateUsing(function (array $data): array {
@@ -304,9 +297,9 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
->deferFilters(false)
->records(function () {
$collection = collect($this->sourceRecords);
$selectedPosition = $this->tableFilters['position_area']['value'] ?? null;
$selectedPosition = $this->tableFilters['area']['value'] ?? null;
if (! empty($selectedPosition)) {
$collection = $collection->where('position_area', $selectedPosition);
$collection = $collection->where('area', $selectedPosition);
}
return $collection;
@@ -338,7 +331,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
}
$this->boxes[$boxNumber] = $record;
$this->sourceRecords[$k]['active'] = 1;
$this->sourceRecords[$k]['position'] = $this->activeBoxes[$boxNumber];
$this->sourceRecords[$k]['pos'] = $this->activeBoxes[$boxNumber];
$this->player_on_field_counter++;
}
@@ -372,7 +365,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
foreach ($this->sourceRecords as $k => $record) {
if ($record['id'] == (int) $player_id) {
$this->boxes[$boxNumber] = [];
$this->sourceRecords[$k]['position'] = '';
$this->sourceRecords[$k]['pos'] = '';
$this->sourceRecords[$k]['active'] = 0;
$this->player_on_field_counter--;
@@ -396,7 +389,6 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
$this->boxes[$i] = [];
}
foreach ($this->sourceRecords as $k => $record) {
$this->sourceRecords[$k]['position'] = '';
$this->sourceRecords[$k]['active'] = 0;
$this->sourceRecords[$k]['gls'] = '';
$this->sourceRecords[$k]['fls'] = '';
@@ -411,45 +403,47 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
public function copyResult()
{
if ($this->player_on_field_counter < 10)
if ($this->player_on_field_counter < 10) {
return;
// "id" => 787607
// "name" => "Keno"
// "preferred_foot" => "Right"
// "player_position" => "LW"
// "position_area" => "attack"
// "player_color" => "warning"
// "timed_color" => "danger"
// "events_played" => 7
// "everage_minutes" => 11
// "position" => "DC"
// "active" => 1
}
// "id" => 1218016
// "name" => "Walter Nuñez"
// "pos" => "LW"
// "foot" => "Right"
// "tot_evt" => 2
// "tot_min" => 102
// "ave_min" => 51
// "gls" => 0
// "fls" => 0
// "fls" => 3
// "ofs" => 0
// "crd" => 0
// "snt" => 0
// "tsh" => 0
// "crd" => 0
// "color_evt" => "success"
// "area" => "attack"
// "color_pos" => "warning"
$header = ['name', 'foot', 'events', 'average min', 'position', 'on field', 'gls', 'fls', 'ofs', 'snt', 'tsh', 'crd'];
$copystring = implode("\t", $header) . "\n";
$copystring = implode("\t", $header)."\n";
foreach ($this->sourceRecords as $row) {
$tmp = [];
$tmp[] = $row['name'];
$tmp[] = $row['preferred_foot'];
$tmp[] = $row['events_played'];
$tmp[] = $row['everage_minutes'];
if ($row['position'])
$tmp[] = $row['position'];
else
$tmp[] = $row['player_position'];
$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("\t", $tmp) . "\n";
$copystring .= implode("\t", $tmp)."\n";
}
$this->js("navigator.clipboard.writeText(`$copystring`)");
}
@@ -465,6 +459,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
$this->sourceRecords[$k]['tsh'] = '';
$this->sourceRecords[$k]['crd'] = '';
}
return;
}
// Calcolare Aspettativa Team per GOALS
@@ -479,28 +474,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
$asp_team = $res->exp_away;
}
// "atr" => 2.8868026211843
// "id" => 44691
// "name" => "Maicon"
// "on_field" => 0
// "position" => "DC"
// "sgf" => 1044
// "smg" => 1044
// "adg" => 90
// "as_goals" => 0.044
// "at_goals" => 67.511
// "as_cards" => 0.195
// "at_cards" => 67.54875
// "as_fouls" => 0.959
// "at_fouls" => 67.73975
// "as_offsides" => 0.036
// "at_offsides" => 67.509
// "as_total_shots" => 0.525
// "at_total_shots" => 67.63125
// "as_shots_on_target" => 0.263
// "at_shots_on_target" => 67.56575
$player = StatistikoDetail::where('ss_team_id', (int) $team_id)->where('position', '!=', 'GK')->where('is_active', 1)->get();
$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.
@@ -531,7 +505,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
} else {
$tmp['active'] = 0;
}
$tmp['position'] = $position;
$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).
@@ -555,18 +529,18 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
$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;
if ($somma_minuti < $this->y_value) {
// Se la SMG è < Y per quel Player prenderemo in considerazione solo l'Aspettativa Statistica (AS).
$tmp['asp_teorica_' . $bettype] = $asp_statistica;
$tmp['asp_teorica_'.$bettype] = $asp_statistica;
} else {
// Aspettativa Teorica (AT) Goals = (X * AdG + AS) / (1 + X)
// dove X è un valore che dovrebbe essere parametrizzabile da una interfaccia.
// Il valore iniziale lo fissiamo a X = 3
// (AT)
$tmp['asp_teorica_' . $bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value);
$tmp['asp_teorica_'.$bettype] = ($this->x_value * $asp_gioco + $asp_statistica) / (1 + $this->x_value);
}
}
@@ -580,11 +554,11 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
$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_total_'.$bettype] = $total_bettype;
$results[$key]['asp_player_'.$bettype] = ((float) $value['asp_team'] * (float) $value['asp_teorica_'.$bettype]) / $total_bettype;
}
}
@@ -592,23 +566,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
// update frontend
foreach ($this->sourceRecords as $k => $record) {
// "id" => 787607
// "name" => "Keno"
// "preferred_foot" => "Right"
// "player_position" => "LW"
// "position_area" => "attack"
// "player_color" => "warning"
// "timed_color" => "danger"
// "events_played" => 7
// "everage_minutes" => 11
// "position" => "DC"
// "active" => 1
// "gls" => 0
// "fls" => 0
// "ofs" => 0
// "snt" => 0
// "tsh" => 0
// "crd" => 0
foreach ($results as $key => $result) {
// "id" => 44691
// "name" => "Maicon"
@@ -656,7 +614,7 @@ class BoardDispatcher extends Component implements HasActions, HasSchemas, HasTa
// 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['position'];
return $record['pos'];
}
}