Skip to content

Fix #14958 - remove sales sequence data on store view delete #22296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8529467
Fix #14958 - remove sales sequence data on store view delete
Bartlomiejsz Apr 12, 2019
4c4ae53
Fix #14958 - add unit tests
Bartlomiejsz Apr 12, 2019
774d40f
FIx #14958 - add last unit test
Bartlomiejsz Apr 12, 2019
8dab9d7
FIx #14958 - fix integration tests
Bartlomiejsz Apr 12, 2019
4385c2f
Revert "FIx #14958 - fix integration tests"
Bartlomiejsz Apr 15, 2019
78bfbc8
Revert "FIx #14958 - add last unit test"
Bartlomiejsz Apr 15, 2019
3ff5c06
Fix #14958 - move sales sequence removal to external class
Bartlomiejsz Apr 15, 2019
85b0730
Fix #14958 - change fields visibility
Bartlomiejsz Apr 15, 2019
309a25f
Fix #14958 - declare dependency on Magento_Store
Bartlomiejsz Apr 16, 2019
c83a283
magento/magento2#22296: Static test fix.
p-bystritsky Apr 23, 2019
328bc51
Fix #14958 - apply requested changes
Bartlomiejsz Jun 4, 2019
7c078cf
Fix #14958 - add declare strict_types
Bartlomiejsz Jun 4, 2019
76b2085
Fix #14958 - move two methods from resource models to private methods…
Bartlomiejsz Jun 7, 2019
11f013c
Fix #14958 - remove requirement of magento/module-store
Bartlomiejsz Aug 13, 2019
68d1bed
fix #14958 - fix static check
Bartlomiejsz Aug 14, 2019
48f213d
Merge remote-tracking branch 'mainline/2.3-develop' into feature/fix_…
engcom-Foxtrot Oct 7, 2019
6458cc8
magento/magento2#22296: Integration test fix.
engcom-Foxtrot Oct 7, 2019
94b6a17
Merge remote-tracking branch 'mainline/2.4-develop' into feature/fix_…
engcom-Foxtrot Dec 16, 2019
f894321
refactor integration tests, change fixtures
engcom-Foxtrot Jan 3, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object)
|| $object->getData('store_id') === null
|| !$object->getData('sequence_table')
) {
// phpcs:ignore Magento2.Exceptions.DirectThrow
throw new Exception(__('Not enough arguments'));
}

Expand Down
117 changes: 117 additions & 0 deletions app/code/Magento/SalesSequence/Model/Sequence/DeleteByStore.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\SalesSequence\Model\Sequence;

use Magento\Framework\App\ResourceConnection as AppResource;
use Magento\SalesSequence\Model\MetaFactory;
use Magento\SalesSequence\Model\ResourceModel\Meta as ResourceMetadata;

/**
* Delete Sequence by Store.
*/
class DeleteByStore
{
/**
* @var ResourceMetadata
*/
private $resourceMetadata;

/**
* @var MetaFactory
*/
private $metaFactory;

/**
* @var AppResource
*/
private $appResource;

/**
* @param ResourceMetadata $resourceMetadata
* @param MetaFactory $metaFactory
* @param AppResource $appResource
*/
public function __construct(
ResourceMetadata $resourceMetadata,
MetaFactory $metaFactory,
AppResource $appResource
) {
$this->resourceMetadata = $resourceMetadata;
$this->metaFactory = $metaFactory;
$this->appResource = $appResource;
}

/**
* Deletes all sequence linked entites
*
* @param int $storeId
* @return void
* @throws \Exception
*/
public function execute($storeId): void
{
$metadataIds = $this->getMetadataIdsByStoreId($storeId);
$profileIds = $this->getProfileIdsByMetadataIds($metadataIds);

$this->appResource->getConnection()->delete(
$this->appResource->getTableName('sales_sequence_profile'),
['profile_id IN (?)' => $profileIds]
);

foreach ($metadataIds as $metadataId) {
$metadata = $this->metaFactory->create();
$this->resourceMetadata->load($metadata, $metadataId);
if (!$metadata->getId()) {
continue;
}

$this->appResource->getConnection()->dropTable(
$metadata->getSequenceTable()
);
$this->resourceMetadata->delete($metadata);
}
}

/**
* Retrieves Metadata Ids by store id
*
* @param int $storeId
* @return int[]
*/
private function getMetadataIdsByStoreId($storeId)
{
$connection = $this->appResource->getConnection();
$bind = ['store_id' => $storeId];
$select = $connection->select()->from(
$this->appResource->getTableName('sales_sequence_meta'),
['meta_id']
)->where(
'store_id = :store_id'
);

return $connection->fetchCol($select, $bind);
}

/**
* Retrieves Profile Ids by metadata ids
*
* @param int[] $metadataIds
* @return int[]
*/
private function getProfileIdsByMetadataIds(array $metadataIds)
{
$connection = $this->appResource->getConnection();
$select = $connection->select()
->from(
$this->appResource->getTableName('sales_sequence_profile'),
['profile_id']
)->where('meta_id IN (?)', $metadataIds);

return $connection->fetchCol($select);
}
}
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.
*/
declare(strict_types=1);

