Skip to content

Commit 0116b31

Browse files
author
Valeriy Nayda
committed
Merge remote-tracking branch 'origin/develop' into msi-website-default-stock
# Conflicts: # app/code/Magento/InventorySales/etc/di.xml
2 parents 967c9f6 + 39320a3 commit 0116b31

File tree

15 files changed

+332
-36
lines changed

15 files changed

+332
-36
lines changed

app/code/Magento/Inventory/Controller/Adminhtml/Stock/Save.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Magento\Backend\App\Action\Context;
1111
use Magento\Framework\Api\DataObjectHelper;
1212
use Magento\Framework\Controller\Result\Redirect;
13+
use Magento\Framework\EntityManager\EventManager;
1314
use Magento\Framework\Exception\CouldNotSaveException;
1415
use Magento\Framework\Exception\InputException;
1516
use Magento\Framework\Exception\NoSuchEntityException;
@@ -48,25 +49,33 @@ class Save extends Action
4849
*/
4950
private $stockSourceLinkProcessor;
5051

52+
/**
53+
* @var EventManager
54+
*/
55+
private $eventManager;
56+
5157
/**
5258
* @param Context $context
5359
* @param StockInterfaceFactory $stockFactory
5460
* @param StockRepositoryInterface $stockRepository
5561
* @param DataObjectHelper $sourceHydrator
5662
* @param StockSourceLinkProcessor $stockSourceLinkProcessor
63+
* @param EventManager $eventManager
5764
*/
5865
public function __construct(
5966
Context $context,
6067
StockInterfaceFactory $stockFactory,
6168
StockRepositoryInterface $stockRepository,
6269
DataObjectHelper $sourceHydrator,
63-
StockSourceLinkProcessor $stockSourceLinkProcessor
70+
StockSourceLinkProcessor $stockSourceLinkProcessor,
71+
EventManager $eventManager
6472
) {
6573
parent::__construct($context);
6674
$this->stockFactory = $stockFactory;
6775
$this->stockRepository = $stockRepository;
6876
$this->dataObjectHelper = $sourceHydrator;
6977
$this->stockSourceLinkProcessor = $stockSourceLinkProcessor;
78+
$this->eventManager = $eventManager;
7079
}
7180

7281
/**
@@ -126,6 +135,13 @@ private function processSave(array $requestData, int $stockId = null): int
126135
$stock = $this->stockRepository->get($stockId);
127136
}
128137
$this->dataObjectHelper->populateWithArray($stock, $requestData['general'], StockInterface::class);
138+
$this->eventManager->dispatch(
139+
'save_stock_controller_populate_stock_with_data',
140+
[
141+
'request_data' => $requestData,
142+
'stock' => $stock,
143+
]
144+
);
129145
$stockId = $this->stockRepository->save($stock);
130146

131147
$assignedSources =

app/code/Magento/Inventory/view/adminhtml/ui_component/inventory_source_listing.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@
268268
<label translate="true">Priority</label>
269269
</settings>
270270
</column>
271-
<actionsColumn name="actions" class="Magento\Backend\Ui\Component\Listing\Column\EditAction">
271+
<actionsColumn name="actions" class="Magento\Backend\Ui\Component\Listing\Column\EditAction" sortOrder="100">
272272
<argument name="data" xsi:type="array">
273273
<item name="config" xsi:type="array">
274274
<item name="editUrlPath" xsi:type="string">inventory/source/edit</item>

app/code/Magento/Inventory/view/adminhtml/ui_component/inventory_stock_listing.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118
</editor>
119119
</settings>
120120
</column>
121-
<actionsColumn name="actions" class="Magento\Backend\Ui\Component\Listing\Column\EditAction">
121+
<actionsColumn name="actions" class="Magento\Backend\Ui\Component\Listing\Column\EditAction" sortOrder="100">
122122
<argument name="data" xsi:type="array">
123123
<item name="config" xsi:type="array">
124124
<item name="editUrlPath" xsi:type="string">inventory/stock/edit</item>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\InventorySales\Observer\Stock;
9+
10+
use Magento\Framework\Event\ObserverInterface;
11+
use Magento\Framework\Event\Observer as EventObserver;
12+
use Magento\InventoryApi\Api\Data\StockInterface;
13+
use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;
14+
use Magento\InventorySalesApi\Api\Data\SalesChannelInterfaceFactory;
15+
16+
/**
17+
* Populate stock with sales channels during saving via controller
18+
*
19+
* This needs to be handled in dedicated observer, because there is no pre-defined way of making several API calls for
20+
* Form submission handling
21+
*/
22+
class PopulateWithWebsiteSalesChannelsObserver implements ObserverInterface
23+
{
24+
/**
25+
* @var SalesChannelInterfaceFactory
26+
*/
27+
private $salesChannelFactory;
28+
29+
/**
30+
* @param SalesChannelInterfaceFactory $salesChannelFactory
31+
*/
32+
public function __construct(SalesChannelInterfaceFactory $salesChannelFactory)
33+
{
34+
$this->salesChannelFactory = $salesChannelFactory;
35+
}
36+
37+
/**
38+
* Populate stock with sales channels during saving via controller
39+
*
40+
* @param EventObserver $observer
41+
* @return void
42+
*/
43+
public function execute(EventObserver $observer)
44+
{
45+
/** @var StockInterface $stock */
46+
$stock = $observer->getEvent()->getStock();
47+
$requestData = $observer->getEvent()->getRequestData();
48+
49+
$extensionAttributes = $stock->getExtensionAttributes();
50+
$assignedSalesChannels = $extensionAttributes->getSalesChannels();
51+
52+
foreach ($assignedSalesChannels as $key => $assignedSalesChannel) {
53+
if ($assignedSalesChannel->getType() === SalesChannelInterface::TYPE_WEBSITE) {
54+
unset($assignedSalesChannels[$key]);
55+
}
56+
}
57+
58+
if (isset($requestData['sales_channels'][SalesChannelInterface::TYPE_WEBSITE])
59+
&& is_array($requestData['sales_channels'][SalesChannelInterface::TYPE_WEBSITE])
60+
) {
61+
foreach ($requestData['sales_channels'][SalesChannelInterface::TYPE_WEBSITE] as $websiteCode) {
62+
$assignedSalesChannels[] = $this->createSalesChannelByWebsiteCode($websiteCode);
63+
}
64+
}
65+
$extensionAttributes->setSalesChannels($assignedSalesChannels);
66+
}
67+
68+
/**
69+
* Create the sales channel by given website code
70+
*
71+
* @param string $websiteCode
72+
* @return SalesChannelInterface
73+
*/
74+
private function createSalesChannelByWebsiteCode(string $websiteCode): SalesChannelInterface
75+
{
76+
$salesChannel = $this->salesChannelFactory->create();
77+
$salesChannel->setCode($websiteCode);
78+
$salesChannel->setType(SalesChannelInterface::TYPE_WEBSITE);
79+
return $salesChannel;
80+
}
81+
}

