Magento2: Can not change product status which product created with productRepository

Created on 15 Jul 2016  路  28Comments  路  Source: magento/magento2

Preconditions

  • Any supported Magento version

Steps to reproduce

$product = $objectManager->create(Product::class); $product->setTypeId(Type::TYPE_SIMPLE) ->setWebsiteIds([1]) ->setName(NAME) ->setSku(SKU) ->setPrice(10) ->setVisibility(Visibility::VISIBILITY_BOTH) ->setStatus(Status::STATUS_DISABLED) ->setCategoryIds(array(1,5,7)); try { $product = $productRepository->save($product); } catch (\Exception $e) { echo $e->getMessage(); }
Product created successfully.
In admin set 'Enable Product' true. But at product grid in admin, status seems 'Disabled'.

Expected result

Product have to be online in website

Actual result

'We can't find products matching the selection.'
And product status seen Disabled in admin grid.

Catalog Clear Description Confirmed Format is valid Ready for Work Reproduced on 2.1.x Reproduced on 2.2.x

Most helpful comment

Why is it still not fixed. It was reported on 16 July 2016. It is really serious issue
@magento-engcom-team

All 28 comments

An addition;
If I change status via products grid (check checkbox of item, select 'Change Status'->'Enabled' action) it is working fine

Got this issue too.
I'm not able to create product programaticly, using standard code with InstalData script and Magento\Catalog\Model\ProductFactory.

Steps to reproduce:

use Magento\Catalog\Model\ProductFactory;
use Magento\Framework\Setup\InstallDataInterface;

class InstallData implements InstallDataInterface

{
    protected $_productFactory;

    public function __construct( ProductFactory $productFactory )
    {
    $this->_productFactory = $productFactory;
    }

   public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        $product = $this->_productFactory->create();
        $product->setSku('sku');
        $product->setName('Sample Product');
        $product->setAttributeSetId(4);
        $product->setStatus(1);
        $product->setWeight(10);
        $product->setVisibility(4);
        $product->setPrice(100);
        $product->setStockData(
                        array(
                            'use_config_manage_stock' => 0,
                            'manage_stock' => 1,
                            'is_in_stock' => 1,
                            'qty' => 999999999
                        )
                    );
        $product->save();
        $setup->endSetup();
    }

Expected result

Status is 'Product is online', and Database value of attribute = 1

Actual result

Status is 'Product is offline', and Database value of attribute = 2

@rbostan please specify Magento version used.

I'm using 2.1.1 now and problem still exists.

I am having the same problem on 2.1.3

I found the bug.

It is in class \Magento\PricePermissions\Helper\Data, method getCanAdminEditProductStatus()

It does not check if there is a session or a role. In magento 1, it was done in the following way, but it was not ported to magento2.

Or it can be fixed in class Magento\PricePermissions\Observer, method execute()

    /**
     * Handle catalog_product_save_before event
     *
     * @param EventObserver $observer
     * @return void
     */
    public function execute(EventObserver $observer)
    {
        /** @var $helper \Magento\PricePermissions\Helper\Data */
        $helper = $this->_pricePermData;
        $this->observerData->setCanEditProductStatus($helper->getCanAdminEditProductStatus());

        /** @var $product \Magento\Catalog\Model\Product */
        $product = $observer->getEvent()->getDataObject();
        if ($product->isObjectNew() && !$this->observerData->isCanEditProductStatus()) {
            $product->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED);
        }
        if ($product->isObjectNew() && !$this->observerData->isCanReadProductPrice()) {
            $product->setPrice($this->observerData->getDefaultProductPriceString());
        }
    }

Magento 1, class: Enterprise_PricePermissions_Model_Observer, method: adminControllerPredispatch

// load role with true websites and store groups
if ($session->isLoggedIn() && $session->getUser()->getRole()) {

}

I have the same issue here.

I saw the file @kervin mentioned. That observer is triggered when a new product is created. I can confirm that even though I update a product (Not creating new one), I am not able to change its status.

Expected Result

Chaning the status to enabled.

Actual Result

Status is still disabled.

Steps to Reproduce

public function __construct(
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
    \Magento\Catalog\Api\Data\ProductInterfaceFactory $productFactory,
) {
    $this->productRepository = $productRepository;
    $this->productFactory = $productFactory;
}
$parentProduct = $this->productRepository->get('PARENT_SKU');

$product = $this->productFactory->create();
$product->setStoreId(0);
$product->setWebsiteIds([1,2]);
$product->setSku('UNIQUE SKU');
$product->setName("Some custom title");
$product->setAttributeSetId(1);
$product->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
$product->setVisibility($parentProduct->getVisibility());
$product->setTypeId('simple');
$product->setWeight($parentProduct->getWeight());
$product->setExtensionAttributes($parentProduct->getExtensionAttributes());
$product->setOptions($parentProduct->getOptions());
$product->setCustomAttributes($parentProduct->getCustomAttributes());
$product->setPrice($productPrice->getRegularPrice());

