/** * {@inheritDoc} * @SuppressWarnings(PHPMD.NPathComplexity) */ public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address) { /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); if ($quote->isVirtual()) { throw new NoSuchEntityException(__('Cart contains virtual product(s) only. Shipping address is not applicable.')); } $saveInAddressBook = $address->getSaveInAddressBook() ? 1 : 0; $sameAsBilling = $address->getSameAsBilling() ? 1 : 0; $customerAddressId = $address->getCustomerAddressId(); $this->addressValidator->validate($address); $quote->setShippingAddress($address); $address = $quote->getShippingAddress(); if ($customerAddressId) { $addressData = $this->addressRepository->getById($customerAddressId); $address = $quote->getShippingAddress()->importCustomerAddressData($addressData); } elseif ($quote->getCustomerId()) { $address->setEmail($quote->getCustomerEmail()); } $address->setSameAsBilling($sameAsBilling); $address->setSaveInAddressBook($saveInAddressBook); $address->setCollectShippingRates(true); try { $this->totalsCollector->collectAddressTotals($quote, $address); $address->save(); } catch (\Exception $e) { $this->logger->critical($e); throw new InputException(__('Unable to save address. Please, check input data.')); } if (!$quote->validateMinimumAmount($quote->getIsMultiShipping())) { throw new InputException($this->scopeConfig->getValue('sales/minimum_order/error_message', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $quote->getStoreId())); } return $quote->getShippingAddress()->getId(); }
/** * {@inheritDoc} * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function saveAddressInformation($cartId, \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation) { $address = $addressInformation->getShippingAddress(); $carrierCode = $addressInformation->getShippingCarrierCode(); $methodCode = $addressInformation->getShippingMethodCode(); /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); $this->validateQuote($quote); $quote->setIsMultiShipping(false); $saveInAddressBook = $address->getSaveInAddressBook() ? 1 : 0; $sameAsBilling = $address->getSameAsBilling() ? 1 : 0; $customerAddressId = $address->getCustomerAddressId(); $this->addressValidator->validate($address); $quote->setShippingAddress($address); $address = $quote->getShippingAddress(); if ($customerAddressId) { $addressData = $this->addressRepository->getById($customerAddressId); $address = $quote->getShippingAddress()->importCustomerAddressData($addressData); } $billingAddress = $addressInformation->getBillingAddress(); if ($billingAddress) { $quote->setBillingAddress($billingAddress); } $address->setSaveInAddressBook($saveInAddressBook); $address->setSameAsBilling($sameAsBilling); $address->setCollectShippingRates(true); if (!$address->getCountryId()) { throw new StateException(__('Shipping address is not set')); } $address->setShippingMethod($carrierCode . '_' . $methodCode); try { $this->totalsCollector->collectAddressTotals($quote, $address); } catch (\Exception $e) { $this->logger->critical($e); throw new InputException(__('Unable to save address. Please check input data.')); } if (!$address->getShippingRateByCode($address->getShippingMethod())) { throw new NoSuchEntityException(__('Carrier with such method not found: %1, %2', $carrierCode, $methodCode)); } if (!$quote->validateMinimumAmount($quote->getIsMultiShipping())) { throw new InputException($this->scopeConfig->getValue('sales/minimum_order/error_message', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $quote->getStoreId())); } try { $address->save(); $quote->collectTotals(); $this->quoteRepository->save($quote); } catch (\Exception $e) { $this->logger->critical($e); throw new InputException(__('Unable to save shipping information. Please check input data.')); } /** @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; }
/** * Get list of available shipping methods * @param \Magento\Quote\Model\Quote $quote * @param array $addressData * @return \Magento\Quote\Api\Data\ShippingMethodInterface[] */ private function getShippingMethods(Quote $quote, array $addressData) { $output = []; $shippingAddress = $quote->getShippingAddress(); $shippingAddress->addData($addressData); $shippingAddress->setCollectShippingRates(true); $this->totalsCollector->collectAddressTotals($quote, $shippingAddress); $shippingRates = $shippingAddress->getGroupedAllShippingRates(); foreach ($shippingRates as $carrierRates) { foreach ($carrierRates as $rate) { $output[] = $this->converter->modelToDataObject($rate, $quote->getQuoteCurrencyCode()); } } return $output; }
/** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/Checkout/_files/quote_with_shipping_method.php */ public function testGetMethodForMyCart() { $this->_markTestAsRestOnly(); $this->quote->load('test_order_1', 'reserved_order_id'); /** @var \Magento\Integration\Api\CustomerTokenServiceInterface $customerTokenService */ $customerTokenService = $this->objectManager->create('Magento\\Integration\\Api\\CustomerTokenServiceInterface'); $token = $customerTokenService->createCustomerAccessToken('*****@*****.**', 'password'); /** @var \Magento\Quote\Api\ShippingMethodManagementInterface $shippingMethodManagementService */ $shippingAddress = $this->quote->getShippingAddress(); $shippingAddress->setCollectShippingRates(true); $this->totalsCollector->collectAddressTotals($this->quote, $shippingAddress); $shippingAddress->save(); $serviceInfo = ['rest' => ['resourcePath' => '/V1/carts/mine/selected-shipping-method', 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, 'token' => $token]]; $result = $this->_webApiCall($serviceInfo, []); $this->assertEquals('flatrate', $result[ShippingMethodInterface::KEY_CARRIER_CODE]); $this->assertEquals('flatrate', $result[ShippingMethodInterface::KEY_METHOD_CODE]); }
/** * Get estimated rates * * @param Quote $quote * @param int $country * @param string $postcode * @param int $regionId * @param string $region * @return \Magento\Quote\Api\Data\ShippingMethodInterface[] An array of shipping methods. */ protected function getEstimatedRates(\Magento\Quote\Model\Quote $quote, $country, $postcode, $regionId, $region) { $output = []; $shippingAddress = $quote->getShippingAddress(); $shippingAddress->setCountryId($country); $shippingAddress->setPostcode($postcode); $shippingAddress->setRegionId($regionId); $shippingAddress->setRegion($region); $shippingAddress->setCollectShippingRates(true); $this->totalsCollector->collectAddressTotals($quote, $shippingAddress); $shippingRates = $shippingAddress->getGroupedAllShippingRates(); foreach ($shippingRates as $carrierRates) { foreach ($carrierRates as $rate) { $output[] = $this->converter->modelToDataObject($rate, $quote->getQuoteCurrencyCode()); } } return $output; }
/** * @covers \Magento\Quote\Model\ShippingMethodManagement::estimateByExtendedAddress */ public function testEstimateByExtendedAddress() { $cartId = 1; $addressData = ['region' => 'California', 'region_id' => 23, 'country_id' => 1, 'postcode' => 90200]; $currencyCode = 'UAH'; $address = $this->getMockBuilder(Address::class)->disableOriginalConstructor()->setMethods(['getData'])->getMock(); $this->quoteRepository->expects(static::once())->method('getActive')->with($cartId)->willReturn($this->quote); $this->quote->expects(static::once())->method('isVirtual')->willReturn(false); $this->quote->expects(static::once())->method('getItemsCount')->willReturn(1); $address->expects(static::once())->method('getData')->willReturn($addressData); $this->quote->expects(static::once())->method('getShippingAddress')->willReturn($this->shippingAddress); $this->shippingAddress->expects(static::once())->method('addData')->with($addressData)->willReturnSelf(); $this->shippingAddress->expects(static::once())->method('setCollectShippingRates')->with(true)->willReturnSelf(); $this->totalsCollector->expects(static::once())->method('collectAddressTotals')->with($this->quote, $this->shippingAddress)->willReturnSelf(); $rate = $this->getMockBuilder(Rate::class)->disableOriginalConstructor()->setMethods([])->getMock(); $methodObject = $this->getMockForAbstractClass(ShippingMethodInterface::class); $expectedRates = [$methodObject]; $this->shippingAddress->expects(static::once())->method('getGroupedAllShippingRates')->willReturn([[$rate]]); $this->quote->expects(static::once())->method('getQuoteCurrencyCode')->willReturn($currencyCode); $this->converter->expects(static::once())->method('modelToDataObject')->with($rate, $currencyCode)->willReturn($methodObject); $carriersRates = $this->model->estimateByExtendedAddress($cartId, $address); static::assertEquals($expectedRates, $carriersRates); }
/** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_shipping_method.php */ public function testGetMethod() { /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->objectManager->create('Magento\\Quote\\Model\\Quote'); $quote->load('test_order_1', 'reserved_order_id'); $cartId = $quote->getId(); /** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */ $quoteIdMask = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\\Quote\\Model\\QuoteIdMaskFactory')->create(); $quoteIdMask->load($cartId, 'quote_id'); //Use masked cart Id $cartId = $quoteIdMask->getMaskedId(); $shippingAddress = $quote->getShippingAddress(); $shippingAddress->setCollectShippingRates(true); $this->totalsCollector->collectAddressTotals($this->quote, $shippingAddress); $shippingAddress->save(); list($carrierCode, $methodCode) = explode('_', $shippingAddress->getShippingMethod()); list($carrierTitle, $methodTitle) = explode(' - ', $shippingAddress->getShippingDescription()); $data = [ShippingMethodInterface::KEY_CARRIER_CODE => $carrierCode, ShippingMethodInterface::KEY_METHOD_CODE => $methodCode, ShippingMethodInterface::KEY_CARRIER_TITLE => $carrierTitle, ShippingMethodInterface::KEY_METHOD_TITLE => $methodTitle, ShippingMethodInterface::KEY_SHIPPING_AMOUNT => $shippingAddress->getShippingAmount(), ShippingMethodInterface::KEY_BASE_SHIPPING_AMOUNT => $shippingAddress->getBaseShippingAmount(), ShippingMethodInterface::KEY_AVAILABLE => true, ShippingMethodInterface::KEY_ERROR_MESSAGE => null]; $requestData = ["cartId" => $cartId]; $actual = $this->_webApiCall($this->getSelectedMethodServiceInfo($cartId), $requestData); unset($actual[ShippingMethodInterface::KEY_PRICE_EXCL_TAX]); unset($actual[ShippingMethodInterface::KEY_PRICE_INCL_TAX]); $this->assertEquals($data, $actual); }
/** * Return callback response with shipping options * * @param array $request * @return string * @throws \Exception */ public function getShippingOptionsCallbackResponse(array $request) { $debugData = ['request' => $request, 'response' => []]; try { // obtain addresses $this->_getApi(); $address = $this->_api->prepareShippingOptionsCallbackAddress($request); $quoteAddress = $this->_quote->getShippingAddress(); // compare addresses, calculate shipping rates and prepare response $options = []; if ($address && $quoteAddress && !$this->_quote->getIsVirtual()) { foreach ($address->getExportedKeys() as $key) { $quoteAddress->setDataUsingMethod($key, $address->getData($key)); } $quoteAddress->setCollectShippingRates(true); $this->totalsCollector->collectAddressTotals($this->_quote, $quoteAddress); $options = $this->_prepareShippingOptions($quoteAddress, false, true); } $response = $this->_api->setShippingOptions($options)->formatShippingOptionsCallback(); // log request and response $debugData['response'] = $response; $this->_logger->debug(var_export($debugData, true)); return $response; } catch (\Exception $e) { $this->_logger->debug(var_export($debugData, true)); throw $e; } }
/** * Collect totals * * @return $this */ public function collectTotals() { if ($this->getTotalsCollectedFlag()) { return $this; } $total = $this->totalsCollector->collect($this); $this->addData($total->getData()); $this->setTotalsCollectedFlag(true); return $this; }
/** * Reimport customer billing address to quote * * @param int $addressId customer address id * @throws \Magento\Framework\Exception\LocalizedException * @return \Magento\Multishipping\Model\Checkout\Type\Multishipping */ public function setQuoteCustomerBillingAddress($addressId) { if (!$this->isAddressIdApplicable($addressId)) { throw new LocalizedException(__('Please check billing address information.')); } try { $address = $this->addressRepository->getById($addressId); } catch (\Exception $e) { // } if (isset($address)) { $quoteAddress = $this->getQuote()->getBillingAddress($addressId)->importCustomerAddressData($address); $this->totalsCollector->collectAddressTotals($this->getQuote(), $quoteAddress); $this->getQuote()->collectTotals(); $this->quoteRepository->save($this->getQuote()); } return $this; }
/** * Save checkout shipping address * * @param array $data * @param int $customerAddressId * @return array * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function saveShipping($data, $customerAddressId) { if (empty($data)) { return ['error' => -1, 'message' => __('Invalid data')]; } $address = $this->getQuote()->getShippingAddress(); $addressForm = $this->_formFactory->create('customer_address', 'customer_address_edit', [], $this->_request->isAjax(), Form::IGNORE_INVISIBLE, []); if (!empty($customerAddressId)) { $addressData = null; try { $addressData = $this->addressRepository->getById($customerAddressId); } catch (NoSuchEntityException $e) { // do nothing if customer is not found by id } if ($addressData->getCustomerId() != $this->getQuote()->getCustomerId()) { return ['error' => 1, 'message' => __('The customer address is not valid.')]; } $address->importCustomerAddressData($addressData)->setSaveInAddressBook(0); $addressErrors = $addressForm->validateData($address->getData()); if ($addressErrors !== true) { return ['error' => 1, 'message' => $addressErrors]; } } else { // emulate request object $addressData = $addressForm->extractData($addressForm->prepareRequest($data)); $addressErrors = $addressForm->validateData($addressData); if ($addressErrors !== true) { return ['error' => 1, 'message' => $addressErrors]; } $compactedData = $addressForm->compactData($addressData); // unset shipping address attributes which were not shown in form foreach ($addressForm->getAttributes() as $attribute) { $attributeCode = $attribute->getAttributeCode(); if (!isset($data[$attributeCode])) { $address->setData($attributeCode, null); } else { if (isset($compactedData[$attributeCode])) { $address->setDataUsingMethod($attributeCode, $compactedData[$attributeCode]); } } } $address->setCustomerAddressId(null); // Additional form data, not fetched by extractData (as it fetches only attributes) $address->setSaveInAddressBook(empty($data['save_in_address_book']) ? 0 : 1); $address->setSameAsBilling(empty($data['same_as_billing']) ? 0 : 1); } $address->setCollectShippingRates(true); if (($validateRes = $address->validate()) !== true) { return ['error' => 1, 'message' => $validateRes]; } $this->totalsCollector->collectAddressTotals($this->getQuote(), $address); $address->save(); $this->getCheckout()->setStepData('shipping', 'complete', true)->setStepData('shipping_method', 'allow', true); return []; }