Skip to content
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

Issue 1306 rename website breaks grid #1344

Merged
merged 14 commits into from
Jun 12, 2018

Conversation

phoenix128
Copy link
Contributor

@phoenix128 phoenix128 commented Jun 9, 2018

Fixed Issues (if relevant)

  1. Renaming website breaks MSI grid #1306: Renaming website breaks MSI grid

Contribution checklist

  • Pull request has a meaningful description of its purpose
  • All commits are accompanied by meaningful commit messages
  • All new or changed code is covered with unit/integration tests (if applicable)
  • All automated tests passed successfully (all builds on Travis CI are green)

If a website was renamed/removed, sales channels were still tying to search for it
private function getCodeFromDatabase(
\Magento\Store\Model\ResourceModel\Website $resourceModel,
int $websiteId
) {
Copy link

Choose a reason for hiding this comment

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

Pls,

  1. use return type hinting
  2. $qry is not clear name for the variable
  3. Need to use $this->resource instead of $resourceModel->getConnection(),
    generally we don't need dependency on ResourceModel\Website for obtaining website code
  4. Also, need to think about extracting this logic to separate class

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 used \Magento\Store\Model\ResourceModel\Website with intention because it can be potentially stored in a different database from the standard one.

$tableName = $this->resource->getTableName('inventory_stock_sales_channel');
$connection->update($tableName, [
SalesChannelInterface::CODE => $newCode,
], $connection->quoteInto(SalesChannelInterface::CODE . "=? and type='website'", $oldCode));
Copy link

Choose a reason for hiding this comment

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

  1. Use `\Magento\InventorySalesApi\Api\Data\SalesChannelInterface::TYPE_WEBSITE
  2. Second parameter can be array with clauses instead of sql string

if ($object->getId()) {
// Keep database consistency while updating the website code
// See https://github.com/magento-engcom/msi/issues/1306
$oldCode = $this->getCodeFromDatabase($subject, (int) $object->getId());
Copy link

Choose a reason for hiding this comment

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

Bad interface of method

'code' => $code,
];
} catch (NoSuchEntityException $e) {
// We must handle the scenario in which a previous website was removed/renamed
Copy link

Choose a reason for hiding this comment

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

I'm not sure that is good idea to skip exception... especially if we fixed initial case

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 agree, but this is the only way to fix the already done mistake.

@naydav naydav self-assigned this Jun 9, 2018
int $websiteId
) {
$connection = $resourceModel->getConnection();
$qry = $connection->select()->from($resourceModel->getMainTable(), 'code')->where('website_id = ?', $websiteId);
Copy link
Contributor

Choose a reason for hiding this comment

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

please don't use shortening in variable names
like $qry
it's better to have long variable names than shortening

* @param \Magento\Store\Model\ResourceModel\Website $subject
* @param callable $proceed
* @param \Magento\Store\Model\Website $object
* @return mixed
Copy link
Contributor

Choose a reason for hiding this comment

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

why do you have mixed as return type?
you can specify \Magento\Store\Model\ResourceModel\Website as resource model::save returns this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Phpstorm autocompletition... my fault I did not notice it.

…o around plugin

to keep data consistent while chaning the website code on an existing website.
This commit is realted to issue #1306
@phoenix128
Copy link
Contributor Author

phoenix128 commented Jun 11, 2018

@naydav @maghamed , tests are failing because Magento_Catalog does not have a sequence entry in module.xml for Magento_Store. It should be since tests and business logic require it.

Magento/Catalog/etc/module.xml:

<?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:Module/etc/module.xsd">
    <module name="Magento_Catalog" >
        <sequence>
            <module name="Magento_Eav"/>
            <module name="Magento_Cms"/>
            <module name="Magento_Indexer"/>
            <module name="Magento_Customer"/>
        </sequence>
    </module>
</config>

It happens on this module because the fixture dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/_files/website_attribute_sync.php it is updating core_website table through resource model:

$website = $objectManager->create(Website::class);
$website->setName('custom website for av test')
    ->setCode('customwebsite1');
$website->isObjectNew(true);
$websiteResourceModel->save($website);

Should I fix this issue in the core or temporary skip this exception?

Skipping the exception in \Magento\InventorySales\Plugin\Store\WebsiteResourcePlugin::aroundSave is not my best option of course, but looking at current tests is not a big issue.

private function getCodeFromDatabase(int $websiteId): string
{
$connection = $this->resourceConnection->getConnection();
$tableName = $connection->getTableName('store_website');
Copy link

Choose a reason for hiding this comment

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

We need to extract table name via $this->resourceConnection->getTableName()
Because $connection->getTableName is only wrapper which doesn't take into account table prefix

$connection = $this->resourceConnection->getConnection();
$tableName = $connection->getTableName('store_website');
$selectQry = $connection->select()->from($tableName, 'code')->where('website_id = ?', $websiteId);
return (string) $connection->fetchOne($selectQry);
Copy link

Choose a reason for hiding this comment

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

I'm not sure that we need to return ''(empty string) if the record was not found (website id is not existing)
More clear is return null in this case

Copy link
Contributor Author

@phoenix128 phoenix128 Jun 11, 2018

Choose a reason for hiding this comment

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

That method can't return an empty string. If it is called, it is called from aroundSave and only if the website exists.

Maybe I should change the initialization of $oldCode = ''; to $oldCode = null;.
And change the if statement accordingly:

...
if (($oldCode !== null) && ($oldCode !== $newCode)) {
...

use Magento\InventorySales\Model\AssignWebsiteToDefaultStock;
use Magento\InventorySales\Model\ResourceModel\UpdateSalesChannelWebsiteCode;

class WebsiteResourcePlugin
Copy link

Choose a reason for hiding this comment

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

No bad to have what does the plugin do in the class name

@@ -6,9 +6,6 @@
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="website_save_after">
<observer name="assign_website_to_default_stock" instance="Magento\InventorySales\Observer\Website\AssignWebsiteToDefaultStock"/>
</event>
<event name="website_delete_after">
Copy link

Choose a reason for hiding this comment

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

Looks like we also need to update delete logic website_delete_after

Copy link
Contributor Author

Choose a reason for hiding this comment

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

An observer after delete seems to be an efficient way and seems to be working, do you prefer to pluginize it?

Copy link
Contributor Author

@phoenix128 phoenix128 Jun 11, 2018

Choose a reason for hiding this comment

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

Done in: #1356

phoenix128 added a commit that referenced this pull request Jun 11, 2018
…and eventual stock_link deletion

This commit is related to PR #1344 .
The logic was implmented with a plugin on website save and to keep code consistency I decided to apply the same
logic to website delete.
@magento-cicd2
Copy link

magento-cicd2 commented Jun 11, 2018

CLA assistant check
All committers have signed the CLA.

@phoenix128 phoenix128 force-pushed the issue-1306-rename-website-breaks-grid branch from 1f48ab7 to fabd833 Compare June 11, 2018 17:42
@smoskaluk
Copy link

smoskaluk commented Jun 12, 2018

@phoenix128 Problem is not fixed, please recheck. I changed code(or name) of Main Website and saved it - and 've got fatal error:
Fatal error: Uncaught Error: Call to undefined method Magento\Framework\App\ResourceConnection\Interceptor::execute() in /var/www/html/magento2ce/pr7/app/code/Magento/InventorySales/Plugin/Store/Model/ResourceModel/Website/UpdateSalesChannelWebsiteCodePlugin.php:64 Stack trace: #0 /var/www/html/magento2ce/pr7/lib/internal/Magento/Framework/Interception/Interceptor.php(135): Magento\InventorySales\Plugin\Store\Model\ResourceModel\Website\UpdateSalesChannelWebsiteCodePlugin->aroundSave(Object(Magento\Store\Model\ResourceModel\Website\Interceptor), Object(Closure), Object(Magento\Store\Model\Website\Interceptor)) #1 /var/www/html/magento2ce/pr7/lib/internal/Magento/Framework/Interception/Interceptor.php(153): Magento\Store\Model\ResourceModel\Website\Interceptor->Magento\Framework\Interception{closure}(Object(Magento\Store\Model\Website\Interceptor)) #2 /var/www/html/magento2ce/pr7/generated/code/Magento/Store/Model/ResourceModel/Website/Interceptor.php(130): Magento\Store\Model\ResourceModel\Website\Interceptor->___callPlu in /var/www/html/magento2ce/pr7/app/code/Magento/InventorySales/Plugin/Store/Model/ResourceModel/Website/UpdateSalesChannelWebsiteCodePlugin.php on line 64

@phoenix128
Copy link
Contributor Author

@smoskaluk , seems it is not coming from my original code, but from other commits, let me check it.

@naydav
Copy link

naydav commented Jun 12, 2018

Sorry, It was a mistake from my side
Already fixed

@naydav naydav merged commit 1a6334c into 2.3-develop Jun 12, 2018
@maghamed maghamed deleted the issue-1306-rename-website-breaks-grid branch March 20, 2019 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants