Skip to content

Commit 11a29d7

Browse files
authored
Merge pull request #1537 from magento-honey-badgers/MAGETWO-72747-Rest-Shipment-Config
[honey] MAGETWO-72747: [Magento Cloud] - /rest/default/V1/order/<order id>/ship and configurable products - for 2.2
2 parents 850b9e5 + d5e2fcc commit 11a29d7

File tree

12 files changed

+356
-119
lines changed

12 files changed

+356
-119
lines changed

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,6 @@ public function register()
257257
if (!$item->getOrderItem()->isDummy(true)) {
258258
$totalQty += $item->getQty();
259259
}
260-
} else {
261-
$item->isDeleted(true);
262260
}
263261
}
264262

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

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Magento\Sales\Api\Data\OrderInterface;
1515
use Magento\Sales\Api\Data\ShipmentCommentCreationInterface;
1616
use Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface;
17+
use Magento\Sales\Api\Data\OrderItemInterface;
1718

1819
/**
1920
* Class ShipmentDocumentFactory
@@ -77,13 +78,23 @@ public function create(
7778
array $packages = [],
7879
ShipmentCreationArgumentsInterface $arguments = null
7980
) {
80-
$shipmentItems = $this->itemsToArray($items);
81+
$shipmentItems = empty($items)
82+
? $this->getQuantitiesFromOrderItems($order->getItems())
83+
: $this->getQuantitiesFromShipmentItems($items);
84+
8185
/** @var Shipment $shipment */
8286
$shipment = $this->shipmentFactory->create(
8387
$order,
8488
$shipmentItems
8589
);
86-
$this->prepareTracks($shipment, $tracks);
90+
91+
foreach ($tracks as $track) {
92+
$hydrator = $this->hydratorPool->getHydrator(
93+
\Magento\Sales\Api\Data\ShipmentTrackCreationInterface::class
94+
);
95+
$shipment->addTrack($this->trackFactory->create(['data' => $hydrator->extract($track)]));
96+
}
97+
8798
if ($comment) {
8899
$shipment->addComment(
89100
$comment->getComment(),
@@ -96,30 +107,29 @@ public function create(
96107
}
97108

98109
/**
99-
* Adds tracks to the shipment.
110+
* Translate OrderItemInterface array to product id => product quantity array.
100111
*
101-
* @param ShipmentInterface $shipment
102-
* @param ShipmentTrackCreationInterface[] $tracks
103-
* @return ShipmentInterface
112+
* @param OrderItemInterface[] $items
113+
* @return int[]
104114
*/
105-
private function prepareTracks(\Magento\Sales\Api\Data\ShipmentInterface $shipment, array $tracks)
115+
private function getQuantitiesFromOrderItems(array $items)
106116
{
107-
foreach ($tracks as $track) {
108-
$hydrator = $this->hydratorPool->getHydrator(
109-
\Magento\Sales\Api\Data\ShipmentTrackCreationInterface::class
110-
);
111-
$shipment->addTrack($this->trackFactory->create(['data' => $hydrator->extract($track)]));
117+
$shipmentItems = [];
118+
foreach ($items as $item) {
119+
if (!$item->getIsVirtual() && !$item->getParentItem()) {
120+
$shipmentItems[$item->getItemId()] = $item->getQtyOrdered();
121+
}
112122
}
113-
return $shipment;
123+
return $shipmentItems;
114124
}
115125

116126
/**
117-
* Convert items to array
127+
* Translate ShipmentItemCreationInterface array to product id => product quantity array.
118128
*
119129
* @param ShipmentItemCreationInterface[] $items
120-
* @return array
130+
* @return int[]
121131
*/
122-
private function itemsToArray(array $items = [])
132+
private function getQuantitiesFromShipmentItems(array $items)
123133
{
124134
$shipmentItems = [];
125135
foreach ($items as $item) {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ protected function prepareItems(
104104

105105
/** @var \Magento\Sales\Model\Order\Shipment\Item $item */
106106
$item = $this->converter->itemToShipmentItem($orderItem);
107+
if ($orderItem->getIsVirtual() || $orderItem->getParentItemId()) {
108+
$item->isDeleted(true);
109+
}
107110

108111
if ($orderItem->isDummy(true)) {
109112
$qty = 0;

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
use Magento\Framework\EntityManager\HydratorInterface;
1919

2020
/**
21-
* Class ShipmentDocumentFactoryTest
21+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2222
*/
2323
class ShipmentDocumentFactoryTest extends \PHPUnit\Framework\TestCase
2424
{
@@ -128,14 +128,8 @@ public function testCreate()
128128
$packages = [];
129129
$items = [1 => 10];
130130

131-
$this->itemMock->expects($this->once())
132-
->method('getOrderItemId')
133-
->willReturn(1);
134-
135-
$this->itemMock->expects($this->once())
136-
->method('getQty')
137-
->willReturn(10);
138-
131+
$this->itemMock->expects($this->once())->method('getOrderItemId')->willReturn(1);
132+
$this->itemMock->expects($this->once())->method('getQty')->willReturn(10);
139133
$this->shipmentFactoryMock->expects($this->once())
140134
->method('create')
141135
->with(

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,18 @@ protected function setUp()
7171
*/
7272
public function testCreate($tracks)
7373
{
74-
$orderItem = $this->createPartialMock(\Magento\Sales\Model\Order\Item::class, ['getId', 'getQtyOrdered']);
74+
$orderItem = $this->createPartialMock(
75+
\Magento\Sales\Model\Order\Item::class,
76+
['getId', 'getQtyOrdered', 'getParentItemId', 'getIsVirtual']
77+
);
7578
$orderItem->expects($this->any())
7679
->method('getId')
7780
->willReturn(1);
7881
$orderItem->expects($this->any())
7982
->method('getQtyOrdered')
8083
->willReturn(5);
84+
$orderItem->expects($this->any())->method('getParentItemId')->willReturn(false);
85+
$orderItem->expects($this->any())->method('getIsVirtual')->willReturn(false);
8186

8287
$shipmentItem = $this->createPartialMock(\Magento\Sales\Model\Order\Shipment\Item::class, ['setQty']);
8388
$shipmentItem->expects($this->once())

app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php

Lines changed: 108 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66
namespace Magento\Shipping\Controller\Adminhtml\Order;
77

88
use Magento\Framework\DataObject;
9+
use Magento\Framework\Exception\LocalizedException;
10+
use Magento\Framework\Message\ManagerInterface;
11+
use Magento\Framework\Registry;
12+
use Magento\Sales\Api\Data\ShipmentTrackCreationInterface;
13+
use Magento\Sales\Api\Data\ShipmentTrackCreationInterfaceFactory;
14+
use Magento\Sales\Api\Data\ShipmentItemCreationInterfaceFactory;
15+
use Magento\Sales\Api\ShipmentRepositoryInterface;
16+
use Magento\Sales\Api\OrderRepositoryInterface;
17+
use Magento\Sales\Model\Order\ShipmentDocumentFactory;
18+
use Magento\Sales\Api\Data\ShipmentItemCreationInterface;
919

1020
/**
1121
* Class ShipmentLoader
@@ -17,80 +27,77 @@
1727
* @method ShipmentLoader setTracking($tracking)
1828
* @method int getOrderId()
1929
* @method int getShipmentId()
20-
* @method array getShipment()
2130
* @method array getTracking()
2231
*/
2332
class ShipmentLoader extends DataObject
2433
{
34+
const SHIPMENT = 'shipment';
35+
2536
/**
26-
* @var \Magento\Framework\Message\ManagerInterface
37+
* @var ManagerInterface
2738
*/
28-
protected $messageManager;
39+
private $messageManager;
2940

3041
/**
31-
* @var \Magento\Framework\Registry
42+
* @var Registry
3243
*/
33-
protected $registry;
44+
private $registry;
3445

3546
/**
36-
* @var \Magento\Sales\Api\ShipmentRepositoryInterface
47+
* @var ShipmentRepositoryInterface
3748
*/
38-
protected $shipmentRepository;
49+
private $shipmentRepository;
3950

4051
/**
41-
* @var \Magento\Sales\Model\Order\ShipmentFactory
52+
* @var OrderRepositoryInterface
4253
*/
43-
protected $shipmentFactory;
54+
private $orderRepository;
4455

4556
/**
46-
* @var \Magento\Sales\Model\Order\Shipment\TrackFactory
57+
* @var ShipmentDocumentFactory
4758
*/
48-
protected $trackFactory;
59+
private $documentFactory;
4960

5061
/**
51-
* @var \Magento\Sales\Api\OrderRepositoryInterface
62+
* @var ShipmentTrackCreationInterfaceFactory
5263
*/
53-
protected $orderRepository;
64+
private $trackFactory;
5465

5566
/**
56-
* @param \Magento\Framework\Message\ManagerInterface $messageManager
57-
* @param \Magento\Framework\Registry $registry
58-
* @param \Magento\Sales\Api\ShipmentRepositoryInterface $shipmentRepository
59-
* @param \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory
60-
* @param \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory
61-
* @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
67+
* @var ShipmentItemCreationInterfaceFactory
68+
*/
69+
private $itemFactory;
70+
71+
/**
72+
* @param ManagerInterface $messageManager
73+
* @param Registry $registry
74+
* @param ShipmentRepositoryInterface $shipmentRepository
75+
* @param OrderRepositoryInterface $orderRepository
76+
* @param ShipmentDocumentFactory $documentFactory
77+
* @param ShipmentTrackCreationInterfaceFactory $trackFactory
78+
* @param ShipmentItemCreationInterfaceFactory $itemFactory
6279
* @param array $data
6380
*/
6481
public function __construct(
65-
\Magento\Framework\Message\ManagerInterface $messageManager,
66-
\Magento\Framework\Registry $registry,
67-
\Magento\Sales\Api\ShipmentRepositoryInterface $shipmentRepository,
68-
\Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory,
69-
\Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory,
70-
\Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
82+
ManagerInterface $messageManager,
83+
Registry $registry,
84+
ShipmentRepositoryInterface $shipmentRepository,
85+
OrderRepositoryInterface $orderRepository,
86+
ShipmentDocumentFactory $documentFactory,
87+
ShipmentTrackCreationInterfaceFactory $trackFactory,
88+
ShipmentItemCreationInterfaceFactory $itemFactory,
7189
array $data = []
7290
) {
7391
$this->messageManager = $messageManager;
7492
$this->registry = $registry;
7593
$this->shipmentRepository = $shipmentRepository;
76-
$this->shipmentFactory = $shipmentFactory;
77-
$this->trackFactory = $trackFactory;
7894
$this->orderRepository = $orderRepository;
95+
$this->documentFactory = $documentFactory;
96+
$this->trackFactory = $trackFactory;
97+
$this->itemFactory = $itemFactory;
7998
parent::__construct($data);
8099
}
81100

82-
/**
83-
* Initialize shipment items QTY
84-
*
85-
* @return array
86-
*/
87-
protected function getItemQtys()
88-
{
89-
$data = $this->getShipment();
90-
91-
return isset($data['items']) ? $data['items'] : [];
92-
}
93-
94101
/**
95102
* Initialize shipment model instance
96103
*
@@ -129,14 +136,73 @@ public function load()
129136
return false;
130137
}
131138

132-
$shipment = $this->shipmentFactory->create(
139+
$shipmentItems = $this->getShipmentItems($this->getShipment());
140+
141+
$shipment = $this->documentFactory->create(
133142
$order,
134-
$this->getItemQtys(),
135-
$this->getTracking()
143+
$shipmentItems,
144+
$this->getTrackingArray()
136145
);
137146
}
138147

139148
$this->registry->register('current_shipment', $shipment);
140149
return $shipment;
141150
}
151+
152+
/**
153+
* Convert UI-generated tracking array to Data Object array
154+
*
155+
* @return ShipmentTrackCreationInterface[]
156+
* @throws LocalizedException
157+
*/
158+
private function getTrackingArray()
159+
{
160+
$tracks = $this->getTracking() ?: [];
161+
$trackingCreation = [];
162+
foreach ($tracks as $track) {
163+
if (!isset($track['number']) || !isset($track['title']) || !isset($track['carrier_code'])) {
164+
throw new LocalizedException(
165+
__('Tracking information must contain title, carrier code, and tracking number')
166+
);
167+
}
168+
/** @var ShipmentTrackCreationInterface $trackCreation */
169+
$trackCreation = $this->trackFactory->create();
170+
$trackCreation->setTrackNumber($track['number']);
171+
$trackCreation->setTitle($track['title']);
172+
$trackCreation->setCarrierCode($track['carrier_code']);
173+
$trackingCreation[] = $trackCreation;
174+
}
175+
176+
return $trackingCreation;
177+
}
178+
179+
/**
180+
* Extract product id => product quantity array from shipment data.
181+
*
182+
* @param array $shipmentData
183+
* @return int[]
184+
*/
185+
private function getShipmentItems(array $shipmentData)
186+
{
187+
$shipmentItems = [];
188+
$itemQty = isset($shipmentData['items']) ? $shipmentData['items'] : [];
189+
foreach ($itemQty as $itemId => $quantity) {
190+
/** @var ShipmentItemCreationInterface $item */
191+
$item = $this->itemFactory->create();
192+
$item->setOrderItemId($itemId);
193+
$item->setQty($quantity);
194+
$shipmentItems[] = $item;
195+
}
196+
return $shipmentItems;
197+
}
198+
199+
/**
200+
* Retrieve shipment
201+
*
202+
* @return array
203+
*/
204+
public function getShipment()
205+
{
206+
return $this->getData(self::SHIPMENT) ?: [];
207+
}
142208
}

0 commit comments

Comments
 (0)