From 7feb7fd1848a1761818a1d60572d31d2fcb65485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Jaussoin?= Date: Wed, 4 Oct 2023 08:24:47 +0000 Subject: [PATCH] Add Account statistics --- flexiapi/app/Account.php | 29 +- .../Admin/AccountStatisticsController.php | 62 ++++ .../Admin/StatisticsController.php | 210 ++----------- .../app/Libraries/StatisticsGraphFactory.php | 282 ++++++++++++++++++ flexiapi/app/StatisticsCall.php | 13 + flexiapi/app/StatisticsMessage.php | 10 +- flexiapi/app/StatisticsMessageDevice.php | 8 +- flexiapi/composer.json | 1 + flexiapi/composer.lock | 236 +++++++++------ .../database/factories/AccountFactory.php | 9 +- flexiapi/database/factories/AdminFactory.php | 1 - .../StatisticsMessageDeviceFactory.php | 26 ++ .../factories/StatisticsMessageFactory.php | 3 + ...23_10_03_121128_add_statistics_indexes.php | 58 ++++ flexiapi/database/seeds/StatisticsSeeder.php | 12 +- flexiapi/public/css/style.css | 2 +- .../views/admin/account/create_edit.blade.php | 23 +- .../admin/account/device/index.blade.php | 5 +- .../admin/account/statistics/show.blade.php | 72 +++++ .../admin/statistics/parts/columns.blade.php | 12 - .../admin/statistics/parts/filters.blade.php | 73 +++++ .../admin/statistics/parts/legend.blade.php | 6 - .../views/admin/statistics/show.blade.php | 44 +-- .../resources/views/parts/graph.blade.php | 26 +- flexiapi/routes/web.php | 7 + 25 files changed, 864 insertions(+), 366 deletions(-) create mode 100644 flexiapi/app/Http/Controllers/Admin/AccountStatisticsController.php create mode 100644 flexiapi/app/Libraries/StatisticsGraphFactory.php create mode 100644 flexiapi/database/factories/StatisticsMessageDeviceFactory.php create mode 100644 flexiapi/database/migrations/2023_10_03_121128_add_statistics_indexes.php create mode 100644 flexiapi/resources/views/admin/account/statistics/show.blade.php delete mode 100644 flexiapi/resources/views/admin/statistics/parts/columns.blade.php create mode 100644 flexiapi/resources/views/admin/statistics/parts/filters.blade.php delete mode 100644 flexiapi/resources/views/admin/statistics/parts/legend.blade.php diff --git a/flexiapi/app/Account.php b/flexiapi/app/Account.php index af66d9a..bd5e081 100644 --- a/flexiapi/app/Account.php +++ b/flexiapi/app/Account.php @@ -23,17 +23,20 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Auth; use Illuminate\Foundation\Auth\User as Authenticatable; -use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController; +use Illuminate\Http\Request; use Illuminate\Support\Str; +use Carbon\Carbon; + +use Awobaz\Compoships\Compoships; use App\ApiKey; use App\Password; -use Carbon\Carbon; -use Illuminate\Http\Request; +use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController; class Account extends Authenticatable { use HasFactory; + use Compoships; protected $with = ['passwords', 'admin', 'alias', 'activationExpiration', 'emailChangeCode', 'types', 'actions']; protected $hidden = ['alias', 'expire_time', 'confirmation_key', 'provisioning_token', 'pivot']; @@ -180,6 +183,26 @@ class Account extends Authenticatable return $this->belongsToMany(AccountType::class); } + public function statisticsFromCalls() + { + return $this->hasMany(StatisticsCall::class, ['from_username', 'from_domain'], ['username', 'domain']); + } + + public function statisticsToCalls() + { + return $this->hasMany(StatisticsCall::class, ['to_username', 'to_domain'], ['username', 'domain']); + } + + public function statisticsFromMessages() + { + return $this->hasMany(StatisticsMessage::class, ['from_username', 'from_domain'], ['username', 'domain']); + } + + public function statisticsToMessageDevices() + { + return $this->hasMany(StatisticsMessageDevice::class, ['to_username', 'to_domain'], ['username', 'domain']); + } + /** * Attributes */ diff --git a/flexiapi/app/Http/Controllers/Admin/AccountStatisticsController.php b/flexiapi/app/Http/Controllers/Admin/AccountStatisticsController.php new file mode 100644 index 0000000..6d6da30 --- /dev/null +++ b/flexiapi/app/Http/Controllers/Admin/AccountStatisticsController.php @@ -0,0 +1,62 @@ +route('admin.account.statistics.show', [ + 'account' => $account, + 'from' => $request->get('from'), + 'to' => $request->get('to'), + 'by' => $request->get('by'), + ]); + } + + public function show(Request $request, int $accountId) + { + $request->validate([ + 'from' => 'date_format:Y-m-d|before:to', + 'to' => 'date_format:Y-m-d|after:from', + 'by' => 'in:day,week,month,year', + ]); + + $account = Account::findOrFail($accountId); + + $messagesFromGraph = view('parts.graph', [ + 'jsonConfig' => json_encode((new StatisticsGraphFactory($request, 'messages', fromUsername: $account->username, fromDomain: $account->domain))->getConfig()), + 'request' => $request + ])->render(); + + $messagesToGraph = view('parts.graph', [ + 'jsonConfig' => json_encode((new StatisticsGraphFactory($request, 'messages', toUsername: $account->username, toDomain: $account->domain))->getConfig()), + 'request' => $request + ])->render(); + + $callsFromGraph = view('parts.graph', [ + 'jsonConfig' => json_encode((new StatisticsGraphFactory($request, 'calls', fromUsername: $account->username, fromDomain: $account->domain))->getConfig()), + 'request' => $request + ])->render(); + + $callsToGraph = view('parts.graph', [ + 'jsonConfig' => json_encode((new StatisticsGraphFactory($request, 'calls', toUsername: $account->username, toDomain: $account->domain))->getConfig()), + 'request' => $request + ])->render(); + + return view('admin.account.statistics.show', [ + 'account' => $account, + 'messagesFromGraph' => $messagesFromGraph, + 'messagesToGraph' => $messagesToGraph, + 'callsFromGraph' => $callsFromGraph, + 'callsToGraph' => $callsToGraph, + ]); + } +} diff --git a/flexiapi/app/Http/Controllers/Admin/StatisticsController.php b/flexiapi/app/Http/Controllers/Admin/StatisticsController.php index d86ec6c..51e355f 100644 --- a/flexiapi/app/Http/Controllers/Admin/StatisticsController.php +++ b/flexiapi/app/Http/Controllers/Admin/StatisticsController.php @@ -3,16 +3,13 @@ namespace App\Http\Controllers\Admin; use App\Account; +use App\ContactsList; use App\StatisticsMessage; use App\StatisticsCall; use App\Http\Controllers\Controller; -use Illuminate\Http\Request; +use App\Libraries\StatisticsGraphFactory; -use Carbon\Carbon; -use Carbon\CarbonInterval; -use Carbon\CarbonPeriod; -use Illuminate\Support\Collection; -use Illuminate\Support\Facades\DB; +use Illuminate\Http\Request; class StatisticsController extends Controller { @@ -27,12 +24,19 @@ class StatisticsController extends Controller { return redirect()->route('admin.statistics.show', [ 'from' => $request->get('from'), - 'type' => $request->get('type'), 'to' => $request->get('to'), 'by' => $request->get('by'), + 'type' => $request->get('type'), + 'domain' => $request->get('domain'), + 'contacts_list' => $request->get('contacts_list'), ]); } + /*public function search(Request $request) + { + return redirect()->route('admin.statistics.search', $request->except('_token', 'query')); + }*/ + public function show(Request $request, string $type = 'messages') { $request->validate([ @@ -41,186 +45,36 @@ class StatisticsController extends Controller 'by' => 'in:day,week,month,year', ]); - $dateColumn = 'created_at'; - $label = 'Label'; - - switch ($type) { - case 'messages': - $dateColumn = 'sent_at'; - $label = 'Messages'; - $data = StatisticsMessage::orderBy($dateColumn, 'asc'); - break; - - case 'calls': - $dateColumn = 'initiated_at'; - $label = 'Calls'; - $data = StatisticsCall::orderBy($dateColumn, 'asc'); - break; - - case 'accounts': - $label = 'Accounts'; - $data = Account::orderBy($dateColumn, 'asc'); - break; - } - - $data = $data->groupBy('moment') - ->orderBy('moment', 'desc') - ->setEagerLoads([]); - - if ($request->get('to')) { - $data = $data->where($dateColumn, '<=', $request->get('to')); - } - - $by = $request->get('by', 'day'); - - switch ($by) { - case 'day': - $data = $data->where($dateColumn, '>=', $request->get('from', Carbon::now()->subDay()->format('Y-m-d H:i:s'))) - ->get([ - DB::raw("date_format(" . $dateColumn . ",'%Y-%m-%d %H') as moment"), - DB::raw('COUNT(*) as "count"') - ]); - break; - case 'week': - $data = $data->where($dateColumn, '>=', $request->get('from', Carbon::now()->subWeek()->format('Y-m-d H:i:s'))) - ->get([ - DB::raw("date_format(" . $dateColumn . ",'%Y-%m-%d') as moment"), - DB::raw('COUNT(*) as "count"') - ]); - break; - case 'month': - $data = $data->where($dateColumn, '>=', $request->get('from', Carbon::now()->subMonth()->format('Y-m-d H:i:s'))) - ->get([ - DB::raw("date_format(" . $dateColumn . ",'%Y-%m-%d') as moment"), - DB::raw('COUNT(*) as "count"') - ]); - break; - case 'year': - $data = $data->where($dateColumn, '>=', $request->get('from', Carbon::now()->subYear()->format('Y-m-d H:i:s'))) - ->get([ - DB::raw("date_format(" . $dateColumn . ",'%Y-%m') as moment"), - DB::raw('COUNT(*) as "count"') - ]); - break; - } - - $data = $data->each->setAppends([])->pluck('count', 'moment'); - - $data = $this->compileStatistics( - $by, - $request->get('from'), - $request->get('to'), - $data - ); + $graph = new StatisticsGraphFactory($request, $type, fromDomain: $request->get('domain')); + $config = $graph->getConfig(); + $domains = collect(); if ($request->get('export', false)) { - $file = fopen('php://output', 'w'); - - $callback = function () use ($data, $file) { - foreach ($data as $key => $value) { - fputcsv($file, [$key, $value]); - } - - fclose($file); - }; - - return response()->stream($callback, 200, [ - "Content-type" => "text/csv", - "Content-Disposition" => "attachment; filename=export.csv", - "Pragma" => "no-cache", - "Cache-Control" => "must-revalidate, post-check=0, pre-check=0", - "Expires" => "0" - ]); + return $graph->export(); } - $config = [ - 'type' => 'bar', - 'data' => [ - 'labels' => $data->keys()->toArray(), - 'datasets' => [[ - 'label' => $label, - 'borderColor' => 'rgba(108, 122, 135, 1)', - 'backgroundColor' => 'rgba(108, 122, 135, 1)', - 'data' => $data->values()->toArray(), - 'order' => 1 - ]] - ], - 'options' => [ - 'maintainAspectRatio' => false, - 'spanGaps' => true, - 'legend' => [ - 'position' => 'right' - ], - 'scales' => [ - 'y' => [ - 'stacked' => true, - 'title' => [ - 'display' => true, - 'text' => $label - ] - ], - 'x' => [ - 'stacked' => true, - ] - ], - 'interaction' => [ - 'mode' => 'nearest', - 'axis' => 'x', - 'intersect' => false - ], - ] - ]; + if (config('app.admins_manage_multi_domains')) { + switch ($type) { + case 'messages': + $domains = StatisticsMessage::groupBy('from_domain')->pluck('from_domain'); + break; + + case 'calls': + $domains = StatisticsCall::groupBy('from_domain')->pluck('from_domain'); + break; + + case 'accounts': + $domains = Account::groupBy('domain')->pluck('domain'); + break; + } + } return view('admin.statistics.show', [ + 'domains' => $domains, + 'contacts_lists' => ContactsList::all()->pluck('title', 'id'), 'jsonConfig' => json_encode($config), - 'by' => $by, 'type' => $type, 'request' => $request ]); } - - private static function compileStatistics(string $by, $from, $to, $data): Collection - { - $stats = []; - - switch ($by) { - case 'day': - $period = collect(CarbonInterval::hour()->toPeriod( - $from ?? Carbon::now()->subDay()->format('Y-m-d H:i:s'), - $to ?? Carbon::now()->format('Y-m-d H:i:s') - ))->map->format('Y-m-d H'); - break; - - case 'week': - $period = collect(CarbonPeriod::create( - $from ?? Carbon::now()->subWeek(), - $to ?? Carbon::now() - ))->map->format('Y-m-d'); - break; - - case 'month': - $period = collect( - CarbonPeriod::create( - $from ?? Carbon::now()->subMonth(), - $to ?? Carbon::now() - ) - )->map->format('Y-m-d'); - break; - - case 'year': - $period = collect( - CarbonPeriod::create( - $from ?? Carbon::now()->subYear(), - $to ?? Carbon::now() - ) - )->map->format('Y-m'); - break; - } - - foreach ($period as $moment) { - $stats[$moment] = $data[$moment] ?? 0; - } - - return collect($stats); - } } diff --git a/flexiapi/app/Libraries/StatisticsGraphFactory.php b/flexiapi/app/Libraries/StatisticsGraphFactory.php new file mode 100644 index 0000000..1d036a1 --- /dev/null +++ b/flexiapi/app/Libraries/StatisticsGraphFactory.php @@ -0,0 +1,282 @@ +. +*/ + +namespace App\Libraries; + +use App\Account; +use App\ContactsList; +use App\StatisticsCall; +use App\StatisticsMessage; +use Carbon\Carbon; +use Carbon\CarbonInterval; +use Carbon\CarbonPeriod; +use Illuminate\Http\Request; +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\DB; + +class StatisticsGraphFactory +{ + private $data = null; + + public function __construct( + private Request $request, + private string $type = 'messages', + public ?string $fromUsername = null, + public ?string $fromDomain = null, + public ?string $toUsername = null, + public ?string $toDomain = null + ) { + } + + public function getConfig() + { + $dateColumn = 'created_at'; + $label = 'Label'; + + switch ($this->type) { + case 'messages': + $dateColumn = 'sent_at'; + $label = 'Messages'; + $this->data = StatisticsMessage::orderBy($dateColumn, 'asc'); + + if (!config('app.admins_manage_multi_domains')) { + $this->data->where('from_domain', config('app.sip_domain')); + } elseif ($this->fromDomain) { + $this->data->where('from_domain', $this->fromDomain)->orderBy('from_domain'); + + if ($this->fromUsername) { + $this->data->where('from_username', $this->fromUsername); + } + } elseif ($this->toDomain && $this->toUsername) { + $this->data->whereIn('id', function ($query) { + $query->select('message_id') + ->from('statistics_message_devices') + ->where('to_username', $this->toUsername) + ->where('to_domain', $this->toDomain); + }); + } + + break; + + case 'calls': + $dateColumn = 'initiated_at'; + $label = 'Calls'; + $this->data = StatisticsCall::orderBy($dateColumn, 'asc'); + + if (!config('app.admins_manage_multi_domains')) { + $this->data->where('from_domain', config('app.sip_domain')); + } elseif ($this->fromDomain) { + $this->data->where('from_domain', $this->fromDomain)->orderBy('from_domain'); + + if ($this->fromUsername) { + $this->data->where('from_username', $this->fromUsername); + } + } elseif ($this->toDomain) { + $this->data->where('to_domain', $this->toDomain)->orderBy('to_domain'); + + if ($this->toUsername) { + $this->data->where('to_username', $this->toUsername); + } + } + + break; + + case 'accounts': + $label = 'Accounts'; + $this->data = Account::orderBy($dateColumn, 'asc'); + + if (!config('app.admins_manage_multi_domains')) { + $this->data->where('domain', config('app.sip_domain')); + } elseif ($this->fromDomain) { + $this->data->where('domain', $this->fromDomain)->orderBy('domain'); + + if ($this->fromUsername) { + $this->data->where('username', $this->fromUsername); + } + } + + if ($this->request->has('contacts_list')) { + $this->data->whereIn('id', function ($query) { + $query->select('contact_id') + ->from('contacts_list_contact') + ->where('contacts_list_id', $this->request->get('contacts_list')); + }); + } + + break; + } + + $this->data = $this->data->groupBy('moment') + ->orderBy('moment', 'desc') + ->setEagerLoads([]); + + if ($this->request->get('to')) { + $this->data = $this->data->where($dateColumn, '<=', $this->request->get('to')); + } + + $by = $this->request->get('by', 'day'); + + switch ($by) { + case 'day': + $this->data = $this->data->where($dateColumn, '>=', $this->request->get('from', Carbon::now()->subDay()->format('Y-m-d H:i:s'))) + ->get([ + DB::raw("date_format(" . $dateColumn . ",'%Y-%m-%d %H') as moment"), + DB::raw('COUNT(*) as "count"') + ]); + break; + case 'week': + $this->data = $this->data->where($dateColumn, '>=', $this->request->get('from', Carbon::now()->subWeek()->format('Y-m-d H:i:s'))) + ->get([ + DB::raw("date_format(" . $dateColumn . ",'%Y-%m-%d') as moment"), + DB::raw('COUNT(*) as "count"') + ]); + break; + case 'month': + $this->data = $this->data->where($dateColumn, '>=', $this->request->get('from', Carbon::now()->subMonth()->format('Y-m-d H:i:s'))) + ->get([ + DB::raw("date_format(" . $dateColumn . ",'%Y-%m-%d') as moment"), + DB::raw('COUNT(*) as "count"') + ]); + break; + case 'year': + $this->data = $this->data->where($dateColumn, '>=', $this->request->get('from', Carbon::now()->subYear()->format('Y-m-d H:i:s'))) + ->get([ + DB::raw("date_format(" . $dateColumn . ",'%Y-%m') as moment"), + DB::raw('COUNT(*) as "count"') + ]); + break; + } + + $this->data = $this->data->each->setAppends([])->pluck('count', 'moment'); + $this->data = $this->compileStatistics( + $by, + $this->request->get('from'), + $this->request->get('to'), + $this->data + ); + + return [ + 'type' => 'bar', + 'data' => [ + 'labels' => $this->data->keys()->toArray(), + 'datasets' => [[ + 'label' => $label, + 'borderColor' => 'rgba(108, 122, 135, 1)', + 'backgroundColor' => 'rgba(108, 122, 135, 1)', + 'data' => $this->data->values()->toArray(), + 'order' => 1 + ]] + ], + 'options' => [ + 'maintainAspectRatio' => false, + 'spanGaps' => true, + 'legend' => [ + 'position' => 'right' + ], + 'scales' => [ + 'y' => [ + 'stacked' => true, + 'title' => [ + 'display' => true, + 'text' => $label + ] + ], + 'x' => [ + 'stacked' => true, + ] + ], + 'interaction' => [ + 'mode' => 'nearest', + 'axis' => 'x', + 'intersect' => false + ], + ] + ]; + } + + public function export() + { + $file = fopen('php://output', 'w'); + + if ($this->data == null) { + $this->getConfig(); + } + + $callback = function () use ($file) { + foreach ($this->data as $key => $value) { + fputcsv($file, [$key, $value]); + } + + fclose($file); + }; + + return response()->stream($callback, 200, [ + "Content-type" => "text/csv", + "Content-Disposition" => "attachment; filename=export.csv", + "Pragma" => "no-cache", + "Cache-Control" => "must-revalidate, post-check=0, pre-check=0", + "Expires" => "0" + ]); + } + + private function compileStatistics(string $by, $from, $to, $data): Collection + { + $stats = []; + + switch ($by) { + case 'day': + $period = collect(CarbonInterval::hour()->toPeriod( + $from ?? Carbon::now()->subDay()->format('Y-m-d H:i:s'), + $to ?? Carbon::now()->format('Y-m-d H:i:s') + ))->map->format('Y-m-d H'); + break; + + case 'week': + $period = collect(CarbonPeriod::create( + $from ?? Carbon::now()->subWeek(), + $to ?? Carbon::now() + ))->map->format('Y-m-d'); + break; + + case 'month': + $period = collect( + CarbonPeriod::create( + $from ?? Carbon::now()->subMonth(), + $to ?? Carbon::now() + ) + )->map->format('Y-m-d'); + break; + + case 'year': + $period = collect( + CarbonPeriod::create( + $from ?? Carbon::now()->subYear(), + $to ?? Carbon::now() + ) + )->map->format('Y-m'); + break; + } + + foreach ($period as $moment) { + $stats[$moment] = $data[$moment] ?? 0; + } + + return collect($stats); + } +} diff --git a/flexiapi/app/StatisticsCall.php b/flexiapi/app/StatisticsCall.php index 0d9591d..084f7b6 100644 --- a/flexiapi/app/StatisticsCall.php +++ b/flexiapi/app/StatisticsCall.php @@ -22,11 +22,24 @@ namespace App; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Awobaz\Compoships\Compoships; + class StatisticsCall extends Model { use HasFactory; + use Compoships; public $incrementing = false; protected $casts = ['initiated_at' => 'datetime', 'ended_at' => 'datetime']; protected $keyType = 'string'; + + public function accountFrom() + { + return $this->belongsTo(Account::class, ['username', 'domain'], ['to_username', 'to_domain']); + } + + public function accountTo() + { + return $this->belongsTo(Account::class, ['username', 'domain'], ['to_username', 'to_domain']); + } } diff --git a/flexiapi/app/StatisticsMessage.php b/flexiapi/app/StatisticsMessage.php index 11ae279..48b31a9 100644 --- a/flexiapi/app/StatisticsMessage.php +++ b/flexiapi/app/StatisticsMessage.php @@ -20,13 +20,21 @@ namespace App; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Database\Eloquent\Model; + +use Awobaz\Compoships\Compoships; +use Awobaz\Compoships\Database\Eloquent\Model; class StatisticsMessage extends Model { use HasFactory; + use Compoships; public $incrementing = false; protected $casts = ['sent_at' => 'datetime']; protected $keyType = 'string'; + + public function accountFrom() + { + return $this->belongsTo(Account::class, ['username', 'domain'], ['to_username', 'to_domain']); + } } diff --git a/flexiapi/app/StatisticsMessageDevice.php b/flexiapi/app/StatisticsMessageDevice.php index 719a21e..01fccde 100644 --- a/flexiapi/app/StatisticsMessageDevice.php +++ b/flexiapi/app/StatisticsMessageDevice.php @@ -20,7 +20,8 @@ namespace App; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Database\Eloquent\Model; + +use Awobaz\Compoships\Database\Eloquent\Model; class StatisticsMessageDevice extends Model { @@ -33,4 +34,9 @@ class StatisticsMessageDevice extends Model { return $this->hasOne(StatisticsMessage::class, 'id', 'message_id'); } + + public function accountTo() + { + return $this->belongsTo(Account::class, ['username', 'domain'], ['to_username', 'to_domain']); + } } diff --git a/flexiapi/composer.json b/flexiapi/composer.json index 489b75a..1fc27b4 100644 --- a/flexiapi/composer.json +++ b/flexiapi/composer.json @@ -10,6 +10,7 @@ "require": { "php": ">=8.0.2", "anhskohbo/no-captcha": "^3.5", + "awobaz/compoships": "^2.2", "doctrine/dbal": "^3.6.6", "endroid/qr-code": "^4.8.2", "fakerphp/faker": "^1.23", diff --git a/flexiapi/composer.lock b/flexiapi/composer.lock index 516dc41..ae938b2 100644 --- a/flexiapi/composer.lock +++ b/flexiapi/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1c0a59db2fada52615ad6f31e0599291", + "content-hash": "b6a450b1e7adf4c259121350856f83a6", "packages": [ { "name": "anhskohbo/no-captcha", @@ -70,6 +70,68 @@ }, "time": "2023-02-15T16:07:08+00:00" }, + { + "name": "awobaz/compoships", + "version": "2.2.3", + "source": { + "type": "git", + "url": "https://github.com/topclaudy/compoships.git", + "reference": "404901e2ebd6794f70d2710a56edd4b0c500ce1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/topclaudy/compoships/zipball/404901e2ebd6794f70d2710a56edd4b0c500ce1f", + "reference": "404901e2ebd6794f70d2710a56edd4b0c500ce1f", + "shasum": "" + }, + "require": { + "fakerphp/faker": "^1.18", + "illuminate/database": ">=5.6 <11.0" + }, + "require-dev": { + "ext-sqlite3": "*", + "phpunit/phpunit": "^6.0|^8.0|^9.0" + }, + "suggest": { + "awobaz/blade-active": "Blade directives for the Laravel 'Active' package", + "awobaz/eloquent-auto-append": "Automatically append accessors to model serialization", + "awobaz/eloquent-mutators": "Reusable mutators (getters/setters) for Laravel 5's Eloquent", + "awobaz/syntactic": "Syntactic sugar for named and indexed parameters call." + }, + "type": "library", + "autoload": { + "psr-4": { + "Awobaz\\Compoships\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Claudin J. Daniel", + "email": "cdaniel@awobaz.com" + } + ], + "description": "Laravel relationships with support for composite/multiple keys", + "keywords": [ + "laravel", + "laravel composite keys", + "laravel relationships" + ], + "support": { + "issues": "https://github.com/topclaudy/compoships/issues", + "source": "https://github.com/topclaudy/compoships/tree/2.2.3" + }, + "funding": [ + { + "url": "https://paypal.me/awobaz", + "type": "custom" + } + ], + "time": "2023-02-22T16:52:55+00:00" + }, { "name": "bacon/bacon-qr-code", "version": "2.0.8", @@ -399,16 +461,16 @@ }, { "name": "doctrine/dbal", - "version": "3.6.6", + "version": "3.7.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "63646ffd71d1676d2f747f871be31b7e921c7864" + "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/63646ffd71d1676d2f747f871be31b7e921c7864", - "reference": "63646ffd71d1676d2f747f871be31b7e921c7864", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/00d03067f07482f025d41ab55e4ba0db5eca2cdf", + "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf", "shasum": "" }, "require": { @@ -424,9 +486,9 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.10.29", + "phpstan/phpstan": "1.10.35", "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "9.6.9", + "phpunit/phpunit": "9.6.13", "psalm/plugin-phpunit": "0.18.4", "slevomat/coding-standard": "8.13.1", "squizlabs/php_codesniffer": "3.7.2", @@ -492,7 +554,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.6.6" + "source": "https://github.com/doctrine/dbal/tree/3.7.0" }, "funding": [ { @@ -508,20 +570,20 @@ "type": "tidelift" } ], - "time": "2023-08-17T05:38:17+00:00" + "time": "2023-09-26T20:56:55+00:00" }, { "name": "doctrine/deprecations", - "version": "v1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3" + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", - "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931", "shasum": "" }, "require": { @@ -553,9 +615,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.1.1" + "source": "https://github.com/doctrine/deprecations/tree/1.1.2" }, - "time": "2023-06-03T09:27:29+00:00" + "time": "2023-09-27T20:04:15+00:00" }, { "name": "doctrine/event-manager", @@ -2054,16 +2116,16 @@ }, { "name": "league/commonmark", - "version": "2.4.0", + "version": "2.4.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048" + "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d44a24690f16b8c1808bf13b1bd54ae4c63ea048", - "reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/3669d6d5f7a47a93c08ddff335e6d945481a1dd5", + "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5", "shasum": "" }, "require": { @@ -2156,7 +2218,7 @@ "type": "tidelift" } ], - "time": "2023-03-24T15:16:10+00:00" + "time": "2023-08-30T16:55:00+00:00" }, { "name": "league/config", @@ -2242,16 +2304,16 @@ }, { "name": "league/flysystem", - "version": "3.15.1", + "version": "3.16.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "a141d430414fcb8bf797a18716b09f759a385bed" + "reference": "4fdf372ca6b63c6e281b1c01a624349ccb757729" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a141d430414fcb8bf797a18716b09f759a385bed", - "reference": "a141d430414fcb8bf797a18716b09f759a385bed", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/4fdf372ca6b63c6e281b1c01a624349ccb757729", + "reference": "4fdf372ca6b63c6e281b1c01a624349ccb757729", "shasum": "" }, "require": { @@ -2260,6 +2322,8 @@ "php": "^8.0.2" }, "conflict": { + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", "aws/aws-sdk-php": "3.209.31 || 3.210.0", "guzzlehttp/guzzle": "<7.0", "guzzlehttp/ringphp": "<1.1.1", @@ -2279,7 +2343,7 @@ "microsoft/azure-storage-blob": "^1.1", "phpseclib/phpseclib": "^3.0.14", "phpstan/phpstan": "^0.12.26", - "phpunit/phpunit": "^9.5.11", + "phpunit/phpunit": "^9.5.11|^10.0", "sabre/dav": "^4.3.1" }, "type": "library", @@ -2314,7 +2378,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.15.1" + "source": "https://github.com/thephpleague/flysystem/tree/3.16.0" }, "funding": [ { @@ -2326,20 +2390,20 @@ "type": "github" } ], - "time": "2023-05-04T09:04:26+00:00" + "time": "2023-09-07T19:22:17+00:00" }, { "name": "league/flysystem-local", - "version": "3.15.0", + "version": "3.16.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "543f64c397fefdf9cfeac443ffb6beff602796b3" + "reference": "ec7383f25642e6fd4bb0c9554fc2311245391781" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/543f64c397fefdf9cfeac443ffb6beff602796b3", - "reference": "543f64c397fefdf9cfeac443ffb6beff602796b3", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/ec7383f25642e6fd4bb0c9554fc2311245391781", + "reference": "ec7383f25642e6fd4bb0c9554fc2311245391781", "shasum": "" }, "require": { @@ -2374,7 +2438,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem-local/issues", - "source": "https://github.com/thephpleague/flysystem-local/tree/3.15.0" + "source": "https://github.com/thephpleague/flysystem-local/tree/3.16.0" }, "funding": [ { @@ -2386,7 +2450,7 @@ "type": "github" } ], - "time": "2023-05-02T20:02:14+00:00" + "time": "2023-08-30T10:23:59+00:00" }, { "name": "league/mime-type-detection", @@ -2668,16 +2732,16 @@ }, { "name": "nesbot/carbon", - "version": "2.69.0", + "version": "2.71.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c" + "reference": "98276233188583f2ff845a0f992a235472d9466a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4308217830e4ca445583a37d1bf4aff4153fa81c", - "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/98276233188583f2ff845a0f992a235472d9466a", + "reference": "98276233188583f2ff845a0f992a235472d9466a", "shasum": "" }, "require": { @@ -2770,7 +2834,7 @@ "type": "tidelift" } ], - "time": "2023-08-03T09:00:52+00:00" + "time": "2023-09-25T11:31:05+00:00" }, { "name": "nette/schema", @@ -2836,16 +2900,16 @@ }, { "name": "nette/utils", - "version": "v4.0.1", + "version": "v4.0.2", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "9124157137da01b1f5a5a22d6486cb975f26db7e" + "reference": "cead6637226456b35e1175cc53797dd585d85545" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/9124157137da01b1f5a5a22d6486cb975f26db7e", - "reference": "9124157137da01b1f5a5a22d6486cb975f26db7e", + "url": "https://api.github.com/repos/nette/utils/zipball/cead6637226456b35e1175cc53797dd585d85545", + "reference": "cead6637226456b35e1175cc53797dd585d85545", "shasum": "" }, "require": { @@ -2867,8 +2931,7 @@ "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", "ext-json": "to use Nette\\Utils\\Json", "ext-mbstring": "to use Strings::lower() etc...", - "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", - "ext-xml": "to use Strings::length() etc. when mbstring is not available" + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" }, "type": "library", "extra": { @@ -2917,9 +2980,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.1" + "source": "https://github.com/nette/utils/tree/v4.0.2" }, - "time": "2023-07-30T15:42:21+00:00" + "time": "2023-09-19T11:58:07+00:00" }, { "name": "nikic/php-parser", @@ -3362,16 +3425,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.27", + "version": "9.2.29", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "b0a88255cb70d52653d80c890bd7f38740ea50d1" + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/b0a88255cb70d52653d80c890bd7f38740ea50d1", - "reference": "b0a88255cb70d52653d80c890bd7f38740ea50d1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", "shasum": "" }, "require": { @@ -3428,7 +3491,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.27" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" }, "funding": [ { @@ -3436,7 +3499,7 @@ "type": "github" } ], - "time": "2023-07-26T13:44:30+00:00" + "time": "2023-09-19T04:57:46+00:00" }, { "name": "phpunit/php-file-iterator", @@ -3681,16 +3744,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.11", + "version": "9.6.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "810500e92855eba8a7a5319ae913be2da6f957b0" + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/810500e92855eba8a7a5319ae913be2da6f957b0", - "reference": "810500e92855eba8a7a5319ae913be2da6f957b0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be", + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be", "shasum": "" }, "require": { @@ -3705,7 +3768,7 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-code-coverage": "^9.2.28", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -3764,7 +3827,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.11" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13" }, "funding": [ { @@ -3780,7 +3843,7 @@ "type": "tidelift" } ], - "time": "2023-08-19T07:10:56+00:00" + "time": "2023-09-19T05:39:22+00:00" }, { "name": "psr/cache", @@ -3984,16 +4047,16 @@ }, { "name": "psr/http-client", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { @@ -4030,9 +4093,9 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/1.0.2" + "source": "https://github.com/php-fig/http-client" }, - "time": "2023-04-10T20:12:12+00:00" + "time": "2023-09-23T14:17:50+00:00" }, { "name": "psr/http-factory", @@ -8920,16 +8983,16 @@ }, { "name": "maximebf/debugbar", - "version": "v1.18.2", + "version": "v1.19.0", "source": { "type": "git", "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "17dcf3f6ed112bb85a37cf13538fd8de49f5c274" + "reference": "30f65f18f7ac086255a77a079f8e0dcdd35e828e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/17dcf3f6ed112bb85a37cf13538fd8de49f5c274", - "reference": "17dcf3f6ed112bb85a37cf13538fd8de49f5c274", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/30f65f18f7ac086255a77a079f8e0dcdd35e828e", + "reference": "30f65f18f7ac086255a77a079f8e0dcdd35e828e", "shasum": "" }, "require": { @@ -8980,9 +9043,9 @@ ], "support": { "issues": "https://github.com/maximebf/php-debugbar/issues", - "source": "https://github.com/maximebf/php-debugbar/tree/v1.18.2" + "source": "https://github.com/maximebf/php-debugbar/tree/v1.19.0" }, - "time": "2023-02-04T15:27:00+00:00" + "time": "2023-09-19T19:53:10+00:00" }, { "name": "mockery/mockery", @@ -9159,16 +9222,16 @@ }, { "name": "pdepend/pdepend", - "version": "2.14.0", + "version": "2.15.1", "source": { "type": "git", "url": "https://github.com/pdepend/pdepend.git", - "reference": "1121d4b04af06e33e9659bac3a6741b91cab1de1" + "reference": "d12f25bcdfb7754bea458a4a5cb159d55e9950d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/1121d4b04af06e33e9659bac3a6741b91cab1de1", - "reference": "1121d4b04af06e33e9659bac3a6741b91cab1de1", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/d12f25bcdfb7754bea458a4a5cb159d55e9950d0", + "reference": "d12f25bcdfb7754bea458a4a5cb159d55e9950d0", "shasum": "" }, "require": { @@ -9210,7 +9273,7 @@ ], "support": { "issues": "https://github.com/pdepend/pdepend/issues", - "source": "https://github.com/pdepend/pdepend/tree/2.14.0" + "source": "https://github.com/pdepend/pdepend/tree/2.15.1" }, "funding": [ { @@ -9218,26 +9281,26 @@ "type": "tidelift" } ], - "time": "2023-05-26T13:15:18+00:00" + "time": "2023-09-28T12:00:56+00:00" }, { "name": "phpmd/phpmd", - "version": "2.13.0", + "version": "2.14.1", "source": { "type": "git", "url": "https://github.com/phpmd/phpmd.git", - "reference": "dad0228156856b3ad959992f9748514fa943f3e3" + "reference": "442fc2c34edcd5198b442d8647c7f0aec3afabe8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/dad0228156856b3ad959992f9748514fa943f3e3", - "reference": "dad0228156856b3ad959992f9748514fa943f3e3", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/442fc2c34edcd5198b442d8647c7f0aec3afabe8", + "reference": "442fc2c34edcd5198b442d8647c7f0aec3afabe8", "shasum": "" }, "require": { "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0", "ext-xml": "*", - "pdepend/pdepend": "^2.12.1", + "pdepend/pdepend": "^2.15.1", "php": ">=5.3.9" }, "require-dev": { @@ -9247,7 +9310,7 @@ "gregwar/rst": "^1.0", "mikey179/vfsstream": "^1.6.8", "phpunit/phpunit": "^4.8.36 || ^5.7.27", - "squizlabs/php_codesniffer": "^2.0" + "squizlabs/php_codesniffer": "^2.9.2 || ^3.7.2" }, "bin": [ "src/bin/phpmd" @@ -9284,6 +9347,7 @@ "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", "homepage": "https://phpmd.org/", "keywords": [ + "dev", "mess detection", "mess detector", "pdepend", @@ -9293,7 +9357,7 @@ "support": { "irc": "irc://irc.freenode.org/phpmd", "issues": "https://github.com/phpmd/phpmd/issues", - "source": "https://github.com/phpmd/phpmd/tree/2.13.0" + "source": "https://github.com/phpmd/phpmd/tree/2.14.1" }, "funding": [ { @@ -9301,7 +9365,7 @@ "type": "tidelift" } ], - "time": "2022-09-10T08:44:15+00:00" + "time": "2023-09-28T13:07:44+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -9602,5 +9666,5 @@ "platform-overrides": { "php": "8.0.2" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/flexiapi/database/factories/AccountFactory.php b/flexiapi/database/factories/AccountFactory.php index 4acb294..d2c6eac 100644 --- a/flexiapi/database/factories/AccountFactory.php +++ b/flexiapi/database/factories/AccountFactory.php @@ -19,14 +19,17 @@ namespace Database\Factories; -use App\Account; -use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController; use Illuminate\Support\Str; use Illuminate\Database\Eloquent\Factories\Factory; +use Awobaz\Compoships\Database\Eloquent\Factories\ComposhipsFactory; + +use App\Account; +use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController; class AccountFactory extends Factory { protected $model = Account::class; + use ComposhipsFactory; public function definition() { @@ -39,7 +42,7 @@ class AccountFactory extends Factory 'confirmation_key' => Str::random(WebAuthenticateController::$emailCodeSize), 'provisioning_token' => Str::random(WebAuthenticateController::$emailCodeSize), 'ip_address' => $this->faker->ipv4, - 'created_at' => $this->faker->dateTime, + 'created_at' => $this->faker->dateTimeBetween('-1 year'), 'dtmf_protocol' => array_rand(Account::$dtmfProtocols), 'activated' => true ]; diff --git a/flexiapi/database/factories/AdminFactory.php b/flexiapi/database/factories/AdminFactory.php index 02e92cc..fa90eac 100644 --- a/flexiapi/database/factories/AdminFactory.php +++ b/flexiapi/database/factories/AdminFactory.php @@ -22,7 +22,6 @@ namespace Database\Factories; use App\Admin; use App\Password; use Illuminate\Database\Eloquent\Factories\Factory; -use Illuminate\Support\Str; class AdminFactory extends Factory { diff --git a/flexiapi/database/factories/StatisticsMessageDeviceFactory.php b/flexiapi/database/factories/StatisticsMessageDeviceFactory.php new file mode 100644 index 0000000..abb7eaa --- /dev/null +++ b/flexiapi/database/factories/StatisticsMessageDeviceFactory.php @@ -0,0 +1,26 @@ +create(); + + return [ + 'message_id' => $message->id, + 'to_username' => $this->faker->userName(), + 'to_domain' => $this->faker->domainName(), + 'device_id' => $this->faker->uuid(), + 'received_at' => $this->faker->dateTimeBetween('-1 year'), + 'last_status' => 200, + ]; + } +} diff --git a/flexiapi/database/factories/StatisticsMessageFactory.php b/flexiapi/database/factories/StatisticsMessageFactory.php index 4c70d9e..9258165 100644 --- a/flexiapi/database/factories/StatisticsMessageFactory.php +++ b/flexiapi/database/factories/StatisticsMessageFactory.php @@ -3,9 +3,12 @@ namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; +use Awobaz\Compoships\Database\Eloquent\Factories\ComposhipsFactory; class StatisticsMessageFactory extends Factory { + use ComposhipsFactory; + public function definition(): array { return [ diff --git a/flexiapi/database/migrations/2023_10_03_121128_add_statistics_indexes.php b/flexiapi/database/migrations/2023_10_03_121128_add_statistics_indexes.php new file mode 100644 index 0000000..357c559 --- /dev/null +++ b/flexiapi/database/migrations/2023_10_03_121128_add_statistics_indexes.php @@ -0,0 +1,58 @@ +index('from_domain'); + $table->index('from_username'); + $table->index('to_domain'); + $table->index('to_username'); + }); + + Schema::table('statistics_messages', function (Blueprint $table) { + $table->index('from_domain'); + $table->index('from_username'); + }); + + Schema::table('statistics_message_devices', function (Blueprint $table) { + $table->index('to_domain'); + $table->index('to_username'); + }); + + Schema::table('accounts', function (Blueprint $table) { + $table->index('domain'); + $table->index('username'); + }); + } + + public function down() + { + Schema::table('statistics_calls', function (Blueprint $table) { + $table->dropIndex('statistics_calls_from_domain_index'); + $table->dropIndex('statistics_calls_from_username_index'); + $table->dropIndex('statistics_calls_to_domain_index'); + $table->dropIndex('statistics_calls_to_username_index'); + }); + + Schema::table('statistics_messages', function (Blueprint $table) { + $table->dropIndex('statistics_messages_from_domain_index'); + $table->dropIndex('statistics_messages_from_username_index'); + }); + + Schema::table('statistics_message_devices', function (Blueprint $table) { + $table->dropIndex('statistics_message_devices_to_domain_index'); + $table->dropIndex('statistics_message_devices_to_username_index'); + }); + + Schema::table('accounts', function (Blueprint $table) { + $table->dropIndex('accounts_domain_index'); + $table->dropIndex('accounts_username_index'); + }); + } +}; diff --git a/flexiapi/database/seeds/StatisticsSeeder.php b/flexiapi/database/seeds/StatisticsSeeder.php index e8fd62e..531e3b9 100644 --- a/flexiapi/database/seeds/StatisticsSeeder.php +++ b/flexiapi/database/seeds/StatisticsSeeder.php @@ -19,6 +19,7 @@ namespace Database\Seeders; +use App\Account; use App\StatisticsCall; use App\StatisticsCallDevice; use App\StatisticsMessage; @@ -39,12 +40,11 @@ class StatisticsSeeder extends Seeder StatisticsCall::truncate(); Schema::enableForeignKeyConstraints(); - StatisticsMessage::factory() - ->count(10000) - ->create(); - - StatisticsCall::factory() - ->count(10000) + Account::factory(10) + ->hasStatisticsFromMessages(20) + ->hasStatisticsToMessageDevices(20) + ->hasStatisticsFromCalls(20) + ->hasStatisticsToCalls(20) ->create(); } } diff --git a/flexiapi/public/css/style.css b/flexiapi/public/css/style.css index 94299b8..d382d17 100644 --- a/flexiapi/public/css/style.css +++ b/flexiapi/public/css/style.css @@ -760,7 +760,7 @@ select.list_toggle { pointer-events: none; } -#chart { +.chart { min-height: 80vh; } diff --git a/flexiapi/resources/views/admin/account/create_edit.blade.php b/flexiapi/resources/views/admin/account/create_edit.blade.php index d71d6ad..6146b85 100644 --- a/flexiapi/resources/views/admin/account/create_edit.blade.php +++ b/flexiapi/resources/views/admin/account/create_edit.blade.php @@ -21,8 +21,9 @@

Updated on {{ $account->updated_at->format('d/m/Y') }} @include('parts.tabs', [ 'items' => [ - route('admin.account.edit', $account->id, ['type' => 'messages']) => 'Information', - route('admin.account.device.index', $account->id, ['type' => 'accounts']) => 'Devices', + route('admin.account.edit', $account->id) => 'Information', + route('admin.account.device.index', $account->id) => 'Devices', + route('admin.account.statistics.show', $account->id) => 'Statistics', ], ]) @else @@ -41,7 +42,8 @@

Connexion

id) readonly @endif> + value="@if ($account->id) {{ $account->username }}@else{{ old('username') }} @endif" + @if ($account->id) readonly @endif> @include('parts.errors', ['name' => 'username'])
@@ -53,32 +55,37 @@
- + @include('parts.errors', ['name' => 'display_name'])
- id)required @endif> + id) required @endif> @include('parts.errors', ['name' => 'password'])
- id)required @endif> + id) required @endif> @include('parts.errors', ['name' => 'password_confirmation'])
- + @include('parts.errors', ['name' => 'email'])
- + @include('parts.errors', ['name' => 'phone'])
diff --git a/flexiapi/resources/views/admin/account/device/index.blade.php b/flexiapi/resources/views/admin/account/device/index.blade.php index 81e3c5e..df5428f 100644 --- a/flexiapi/resources/views/admin/account/device/index.blade.php +++ b/flexiapi/resources/views/admin/account/device/index.blade.php @@ -19,8 +19,9 @@ @include('parts.tabs', [ 'items' => [ - route('admin.account.edit', $account->id, ['type' => 'messages']) => 'Information', - route('admin.account.device.index', $account->id, ['type' => 'accounts']) => 'Devices', + route('admin.account.edit', $account->id) => 'Information', + route('admin.account.device.index', $account->id) => 'Devices', + route('admin.account.statistics.show', $account->id) => 'Statistics', ], ]) diff --git a/flexiapi/resources/views/admin/account/statistics/show.blade.php b/flexiapi/resources/views/admin/account/statistics/show.blade.php new file mode 100644 index 0000000..65ec2f4 --- /dev/null +++ b/flexiapi/resources/views/admin/account/statistics/show.blade.php @@ -0,0 +1,72 @@ +@extends('layouts.main') + +@section('breadcrumb') + + + +@endsection + +@section('content') + +
+

