Skip to content

Commit

Permalink
Regulation order visas (#997)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmarchois authored Oct 10, 2024
1 parent 88e8aef commit 33101e0
Show file tree
Hide file tree
Showing 12 changed files with 296 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@
<option name="type">\DateTimeInterface</option>
</constraint>
</property>
<property name="additionalVisas">
<constraint name="All">
<option name="constraints">
<constraint name="NotBlank"/>
</option>
</constraint>
</property>
<property name="additionalReasons">
<constraint name="All">
<option name="constraints">
<constraint name="NotBlank"/>
</option>
</constraint>
</property>
<constraint name="App\Infrastructure\Validator\SaveRegulationGeneralInfoCommandConstraint" />
</class>
</constraint-mapping>
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ private function duplicateRegulationOrderRecord(
$generalInfo->description = $originalRegulationOrder->getDescription();
$generalInfo->startDate = $originalRegulationOrder->getStartDate();
$generalInfo->endDate = $originalRegulationOrder->getEndDate();
$generalInfo->additionalVisas = $originalRegulationOrder->getAdditionalVisas();
$generalInfo->additionalReasons = $originalRegulationOrder->getAdditionalReasons();

return $this->commandBus->handle($generalInfo);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ final class SaveRegulationGeneralInfoCommand implements CommandInterface
public ?Organization $organization;
public ?\DateTimeInterface $startDate;
public ?\DateTimeInterface $endDate = null;
public array $additionalVisas = [];
public array $additionalReasons = [];

public function __construct(
public readonly ?RegulationOrderRecord $regulationOrderRecord = null,
Expand All @@ -40,6 +42,8 @@ public static function create(
$command->description = $regulationOrder?->getDescription();
$command->startDate = $startDate ?? $regulationOrder?->getStartDate();
$command->endDate = $regulationOrder?->getEndDate();
$command->additionalVisas = $regulationOrder?->getAdditionalVisas() ?? [];
$command->additionalReasons = $regulationOrder?->getAdditionalReasons() ?? [];

return $command;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public function __invoke(SaveRegulationGeneralInfoCommand $command): RegulationO
startDate: $command->startDate,
endDate: $command->endDate,
otherCategoryText: $command->otherCategoryText,
additionalVisas: $command->additionalVisas,
additionalReasons: $command->additionalReasons,
),
);

Expand All @@ -61,6 +63,8 @@ public function __invoke(SaveRegulationGeneralInfoCommand $command): RegulationO
startDate: $command->startDate,
endDate: $command->endDate,
otherCategoryText: $command->otherCategoryText,
additionalVisas: $command->additionalVisas,
additionalReasons: $command->additionalReasons,
);

return $command->regulationOrderRecord;
Expand Down
6 changes: 5 additions & 1 deletion src/Domain/Regulation/RegulationOrder.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public function getAdditionalVisas(): ?array
return $this->additionalVisas;
}

