feat: pre-flight check of agency bookings

addresses #869bqxr4q
This commit is contained in:
Björn Fromme
2026-07-10 14:33:09 +02:00
parent f9142e3080
commit b41b19d4c6
26 changed files with 1818 additions and 304 deletions
+94 -2
View File
@@ -7,10 +7,14 @@ namespace App\Tests\Service;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\ConstraintViolationList;
use App\BusProNet\Model\Booking;
use App\BusProNet\Model\Room;
use App\BusProNet\Model\Surcharge;
use App\BusProNet\Model\Travel;
use App\BusProNet\XmlLoader\AgencyLoader;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Form\Model\ParticipantEditDto;
use App\Service\BookingPriceCalculator;
use App\Service\ParticipantCardAssembler;
use PHPUnit\Framework\TestCase;
@@ -278,7 +282,7 @@ class ParticipantCardAssemblerTest extends TestCase
// Mock price calculation
$this->priceCalculator
->expects($this->exactly(3))
->expects($this->once())
->method('calculateAllParticipantIndividualPrices')
->with($bookingDto)
->willReturn([450.0, 500.0, 480.0]);
@@ -306,6 +310,50 @@ class ParticipantCardAssemblerTest extends TestCase
$this->assertFalse($result[2]->price->showDash);
}
public function testGetAllCardsDataUsesCanceledSurchargesBeforePrecomputedActivePrices(): void
{
$room = new Room();
$room->id = 1;
$room->label = 'Doppelzimmer';
$travel = new Travel();
$travel->rooms = [$room];
$activeParticipant = new ParticipantDto();
$activeParticipant->firstName = 'Max';
$activeParticipant->lastName = 'Mustermann';
$activeParticipant->assignedRoomId = 1;
$canceledParticipant = new ParticipantDto();
$canceledParticipant->firstName = 'Anna';
$canceledParticipant->lastName = 'Schmidt';
$canceledParticipant->assignedRoomId = 1;
$surcharge = new Surcharge();
$surcharge->mapping = [1];
$surcharge->individualPrice = [1 => 75.0];
$booking = new Booking();
$booking->participantsStatus = [0 => 'A', 1 => 'S'];
$booking->surcharges = [$surcharge];
$bookingDto = new BookingDto($travel, 1);
$bookingDto->booking = $booking;
$bookingDto->participants = [$activeParticipant, $canceledParticipant];
$this->priceCalculator
->expects($this->once())
->method('calculateAllParticipantIndividualPrices')
->with($bookingDto)
->willReturn([0 => 450.0, 1 => 999.0]);
$result = $this->service->getAllCardsData($bookingDto);
$this->assertSame(450.0, $result[0]->price->amount);
$this->assertSame(75.0, $result[1]->price->amount);
$this->assertFalse($result[1]->price->showDash);
}
public function testGetAllCardsDataWithEmptyParticipants(): void
{
$travel = new Travel();
@@ -471,7 +519,7 @@ class ParticipantCardAssemblerTest extends TestCase
$bookingDto->participants = [$participant1, $participant2];
$this->priceCalculator
->expects($this->exactly(2))
->expects($this->once())
->method('calculateAllParticipantIndividualPrices')
->willReturn([450.0, 500.0]);
@@ -494,4 +542,48 @@ class ParticipantCardAssemblerTest extends TestCase
$this->assertSame('Max Mustermann', $result[0]->name);
$this->assertSame('Anna Schmidt', $result[1]->name);
}
public function testGetCardDataWithValidationCanForceStrictRequiredInEditMode(): void
{
$travel = new Travel();
$travel->rooms = [];
$participant = new ParticipantDto();
$participant->index = 0;
$participant->firstName = null;
$participant->lastName = 'Mustermann';
$participant->email = '[email protected]';
$bookingDto = new BookingDto($travel, 1);
$bookingDto->agencyCode = AgencyLoader::INTERNAL_AGENCY_CODE;
$bookingDto->booking = new \App\BusProNet\Model\Booking();
$bookingDto->participants = [$participant];
$this->priceCalculator
->method('calculateAllParticipantIndividualPrices')
->willReturn([0.0]);
$violation = $this->createMock(ConstraintViolationInterface::class);
$violation->expects($this->once())
->method('getMessage')
->willReturn('Bitte angeben');
$violations = new ConstraintViolationList([$violation]);
$this->validator
->expects($this->once())
->method('validate')
->with(
$this->isInstanceOf(\App\Form\Model\ParticipantEditDto::class),
null,
['booking_edit', 'strict_required']
)
->willReturn($violations);
$result = $this->service->getCardDataWithValidation($bookingDto, 0, true);
$this->assertFalse($result->isValid);
$this->assertSame(['Bitte angeben'], $result->errorMessages);
}
}