people {{ $account->identifier }}

+
+ +@include('parts.tabs', [ + 'items' => [ + route('admin.account.edit', $account->id) => 'Information', + route('admin.account.device.index', $account->id) => 'Devices', + route('admin.account.statistics.show', $account->id) => 'Statistics', + ], +]) + +
+
+ @csrf + @method('post') + + + +
+ + +
+
+ + +
+ +
+ Day + Week + Month + Year +
+
+
+ +

message Messages from the account

+ +{!! $messagesFromGraph !!} + +

message Messages to the account

+ +{!! $messagesToGraph !!} + +

call Calls from the account

+ +{!! $callsFromGraph !!} + +

call Calls to the account

+ +{!! $callsToGraph !!} + +@endsection \ No newline at end of file diff --git a/flexiapi/resources/views/admin/statistics/parts/columns.blade.php b/flexiapi/resources/views/admin/statistics/parts/columns.blade.php deleted file mode 100644 index 67e1585..0000000 --- a/flexiapi/resources/views/admin/statistics/parts/columns.blade.php +++ /dev/null @@ -1,12 +0,0 @@ -
-
-
-
\ No newline at end of file diff --git a/flexiapi/resources/views/admin/statistics/parts/filters.blade.php b/flexiapi/resources/views/admin/statistics/parts/filters.blade.php new file mode 100644 index 0000000..6fc9cd2 --- /dev/null +++ b/flexiapi/resources/views/admin/statistics/parts/filters.blade.php @@ -0,0 +1,73 @@ +
+
+ @csrf + @method('post') + + + + +
+ + +
+
+ + +
+ +
+ + @if (config('app.admins_manage_multi_domains')) +
+ + +
+ @endif + + @if ($type == 'accounts') +
+ + +
+ @endif + +
+ Day + Week + Month + Year +
+ + +
+
diff --git a/flexiapi/resources/views/admin/statistics/parts/legend.blade.php b/flexiapi/resources/views/admin/statistics/parts/legend.blade.php deleted file mode 100644 index b250ea4..0000000 --- a/flexiapi/resources/views/admin/statistics/parts/legend.blade.php +++ /dev/null @@ -1,6 +0,0 @@ -
-
Unactivated phones
-
Activated phones
-
Unactivated emails
-
Activated emails
-
\ No newline at end of file diff --git a/flexiapi/resources/views/admin/statistics/show.blade.php b/flexiapi/resources/views/admin/statistics/show.blade.php index e46d83a..8ab4815 100644 --- a/flexiapi/resources/views/admin/statistics/show.blade.php +++ b/flexiapi/resources/views/admin/statistics/show.blade.php @@ -5,9 +5,9 @@ @endsection @section('content') -
-

