feat: split nights off an accommodation booking as separate periods
addresses #869f6z36v
This commit is contained in:
1 parent
972839286c
commit
7001bc0cf2
35 files changed
+2221
-25
No files matched your search
@@ -8,13 +8,16 @@ use App\Email\EmailAttachmentInterface;
|
||||
use App\Email\Mailer;
|
||||
use App\Entity\Groups\Accommodation;
|
||||
use App\Entity\Groups\AccommodationBooking;
|
||||
use App\Entity\Groups\AccommodationBookingPeriod;
|
||||
use App\Entity\Groups\AccommodationPrice;
|
||||
use App\Entity\Groups\AdditionalService;
|
||||
use App\Entity\Groups\BoardService;
|
||||
use App\Enum\Groups\AccommodationBookingOrigin;
|
||||
use App\Enum\Groups\AccommodationBookingPeriodPosition;
|
||||
use App\Enum\Groups\AccommodationBookingStatus;
|
||||
use App\Exception\ImplausibleBookingPriceException;
|
||||
use App\Form\Model\AccommodationBookingDto;
|
||||
use App\Form\Model\AccommodationBookingPeriodDto;
|
||||
use App\Model\AccommodationBookingContext;
|
||||
use App\Model\AccommodationBookingQueryParams;
|
||||
use App\Model\CmsHotelData;
|
||||
@@ -25,11 +28,16 @@ use App\Repository\Groups\AdditionalServiceRepository;
|
||||
use App\Repository\Groups\BoardServiceRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Validator\ConstraintViolationListInterface;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
class AccommodationBookingService
|
||||
{
|
||||
private const int PRICING_VERSION = 1;
|
||||
/**
|
||||
* 2: the breakdown carries the split-off `periods` and `periodsTotal`, and `total` includes
|
||||
* them. Version 1 snapshots are read as bookings without periods.
|
||||
*/
|
||||
private const int PRICING_VERSION = 2;
|
||||
|
||||
public function __construct(
|
||||
private readonly AccommodationRepository $accommodationRepo,
|
||||
@@ -381,6 +389,54 @@ class AccommodationBookingService
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The three period changes below each take effect at once, like the house change: they
|
||||
* reprice the booking, and the office wants to see the new price before it goes on.
|
||||
* On violations nothing is written and the violations are returned for the modal.
|
||||
*
|
||||
* @throws ImplausibleBookingPriceException if the new total is too large to be a real price
|
||||
*/
|
||||
public function splitOffPeriod(AccommodationBooking $booking, AccommodationBookingPeriodPosition $position, AccommodationBookingPeriodDto $dto): ConstraintViolationListInterface
|
||||
{
|
||||
$booking->splitOffPeriod($position, (int) $dto->nights)
|
||||
->setLabel($dto->label)
|
||||
->setLines($dto->linesSnapshot());
|
||||
|
||||
return $this->commitPeriodChange($booking);
|
||||
}
|
||||
|
||||
/** @throws ImplausibleBookingPriceException if the new total is too large to be a real price */
|
||||
public function updatePeriod(AccommodationBooking $booking, AccommodationBookingPeriod $period, AccommodationBookingPeriodDto $dto): ConstraintViolationListInterface
|
||||
{
|
||||
$booking->resizePeriod($period, (int) $dto->nights);
|
||||
$period->setLabel($dto->label)->setLines($dto->linesSnapshot());
|
||||
|
||||
return $this->commitPeriodChange($booking);
|
||||
}
|
||||
|
||||
/** @throws ImplausibleBookingPriceException if the new total is too large to be a real price */
|
||||
public function removePeriod(AccommodationBooking $booking, AccommodationBookingPeriod $period): ConstraintViolationListInterface
|
||||
{
|
||||
$booking->removePeriod($period);
|
||||
|
||||
return $this->commitPeriodChange($booking);
|
||||
}
|
||||
|
||||
private function commitPeriodChange(AccommodationBooking $booking): ConstraintViolationListInterface
|
||||
{
|
||||
// Default only: the `edit` group asks for contact data, which a period change neither
|
||||
// shows nor touches, and which the edit form already enforces where it belongs.
|
||||
$violations = $this->validator->validate($booking, null, ['Default']);
|
||||
if (count($violations) > 0) {
|
||||
return $violations;
|
||||
}
|
||||
|
||||
$this->refreshPriceSnapshot($booking);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $violations;
|
||||
}
|
||||
|
||||
public function sendNotificationEmail(AccommodationBooking $booking): void
|
||||
{
|
||||
$this->sendBookingEmail(
|
||||
|
||||
Reference in new issue
Block a user