Skip to content

Duplicate product #15656

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

Closed
rommelfreddy opened this issue Jun 1, 2018 · 20 comments
Closed

Duplicate product #15656

rommelfreddy opened this issue Jun 1, 2018 · 20 comments
Labels
Component: Catalog Event: mm19in Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Priority: P4 No current plan to fix. Fixing can be deferred as a logical part of more important work. Progress: done Reproduced on 2.1.x The issue has been reproduced on latest 2.1 release Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release Severity: S4 Affects aesthetics, professional look and feel, “quality” or “usability”. stale issue

Comments

@rommelfreddy
Copy link

Preconditions

  1. Magento 2.2.2
  2. Existing product with different values in different StoreViews (e.g StoreView UK, NL, DE, ...)

Steps to reproduce

  1. open the product
  2. select one StoreView (e.g. UK - not "All StoreViews"!)
  3. click on "Save product & duplicate"

Expected result

  1. the product got be duplicated with all (different) values in each storeView

Actual result

  1. the default values of the new product are not the default values from the original product. Instead, the values from the selected storeView will be used to create the new product.

Example (Productname):

Original product:
StoreView Default: "My default name"
StoreView UK: "My UK name"
StoreView NL: "My NL name"
...

Duplicated product: (before clicking on duplicate, I switch to the storeView "UK")
StoreView Default: "My UK name"
StoreView UK: "My UK name"
StoreView NL: "My NL name"
...

@magento-engcom-team magento-engcom-team added the Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed label Jun 1, 2018
@rogyar
Copy link
Contributor

rogyar commented Jun 7, 2018

I believe that's expected behavior. You have a possibility to choose the exact product's variant to duplicate. If you need default values - choose the global scope, otherwise choose the variant that should be duplicated.

@ghost ghost self-assigned this Jul 6, 2018
@ghost
Copy link

ghost commented Jul 6, 2018

@Fredwak, thank you for your report.
We've acknowledged the issue and added to our backlog.

@ghost ghost added Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Reproduced on 2.1.x The issue has been reproduced on latest 2.1 release Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development Component: Catalog labels Jul 6, 2018
@ghost ghost removed their assignment Jul 12, 2018
@shikhamis11 shikhamis11 self-assigned this Feb 3, 2019
@magento-engcom-team
Copy link
Contributor

Hi @shikhamis11. 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.

@shikhamis11
Copy link
Member

#MM19IN

@m2-assistant
Copy link

m2-assistant bot commented Jun 11, 2019

Hi @JeroenVanLeusden. 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.


@m2-assistant
Copy link

m2-assistant bot commented Sep 27, 2019

Hi @deadlexus. 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. If the issue is not relevant or is not reproducible any more, feel free to close it.


@deadlexus
Copy link
Contributor

@magento give me 2.3-develop instance

@magento-engcom-team
Copy link
Contributor

Hi @deadlexus. Thank you for your request. I'm working on Magento 2.3-develop instance for you

@magento-engcom-team
Copy link
Contributor

Hi @deadlexus, here is your Magento instance.
Admin access: https://i-15656-2-3-develop.instances.magento-community.engineering/admin
Login: admin Password: 123123q
Instance will be terminated in up to 3 hours.

deadlexus pushed a commit to deadlexus/magento2 that referenced this issue Sep 27, 2019
- Fixed an issue with incorrect duplicating of product attributes when they have different values on store view level;
deadlexus pushed a commit to deadlexus/magento2 that referenced this issue Sep 27, 2019
- Fixed static and unit tests;
deadlexus pushed a commit to deadlexus/magento2 that referenced this issue Sep 27, 2019
@ghost ghost unassigned deadlexus Oct 18, 2019
@rvm-pmis
Copy link

I'm seeing something very similar (perhaps the same issue) when duplicating from the default storeview (currently on magento version 2.3.3-p1)
In the default storeview we have everything in english.
In the dutch storeview it's translated to nl_NL
When duplicating a product in the default storeview, the duplicate has the default english content in the dutch storeview instead of dutch content like the original product.

We solved it by applying the attached patch:
issue-15656.patch.txt

@michel334
Copy link

michel334 commented Mar 2, 2020

Same issue as rvm-pmis. Magento version 2.3.3, duplicating from default store view with 2 language store views (dutch and french). It only happens when i change the URL key for a store view. Then, when i save and duplicate, the store view information (description etc) is not copied. The default store information is copied. Also the images get duplicated multiple times. This does not happen when "use default value" is checked for the URL key for each store view. Only then save and duplicate works as expected.

@peterjaap
Copy link
Contributor

@sdzhepa any progress on this?

@peterjaap
Copy link
Contributor

peterjaap commented May 8, 2020

Some extra findings on my end. It might be related, might not.

I have one website with 3 storeviews. If I duplicate a product from the Default (i.e. "All") storeviews, all attributes that have Scope = Website configured, those values are copied from the Default storeview into all storeviews, even though in the original product the value is only set in the default storeview!

