Skip to content

Commit

Permalink
imp: List tickets requested by user in "Your tickets"
Browse files Browse the repository at this point in the history
  • Loading branch information
marien-probesys committed Mar 16, 2023
2 parents dec0f8d + caa9e31 commit 984244d
Show file tree
Hide file tree
Showing 13 changed files with 287 additions and 103 deletions.
29 changes: 13 additions & 16 deletions src/Controller/Organizations/TicketsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,26 @@ public function index(
/** @var \App\Entity\User $user */
$user = $this->getUser();

/** @var string $assigneeUid */
$assigneeUid = $request->query->get('assignee', '');
/** @var string $view */
$view = $request->query->get('view', 'all');

$ticketSearcher->setOrganization($organization);
$ticketSearcher->setCriteria('status', Ticket::OPEN_STATUSES);

if ($assigneeUid === 'none') {
$ticketSearcher->setCriteria('assignee', null);
$currentView = 'to assign';
} elseif ($assigneeUid !== '') {
$assignee = $userRepository->findOneBy(['uid' => $assigneeUid]);
$ticketSearcher->setCriteria('assignee', $assignee);
$currentView = 'owned';

if ($view === 'unassigned') {
$tickets = $ticketSearcher->getTicketsToAssign();
} elseif ($view === 'owned') {
$tickets = $ticketSearcher->getTicketsOfCurrentUser();
} else {
$currentView = 'all';
$ticketSearcher->setCriteria('status', Ticket::OPEN_STATUSES);
$tickets = $ticketSearcher->getTickets();
}

return $this->render('organizations/tickets/index.html.twig', [
'organization' => $organization,
'tickets' => $ticketSearcher->getTickets(),
'countToAssign' => $ticketSearcher->countToAssign(),
'countOwned' => $ticketSearcher->countAssignedTo($user),
'currentView' => $currentView,
'tickets' => $tickets,
'countToAssign' => $ticketSearcher->countTicketsToAssign(),
'countOwned' => $ticketSearcher->countTicketsOfCurrentUser(),
'view' => $view,
]);
}

Expand Down
6 changes: 2 additions & 4 deletions src/Controller/PagesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ public function home(
): Response {
/** @var \App\Entity\User $user */
$user = $this->getUser();
$ticketSearcher->setCriteria('assignee', $user);
$ticketSearcher->setCriteria('status', Ticket::OPEN_STATUSES);
$tickets = $ticketSearcher->getTickets();

$orgaIds = $authorizationRepository->getAuthorizedOrganizationIds($user);
if (in_array(null, $orgaIds)) {
$organizations = $orgaRepository->findAll();
Expand All @@ -38,6 +34,8 @@ public function home(
}
$organizations = $orgaSorter->asTree($organizations);

$tickets = $ticketSearcher->getTicketsOfCurrentUser();

return $this->render('pages/home.html.twig', [
'tickets' => $tickets,
'organizations' => $organizations,
Expand Down
29 changes: 13 additions & 16 deletions src/Controller/TicketsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public function index(
/** @var \App\Entity\User $user */
$user = $this->getUser();

/** @var string $assigneeUid */
$assigneeUid = $request->query->get('assignee', '');
/** @var string $view */
$view = $request->query->get('view', 'all');

$orgaIds = $authorizationRepository->getAuthorizedOrganizationIds($user);
if (in_array(null, $orgaIds)) {
Expand All @@ -44,24 +44,21 @@ public function index(
}

$ticketSearcher->setOrganizations($organizations);
$ticketSearcher->setCriteria('status', Ticket::OPEN_STATUSES);

if ($assigneeUid === 'none') {
$ticketSearcher->setCriteria('assignee', null);
$currentView = 'to assign';
} elseif ($assigneeUid !== '') {
$assignee = $userRepository->findOneBy(['uid' => $assigneeUid]);
$ticketSearcher->setCriteria('assignee', $assignee);
$currentView = 'owned';

if ($view === 'unassigned') {
$tickets = $ticketSearcher->getTicketsToAssign();
} elseif ($view === 'owned') {
$tickets = $ticketSearcher->getTicketsOfCurrentUser();
} else {
$currentView = 'all';
$ticketSearcher->setCriteria('status', Ticket::OPEN_STATUSES);
$tickets = $ticketSearcher->getTickets();
}

return $this->render('tickets/index.html.twig', [
'tickets' => $ticketSearcher->getTickets(),
'countToAssign' => $ticketSearcher->countToAssign(),
'countOwned' => $ticketSearcher->countAssignedTo($user),
'currentView' => $currentView,
'tickets' => $tickets,
'countToAssign' => $ticketSearcher->countTicketsToAssign(),
'countOwned' => $ticketSearcher->countTicketsOfCurrentUser(),
'view' => $view,
]);
}

Expand Down
54 changes: 43 additions & 11 deletions src/Repository/TicketRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Query\Expr;

/**
* @extends ServiceEntityRepository<Ticket>
Expand Down Expand Up @@ -52,7 +53,7 @@ public function remove(Ticket $entity, bool $flush = false): void

/**
* @param array<string, int[]> $orgaFilters
* @param array<string, mixed> $criteria
* @param array<array<string|int,mixed>> $criteria
* @param string[] $sort
* @return Ticket[]
*/
Expand All @@ -67,7 +68,7 @@ public function findBySearch(User $actor, array $orgaFilters, array $criteria, a

/**
* @param array<string, int[]> $orgaFilters
* @param array<string, mixed> $criteria
* @param array<array<string|int,mixed>> $criteria
*/
public function countBySearch(User $actor, array $orgaFilters, array $criteria): int
{
Expand All @@ -80,7 +81,7 @@ public function countBySearch(User $actor, array $orgaFilters, array $criteria):

/**
* @param array<string, int[]> $orgaFilters
* @param array<string, mixed> $criteria
* @param array<array<string|int,mixed>> $criteria
*/
private function createSearchQueryBuilder(User $actor, array $orgaFilters, array $criteria): QueryBuilder
{
Expand Down Expand Up @@ -121,20 +122,51 @@ private function createSearchQueryBuilder(User $actor, array $orgaFilters, array
$qb->setParameter('actor', $actor->getId());
}

foreach ($criteria as $field => $condition) {
if ($condition === null) {
$expr = $qb->expr()->isNull("t.{$field}");
} elseif (is_array($condition)) {
$expr = $qb->expr()->in("t.{$field}", ":{$field}");
$qb->setParameter($field, $condition);
foreach ($criteria as $criterion) {
if (count($criterion) === 1) {
/** @var string $field */
$field = array_key_first($criterion);
$condition = $criterion[$field];
$expr = $this->buildCriteriaExpr($qb, $field, $condition);
} else {
$expr = $qb->expr()->eq("t.{$field}", ":{$field}");
$qb->setParameter($field, $condition);
$expr = $this->buildOrExpr($qb, $criterion);
}

$qb->andWhere($expr);
}

return $qb;
}

/**
* return Expr\Comparison|Expr\Func|string
*/
private function buildCriteriaExpr(QueryBuilder $qb, string $field, mixed $condition): mixed
{
if ($condition === null) {
return $qb->expr()->isNull("t.{$field}");
} elseif (is_array($condition)) {
$qb->setParameter($field, $condition);
return $qb->expr()->in("t.{$field}", ":{$field}");
} else {
$qb->setParameter($field, $condition);
return $qb->expr()->eq("t.{$field}", ":{$field}");
}
}

/**
* @param array<array<string|int,mixed>> $criteria
*/
private function buildOrExpr(QueryBuilder $qb, array $criteria): Expr\Orx
{
$expressions = [];
foreach ($criteria as $criterion) {
/** @var string $field */
$field = array_key_first($criterion);
$condition = $criterion[$field];
$expressions[] = $this->buildCriteriaExpr($qb, $field, $condition);
}

return $qb->expr()->orX(...$expressions);
}
}
107 changes: 87 additions & 20 deletions src/Service/TicketSearcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace App\Service;

use App\Entity\Organization;
use App\Entity\Ticket;
use App\Entity\User;
use App\Repository\TicketRepository;
use Symfony\Bundle\SecurityBundle\Security;
Expand All @@ -15,7 +16,7 @@ class TicketSearcher
{
private TicketRepository $ticketRepository;

/** @var array<string,mixed> $criteria */
/** @var array<array<string|int,mixed>> $criteria */
private array $criteria = [];

/** @var array<string,int[]> $orgaFilters */
Expand Down Expand Up @@ -66,9 +67,9 @@ private function addOrgaFilter(Organization $organization): void
}
}

public function setCriteria(string $property, mixed $criteria): self
public function setCriteria(string $field, mixed $condition): self
{
$this->criteria[$property] = $criteria;
$this->criteria[] = [$field => $condition];

return $this;
}
Expand All @@ -78,29 +79,95 @@ public function setCriteria(string $property, mixed $criteria): self
*/
public function getTickets(): array
{
/** @var User $user */
$user = $this->security->getUser();
/** @var User $currentUser */
$currentUser = $this->security->getUser();
$sort = ['createdAt', 'DESC'];
return $this->ticketRepository->findBySearch($user, $this->orgaFilters, $this->criteria, $sort);

return $this->ticketRepository->findBySearch(
$currentUser,
$this->orgaFilters,
$this->criteria,
$sort,
);
}

/**
* @return \App\Entity\Ticket[]
*/
public function getTicketsOfCurrentUser(): array
{
/** @var User $currentUser */
$currentUser = $this->security->getUser();
$criteria = [
['status' => Ticket::OPEN_STATUSES],
[
['assignee' => $currentUser],
['requester' => $currentUser],
],
];
$sort = ['createdAt', 'DESC'];

return $this->ticketRepository->findBySearch(
$currentUser,
$this->orgaFilters,
$criteria,
$sort,
);
}

public function countToAssign(): int
public function countTicketsOfCurrentUser(): int
{
/** @var User $user */
$user = $this->security->getUser();
$criteria = array_merge($this->criteria, [
'assignee' => null,
]);
return $this->ticketRepository->countBySearch($user, $this->orgaFilters, $criteria);
/** @var User $currentUser */
$currentUser = $this->security->getUser();
$criteria = [
['status' => Ticket::OPEN_STATUSES],
[
['assignee' => $currentUser],
['requester' => $currentUser],
],
];

return $this->ticketRepository->countBySearch(
$currentUser,
$this->orgaFilters,
$criteria,
);
}

/**
* @return \App\Entity\Ticket[]
*/
public function getTicketsToAssign(): array
{
/** @var User $currentUser */
$currentUser = $this->security->getUser();
$criteria = [
['status' => Ticket::OPEN_STATUSES],
['assignee' => null],
];
$sort = ['createdAt', 'DESC'];

return $this->ticketRepository->findBySearch(
$currentUser,
$this->orgaFilters,
$criteria,
$sort,
);
}

public function countAssignedTo(User $assignee): int
public function countTicketsToAssign(): int
{
/** @var User $user */
$user = $this->security->getUser();
$criteria = array_merge($this->criteria, [
'assignee' => $assignee->getId(),
]);
return $this->ticketRepository->countBySearch($user, $this->orgaFilters, $criteria);
/** @var User $currentUser */
$currentUser = $this->security->getUser();
$criteria = [
['status' => Ticket::OPEN_STATUSES],
['assignee' => null],
];

return $this->ticketRepository->countBySearch(
$currentUser,
$this->orgaFilters,
$criteria,
);
}
}
10 changes: 5 additions & 5 deletions templates/organizations/tickets/index.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@

{% set currentPage = 'tickets' %}

{% if currentView == 'all' %}
{% if view == 'all' %}
{% set title = 'tickets.index.title.all' | trans %}
{% elseif currentView == 'to assign' %}
{% elseif view == 'unassigned' %}
{% set title = 'tickets.index.title.to_assign' | trans %}
{% elseif currentView == 'owned' %}
{% set title = 'tickets.index.title.my' | trans %}
{% elseif view == 'owned' %}
{% set title = 'tickets.index.title.your_tickets' | trans %}
{% endif %}

{% block title %}{{ title ~ '' ~ organization.name }}{% endblock %}

{% block sidebar %}
{% if is_granted('orga:see:tickets:all', 'any') %}
{{ include('tickets/_sidebar.html.twig', {
current: currentView,
current: view,
countOwned: countOwned,
countToAssign: countToAssign,
}, with_context = false) }}
Expand Down
8 changes: 4 additions & 4 deletions templates/tickets/_sidebar.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
<li class="sidebar__item">
<a
class="sidebar__anchor row row--always row--center flow-small"
href="?assignee=none"
{{ current == 'to assign' ? 'aria-current="page"' }}
href="?view=unassigned"
{{ current == 'unassigned' ? 'aria-current="page"' }}
>
<span class="row__item--extend">
{{ 'tickets.index.title.to_assign' | trans }}
Expand All @@ -41,11 +41,11 @@
<li class="sidebar__item">
<a
class="sidebar__anchor row row--always row--center flow-small"
href="?assignee={{ app.user.uid }}"
href="?view=owned"
{{ current == 'owned' ? 'aria-current="page"' }}
>
<span class="row__item--extend">
{{ 'tickets.index.title.my' | trans }}
{{ 'tickets.index.title.your_tickets' | trans }}
</span>

{% if countOwned > 0 %}
Expand Down
Loading

0 comments on commit 984244d

Please sign in to comment.