feat : extend export endpoint for multi-user, multi-project, client filters
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -47,27 +47,65 @@ class TimeEntryExportController extends AbstractController
|
||||
throw new BadRequestHttpException('Format de date invalide. Utilisez YYYY-MM-DD.');
|
||||
}
|
||||
|
||||
// Max range: 12 months
|
||||
if ($after->modify('+12 months') < $before) {
|
||||
throw new BadRequestHttpException('La plage de dates ne peut pas dépasser 12 mois.');
|
||||
}
|
||||
|
||||
// Authorization: non-admin users can only export their own data
|
||||
$user = null;
|
||||
// --- Users ---
|
||||
$users = null;
|
||||
if (!$this->security->isGranted('ROLE_ADMIN')) {
|
||||
/** @var User $user */
|
||||
$user = $this->security->getUser();
|
||||
/** @var User $currentUser */
|
||||
$currentUser = $this->security->getUser();
|
||||
$users = [$currentUser];
|
||||
} else {
|
||||
$userId = $request->query->getInt('user');
|
||||
if ($userId > 0) {
|
||||
$user = $this->entityManager->getRepository(User::class)->find($userId);
|
||||
/** @var int[] $userIds */
|
||||
$userIds = array_filter(
|
||||
array_map('intval', (array) $request->query->all('users')),
|
||||
fn (int $id) => $id > 0,
|
||||
);
|
||||
if ([] !== $userIds) {
|
||||
$users = $this->entityManager->getRepository(User::class)->findBy(['id' => $userIds]);
|
||||
}
|
||||
}
|
||||
|
||||
$project = null;
|
||||
$projectId = $request->query->getInt('project');
|
||||
if ($projectId > 0) {
|
||||
$project = $this->entityManager->getRepository(Project::class)->find($projectId);
|
||||
// --- Client (filter projects by client) ---
|
||||
$clientId = $request->query->getInt('client');
|
||||
$clientProjects = null;
|
||||
if ($clientId > 0) {
|
||||
$clientProjects = $this->entityManager->getRepository(Project::class)->findBy(['client' => $clientId]);
|
||||
}
|
||||
|
||||
// --- Projects ---
|
||||
$projects = null;
|
||||
|
||||
/** @var int[] $projectIds */
|
||||
$projectIds = array_filter(
|
||||
array_map('intval', (array) $request->query->all('projects')),
|
||||
fn (int $id) => $id > 0,
|
||||
);
|
||||
if ([] !== $projectIds) {
|
||||
$projects = $this->entityManager->getRepository(Project::class)->findBy(['id' => $projectIds]);
|
||||
}
|
||||
|
||||
// Merge: if both client and projects are set, intersect; if only client, use client projects
|
||||
if (null !== $clientProjects && null !== $projects) {
|
||||
$clientProjectIds = array_map(fn (Project $p) => $p->getId(), $clientProjects);
|
||||
$projects = array_values(array_filter($projects, fn (Project $p) => in_array($p->getId(), $clientProjectIds, true)));
|
||||
if ([] === $projects) {
|
||||
$projects = null;
|
||||
// No matching projects — force empty result by using a dummy condition
|
||||
$entries = [];
|
||||
$tempFile = $this->exportService->generate($entries, $after, $before);
|
||||
$filename = sprintf('export-temps-%s_%s.xlsx', $after->format('Y-m-d'), $before->format('Y-m-d'));
|
||||
$response = new BinaryFileResponse($tempFile);
|
||||
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename);
|
||||
$response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
$response->deleteFileAfterSend(true);
|
||||
|
||||
return $response;
|
||||
}
|
||||
} elseif (null !== $clientProjects) {
|
||||
$projects = $clientProjects;
|
||||
}
|
||||
|
||||
/** @var int[] $tagIds */
|
||||
@@ -79,8 +117,8 @@ class TimeEntryExportController extends AbstractController
|
||||
$entries = $this->timeEntryRepository->findForExport(
|
||||
$after,
|
||||
$before,
|
||||
$user,
|
||||
$project,
|
||||
$users ?: null,
|
||||
$projects ?: null,
|
||||
$tagIds ?: null,
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user