Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 1743a36

Browse files
committed
Sync billing with shipping address on Admin Order Page
- Set customer address ID only if the address was selected in dropdown - Removed "old" billing address from quote if customer address doesn't specified
1 parent d2cbddd commit 1743a36

File tree

3 files changed

+114
-43
lines changed
  • app/code/Magento/Sales
  • dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order

3 files changed

+114
-43
lines changed

app/code/Magento/Sales/Model/AdminOrder/Create.php

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use Magento\Customer\Api\AddressMetadataInterface;
1212
use Magento\Customer\Model\Metadata\Form as CustomerForm;
13+
use Magento\Quote\Model\Quote\Address;
1314
use Magento\Quote\Model\Quote\Item;
1415

1516
/**
@@ -1449,32 +1450,35 @@ public function getBillingAddress()
14491450
*/
14501451
public function setBillingAddress($address)
14511452
{
1452-
if (is_array($address)) {
1453-
$billingAddress = $this->_objectManager->create(
1454-
\Magento\Quote\Model\Quote\Address::class
1455-
)->setData(
1456-
$address
1457-
)->setAddressType(
1458-
\Magento\Quote\Model\Quote\Address::TYPE_BILLING
1459-
);
1460-
$this->_setQuoteAddress($billingAddress, $address);
1461-
/**
1462-
* save_in_address_book is not a valid attribute and is filtered out by _setQuoteAddress,
1463-
* that is why it should be added after _setQuoteAddress call
1464-
*/
1465-
$saveInAddressBook = (int)(!empty($address['save_in_address_book']));
1466-
$billingAddress->setData('save_in_address_book', $saveInAddressBook);
1467-
1468-
if (!$this->getQuote()->isVirtual() && $this->getShippingAddress()->getSameAsBilling()) {
1469-
$shippingAddress = clone $billingAddress;
1470-
$shippingAddress->setSameAsBilling(true);
1471-
$shippingAddress->setSaveInAddressBook(false);
1472-
$address['save_in_address_book'] = 0;
1473-
$this->setShippingAddress($address);
1474-
}
1453+
if (!is_array($address)) {
1454+
return $this;
1455+
}
1456+
1457+
$billingAddress = $this->_objectManager->create(Address::class)
1458+
->setData($address)
1459+
->setAddressType(Address::TYPE_BILLING);
1460+
1461+
$this->_setQuoteAddress($billingAddress, $address);
1462+
1463+
/**
1464+
* save_in_address_book is not a valid attribute and is filtered out by _setQuoteAddress,
1465+
* that is why it should be added after _setQuoteAddress call
1466+
*/
1467+
$saveInAddressBook = (int)(!empty($address['save_in_address_book']));
1468+
$billingAddress->setData('save_in_address_book', $saveInAddressBook);
1469+
1470+
$quote = $this->getQuote();
1471+
if (!$quote->isVirtual() && $this->getShippingAddress()->getSameAsBilling()) {
1472+
$address['save_in_address_book'] = 0;
1473+
$this->setShippingAddress($address);
1474+
}
14751475

1476-
$this->getQuote()->setBillingAddress($billingAddress);
1476+
// not assigned billing address should be saved as new
1477+
// but if quote already has the billing address it won't be overridden
1478+
if (empty($billingAddress->getCustomerAddressId())) {
1479+
$quote->removeAddress($quote->getBillingAddress()->getId());
14771480
}
1481+
$quote->setBillingAddress($billingAddress);
14781482

14791483
return $this;
14801484
}

app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ define([
157157
}
158158
if(this.addresses[id]){
159159
this.fillAddressFields(container, this.addresses[id]);
160+
160161
}
161162
else{
162163
this.fillAddressFields(container, {});
@@ -190,43 +191,52 @@ define([
190191
}
191192
},
192193

193-
changeAddressField : function(event){
194-
var field = Event.element(event);
195-
var re = /[^\[]*\[([^\]]*)_address\]\[([^\]]*)\](\[(\d)\])?/;
196-
var matchRes = field.name.match(re);
194+
/**
195+
* Triggers on each form's element changes.
196+
*
197+
* @param {Object} event
198+
*/
199+
changeAddressField: function (event) {
200+
var field = Event.element(event),
201+
re = /[^\[]*\[([^\]]*)_address\]\[([^\]]*)\](\[(\d)\])?/,
202+
matchRes = field.name.match(re),
203+
type,
204+
name,
205+
data;
197206

198207
if (!matchRes) {
199208
return;
200209
}
201210

202-
var type = matchRes[1];
203-
var name = matchRes[2];
204-
var data;
211+
type = matchRes[1];
212+
name = matchRes[2];
205213

206-
if(this.isBillingField(field.id)){
207-
data = this.serializeData(this.billingAddressContainer)
208-
}
209-
else{
210-
data = this.serializeData(this.shippingAddressContainer)
214+
if (this.isBillingField(field.id)) {
215+
data = this.serializeData(this.billingAddressContainer);
216+
} else {
217+
data = this.serializeData(this.shippingAddressContainer);
211218
}
212219
data = data.toObject();
213220

214-
if( (type == 'billing' && this.shippingAsBilling)
215-
|| (type == 'shipping' && !this.shippingAsBilling) ) {
221+
if (type === 'billing' && this.shippingAsBilling || type === 'shipping' && !this.shippingAsBilling) {
216222
data['reset_shipping'] = true;
217223
}
218224

219-
data['order['+type+'_address][customer_address_id]'] = $('order-'+type+'_address_customer_address_id').value;
225+
data['order[' + type + '_address][customer_address_id]'] = null;
226+
227+
if (name === 'customer_address_id') {
228+
data['order[' + type + '_address][customer_address_id]'] =
229+
$('order-' + type + '_address_customer_address_id').value;
230+
}
220231

221232
if (data['reset_shipping']) {
222233
this.resetShippingMethod(data);
223234
} else {
224235
this.saveData(data);
225-
if (name == 'country_id' || name == 'customer_address_id') {
236+
237+
if (name === 'country_id' || name === 'customer_address_id') {
226238
this.loadArea(['shipping_method', 'billing_method', 'totals', 'items'], true, data);
227239
}
228-
// added for reloading of default sender and default recipient for giftmessages
229-
//this.loadArea(['giftmessage'], true, data);
230240
}
231241
},
232242

dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
*/
66
namespace Magento\Sales\Controller\Adminhtml\Order;
77

8+
use Magento\Customer\Api\CustomerRepositoryInterface;
9+
use Magento\Backend\Model\Session\Quote;
10+
use Magento\Quote\Api\CartRepositoryInterface;
11+
812
/**
913
* @magentoAppArea adminhtml
1014
* @magentoDbIsolation enabled
@@ -158,7 +162,7 @@ public function testIndexAction()
158162
*/
159163
public function testGetAclResource($actionName, $reordered, $expectedResult)
160164
{
161-
$this->_objectManager->get(\Magento\Backend\Model\Session\Quote::class)->setReordered($reordered);
165+
$this->_objectManager->get(Quote::class)->setReordered($reordered);
162166
$orderController = $this->_objectManager->get(
163167
\Magento\Sales\Controller\Adminhtml\Order\Stub\OrderCreateStub::class
164168
);
@@ -229,4 +233,57 @@ public function testDeniedSaveAction()
229233
$this->dispatch('backend/sales/order_create/save');
230234
$this->assertEquals('403', $this->getResponse()->getHttpResponseCode());
231235
}
236+
237+
/**
238+
* Checks a case when shipping is the same as billing and billing address details was changed by request.
239+
* Both billing and shipping addresses should be updated.
240+
*
241+
* @magentoAppArea adminhtml
242+
* @magentoDataFixture Magento/Sales/_files/quote_with_customer.php
243+
*/
244+
public function testSyncBetweenQuoteAddresses()
245+
{
246+
/** @var CustomerRepositoryInterface $customerRepository */
247+
$customerRepository = $this->_objectManager->get(CustomerRepositoryInterface::class);
248+
$customer = $customerRepository->get('[email protected]');
249+
250+
/** @var CartRepositoryInterface $quoteRepository */
251+
$quoteRepository = $this->_objectManager->get(CartRepositoryInterface::class);
252+
$quote = $quoteRepository->getActiveForCustomer($customer->getId());
253+
254+
$session = $this->_objectManager->get(Quote::class);
255+
$session->setQuoteId($quote->getId());
256+
257+
$data = [
258+
'firstname' => 'John',
259+
'lastname' => 'Doe',
260+
'street' => ['Soborna 23'],
261+
'city' => 'Kyiv',
262+
'country_id' => 'UA',
263+
'region' => 'Kyivska',
264+
'region_id' => 1
265+
];
266+
$this->getRequest()->setPostValue(
267+
[
268+
'order' => ['billing_address' => $data],
269+
'reset_shipping' => 1,
270+
'customer_id' => $customer->getId(),
271+
'store_id' => 1,
272+
'json' => true
273+
]
274+
);
275+
276+
$this->dispatch('backend/sales/order_create/loadBlock/block/shipping_address');
277+
self::assertEquals(200, $this->getResponse()->getHttpResponseCode());
278+
279+
$updatedQuote = $quoteRepository->get($quote->getId());
280+
281+
$billingAddress = $updatedQuote->getBillingAddress();
282+
self::assertEquals($data['region_id'], $billingAddress->getRegionId());
283+
self::assertEquals($data['country_id'], $billingAddress->getCountryId());
284+
285+
$shippingAddress = $updatedQuote->getShippingAddress();
286+
self::assertEquals($data['city'], $shippingAddress->getCity());
287+
self::assertEquals($data['street'], $shippingAddress->getStreet());
288+
}
232289
}

0 commit comments

Comments
 (0)