diff --git a/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Pages/CreateStatisticFixtures.php b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Pages/CreateStatisticFixtures.php
new file mode 100644
index 00000000..736cab98
--- /dev/null
+++ b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Pages/CreateStatisticFixtures.php
@@ -0,0 +1,11 @@
+icon('phosphor-trash')
+ ->requiresConfirmation()
+ ->color('danger')
+ ->action(function () {
+ StatistikoEvent::where('starttime', '<', now()->subHour())->delete();
+ }),
+ ];
+ }
+}
diff --git a/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Schemas/StatisticFixturesForm.php b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Schemas/StatisticFixturesForm.php
new file mode 100644
index 00000000..b8f33890
--- /dev/null
+++ b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Schemas/StatisticFixturesForm.php
@@ -0,0 +1,18 @@
+components([
+ TextInput::make('exp_home')->required(),
+ TextInput::make('exp_away')->required(),
+ ]);
+ }
+}
diff --git a/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/StatisticFixturesResource.php b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/StatisticFixturesResource.php
new file mode 100644
index 00000000..125ab4d5
--- /dev/null
+++ b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/StatisticFixturesResource.php
@@ -0,0 +1,50 @@
+ ListStatisticFixtures::route('/'),
+ ];
+ }
+
+ public static function getNavigationBadge(): ?string
+ {
+ return parent::getEloquentQuery()->count();
+ }
+}
diff --git a/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Tables/StatisticFixturesTable.php b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Tables/StatisticFixturesTable.php
new file mode 100644
index 00000000..d021905f
--- /dev/null
+++ b/app/Filament/Clusters/StaticData/Resources/StatisticFixtures/Tables/StatisticFixturesTable.php
@@ -0,0 +1,69 @@
+columns([
+ IconColumn::make('sport_id')
+ ->label('')
+ ->icon(fn (string $state): string => match ($state) {
+ '1' => 'icon-soccerball',
+ '2' => 'icon-icehockey',
+ '3' => 'icon-basketball',
+ '5' => 'icon-tennisball',
+ }),
+ TextColumn::make('league.name')
+ ->label('League')
+ ->searchable()
+ ->wrap()
+ ->hidden(fn () => auth()->user()->sport_id == 5)
+ ->description(fn ($record) => ucwords($record->league?->country->name)),
+ TextColumn::make('starttime')->dateTime('M j, Y')->label('Date'),
+ TextColumn::make('home.name')->color('primary')->searchable(),
+ TextColumn::make('away.name')->color('success')->searchable(),
+ // TextColumn::make('exp_home')->alignCenter()->numeric(),
+ // TextColumn::make('exp_away')->alignCenter()->numeric(),
+ TextColumn::make('updated_at')->alignCenter()->date(),
+ ])
+ ->filters([
+ SelectFilter::make('league_id')
+ ->options(function () {
+ $res = StatisticFixtures::where('sport_id', 1)
+ ->groupBy('league_id')
+ ->pluck('league_id')->toArray();
+
+ return CompetitionGroup::query()->whereIn('id', $res)->orderBy('name')->pluck('name', 'id');
+ })
+ ->preload()
+ ->searchable()
+ ->columnSpan(2)
+ ->label('League'),
+ ], layout: FiltersLayout::AboveContent)
+ ->deferFilters(false)
+ ->recordActions([
+ EditAction::make()->iconButton(),
+ DeleteAction::make()->iconButton(),
+ ])
+ ->toolbarActions([
+ BulkActionGroup::make([
+ DeleteBulkAction::make(),
+ ]),
+ ]);
+ }
+}
diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Pages/ListStatistikoEvents.php b/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Pages/ListStatistikoEvents.php
index 2712db2a..f0228d0a 100644
--- a/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Pages/ListStatistikoEvents.php
+++ b/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Pages/ListStatistikoEvents.php
@@ -3,7 +3,6 @@
namespace App\Filament\Clusters\StaticData\Resources\StatistikoEvents\Pages;
use App\Filament\Clusters\StaticData\Resources\StatistikoEvents\StatistikoEventsResource;
-// use App\Filament\Imports\StatistikoEventImporter;
use App\Models\StatistikoEvent;
use Filament\Actions\Action;
use Filament\Actions\CreateAction;
@@ -27,14 +26,6 @@ class ListStatistikoEvents extends ListRecords
CreateAction::make()
->label('New')
->icon('phosphor-plus'),
- // ImportAction::make('importEvents')
- // ->maxRows(200000)
- // ->color('success')
- // ->chunkSize(250)
- // ->icon('phosphor-upload')
- // ->label('Import')
- // ->modalDescription('Max 20k rows per import, column separator: ";"')
- // ->importer(StatistikoEventImporter::class),
];
}
}
diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/StatistikoEventsResource.php b/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/StatistikoEventsResource.php
index d8a5c354..3ffd6adf 100644
--- a/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/StatistikoEventsResource.php
+++ b/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/StatistikoEventsResource.php
@@ -47,9 +47,4 @@ class StatistikoEventsResource extends Resource
{
return parent::getEloquentQuery()->count();
}
-
- public static function getNavigationBadgeColor(): ?string
- {
- return 'success';
- }
}
diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Tables/StatistikoEventsTable.php b/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Tables/StatistikoEventsTable.php
index 5fb2e6ca..7d75c402 100644
--- a/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Tables/StatistikoEventsTable.php
+++ b/app/Filament/Clusters/StaticData/Resources/StatistikoEvents/Tables/StatistikoEventsTable.php
@@ -2,7 +2,6 @@
namespace App\Filament\Clusters\StaticData\Resources\StatistikoEvents\Tables;
-use App\Models\Sport;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoImports/Schemas/StatistikoImportForm.php b/app/Filament/Clusters/StaticData/Resources/StatistikoImports/Schemas/StatistikoImportForm.php
index 82d4c2c0..a01ad695 100644
--- a/app/Filament/Clusters/StaticData/Resources/StatistikoImports/Schemas/StatistikoImportForm.php
+++ b/app/Filament/Clusters/StaticData/Resources/StatistikoImports/Schemas/StatistikoImportForm.php
@@ -20,10 +20,12 @@ class StatistikoImportForm
->options(Sport::where('is_active', 1)->pluck('name', 'id')),
Select::make('data_type')
->required()
+ ->allowHtml()
->options([
- 'player' => 'Player',
- 'events' => 'Events',
- 'events_player' => 'Events & Player',
+ 'player' => 'Player',
+ 'events' => 'Events',
+ 'fixtures' => 'Fixtures',
+ 'events_player' => 'Events & Player',
]),
FileUpload::make('file_name')
diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoImports/Tables/StatistikoImportsTable.php b/app/Filament/Clusters/StaticData/Resources/StatistikoImports/Tables/StatistikoImportsTable.php
index 0f593303..75f48f16 100644
--- a/app/Filament/Clusters/StaticData/Resources/StatistikoImports/Tables/StatistikoImportsTable.php
+++ b/app/Filament/Clusters/StaticData/Resources/StatistikoImports/Tables/StatistikoImportsTable.php
@@ -34,11 +34,11 @@ class StatistikoImportsTable
->options([
'player' => 'Player',
'events' => 'Events',
+ 'fixtures' => 'Fixtures',
'events_player' => 'Events & Player',
]),
TextColumn::make('file_name_original')
->searchable()
- ->color('primary')
->label('Name'),
IconColumn::make('has_run')
->label('Import')
diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/Pages/ListStatistikoPlayers.php b/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/Pages/ListStatistikoPlayers.php
index 7d46fe60..6526300c 100644
--- a/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/Pages/ListStatistikoPlayers.php
+++ b/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/Pages/ListStatistikoPlayers.php
@@ -3,11 +3,9 @@
namespace App\Filament\Clusters\StaticData\Resources\StatistikoPlayers\Pages;
use App\Filament\Clusters\StaticData\Resources\StatistikoPlayers\StatistikoPlayerResource;
-// use App\Filament\Imports\StatistikoPlayerImporter;
use App\Models\StatistikoPlayer;
use Filament\Actions\Action;
use Filament\Actions\CreateAction;
-// use Filament\Actions\ImportAction;
use Filament\Resources\Pages\ListRecords;
class ListStatistikoPlayers extends ListRecords
@@ -27,14 +25,6 @@ class ListStatistikoPlayers extends ListRecords
CreateAction::make()
->label('New')
->icon('phosphor-plus'),
- // ImportAction::make('importPlayer')
- // ->maxRows(200000)
- // ->color('success')
- // ->chunkSize(250)
- // ->icon('phosphor-upload')
- // ->label('Import')
- // ->modalDescription('Max 20k rows per import, column separator ";"')
- // ->importer(StatistikoPlayerImporter::class),
];
}
}
diff --git a/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/StatistikoPlayerResource.php b/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/StatistikoPlayerResource.php
index 61148e29..4aa43324 100644
--- a/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/StatistikoPlayerResource.php
+++ b/app/Filament/Clusters/StaticData/Resources/StatistikoPlayers/StatistikoPlayerResource.php
@@ -24,7 +24,7 @@ class StatistikoPlayerResource extends Resource
protected static ?string $cluster = StaticDataCluster::class;
- protected static ?int $navigationSort = 2;
+ protected static ?int $navigationSort = 4;
protected static ?string $recordTitleAttribute = 'giocatore';
@@ -49,9 +49,4 @@ class StatistikoPlayerResource extends Resource
{
return parent::getEloquentQuery()->count();
}
-
- public static function getNavigationBadgeColor(): ?string
- {
- return 'success';
- }
}
diff --git a/app/Filament/Clusters/Statistic/Resources/StatisticEvents/Pages/CreateStatisticEvents.php b/app/Filament/Clusters/Statistic/Resources/StatisticEvents/Pages/CreateStatisticEvents.php
deleted file mode 100644
index 7771b26e..00000000
--- a/app/Filament/Clusters/Statistic/Resources/StatisticEvents/Pages/CreateStatisticEvents.php
+++ /dev/null
@@ -1,11 +0,0 @@
-components([
- //
- ]);
- }
-}
diff --git a/app/Filament/Clusters/Statistic/Resources/StatisticEvents/StatisticEventsResource.php b/app/Filament/Clusters/Statistic/Resources/StatisticEvents/StatisticEventsResource.php
deleted file mode 100644
index c4f2dfc3..00000000
--- a/app/Filament/Clusters/Statistic/Resources/StatisticEvents/StatisticEventsResource.php
+++ /dev/null
@@ -1,47 +0,0 @@
- ListStatisticEvents::route('/'),
- ];
- }
-}
diff --git a/app/Filament/Clusters/Statistic/Resources/StatisticEvents/Tables/StatisticEventsTable.php b/app/Filament/Clusters/Statistic/Resources/StatisticEvents/Tables/StatisticEventsTable.php
deleted file mode 100644
index a4cee8b5..00000000
--- a/app/Filament/Clusters/Statistic/Resources/StatisticEvents/Tables/StatisticEventsTable.php
+++ /dev/null
@@ -1,189 +0,0 @@
-striped()
- ->columns([
- IconColumn::make('sport_id')
- ->label('')
- ->icon(fn (string $state): string => match ($state) {
- '1' => 'icon-soccerball',
- '2' => 'icon-icehockey',
- '3' => 'icon-basketball',
- '5' => 'icon-tennisball',
- }),
- TextColumn::make('league.name')->searchable(),
- TextColumn::make('starttime')->dateTime('M j, Y')->label('Date'),
- TextColumn::make('home.name')->color('primary')->searchable(),
- TextColumn::make('away.name')->color('success')->searchable(),
- ])
- ->filters([
- Filter::make('events')
- ->columns(5)->columnSpan(5)
- ->schema([
- Select::make('sport_id')
- ->default(1)
- ->hiddenLabel()
- ->options(Sport::whereIn('id', [1, 2, 3, 5])->pluck('name', 'id')),
- Select::make(name: 'country_id')
- ->hidden(fn (Get $get) => $get('sport_id') == 5)
- ->placeholder('Country')
- ->prefixIcon('phosphor-flag')
- ->hiddenLabel()
- ->searchable()
- ->options(function (Get $get) {
- $res = Event::where('has_markets', 1)
- ->where('sport_id', $get('sport_id'))
- ->groupBy('country_id')
- ->pluck('country_id')->toArray();
-
- return Country::query()->whereIn('id', $res)->orderBy('name')->pluck('name', 'id');
- })
- ->live()
- ->reactive()
- ->afterStateUpdated(function (callable $set) {
- $set('competition_group_id', null);
- }),
- Select::make('competition_group_id')
- ->placeholder(fn (Get $get) => $get('sport_id') == 5 ? 'Tournament' : 'League')
- ->prefixIcon('phosphor-trophy')
- ->hiddenLabel()
- // ->multiple()
- ->searchable()
- ->options(function (Get $get) {
- $country_id = $get('country_id') ?? 0;
- $res = Event::with('country')
- ->with('competition_group')
- ->where('sport_id', $get('sport_id'))
- ->when($country_id, function ($query, $country_id) {
- $query->where('country_id', $country_id);
- })->groupBy('competition_group_id')->get();
-
- $arr = [];
- foreach ($res as $val) {
- $arr[(int) $val->competition_group_id] = $val->country?->name.' '.$val->competition_group?->name;
- }
-
- asort($arr);
-
- return $arr;
- })
- ->live(),
- DatePicker::make('starttime_from')
- ->prefix(fn () => new HtmlString('From'))
- ->displayFormat('d M Y')
- ->hiddenLabel()
- ->label(''),
- DatePicker::make('starttime_to')
- ->prefix(fn () => new HtmlString('To:'))
- ->displayFormat('d M Y')
- ->hiddenLabel()
- ->label(''),
- ])
- ->query(function (Builder $query, array $data): Builder {
- return $query->when(
- $data['sport_id'],
- function (Builder $query, $sport_id) {
- $query->where('sport_id', (int) $sport_id);
- }
- )->when(
- $data['competition_group_id'],
- function (Builder $query, $competition_group_id) {
- // dd($competition_group_id);
- $query->where('league_id', (int) $competition_group_id);
- }
- )->when(
- $data['starttime_from'],
- function (Builder $query, $starttime_from) {
- if (isset($starttime_from)) {
- $from = Carbon::createFromDate($starttime_from);
-
- return $query->where('starttime', '>=', $starttime_from);
- }
- }
- )->when(
- $data['starttime_to'],
- function (Builder $query, $starttime_to) {
- if (isset($starttime_to)) {
- $to = Carbon::createFromDate($starttime_to);
-
- return $query->where('starttime', '<=', $starttime_to);
- }
- }
- );
- })->indicateUsing(function (array $data): array {
- $indicators = [];
-
- if ($data['starttime_from'] ?? null) {
- $starttime_from = $data['starttime_from'];
- if ($starttime_from ?? null) {
- $text = Carbon::parse($starttime_from)->format('d. M. Y');
- $indicators[] = Indicator::make('From: '.$text)->removeField('starttime_from')->color('info');
- }
- }
- if ($data['starttime_to'] ?? null) {
- $starttime_to = $data['starttime_to'];
- if ($starttime_to ?? null) {
- $text = Carbon::parse($starttime_to)->format('d. M. Y');
- $indicators[] = Indicator::make('To: '.$text)->removeField('starttime_to')->color('success');
- }
- }
-
- if ($data['country_id'] ?? null) {
- $country_id = $data['country_id'];
- if ($country_id ?? null) {
- $text = Country::where('id', $country_id)->value('name');
- $indicators[] = Indicator::make('Country: '.$text)->removeField('country_id');
- }
- }
-
- // if ($data['competition_group_id'] ?? null) {
- // $competition_groups = CompetitionGroup::whereIn('id', $data['competition_group_id'])->pluck('name')->toArray();
- // if (count($competition_groups) > 1) {
- // $indicators[] = Indicator::make(implode(', ', $competition_groups))->removeField('competition_group_id')->color('info');
- // } else {
- // $indicators[] = Indicator::make($competition_groups[0])->removeField('competition_group_id')->color('info')->color('info');
- // }
- // }
-
- return $indicators;
- }),
-
- ], layout: FiltersLayout::AboveContent)
- ->deferFilters(false)
- ->hiddenFilterIndicators(false)
- ->persistFiltersInSession()
- ->recordActions([
- EditAction::make(),
- ])
- ->toolbarActions([
- BulkActionGroup::make([
- DeleteBulkAction::make(),
- ]),
- ]);
- }
-}
diff --git a/app/Filament/Clusters/Statistic/StatisticCluster.php b/app/Filament/Clusters/Statistic/StatisticCluster.php
deleted file mode 100644
index d4a19b81..00000000
--- a/app/Filament/Clusters/Statistic/StatisticCluster.php
+++ /dev/null
@@ -1,16 +0,0 @@
-table($table)->count();
+ self::$benchmarkStartTime = microtime(true);
+ self::$benchmarkStartMemory = memory_get_usage();
+ DB::connection('mongodb')->enableQueryLog();
+ }
+
+ public static function end(string $table): void
+ {
+ $executionTime = microtime(true) - self::$benchmarkStartTime;
+ $memoryUsage = round((memory_get_usage() - self::$benchmarkStartMemory) / 1024 / 1024, 2);
+
+ $logs = DB::connection('mongodb')->getQueryLog();
+ $queriesCount = \count($logs);
+
+ // Get row count after we've stopped tracking queries
+ $rowDiff = DB::connection('mongodb')->table($table)->count() - self::$startRowCount;
+
+ $formattedTime = match (true) {
+ $executionTime >= 60 => sprintf('%dm %ds', floor($executionTime / 60), $executionTime % 60),
+ $executionTime >= 1 => round($executionTime, 2).'s',
+ default => round($executionTime * 1000).'ms',
+ };
+
+ $str = '⚡ TIME: '.$formattedTime;
+ $str .= '
MEM: '.$memoryUsage.'MB';
+ $str .= '
SQL: '.number_format($queriesCount);
+ $str .= '
ROWS: '.number_format($rowDiff);
+
+ $recipient = auth()->user();
+
+ Notification::make()
+ ->success()
+ ->title('Import compleated')
+ ->body(new HtmlString($str))
+ ->sendToDatabase($recipient);
+ }
+}
diff --git a/app/Filament/Imports/Helper/ImportEvents.php b/app/Filament/Imports/Helper/ImportEvents.php
new file mode 100644
index 00000000..8c477e84
--- /dev/null
+++ b/app/Filament/Imports/Helper/ImportEvents.php
@@ -0,0 +1,59 @@
+format('Y-m-d H:i:s');
+
+ SimpleExcelReader::create(storage_path('app/public/'.$filePath))
+ ->getRows()
+ ->chunk(1000)
+ ->each(function (LazyCollection $chunk) use ($now, $sport_id) {
+
+ foreach ($chunk as $row) {
+
+ $row = array_values($row);
+
+ StatistikoEvent::where('sport_id', $sport_id)
+ ->where('league_id', $row[0])
+ ->where('home_id', $row[1])
+ ->where('away_id', $row[2])
+ ->where('starttime', Carbon::parse($row[3])->toIso8601String())
+ ->update(
+ [
+ 'season' => $row[4],
+ 'gls_h' => $row[5],
+ 'gls_a' => $row[6],
+ 'crn_h' => $row[7],
+ 'crn_a' => $row[8],
+ 'fls_h' => $row[9],
+ 'fls_a' => $row[10],
+ 'ofs_h' => $row[11],
+ 'ofs_a' => $row[12],
+ 'snt_h' => $row[13],
+ 'snt_a' => $row[14],
+ 'tsh_h' => $row[15],
+ 'tsh_a' => $row[16],
+ 'crd_h' => $row[17],
+ 'crd_a' => $row[18],
+ 'expgoalshome_value' => $row[19],
+ 'expgoalsaway_value' => $row[20],
+ 'exp_handicap' => $row[21],
+ 'exp_total' => $row[22],
+ 'created_at' => $now,
+ 'updated_at' => $now,
+ ],
+ ['upsert' => true],
+ );
+ }
+ });
+ }
+}
diff --git a/app/Filament/Imports/Helper/ImportFixtures.php b/app/Filament/Imports/Helper/ImportFixtures.php
new file mode 100644
index 00000000..9c037df7
--- /dev/null
+++ b/app/Filament/Imports/Helper/ImportFixtures.php
@@ -0,0 +1,45 @@
+getRows()
+ ->chunk(200)
+ ->each(function (LazyCollection $chunk) use ($sport_id) {
+
+ foreach ($chunk as $row) {
+
+ $row = array_values($row);
+
+ /*
+ 0 => 87
+ 1 => 3614
+ 2 => 1491
+ 3 => DateTimeImmutable @1777334400 {#2722 ▶}
+ 4 => 0.90433699503783
+ 5 => 1.035168989838
+ */
+
+ StatisticFixtures::updateOrCreate(
+ [
+ 'sport_id' => (int) $sport_id,
+ 'league_id' => (int) $row[0],
+ 'home_id' => (int) $row[1],
+ 'away_id' => (int) $row[2],
+ 'starttime' => Carbon::parse($row[3])->toDateString(),
+ ],
+ ['exp_home' => (float) $row[4], 'exp_away' => (float) $row[5]]
+ );
+ }
+ });
+ }
+}
diff --git a/app/Filament/Imports/Helper/ImportPlayer.php b/app/Filament/Imports/Helper/ImportPlayer.php
new file mode 100644
index 00000000..7c73bb64
--- /dev/null
+++ b/app/Filament/Imports/Helper/ImportPlayer.php
@@ -0,0 +1,52 @@
+format('Y-m-d H:i:s');
+
+ SimpleExcelReader::create(storage_path('app/public/'.$filePath))
+ ->getRows()
+ ->chunk(1000)
+ ->each(function (LazyCollection $chunk) use ($now) {
+
+ foreach ($chunk as $row) {
+
+ $row = array_values($row);
+
+ StatistikoPlayer::where('player_id', $row[0])
+ ->update(
+ [
+ 'name' => $row[1],
+ 'birthdate' => Carbon::parse($row[2])->toDateString(),
+ 'height' => $row[3],
+ 'nationality' => $row[4],
+ 'position' => $row[5],
+ 'sport_radar_id' => $row[6],
+ 'id_squadra_tm' => $row[7],
+ 'full_name' => $row[8],
+ 'no_specialities' => $row[9],
+ 'rigorist' => $row[10],
+ 'national_team_id' => $row[11],
+ 'last_update' => Carbon::parse($row[12])->toDateString(),
+ 'league_code' => $row[13],
+ 'team_code' => $row[14],
+ 'team_name' => $row[15],
+ 'created_at' => $now,
+ 'updated_at' => $now,
+ ],
+ ['upsert' => true],
+ );
+
+ }
+ });
+ }
+}
diff --git a/app/Filament/Imports/StatistikoEventImporter.php b/app/Filament/Imports/StatistikoEventImporter.php
deleted file mode 100644
index fb059ef1..00000000
--- a/app/Filament/Imports/StatistikoEventImporter.php
+++ /dev/null
@@ -1,104 +0,0 @@
-where('sport_id', $this->data['sport_id'])
- ->where('league_id', $this->data['league_id'])
- ->where('home_id', $this->data['home_id'])
- ->where('away_id', $this->data['away_id'])
- ->where('starttime', $this->data['starttime'])
- ->first();
- if ($res) {
- return StatistikoEvent::find($res->id);
- } else {
- return new StatistikoEvent;
- }
- }
-
- public static function getColumns(): array
- {
- return [
- ImportColumn::make('sport_id')->numeric()->guess(['SPORT']),
- ImportColumn::make('league_id')->numeric()->guess(['LEAGUE']),
- ImportColumn::make('home_id')->numeric()->guess(['HOME']),
- ImportColumn::make('away_id')->numeric()->guess(['AWAY']),
- ImportColumn::make('starttime')
- ->guess(['STARTTIME'])
- ->castStateUsing(function ($state) {
- return Carbon::parse($state);
- }),
- ImportColumn::make('season')->guess(['SEASON']),
- ImportColumn::make('gls_h')->numeric(),
- ImportColumn::make('gls_a')->numeric(),
- ImportColumn::make('crn_h')->numeric(),
- ImportColumn::make('fls_h')->numeric(),
- ImportColumn::make('ofs_h')->numeric(),
- ImportColumn::make('snt_h')->numeric(),
- ImportColumn::make('tsh_h')->numeric(),
- ImportColumn::make('crd_h')->numeric(),
- ImportColumn::make('crn_a')->numeric(),
- ImportColumn::make('fls_a')->numeric(),
- ImportColumn::make('ofs_a')->numeric(),
- ImportColumn::make('snt_a')->numeric(),
- ImportColumn::make('tsh_a')->numeric(),
- ImportColumn::make('crd_a')->numeric(),
- ImportColumn::make('expgoalshome_value')
- ->castStateUsing(function (string $state) {
- if (blank($state)) {
- return null;
- }
-
- return (float) str_replace(',', '.', $state);
- }),
- ImportColumn::make('expgoalsaway_value')
- ->castStateUsing(function (string $state) {
- if (blank($state)) {
- return null;
- }
-
- return str_replace(',', '.', $state);
- }),
- ImportColumn::make('exp_handicap')
- ->castStateUsing(function (string $state) {
- if (blank($state)) {
- return null;
- }
-
- return str_replace(',', '.', $state);
- }),
- ImportColumn::make('exp_total')
- ->castStateUsing(function (string $state) {
- if (blank($state)) {
- return null;
- }
-
- return str_replace(',', '.', $state);
- }),
- ];
- }
-
- public static function getCompletedNotificationBody(Import $import): string
- {
- $body = 'Your events import has completed and '.Number::format($import->successful_rows).' '.str('row')->plural($import->successful_rows).' imported.';
-
- if ($failedRowsCount = $import->getFailedRowsCount()) {
- $body .= ' '.Number::format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
- }
-
- return $body;
- }
-}
diff --git a/app/Filament/Imports/StatistikoImporter.php b/app/Filament/Imports/StatistikoImporter.php
index ffd120ce..3cc88949 100644
--- a/app/Filament/Imports/StatistikoImporter.php
+++ b/app/Filament/Imports/StatistikoImporter.php
@@ -2,15 +2,11 @@
namespace App\Filament\Imports;
-use App\Models\StatistikoEvent;
+use App\Filament\Imports\Helper\ImportBenchmark;
+use App\Filament\Imports\Helper\ImportEvents;
+use App\Filament\Imports\Helper\ImportFixtures;
+use App\Filament\Imports\Helper\ImportPlayer;
use App\Models\StatistikoImport;
-use App\Models\StatistikoPlayer;
-use Filament\Notifications\Notification;
-use Illuminate\Support\Carbon;
-use Illuminate\Support\Facades\DB;
-use Illuminate\Support\HtmlString;
-use Illuminate\Support\LazyCollection;
-use Spatie\SimpleExcel\SimpleExcelReader;
class StatistikoImporter
{
@@ -33,14 +29,17 @@ class StatistikoImporter
$filePath = $record['file_name'];
$sport_id = $record['sport_id'];
- self::startBenchmark($table);
+ ImportBenchmark::start($table);
switch ($record['data_type']) {
case 'player':
- self::importPlayer($filePath);
+ ImportPlayer::run($filePath);
break;
case 'events':
- self::importEvents($filePath, $sport_id);
+ ImportEvents::run($filePath, $sport_id);
+ break;
+ case 'fixtures':
+ ImportFixtures::run($filePath, $sport_id);
break;
case 'events_player':
break;
@@ -48,134 +47,6 @@ class StatistikoImporter
StatistikoImport::where('id', $record->id)->update(['has_run' => 1]);
- self::endBenchmark($table);
- }
-
- protected static function startBenchmark(string $table): void
- {
- self::$startRowCount = DB::connection('mongodb')->table($table)->count();
- self::$benchmarkStartTime = microtime(true);
- self::$benchmarkStartMemory = memory_get_usage();
- DB::connection('mongodb')->enableQueryLog();
- }
-
- protected static function endBenchmark(string $table): void
- {
- $executionTime = microtime(true) - self::$benchmarkStartTime;
- $memoryUsage = round((memory_get_usage() - self::$benchmarkStartMemory) / 1024 / 1024, 2);
-
- $logs = DB::connection('mongodb')->getQueryLog();
- $queriesCount = \count($logs);
-
- // Get row count after we've stopped tracking queries
- $rowDiff = DB::connection('mongodb')->table($table)->count() - self::$startRowCount;
-
- $formattedTime = match (true) {
- $executionTime >= 60 => sprintf('%dm %ds', floor($executionTime / 60), $executionTime % 60),
- $executionTime >= 1 => round($executionTime, 2).'s',
- default => round($executionTime * 1000).'ms',
- };
-
- $str = '⚡ TIME: '.$formattedTime;
- $str .= '
MEM: '.$memoryUsage.'MB';
- $str .= '
SQL: '.number_format($queriesCount);
- $str .= '
ROWS: '.number_format($rowDiff);
-
- $recipient = auth()->user();
-
- Notification::make()
- ->success()
- ->title('Import compleated')
- ->body(new HtmlString($str))
- ->sendToDatabase($recipient);
- }
-
- private static function importPlayer(string $filePath): void
- {
- $now = now()->format('Y-m-d H:i:s');
-
- SimpleExcelReader::create(storage_path('app/public/'.$filePath))
- ->getRows()
- ->chunk(1000)
- ->each(function (LazyCollection $chunk) use ($now) {
-
- foreach ($chunk as $row) {
-
- $row = array_values($row);
-
- StatistikoPlayer::where('player_id', $row[0])
- ->update(
- [
- 'name' => $row[1],
- 'birthdate' => Carbon::parse($row[2])->toDateString(),
- 'height' => $row[3],
- 'nationality' => $row[4],
- 'position' => $row[5],
- 'sport_radar_id' => $row[6],
- 'id_squadra_tm' => $row[7],
- 'full_name' => $row[8],
- 'no_specialities' => $row[9],
- 'rigorist' => $row[10],
- 'national_team_id' => $row[11],
- 'last_update' => Carbon::parse($row[12])->toDateString(),
- 'league_code' => $row[13],
- 'team_code' => $row[14],
- 'team_name' => $row[15],
- 'created_at' => $now,
- 'updated_at' => $now,
- ],
- ['upsert' => true],
- );
-
- }
- });
- }
-
- private static function importEvents(string $filePath, int $sport_id): void
- {
- $now = now()->format('Y-m-d H:i:s');
-
- SimpleExcelReader::create(storage_path('app/public/'.$filePath))
- ->getRows()
- ->chunk(1000)
- ->each(function (LazyCollection $chunk) use ($now, $sport_id) {
-
- foreach ($chunk as $row) {
-
- $row = array_values($row);
-
- StatistikoEvent::where('sport_id', $sport_id)
- ->where('league_id', $row[0])
- ->where('home_id', $row[1])
- ->where('away_id', $row[2])
- ->where('starttime', Carbon::parse($row[3])->toIso8601String())
- ->update(
- [
- 'season' => $row[4],
- 'gls_h' => $row[5],
- 'gls_a' => $row[6],
- 'crn_h' => $row[7],
- 'crn_a' => $row[8],
- 'fls_h' => $row[9],
- 'fls_a' => $row[10],
- 'ofs_h' => $row[11],
- 'ofs_a' => $row[12],
- 'snt_h' => $row[13],
- 'snt_a' => $row[14],
- 'tsh_h' => $row[15],
- 'tsh_a' => $row[16],
- 'crd_h' => $row[17],
- 'crd_a' => $row[18],
- 'expgoalshome_value' => $row[19],
- 'expgoalsaway_value' => $row[20],
- 'exp_handicap' => $row[21],
- 'exp_total' => $row[22],
- 'created_at' => $now,
- 'updated_at' => $now,
- ],
- ['upsert' => true],
- );
- }
- });
+ ImportBenchmark::end($table);
}
}
diff --git a/app/Filament/Imports/StatistikoPlayerImporter.php b/app/Filament/Imports/StatistikoPlayerImporter.php
deleted file mode 100644
index 559271d2..00000000
--- a/app/Filament/Imports/StatistikoPlayerImporter.php
+++ /dev/null
@@ -1,130 +0,0 @@
-where('id_giocatore', $this->data['id_giocatore'])
- ->first();
- if ($res) {
- return StatistikoPlayer::find($res->id);
- } else {
- return new StatistikoPlayer;
- }
- }
-
- public static function getColumns(): array
- {
- return [
- ImportColumn::make('id_giocatore')
- ->label('ID GIOCATORE'),
- ImportColumn::make('giocatore')
- ->label('GIOCATORE')
- ->castStateUsing(function (string $state): ?string {
- if (blank($state)) {
- return null;
- }
-
- return (string) trim($state);
- }),
- ImportColumn::make('data_di_nascita')
- ->label('DATA DI NASCITA')
- ->castStateUsing(function ($state) {
- if (blank($state)) {
- return null;
- }
-
- return Carbon::parse($state);
- }),
- ImportColumn::make('altezza')
- ->label('ALTEZZA')
- ->numeric(),
- ImportColumn::make('nazionalita')
- ->label('NAZIONALITA')
- ->castStateUsing(function (string $state): ?string {
- return (string) trim($state);
- }),
- ImportColumn::make('posizione')
- ->label('POSIZIONE')
- ->castStateUsing(function (string $state): ?string {
- if (blank($state)) {
- return null;
- }
-
- return (string) trim($state);
- }),
- ImportColumn::make('sport_radar_id')
- ->label('SPORT RADAR ID'),
- ImportColumn::make('id_squadra_tm')
- ->label('ID SQUADRA TM'),
- ImportColumn::make('nome_completo')
- ->label('NOME COMPLETO')
- ->castStateUsing(function (?string $state): ?string {
- if (blank($state)) {
- return null;
- }
-
- return (string) trim($state);
- }),
- ImportColumn::make('rigorista')
- ->label('RIGORISTA')
- ->castStateUsing(function (?string $state): ?string {
- if (blank($state)) {
- return null;
- }
-
- return (string) trim($state);
- }),
- ImportColumn::make('national_team_id')
- ->label('NATIONAL TEAM ID'),
- ImportColumn::make('data_aggiornamento')
- ->label('DATA AGGIORNAMENTO')
- ->castStateUsing(function ($state) {
- return Carbon::parse($state);
- }),
- ImportColumn::make('league_code')
- ->label('LEAGUE CODE')
- ->castStateUsing(function (string $state): ?string {
- return (string) trim($state);
- }),
- ImportColumn::make('team_code')
- ->label('TEAM CODE')
- ->castStateUsing(function (string $state): ?string {
- return (string) trim($state);
- }),
- ImportColumn::make('team_name')
- ->label('TEAM NAME')
- ->castStateUsing(function (string $state): ?string {
- return (string) trim($state);
- }),
- ];
- }
-
- public static function getCompletedNotificationBody(Import $import): string
- {
- $body = 'Your player import has completed and '.Number::format($import->successful_rows).' '.str('row')->plural($import->successful_rows).' imported.';
-
- if ($failedRowsCount = $import->getFailedRowsCount()) {
- $body .= ' '.Number::format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
- }
-
- return $body;
- }
-}
diff --git a/app/Filament/Pages/Statistic.php b/app/Filament/Pages/Statistic.php
new file mode 100644
index 00000000..053f5382
--- /dev/null
+++ b/app/Filament/Pages/Statistic.php
@@ -0,0 +1,127 @@
+components([
+ Section::make()
+ ->schema([
+ Select::make('league_id')
+ ->prefixIcon('phosphor-trophy')
+ ->options(function () {
+ $res = StatisticFixtures::where('sport_id', 1)
+ ->groupBy('league_id')
+ ->pluck('league_id')->toArray();
+
+ return CompetitionGroup::query()->whereIn('id', $res)->orderBy('name')->pluck('name', 'id');
+ })
+ ->preload()
+ ->searchable()
+ ->live()
+ ->label('League'),
+ Select::make('team_id')
+ ->prefixIcon('icon-team')
+ ->options(function (Get $get) {
+ if ($get('league_id')) {
+ $res = StatisticFixtures::where('league_id', $get('league_id'))->get();
+ $arr = [];
+ foreach ($res as $value) {
+ $arr[] = $value->home_id;
+ $arr[] = $value->away_id;
+ }
+
+ $arr = array_unique($arr);
+
+ return Element::query()->whereIn('id', $arr)->orderBy('name')->pluck('name', 'id');
+ }
+ })
+ ->preload()
+ ->searchable()
+ ->label('Team'),
+ DatePicker::make('startDate'),
+ DatePicker::make('endDate'),
+ ])->columns(4)
+ ->columnSpanFull(),
+ Section::make()
+ ->schema([
+ Select::make('palyer_id')
+ ->label('Player')
+ ->prefixIcon('icon-player')
+ ->options(function () {
+ $res = StatisticFixtures::where('sport_id', 1)
+ ->groupBy('league_id')
+ ->pluck('league_id')->toArray();
+
+ return CompetitionGroup::query()->whereIn('id', $res)->orderBy('name')->pluck('name', 'id');
+ })
+ ->preload()
+ ->searchable()
+ ->live(),
+ Select::make('team_position')
+ ->prefixIcon('phosphor-map-pin')
+ ->default('home')
+ ->selectablePlaceholder(false)
+ ->options([
+ 'home' => 'Home',
+ 'away' => 'Away',
+ 'all' => 'All',
+ ]),
+ Select::make('similar_past_matches')
+ ->prefixIcon('phosphor-align-center-horizontal')
+ ->default('none')
+ ->selectablePlaceholder(false)
+ ->options([
+ 'none' => 'None',
+ 'league' => 'League',
+ 'all' => 'All Database',
+ ]),
+ Select::make('statistic_type')
+ ->prefixIcon('phosphor-cell-signal-full')
+ ->default('none')
+ ->selectablePlaceholder(false)
+ ->options([
+ 'gls' => 'Gouls',
+ 'crn' => 'Corner',
+ 'fls' => 'Fouls commited',
+ 'ofs' => 'Offside',
+ 'crd' => 'Cards',
+ 'snt' => 'Shot on target',
+ 'tsh' => 'Total shots',
+ ]),
+ ])->columns(4)
+ ->columnSpanFull(),
+ Slider::make('accuracy')
+ ->default(0.5)
+ ->decimalPlaces(1)
+ ->tooltips()
+ ->fillTrack()
+ ->range(minValue: 0, maxValue: 1)
+ ->pips(),
+ ]);
+ }
+}
diff --git a/app/Filament/Resources/Events/Tables/EventsTable.php b/app/Filament/Resources/Events/Tables/EventsTable.php
index 9ca847aa..0d871581 100644
--- a/app/Filament/Resources/Events/Tables/EventsTable.php
+++ b/app/Filament/Resources/Events/Tables/EventsTable.php
@@ -37,7 +37,6 @@ use Filament\Tables\Enums\FiltersLayout;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\Indicator;
use Filament\Tables\Table;
-use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
diff --git a/app/Filament/Widgets/StatisticChart.php b/app/Filament/Widgets/StatisticChart.php
new file mode 100644
index 00000000..4f930fde
--- /dev/null
+++ b/app/Filament/Widgets/StatisticChart.php
@@ -0,0 +1,22 @@
+ 'date',
+ ];
+ }
+
+ public function sport()
+ {
+ return $this->belongsTo(Sport::class)->where('is_active', 1);
+ }
+
+ public function league()
+ {
+ return $this->belongsTo(CompetitionGroup::class);
+ }
+
+ public function home()
+ {
+ return $this->belongsTo(Element::class);
+ }
+
+ public function away()
+ {
+ return $this->belongsTo(Element::class);
+ }
+}
diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php
index 157688dc..d8742105 100644
--- a/app/Providers/Filament/AdminPanelProvider.php
+++ b/app/Providers/Filament/AdminPanelProvider.php
@@ -4,6 +4,8 @@ namespace App\Providers\Filament;
// use Agencetwogether\HooksHelper\HooksHelperPlugin;
use App\Filament\Exports\BetfairExporter;
+use App\Filament\Pages\Statistic;
+use App\Filament\Widgets\StatisticChart;
use App\Http\Middleware\RecordUserActivity;
use Awcodes\LightSwitch\Enums\Alignment;
use Awcodes\LightSwitch\LightSwitchPlugin;
@@ -21,8 +23,6 @@ use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Enums\Width;
-use Filament\Widgets\AccountWidget;
-use Filament\Widgets\FilamentInfoWidget;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Database\Eloquent\Builder;
@@ -87,9 +87,6 @@ class AdminPanelProvider extends PanelProvider
->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages')
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets')
->discoverClusters(in: app_path('Filament/Clusters'), for: 'App\\Filament\\Clusters')
- ->pages([
- // Dashboard::class,
- ])
->maxContentWidth(Width::ScreenTwoExtraLarge)
->breadcrumbs(false)
->topNavigation()
@@ -100,9 +97,11 @@ class AdminPanelProvider extends PanelProvider
->url(fn (): string => EditProfilePage::getUrl())
->icon('phosphor-user-circle-fill'),
])
+ ->pages([
+ Statistic::class,
+ ])
->widgets([
- AccountWidget::class,
- FilamentInfoWidget::class,
+ StatisticChart::class,
])
->middleware([
EncryptCookies::class,
diff --git a/database/migrations/2026_04_28_075531_create_statistic_fixtures_table.php b/database/migrations/2026_04_28_075531_create_statistic_fixtures_table.php
new file mode 100644
index 00000000..0af4a43d
--- /dev/null
+++ b/database/migrations/2026_04_28_075531_create_statistic_fixtures_table.php
@@ -0,0 +1,34 @@
+id();
+ $table->integer('sport_id')->index();
+ $table->integer('league_id')->index();
+ $table->integer('home_id')->index();
+ $table->integer('away_id')->index();
+ $table->dateTime('starttime')->index();
+ $table->decimal('exp_home', 15, 14)->default(0);
+ $table->decimal('exp_away', 15, 14)->default(0);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('statistic_fixtures');
+ }
+};
diff --git a/resources/views/filament/pages/statistic.blade.php b/resources/views/filament/pages/statistic.blade.php
new file mode 100644
index 00000000..166e4fa1
--- /dev/null
+++ b/resources/views/filament/pages/statistic.blade.php
@@ -0,0 +1,2 @@
+
+