Ver código fonte

fix(core): Allow loading of Order with deleted ShippingMethod

Fixes #716
Michael Bromley 4 anos atrás
pai
commit
7ba27f28ca

+ 2 - 0
packages/core/e2e/graphql/fragments.ts

@@ -408,9 +408,11 @@ export const ORDER_WITH_LINES_FRAGMENT = gql`
         shipping
         shippingWithTax
         shippingLines {
+            priceWithTax
             shippingMethod {
                 id
                 code
+                name
                 description
             }
         }

+ 19 - 15
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -5190,7 +5190,11 @@ export type OrderWithLinesFragment = Pick<
         }
     >;
     surcharges: Array<Pick<Surcharge, 'id' | 'description' | 'sku' | 'price' | 'priceWithTax'>>;
-    shippingLines: Array<{ shippingMethod: Pick<ShippingMethod, 'id' | 'code' | 'description'> }>;
+    shippingLines: Array<
+        Pick<ShippingLine, 'priceWithTax'> & {
+            shippingMethod: Pick<ShippingMethod, 'id' | 'code' | 'name' | 'description'>;
+        }
+    >;
     shippingAddress?: Maybe<ShippingAddressFragment>;
     payments?: Maybe<Array<PaymentFragment>>;
 };
@@ -5901,6 +5905,14 @@ export type CreateAssetsMutation = {
     >;
 };
 
+export type DeleteShippingMethodMutationVariables = Exact<{
+    id: Scalars['ID'];
+}>;
+
+export type DeleteShippingMethodMutation = {
+    deleteShippingMethod: Pick<DeletionResponse, 'result' | 'message'>;
+};
+
 export type CancelJobMutationVariables = Exact<{
     id: Scalars['ID'];
 }>;
@@ -6282,14 +6294,6 @@ export type GetShippingMethodQueryVariables = Exact<{
 
 export type GetShippingMethodQuery = { shippingMethod?: Maybe<ShippingMethodFragment> };
 
-export type DeleteShippingMethodMutationVariables = Exact<{
-    id: Scalars['ID'];
-}>;
-
-export type DeleteShippingMethodMutation = {
-    deleteShippingMethod: Pick<DeletionResponse, 'result' | 'message'>;
-};
-
 export type GetEligibilityCheckersQueryVariables = Exact<{ [key: string]: never }>;
 
 export type GetEligibilityCheckersQuery = {
@@ -8048,6 +8052,12 @@ export namespace CreateAssets {
     >;
 }
 
+export namespace DeleteShippingMethod {
+    export type Variables = DeleteShippingMethodMutationVariables;
+    export type Mutation = DeleteShippingMethodMutation;
+    export type DeleteShippingMethod = NonNullable<DeleteShippingMethodMutation['deleteShippingMethod']>;
+}
+
 export namespace CancelJob {
     export type Variables = CancelJobMutationVariables;
     export type Mutation = CancelJobMutation;
@@ -8468,12 +8478,6 @@ export namespace GetShippingMethod {
     export type ShippingMethod = NonNullable<GetShippingMethodQuery['shippingMethod']>;
 }
 
-export namespace DeleteShippingMethod {
-    export type Variables = DeleteShippingMethodMutationVariables;
-    export type Mutation = DeleteShippingMethodMutation;
-    export type DeleteShippingMethod = NonNullable<DeleteShippingMethodMutation['deleteShippingMethod']>;
-}
-
 export namespace GetEligibilityCheckers {
     export type Variables = GetEligibilityCheckersQueryVariables;
     export type Query = GetEligibilityCheckersQuery;

+ 9 - 0
packages/core/e2e/graphql/shared-definitions.ts

@@ -871,3 +871,12 @@ export const CREATE_ASSETS = gql`
     }
     ${ASSET_FRAGMENT}
 `;
+
+export const DELETE_SHIPPING_METHOD = gql`
+    mutation DeleteShippingMethod($id: ID!) {
+        deleteShippingMethod(id: $id) {
+            result
+            message
+        }
+    }
+`;

+ 78 - 1
packages/core/e2e/order.e2e-spec.ts

@@ -1,6 +1,10 @@
 /* tslint:disable:no-non-null-assertion */
 import { pick } from '@vendure/common/lib/pick';
-import { manualFulfillmentHandler } from '@vendure/core';
+import {
+    defaultShippingCalculator,
+    defaultShippingEligibilityChecker,
+    manualFulfillmentHandler,
+} from '@vendure/core';
 import {
     createErrorResultGuard,
     createTestEnvironment,
@@ -25,7 +29,9 @@ import {
     CanceledOrderFragment,
     CancelOrder,
     CreateFulfillment,
+    CreateShippingMethod,
     DeleteOrderNote,
+    DeleteShippingMethod,
     ErrorCode,
     FulfillmentFragment,
     GetCustomerList,
@@ -41,6 +47,7 @@ import {
     GetStockMovement,
     GlobalFlag,
     HistoryEntryType,
+    LanguageCode,
     OrderLineInput,
     PaymentFragment,
     RefundFragment,
@@ -59,6 +66,8 @@ import {
     DeletionResult,
     GetActiveOrder,
     GetOrderByCodeWithPayments,
+    SetShippingAddress,
+    SetShippingMethod,
     TestOrderFragmentFragment,
     UpdatedOrder,
     UpdatedOrderFragment,
@@ -66,6 +75,8 @@ import {
 import {
     CANCEL_ORDER,
     CREATE_FULFILLMENT,
+    CREATE_SHIPPING_METHOD,
+    DELETE_SHIPPING_METHOD,
     GET_CUSTOMER_LIST,
     GET_ORDER,
     GET_ORDERS_LIST,
@@ -82,6 +93,8 @@ import {
     APPLY_COUPON_CODE,
     GET_ACTIVE_ORDER,
     GET_ORDER_BY_CODE_WITH_PAYMENTS,
+    SET_SHIPPING_ADDRESS,
+    SET_SHIPPING_METHOD,
 } from './graphql/shop-definitions';
 import { assertThrowsWithMessage } from './utils/assert-throws-with-message';
 import { addPaymentToOrder, proceedToArrangingPayment, sortById } from './utils/test-order-utils';
@@ -1744,6 +1757,70 @@ describe('Orders resolver', () => {
             expect(orders.items[0].totalQuantity).toBe(2);
             expect(orders.items[0].lines[0].quantity).toBe(2);
         });
+
+        // https://github.com/vendure-ecommerce/vendure/issues/716
+        it('get an Order with a deleted ShippingMethod', async () => {
+            const { createShippingMethod: shippingMethod } = await adminClient.query<
+                CreateShippingMethod.Mutation,
+                CreateShippingMethod.Variables
+            >(CREATE_SHIPPING_METHOD, {
+                input: {
+                    code: 'royal-mail',
+                    translations: [{ languageCode: LanguageCode.en, name: 'Royal Mail', description: '' }],
+                    fulfillmentHandler: manualFulfillmentHandler.code,
+                    checker: {
+                        code: defaultShippingEligibilityChecker.code,
+                        arguments: [{ name: 'orderMinimum', value: '0' }],
+                    },
+                    calculator: {
+                        code: defaultShippingCalculator.code,
+                        arguments: [
+                            { name: 'rate', value: '500' },
+                            { name: 'taxRate', value: '0' },
+                        ],
+                    },
+                },
+            });
+            await shopClient.asUserWithCredentials(customers[0].emailAddress, password);
+            await shopClient.query<AddItemToOrder.Mutation, AddItemToOrder.Variables>(ADD_ITEM_TO_ORDER, {
+                productVariantId: 'T_1',
+                quantity: 2,
+            });
+            await shopClient.query<SetShippingAddress.Mutation, SetShippingAddress.Variables>(
+                SET_SHIPPING_ADDRESS,
+                {
+                    input: {
+                        fullName: 'name',
+                        streetLine1: '12 the street',
+                        city: 'foo',
+                        postalCode: '123456',
+                        countryCode: 'US',
+                    },
+                },
+            );
+            const { setOrderShippingMethod: order } = await shopClient.query<
+                SetShippingMethod.Mutation,
+                SetShippingMethod.Variables
+            >(SET_SHIPPING_METHOD, {
+                id: shippingMethod.id,
+            });
+            orderGuard.assertSuccess(order);
+
+            await adminClient.query<DeleteShippingMethod.Mutation, DeleteShippingMethod.Variables>(
+                DELETE_SHIPPING_METHOD,
+                {
+                    id: shippingMethod.id,
+                },
+            );
+
+            const { order: order2 } = await adminClient.query<GetOrder.Query, GetOrder.Variables>(GET_ORDER, {
+                id: order.id,
+            });
+            expect(order2?.shippingLines[0]).toEqual({
+                priceWithTax: 500,
+                shippingMethod: pick(shippingMethod, ['id', 'name', 'code', 'description']),
+            });
+        });
     });
 });
 

+ 5 - 10
packages/core/e2e/shipping-method.e2e-spec.ts

@@ -26,7 +26,11 @@ import {
     TestShippingMethod,
     UpdateShippingMethod,
 } from './graphql/generated-e2e-admin-types';
-import { CREATE_SHIPPING_METHOD, UPDATE_SHIPPING_METHOD } from './graphql/shared-definitions';
+import {
+    CREATE_SHIPPING_METHOD,
+    DELETE_SHIPPING_METHOD,
+    UPDATE_SHIPPING_METHOD,
+} from './graphql/shared-definitions';
 
 const TEST_METADATA = {
     foo: 'bar',
@@ -356,15 +360,6 @@ const GET_SHIPPING_METHOD = gql`
     ${SHIPPING_METHOD_FRAGMENT}
 `;
 
-const DELETE_SHIPPING_METHOD = gql`
-    mutation DeleteShippingMethod($id: ID!) {
-        deleteShippingMethod(id: $id) {
-            result
-            message
-        }
-    }
-`;
-
 const GET_ELIGIBILITY_CHECKERS = gql`
     query GetEligibilityCheckers {
         shippingEligibilityCheckers {

+ 1 - 1
packages/core/src/api/resolvers/entity/shipping-line-entity.resolver.ts

@@ -15,7 +15,7 @@ export class ShippingLineEntityResolver {
             // Does not need to be decoded because it is an internal property
             // which is never exposed to the outside world.
             const shippingMethodId = shippingLine.shippingMethodId;
-            return this.shippingMethodService.findOne(ctx, shippingMethodId);
+            return this.shippingMethodService.findOne(ctx, shippingMethodId, true);
         } else {
             return null;
         }

+ 6 - 2
packages/core/src/service/services/shipping-method.service.ts

@@ -68,7 +68,11 @@ export class ShippingMethodService {
             }));
     }
 
-    async findOne(ctx: RequestContext, shippingMethodId: ID): Promise<ShippingMethod | undefined> {
+    async findOne(
+        ctx: RequestContext,
+        shippingMethodId: ID,
+        includeDeleted = false,
+    ): Promise<ShippingMethod | undefined> {
         const shippingMethod = await this.connection.findOneInChannel(
             ctx,
             ShippingMethod,
@@ -76,7 +80,7 @@ export class ShippingMethodService {
             ctx.channelId,
             {
                 relations: ['channels'],
-                where: { deletedAt: null },
+                ...(includeDeleted === false ? { where: { deletedAt: null } } : {}),
             },
         );
         return shippingMethod && translateDeep(shippingMethod, ctx.languageCode);