| @@ -1,16 +1,118 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace FluentBoards\App\Http\Controllers; |
| 4 | 4 | |
| 5 | -use FluentBoards\App\Services\BoardService; | |
| 6 | 5 | use FluentBoards\App\Services\PermissionManager; |
| 6 | +use FluentBoards\App\Services\ReportService; | |
| 7 | 7 | use FluentBoards\Framework\Http\Request\Request; |
| 8 | 8 | use FluentBoardsPro\App\Modules\TimeTracking\Model\TimeTrack; |
| 9 | + | |
| 9 | 10 | class ReportController extends Controller |
| 10 | 11 | { |
| 12 | + /** | |
| 13 | + * Reports → Overview aggregates for the selected board and date range. | |
| 14 | + */ | |
| 15 | + public function getOverviewReport(Request $request) | |
| 16 | + { | |
| 17 | + return $this->sendReport($request, 'getOverviewReport'); | |
| 18 | + } | |
| 19 | + | |
| 20 | + /** | |
| 21 | + * Reports → Tasks aggregates for the selected board and date range. | |
| 22 | + */ | |
| 23 | + public function getTasksReport(Request $request) | |
| 24 | + { | |
| 25 | + return $this->sendReport($request, 'getTasksReport'); | |
| 26 | + } | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * Reports → Activity aggregates for the selected board and date range. | |
| 30 | + */ | |
| 31 | + public function getActivityReport(Request $request) | |
| 32 | + { | |
| 33 | + return $this->sendReport($request, 'getActivityReport'); | |
| 34 | + } | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * Reports → Roadmap aggregates for accessible roadmap boards. | |
| 38 | + */ | |
| 39 | + public function getRoadmapReport(Request $request) | |
| 40 | + { | |
| 41 | + if (!defined('FLUENT_BOARDS_PRO_VERSION')) { | |
| 42 | + return $this->sendError( | |
| 43 | + esc_html__('This is a pro feature', 'fluent-boards'), | |
| 44 | + 403 | |
| 45 | + ); | |
| 46 | + } | |
| 47 | + | |
| 48 | + try { | |
| 49 | + $reportService = new ReportService(); | |
| 50 | + $scope = $reportService->resolveRoadmapScope([ | |
| 51 | + 'board_id' => $this->getRequestedBoardId($request), | |
| 52 | + 'start_date' => $request->getSafe('start_date', 'sanitize_text_field'), | |
| 53 | + 'end_date' => $request->getSafe('end_date', 'sanitize_text_field'), | |
| 54 | + ]); | |
| 55 | + | |
| 56 | + return $this->sendSuccess([ | |
| 57 | + 'report' => $reportService->getRoadmapReport($scope), | |
| 58 | + ], 200); | |
| 59 | + } catch (\Exception $e) { | |
| 60 | + return $this->sendError($e->getMessage(), 400); | |
| 61 | + } | |
| 62 | + } | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * The three report screens share their parameters and their envelope; only | |
| 66 | + * the aggregate they ask for differs. | |
| 67 | + */ | |
| 68 | + private function sendReport(Request $request, $method) | |
| 69 | + { | |
| 70 | + try { | |
| 71 | + $reportService = new ReportService(); | |
| 72 | + | |
| 73 | + $scope = $reportService->resolveScope([ | |
| 74 | + 'board_id' => $this->getRequestedBoardId($request), | |
| 75 | + 'start_date' => $request->getSafe('start_date', 'sanitize_text_field'), | |
| 76 | + 'end_date' => $request->getSafe('end_date', 'sanitize_text_field'), | |
| 77 | + ]); | |
| 78 | + | |
| 79 | + return $this->sendSuccess([ | |
| 80 | + 'report' => $reportService->{$method}($scope), | |
| 81 | + ], 200); | |
| 82 | + } catch (\Exception $e) { | |
| 83 | + return $this->sendError($e->getMessage(), 400); | |
| 84 | + } | |
| 85 | + } | |
| 86 | + | |
| 87 | + /** | |
| 88 | + * Preserves a non-empty invalid board filter as an impossible ID so it | |
| 89 | + * cannot silently widen a report to every accessible board. | |
| 90 | + */ | |
| 91 | + private function getRequestedBoardId(Request $request) | |
| 92 | + { | |
| 93 | + $rawBoardId = $request->get('board_id'); | |
| 94 | + $boardId = $request->getSafe('board_id', 'intval'); | |
| 95 | + | |
| 96 | + if ($rawBoardId !== null && $rawBoardId !== '' && !$boardId) { | |
| 97 | + return -1; | |
| 98 | + } | |
| 99 | + | |
| 100 | + return $boardId; | |
| 101 | + } | |
| 102 | + | |
| 103 | + /** | |
| 104 | + * Returns the timesheet report for accessible boards when Pro is active. | |
| 105 | + */ | |
| 11 | 106 | public function getTimeSheetReport(Request $request) |
| 12 | 107 | { |
| 108 | + if (!defined('FLUENT_BOARDS_PRO_VERSION')) { | |
| 109 | + return $this->sendError( | |
| 110 | + esc_html__('This is a pro feature', 'fluent-boards'), | |
| 111 | + 403 | |
| 112 | + ); | |
| 113 | + } | |
| 114 | + | |
| 13 | 115 | // Sanitize date inputs - validate they are valid date strings |
| 14 | 116 | $startDate = $request->getSafe('start_date', 'sanitize_text_field'); |
| 15 | 117 | $endDate = $request->getSafe('end_date', 'sanitize_text_field'); |
| 16 | 118 | |
| @@ -96,39 +198,5 @@ | ||
| 96 | 198 | 'timings' => $sortTasks |
| 97 | 199 | ], 200); |
| 98 | 200 | } |
| 99 | 201 | |
| 100 | - public function getBoardReports(Request $request) | |
| 101 | - { | |
| 102 | - try { | |
| 103 | - $boardService = new BoardService(); | |
| 104 | - $boardId = $request->getSafe('board_id', 'intval'); | |
| 105 | - if (!empty($boardId)) | |
| 106 | - { | |
| 107 | - $boardReport = $boardService->getBoardReports($boardId); | |
| 108 | - } else { | |
| 109 | - $boardReport = $boardService->getAllBoardReports(); | |
| 110 | - } | |
| 111 | - return $this->sendSuccess([ | |
| 112 | - 'report' => $boardReport, | |
| 113 | - ], 200); | |
| 114 | - } catch (\Exception $e) { | |
| 115 | - return $this->sendError($e->getMessage(), 400); | |
| 116 | - } | |
| 117 | - } | |
| 118 | - | |
| 119 | - public function getStageWiseBoardReports($board_id) | |
| 120 | - { | |
| 121 | - $board_id = absint($board_id); | |
| 122 | - try { | |
| 123 | - $boardService = new BoardService(); | |
| 124 | - $stages = $boardService->getStageWiseBoardReports($board_id); | |
| 125 | - return $this->sendSuccess([ | |
| 126 | - 'stages' => $stages, | |
| 127 | - ], 200); | |
| 128 | - } catch (\Exception $e) { | |
| 129 | - return $this->sendError($e->getMessage(), 400); | |
| 130 | - } | |
| 131 | - } | |
| 132 | - | |
| 133 | - | |
| 134 | -} | |
| 202 | +} | |