From 28aeddbb0d9f1959a3d1010d1e4e298eea164e9e Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Tue, 14 Dec 2021 11:24:20 +0100 Subject: [PATCH] fix(core): Fix FK error with adjustOrderLine when zero saleable stock Fixes #1273 --- packages/core/e2e/stock-control.e2e-spec.ts | 64 +++++++++++++++++++ .../src/service/services/order.service.ts | 4 +- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/packages/core/e2e/stock-control.e2e-spec.ts b/packages/core/e2e/stock-control.e2e-spec.ts index aa5625d893..411544beae 100644 --- a/packages/core/e2e/stock-control.e2e-spec.ts +++ b/packages/core/e2e/stock-control.e2e-spec.ts @@ -31,7 +31,9 @@ import { import { AddItemToOrder, AddPaymentToOrder, + AdjustItemQuantity, ErrorCode, + GetActiveOrder, GetProductStockLevel, GetShippingMethods, PaymentInput, @@ -54,6 +56,8 @@ import { import { ADD_ITEM_TO_ORDER, ADD_PAYMENT, + ADJUST_ITEM_QUANTITY, + GET_ACTIVE_ORDER, GET_ELIGIBLE_SHIPPING_METHODS, GET_PRODUCT_WITH_STOCK_LEVEL, SET_SHIPPING_ADDRESS, @@ -941,6 +945,7 @@ describe('Stock control', () => { describe('edge cases', () => { const variant5Id = 'T_5'; const variant6Id = 'T_6'; + const variant7Id = 'T_7'; beforeAll(async () => { // First place an order which creates a backorder (excess of allocated units) @@ -962,6 +967,13 @@ describe('Stock control', () => { trackInventory: GlobalFlag.TRUE, useGlobalOutOfStockThreshold: false, }, + { + id: variant7Id, + stockOnHand: 3, + outOfStockThreshold: 0, + trackInventory: GlobalFlag.TRUE, + useGlobalOutOfStockThreshold: false, + }, ], }, ); @@ -1055,6 +1067,58 @@ describe('Stock control', () => { expect((add2 as any).order.lines[0].productVariant.id).toBe(variant6Id); expect((add2 as any).order.lines[0].quantity).toBe(3); }); + + // https://github.com/vendure-ecommerce/vendure/issues/1273 + it('adjustOrderLine when saleable stock changes to zero', async () => { + await adminClient.query( + UPDATE_PRODUCT_VARIANTS, + { + input: [ + { + id: variant7Id, + stockOnHand: 10, + }, + ], + }, + ); + + await shopClient.asAnonymousUser(); + const { addItemToOrder: add1 } = await shopClient.query< + AddItemToOrder.Mutation, + AddItemToOrder.Variables + >(ADD_ITEM_TO_ORDER, { + productVariantId: variant7Id, + quantity: 1, + }); + orderGuard.assertSuccess(add1); + expect(add1.lines.length).toBe(1); + + await adminClient.query( + UPDATE_PRODUCT_VARIANTS, + { + input: [ + { + id: variant7Id, + stockOnHand: 0, + }, + ], + }, + ); + + const { adjustOrderLine: add2 } = await shopClient.query< + AdjustItemQuantity.Mutation, + AdjustItemQuantity.Variables + >(ADJUST_ITEM_QUANTITY, { + orderLineId: add1.lines[0].id, + quantity: 2, + }); + orderGuard.assertErrorResult(add2); + + expect(add2.errorCode).toBe(ErrorCode.INSUFFICIENT_STOCK_ERROR); + + const { activeOrder } = await shopClient.query(GET_ACTIVE_ORDER); + expect(activeOrder!.lines.length).toBe(0); + }); }); }); diff --git a/packages/core/src/service/services/order.service.ts b/packages/core/src/service/services/order.service.ts index efd09ab7dc..4d5bd2615d 100644 --- a/packages/core/src/service/services/order.service.ts +++ b/packages/core/src/service/services/order.service.ts @@ -505,14 +505,16 @@ export class OrderService { orderLine.productVariant, quantity, ); + let updatedOrderLines = [orderLine]; if (correctedQuantity === 0) { order.lines = order.lines.filter(l => !idsAreEqual(l.id, orderLine.id)); await this.connection.getRepository(ctx, OrderLine).remove(orderLine); + updatedOrderLines = []; } else { await this.orderModifier.updateOrderLineQuantity(ctx, orderLine, correctedQuantity, order); } const quantityWasAdjustedDown = correctedQuantity < quantity; - const updatedOrder = await this.applyPriceAdjustments(ctx, order, [orderLine]); + const updatedOrder = await this.applyPriceAdjustments(ctx, order, updatedOrderLines); if (quantityWasAdjustedDown) { return new InsufficientStockError(correctedQuantity, updatedOrder); } else {