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);
|
|
}
|
|
}
|