Browse Source

fix(core): Fix foreign key error on merging orders

Fixes #754
Michael Bromley 4 years ago
parent
commit
5e385df475

+ 254 - 187
packages/admin-ui/src/lib/core/src/common/introspection-result.ts

@@ -1,190 +1,257 @@
 // tslint:disable
 
-export interface PossibleTypesResultData {
-    possibleTypes: {
-        [key: string]: string[];
-    };
-}
-const result: PossibleTypesResultData = {
-    possibleTypes: {
-        CreateAssetResult: ['Asset', 'MimeTypeError'],
-        NativeAuthenticationResult: ['CurrentUser', 'InvalidCredentialsError', 'NativeAuthStrategyError'],
-        AuthenticationResult: ['CurrentUser', 'InvalidCredentialsError'],
-        CreateChannelResult: ['Channel', 'LanguageNotAvailableError'],
-        UpdateChannelResult: ['Channel', 'LanguageNotAvailableError'],
-        CreateCustomerResult: ['Customer', 'EmailAddressConflictError'],
-        UpdateCustomerResult: ['Customer', 'EmailAddressConflictError'],
-        UpdateGlobalSettingsResult: ['GlobalSettings', 'ChannelDefaultLanguageError'],
-        TransitionOrderToStateResult: ['Order', 'OrderStateTransitionError'],
-        SettlePaymentResult: [
-            'Payment',
-            'SettlePaymentError',
-            'PaymentStateTransitionError',
-            'OrderStateTransitionError',
-        ],
-        AddFulfillmentToOrderResult: [
-            'Fulfillment',
-            'EmptyOrderLineSelectionError',
-            'ItemsAlreadyFulfilledError',
-            'InsufficientStockOnHandError',
-            'InvalidFulfillmentHandlerError',
-            'FulfillmentStateTransitionError',
-            'CreateFulfillmentError',
-        ],
-        CancelOrderResult: [
-            'Order',
-            'EmptyOrderLineSelectionError',
-            'QuantityTooGreatError',
-            'MultipleOrderError',
-            'CancelActiveOrderError',
-            'OrderStateTransitionError',
-        ],
-        RefundOrderResult: [
-            'Refund',
-            'QuantityTooGreatError',
-            'NothingToRefundError',
-            'OrderStateTransitionError',
-            'MultipleOrderError',
-            'PaymentOrderMismatchError',
-            'RefundOrderStateError',
-            'AlreadyRefundedError',
-            'RefundStateTransitionError',
-        ],
-        SettleRefundResult: ['Refund', 'RefundStateTransitionError'],
-        TransitionFulfillmentToStateResult: ['Fulfillment', 'FulfillmentStateTransitionError'],
-        TransitionPaymentToStateResult: ['Payment', 'PaymentStateTransitionError'],
-        ModifyOrderResult: [
-            'Order',
-            'NoChangesSpecifiedError',
-            'OrderModificationStateError',
-            'PaymentMethodMissingError',
-            'RefundPaymentIdMissingError',
-            'OrderLimitError',
-            'NegativeQuantityError',
-            'InsufficientStockError',
-        ],
-        AddManualPaymentToOrderResult: ['Order', 'ManualPaymentStateError'],
-        RemoveOptionGroupFromProductResult: ['Product', 'ProductOptionInUseError'],
-        CreatePromotionResult: ['Promotion', 'MissingConditionsError'],
-        UpdatePromotionResult: ['Promotion', 'MissingConditionsError'],
-        StockMovement: ['StockAdjustment', 'Allocation', 'Sale', 'Cancellation', 'Return', 'Release'],
-        StockMovementItem: ['StockAdjustment', 'Allocation', 'Sale', 'Cancellation', 'Return', 'Release'],
-        PaginatedList: [
-            'AdministratorList',
-            'CustomerGroupList',
-            'JobList',
-            'PaymentMethodList',
-            'AssetList',
-            'CollectionList',
-            'ProductVariantList',
-            'CountryList',
-            'CustomerList',
-            'FacetList',
-            'HistoryEntryList',
-            'OrderList',
-            'ProductList',
-            'PromotionList',
-            'RoleList',
-            'ShippingMethodList',
-            'TagList',
-            'TaxRateList',
-        ],
-        Node: [
-            'Administrator',
-            'Asset',
-            'Collection',
-            'Customer',
-            'Facet',
-            'HistoryEntry',
-            'Job',
-            'Order',
-            'Fulfillment',
-            'Payment',
-            'OrderModification',
-            'PaymentMethod',
-            'Product',
-            'ProductVariant',
-            'StockAdjustment',
-            'Allocation',
-            'Sale',
-            'Cancellation',
-            'Return',
-            'Release',
-            'Address',
-            'Channel',
-            'Country',
-            'CustomerGroup',
-            'FacetValue',
-            'OrderItem',
-            'OrderLine',
-            'Refund',
-            'Surcharge',
-            'ProductOptionGroup',
-            'ProductOption',
-            'Promotion',
-            'Role',
-            'ShippingMethod',
-            'Tag',
-            'TaxCategory',
-            'TaxRate',
-            'User',
-            'AuthenticationMethod',
-            'Zone',
-        ],
-        ErrorResult: [
-            'MimeTypeError',
-            'LanguageNotAvailableError',
-            'ChannelDefaultLanguageError',
-            'SettlePaymentError',
-            'EmptyOrderLineSelectionError',
-            'ItemsAlreadyFulfilledError',
-            'InvalidFulfillmentHandlerError',
-            'CreateFulfillmentError',
-            'InsufficientStockOnHandError',
-            'MultipleOrderError',
-            'CancelActiveOrderError',
-            'PaymentOrderMismatchError',
-            'RefundOrderStateError',
-            'NothingToRefundError',
-            'AlreadyRefundedError',
-            'QuantityTooGreatError',
-            'RefundStateTransitionError',
-            'PaymentStateTransitionError',
-            'FulfillmentStateTransitionError',
-            'OrderModificationStateError',
-            'NoChangesSpecifiedError',
-            'PaymentMethodMissingError',
-            'RefundPaymentIdMissingError',
-            'ManualPaymentStateError',
-            'ProductOptionInUseError',
-            'MissingConditionsError',
-            'NativeAuthStrategyError',
-            'InvalidCredentialsError',
-            'OrderStateTransitionError',
-            'EmailAddressConflictError',
-            'OrderLimitError',
-            'NegativeQuantityError',
-            'InsufficientStockError',
-        ],
-        CustomField: [
-            'StringCustomFieldConfig',
-            'LocaleStringCustomFieldConfig',
-            'IntCustomFieldConfig',
-            'FloatCustomFieldConfig',
-            'BooleanCustomFieldConfig',
-            'DateTimeCustomFieldConfig',
-            'RelationCustomFieldConfig',
-        ],
-        CustomFieldConfig: [
-            'StringCustomFieldConfig',
-            'LocaleStringCustomFieldConfig',
-            'IntCustomFieldConfig',
-            'FloatCustomFieldConfig',
-            'BooleanCustomFieldConfig',
-            'DateTimeCustomFieldConfig',
-            'RelationCustomFieldConfig',
-        ],
-        SearchResultPrice: ['PriceRange', 'SinglePrice'],
-    },
+      export interface PossibleTypesResultData {
+        possibleTypes: {
+          [key: string]: string[]
+        }
+      }
+      const result: PossibleTypesResultData = {
+  "possibleTypes": {
+    "CreateAssetResult": [
+      "Asset",
+      "MimeTypeError"
+    ],
+    "NativeAuthenticationResult": [
+      "CurrentUser",
+      "InvalidCredentialsError",
+      "NativeAuthStrategyError"
+    ],
+    "AuthenticationResult": [
+      "CurrentUser",
+      "InvalidCredentialsError"
+    ],
+    "CreateChannelResult": [
+      "Channel",
+      "LanguageNotAvailableError"
+    ],
+    "UpdateChannelResult": [
+      "Channel",
+      "LanguageNotAvailableError"
+    ],
+    "CreateCustomerResult": [
+      "Customer",
+      "EmailAddressConflictError"
+    ],
+    "UpdateCustomerResult": [
+      "Customer",
+      "EmailAddressConflictError"
+    ],
+    "UpdateGlobalSettingsResult": [
+      "GlobalSettings",
+      "ChannelDefaultLanguageError"
+    ],
+    "TransitionOrderToStateResult": [
+      "Order",
+      "OrderStateTransitionError"
+    ],
+    "SettlePaymentResult": [
+      "Payment",
+      "SettlePaymentError",
+      "PaymentStateTransitionError",
+      "OrderStateTransitionError"
+    ],
+    "AddFulfillmentToOrderResult": [
+      "Fulfillment",
+      "EmptyOrderLineSelectionError",
+      "ItemsAlreadyFulfilledError",
+      "InsufficientStockOnHandError",
+      "InvalidFulfillmentHandlerError",
+      "FulfillmentStateTransitionError",
+      "CreateFulfillmentError"
+    ],
+    "CancelOrderResult": [
+      "Order",
+      "EmptyOrderLineSelectionError",
+      "QuantityTooGreatError",
+      "MultipleOrderError",
+      "CancelActiveOrderError",
+      "OrderStateTransitionError"
+    ],
+    "RefundOrderResult": [
+      "Refund",
+      "QuantityTooGreatError",
+      "NothingToRefundError",
+      "OrderStateTransitionError",
+      "MultipleOrderError",
+      "PaymentOrderMismatchError",
+      "RefundOrderStateError",
+      "AlreadyRefundedError",
+      "RefundStateTransitionError"
+    ],
+    "SettleRefundResult": [
+      "Refund",
+      "RefundStateTransitionError"
+    ],
+    "TransitionFulfillmentToStateResult": [
+      "Fulfillment",
+      "FulfillmentStateTransitionError"
+    ],
+    "TransitionPaymentToStateResult": [
+      "Payment",
+      "PaymentStateTransitionError"
+    ],
+    "ModifyOrderResult": [
+      "Order",
+      "NoChangesSpecifiedError",
+      "OrderModificationStateError",
+      "PaymentMethodMissingError",
+      "RefundPaymentIdMissingError",
+      "OrderLimitError",
+      "NegativeQuantityError",
+      "InsufficientStockError"
+    ],
+    "AddManualPaymentToOrderResult": [
+      "Order",
+      "ManualPaymentStateError"
+    ],
+    "RemoveOptionGroupFromProductResult": [
+      "Product",
+      "ProductOptionInUseError"
+    ],
+    "CreatePromotionResult": [
+      "Promotion",
+      "MissingConditionsError"
+    ],
+    "UpdatePromotionResult": [
+      "Promotion",
+      "MissingConditionsError"
+    ],
+    "StockMovement": [
+      "StockAdjustment",
+      "Allocation",
+      "Sale",
+      "Cancellation",
+      "Return",
+      "Release"
+    ],
+    "StockMovementItem": [
+      "StockAdjustment",
+      "Allocation",
+      "Sale",
+      "Cancellation",
+      "Return",
+      "Release"
+    ],
+    "PaginatedList": [
+      "AdministratorList",
+      "CustomerGroupList",
+      "JobList",
+      "PaymentMethodList",
+      "AssetList",
+      "CollectionList",
+      "ProductVariantList",
+      "CountryList",
+      "CustomerList",
+      "FacetList",
+      "HistoryEntryList",
+      "OrderList",
+      "ProductList",
+      "PromotionList",
+      "RoleList",
+      "ShippingMethodList",
+      "TagList",
+      "TaxRateList"
+    ],
+    "Node": [
+      "Administrator",
+      "Asset",
+      "Collection",
+      "Customer",
+      "Facet",
+      "HistoryEntry",
+      "Job",
+      "Order",
+      "Fulfillment",
+      "Payment",
+      "OrderModification",
+      "PaymentMethod",
+      "Product",
+      "ProductVariant",
+      "StockAdjustment",
+      "Allocation",
+      "Sale",
+      "Cancellation",
+      "Return",
+      "Release",
+      "Address",
+      "Channel",
+      "Country",
+      "CustomerGroup",
+      "FacetValue",
+      "OrderItem",
+      "OrderLine",
+      "Refund",
+      "Surcharge",
+      "ProductOptionGroup",
+      "ProductOption",
+      "Promotion",
+      "Role",
+      "ShippingMethod",
+      "Tag",
+      "TaxCategory",
+      "TaxRate",
+      "User",
+      "AuthenticationMethod",
+      "Zone"
+    ],
+    "ErrorResult": [
+      "MimeTypeError",
+      "LanguageNotAvailableError",
+      "ChannelDefaultLanguageError",
+      "SettlePaymentError",
+      "EmptyOrderLineSelectionError",
+      "ItemsAlreadyFulfilledError",
+      "InvalidFulfillmentHandlerError",
+      "CreateFulfillmentError",
+      "InsufficientStockOnHandError",
+      "MultipleOrderError",
+      "CancelActiveOrderError",
+      "PaymentOrderMismatchError",
+      "RefundOrderStateError",
+      "NothingToRefundError",
+      "AlreadyRefundedError",
+      "QuantityTooGreatError",
+      "RefundStateTransitionError",
+      "PaymentStateTransitionError",
+      "FulfillmentStateTransitionError",
+      "OrderModificationStateError",
+      "NoChangesSpecifiedError",
+      "PaymentMethodMissingError",
+      "RefundPaymentIdMissingError",
+      "ManualPaymentStateError",
+      "ProductOptionInUseError",
+      "MissingConditionsError",
+      "NativeAuthStrategyError",
+      "InvalidCredentialsError",
+      "OrderStateTransitionError",
+      "EmailAddressConflictError",
+      "OrderLimitError",
+      "NegativeQuantityError",
+      "InsufficientStockError"
+    ],
+    "CustomField": [
+      "StringCustomFieldConfig",
+      "LocaleStringCustomFieldConfig",
+      "IntCustomFieldConfig",
+      "FloatCustomFieldConfig",
+      "BooleanCustomFieldConfig",
+      "DateTimeCustomFieldConfig",
+      "RelationCustomFieldConfig"
+    ],
+    "CustomFieldConfig": [
+      "StringCustomFieldConfig",
+      "LocaleStringCustomFieldConfig",
+      "IntCustomFieldConfig",
+      "FloatCustomFieldConfig",
+      "BooleanCustomFieldConfig",
+      "DateTimeCustomFieldConfig",
+      "RelationCustomFieldConfig"
+    ],
+    "SearchResultPrice": [
+      "PriceRange",
+      "SinglePrice"
+    ]
+  }
 };
-export default result;
+      export default result;
+    

File diff suppressed because it is too large
+ 646 - 502
packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts


File diff suppressed because it is too large
+ 579 - 542
packages/common/src/generated-shop-types.ts


File diff suppressed because it is too large
+ 646 - 502
packages/core/e2e/graphql/generated-e2e-admin-types.ts


File diff suppressed because it is too large
+ 545 - 508
packages/core/e2e/graphql/generated-e2e-shop-types.ts


+ 59 - 0
packages/core/e2e/shop-order.e2e-spec.ts

@@ -1239,6 +1239,57 @@ describe('Shop orders', () => {
             expect(activeOrder!.lines[0].productVariant.id).toBe('T_1');
             expect(activeOrder!.lines[1].productVariant.id).toBe('T_2');
         });
+
+        // https://github.com/vendure-ecommerce/vendure/issues/754
+        it('handles merging when an existing order has OrderLines', async () => {
+            async function setShippingOnActiveOrder() {
+                await shopClient.query<SetShippingAddress.Mutation, SetShippingAddress.Variables>(
+                    SET_SHIPPING_ADDRESS,
+                    {
+                        input: {
+                            streetLine1: '12 the street',
+                            countryCode: 'US',
+                        },
+                    },
+                );
+                const { eligibleShippingMethods } = await shopClient.query<GetShippingMethods.Query>(
+                    GET_ELIGIBLE_SHIPPING_METHODS,
+                );
+                await shopClient.query<SetShippingMethod.Mutation, SetShippingMethod.Variables>(
+                    SET_SHIPPING_METHOD,
+                    {
+                        id: eligibleShippingMethods[1].id,
+                    },
+                );
+            }
+
+            // Set up an existing order and add a ShippingLine
+            await shopClient.asUserWithCredentials(customers[2].emailAddress, 'test');
+            await shopClient.query<AddItemToOrder.Mutation, AddItemToOrder.Variables>(ADD_ITEM_TO_ORDER, {
+                productVariantId: 'T_3',
+                quantity: 1,
+            });
+            await setShippingOnActiveOrder();
+
+            // Now start a new guest order
+            await shopClient.query(LOG_OUT);
+            await shopClient.query<AddItemToOrder.Mutation, AddItemToOrder.Variables>(ADD_ITEM_TO_ORDER, {
+                productVariantId: 'T_4',
+                quantity: 1,
+            });
+            await setShippingOnActiveOrder();
+
+            // attempt to log in and merge the guest order with the existing order
+            const { login } = await shopClient.query<AttemptLogin.Mutation, AttemptLogin.Variables>(
+                ATTEMPT_LOGIN,
+                {
+                    username: customers[2].emailAddress,
+                    password: 'test',
+                },
+            );
+
+            expect(login.identifier).toBe(customers[2].emailAddress);
+        });
     });
 
     describe('security of customer data', () => {
@@ -1444,3 +1495,11 @@ export const ADD_ITEM_TO_ORDER_WITH_CUSTOM_FIELDS = gql`
     }
     ${UPDATED_ORDER_FRAGMENT}
 `;
+
+export const LOG_OUT = gql`
+    mutation LogOut {
+        logout {
+            success
+        }
+    }
+`;

+ 1 - 0
packages/core/src/entity/shipping-line/shipping-line.entity.ts

@@ -22,6 +22,7 @@ export class ShippingLine extends VendureEntity {
     @ManyToOne(type => ShippingMethod)
     shippingMethod: ShippingMethod | null;
 
+    // TODO: v2 - Add `{ onDelete: 'CASCADE' }` constraint
     @ManyToOne(type => Order, order => order.shippingLines)
     order: Order;
 

+ 4 - 0
packages/core/src/service/services/order.service.ts

@@ -1198,6 +1198,10 @@ export class OrderService {
         const { orderToDelete, linesToInsert, linesToDelete, linesToModify } = mergeResult;
         let { order } = mergeResult;
         if (orderToDelete) {
+            // TODO: v2 - Will not be needed after adding `{ onDelete: 'CASCADE' }` constraint to ShippingLine.order
+            for (const shippingLine of orderToDelete.shippingLines) {
+                await this.connection.getRepository(ctx, ShippingLine).delete(shippingLine.id);
+            }
             await this.connection.getRepository(ctx, Order).delete(orderToDelete.id);
         }
         if (order && linesToInsert) {

File diff suppressed because it is too large
+ 646 - 502
packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts


Some files were not shown because too many files changed in this diff