Skip to content

Commit

Permalink
MAGETWO-81680: Fix #10856: Sync billing with shipping address on Admi…
Browse files Browse the repository at this point in the history
…n Order Page #11385
  • Loading branch information
Oleksii Korshenko authored Oct 24, 2017
2 parents 3f8b857 + 8e8cce8 commit 4d613f2
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 60 deletions.
3 changes: 2 additions & 1 deletion app/code/Magento/Quote/Model/Quote/Address.php
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,8 @@ public function validateMinimumAmount()
*/
public function getAppliedTaxes()
{
return $this->serializer->unserialize($this->getData('applied_taxes'));
$taxes = $this->getData('applied_taxes');
return $taxes ? $this->serializer->unserialize($taxes) : [];
}

/**
Expand Down
28 changes: 13 additions & 15 deletions app/code/Magento/Quote/Test/Unit/Model/Quote/AddressTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace Magento\Quote\Test\Unit\Model\Quote;

use Magento\Directory\Model\Currency;
use \Magento\Quote\Model\Quote\Address;
use Magento\Quote\Model\Quote\Address;
use Magento\Quote\Model\Quote\Address\Rate;
use Magento\Quote\Model\ResourceModel\Quote\Address\Rate\CollectionFactory as RateCollectionFactory;
use Magento\Quote\Model\ResourceModel\Quote\Address\Rate\Collection as RatesCollection;
Expand All @@ -28,6 +28,7 @@
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Api\Data\WebsiteInterface;
use Magento\Quote\Model\Quote\Address\RateResult\AbstractResult;
use Magento\Framework\Serialize\Serializer\Json;

/**
* Test class for sales quote address model
Expand Down Expand Up @@ -117,7 +118,7 @@ protected function setUp()
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);

$this->scopeConfig = $this->createMock(\Magento\Framework\App\Config::class);
$this->serializer = $this->createMock(\Magento\Framework\Serialize\Serializer\Json::class);
$this->serializer = new Json();

$this->requestFactory = $this->getMockBuilder(RateRequestFactory::class)
->disableOriginalConstructor()
Expand Down Expand Up @@ -273,20 +274,17 @@ public function testValidateMiniumumAmountNegative()
public function testSetAndGetAppliedTaxes()
{
$data = ['data'];
$result = json_encode($data);

$this->serializer->expects($this->once())
->method('serialize')
->with($data)
->willReturn($result);

$this->serializer->expects($this->once())
->method('unserialize')
->with($result)
->willReturn($data);
self::assertInstanceOf(Address::class, $this->address->setAppliedTaxes($data));
self::assertEquals($data, $this->address->getAppliedTaxes());
}

$this->assertInstanceOf(\Magento\Quote\Model\Quote\Address::class, $this->address->setAppliedTaxes($data));
$this->assertEquals($data, $this->address->getAppliedTaxes());
/**
* Checks a case, when applied taxes are not provided.
*/
public function testGetAppliedTaxesWithEmptyValue()
{
$this->address->setData('applied_taxes', null);
self::assertEquals([], $this->address->getAppliedTaxes());
}

