feat: dedicated terms urls per country for accommodation bookings
This commit is contained in:
@@ -267,6 +267,13 @@ services:
|
|||||||
arguments:
|
arguments:
|
||||||
$accommodationEmail: '%accommodation_inquiry_email%'
|
$accommodationEmail: '%accommodation_inquiry_email%'
|
||||||
|
|
||||||
|
App\Service\AccommodationTermsUrlProvider:
|
||||||
|
arguments:
|
||||||
|
$config:
|
||||||
|
AT: '%env(ACCOMMODATION_TERMS_AT)%'
|
||||||
|
CH: '%env(ACCOMMODATION_TERMS_CH)%'
|
||||||
|
IT: '%env(ACCOMMODATION_TERMS_IT)%'
|
||||||
|
|
||||||
App\Service\GroupsPriceCalculator:
|
App\Service\GroupsPriceCalculator:
|
||||||
arguments:
|
arguments:
|
||||||
$config:
|
$config:
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use App\Repository\Groups\AccommodationBookingRepository;
|
|||||||
use App\Service\AccommodationBookingBreakdownCalculator;
|
use App\Service\AccommodationBookingBreakdownCalculator;
|
||||||
use App\Service\AccommodationBookingLinkSigner;
|
use App\Service\AccommodationBookingLinkSigner;
|
||||||
use App\Service\AccommodationBookingService;
|
use App\Service\AccommodationBookingService;
|
||||||
|
use App\Service\AccommodationTermsUrlProvider;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
@@ -27,6 +28,7 @@ class OfferController extends AbstractController
|
|||||||
private readonly AccommodationBookingLinkSigner $linkSigner,
|
private readonly AccommodationBookingLinkSigner $linkSigner,
|
||||||
private readonly AccommodationBookingBreakdownCalculator $breakdownCalculator,
|
private readonly AccommodationBookingBreakdownCalculator $breakdownCalculator,
|
||||||
private readonly AccommodationBookingService $bookingService,
|
private readonly AccommodationBookingService $bookingService,
|
||||||
|
private readonly AccommodationTermsUrlProvider $termsUrlProvider,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +98,7 @@ class OfferController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$confirmationForm = $this->createForm(OfferAcceptConfirmationType::class, null, [
|
$confirmationForm = $this->createForm(OfferAcceptConfirmationType::class, null, [
|
||||||
'terms_url' => $this->getParameter('terms_and_conditions_url'),
|
'terms_url' => $this->termsUrlProvider->forAccommodation($booking->getAccommodation()),
|
||||||
]);
|
]);
|
||||||
$confirmationForm->handleRequest($request);
|
$confirmationForm->handleRequest($request);
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use App\Htmx\HxTrait;
|
|||||||
use App\Model\AccommodationBookingContext;
|
use App\Model\AccommodationBookingContext;
|
||||||
use App\Service\AccommodationBookingService;
|
use App\Service\AccommodationBookingService;
|
||||||
use App\Service\AccommodationSessionManager;
|
use App\Service\AccommodationSessionManager;
|
||||||
|
use App\Service\AccommodationTermsUrlProvider;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
@@ -26,6 +27,7 @@ class Step4Controller extends AbstractAccommodationController
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly AccommodationBookingService $bookingService,
|
private readonly AccommodationBookingService $bookingService,
|
||||||
private readonly AccommodationSessionManager $sessionManager,
|
private readonly AccommodationSessionManager $sessionManager,
|
||||||
|
private readonly AccommodationTermsUrlProvider $termsUrlProvider,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +96,7 @@ class Step4Controller extends AbstractAccommodationController
|
|||||||
$accommodation = $this->loadAccommodationOrFail($dto);
|
$accommodation = $this->loadAccommodationOrFail($dto);
|
||||||
|
|
||||||
$confirmationForm = $this->createForm(AccommodationBookingConfirmationType::class, $dto, [
|
$confirmationForm = $this->createForm(AccommodationBookingConfirmationType::class, $dto, [
|
||||||
'terms_url' => $this->getParameter('terms_and_conditions_url'),
|
'terms_url' => $this->termsUrlProvider->forAccommodation($accommodation),
|
||||||
]);
|
]);
|
||||||
$confirmationForm->handleRequest($request);
|
$confirmationForm->handleRequest($request);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
use App\Entity\Groups\Accommodation;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the terms and conditions a booking is concluded under.
|
||||||
|
*
|
||||||
|
* Which legal entity operates an accommodation depends on the country it is located in,
|
||||||
|
* and each entity has its own AGB document. Countries without a dedicated entity — and
|
||||||
|
* any country whose document is not configured in this environment — fall back to the
|
||||||
|
* general E&P terms.
|
||||||
|
*/
|
||||||
|
class AccommodationTermsUrlProvider
|
||||||
|
{
|
||||||
|
/** @var array<string, string> country code → terms document URL */
|
||||||
|
private array $termsUrls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, string> $config
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
array $config,
|
||||||
|
private readonly string $termsAndConditionsUrl,
|
||||||
|
) {
|
||||||
|
$this->termsUrls = $this->resolveConfig($config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function forAccommodation(?Accommodation $accommodation): string
|
||||||
|
{
|
||||||
|
$country = $accommodation?->getCountry();
|
||||||
|
$url = null !== $country ? ($this->termsUrls[$country->value] ?? '') : '';
|
||||||
|
|
||||||
|
return '' !== $url ? $url : $this->termsAndConditionsUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, string> $config
|
||||||
|
*
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
private function resolveConfig(array $config): array
|
||||||
|
{
|
||||||
|
$resolver = new OptionsResolver();
|
||||||
|
$resolver->setRequired(['AT', 'CH', 'IT']);
|
||||||
|
$resolver->setAllowedTypes('AT', 'string');
|
||||||
|
$resolver->setAllowedTypes('CH', 'string');
|
||||||
|
$resolver->setAllowedTypes('IT', 'string');
|
||||||
|
|
||||||
|
return $resolver->resolve($config);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ use App\Repository\Groups\AccommodationBookingRepository;
|
|||||||
use App\Service\AccommodationBookingBreakdownCalculator;
|
use App\Service\AccommodationBookingBreakdownCalculator;
|
||||||
use App\Service\AccommodationBookingLinkSigner;
|
use App\Service\AccommodationBookingLinkSigner;
|
||||||
use App\Service\AccommodationBookingService;
|
use App\Service\AccommodationBookingService;
|
||||||
|
use App\Service\AccommodationTermsUrlProvider;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
@@ -418,7 +419,13 @@ final class TestableOfferController extends OfferController
|
|||||||
AccommodationBookingService $bookingService,
|
AccommodationBookingService $bookingService,
|
||||||
private readonly ?FormInterface $confirmationForm = null,
|
private readonly ?FormInterface $confirmationForm = null,
|
||||||
) {
|
) {
|
||||||
parent::__construct($bookingRepository, $linkSigner, $breakdownCalculator, $bookingService);
|
parent::__construct(
|
||||||
|
$bookingRepository,
|
||||||
|
$linkSigner,
|
||||||
|
$breakdownCalculator,
|
||||||
|
$bookingService,
|
||||||
|
new AccommodationTermsUrlProvider(['AT' => '', 'CH' => '', 'IT' => ''], 'https://example.test/agb/'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createForm(string $type, mixed $data = null, array $options = []): FormInterface
|
protected function createForm(string $type, mixed $data = null, array $options = []): FormInterface
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use App\Enum\Groups\AccommodationBookingStatus;
|
|||||||
use App\Form\Model\AccommodationBookingDto;
|
use App\Form\Model\AccommodationBookingDto;
|
||||||
use App\Service\AccommodationBookingService;
|
use App\Service\AccommodationBookingService;
|
||||||
use App\Service\AccommodationSessionManager;
|
use App\Service\AccommodationSessionManager;
|
||||||
|
use App\Service\AccommodationTermsUrlProvider;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
@@ -353,7 +354,11 @@ final class TestableStep4Controller extends Step4Controller
|
|||||||
AccommodationSessionManager $sessionManager,
|
AccommodationSessionManager $sessionManager,
|
||||||
private readonly FormInterface $form,
|
private readonly FormInterface $form,
|
||||||
) {
|
) {
|
||||||
parent::__construct($bookingService, $sessionManager);
|
parent::__construct(
|
||||||
|
$bookingService,
|
||||||
|
$sessionManager,
|
||||||
|
new AccommodationTermsUrlProvider(['AT' => '', 'CH' => '', 'IT' => ''], 'https://example.test/agb/'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user