Skip to content

Commit

Permalink
fix(core): Soft-delete variants when a product is soft-deleted
Browse files Browse the repository at this point in the history
Fixes #1096
  • Loading branch information
michaelbromley committed Sep 23, 2021
1 parent 9e36873 commit ff1ae90
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
31 changes: 26 additions & 5 deletions packages/core/e2e/product.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1617,7 +1617,7 @@ describe('Product resolver', () => {

describe('deletion', () => {
let allProducts: GetProductList.Items[];
let productToDelete: GetProductList.Items;
let productToDelete: GetProductWithVariants.Product;

beforeAll(async () => {
const result = await adminClient.query<GetProductList.Query, GetProductList.Variables>(
Expand All @@ -1634,24 +1634,45 @@ describe('Product resolver', () => {
});

it('deletes a product', async () => {
productToDelete = allProducts[0];
const { product } = await adminClient.query<
GetProductWithVariants.Query,
GetProductWithVariants.Variables
>(GET_PRODUCT_WITH_VARIANTS, {
id: allProducts[0].id,
});
const result = await adminClient.query<DeleteProduct.Mutation, DeleteProduct.Variables>(
DELETE_PRODUCT,
{ id: productToDelete.id },
{ id: product!.id },
);

expect(result.deleteProduct).toEqual({ result: DeletionResult.DELETED });

productToDelete = product!;
});

it('cannot get a deleted product', async () => {
const result = await adminClient.query<
const { product } = await adminClient.query<
GetProductWithVariants.Query,
GetProductWithVariants.Variables
>(GET_PRODUCT_WITH_VARIANTS, {
id: productToDelete.id,
});

expect(result.product).toBe(null);
expect(product).toBe(null);
});

// https://github.com/vendure-ecommerce/vendure/issues/1096
it('variants of deleted product are also deleted', async () => {
for (const variant of productToDelete.variants) {
const { productVariant } = await adminClient.query<
GetProductVariant.Query,
GetProductVariant.Variables
>(GET_PRODUCT_VARIANT, {
id: variant.id,
});

expect(productVariant).toBe(null);
}
});

it('deleted product omitted from list', async () => {
Expand Down
18 changes: 12 additions & 6 deletions packages/core/src/service/services/product-variant.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ export class ProductVariantService {
findOne(ctx: RequestContext, productVariantId: ID): Promise<Translated<ProductVariant> | undefined> {
const relations = ['product', 'product.featuredAsset', 'taxCategory'];
return this.connection
.findOneInChannel(ctx, ProductVariant, productVariantId, ctx.channelId, { relations })
.findOneInChannel(ctx, ProductVariant, productVariantId, ctx.channelId, {
relations,
where: { deletedAt: null },
})
.then(async result => {
if (result) {
return translateDeep(await this.applyChannelPriceAndTax(result, ctx), ctx.languageCode, [
Expand Down Expand Up @@ -498,11 +501,14 @@ export class ProductVariantService {
return this.connection.getRepository(ctx, ProductVariantPrice).save(variantPrice);
}

async softDelete(ctx: RequestContext, id: ID): Promise<DeletionResponse> {
const variant = await this.connection.getEntityOrThrow(ctx, ProductVariant, id);
variant.deletedAt = new Date();
await this.connection.getRepository(ctx, ProductVariant).save(variant, { reload: false });
this.eventBus.publish(new ProductVariantEvent(ctx, [variant], 'deleted'));
async softDelete(ctx: RequestContext, id: ID | ID[]): Promise<DeletionResponse> {
const ids = Array.isArray(id) ? id : [id];
const variants = await this.connection.getRepository(ctx, ProductVariant).findByIds(ids);
for (const variant of variants) {
variant.deletedAt = new Date();
}
await this.connection.getRepository(ctx, ProductVariant).save(variants, { reload: false });
this.eventBus.publish(new ProductVariantEvent(ctx, variants, 'deleted'));
return {
result: DeletionResult.DELETED,
};
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/service/services/product.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,15 @@ export class ProductService {
async softDelete(ctx: RequestContext, productId: ID): Promise<DeletionResponse> {
const product = await this.connection.getEntityOrThrow(ctx, Product, productId, {
channelId: ctx.channelId,
relations: ['variants'],
});
product.deletedAt = new Date();
await this.connection.getRepository(ctx, Product).save(product, { reload: false });
this.eventBus.publish(new ProductEvent(ctx, product, 'deleted'));
await this.productVariantService.softDelete(
ctx,
product.variants.map(v => v.id),
);
return {
result: DeletionResult.DELETED,
};
Expand Down

0 comments on commit ff1ae90

Please sign in to comment.