mirror of
https://github.com/bdnugget/magento2.git
synced 2026-11-07 09:17:35 +00:00
297 lines
10 KiB
PHP
297 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
namespace Magento\Checkout\Model;
|
|
|
|
use Magento\Checkout\Api\Data\PaymentDetailsInterface;
|
|
use Magento\Checkout\Api\Data\ShippingInformationInterface;
|
|
use Magento\Checkout\Api\ShippingInformationManagementInterface;
|
|
use Magento\Customer\Api\AddressRepositoryInterface;
|
|
use Magento\Framework\App\Config\ScopeConfigInterface;
|
|
use Magento\Framework\App\ObjectManager;
|
|
use Magento\Framework\Exception\InputException;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use Magento\Framework\Exception\NoSuchEntityException;
|
|
use Magento\Framework\Exception\StateException;
|
|
use Magento\Quote\Api\CartRepositoryInterface;
|
|
use Magento\Quote\Api\CartTotalRepositoryInterface;
|
|
use Magento\Quote\Api\Data\AddressInterface;
|
|
use Magento\Quote\Api\Data\CartExtensionFactory;
|
|
use Magento\Quote\Api\Data\CartInterface;
|
|
use Magento\Quote\Api\PaymentMethodManagementInterface;
|
|
use Magento\Quote\Model\Quote;
|
|
use Magento\Quote\Model\Quote\TotalsCollector;
|
|
use Magento\Quote\Model\QuoteAddressValidator;
|
|
use Magento\Quote\Model\ShippingAssignmentFactory;
|
|
use Magento\Quote\Model\ShippingFactory;
|
|
use Psr\Log\LoggerInterface as Logger;
|
|
|
|
/**
|
|
* Class checkout shipping information management
|
|
*
|
|
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
|
*/
|
|
class ShippingInformationManagement implements ShippingInformationManagementInterface
|
|
{
|
|
/**
|
|
* @var PaymentMethodManagementInterface
|
|
*/
|
|
protected PaymentMethodManagementInterface $paymentMethodManagement;
|
|
|
|
/**
|
|
* @var PaymentDetailsFactory
|
|
*/
|
|
protected PaymentDetailsFactory $paymentDetailsFactory;
|
|
|
|
/**
|
|
* @var CartTotalRepositoryInterface
|
|
*/
|
|
protected CartTotalRepositoryInterface $cartTotalsRepository;
|
|
|
|
/**
|
|
* @var CartRepositoryInterface
|
|
*/
|
|
protected CartRepositoryInterface $quoteRepository;
|
|
/**
|
|
* @var Logger
|
|
*/
|
|
protected Logger $logger;
|
|
|
|
/**
|
|
* @var QuoteAddressValidator
|
|
*/
|
|
protected QuoteAddressValidator $addressValidator;
|
|
|
|
/**
|
|
* @var AddressRepositoryInterface
|
|
* @deprecated 100.2.0
|
|
* @see AddressRepositoryInterface
|
|
*/
|
|
protected AddressRepositoryInterface $addressRepository;
|
|
|
|
/**
|
|
* @var ScopeConfigInterface
|
|
* @deprecated 100.2.0
|
|
* @see ScopeConfigInterface
|
|
*/
|
|
protected ScopeConfigInterface $scopeConfig;
|
|
|
|
/**
|
|
* @var TotalsCollector
|
|
* @deprecated 100.2.0
|
|
* @see TotalsCollector
|
|
*/
|
|
protected TotalsCollector $totalsCollector;
|
|
|
|
/**
|
|
* @var CartExtensionFactory
|
|
*/
|
|
private CartExtensionFactory $cartExtensionFactory;
|
|
|
|
/**
|
|
* @var ShippingAssignmentFactory
|
|
*/
|
|
protected ShippingAssignmentFactory $shippingAssignmentFactory;
|
|
|
|
/**
|
|
* @var ShippingFactory
|
|
*/
|
|
private $shippingFactory;
|
|
|
|
/**
|
|
* @param PaymentMethodManagementInterface $paymentMethodManagement
|
|
* @param PaymentDetailsFactory $paymentDetailsFactory
|
|
* @param CartTotalRepositoryInterface $cartTotalsRepository
|
|
* @param CartRepositoryInterface $quoteRepository
|
|
* @param QuoteAddressValidator $addressValidator
|
|
* @param Logger $logger
|
|
* @param AddressRepositoryInterface $addressRepository
|
|
* @param ScopeConfigInterface $scopeConfig
|
|
* @param TotalsCollector $totalsCollector
|
|
* @param CartExtensionFactory|null $cartExtensionFactory
|
|
* @param ShippingAssignmentFactory|null $shippingAssignmentFactory
|
|
* @param ShippingFactory|null $shippingFactory
|
|
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
|
|
*/
|
|
public function __construct(
|
|
PaymentMethodManagementInterface $paymentMethodManagement,
|
|
PaymentDetailsFactory $paymentDetailsFactory,
|
|
CartTotalRepositoryInterface $cartTotalsRepository,
|
|
CartRepositoryInterface $quoteRepository,
|
|
QuoteAddressValidator $addressValidator,
|
|
Logger $logger,
|
|
AddressRepositoryInterface $addressRepository,
|
|
ScopeConfigInterface $scopeConfig,
|
|
TotalsCollector $totalsCollector,
|
|
CartExtensionFactory $cartExtensionFactory = null,
|
|
ShippingAssignmentFactory $shippingAssignmentFactory = null,
|
|
ShippingFactory $shippingFactory = null
|
|
) {
|
|
$this->paymentMethodManagement = $paymentMethodManagement;
|
|
$this->paymentDetailsFactory = $paymentDetailsFactory;
|
|
$this->cartTotalsRepository = $cartTotalsRepository;
|
|
$this->quoteRepository = $quoteRepository;
|
|
$this->addressValidator = $addressValidator;
|
|
$this->logger = $logger;
|
|
$this->addressRepository = $addressRepository;
|
|
$this->scopeConfig = $scopeConfig;
|
|
$this->totalsCollector = $totalsCollector;
|
|
$this->cartExtensionFactory = $cartExtensionFactory ?: ObjectManager::getInstance()
|
|
->get(CartExtensionFactory::class);
|
|
$this->shippingAssignmentFactory = $shippingAssignmentFactory ?: ObjectManager::getInstance()
|
|
->get(ShippingAssignmentFactory::class);
|
|
$this->shippingFactory = $shippingFactory ?: ObjectManager::getInstance()
|
|
->get(ShippingFactory::class);
|
|
}
|
|
|
|
/**
|
|
* Save address information.
|
|
*
|
|
* @param int $cartId
|
|
* @param ShippingInformationInterface $addressInformation
|
|
* @return PaymentDetailsInterface
|
|
* @throws InputException
|
|
* @throws NoSuchEntityException
|
|
* @throws StateException
|
|
*/
|
|
public function saveAddressInformation(
|
|
$cartId,
|
|
ShippingInformationInterface $addressInformation
|
|
): PaymentDetailsInterface {
|
|
/** @var Quote $quote */
|
|
$quote = $this->quoteRepository->getActive($cartId);
|
|
$this->validateQuote($quote);
|
|
|
|
$address = $addressInformation->getShippingAddress();
|
|
$this->validateAddress($address);
|
|
|
|
if (!$address->getCustomerAddressId()) {
|
|
$address->setCustomerAddressId(null);
|
|
}
|
|
|
|
try {
|
|
$billingAddress = $addressInformation->getBillingAddress();
|
|
if ($billingAddress) {
|
|
if (!$billingAddress->getCustomerAddressId()) {
|
|
$billingAddress->setCustomerAddressId(null);
|
|
}
|
|
$this->addressValidator->validateForCart($quote, $billingAddress);
|
|
$quote->setBillingAddress($billingAddress);
|
|
}
|
|
|
|
$this->addressValidator->validateForCart($quote, $address);
|
|
$carrierCode = $addressInformation->getShippingCarrierCode();
|
|
$address->setLimitCarrier($carrierCode);
|
|
$methodCode = $addressInformation->getShippingMethodCode();
|
|
$quote = $this->prepareShippingAssignment($quote, $address, $carrierCode . '_' . $methodCode);
|
|
|
|
$quote->setIsMultiShipping(false);
|
|
|
|
$this->quoteRepository->save($quote);
|
|
} catch (LocalizedException $e) {
|
|
$this->logger->critical($e);
|
|
throw new InputException(
|
|
__(
|
|
'The shipping information was unable to be saved. Error: "%message"',
|
|
['message' => $e->getMessage()]
|
|
)
|
|
);
|
|
} catch (\Exception $e) {
|
|
$this->logger->critical($e);
|
|
throw new InputException(
|
|
__('The shipping information was unable to be saved. Verify the input data and try again.')
|
|
);
|
|
}
|
|
|
|
$shippingAddress = $quote->getShippingAddress();
|
|
|
|
if (!$quote->getIsVirtual()
|
|
&& !$shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod())
|
|
) {
|
|
$errorMessage = $methodCode ?
|
|
__('Carrier with such method not found: %1, %2', $carrierCode, $methodCode)
|
|
: __('The shipping method is missing. Select the shipping method and try again.');
|
|
throw new NoSuchEntityException(
|
|
$errorMessage
|
|
);
|
|
}
|
|
|
|
/** @var PaymentDetailsInterface $paymentDetails */
|
|
$paymentDetails = $this->paymentDetailsFactory->create();
|
|
$paymentDetails->setPaymentMethods($this->paymentMethodManagement->getList($cartId));
|
|
$paymentDetails->setTotals($this->cartTotalsRepository->get($cartId));
|
|
return $paymentDetails;
|
|
}
|
|
|
|
/**
|
|
* Validate shipping address
|
|
*
|
|
* @param AddressInterface|null $address
|
|
* @return void
|
|
* @throws StateException
|
|
*/
|
|
private function validateAddress(?AddressInterface $address): void
|
|
{
|
|
if (!$address || !$address->getCountryId()) {
|
|
throw new StateException(__('The shipping address is missing. Set the address and try again.'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validate quote
|
|
*
|
|
* @param Quote $quote
|
|
* @throws InputException
|
|
* @return void
|
|
*/
|
|
protected function validateQuote(Quote $quote): void
|
|
{
|
|
if (!$quote->getItemsCount()) {
|
|
throw new InputException(
|
|
__('The shipping method can\'t be set for an empty cart. Add an item to cart and try again.')
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prepare shipping assignment.
|
|
*
|
|
* @param CartInterface $quote
|
|
* @param AddressInterface $address
|
|
* @param string $method
|
|
* @return CartInterface
|
|
*/
|
|
private function prepareShippingAssignment(
|
|
CartInterface $quote,
|
|
AddressInterface $address,
|
|
string $method
|
|
): CartInterface {
|
|
$cartExtension = $quote->getExtensionAttributes();
|
|
if ($cartExtension === null) {
|
|
$cartExtension = $this->cartExtensionFactory->create();
|
|
}
|
|
|
|
$shippingAssignments = $cartExtension->getShippingAssignments();
|
|
if (empty($shippingAssignments)) {
|
|
$shippingAssignment = $this->shippingAssignmentFactory->create();
|
|
} else {
|
|
$shippingAssignment = $shippingAssignments[0];
|
|
}
|
|
|
|
$shipping = $shippingAssignment->getShipping();
|
|
if ($shipping === null) {
|
|
$shipping = $this->shippingFactory->create();
|
|
}
|
|
|
|
$shipping->setAddress($address);
|
|
$shipping->setMethod($method);
|
|
$shippingAssignment->setShipping($shipping);
|
|
$cartExtension->setShippingAssignments([$shippingAssignment]);
|
|
return $quote->setExtensionAttributes($cartExtension);
|
|
}
|
|
}
|