Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions app/code/Magento/Backend/Ui/Component/Control/DeleteButton.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Backend\Ui\Component\Control;

use Magento\Framework\App\RequestInterface;
use Magento\Framework\UrlInterface;
use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;

/**
* Represents delete button with pre-configured options
* Provide an ability to show confirmation message on click on the "Delete" button
*
* @api
*/
class DeleteButton implements ButtonProviderInterface
{
/**
* @var RequestInterface
*/
private $request;

/**
* @var UrlInterface
*/
private $urlBuilder;

/**
* @var string
*/
private $confirmationMessage;

/**
* @var string
*/
private $idFieldName;

/**
* @var string
*/
private $deleteRoutePath;

/**
* @var int
*/
private $sortOrder;

/**
* @param RequestInterface $request
* @param UrlInterface $urlBuilder
* @param string $confirmationMessage
* @param string $idFieldName
* @param string $deleteRoutePath
* @param int $sortOrder
*/
public function __construct(
RequestInterface $request,
UrlInterface $urlBuilder,
string $confirmationMessage,
string $idFieldName,
string $deleteRoutePath,
int $sortOrder
) {
$this->request = $request;
$this->urlBuilder = $urlBuilder;
$this->confirmationMessage = $confirmationMessage;
$this->idFieldName = $idFieldName;
$this->deleteRoutePath = $deleteRoutePath;
$this->sortOrder = $sortOrder;
}

/**
* {@inheritdoc}
*/
public function getButtonData()
{
$data = [];
$id = $this->request->getParam($this->idFieldName);
if (null !== $id) {
$url = $this->urlBuilder->getUrl($this->deleteRoutePath);
$data = [
'label' => __('Delete'),
'class' => 'delete',
'on_click' =>
"deleteConfirm('{$this->confirmationMessage}', '{$url}', {data:{{$this->idFieldName}:{$id}}})",
'sort_order' => $this->sortOrder,
];
}
return $data;
}
}
71 changes: 71 additions & 0 deletions app/code/Magento/Inventory/Controller/Adminhtml/Stock/Delete.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Inventory\Controller\Adminhtml\Stock;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Exception\CouldNotDeleteException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\InventoryApi\Api\StockRepositoryInterface;
use Magento\InventoryApi\Api\Data\StockInterface;

