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

Duplicate existing Product #627

Closed
oncode opened this issue Jan 8, 2021 · 11 comments
Closed

Duplicate existing Product #627

oncode opened this issue Jan 8, 2021 · 11 comments
Labels
next minor Candidate for the next minor release type: feature ✨ @vendure/core

Comments

@oncode
Copy link
Contributor

oncode commented Jan 8, 2021

Is your feature request related to a problem? Please describe.
When adding a product which is similar to existing ones, I often open a product in another tab while creating a new one, so I don't forget to add the same kind of facets.

Bildschirmfoto 2021-01-08 um 13 09 53

Describe the solution you'd like
It would be cool if product facets could be taken from an existing product.

Describe alternatives you've considered
Maybe this problem is to specific and writing my own plugin would be better. Or a more general solution, like the ability to duplicate a product as whole.

@michaelbromley
Copy link
Member

I think "duplicate product" is probably something I'll include as standard. Maybe we can have an API where you can choose which properties of the current product to duplicate. Thus for your case you could check the "facets" and leave the rest as default (empty).

@oncode
Copy link
Contributor Author

oncode commented Jan 8, 2021

Yes, that sounds awesome! If you want you can close this request, if you have it already on your agenda.

@michaelbromley michaelbromley changed the title Copy facets of a product Duplicate existing Product Jan 8, 2021
@michaelbromley michaelbromley added this to the v1.0.0 milestone Jan 8, 2021
@michaelbromley michaelbromley added this to Planned in Vendure Roadmap May 7, 2021
@chladog
Copy link
Contributor

chladog commented May 31, 2021

If anyone in need of this right now, here's simple plugin that allows to duplicate product and product variant with all data:
https://github.com/chladog/vendure-duplicator

@floze
Copy link
Contributor

floze commented Oct 25, 2023

+1 for this feature, I would find it very important.

@michaelbromley michaelbromley added the next minor Candidate for the next minor release label Nov 1, 2023
@michaelbromley
Copy link
Member

Ideally I would like to be able to offer a generic "duplicate" mutation that is potentially capable of duplicating any entity.

Something like this:

GraphQL API

input DuplicateEntityInput {
  entityName: String!
  entityId: ID!
}

type DuplicateEntitySuccess {
  newEntityId: ID!
}

type DuplicateEntityError implements ErrorResult {
    errorCode: ErrorCode!
    message: String!
    duplicationError: String!
}

union DuplicateEntityResult = DuplicateEntitySuccess  | DuplicateEntityError

extend type Mutation {
  duplicateEntity(input: DuplicateEntityInput!): DuplicateEntityResult
}

Server Implementation

Then we need to have a way to provide the actual logic used when duplicating a particular entity. To make this able to also be able to handle custom entities too, we could add a new config option like this:

interface VendureConfig {
  // ...
  entityOptions: {
    entityDuplicationStrategy: EntityDuplicationStrategy[];
  }
}

interface EntityDuplicationStrategy extends InjectableStrategy {
  canDuplicate(entityName: string): boolean;
  duplicate(ctx: RequestContext, entityName: string, id: ID): Promise<VendureEntity>;
}

this allows us to provide any number of strategies for handling the duplication of given entities. A single strategy for e.g. Product could look like this:

export class ProductDuplicationStrategy implements EntityDuplicationStrategy {
  private connection: TransactionalConnection;

  init(injector: Injector) {
    this.connection = injector.get(TransactionalConnection);
  }

  canDuplicate(entityName: string) {
    return entityName === 'Product';
  }

  async duplicate(ctx: RequestContext, entityName: string, id: ID) {
    const product = await this.connection.getEntityOrThrow(ctx, Product, id);
   
    // specific logic to duplicate the product omitted;

    return newProduct;
  }
}

Permissions

We'd need to make sure to restrict the duplicateEntity mutation to users with "update" permissions on the given entity. It's not clear yet how to implement that, but perhaps we can add to the strategy interface a way to specify permissions required to carry out the operation.

Configurable duplication

In my comment above I talk about the idea of being able to select which properties of an entity to duplicate. Supporting this in a generic way would introduce quite a bit of complexity, but it is worth considering how it might be supported. Or perhaps allowing a strategy to define a set of options that it is then free to interpret during the duplication process, which could be used to allow selective duplication, or even allow other types of sophisticated duplication.

Admin UI

We'd then want some UI controls that allow the admin to duplicate an entity. This could be done from either

  • the detail view
  • the list view

I personally think it makes the most sense from the list view, but we'd need to keep in mind what happens if a user has multiple entities selected. Maybe we make the mutation input accept an array of IDs, and on the server we just call the strategy duplicate method multiple times, once for each ID.

Default strategies

Then Vendure would ship with a set of strategies to handle duplication of the most common entities. We can add to these over time to increase coverage, but initially I would consider (in order of importance):

  • Product
  • ProductVariant
  • Collection
  • Promotion
  • Shipping Method
  • Payment Method

@michaelbromley michaelbromley pinned this issue Feb 16, 2024
michaelbromley added a commit that referenced this issue Feb 20, 2024
michaelbromley added a commit that referenced this issue Feb 20, 2024
michaelbromley added a commit that referenced this issue Feb 20, 2024
michaelbromley added a commit that referenced this issue Feb 20, 2024
michaelbromley added a commit that referenced this issue Feb 20, 2024
michaelbromley added a commit that referenced this issue Feb 20, 2024
@mschipperheyn
Copy link
Contributor

I would suggest adding the option to copy-duplicate a product to a different channel. For us, it's not so much about duplicating a product as much as it is copying instead of referencing a product on another channel

@michaelbromley
Copy link
Member

With the new API you'll be able to write a custom duplicator that will do exactly this, including having a widget where you can specify the target channel in the admin ui.

@martijnvdbrug
Copy link
Contributor

martijnvdbrug commented Mar 14, 2024

Good thing I did a quick search before implementing this as a plugin this time 😆

Some other things that came to mind for duplicating a product:

  • Should duplicate variants
  • Should duplicate facet values
  • Should duplicate custom fields, including relations
  • Should only create the copied product in the current channel, based on the user's RequestContext
  • Should redirect admin to the duplicated product after duplication

I think all of these make sense to have as default behaviour, but I might be a bit biased 🙃 We can help on implementing the Product duplicator strategy, but I am unsure wether we have the time to contribute on the generic duplicate interface part.

@michaelbromley
Copy link
Member

@martijnvdbrug the generic duplicate interface is all done already! see the commits referenced above.

You can take a look at the current implementation of product duplication - it is less comprehensive than your suggestions so feel free to PR improvements!

@martijnvdbrug
Copy link
Contributor

Is this going to be in V2 already? Or only the backend? Or inlcuding admin Ui part?

@michaelbromley
Copy link
Member

v2.2 yeah. It's in there already including the Admin UI part. You can test it quickly with npx @vendure/create@next my-shop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
next minor Candidate for the next minor release type: feature ✨ @vendure/core
Projects
Status: Done
Development

No branches or pull requests

6 participants