Skip to content

Commit b4f87e9

Browse files
committed
Merge remote-tracking branches 'local/ACP2E-1171', 'local/ACP2E-895' and 'local/ACP2E-1117' into PR_combine
4 parents 1de1cea + d736ef7 + a9f60f8 + cc9bb53 commit b4f87e9

File tree

8 files changed

+289
-29
lines changed

8 files changed

+289
-29
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Checkout\Model;
9+
10+
use Magento\Framework\Serialize\SerializerInterface;
11+
use Magento\Quote\Api\Data\AddressInterface;
12+
13+
class AddressComparator implements AddressComparatorInterface
14+
{
15+
/**
16+
* @var SerializerInterface
17+
*/
18+
private $serializer;
19+
20+
/**
21+
* AddressComparator constructor
22+
*
23+
* @param SerializerInterface $serializer
24+
*/
25+
public function __construct(SerializerInterface $serializer)
26+
{
27+
$this->serializer = $serializer;
28+
}
29+
30+
/**
31+
* @inheritDoc
32+
*/
33+
public function isEqual(?AddressInterface $address1, ?AddressInterface $address2): bool
34+
{
35+
if ($address1 === null || $address2 === null) {
36+
return false;
37+
}
38+
39+
if ($address1->getCustomerAddressId() !== null &&
40+
$address2->getCustomerAddressId() !== null
41+
) {
42+
return ((int)$address1->getCustomerAddressId() ===
43+
(int)$address2->getCustomerAddressId());
44+
} else {
45+
$addressKeys = array_intersect_key($address1->getData(), $address2->getData());
46+
$removeKeys = ['address_type', 'region_code', 'save_in_address_book'];
47+
$addressKeys = array_diff_key($addressKeys, array_flip($removeKeys));
48+
49+
$address1Data = array_intersect_key($address1->getData(), $addressKeys);
50+
$address2Data = array_intersect_key($address2->getData(), $addressKeys);
51+
$diff = $this->computeArrayDifference($address1Data, $address2Data);
52+
return empty($diff);
53+
}
54+
}
55+
56+
/**
57+
* Computing the difference of two arrays
58+
*
59+
* @param array $array1
60+
* @param array $array2
61+
* @return array
62+
*/
63+
private function computeArrayDifference(array $array1, array $array2): array
64+
{
65+
return array_udiff_assoc(
66+
$array1,
67+
$array2,
68+
function ($el1, $el2) {
69+
if (is_object($el1) || is_array($el1)) {
70+
$el1 = $this->serializer->serialize($el1);
71+
}
72+
if (is_object($el2) || is_array($el2)) {
73+
$el2 = $this->serializer->serialize($el2);
74+
}
75+
return strcmp((string)$el1, (string)$el2);
76+
}
77+
);
78+
}
79+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Checkout\Model;
9+
10+
use Magento\Quote\Api\Data\AddressInterface;
11+
12+
interface AddressComparatorInterface
13+
{
14+
/**
15+
* Returns true/false, after addresses comparison
16+
*
17+
* @param AddressInterface|null $address1
18+
* @param AddressInterface|null $address2
19+
* @return bool
20+
*/
21+
public function isEqual(?AddressInterface $address1, ?AddressInterface $address2): bool;
22+
}

app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* Guest payment information management model.
2121
*
2222
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
23+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
2324
*/
2425
class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPaymentInformationManagementInterface
2526
{
@@ -74,6 +75,11 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa
7475
*/
7576
private $saveRateLimitDisabled = false;
7677

78+
/**
79+
* @var AddressComparatorInterface
80+
*/
81+
private $addressComparator;
82+
7783
/**
7884
* @param \Magento\Quote\Api\GuestBillingAddressManagementInterface $billingAddressManagement
7985
* @param \Magento\Quote\Api\GuestPaymentMethodManagementInterface $paymentMethodManagement
@@ -84,6 +90,7 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa
8490
* @param Logger $logger
8591
* @param PaymentProcessingRateLimiterInterface|null $paymentsRateLimiter
8692
* @param PaymentSavingRateLimiterInterface|null $savingRateLimiter
93+
* @param AddressComparatorInterface|null $addressComparator
8794
* @codeCoverageIgnore
8895
*/
8996
public function __construct(
@@ -95,7 +102,8 @@ public function __construct(
95102
CartRepositoryInterface $cartRepository,
96103
Logger $logger,
97104
?PaymentProcessingRateLimiterInterface $paymentsRateLimiter = null,
98-
?PaymentSavingRateLimiterInterface $savingRateLimiter = null
105+
?PaymentSavingRateLimiterInterface $savingRateLimiter = null,
106+
?AddressComparatorInterface $addressComparator = null
99107
) {
100108
$this->billingAddressManagement = $billingAddressManagement;
101109
$this->paymentMethodManagement = $paymentMethodManagement;
@@ -107,6 +115,8 @@ public function __construct(
107115
?? ObjectManager::getInstance()->get(PaymentProcessingRateLimiterInterface::class);
108116
$this->savingRateLimiter = $savingRateLimiter
109117
?? ObjectManager::getInstance()->get(PaymentSavingRateLimiterInterface::class);
118+
$this->addressComparator = $addressComparator
119+
?? ObjectManager::getInstance()->get(AddressComparatorInterface::class);
110120
$this->logger = $logger;
111121
}
112122

@@ -169,7 +179,10 @@ public function savePaymentInformation(
169179
$quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
170180
/** @var Quote $quote */
171181
$quote = $this->cartRepository->getActive($quoteIdMask->getQuoteId());
172-
182+
$shippingAddress = $quote->getShippingAddress();
183+
if ($this->addressComparator->isEqual($shippingAddress, $billingAddress)) {
184+
$shippingAddress->setSameAsBilling(1);
185+
}
173186
if ($billingAddress) {
174187
$billingAddress->setEmail($email);
175188
$quote->removeAddress($quote->getBillingAddress()->getId());

app/code/Magento/Checkout/Model/PaymentInformationManagement.php

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@
99
use Magento\Checkout\Api\Exception\PaymentProcessingRateLimitExceededException;
1010
use Magento\Checkout\Api\PaymentProcessingRateLimiterInterface;
1111
use Magento\Checkout\Api\PaymentSavingRateLimiterInterface;
12+
use Magento\Customer\Api\AddressRepositoryInterface;
1213
use Magento\Framework\App\ObjectManager;
1314
use Magento\Framework\Exception\CouldNotSaveException;
15+
use Magento\Framework\Exception\LocalizedException;
1416
use Magento\Quote\Api\CartRepositoryInterface;
17+
use Magento\Quote\Model\Quote;
18+
use Psr\Log\LoggerInterface;
1519

1620
/**
1721
* Payment information management service.
@@ -23,6 +27,7 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
2327
/**
2428
* @var \Magento\Quote\Api\BillingAddressManagementInterface
2529
* @deprecated 100.1.0 This call was substituted to eliminate extra quote::save call
30+
* @see not in use anymore
2631
*/
2732
protected $billingAddressManagement;
2833

@@ -46,11 +51,6 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
4651
*/
4752
protected $cartTotalsRepository;
4853

49-
/**
50-
* @var \Psr\Log\LoggerInterface
51-
*/
52-
private $logger;
53-
5454
/**
5555
* @var CartRepositoryInterface
5656
*/
@@ -71,6 +71,21 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
7171
*/
7272
private $saveRateLimiterDisabled = false;
7373

74+
/**
75+
* @var AddressRepositoryInterface
76+
*/
77+
private $addressRepository;
78+
79+
/**
80+
* @var AddressComparatorInterface
81+
*/
82+
private $addressComparator;
83+
84+
/**
85+
* @var LoggerInterface
86+
*/
87+
private $logger;
88+
7489
/**
7590
* @param \Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement
7691
* @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement
@@ -80,7 +95,11 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
8095
* @param PaymentProcessingRateLimiterInterface|null $paymentRateLimiter
8196
* @param PaymentSavingRateLimiterInterface|null $saveRateLimiter
8297
* @param CartRepositoryInterface|null $cartRepository
98+
* @param AddressRepositoryInterface|null $addressRepository
99+
* @param AddressComparatorInterface|null $addressComparator
100+
* @param LoggerInterface|null $logger
83101
* @codeCoverageIgnore
102+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
84103
*/
85104
public function __construct(
86105
\Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement,
@@ -90,7 +109,10 @@ public function __construct(
90109
\Magento\Quote\Api\CartTotalRepositoryInterface $cartTotalsRepository,
91110
?PaymentProcessingRateLimiterInterface $paymentRateLimiter = null,
92111
?PaymentSavingRateLimiterInterface $saveRateLimiter = null,
93-
?CartRepositoryInterface $cartRepository = null
112+
?CartRepositoryInterface $cartRepository = null,
113+
?AddressRepositoryInterface $addressRepository = null,
114+
?AddressComparatorInterface $addressComparator = null,
115+
?LoggerInterface $logger = null
94116
) {
95117
$this->billingAddressManagement = $billingAddressManagement;
96118
$this->paymentMethodManagement = $paymentMethodManagement;
@@ -103,6 +125,11 @@ public function __construct(
103125
?? ObjectManager::getInstance()->get(PaymentSavingRateLimiterInterface::class);
104126
$this->cartRepository = $cartRepository
105127
?? ObjectManager::getInstance()->get(CartRepositoryInterface::class);
128+
$this->addressRepository = $addressRepository
129+
?? ObjectManager::getInstance()->get(AddressRepositoryInterface::class);
130+
$this->addressComparator = $addressComparator
131+
?? ObjectManager::getInstance()->get(AddressComparatorInterface::class);
132+
$this->logger = $logger ?? ObjectManager::getInstance()->get(LoggerInterface::class);
106133
}
107134

108135
/**
@@ -123,16 +150,16 @@ public function savePaymentInformationAndPlaceOrder(
123150
}
124151
try {
125152
$orderId = $this->cartManagement->placeOrder($cartId);
126-
} catch (\Magento\Framework\Exception\LocalizedException $e) {
127-
$this->getLogger()->critical(
153+
} catch (LocalizedException $e) {
154+
$this->logger->critical(
128155
'Placing an order with quote_id ' . $cartId . ' is failed: ' . $e->getMessage()
129156
);
130157
throw new CouldNotSaveException(
131158
__($e->getMessage()),
132159
$e
133160
);
134161
} catch (\Exception $e) {
135-
$this->getLogger()->critical($e);
162+
$this->logger->critical($e);
136163
throw new CouldNotSaveException(
137164
__('A server error stopped your order from being placed. Please try to place your order again.'),
138165
$e
@@ -143,6 +170,8 @@ public function savePaymentInformationAndPlaceOrder(
143170

144171
/**
145172
* @inheritdoc
173+
*
174+
* @throws LocalizedException
146175
*/
147176
public function savePaymentInformation(
148177
$cartId,
@@ -170,12 +199,8 @@ public function savePaymentInformation(
170199
$quote->removeAddress($quote->getBillingAddress()->getId());
171200
$quote->setBillingAddress($billingAddress);
172201
$quote->setDataChanges(true);
173-
$shippingAddress = $quote->getShippingAddress();
174-
if ($shippingAddress && $shippingAddress->getShippingMethod()) {
175-
$shippingRate = $shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod());
176-
if ($shippingRate) {
177-
$shippingAddress->setLimitCarrier($shippingRate->getCarrier());
178-
}
202+
if ($quote->getShippingAddress()) {
203+
$this->processShippingAddress($quote);
179204
}
180205
}
181206
$this->paymentMethodManagement->set($cartId, $paymentMethod);
@@ -195,16 +220,44 @@ public function getPaymentInformation($cartId)
195220
}
196221

197222
/**
198-
* Get logger instance
223+
* Processes shipping address.
199224
*
200-
* @return \Psr\Log\LoggerInterface
201-
* @deprecated 100.1.8
225+
* @param Quote $quote
226+
* @return void
227+
* @throws LocalizedException
202228
*/
203-
private function getLogger()
229+
private function processShippingAddress(Quote $quote): void
204230
{
205-
if (!$this->logger) {
206-
$this->logger = ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class);
231+
$shippingAddress = $quote->getShippingAddress();
232+
$billingAddress = $quote->getBillingAddress();
233+
if ($shippingAddress->getShippingMethod()) {
234+
$shippingRate = $shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod());
235+
if ($shippingRate) {
236+
$shippingAddress->setLimitCarrier($shippingRate->getCarrier());
237+
}
238+
}
239+
if ($this->addressComparator->isEqual($shippingAddress, $billingAddress)) {
240+
$shippingAddress->setSameAsBilling(1);
241+
}
242+
// Save new address in the customer address book and set it id for billing and shipping quote addresses.
243+
if ($shippingAddress->getSameAsBilling() && $shippingAddress->getSaveInAddressBook()) {
244+
$shippingAddressData = $shippingAddress->exportCustomerAddress();
245+
$customer = $quote->getCustomer();
246+
$hasDefaultBilling = (bool)$customer->getDefaultBilling();
247+
$hasDefaultShipping = (bool)$customer->getDefaultShipping();
248+
if (!$hasDefaultShipping) {
249+
//Make provided address as default shipping address
250+
$shippingAddressData->setIsDefaultShipping(true);
251+
if (!$hasDefaultBilling && !$billingAddress->getSaveInAddressBook()) {
252+
$shippingAddressData->setIsDefaultBilling(true);
253+
}
254+
}
255+
$shippingAddressData->setCustomerId($quote->getCustomerId());
256+
$this->addressRepository->save($shippingAddressData);
257+
$quote->addCustomerAddress($shippingAddressData);
258+
$shippingAddress->setCustomerAddressData($shippingAddressData);
259+
$shippingAddress->setCustomerAddressId($shippingAddressData->getId());
260+
$billingAddress->setCustomerAddressId($shippingAddressData->getId());
207261
}
208-
return $this->logger;
209262
}
210263
}

app/code/Magento/Checkout/etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<preference for="Magento\Checkout\Api\AgreementsValidatorInterface" type="Magento\Checkout\Model\AgreementsValidator" />
2929
<preference for="Magento\Checkout\Model\Cart\RequestInfoFilterInterface"
3030
type="Magento\Checkout\Model\Cart\RequestInfoFilterComposite"/>
31+
<preference for="Magento\Checkout\Model\AddressComparatorInterface" type="Magento\Checkout\Model\AddressComparator" />
3132
<type name="Magento\Checkout\Model\Cart\RequestInfoFilter">
3233
<arguments>
3334
<argument name="filterList" xsi:type="array">

app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,21 @@
460460
<entity name="Simple_US_Customer_US_UK_Addresses" type="customer" extends="Simple_US_Customer_ArmedForcesEurope">
461461
<requiredEntity type="address">UK_Not_Default_Address</requiredEntity>
462462
</entity>
463+
<entity name="Simple_US_Customer_With_Unique_Taxvat" type="customer">
464+
<data key="group_id">1</data>
465+
<data key="default_billing">true</data>
466+
<data key="default_shipping">true</data>
467+
<data key="email" unique="prefix">John.Doe@example.com</data>
468+
<data key="firstname">John</data>
469+
<data key="lastname">Doe</data>
470+
<data key="fullname">John Doe</data>
471+
<data key="password">pwdTest123!</data>
472+
<data key="store_id">0</data>
473+
<data key="website_id">0</data>
474+
<data key="group">General</data>
475+
<data key="taxvat" unique="prefix">taxValue</data>
476+
<requiredEntity type="address">US_Address_TX</requiredEntity>
477+
</entity>
463478
<entity name="Simple_CA_Customer" type="customer">
464479
<data key="group_id">1</data>
465480
<data key="default_billing">true</data>

0 commit comments

Comments
 (0)