Skip to content

Commit

Permalink
Fix #14958 - move sales sequence removal to external class
Browse files Browse the repository at this point in the history
  • Loading branch information
Bartlomiejsz committed Apr 15, 2019
1 parent 78bfbc8 commit 3ff5c06
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 51 deletions.
44 changes: 1 addition & 43 deletions app/code/Magento/SalesSequence/Model/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
*/
namespace Magento\SalesSequence\Model;

use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResourceConnection as AppResource;
use Magento\Framework\DB\Ddl\Sequence as DdlSequence;
use Magento\Framework\Webapi\Exception;
use Magento\SalesSequence\Model\ResourceModel\Meta as ResourceMetadata;
use Magento\SalesSequence\Model\ResourceModel\Profile as ResourceProfile;
use Psr\Log\LoggerInterface as Logger;

/**
Expand Down Expand Up @@ -85,36 +83,28 @@ class Builder
*/
protected $logger;

/**
* @var ResourceProfile
*/
private $resourceProfile;

/**
* @param ResourceMetadata $resourceMetadata
* @param MetaFactory $metaFactory
* @param ProfileFactory $profileFactory
* @param AppResource $appResource
* @param DdlSequence $ddlSequence
* @param Logger $logger
* @param ResourceProfile|null $resourceProfile
*/
public function __construct(
ResourceMetadata $resourceMetadata,
MetaFactory $metaFactory,
ProfileFactory $profileFactory,
AppResource $appResource,
DdlSequence $ddlSequence,
Logger $logger,
ResourceProfile $resourceProfile = null
Logger $logger
) {
$this->resourceMetadata = $resourceMetadata;
$this->metaFactory = $metaFactory;
$this->profileFactory = $profileFactory;
$this->appResource = $appResource;
$this->ddlSequence = $ddlSequence;
$this->logger = $logger;
$this->resourceProfile = $resourceProfile ?: ObjectManager::getInstance()->get(ResourceProfile::class);
$this->data = array_flip($this->pattern);
}

Expand Down Expand Up @@ -274,36 +264,4 @@ public function create()
}
$this->data = array_flip($this->pattern);
}

/**
* Deletes all sequence linked entites
*
* @param $storeId
*
* @return void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function deleteByStoreId($storeId)
{
$metadataIds = $this->resourceMetadata->getIdsByStore($storeId);
$profileIds = $this->resourceProfile->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);
}
}
}
90 changes: 90 additions & 0 deletions app/code/Magento/SalesSequence/Model/Sequence/DeleteByStore.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?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;
use Magento\SalesSequence\Model\ResourceModel\Profile as ResourceProfile;
use Magento\Store\Api\Data\StoreInterface;

/**
* Class DeleteByStore
* @api
*/
class DeleteByStore
{
/**
* @var resourceMetadata
*/
protected $resourceMetadata;

/**
* @var ResourceProfile
*/
private $resourceProfile;

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

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

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

/**
* Deletes all sequence linked entites
*
* @param StoreInterface $store
* @return void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function execute(StoreInterface $store): void
{
$metadataIds = $this->resourceMetadata->getIdsByStore($store->getId());
$profileIds = $this->resourceProfile->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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,30 @@
* 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\Builder;
use Magento\SalesSequence\Model\Sequence\DeleteByStore;

/**
* Class SequenceRemovalObserver
*/
class SequenceRemovalObserver implements ObserverInterface
{
/**
* @var Builder
* @var DeleteByStore
*/
private $sequenceBuilder;
private $deleteByStore;

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

/**
Expand All @@ -36,8 +37,7 @@ public function __construct(
*/
public function execute(EventObserver $observer)
{
$storeId = $observer->getData('store')->getId();
$this->sequenceBuilder->deleteByStoreId($storeId);
$this->deleteByStore->execute($observer->getData('store'));

return $this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<?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\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\ResourceModel\Profile as ResourceProfile;
use Magento\SalesSequence\Model\Sequence\DeleteByStore;
use Magento\Store\Api\Data\StoreInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

/**
* Class DeleteByStoreTest
*/
class DeleteByStoreTest extends TestCase
{
/**
* @var DeleteByStore
*/
private $deleteByStore;

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

/**
* @var ResourceProfile | MockObject
*/
private $resourceSequenceProfile;

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

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

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

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

/**
* @var StoreInterface | MockObject
*/
private $store;

protected function setUp()
{
$this->connectionMock = $this->getMockForAbstractClass(
AdapterInterface::class,
[],
'',
false,
false,
true,
['delete']
);
$this->resourceSequenceMeta = $this->createPartialMock(
ResourceMeta::class,
['getIdsByStore', 'load', 'delete']
);
$this->resourceSequenceProfile = $this->createPartialMock(
ResourceProfile::class,
['getProfileIdsByMetadataIds']
);
$this->meta = $this->createPartialMock(
Meta::class,
['getSequenceTable']
);
$this->resourceMock = $this->createMock(ResourceConnection::class);
$this->metaFactory = $this->createPartialMock(MetaFactory::class, ['create']);
$this->metaFactory->expects($this->any())->method('create')->willReturn($this->meta);
$this->store = $this->getMockForAbstractClass(
StoreInterface::class,
[],
'',
false,
false,
true,
['getId']
);

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

public function testExecute()
{
$storeId = 1;
$metadataIds = [1, 2];
$profileIds = [10, 11];
$tableName = 'sales_sequence_profile';
$this->store->expects($this->once())
->method('getId')
->willReturn($storeId);
$this->resourceSequenceMeta->expects($this->once())
->method('getIdsByStore')
->with($storeId)
->willReturn($metadataIds);
$this->resourceSequenceProfile->expects($this->once())
->method('getProfileIdsByMetadataIds')
->with($metadataIds)
->willReturn($profileIds);
$this->resourceMock->expects($this->once())
->method('getTableName')
->with($tableName)
->willReturn($tableName);
$this->resourceMock->expects($this->any())
->method('getConnection')
->willReturn($this->connectionMock);
$this->connectionMock->expects($this->once())
->method('delete')
->with($tableName, ['profile_id IN (?)' => $profileIds])
->willReturn(2);
$this->resourceSequenceMeta->expects($this->any())
->method('load')
->willReturn($this->meta);
$this->connectionMock->expects($this->any())
->method('dropTable')
->willReturn(true);
$this->resourceSequenceMeta->expects($this->any())
->method('delete')
->willReturn($this->resourceSequenceMeta);
$this->deleteByStore->execute($this->store);
}
}

0 comments on commit 3ff5c06

Please sign in to comment.