Przeglądaj źródła

feat(core): Make ShippingMethod translatable

Relates to #530

BREAKING CHANGE: The `ShippingMethod` entity is now translatable. This change will require a DB
migration to be performed, including custom queries to migrate any existing ShippingMethods
to the new table structure (see release blog post for details).
Michael Bromley 5 lat temu
rodzic
commit
c7418d1358
27 zmienionych plików z 315 dodań i 90 usunięć
  1. 14 2
      packages/admin-ui/src/lib/core/src/common/generated-types.ts
  2. 24 3
      packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts
  3. 13 0
      packages/common/src/generated-shop-types.ts
  4. 25 3
      packages/common/src/generated-types.ts
  5. 1 0
      packages/core/e2e/graphql/fragments.ts
  6. 48 27
      packages/core/e2e/graphql/generated-e2e-admin-types.ts
  7. 13 1
      packages/core/e2e/graphql/generated-e2e-shop-types.ts
  8. 1 0
      packages/core/e2e/graphql/shop-definitions.ts
  9. 14 6
      packages/core/e2e/shipping-method-eligibility.e2e-spec.ts
  10. 12 7
      packages/core/e2e/shipping-method.e2e-spec.ts
  11. 2 2
      packages/core/e2e/shop-order.e2e-spec.ts
  12. 9 3
      packages/core/src/api/schema/admin-api/shipping-method.api.graphql
  13. 1 0
      packages/core/src/api/schema/type/order.type.graphql
  14. 11 0
      packages/core/src/api/schema/type/shipping-method.type.graphql
  15. 2 2
      packages/core/src/data-import/providers/populator/populator.ts
  16. 1 0
      packages/core/src/entity/custom-entity-fields.ts
  17. 2 0
      packages/core/src/entity/entities.ts
  18. 1 4
      packages/core/src/entity/product/product-translation.entity.ts
  19. 2 0
      packages/core/src/entity/register-custom-entity-fields.ts
  20. 32 0
      packages/core/src/entity/shipping-method/shipping-method-translation.entity.ts
  21. 13 3
      packages/core/src/entity/shipping-method/shipping-method.entity.ts
  22. 15 11
      packages/core/src/service/services/order-testing.service.ts
  23. 1 0
      packages/core/src/service/services/order.service.ts
  24. 34 13
      packages/core/src/service/services/shipping-method.service.ts
  25. 24 3
      packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts
  26. 0 0
      schema-admin.json
  27. 0 0
      schema-shop.json

+ 14 - 2
packages/admin-ui/src/lib/core/src/common/generated-types.ts

@@ -1839,20 +1839,28 @@ export type UpdateRoleInput = {
   channelIds?: Maybe<Array<Scalars['ID']>>;
 };
 