try {
    $product = $this->productRepository->save($product);
} catch (\Exception $e) {
    $this->logger->warning($e->getMessage());
    return false;
}

// Change the status (Updating product)
// You can confirm that $product->getId() is not NULL
$product->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
try {
    $product = $this->productRepository->save($product);
} catch (\Exception $e) {
    $this->logger->warning($e->getMessage());
    return false;
}

Hi there,

I have tried cloning the product, but the problem still continues with the cloning.

Expected Output

(1) (COPY PRODUCT ID: XXXX) (COPY PRODUCT STATUS: 1) (COPY PRODUCT STORE ID: 0)
(2) (COPY PRODUCT ID: XXXX) (COPY PRODUCT STATUS: 1) (COPY PRODUCT STORE ID: 0)

Actual Output

(1) (COPY PRODUCT ID: XXXX) (COPY PRODUCT STATUS: 2) (COPY PRODUCT STORE ID: 0)
(2) (COPY PRODUCT ID: XXXX) (COPY PRODUCT STATUS: 2) (COPY PRODUCT STORE ID: 0)

Steps to Reproduce

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();

/** @var \Magento\Catalog\Model\ProductRepository $productRepository */
$productRepository = $objectManager->create(\Magento\Catalog\Model\ProductRepository::class);

/** @var \Magento\Catalog\Model\Product\Copier $copier */
$copier = $objectManager->create(\Magento\Catalog\Model\Product\Copier::class);

$originalProduct = $productRepository->get('000000000089210800', true, 0, true);

try {
    $product = $copier->copy($originalProduct);
    echo "(1) (COPY PRODUCT ID: {$product->getId()}) (COPY PRODUCT STATUS: {$product->getStatus()}) (COPY PRODUCT STORE ID: {$product->getStoreId()})\n";

    $product->setStatus(1);
    $product->save();

    echo "(2) (COPY PRODUCT ID: {$product->getId()}) (COPY PRODUCT STATUS: {$product->getStatus()}) (COPY PRODUCT STORE ID: {$product->getStoreId()})\n";
} catch (\Exception $e) {
    echo $e->getMessage()."\n";
    echo $e->getTraceAsString()."\n";
}

Any update on this issue? This is still present in Magento 2.1.6.

@denisrpriebe There is still no solution, so I did the following work-around. It is not pretty but it works.

public function __construct(
\Magento\Framework\App\ResourceConnection $resourceConnection
){
    $this->resourceConnection = $resourceConnection;
}
    /**
     * Changes product status
     *
     * This function changes the status of given product.
     *
     * @param \Magento\Catalog\Api\Data\ProductInterface $product
     * @param int $status
     */
    protected function changeStatus(\Magento\Catalog\Api\Data\ProductInterface $product, $status)
    {
        $resourceConnection = $this->resourceConnection;
        $connection = $resourceConnection->getConnection();

        $tableEavAttribute = $resourceConnection->getTableName('eav_attribute');
        $tableProductEntityInt = $resourceConnection->getTableName('catalog_product_entity_int');
        $tableEavEntityType = $resourceConnection->getTableName('eav_entity_type');

        $entityTypeIdProduct = $connection->fetchOne("SELECT `entity_type_id` FROM `{$tableEavEntityType}` WHERE `entity_type_code` = 'catalog_product' LIMIT 0,1;");
        $attributeIdStatus = $connection->fetchOne("SELECT `attribute_id` FROM `{$tableEavAttribute}` WHERE `attribute_code` = 'status' AND `entity_type_id` = {$entityTypeIdProduct}");
        $connection->update($tableProductEntityInt, ['value' => $status], "`attribute_id` = {$attributeIdStatus} AND `row_id` = {$product->getRowId()}");
    }

@bnymn Thanks for posting that. I just integrated your code and it works. It's insane that we have to do things like this just to enable products. I'm pretty sure the core Magento engineers have absolutely no idea of SOLID principles or any concept of quality.

Easier solution would be to login the user... then you can use the the normal way to change status

    /**
     * Dirty Fix to login customer due to Magento 2 Bug
     * https://github.com/magento/magento2/issues/5664
     *
     * @return $this
     */
    public function loginAdminUser()
    {
        $model = $this->userFactory->create()->loadByUsername('USERNAME');

        $this->state->emulateAreaCode('adminhtml', function ($model) {
            $session = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Backend\Model\Auth\Session');
            $session->start();
            $session->setUser($model);
            $session->processLogin();
        }, array($model));

        return $this;
    }

Why is it still not fixed. It was reported on 16 July 2016. It is really serious issue
@magento-engcom-team

@rbostan, thank you for your report.
We've created internal ticket(s) MAGETWO-84408 to track progress on the issue.

The same issue occurs when you insert a product with API.

distributed-cd

Are there any updates on this?

Ok. In 2.2.4 you need to set the default role model in your di.xml. Below is the code to login the user.

