DX: improve performance for counting feature linked to person

This commit is contained in:
Julien Fastré 2023-02-28 17:22:54 +01:00
parent 77c545344c
commit dbcc425f5f
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
4 changed files with 43 additions and 7 deletions

View File

@ -680,6 +680,11 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
$this->proxyAccompanyingPeriodOpenState = false;
}
public function countResources(): int
{
return $this->resources->count();
}
/**
* This public function is the same but return only true or false.
*/
@ -764,6 +769,18 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
return $result;
}
public function countAccompanyingPeriodInvolved(
bool $asParticipantOpen = true,
bool $asRequestor = true
): int {
// TODO should be optimized to avoid loading accompanying period ?
return $this->getAccompanyingPeriodInvolved($asParticipantOpen, $asRequestor)
->filter(function (AccompanyingPeriod $p) {
return $p->getStep() !== AccompanyingPeriod::STEP_DRAFT;
})
->count();
}
/**
* Get AccompanyingPeriodParticipations Collection.
*

View File

@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Menu;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Knp\Menu\MenuItem;
@ -53,6 +54,12 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
$this->residentialAddressRepo = $residentialAddressRepo;
}
/**
* @param $menuId
* @param MenuItem $menu
* @param array{person: Person} $parameters
* @return void
*/
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
$menu->addChild($this->translator->trans('Person details'), [
@ -73,8 +80,8 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
])
->setExtras([
'order' => 60,
'counter' => count($this->residentialAddressRepo->findBy(['person' => $parameters['person']])) > 0 ?
count($this->residentialAddressRepo->findBy(['person' => $parameters['person']])) : null,
'counter' => 0 < ($nbResidentials = $this->residentialAddressRepo->countByPerson($parameters['person'])) ?
$nbResidentials : null,
]);
$menu->addChild($this->translator->trans('person_resources_menu'), [
@ -85,7 +92,7 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
])
->setExtras([
'order' => 70,
'counter' => count($parameters['person']->getResources()) > 0 ? count($parameters['person']->getResources()) : null,
'counter' => 0 < ($nbResources = $parameters['person']->countResources()) ? $nbResources : null,
]);
$menu->addChild($this->translator->trans('household.person history'), [
@ -120,6 +127,8 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
])
->setExtras([
'order' => 100,
'counter' => 0 < ($nbAccompanyingPeriod = $parameters['person']->countAccompanyingPeriodInvolved())
? $nbAccompanyingPeriod : null,
]);
}
}

View File

@ -32,6 +32,16 @@ class ResidentialAddressRepository extends ServiceEntityRepository
parent::__construct($registry, ResidentialAddress::class);
}
public function countByPerson(Person $person): int
{
return $this->createQueryBuilder('ra')
->select('COUNT(ra)')
->where('ra.person = :person')
->setParameter('person', $person)
->getQuery()
->getSingleScalarResult();
}
public function buildQueryFindCurrentResidentialAddresses(Person $person, ?DateTimeImmutable $at = null): QueryBuilder
{
$date = null === $at ? new DateTimeImmutable('today') : $at;

View File

@ -18,12 +18,12 @@
<div class="list-group vertical-menu {{ 'menu-' ~ menus.name }}">
{% for menu in menus %}
<a class="list-group-item list-group-item-action"
<a class="list-group-item list-group-item-action d-flex justify-content-between align-items-center"
href="{{ menu.uri }}">
{% if menu.extras.counter is defined and menu.extras.counter is not null %}
<span class="badge rounded-pill bg-danger notification-counter">{{ menu.extras.counter }}</span>
{% endif %}
{{ menu.label|upper }}
{% if menu.extras.counter is defined and menu.extras.counter is not null %}
<span class="badge rounded-pill bg-secondary notification-counter">{{ menu.extras.counter }}</span>
{% endif %}
</a>
{% endfor %}
</div>