Skip to content

Commit

Permalink
fix(core): Remove inapplicable order-level discounts
Browse files Browse the repository at this point in the history
Fixes #710
  • Loading branch information
michaelbromley committed Feb 17, 2021
1 parent 950582e commit 2396cc3
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 1 deletion.
50 changes: 50 additions & 0 deletions packages/core/e2e/order-promotion.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
GetActiveOrder,
GetOrderPromotionsByCode,
RemoveCouponCode,
RemoveItemFromOrder,
SetCustomerForOrder,
SetShippingMethod,
TestOrderFragmentFragment,
Expand All @@ -76,6 +77,7 @@ import {
GET_ACTIVE_ORDER,
GET_ORDER_PROMOTIONS_BY_CODE,
REMOVE_COUPON_CODE,
REMOVE_ITEM_FROM_ORDER,
SET_CUSTOMER,
SET_SHIPPING_METHOD,
} from './graphql/shop-definitions';
Expand Down Expand Up @@ -1387,6 +1389,54 @@ describe('Promotions applied to Orders', () => {
});
});

// https://github.com/vendure-ecommerce/vendure/issues/710
it('removes order-level discount made invalid by removing OrderLine', async () => {
const promotion = await createPromotion({
enabled: true,
name: 'Test Promo',
conditions: [minOrderAmountCondition(10000)],
actions: [
{
code: orderFixedDiscount.code,
arguments: [{ name: 'discount', value: '1000' }],
},
],
});

await shopClient.asAnonymousUser();
await shopClient.query<AddItemToOrder.Mutation, AddItemToOrder.Variables>(ADD_ITEM_TO_ORDER, {
productVariantId: getVariantBySlug('item-1000').id,
quantity: 8,
});
const { addItemToOrder } = await shopClient.query<AddItemToOrder.Mutation, AddItemToOrder.Variables>(
ADD_ITEM_TO_ORDER,
{
productVariantId: getVariantBySlug('item-5000').id,
quantity: 1,
},
);
orderResultGuard.assertSuccess(addItemToOrder);
expect(addItemToOrder!.discounts.length).toBe(1);
expect(addItemToOrder!.discounts[0].description).toBe('Test Promo');

const { activeOrder: check1 } = await shopClient.query<GetActiveOrder.Query>(GET_ACTIVE_ORDER);
expect(check1!.discounts.length).toBe(1);
expect(check1!.discounts[0].description).toBe('Test Promo');

const { removeOrderLine } = await shopClient.query<
RemoveItemFromOrder.Mutation,
RemoveItemFromOrder.Variables
>(REMOVE_ITEM_FROM_ORDER, {
orderLineId: addItemToOrder.lines[1].id,
});

orderResultGuard.assertSuccess(removeOrderLine);
expect(removeOrderLine.discounts.length).toBe(0);

const { activeOrder: check2 } = await shopClient.query<GetActiveOrder.Query>(GET_ACTIVE_ORDER);
expect(check2!.discounts.length).toBe(0);
});

async function getProducts() {
const result = await adminClient.query<GetProductsWithVariantPrices.Query>(
GET_PRODUCTS_WITH_VARIANT_PRICES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,20 @@ export class OrderCalculator {
promotions: Promotion[],
): Promise<OrderItem[]> {
const updatedItems = new Set<OrderItem>();
order.lines.forEach(line => line.clearAdjustments(AdjustmentType.DISTRIBUTED_ORDER_PROMOTION));
const orderHasDistributedPromotions = !!order.discounts.find(
adjustment => adjustment.type === AdjustmentType.DISTRIBUTED_ORDER_PROMOTION,
);
if (orderHasDistributedPromotions) {
// If the Order currently has any Order-level discounts applied, we need to
// mark all OrderItems in the Order as "updated", since one or more of those
// Order-level discounts may become invalid, which will require _all_ OrderItems
// to be saved.
order.lines.forEach(line => {
line.clearAdjustments(AdjustmentType.DISTRIBUTED_ORDER_PROMOTION);
line.items.forEach(item => updatedItems.add(item));
});
}

this.calculateOrderTotals(order);
const applicableOrderPromotions = await filterAsync(promotions, p => p.test(ctx, order));
if (applicableOrderPromotions.length) {
Expand Down

0 comments on commit 2396cc3

Please sign in to comment.