Skip to content

Commit 6721bcf

Browse files
committed
Merge remote-tracking branch 'origin/2.2-develop' into MAGETWO-83169
2 parents 619f01d + dbcc3c4 commit 6721bcf

File tree

29 files changed

+807
-86
lines changed

29 files changed

+807
-86
lines changed

app/code/Magento/Catalog/Model/Product/Attribute/OptionManagement.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ public function getItems($attributeCode)
4040
*/
4141
public function add($attributeCode, $option)
4242
{
43+
/** @var \Magento\Eav\Api\Data\AttributeOptionInterface[] $currentOptions */
44+
$currentOptions = $this->getItems($attributeCode);
45+
if (is_array($currentOptions)) {
46+
array_walk($currentOptions, function (&$attributeOption) {
47+
/** @var \Magento\Eav\Api\Data\AttributeOptionInterface $attributeOption */
48+
$attributeOption = $attributeOption->getLabel();
49+
});
50+
if (in_array($option->getLabel(), $currentOptions)) {
51+
return false;
52+
}
53+
}
4354
return $this->eavOptionManagement->add(
4455
\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE,
4556
$attributeCode,

app/code/Magento/Catalog/Model/Product/Gallery/Processor.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ public function addImage(
192192
$mediaGalleryData['images'][] = [
193193
'file' => $fileName,
194194
'position' => $position,
195+
'media_type' => 'image',
195196
'label' => '',
196197
'disabled' => (int)$exclude,
197198
];

app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
}
6060
};
6161

62+
var treeRoot = '#tree-div';
63+
6264
/**
6365
* Fix ext compatibility with prototype 1.6
6466
*/
@@ -491,7 +493,7 @@
491493
if (data.error) {
492494
reRenderTree();
493495
} else {
494-
$(obj.tree.container.dom).trigger('categoryMove.tree');
496+
$(treeRoot).trigger('categoryMove.tree');
495497
}
496498
$('.page-main-actions').next('.messages').remove();
497499
$('.page-main-actions').next('#messages').remove();

app/code/Magento/Newsletter/Model/Subscriber.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77

88
use Magento\Customer\Api\AccountManagementInterface;
99
use Magento\Customer\Api\CustomerRepositoryInterface;
10+
use Magento\Framework\App\ObjectManager;
1011
use Magento\Framework\Exception\MailException;
1112
use Magento\Framework\Exception\NoSuchEntityException;
13+
use Magento\Framework\Stdlib\DateTime\DateTime;
1214

1315
/**
1416
* Subscriber model
@@ -94,6 +96,12 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel
9496
*/
9597
protected $_customerSession;
9698

99+
/**
100+
* Date
101+
* @var DateTime
102+
*/
103+
private $dateTime;
104+
97105
/**
98106
* Store manager
99107
*
@@ -134,9 +142,10 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel
134142
* @param CustomerRepositoryInterface $customerRepository
135143
* @param AccountManagementInterface $customerAccountManagement
136144
* @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
137-
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
138-
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
145+
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
146+
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
139147
* @param array $data
148+
* @param DateTime|null $dateTime
140149
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
141150
*/
142151
public function __construct(
@@ -152,7 +161,8 @@ public function __construct(
152161
\Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
153162
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
154163
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
155-
array $data = []
164+
array $data = [],
165+
DateTime $dateTime = null
156166
) {
157167
$this->_newsletterData = $newsletterData;
158168
$this->_scopeConfig = $scopeConfig;
@@ -162,6 +172,7 @@ public function __construct(
162172
$this->customerRepository = $customerRepository;
163173
$this->customerAccountManagement = $customerAccountManagement;
164174
$this->inlineTranslation = $inlineTranslation;
175+
$this->dateTime = $dateTime ?: ObjectManager::getInstance()->get(DateTime::class);
165176
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
166177
}
167178

@@ -810,4 +821,18 @@ public function getSubscriberFullName()
810821
}
811822
return $name;
812823
}
824+
825+
/**
826+
* Set date of last changed status
827+
*
828+
* @return $this
829+
*/
830+
public function beforeSave()
831+
{
832+
parent::beforeSave();
833+
if ($this->dataHasChangedFor('subscriber_status')) {
834+
$this->setChangeStatusAt($this->dateTime->gmtDate());
835+
}
836+
return $this;
837+
}
813838
}