analytics Statistics

-
+
+

analytics Statistics

+
@include('parts.tabs', [ 'items' => [ @@ -17,43 +17,7 @@ ], ]) -
-
- @csrf - @method('post') - - - - -
- - -
-
- - -
- -
- Day - Week - Month - Year -
- - -
-
+ @include('admin.statistics.parts.filters') @include('parts.graph') @endsection diff --git a/flexiapi/resources/views/parts/graph.blade.php b/flexiapi/resources/views/parts/graph.blade.php index 84d23fd..f8c01d9 100644 --- a/flexiapi/resources/views/parts/graph.blade.php +++ b/flexiapi/resources/views/parts/graph.blade.php @@ -1,27 +1,17 @@ -
+@php($id = generatePin()) + +
\ No newline at end of file + diff --git a/flexiapi/routes/web.php b/flexiapi/routes/web.php index d39a8b0..2d03c18 100644 --- a/flexiapi/routes/web.php +++ b/flexiapi/routes/web.php @@ -31,6 +31,7 @@ use App\Http\Controllers\Admin\AccountDeviceController; use App\Http\Controllers\Admin\AccountTypeController; use App\Http\Controllers\Admin\AccountController as AdminAccountController; use App\Http\Controllers\Admin\AccountImportController; +use App\Http\Controllers\Admin\AccountStatisticsController; use App\Http\Controllers\Admin\ContactsListController; use App\Http\Controllers\Admin\ContactsListContactController; use App\Http\Controllers\Admin\StatisticsController; @@ -132,6 +133,7 @@ if (config('app.web_panel')) { Route::get('/', 'index')->name('index'); Route::get('/{type?}', 'show')->name('show'); Route::post('/', 'edit')->name('edit'); + //Route::post('search', 'search')->name('search'); }); Route::name('account.')->prefix('accounts')->group(function () { @@ -191,6 +193,11 @@ if (config('app.web_panel')) { Route::delete('/', 'destroy')->name('destroy'); }); + Route::name('statistics.')->prefix('{account}/statistics')->controller(AccountStatisticsController::class)->group(function () { + Route::get('/', 'show')->name('show'); + Route::post('/', 'edit')->name('edit'); + }); + Route::name('action.')->prefix('{account}/actions')->controller(AccountActionController::class)->group(function () { Route::get('create', 'create')->name('create'); Route::post('/', 'store')->name('store');