Skip to content

Commit 001e518

Browse files
authored
Merge pull request #8910 from adobe-commerce-tier-4/PR-Tier3-04-29-2024-olga
[Support Tier-4 omoyseyenko] 04-29-2024 Regular delivery of bugfixes and improvements
2 parents 0574ac2 + b23a3cd commit 001e518

File tree

32 files changed

+964
-575
lines changed

32 files changed

+964
-575
lines changed

Diff for: app/code/Magento/Checkout/Model/AddressComparator.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function isEqual(?AddressInterface $address1, ?AddressInterface $address2
4343
(int)$address2->getCustomerAddressId());
4444
} else {
4545
$addressKeys = array_intersect_key($address1->getData(), $address2->getData());
46-
$removeKeys = ['address_type', 'region_code', 'save_in_address_book'];
46+
$removeKeys = ['address_type', 'region_code', 'save_in_address_book', 'customer_address_id'];
4747
$addressKeys = array_diff_key($addressKeys, array_flip($removeKeys));
4848

4949
$address1Data = array_intersect_key($address1->getData(), $addressKeys);

Diff for: app/code/Magento/Checkout/Model/PaymentInformationManagement.php

+57-15
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010
use Magento\Checkout\Api\PaymentProcessingRateLimiterInterface;
1111
use Magento\Checkout\Api\PaymentSavingRateLimiterInterface;
1212
use Magento\Customer\Api\AddressRepositoryInterface;
13+
use Magento\Customer\Api\Data\AddressInterface;
1314
use Magento\Framework\App\ObjectManager;
1415
use Magento\Framework\Exception\CouldNotSaveException;
1516
use Magento\Framework\Exception\LocalizedException;
1617
use Magento\Quote\Api\CartRepositoryInterface;
18+
use Magento\Quote\Api\Data\AddressInterface as QuoteAddressInterface;
19+
use Magento\Quote\Api\Data\PaymentInterface;
1720
use Magento\Quote\Model\Quote;
21+
use Magento\Quote\Model\Quote\Address;
1822
use Psr\Log\LoggerInterface;
1923

2024
/**
@@ -137,8 +141,8 @@ public function __construct(
137141
*/
138142
public function savePaymentInformationAndPlaceOrder(
139143
$cartId,
140-
\Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
141-
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
144+
PaymentInterface $paymentMethod,
145+
QuoteAddressInterface $billingAddress = null
142146
) {
143147
$this->paymentRateLimiter->limit();
144148
try {
@@ -180,8 +184,8 @@ public function savePaymentInformationAndPlaceOrder(
180184
*/
181185
public function savePaymentInformation(
182186
$cartId,
183-
\Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
184-
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
187+
PaymentInterface $paymentMethod,
188+
QuoteAddressInterface $billingAddress = null
185189
) {
186190
if (!$this->saveRateLimiterDisabled) {
187191
try {
@@ -201,6 +205,7 @@ public function savePaymentInformation(
201205
//It's necessary to verify the price rules with the customer data
202206
$billingAddress->setCustomerId($customerId);
203207
}
208+
$this->updateCustomerBillingAddressId($quote, $billingAddress);
204209
$quote->removeAddress($quote->getBillingAddress()->getId());
205210
$quote->setBillingAddress($billingAddress);
206211
$quote->setDataChanges(true);
@@ -245,18 +250,12 @@ private function processShippingAddress(Quote $quote): void
245250
$shippingAddress->setSameAsBilling(1);
246251
}
247252
// Save new address in the customer address book and set it id for billing and shipping quote addresses.
248-
if ($shippingAddress->getSameAsBilling() && $shippingAddress->getSaveInAddressBook()) {
253+
if ($shippingAddress->getSameAsBilling() &&
254+
$shippingAddress->getSaveInAddressBook() &&
255+
!$shippingAddress->getCustomerAddressId()
256+
) {
249257
$shippingAddressData = $shippingAddress->exportCustomerAddress();
250-
$customer = $quote->getCustomer();
251-
$hasDefaultBilling = (bool)$customer->getDefaultBilling();
252-
$hasDefaultShipping = (bool)$customer->getDefaultShipping();
253-
if (!$hasDefaultShipping) {
254-
//Make provided address as default shipping address
255-
$shippingAddressData->setIsDefaultShipping(true);
256-
if (!$hasDefaultBilling && !$billingAddress->getSaveInAddressBook()) {
257-
$shippingAddressData->setIsDefaultBilling(true);
258-
}
259-
}
258+
$this->saveAddressesAsDefault($quote, $shippingAddressData, $billingAddress);
260259
$shippingAddressData->setCustomerId($quote->getCustomerId());
261260
$this->addressRepository->save($shippingAddressData);
262261
$quote->addCustomerAddress($shippingAddressData);
@@ -265,4 +264,47 @@ private function processShippingAddress(Quote $quote): void
265264
$billingAddress->setCustomerAddressId($shippingAddressData->getId());
266265
}
267266
}
267+
268+
/**
269+
* Update customer billing address ID if the address is the same as the quote billing address.
270+
*
271+
* @param Quote $quote
272+
* @param QuoteAddressInterface $billingAddress
273+
* @return void
274+
*/
275+
private function updateCustomerBillingAddressId(Quote $quote, QuoteAddressInterface $billingAddress): void
276+
{
277+
$quoteBillingAddress = $quote->getBillingAddress();
278+
if (!$billingAddress->getCustomerAddressId() &&
279+
$quoteBillingAddress->getCustomerAddressId() &&
280+
$this->addressComparator->isEqual($billingAddress, $quoteBillingAddress)
281+
) {
282+
$billingAddress->setCustomerAddressId($quoteBillingAddress->getCustomerAddressId());
283+
}
284+
}
285+
286+
/**
287+
* Save addresses as default shipping/ billing if they are not set yet.
288+
*
289+
* @param Quote $quote
290+
* @param AddressInterface $shippingAddressData
291+
* @param Address $billingAddress
292+
* @return void
293+
*/
294+
private function saveAddressesAsDefault(
295+
Quote $quote,
296+
AddressInterface $shippingAddressData,
297+
Address $billingAddress
298+
): void {
299+
$customer = $quote->getCustomer();
300+
$hasDefaultBilling = (bool)$customer->getDefaultBilling();
301+
$hasDefaultShipping = (bool)$customer->getDefaultShipping();
302+
if (!$hasDefaultShipping) {
303+
//Make provided address as default shipping address
304+
$shippingAddressData->setIsDefaultShipping(true);
305+
if (!$hasDefaultBilling && !$billingAddress->getSaveInAddressBook()) {
306+
$shippingAddressData->setIsDefaultBilling(true);
307+
}
308+
}
309+
}
268310
}

Diff for: app/code/Magento/Checkout/Model/ShippingInformationManagement.php

+47-2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ class ShippingInformationManagement implements ShippingInformationManagementInte
102102
*/
103103
private $shippingFactory;
104104

105+
/**
106+
* @var AddressComparatorInterface
107+
*/
108+
private $addressComparator;
109+
105110
/**
106111
* @param PaymentMethodManagementInterface $paymentMethodManagement
107112
* @param PaymentDetailsFactory $paymentDetailsFactory
@@ -115,6 +120,7 @@ class ShippingInformationManagement implements ShippingInformationManagementInte
115120
* @param CartExtensionFactory|null $cartExtensionFactory
116121
* @param ShippingAssignmentFactory|null $shippingAssignmentFactory
117122
* @param ShippingFactory|null $shippingFactory
123+
* @param AddressComparatorInterface|null $addressComparator
118124
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
119125
*/
120126
public function __construct(
@@ -129,7 +135,8 @@ public function __construct(
129135
TotalsCollector $totalsCollector,
130136
CartExtensionFactory $cartExtensionFactory = null,
131137
ShippingAssignmentFactory $shippingAssignmentFactory = null,
132-
ShippingFactory $shippingFactory = null
138+
ShippingFactory $shippingFactory = null,
139+
?AddressComparatorInterface $addressComparator = null,
133140
) {
134141
$this->paymentMethodManagement = $paymentMethodManagement;
135142
$this->paymentDetailsFactory = $paymentDetailsFactory;
@@ -146,6 +153,8 @@ public function __construct(
146153
->get(ShippingAssignmentFactory::class);
147154
$this->shippingFactory = $shippingFactory ?: ObjectManager::getInstance()
148155
->get(ShippingFactory::class);
156+
$this->addressComparator = $addressComparator
157+
?? ObjectManager::getInstance()->get(AddressComparatorInterface::class);
149158
}
150159

151160
/**
@@ -168,14 +177,15 @@ public function saveAddressInformation(
168177

169178
$address = $addressInformation->getShippingAddress();
170179
$this->validateAddress($address);
171-
180+
$this->updateCustomerShippingAddressId($quote, $address);
172181
if (!$address->getCustomerAddressId()) {
173182
$address->setCustomerAddressId(null);
174183
}
175184

176185
try {
177186
$billingAddress = $addressInformation->getBillingAddress();
178187
if ($billingAddress) {
188+
$this->updateCustomerBillingAddressId($quote, $billingAddress);
179189
if (!$billingAddress->getCustomerAddressId()) {
180190
$billingAddress->setCustomerAddressId(null);
181191
}
@@ -293,4 +303,39 @@ private function prepareShippingAssignment(
293303
$cartExtension->setShippingAssignments([$shippingAssignment]);
294304
return $quote->setExtensionAttributes($cartExtension);
295305
}
306+
307+
/**
308+
* Update customer shipping address ID if the address is the same as the quote shipping address.
309+
*
310+
* @param Quote $quote
311+
* @param AddressInterface $address
312+
* @return void
313+
*/
314+
private function updateCustomerShippingAddressId(Quote $quote, AddressInterface $address): void
315+
{
316+
$quoteShippingAddress = $quote->getShippingAddress();
317+
if (!$address->getCustomerAddressId() &&
318+
$quoteShippingAddress->getCustomerAddressId() &&
319+
$this->addressComparator->isEqual($address, $quoteShippingAddress)
320+
) {
321+
$address->setCustomerAddressId($quoteShippingAddress->getCustomerAddressId());
322+
}
323+
}
324+
325+
/**
326+
* Update customer billing address ID if the address is the same as the quote billing address.
327+
*
328+
* @param Quote $quote
329+
* @param AddressInterface $billingAddress
330+
* @return void
331+
*/
332+
private function updateCustomerBillingAddressId(Quote $quote, AddressInterface $billingAddress): void
333+
{
334+
$quoteBillingAddress = $quote->getBillingAddress();
335+
if ($quoteBillingAddress->getCustomerAddressId() &&
336+
$this->addressComparator->isEqual($billingAddress, $quoteBillingAddress)
337+
) {
338+
$billingAddress->setCustomerAddressId($quoteBillingAddress->getCustomerAddressId());
339+
}
340+
}
296341
}

Diff for: app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php

+43-9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use Magento\Checkout\Api\PaymentProcessingRateLimiterInterface;
1212
use Magento\Checkout\Api\PaymentSavingRateLimiterInterface;
1313
use Magento\Checkout\Model\PaymentInformationManagement;
14+
use Magento\Customer\Api\Data\AddressInterface as CustomerAddressInterface;
15+
use Magento\Customer\Api\Data\CustomerInterface;
1416
use Magento\Framework\Exception\LocalizedException;
1517
use Magento\Framework\Phrase;
1618
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
@@ -72,6 +74,11 @@ class PaymentInformationManagementTest extends TestCase
7274
*/
7375
private $saveLimiterMock;
7476

77+
/**
78+
* @var Address|MockObject
79+
*/
80+
private $quoteShippingAddress;
81+
7582
protected function setUp(): void
7683
{
7784
$objectManager = new ObjectManager($this);
@@ -100,10 +107,33 @@ protected function setUp(): void
100107
);
101108
$objectManager->setBackwardCompatibleProperty($this->model, 'logger', $this->loggerMock);
102109
$objectManager->setBackwardCompatibleProperty($this->model, 'cartRepository', $this->cartRepositoryMock);
110+
111+
$this->quoteShippingAddress = $this->getMockBuilder(Address::class)
112+
->addMethods(['setLimitCarrier'])
113+
->onlyMethods([
114+
'getShippingMethod',
115+
'getShippingRateByCode',
116+
'getSameAsBilling',
117+
'getSaveInAddressBook',
118+
'setSaveInAddressBook',
119+
'exportCustomerAddress'])
120+
->disableOriginalConstructor()
121+
->getMock();
103122
}
104123

105124
public function testSavePaymentInformationAndPlaceOrder()
106125
{
126+
$shippingAddressMock = $this->createMock(CustomerAddressInterface::class);
127+
$this->quoteShippingAddress->expects($this->once())
128+
->method('getSaveInAddressBook')
129+
->willReturn(true);
130+
$this->quoteShippingAddress->expects($this->once())
131+
->method('getSameAsBilling')
132+
->willReturn(true);
133+
$this->quoteShippingAddress->expects($this->once())
134+
->method('exportCustomerAddress')
135+
->willReturn($shippingAddressMock);
136+
107137
$orderId = 200;
108138
$this->assertEquals(
109139
$orderId,
@@ -239,25 +269,29 @@ private function getMockForAssignBillingAddress($cartId, $billingAddressMock)
239269
{
240270
$billingAddressId = 1;
241271
$quoteMock = $this->createMock(Quote::class);
272+
$customerMock = $this->createMock(CustomerInterface::class);
242273
$quoteBillingAddress = $this->createMock(Address::class);
243274
$shippingRate = $this->createPartialMock(Rate::class, []);
244275
$shippingRate->setCarrier('flatrate');
245-
$quoteShippingAddress = $this->getMockBuilder(Address::class)
246-
->addMethods(['setLimitCarrier'])
247-
->onlyMethods(['getShippingMethod', 'getShippingRateByCode'])
248-
->disableOriginalConstructor()
249-
->getMock();
250276
$this->cartRepositoryMock->expects($this->any())->method('getActive')->with($cartId)->willReturn($quoteMock);
251277
$quoteMock->method('getBillingAddress')->willReturn($quoteBillingAddress);
252-
$quoteMock->expects($this->any())->method('getShippingAddress')->willReturn($quoteShippingAddress);
278+
$quoteMock->method('getCustomer')->willReturn($customerMock);
279+
$quoteMock->expects($this->any())->method('getShippingAddress')->willReturn($this->quoteShippingAddress);
253280
$quoteBillingAddress->expects($this->any())->method('getId')->willReturn($billingAddressId);
254281
$quoteBillingAddress->expects($this->any())->method('getId')->willReturn($billingAddressId);
255282
$quoteMock->expects($this->any())->method('removeAddress')->with($billingAddressId);
256283
$quoteMock->expects($this->any())->method('setBillingAddress')->with($billingAddressMock);
257284
$quoteMock->expects($this->any())->method('setDataChanges')->willReturnSelf();
258-
$quoteShippingAddress->expects($this->any())->method('getShippingRateByCode')->willReturn($shippingRate);
259-
$quoteShippingAddress->expects($this->any())->method('getShippingMethod')->willReturn('flatrate_flatrate');
260-
$quoteShippingAddress->expects($this->any())->method('setLimitCarrier')->with('flatrate')->willReturnSelf();
285+
$this->quoteShippingAddress->expects($this->any())
286+
->method('getShippingRateByCode')
287+
->willReturn($shippingRate);
288+
$this->quoteShippingAddress->expects($this->any())
289+
->method('getShippingMethod')
290+
->willReturn('flatrate_flatrate');
291+
$this->quoteShippingAddress->expects($this->any())
292+
->method('setLimitCarrier')
293+
->with('flatrate')
294+
->willReturnSelf();
261295
}
262296

263297
/**

0 commit comments

Comments
 (0)