Skip to content

Commit c820f42

Browse files
authored
fix(core): Avoid variant options combination check on updateProductVariant mutation (#3361)
1 parent 0ea3441 commit c820f42

File tree

2 files changed

+30
-18
lines changed

2 files changed

+30
-18
lines changed

packages/core/e2e/product.e2e-spec.ts

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,22 +1736,28 @@ describe('Product resolver', () => {
17361736
}, 'ProductVariant optionIds must include one optionId from each of the groups: group-2, group-3'),
17371737
);
17381738

1739-
it(
1740-
'passing optionIds that match an existing variant throws',
1741-
assertThrowsWithMessage(async () => {
1742-
await adminClient.query<
1743-
Codegen.UpdateProductVariantsMutation,
1744-
Codegen.UpdateProductVariantsMutationVariables
1745-
>(UPDATE_PRODUCT_VARIANTS, {
1746-
input: [
1747-
{
1748-
id: variantToModify.id,
1749-
optionIds: variants[1]!.options.map(o => o.id),
1750-
},
1751-
],
1752-
});
1753-
}, 'A ProductVariant with the selected options already exists: Variant 3'),
1754-
);
1739+
it('passing optionIds that match an existing variant should not throw', async () => {
1740+
const { updateProductVariants } = await adminClient.query<
1741+
Codegen.UpdateProductVariantsMutation,
1742+
Codegen.UpdateProductVariantsMutationVariables
1743+
>(UPDATE_PRODUCT_VARIANTS, {
1744+
input: [
1745+
{
1746+
id: variantToModify.id,
1747+
optionIds: variantToModify!.options.map(o => o.id),
1748+
sku: 'ABC',
1749+
price: 432,
1750+
},
1751+
],
1752+
});
1753+
const updatedVariant = updateProductVariants[0];
1754+
if (!updatedVariant) {
1755+
fail('no updated variant returned.');
1756+
return;
1757+
}
1758+
expect(updatedVariant.sku).toBe('ABC');
1759+
expect(updatedVariant.price).toBe(432);
1760+
});
17551761

17561762
it('addOptionGroupToProduct and then update existing ProductVariant with a new option', async () => {
17571763
const optionGroup4 = await createOptionGroup('group-4', [

packages/core/src/service/services/product-variant.service.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ export class ProductVariantService {
483483
throw new UserInputError('error.stockonhand-cannot-be-negative');
484484
}
485485
if (input.optionIds) {
486-
await this.validateVariantOptionIds(ctx, existingVariant.productId, input.optionIds);
486+
await this.validateVariantOptionIds(ctx, existingVariant.productId, input.optionIds, true);
487487
}
488488
const inputWithoutPriceAndStockLevels = {
489489
...input,
@@ -899,7 +899,12 @@ export class ProductVariantService {
899899
return result;
900900
}
901901

902-
private async validateVariantOptionIds(ctx: RequestContext, productId: ID, optionIds: ID[] = []) {
902+
private async validateVariantOptionIds(
903+
ctx: RequestContext,
904+
productId: ID,
905+
optionIds: ID[] = [],
906+
isUpdateOperation?: boolean,
907+
) {
903908
// this could be done with fewer queries but depending on the data, node will crash
904909
// https://github.com/vendure-ecommerce/vendure/issues/328
905910
const optionGroups = (
@@ -936,6 +941,7 @@ export class ProductVariantService {
936941
.filter(v => !v.deletedAt)
937942
.forEach(variant => {
938943
const variantOptionIds = this.sortJoin(variant.options, ',', 'id');
944+
if (isUpdateOperation) return;
939945
if (variantOptionIds === inputOptionIds) {
940946
throw new UserInputError('error.product-variant-options-combination-already-exists', {
941947
variantName: this.translator.translate(variant, ctx).name,

0 commit comments

Comments
 (0)