Skip to content

Commit

Permalink
Semaine type : optimisations des requêtes SQL (#846)
Browse files Browse the repository at this point in the history
* Period Admin: use repository to fetch data

* Move daysOfWeek to Period const

* Period: optimize loading

* Refactor daysOfWeek list

* Créneaux : optimisation des requêtes SQL (#847)

* Shifts: prefetch data to reduce the number of queries

* Manage case where shops have display_name_shifters

* Member admin display: accelerate page (#848)
  • Loading branch information
raphodn authored May 12, 2023
1 parent 85cadc6 commit 40fc03a
Show file tree
Hide file tree
Showing 16 changed files with 147 additions and 155 deletions.
3 changes: 1 addition & 2 deletions app/Resources/views/period/_partial/period_card.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@
{% if (week in week_filter) or not week_filter %}
<h6>Semaine {{ week }}</h6>
{% for position in positions %}
{% include 'period/_partial/position_shifter_display.html.twig'
with {'position':position, 'anonymized':anonymized} %}
{% include 'period/_partial/position_shifter_display.html.twig' with {'position': position, 'anonymized': anonymized} %}
{% endfor %}
{% endif %}
{% endfor %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,21 @@
# anonymized: if true will not display the shifter name
#}

{% set anonymized = anonymized ?? true %}
{% set shifter = position.shifter %}
{% set formation = position.formation??"Sans formation" %}
{% set formation = position.formation ?? "Sans formation" %}

{% if shifter %}
{# sombody is registered for this PeriodPosition #}

{% if anonymized %}
{% if anonymized %}
{# sombody is registered for this periodposition #}
{% set warning = beneficiary_service.hasWarningStatus(shifter) %}
<div class="tooltipped truncate black-text" data-position="bottom" data-tooltip="Formation : {{ formation }}">
<i class="material-icons">person</i>
Réservé
</div>
{% else %}

{% set warning = beneficiary_service.hasWarningStatus(shifter) %}

<a href="{{ path('member_show', { 'member_number': shifter.membership.memberNumber }) }}" target="_blank"
class="black-text tooltipped editable-box truncate" data-position="bottom"
data-tooltip="{{ shifter | print_with_number_and_status_icon | raw }} &#013;&#010; ({{ formation }})">
Expand All @@ -31,11 +29,9 @@
{{ shifter.getFirstname() }} {{ shifter.getLastname() | first }}
</a>
{% endif %}
{% else %}
{# free PeriodPosition #}
{% else %} {# free PeriodPosition #}
<div class="tooltipped truncate black-text" data-position="bottom" data-tooltip="{{ formation }}">
<i class="material-icons">person</i>
<strong><i>Libre</i></strong>
</div>

{% endif %}
{% endif %}
28 changes: 14 additions & 14 deletions app/Resources/views/period/index.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,20 @@ It display a page with all the avaible periods (a.k.a the "Semaine type")
{{ form_end(filter_form) }}
</div>
{% if use_fly_and_fixed %}
<div class="row">
<a id="shifter" style="display: None;" onClick="showShifters()"
class="btn col m3 waves-effect waves-light purple tooltipped"
data-position="bottom"
data-tooltip="Afficher le nom des membres inscrits en créneaux fixes">
<i class="material-icons left">accessibility</i>Afficher les membres
</a>
<a id="training" onClick="showTraining()"
class="btn col m3 waves-effect waves-light purple tooltipped"
data-position="bottom"
data-tooltip="Afficher la formation demandée pour être inscrit à un créneau">
<i class="material-icons left">accessibility</i>Afficher les formations
</a>
</div>
<div class="row">
<a id="shifter" style="display: None;" onClick="showShifters()"
class="btn col m3 waves-effect waves-light purple tooltipped"
data-position="bottom"
data-tooltip="Afficher le nom des membres inscrits en créneaux fixes">
<i class="material-icons left">accessibility</i>Afficher les membres
</a>
<a id="training" onClick="showTraining()"
class="btn col m3 waves-effect waves-light purple tooltipped"
data-position="bottom"
data-tooltip="Afficher la formation demandée pour être inscrit à un créneau">
<i class="material-icons left">accessibility</i>Afficher les formations
</a>
</div>
{% endif %}
</div>
</li>
Expand Down
1 change: 1 addition & 0 deletions app/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ services:
AppBundle\Controller\BookingController:
arguments:
- "%use_fly_and_fixed%"
- "%display_name_shifters%"
AppBundle\Controller\ShiftController:
arguments:
- "%forbid_own_shift_book_admin%"
Expand Down
23 changes: 10 additions & 13 deletions src/AppBundle/Controller/BookingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@ class BookingController extends Controller
/**
* @var boolean
*/
private $useFlyAndFixed;
private $use_fly_and_fixed;
private $display_name_shifters;

public function __construct(bool $useFlyAndFixed)
public function __construct(bool $use_fly_and_fixed, bool $display_name_shifters)
{
$this->useFlyAndFixed = $useFlyAndFixed;
$this->use_fly_and_fixed = $use_fly_and_fixed;
$this->display_name_shifters = $display_name_shifters;
}

/**
Expand Down Expand Up @@ -94,6 +96,7 @@ public function homepageShiftsAction(): Response
public function indexAction(Request $request)
{
$session = new Session();

$mode = null;
if ($this->getUser()->getBeneficiary() == null) {
$session->getFlashBag()->add('error', 'Oups, tu n\'as pas de bénéficiaire enregistré ! MODE ADMIN');
Expand Down Expand Up @@ -129,15 +132,15 @@ public function indexAction(Request $request)

//beneficiary selected, or only one beneficiary
if ($beneficiaryForm->isSubmitted() || $beneficiaries->count() == 1) {

$em = $this->getDoctrine()->getManager();

if ($beneficiaries->count() > 1) {
$beneficiary = $beneficiaryForm->get('beneficiary')->getData();
} else {
$beneficiary = $beneficiaries->first();
}

$shifts = $em->getRepository('AppBundle:Shift')->findFutures();
$shifts = $em->getRepository('AppBundle:Shift')->findFutures(null, null, $this->display_name_shifters);
$bucketsByDay = $this->get('shift_service')->generateShiftBucketsByDayAndJob($shifts);

$hours = array();
Expand All @@ -153,7 +156,6 @@ public function indexAction(Request $request)
]);

} else { // no beneficiary selected

return $this->render('booking/index.html.twig', [
'beneficiary_form' => $beneficiaryForm->createView(),
]);
Expand Down Expand Up @@ -307,18 +309,13 @@ public function adminAction(Request $request): Response
$em = $this->getDoctrine()->getManager();
$filter = $this->adminFilterFormFactory($em, $request);

$jobs = $em->getRepository(Job::class)->findByEnabled(true);
$beneficiaries = $em->getRepository(Beneficiary::class)->findAllActive();
$shifts = $em->getRepository(Shift::class)->findFrom($filter["from"], $filter["to"], $filter["job"]);

$shifts = $em->getRepository(Shift::class)->findFrom($filter["from"], $filter["to"], $filter["job"], true);
$bucketsByDay = $this->get('shift_service')->generateShiftBucketsByDayAndJob($shifts);
$bucketsByDay = $this->get('shift_service')->filterBucketsByDayAndJobByFilling($bucketsByDay, $filter["filling"]);

return $this->render('admin/booking/index.html.twig', [
'filterForm' => $filter["form"]->createView(),
'bucketsByDay' => $bucketsByDay,
'jobs' => $jobs,
'beneficiaries' => $beneficiaries,
]);
}

Expand Down Expand Up @@ -563,7 +560,7 @@ private function createShiftBookAdminForm(Shift $shift)
->setAction($this->generateUrl('shift_book_admin', array('id' => $shift->getId())))
->add('shifter', AutocompleteBeneficiaryType::class, array('label' => 'Numéro d\'adhérent ou nom du membre', 'required' => true));

if ($this->useFlyAndFixed) {
if ($this->use_fly_and_fixed) {
$form = $form->add('fixe', RadioChoiceType::class, [
'choices' => [
'Volant' => 0,
Expand Down
8 changes: 4 additions & 4 deletions src/AppBundle/Controller/MembershipController.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public function showAction(Membership $member)
$this->denyAccessUnlessGranted('view', $member);

$session = new Session();
$em = $this->getDoctrine()->getManager();

$freezeForm = $this->createFreezeForm($member);
$unfreezeForm = $this->createUnfreezeForm($member);
Expand Down Expand Up @@ -112,6 +113,7 @@ public function showAction(Membership $member)

$new_notes_form[$n->getId()] = $response_note_form->createView();
}

$newReg = new Registration();
$remainder = $this->get('membership_service')->getRemainder($member);
if (!$remainder->invert) { //still some days
Expand Down Expand Up @@ -155,12 +157,10 @@ public function showAction(Membership $member)
->setMethod('DELETE')->getForm()->createView();
}
}

$beneficiaryForm = $this->createNewBeneficiaryForm($member);

$timeLogForm = $this->createNewTimeLogForm($member);

$em = $this->getDoctrine()->getManager();
$period_positions = $em->getRepository('AppBundle:PeriodPosition')->findByBeneficiaries($member->getBeneficiaries());
$previous_cycle_start = $this->get('membership_service')->getStartOfCycle($member, -1 * $this->getParameter('max_nb_of_past_cycles_to_display'));
$next_cycle_end = $this->get('membership_service')->getEndOfCycle($member, 1);
Expand All @@ -181,11 +181,11 @@ public function showAction(Membership $member)
'member' => $member,
'note' => $note,
'note_form' => $note_form->createView(),
'new_registration_form' => $registrationForm->createView(),
'new_beneficiary_form' => $beneficiaryForm->createView(),
'notes_form' => $notes_form,
'notes_delete_form' => $notes_delete_form,
'new_notes_form' => $new_notes_form,
'new_registration_form' => $registrationForm->createView(),
'new_beneficiary_form' => $beneficiaryForm->createView(),
'detach_beneficiary_forms' => $detachBeneficiaryForms,
'delete_beneficiary_forms' => $deleteBeneficiaryForms,
'freeze_form' => $freezeForm->createView(),
Expand Down
55 changes: 17 additions & 38 deletions src/AppBundle/Controller/PeriodController.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,24 +148,18 @@ private function filterFormFactory(Request $request, bool $withBeneficiaryField)
*/
public function indexAction(Request $request, EntityManagerInterface $em): Response
{
$daysOfWeek = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"];
$filter = $this->filterFormFactory($request, False);
$filter = $this->filterFormFactory($request, false);
$sort = 'start';
$order = 'ASC';
$periodsByDay = array();
$order = array('start' => 'ASC');

foreach ($daysOfWeek as $i => $value) {
foreach (Period::DAYS_OF_WEEK as $i => $value) {
$findByFilter = array('dayOfWeek' => $i);

if ($filter['job']) {
$findByFilter['job'] = $filter['job'];
}

$periodsByDay[$i] = $em->getRepository('AppBundle:Period')
->findBy($findByFilter, $order);
$periodsByDay[$i] = $em->getRepository('AppBundle:Period')->findAll($i, $filter['job'], false);
}

return $this->render('period/index.html.twig', array(
'days_of_week' => $daysOfWeek,
'days_of_week' => Period::DAYS_OF_WEEK,
'periods_by_day' => $periodsByDay,
'filter_form' => $filter['form']->createView(),
'week_filter' => $filter['week'],
Expand All @@ -181,24 +175,16 @@ public function indexAction(Request $request, EntityManagerInterface $em): Respo
*/
public function adminIndexAction(Request $request, EntityManagerInterface $em): Response
{
$daysOfWeek = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"];
$filter = $this->filterFormFactory($request, True);
$filter = $this->filterFormFactory($request, true);
$periodsByDay = array();
$order = array('start' => 'ASC');

foreach ($daysOfWeek as $i => $value) {
foreach (Period::DAYS_OF_WEEK as $i => $value) {
$findByFilter = array('dayOfWeek' => $i);

if ($filter['job']) {
$findByFilter['job'] = $filter['job'];
}

$periodsByDay[$i] = $em->getRepository('AppBundle:Period')
->findBy($findByFilter, $order);
$periodsByDay[$i] = $em->getRepository('AppBundle:Period')->findAll($i, $filter['job'], true);
}

return $this->render('admin/period/index.html.twig', array(
'days_of_week' => $daysOfWeek,
'days_of_week' => Period::DAYS_OF_WEEK,
'periods_by_day' => $periodsByDay,
'filter_form' => $filter['form']->createView(),
'beneficiary_filter' => $filter['beneficiary'],
Expand Down Expand Up @@ -470,20 +456,12 @@ public function deletePeriodAction(Request $request, Period $period)
* @Route("/copyPeriod/", name="period_copy", methods={"GET","POST"})
* @Security("has_role('ROLE_ADMIN')")
*/
public function copyPeriodAction(Request $request){
$days = array(
"Lundi" => 0,
"Mardi" => 1,
"Mercredi" => 2,
"Jeudi" => 3,
"Vendredi" => 4,
"Samedi" => 5,
"Dimanche" => 6,
);
public function copyPeriodAction(Request $request)
{
$form = $this->createFormBuilder()
->setAction($this->generateUrl('period_copy'))
->add('day_of_week_from', ChoiceType::class, array('label' => 'Jour de la semaine référence', 'choices' => $days))
->add('day_of_week_to', ChoiceType::class, array('label' => 'Jour de la semaine destination', 'choices' => $days))
->add('day_of_week_from', ChoiceType::class, array('label' => 'Jour de la semaine référence', 'choices' => Period::DAYS_OF_WEEK_LIST_WITH_INT))
->add('day_of_week_to', ChoiceType::class, array('label' => 'Jour de la semaine destination', 'choices' => Period::DAYS_OF_WEEK_LIST_WITH_INT))
->getForm();

$form->handleRequest($request);
Expand All @@ -508,7 +486,7 @@ public function copyPeriodAction(Request $request){
$em->flush();

$session = new Session();
$session->getFlashBag()->add('success',$count.' creneaux copiés de'.array_search($from,$days).' à '.array_search($to,$days));
$session->getFlashBag()->add('success', $count . ' creneaux copiés de' . array_search($from, Period::DAYS_OF_WEEK_LIST_WITH_INT) . ' à ' . array_search($to, Period::DAYS_OF_WEEK_LIST_WITH_INT));

return $this->redirectToRoute('period_admin');
}
Expand All @@ -522,7 +500,8 @@ public function copyPeriodAction(Request $request){
* @Route("/generateShifts/", name="shifts_generation", methods={"GET","POST"})
* @Security("has_role('ROLE_ADMIN')")
*/
public function generateShiftsForDateAction(Request $request, KernelInterface $kernel){
public function generateShiftsForDateAction(Request $request, KernelInterface $kernel)
{
$form = $this->createFormBuilder()
->setAction($this->generateUrl('shifts_generation'))
->add('date_from',TextType::class,array('label'=>'du*','attr'=>array('class'=>'datepicker')))
Expand Down
3 changes: 3 additions & 0 deletions src/AppBundle/Entity/Period.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
*/
class Period
{
const DAYS_OF_WEEK = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"];
const DAYS_OF_WEEK_LIST_WITH_INT = ["Lundi" => 0, "Mardi" => 1, "Mercredi" => 2, "Jeudi" => 3, "Vendredi" => 4, "Samedi" => 5, "Dimanche" => 6];

/**
* @var int
*
Expand Down
2 changes: 1 addition & 1 deletion src/AppBundle/Entity/Registration.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Registration
private $mode;

/**
* @ORM\ManyToOne(targetEntity="Membership", inversedBy="registrations",)
* @ORM\ManyToOne(targetEntity="Membership", inversedBy="registrations")
* @ORM\JoinColumn(name="membership_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $membership;
Expand Down
2 changes: 1 addition & 1 deletion src/AppBundle/Entity/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class User extends BaseUser
/**
* Beneficiary's user.
* @Assert\Valid()
* @ORM\OneToOne(targetEntity="Beneficiary", mappedBy="user")
* @ORM\OneToOne(targetEntity="Beneficiary", mappedBy="user", fetch="EAGER")
*/
private $beneficiary;

Expand Down
11 changes: 2 additions & 9 deletions src/AppBundle/Form/OpeningHourType.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace AppBundle\Form;

use AppBundle\Entity\OpeningHour;
use AppBundle\Entity\Period;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
Expand All @@ -19,15 +20,7 @@ class OpeningHourType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('dayOfWeek', ChoiceType::class, array('label' => 'Jour de la semaine', 'choices' => array(
"Lundi" => 0,
"Mardi" => 1,
"Mercredi" => 2,
"Jeudi" => 3,
"Vendredi" => 4,
"Samedi" => 5,
"Dimanche" => 6,
)))
->add('dayOfWeek', ChoiceType::class, array('label' => 'Jour de la semaine', 'choices' => Period::DAYS_OF_WEEK_LIST_WITH_INT))
->add('start', TextType::class, array('label' => 'Heure de début', 'attr' => array('class' => 'timepicker')))
->add('end', TextType::class, array('label' => 'Heure de fin', 'attr' => array('class' => 'timepicker')));
}
Expand Down
10 changes: 1 addition & 9 deletions src/AppBundle/Form/PeriodType.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,7 @@ class PeriodType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('day_of_week', ChoiceType::class, array('label' => 'Jour de la semaine', 'choices' => array(
"Lundi" => 0,
"Mardi" => 1,
"Mercredi" => 2,
"Jeudi" => 3,
"Vendredi" => 4,
"Samedi" => 5,
"Dimanche" => 6,
)))
->add('day_of_week', ChoiceType::class, array('label' => 'Jour de la semaine', 'choices' => Period::DAYS_OF_WEEK_LIST_WITH_INT))
->add('start', TextType::class, array('label' => 'Heure de début', 'attr' => array('class' => 'timepicker')))
->add('end', TextType::class, array('label' => 'Heure de fin', 'attr' => array('class' => 'timepicker')))
->add('job', EntityType::class, array(
Expand Down
Loading

0 comments on commit 40fc03a

Please sign in to comment.