This commit is contained in:
2025-07-24 22:26:12 +02:00
parent 52036c690b
commit 96b2830af7
6 changed files with 55 additions and 37 deletions

View File

@ -41,9 +41,6 @@ class RedmineCommand extends Command
$projects = $this->em->getRepository(Project::class)->findAll();
foreach ($projects as $project) {
$io->text('> Project = '.$project->getTitle());
$redmine = $this->redmineService->getProject($project->getId(), $this->params->get('redmineApikey'));
$project->setRedmine($redmine);
$this->em->flush();
$this->redmineService->majProjectIssues($project, $this->params->get('redmineApikey'), true);
}

View File

@ -29,8 +29,6 @@ class IssueController extends AbstractController
{
$projects = $projectRepository->findAll();
foreach ($projects as $project) {
$redmine = $this->redmineService->getProject($project->getId(), $this->getParameter('redmineApikey'));
$project->setRedmine($redmine);
$this->redmineService->majProjectIssues($project, $this->getParameter('redmineApikey'), false);
}
@ -124,7 +122,11 @@ class IssueController extends AbstractController
'agile_data_attributes' => ['agile_sprint_id' => $targetSprint],
'status_id' => $targetStatus,
];
$this->redmineService->updateIssue($id, $payload, $this->getUser()->getApikey());
$user = $this->getUser();
if ($user instanceof \App\Entity\User) {
$apikey = $user->getApikey();
$this->redmineService->updateIssue($id, $payload, $apikey);
}
} catch (\RuntimeException $e) {
return new JsonResponse(['message' => $e->getMessage()], 400);
}

View File

@ -36,12 +36,9 @@ class ProjectController extends AbstractController
throw new AccessDeniedException('Vous n\'avez pas accès à cette ressource.');
}
$redmine = $this->redmineService->getProject($project->getId(), $this->getParameter('redmineApikey'));
$project->setRedmine($redmine);
$this->redmineService->majProjectIssues($project, $this->getParameter('redmineApikey'), false);
$predmine = $project->getRedmine();
foreach ($project->getIssues() as $issue) {
foreach ($predmine['sprints'] as $key => $sprint) {
if ($sprint['id'] === $issue->getRedmine()['sprint']['agile_sprint_id']) {
@ -71,11 +68,9 @@ class ProjectController extends AbstractController
#[Route('/user/report/{month}', name: 'app_project_report')]
public function reportProject(int $month, ProjectRepository $projectRepository, IssueRepository $issueRepository): Response
{
$date=new \DateTime($month.'01');
$date = new \DateTime($month.'01');
$projects = $projectRepository->findAll();
foreach($projects as $project) {
$redmine = $this->redmineService->getProject($project->getId(), $this->getParameter('redmineApikey'));
$project->setRedmine($redmine);
foreach ($projects as $project) {
$this->redmineService->majProjectIssues($project, $this->getParameter('redmineApikey'), false);
}
@ -83,10 +78,10 @@ class ProjectController extends AbstractController
'usemenu' => true,
'usesidebar' => false,
'project' => $project,
'issues' => $issueRepository->findIssues(null,true,$this->getUser()),
'issues' => $issueRepository->findIssues(null, true, $this->getUser()),
'date' => $date,
]);
}
]);
}
#[Route('/admin/project', name: 'app_admin_project')]
public function list(ProjectRepository $projectRepository): Response
@ -111,10 +106,9 @@ class ProjectController extends AbstractController
$form = $this->createForm(ProjectType::class, $project, ['mode' => 'submit', 'redmineprojects' => $this->redmineService->getProjects($this->getParameter('redmineApikey'))]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$redmine = $this->redmineService->getProject($project->getId(), $this->getParameter('redmineApikey'));
$project->setRedmine($redmine);
$em->persist($project);
$em->flush();
$this->redmineService->majProjectIssues($project, $this->getParameter('redmineApikey'), false);
return $this->redirectToRoute('app_admin_project');
@ -139,17 +133,11 @@ class ProjectController extends AbstractController
throw new NotFoundHttpException('La ressource demandée est introuvable.');
}
$redmine = $this->redmineService->getProject($project->getId(), $this->getParameter('redmineApikey'));
$project->setRedmine($redmine);
$em->persist($project);
$em->flush();
$form = $this->createForm(ProjectType::class, $project, ['mode' => 'update', 'redmineprojects' => $this->redmineService->getProjects($this->getParameter('redmineApikey')), 'redmine' => $redmine]);
$form = $this->createForm(ProjectType::class, $project, ['mode' => 'update', 'redmineprojects' => $this->redmineService->getProjects($this->getParameter('redmineApikey')), 'redmine' => $project->getRedmine()]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$redmine = $this->redmineService->getProject($project->getId(), $this->getParameter('redmineApikey'));
$project->setRedmine($redmine);
$em->flush();
$this->redmineService->majProjectIssues($project, $this->getParameter('redmineApikey'), false);
return $this->redirectToRoute('app_admin_project');
@ -175,9 +163,8 @@ class ProjectController extends AbstractController
throw new NotFoundHttpException('La ressource demandée est introuvable.');
}
$redmine = $this->redmineService->getProject($project->getId(), $this->getParameter('redmineApikey'));
$project->setRedmine($redmine);
$em->flush();
$this->redmineService->majProjectIssues($project, $this->getParameter('redmineApikey'), true);
return $this->redirectToRoute('app_admin_project');