public function getaAdditionalReasons(): ?array
public function getAdditionalReasons(): ?array
{
return $this->additionalReasons;
}
Expand All @@ -107,12 +107,16 @@ public function update(
\DateTimeInterface $startDate,
?\DateTimeInterface $endDate = null,
?string $otherCategoryText = null,
array $additionalVisas = [],
array $additionalReasons = [],
): void {
$this->identifier = $identifier;
$this->category = $category;
$this->description = $description;
$this->startDate = $startDate;
$this->endDate = $endDate;
$this->otherCategoryText = $otherCategoryText;
$this->additionalVisas = $additionalVisas;
$this->additionalReasons = $additionalReasons;
}
}
33 changes: 33 additions & 0 deletions src/Infrastructure/Form/Regulation/GeneralInfoFormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
Expand Down Expand Up @@ -93,6 +94,38 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'help' => 'regulation.general_info.description.help',
],
)
->add(
'additionalVisas',
CollectionType::class,
options: [
'entry_type' => TextareaType::class,
'label' => null,
'prototype_name' => '__visa_name__',
'entry_options' => [
'label' => 'regulation.general_info.visa',
],
'allow_add' => true,
'allow_delete' => true,
'keep_as_list' => true,
'error_bubbling' => false,
],
)
->add(
'additionalReasons',
CollectionType::class,
options: [
'entry_type' => TextareaType::class,
'label' => null,
'prototype_name' => '__reason_name__',
'entry_options' => [
'label' => 'regulation.general_info.reason',
],
'allow_add' => true,
'allow_delete' => true,
'keep_as_list' => true,
'error_bubbling' => false,
],
)
->add(
'save',
SubmitType::class,
Expand Down
143 changes: 119 additions & 24 deletions templates/regulation/_general_info_form.html.twig
Original file line number Diff line number Diff line change
@@ -1,33 +1,128 @@
{% macro collection_item(form, index) %}
<li
class="app-card app-card--no-header fr-mb-2w"
data-controller="remove"
data-remove-target="this"
data-form-collection-target="collectionItem"
>
<div class="app-card__content">
{{ form_row(form, {group_class: 'fr-input-group', attr: {class: 'fr-input'}}) }}
</div>
<div class="app-card__actions">
<button
type="button"
class="fr-btn fr-btn--sm fr-btn--secondary fr-icon-delete-bin-line"
data-action="remove#removeElement"
aria-label="{{ 'common.delete'|trans }}"
>
</button>
</div>
</li>
{% endmacro %}

<div class="app-card app-card--raised">
<div class="app-card__header">
<span class="app-card__img fr-icon-article-fill fr-x-icon-decorative--blue-france fr-x-icon--xl" aria-hidden="true"></span>
<h3 class="app-card__title fr-h4 fr-mb-0">
{{ form.description.vars.value|default('regulation.general_info'|trans)|u.truncate(36, '...', false) }}
</h3>
</div>
<div class="app-card__content">
{{ form_start(form) }}
{{ form_row(form.identifier, {group_class: 'fr-input-group', widget_class: 'fr-input'}) }}
{{ form_row(form.organization, {group_class: 'fr-select-group', widget_class: 'fr-select'}) }}
<div class="fr-fieldset" data-controller="form-reveal">
<div class="fr-fieldset__element">
{{ form_row(form.category, {
group_class: 'fr-select-group',
widget_class: 'fr-select',
attr: {
'data-controller': 'condition',
'data-condition-equals-value': 'other',
'data-action': 'change->condition#dispatchFromInputChange condition:yes->form-reveal#open condition:no->form-reveal#close',
}
}) }}
<div class="fr-tabs fr-mb-3w">
<ul class="fr-tabs__list" role="tablist" aria-label="{{ 'regulation.general_info'|trans }}">
<li role="presentation">
<button type="button" id="general-form" class="fr-tabs__tab" tabindex="0" role="tab" aria-selected="true" aria-controls="general-form-panel">
{{ 'regulation.general_info'|trans }}
</button>
</li>
<li role="presentation">
<button type="button" id="reasons" class="fr-tabs__tab" tabindex="-1" role="tab" aria-selected="false" aria-controls="reasons-panel">
{{ 'regulation.general_info.visas_and_reasons'|trans }}
</button>
</li>
</ul>
<div id="general-form-panel" class="fr-tabs__panel fr-tabs__panel--selected" role="tabpanel" aria-labelledby="general-form" tabindex="0">
{{ form_row(form.identifier, {group_class: 'fr-input-group', widget_class: 'fr-input'}) }}
{{ form_row(form.organization, {group_class: 'fr-select-group', widget_class: 'fr-select'}) }}
<div class="fr-fieldset" data-controller="form-reveal">
<div class="fr-fieldset__element">
{{ form_row(form.category, {
group_class: 'fr-select-group',
widget_class: 'fr-select',
attr: {
'data-controller': 'condition',
'data-condition-equals-value': 'other',
'data-action': 'change->condition#dispatchFromInputChange condition:yes->form-reveal#open condition:no->form-reveal#close',
}
}) }}
</div>
<div id="otherCategoryText-output" class="fr-fieldset__element" data-form-reveal-target="section" {% if form.category.vars.value != 'other' %}hidden{% endif %}>
{{ form_row(form.otherCategoryText, { group_class: 'fr-input-group', widget_class: 'fr-input', attr: { 'data-form-reveal-target': 'form-control' } }) }}
</div>
</div>
{{ form_row(form.description, {group_class: 'fr-input-group', attr: {class: 'fr-input'}, help_attr: {class: 'fr-hint-text'}}) }}
{{ form_row(form.startDate, {group_class: 'fr-input-group', widget_class: 'fr-input', row_attr: {class: 'fr-col-12 fr-col-sm-6 fr-col-lg-5'}}) }}
{{ form_row(form.endDate, {group_class: 'fr-input-group', widget_class: 'fr-input', row_attr: {class: 'fr-col-12 fr-col-sm-6 fr-col-lg-5'}}) }}
</div>
<div id="otherCategoryText-output" class="fr-fieldset__element" data-form-reveal-target="section" {% if form.category.vars.value != 'other' %}hidden{% endif %}>
{{ form_row(form.otherCategoryText, { group_class: 'fr-input-group', widget_class: 'fr-input', attr: { 'data-form-reveal-target': 'form-control' } }) }}
<div id="reasons-panel" class="fr-tabs__panel" role="tabpanel" aria-labelledby="reasons" tabindex="0">
<p>{{ 'regulation.general_info.visas_and_reasons.description'|trans }}</p>
<div
class="fr-mb-2w"
data-controller="form-collection"
data-form-collection-prototype-key-value="visa"
data-form-collection-next-index-value="{{ form.additionalVisas|length > 0 ? form.additionalVisas|last.vars.name + 1 : 0 }}"
data-form-collection-prototype-value="{{ _self.collection_item(form.additionalVisas.vars.prototype, '__visa_name__')|e('html_attr') }}"
>
<h3 class="fr-h4">{{ 'regulation.general_info.visas'|trans }}</h3>
<p class="fr-text--sm">{{ 'regulation.general_info.visas.help'|trans }}</p>
{{ form_errors(form.additionalVisas) }}
<ul
id="visa-list"
class="fr-raw-list"
data-form-collection-target="collectionContainer"
>
{% for item in form.additionalVisas %}
{{ _self.collection_item(item) }}
{% else %}
{% do form.additionalVisas.setRendered %}
{% endfor %}
</ul>
<button
type="button"
class="fr-btn fr-btn--tertiary fr-btn--icon-left fr-icon-add-line"
data-action="form-collection#addCollectionElement"
aria-controls="visa-list"
>
{{ 'visa.add'|trans }}
</button>
</div>
<div
class="fr-mb-2w"
data-controller="form-collection"
data-form-collection-prototype-key-value="reason"
data-form-collection-next-index-value="{{ form.additionalReasons|length > 0 ? form.additionalReasons|last.vars.name + 1 : 0 }}"
data-form-collection-prototype-value="{{ _self.collection_item(form.additionalReasons.vars.prototype, '__reason_name__')|e('html_attr') }}"
>
<h3 class="fr-h4">{{ 'regulation.general_info.reasons'|trans }}</h3>
<p class="fr-text--sm">{{ 'regulation.general_info.reasons.help'|trans }}</p>
{{ form_errors(form.additionalReasons) }}
<ul
id="reason-list"
class="fr-raw-list"
data-form-collection-target="collectionContainer"
>
{% for item in form.additionalReasons %}
{{ _self.collection_item(item) }}
{% else %}
{% do form.additionalReasons.setRendered %}
{% endfor %}
</ul>
<button
type="button"
class="fr-btn fr-btn--tertiary fr-btn--icon-left fr-icon-add-line"
data-action="form-collection#addCollectionElement"
aria-controls="reason-list"
>
{{ 'regulation.general_info.reasons.add'|trans }}
</button>
</div>
</div>
</div>
{{ form_row(form.description, {group_class: 'fr-input-group', attr: {class: 'fr-input'}, help_attr: {class: 'fr-hint-text'}}) }}
{{ form_row(form.startDate, {group_class: 'fr-input-group', widget_class: 'fr-input', row_attr: {class: 'fr-col-12 fr-col-sm-6 fr-col-lg-5'}}) }}
{{ form_row(form.endDate, {group_class: 'fr-input-group', widget_class: 'fr-input', row_attr: {class: 'fr-col-12 fr-col-sm-6 fr-col-lg-5'}}) }}
<a href="{{ cancelUrl }}" class="fr-btn fr-btn--tertiary fr-mr-3w">
{{ "common.cancel"|trans }}
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ public function testAdd(): void
$this->assertSecurityHeaders();
$this->assertSame('Nouvel arrêté', $crawler->filter('h2')->text());
$this->assertMetaTitle('Nouvel arrêté - DiaLog', $crawler);
$this->assertSame('Informations générales', $crawler->filter('h3')->text());

$this->assertSame('Brouillon', $crawler->filter('[data-testid="status-badge"]')->text());
$this->assertSame('', $crawler->selectButton('Publier')->attr('disabled'));
Expand All @@ -34,21 +33,29 @@ public function testAdd(): void
$saveButton = $crawler->selectButton('Continuer');
$form = $saveButton->form();
$this->assertSame('2023-05-10', $form->get('general_info_form[startDate]')->getValue()); // Init with tomorrow date
$form['general_info_form[identifier]'] = 'F022023';
$form['general_info_form[organization]'] = OrganizationFixture::MAIN_ORG_ID;
$form['general_info_form[description]'] = 'Interdiction de circuler dans Paris';
$form['general_info_form[startDate]'] = '2023-02-14';
$form['general_info_form[category]'] = RegulationOrderCategoryEnum::OTHER->value;
$form['general_info_form[otherCategoryText]'] = 'Trou en formation';

/** @var UserRepositoryInterface */
$userRepository = static::getContainer()->get(UserRepositoryInterface::class);
$this->assertNull($userRepository->findOneByEmail($email)->getLastActiveAt());
$client->submit($form);

// Get the raw values.
$values = $form->getPhpValues();
$values['general_info_form']['identifier'] = 'F022023';
$values['general_info_form']['organization'] = OrganizationFixture::MAIN_ORG_ID;
$values['general_info_form']['description'] = 'Interdiction de circuler dans Paris';
$values['general_info_form']['startDate'] = '2023-02-14';
$values['general_info_form']['category'] = RegulationOrderCategoryEnum::OTHER->value;
$values['general_info_form']['otherCategoryText'] = 'Trou en formation';
$values['general_info_form']['additionalVisas'][0] = 'Vu 1';
$values['general_info_form']['additionalVisas'][1] = 'Vu 2';
$values['general_info_form']['additionalReasons'][0] = 'Motif 1';
$values['general_info_form']['additionalReasons'][1] = 'Motif 2';
$crawler = $client->request($form->getMethod(), $form->getUri(), $values, $form->getPhpFiles());

$this->assertResponseStatusCodeSame(303);
$this->assertEquals(new \DateTimeImmutable('2023-06-09'), $userRepository->findOneByEmail($email)->getLastActiveAt());

$client->followRedirect();

$this->assertResponseStatusCodeSame(200);
$this->assertRouteSame('app_regulation_detail');
}
Expand Down
Loading

0 comments on commit 33101e0

Please sign in to comment.