/**
  * {@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);
 }
예제 #8
0
 /**
  * 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;
     }
 }
예제 #9
0
 /**
  * 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;
 }
예제 #10
0
 /**
  * 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;
 }
예제 #11
0
 /**
  * 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 [];
 }