diff --git a/app/Actions/MultilineGenerator.php b/app/Actions/MultilineGenerator.php
new file mode 100644
index 00000000..e0d09b4b
--- /dev/null
+++ b/app/Actions/MultilineGenerator.php
@@ -0,0 +1,8 @@
+all();
+ $_provider = Provider::get()->all();
+ $_sports = Sport::where('is_active', 1)->get()->all();
+ $_bookmaker = Bookmaker::where('is_active', 1)->get()->all();
+
+ $processes = Supervisor::where('command', $command)->get()->all();
+
+ $have = [];
+ foreach ($processes as $process) {
+
+ dd($process);
+
+ $have[] = $process['code'];
+
+ $tmp = [];
+ $tmp['process'] = $process->command;
+
+ if (! $process->per_sport && ! $process->per_client) {
+ // $tmp['code'] = $row->command.$row->process;
+ // $tmp['command'] = $row->command.' '.$row->process;
+ // $tmp['description'] = $row->description;
+ // $res = Supervisor::where('code', $tmp['code'])->get();
+ // if (! $res->count()) {
+ // Supervisor::insert($tmp);
+ // }
+
+ } elseif ($process->per_sport && ! $process->per_client) {
+ foreach ($sports as $sport) {
+ $tmp['command'] = $process->process.$sport->code;
+ $tmp['sport_id'] = $sport->id;
+ $tmp['description'] = $process->description.' '.$sport->sport;
+ $flight = Supervisor::updateOrCreate(
+ ['code' => $process->command.$sport->code, 'sport_id' => $sport->id],
+ ['command' => $process->process.$sport->code, 'description' => $process->description]
+ );
+ }
+
+ // } elseif (! $row->per_sport && $row->per_client) {
+ // foreach ($clients as $client) {
+
+ // $tmp['customer_id'] = $client->id;
+ // if ($row->command == 'sen') {
+ // $tmp['code'] = $row->command.$row->process.$client->id;
+ // $tmp['command'] = $row->command.' '.$row->process.' '.$client->id;
+ // } else {
+ // $tmp['code'] = $row->command.$client->id;
+ // $tmp['command'] = $row->command.' '.$client->id;
+ // }
+ // $tmp['description'] = $row->description.' '.$client->customer;
+ // $res = Supervisor::where('code', $tmp['code'])->get();
+ // if (! $res->count()) {
+ // Supervisor::insert($tmp);
+ // }
+ // }
+ // } else {
+ // foreach ($sports as $sport) {
+ // foreach ($clients as $client) {
+ // $tmp['sport_id'] = $sport->id;
+ // $tmp['customer_id'] = $client->id;
+ // $tmp['code'] = $row->command.$sport->code.$client->id;
+ // $tmp['command'] = $row->command.' '.$sport->code.' '.$client->id;
+ // $tmp['description'] = $row->description.' '.$client->customer.' '.$sport->sport;
+ // $res = Supervisor::where('code', $tmp['code'])->get();
+ // if (! $res->count()) {
+ // Supervisor::insert($tmp);
+ // }
+ // }
+ // }
+ }
+ }
+ Supervisor::where('process', $command)->whereNotIn('code', $have)->delete();
+ }
+}
diff --git a/app/Actions/SupervisorMaker.php b/app/Actions/SupervisorMaker.php
new file mode 100644
index 00000000..45f94834
--- /dev/null
+++ b/app/Actions/SupervisorMaker.php
@@ -0,0 +1,75 @@
+with('sport')
+ ->with('provider')
+ ->with('client')
+ ->with('bookmaker')
+ ->get()->all();
+
+ foreach ($sup as $row) {
+
+ $process = $row->command;
+ if ($row->option) {
+ $process .= '_'.strtolower(preg_replace('"\W"', '', $row->option->name));
+ }
+ if ($row->provider) {
+ $process .= '_'.strtolower(preg_replace('"\W"', '', $row->provider->name));
+ }
+ if ($row->sport) {
+ $process .= '_'.strtolower(preg_replace('"\W"', '', $row->sport->name));
+ }
+ if ($row->client) {
+ $process .= '_'.strtolower(preg_replace('"\W"', '', $row->client->name));
+ }
+ if ($row->bookmaker) {
+ $process .= '_'.strtolower(preg_replace('"\W"', '', $row->bookmaker->name));
+ }
+
+ if (! is_dir(self::$base.$row->command)) {
+ mkdir(self::$base.$row->command, 0777, true);
+ }
+
+ self::$path = self::$base.$row->command.DIRECTORY_SEPARATOR;
+
+ self::create_single($process, $row->is_active, $row->is_cron, $row->command, $row->id);
+ }
+
+ if (config('env.app_env') == 'production') {
+ $exec = base_path().'/super_update.sh';
+ exec($exec, $out, $rcode);
+ }
+ }
+
+ public static function create_single($process, $is_active, $is_cron, $command, $id)
+ {
+ $file = self::$path.$process.'.ini';
+ $content = '[program:'.$process.']'.PHP_EOL;
+ $content .= 'command=/usr/bin/php '.base_path().'/artisan '.$command.' '.$id.PHP_EOL;
+ $content .= 'autostart=true'.PHP_EOL;
+ $content .= 'autorestart=true'.PHP_EOL;
+
+ if ($is_active && ! $is_cron) {
+ file_put_contents($file, $content);
+ chmod($file, 0777);
+ } else {
+ if (is_file($file)) {
+ unlink($file);
+ }
+ }
+ }
+}
diff --git a/app/Console/Commands/Comparatore/Comparatore.php b/app/Console/Commands/Comparatore/Comparatore.php
new file mode 100644
index 00000000..9e94927d
--- /dev/null
+++ b/app/Console/Commands/Comparatore/Comparatore.php
@@ -0,0 +1,64 @@
+options();
+ self::$options['supervisor_id'] = $this->argument('process');
+ self::$options['event_id'] = $this->argument('eventid');
+
+ if ($this->argument('process') == 'help') {
+ $txt = PHP_EOL.'a com process [id] eventid [id]'.PHP_EOL;
+ $txt .= '--d debug'.PHP_EOL;
+ $txt .= '--f force update market'.PHP_EOL;
+ $txt .= '--a reload all'.PHP_EOL;
+ $txt .= '--w reload one week'.PHP_EOL;
+ $txt .= '--p print feed'.PHP_EOL.PHP_EOL;
+ $txt .= 'eventid'.PHP_EOL.PHP_EOL;
+ $txt .= 'use "com l" to show options'.PHP_EOL;
+ Notice::note($txt, 'b', 1);
+ } elseif ($this->argument('process') == 'l') {
+ $txt = 'list of comparatore processes';
+ $txt .= Supervisor::list('com');
+ Notice::note($txt, 'b', 1);
+ }
+
+ Supervisorctl::start(self::$options);
+
+ $res = Event::where('time', '>', Carbon::now()->toDateTimeString())->get();
+
+ foreach ($res as $event) {
+ $bookmaker = EventBookmaker::where('event_id', $event->id)->get();
+ if ($bookmaker->count() != null) {
+ dd($bookmaker);
+ }
+ }
+
+ Supervisorctl::end(self::$options);
+ }
+}
diff --git a/app/Console/Commands/Grapper/Grapper.php b/app/Console/Commands/Grapper/Grapper.php
new file mode 100644
index 00000000..32544f54
--- /dev/null
+++ b/app/Console/Commands/Grapper/Grapper.php
@@ -0,0 +1,74 @@
+options();
+ self::$options['supervisor_id'] = $this->argument('process');
+ self::$options['event_id'] = $this->argument('eventid');
+
+ if ($this->argument('process') == 'help') {
+ $txt = PHP_EOL.'a gra process [id] eventid [id]'.PHP_EOL;
+ $txt .= '--d debug'.PHP_EOL;
+ $txt .= '--f force update market'.PHP_EOL;
+ $txt .= '--a reload all'.PHP_EOL;
+ $txt .= '--w reload one week'.PHP_EOL;
+ $txt .= '--p print odds'.PHP_EOL.PHP_EOL;
+ $txt .= 'eventid'.PHP_EOL.PHP_EOL;
+ $txt .= 'use "gra l" to show options'.PHP_EOL;
+ Notice::note($txt, 'b', 1);
+ } elseif ($this->argument('process') == 'l') {
+ $txt = 'list of grapper processes';
+ $txt .= Supervisor::list('gra');
+ Notice::note($txt, 'b', 1);
+ }
+
+ Supervisorctl::start(self::$options);
+
+ Helper::get_auth_string();
+
+ switch (self::$options['provider_id']) {
+ case 1:
+ case 2:
+ TxOdds::switch();
+ break;
+ case 3:
+ // betsapi
+ break;
+ default:
+ Note::notice('Provider not defined', 'r', 1);
+ break;
+ }
+
+ Supervisorctl::end(self::$options);
+ }
+}
diff --git a/app/Console/Commands/Grapper/Helper.php b/app/Console/Commands/Grapper/Helper.php
new file mode 100644
index 00000000..1f1cbc94
--- /dev/null
+++ b/app/Console/Commands/Grapper/Helper.php
@@ -0,0 +1,36 @@
+ $value) {
+ $r += 100 / $value;
+ }
+
+ return round($r, 3);
+ }
+}
diff --git a/app/Console/Commands/Grapper/TxOdds/Countries.php b/app/Console/Commands/Grapper/TxOdds/Countries.php
new file mode 100644
index 00000000..0591f322
--- /dev/null
+++ b/app/Console/Commands/Grapper/TxOdds/Countries.php
@@ -0,0 +1,33 @@
+country as $country) {
+ $res = Country::where('txid', $country->id)->first();
+ if ($res !== null) {
+ // $res->txid = $country->id;
+ // $res->txid = $country->id;
+ // $res->save();
+ } else {
+ $res = new Country;
+ $res->name = $country->name;
+ $res->iso3 = $country->cc;
+ $res->txid = $country->id;
+ $res->tx_only = 1;
+ $res->save();
+ }
+ }
+ }
+}
diff --git a/app/Console/Commands/Grapper/TxOdds/Events.php b/app/Console/Commands/Grapper/TxOdds/Events.php
new file mode 100644
index 00000000..6dfd9c04
--- /dev/null
+++ b/app/Console/Commands/Grapper/TxOdds/Events.php
@@ -0,0 +1,51 @@
+toDateString();
+ $to = $now->addDays(1)->toDateString();
+ $url = Grapper::$domain.'feed/result/xml.php?'.Grapper::$auth."&date=$from,$to";
+ if ($debug) {
+ Notice::note($url, 'y');
+ }
+ $xml = simplexml_load_file($url, null, LIBXML_NOCDATA);
+ foreach ($xml->match as $_match) {
+
+ Event::updateOrCreate([
+ 'txid' => (int) $_match['id'],
+ 'spid' => Grapper::$options['sport_id'],
+ 'prid' => Grapper::$options['provider_id'],
+
+ 'cnid' => (int) $_match->group['cnid'], // country_id
+ 'grid' => (int) $_match->group['id'], // group_id
+ 'cgid' => (int) $_match->group['cgid'], // competition_group_id
+
+ 'hoid' => (int) $_match->hteam['id'],
+ 'awid' => (int) $_match->ateam['id'],
+ 'home' => (string) $_match->hteam,
+ 'away' => (string) $_match->ateam,
+ 'liga' => (string) $_match->group['cname'],
+ ], [
+ 'time' => Carbon::parse($_match->time)->toDateTimeString(),
+ ]);
+ }
+ }
+ }
+}
diff --git a/app/Console/Commands/Grapper/TxOdds/Odds.php b/app/Console/Commands/Grapper/TxOdds/Odds.php
new file mode 100644
index 00000000..fbdc8f6b
--- /dev/null
+++ b/app/Console/Commands/Grapper/TxOdds/Odds.php
@@ -0,0 +1,239 @@
+', Carbon::now()->toDateTimeString())->pluck('txid');
+ foreach ($res as $id) {
+ $_calls[] = $url."&ot=$markets&peid=".$id;
+ }
+ } elseif (Grapper::$options['w']) {
+ $res = Event::where('time', '>', Carbon::now()->toDateTimeString())->where('time', '<', Carbon::now()->addDays(7)->toDateTimeString())->pluck('txid');
+ foreach ($res as $id) {
+ $_calls[] = $url."&ot=$markets&peid=".$id;
+ }
+ } else {
+ $_calls[] = $url.'&last='.Grapper::$options['lastcall'];
+ }
+
+ /*************************************************
+ * CALL
+ *************************************************/
+ foreach ($_calls as $url) {
+ Notice::note($url, 'r');
+
+ $xml = simplexml_load_file($url, null, LIBXML_NOCDATA);
+
+ if (Grapper::$options['p']) {
+ Notice::note($url);
+ foreach ($xml->match as $match) {
+ print_r($match);
+ }
+ exit;
+ }
+
+ Supervisorctl::set_lastcall($xml['timestamp']);
+
+ foreach ($xml->match as $m) {
+
+ if (Grapper::$options['d']) {
+ Notice::note((int) $m['id'].' : '.$m->hteam.' - '.$m->ateam);
+ }
+
+ $evid = Event::where('txid', (int) $m['id'])->pluck('id')->first();
+
+ if ($evid) {
+ $fixed_array = [];
+ $fixed_array['event_id'] = $evid;
+
+ Event::where('id', $evid)->update(['cnt_bkm_tx' => count($m->bookmaker)]);
+
+ foreach ($m->bookmaker as $bookmaker) {
+
+ $fixed_array['bkid'] = (int) $bookmaker['bid'];
+
+ $value_array = [];
+
+ foreach ($bookmaker->offer as $offer) {
+ switch ($offer['ot']) {
+ case '0':
+
+ $value_array['f3w'] = (int) $offer['flags'] ?? 0;
+ $value_array['boid'] = (string) $offer['bmoid'] ?? 0;
+ $value_array['time'] = Carbon::parse($offer->odds['starting_time'])->toDateTimeString();
+
+ $tmp = [];
+ $tmp['h3w'] = (float) $offer->odds->o1 ?? 1;
+ $tmp['d3w'] = (float) $offer->odds->o2 ?? 1;
+ $tmp['a3w'] = (float) $offer->odds->o3 ?? 1;
+ $tmp['m3w'] = Helper::margin($tmp);
+ $value_array += $tmp;
+ break;
+
+ case '1':
+
+ $value_array['f2w'] = (int) $offer['flags'] ?? 0;
+ $value_array['boid'] = (string) $offer['bmoid'] ?? 0;
+ $value_array['time'] = Carbon::parse($offer->odds['starting_time'])->toDateTimeString();
+
+ $tmp = [];
+ $tmp['h2w'] = (float) $offer->odds->o1 ?? 1;
+ $tmp['a2w'] = (float) $offer->odds->o3 ?? 1;
+ $tmp['m2w'] = Helper::margin($tmp);
+ $value_array += $tmp;
+ break;
+
+ case '4':
+ $hc = (float) $offer->odds->o3;
+ if (Grapper::$options['sport_id'] == 1 && $hc == 2.5) {
+ $tmp = [];
+ $tmp['ov'] = (float) $offer->odds->o1 ?? 1;
+ $tmp['un'] = (float) $offer->odds->o2 ?? 1;
+ $tmp['mto'] = Helper::margin($tmp);
+ $tmp['fto'] = (int) $offer->odd['flags'] ?? 0;
+ $tmp['hc'] = 2.5;
+ $value_array += $tmp;
+ }
+ break;
+
+ case '5242880':
+ // Double Chance (dc1x,dc12,dcx2)
+ $value_array['fdc'] = (int) $offer['flags'] ?? 0;
+ $tmp = [];
+ $tmp['dc1x'] = (float) $offer->odds->o1 ?? 1;
+ $tmp['dc12'] = (float) $offer->odds->o2 ?? 1;
+ $tmp['dcx2'] = (float) $offer->odds->o3 ?? 1;
+ $tmp['mdc'] = Helper::margin($tmp);
+ $value_array += $tmp;
+ break;
+
+ case '11534337':
+ // goal/nogoal (gg,ng)
+ $value_array['fgg'] = (int) $offer['flags'] ?? 0;
+ $tmp = [];
+ $tmp['gg'] = (float) $offer->odds->o1 ?? 1;
+ $tmp['ng'] = (float) $offer->odds->o3 ?? 1;
+ $tmp['mgg'] = Helper::margin($tmp);
+ $value_array += $tmp;
+ break;
+
+ case '7340033':
+ // to qualify (htq,atq)
+ $value_array['ftq'] = (int) $offer['flags'] ?? 0;
+ $tmp = [];
+ $tmp['htq'] = (float) $offer->odds->o1 ?? 1;
+ $tmp['atq'] = (float) $offer->odds->o3 ?? 1;
+ $tmp['mtq'] = Helper::margin($tmp);
+ $value_array += $tmp;
+ break;
+ }
+ }
+
+ EventBookmaker::updateOrCreate($fixed_array, $value_array);
+ if (Grapper::$options['d']) {
+ Notice::note($fixed_array + $value_array, 'b');
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/Console/Commands/Grapper/TxOdds/TxOdds.php b/app/Console/Commands/Grapper/TxOdds/TxOdds.php
new file mode 100644
index 00000000..37cb35f6
--- /dev/null
+++ b/app/Console/Commands/Grapper/TxOdds/TxOdds.php
@@ -0,0 +1,35 @@
+command('model:prune')->daily();
+ // $schedule->command('inspire')->hourly();
+ }
+
+ /**
+ * Register the commands for the application.
+ */
+ protected function commands(): void
+ {
+ $this->load(__DIR__.'/Commands');
+
+ require base_path('routes/console.php');
+ }
+}
diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php
index 67a1289d..4bfb38cd 100644
--- a/app/Providers/Filament/AdminPanelProvider.php
+++ b/app/Providers/Filament/AdminPanelProvider.php
@@ -36,8 +36,8 @@ class AdminPanelProvider extends PanelProvider
->path('')
->login()
->passwordReset()
- ->brandLogo(asset('images/nuh.svg'))
- ->darkModeBrandLogo(asset('images/nuh-d.svg'))
+ ->brandLogo(asset('images/nuh-odds.svg'))
+ ->darkModeBrandLogo(asset('images/nuh-odds-d.svg'))
->favicon(asset('images/nuh.svg'))
->brandLogoHeight('1.8rem')
->unsavedChangesAlerts()
diff --git a/database/migrations/2023_07_14_131257_create_sport_table.php b/database/migrations/2023_07_14_131257_create_sport_table.php
new file mode 100644
index 00000000..743758b2
--- /dev/null
+++ b/database/migrations/2023_07_14_131257_create_sport_table.php
@@ -0,0 +1,37 @@
+id();
+ $table->string('name');
+ $table->string('code')->nullable();
+ $table->string('icon')->nullable();
+ $table->boolean('disabled')->default(0);
+ $table->integer('bapi')->default(0);
+ $table->integer('bwin')->default(0);
+ $table->integer('b365')->default(0);
+ $table->integer('logi')->default(0);
+ $table->integer('magl')->default(0);
+ $table->timestamps();
+
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('sports');
+ }
+};
diff --git a/database/migrations/2023_08_06_085243_create_supervisor_table.php b/database/migrations/2023_08_06_085243_create_supervisor_table.php
new file mode 100644
index 00000000..82dda0f6
--- /dev/null
+++ b/database/migrations/2023_08_06_085243_create_supervisor_table.php
@@ -0,0 +1,47 @@
+id();
+ $table->string('command')->nullable();
+ $table->string('name')->nullable();
+
+ $table->integer('option_id')->default(0);
+ $table->integer('sport_id')->default(0);
+ $table->integer('provider_id')->default(0);
+ $table->integer('client_id')->default(0);
+ $table->integer('bookmaker_id')->default(0);
+
+ $table->integer('sleep')->default(10);
+ $table->integer('limit')->default(0);
+ $table->integer('multi')->default(0);
+
+ $table->string('runtime')->nullable();
+ $table->integer('events')->default(0);
+ $table->integer('lastcall')->default(0);
+
+ $table->boolean('is_cron')->default(0);
+ $table->boolean('is_active')->default(0);
+ $table->boolean('has_log')->default(0);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('supervisors');
+ }
+};
diff --git a/database/migrations/2025_05_17_074540_create_bookmakers_table.php b/database/migrations/2025_05_17_074540_create_bookmakers_table.php
new file mode 100644
index 00000000..8d394497
--- /dev/null
+++ b/database/migrations/2025_05_17_074540_create_bookmakers_table.php
@@ -0,0 +1,35 @@
+id();
+ $table->string('name');
+ $table->string('icon')->nullable();
+ $table->integer('baid')->default(0);
+ $table->integer('txid')->default(0);
+ $table->boolean('txso')->default(0);
+ $table->boolean('txot')->default(0);
+ $table->boolean('provider_id')->default(0);
+ $table->boolean('is_active')->default(0);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('bookmakers');
+ }
+};
diff --git a/database/migrations/2025_05_17_074558_create_providers_table.php b/database/migrations/2025_05_17_074558_create_providers_table.php
new file mode 100644
index 00000000..ab34e311
--- /dev/null
+++ b/database/migrations/2025_05_17_074558_create_providers_table.php
@@ -0,0 +1,30 @@
+id();
+ $table->string('name');
+ $table->string('icon')->nullable();
+ $table->boolean('is_leader')->default(0);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('providers');
+ }
+};
diff --git a/database/migrations/2025_05_17_074607_create_clients_table.php b/database/migrations/2025_05_17_074607_create_clients_table.php
new file mode 100644
index 00000000..f78dcc3b
--- /dev/null
+++ b/database/migrations/2025_05_17_074607_create_clients_table.php
@@ -0,0 +1,29 @@
+id();
+ $table->string('name');
+ $table->string('icon')->nullable();
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('clients');
+ }
+};
diff --git a/database/migrations/2025_05_19_121513_create_client_bookmakers_table.php b/database/migrations/2025_05_19_121513_create_client_bookmakers_table.php
new file mode 100644
index 00000000..8ff2f777
--- /dev/null
+++ b/database/migrations/2025_05_19_121513_create_client_bookmakers_table.php
@@ -0,0 +1,30 @@
+id();
+ $table->integer('client_id');
+ $table->integer('bookmaker_id');
+ $table->boolean('is_active')->default(0);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('client_bookmakers');
+ }
+};
diff --git a/database/migrations/2025_05_22_054749_create_supervisor_options_table.php b/database/migrations/2025_05_22_054749_create_supervisor_options_table.php
new file mode 100644
index 00000000..0651fb9c
--- /dev/null
+++ b/database/migrations/2025_05_22_054749_create_supervisor_options_table.php
@@ -0,0 +1,28 @@
+id();
+ $table->string('name');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('supervisor_options');
+ }
+};
diff --git a/database/migrations/2025_05_22_080907_create_countries_table.php b/database/migrations/2025_05_22_080907_create_countries_table.php
new file mode 100644
index 00000000..88c71aaa
--- /dev/null
+++ b/database/migrations/2025_05_22_080907_create_countries_table.php
@@ -0,0 +1,33 @@
+id();
+ $table->string('name');
+ $table->string('iso2');
+ $table->string('iso3');
+ $table->string('numeric');
+ $table->integer('txid')->default(0);
+ $table->boolean('tx_only')->default(0);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('countries');
+ }
+};
diff --git a/database/migrations/2025_05_25_112748_create_events_table.php b/database/migrations/2025_05_25_112748_create_events_table.php
new file mode 100644
index 00000000..8dbf2dfa
--- /dev/null
+++ b/database/migrations/2025_05_25_112748_create_events_table.php
@@ -0,0 +1,57 @@
+id();
+ $table->timestamp('time')->nullable();
+ // sport id
+ $table->integer('spid');
+ // provider id
+ $table->integer('prid')->default(0);
+ // txodds id
+ $table->integer('txid')->default(0);
+ // betradar id
+ $table->integer('brid')->default(0);
+ // betaid id
+ $table->integer('baid')->default(0);
+ // county id
+ $table->integer('cnid')->default(0);
+ // group id
+ $table->integer('grid')->default(0);
+ // competition group id
+ $table->integer('cgid')->default(0);
+ // home id
+ $table->integer('hoid')->default(0);
+ // away id
+ $table->integer('awid')->default(0);
+ // liga (group name)
+ $table->string('liga');
+ // home
+ $table->string('home');
+ // away
+ $table->string('away');
+ $table->integer('cnt_bkm_tx')->default(0);
+ $table->integer('cnt_bkm_ba')->default(0);
+ $table->timestamps();
+ $table->index(['spid', 'prid', 'txid', 'brid', 'baid', 'cnid', 'grid', 'cgid', 'hoid', 'awid']);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('events');
+ }
+};
diff --git a/database/migrations/2025_05_26_051927_create_event_bookmakers_table.php b/database/migrations/2025_05_26_051927_create_event_bookmakers_table.php
new file mode 100644
index 00000000..52c457fd
--- /dev/null
+++ b/database/migrations/2025_05_26_051927_create_event_bookmakers_table.php
@@ -0,0 +1,78 @@
+id();
+ $table->foreignId('event_id')->constrained()->cascadeOnDelete();
+ $table->timestamp('time')->nullable();
+ $table->integer('bkid')->default(0);
+ $table->string('boid')->nullable();
+
+ // flag status
+ $table->integer('flag')->default(0);
+ // swop (inverted odds)
+ $table->integer('swop')->default(0);
+
+ // 1x2
+ $table->decimal('h3w', 7, 3)->default(0);
+ $table->decimal('d3w', 7, 3)->default(0);
+ $table->decimal('a3w', 7, 3)->default(0);
+ $table->decimal('m3w', 7, 3)->default(0);
+ $table->integer('f3w')->default(0);
+ // bookmaker offer id
+
+ // Total
+ $table->decimal('ov', 7, 3)->default(0);
+ $table->decimal('un', 7, 3)->default(0);
+ $table->decimal('hc', 7, 3)->default(0);
+ $table->decimal('mto', 7, 3)->default(0);
+ $table->integer('fto')->default(0);
+
+ // ML
+ $table->decimal('h2w', 7, 3)->default(0);
+ $table->decimal('a2w', 7, 3)->default(0);
+ $table->decimal('m2w', 7, 3)->default(0);
+ $table->integer('f2w')->default(0);
+
+ // DC
+ $table->decimal('dc1x', 7, 3)->default(0);
+ $table->decimal('dc12', 7, 3)->default(0);
+ $table->decimal('dc2x', 7, 3)->default(0);
+ $table->decimal('mdc', 7, 3)->default(0);
+ $table->integer('fdc')->default(0);
+
+ // GG NG
+ $table->decimal('gg', 7, 3)->default(0);
+ $table->decimal('ng', 7, 3)->default(0);
+ $table->decimal('mgg', 7, 3)->default(0);
+ $table->integer('fgg')->default(0);
+
+ // TO QUALIFY
+ $table->decimal('htq', 7, 3)->default(0);
+ $table->decimal('atq', 7, 3)->default(0);
+ $table->decimal('mtq', 7, 3)->default(0);
+ $table->integer('ftq')->default(0);
+
+ $table->timestamps();
+ $table->index(['event_id', 'boid', 'bkid', 'flag']);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('event_bookmakers');
+ }
+};
diff --git a/database/migrations/2025_05_26_124609_create_multilines_table.php b/database/migrations/2025_05_26_124609_create_multilines_table.php
new file mode 100644
index 00000000..3c58fa74
--- /dev/null
+++ b/database/migrations/2025_05_26_124609_create_multilines_table.php
@@ -0,0 +1,31 @@
+id();
+ $table->integer('client_id')->default(0);
+ $table->integer('bettype_id')->default(0);
+ $table->integer('bookmaker_id')->default(0);
+ $table->integer('sort-order')->default(0);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('multilines');
+ }
+};
diff --git a/database/migrations/2025_05_26_125215_create_bettypes_table.php b/database/migrations/2025_05_26_125215_create_bettypes_table.php
new file mode 100644
index 00000000..f4d6cc42
--- /dev/null
+++ b/database/migrations/2025_05_26_125215_create_bettypes_table.php
@@ -0,0 +1,28 @@
+id();
+ $table->string('name');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('bettypes');
+ }
+};
diff --git a/database/seeders/BookmakerSeeder.php b/database/seeders/BookmakerSeeder.php
new file mode 100644
index 00000000..a75ed0ff
--- /dev/null
+++ b/database/seeders/BookmakerSeeder.php
@@ -0,0 +1,68 @@
+call([
RolesAndPermissionsSeeder::class,
+ BookmakerSeeder::class,
+ CountrySeeder::class,
+ SportSeeder::class,
]);
}
}
diff --git a/database/seeders/SportSeeder.php b/database/seeders/SportSeeder.php
new file mode 100644
index 00000000..d017d5ca
--- /dev/null
+++ b/database/seeders/SportSeeder.php
@@ -0,0 +1,92 @@
+
+
+
diff --git a/resources/svg/handball.svg b/resources/svg/handball.svg
new file mode 100644
index 00000000..96693d5e
--- /dev/null
+++ b/resources/svg/handball.svg
@@ -0,0 +1,4 @@
+
diff --git a/resources/svg/icehockey.svg b/resources/svg/icehockey.svg
new file mode 100644
index 00000000..f241704b
--- /dev/null
+++ b/resources/svg/icehockey.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/resources/svg/soccerball.svg b/resources/svg/soccerball.svg
new file mode 100644
index 00000000..14df688f
--- /dev/null
+++ b/resources/svg/soccerball.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/resources/svg/tennisball.svg b/resources/svg/tennisball.svg
new file mode 100644
index 00000000..312a8822
--- /dev/null
+++ b/resources/svg/tennisball.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file