diff --git a/src/Component/Constraints/TransportInCartValidator.php b/src/Component/Constraints/TransportInCartValidator.php index 8bac37250..c28589ca3 100644 --- a/src/Component/Constraints/TransportInCartValidator.php +++ b/src/Component/Constraints/TransportInCartValidator.php @@ -13,6 +13,7 @@ use Shopsys\FrontendApiBundle\Model\Cart\CartApiFacade; use Shopsys\FrontendApiBundle\Model\Transport\Exception\InvalidTransportPaymentCombinationException; use Shopsys\FrontendApiBundle\Model\Transport\Exception\MissingPickupPlaceIdentifierException; +use Shopsys\FrontendApiBundle\Model\Transport\Exception\TransportUnavailableForProductsInCartException; use Shopsys\FrontendApiBundle\Model\Transport\Exception\TransportWeightLimitExceededException; use Shopsys\FrontendApiBundle\Model\Transport\TransportValidationFacade; use Symfony\Component\Validator\Constraint; @@ -58,6 +59,7 @@ public function validate($value, Constraint $constraint) $this->checkTransportPaymentRelation($transport, $value->cartUuid, $constraint); $this->checkRequiredPickupPlaceIdentifier($transport, $pickupPlaceIdentifier, $constraint); $this->checkPersonalPickupStoreAvailability($transport, $pickupPlaceIdentifier, $constraint); + $this->checkTransportAvailabilityForProductsInCart($transport, $value->cartUuid, $constraint); $this->checkTransportWeightLimit($transport, $value->cartUuid, $constraint); } catch (TransportNotFoundException $exception) { $this->context->buildViolation($constraint->unavailableTransportMessage) @@ -131,6 +133,28 @@ protected function checkTransportWeightLimit( } } + /** + * @param \Shopsys\FrameworkBundle\Model\Transport\Transport $transport + * @param string|null $cartUuid + * @param \Shopsys\FrontendApiBundle\Component\Constraints\TransportInCart $transportInCartConstraint + */ + protected function checkTransportAvailabilityForProductsInCart( + Transport $transport, + ?string $cartUuid, + TransportInCart $transportInCartConstraint, + ): void { + $customerUser = $this->currentCustomerUser->findCurrentCustomerUser(); + $cart = $this->cartApiFacade->getCartCreateIfNotExists($customerUser, $cartUuid); + + try { + $this->transportValidationFacade->checkTransportAvailabilityForProductsInCart($transport, $cart); + } catch (TransportUnavailableForProductsInCartException) { + $this->context->buildViolation($transportInCartConstraint->unavailableTransportMessage) + ->setCode(TransportInCart::UNAVAILABLE_TRANSPORT_ERROR) + ->addViolation(); + } + } + /** * @param \Shopsys\FrameworkBundle\Model\Transport\Transport $transport * @param string|null $cartUuid diff --git a/src/Model/Cart/TransportAndPaymentWatcherFacade.php b/src/Model/Cart/TransportAndPaymentWatcherFacade.php index 3a134038d..3b6f93300 100644 --- a/src/Model/Cart/TransportAndPaymentWatcherFacade.php +++ b/src/Model/Cart/TransportAndPaymentWatcherFacade.php @@ -15,6 +15,7 @@ use Shopsys\FrameworkBundle\Model\Payment\Payment; use Shopsys\FrameworkBundle\Model\Payment\PaymentFacade; use Shopsys\FrameworkBundle\Model\Store\Exception\StoreByUuidNotFoundException; +use Shopsys\FrameworkBundle\Model\Transport\Exception\TransportPriceNotFoundException; use Shopsys\FrameworkBundle\Model\Transport\Transport; use Shopsys\FrameworkBundle\Model\Transport\TransportFacade; use Shopsys\FrameworkBundle\Model\TransportAndPayment\FreeTransportAndPaymentFacade; @@ -22,7 +23,7 @@ use Shopsys\FrontendApiBundle\Model\Payment\Exception\PaymentPriceChangedException; use Shopsys\FrontendApiBundle\Model\Payment\PaymentValidationFacade; use Shopsys\FrontendApiBundle\Model\Transport\Exception\TransportPriceChangedException; -use Shopsys\FrontendApiBundle\Model\Transport\Exception\TransportWeightLimitExceededException; +use Shopsys\FrontendApiBundle\Model\Transport\Exception\TransportUnavailableForProductsInCartException; use Shopsys\FrontendApiBundle\Model\Transport\TransportValidationFacade; class TransportAndPaymentWatcherFacade @@ -67,6 +68,7 @@ public function checkTransportAndPayment( Cart $cart, ): CartWithModificationsResult { $this->cartWithModificationsResult = $cartWithModificationsResult; + $this->checkTransport($cart); $domainId = $this->domain->getId(); @@ -96,7 +98,6 @@ public function checkTransportAndPayment( ); $this->cartWithModificationsResult->setRoundingPrice($orderData->totalPricesByItemType[OrderItemTypeEnum::TYPE_ROUNDING]); - $this->checkTransport($cart); $this->checkPayment($cart); return $this->cartWithModificationsResult; @@ -106,13 +107,16 @@ public function checkTransportAndPayment( * @param \Shopsys\FrameworkBundle\Model\Transport\Transport $transport * @param \Shopsys\FrameworkBundle\Model\Cart\Cart $cart */ - protected function checkTransportPrice(Transport $transport, Cart $cart): void + protected function checkTransportPriceAndWeightLimit(Transport $transport, Cart $cart): void { try { - $this->transportValidationFacade->checkTransportPrice($transport, $cart); + $this->transportValidationFacade->checkTransportPriceAndWeightLimit($transport, $cart); } catch (TransportPriceChangedException $exception) { $this->cartWithModificationsResult->setTransportPriceChanged(true); $this->cartTransportFacade->setTransportWatchedPrice($cart, $exception->getCurrentTransportPrice()->getPriceWithVat()); + } catch (TransportPriceNotFoundException) { + $this->cartWithModificationsResult->setTransportWeightLimitExceeded(true); + $this->cartTransportFacade->unsetCartTransport($cart); } } @@ -134,12 +138,12 @@ protected function checkPaymentPrice(Cart $cart, Payment $payment): void * @param \Shopsys\FrameworkBundle\Model\Transport\Transport $transport * @param \Shopsys\FrameworkBundle\Model\Cart\Cart $cart */ - protected function checkTransportWeightLimit(Transport $transport, Cart $cart): void + protected function checkTransportAvailabilityForProductsInCart(Transport $transport, Cart $cart): void { try { - $this->transportValidationFacade->checkTransportWeightLimit($transport, $cart); - } catch (TransportWeightLimitExceededException) { - $this->cartWithModificationsResult->setTransportWeightLimitExceeded(true); + $this->transportValidationFacade->checkTransportAvailabilityForProductsInCart($transport, $cart); + } catch (TransportUnavailableForProductsInCartException) { + $this->cartWithModificationsResult->setTransportIsUnavailable(); $this->cartTransportFacade->unsetCartTransport($cart); } } @@ -194,8 +198,13 @@ protected function checkTransport(Cart $cart): void return; } - $this->checkTransportPrice($transport, $cart); - $this->checkTransportWeightLimit($transport, $cart); + + $this->checkTransportPriceAndWeightLimit($transport, $cart); + + if ($cart->getTransport() === null) { + return; + } + $this->checkTransportAvailabilityForProductsInCart($transport, $cart); $this->checkPersonalPickupStoreAvailability($transport, $cart); $this->checkPacketeryIdIsValid($transport, $cart); } diff --git a/src/Model/Resolver/Price/PriceQuery.php b/src/Model/Resolver/Price/PriceQuery.php index f60b35a82..7be491dc5 100644 --- a/src/Model/Resolver/Price/PriceQuery.php +++ b/src/Model/Resolver/Price/PriceQuery.php @@ -162,9 +162,7 @@ public function priceByTransportQuery( protected function calculateIndependentTransportPrice(Transport $transport): Price { return $this->transportPriceCalculation->calculateIndependentPrice( - $transport, - $this->currencyFacade->getDomainDefaultCurrencyByDomainId($this->domain->getId()), - $this->domain->getId(), + $transport->getLowestPriceOnDomain($this->domain->getId()), ); } } diff --git a/src/Model/Resolver/Transport/TransportsQuery.php b/src/Model/Resolver/Transport/TransportsQuery.php index bb398e344..6447072bf 100644 --- a/src/Model/Resolver/Transport/TransportsQuery.php +++ b/src/Model/Resolver/Transport/TransportsQuery.php @@ -41,6 +41,6 @@ public function transportsQuery(?string $cartUuid = null): array return $this->transportFacade->getVisibleOnCurrentDomainWithEagerLoadedDomainsAndTranslations(); } - return $this->transportFacade->getVisibleOnCurrentDomainWithEagerLoadedDomainsAndTranslations($cart->getTotalWeight()); + return $this->transportFacade->getVisibleOnCurrentDomainWithEagerLoadedDomainsAndTranslations($cart); } } diff --git a/src/Model/Transport/Exception/TransportUnavailableForProductsInCartException.php b/src/Model/Transport/Exception/TransportUnavailableForProductsInCartException.php new file mode 100644 index 000000000..e9e8cdb7d --- /dev/null +++ b/src/Model/Transport/Exception/TransportUnavailableForProductsInCartException.php @@ -0,0 +1,11 @@ +getMaxWeight() !== null && $transport->getMaxWeight() < $cart->getTotalWeight()) { + try { + $this->transportPriceFacade->getTransportPriceOnDomainByTransportAndClosestWeight( + $this->domain->getId(), + $transport, + $cart->getTotalWeight(), + ); + } catch (TransportPriceNotFoundException) { throw new TransportWeightLimitExceededException(); } } @@ -65,7 +79,18 @@ public function checkTransportWeightLimit(Transport $transport, Cart $cart): voi * @param \Shopsys\FrameworkBundle\Model\Transport\Transport $transport * @param \Shopsys\FrameworkBundle\Model\Cart\Cart $cart */ - public function checkTransportPrice(Transport $transport, Cart $cart): void + public function checkTransportAvailabilityForProductsInCart(Transport $transport, Cart $cart): void + { + if ($this->transportVisibilityCalculation->filterTransportsByProductsInCart([$transport], $cart) === []) { + throw new TransportUnavailableForProductsInCartException(); + } + } + + /** + * @param \Shopsys\FrameworkBundle\Model\Transport\Transport $transport + * @param \Shopsys\FrameworkBundle\Model\Cart\Cart $cart + */ + public function checkTransportPriceAndWeightLimit(Transport $transport, Cart $cart): void { $calculatedTransportPrice = $this->transportPriceProvider->getTransportPrice( $cart,