app/code/Magento/InventorySales/Plugin/Inventory/Ui/StockDataProvider/SalesChannels.php

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,37 @@
77

88
namespace Magento\InventorySales\Plugin\Inventory\Ui\StockDataProvider;
99

10+
use Magento\CatalogInventory\Model\Stock\StockRepository;
1011
use Magento\Inventory\Ui\DataProvider\StockDataProvider;
12+
use Magento\InventorySales\Model\GetAssignedSalesChannelsForStockInterface;
1113

1214
/**
1315
* Customize stock form. Add sales channels data
1416
*/
1517
class SalesChannels
1618
{
19+
/**
20+
* @var GetAssignedSalesChannelsForStockInterface
21+
*/
22+
private $getAssignedSalesChannelsForStock;
23+
24+
/**
25+
* @var StockRepository
26+
*/
27+
private $stockRepository;
28+
29+
/**
30+
* @param GetAssignedSalesChannelsForStockInterface $getAssignedSalesChannelsForStock
31+
* @param StockRepository $stockRepository
32+
*/
33+
public function __construct(
34+
GetAssignedSalesChannelsForStockInterface $getAssignedSalesChannelsForStock,
35+
StockRepository $stockRepository
36+
) {
37+
$this->getAssignedSalesChannelsForStock = $getAssignedSalesChannelsForStock;
38+
$this->stockRepository = $stockRepository;
39+
}
40+
1741
/**
1842
* @param StockDataProvider $subject
1943
* @param array $data
@@ -23,26 +47,36 @@ public function afterGetData(StockDataProvider $subject, array $data): array
2347
{
2448
if ('inventory_stock_form_data_source' === $subject->getName()) {
2549
foreach ($data as &$stockData) {
26-
$stockData['sales_channels'] = $this->getSalesChannelsDataForStock();
50+
$salesChannelsData = $this->getSalesChannelsDataForStock($stockData['general']);
51+
if (count($salesChannelsData)) {
52+
$stockData['sales_channels'] = $salesChannelsData;
53+
}
2754
}
2855
unset($stockData);
2956
} elseif ($data['totalRecords'] > 0) {
3057
foreach ($data['items'] as &$stockData) {
31-
$stockData['sales_channels'] = $this->getSalesChannelsDataForStock();
58+
$salesChannelsData = $this->getSalesChannelsDataForStock($stockData);
59+
if (count($salesChannelsData)) {
60+
$stockData['sales_channels'] = $salesChannelsData;
61+
}
3262
}
3363
unset($stockData);
3464
}
3565
return $data;
3666
}
3767

3868
/**
69+
* @param array $stock
3970
* @return array
4071
*/
41-
private function getSalesChannelsDataForStock(): array
72+
private function getSalesChannelsDataForStock(array $stock): array
4273
{
43-
// @todo: replace on real data
44-
return [
45-
'websites' => ['base'],
46-
];
74+
$salesChannelsData = [];
75+
foreach ($stock['extension_attributes'] as $salesChannels) {
76+
foreach ($salesChannels as $salesChannel) {
77+
$salesChannelsData[$salesChannel['type']][] = $salesChannel['code'];
78+
}
79+
}
80+
return $salesChannelsData;
4781
}
4882
}

