Once #3042257: Allow stores, promotions to be duplicated is done, we can proceed to products.
The simplest implementation would remove all referenced variations in createDuplicate(), since variations can't be shared between products and they have unique SKUs. However, we can implement an optimization for single-variation products ($product_type->allowMultipleVariations() is FALSE), and clone the variation in that case (since we know that the SKU field will be shown along with the product form).
Also, feedback suggests we need a way to duplicate variations as well. If we proceed without it, we should open a followup.
| Comment | File | Size | Author |
|---|
Issue fork commerce-3042258
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
bojanz commentedInitial work.
Comment #3
luksakWorks perfectly as described.
In my use case it is crucial to be able to clone the product variations as well, since they cause the main work for the editors. How could we solve this?
Comment #4
zenimagine commentedI applied the patch and it works for store owners.
But there is a problem with the module :
https://www.drupal.org/project/commerce_autosku
If the module is configured on "Automatically generate the SKU and hide the label field " the product variation which is duplicated displays an error of an empty SKU field.
If anyone knows an alternative to the Auto SKU module I am a taker. Because it's been 2 years since it had no update and it's been a long time since it is no longer compatible with commerce.
Comment #5
liquidcms commentedHaving this as an action would be great.
Although, would it be ok to leave variation info blank (title, sku, price) or clone those from original (as Lukas suggests). Is it even allowed to save a product with a variation with an sku value already in use?
Comment #6
abx commentedFrom this issue -> https://www.drupal.org/project/commerce/issues/2986656
The patch #8 works great with Entity Clone module. Just tested it. The only thing changed after cloned is random SKU which is ok in my case since it's better than having to fill out all information in product variation again.
Also, attach the patch that should work with current Commerce Dev.
Comment #7
matthiasm11 commentedDuplicating the product variations suits my situations the best too.
Fixed a warning regarding
Random::string()should not be called statically, patch in attachment.Instead of creating a random SKU, we should probably just append
_clonedto the SKU, just like we do with the product label. Ifmy_product_variation_clonedalready exists, a_1,_2etc should be appended I think. An example can be found inWebformHandlerFormBase::getUniqueMachineName()in the Webform module.I agree with bojanz in https://www.drupal.org/project/commerce/issues/2986656#comment-13033975, regarding duplicating product variations may not be suitable for everyone. I suggest two possible solutions:
/admin/config/system/entity-clonework. This means a checkbox for the product variation field should be added to/entity_clone/commerce_product/{product_variation_id}.createDuplicate()check this setting.The first suggestion seems the most flexibel and most correct one to me. (use the power of entity_clone instead of programming something Commerce specific)
Comment #8
abx commentedAnother patch, instead of random the sku. Use the original sku with "_clone" after it. Also, if it's duplicated, then, add number in the end.
Comment #9
matthiasm11 commentedComment #10
jsacksick commentedI don't really understand what happened with the patches (the initial patch from comment #2 had tests coverage), the latest patch has none and duplicated logic from the parent
createDuplicate()method.If we end up adding logic to support duplicating variations, I believe we should simply implement a createDuplicate() method from ProductVariation that clears out the variation SKU.
Then I'd expect the Commerce AUTOSKU module to automatically generate a SKU if configured to do so. If the module isn't present, I wonder what would happen with empty skus though :p.
Comment #11
igor.barato commentedI added support to Commerce AutoSKU module when it's enabled.
When module is not installed, we are using the same logic but I removed ' _clone' after SKU, we only add a count when the SKU already exist because this would be confuse when we re-clone a entity 'my-sku_clone_0_clone_0'.
Comment #12
igor.barato commentedFixed a wrong logic that is cloning the variations and set the old product value.
Comment #13
igor.barato commentedComment #14
s.messaris commented+1 for this functionality, will test soon and provide feedback.
Comment #15
s.messaris commentedMy review:
- #2 works to duplicate without variations.
- the patch in #13 adds a duplicate logic for variations that works, but misses everything else in #2, such as UI buttons and tests.
The derailing of this issue suggests we need to add a way to include cloning variations with the product cloning. If we proceed without it, we should open a followup, but I believe we better include the duplication of variations here.
I am adding a patch based on #2, with the duplicate variation logic from #13.
It works for me for now, but setting to needs work, as:
- the tests need to be updated and
- I am not sure the way to duplicate variations and set skus is the best we can do. For example the way added to support commerce_autosku, might be better done with some event / hook that commerce_autosku can subscribe to.
Comment #16
abx commentedJust did a quick tested.
Patch #15 does work only with Product with multiple variations. In case we have single variation, there is no way we can clone that product. (Uncheck "Allow each product to have multiple variations." in "Product Types") We have to install Entity Clone Module. But then, when, we cloned with Entity Clone module - Body, Price and SKU are linked to the Original product. Any edit in those field will also change content in the original product.
Patch #12 works great with single variation and Entity Clone module. Once cloned, both product are completely separate from each other.
Comment #17
simgui8 commented#2 is in line with the initial feature request: duplicate products.
Since products often hold a lot of marketing information that can take some time to create, staff in charge of building those products will immediately benefit from it.
I would prefer to have #2 now than wait for all the bells and whistles of duplicated variations sometime later.
Comment #18
rokzabukovec commentedI just added the event before the opening the form so we can modify the duplicated entity before the user sees it. I used patch from #15 as a base. Which was working ok for me.
Comment #19
garmoza commentedAs said abx,
This is exactly what I needed.
Patch #18 works for me. Thanks!
Comment #20
walkingdexter commentedI simplified the patch and removed its main drawback - creating variations before creating a product. I tested the patch with different number of variations and the duplication works as expected.
@rokzabukovec You can use
hook_ENTITY_TYPE_prepare_formto modify the duplicated entity.https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21...
P.S. The tests still need work.
Comment #21
walkingdexter commentedThe tests are ready.
Comment #22
abx commentedTested #21 and it works for both Product and Product Variation cloning. However, after click at Duplicate product item, there is a button "Save and add variations" but it's actually "Save and go to variations tab" to allow us to add/edit/delete variation. (Which is good since SKU is randomly generated and we usually has to go into variation to change to what we want to.)
Thanks WalkingDexter,
Comment #23
dunot commentedPatch #12 for 1 product = 1 variation on D9.4.5 DC2.31:
variation` title stucks until 2-nd Product save. It results in "- Cloned" products in Cart and in orders.
I tried to change variation title on hook_entity_presave/update/postsave, but unsuccessfully.
Edited: aaa, no, it's dc bug
Comment #25
marios anagnostopoulos commentedAttaching a patch based on #24 for 2.37
Comment #26
jsacksick commentedMain thing I'm worried about here is duplicating a product with thousands of variations... Even though that concern is also valid for the Product::postSave() logic as we loop over all variations there... This potentially has to be improved btw...
Comment #27
marios anagnostopoulos commentedThis probably is a more general issue, as you mentioned, and maybe it's best to be tackled on a separate issue.
+1
Comment #30
rhovlandOne bug we noticed today: The created time of the old product gets duplicated. The creation time should be set to when the duplicate is created.
Comment #31
hongqing commentedThx.
Comment #32
anybody+1 on this feature! Setting to NW based on #30
Comment #35
rhovlandCreated a new branch for 3.0.x. Attempted to address the creation time issue.
Comment #36
rhovlandTested latest change to creation time and it does correctly update the creation time for both the product and the variations
Comment #37
flink den haag commentedfollowing
Comment #38
hikkypo commentedI am uncertain this is within the scope of this issue, but i use this module in combination with the paragraphs module. It seems currently that if you have a product with a paragraph field and a paragraph and then clone this product. The exact same paragraph is copied to the cloned product. Resulting in a situation where if you change anything in one product the clone changes too because its the exact same paragraph instead of a new paragraph with the copied information. The quick node clone module does have support for this so maybe this is something that can be copied. Their solution is to loop through all fields and for all paragraph reference fields to then call entity::createDuplicate and then bind this to the field.
Comment #39
swentel commentedSeeing the same behavior from #38, checking if I can alter the behavior.
Comment #40
rhovlandThere is an event you can subscribe to in the entity module that is triggered whenever a duplicate entity is created. That would potentially allow the paragraphs module to fix their bug for all entities that implement duplication using the EntityDuplicationTrait not just commerce.
https://git.drupalcode.org/project/entity/-/blob/8.x-1.x/src/Event/Entit...
Comment #42
grietdk commentedI added a setting on product types to set whether variations should be duplicated when duplicating a product of the type. By default, variations will still be duplicated as well. This allows to not duplicate variations for certain product types, so the duplicated product does not have any variations on it.
Comment #43
alphex commentedRunning commerce 3.2.0
using the 212 MR patch...
Trying to clone a variation on the variations screen.
Symfony\Component\Routing\Exception\MissingMandatoryParametersException: Some mandatory parameters are missing ("commerce_product") to generate a URL for route "entity.commerce_product_variation.edit_form". in Drupal\Core\Routing\UrlGenerator->doGenerate() (line 189 of core/lib/Drupal/Core/Routing/UrlGenerator.php).
This is after running drush updb and drush cr...
I get the same error when trying the 352 MR patch.
Comment #44
rhovlandPutting a setting on the product type is not good UX. It doesn't give the person duplicating a product control over the behavior.
The variation duplication uses a form, that form should have UX to handle if variations get copied or not when the user hits save.
Comment #45
klausiThanks, MR 352 looks good and has test coverage as well.
Comment #46
fonant commentedPatch from #352 works nicely for the latest Commerce for me. Clones the Product and its Variations, giving the new variations random UUID SKUs. Easy enough to go through them and edit as needed. Thank you!