diff --git a/vendor/magento/module-checkout/Model/AddressComparator.php b/vendor/magento/module-checkout/Model/AddressComparator.php
new file mode 100644
index 000000000000..c285f15e4e40
--- /dev/null
+++ b/vendor/magento/module-checkout/Model/AddressComparator.php
@@ -0,0 +1,79 @@
+serializer = $serializer;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function isEqual(?AddressInterface $address1, ?AddressInterface $address2): bool
+ {
+ if ($address1 === null || $address2 === null) {
+ return false;
+ }
+
+ if ($address1->getCustomerAddressId() !== null &&
+ $address2->getCustomerAddressId() !== null
+ ) {
+ return ((int)$address1->getCustomerAddressId() ===
+ (int)$address2->getCustomerAddressId());
+ } else {
+ $addressKeys = array_intersect_key($address1->getData(), $address2->getData());
+ $removeKeys = ['address_type', 'region_code', 'save_in_address_book'];
+ $addressKeys = array_diff_key($addressKeys, array_flip($removeKeys));
+
+ $address1Data = array_intersect_key($address1->getData(), $addressKeys);
+ $address2Data = array_intersect_key($address2->getData(), $addressKeys);
+ $diff = $this->computeArrayDifference($address1Data, $address2Data);
+ return empty($diff);
+ }
+ }
+
+ /**
+ * Computing the difference of two arrays
+ *
+ * @param array $array1
+ * @param array $array2
+ * @return array
+ */
+ private function computeArrayDifference(array $array1, array $array2): array
+ {
+ return array_udiff_assoc(
+ $array1,
+ $array2,
+ function ($el1, $el2) {
+ if (is_object($el1) || is_array($el1)) {
+ $el1 = $this->serializer->serialize($el1);
+ }
+ if (is_object($el2) || is_array($el2)) {
+ $el2 = $this->serializer->serialize($el2);
+ }
+ return strcmp((string)$el1, (string)$el2);
+ }
+ );
+ }
+}
diff --git a/vendor/magento/module-checkout/Model/AddressComparatorInterface.php b/vendor/magento/module-checkout/Model/AddressComparatorInterface.php
new file mode 100644
index 000000000000..2face53aa824
--- /dev/null
+++ b/vendor/magento/module-checkout/Model/AddressComparatorInterface.php
@@ -0,0 +1,22 @@
+billingAddressManagement = $billingAddressManagement;
$this->paymentMethodManagement = $paymentMethodManagement;
@@ -104,6 +112,8 @@ public function __construct(
?? ObjectManager::getInstance()->get(PaymentProcessingRateLimiterInterface::class);
$this->savingRateLimiter = $savingRateLimiter
?? ObjectManager::getInstance()->get(PaymentSavingRateLimiterInterface::class);
+ $this->addressComparator = $addressComparator
+ ?? ObjectManager::getInstance()->get(AddressComparatorInterface::class);
}
/**
@@ -165,7 +175,10 @@ public function savePaymentInformation(
$quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
/** @var Quote $quote */
$quote = $this->cartRepository->getActive($quoteIdMask->getQuoteId());
-
+ $shippingAddress = $quote->getShippingAddress();
+ if ($this->addressComparator->isEqual($shippingAddress, $billingAddress)) {
+ $shippingAddress->setSameAsBilling(1);
+ }
if ($billingAddress) {
$billingAddress->setEmail($email);
$quote->removeAddress($quote->getBillingAddress()->getId());
diff --git a/vendor/magento/module-checkout/Model/PaymentInformationManagement.php b/vendor/magento/module-checkout/Model/PaymentInformationManagement.php
index 1aad8a78bda5..41867d3c8350 100644
--- a/vendor/magento/module-checkout/Model/PaymentInformationManagement.php
+++ b/vendor/magento/module-checkout/Model/PaymentInformationManagement.php
@@ -9,9 +9,13 @@
use Magento\Checkout\Api\Exception\PaymentProcessingRateLimitExceededException;
use Magento\Checkout\Api\PaymentProcessingRateLimiterInterface;
use Magento\Checkout\Api\PaymentSavingRateLimiterInterface;
+use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\CouldNotSaveException;
+use Magento\Framework\Exception\LocalizedException;
use Magento\Quote\Api\CartRepositoryInterface;
+use Magento\Quote\Model\Quote;
+use Psr\Log\LoggerInterface;
/**
* Payment information management service.
@@ -23,6 +27,7 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
/**
* @var \Magento\Quote\Api\BillingAddressManagementInterface
* @deprecated 100.1.0 This call was substituted to eliminate extra quote::save call
+ * @see not in use anymore
*/
protected $billingAddressManagement;
@@ -46,11 +51,6 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
*/
protected $cartTotalsRepository;
- /**
- * @var \Psr\Log\LoggerInterface
- */
- private $logger;
-
/**
* @var CartRepositoryInterface
*/
@@ -71,6 +71,21 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
*/
private $saveRateLimiterDisabled = false;
+ /**
+ * @var AddressRepositoryInterface
+ */
+ private $addressRepository;
+
+ /**
+ * @var AddressComparatorInterface
+ */
+ private $addressComparator;
+
+ /**
+ * @var LoggerInterface
+ */
+ private $logger;
+
/**
* @param \Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement
* @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement
@@ -80,7 +95,11 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
* @param PaymentProcessingRateLimiterInterface|null $paymentRateLimiter
* @param PaymentSavingRateLimiterInterface|null $saveRateLimiter
* @param CartRepositoryInterface|null $cartRepository
+ * @param AddressRepositoryInterface|null $addressRepository
+ * @param AddressComparatorInterface|null $addressComparator
+ * @param LoggerInterface|null $logger
* @codeCoverageIgnore
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
\Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement,
@@ -90,7 +109,10 @@ public function __construct(
\Magento\Quote\Api\CartTotalRepositoryInterface $cartTotalsRepository,
?PaymentProcessingRateLimiterInterface $paymentRateLimiter = null,
?PaymentSavingRateLimiterInterface $saveRateLimiter = null,
- ?CartRepositoryInterface $cartRepository = null
+ ?CartRepositoryInterface $cartRepository = null,
+ ?AddressRepositoryInterface $addressRepository = null,
+ ?AddressComparatorInterface $addressComparator = null,
+ ?LoggerInterface $logger = null
) {
$this->billingAddressManagement = $billingAddressManagement;
$this->paymentMethodManagement = $paymentMethodManagement;
@@ -103,6 +125,11 @@ public function __construct(
?? ObjectManager::getInstance()->get(PaymentSavingRateLimiterInterface::class);
$this->cartRepository = $cartRepository
?? ObjectManager::getInstance()->get(CartRepositoryInterface::class);
+ $this->addressRepository = $addressRepository
+ ?? ObjectManager::getInstance()->get(AddressRepositoryInterface::class);
+ $this->addressComparator = $addressComparator
+ ?? ObjectManager::getInstance()->get(AddressComparatorInterface::class);
+ $this->logger = $logger ?? ObjectManager::getInstance()->get(LoggerInterface::class);
}
/**
@@ -123,8 +150,8 @@ public function savePaymentInformationAndPlaceOrder(
}
try {
$orderId = $this->cartManagement->placeOrder($cartId);
- } catch (\Magento\Framework\Exception\LocalizedException $e) {
- $this->getLogger()->critical(
+ } catch (LocalizedException $e) {
+ $this->logger->critical(
'Placing an order with quote_id ' . $cartId . ' is failed: ' . $e->getMessage()
);
throw new CouldNotSaveException(
@@ -132,7 +159,7 @@ public function savePaymentInformationAndPlaceOrder(
$e
);
} catch (\Exception $e) {
- $this->getLogger()->critical($e);
+ $this->logger->critical($e);
throw new CouldNotSaveException(
__('A server error stopped your order from being placed. Please try to place your order again.'),
$e
@@ -143,6 +170,8 @@ public function savePaymentInformationAndPlaceOrder(
/**
* @inheritdoc
+ *
+ * @throws LocalizedException
*/
public function savePaymentInformation(
$cartId,
@@ -170,12 +199,8 @@ public function savePaymentInformation(
$quote->removeAddress($quote->getBillingAddress()->getId());
$quote->setBillingAddress($billingAddress);
$quote->setDataChanges(true);
- $shippingAddress = $quote->getShippingAddress();
- if ($shippingAddress && $shippingAddress->getShippingMethod()) {
- $shippingRate = $shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod());
- if ($shippingRate) {
- $shippingAddress->setLimitCarrier($shippingRate->getCarrier());
- }
+ if ($quote->getShippingAddress()) {
+ $this->processShippingAddress($quote);
}
}
$this->paymentMethodManagement->set($cartId, $paymentMethod);
@@ -195,16 +220,44 @@ public function getPaymentInformation($cartId)
}
/**
- * Get logger instance
+ * Processes shipping address.
*
- * @return \Psr\Log\LoggerInterface
- * @deprecated 100.1.8
+ * @param Quote $quote
+ * @return void
+ * @throws LocalizedException
*/
- private function getLogger()
+ private function processShippingAddress(Quote $quote): void
{
- if (!$this->logger) {
- $this->logger = ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class);
+ $shippingAddress = $quote->getShippingAddress();
+ $billingAddress = $quote->getBillingAddress();
+ if ($shippingAddress->getShippingMethod()) {
+ $shippingRate = $shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod());
+ if ($shippingRate) {
+ $shippingAddress->setLimitCarrier($shippingRate->getCarrier());
+ }
+ }
+ if ($this->addressComparator->isEqual($shippingAddress, $billingAddress)) {
+ $shippingAddress->setSameAsBilling(1);
+ }
+ // Save new address in the customer address book and set it id for billing and shipping quote addresses.
+ if ($shippingAddress->getSameAsBilling() && $shippingAddress->getSaveInAddressBook()) {
+ $shippingAddressData = $shippingAddress->exportCustomerAddress();
+ $customer = $quote->getCustomer();
+ $hasDefaultBilling = (bool)$customer->getDefaultBilling();
+ $hasDefaultShipping = (bool)$customer->getDefaultShipping();
+ if (!$hasDefaultShipping) {
+ //Make provided address as default shipping address
+ $shippingAddressData->setIsDefaultShipping(true);
+ if (!$hasDefaultBilling && !$billingAddress->getSaveInAddressBook()) {
+ $shippingAddressData->setIsDefaultBilling(true);
+ }
+ }
+ $shippingAddressData->setCustomerId($quote->getCustomerId());
+ $this->addressRepository->save($shippingAddressData);
+ $quote->addCustomerAddress($shippingAddressData);
+ $shippingAddress->setCustomerAddressData($shippingAddressData);
+ $shippingAddress->setCustomerAddressId($shippingAddressData->getId());
+ $billingAddress->setCustomerAddressId($shippingAddressData->getId());
}
- return $this->logger;
}
}
diff --git a/vendor/magento/module-checkout/etc/di.xml b/vendor/magento/module-checkout/etc/di.xml
index 9a23e0343859..280944dc4090 100644
--- a/vendor/magento/module-checkout/etc/di.xml
+++ b/vendor/magento/module-checkout/etc/di.xml
@@ -28,6 +28,7 @@
+
diff --git a/vendor/magento/module-quote/Model/QuoteManagement.php b/vendor/magento/module-quote/Model/QuoteManagement.php
index 51b68411d408..9a66bfaddfcb 100644
--- a/vendor/magento/module-quote/Model/QuoteManagement.php
+++ b/vendor/magento/module-quote/Model/QuoteManagement.php
@@ -32,8 +32,8 @@
use Magento\Quote\Api\Data\PaymentInterface;
use Magento\Quote\Model\Quote\Address\ToOrder as ToOrderConverter;
use Magento\Quote\Model\Quote\Address\ToOrderAddress as ToOrderAddressConverter;
-use Magento\Quote\Model\Quote as QuoteEntity;
use Magento\Quote\Model\Quote\AddressFactory;
+use Magento\Quote\Model\Quote as QuoteEntity;
use Magento\Quote\Model\Quote\Item\ToOrderItem as ToOrderItemConverter;
use Magento\Quote\Model\Quote\Payment\ToOrderPayment as ToOrderPaymentConverter;
use Magento\Quote\Model\ResourceModel\Quote\Item;
@@ -324,7 +324,7 @@ public function assignCustomer($cartId, $customerId, $storeId)
$customerActiveQuote->setIsActive(0);
$this->quoteRepository->save($customerActiveQuote);
- // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
+ // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
} catch (NoSuchEntityException $e) {
}
@@ -622,12 +622,13 @@ protected function submitQuote(QuoteEntity $quote, $orderData = [])
*
* @param Quote $quote
* @return void
+ * @throws LocalizedException
+ * @throws NoSuchEntityException
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function _prepareCustomerQuote($quote)
{
- /** @var Quote $quote */
$billing = $quote->getBillingAddress();
$shipping = $quote->isVirtual() ? null : $quote->getShippingAddress();
@@ -645,7 +646,7 @@ protected function _prepareCustomerQuote($quote)
if ($defaultShipping) {
try {
$shippingAddress = $this->addressRepository->getById($defaultShipping);
- // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
+ // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
} catch (LocalizedException $e) {
// no address
}
@@ -679,7 +680,7 @@ protected function _prepareCustomerQuote($quote)
if ($defaultBilling) {
try {
$billingAddress = $this->addressRepository->getById($defaultBilling);
- // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
+ // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
} catch (LocalizedException $e) {
// no address
}
@@ -700,6 +701,13 @@ protected function _prepareCustomerQuote($quote)
$billing->setCustomerAddressData($billingAddress);
$this->addressesToSync[] = $billingAddress->getId();
$billing->setCustomerAddressId($billingAddress->getId());
+
+ // Admin order: `Same As Billing Address`- when new billing address saved in address book
+ if ($shipping !== null
+ && !$shipping->getCustomerAddressId()
+ && $shipping->getSameAsBilling()) {
+ $shipping->setCustomerAddressId($billingAddress->getId());
+ }
}
}
if ($shipping && !$shipping->getCustomerId() && !$hasDefaultBilling) {