/**
Expand Down
57 changes: 32 additions & 25 deletions app/code/Magento/Sales/Model/AdminOrder/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

use Magento\Customer\Api\AddressMetadataInterface;
use Magento\Customer\Model\Metadata\Form as CustomerForm;
use Magento\Framework\App\ObjectManager;
use Magento\Quote\Model\Quote\Address;
use Magento\Quote\Model\Quote\Item;

/**
Expand Down Expand Up @@ -323,7 +325,7 @@ public function __construct(
$this->dataObjectHelper = $dataObjectHelper;
$this->orderManagement = $orderManagement;
$this->quoteFactory = $quoteFactory;
$this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
$this->serializer = $serializer ?: ObjectManager::getInstance()
->get(\Magento\Framework\Serialize\Serializer\Json::class);
parent::__construct($data);
}
Expand Down Expand Up @@ -1449,32 +1451,36 @@ public function getBillingAddress()
*/
public function setBillingAddress($address)
{
if (is_array($address)) {
$billingAddress = $this->_objectManager->create(
\Magento\Quote\Model\Quote\Address::class
)->setData(
$address
)->setAddressType(
\Magento\Quote\Model\Quote\Address::TYPE_BILLING
);
$this->_setQuoteAddress($billingAddress, $address);
/**
* save_in_address_book is not a valid attribute and is filtered out by _setQuoteAddress,
* that is why it should be added after _setQuoteAddress call
*/
$saveInAddressBook = (int)(!empty($address['save_in_address_book']));
$billingAddress->setData('save_in_address_book', $saveInAddressBook);

if (!$this->getQuote()->isVirtual() && $this->getShippingAddress()->getSameAsBilling()) {
$shippingAddress = clone $billingAddress;
$shippingAddress->setSameAsBilling(true);
$shippingAddress->setSaveInAddressBook(false);
$address['save_in_address_book'] = 0;
$this->setShippingAddress($address);
}
if (!is_array($address)) {
return $this;
}

$billingAddress = $this->_objectManager->create(Address::class)
->setData($address)
->setAddressType(Address::TYPE_BILLING);

$this->_setQuoteAddress($billingAddress, $address);

/**
* save_in_address_book is not a valid attribute and is filtered out by _setQuoteAddress,
* that is why it should be added after _setQuoteAddress call
*/
$saveInAddressBook = (int)(!empty($address['save_in_address_book']));
$billingAddress->setData('save_in_address_book', $saveInAddressBook);

$quote = $this->getQuote();
if (!$quote->isVirtual() && $this->getShippingAddress()->getSameAsBilling()) {
$address['save_in_address_book'] = 0;
$this->setShippingAddress($address);
}

$this->getQuote()->setBillingAddress($billingAddress);
// not assigned billing address should be saved as new
// but if quote already has the billing address it won't be overridden
if (empty($billingAddress->getCustomerAddressId())) {
$billingAddress->setCustomerAddressId(null);
$quote->getBillingAddress()->setCustomerAddressId(null);
}
$quote->setBillingAddress($billingAddress);

return $this;
}
Expand Down Expand Up @@ -1775,6 +1781,7 @@ public function _prepareCustomer()
$address = $this->getShippingAddress()->setCustomerId($this->getQuote()->getCustomer()->getId());
$this->setShippingAddress($address);
}
$this->getBillingAddress()->setCustomerId($customer->getId());
$this->getQuote()->updateCustomerData($this->getQuote()->getCustomer());

$customer = $this->getQuote()->getCustomer();
Expand Down
47 changes: 29 additions & 18 deletions app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ define([
}
if(this.addresses[id]){
this.fillAddressFields(container, this.addresses[id]);

}
else{
this.fillAddressFields(container, {});
Expand Down Expand Up @@ -190,43 +191,53 @@ define([
}
},

changeAddressField : function(event){
var field = Event.element(event);
var re = /[^\[]*\[([^\]]*)_address\]\[([^\]]*)\](\[(\d)\])?/;
var matchRes = field.name.match(re);
/**
* Triggers on each form's element changes.
*
* @param {Object} event
*/
changeAddressField: function (event) {
var field = Event.element(event),
re = /[^\[]*\[([^\]]*)_address\]\[([^\]]*)\](\[(\d)\])?/,
matchRes = field.name.match(re),
type,
name,
data;

if (!matchRes) {
return;
}

var type = matchRes[1];
var name = matchRes[2];
var data;
type = matchRes[1];
name = matchRes[2];

if(this.isBillingField(field.id)){
data = this.serializeData(this.billingAddressContainer)
}
else{
data = this.serializeData(this.shippingAddressContainer)
if (this.isBillingField(field.id)) {
data = this.serializeData(this.billingAddressContainer);
} else {
data = this.serializeData(this.shippingAddressContainer);
}
data = data.toObject();

if( (type == 'billing' && this.shippingAsBilling)
|| (type == 'shipping' && !this.shippingAsBilling) ) {
if (type === 'billing' && this.shippingAsBilling || type === 'shipping' && !this.shippingAsBilling) {
data['reset_shipping'] = true;
}

data['order['+type+'_address][customer_address_id]'] = $('order-'+type+'_address_customer_address_id').value;
data['order[' + type + '_address][customer_address_id]'] = null;
data['shipping_as_billing'] = jQuery('[name="shipping_same_as_billing"]').is(':checked') ? 1 : 0;

if (name === 'customer_address_id') {
data['order[' + type + '_address][customer_address_id]'] =
$('order-' + type + '_address_customer_address_id').value;
}

if (data['reset_shipping']) {
this.resetShippingMethod(data);
} else {
this.saveData(data);
if (name == 'country_id' || name == 'customer_address_id') {

if (name === 'country_id' || name === 'customer_address_id') {
this.loadArea(['shipping_method', 'billing_method', 'totals', 'items'], true, data);
}
// added for reloading of default sender and default recipient for giftmessages
//this.loadArea(['giftmessage'], true, data);
}
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order;

use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Backend\Model\Session\Quote;
use Magento\Quote\Api\CartRepositoryInterface;

/**
* @magentoAppArea adminhtml
* @magentoDbIsolation enabled
Expand Down Expand Up @@ -158,7 +162,7 @@ public function testIndexAction()
*/
public function testGetAclResource($actionName, $reordered, $expectedResult)
{
$this->_objectManager->get(\Magento\Backend\Model\Session\Quote::class)->setReordered($reordered);
$this->_objectManager->get(Quote::class)->setReordered($reordered);
$orderController = $this->_objectManager->get(
\Magento\Sales\Controller\Adminhtml\Order\Stub\OrderCreateStub::class
);
Expand Down Expand Up @@ -229,4 +233,57 @@ public function testDeniedSaveAction()
$this->dispatch('backend/sales/order_create/save');
$this->assertEquals('403', $this->getResponse()->getHttpResponseCode());
}

/**
* Checks a case when shipping is the same as billing and billing address details was changed by request.
* Both billing and shipping addresses should be updated.
*
* @magentoAppArea adminhtml
* @magentoDataFixture Magento/Sales/_files/quote_with_customer.php
*/
public function testSyncBetweenQuoteAddresses()
{
/** @var CustomerRepositoryInterface $customerRepository */
$customerRepository = $this->_objectManager->get(CustomerRepositoryInterface::class);
$customer = $customerRepository->get('customer@example.com');

/** @var CartRepositoryInterface $quoteRepository */
$quoteRepository = $this->_objectManager->get(CartRepositoryInterface::class);
$quote = $quoteRepository->getActiveForCustomer($customer->getId());

$session = $this->_objectManager->get(Quote::class);
$session->setQuoteId($quote->getId());

$data = [
'firstname' => 'John',
'lastname' => 'Doe',
'street' => ['Soborna 23'],
'city' => 'Kyiv',
'country_id' => 'UA',
'region' => 'Kyivska',
'region_id' => 1
];
$this->getRequest()->setPostValue(
[
'order' => ['billing_address' => $data],
'reset_shipping' => 1,
'customer_id' => $customer->getId(),
'store_id' => 1,
'json' => true
]
);

$this->dispatch('backend/sales/order_create/loadBlock/block/shipping_address');
self::assertEquals(200, $this->getResponse()->getHttpResponseCode());

$updatedQuote = $quoteRepository->get($quote->getId());

$billingAddress = $updatedQuote->getBillingAddress();
self::assertEquals($data['region_id'], $billingAddress->getRegionId());
self::assertEquals($data['country_id'], $billingAddress->getCountryId());

$shippingAddress = $updatedQuote->getShippingAddress();
self::assertEquals($data['city'], $shippingAddress->getCity());
self::assertEquals($data['street'], $shippingAddress->getStreet());
}
}

0 comments on commit 4d613f2

Please sign in to comment.