fix: don't auto assign discounted transport to babies
This commit is contained in:
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Form\Service;
|
namespace App\Form\Service;
|
||||||
|
|
||||||
|
use App\BusProNet\Constants;
|
||||||
use App\BusProNet\Utility\DirectionMapper;
|
use App\BusProNet\Utility\DirectionMapper;
|
||||||
use App\Form\Model\BookingDto;
|
use App\Form\Model\BookingDto;
|
||||||
use App\Form\Service\Abstract\AbstractParticipantFieldHandler;
|
use App\Form\Service\Abstract\AbstractParticipantFieldHandler;
|
||||||
@@ -119,6 +120,12 @@ class ParticipantTransportationDiscountReplacementFieldHandler extends AbstractP
|
|||||||
// Step 4b: Handle non-BUS inbound scenario (restore discount if available)
|
// Step 4b: Handle non-BUS inbound scenario (restore discount if available)
|
||||||
// Inbound is NOT BUS - try to restore discounted PKW if available
|
// Inbound is NOT BUS - try to restore discounted PKW if available
|
||||||
|
|
||||||
|
// Baby participants never get discounted transportation
|
||||||
|
$age = $participant->getAge($bookingDto->travel->dateFrom);
|
||||||
|
if (null !== $age && $age <= Constants::BABY_MAX_AGE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if outbound is currently REGULAR PKW
|
// Check if outbound is currently REGULAR PKW
|
||||||
$outboundIsRegularPkw = DirectionMapper::isCar($participant->transportationOutbound->subType)
|
$outboundIsRegularPkw = DirectionMapper::isCar($participant->transportationOutbound->subType)
|
||||||
&& (null === $participant->transportationOutbound->price
|
&& (null === $participant->transportationOutbound->price
|
||||||
|
|||||||
@@ -312,6 +312,117 @@ class ParticipantTransportationDiscountReplacementFieldHandlerTest extends TestC
|
|||||||
$this->expectNotToPerformAssertions();
|
$this->expectNotToPerformAssertions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testProcessFieldSkipsDiscountRestorationForBabyParticipant(): void
|
||||||
|
{
|
||||||
|
// Setup services
|
||||||
|
$discountedPkw = $this->createPkwService(100, 'Selbstorganisiert (-15€ Rabatt)', -15.0);
|
||||||
|
$regularPkw = $this->createPkwService(101, 'Selbstorganisiert', 0.0);
|
||||||
|
$pkwInbound = $this->createPkwService(201, 'Selbstorganisiert', 0.0, DirectionMapper::INBOUND_TRAVEL);
|
||||||
|
|
||||||
|
// Setup baby participant (age 1) with regular PKW outbound and PKW inbound
|
||||||
|
$participant = new ParticipantDto();
|
||||||
|
$participant->dateOfBirth = new \DateTimeImmutable('-1 year');
|
||||||
|
$participant->transportationOutbound = $regularPkw;
|
||||||
|
$participant->transportationInbound = $pkwInbound;
|
||||||
|
|
||||||
|
// Setup booking with travel services - travel starts today
|
||||||
|
$travel = $this->createTravelWithServices([$discountedPkw, $regularPkw, $pkwInbound]);
|
||||||
|
$travel->dateFrom = new \DateTimeImmutable('today');
|
||||||
|
$bookingDto = new BookingDto($travel, 1);
|
||||||
|
$bookingDto->participants = [$participant];
|
||||||
|
|
||||||
|
// Availability calculator should NOT be called for babies
|
||||||
|
$this->serviceAvailabilityCalculator
|
||||||
|
->expects($this->never())
|
||||||
|
->method('isServiceUnavailable');
|
||||||
|
|
||||||
|
$submittedData = [];
|
||||||
|
|
||||||
|
// Process
|
||||||
|
$this->handler->processField($submittedData, $bookingDto, 0);
|
||||||
|
|
||||||
|
// Assert outbound remains regular PKW (no discount restoration for babies)
|
||||||
|
$this->assertSame($regularPkw->id, $participant->transportationOutbound->id);
|
||||||
|
|
||||||
|
// Assert no notification was generated
|
||||||
|
$this->assertEmpty($participant->notifications);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testProcessFieldSkipsDiscountRestorationForTwoYearOldParticipant(): void
|
||||||
|
{
|
||||||
|
// Setup services
|
||||||
|
$discountedPkw = $this->createPkwService(100, 'Selbstorganisiert (-15€ Rabatt)', -15.0);
|
||||||
|
$regularPkw = $this->createPkwService(101, 'Selbstorganisiert', 0.0);
|
||||||
|
$pkwInbound = $this->createPkwService(201, 'Selbstorganisiert', 0.0, DirectionMapper::INBOUND_TRAVEL);
|
||||||
|
|
||||||
|
// Setup participant at BABY_MAX_AGE (2 years) with regular PKW
|
||||||
|
$participant = new ParticipantDto();
|
||||||
|
$participant->dateOfBirth = new \DateTimeImmutable('-2 years');
|
||||||
|
$participant->transportationOutbound = $regularPkw;
|
||||||
|
$participant->transportationInbound = $pkwInbound;
|
||||||
|
|
||||||
|
// Setup booking with travel services - travel starts today
|
||||||
|
$travel = $this->createTravelWithServices([$discountedPkw, $regularPkw, $pkwInbound]);
|
||||||
|
$travel->dateFrom = new \DateTimeImmutable('today');
|
||||||
|
$bookingDto = new BookingDto($travel, 1);
|
||||||
|
$bookingDto->participants = [$participant];
|
||||||
|
|
||||||
|
// Availability calculator should NOT be called for babies
|
||||||
|
$this->serviceAvailabilityCalculator
|
||||||
|
->expects($this->never())
|
||||||
|
->method('isServiceUnavailable');
|
||||||
|
|
||||||
|
$submittedData = [];
|
||||||
|
|
||||||
|
// Process
|
||||||
|
$this->handler->processField($submittedData, $bookingDto, 0);
|
||||||
|
|
||||||
|
// Assert outbound remains regular PKW
|
||||||
|
$this->assertSame($regularPkw->id, $participant->transportationOutbound->id);
|
||||||
|
|
||||||
|
// Assert no notification was generated
|
||||||
|
$this->assertEmpty($participant->notifications);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testProcessFieldRestoresDiscountForThreeYearOldParticipant(): void
|
||||||
|
{
|
||||||
|
// Setup services
|
||||||
|
$discountedPkw = $this->createPkwService(100, 'Selbstorganisiert (-15€ Rabatt)', -15.0);
|
||||||
|
$regularPkw = $this->createPkwService(101, 'Selbstorganisiert', 0.0);
|
||||||
|
$pkwInbound = $this->createPkwService(201, 'Selbstorganisiert', 0.0, DirectionMapper::INBOUND_TRAVEL);
|
||||||
|
|
||||||
|
// Setup participant clearly above BABY_MAX_AGE (3+ years) with regular PKW
|
||||||
|
// Use specific dates to ensure age calculation is unambiguous
|
||||||
|
$participant = new ParticipantDto();
|
||||||
|
$participant->dateOfBirth = new \DateTimeImmutable('2020-01-01');
|
||||||
|
$participant->transportationOutbound = $regularPkw;
|
||||||
|
$participant->transportationInbound = $pkwInbound;
|
||||||
|
|
||||||
|
// Setup booking with travel services - travel starts well after 3rd birthday
|
||||||
|
$travel = $this->createTravelWithServices([$discountedPkw, $regularPkw, $pkwInbound]);
|
||||||
|
$travel->dateFrom = new \DateTimeImmutable('2024-06-01');
|
||||||
|
$bookingDto = new BookingDto($travel, 1);
|
||||||
|
$bookingDto->participants = [$participant];
|
||||||
|
|
||||||
|
// Mock availability: discounted PKW is available
|
||||||
|
$this->serviceAvailabilityCalculator
|
||||||
|
->expects($this->once())
|
||||||
|
->method('isServiceUnavailable')
|
||||||
|
->with($discountedPkw->id, $bookingDto, 0)
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$submittedData = [];
|
||||||
|
|
||||||
|
// Process
|
||||||
|
$this->handler->processField($submittedData, $bookingDto, 0);
|
||||||
|
|
||||||
|
// Assert outbound was replaced with discounted PKW (3-year-old is eligible)
|
||||||
|
$this->assertSame($discountedPkw->id, $participant->transportationOutbound->id);
|
||||||
|
|
||||||
|
// Assert notification was generated
|
||||||
|
$this->assertCount(1, $participant->notifications);
|
||||||
|
}
|
||||||
|
|
||||||
private function createPkwService(int $id, string $label, float $price, string $direction = DirectionMapper::OUTBOUND_TRAVEL): Service
|
private function createPkwService(int $id, string $label, float $price, string $direction = DirectionMapper::OUTBOUND_TRAVEL): Service
|
||||||
{
|
{
|
||||||
$service = new Service();
|
$service = new Service();
|
||||||
|
|||||||
Reference in New Issue
Block a user