diff --git a/.env.example b/.env.example index ce7f61b..e9ba913 100644 --- a/.env.example +++ b/.env.example @@ -70,3 +70,4 @@ TRUSTED_IP="127.0.0.1" NOTIFICATION_SERVER_URL= LOGIN_HASH_VALUE= +SETAD_IP= diff --git a/app/Console/Commands/SendSupervisorCheckStatsCommand.php b/app/Console/Commands/SendSupervisorCheckStatsCommand.php new file mode 100644 index 0000000..0e67815 --- /dev/null +++ b/app/Console/Commands/SendSupervisorCheckStatsCommand.php @@ -0,0 +1,32 @@ +execute(); + $this->info('Done!'); + } +} diff --git a/app/Exports/OperatorDialogues/OperatorCartableExcel.php b/app/Exports/OperatorDialogues/OperatorCartableExcel.php new file mode 100644 index 0000000..6171456 --- /dev/null +++ b/app/Exports/OperatorDialogues/OperatorCartableExcel.php @@ -0,0 +1,41 @@ + $this->data, + ]); + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $event->sheet->getDelegate()->setRightToLeft(true); + $event->sheet->getDelegate()->getStyle('A:U')->getFont()->setName('Arial'); + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setHorizontal(Alignment::HORIZONTAL_CENTER); + + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setVertical(Alignment::VERTICAL_CENTER); + } + ]; + } + +} diff --git a/app/Exports/OperatorDialogues/SupervisorCartableExcel.php b/app/Exports/OperatorDialogues/SupervisorCartableExcel.php new file mode 100644 index 0000000..5073d8d --- /dev/null +++ b/app/Exports/OperatorDialogues/SupervisorCartableExcel.php @@ -0,0 +1,41 @@ + $this->data, + ]); + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $event->sheet->getDelegate()->setRightToLeft(true); + $event->sheet->getDelegate()->getStyle('A:U')->getFont()->setName('Arial'); + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setHorizontal(Alignment::HORIZONTAL_CENTER); + + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setVertical(Alignment::VERTICAL_CENTER); + } + ]; + } + +} diff --git a/app/Exports/PeopleMessages/OperatorCartableExcel.php b/app/Exports/PeopleMessages/OperatorCartableExcel.php new file mode 100644 index 0000000..f0c08b6 --- /dev/null +++ b/app/Exports/PeopleMessages/OperatorCartableExcel.php @@ -0,0 +1,41 @@ + $this->data, + ]); + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $event->sheet->getDelegate()->setRightToLeft(true); + $event->sheet->getDelegate()->getStyle('A:U')->getFont()->setName('Arial'); + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setHorizontal(Alignment::HORIZONTAL_CENTER); + + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setVertical(Alignment::VERTICAL_CENTER); + } + ]; + } + +} diff --git a/app/Exports/PeopleMessages/SupervisorCartableExcel.php b/app/Exports/PeopleMessages/SupervisorCartableExcel.php new file mode 100644 index 0000000..9b76d67 --- /dev/null +++ b/app/Exports/PeopleMessages/SupervisorCartableExcel.php @@ -0,0 +1,41 @@ + $this->data, + ]); + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $event->sheet->getDelegate()->setRightToLeft(true); + $event->sheet->getDelegate()->getStyle('A:U')->getFont()->setName('Arial'); + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setHorizontal(Alignment::HORIZONTAL_CENTER); + + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setVertical(Alignment::VERTICAL_CENTER); + } + ]; + } + +} diff --git a/app/Exports/SystemMessage/OperatorCartableExcel.php b/app/Exports/SystemMessage/OperatorCartableExcel.php new file mode 100644 index 0000000..cbf0f7d --- /dev/null +++ b/app/Exports/SystemMessage/OperatorCartableExcel.php @@ -0,0 +1,41 @@ + $this->data, + ]); + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $event->sheet->getDelegate()->setRightToLeft(true); + $event->sheet->getDelegate()->getStyle('A:U')->getFont()->setName('Arial'); + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setHorizontal(Alignment::HORIZONTAL_CENTER); + + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setVertical(Alignment::VERTICAL_CENTER); + } + ]; + } + +} diff --git a/app/Exports/SystemMessage/SupervisorCartableExcel.php b/app/Exports/SystemMessage/SupervisorCartableExcel.php new file mode 100644 index 0000000..f2ab817 --- /dev/null +++ b/app/Exports/SystemMessage/SupervisorCartableExcel.php @@ -0,0 +1,41 @@ + $this->data, + ]); + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $event->sheet->getDelegate()->setRightToLeft(true); + $event->sheet->getDelegate()->getStyle('A:U')->getFont()->setName('Arial'); + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setHorizontal(Alignment::HORIZONTAL_CENTER); + + $event->sheet->getDelegate()->getStyle('A:U') + ->getAlignment() + ->setVertical(Alignment::VERTICAL_CENTER); + } + ]; + } + +} diff --git a/app/Http/Controllers/HeadquartersDashboard/CumulativeSupervisorPerformanceStatsController.php b/app/Http/Controllers/HeadquartersDashboard/CumulativeSupervisorPerformanceStatsController.php new file mode 100644 index 0000000..efe7807 --- /dev/null +++ b/app/Http/Controllers/HeadquartersDashboard/CumulativeSupervisorPerformanceStatsController.php @@ -0,0 +1,41 @@ +selectRaw(" + province_id, + province_name, + SUM(calls) AS total, + SUM(reviews) AS reviews, + SUM(good) AS good, + SUM(bad) AS bad + ") + ->groupBy('province_id', 'province_name') + ->unionAll(DB::table('supervisor_performances')->selectRaw(" + 0 as province_id, + 'کشوری' as province_name, + SUM(calls) AS total, + SUM(reviews) AS reviews, + SUM(good) AS good, + SUM(bad) AS bad + ")); + + return response()->json( + DataTableFacade::run( + $query, + $request, + allowedFilters: ['*'], + allowedSortings: ['*']) + ); + } +} diff --git a/app/Http/Controllers/HeadquartersDashboard/LoginToProvinceController.php b/app/Http/Controllers/HeadquartersDashboard/LoginToProvinceController.php index 746d348..bb2a13d 100644 --- a/app/Http/Controllers/HeadquartersDashboard/LoginToProvinceController.php +++ b/app/Http/Controllers/HeadquartersDashboard/LoginToProvinceController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\HeadquartersDashboard; use App\Http\Controllers\Controller; +use app\Http\Traits\ApiResponse; use App\Models\Province; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -10,19 +11,20 @@ use Illuminate\Support\Facades\Hash; class LoginToProvinceController extends Controller { - public function loginToProvince(Request $request) + use ApiResponse; + + public function authenticate(Request $request) { $province_ip = Province::query() ->Where('id', '=', $request->province_id) ->value('ip_address'); - $payload = [ + $data = [ 'user_id' => auth()->user()->id, 'token' => Hash::make(config('globalVariables.LOGIN_HASH_VALUE')), + 'ip' => $province_ip, ]; - $url = $province_ip . "?" . http_build_query($payload); - - return redirect($url); + return $this->successResponse($data); } } diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 887c227..05b8c08 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -37,9 +37,11 @@ class ProfileController extends Controller public function changeAvatar(ChangeAvatarRequest $request): JsonResponse { $user = auth()->user(); + if ($user->avatar){ FileFacade::delete($user->avatar, true); } + $user->update([ 'avatar' => FileFacade::save($request->file('avatar'), 'users/avatars/' . $request->username) ]); @@ -49,16 +51,19 @@ class ProfileController extends Controller public function online(Request $request): JsonResponse { - User::query()->where('telephone_id', '=', $request->telephone_id)->update([ - 'is_online' => true, - ]); + User::query() + ->firstWhere('telephone_id', '=', $request->telephone_id) + ->update(['is_online' => true,]); + return $this->successResponse(); } public function offline(Request $request): JsonResponse { - $user= User::query()->where('telephone_id', '=', $request->telephone_id)->first(); - $user->update(['is_online' => false]); + User::query() + ->firstWhere('telephone_id', '=', $request->telephone_id) + ->update(['is_online' => false]); + return $this->successResponse(); } diff --git a/app/Http/Controllers/ProvinceDashboard/OperatorDialogues/OperatorController.php b/app/Http/Controllers/ProvinceDashboard/OperatorDialogues/OperatorController.php index 614733a..8a733d9 100644 --- a/app/Http/Controllers/ProvinceDashboard/OperatorDialogues/OperatorController.php +++ b/app/Http/Controllers/ProvinceDashboard/OperatorDialogues/OperatorController.php @@ -2,13 +2,19 @@ namespace App\Http\Controllers\ProvinceDashboard\OperatorDialogues; +use App\Exports\OperatorDialogues\OperatorCartableExcel; use App\Http\Controllers\Controller; +use app\Http\Traits\ApiResponse; +use App\Models\OperatorDialogue; use App\Services\Dashboard\Province\OperatorDialogues\DataTableService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Maatwebsite\Excel\Facades\Excel; +use Symfony\Component\HttpFoundation\BinaryFileResponse; class OperatorController extends Controller { + use ApiResponse; /** * Display a listing of the resource. */ @@ -20,9 +26,9 @@ class OperatorController extends Controller /** * Display the specified resource. */ - public function show(string $id) + public function show(OperatorDialogue $operatorDialogue): JsonResponse { - // + return $this->successResponse($operatorDialogue); } /** @@ -36,8 +42,10 @@ class OperatorController extends Controller /** * Remove the specified resource from storage. */ - public function excel(string $id) + public function excel(Request $request, DataTableService $dataTableService): BinaryFileResponse { - // + $name = 'گزارش از کارتابل پیام های سیستمی ' . now()->format('Y-m-d H:i') . '.xlsx'; + $data = $dataTableService->dataTable($request, true); + return Excel::download(new OperatorCartableExcel($data['data']), $name); } } diff --git a/app/Http/Controllers/ProvinceDashboard/OperatorDialogues/SupervisorController.php b/app/Http/Controllers/ProvinceDashboard/OperatorDialogues/SupervisorController.php index 1fd5395..c3cdace 100644 --- a/app/Http/Controllers/ProvinceDashboard/OperatorDialogues/SupervisorController.php +++ b/app/Http/Controllers/ProvinceDashboard/OperatorDialogues/SupervisorController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\ProvinceDashboard\OperatorDialogues; +use App\Exports\OperatorDialogues\SupervisorCartableExcel; use App\Http\Controllers\Controller; use App\Http\Requests\ProvinceDashboard\OperatorDialogs\RateRequest; use app\Http\Traits\ApiResponse; @@ -9,6 +10,8 @@ use App\Models\OperatorDialogue; use App\Services\Dashboard\Province\OperatorDialogues\DataTableService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Maatwebsite\Excel\Facades\Excel; +use Symfony\Component\HttpFoundation\BinaryFileResponse; class SupervisorController extends Controller { @@ -35,9 +38,10 @@ class SupervisorController extends Controller return $this->successResponse($operatorDialogue); } - public function excel() + public function excel(Request $request, DataTableService $dataTableService): BinaryFileResponse { - // + $name = 'گزارش از کارتابل پیام های سیستمی ' . now()->format('Y-m-d H:i') . '.xlsx'; + $data = $dataTableService->dataTable($request, true); + return Excel::download(new SupervisorCartableExcel($data['data']), $name); } - } diff --git a/app/Http/Controllers/ProvinceDashboard/PeopleMessages/OperatorController.php b/app/Http/Controllers/ProvinceDashboard/PeopleMessages/OperatorController.php index 41677ec..8b30444 100644 --- a/app/Http/Controllers/ProvinceDashboard/PeopleMessages/OperatorController.php +++ b/app/Http/Controllers/ProvinceDashboard/PeopleMessages/OperatorController.php @@ -3,12 +3,14 @@ namespace App\Http\Controllers\ProvinceDashboard\PeopleMessages; use App\Enums\PeopleMessageActions; +use App\Exports\PeopleMessages\OperatorCartableExcel; use App\Http\Controllers\Controller; use app\Http\Traits\ApiResponse; use App\Models\PeopleMessage; use App\Services\Dashboard\Province\PeopleMessages\DataTableService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Maatwebsite\Excel\Facades\Excel; class OperatorController extends Controller { @@ -21,8 +23,11 @@ class OperatorController extends Controller return response()->json($dataTableService->index($request)); } - public function excel() + public function excel(Request $request, DataTableService $dataTableService) { + $name = 'گزارش از کارتابل پیام های سیستمی ' . now()->format('Y-m-d H:i') . '.xlsx'; + $data = $dataTableService->dataTable($request, true); + return Excel::download(new OperatorCartableExcel($data['data']), $name); } diff --git a/app/Http/Controllers/ProvinceDashboard/PeopleMessages/SupervisorController.php b/app/Http/Controllers/ProvinceDashboard/PeopleMessages/SupervisorController.php index 6028dcf..7d265b5 100644 --- a/app/Http/Controllers/ProvinceDashboard/PeopleMessages/SupervisorController.php +++ b/app/Http/Controllers/ProvinceDashboard/PeopleMessages/SupervisorController.php @@ -2,13 +2,19 @@ namespace App\Http\Controllers\ProvinceDashboard\PeopleMessages; +use App\Exports\PeopleMessages\SupervisorCartableExcel; use App\Http\Controllers\Controller; +use app\Http\Traits\ApiResponse; +use App\Models\PeopleMessage; use App\Services\Dashboard\Province\PeopleMessages\DataTableService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Maatwebsite\Excel\Facades\Excel; class SupervisorController extends Controller { + use ApiResponse; + /** * Display a listing of the resource. */ @@ -17,16 +23,18 @@ class SupervisorController extends Controller return response()->json($dataTableService->index($request)); } - public function excel() + public function excel(Request $request, DataTableService $dataTableService) { - + $name = 'گزارش از کارتابل پیام های سیستمی ' . now()->format('Y-m-d H:i') . '.xlsx'; + $data = $dataTableService->dataTable($request, true); + return Excel::download(new SupervisorCartableExcel($data['data']), $name); } /** * Display the specified resource. */ - public function show(string $id) + public function show(PeopleMessage $peopleMessage) { - // + return $this->successResponse($peopleMessage); } } diff --git a/app/Http/Controllers/ProvinceDashboard/SystemMessages/OperatorController.php b/app/Http/Controllers/ProvinceDashboard/SystemMessages/OperatorController.php index fe582d7..c7bd230 100644 --- a/app/Http/Controllers/ProvinceDashboard/SystemMessages/OperatorController.php +++ b/app/Http/Controllers/ProvinceDashboard/SystemMessages/OperatorController.php @@ -2,12 +2,14 @@ namespace App\Http\Controllers\ProvinceDashboard\SystemMessages; +use App\Exports\SystemMessage\OperatorCartableExcel; use App\Http\Controllers\Controller; use app\Http\Traits\ApiResponse; use App\Models\SystemMessage; use App\Services\Dashboard\Province\SystemMessages\OperatorService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Maatwebsite\Excel\Facades\Excel; class OperatorController extends Controller { @@ -33,8 +35,11 @@ class OperatorController extends Controller // } - public function excel() + public function excel(Request $request, OperatorService $operatorService) { + $name = 'گزارش از کارتابل پیام های سیستمی ' . now()->format('Y-m-d H:i') . '.xlsx'; + $data = $operatorService->dataTable($request, true); + return Excel::download(new OperatorCartableExcel($data['data']), $name); } } diff --git a/app/Http/Controllers/ProvinceDashboard/SystemMessages/SupervisorController.php b/app/Http/Controllers/ProvinceDashboard/SystemMessages/SupervisorController.php index 914f594..d5b4d96 100644 --- a/app/Http/Controllers/ProvinceDashboard/SystemMessages/SupervisorController.php +++ b/app/Http/Controllers/ProvinceDashboard/SystemMessages/SupervisorController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\ProvinceDashboard\SystemMessages; +use App\Exports\SystemMessage\SupervisorCartableExcel; use App\Http\Controllers\Controller; use App\Http\Requests\ProvinceDashboard\SystemMessages\RateRequest; use app\Http\Traits\ApiResponse; @@ -9,6 +10,7 @@ use App\Models\SystemMessage; use App\Services\Dashboard\Province\SystemMessages\SupervisorService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Maatwebsite\Excel\Facades\Excel; class SupervisorController extends Controller { @@ -21,8 +23,11 @@ class SupervisorController extends Controller return response()->json($supervisorService->datatable($request)); } - public function excel() + public function excel(Request $request, SupervisorService $supervisorService) { + $name = 'گزارش از کارتابل پیام های سیستمی ' . now()->format('Y-m-d H:i') . '.xlsx'; + $data = $supervisorService->dataTable($request, true); + return Excel::download(new SupervisorCartableExcel($data['data']), $name); } diff --git a/app/Http/Controllers/ProvinceDashboard/VerifyAuthenticationController.php b/app/Http/Controllers/ProvinceDashboard/VerifyAuthenticationController.php new file mode 100644 index 0000000..e5d12e3 --- /dev/null +++ b/app/Http/Controllers/ProvinceDashboard/VerifyAuthenticationController.php @@ -0,0 +1,28 @@ +token)) { + return $this->errorResponse('Invalid token'); + } + + $user = User::query()->findOrFail($request->user_id); + + Auth::login($user); + + return $this->successResponse(); + } +} diff --git a/app/Http/Middleware/VerifySetadIp.php b/app/Http/Middleware/VerifySetadIp.php index a6d3bac..00f3b45 100644 --- a/app/Http/Middleware/VerifySetadIp.php +++ b/app/Http/Middleware/VerifySetadIp.php @@ -11,18 +11,14 @@ class VerifySetadIp /** * Handle an incoming request. * - * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next + * @param Closure(Request): (Response) $next */ public function handle(Request $request, Closure $next): Response { - $masterServerIp = env('MASTER_SERVER_IP'); - if (is_null($masterServerIp)) { - return response('Master server IP not configured.', 500); + if ($request->ip() == config('globalVariables.SETAD_IP')) { + return $next($request); } - if ($request->ip() !== $masterServerIp) { - return response('Unauthorized.', 401); - } - return $next($request); + abort(Response::HTTP_FORBIDDEN); } } diff --git a/app/Models/ExpertPerformance.php b/app/Models/ExpertPerformance.php deleted file mode 100644 index a6aa1f8..0000000 --- a/app/Models/ExpertPerformance.php +++ /dev/null @@ -1,12 +0,0 @@ - */ - use HasFactory; -} diff --git a/app/Models/SupervisorPerformance.php b/app/Models/SupervisorPerformance.php new file mode 100644 index 0000000..0003ff1 --- /dev/null +++ b/app/Models/SupervisorPerformance.php @@ -0,0 +1,15 @@ + */ + use HasFactory; + + protected $guarded = []; +} diff --git a/app/Models/SystemMessage.php b/app/Models/SystemMessage.php index 20e004a..d69a3e1 100644 --- a/app/Models/SystemMessage.php +++ b/app/Models/SystemMessage.php @@ -2,13 +2,23 @@ namespace App\Models; +use Database\Factories\SystemMessageFactory; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Storage; class SystemMessage extends Model { - /** @use HasFactory<\Database\Factories\SystemMessageFactory> */ + /** @use HasFactory */ use HasFactory; protected $guarded = []; + + protected function voice(): Attribute + { + return Attribute::make( + get: fn($value) => $value == null ? null : Storage::disk('public')->url($value) + ); + } } diff --git a/app/Services/Commands/SendSupervisorCheckStatsReportService.php b/app/Services/Commands/SendSupervisorCheckStatsReportService.php new file mode 100644 index 0000000..759dcfa --- /dev/null +++ b/app/Services/Commands/SendSupervisorCheckStatsReportService.php @@ -0,0 +1,80 @@ +url = config('ProvinceInfo.center_ip'); + $this->channelName = 'send_supervisor_check_stats_report'; + $this->provinceId = config('ProvinceInfo.id'); + $this->provinceName = config('ProvinceInfo.name'); + } + + /** + * @throws ConnectionException + * @throws RequestException + */ + public function execute(): void + { + try + { + $data = $this->prepare(); + Http::post($this->url, $data)->throw(); + Log::channel($this->channelName)->info(SendSupervisorCheckStatsReportService::class, [$this->provinceName, array_sum($data), 'successful']); + } + catch (Exception $e) + { + Log::channel($this->channelName)->error(SendSupervisorCheckStatsReportService::class, [$e->getMessage()]); + throw $e; + } + } + + private function prepare(): array + { + $query = " + SELECT + {$this->provinceId} AS province_id, + '{$this->provinceName}' AS province_name, + od.date, + COUNT(*) AS reviews, + COUNT(CASE WHEN is_good = 1 THEN 1 END) AS good, + COUNT(CASE WHEN is_good = 0 THEN 1 END) AS bad, + COALESCE(cdr_data.calls, 0) AS calls + FROM ( + SELECT date, is_good + FROM operator_dialogues + WHERE supervisor_id IS NOT NULL + AND create_at > NOW() - INTERVAL 3 DAY + ) AS od + LEFT JOIN ( + SELECT + DATE(calldate) AS d, + COUNT(CASE + WHEN dcontext = 'from-internal' + AND disposition = 'ANSWERED' + AND dst > 100 AND dst < 105 + THEN 1 END) AS calls + FROM asteriskcdrdb.cdr + WHERE calldate > NOW() - INTERVAL 3 DAY + GROUP BY d + ) AS cdr_data + ON od.date = cdr_data.d + GROUP BY od.date, cdr_data.calls + ORDER BY od.date DESC"; + + return DB::select($query); + } +} diff --git a/app/Services/Dashboard/Province/OperatorDialogues/DataTableService.php b/app/Services/Dashboard/Province/OperatorDialogues/DataTableService.php index 0a0fc65..4354160 100644 --- a/app/Services/Dashboard/Province/OperatorDialogues/DataTableService.php +++ b/app/Services/Dashboard/Province/OperatorDialogues/DataTableService.php @@ -12,12 +12,11 @@ class DataTableService public function index(Request $request) { $query = DB::table('asteriskcdrdb.cdr') - ->leftJoin('crm_db.voice_experts', 'asteriskcdrdb.cdr.uniqueid', '=', 'crm_db.operator_dialogues.cdr_unique_id') + ->leftJoin('crm_db.operator_dialogues', 'asteriskcdrdb.cdr.uniqueid', '=', 'crm_db.operator_dialogues.cdr_unique_id') ->where('dst', '<>', '') ->where('lastapp', '=', 'Dial') ->where('duration', '>', 0) - ->where('recordingfile', '<>', '') - ->select('*'); + ->where('recordingfile', '<>', ''); return DataTableFacade::run( $query, diff --git a/app/Services/Dashboard/Province/ReportService.php b/app/Services/Dashboard/Province/ReportService.php index 18bef68..f3952d6 100644 --- a/app/Services/Dashboard/Province/ReportService.php +++ b/app/Services/Dashboard/Province/ReportService.php @@ -13,18 +13,18 @@ class ReportService $query = DB::table('asteriskcdrdb.cdr') ->selectRaw(" DATE(calldate) AS d, - COUNT(CASE WHEN (recordingfile = '' OR recordingfile LIKE 'q-%') THEN 1 END) AS c_all, - COUNT(CASE WHEN lastdata = 'IAX2/serverpeer/100' THEN 1 END) AS c_teh4, - COUNT(CASE WHEN lastdata = 'IAX2/242serverpeer/200' THEN 1 END) AS c_teh5, - COUNT(CASE WHEN dst = '500' THEN 1 END) AS c_os4, - COUNT(CASE WHEN dst = '600' THEN 1 END) AS c_os5, - COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 THEN 1 END) AS c_ok, - COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'NO ANSWER' AND dst BETWEEN 101 AND 104 AND duration > 14 THEN 1 END) AS c_nok, - COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 AND billsec > 9 THEN 1 END) AS c_b10, - COUNT(CASE WHEN lastapp = 'Busy' THEN 1 END) AS c_dnd, - COUNT(CASE WHEN dst BETWEEN 502 AND 599 THEN 1 END) AS c_trans, - COUNT(CASE WHEN disposition <> 'BUSY' AND dst BETWEEN 101 AND 105 THEN 1 END) AS ch_all, - AVG(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' THEN billsec END) AS c_avg + COUNT(CASE WHEN (recordingfile = '' OR recordingfile LIKE 'q-%') THEN 1 END) AS total, + COUNT(CASE WHEN lastdata = 'IAX2/serverpeer/100' THEN 1 END) AS teh4, + COUNT(CASE WHEN lastdata = 'IAX2/242serverpeer/200' THEN 1 END) AS teh5, + COUNT(CASE WHEN dst = '500' THEN 1 END) AS os4, + COUNT(CASE WHEN dst = '600' THEN 1 END) AS os5, + COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 THEN 1 END) AS ok, + COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'NO ANSWER' AND dst BETWEEN 101 AND 104 AND duration > 14 THEN 1 END) AS nok, + COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 AND billsec > 9 THEN 1 END) AS b10, + COUNT(CASE WHEN lastapp = 'Busy' THEN 1 END) AS dnd, + COUNT(CASE WHEN dst BETWEEN 502 AND 599 THEN 1 END) AS trans, + COUNT(CASE WHEN disposition <> 'BUSY' AND dst BETWEEN 101 AND 105 THEN 1 END) AS all, + AVG(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' THEN billsec END) AS avg "); // ->whereBetween('calldate', [$from, $to]) // use Carbon or date strings // ->groupBy(DB::raw('DATE(calldate)')) @@ -44,8 +44,8 @@ class ReportService { $query = DB::table('people_messages') ->selectRaw(' - COUNT(CASE WHEN is_listen = 1 THEN 1 END) AS c_l, - COUNT(CASE WHEN is_listen = 0 THEN 1 END) AS c_nl + COUNT(CASE WHEN is_listen = 1 THEN 1 END) AS l, + COUNT(CASE WHEN is_listen = 0 THEN 1 END) AS nl '); // ->whereBetween('date', [$date_from, $date_to]) // ->first(); @@ -85,21 +85,20 @@ class ReportService { $query = DB::table('asteriskcdrdb.cdr') ->selectRaw(" - SELECT * - (ch_all - (c_ok + c_nok)) AS c_fail + (all - (ok + nok)) AS fail FROM ( SELECT DATE(calldate) AS d, dst, - COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 THEN 1 END) AS c_ok, - COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'NO ANSWER' AND dst BETWEEN 101 AND 104 AND duration > 14 THEN 1 END) AS c_nok, - COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 AND billsec > 9 THEN 1 END) AS c_b10, - COUNT(CASE WHEN lastapp = 'Busy' THEN 1 END) AS c_dnd, - COUNT(CASE WHEN dst BETWEEN 502 AND 599 THEN 1 END) AS c_trans, - COUNT(CASE WHEN disposition <> 'BUSY' AND dst BETWEEN 101 AND 105 THEN 1 END) AS ch_all + COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 THEN 1 END) AS ok, + COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'NO ANSWER' AND dst BETWEEN 101 AND 104 AND duration > 14 THEN 1 END) AS nok, + COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 AND billsec > 9 THEN 1 END) AS b10, + COUNT(CASE WHEN lastapp = 'Busy' THEN 1 END) AS dnd, + COUNT(CASE WHEN dst BETWEEN 502 AND 599 THEN 1 END) AS trans, + COUNT(CASE WHEN disposition <> 'BUSY' AND dst BETWEEN 101 AND 105 THEN 1 END) AS all FROM asteriskcdrdb.cdr - WHERE dst BETWEEN 101 AND 105 AND calldate BETWEEN ? AND ? + WHERE dst BETWEEN 101 AND 105 GROUP BY d, dst ORDER BY d, dst ); @@ -127,24 +126,22 @@ class ReportService { $query = DB::table('asteriskcdrdb.cdr') ->selectRaw(" - SELECT * - (ch_all - (c_ok + c_nok)) AS c_fail + (all - (ok + nok)) AS fail FROM ( SELECT DATE(calldate) AS d, dst, - COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 THEN 1 END) AS c_ok, - COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'NO ANSWER' AND dst BETWEEN 101 AND 104 AND duration > 14 THEN 1 END) AS c_nok, - COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 AND billsec > 9 THEN 1 END) AS c_b10, - COUNT(CASE WHEN lastapp = 'Busy' THEN 1 END) AS c_dnd, - COUNT(CASE WHEN dst BETWEEN 502 AND 599 THEN 1 END) AS c_trans, - COUNT(CASE WHEN disposition <> 'BUSY' AND dst BETWEEN 101 AND 105 THEN 1 END) AS ch_all + COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 THEN 1 END) AS ok, + COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'NO ANSWER' AND dst BETWEEN 101 AND 104 AND duration > 14 THEN 1 END) AS nok, + COUNT(CASE WHEN dcontext = 'from-internal' AND disposition = 'ANSWERED' AND dst BETWEEN 101 AND 104 AND billsec > 9 THEN 1 END) AS b10, + COUNT(CASE WHEN lastapp = 'Busy' THEN 1 END) AS dnd, + COUNT(CASE WHEN dst BETWEEN 502 AND 599 THEN 1 END) AS trans, + COUNT(CASE WHEN disposition <> 'BUSY' AND dst BETWEEN 101 AND 105 THEN 1 END) AS all FROM asteriskcdrdb.cdr - WHERE dst BETWEEN 101 AND 105 AND calldate BETWEEN ? AND ? - GROUP dst - ORDER dst - ); + WHERE dst BETWEEN 101 AND 105 + GROUP BY dst + ORDER BY dst); "); return DataTableFacade::run( diff --git a/bootstrap/providers.php b/bootstrap/providers.php index dbaa61a..5d11af9 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -5,4 +5,5 @@ return [ App\Providers\DataTableServiceProvider::class, App\Providers\FileServiceProvider::class, App\Providers\TelescopeServiceProvider::class, + Maatwebsite\Excel\ExcelServiceProvider::class, ]; diff --git a/composer.json b/composer.json index 046b61e..93db14c 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "laravel/sanctum": "^4.0", "laravel/telescope": "^5.7", "laravel/tinker": "^2.10.1", + "maatwebsite/excel": "^3.1", "spatie/laravel-permission": "^6.17" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 6eff47c..74715b5 100644 --- a/composer.lock +++ b/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": "8eb5ac276d904be6e4f6bd9ca7aa7b2f", + "content-hash": "8238c006d65780b3b7c4e5059ede9197", "packages": [ { "name": "brick/math", @@ -135,6 +135,166 @@ ], "time": "2024-02-09T16:56:22+00:00" }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.3", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-09-19T14:15:21+00:00" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.3", @@ -565,6 +725,67 @@ ], "time": "2025-03-06T22:45:56+00:00" }, + { + "name": "ezyang/htmlpurifier", + "version": "v4.18.0", + "source": { + "type": "git", + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "cb56001e54359df7ae76dc522d08845dc741621b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/cb56001e54359df7ae76dc522d08845dc741621b", + "reference": "cb56001e54359df7ae76dc522d08845dc741621b", + "shasum": "" + }, + "require": { + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-tidy": "Used for pretty-printing HTML" + }, + "type": "library", + "autoload": { + "files": [ + "library/HTMLPurifier.composer.php" + ], + "psr-0": { + "HTMLPurifier": "library/" + }, + "exclude-from-classmap": [ + "/library/HTMLPurifier/Language/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Edward Z. Yang", + "email": "admin@htmlpurifier.org", + "homepage": "http://ezyang.com" + } + ], + "description": "Standards compliant HTML filter written in PHP", + "homepage": "http://htmlpurifier.org/", + "keywords": [ + "html" + ], + "support": { + "issues": "https://github.com/ezyang/htmlpurifier/issues", + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.18.0" + }, + "time": "2024-11-01T03:51:45+00:00" + }, { "name": "fruitcake/php-cors", "version": "v1.3.0", @@ -2357,6 +2578,272 @@ ], "time": "2025-04-12T22:26:52+00:00" }, + { + "name": "maatwebsite/excel", + "version": "3.1.66", + "source": { + "type": "git", + "url": "https://github.com/SpartnerNL/Laravel-Excel.git", + "reference": "3b29c2426a46674f444890c45f742452a396aae8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/3b29c2426a46674f444890c45f742452a396aae8", + "reference": "3b29c2426a46674f444890c45f742452a396aae8", + "shasum": "" + }, + "require": { + "composer/semver": "^3.3", + "ext-json": "*", + "illuminate/support": "5.8.*||^6.0||^7.0||^8.0||^9.0||^10.0||^11.0||^12.0", + "php": "^7.0||^8.0", + "phpoffice/phpspreadsheet": "^1.29.12", + "psr/simple-cache": "^1.0||^2.0||^3.0" + }, + "require-dev": { + "laravel/scout": "^7.0||^8.0||^9.0||^10.0", + "orchestra/testbench": "^6.0||^7.0||^8.0||^9.0||^10.0", + "predis/predis": "^1.1" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Excel": "Maatwebsite\\Excel\\Facades\\Excel" + }, + "providers": [ + "Maatwebsite\\Excel\\ExcelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Maatwebsite\\Excel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Patrick Brouwers", + "email": "patrick@spartner.nl" + } + ], + "description": "Supercharged Excel exports and imports in Laravel", + "keywords": [ + "PHPExcel", + "batch", + "csv", + "excel", + "export", + "import", + "laravel", + "php", + "phpspreadsheet" + ], + "support": { + "issues": "https://github.com/SpartnerNL/Laravel-Excel/issues", + "source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.66" + }, + "funding": [ + { + "url": "https://laravel-excel.com/commercial-support", + "type": "custom" + }, + { + "url": "https://github.com/patrickbrouwers", + "type": "github" + } + ], + "time": "2025-08-07T08:31:22+00:00" + }, + { + "name": "maennchen/zipstream-php", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/maennchen/ZipStream-PHP.git", + "reference": "9712d8fa4cdf9240380b01eb4be55ad8dcf71416" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/9712d8fa4cdf9240380b01eb4be55ad8dcf71416", + "reference": "9712d8fa4cdf9240380b01eb4be55ad8dcf71416", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-zlib": "*", + "php-64bit": "^8.3" + }, + "require-dev": { + "brianium/paratest": "^7.7", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.16", + "guzzlehttp/guzzle": "^7.5", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.5", + "phpunit/phpunit": "^12.0", + "vimeo/psalm": "^6.0" + }, + "suggest": { + "guzzlehttp/psr7": "^2.4", + "psr/http-message": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZipStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paul Duncan", + "email": "pabs@pablotron.org" + }, + { + "name": "Jonatan Männchen", + "email": "jonatan@maennchen.ch" + }, + { + "name": "Jesse Donat", + "email": "donatj@gmail.com" + }, + { + "name": "András Kolesár", + "email": "kolesar@kolesar.hu" + } + ], + "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", + "keywords": [ + "stream", + "zip" + ], + "support": { + "issues": "https://github.com/maennchen/ZipStream-PHP/issues", + "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/maennchen", + "type": "github" + } + ], + "time": "2025-07-17T11:15:13+00:00" + }, + { + "name": "markbaker/complex", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPComplex/issues", + "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2" + }, + "time": "2022-12-06T16:21:08+00:00" + }, + { + "name": "markbaker/matrix", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPMatrix.git", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "^4.0", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "sebastian/phpcpd": "^4.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Matrix\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@demon-angel.eu" + } + ], + "description": "PHP Class for working with matrices", + "homepage": "https://github.com/MarkBaker/PHPMatrix", + "keywords": [ + "mathematics", + "matrix", + "vector" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPMatrix/issues", + "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1" + }, + "time": "2022-12-02T22:17:43+00:00" + }, { "name": "monolog/monolog", "version": "3.9.0", @@ -2859,6 +3346,112 @@ ], "time": "2024-11-21T10:39:51+00:00" }, + { + "name": "phpoffice/phpspreadsheet", + "version": "1.30.0", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "2f39286e0136673778b7a142b3f0d141e43d1714" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/2f39286e0136673778b7a142b3f0d141e43d1714", + "reference": "2f39286e0136673778b7a142b3f0d141e43d1714", + "shasum": "" + }, + "require": { + "composer/pcre": "^1||^2||^3", + "ext-ctype": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "ext-zip": "*", + "ext-zlib": "*", + "ezyang/htmlpurifier": "^4.15", + "maennchen/zipstream-php": "^2.1 || ^3.0", + "markbaker/complex": "^3.0", + "markbaker/matrix": "^3.0", + "php": "^7.4 || ^8.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-main", + "dompdf/dompdf": "^1.0 || ^2.0 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.2", + "mitoteam/jpgraph": "^10.3", + "mpdf/mpdf": "^8.1.1", + "phpcompatibility/php-compatibility": "^9.3", + "phpstan/phpstan": "^1.1", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^8.5 || ^9.0", + "squizlabs/php_codesniffer": "^3.7", + "tecnickcom/tcpdf": "^6.5" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "ext-intl": "PHP Internationalization Functions", + "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "https://blog.maartenballiauw.be" + }, + { + "name": "Mark Baker", + "homepage": "https://markbakeruk.net" + }, + { + "name": "Franck Lefevre", + "homepage": "https://rootslabs.net" + }, + { + "name": "Erik Tilt" + }, + { + "name": "Adrien Crivelli" + } + ], + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "keywords": [ + "OpenXML", + "excel", + "gnumeric", + "ods", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "support": { + "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.30.0" + }, + "time": "2025-08-10T06:28:02+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.3", diff --git a/config/excel.php b/config/excel.php new file mode 100644 index 0000000..c1fd34a --- /dev/null +++ b/config/excel.php @@ -0,0 +1,380 @@ + [ + + /* + |-------------------------------------------------------------------------- + | Chunk size + |-------------------------------------------------------------------------- + | + | When using FromQuery, the query is automatically chunked. + | Here you can specify how big the chunk should be. + | + */ + 'chunk_size' => 1000, + + /* + |-------------------------------------------------------------------------- + | Pre-calculate formulas during export + |-------------------------------------------------------------------------- + */ + 'pre_calculate_formulas' => false, + + /* + |-------------------------------------------------------------------------- + | Enable strict null comparison + |-------------------------------------------------------------------------- + | + | When enabling strict null comparison empty cells ('') will + | be added to the sheet. + */ + 'strict_null_comparison' => false, + + /* + |-------------------------------------------------------------------------- + | CSV Settings + |-------------------------------------------------------------------------- + | + | Configure e.g. delimiter, enclosure and line ending for CSV exports. + | + */ + 'csv' => [ + 'delimiter' => ',', + 'enclosure' => '"', + 'line_ending' => PHP_EOL, + 'use_bom' => false, + 'include_separator_line' => false, + 'excel_compatibility' => false, + 'output_encoding' => '', + 'test_auto_detect' => true, + ], + + /* + |-------------------------------------------------------------------------- + | Worksheet properties + |-------------------------------------------------------------------------- + | + | Configure e.g. default title, creator, subject,... + | + */ + 'properties' => [ + 'creator' => '', + 'lastModifiedBy' => '', + 'title' => '', + 'description' => '', + 'subject' => '', + 'keywords' => '', + 'category' => '', + 'manager' => '', + 'company' => '', + ], + ], + + 'imports' => [ + + /* + |-------------------------------------------------------------------------- + | Read Only + |-------------------------------------------------------------------------- + | + | When dealing with imports, you might only be interested in the + | data that the sheet exists. By default we ignore all styles, + | however if you want to do some logic based on style data + | you can enable it by setting read_only to false. + | + */ + 'read_only' => true, + + /* + |-------------------------------------------------------------------------- + | Ignore Empty + |-------------------------------------------------------------------------- + | + | When dealing with imports, you might be interested in ignoring + | rows that have null values or empty strings. By default rows + | containing empty strings or empty values are not ignored but can be + | ignored by enabling the setting ignore_empty to true. + | + */ + 'ignore_empty' => false, + + /* + |-------------------------------------------------------------------------- + | Heading Row Formatter + |-------------------------------------------------------------------------- + | + | Configure the heading row formatter. + | Available options: none|slug|custom + | + */ + 'heading_row' => [ + 'formatter' => 'slug', + ], + + /* + |-------------------------------------------------------------------------- + | CSV Settings + |-------------------------------------------------------------------------- + | + | Configure e.g. delimiter, enclosure and line ending for CSV imports. + | + */ + 'csv' => [ + 'delimiter' => null, + 'enclosure' => '"', + 'escape_character' => '\\', + 'contiguous' => false, + 'input_encoding' => Csv::GUESS_ENCODING, + ], + + /* + |-------------------------------------------------------------------------- + | Worksheet properties + |-------------------------------------------------------------------------- + | + | Configure e.g. default title, creator, subject,... + | + */ + 'properties' => [ + 'creator' => '', + 'lastModifiedBy' => '', + 'title' => '', + 'description' => '', + 'subject' => '', + 'keywords' => '', + 'category' => '', + 'manager' => '', + 'company' => '', + ], + + /* + |-------------------------------------------------------------------------- + | Cell Middleware + |-------------------------------------------------------------------------- + | + | Configure middleware that is executed on getting a cell value + | + */ + 'cells' => [ + 'middleware' => [ + //\Maatwebsite\Excel\Middleware\TrimCellValue::class, + //\Maatwebsite\Excel\Middleware\ConvertEmptyCellValuesToNull::class, + ], + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Extension detector + |-------------------------------------------------------------------------- + | + | Configure here which writer/reader type should be used when the package + | needs to guess the correct type based on the extension alone. + | + */ + 'extension_detector' => [ + 'xlsx' => Excel::XLSX, + 'xlsm' => Excel::XLSX, + 'xltx' => Excel::XLSX, + 'xltm' => Excel::XLSX, + 'xls' => Excel::XLS, + 'xlt' => Excel::XLS, + 'ods' => Excel::ODS, + 'ots' => Excel::ODS, + 'slk' => Excel::SLK, + 'xml' => Excel::XML, + 'gnumeric' => Excel::GNUMERIC, + 'htm' => Excel::HTML, + 'html' => Excel::HTML, + 'csv' => Excel::CSV, + 'tsv' => Excel::TSV, + + /* + |-------------------------------------------------------------------------- + | PDF Extension + |-------------------------------------------------------------------------- + | + | Configure here which Pdf driver should be used by default. + | Available options: Excel::MPDF | Excel::TCPDF | Excel::DOMPDF + | + */ + 'pdf' => Excel::DOMPDF, + ], + + /* + |-------------------------------------------------------------------------- + | Value Binder + |-------------------------------------------------------------------------- + | + | PhpSpreadsheet offers a way to hook into the process of a value being + | written to a cell. In there some assumptions are made on how the + | value should be formatted. If you want to change those defaults, + | you can implement your own default value binder. + | + | Possible value binders: + | + | [x] Maatwebsite\Excel\DefaultValueBinder::class + | [x] PhpOffice\PhpSpreadsheet\Cell\StringValueBinder::class + | [x] PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder::class + | + */ + 'value_binder' => [ + 'default' => Maatwebsite\Excel\DefaultValueBinder::class, + ], + + 'cache' => [ + /* + |-------------------------------------------------------------------------- + | Default cell caching driver + |-------------------------------------------------------------------------- + | + | By default PhpSpreadsheet keeps all cell values in memory, however when + | dealing with large files, this might result into memory issues. If you + | want to mitigate that, you can configure a cell caching driver here. + | When using the illuminate driver, it will store each value in the + | cache store. This can slow down the process, because it needs to + | store each value. You can use the "batch" store if you want to + | only persist to the store when the memory limit is reached. + | + | Drivers: memory|illuminate|batch + | + */ + 'driver' => 'memory', + + /* + |-------------------------------------------------------------------------- + | Batch memory caching + |-------------------------------------------------------------------------- + | + | When dealing with the "batch" caching driver, it will only + | persist to the store when the memory limit is reached. + | Here you can tweak the memory limit to your liking. + | + */ + 'batch' => [ + 'memory_limit' => 60000, + ], + + /* + |-------------------------------------------------------------------------- + | Illuminate cache + |-------------------------------------------------------------------------- + | + | When using the "illuminate" caching driver, it will automatically use + | your default cache store. However if you prefer to have the cell + | cache on a separate store, you can configure the store name here. + | You can use any store defined in your cache config. When leaving + | at "null" it will use the default store. + | + */ + 'illuminate' => [ + 'store' => null, + ], + + /* + |-------------------------------------------------------------------------- + | Cache Time-to-live (TTL) + |-------------------------------------------------------------------------- + | + | The TTL of items written to cache. If you want to keep the items cached + | indefinitely, set this to null. Otherwise, set a number of seconds, + | a \DateInterval, or a callable. + | + | Allowable types: callable|\DateInterval|int|null + | + */ + 'default_ttl' => 10800, + ], + + /* + |-------------------------------------------------------------------------- + | Transaction Handler + |-------------------------------------------------------------------------- + | + | By default the import is wrapped in a transaction. This is useful + | for when an import may fail and you want to retry it. With the + | transactions, the previous import gets rolled-back. + | + | You can disable the transaction handler by setting this to null. + | Or you can choose a custom made transaction handler here. + | + | Supported handlers: null|db + | + */ + 'transactions' => [ + 'handler' => 'db', + 'db' => [ + 'connection' => null, + ], + ], + + 'temporary_files' => [ + + /* + |-------------------------------------------------------------------------- + | Local Temporary Path + |-------------------------------------------------------------------------- + | + | When exporting and importing files, we use a temporary file, before + | storing reading or downloading. Here you can customize that path. + | permissions is an array with the permission flags for the directory (dir) + | and the create file (file). + | + */ + 'local_path' => storage_path('framework/cache/laravel-excel'), + + /* + |-------------------------------------------------------------------------- + | Local Temporary Path Permissions + |-------------------------------------------------------------------------- + | + | Permissions is an array with the permission flags for the directory (dir) + | and the create file (file). + | If omitted the default permissions of the filesystem will be used. + | + */ + 'local_permissions' => [ + // 'dir' => 0755, + // 'file' => 0644, + ], + + /* + |-------------------------------------------------------------------------- + | Remote Temporary Disk + |-------------------------------------------------------------------------- + | + | When dealing with a multi server setup with queues in which you + | cannot rely on having a shared local temporary path, you might + | want to store the temporary file on a shared disk. During the + | queue executing, we'll retrieve the temporary file from that + | location instead. When left to null, it will always use + | the local path. This setting only has effect when using + | in conjunction with queued imports and exports. + | + */ + 'remote_disk' => null, + 'remote_prefix' => null, + + /* + |-------------------------------------------------------------------------- + | Force Resync + |-------------------------------------------------------------------------- + | + | When dealing with a multi server setup as above, it's possible + | for the clean up that occurs after entire queue has been run to only + | cleanup the server that the last AfterImportJob runs on. The rest of the server + | would still have the local temporary file stored on it. In this case your + | local storage limits can be exceeded and future imports won't be processed. + | To mitigate this you can set this config value to be true, so that after every + | queued chunk is processed the local temporary file is deleted on the server that + | processed it. + | + */ + 'force_resync_remote' => null, + ], +]; diff --git a/config/globalVariables.php b/config/globalVariables.php index 65c5e42..ec26ab5 100644 --- a/config/globalVariables.php +++ b/config/globalVariables.php @@ -4,4 +4,5 @@ return [ 'TRUSTED_IP' => explode(',', env("TRUSTED_IP", '127.0.0.1')), 'NOTIFICATION_SERVER_URL' => env('NOTIFICATION_SERVER_URL', '127.0.0.1'), 'LOGIN_HASH_VALUE' => env('LOGIN_HASH_VALUE'), + 'SETAD_IP' => env('SETAD_IP'), ]; diff --git a/config/logging.php b/config/logging.php index ca78f2e..ddd3970 100644 --- a/config/logging.php +++ b/config/logging.php @@ -150,6 +150,11 @@ return [ 'path' => storage_path('logs/send_system_message_stats_report.log'), 'level' => 'debug', ], - ], + 'send_supervisor_check_stats_report' => [ + 'driver' => 'single', + 'path' => storage_path('logs/send_supervisor_check_stats_report.log'), + 'level' => 'debug', + ], + ], ]; diff --git a/database/factories/ExpertPerformanceFactory.php b/database/factories/SupervisorPerformanceFactory.php similarity index 81% rename from database/factories/ExpertPerformanceFactory.php rename to database/factories/SupervisorPerformanceFactory.php index 2ee7b2e..c878543 100644 --- a/database/factories/ExpertPerformanceFactory.php +++ b/database/factories/SupervisorPerformanceFactory.php @@ -5,9 +5,9 @@ namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; /** - * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\ExpertPerformance> + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\SupervisorPerformance> */ -class ExpertPerformanceFactory extends Factory +class SupervisorPerformanceFactory extends Factory { /** * Define the model's default state. diff --git a/database/migrations/2025_07_23_061700_create_expert_performances_table.php b/database/migrations/2025_07_23_061700_create_expert_performances_table.php deleted file mode 100644 index 2a0b866..0000000 --- a/database/migrations/2025_07_23_061700_create_expert_performances_table.php +++ /dev/null @@ -1,27 +0,0 @@ -id(); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('expert_performances'); - } -}; diff --git a/database/migrations/2025_08_10_064355_create_supervisor_performances_table.php b/database/migrations/2025_08_10_064355_create_supervisor_performances_table.php new file mode 100644 index 0000000..0f6718d --- /dev/null +++ b/database/migrations/2025_08_10_064355_create_supervisor_performances_table.php @@ -0,0 +1,34 @@ +id(); + $table->date('date'); + $table->foreignId('province_id')->constrained('provinces'); + $table->string('province_name'); + $table->integer('calls'); + $table->integer('reviews'); + $table->integer('good'); + $table->integer('bad'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('supervisor_performances'); + } +}; diff --git a/database/seeders/ExpertPerformanceSeeder.php b/database/seeders/SupervisorPerformanceSeeder.php similarity index 82% rename from database/seeders/ExpertPerformanceSeeder.php rename to database/seeders/SupervisorPerformanceSeeder.php index ea2f8ea..1efcbbb 100644 --- a/database/seeders/ExpertPerformanceSeeder.php +++ b/database/seeders/SupervisorPerformanceSeeder.php @@ -5,7 +5,7 @@ namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; -class ExpertPerformanceSeeder extends Seeder +class SupervisorPerformanceSeeder extends Seeder { /** * Run the database seeds. diff --git a/public/file_example_WAV_1MG.wav b/public/file_example_WAV_1MG.wav new file mode 100644 index 0000000..3179e0e Binary files /dev/null and b/public/file_example_WAV_1MG.wav differ diff --git a/resources/views/Reports/OperatorDialogues/OperatorCartableReport.blade.php b/resources/views/Reports/OperatorDialogues/OperatorCartableReport.blade.php new file mode 100644 index 0000000..087f9fa --- /dev/null +++ b/resources/views/Reports/OperatorDialogues/OperatorCartableReport.blade.php @@ -0,0 +1,78 @@ + + + + + + + + گزارش مکالمات کارشناسان + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach ($data as $item) + + + + + + + + + @endforeach + +
+ تاریخ دریافت گزارش: {{ now()->format('Y/m/d H:i') }} +
+
+ گزارش کارتابل مکالمات کارشناسان +
کد + یکتا + تاریخ + شنیده شده + امتیاز کسب شده + توضیحات
{{ $item['id'] ?? '-' }}{{ $item['data'] ?? '-' }}{{ $item['is_listen'] ?? '-' }}{{ $item['is_good'] ?? '-' }}{{ $item['description'] ?? '-' }}
+ + + diff --git a/resources/views/Reports/OperatorDialogues/SupervisorCartableReport.blade.php b/resources/views/Reports/OperatorDialogues/SupervisorCartableReport.blade.php new file mode 100644 index 0000000..301b0f5 --- /dev/null +++ b/resources/views/Reports/OperatorDialogues/SupervisorCartableReport.blade.php @@ -0,0 +1,83 @@ + + + + + + + + گزارش مکالمات کارشناسان + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach ($data as $item) + + + + + + + + + + @endforeach + +
+ تاریخ دریافت گزارش: {{ now()->format('Y/m/d H:i') }} +
+
+ گزارش کارتابل مکالمات کارشناسان +
کد + یکتا + تاریخ + بازرس + شنیده شده + امتیاز کسب شده + توضیحات
{{ $item['id'] ?? '-' }}{{ $item['data'] ?? '-' }}{{ $item['supervisor_id'] ?? '-' }}{{ $item['is_listen'] ?? '-' }}{{ $item['is_good'] ?? '-' }}{{ $item['description'] ?? '-' }}
+ + + diff --git a/resources/views/Reports/PeopleMessages/OperatorCartableReport.blade.php b/resources/views/Reports/PeopleMessages/OperatorCartableReport.blade.php new file mode 100644 index 0000000..0ed31e6 --- /dev/null +++ b/resources/views/Reports/PeopleMessages/OperatorCartableReport.blade.php @@ -0,0 +1,94 @@ + + + + + + + + گزارش پیام های مردمی + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach ($data as $item) + + + + + + + + + + + + @endforeach + +
+ تاریخ دریافت گزارش: {{ now()->format('Y/m/d H:i') }} +
+
+ گزارش کارتابل ارزیابی پیام های مردمی +
کد + یکتاشماره تماس گیرنده + + تاریخ + زمان بررسی + تاریخ مشاهده + شنیده شده + اقدام انجام شده + توضیحات + کد سامانه سوانح
{{ $item['id'] ?? '-' }}{{ $item['caller_phone_number'] ?? '-' }}{{ $item['data'] ?? '-' }}{{ $item['review_duration'] ?? '-' }}{{ $item['listen_at'] ?? '-' }}{{ $item['action_name'] ?? '-' }}{{ $item['description'] ?? '-' }}{{ $item['savaneh_id'] ?? '-' }}
+ + + diff --git a/resources/views/Reports/PeopleMessages/SupervisorCartableReport.blade.php b/resources/views/Reports/PeopleMessages/SupervisorCartableReport.blade.php new file mode 100644 index 0000000..b869e59 --- /dev/null +++ b/resources/views/Reports/PeopleMessages/SupervisorCartableReport.blade.php @@ -0,0 +1,94 @@ + + + + + + + + گزارش پیام های مردمی + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach ($data as $item) + + + + + + + + + + + + @endforeach + +
+ تاریخ دریافت گزارش: {{ now()->format('Y/m/d H:i') }} +
+
+ گزارش کارتابل ارزیابی پیام های مردمی +
کد + یکتاشماره تماس گیرنده + + تاریخ + زمان بررسی + تاریخ مشاهده + شنیده شده + اقدام انجام شده + توضیحات + کد سامانه سوانح
{{ $item['id'] ?? '-' }}{{ $item['caller_phone_number'] ?? '-' }}{{ $item['data'] ?? '-' }}{{ $item['review_duration'] ?? '-' }}{{ $item['listen_at'] ?? '-' }}{{ $item['action_name'] ?? '-' }}{{ $item['description'] ?? '-' }}{{ $item['savaneh_id'] ?? '-' }}
+ + + diff --git a/resources/views/Reports/SystemMessage/OperatorCartableReport.blade.php b/resources/views/Reports/SystemMessage/OperatorCartableReport.blade.php new file mode 100644 index 0000000..01089bf --- /dev/null +++ b/resources/views/Reports/SystemMessage/OperatorCartableReport.blade.php @@ -0,0 +1,71 @@ + + + + + + + + گزارش پیام های سیستمی + + + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach ($data as $item) + + + + + + + + @endforeach + +
+ تاریخ دریافت گزارش: {{ now()->format('Y/m/d H:i') }} +
+
+ گزارش کارتابل ارزیابی پیام های سیستمی +
کد + یکتاتاریخ + + ایدی کاربر + اسم کاربر
{{ $item['id'] ?? '-' }}{{ $item['data'] ?? '-' }}{{ $item['type_id'] ?? '-' }}{{ $item['type_name'] ?? '-' }}
+ + + diff --git a/resources/views/Reports/SystemMessage/SupervisorCartableReport.blade.php b/resources/views/Reports/SystemMessage/SupervisorCartableReport.blade.php new file mode 100644 index 0000000..9cc3030 --- /dev/null +++ b/resources/views/Reports/SystemMessage/SupervisorCartableReport.blade.php @@ -0,0 +1,87 @@ + + + + + + + + گزارش پیام های سیستمی + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach ($data as $item) + + + + + + + + + + + @endforeach + +
+ تاریخ دریافت گزارش: {{ now()->format('Y/m/d H:i') }} +
+
+ گزارش کارتابل ارزیابی پیام های سیستمی +
کد + یکتاتاریخ + + کیفیت پیام + ساختار پیام + توضیحات + ایدی کاربر + اسم کاربر
{{ $item['id'] ?? '-' }}{{ $item['data'] ?? '-' }}{{ $item['message_quality'] ?? '-' }}{{ $item['format_quality'] ?? '-' }}{{ $item['description'] ?? '-' }}{{ $item['type_id'] ?? '-' }}{{ $item['type_name'] ?? '-' }}
+ + + diff --git a/routes/console.php b/routes/console.php index 8243f79..31b8b56 100644 --- a/routes/console.php +++ b/routes/console.php @@ -3,11 +3,8 @@ use Illuminate\Foundation\Inspiring; use Illuminate\Support\Facades\Artisan; -Artisan::command('inspire', function () { - $this->comment(Inspiring::quote()); -})->purpose('Display an inspiring quote'); - Schedule::command('report:send-call-stats')->everyTwoMinutes(); Schedule::command('report:send-system-message-stats')->everyThreeMinutes(); Schedule::command('report:send-keypress-stats')->everyFourMinutes(); Schedule::command('report:send-people-message-stats')->everyFiveMinutes(); +Schedule::command('report:send-supervisor-check-stats')->everyFiveMinutes(); diff --git a/routes/web.php b/routes/web.php index 73a7790..7f1a5c6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -13,7 +13,7 @@ use App\Http\Controllers\HeadquartersDashboard\CumulativeCentersStatsController; use App\Http\Controllers\HeadquartersDashboard\CumulativeKeypressStatsController; use App\Http\Controllers\HeadquartersDashboard\CumulativeMessageRatingStatsController; use App\Http\Controllers\HeadquartersDashboard\CumulativeVoiceRatingStatsController; -use App\Http\Controllers\ProvinceDashboard\CheckSetadController; +use App\Http\Controllers\ProvinceDashboard\VerifyAuthenticationController; use App\Http\Middleware\SuperAdminCheck; use Illuminate\Support\Facades\Route; @@ -203,19 +203,20 @@ Route::prefix('server')->group(function () { Route::get('/{peopleMessage}', 'show')->name('show'); }); }); - Route::middleware(['auth', 'permission:setat_ip']) + + Route::middleware(['auth', 'role:admin']) ->prefix('login_to_province') ->name('loginToProvince.') ->controller(LoginToProvinceController::class) ->group(function () { - Route::post('/', 'loginToProvince')->name('loginToProvince'); - }); - Route::middleware('auth') - ->prefix('check_setad') - ->name('checkSetad.') - ->controller(CheckSetadController::class) - ->group(function () { - Route::get('/', 'verifyToken')->name('verifyToken'); + Route::post('/', 'authenticate')->name('authenticate'); }); + Route::middleware(['auth', 'setadIp']) + ->prefix('verify_authentication') + ->name('verifyAuthentication.') + ->controller(VerifyAuthenticationController::class) + ->group(function () { + Route::get('/', 'login')->name('login'); + }); });