feat: implement mutability cutoff for rentals

addresses #869cca42x
This commit is contained in:
Björn Fromme committed 2026-03-17 10:29:43 +01:00
1 parent 752e6752b4
commit cb56a4fe46
9 files changed
+253 -8

No files matched your search

+26 -5
View File
@@ -10,6 +10,7 @@ use App\BusProNet\Model\Pickup;
use App\BusProNet\Model\Service;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Form\Service\Condition\TravelStartCutoffReachedCondition;
/**
* Enforces immutable edit categories before submitting booking updates.
@@ -34,6 +35,14 @@ class BookingEditSubmitGuardService
public function reconcileImmutableCategories(BookingDto $workingDto, Booking $freshBooking): bool
{
$baselineDto = $this->bookingDataProcessor->createBookingDtoFromBooking($freshBooking, $workingDto->travel);
// Booking-level D-4 cutoff used as submit-time safety net for rentals.
$serviceCutoffReachedCondition = new TravelStartCutoffReachedCondition(
TravelStartCutoffReachedCondition::DEFAULT_DAYS_BEFORE_START
);
// TravelStartCutoffReachedCondition is booking-level (travel date only).
// The interface requires a participant index, but this condition does not use it,
// so we pass 0 as a neutral placeholder.
$rentalsLockedByCutoff = $serviceCutoffReachedCondition->evaluate($workingDto, 0, []);
$changed = false;
@@ -47,6 +56,12 @@ class BookingEditSubmitGuardService
$changed = $this->reconcileAdditionalServices($participant, $baseline) || $changed;
}
// Reconcile rentals either when BPN additional services are immutable
// or when our D-4 rule has been reached.
if (false === $workingDto->travel->additionalServicesMutable || $rentalsLockedByCutoff) {
$changed = $this->reconcileRentals($participant, $baseline) || $changed;
}
if (false === $workingDto->travel->transportationServicesMutable) {
$changed = $this->reconcileTransportationServices($participant, $baseline) || $changed;
}
@@ -78,11 +93,6 @@ class BookingEditSubmitGuardService
$changed = true;
}
if (false === $this->areServiceListsEqual($participant->rentals, $baseline->rentals)) {
$participant->rentals = $baseline->rentals;
$changed = true;
}
if (false === $this->isSameService($participant->skiPass, $baseline->skiPass)) {
$participant->skiPass = $baseline->skiPass;
$changed = true;
@@ -101,6 +111,17 @@ class BookingEditSubmitGuardService
return $changed;
}
private function reconcileRentals(ParticipantDto $participant, ParticipantDto $baseline): bool
{
if (false === $this->areServiceListsEqual($participant->rentals, $baseline->rentals)) {
$participant->rentals = $baseline->rentals;
return true;
}
return false;
}
private function reconcileTransportationServices(ParticipantDto $participant, ParticipantDto $baseline): bool
{
$changed = false;