vendure icon indicating copy to clipboard operation
vendure copied to clipboard

Duplicate existing Product

Open oncode opened this issue 5 years ago • 7 comments

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.

oncode avatar Jan 08 '21 12:01 oncode

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).

michaelbromley avatar Jan 08 '21 12:01 michaelbromley

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

oncode avatar Jan 08 '21 12:01 oncode

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

chladog avatar May 31 '21 10:05 chladog

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

floze avatar Oct 25 '23 11:10 floze

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 avatar Feb 16 '24 11:02 michaelbromley

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

mschipperheyn avatar Feb 21 '24 12:02 mschipperheyn

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.

michaelbromley avatar Feb 21 '24 15:02 michaelbromley

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

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 :upside_down_face: 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.

martijnvdbrug avatar Mar 14 '24 07:03 martijnvdbrug

@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!

michaelbromley avatar Mar 14 '24 10:03 michaelbromley

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

martijnvdbrug avatar Mar 20 '24 09:03 martijnvdbrug

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

michaelbromley avatar Mar 20 '24 09:03 michaelbromley