app/code/Magento/InventorySales/Ui/Component/Listing/Column/SalesChannels.php

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,74 @@
77

88
namespace Magento\InventorySales\Ui\Component\Listing\Column;
99

10+
use Magento\InventorySales\Ui\SalesChannelNameResolverInterface;
1011
use Magento\Ui\Component\Listing\Columns\Column;
12+
use Magento\Framework\View\Element\UiComponentFactory;
13+
use Magento\Framework\View\Element\UiComponent\ContextInterface;
1114

1215
/**
13-
* Add grid column for sales channels
16+
* Add grid column for sales channels. Prepare data
1417
*/
1518
class SalesChannels extends Column
1619
{
1720
/**
18-
* Prepare column value
19-
*
20-
* @param array $salesChannelData
21-
* @return string
21+
* @var SalesChannelNameResolverInterface
2222
*/
23-
private function prepareStockChannelData(array $salesChannelData)
24-
{
25-
$websiteData = '';
26-
foreach ($salesChannelData as $key => $channelData) {
27-
$websiteData .= $key . ': ' . implode(',', $channelData);
28-
}
29-
return $websiteData;
23+
private $salesChannelNameResolver;
24+
25+
/**
26+
* @param ContextInterface $context
27+
* @param UiComponentFactory $uiComponentFactory
28+
* @param SalesChannelNameResolverInterface $salesChannelNameResolver
29+
* @param array $components
30+
* @param array $data
31+
*/
32+
public function __construct(
33+
ContextInterface $context,
34+
UiComponentFactory $uiComponentFactory,
35+
SalesChannelNameResolverInterface $salesChannelNameResolver,
36+
array $components = [],
37+
array $data = []
38+
) {
39+
parent::__construct($context, $uiComponentFactory, $components, $data);
40+
$this->salesChannelNameResolver = $salesChannelNameResolver;
3041
}
3142

3243
/**
33-
* @inheritdoc
44+
* Prepare data source
45+
*
46+
* @param array $dataSource
47+
* @return array
3448
*/
3549
public function prepareDataSource(array $dataSource)
3650
{
3751
if ($dataSource['data']['totalRecords'] > 0) {
3852
foreach ($dataSource['data']['items'] as &$row) {
39-
if (isset($row['sales_channels'])) {
40-
$row['sales_channels'] = $this->prepareStockChannelData($row['sales_channels']);
41-
}
53+
$row['sales_channels'] = $this->prepareSalesChannelData($row['sales_channels']);
4254
}
4355
}
4456
unset($row);
4557

4658
return $dataSource;
4759
}
60+
61+
/**
62+
* Prepare sales value
63+
*
64+
* @param array $salesChannelData
65+
* @return array
66+
*/
67+
private function prepareSalesChannelData(array $salesChannelData): array
68+
{
69+
$preparedChannelData = [];
70+
foreach ($salesChannelData as $type => $salesChannel) {
71+
foreach ($salesChannel as $code) {
72+
$preparedChannelData[$type][] = [
73+
'name' => $this->salesChannelNameResolver->resolve($type, $code),
74+
'code' => $code,
75+
];
76+
}
77+
}
78+
return $preparedChannelData;
79+
}
4880
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\InventorySales\Ui;
9+
10+
/**
11+
* Resolve sales channel name by type and code
12+
*/
13+
interface SalesChannelNameResolverInterface
14+
{
15+
/**
16+
* Resolve sales channel name by type and code
17+
*
18+
* @param string $type
19+
* @param string $code
20+
* @return string
21+
*/
22+
public function resolve(string $type, string $code): string;
23+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\InventorySales\Ui;
9+
10+
use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;
11+
use Magento\Store\Api\WebsiteRepositoryInterface;
12+
13+
/**
14+
* {@inheritdoc}
15+
*
16+
* In default implementation works only with website
17+
*/
18+
class WebsiteNameResolver implements SalesChannelNameResolverInterface
19+
{
20+
/**
21+
* @var WebsiteRepositoryInterface
22+
*/
23+
private $websiteRepository;
24+
25+
/**
26+
* @param WebsiteRepositoryInterface $websiteRepository
27+
*/
28+
public function __construct(
29+
WebsiteRepositoryInterface $websiteRepository
30+
) {
31+
$this->websiteRepository = $websiteRepository;
32+
}
33+
34+
/**
35+
* @inheritdoc
36+
*/
37+
public function resolve(string $type, string $code): string
38+
{
39+
return SalesChannelInterface::TYPE_WEBSITE === $type ? $this->websiteRepository->get($code)->getName() : $code;
40+
}
41+
}

0 commit comments

Comments
 (0)