314 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			314 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
	
<?php
 | 
						|
 | 
						|
namespace App\Services;
 | 
						|
 | 
						|
use App\Models\User;
 | 
						|
use GuzzleHttp\Client;
 | 
						|
use GuzzleHttp\Promise\Utils;
 | 
						|
 | 
						|
class JiraService
 | 
						|
{
 | 
						|
    protected $client;
 | 
						|
    protected $baseUrl;
 | 
						|
    protected $authHeader;
 | 
						|
 | 
						|
    public function __construct()
 | 
						|
    {
 | 
						|
        $this->baseUrl = env('JIRA_BASE_URL');
 | 
						|
        $this->authHeader = 'Basic ' . base64_encode(env('JIRA_USERNAME') . ':' . env('JIRA_API_TOKEN'));
 | 
						|
        $this->client = new Client([
 | 
						|
            'base_uri' => $this->baseUrl,
 | 
						|
            'headers' => [
 | 
						|
                'Authorization' => $this->authHeader,
 | 
						|
                'Accept' => 'application/json',
 | 
						|
                'Content-Type' => 'application/json'
 | 
						|
            ]
 | 
						|
        ]);
 | 
						|
    }
 | 
						|
 | 
						|
    public function getAllProjects()
 | 
						|
    {
 | 
						|
        $response = $this->client->get('/rest/api/3/project');
 | 
						|
        return json_decode($response->getBody()->getContents(), true);
 | 
						|
    }
 | 
						|
 | 
						|
    public function getIssuesAsync($projectKey, $startAt = 0, $maxResults = 50)
 | 
						|
    {
 | 
						|
        $body = [
 | 
						|
            'expand' => ['names', 'schema', 'operations'],
 | 
						|
            'fields' => ['summary', 'status', 'description', 'timeoriginalestimate', 'timespent', 'worklog', 'assignee'],
 | 
						|
            'jql' => "project = '{$projectKey}' ORDER BY created DESC",
 | 
						|
            'maxResults' => $maxResults,
 | 
						|
            'startAt' => $startAt
 | 
						|
        ];
 | 
						|
 | 
						|
        return $this->client->postAsync($this->baseUrl . '/rest/api/3/search', [
 | 
						|
            'body' => json_encode($body),
 | 
						|
            'headers' => [
 | 
						|
                'Authorization' => $this->authHeader,
 | 
						|
                'Accept' => 'application/json',
 | 
						|
                'Content-Type' => 'application/json'
 | 
						|
            ]
 | 
						|
        ]);
 | 
						|
    }
 | 
						|
    public function getIssues($projectKey, $startAt = 0)
 | 
						|
    {
 | 
						|
        $body = [
 | 
						|
            'expand' => ['names', 'schema', 'operations'],
 | 
						|
            'fields' => ['summary', 'status', 'description', 'timeoriginalestimate', 'timespent', 'worklog', 'assignee'],
 | 
						|
            'jql' => "project = '{$projectKey}' ORDER BY created DESC",
 | 
						|
            'maxResults' => 100,
 | 
						|
            'startAt' => $startAt
 | 
						|
        ];
 | 
						|
 | 
						|
        $response = $this->client->post('/rest/api/3/search', [
 | 
						|
            'body' => json_encode($body)
 | 
						|
        ]);
 | 
						|
 | 
						|
        return json_decode($response->getBody()->getContents(), true);
 | 
						|
    }
 | 
						|
 | 
						|
    public function getIssuesByUser($accountId, $startAt = 0)
 | 
						|
    {
 | 
						|
        $body = [
 | 
						|
            'expand' => ['names', 'schema', 'operations'],
 | 
						|
            'fields' => ['summary', 'status', 'timeoriginalestimate', 'timespent', 'assignee', 'project'],
 | 
						|
            'jql' => sprintf(
 | 
						|
                "assignee = '%s' AND status IN ('backlog', 'to do', 'in progress')",
 | 
						|
                $accountId
 | 
						|
            ),
 | 
						|
            'maxResults' => 50,
 | 
						|
            'startAt' => $startAt
 | 
						|
        ];
 | 
						|
 | 
						|
        $response = $this->client->post('/rest/api/3/search', [
 | 
						|
            'body' => json_encode($body)
 | 
						|
        ]);
 | 
						|
 | 
						|
        $issues = json_decode($response->getBody()->getContents(), true);
 | 
						|
 | 
						|
        foreach ($issues['issues'] as &$issue) {
 | 
						|
            $issueKey = $issue['key'];
 | 
						|
            $issueResponse = $this->client->get("/rest/api/3/issue/{$issueKey}?expand=changelog");
 | 
						|
            $issueDetails = json_decode($issueResponse->getBody()->getContents(), true);
 | 
						|
            $issue['changelog'] = $issueDetails['changelog'];
 | 
						|
        }
 | 
						|
 | 
						|
        return $issues;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getAllUsers()
 | 
						|
    {
 | 
						|
        $response = $this->client->get('/rest/api/3/users/search', [
 | 
						|
            'headers' => [
 | 
						|
                'Authorization' => $this->authHeader,
 | 
						|
                'Accept' => 'application/json'
 | 
						|
            ]
 | 
						|
        ]);
 | 
						|
 | 
						|
        return json_decode($response->getBody()->getContents(), true);
 | 
						|
    }
 | 
						|
 | 
						|
    public function getUserByEmail($email)
 | 
						|
    {
 | 
						|
 | 
						|
        $response = $this->client->get("/rest/api/3/user/search?query={$email}", [
 | 
						|
            'headers' => [
 | 
						|
                'Authorization' => $this->authHeader,
 | 
						|
                'Accept' => 'application/json'
 | 
						|
            ]
 | 
						|
        ]);
 | 
						|
 | 
						|
        if ($response->getStatusCode() == 200) {
 | 
						|
            return json_decode($response->getBody(), true);
 | 
						|
        }
 | 
						|
 | 
						|
        return null;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getUsersByEmails($all_users)
 | 
						|
    {
 | 
						|
        $users = [];
 | 
						|
 | 
						|
        foreach ($all_users as $user) {
 | 
						|
            $user_info = $this->getUserByEmail($user->email);
 | 
						|
 | 
						|
            if (isset($user_info[0]['self'])) {
 | 
						|
                $user_info[0]['emailAddress'] = $user->email;
 | 
						|
                $users[] = $user_info;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return $users;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getUserWorkLogs($accountId, $startDate, $endDate)
 | 
						|
    {
 | 
						|
        $body = [
 | 
						|
            'jql' => "worklogAuthor = '{$accountId}'AND worklogDate >= '{$startDate}' AND worklogDate <= '{$endDate}'",
 | 
						|
            'fields' => ['summary', 'status', 'timeoriginalestimate', 'timespent', 'project'],
 | 
						|
            'maxResults' => 100
 | 
						|
        ];
 | 
						|
 | 
						|
        $response = $this->client->post('/rest/api/3/search', [
 | 
						|
            'body' => json_encode($body),
 | 
						|
            'headers' => [
 | 
						|
                'Authorization' => $this->authHeader,
 | 
						|
                'Accept' => 'application/json',
 | 
						|
                'Content-Type' => 'application/json'
 | 
						|
            ]
 | 
						|
        ]);
 | 
						|
 | 
						|
        $data_response = json_decode($response->getBody()->getContents(), true);
 | 
						|
 | 
						|
        if ($data_response['total'] == 0) {
 | 
						|
            return $data_response;
 | 
						|
        }
 | 
						|
 | 
						|
        $promises = [];
 | 
						|
        foreach ($data_response['issues'] as $index => $issue) {
 | 
						|
            $issueId = $issue['id'];
 | 
						|
 | 
						|
            // Get the initial worklog data to determine total number of worklogs
 | 
						|
            $promises[$index] = $this->client->getAsync("/rest/api/3/issue/{$issueId}/worklog", [
 | 
						|
                'query' => [
 | 
						|
                    'startAt' => 0,
 | 
						|
                    'maxResults' => 1
 | 
						|
                ]
 | 
						|
            ])->then(function ($checkApiResponse) use ($issueId, $index) {
 | 
						|
                $checkApi = json_decode($checkApiResponse->getBody()->getContents(), true);
 | 
						|
                $maxResults = 100;
 | 
						|
                $totalWorklogs = $checkApi['total'];
 | 
						|
                return $this->client->getAsync("/rest/api/3/issue/{$issueId}/worklog", [
 | 
						|
                    'query' => [
 | 
						|
                        'startAt' => $totalWorklogs - $maxResults,
 | 
						|
                        'maxResults' => $totalWorklogs
 | 
						|
                    ]
 | 
						|
                ])->then(function ($worklogResponse) use ($index) {
 | 
						|
                    return [
 | 
						|
                        'index' => $index,
 | 
						|
                        'worklogs' => json_decode($worklogResponse->getBody()->getContents(), true)
 | 
						|
                    ];
 | 
						|
                });
 | 
						|
            });
 | 
						|
        }
 | 
						|
 | 
						|
        // Wait for all promises to complete
 | 
						|
        $results = Utils::settle($promises)->wait();
 | 
						|
 | 
						|
        // Attach worklogs to issues
 | 
						|
        foreach ($results as $result) {
 | 
						|
            if ($result['state'] === 'fulfilled') {
 | 
						|
                $data_response['issues'][$result['value']['index']]["fields"]['worklog'] = $result['value']['worklogs'];
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return $data_response;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getAllUserWorkLogs($startDate, $endDate)
 | 
						|
    {
 | 
						|
        $users = $this->getAllUsers();
 | 
						|
        $workLogs = [];
 | 
						|
 | 
						|
        foreach ($users as $user) {
 | 
						|
            $userWorkLogs = $this->getUserWorkLogs($user['accountId'], $startDate, $endDate);
 | 
						|
            $assignTask = [];
 | 
						|
            if (count($userWorkLogs['issues']) > 0) {
 | 
						|
                $assignTask = $this->getIssuesByUser($user['accountId']);
 | 
						|
                $workLogs[] = ['username' => $user['displayName'], 'information' => $userWorkLogs, 'tasksAssign' => $assignTask, 'user' => $user];
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return $workLogs;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getAllUserDoing()
 | 
						|
    {
 | 
						|
        $all_users = User::all();
 | 
						|
        $users = $this->getUsersByEmails($all_users);
 | 
						|
        // $projects = $this->getAllProjects();
 | 
						|
        $groupedIssues = [];
 | 
						|
        $users_data = [];
 | 
						|
        $user_warning = [];
 | 
						|
        foreach ($users as $user) {
 | 
						|
            $user = $user[0];
 | 
						|
            $users_data[$user['displayName']]['user'] = $user;
 | 
						|
            $users_data[$user['displayName']]['total_spent'] = 0;
 | 
						|
            $users_data[$user['displayName']]['total_est'] = 0;
 | 
						|
            $body = [
 | 
						|
                'expand' => ['names', 'schema'],
 | 
						|
                'fields' => ['summary', 'status', 'timeoriginalestimate', 'timespent', 'assignee', 'project'],
 | 
						|
                'jql' => sprintf(
 | 
						|
                    "assignee = '%s' AND status IN ('to do', 'in progress')",
 | 
						|
                    $user['accountId']
 | 
						|
                ),
 | 
						|
                'maxResults' => 50,
 | 
						|
                'startAt' => 0
 | 
						|
            ];
 | 
						|
 | 
						|
            $response = $this->client->post('/rest/api/3/search', [
 | 
						|
                'body' => json_encode($body)
 | 
						|
            ]);
 | 
						|
 | 
						|
            $issues = json_decode($response->getBody()->getContents(), true);
 | 
						|
 | 
						|
            if (count($issues['issues']) == 0) {
 | 
						|
                $user_warning[] = $user;
 | 
						|
            }
 | 
						|
 | 
						|
            foreach ($issues['issues'] as $issue) {
 | 
						|
                $projectName = $issue['fields']['project']['name'];
 | 
						|
                $username = $issue['fields']['assignee']['displayName'];
 | 
						|
 | 
						|
                if (!isset($groupedIssues[$projectName])) {
 | 
						|
                    $groupedIssues[$projectName] = [];
 | 
						|
                    $groupedIssues[$projectName]['project'] = $issue['fields']['project'];
 | 
						|
                }
 | 
						|
 | 
						|
                if (!isset($groupedIssues[$projectName]['users'][$username])) {
 | 
						|
                    $groupedIssues[$projectName]['users'][$username] = [];
 | 
						|
                    $groupedIssues[$projectName]['users'][$username]['user'] = $issue['fields']['assignee'];
 | 
						|
                    $groupedIssues[$projectName]['users'][$username]['p_total_spent'] = 0;
 | 
						|
                    $groupedIssues[$projectName]['users'][$username]['p_total_est'] = 0;
 | 
						|
                }
 | 
						|
 | 
						|
                $groupedIssues[$projectName]['users'][$username]['issues'][] = $issue;
 | 
						|
                $groupedIssues[$projectName]['users'][$username]['p_total_spent'] = $groupedIssues[$projectName]['users'][$username]['p_total_spent'] + $issue['fields']['timespent'];
 | 
						|
                $groupedIssues[$projectName]['users'][$username]['p_total_est'] = $groupedIssues[$projectName]['users'][$username]['p_total_est'] + ($issue['fields']['timeoriginalestimate'] ?? 0);
 | 
						|
 | 
						|
                $users_data[$user['displayName']]['total_spent'] = $users_data[$user['displayName']]['total_spent'] + $issue['fields']['timespent'];
 | 
						|
                $users_data[$user['displayName']]['total_est'] = $users_data[$user['displayName']]['total_est'] + ($issue['fields']['timeoriginalestimate'] ?? 0);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
        return ['projects' => $groupedIssues, 'users' => $users_data, 'warningList' => $user_warning];
 | 
						|
        // return $projects;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getDetailsProjectsById($id)
 | 
						|
    {
 | 
						|
        $response = $this->client->get('/rest/api/3/project/' . $id);
 | 
						|
        return json_decode($response->getBody()->getContents(), true);
 | 
						|
    }
 | 
						|
    public function getAllBoardByIdProjects($id)
 | 
						|
    {
 | 
						|
        $response = $this->client->get('/rest/agile/1.0/board?projectKeyOrI=/' . $id);
 | 
						|
        return json_decode($response->getBody()->getContents(), true);
 | 
						|
    }
 | 
						|
    public function getAllSprintByIdBoard($id)
 | 
						|
    {
 | 
						|
        $response = $this->client->get('/rest/agile/1.0/board/' . $id . '/sprint');
 | 
						|
        return json_decode($response->getBody()->getContents(), true);
 | 
						|
    }
 | 
						|
    public function getAllIssueByIdSprint($id)
 | 
						|
    {
 | 
						|
        $response = $this->client->get('/rest/agile/1.0/sprint/' . $id . '/issue');
 | 
						|
        return json_decode($response->getBody()->getContents(), true);
 | 
						|
    }
 | 
						|
}
 |