View File

@ -24,6 +24,9 @@ class Project
#[ORM\Column(type: 'datetime', nullable: true)]
private ?\DateTimeInterface $updateAt = null;
#[ORM\Column(type: 'datetime', nullable: true)]
private ?\DateTimeInterface $updateIssuesAt = null;
#[ORM\Column(nullable: false)]
private array $redmine;
@ -109,6 +112,18 @@ class Project
return $this;
}
public function getUpdateIssuesAt(): ?\DateTimeInterface
{
return $this->updateIssuesAt;
}
public function setUpdateIssuesAt(?\DateTimeInterface $updateIssuesAt): static
{
$this->updateIssuesAt = $updateIssuesAt;
return $this;
}
public function getRedmine(): array
{
return $this->redmine;

View File

@ -27,9 +27,6 @@ class RedmineService
$this->em = $em;
}
/**
* Récupère les projets accessibles via l'API key.
*/
public function getProjects(string $apiKey): array
{
try {
@ -51,7 +48,20 @@ class RedmineService
}
}
public function getProject(int|string $id, string $apiKey): ?array
public function majProject(Project $project, string $apiKey, bool $force = false): void
{
$updatedAt = $project->getUpdateAt();
$updatedMinus10 = $updatedAt instanceof \DateTime ? (clone $updatedAt)->sub(new \DateInterval('PT10M')) : null;
$redmine = $this->getProject($project->getId(), $apiKey, $updatedMinus10, $force);
if ($redmine) {
$project->setRedmine($redmine);
}
$project->setUpdateIssuesAt(new \DateTime());
$this->em->flush();
}
public function getProject(int|string $id, string $apiKey, \DateTimeInterface $date, bool $force = false): ?array
{
try {
$response = $this->client->request('GET', $this->baseUrl.'/projects/'.$id.'.json?include=trackers,issue_categories,issue_custom_fields', [
@ -66,6 +76,10 @@ class RedmineService
}
$data = $response->toArray();
if (!$force && $date && $data['project']['updated_on'] <= $date) {
return null;
}
$data['project']['issue_statuses'] = $this->getIssueStatuses($apiKey);
$data['project']['issue_priorities'] = $this->getIssuePriorities($apiKey);
@ -173,8 +187,10 @@ class RedmineService
public function majProjectIssues(Project $project, string $apiKey, bool $force = false)
{
$updatedAt = $project->getUpdateAt();
$updatedMinus10 = $updatedAt ? (clone $updatedAt)->sub(new \DateInterval('PT10M')) : null;
$this->majProject($project, $apiKey, $force);
$updatedAt = $project->getUpdateIssuesAt();
$updatedMinus10 = $updatedAt instanceof \DateTime ? (clone $updatedAt)->sub(new \DateInterval('PT10M')) : null;
$rissues = $this->getProjectIssues($project->getId(), $apiKey, $force ? null : $updatedMinus10);
$rissueids = [];
@ -231,7 +247,7 @@ class RedmineService
*/
$this->em->persist($issue);
$project->setUpdateAt(new \DateTime());
$project->setUpdateIssuesAt(new \DateTime());
$this->em->flush();
}

View File

@ -2,8 +2,9 @@
<div class="card-header">
<div class="mb-0 d-flex" style="align-items:baseline">
<h5 style="flex-grow:1">#{{ issue.redmine.id }} = {{ issue.redmine.subject }}</h5>
<a href="{{redmineUrl}}/issues/{{issue.id}}/edit" target="_blank" class="btn btn-primary"><i class="fas fa-eye"></i></a>
<div class="btn btn-secondary" onClick="hideIssue()"><i class="fas fa-window-close"></i></div>
<a href="{{redmineUrl}}/issues/{{issue.id}}" target="_blank" class="btn btn-primary me-1"><i class="fas fa-eye"></i></a>
<a href="{{redmineUrl}}/issues/{{issue.id}}/edit" target="_blank" class="btn btn-primary me-1"><i class="fas fa-pencil"></i></a>
<div class="btn btn-warning" onClick="hideIssue()"><i class="fas fa-window-close"></i></div>
</div>
<div class="d-flex">