Example in case; country_of_manufacture. This has Scope set to Website in a vanilla M2 installation;

image

This is the value for that attribute for my original product in catalog_product_entity_varchar (entity_id 32767);

value_id,attribute_id,store_id,entity_id,value
1805753,114,0,32767,AF

But when I duplicate that product, the rows for the new product are as follows: (duplicated product ID in this test is 46406)

value_id,attribute_id,store_id,entity_id,value
1805677,114,0,46406,AF
1805702,114,1,46406,AF
1805701,114,2,46406,AF
1805700,114,3,46406,AF

When I update the attribute to Scope 'Global' this does not happen! (duplicated product ID in this test is 46407)

value_id,attribute_id,store_id,entity_id,value
1805677,114,0,46407,AF

But it gets weirder; if I update the attribute to Scope 'Store view', it gets copied to all storeviews except to store id 1, which is my default storeview. (duplicated product ID in this test is 46408)

value_id,attribute_id,store_id,entity_id,value
1805826,114,0,46408,AF
1805872,114,2,46408,AF
1805849,114,3,46408,AF

🤯

The following attributes are Scope=Website by default;

special_from_date
special_to_date
tier_price
news_from_date
news_to_date
status
country_of_manufacture
msrp_display_actual_price_type
tax_class_id

Edit; when I Xdebug and Duplicate the product, I see duplicate lines show up when this save() is called; https://github.com/magento/magento2/blob/2.3/app/code/Magento/Catalog/Model/Product/Copier.php#L152

I see there have been 3 commits to this file in 2.4-develop;

@peterjaap
Copy link
Contributor

peterjaap commented May 8, 2020

Ha! It appears this commit from this PR by @JeroenVanLeusden not only fixes the original problem in this issue, but also my specific issue! 🎉

@peterjaap
Copy link
Contributor

peterjaap commented May 8, 2020

Here's my patch based on the abovementioned PR for Magento 2.3.4;

--- a/app/code/Magento/Catalog/Model/Product/Copier.php	2020-01-10 07:20:38.000000000 +0100
+++ b/app/code/Magento/Catalog/Model/Product/Copier.php	2020-05-08 15:58:47.320664853 +0200
@@ -8,7 +8,11 @@
 use Magento\Catalog\Api\Data\ProductInterface;
 use Magento\Catalog\Model\Attribute\ScopeOverriddenValue;
 use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\Product\Option\Repository as OptionRepository;
 use Magento\Catalog\Model\ProductFactory;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\EntityManager\MetadataPool;
+use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException;

 /**
  * Catalog product copier.
@@ -35,9 +39,10 @@
     protected $productFactory;

     /**
-     * @var \Magento\Framework\EntityManager\MetadataPool
+     * @var MetadataPool
      */
     protected $metadataPool;
+
     /**
      * @var ScopeOverriddenValue
      */
@@ -47,30 +52,38 @@
      * @param CopyConstructorInterface $copyConstructor
      * @param ProductFactory $productFactory
      * @param ScopeOverriddenValue $scopeOverriddenValue