use Magento\Framework\App\State;
use Magento\User\Model\UserFactory;


 public function __construct(
        State $state,
        UserFactory $userFactory,
    ) {
        $this->state = $state;
        $this->userFactory = $userFactory;
        $this->loginAdminUser();

        return $this;
    }
    /**
     * Fix to login customer due to Magento 2 Bug
     * https://github.com/magento/magento2/issues/5664
     *
     * @return $this
     * @throws \Exception
     */
    public function loginAdminUser()
    {
        $user = $this->userFactory->create()->loadByUsername('kervin');

        $this->state->emulateAreaCode('adminhtml', function ($user) {
            $session = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Backend\Model\Auth\Session');
            $session->start();
            $session->setUser($user);
            $session->processLogin();
        }, array($user));

        return $this;
    }

di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Framework\Authorization\RoleLocatorInterface" type="Magento\Backend\Model\Authorization\RoleLocator" />
</config>

@magento-engcom-team Thank you for verifying the issue.

Unfortunately, not enough information was provided to created internal ticket. Please consider adding the following:

  • [ ] Add "Component: " label(s) to this ticket based on verification result. If uncertain, you may follow the best guess
  • [ ] Update issue content to follow format required by Issue Reporting Guidelines

Once all required information is added, please label this ticket with "acknowledged" again.
Thanks!

@magento-engcom-team Thank you for verifying the issue. Based on the provided information internal tickets MAGETWO-94984, MAGETWO-94983 were created

as temporary workaround you can do

$duplicateSimple->setData('status', Product\Attribute\Source\Status::STATUS_ENABLED);
$this->product->saveAttribute($duplicateSimple, 'status');

with $this-product as Magento\Catalog\Model\ResourceModel\Product

[Magento 2.2.6]
It's important to use deprecated method _save()_ before this workaround (with _productRepository->save($product)_ it's not working).

$product->save();
$product->setStatus(Product\Attribute\Source\Status::STATUS_ENABLED);
$this->productResourceModel->saveAttribute($product, Magento\Catalog\Model\Product::STATUS);

Hi @milindsingh. Thank you for working on this issue.
Looks like this issue is already verified and confirmed. But if your want to validate it one more time, please, go though the following instruction:

  • [ ] 1. Add/Edit Component: XXXXX label(s) to the ticket, indicating the components it may be related to.
  • [ ] 2. Verify that the issue is reproducible on 2.3-develop branch

    Details- Add the comment @magento-engcom-team give me 2.3-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.3-develop branch, please, add the label Reproduced on 2.3.x.
    - If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and _stop verification process here_!

  • [ ] 3. Verify that the issue is reproducible on 2.2-develop branch.

    Details- Add the comment @magento-engcom-team give me 2.2-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.2-develop branch, please add the label Reproduced on 2.2.x

  • [ ] 4. If the issue is not relevant or is not reproducible any more, feel free to close it.

Have No issue on both 2.1.x 2.2.x and 2.3x
```
$product = $this->productFactory->create();
$product->setSku('sku');
$product->setName('Sample Product');
$product->setAttributeSetId(4);
$product->setStatus(1);
$product->setWeight(10);
$product->setVisibility(4);
$product->setPrice(100);
$product->setWebsiteIds([1]);
$product->setStockData(
array(
'use_config_manage_stock' => 0,
'manage_stock' => 1,
'is_in_stock' => 1,
'qty' => 999999999
)
);

    $this->productRepository->save($product);

````

image

I have product available both frontend and admin

I am working on this at #dmdcindia1

Please try to redeclare the preference for the PolicyInterface during the object manager initialization:

$objectManager->configure([
            'preferences' => [
                'Magento\Framework\Authorization\PolicyInterface' => 'Magento\Framework\Authorization\Policy\DefaultPolicy'
            ]
        ]);

Hi @sergey-solo. Thank you for working on this issue.
Looks like this issue is already verified and confirmed. But if you want to validate it one more time, please, go though the following instruction:

  • [ ] 1. Add/Edit Component: XXXXX label(s) to the ticket, indicating the components it may be related to.
  • [ ] 2. Verify that the issue is reproducible on 2.3-develop branch

    Details- Add the comment @magento give me 2.3-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.3-develop branch, please, add the label Reproduced on 2.3.x.
    - If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and _stop verification process here_!

  • [ ] 3. Verify that the issue is reproducible on 2.2-develop branch.

    Details- Add the comment @magento give me 2.2-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.2-develop branch, please add the label Reproduced on 2.2.x

  • [ ] 4. If the issue is not relevant or is not reproducible any more, feel free to close it.


Can't reproduce on 2.3-develop

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jzalenski picture jzalenski  路  3Comments

denis-g picture denis-g  路  3Comments

PushEngineering picture PushEngineering  路  3Comments

BenSpace48 picture BenSpace48  路  3Comments

fvillata picture fvillata  路  3Comments