Browse Source

fix(core): Correctly calculate refund amount when modifying order

Fixes #890
Michael Bromley 4 years ago
parent
commit
56d058d0fd

+ 1 - 0
packages/core/e2e/graphql/generated-e2e-shop-types.ts

@@ -2856,6 +2856,7 @@ export type TestOrderFragmentFragment = Pick<
             | 'unitPriceWithTax'
             | 'unitPriceChangeSinceAdded'
             | 'unitPriceWithTaxChangeSinceAdded'
+            | 'proratedUnitPriceWithTax'
         > & {
             productVariant: Pick<ProductVariant, 'id'>;
             discounts: Array<

+ 1 - 0
packages/core/e2e/graphql/shop-definitions.ts

@@ -31,6 +31,7 @@ export const TEST_ORDER_FRAGMENT = gql`
             unitPriceWithTax
             unitPriceChangeSinceAdded
             unitPriceWithTaxChangeSinceAdded
+            proratedUnitPriceWithTax
             productVariant {
                 id
             }

+ 67 - 3
packages/core/e2e/order-modification.e2e-spec.ts

@@ -16,6 +16,7 @@ import { initialData } from '../../../e2e-common/e2e-initial-data';
 import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
 import { manualFulfillmentHandler } from '../src/config/fulfillment/manual-fulfillment-handler';
 import { orderFixedDiscount } from '../src/config/promotion/actions/order-fixed-discount-action';
+import { defaultPromotionActions } from '../src/config/promotion/index';
 
 import {
     failsToSettlePaymentMethod,
@@ -104,9 +105,6 @@ describe('Order modification', () => {
                     testFailingPaymentMethod,
                 ],
             },
-            promotionOptions: {
-                promotionConditions: [orderFixedDiscount],
-            },
             shippingOptions: {
                 shippingCalculators: [defaultShippingCalculator, testCalculator],
             },
@@ -1443,6 +1441,72 @@ describe('Order modification', () => {
         });
     });
 
+    // https://github.com/vendure-ecommerce/vendure/issues/890
+    describe('refund handling when promotions are active on order', () => {
+        it('refunds correct amount when order-level promotion applied', async () => {
+            await adminClient.query<CreatePromotion.Mutation, CreatePromotion.Variables>(CREATE_PROMOTION, {
+                input: {
+                    name: '$5 off',
+                    couponCode: '5OFF2',
+                    enabled: true,
+                    conditions: [],
+                    actions: [
+                        {
+                            code: orderFixedDiscount.code,
+                            arguments: [{ name: 'discount', value: '500' }],
+                        },
+                    ],
+                },
+            });
+
+            await shopClient.asUserWithCredentials('trevor_donnelly96@hotmail.com', 'test');
+            await shopClient.query(gql(ADD_ITEM_TO_ORDER_WITH_CUSTOM_FIELDS), {
+                productVariantId: 'T_1',
+                quantity: 2,
+            } as any);
+            await shopClient.query<ApplyCouponCode.Mutation, ApplyCouponCode.Variables>(APPLY_COUPON_CODE, {
+                couponCode: '5OFF2',
+            });
+            await proceedToArrangingPayment(shopClient);
+            const order = await addPaymentToOrder(shopClient, testSuccessfulPaymentMethod);
+            orderGuard.assertSuccess(order);
+
+            const originalTotalWithTax = order.totalWithTax;
+
+            const { transitionOrderToState } = await adminClient.query<
+                AdminTransition.Mutation,
+                AdminTransition.Variables
+            >(ADMIN_TRANSITION_TO_STATE, {
+                id: order.id,
+                state: 'Modifying',
+            });
+            orderGuard.assertSuccess(transitionOrderToState);
+
+            expect(transitionOrderToState.state).toBe('Modifying');
+
+            const { modifyOrder } = await adminClient.query<ModifyOrder.Mutation, ModifyOrder.Variables>(
+                MODIFY_ORDER,
+                {
+                    input: {
+                        dryRun: false,
+                        orderId: order.id,
+                        adjustOrderLines: [{ orderLineId: order.lines[0].id, quantity: 1 }],
+                        refund: {
+                            paymentId: order.payments![0].id,
+                            reason: 'requested',
+                        },
+                    },
+                },
+            );
+            orderGuard.assertSuccess(modifyOrder);
+
+            expect(modifyOrder.totalWithTax).toBe(
+                originalTotalWithTax - order.lines[0].proratedUnitPriceWithTax,
+            );
+            expect(modifyOrder.payments![0].refunds![0].total).toBe(order.lines[0].proratedUnitPriceWithTax);
+        });
+    });
+
     async function assertOrderIsUnchanged(order: OrderWithLinesFragment) {
         const { order: order2 } = await adminClient.query<GetOrder.Query, GetOrder.Variables>(GET_ORDER, {
             id: order.id,

+ 1 - 1
packages/core/src/entity/order-line/order-line.entity.ts

@@ -209,7 +209,7 @@ export class OrderLine extends VendureEntity implements HasCustomFields {
      * is specified, then all adjustments are removed.
      */
     clearAdjustments(type?: AdjustmentType) {
-        this.activeItems.forEach(item => item.clearAdjustments(type));
+        this.items.forEach(item => item.clearAdjustments(type));
     }
 
     private firstActiveItemPropOr<K extends keyof OrderItem>(