diff --git a/app/code/Magento/Sales/Model/Order/Invoice/Plugin/AddressUpdate.php b/app/code/Magento/Sales/Model/Order/Invoice/Plugin/AddressUpdate.php new file mode 100644 index 0000000000000000000000000000000000000000..9efa4258763e08d4e1833a6ab1108b1f1074b0a2 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Invoice/Plugin/AddressUpdate.php @@ -0,0 +1,76 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Model\Order\Invoice\Plugin; + +class AddressUpdate +{ + /** + * @var \Magento\Sales\Model\ResourceModel\GridPool + */ + private $gridPool; + + /** + * @var \Magento\Sales\Model\ResourceModel\Attribute + */ + private $attribute; + + /** + * AddressUpdate constructor. + * @param \Magento\Sales\Model\ResourceModel\GridPool $gridPool + * @param \Magento\Sales\Model\ResourceModel\Attribute $attribute + */ + public function __construct( + \Magento\Sales\Model\ResourceModel\GridPool $gridPool, + \Magento\Sales\Model\ResourceModel\Attribute $attribute + ) { + $this->gridPool = $gridPool; + $this->attribute = $attribute; + } + + /** + * @param \Magento\Sales\Model\ResourceModel\Order\Handler\Address $subject + * @param \Magento\Sales\Model\Order $order + * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterProcess( + \Magento\Sales\Model\ResourceModel\Order\Handler\Address $subject, + \Magento\Sales\Model\ResourceModel\Order\Handler\Address $result, + \Magento\Sales\Model\Order $order + ) { + if ($order->hasInvoices()) { + $billingAddress = $order->getBillingAddress(); + $shippingAddress = $order->getShippingAddress(); + + $orderInvoiceHasChanges = false; + /** @var \Magento\Sales\Model\Order\Invoice $invoice */ + foreach ($order->getInvoiceCollection()->getItems() as $invoice) { + $invoiceAttributesForSave = []; + + if (!$invoice->getBillingAddressId()) { + $invoice->setBillingAddressId($billingAddress->getId()); + $invoiceAttributesForSave[] = 'billing_address_id'; + $orderInvoiceHasChanges = true; + } + + if (!$invoice->getShippingAddressId()) { + $invoice->setShippingAddressId($shippingAddress->getId()); + $invoiceAttributesForSave[] = 'shipping_address_id'; + $orderInvoiceHasChanges = true; + } + + if (!empty($invoiceAttributesForSave)) { + $this->attribute->saveAttribute($invoice, $invoiceAttributesForSave); + } + } + + if ($orderInvoiceHasChanges) { + $this->gridPool->refreshByOrderId($order->getId()); + } + } + } +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Plugin/AddressUpdateTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Plugin/AddressUpdateTest.php new file mode 100644 index 0000000000000000000000000000000000000000..949ec38076db67f190eda22f626385282af922db --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Plugin/AddressUpdateTest.php @@ -0,0 +1,90 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Test\Unit\Model\Order\Invoice\Plugin; + +class AddressUpdateTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Sales\Model\Order\Invoice\Plugin\AddressUpdate + */ + private $model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $gripPoolMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $attributeMock; + + protected function setUp() + { + $this->gripPoolMock = $this->getMock(\Magento\Sales\Model\ResourceModel\GridPool::class, [], [], '', false); + $this->attributeMock = $this->getMock(\Magento\Sales\Model\ResourceModel\Attribute::class, [], [], '', false); + $this->model = new \Magento\Sales\Model\Order\Invoice\Plugin\AddressUpdate( + $this->gripPoolMock, + $this->attributeMock + ); + } + + public function testAfterProcess() + { + $billingId = 100; + $shippingId = 200; + $orderId = 50; + + $orderMock = $this->getMock( + \Magento\Sales\Model\Order::class, + ['hasInvoices', 'getBillingAddress', 'getShippingAddress', 'getInvoiceCollection', 'getId'], + [], + '', + false + ); + + $shippingMock = $this->getMock(\Magento\Sales\Model\Order\Address::class, [], [], '', false); + $shippingMock->expects($this->once())->method('getId')->willReturn($shippingId); + + $billingMock = $this->getMock(\Magento\Sales\Model\Order\Address::class, [], [], '', false); + $billingMock->expects($this->once())->method('getId')->willReturn($billingId); + + $invoiceCollectionMock = $this->getMock( + \Magento\Sales\Model\ResourceModel\Order\Invoice\Collection::class, + [], + [], + '', + false + ); + $invoiceMock = $this->getMock(\Magento\Sales\Model\Order\Invoice::class, [], [], '', false); + $invoiceCollectionMock->expects($this->once())->method('getItems')->willReturn([$invoiceMock]); + + $orderMock->expects($this->once())->method('hasInvoices')->willReturn(true); + $orderMock->expects($this->once())->method('getBillingAddress')->willReturn($billingMock); + $orderMock->expects($this->once())->method('getShippingAddress')->willReturn($shippingMock); + $orderMock->expects($this->once())->method('getInvoiceCollection')->willReturn($invoiceCollectionMock); + $orderMock->expects($this->once())->method('getId')->willReturn($orderId); + + $invoiceMock->expects($this->once())->method('getBillingAddressId')->willReturn(null); + $invoiceMock->expects($this->once())->method('getShippingAddressId')->willReturn(null); + $invoiceMock->expects($this->once())->method('setShippingAddressId')->with($shippingId)->willReturnSelf(); + $invoiceMock->expects($this->once())->method('setBillingAddressId')->with($billingId)->willReturnSelf(); + + $this->attributeMock->expects($this->once()) + ->method('saveAttribute') + ->with($invoiceMock, ['billing_address_id', 'shipping_address_id']) + ->willReturnSelf(); + + $this->gripPoolMock->expects($this->once())->method('refreshByOrderId')->with($orderId)->willReturnSelf(); + + $this->model->afterProcess( + $this->getMock(\Magento\Sales\Model\ResourceModel\Order\Handler\Address::class, [], [], '', false), + $this->getMock(\Magento\Sales\Model\ResourceModel\Order\Handler\Address::class, [], [], '', false), + $orderMock + ); + } +} diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index dfdb0f6a261c51490e99955bdd61fd1bae328e60..47800b377bb4dd5703a6d3640980982e99bbeaed 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -933,4 +933,7 @@ </argument> </arguments> </type> + <type name="Magento\Sales\Model\ResourceModel\Order\Handler\Address"> + <plugin name="addressUpdate" type="Magento\Sales\Model\Order\Invoice\Plugin\AddressUpdate"/> + </type> </config>