app/code/Magento/Quote/Model/Quote.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ public function addCustomerAddress(\Magento\Customer\Api\Data\AddressInterface $
10571057
public function updateCustomerData(\Magento\Customer\Api\Data\CustomerInterface $customer)
10581058
{
10591059
$quoteCustomer = $this->getCustomer();
1060-
$this->dataObjectHelper->mergeDataObjects(get_class($quoteCustomer), $quoteCustomer, $customer);
1060+
$this->dataObjectHelper->mergeDataObjects(CustomerInterface::class, $quoteCustomer, $customer);
10611061
$this->setCustomer($quoteCustomer);
10621062
return $this;
10631063
}

app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrar.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,19 @@ class OrderRegistrar implements \Magento\Sales\Model\Order\Shipment\OrderRegistr
1717
*/
1818
public function register(OrderInterface $order, ShipmentInterface $shipment)
1919
{
20-
/** @var \Magento\Sales\Api\Data\ShipmentItemInterface|\Magento\Sales\Model\Order\Shipment\Item $item */
20+
$totalQty = 0;
21+
/** @var \Magento\Sales\Model\Order\Shipment\Item $item */
2122
foreach ($shipment->getItems() as $item) {
2223
if ($item->getQty() > 0) {
2324
$item->register();
25+
26+
if (!$item->getOrderItem()->isDummy(true)) {
27+
$totalQty += $item->getQty();
28+
}
2429
}
2530
}
31+
$shipment->setTotalQty($totalQty);
32+
2633
return $order;
2734
}
2835
}