namespace Magento\SalesSequence\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\SalesSequence\Model\Sequence\DeleteByStore;

/**
* Observer for Sequence Removal.
*/
class SequenceRemovalObserver implements ObserverInterface
{
/**
* @var DeleteByStore
*/
private $deleteByStore;

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

/**
* Deletes all sequence linked entities.
*
* @param EventObserver $observer
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function execute(EventObserver $observer)
{
if ($store = $observer->getData('store')) {
$this->deleteByStore->execute($store->getId());
}

return $this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\SalesSequence\Test\Unit\Model\Sequence;

use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Select;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\SalesSequence\Model\Meta;
use Magento\SalesSequence\Model\MetaFactory;
use Magento\SalesSequence\Model\ResourceModel\Meta as ResourceMeta;
use Magento\SalesSequence\Model\Sequence\DeleteByStore;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

/**
* Test for \Magento\SalesSequence\Model\Sequence\DeleteByStore class.
*/
class DeleteByStoreTest extends TestCase
{
/**
* @var DeleteByStore
*/
private $deleteByStore;

/**
* @var ResourceMeta | MockObject
*/
private $resourceSequenceMeta;

/**
* @var Meta | MockObject
*/
private $meta;

/**
* @var MetaFactory | MockObject
*/
private $metaFactory;

/**
* @var AdapterInterface | MockObject
*/
private $connectionMock;

/**
* @var ResourceConnection | MockObject
*/
private $resourceMock;

/**
* @var Select | MockObject
*/
private $select;

protected function setUp()
{
$this->connectionMock = $this->getMockForAbstractClass(
AdapterInterface::class,
[],
'',
false,
false,
true,
['delete', 'query']
);
$this->resourceSequenceMeta = $this->createPartialMock(
ResourceMeta::class,
['load', 'delete']
);
$this->meta = $this->createPartialMock(
Meta::class,
['getSequenceTable']
);
$this->resourceMock = $this->createMock(ResourceConnection::class);
$this->select = $this->createMock(Select::class);
$this->metaFactory = $this->createPartialMock(MetaFactory::class, ['create']);
$this->metaFactory->method('create')->willReturn($this->meta);

$helper = new ObjectManager($this);
$this->deleteByStore = $helper->getObject(
DeleteByStore::class,
[
'resourceMetadata' => $this->resourceSequenceMeta,
'metaFactory' => $this->metaFactory,
'appResource' => $this->resourceMock,
]
);
}

/**
* @throws \Exception
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
public function testExecute()
{
$profileTableName = 'sales_sequence_profile';
$storeId = 1;
$metadataIds = [1, 2];
$profileIds = [10, 11];
$this->resourceMock->method('getTableName')
->willReturnCallback(
static function ($tableName) {
return $tableName;
}
);
$this->resourceMock->method('getConnection')
->willReturn($this->connectionMock);
$this->connectionMock
->method('select')
->willReturn($this->select);

$this->select->method('from')
->willReturn($this->select);
$this->select->method('where')
->willReturn($this->select);

$this->connectionMock->method('fetchCol')
->willReturnCallback(
static function ($arg, $arg2) use ($metadataIds, $profileIds) {
if (array_key_exists('store', $arg2)) {
return $metadataIds;
}

return $profileIds;
}
);

$this->connectionMock->expects($this->once())
->method('delete')
->with($profileTableName, ['profile_id IN (?)' => $profileIds])
->willReturn(2);
$this->resourceSequenceMeta
->method('load')
->willReturn($this->meta);
$this->connectionMock
->method('dropTable')
->willReturn(true);
$this->resourceSequenceMeta
->method('delete')
->willReturn($this->resourceSequenceMeta);
$this->deleteByStore->execute($storeId);
}
}
12 changes: 12 additions & 0 deletions app/code/Magento/SalesSequence/etc/events.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="store_delete">
<observer name="magento_sequence" instance="Magento\SalesSequence\Observer\SequenceRemovalObserver" />
</event>
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ private function copyAppConfigFiles()
}
}
}

/**
* Copies global configuration file from the tests folder (see TESTS_GLOBAL_CONFIG_FILE)
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ public function testGetUrlInStore()
* @magentoConfigFixture fixturestore_store web/unsecure/base_url http://sample-second.com/
* @magentoConfigFixture fixturestore_store web/unsecure/base_link_url http://sample-second.com/
* @magentoDataFixture Magento/Catalog/_files/product_simple_multistore.php
* @magentoDbIsolation disabled
* @dataProvider getUrlsWithSecondStoreProvider
* @magentoDbIsolation disabled
* @magentoAppArea adminhtml
*/
public function testGetUrlInStoreWithSecondStore($storeCode, $expectedProductUrl)
Expand Down
Loading