PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.11
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.11
2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 1.45 All 41 releases
fluent-boards / app / Services / BoardService.php

BoardService.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.11, at app/Services/BoardService.php

800 lines 26.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\App\Services;
4
5 use FluentBoards\App\Models\Activity;
6 use FluentBoards\App\Models\Stage;
7 use FluentBoards\App\Models\User;
8 use FluentBoards\App\Models\Board;
9 use FluentBoards\App\Models\Relation;
10 use FluentBoards\App\Models\Task;
11 use FluentBoards\App\Models\Meta;
12 use FluentBoards\App\Models\TaskMeta;
13 use FluentBoards\Framework\Support\Arr;
14
15 class BoardService
16 {
17 public function getBoardsByType($type)
18 {
19 return Board::where('type', $type)->whereNull('archived_at')->orderBy('created_at', 'ASC')->get();
20 }
21
22 public function deleteBoard($boardId)
23 {
24 $board = Board::findOrFail($boardId);
25
26 $options = null;
27 //if we need to do something before a board is deleted
28 do_action('fluent_boards/before_board_deleted', $board, $options);
29
30 //related task delete, task related relations delete
31 $allTaskIdsInBoard = $board->tasks->pluck('id');
32 $taskRelatedRelations = Relation::whereIn('object_id', $allTaskIdsInBoard);
33 $taskRelatedRelations->delete();
34 TaskMeta::whereIn('task_id', $allTaskIdsInBoard)->delete();
35
36
37 Task::whereIn('id', $allTaskIdsInBoard)->delete();
38
39 //removing all Board Settings
40 $board->boardUserEmailNotificationSettings()->detach();
41 $board->boardUserNotificationSettings()->detach();
42 //removing all Board users
43 $board->users()->detach();
44
45 //removing add board stages
46 $board->stages()->delete();
47
48 //removing add board labels
49 $board->labels()->delete();
50
51 //removing add board comment
52 $board->comments()->delete();
53
54 foreach ($board->notifications as $notification) {
55 $notification->users()->detach();
56 }
57 $board->notifications()->delete();
58
59 //delete board related meta
60 $this->deleteBoardMeta($boardId);
61
62 $board->delete();
63 // do_action('fluent_boards/board_deleted', $board);
64 }
65
66 public function fetchBoardMeta($boardId)
67 {
68 $boardMeta = Meta::where('object_id', $boardId)
69 ->where('object_type', 'board')
70 ->where('key', 'is_auth_require')
71 ->orderBy('id', 'desc')->first();
72
73 if ($boardMeta) {
74 $boardMeta->value = maybe_unserialize($boardMeta->value);
75 return $boardMeta;
76 } else {
77 $meta = new Meta();
78 $settingData = array(
79 'is_auth_require_idea_submit' => '',
80 'is_auth_require_voting_commenting' => '',
81 'is_auth_require_reaction' => '',
82 'is_allow_email_along_with_auth' => '',
83 'is_allow_unauthentication_reaction_along_with_auth' => ''
84 );
85 $meta->object_id = $boardId;
86 $meta->object_type = 'board';
87 $meta->key = 'is_auth_require';
88 $meta->value = \maybe_serialize($settingData);
89 $meta->save();
90 $meta->value = $settingData;
91 return $meta;
92 }
93 }
94
95 public function modifyAuthenticationPermission($data, $boardId)
96 {
97 $boardMeta = Meta::where('object_id', $boardId)
98 ->where('object_type', 'board')
99 ->where('key', 'is_auth_require')
100 ->orderBy('id', 'desc')->first();
101
102 if ($boardMeta) {
103 $settings = array(
104 'is_auth_require_idea_submit' => $data['is_auth_require_idea_submit'],
105 'is_auth_require_voting_commenting' => $data['is_auth_require_voting_commenting'],
106 'is_auth_require_reaction' => $data['is_auth_require_reaction'],
107 'is_allow_email_along_with_auth' => $data['is_allow_email_along_with_auth'],
108 'is_allow_unauthentication_reaction_along_with_auth' => $data['is_allow_unauthentication_reaction_along_with_auth']
109 );
110 $boardMeta->value = \maybe_serialize($settings);
111 $boardMeta->save();
112 }
113 return $boardMeta;
114 }
115
116 public function createBoard($boardData)
117 {
118 $boardData = [
119 'title' => $boardData['title'],
120 'type' => $boardData['type'] ? $boardData['type'] : 'todo',
121 'description' => $boardData['description'],
122 'currency' => isset($boardData['currency']) ? $boardData['currency'] : 'USD',
123 'background' => isset($boardData['background']) ? $boardData['background'] : '',
124 ];
125
126 $boardData = apply_filters('fluent_boards/before_create_board', $boardData);
127
128 $board = Board::create($boardData);
129
130 $this->setCurrentUserPreferencesOnBoardCreate($board);
131
132 return $board;
133 }
134
135 private function setCurrentUserPreferencesOnBoardCreate($board)
136 {
137 $board->users()->attach(
138 get_current_user_id(),
139 [
140 'object_type' => Constant::OBJECT_TYPE_BOARD_USER,
141 'settings' => maybe_serialize([
142 Constant::IS_BOARD_ADMIN => true
143 ]),
144 'preferences' => maybe_serialize(Constant::BOARD_NOTIFICATION_TYPES)
145 ]
146 );
147 }
148
149 public function removeUserFromBoard($boardId, $userId)
150 {
151
152 $board = Board::findOrFail($boardId);
153 $user = User::findOrFail($userId);
154
155 $board->users()->detach($userId);
156 $board->boardUserNotificationSettings()->detach($userId); //removing notification settings of user in that board
157 $board->boardUserEmailNotificationSettings()->detach($userId); //removing email notification settings of user in that board
158
159 //detacing all tasks of this board from user
160 $taskIdsToDetach = $user->tasks()->where('board_id', $boardId)->get()->pluck('id');
161
162 $user->tasks()->detach($taskIdsToDetach);
163 $user->watchingTasks()->detach($taskIdsToDetach);
164
165 // do_action('fluent_boards/board_member_removed', $boardId, $user->display_name);
166 }
167
168 public function removeFromRecentlyOpened($boardId, $userId)
169 {
170 $recentlyOpened = Meta::where('object_id', $userId)
171 ->where('object_type', Constant::OBJECT_TYPE_USER)
172 ->where('key', Constant::USER_RECENT_BOARDS)
173 ->first();
174 if ($recentlyOpened) {
175 $recentBoardIds = $recentlyOpened->value;
176
177 $index = array_search($boardId, $recentBoardIds);
178 array_splice($recentBoardIds, $index, 1);
179
180 $recentlyOpened->value = $recentBoardIds;
181 $recentlyOpened->save();
182 }
183
184 }
185
186 public function updateBoard($board, $data)
187 {
188 if ($data['title']) {
189 $data['title'] = $data['title'];
190 } else {
191 throw new \Exception('Title cannot be empty');
192 }
193 if (isset($data['description'])) {
194 $data['description'] = $data['description'];
195 }
196 $board->fill($data);
197 $board->save();
198 // do_action('fluent_boards/board_updated', $board);
199 return $board;
200 }
201
202 public function defaultStages()
203 {
204 $stages = [
205 (object)[
206 'group' => 'open',
207 'label' => 'Open',
208 ],
209 (object)[
210 'group' => 'in_progress',
211 'label' => 'In Progress',
212 ],
213 (object)[
214 'group' => 'completed',
215 'label' => 'Completed',
216 ],
217 ];
218
219 return serialize($this->processStages($stages));
220 }
221
222 public function changePositionOfStage($boardId, $changeData)
223 {
224 $allStages = Stage::where('board_id', $boardId)
225 ->where('is_archived', 0)
226 ->where('type', 'stage')
227 ->orderBy('position', 'asc')
228 ->get();
229
230 $changedStage = null;
231
232 foreach ($allStages as $stage) {
233 if ($changeData['fromPosition'] < $changeData['toPosition']) {
234 if ($stage['position'] == $changeData['fromPosition']) {
235 $stage['position'] = (int)$changeData['toPosition'];
236 $stage->save();
237 $changedStage = $stage;
238 } elseif (
239 $stage['position'] > $changeData['fromPosition'] &&
240 $stage['position'] <= $changeData['toPosition']
241 ) {
242 $stage['position'] = $stage->position - 1;
243 $stage->save();
244 }
245 } else {
246 if (
247 $stage['position'] >= $changeData['toPosition'] &&
248 $stage['position'] < $changeData['fromPosition']
249 ) {
250 $stage['position'] = $stage->position + 1;
251 $stage->save();
252 } elseif ($stage['position'] == $changeData['fromPosition']) {
253 $stage['position'] = (int)$changeData['toPosition'];
254 $stage->save();
255 $changedStage = $stage;
256 }
257 }
258 }
259
260 do_action('fluent_boards/board_stage_dragged', $changedStage);
261 }
262
263 public function rePositionStages($boardId, $incomingList)
264 {
265 $oldList = Stage::where('board_id', $boardId)->where('type', 'stage')->whereNull('archived_at')->orderBy('position')->pluck('id');
266
267 foreach ($incomingList as $key => $stage_id) {
268 $stage = Stage::findOrFail($stage_id);
269 $stage->moveToNewPosition($key + 1);
270 }
271 do_action('fluent_boards/board_stages_reordered', $boardId, $oldList);
272 }
273
274 public function processStages($stages)
275 {
276 $processedStages = [];
277 foreach ($stages as $stage) {
278 if (is_object($stage)) {
279 $processedStages[] = (object)[
280 'group' => Helper::snake_case($stage->slug),
281 'label' => sanitize_text_field($stage->label)
282 ];
283 } else {
284 $processedStages[] = (object)[
285 'group' => Helper::snake_case($stage['group']),
286 'label' => sanitize_text_field($stage['label'])
287 ];
288 }
289 }
290 return $processedStages;
291 }
292
293 public function archiveStage($id, $stage)
294 {
295 $stage->archived_at = current_time('mysql');
296 $stage->position = 0;
297 $stage->save();
298
299 do_action('fluent_boards/board_stage_archived', $id, $stage->title);
300 return $stage;
301 }
302
303 public function restoreStage($id, $stage)
304 {
305 $stageService = new StageService();
306 $lastStagePosition = $stageService->getLastPositionOfStagesOfBoard($stage->board_id);
307 $stage->archived_at = null;
308 $stage->position = $lastStagePosition ? $lastStagePosition->position + 1 : 1;
309 $stage->save();
310 do_action('fluent_boards/board_stage_restored', $id, $stage->title);
311 return $stage;
312 }
313
314 public function getActivities($id, $data)
315 {
316 $per_page = isset($data['per_page']) ? $data['per_page'] : 40;
317 $page = isset($data['page']) ? $data['page'] : 1;
318 return Activity::where('object_id', $id)->where('object_type', Constant::ACTIVITY_BOARD)->with(['user'])
319 ->orderBy('id', 'DESC')
320 ->paginate($per_page, ['*'], 'page', $page);
321 }
322
323 public function isAlreadyMember($boardId, $memberId)
324 {
325 $isAlreadyMember = Relation::where('object_id', $boardId)
326 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
327 ->where('foreign_id', $memberId)->first();
328
329 return $isAlreadyMember ?? false;
330 }
331
332 public function addMembersInBoard($boardId, $memberId)
333 {
334 $board = Board::find($boardId);
335
336 if (!$board) {
337 return false;
338 }
339
340 $board->users()->attach(
341 $memberId,
342 [
343 'object_type' => Constant::OBJECT_TYPE_BOARD_USER,
344 'settings' => maybe_serialize(Constant::BOARD_USER_SETTINGS),
345 'preferences' => maybe_serialize(Constant::BOARD_NOTIFICATION_TYPES)
346 ]
347 );
348 $boardMember = User::find($memberId);
349 do_action('fluent_boards/board_member_added', $boardId, $boardMember->display_name);
350 return $boardMember;
351 }
352
353 public function makeAdminOfBoard($boardId, $userId)
354 {
355 $boardUser = Relation::where('object_id', $boardId)
356 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
357 ->where('foreign_id', $userId)->first();
358 $boardUser->settings = [
359 'is_admin' => true
360 ];
361 $boardUser->save();
362
363 $user = User::findOrFail($userId);
364 do_action('fluent_boards/board_admin_added', $boardId, $userId);
365 $user['is_admin'] = true;
366 $user['is_board_admin'] = true;
367 return $user;
368 }
369
370 public function removeAdminFromBoard($boardId, $userId)
371 {
372 $boardUser = Relation::where('object_id', $boardId)
373 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
374 ->where('foreign_id', $userId)->first();
375
376 $boardUser->settings = [
377 'is_admin' => false
378 ];
379
380 $boardUser->save();
381 $user = User::findOrFail($userId);
382 do_action('fluent_boards/board_admin_removed', $boardId, $userId);
383 $user['is_admin'] = false;
384 $user['is_board_admin'] = false;
385 return $user;
386 }
387
388 public function getUsersOfBoards()
389 {
390 $userBoards = Relation::whereNotNull('board_id')
391 ->where('user_id', get_current_user_id())
392 ->where('status', 'ACTIVE')->get();
393
394 return $userBoards;
395 }
396
397 /**
398 * change board background
399 * @param mixed $backgroundData
400 * @return string
401 */
402
403 public function setBoardBackground($backgroundData, $board_id)
404 {
405 $board = Board::find($board_id);
406 $background = $board->background;
407
408 // if board background has color
409 if (isset($backgroundData['color'])) {
410 $background['color'] = $backgroundData['color'];
411 $background['image_url'] = null;
412 $background['is_image'] = false;
413 }
414
415 // if board background has image
416 if (isset($backgroundData['image_url'])) {
417 $background['image_url'] = $backgroundData['image_url'];
418 $background['is_image'] = true;
419 $background['color'] = null;
420 }
421 $background['id'] = $backgroundData['id'];
422
423 $board->background = $background;
424 $board->save();
425
426 return $board->background;
427 }
428
429
430 /**
431 * Summary of getStageTaskAvailablePositions
432 * @param mixed $board_id
433 * @param mixed $stage_slug
434 * @return array of available positions of the stage with one increased value because if the stage has 10 tasks than it will have 10 position and +1 as last position of the stage
435 */
436 public function getStageTaskAvailablePositions($board_id, $stage_id)
437 {
438 $availablePositions = Task::query()
439 ->where('board_id', $board_id)
440 ->where('parent_id', null)
441 ->where('stage_id', $stage_id)
442 ->whereNull('archived_at')
443 ->orderBy('position', 'asc')
444 ->get()
445 ->pluck('position')->toArray();
446
447 $totalPosition = count($availablePositions);
448 $availablePositions[$totalPosition] = $totalPosition + 1;
449
450 return $availablePositions;
451 }
452
453 public function getAssigneesByBoard($board_id, $search = '')
454 {
455 $assignees = [];
456 $boardUsers = [];
457 $board = Board::with('users')->find($board_id);
458
459 if ($board) {
460 if ($search) {
461 $boardUsers = $board->users->filter(
462 function ($user) use ($search) {
463 return strpos($user->display_name, $search) !== false || strpos($user->user_email, $search) !== false;
464 }
465 );
466 } else {
467 $boardUsers = $board->users;
468 }
469 };
470 foreach ($boardUsers as $user) {
471 $taskAssignee = Relation::where('foreign_id', $user->ID)->where('object_type', 'task_assignee')->exists();
472 if ($taskAssignee) {
473 $assignees[] = $user;
474 }
475 }
476 return $assignees;
477 }
478
479 public function updateRecentOpenedBoards($boardId)
480 {
481 $userId = get_current_user_id();
482
483 $recentlyOpened = Meta::where('object_id', $userId)
484 ->where('object_type', Constant::OBJECT_TYPE_USER)
485 ->where('key', Constant::USER_RECENT_BOARDS)
486 ->first();
487
488 if (!$recentlyOpened) {
489 $openedBoards = [$boardId];
490 $userMeta = new Meta();
491 $userMeta->object_id = $userId;
492 $userMeta->object_type = Constant::OBJECT_TYPE_USER;
493 $userMeta->key = Constant::USER_RECENT_BOARDS;
494 $userMeta->value = $openedBoards;
495 $userMeta->save();
496 } else {
497 $boards = $recentlyOpened->value;
498 if (in_array($boardId, $boards)) {
499 $index = array_search($boardId, $boards);
500 if ($index == 1) {
501 $boards[1] = $boards[0];
502 $boards[0] = $boardId;
503 } elseif ($index == 2) {
504 $boards[2] = $boards[1];
505 $boards[1] = $boards[0];
506 $boards[0] = $boardId;
507 }
508 $recentlyOpened->value = $boards;
509 $recentlyOpened->save();
510 } else {
511 $boards[2] = $boards[1];
512 $boards[1] = $boards[0];
513 $boards[0] = $boardId;
514 $recentlyOpened->value = $boards;
515 $recentlyOpened->save();
516 }
517 }
518 }
519
520 public function getRecentBoards()
521 {
522 $userId = get_current_user_id();
523
524 $recentBoardIds = Meta::query()->where('object_id', $userId)
525 ->where('object_type', Constant::OBJECT_TYPE_USER)
526 ->where('key', Constant::USER_RECENT_BOARDS)
527 ->value('value');
528
529 if (!$recentBoardIds) {
530 return [];
531 }
532
533 $currentUser = User::find($userId);
534 $recentBoardIdsWithPermission = array_intersect($recentBoardIds, $currentUser->whichBoards->pluck('id')->toArray());
535
536 return Board::whereIn('id', $recentBoardIdsWithPermission)->withCount('completedTasks')->with(['stages', 'users'])->get();
537 }
538
539 public function updateAssociateMember($contactId, $boardId)
540 {
541 $contactOfBoard = $this->getAssociateMember($boardId, true);
542
543 if ($contactOfBoard) {
544 $contactOfBoard->value = $contactId;
545 $contactOfBoard->save();
546 } else {
547 $contactOfBoard = new Meta();
548 $contactOfBoard->object_id = $boardId;
549 $contactOfBoard->object_type = Constant::OBJECT_TYPE_BOARD;
550 $contactOfBoard->key = Constant::BOARD_ASSOCIATED_CRM_CONTACT;
551 $contactOfBoard->value = $contactId;
552 $contactOfBoard->save();
553 }
554
555 $board = Board::findOrFail($boardId);
556 do_action('fluent_boards/contact_added_to_board', $board, $contactId);
557
558 }
559
560 public function getAssociateMember($boardId, $fromUpdateMethod = false)
561 {
562
563 $contactOfBoard = Meta::query()->where('object_id', $boardId)
564 ->where('object_type', Constant::OBJECT_TYPE_BOARD)
565 ->where('key', Constant::BOARD_ASSOCIATED_CRM_CONTACT)
566 ->first();
567
568 if ($fromUpdateMethod) {
569 return $contactOfBoard;
570 }
571
572 if (!$contactOfBoard) {
573 return null;
574 }
575
576 return Helper::crm_contact($contactOfBoard->value);
577
578 // return \FluentCrm\App\Models\Subscriber::find($contactOfBoard->value);
579 }
580
581 public function deleteAssociateMember($boardId, $contact_id)
582 {
583 $contactOfBoard = Meta::query()->where('object_id', $boardId)
584 ->where('object_type', Constant::OBJECT_TYPE_BOARD)
585 ->where('key', Constant::BOARD_ASSOCIATED_CRM_CONTACT)
586 ->where('value', $contact_id)
587 ->first();
588
589 $contactOfBoard->delete();
590 }
591
592 public function sendInvitationToBoard($boardId, $email)
593 {
594 $user = User::query()->where('user_email', $email)->first();
595
596 if ($user) {
597 return $user;
598 }
599
600 do_action('fluent_boards_pro/send_invitation', $boardId, $email);
601
602 return;
603
604 }
605
606 public function getInvitations($boardId)
607 {
608 return Meta::query()->where('object_id', $boardId)
609 ->where('object_type', Constant::OBJECT_TYPE_BOARD)
610 ->where('key', Constant::BOARD_INVITATION)
611 ->get();
612 }
613
614 public function deleteInvitation($invitationId)
615 {
616 Meta::findOrFail($invitationId)->delete();
617 }
618
619 public function hasDataChanged($boardId)
620 {
621 $stages = [];
622 $labels = [];
623 $tasks = [];
624 $labels = [];
625 $taskDeleted = false;
626 $stageDeleted = false;
627 $labelDeleted = false;
628 $oneMinuteAgoTimestamp = current_time('timestamp') - 60; // Get the current timestamp and subtract 60 seconds
629 $oneMinuteAgo = date_i18n('Y-m-d H:i:s', $oneMinuteAgoTimestamp); // Format the timestamp into the desired format in GMT
630
631 $board = Board::find($boardId);
632 if (!$board) {
633 throw new \Exception("Board doesn't exists");
634 }
635 // if stage in this board has been deleted
636 $stageDeleted = Activity::where('object_id', $boardId)->where('updated_at', '>=', $oneMinuteAgo)->where('action', 'deleted')->where('column', 'stage')->exists();
637
638 if ($stageDeleted) {
639 $stages = $board->stages;
640 } else {
641 $stages = (new StageService())->getLastOneMinuteUpdatedStages($boardId);
642 }
643
644 $labelDeleted = Activity::where('object_id', $boardId)->where('updated_at', '>=', $oneMinuteAgo)->where('action', 'deleted')->where('column', 'label')->exists();
645 if ($labelDeleted) {
646 $labels = $board->labels;
647 } else {
648 $labels = (new LabelService())->getLastOneMinuteUpdatedLabels($boardId);
649 }
650
651 // if task in this board has been deleted
652 $taskDeletedOrMovedFormBoard = Activity::where('object_id', $boardId)->where('updated_at', '>=', $oneMinuteAgo)->where('action', 'deleted')->orWhere('action', 'moved')->where('column', 'task')->exists();
653
654 if ($taskDeletedOrMovedFormBoard) {
655 $tasks = Task::query()
656 ->where([
657 'board_id' => $boardId,
658 'parent_id' => null,
659 'archived_at' => null
660 ])
661 ->with(['assignees', 'labels'])
662 ->orderBy('due_at', 'ASC')
663 ->get();
664 } else {
665 $tasks = (new TaskService())->getLastOneMinuteUpdatedTasks($boardId);
666 }
667
668 foreach ($tasks as $task) {
669 $task->isOverdue = $task->isOverdue();
670 $task->isUpcoming = $task->upcoming();
671 }
672
673 if ($board->updated_at >= $oneMinuteAgo) {
674 $board->background = \maybe_unserialize($board->background);
675 } else {
676 $board = [];
677 }
678
679 return [
680 'board' => $board,
681 'stages' => $stages,
682 'labels' => $labels,
683 'tasks' => $tasks,
684 'taskDeleted' => $taskDeletedOrMovedFormBoard,
685 'stageDeleted' => $stageDeleted,
686 ];
687 }
688
689 public function getAssociatedBoards($associatedId)
690 {
691
692 $boardIds = Meta::query()->where('value', $associatedId)
693 ->where('object_type', Constant::OBJECT_TYPE_BOARD)
694 ->where('key', Constant::BOARD_ASSOCIATED_CRM_CONTACT)
695 ->pluck('object_id');
696
697 return Board::query()->whereIn('id', $boardIds)->with('stages', 'users')->get();
698 }
699
700 private function deleteBoardMeta($boardId)
701 {
702 Meta::where('object_id', $boardId)
703 ->where('object_type', Constant::OBJECT_TYPE_BOARD)
704 ->delete();
705 }
706
707 public function copyBoard($boardData)
708 {
709 $boardData = apply_filters('fluent_boards/before_create_board', $boardData);
710
711 $board = Board::create($boardData);
712
713 $this->setCurrentUserPreferencesOnBoardCreate($board);
714
715 return $board;
716 }
717
718 public function getBoardReports($board_id)
719 {
720 $completedTaskCount = Task::where('board_id', $board_id)
721 ->where('status', 'closed')
722 ->whereNull('parent_id')
723 ->whereNull('archived_at')
724 ->count();
725
726 $openTaskCount = Task::where('board_id', $board_id)
727 // ->whereNull('due_at')
728 ->whereNull('parent_id')
729 ->whereNull('archived_at')
730 ->where('status', 'open')
731 ->count();
732
733 $overDue = Task::where('board_id', $board_id)
734 // ->whereNotNull('due_at')
735 // ->where('status', 'open')
736 ->whereNull('parent_id')
737 ->whereNull('archived_at')
738 ->overdue(true)
739 ->count();
740
741 $totalTasks = Task::where('board_id', $board_id)
742 ->whereNull('parent_id')
743 ->whereNull('archived_at')
744 ->count();
745
746 $high = Task::where('board_id', $board_id)->where('status', 'open')->where('priority', 'high')->count();
747 $medium = Task::where('board_id', $board_id)->where('status', 'open')->where('priority', 'medium')->count();
748 $low = Task::where('board_id', $board_id)->where('status', 'open')->where('priority', 'low')->count();
749
750 $reportData = [
751 'completion' => [
752 'completed' => $completedTaskCount,
753 'incomplete' => $openTaskCount,
754 'overdue' => $overDue,
755 'total' => $totalTasks
756 ],
757 'priority' => [
758 'high' => $high,
759 'medium' => $medium,
760 'low' => $low
761 ]
762
763 ];
764 return $reportData;
765 }
766
767 public function getStageWiseBoardReports($board_id)
768 {
769 $stages = Stage::where('board_id', $board_id)
770 ->where('type', 'stage')
771 ->whereNull('archived_at')
772 ->get();
773
774 foreach ($stages as $stage) {
775 $completedTaskCount = Task::where('stage_id', $stage->id)
776 ->where('status', 'closed')
777 ->count();
778
779 $openTaskCount = Task::where('stage_id', $stage->id)
780 ->whereNull('due_at')
781 ->where('status', 'open')
782 ->count();
783
784 $overDue = Task::where('stage_id', $stage->id)
785 ->whereNotNull('due_at')
786 ->where('status', 'open')
787 ->overdue(true)
788 ->count();
789
790 $stage->report = [
791 'completed' => $completedTaskCount,
792 'incomplete' => $openTaskCount,
793 'overdue' => $overDue
794 ];
795 }
796
797 return $stages;
798 }
799 }
800