app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ private function getQuantitiesFromOrderItems(array $items)
121121
{
122122
$shipmentItems = [];
123123
foreach ($items as $item) {
124-
if (!$item->getIsVirtual() && !$item->getParentItem()) {
124+
if (!$item->getIsVirtual() && (!$item->getParentItem() || $item->isShipSeparately())) {
125125
$shipmentItems[$item->getItemId()] = $item->getQtyOrdered();
126126
}
127127
}

app/code/Magento/Sales/Model/Order/ShipmentFactory.php

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,15 @@ protected function prepareItems(
9696
\Magento\Sales\Model\Order $order,
9797
array $items = []
9898
) {
99-
$totalQty = 0;
99+
$shipmentItems = [];
100100
foreach ($order->getAllItems() as $orderItem) {
101-
if (!$this->canShipItem($orderItem, $items)) {
101+
if ($this->validateItem($orderItem, $items) === false) {
102102
continue;
103103
}
104104

105105
/** @var \Magento\Sales\Model\Order\Shipment\Item $item */
106106
$item = $this->converter->itemToShipmentItem($orderItem);
107-
if ($orderItem->getIsVirtual() || $orderItem->getParentItemId()) {
107+
if ($orderItem->getIsVirtual() || ($orderItem->getParentItemId() && !$orderItem->isShipSeparately())) {
108108
$item->isDeleted(true);
109109
}
110110

@@ -124,8 +124,7 @@ protected function prepareItems(
124124
$qty = min($qty, $orderItem->getSimpleQtyToShip());
125125

126126
$item->setQty($this->castQty($orderItem, $qty));
127-
$shipment->addItem($item);
128-
127+
$shipmentItems[] = $item;
129128
continue;
130129
} else {
131130
$qty = 1;
@@ -144,10 +143,65 @@ protected function prepareItems(
144143
}
145144
}
146145

147-
$totalQty += $qty;
148-
149146
$item->setQty($this->castQty($orderItem, $qty));
150-
$shipment->addItem($item);
147+
$shipmentItems[] = $item;
148+
}
149+
return $this->setItemsToShipment($shipment, $shipmentItems);
150+
}
151+
152+
/**
153+
* Validate order item before shipment
154+
*
155+
* @param Item $orderItem
156+
* @param array $items
157+
* @return bool
158+
*/
159+
private function validateItem(\Magento\Sales\Model\Order\Item $orderItem, array $items)
160+
{
161+
if (!$this->canShipItem($orderItem, $items)) {
162+
return false;
163+
}
164+
165+
// Remove from shipment items without qty or with qty=0
166+
if (!$orderItem->isDummy(true)
167+
&& (!isset($items[$orderItem->getId()]) || $items[$orderItem->getId()] <= 0)
168+
) {
169+
return false;
170+
}
171+
return true;
172+
}
173+
174+
/**
175+
* Set prepared items to shipment document
176+
*
177+
* @param \Magento\Sales\Api\Data\ShipmentInterface $shipment
178+
* @param array $shipmentItems
179+
* @return \Magento\Sales\Api\Data\ShipmentInterface
180+
*/
181+
private function setItemsToShipment(\Magento\Sales\Api\Data\ShipmentInterface $shipment, $shipmentItems)
182+
{
183+
$totalQty = 0;
184+
185+
/**
186+
* Verify that composite products shipped separately has children, if not -> remove from collection
187+
*/
188+
/** @var \Magento\Sales\Model\Order\Shipment\Item $shipmentItem */
189+
foreach ($shipmentItems as $key => $shipmentItem) {
190+
if ($shipmentItem->getOrderItem()->getHasChildren()
191+
&& $shipmentItem->getOrderItem()->isShipSeparately()
192+
) {
193+
$containerId = $shipmentItem->getOrderItem()->getId();
194+
$childItems = array_filter($shipmentItems, function ($item) use ($containerId) {
195+
return $containerId == $item->getOrderItem()->getParentItemId();
196+
});
197+
198+
if (count($childItems) <= 0) {
199+
unset($shipmentItems[$key]);
200+
continue;
201+
}
202+
}
203+
$totalQty += $shipmentItem->getQty();
204+
$shipment->addItem($shipmentItem);
151205
}
152206
return $shipment->setTotalQty($totalQty);
153207
}

app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/OrderRegistrarTest.php

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,20 @@ protected function setUp()
3737
public function testRegister()
3838
{
3939
$item1 = $this->getShipmentItemMock();
40-
$item1->expects($this->once())
41-
->method('getQty')
42-
->willReturn(0);
43-
$item1->expects($this->never())
44-
->method('register');
40+
$item1->expects($this->once())->method('getQty')->willReturn(0);
41+
$item1->expects($this->never())->method('register');
42+
$item1->expects($this->never())->method('getOrderItem');
4543

4644
$item2 = $this->getShipmentItemMock();
47-
$item2->expects($this->once())
48-
->method('getQty')
49-
->willReturn(0.5);
50-
$item2->expects($this->once())
51-
->method('register');
45+
$item2->expects($this->atLeastOnce())->method('getQty')->willReturn(0.5);
46+
$item2->expects($this->once())->method('register');
47+
48+
$orderItemMock = $this->createMock(\Magento\Sales\Model\Order\Item::class);
49+
$orderItemMock->expects($this->once())->method('isDummy')->with(true)->willReturn(false);
50+
$item2->expects($this->once())->method('getOrderItem')->willReturn($orderItemMock);
5251

5352
$items = [$item1, $item2];
54-
$this->shipmentMock->expects($this->once())
55-
->method('getItems')
56-
->willReturn($items);
53+
$this->shipmentMock->expects($this->once())->method('getItems')->willReturn($items);
5754
$this->assertEquals(
5855
$this->orderMock,
5956
$this->model->register($this->orderMock, $this->shipmentMock)
@@ -67,7 +64,7 @@ private function getShipmentItemMock()
6764
{
6865
return $this->getMockBuilder(\Magento\Sales\Api\Data\ShipmentItemInterface::class)
6966
->disableOriginalConstructor()
70-
->setMethods(['register'])
67+
->setMethods(['register', 'getOrderItem'])
7168
->getMockForAbstractClass();
7269
}
7370
}

app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,18 @@ public function testCreate($tracks)
8484
$orderItem->expects($this->any())->method('getParentItemId')->willReturn(false);
8585
$orderItem->expects($this->any())->method('getIsVirtual')->willReturn(false);
8686

87-
$shipmentItem = $this->createPartialMock(\Magento\Sales\Model\Order\Shipment\Item::class, ['setQty']);
87+
$shipmentItem = $this->createPartialMock(
88+
\Magento\Sales\Model\Order\Shipment\Item::class,
89+
['setQty', 'getOrderItem', 'getQty']
90+
);
8891
$shipmentItem->expects($this->once())
8992
->method('setQty')
9093
->with(5);
94+
$shipmentItem->expects($this->once())
95+
->method('getQty')
96+
->willReturn(5);
97+
98+
$shipmentItem->expects($this->atLeastOnce())->method('getOrderItem')->willReturn($orderItem);
9199

92100
$order = $this->createPartialMock(\Magento\Sales\Model\Order::class, ['getAllItems']);
93101
$order->expects($this->any())

0 commit comments

Comments
 (0)