/**
* Delete Controller
*/
class Delete extends Action
{
/**
* @see _isAllowed()
*/
const ADMIN_RESOURCE = 'Magento_Inventory::stock';

/**
* @var StockRepositoryInterface
*/
private $stockRepository;

/**
* @param Context $context
* @param StockRepositoryInterface $stockRepository
*/
public function __construct(
Context $context,
StockRepositoryInterface $stockRepository
) {
parent::__construct($context);
$this->stockRepository = $stockRepository;
}

/**
* @inheritdoc
*/
public function execute()
{
$resultRedirect = $this->resultRedirectFactory->create();

$stockId = $this->getRequest()->getPost(StockInterface::STOCK_ID);
if ($stockId === null) {
$this->messageManager->addErrorMessage(__('Wrong request.'));
return $resultRedirect->setPath('*/*');
}

try {
$this->stockRepository->deleteById($stockId);
$this->messageManager->addSuccessMessage(__('The Stock has been deleted.'));
$resultRedirect->setPath('*/*');
} catch (NoSuchEntityException $e) {
$this->messageManager->addErrorMessage(__('Stock with id "%1" does not exist.', $stockId));
$resultRedirect->setPath('*/*');
} catch (CouldNotDeleteException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
$resultRedirect->setPath('*/*/edit', [
StockInterface::STOCK_ID => $stockId,
'_current' => true,
]);
}
return $resultRedirect;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Inventory\Controller\Adminhtml\Stock;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Inventory\Ui\Component\MassAction\Filter;
use Magento\Framework\Exception\CouldNotDeleteException;
use Magento\InventoryApi\Api\StockRepositoryInterface;

/**
* MassDelete Controller
*/
class MassDelete extends Action
{
/**
* @see _isAllowed()
*/
const ADMIN_RESOURCE = 'Magento_Inventory::stock';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in both Delete and MassDelete we have a duplication of this constant, that means that it should be declared in another place.
Because currently, such code violates DRY


/**
* @var StockRepositoryInterface
*/
private $stockRepository;

/**
* @var Filter
*/
private $massActionFilter;

/**
* @param Context $context
* @param StockRepositoryInterface $stockRepository
* @param Filter $massActionFilter
*/
public function __construct(
Context $context,
StockRepositoryInterface $stockRepository,
Filter $massActionFilter
) {
parent::__construct($context);
$this->stockRepository = $stockRepository;
$this->massActionFilter = $massActionFilter;
}

/**
* @inheritdoc
*/
public function execute()
{
if ($this->getRequest()->isPost() !== true) {
$this->messageManager->addErrorMessage(__('Wrong request.'));
return $this->resultRedirectFactory->create()->setPath('*/*');
}

$deletedItemsCount = 0;
foreach ($this->massActionFilter->getIds() as $id) {
try {
$this->stockRepository->deleteById($id);
$deletedItemsCount++;
} catch (CouldNotDeleteException $e) {
$errorMessage = __('[ID: %1] ', $id) . $e->getMessage();
$this->messageManager->addErrorMessage($errorMessage);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about NoSuchEntityException?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it is not necessary because deleteById method throw CouldNotDeleteException and this scenario is served. See Magento\InventoryApi\Api\StockRepositoryInterface.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
$this->messageManager->addSuccessMessage(__('You deleted %1 Stock(s).', $deletedItemsCount));

return $this->resultRedirectFactory->create()->setPath('*/*');
}
}
48 changes: 48 additions & 0 deletions app/code/Magento/Inventory/Ui/Component/MassAction/Filter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Inventory\Ui\Component\MassAction;

use Magento\Ui\Component\MassAction\Filter as BaseFilter;
use Magento\Framework\Api\Search\DocumentInterface;

/**
* Temporary solution
* @todo Need to remove after fixing the issue
* @see https://github.com/magento/magento2/issues/10988
*/
class Filter
{
/**
* @var BaseFilter
*/
private $filter;

/**
* @param BaseFilter $filter
*/
public function __construct(
BaseFilter $filter
) {
$this->filter = $filter;
}

/**
* Get ids from search filter
*
* @return array
*/
public function getIds()
{
$this->filter->applySelectionOnTargetProvider();
$component = $this->filter->getComponent();
$dataProvider = $component->getContext()->getDataProvider();
$searchResult = $dataProvider->getSearchResult();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a violation of encapsulation and Law of Demeter here.
Because current code is equivalent to
$this->filter->getComponent()->getContext()->getDataProvider()->getSearchResult()

@naydav is it really recommended way of applying Filtering?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub issue number magento/magento2#10988


return array_map(function (DocumentInterface $item) {
return $item->getId();
}, $searchResult->getItems());
}
}
8 changes: 8 additions & 0 deletions app/code/Magento/Inventory/etc/adminhtml/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
<argument name="saveTarget" xsi:type="string">inventory_stock_form.inventory_stock_form</argument>
</arguments>
</virtualType>
<virtualType name="Magento\Inventory\Ui\Component\Control\Stock\DeleteButton" type="Magento\Backend\Ui\Component\Control\DeleteButton">
<arguments>
<argument name="confirmationMessage" xsi:type="string" translate="true">Are you sure you want to delete this stock?</argument>
<argument name="idFieldName" xsi:type="const">Magento\InventoryApi\Api\Data\StockInterface::STOCK_ID</argument>
<argument name="deleteRoutePath" xsi:type="string">*/*/delete</argument>
<argument name="sortOrder" xsi:type="number">30</argument>
</arguments>
</virtualType>
<!-- Product form configurations -->
<virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
<arguments>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<class>reset</class>
<label translate="true">Reset</label>
</button>
<button name="delete" class="Magento\Inventory\Ui\Component\Control\Stock\DeleteButton"/>
<button name="save" class="Magento\Inventory\Ui\Component\Control\Stock\SaveSplitButton"/>
</buttons>
</settings>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,19 @@
</templates>
</settings>
</filters>
<massaction/>
<massaction name="listing_massaction" component="Magento_Ui/js/grid/tree-massactions">
<action name="delete">
<settings>
<confirm>
<message translate="true">Delete selected items?</message>
<title translate="true">Delete items</title>
</confirm>
<url path="inventory/stock/massDelete"/>
<type>delete</type>
<label translate="true">Delete</label>
</settings>
</action>
</massaction>
<paging name="listing_paging"/>
</listingToolbar>
<columns name="inventory_stock_listing_columns">
Expand Down