+     * @param OptionRepository|null $optionRepository
+     * @param MetadataPool|null $metadataPool
      */
     public function __construct(
         CopyConstructorInterface $copyConstructor,
         ProductFactory $productFactory,
-        ScopeOverriddenValue $scopeOverriddenValue
+        ScopeOverriddenValue $scopeOverriddenValue,
+        OptionRepository $optionRepository,
+        MetadataPool $metadataPool
     ) {
         $this->productFactory = $productFactory;
         $this->copyConstructor = $copyConstructor;
         $this->scopeOverriddenValue = $scopeOverriddenValue;
+        $this->optionRepository = $optionRepository;
+        $this->metadataPool = $metadataPool;
     }

     /**
      * Create product duplicate
      *
      * @param \Magento\Catalog\Model\Product $product
+     *
      * @return \Magento\Catalog\Model\Product
+     *
+     * @throws \Exception
      */
     public function copy(Product $product)
     {
         $product->getWebsiteIds();
         $product->getCategoryIds();

-        /** @var \Magento\Framework\EntityManager\EntityMetadataInterface $metadata */
-        $metadata = $this->getMetadataPool()->getMetadata(ProductInterface::class);
+        $metadata = $this->metadataPool->getMetadata(ProductInterface::class);

         /** @var \Magento\Catalog\Model\Product $duplicate */
         $duplicate = $this->productFactory->create();
@@ -88,7 +101,7 @@
         $this->copyConstructor->build($product, $duplicate);
         $this->setDefaultUrl($product, $duplicate);
         $this->setStoresUrl($product, $duplicate);
-        $this->getOptionRepository()->duplicate($product, $duplicate);
+        $this->optionRepository->duplicate($product, $duplicate);
         $product->getResource()->duplicate(
             $product->getData($metadata->getLinkField()),
             $duplicate->getData($metadata->getLinkField())
@@ -123,13 +136,16 @@
      *
      * @param Product $product
      * @param Product $duplicate
+     *
      * @return void
+     * @throws UrlAlreadyExistsException
      */
     private function setStoresUrl(Product $product, Product $duplicate) : void
     {
         $storeIds = $duplicate->getStoreIds();
         $productId = $product->getId();
         $productResource = $product->getResource();
+        $attribute = $productResource->getAttribute('url_key');
         $duplicate->setData('save_rewrites_history', false);
         foreach ($storeIds as $storeId) {
             $useDefault = !$this->scopeOverriddenValue->containsValue(
@@ -141,20 +157,23 @@
             if ($useDefault) {
                 continue;
             }
-            $isDuplicateSaved = false;
+
             $duplicate->setStoreId($storeId);
             $urlKey = $productResource->getAttributeRawValue($productId, 'url_key', $storeId);
+            $iteration = 0;
+
             do {
+                if ($iteration === 10) {
+                    throw new UrlAlreadyExistsException();
+                }
+
                 $urlKey = $this->modifyUrl($urlKey);
                 $duplicate->setUrlKey($urlKey);
-                $duplicate->setData('url_path', null);
-                try {
-                    $duplicate->save();
-                    $isDuplicateSaved = true;
-                    // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
-                } catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
-                }
-            } while (!$isDuplicateSaved);
+                $iteration++;
+            } while (!$attribute->getEntity()->checkAttributeUniqueValue($attribute, $duplicate));
+            $duplicate->setData('url_path', null);
+            $productResource->saveAttribute($duplicate, 'url_path');
+            $productResource->saveAttribute($duplicate, 'url_key');
         }
         $duplicate->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID);
     }
@@ -168,38 +187,8 @@
     private function modifyUrl(string $urlKey) : string
     {
         return preg_match('/(.*)-(\d+)$/', $urlKey, $matches)
-                    ? $matches[1] . '-' . ($matches[2] + 1)
-                    : $urlKey . '-1';
-    }
-
-    /**
-     * Returns product option repository.
-     *
-     * @return Option\Repository
-     * @deprecated 101.0.0
-     */
-    private function getOptionRepository()
-    {
-        if (null === $this->optionRepository) {
-            $this->optionRepository = \Magento\Framework\App\ObjectManager::getInstance()
-                ->get(\Magento\Catalog\Model\Product\Option\Repository::class);
-        }
-        return $this->optionRepository;
-    }
-
-    /**
-     * Returns metadata pool.
-     *
-     * @return \Magento\Framework\EntityManager\MetadataPool
-     * @deprecated 101.0.0
-     */
-    private function getMetadataPool()
-    {
-        if (null === $this->metadataPool) {
-            $this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance()
-                ->get(\Magento\Framework\EntityManager\MetadataPool::class);
-        }
-        return $this->metadataPool;
+            ? $matches[1] . '-' . ($matches[2] + 1)
+            : $urlKey . '-1';
     }

     /**

@PsmIndia
Copy link

Need Urgent Help, magento setup version is 2.3.4[upgraded m1], we have "29542 records found" products, i am facing duplicate product issue, try to fix using available patch but its not fix.

Today i remove all products images in test environment, there no image for a single product, now i add product image for a single product, i save it, working cool, but when i try to do duplicate this product, its again went into infinite loop, within few mints it create huge[4.3GB] garbage of that image that recently add. now i am helpless.

@ghost ghost removed Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development labels Oct 20, 2020
@magento-engcom-team magento-engcom-team added Priority: P4 No current plan to fix. Fixing can be deferred as a logical part of more important work. Severity: S4 Affects aesthetics, professional look and feel, “quality” or “usability”. labels Nov 30, 2020
@timbaltissen
Copy link

timbaltissen commented Feb 3, 2021

Does anyone have a solution for 2,4,1? Still facing this problem, but logic seems to have changed a lot and patches won't work anymore.

@pprignesh
Copy link

Hello;

We also discover the same issue in magento2.4.1 as @rvm-pmis facing.

Please let us know if you have any news on it.

Thanks

@leonhardtjo
Copy link

Hi,
same problem here - but on version magento2.4.2. Any news or patches on this topic?
Thanks.

@stale
Copy link

stale bot commented Jun 8, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 14 days if no further activity occurs. Is this issue still relevant? If so, what is blocking it? Is there anything you can do to help move it forward? Thank you for your contributions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Catalog Event: mm19in Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Priority: P4 No current plan to fix. Fixing can be deferred as a logical part of more important work. Progress: done Reproduced on 2.1.x The issue has been reproduced on latest 2.1 release Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release Severity: S4 Affects aesthetics, professional look and feel, “quality” or “usability”. stale issue
Projects
None yet
Development

No branches or pull requests