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 \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation * @return \Magento\Checkout\Api\Data\PaymentDetailsInterface * @throws InputException * @throws NoSuchEntityException * @throws StateException */ public function saveAddressInformation( $cartId, \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation ) { $address = $addressInformation->getShippingAddress(); $billingAddress = $addressInformation->getBillingAddress(); $carrierCode = $addressInformation->getShippingCarrierCode(); $methodCode = $addressInformation->getShippingMethodCode(); if (!$address->getCustomerAddressId()) { $address->setCustomerAddressId(null); } if ($billingAddress && !$billingAddress->getCustomerAddressId()) { $billingAddress->setCustomerAddressId(null); } if (!$address->getCountryId()) { throw new StateException(__('The shipping address is missing. Set the address and try again.')); } /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); $address->setLimitCarrier($carrierCode); $quote = $this->prepareShippingAssignment($quote, $address, $carrierCode . '_' . $methodCode); $this->validateQuote($quote); $quote->setIsMultiShipping(false); if ($billingAddress) { $quote->setBillingAddress($billingAddress); } try { $this->quoteRepository->save($quote); } 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 (!$shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod())) { throw new NoSuchEntityException( __('Carrier with such method not found: %1, %2', $carrierCode, $methodCode) ); } /** @var \Magento\Checkout\Api\Data\PaymentDetailsInterface $paymentDetails */ $paymentDetails = $this->paymentDetailsFactory->create(); $paymentDetails->setPaymentMethods($this->paymentMethodManagement->getList($cartId)); $paymentDetails->setTotals($this->cartTotalsRepository->get($cartId)); return $paymentDetails; } /** * Validate quote * * @param \Magento\Quote\Model\Quote $quote * @throws InputException * @throws NoSuchEntityException * @return void */ protected function validateQuote(\Magento\Quote\Model\Quote $quote) { if (0 == $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, $method) { $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); } }