File manager - Edit - /var/www/html/portal/app/Http/Controllers/Accounts/Cronogramas/CronogramasController.php
Back
<?php namespace App\Http\Controllers\Accounts\Cronogramas; use App\Enums\Accounts\Cronogramas\CronogramaActivityStatus; use App\Enums\Accounts\Cronogramas\CronogramaProjectStatus; use App\Exports\CronogramasAtividadesExport; use App\Http\Controllers\Controller; use App\Http\Requests\Accounts\Cronogramas\CronogramasRequest; use App\Http\Resources\Accounts\Cronogramas\CronogramasResource; use App\Http\Services\Accounts\Cronogramas\CronogramasService; use App\Models\Accounts\Cronogramas\Activity; use App\Models\Accounts\Cronogramas\Attachment; use App\Models\Accounts\Cronogramas\Comment; use App\Models\Accounts\Cronogramas\Project; use Barryvdh\DomPDF\Facade\Pdf; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\View\View; use Maatwebsite\Excel\Facades\Excel; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\StreamedResponse; /** * Orquestração do módulo Cronogramas (painel administrativo). */ class CronogramasController extends Controller { private string $permissao = 'GERENCIADOR_DE_CRONOGRAMAS'; public function __construct( private readonly CronogramasService $service, private readonly CronogramasResource $resource, ) {} public function dashboard(Request $request): View|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'visualizar'); if ($gate instanceof RedirectResponse) { return $gate; } $viewTab = in_array($request->get('tab', 'table'), ['table', 'archived'], true) ? $request->get('tab', 'table') : 'table'; $indicators = $this->resource->dashboardIndicators(Auth::user()); $projects = $this->service->paginateProjects($request, Auth::user(), $viewTab); $filterParams = $this->resource->dashboardListParams($request); $archivedCount = $this->service->countArchivedProjects(Auth::user()); $perm = Auth::user()->getPermissaoDetalhes($this->permissao); $archivedRows = $viewTab === 'archived' ? $this->resource->archivedProjectsToTableRows($projects->getCollection()) : []; return view('admin.cronogramas.dashboard', compact( 'indicators', 'projects', 'filterParams', 'viewTab', 'archivedCount', 'perm', 'archivedRows', )); } public function createProject(Request $request): View|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'adicionar'); if ($gate instanceof RedirectResponse) { return $gate; } $filterParams = $this->resource->dashboardListParams($request); $scopeOptions = $this->service->listProjectScopeOptions(); $selectedScopes = [ 'structures' => old('scope_structures', []), 'unidades' => old('scope_unidades', []), 'empresas' => old('scope_empresas', []), ]; return view('admin.cronogramas.create', compact('filterParams', 'scopeOptions', 'selectedScopes')); } public function storeProject(CronogramasRequest $request): RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'adicionar'); if ($gate instanceof RedirectResponse) { return $gate; } $project = $this->service->createProject(Auth::user(), $request->validated()); return redirect() ->route('admin.cronogramas.projetos.show', $project) ->with('success', __('Projeto criado com sucesso.')); } public function showProject(Request $request, Project $project): View|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'visualizar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $this->service->resolveOverdueStatusesForProject($project); $project->load('user'); $viewTab = in_array($request->get('tab', 'table'), ['table', 'gantt', 'kanban', 'timeline', 'archived'], true) ? $request->get('tab', 'table') : 'table'; $chartActivities = $this->service->loadActiveActivitiesForCharts($project); $viewData = $this->resource->activitiesViewPayload($chartActivities); $ganttData = $viewData['gantt']; $kanbanRows = $viewData['table_rows']; $activitiesPaginator = null; $archivedPaginator = null; $timelinePaginator = null; $allowTableReorder = true; $tableRows = $kanbanRows; $archivedRows = []; [$activitySort, $activityDir] = $this->resource->resolveActivitySort($request); $activityFilters = $this->resource->resolveActivityFilters($request); $filtersActive = $this->resource->activityFiltersActive($activityFilters); $filtersCount = $this->resource->activityFiltersCount($activityFilters); if ($viewTab === 'table') { $pageData = $this->service->paginateProjectActivities($project, $request); $activitiesPaginator = $pageData['paginator']; $tableRows = $this->resource->activitiesToTableRows($pageData['activities'], $pageData['index']); $allowTableReorder = $activitySort === 'manual' && ! $activitiesPaginator->hasPages() && ! $filtersActive; } elseif ($viewTab === 'archived') { $archivedPaginator = $this->service->paginateArchivedActivities($project, $request); $archivedRows = $this->resource->archivedActivitiesToTableRows($archivedPaginator->getCollection()); } elseif ($viewTab === 'timeline') { $timelinePaginator = $this->service->paginateTimelineActivities($project, $request); $tableRows = $this->resource->activitiesToTableRows( $timelinePaginator->getCollection(), $this->service->loadActivityIndex($project), ); } $responsibleOptions = $this->service->listResponsibleOptions(); $responsibles = $responsibleOptions['users']; $filterResponsibleOptions = $this->service->listProjectResponsibleOptions($project); $statusOptions = CronogramaActivityStatus::selectableCases(); $perm = Auth::user()->getPermissaoDetalhes($this->permissao); $readOnly = $project->isReadOnly(); $archivedCount = Activity::onlyTrashed()->where('project_id', $project->id)->count(); $projectStats = $this->resource->projectStats($project); $rootActivities = $this->service->listRootActivitiesForSelect($project); $allActivitiesForSelect = $this->service->listAllActivitiesForSelect($project); $filterParams = $this->resource->projectShowListParams($request); $perPageOptions = $this->resource->perPageOptions(); $currentPerPage = $this->resource->resolveActivitiesPerPage($request); $sortOptions = $this->resource->activitySortOptions(); $publicShareUrl = $this->resource->publicShareUrl($project); return view('admin.cronogramas.show', compact( 'project', 'tableRows', 'kanbanRows', 'ganttData', 'responsibles', 'responsibleOptions', 'filterResponsibleOptions', 'statusOptions', 'viewTab', 'perm', 'readOnly', 'filterParams', 'archivedCount', 'archivedRows', 'activitiesPaginator', 'archivedPaginator', 'timelinePaginator', 'projectStats', 'rootActivities', 'allActivitiesForSelect', 'allowTableReorder', 'perPageOptions', 'currentPerPage', 'sortOptions', 'activitySort', 'activityDir', 'activityFilters', 'filtersActive', 'filtersCount', 'publicShareUrl', )); } public function editProject(Request $request, Project $project): View|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $filterParams = $this->resource->projectShowListParams($request); $scopeOptions = $this->service->listProjectScopeOptions(); $selectedScopes = [ 'structures' => old('scope_structures', $this->service->getProjectScopeIds($project)['structures']), 'unidades' => old('scope_unidades', $this->service->getProjectScopeIds($project)['unidades']), 'empresas' => old('scope_empresas', $this->service->getProjectScopeIds($project)['empresas']), ]; return view('admin.cronogramas.edit', compact('project', 'filterParams', 'scopeOptions', 'selectedScopes')); } public function updateProject(CronogramasRequest $request, Project $project): RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $this->service->updateProject($project, Auth::user(), $request->validated()); return $this->redirectToProjectShow($project, $request, __('Projeto atualizado com sucesso.')); } public function destroyProject(Request $request, Project $project): JsonResponse|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'excluir'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $this->service->destroyProject($project, Auth::user()); $archivedCount = $this->service->countArchivedProjects(Auth::user()); if ($request->expectsJson()) { return response()->json([ 'ok' => true, 'deleted_id' => $project->id, 'archived_count' => $archivedCount, ]); } return $this->redirectToDashboard($request, __('Projeto excluído permanentemente.'), ['tab' => 'archived']); } public function projectsBulkDestroy(CronogramasRequest $request): JsonResponse|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'excluir'); if ($gate instanceof RedirectResponse) { return $gate; } $deletedIds = $this->service->destroyArchivedProjectsBulk( Auth::user(), $request->validated('project_ids'), ); $archivedCount = $this->service->countArchivedProjects(Auth::user()); if ($request->expectsJson()) { return response()->json([ 'ok' => true, 'deleted_ids' => $deletedIds, 'deleted_count' => count($deletedIds), 'archived_count' => $archivedCount, ]); } return $this->redirectToDashboard( $request, __(':count projeto(s) excluído(s) permanentemente.', ['count' => count($deletedIds)]), ['tab' => 'archived'], ); } public function archiveProject(Request $request, Project $project): RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $this->service->archiveProject($project, Auth::user()); return $this->redirectToDashboard($request, __('Projeto arquivado com sucesso.')); } public function unarchiveProject(Request $request, Project $project): RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $this->service->unarchiveProject($project, Auth::user()); if ($request->filled('tab') && $request->get('tab') === 'archived') { return $this->redirectToDashboard($request, __('Projeto desarquivado com sucesso.'), ['tab' => 'table']); } return $this->redirectToProjectShow($project, $request, __('Projeto desarquivado com sucesso.')); } public function closeProject(Request $request, Project $project): RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $this->service->closeProject($project, Auth::user()); return $this->redirectToProjectShow($project, $request, __('Projeto encerrado. Somente leitura.')); } public function activityStore(CronogramasRequest $request, Project $project): JsonResponse|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'adicionar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $activity = $this->service->createActivity($project, Auth::user(), $request->validated()); if ($request->expectsJson()) { return response()->json([ 'ok' => true, 'activity' => $this->resource->activityToPayload($activity), 'project_completion' => (float) $project->completion_percent, ]); } return $this->redirectToProjectShow($project, $request, __('Atividade criada com sucesso.'), ['tab' => 'table']); } public function activityDetails(Request $request, Project $project, string $activity): JsonResponse { $gate = $this->checkPermissao($this->permissao, 'visualizar'); if ($gate instanceof RedirectResponse) { return response()->json(['ok' => false, 'message' => __('Sem permissão.')], 403); } $this->service->assertProjectVisible($project, Auth::user()); $model = $this->service->findProjectActivity($project, $activity, withTrashed: true); $model = $this->service->loadActivityForDetail($model); $comments = $this->service->paginateActivityComments($model, $request); $history = $this->service->paginateActivityHistory($model, $request); return response()->json(array_merge( ['ok' => true], $this->resource->activityDetailPayload($model, $comments, $history), )); } public function activityUpdate(CronogramasRequest $request, Project $project, Activity $activity): JsonResponse|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); if ($activity->project_id !== $project->id) { abort(404); } $updated = $this->service->updateActivity($activity, Auth::user(), $request->validated()); if ($request->expectsJson()) { return response()->json([ 'ok' => true, 'activity' => $this->resource->activityToPayload($updated), 'project_completion' => (float) $project->completion_percent, ]); } return $this->redirectToProjectShow($project, $request, __('Atividade atualizada com sucesso.'), ['tab' => 'table']); } public function activityInline(CronogramasRequest $request, Project $project, Activity $activity): JsonResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return response()->json(['ok' => false, 'message' => __('Sem permissão.')], 403); } $this->service->assertProjectVisible($project, Auth::user()); if ($activity->project_id !== $project->id) { abort(404); } $updated = $this->service->inlineUpdateActivity($activity, Auth::user(), $request->validated()); // $project já tem o completion_percent atualizado pelo recalculateProjectCompletion // via updateActivity → não precisa de fresh() $project->refresh(); return response()->json([ 'ok' => true, 'activity' => [ 'id' => $updated->id, 'status' => $updated->status, 'status_label' => CronogramaActivityStatus::tryFrom($updated->status)?->label(), 'completion_percent' => (float) $updated->completion_percent, 'is_overdue' => $updated->isOverdue(), ], 'project_completion' => (float) $project->completion_percent, 'stats' => $this->resource->projectStats($project), ]); } public function activityDuplicate(Project $project, Activity $activity): JsonResponse { $gate = $this->checkPermissao($this->permissao, 'adicionar'); if ($gate instanceof RedirectResponse) { return response()->json(['ok' => false], 403); } $this->service->assertProjectVisible($project, Auth::user()); if ($activity->project_id !== $project->id) { abort(404); } $copy = $this->service->duplicateActivity($activity, Auth::user()); $project->refresh(); return response()->json([ 'ok' => true, 'activity' => $this->resource->activityToPayload($copy), 'project_completion' => (float) $project->completion_percent, ]); } public function activitiesData(Project $project): JsonResponse { $gate = $this->checkPermissao($this->permissao, 'visualizar'); if ($gate instanceof RedirectResponse) { return response()->json(['ok' => false], 403); } $this->service->assertProjectVisible($project, Auth::user()); $project = $this->service->loadProjectWithActivities($project); $viewData = $this->resource->activitiesViewPayload($project->activeActivities); return response()->json([ 'ok' => true, 'table_rows' => $viewData['table_rows'], 'gantt' => $viewData['gantt'], 'project_completion' => (float) $project->completion_percent, 'stats' => $this->resource->projectStats($project), ]); } public function activityArchive(Request $request, Project $project, string $activity): JsonResponse|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $model = $this->service->findProjectActivity($project, $activity); $archivedIds = $this->service->archiveActivity($model, Auth::user()); $project = $this->service->loadProjectWithActivities($project); $viewData = $this->resource->activitiesViewPayload($project->activeActivities); if ($request->expectsJson()) { return response()->json([ 'ok' => true, 'archived_ids' => $archivedIds, 'table_rows' => $viewData['table_rows'], 'gantt' => $viewData['gantt'], 'project_completion' => (float) $project->completion_percent, 'stats' => $this->resource->projectStats($project), 'archived_count' => Activity::onlyTrashed()->where('project_id', $project->id)->count(), ]); } return $this->redirectToProjectShow($project, $request, __('Atividade arquivada com sucesso.')); } public function activityRestore(Request $request, Project $project, string $activity): JsonResponse|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $model = $this->service->findProjectActivity($project, $activity, onlyTrashed: true); $restoredIds = $this->service->restoreActivity($model, Auth::user()); $project = $this->service->loadProjectWithActivities($project); $viewData = $this->resource->activitiesViewPayload($project->activeActivities); if ($request->expectsJson()) { return response()->json([ 'ok' => true, 'restored_ids' => $restoredIds, 'table_rows' => $viewData['table_rows'], 'gantt' => $viewData['gantt'], 'project_completion' => (float) $project->completion_percent, 'stats' => $this->resource->projectStats($project), 'archived_count' => Activity::onlyTrashed()->where('project_id', $project->id)->count(), ]); } return $this->redirectToProjectShow($project, $request, __('Atividade restaurada com sucesso.'), ['tab' => 'table']); } public function activityDestroy(Request $request, Project $project, string $activity): JsonResponse|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'excluir'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $model = $this->service->findProjectActivity($project, $activity, onlyTrashed: true); $deletedIds = $this->service->destroyActivity($model, Auth::user()); $project = $this->service->loadProjectWithActivities($project); $viewData = $this->resource->activitiesViewPayload($project->activeActivities); $archivedRows = $this->resource->archivedActivitiesToTableRows($this->service->listArchivedActivities($project)); if ($request->expectsJson()) { return response()->json([ 'ok' => true, 'deleted_ids' => $deletedIds, 'table_rows' => $viewData['table_rows'], 'gantt' => $viewData['gantt'], 'archived_rows' => $archivedRows, 'project_completion' => (float) $project->completion_percent, 'stats' => $this->resource->projectStats($project), 'archived_count' => count($archivedRows), ]); } return $this->redirectToProjectShow($project, $request, __('Atividade excluída permanentemente.'), ['tab' => 'archived']); } public function activitiesBulkDestroy(CronogramasRequest $request, Project $project): JsonResponse|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'excluir'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $deletedIds = $this->service->destroyArchivedActivitiesBulk( $project, Auth::user(), $request->validated('activity_ids'), ); $project = $this->service->loadProjectWithActivities($project); $viewData = $this->resource->activitiesViewPayload($project->activeActivities); $archivedCount = Activity::onlyTrashed()->where('project_id', $project->id)->count(); if ($request->expectsJson()) { return response()->json([ 'ok' => true, 'deleted_ids' => $deletedIds, 'deleted_count' => count($deletedIds), 'table_rows' => $viewData['table_rows'], 'gantt' => $viewData['gantt'], 'project_completion' => (float) $project->completion_percent, 'stats' => $this->resource->projectStats($project), 'archived_count' => $archivedCount, ]); } return $this->redirectToProjectShow( $project, $request, __(':count atividade(s) excluída(s) permanentemente.', ['count' => count($deletedIds)]), ['tab' => 'archived'], ); } public function activityReorder(CronogramasRequest $request, Project $project): JsonResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return response()->json(['ok' => false], 403); } $this->service->assertProjectVisible($project, Auth::user()); $this->service->reorderActivities($project, Auth::user(), $request->validated('order')); return response()->json(['ok' => true]); } public function commentStore(CronogramasRequest $request, Project $project, Activity $activity): JsonResponse { $gate = $this->checkPermissao($this->permissao, 'adicionar'); if ($gate instanceof RedirectResponse) { return response()->json(['ok' => false], 403); } $this->service->assertProjectVisible($project, Auth::user()); if ($activity->project_id !== $project->id) { abort(404); } $comment = $this->service->storeComment($activity, Auth::user(), $request->validated()); return response()->json([ 'ok' => true, 'comment' => [ 'id' => $comment->id, 'content' => $comment->content, 'author' => $comment->user?->firstName, 'author_id' => $comment->user_id, 'created_at' => $comment->created_at?->format('d/m/Y H:i'), ], 'comments_count' => $activity->comments()->whereNull('deleted_at')->count(), ]); } public function commentDestroy(Project $project, Activity $activity, Comment $comment): JsonResponse { $gate = $this->checkPermissao($this->permissao, 'excluir'); if ($gate instanceof RedirectResponse) { return response()->json(['ok' => false], 403); } $this->service->assertProjectVisible($project, Auth::user()); if ($activity->project_id !== $project->id || $comment->activity_id !== $activity->id) { abort(404); } $this->service->destroyComment($comment, Auth::user()); return response()->json([ 'ok' => true, 'comments_count' => $activity->comments()->whereNull('deleted_at')->count(), ]); } public function attachmentStore(CronogramasRequest $request, Project $project, Activity $activity): JsonResponse { $gate = $this->checkPermissao($this->permissao, 'adicionar'); if ($gate instanceof RedirectResponse) { return response()->json(['ok' => false], 403); } $this->service->assertProjectVisible($project, Auth::user()); if ($activity->project_id !== $project->id) { abort(404); } $files = $request->file('attachments', []) ?: []; $stored = $this->service->storeAttachments($activity, Auth::user(), $files); return response()->json([ 'ok' => true, 'attachments' => $stored->map(fn (Attachment $a) => [ 'id' => $a->id, 'name' => $a->original_name, 'size' => $this->resource->formatBytes((int) $a->file_size_bytes), 'uploaded_by' => Auth::user()->firstName, ])->values(), 'attachments_count' => $activity->attachments()->whereNull('deleted_at')->count(), ]); } public function attachmentDestroy(Project $project, Activity $activity, Attachment $attachment): JsonResponse { $gate = $this->checkPermissao($this->permissao, 'excluir'); if ($gate instanceof RedirectResponse) { return response()->json(['ok' => false, 'message' => __('Sem permissão.')], 403); } $this->service->assertProjectVisible($project, Auth::user()); if ($activity->project_id !== $project->id) { abort(404); } $this->service->destroyAttachment($activity, $attachment, Auth::user()); return response()->json([ 'ok' => true, 'attachments_count' => $activity->attachments()->whereNull('deleted_at')->count(), ]); } public function attachmentDownload(Project $project, Activity $activity, Attachment $attachment): StreamedResponse|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'visualizar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $att = $this->service->downloadAttachment($activity, $attachment); return $this->resource->downloadAttachmentResponse($att); } public function exportPdf(Request $request, Project $project, ?string $type = null): mixed { $gate = $this->checkPermissao($this->permissao, 'visualizar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $project->load('user'); $allowedTypes = ['table', 'gantt', 'timeline']; $exportType = in_array($type, $allowedTypes, true) ? $type : 'table'; $activities = $this->service->loadFilteredActivitiesForExport($project, $request); $tableRows = $this->resource->activitiesToTableRows($activities, $this->service->loadActivityIndex($project)); $ganttData = $this->resource->activitiesToGanttData($activities); $activityFilters = $this->resource->resolveActivityFilters($request); $filtersActive = $this->resource->activityFiltersActive($activityFilters); $filtersSummary = $filtersActive ? $this->resource->activityFiltersSummary($activityFilters) : []; // Com filtros, os indicadores do cabeçalho refletem o subconjunto exportado. $projectStats = $filtersActive ? $this->resource->statsFromTableRows($tableRows) : $this->resource->projectStats($project); $pdf = Pdf::loadView('admin.cronogramas.exports.pdf', compact( 'project', 'tableRows', 'ganttData', 'projectStats', 'exportType', 'filtersActive', 'filtersSummary', )); if (in_array($exportType, ['table', 'gantt', 'timeline'], true)) { $pdf->setPaper('a4', 'landscape'); } $filename = 'cronograma-' . $exportType . '-' . $project->id . '.pdf'; // Abre o relatório inline (nova aba) por padrão; força download apenas quando solicitado. return $request->boolean('download') ? $pdf->download($filename) : $pdf->stream($filename); } public function exportExcel(Project $project): BinaryFileResponse|RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'visualizar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $project = $this->service->loadProjectWithActivities($project); return Excel::download( new CronogramasAtividadesExport($project, $project->activeActivities), 'cronograma-' . $project->id . '.xlsx', ); } /** * Abre a visualização pública do projeto (ativa o link se o usuário puder editar). */ public function openPublicView(Request $request, Project $project): RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'visualizar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); if ($project->status === CronogramaProjectStatus::Archived->value) { return redirect()->back()->with('error', __('Projetos arquivados não possuem visualização pública.')); } $perm = Auth::user()->getPermissaoDetalhes($this->permissao); if (! $project->public_share_enabled) { if (! ($perm['editar'] ?? false)) { return redirect()->back()->with( 'error', __('A visualização pública deste projeto ainda não foi ativada.'), ); } $this->service->enablePublicShare($project, Auth::user()); $project->refresh(); } $this->service->ensurePublicShareToken($project); return redirect()->away($this->resource->publicShareUrl($project)); } /** * Ativa ou desativa a visualização pública do projeto. */ public function togglePublicShare(CronogramasRequest $request, Project $project): RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); if ($request->boolean('enabled')) { $this->service->enablePublicShare($project, Auth::user()); $message = __('Visualização pública ativada.'); } else { $this->service->disablePublicShare($project, Auth::user()); $message = __('Visualização pública desativada.'); } return $this->redirectToProjectShow($project, $request, $message); } /** * Regenera o token do link público. */ public function regeneratePublicShareToken(Request $request, Project $project): RedirectResponse { $gate = $this->checkPermissao($this->permissao, 'editar'); if ($gate instanceof RedirectResponse) { return $gate; } $this->service->assertProjectVisible($project, Auth::user()); $this->service->regeneratePublicShareToken($project, Auth::user()); return $this->redirectToProjectShow($project, $request, __('Link público regenerado. Links anteriores deixaram de funcionar.')); } /** * Redireciona ao dashboard preservando filtros e página da listagem. * * @param array<string, mixed> $extra */ private function redirectToDashboard(Request $request, string $message, array $extra = []): RedirectResponse { return redirect() ->route('admin.cronogramas.dashboard', array_merge($this->resource->dashboardListParams($request), $extra)) ->with('success', $message); } /** * Redireciona ao detalhe do projeto preservando aba, páginas das listas e filtros do dashboard. * * @param array<string, mixed> $extra */ private function redirectToProjectShow( Project $project, Request $request, ?string $message = null, array $extra = [], ): RedirectResponse { $params = array_merge( ['project' => $project->id], $this->resource->projectShowListParams($request), $extra, ); $redirect = redirect()->route('admin.cronogramas.projetos.show', $params); return $message ? $redirect->with('success', $message) : $redirect; } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.28 | Generation time: 0.02 |
proxy
|
phpinfo
|
Settings