Merge branch '105-sync-gitlab-support' into 'develop'

Resolve "Liaison labels (Gitlab) et statuts (support tickets)"

See merge request ldc-web/projets/support-web!123
This commit is contained in:
noah.lancien 2026-03-24 15:48:12 +00:00
commit 9ea4786aa8
4 changed files with 179 additions and 28 deletions

View file

@ -282,6 +282,7 @@ class UpdateGitlabDatas extends Command
if ($gitlabIssueLabels) {
match (true) {
$gitlabIssueLabels->contains('g-wip') => $this->updateTicketStatus($ticket, TicketStatusEnum::inDev),
$gitlabIssueLabels->contains('g-production') => $this->updateTicketStatus($ticket, TicketStatusEnum::production),
default => null,
};
}

View file

@ -2,37 +2,38 @@
namespace App\Http\Controllers\Bo;
use App\Enums\Tickets\TicketStatusEnum;
use App\Enums\Tickets\TicketTypeEnum;
use App\Enums\Users\GitlabUsersEnum;
use App\Events\NotifySubscriptions;
use App\Events\TicketStatusChanged;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\AssignTicketToUserRequest;
use App\Http\Requests\Bo\ChangeTicketStatus;
use App\Http\Requests\Bo\CreateMessage;
use App\Http\Requests\Bo\SortTickets;
use App\Http\Requests\Bo\StoreTicket;
use App\Http\Requests\Bo\UpdateChangeOrderRequest;
use App\Http\Requests\Bo\UpdateMessage;
use App\Http\Requests\Bo\UpdateTicket;
use App\Http\Requests\Bo\LinkTicket;
use App\Http\Requests\Bo\UpdateTicketPriorityRequest;
use App\Lib\Helpers\FileStorageHelper;
use App\Lib\Helpers\ToolboxHelper;
use App\Models\Site;
use App\Models\User;
use App\Models\Ticket;
use App\Mail\NewTicket;
use App\Models\Message;
use App\Models\Site;
use App\Models\Ticket;
use App\Models\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Jobs\UpdateIssueLabels;
use App\Lib\Helpers\ToolboxHelper;
use Illuminate\Support\Facades\DB;
use App\Events\NotifySubscriptions;
use App\Events\TicketStatusChanged;
use App\Enums\Users\GitlabUsersEnum;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\LinkTicket;
use Illuminate\Support\Facades\Mail;
use App\Enums\Tickets\TicketTypeEnum;
use App\Http\Requests\Bo\SortTickets;
use App\Http\Requests\Bo\StoreTicket;
use App\Http\Requests\Bo\UpdateTicket;
use App\Lib\Helpers\FileStorageHelper;
use App\Enums\Tickets\TicketStatusEnum;
use App\Http\Requests\Bo\CreateMessage;
use App\Http\Requests\Bo\UpdateMessage;
use Illuminate\Support\Facades\Session;
use GrahamCampbell\GitLab\Facades\GitLab;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Str;
use App\Http\Requests\Bo\ChangeTicketStatus;
use App\Http\Requests\Bo\UpdateChangeOrderRequest;
use App\Http\Requests\Bo\AssignTicketToUserRequest;
use App\Http\Requests\Bo\UpdateTicketPriorityRequest;
class TicketController extends Controller
{
@ -313,6 +314,10 @@ class TicketController extends Controller
*/
public function changeStatus(ChangeTicketStatus $request, Ticket $ticket)
{
if ($ticket->gitlab_issue) {
\dispatch(new UpdateIssueLabels($ticket, $request->status));
}
$ticket->fill($request->validated());
$ticket->saveOrFail();
@ -749,7 +754,8 @@ class TicketController extends Controller
$description = \sprintf("%s<br>", $ticket->text);
$cLabel = match ($ticket->type) {
TicketTypeEnum::bug => 'c-bug',
TicketTypeEnum::evolution, TicketTypeEnum::newsletter => 'c-feature',
TicketTypeEnum::evolution => 'c-feature',
TicketTypeEnum::newsletter => 'c-feature,g-to-estimate',
};
$assigneeId = match ($ticket->type) {

View file

@ -0,0 +1,85 @@
<?php
namespace App\Jobs;
use App\Models\Ticket;
use App\Enums\Tickets\TicketStatusEnum;
use Illuminate\Foundation\Queue\Queueable;
use App\Traits\Controllers\HasGitlabIssue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Http\Requests\Bo\ChangeTicketStatus;
class UpdateIssueLabels implements ShouldQueue
{
use Queueable;
use HasGitlabIssue;
/** @var Ticket */
protected $ticket;
/** @var requestStatus */
protected $requestStatus;
/**
* Create a new job instance.
*
* @param \App\Models\Ticket $ticket
* @param string $request
*
* @return void
*/
public function __construct(Ticket $ticket, string $requestStatus)
{
$this->ticket = $ticket;
$this->requestStatus = $requestStatus;
}
/**
* Execute the job.
*/
public function handle(): void
{
$oldStatus = $this->ticket->status;
$requestStatus = (int) $this->requestStatus;
$gitlabIssue = $this->getGitlabIssue($this->ticket->site->gitlab_project_id, $this->ticket->gitlab_issue);
$issueLabels = $gitlabIssue['labels'];
if ($oldStatus === TicketStatusEnum::waiting && $requestStatus !== TicketStatusEnum::waiting->value) {
$issueLabels = array_values(array_diff($issueLabels, ['g-wait']));
}
switch ($requestStatus) {
case TicketStatusEnum::takenInAccount->value:
$newLabels = ['g-to-dispatch'];
$updatedLabels = array_unique(array_merge($issueLabels, $newLabels));
$updatedIssue = $this->updateGitlabIssueLabels($gitlabIssue['project_id'], $gitlabIssue['iid'], $updatedLabels);
break;
case TicketStatusEnum::waiting->value:
$newLabels = ['g-wait'];
$updatedLabels = array_unique(array_merge($issueLabels, $newLabels));
$updatedIssue = $this->updateGitlabIssueLabels($gitlabIssue['project_id'], $gitlabIssue['iid'], $updatedLabels);
break;
case TicketStatusEnum::waitingValidation->value:
$removeLabels = ['g-to-estimate'];
$updatedLabels = array_diff($issueLabels, $removeLabels);
$updatedIssue = $this->updateGitlabIssueLabels($gitlabIssue['project_id'], $gitlabIssue['iid'], $updatedLabels);
break;
case TicketStatusEnum::recetteValidated->value:
$newLabels = ['g-re7-ok', 'to-prod'];
$updatedLabels = array_unique(array_merge($issueLabels, $newLabels));
$updatedIssue = $this->updateGitlabIssueLabels($gitlabIssue['project_id'], $gitlabIssue['iid'], $updatedLabels);
break;
case TicketStatusEnum::archived->value:
$updatedIssue = $this->closeGitlabIssue($gitlabIssue['project_id'], $gitlabIssue['iid'], $issueLabels);
break;
default:
$updatedIssue = $this->updateGitlabIssueLabels($gitlabIssue['project_id'], $gitlabIssue['iid'], $issueLabels);
break;
}
}
}

View file

@ -0,0 +1,59 @@
<?php
namespace App\Traits\Controllers;
use App\Models\GitlabIssues;
use GrahamCampbell\GitLab\Facades\GitLab;
trait HasGitlabIssue
{
/**
* Retrieves a GitLab issue id from its URL.
*
* @param int $projectId
* @param string $issueUrl
*
* @return array
*/
public function getGitlabIssue(int $projectId, string $issueUrl): array
{
if (!preg_match('/\/issues\/(\d+)/', $issueUrl, $matches)) { return []; }
$gitlabIssue = GitLab::issues()->show($projectId, (int) $matches[1]);
return $gitlabIssue;
}
/**
* Update labels for a GitLab issue.
*
* @param int|string $projectId
* @param int $issueId
* @param array $labels
*
* @return array
*/
public function updateGitlabIssueLabels($projectId, int $issueId, array $labels): array
{
return GitLab::issues()->update($projectId, $issueId, [
'labels' => implode(',', $labels),
]);
}
/**
* Close a GitLab issue.
*
* @param int|string $projectId
* @param int $issueId
* @param array $labels
*
* @return array
*/
public function closeGitlabIssue($projectId, int $issueId, array $labels): array
{
return GitLab::issues()->update($projectId, $issueId, [
'state_event' => 'close',
'labels' => implode(',', $labels),
]);
}
}