357 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			357 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			PHP
		
	
	
	
<?php
 | 
						|
 | 
						|
namespace Modules\Admin\app\Http\Controllers;
 | 
						|
 | 
						|
use App\Http\Controllers\Controller;
 | 
						|
use App\Mail\WarningLongTask;
 | 
						|
use App\Mail\WorklogReport;
 | 
						|
use App\Models\User;
 | 
						|
use App\Traits\HasFilterRequest;
 | 
						|
use App\Traits\HasOrderByRequest;
 | 
						|
use App\Traits\HasSearchRequest;
 | 
						|
use Illuminate\Http\Request;
 | 
						|
use Illuminate\Http\Response;
 | 
						|
use App\Services\JiraService;
 | 
						|
use Carbon\Carbon;
 | 
						|
use DateTime;
 | 
						|
use DateTimeZone;
 | 
						|
use GuzzleHttp\Promise\Utils;
 | 
						|
use Maatwebsite\Excel\Facades\Excel;
 | 
						|
use Illuminate\Http\JsonResponse;
 | 
						|
use Illuminate\Support\Facades\Mail;
 | 
						|
 | 
						|
class JiraController extends Controller
 | 
						|
{
 | 
						|
    use HasOrderByRequest;
 | 
						|
    use HasFilterRequest;
 | 
						|
    use HasSearchRequest;
 | 
						|
 | 
						|
    protected $jiraService;
 | 
						|
 | 
						|
    public function __construct(JiraService $jiraService)
 | 
						|
    {
 | 
						|
        $this->jiraService = $jiraService;
 | 
						|
    }
 | 
						|
 | 
						|
    public function fetchAllIssues($startAt = 0, $maxResults = 50)
 | 
						|
    {
 | 
						|
        try {
 | 
						|
            $allIssues = [];
 | 
						|
            $projects = $this->jiraService->getAllProjects();
 | 
						|
            $promises = [];
 | 
						|
 | 
						|
            foreach ($projects as $project) {
 | 
						|
                if ($project['key'] !== 'GCT') {
 | 
						|
                    $promises[] = $this->jiraService->getIssuesAsync($project['key'], $startAt, $maxResults)
 | 
						|
                        ->then(function ($response) use ($project) {
 | 
						|
                            $issues = [];
 | 
						|
                            $data = json_decode($response->getBody()->getContents(), true);
 | 
						|
                            foreach ($data['issues'] as $issue) {
 | 
						|
                                $issues[] = [
 | 
						|
                                    'summary' => $issue['fields']['summary'] ?? null,
 | 
						|
                                    'desc' => $issue['fields']['description']['content'][0] ?? null,
 | 
						|
                                    'assignee' => $issue['fields']['assignee']['displayName'] ?? null,
 | 
						|
                                    'status' => $issue['fields']['status']['name'] ?? null,
 | 
						|
                                    'worklogs' => json_encode(array_map(function ($log) {
 | 
						|
                                        return [
 | 
						|
                                            'author' => $log['author']['displayName'] ?? null,
 | 
						|
                                            'timeSpent' => $log['timeSpent'] ?? null,
 | 
						|
                                            'started' => $log['started'] ?? null,
 | 
						|
                                            'updated' => $log['updated'] ?? null,
 | 
						|
                                        ];
 | 
						|
                                    }, $issue['fields']['worklog']['worklogs'] ?? []), JSON_PRETTY_PRINT),
 | 
						|
                                    'originalEstimate' => isset($issue['fields']['timeoriginalestimate']) ? $issue['fields']['timeoriginalestimate'] / 60 / 60 : null,
 | 
						|
                                    'timeSpent' => isset($issue['fields']['timespent']) ? $issue['fields']['timespent'] / 60 / 60 : null
 | 
						|
                                ];
 | 
						|
                            }
 | 
						|
                            return ['project' => $project['name'], 'issues' => $issues];
 | 
						|
                        });
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            $results = Utils::settle($promises)->wait();
 | 
						|
 | 
						|
            foreach ($results as $result) {
 | 
						|
                if ($result['state'] === 'fulfilled') {
 | 
						|
                    $allIssues[] = $result['value'];
 | 
						|
                } else {
 | 
						|
                    // Handle the errors if necessary
 | 
						|
                    \Log::error("Error fetching issues: " . $result['reason']->getMessage());
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return response()->json($allIssues);
 | 
						|
        } catch (\Exception $e) {
 | 
						|
            return response()->json(['error' => $e->getMessage()], 500);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function getAllProject()
 | 
						|
    {
 | 
						|
        $projects = $this->jiraService->getAllProjects();
 | 
						|
 | 
						|
        return response()->json([
 | 
						|
            'data' => $projects,
 | 
						|
            'status' => true
 | 
						|
        ], 200);
 | 
						|
    }
 | 
						|
 | 
						|
    public function fetchIssuesByProject(Request $request)
 | 
						|
    {
 | 
						|
        $project = ['key' => $request->key, 'name' => $request->name];
 | 
						|
        $allIssues = [];
 | 
						|
 | 
						|
        if ($project['key'] !== 'GCT') {
 | 
						|
            $startAt = 0;
 | 
						|
            $issues = [];
 | 
						|
            $total = 0;
 | 
						|
            $issueLength = 0;
 | 
						|
            $checked = true;
 | 
						|
 | 
						|
            // while ($checked) {
 | 
						|
            $response = $this->jiraService->getIssues($project['key'], $startAt);
 | 
						|
            $total = $response['total'];
 | 
						|
            $issueLength = count($response['issues']);
 | 
						|
 | 
						|
            foreach ($response['issues'] as $issue) {
 | 
						|
                $issues[] = [
 | 
						|
                    'summary' => $issue['fields']['summary'] ?? null,
 | 
						|
                    'desc' => $issue['fields']['description']['content'][0] ?? null,
 | 
						|
                    'assignee' => $issue['fields']['assignee']['displayName'] ?? null,
 | 
						|
                    'status' => $issue['fields']['status']['name'] ?? null,
 | 
						|
                    'worklogs' => json_encode(array_map(function ($log) {
 | 
						|
                        return [
 | 
						|
                            'author' => $log['author']['displayName'] ?? null,
 | 
						|
                            'timeSpent' => $log['timeSpent'] ?? null,
 | 
						|
                            'started' => $log['started'] ?? null,
 | 
						|
                            'updated' => $log['updated'] ?? null,
 | 
						|
                        ];
 | 
						|
                    }, $issue['fields']['worklog']['worklogs'] ?? []), JSON_PRETTY_PRINT),
 | 
						|
                    'originalEstimate' => isset($issue['fields']['timeoriginalestimate']) ? $issue['fields']['timeoriginalestimate'] / 60 / 60 : null,
 | 
						|
                    'timeSpent' => isset($issue['fields']['timespent']) ? $issue['fields']['timespent'] / 60 / 60 : null
 | 
						|
                ];
 | 
						|
                // }
 | 
						|
 | 
						|
                // if (($startAt + $issueLength >= $total && $total !== 0) || $total === 0) {
 | 
						|
                //     $checked = false;
 | 
						|
                // }
 | 
						|
 | 
						|
                // $startAt += $issueLength;
 | 
						|
            }
 | 
						|
 | 
						|
            $allIssues[] = [
 | 
						|
                'project' => $project['name'],
 | 
						|
                'issues' => $issues
 | 
						|
            ];
 | 
						|
 | 
						|
            return response()->json([
 | 
						|
                'data' => $allIssues,
 | 
						|
                'status' => true
 | 
						|
            ], 200);
 | 
						|
        }
 | 
						|
        return response()->json([
 | 
						|
            'data' => $allIssues,
 | 
						|
            'status' => false
 | 
						|
        ], 500);
 | 
						|
    }
 | 
						|
 | 
						|
    public function exportToExcel()
 | 
						|
    {
 | 
						|
        $allIssues = $this->fetchAllIssues()->original;
 | 
						|
        $fileName = 'allIssues.xlsx';
 | 
						|
 | 
						|
        Excel::store(new \App\Exports\IssuesExport($allIssues), $fileName);
 | 
						|
 | 
						|
        return response()->download(storage_path("app/{$fileName}"));
 | 
						|
    }
 | 
						|
 | 
						|
    public function getAllUserWorkLogs(Request $request)
 | 
						|
    {
 | 
						|
        try {
 | 
						|
            $workLogs = $this->jiraService->getAllUserWorkLogs($request->startDate, $request->endDate);
 | 
						|
            return response()->json([
 | 
						|
                'data' => $workLogs,
 | 
						|
                'status' => true
 | 
						|
            ], 200);
 | 
						|
        } catch (\Exception $e) {
 | 
						|
            return response()->json(['error' => $e->getMessage()], 500);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function sendReport()
 | 
						|
    {
 | 
						|
        $dateFormatted = Carbon::yesterday()->setTimezone(env('TIME_ZONE'))->format('Y-m-d');
 | 
						|
        // $dateFormatted = Carbon::create(2024, 06, 28)->format('Y-m-d');
 | 
						|
        $workLogs = $this->jiraService->getAllUserWorkLogs($dateFormatted, $dateFormatted);
 | 
						|
 | 
						|
        $tasksByUser = $this->formatWorkLogsByUser($workLogs);
 | 
						|
        // Mail::to(['luanlt632000@gmail.com'])->send(new WorklogReport($tasksByUser));
 | 
						|
        Mail::to(['luanlt632000@gmail.com', 'admin@apactech.io'])->send(new WorklogReport($tasksByUser));
 | 
						|
 | 
						|
        // return "Email sent successfully!";
 | 
						|
        return response()->json([
 | 
						|
            'data' => $tasksByUser,
 | 
						|
            'status' => true
 | 
						|
        ], 200);
 | 
						|
    }
 | 
						|
 | 
						|
    private function customSort($a, $b, $order)
 | 
						|
    {
 | 
						|
        $pos_a = array_search(strtolower($a), $order);
 | 
						|
        $pos_b = array_search(strtolower($b), $order);
 | 
						|
 | 
						|
        if ($pos_a === false || $pos_b === false) {
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
 | 
						|
        return $pos_a - $pos_b;
 | 
						|
    }
 | 
						|
 | 
						|
    private function formatWorkLogsByUser($workLogs)
 | 
						|
    {
 | 
						|
        // Assuming each workLog has a 'user' field
 | 
						|
        $tasksByUser = [];
 | 
						|
        $predefinedOrder = ['closed', 'done', 'customer_test', 'testing', 'in progress', 'to do', 'backlog'];
 | 
						|
        foreach ($workLogs as $log) {
 | 
						|
            $user = $log['username'];
 | 
						|
 | 
						|
            if (!isset($tasksByUser[$user])) {
 | 
						|
                $tasksByUser[$user] = [];
 | 
						|
            }
 | 
						|
            $tasksByUser[$user]['user'] = $log['user'];
 | 
						|
            foreach ($log['information']['issues'] as $issue) {
 | 
						|
 | 
						|
                $today = Carbon::yesterday()->setTimezone(env('TIME_ZONE'))->format('Y-m-d');
 | 
						|
                // $today = Carbon::create('2024','6','28');
 | 
						|
                $filteredWorklogs = [];
 | 
						|
                $totalTimeSpent = 0;
 | 
						|
                foreach ($issue['fields']['worklog']['worklogs'] as $worklog) {
 | 
						|
                    $started = Carbon::parse($worklog['started']);
 | 
						|
                    $totalTimeSpent = $totalTimeSpent + ($worklog['timeSpentSeconds'] / 60 / 60);
 | 
						|
                    if ($started->isSameDay($today) && $worklog['updateAuthor']['displayName'] == $user) {
 | 
						|
                        $filteredWorklogs[] = $worklog;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                $tasksByUser[$user]["allStatus"][$issue['fields']['status']['name']][] = [
 | 
						|
                    'summary' => $issue['fields']['summary'],
 | 
						|
                    'project' => $issue['fields']['project'],
 | 
						|
                    'estimate' => $issue['fields']['timeoriginalestimate'],
 | 
						|
                    'time_spent' => $issue['fields']['timespent'],
 | 
						|
                    'worklogs' => $filteredWorklogs,
 | 
						|
                    'totalTimeSpent' => $totalTimeSpent,
 | 
						|
                ];
 | 
						|
                $tasksByUser[$user]['assignment'] = $log['tasksAssign'];
 | 
						|
                uksort($tasksByUser[$user]["allStatus"], function ($a, $b) use ($predefinedOrder) {
 | 
						|
                    return $this->customSort($a, $b, $predefinedOrder);
 | 
						|
                });
 | 
						|
            }
 | 
						|
        }
 | 
						|
        // dd($tasksByUser);
 | 
						|
        return $tasksByUser;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getAllUserDoing(Request $request)
 | 
						|
    {
 | 
						|
        try {
 | 
						|
            $doing = $this->jiraService->getAllUserDoing();
 | 
						|
            return response()->json([
 | 
						|
                'data' => $doing,
 | 
						|
                'status' => true
 | 
						|
            ], 200);
 | 
						|
        } catch (\Exception $e) {
 | 
						|
            return response()->json(['error' => $e->getMessage()], 500);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function getDetailIssueById(Request $request)
 | 
						|
    {
 | 
						|
        $data = $this->jiraService->getDetailIssueByKey($request->issueKey);
 | 
						|
 | 
						|
        return response()->json([
 | 
						|
            'data' => $data,
 | 
						|
            'status' => true
 | 
						|
        ], 200);
 | 
						|
    }
 | 
						|
 | 
						|
    public function getDetailsProjectsById(Request $request)
 | 
						|
    {
 | 
						|
        $id = $request->input('id');
 | 
						|
        $projects = $this->jiraService->getDetailsProjectsById($id);
 | 
						|
        return response()->json([
 | 
						|
            'data' => $projects,
 | 
						|
            'status' => true
 | 
						|
        ], 200);
 | 
						|
    }
 | 
						|
 | 
						|
    public function getAllBoardByIdProjects(Request $request)
 | 
						|
    {
 | 
						|
        $id = $request->input('id');
 | 
						|
        $projects = $this->jiraService->getAllBoardByIdProjects($id);
 | 
						|
 | 
						|
        return response()->json([
 | 
						|
            'data' => $projects,
 | 
						|
            'status' => true
 | 
						|
        ], 200);
 | 
						|
    }
 | 
						|
 | 
						|
    public function getAllSprintByIdBoard(Request $request)
 | 
						|
    {
 | 
						|
        $id = $request->input('id');
 | 
						|
        $projects = $this->jiraService->getAllSprintByIdBoard($id);
 | 
						|
 | 
						|
        return response()->json([
 | 
						|
            'data' => $projects,
 | 
						|
            'status' => true
 | 
						|
        ], 200);
 | 
						|
    }
 | 
						|
 | 
						|
    public function getAllIssueByIdSprint(Request $request)
 | 
						|
    {
 | 
						|
        $id = $request->input('id');
 | 
						|
        $projects = $this->jiraService->getAllIssueByIdSprint($id);
 | 
						|
 | 
						|
        return response()->json([
 | 
						|
            'data' => $projects,
 | 
						|
            'status' => true
 | 
						|
        ], 200);
 | 
						|
    }
 | 
						|
 | 
						|
    public function sendWarningMailByAllowcation()
 | 
						|
    {
 | 
						|
        $data = $this->jiraService->getAllUserDoing();
 | 
						|
        $user_info = [];
 | 
						|
        foreach ($data['projects'] as $project) {
 | 
						|
            foreach ($project['users'] as $user) {
 | 
						|
                foreach ($user['issues'] as $issue) {
 | 
						|
                    $targetDate = Carbon::parse($issue['changelog']['histories'][0]['created']); // Target date
 | 
						|
                    $daysRemaining = Carbon::now()->setTimezone(env('TIME_ZONE'))->diffInDays($targetDate);
 | 
						|
                    if ($daysRemaining > 10) {
 | 
						|
                        $issue['daysRemaining'] = $daysRemaining;
 | 
						|
                        $user_info[$user['user']['emailAddress']][] = $issue;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        foreach ($user_info as $email => $user) {
 | 
						|
            Mail::to([$email])->cc(['admin@apactech.io', 'joseph@apactech.io'])->send(new WarningLongTask($user_info[$email]));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function getUserProjectParticipating(Request $request)
 | 
						|
    {
 | 
						|
        $userID = $request->input('userID');
 | 
						|
        $startDate = $request->input('fromDate');
 | 
						|
        $endDate = $request->input('toDate');
 | 
						|
        $user = User::find($userID);
 | 
						|
        $userJira = $this->jiraService->getUserByEmail($user->email);
 | 
						|
        $projects = $this->jiraService->getUserWorkLogs($userJira[0]['accountId'], $startDate, $endDate);
 | 
						|
 | 
						|
        return response()->json([
 | 
						|
            'data' => $projects,
 | 
						|
            "accountId" => $userJira[0]['accountId'],
 | 
						|
            'status' => true
 | 
						|
        ], 200);
 | 
						|
    }
 | 
						|
}
 |