Jelajahi Sumber

fix(core): Fix order modification with refund on shipping

Fixes #1197
Michael Bromley 4 tahun lalu
induk
melakukan
95bff8ffaa

+ 49 - 0
packages/core/e2e/order-modification.e2e-spec.ts

@@ -1507,6 +1507,55 @@ describe('Order modification', () => {
         });
     });
 
+    // https://github.com/vendure-ecommerce/vendure/issues/1197
+    describe('refund on shipping when change made to shippingAddress', () => {
+        let order: OrderWithModificationsFragment;
+        beforeAll(async () => {
+            const createdOrder = await createOrderAndTransitionToModifyingState([
+                {
+                    productVariantId: 'T_1',
+                    quantity: 1,
+                },
+            ]);
+            const { modifyOrder } = await adminClient.query<ModifyOrder.Mutation, ModifyOrder.Variables>(
+                MODIFY_ORDER,
+                {
+                    input: {
+                        dryRun: false,
+                        orderId: createdOrder.id,
+                        updateShippingAddress: {
+                            countryCode: 'GB',
+                        },
+                        refund: {
+                            paymentId: createdOrder.payments![0].id,
+                            reason: 'discount',
+                        },
+                    },
+                },
+            );
+            orderGuard.assertSuccess(modifyOrder);
+            order = modifyOrder;
+        });
+
+        it('creates a Refund with the correct amount', async () => {
+            expect(order.payments?.[0].refunds[0].total).toBe(SHIPPING_OTHER - SHIPPING_GB);
+        });
+
+        it('allows transition to PaymentSettled', async () => {
+            const { transitionOrderToState } = await adminClient.query<
+                AdminTransition.Mutation,
+                AdminTransition.Variables
+            >(ADMIN_TRANSITION_TO_STATE, {
+                id: order.id,
+                state: 'PaymentSettled',
+            });
+
+            orderGuard.assertSuccess(transitionOrderToState);
+
+            expect(transitionOrderToState.state).toBe('PaymentSettled');
+        });
+    });
+
     async function assertOrderIsUnchanged(order: OrderWithLinesFragment) {
         const { order: order2 } = await adminClient.query<GetOrder.Query, GetOrder.Variables>(GET_ORDER, {
             id: order.id,

+ 1 - 0
packages/core/src/service/helpers/order-calculator/order-calculator.ts

@@ -404,6 +404,7 @@ export class OrderCalculator {
             shippingLine.listPrice = cheapest.result.price;
             shippingLine.listPriceIncludesTax = cheapest.result.priceIncludesTax;
             shippingLine.shippingMethod = cheapest.method;
+            shippingLine.shippingMethodId = cheapest.method.id;
             shippingLine.taxLines = [
                 {
                     description: 'shipping tax',

+ 5 - 0
packages/core/src/service/helpers/order-modifier/order-modifier.ts

@@ -224,6 +224,7 @@ export class OrderModifier {
             surcharges: [],
         });
         const initialTotalWithTax = order.totalWithTax;
+        const initialShippingWithTax = order.shippingWithTax;
         if (order.state !== 'Modifying') {
             return new OrderModificationStateError();
         }
@@ -408,6 +409,10 @@ export class OrderModifier {
             if (!input.refund) {
                 return new RefundPaymentIdMissingError();
             }
+            const shippingDelta = order.shippingWithTax - initialShippingWithTax;
+            if (shippingDelta < 0) {
+                refundInput.shipping = shippingDelta * -1;
+            }
             const existingPayments = await this.getOrderPayments(ctx, order.id);
             const payment = existingPayments.find(p => idsAreEqual(p.id, input.refund?.paymentId));
             if (payment) {