feat: body dimensions mandatory with selected rentals, updated help text

feat: body dimensions mandatory with selected rentals
This commit is contained in:
Björn Fromme
2026-03-16 12:02:28 +01:00
parent 957e20d763
commit 667324df69
4 changed files with 100 additions and 10 deletions
+4 -7
View File
@@ -50,17 +50,14 @@ class BodyDimensionsType extends AbstractType
{
$resolver->setDefaults([
'data_class' => ParticipantDto::class,
'height_required' => false,
'weight_required' => false,
'shoeSize_required' => false,
'height_required' => true,
'weight_required' => true,
'shoeSize_required' => true,
'height_choices' => [],
'weight_choices' => [],
'shoe_size_min' => 36,
'shoe_size_max' => 48,
'help' => 'Du kannst die Daten auch später nachreichen',
'help_attr' => [
'class' => 'lg:col-span-3 text-sm -mt-2 px-2',
],
'help' => 'Verleih kann bis 4 Tage vor Anreise in MyE&P nachgebucht werden, sollten dir (noch) nicht alle Angaben vorliegen',
]);
$resolver->setAllowedTypes('height_required', 'bool');
@@ -22,6 +22,7 @@ class ParticipantValidator extends ConstraintValidator
$participant = $value;
$this->assertPickupSelected($participant);
$this->assertBodyDimensionsWhenRentalsSelected($participant);
}
public function assertPickupSelected(ParticipantDto $participant): void
@@ -40,4 +41,34 @@ class ParticipantValidator extends ConstraintValidator
;
}
}
public function assertBodyDimensionsWhenRentalsSelected(ParticipantDto $participant): void
{
// Check if any rental services are selected
if (true === empty($participant->rentals)) {
return;
}
// Require body dimensions when rentals are selected
if (null === $participant->height || '' === $participant->height) {
$this->context->buildViolation('Bitte auswählen')
->atPath('height')
->addViolation()
;
}
if (null === $participant->weight || '' === $participant->weight) {
$this->context->buildViolation('Bitte auswählen')
->atPath('weight')
->addViolation()
;
}
if (null === $participant->shoeSize || '' === $participant->shoeSize) {
$this->context->buildViolation('Bitte auswählen')
->atPath('shoeSize')
->addViolation()
;
}
}
}
@@ -398,7 +398,12 @@
{{ form_row(form.bodyDimensions.height) }}
{{ form_row(form.bodyDimensions.shoeSize) }}
{{ form_row(form.bodyDimensions.weight) }}
{{ form_help(form.bodyDimensions) }}
<div class="lg:col-span-3 text-sm -mt-2 px-2 flex items-start space-x-1">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 flex-shrink-0">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />
</svg>
<span>{{ form.bodyDimensions.vars.help }}</span>
</div>
</div>
{% endif %}
@@ -17,17 +17,74 @@ class ParticipantValidatorTest extends ConstraintValidatorTestCase
return new ParticipantValidator();
}
public function testParticipantWithRentalsButNoBodyMeasurementsPassesValidation(): void
public function testParticipantWithRentalsAndBodyMeasurementsPassesValidation(): void
{
$participant = $this->createValidParticipant();
$participant->rentals = [$this->createMockService()];
$participant->height = '170';
$participant->weight = '70';
$participant->shoeSize = '42';
$this->validator->validate($participant, new Participant());
$this->assertNoViolation();
}
public function testParticipantWithRentalsButNoHeightFailsValidation(): void
{
$participant = $this->createValidParticipant();
$participant->rentals = [$this->createMockService()];
$participant->height = null;
$participant->weight = '70';
$participant->shoeSize = '42';
$this->validator->validate($participant, new Participant());
$this->buildViolation('Bitte auswählen')
->atPath('property.path.height')
->assertRaised();
}
public function testParticipantWithRentalsButNoWeightFailsValidation(): void
{
$participant = $this->createValidParticipant();
$participant->rentals = [$this->createMockService()];
$participant->height = '170';
$participant->weight = null;
$participant->shoeSize = '42';
$this->validator->validate($participant, new Participant());
$this->buildViolation('Bitte auswählen')
->atPath('property.path.weight')
->assertRaised();
}
public function testParticipantWithRentalsButNoShoeSizeFailsValidation(): void
{
$participant = $this->createValidParticipant();
$participant->rentals = [$this->createMockService()];
$participant->height = '170';
$participant->weight = '70';
$participant->shoeSize = null;
$this->validator->validate($participant, new Participant());
$this->buildViolation('Bitte auswählen')
->atPath('property.path.shoeSize')
->assertRaised();
}
public function testParticipantWithoutRentalsAndNoBodyMeasurementsPassesValidation(): void
{
$participant = $this->createValidParticipant();
$participant->rentals = [];
$participant->height = null;
$participant->weight = null;
$participant->shoeSize = null;
$this->validator->validate($participant, new Participant());
// Body measurements are optional and can be provided later
$this->assertNoViolation();
}