+export type ShippingMethodTranslationInput = {
+  id?: Maybe<Scalars['ID']>;
+  languageCode: LanguageCode;
+  name?: Maybe<Scalars['String']>;
+  description?: Maybe<Scalars['String']>;
+  customFields?: Maybe<Scalars['JSON']>;
+};
+
 export type CreateShippingMethodInput = {
   code: Scalars['String'];
-  description: Scalars['String'];
   checker: ConfigurableOperationInput;
   calculator: ConfigurableOperationInput;
+  translations: Array<ShippingMethodTranslationInput>;
   customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type UpdateShippingMethodInput = {
   id: Scalars['ID'];
   code?: Maybe<Scalars['String']>;
-  description?: Maybe<Scalars['String']>;
   checker?: Maybe<ConfigurableOperationInput>;
   calculator?: Maybe<ConfigurableOperationInput>;
+  translations: Array<ShippingMethodTranslationInput>;
   customFields?: Maybe<Scalars['JSON']>;
 };
 
@@ -3346,6 +3354,7 @@ export type ShippingMethodQuote = {
   id: Scalars['ID'];
   price: Scalars['Int'];
   priceWithTax: Scalars['Int'];
+  name: Scalars['String'];
   description: Scalars['String'];
   metadata?: Maybe<Scalars['JSON']>;
 };
@@ -3596,6 +3605,7 @@ export type ShippingMethod = Node & {
   createdAt: Scalars['DateTime'];
   updatedAt: Scalars['DateTime'];
   code: Scalars['String'];
+  name: Scalars['String'];
   description: Scalars['String'];
   checker: ConfigurableOperation;
   calculator: ConfigurableOperation;
@@ -4135,6 +4145,7 @@ export type ShippingMethodFilterParameter = {
   createdAt?: Maybe<DateOperators>;
   updatedAt?: Maybe<DateOperators>;
   code?: Maybe<StringOperators>;
+  name?: Maybe<StringOperators>;
   description?: Maybe<StringOperators>;
 };
 
@@ -4143,6 +4154,7 @@ export type ShippingMethodSortParameter = {
   createdAt?: Maybe<SortOrder>;
   updatedAt?: Maybe<SortOrder>;
   code?: Maybe<SortOrder>;
+  name?: Maybe<SortOrder>;
   description?: Maybe<SortOrder>;
 };
 

+ 24 - 3
packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts

@@ -1663,20 +1663,28 @@ export type UpdateRoleInput = {
     channelIds?: Maybe<Array<Scalars['ID']>>;
 };
 
+export type ShippingMethodTranslationInput = {
+    id?: Maybe<Scalars['ID']>;
+    languageCode: LanguageCode;
+    name?: Maybe<Scalars['String']>;
+    description?: Maybe<Scalars['String']>;
+    customFields?: Maybe<Scalars['JSON']>;
+};
+
 export type CreateShippingMethodInput = {
     code: Scalars['String'];
-    description: Scalars['String'];
     checker: ConfigurableOperationInput;
     calculator: ConfigurableOperationInput;
+    translations: Array<ShippingMethodTranslationInput>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type UpdateShippingMethodInput = {
     id: Scalars['ID'];
     code?: Maybe<Scalars['String']>;
-    description?: Maybe<Scalars['String']>;
     checker?: Maybe<ConfigurableOperationInput>;
     calculator?: Maybe<ConfigurableOperationInput>;
+    translations: Array<ShippingMethodTranslationInput>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
@@ -1705,7 +1713,6 @@ export type TestShippingMethodResult = {
 export type TestShippingMethodQuote = {
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
-    description: Scalars['String'];
     metadata?: Maybe<Scalars['JSON']>;
 };
 
@@ -3117,6 +3124,7 @@ export type ShippingMethodQuote = {
     id: Scalars['ID'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
+    name: Scalars['String'];
     description: Scalars['String'];
     metadata?: Maybe<Scalars['JSON']>;
 };
@@ -3344,12 +3352,23 @@ export type ShippingMethod = Node & {
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
     code: Scalars['String'];
+    name: Scalars['String'];
     description: Scalars['String'];
     checker: ConfigurableOperation;
     calculator: ConfigurableOperation;
+    translations: Array<ShippingMethodTranslation>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type ShippingMethodTranslation = {
+    id: Scalars['ID'];
+    createdAt: Scalars['DateTime'];
+    updatedAt: Scalars['DateTime'];
+    languageCode: LanguageCode;
+    name: Scalars['String'];
+    description: Scalars['String'];
+};
+
 export type ShippingMethodList = PaginatedList & {
     items: Array<ShippingMethod>;
     totalItems: Scalars['Int'];
@@ -3875,6 +3894,7 @@ export type ShippingMethodFilterParameter = {
     createdAt?: Maybe<DateOperators>;
     updatedAt?: Maybe<DateOperators>;
     code?: Maybe<StringOperators>;
+    name?: Maybe<StringOperators>;
     description?: Maybe<StringOperators>;
 };
 
@@ -3883,6 +3903,7 @@ export type ShippingMethodSortParameter = {
     createdAt?: Maybe<SortOrder>;
     updatedAt?: Maybe<SortOrder>;
     code?: Maybe<SortOrder>;
+    name?: Maybe<SortOrder>;
     description?: Maybe<SortOrder>;
 };
 

+ 13 - 0
packages/common/src/generated-shop-types.ts

@@ -2094,6 +2094,7 @@ export type ShippingMethodQuote = {
     id: Scalars['ID'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
+    name: Scalars['String'];
     description: Scalars['String'];
     metadata?: Maybe<Scalars['JSON']>;
 };
@@ -2425,12 +2426,24 @@ export type ShippingMethod = Node & {
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
     code: Scalars['String'];
+    name: Scalars['String'];
     description: Scalars['String'];
     checker: ConfigurableOperation;
     calculator: ConfigurableOperation;
+    translations: Array<ShippingMethodTranslation>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type ShippingMethodTranslation = {
+    __typename?: 'ShippingMethodTranslation';
+    id: Scalars['ID'];
+    createdAt: Scalars['DateTime'];
+    updatedAt: Scalars['DateTime'];
+    languageCode: LanguageCode;
+    name: Scalars['String'];
+    description: Scalars['String'];
+};
+
 export type ShippingMethodList = PaginatedList & {
     __typename?: 'ShippingMethodList';
     items: Array<ShippingMethod>;

+ 25 - 3
packages/common/src/generated-types.ts

@@ -1808,20 +1808,28 @@ export type UpdateRoleInput = {
   channelIds?: Maybe<Array<Scalars['ID']>>;
 };
 
+export type ShippingMethodTranslationInput = {
+  id?: Maybe<Scalars['ID']>;
+  languageCode: LanguageCode;
+  name?: Maybe<Scalars['String']>;
+  description?: Maybe<Scalars['String']>;
+  customFields?: Maybe<Scalars['JSON']>;
+};
+
 export type CreateShippingMethodInput = {
   code: Scalars['String'];
-  description: Scalars['String'];
   checker: ConfigurableOperationInput;
   calculator: ConfigurableOperationInput;
+  translations: Array<ShippingMethodTranslationInput>;
   customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type UpdateShippingMethodInput = {
   id: Scalars['ID'];
   code?: Maybe<Scalars['String']>;
-  description?: Maybe<Scalars['String']>;
   checker?: Maybe<ConfigurableOperationInput>;
   calculator?: Maybe<ConfigurableOperationInput>;
+  translations: Array<ShippingMethodTranslationInput>;
   customFields?: Maybe<Scalars['JSON']>;
 };
 
@@ -1852,7 +1860,6 @@ export type TestShippingMethodQuote = {
   __typename?: 'TestShippingMethodQuote';
   price: Scalars['Int'];
   priceWithTax: Scalars['Int'];
-  description: Scalars['String'];
   metadata?: Maybe<Scalars['JSON']>;
 };
 
@@ -3314,6 +3321,7 @@ export type ShippingMethodQuote = {
   id: Scalars['ID'];
   price: Scalars['Int'];
   priceWithTax: Scalars['Int'];
+  name: Scalars['String'];
   description: Scalars['String'];
   metadata?: Maybe<Scalars['JSON']>;
 };
@@ -3564,12 +3572,24 @@ export type ShippingMethod = Node & {
   createdAt: Scalars['DateTime'];
   updatedAt: Scalars['DateTime'];
   code: Scalars['String'];
+  name: Scalars['String'];
   description: Scalars['String'];
   checker: ConfigurableOperation;
   calculator: ConfigurableOperation;
+  translations: Array<ShippingMethodTranslation>;
   customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type ShippingMethodTranslation = {
+  __typename?: 'ShippingMethodTranslation';
+  id: Scalars['ID'];
+  createdAt: Scalars['DateTime'];
+  updatedAt: Scalars['DateTime'];
+  languageCode: LanguageCode;
+  name: Scalars['String'];
+  description: Scalars['String'];
+};
+
 export type ShippingMethodList = PaginatedList & {
   __typename?: 'ShippingMethodList';
   items: Array<ShippingMethod>;
@@ -4103,6 +4123,7 @@ export type ShippingMethodFilterParameter = {
   createdAt?: Maybe<DateOperators>;
   updatedAt?: Maybe<DateOperators>;
   code?: Maybe<StringOperators>;
+  name?: Maybe<StringOperators>;
   description?: Maybe<StringOperators>;
 };
 
@@ -4111,6 +4132,7 @@ export type ShippingMethodSortParameter = {
   createdAt?: Maybe<SortOrder>;
   updatedAt?: Maybe<SortOrder>;
   code?: Maybe<SortOrder>;
+  name?: Maybe<SortOrder>;
   description?: Maybe<SortOrder>;
 };
 

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

@@ -590,6 +590,7 @@ export const SHIPPING_METHOD_FRAGMENT = gql`
     fragment ShippingMethod on ShippingMethod {
         id
         code
+        name
         description
         calculator {
             code

+ 48 - 27
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -1663,20 +1663,28 @@ export type UpdateRoleInput = {
     channelIds?: Maybe<Array<Scalars['ID']>>;
 };
 
+export type ShippingMethodTranslationInput = {
+    id?: Maybe<Scalars['ID']>;
+    languageCode: LanguageCode;
+    name?: Maybe<Scalars['String']>;
+    description?: Maybe<Scalars['String']>;
+    customFields?: Maybe<Scalars['JSON']>;
+};
+
 export type CreateShippingMethodInput = {
     code: Scalars['String'];
-    description: Scalars['String'];
     checker: ConfigurableOperationInput;
     calculator: ConfigurableOperationInput;
+    translations: Array<ShippingMethodTranslationInput>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type UpdateShippingMethodInput = {
     id: Scalars['ID'];
     code?: Maybe<Scalars['String']>;
-    description?: Maybe<Scalars['String']>;
     checker?: Maybe<ConfigurableOperationInput>;
     calculator?: Maybe<ConfigurableOperationInput>;
+    translations: Array<ShippingMethodTranslationInput>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
@@ -1705,7 +1713,6 @@ export type TestShippingMethodResult = {
 export type TestShippingMethodQuote = {
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
-    description: Scalars['String'];
     metadata?: Maybe<Scalars['JSON']>;
 };
 
@@ -3117,6 +3124,7 @@ export type ShippingMethodQuote = {
     id: Scalars['ID'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
+    name: Scalars['String'];
     description: Scalars['String'];
     metadata?: Maybe<Scalars['JSON']>;
 };
@@ -3344,12 +3352,23 @@ export type ShippingMethod = Node & {
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
     code: Scalars['String'];
+    name: Scalars['String'];
     description: Scalars['String'];
     checker: ConfigurableOperation;
     calculator: ConfigurableOperation;
+    translations: Array<ShippingMethodTranslation>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type ShippingMethodTranslation = {
+    id: Scalars['ID'];
+    createdAt: Scalars['DateTime'];
+    updatedAt: Scalars['DateTime'];
+    languageCode: LanguageCode;
+    name: Scalars['String'];
+    description: Scalars['String'];
+};
+
 export type ShippingMethodList = PaginatedList & {
     items: Array<ShippingMethod>;
     totalItems: Scalars['Int'];
@@ -3875,6 +3894,7 @@ export type ShippingMethodFilterParameter = {
     createdAt?: Maybe<DateOperators>;
     updatedAt?: Maybe<DateOperators>;
     code?: Maybe<StringOperators>;
+    name?: Maybe<StringOperators>;
     description?: Maybe<StringOperators>;
 };
 
@@ -3883,6 +3903,7 @@ export type ShippingMethodSortParameter = {
     createdAt?: Maybe<SortOrder>;
     updatedAt?: Maybe<SortOrder>;
     code?: Maybe<SortOrder>;
+    name?: Maybe<SortOrder>;
     description?: Maybe<SortOrder>;
 };
 
@@ -4691,7 +4712,7 @@ export type ProductWithOptionsFragment = Pick<Product, 'id'> & {
     >;
 };
 
-export type ShippingMethodFragment = Pick<ShippingMethod, 'id' | 'code' | 'description'> & {
+export type ShippingMethodFragment = Pick<ShippingMethod, 'id' | 'code' | 'name' | 'description'> & {
     calculator: Pick<ConfigurableOperation, 'code'>;
     checker: Pick<ConfigurableOperation, 'code'>;
 };
@@ -5235,16 +5256,6 @@ export type CreateShippingMethodMutationVariables = Exact<{
 
 export type CreateShippingMethodMutation = { createShippingMethod: ShippingMethodFragment };
 
-export type UpdateOptionGroupMutationVariables = Exact<{
-    input: UpdateProductOptionGroupInput;
-}>;
-
-export type UpdateOptionGroupMutation = { updateProductOptionGroup: Pick<ProductOptionGroup, 'id'> };
-
-export type DeletePromotionAdHoc1MutationVariables = Exact<{ [key: string]: never }>;
-
-export type DeletePromotionAdHoc1Mutation = { deletePromotion: Pick<DeletionResponse, 'result'> };
-
 export type SettlePaymentMutationVariables = Exact<{
     id: Scalars['ID'];
 }>;
@@ -5259,6 +5270,16 @@ export type SettlePaymentMutation = {
 
 export type PaymentFragment = Pick<Payment, 'id' | 'state' | 'metadata'>;
 
+export type UpdateOptionGroupMutationVariables = Exact<{
+    input: UpdateProductOptionGroupInput;
+}>;
+
+export type UpdateOptionGroupMutation = { updateProductOptionGroup: Pick<ProductOptionGroup, 'id'> };
+
+export type DeletePromotionAdHoc1MutationVariables = Exact<{ [key: string]: never }>;
+
+export type DeletePromotionAdHoc1Mutation = { deletePromotion: Pick<DeletionResponse, 'result'> };
+
 export type GetOrderListFulfillmentsQueryVariables = Exact<{ [key: string]: never }>;
 
 export type GetOrderListFulfillmentsQuery = {
@@ -5531,7 +5552,7 @@ export type TestEligibleMethodsQueryVariables = Exact<{
 
 export type TestEligibleMethodsQuery = {
     testEligibleShippingMethods: Array<
-        Pick<ShippingMethodQuote, 'id' | 'description' | 'price' | 'priceWithTax' | 'metadata'>
+        Pick<ShippingMethodQuote, 'id' | 'name' | 'description' | 'price' | 'priceWithTax' | 'metadata'>
     >;
 };
 
@@ -7098,18 +7119,6 @@ export namespace CreateShippingMethod {
     export type CreateShippingMethod = NonNullable<CreateShippingMethodMutation['createShippingMethod']>;
 }
 
-export namespace UpdateOptionGroup {
-    export type Variables = UpdateOptionGroupMutationVariables;
-    export type Mutation = UpdateOptionGroupMutation;
-    export type UpdateProductOptionGroup = NonNullable<UpdateOptionGroupMutation['updateProductOptionGroup']>;
-}
-
-export namespace DeletePromotionAdHoc1 {
-    export type Variables = DeletePromotionAdHoc1MutationVariables;
-    export type Mutation = DeletePromotionAdHoc1Mutation;
-    export type DeletePromotion = NonNullable<DeletePromotionAdHoc1Mutation['deletePromotion']>;
-}
-
 export namespace SettlePayment {
     export type Variables = SettlePaymentMutationVariables;
     export type Mutation = SettlePaymentMutation;
@@ -7128,6 +7137,18 @@ export namespace Payment {
     export type Fragment = PaymentFragment;
 }
 
+export namespace UpdateOptionGroup {
+    export type Variables = UpdateOptionGroupMutationVariables;
+    export type Mutation = UpdateOptionGroupMutation;
+    export type UpdateProductOptionGroup = NonNullable<UpdateOptionGroupMutation['updateProductOptionGroup']>;
+}
+
+export namespace DeletePromotionAdHoc1 {
+    export type Variables = DeletePromotionAdHoc1MutationVariables;
+    export type Mutation = DeletePromotionAdHoc1Mutation;
+    export type DeletePromotion = NonNullable<DeletePromotionAdHoc1Mutation['deletePromotion']>;
+}
+
 export namespace GetOrderListFulfillments {
     export type Variables = GetOrderListFulfillmentsQueryVariables;
     export type Query = GetOrderListFulfillmentsQuery;

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

@@ -2015,6 +2015,7 @@ export type ShippingMethodQuote = {
     id: Scalars['ID'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
+    name: Scalars['String'];
     description: Scalars['String'];
     metadata?: Maybe<Scalars['JSON']>;
 };
@@ -2319,12 +2320,23 @@ export type ShippingMethod = Node & {
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
     code: Scalars['String'];
+    name: Scalars['String'];
     description: Scalars['String'];
     checker: ConfigurableOperation;
     calculator: ConfigurableOperation;
+    translations: Array<ShippingMethodTranslation>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type ShippingMethodTranslation = {
+    id: Scalars['ID'];
+    createdAt: Scalars['DateTime'];
+    updatedAt: Scalars['DateTime'];
+    languageCode: LanguageCode;
+    name: Scalars['String'];
+    description: Scalars['String'];
+};
+
 export type ShippingMethodList = PaginatedList & {
     items: Array<ShippingMethod>;
     totalItems: Scalars['Int'];
@@ -2922,7 +2934,7 @@ export type RemoveItemFromOrderMutation = {
 export type GetShippingMethodsQueryVariables = Exact<{ [key: string]: never }>;
 
 export type GetShippingMethodsQuery = {
-    eligibleShippingMethods: Array<Pick<ShippingMethodQuote, 'id' | 'price' | 'description'>>;
+    eligibleShippingMethods: Array<Pick<ShippingMethodQuote, 'id' | 'price' | 'name' | 'description'>>;
 };
 
 export type SetShippingMethodMutationVariables = Exact<{

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

@@ -363,6 +363,7 @@ export const GET_ELIGIBLE_SHIPPING_METHODS = gql`
         eligibleShippingMethods {
             id
             price
+            name
             description
         }
     }

+ 14 - 6
packages/core/e2e/shipping-method-eligibility.e2e-spec.ts

@@ -10,7 +10,11 @@ import path from 'path';
 import { initialData } from '../../../e2e-common/e2e-initial-data';
 import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
 
-import { CreateShippingMethod, ShippingMethodFragment } from './graphql/generated-e2e-admin-types';
+import {
+    CreateShippingMethod,
+    LanguageCode,
+    ShippingMethodFragment,
+} from './graphql/generated-e2e-admin-types';
 import {
     AddItemToOrder,
     AdjustItemQuantity,
@@ -18,7 +22,6 @@ import {
     GetActiveOrder,
     GetShippingMethods,
     RemoveItemFromOrder,
-    SetCustomerForOrder,
     SetShippingAddress,
     SetShippingMethod,
     TestOrderFragmentFragment,
@@ -31,7 +34,6 @@ import {
     GET_ACTIVE_ORDER,
     GET_ELIGIBLE_SHIPPING_METHODS,
     REMOVE_ITEM_FROM_ORDER,
-    SET_CUSTOMER,
     SET_SHIPPING_ADDRESS,
     SET_SHIPPING_METHOD,
 } from './graphql/shop-definitions';
@@ -118,7 +120,6 @@ describe('ShippingMethod resolver', () => {
         >(CREATE_SHIPPING_METHOD, {
             input: {
                 code: 'single-line',
-                description: 'For single-line orders',
                 checker: {
                     code: checker1.code,
                     arguments: [],
@@ -127,6 +128,9 @@ describe('ShippingMethod resolver', () => {
                     code: calculator.code,
                     arguments: [],
                 },
+                translations: [
+                    { languageCode: LanguageCode.en, name: 'For single-line orders', description: '' },
+                ],
             },
         });
         singleLineShippingMethod = result1.createShippingMethod;
@@ -137,7 +141,6 @@ describe('ShippingMethod resolver', () => {
         >(CREATE_SHIPPING_METHOD, {
             input: {
                 code: 'multi-line',
-                description: 'For multi-line orders',
                 checker: {
                     code: checker2.code,
                     arguments: [],
@@ -146,6 +149,9 @@ describe('ShippingMethod resolver', () => {
                     code: calculator.code,
                     arguments: [],
                 },
+                translations: [
+                    { languageCode: LanguageCode.en, name: 'For multi-line orders', description: '' },
+                ],
             },
         });
         multiLineShippingMethod = result2.createShippingMethod;
@@ -156,7 +162,6 @@ describe('ShippingMethod resolver', () => {
         >(CREATE_SHIPPING_METHOD, {
             input: {
                 code: 'optimized',
-                description: 'Optimized with shouldRunCheck',
                 checker: {
                     code: checker3.code,
                     arguments: [],
@@ -165,6 +170,9 @@ describe('ShippingMethod resolver', () => {
                     code: calculator.code,
                     arguments: [],
                 },
+                translations: [
+                    { languageCode: LanguageCode.en, name: 'Optimized with shouldRunCheck', description: '' },
+                ],
             },
         });
         optimizedShippingMethod = result3.createShippingMethod;

+ 12 - 7
packages/core/e2e/shipping-method.e2e-spec.ts

@@ -154,7 +154,6 @@ describe('ShippingMethod resolver', () => {
         >(CREATE_SHIPPING_METHOD, {
             input: {
                 code: 'new-method',
-                description: 'new method',
                 checker: {
                     code: defaultShippingEligibilityChecker.code,
                     arguments: [
@@ -168,13 +167,15 @@ describe('ShippingMethod resolver', () => {
                     code: calculatorWithMetadata.code,
                     arguments: [],
                 },
+                translations: [{ languageCode: LanguageCode.en, name: 'new method', description: '' }],
             },
         });
 
         expect(createShippingMethod).toEqual({
             id: 'T_3',
             code: 'new-method',
-            description: 'new method',
+            name: 'new method',
+            description: '',
             calculator: {
                 code: 'calculator-with-metadata',
             },
@@ -238,7 +239,8 @@ describe('ShippingMethod resolver', () => {
         expect(testEligibleShippingMethods).toEqual([
             {
                 id: 'T_3',
-                description: 'new method',
+                name: 'new method',
+                description: '',
                 price: 100,
                 priceWithTax: 100,
                 metadata: TEST_METADATA,
@@ -246,14 +248,16 @@ describe('ShippingMethod resolver', () => {
 
             {
                 id: 'T_1',
-                description: 'Standard Shipping',
+                name: 'Standard Shipping',
+                description: '',
                 price: 500,
                 priceWithTax: 500,
                 metadata: null,
             },
             {
                 id: 'T_2',
-                description: 'Express Shipping',
+                name: 'Express Shipping',
+                description: '',
                 price: 1000,
                 priceWithTax: 1000,
                 metadata: null,
@@ -268,11 +272,11 @@ describe('ShippingMethod resolver', () => {
         >(UPDATE_SHIPPING_METHOD, {
             input: {
                 id: 'T_3',
-                description: 'changed method',
+                translations: [{ languageCode: LanguageCode.en, name: 'changed method', description: '' }],
             },
         });
 
-        expect(updateShippingMethod.description).toBe('changed method');
+        expect(updateShippingMethod.name).toBe('changed method');
     });
 
     it('deleteShippingMethod', async () => {
@@ -384,6 +388,7 @@ export const TEST_ELIGIBLE_SHIPPING_METHODS = gql`
     query TestEligibleMethods($input: TestEligibleShippingMethodsInput!) {
         testEligibleShippingMethods(input: $input) {
             id
+            name
             description
             price
             priceWithTax

+ 2 - 2
packages/core/e2e/shop-order.e2e-spec.ts

@@ -844,8 +844,8 @@ describe('Shop orders', () => {
                 shippingMethods = result.eligibleShippingMethods;
 
                 expect(shippingMethods).toEqual([
-                    { id: 'T_1', price: 500, description: 'Standard Shipping' },
-                    { id: 'T_2', price: 1000, description: 'Express Shipping' },
+                    { id: 'T_1', price: 500, name: 'Standard Shipping', description: '' },
+                    { id: 'T_2', price: 1000, name: 'Express Shipping', description: '' },
                 ]);
             });
 

+ 9 - 3
packages/core/src/api/schema/admin-api/shipping-method.api.graphql

@@ -19,19 +19,26 @@ type Mutation {
 # generated by generateListOptions function
 input ShippingMethodListOptions
 
+input ShippingMethodTranslationInput {
+    id: ID
+    languageCode: LanguageCode!
+    name: String
+    description: String
+}
+
 input CreateShippingMethodInput {
     code: String!
-    description: String!
     checker: ConfigurableOperationInput!
     calculator: ConfigurableOperationInput!
+    translations: [ShippingMethodTranslationInput!]!
 }
 
 input UpdateShippingMethodInput {
     id: ID!
     code: String
-    description: String
     checker: ConfigurableOperationInput
     calculator: ConfigurableOperationInput
+    translations: [ShippingMethodTranslationInput!]!
 }
 
 input TestShippingMethodInput {
@@ -59,6 +66,5 @@ type TestShippingMethodResult {
 type TestShippingMethodQuote {
     price: Int!
     priceWithTax: Int!
-    description: String!
     metadata: JSON
 }

+ 1 - 0
packages/core/src/api/schema/type/order.type.graphql

@@ -72,6 +72,7 @@ type ShippingMethodQuote {
     id: ID!
     price: Int!
     priceWithTax: Int!
+    name: String!
     description: String!
     metadata: JSON
 }

+ 11 - 0
packages/core/src/api/schema/type/shipping-method.type.graphql

@@ -3,9 +3,20 @@ type ShippingMethod implements Node {
     createdAt: DateTime!
     updatedAt: DateTime!
     code: String!
+    name: String!
     description: String!
     checker: ConfigurableOperation!
     calculator: ConfigurableOperation!
+    translations: [ShippingMethodTranslation!]!
+}
+
+type ShippingMethodTranslation {
+    id: ID!
+    createdAt: DateTime!
+    updatedAt: DateTime!
+    languageCode: LanguageCode!
+    name: String!
+    description: String!
 }
 
 type ShippingMethodList implements PaginatedList {

+ 2 - 2
packages/core/src/data-import/providers/populator/populator.ts

@@ -1,5 +1,5 @@
 import { Injectable } from '@nestjs/common';
-import { ConfigurableOperationInput } from '@vendure/common/lib/generated-types';
+import { ConfigurableOperationInput, LanguageCode } from '@vendure/common/lib/generated-types';
 import { normalizeString } from '@vendure/common/lib/normalize-string';
 import { notNullOrUndefined } from '@vendure/common/lib/shared-utils';
 
@@ -208,8 +208,8 @@ export class Populator {
                         { name: 'taxRate', value: '0' },
                     ],
                 },
-                description: method.name,
                 code: normalizeString(method.name, '-'),
+                translations: [{ languageCode: ctx.languageCode, name: method.name, description: '' }],
             });
         }
     }

+ 1 - 0
packages/core/src/entity/custom-entity-fields.ts

@@ -20,3 +20,4 @@ export class CustomUserFields {}
 export class CustomGlobalSettingsFields {}
 export class CustomOrderFields {}
 export class CustomShippingMethodFields {}
+export class CustomShippingMethodFieldsTranslation {}

+ 2 - 0
packages/core/src/entity/entities.ts

@@ -43,6 +43,7 @@ import { Role } from './role/role.entity';
 import { AnonymousSession } from './session/anonymous-session.entity';
 import { AuthenticatedSession } from './session/authenticated-session.entity';
 import { Session } from './session/session.entity';
+import { ShippingMethodTranslation } from './shipping-method/shipping-method-translation.entity';
 import { ShippingMethod } from './shipping-method/shipping-method.entity';
 import { Allocation } from './stock-movement/allocation.entity';
 import { Cancellation } from './stock-movement/cancellation.entity';
@@ -109,6 +110,7 @@ export const coreEntitiesMap = {
     Sale,
     Session,
     ShippingMethod,
+    ShippingMethodTranslation,
     StockAdjustment,
     StockMovement,
     TaxCategory,

+ 1 - 4
packages/core/src/entity/product/product-translation.entity.ts

@@ -24,10 +24,7 @@ export class ProductTranslation extends VendureEntity implements Translation<Pro
 
     @Column('text') description: string;
 
-    @ManyToOne(
-        type => Product,
-        base => base.translations,
-    )
+    @ManyToOne(type => Product, base => base.translations)
     base: Product;
 
     @Column(type => CustomProductFieldsTranslation)

+ 2 - 0
packages/core/src/entity/register-custom-entity-fields.ts

@@ -29,6 +29,7 @@ import {
     CustomProductVariantFields,
     CustomProductVariantFieldsTranslation,
     CustomShippingMethodFields,
+    CustomShippingMethodFieldsTranslation,
     CustomUserFields,
 } from './custom-entity-fields';
 
@@ -195,4 +196,5 @@ export function registerCustomEntityFields(config: VendureConfig) {
     registerCustomFieldsForEntity(config, 'User', CustomUserFields);
     registerCustomFieldsForEntity(config, 'GlobalSettings', CustomGlobalSettingsFields);
     registerCustomFieldsForEntity(config, 'ShippingMethod', CustomShippingMethodFields);
+    registerCustomFieldsForEntity(config, 'ShippingMethod', CustomShippingMethodFieldsTranslation, true);
 }

+ 32 - 0
packages/core/src/entity/shipping-method/shipping-method-translation.entity.ts

@@ -0,0 +1,32 @@
+import { LanguageCode } from '@vendure/common/lib/generated-types';
+import { DeepPartial } from '@vendure/common/lib/shared-types';
+import { Column, Entity, ManyToOne } from 'typeorm';
+
+import { Translation } from '../../common/types/locale-types';
+import { HasCustomFields } from '../../config/custom-field/custom-field-types';
+import { VendureEntity } from '../base/base.entity';
+import { CustomShippingMethodFieldsTranslation } from '../custom-entity-fields';
+import { Product } from '../product/product.entity';
+
+import { ShippingMethod } from './shipping-method.entity';
+
+@Entity()
+export class ShippingMethodTranslation
+    extends VendureEntity
+    implements Translation<ShippingMethod>, HasCustomFields {
+    constructor(input?: DeepPartial<Translation<Product>>) {
+        super(input);
+    }
+
+    @Column('varchar') languageCode: LanguageCode;
+
+    @Column({ default: '' }) name: string;
+
+    @Column({ default: '' }) description: string;
+
+    @ManyToOne(type => ShippingMethod, base => base.translations)
+    base: ShippingMethod;
+
+    @Column(type => CustomShippingMethodFieldsTranslation)
+    customFields: CustomShippingMethodFieldsTranslation;
+}

+ 13 - 3
packages/core/src/entity/shipping-method/shipping-method.entity.ts

@@ -1,9 +1,10 @@
 import { ConfigurableOperation } from '@vendure/common/lib/generated-types';
 import { DeepPartial } from '@vendure/common/lib/shared-types';
-import { Column, Entity, JoinTable, ManyToMany } from 'typeorm';
+import { Column, Entity, JoinTable, ManyToMany, OneToMany } from 'typeorm';
 
 import { RequestContext } from '../../api/common/request-context';
 import { ChannelAware, SoftDeletable } from '../../common/types/common-types';
+import { LocaleString, Translatable, Translation } from '../../common/types/locale-types';
 import { getConfig } from '../../config/config-helpers';
 import { HasCustomFields } from '../../config/custom-field/custom-field-types';
 import {
@@ -16,6 +17,8 @@ import { Channel } from '../channel/channel.entity';
 import { CustomShippingMethodFields } from '../custom-entity-fields';
 import { Order } from '../order/order.entity';
 
+import { ShippingMethodTranslation } from './shipping-method-translation.entity';
+
 /**
  * @description
  * A ShippingMethod is used to apply a shipping price to an {@link Order}. It is composed of a
@@ -27,7 +30,9 @@ import { Order } from '../order/order.entity';
  * @docsCategory entities
  */
 @Entity()
-export class ShippingMethod extends VendureEntity implements ChannelAware, SoftDeletable, HasCustomFields {
+export class ShippingMethod
+    extends VendureEntity
+    implements ChannelAware, SoftDeletable, HasCustomFields, Translatable {
     private readonly allCheckers: { [code: string]: ShippingEligibilityChecker } = {};
     private readonly allCalculators: { [code: string]: ShippingCalculator } = {};
 
@@ -44,7 +49,9 @@ export class ShippingMethod extends VendureEntity implements ChannelAware, SoftD
 
     @Column() code: string;
 
-    @Column() description: string;
+    name: LocaleString;
+
+    description: LocaleString;
 
     @Column('simple-json') checker: ConfigurableOperation;
 
@@ -54,6 +61,9 @@ export class ShippingMethod extends VendureEntity implements ChannelAware, SoftD
     @JoinTable()
     channels: Channel[];
 
+    @OneToMany(type => ShippingMethodTranslation, translation => translation.base, { eager: true })
+    translations: Array<Translation<ShippingMethod>>;
+
     @Column(type => CustomShippingMethodFields)
     customFields: CustomShippingMethodFields;
 

+ 15 - 11
packages/core/src/service/services/order-testing.service.ts

@@ -18,6 +18,7 @@ import { ShippingMethod } from '../../entity/shipping-method/shipping-method.ent
 import { OrderCalculator } from '../helpers/order-calculator/order-calculator';
 import { ShippingCalculator } from '../helpers/shipping-calculator/shipping-calculator';
 import { ShippingConfiguration } from '../helpers/shipping-configuration/shipping-configuration';
+import { translateDeep } from '../helpers/utils/translate-entity';
 import { TransactionalConnection } from '../transaction/transactional-connection';
 
 import { ProductVariantService } from './product-variant.service';
@@ -54,10 +55,7 @@ export class OrderTestingService {
         const result = eligible ? await shippingMethod.apply(ctx, mockOrder) : undefined;
         return {
             eligible,
-            quote: result && {
-                ...result,
-                description: shippingMethod.description,
-            },
+            quote: result,
         };
     }
 
@@ -71,13 +69,19 @@ export class OrderTestingService {
     ): Promise<ShippingMethodQuote[]> {
         const mockOrder = await this.buildMockOrder(ctx, input.shippingAddress, input.lines);
         const eligibleMethods = await this.shippingCalculator.getEligibleShippingMethods(ctx, mockOrder);
-        return eligibleMethods.map(result => ({
-            id: result.method.id,
-            price: result.result.price,
-            priceWithTax: result.result.priceWithTax,
-            description: result.method.description,
-            metadata: result.result.metadata,
-        }));
+        return eligibleMethods
+            .map(result => {
+                translateDeep(result.method, ctx.languageCode);
+                return result;
+            })
+            .map(result => ({
+                id: result.method.id,
+                price: result.result.price,
+                priceWithTax: result.result.priceWithTax,
+                name: result.method.name,
+                description: result.method.description,
+                metadata: result.result.metadata,
+            }));
     }
 
     private async buildMockOrder(

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

@@ -523,6 +523,7 @@ export class OrderService {
             price: eligible.result.price,
             priceWithTax: eligible.result.priceWithTax,
             description: eligible.method.description,
+            name: eligible.method.name,
             metadata: eligible.result.metadata,
         }));
     }

+ 34 - 13
packages/core/src/service/services/shipping-method.service.ts

@@ -15,10 +15,13 @@ import { ListQueryOptions } from '../../common/types/common-types';
 import { assertFound } from '../../common/utils';
 import { ConfigService } from '../../config/config.service';
 import { Channel } from '../../entity/channel/channel.entity';
+import { ShippingMethodTranslation } from '../../entity/shipping-method/shipping-method-translation.entity';
 import { ShippingMethod } from '../../entity/shipping-method/shipping-method.entity';
 import { ListQueryBuilder } from '../helpers/list-query-builder/list-query-builder';
 import { ShippingConfiguration } from '../helpers/shipping-configuration/shipping-configuration';
+import { TranslatableSaver } from '../helpers/translatable-saver/translatable-saver';
 import { patchEntity } from '../helpers/utils/patch-entity';
+import { translateDeep } from '../helpers/utils/translate-entity';
 import { TransactionalConnection } from '../transaction/transactional-connection';
 
 import { ChannelService } from './channel.service';
@@ -33,6 +36,7 @@ export class ShippingMethodService {
         private listQueryBuilder: ListQueryBuilder,
         private channelService: ChannelService,
         private shippingConfiguration: ShippingConfiguration,
+        private translatableSaver: TranslatableSaver,
     ) {}
 
     async initShippingMethods() {
@@ -52,24 +56,35 @@ export class ShippingMethodService {
             })
             .getManyAndCount()
             .then(([items, totalItems]) => ({
-                items,
+                items: items.map(i => translateDeep(i, ctx.languageCode)),
                 totalItems,
             }));
     }
 
-    findOne(ctx: RequestContext, shippingMethodId: ID): Promise<ShippingMethod | undefined> {
-        return this.connection.findOneInChannel(ctx, ShippingMethod, shippingMethodId, ctx.channelId, {
-            relations: ['channels'],
-            where: { deletedAt: null },
-        });
+    async findOne(ctx: RequestContext, shippingMethodId: ID): Promise<ShippingMethod | undefined> {
+        const shippingMethod = await this.connection.findOneInChannel(
+            ctx,
+            ShippingMethod,
+            shippingMethodId,
+            ctx.channelId,
+            {
+                relations: ['channels'],
+                where: { deletedAt: null },
+            },
+        );
+        return shippingMethod && translateDeep(shippingMethod, ctx.languageCode);
     }
 
     async create(ctx: RequestContext, input: CreateShippingMethodInput): Promise<ShippingMethod> {
-        const shippingMethod = new ShippingMethod({
-            code: input.code,
-            description: input.description,
-            checker: this.shippingConfiguration.parseCheckerInput(input.checker),
-            calculator: this.shippingConfiguration.parseCalculatorInput(input.calculator),
+        const shippingMethod = await this.translatableSaver.create({
+            ctx,
+            input,
+            entityType: ShippingMethod,
+            translationType: ShippingMethodTranslation,
+            beforeSave: method => {
+                method.checker = this.shippingConfiguration.parseCheckerInput(input.checker);
+                method.calculator = this.shippingConfiguration.parseCalculatorInput(input.calculator);
+            },
         });
         this.channelService.assignToCurrentChannel(shippingMethod, ctx);
         const newShippingMethod = await this.connection
@@ -84,7 +99,12 @@ export class ShippingMethodService {
         if (!shippingMethod) {
             throw new EntityNotFoundError('ShippingMethod', input.id);
         }
-        const updatedShippingMethod = patchEntity(shippingMethod, omit(input, ['checker', 'calculator']));
+        const updatedShippingMethod = await this.translatableSaver.update({
+            ctx,
+            input: omit(input, ['checker', 'calculator']),
+            entityType: ShippingMethod,
+            translationType: ShippingMethodTranslation,
+        });
         if (input.checker) {
             updatedShippingMethod.checker = this.shippingConfiguration.parseCheckerInput(input.checker);
         }
@@ -126,9 +146,10 @@ export class ShippingMethodService {
     }
 
     private async updateActiveShippingMethods(ctx: RequestContext) {
-        this.activeShippingMethods = await this.connection.getRepository(ctx, ShippingMethod).find({
+        const activeShippingMethods = await this.connection.getRepository(ctx, ShippingMethod).find({
             relations: ['channels'],
             where: { deletedAt: null },
         });
+        this.activeShippingMethods = activeShippingMethods.map(m => translateDeep(m, ctx.languageCode));
     }
 }

+ 24 - 3
packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts

@@ -1663,20 +1663,28 @@ export type UpdateRoleInput = {
     channelIds?: Maybe<Array<Scalars['ID']>>;
 };
 
+export type ShippingMethodTranslationInput = {
+    id?: Maybe<Scalars['ID']>;
+    languageCode: LanguageCode;
+    name?: Maybe<Scalars['String']>;
+    description?: Maybe<Scalars['String']>;
+    customFields?: Maybe<Scalars['JSON']>;
+};
+
 export type CreateShippingMethodInput = {
     code: Scalars['String'];
-    description: Scalars['String'];
     checker: ConfigurableOperationInput;
     calculator: ConfigurableOperationInput;
+    translations: Array<ShippingMethodTranslationInput>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type UpdateShippingMethodInput = {
     id: Scalars['ID'];
     code?: Maybe<Scalars['String']>;
-    description?: Maybe<Scalars['String']>;
     checker?: Maybe<ConfigurableOperationInput>;
     calculator?: Maybe<ConfigurableOperationInput>;
+    translations: Array<ShippingMethodTranslationInput>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
@@ -1705,7 +1713,6 @@ export type TestShippingMethodResult = {
 export type TestShippingMethodQuote = {
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
-    description: Scalars['String'];
     metadata?: Maybe<Scalars['JSON']>;
 };
 
@@ -3117,6 +3124,7 @@ export type ShippingMethodQuote = {
     id: Scalars['ID'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
+    name: Scalars['String'];
     description: Scalars['String'];
     metadata?: Maybe<Scalars['JSON']>;
 };
@@ -3344,12 +3352,23 @@ export type ShippingMethod = Node & {
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
     code: Scalars['String'];
+    name: Scalars['String'];
     description: Scalars['String'];
     checker: ConfigurableOperation;
     calculator: ConfigurableOperation;
+    translations: Array<ShippingMethodTranslation>;
     customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type ShippingMethodTranslation = {
+    id: Scalars['ID'];
+    createdAt: Scalars['DateTime'];
+    updatedAt: Scalars['DateTime'];
+    languageCode: LanguageCode;
+    name: Scalars['String'];
+    description: Scalars['String'];
+};
+
 export type ShippingMethodList = PaginatedList & {
     items: Array<ShippingMethod>;
     totalItems: Scalars['Int'];
@@ -3875,6 +3894,7 @@ export type ShippingMethodFilterParameter = {
     createdAt?: Maybe<DateOperators>;
     updatedAt?: Maybe<DateOperators>;
     code?: Maybe<StringOperators>;
+    name?: Maybe<StringOperators>;
     description?: Maybe<StringOperators>;
 };
 
@@ -3883,6 +3903,7 @@ export type ShippingMethodSortParameter = {
     createdAt?: Maybe<SortOrder>;
     updatedAt?: Maybe<SortOrder>;
     code?: Maybe<SortOrder>;
+    name?: Maybe<SortOrder>;
     description?: Maybe<SortOrder>;
 };
 

Plik diff jest za duży
+ 0 - 0
schema-admin.json


Plik diff jest za duży
+ 0 - 0
schema-shop.json


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików