Jelajahi Sumber

feat(core): Implement isDefault on TaxCategory

Relates to #566

BREAKING CHANGE: The TaxCategory entity now has an `isDefault` property, requiring a DB migration.
Michael Bromley 5 tahun lalu
induk
melakukan
7eb21d16d0

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

@@ -2213,11 +2213,13 @@ export type UpdateTagInput = {
 
 export type CreateTaxCategoryInput = {
     name: Scalars['String'];
+    isDefault?: Maybe<Scalars['Boolean']>;
 };
 
 export type UpdateTaxCategoryInput = {
     id: Scalars['ID'];
     name?: Maybe<Scalars['String']>;
+    isDefault?: Maybe<Scalars['Boolean']>;
 };
 
 export type CreateTaxRateInput = {
@@ -3943,6 +3945,7 @@ export type TaxCategory = Node & {
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
     name: Scalars['String'];
+    isDefault: Scalars['Boolean'];
 };
 
 export type TaxRate = Node & {

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

@@ -2290,6 +2290,7 @@ export type TaxCategory = Node & {
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
     name: Scalars['String'];
+    isDefault: Scalars['Boolean'];
 };
 
 export type TaxRate = Node & {

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

@@ -2381,11 +2381,13 @@ export type UpdateTagInput = {
 
 export type CreateTaxCategoryInput = {
   name: Scalars['String'];
+  isDefault?: Maybe<Scalars['Boolean']>;
 };
 
 export type UpdateTaxCategoryInput = {
   id: Scalars['ID'];
   name?: Maybe<Scalars['String']>;
+  isDefault?: Maybe<Scalars['Boolean']>;
 };
 
 export type CreateTaxRateInput = {
@@ -4186,6 +4188,7 @@ export type TaxCategory = Node & {
   createdAt: Scalars['DateTime'];
   updatedAt: Scalars['DateTime'];
   name: Scalars['String'];
+  isDefault: Scalars['Boolean'];
 };
 
 export type TaxRate = Node & {

+ 9 - 4
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -2213,11 +2213,13 @@ export type UpdateTagInput = {
 
 export type CreateTaxCategoryInput = {
     name: Scalars['String'];
+    isDefault?: Maybe<Scalars['Boolean']>;
 };
 
 export type UpdateTaxCategoryInput = {
     id: Scalars['ID'];
     name?: Maybe<Scalars['String']>;
+    isDefault?: Maybe<Scalars['Boolean']>;
 };
 
 export type CreateTaxRateInput = {
@@ -3943,6 +3945,7 @@ export type TaxCategory = Node & {
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
     name: Scalars['String'];
+    isDefault: Scalars['Boolean'];
 };
 
 export type TaxRate = Node & {
@@ -6377,25 +6380,27 @@ export type DeleteTagMutation = { deleteTag: Pick<DeletionResponse, 'message' |
 
 export type GetTaxCategoryListQueryVariables = Exact<{ [key: string]: never }>;
 
-export type GetTaxCategoryListQuery = { taxCategories: Array<Pick<TaxCategory, 'id' | 'name'>> };
+export type GetTaxCategoryListQuery = {
+    taxCategories: Array<Pick<TaxCategory, 'id' | 'name' | 'isDefault'>>;
+};
 
 export type GetTaxCategoryQueryVariables = Exact<{
     id: Scalars['ID'];
 }>;
 
-export type GetTaxCategoryQuery = { taxCategory?: Maybe<Pick<TaxCategory, 'id' | 'name'>> };
+export type GetTaxCategoryQuery = { taxCategory?: Maybe<Pick<TaxCategory, 'id' | 'name' | 'isDefault'>> };
 
 export type CreateTaxCategoryMutationVariables = Exact<{
     input: CreateTaxCategoryInput;
 }>;
 
-export type CreateTaxCategoryMutation = { createTaxCategory: Pick<TaxCategory, 'id' | 'name'> };
+export type CreateTaxCategoryMutation = { createTaxCategory: Pick<TaxCategory, 'id' | 'name' | 'isDefault'> };
 
 export type UpdateTaxCategoryMutationVariables = Exact<{
     input: UpdateTaxCategoryInput;
 }>;
 
-export type UpdateTaxCategoryMutation = { updateTaxCategory: Pick<TaxCategory, 'id' | 'name'> };
+export type UpdateTaxCategoryMutation = { updateTaxCategory: Pick<TaxCategory, 'id' | 'name' | 'isDefault'> };
 
 export type DeleteTaxCategoryMutationVariables = Exact<{
     id: Scalars['ID'];

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

@@ -2200,6 +2200,7 @@ export type TaxCategory = Node & {
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
     name: Scalars['String'];
+    isDefault: Scalars['Boolean'];
 };
 
 export type TaxRate = Node & {

+ 63 - 4
packages/core/e2e/tax-category.e2e-spec.ts

@@ -3,7 +3,7 @@ import gql from 'graphql-tag';
 import path from 'path';
 
 import { initialData } from '../../../e2e-common/e2e-initial-data';
-import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
+import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
 
 import {
     CreateTaxCategory,
@@ -35,9 +35,9 @@ describe('TaxCategory resolver', () => {
         const { taxCategories } = await adminClient.query<GetTaxCategoryList.Query>(GET_TAX_CATEGORY_LIST);
 
         expect(taxCategories.sort(sortById)).toEqual([
-            { id: 'T_1', name: 'Standard Tax' },
-            { id: 'T_2', name: 'Reduced Tax' },
-            { id: 'T_3', name: 'Zero Tax' },
+            { id: 'T_1', name: 'Standard Tax', isDefault: false },
+            { id: 'T_2', name: 'Reduced Tax', isDefault: false },
+            { id: 'T_3', name: 'Zero Tax', isDefault: false },
         ]);
     });
 
@@ -52,6 +52,7 @@ describe('TaxCategory resolver', () => {
         expect(taxCategory).toEqual({
             id: 'T_2',
             name: 'Reduced Tax',
+            isDefault: false,
         });
     });
 
@@ -68,6 +69,7 @@ describe('TaxCategory resolver', () => {
         expect(createTaxCategory).toEqual({
             id: 'T_4',
             name: 'New Category',
+            isDefault: false,
         });
     });
 
@@ -85,9 +87,62 @@ describe('TaxCategory resolver', () => {
         expect(updateTaxCategory).toEqual({
             id: 'T_4',
             name: 'New Category Updated',
+            isDefault: false,
         });
     });
 
+    it('set default', async () => {
+        const { updateTaxCategory } = await adminClient.query<
+            UpdateTaxCategory.Mutation,
+            UpdateTaxCategory.Variables
+        >(UPDATE_TAX_CATEGORY, {
+            input: {
+                id: 'T_2',
+                isDefault: true,
+            },
+        });
+
+        expect(updateTaxCategory).toEqual({
+            id: 'T_2',
+            name: 'Reduced Tax',
+            isDefault: true,
+        });
+
+        const { taxCategories } = await adminClient.query<GetTaxCategoryList.Query>(GET_TAX_CATEGORY_LIST);
+        expect(taxCategories.sort(sortById)).toEqual([
+            { id: 'T_1', name: 'Standard Tax', isDefault: false },
+            { id: 'T_2', name: 'Reduced Tax', isDefault: true },
+            { id: 'T_3', name: 'Zero Tax', isDefault: false },
+            { id: 'T_4', name: 'New Category Updated', isDefault: false },
+        ]);
+    });
+
+    it('set a different default', async () => {
+        const { updateTaxCategory } = await adminClient.query<
+            UpdateTaxCategory.Mutation,
+            UpdateTaxCategory.Variables
+        >(UPDATE_TAX_CATEGORY, {
+            input: {
+                id: 'T_1',
+                isDefault: true,
+            },
+        });
+
+        expect(updateTaxCategory).toEqual({
+            id: 'T_1',
+            name: 'Standard Tax',
+            isDefault: true,
+        });
+
+        const { taxCategories } = await adminClient.query<GetTaxCategoryList.Query>(GET_TAX_CATEGORY_LIST);
+        expect(taxCategories.sort(sortById)).toEqual([
+            { id: 'T_1', name: 'Standard Tax', isDefault: true },
+            { id: 'T_2', name: 'Reduced Tax', isDefault: false },
+            { id: 'T_3', name: 'Zero Tax', isDefault: false },
+            { id: 'T_4', name: 'New Category Updated', isDefault: false },
+        ]);
+    });
+
     describe('deletion', () => {
         it('cannot delete if used by a TaxRate', async () => {
             const { deleteTaxCategory } = await adminClient.query<
@@ -131,6 +186,7 @@ const GET_TAX_CATEGORY_LIST = gql`
         taxCategories {
             id
             name
+            isDefault
         }
     }
 `;
@@ -140,6 +196,7 @@ const GET_TAX_CATEGORY = gql`
         taxCategory(id: $id) {
             id
             name
+            isDefault
         }
     }
 `;
@@ -149,6 +206,7 @@ const CREATE_TAX_CATEGORY = gql`
         createTaxCategory(input: $input) {
             id
             name
+            isDefault
         }
     }
 `;
@@ -158,6 +216,7 @@ const UPDATE_TAX_CATEGORY = gql`
         updateTaxCategory(input: $input) {
             id
             name
+            isDefault
         }
     }
 `;

+ 2 - 0
packages/core/src/api/schema/admin-api/tax-category.api.graphql

@@ -16,9 +16,11 @@ type Mutation {
 
 input CreateTaxCategoryInput {
     name: String!
+    isDefault: Boolean
 }
 
 input UpdateTaxCategoryInput {
     id: ID!
     name: String
+    isDefault: Boolean
 }

+ 1 - 0
packages/core/src/api/schema/common/tax-category.type.graphql

@@ -3,4 +3,5 @@ type TaxCategory implements Node {
     createdAt: DateTime!
     updatedAt: DateTime!
     name: String!
+    isDefault: Boolean!
 }

+ 2 - 0
packages/core/src/entity/tax-category/tax-category.entity.ts

@@ -16,4 +16,6 @@ export class TaxCategory extends VendureEntity {
     }
 
     @Column() name: string;
+
+    @Column({ default: false }) isDefault: boolean;
 }

+ 1 - 1
packages/core/src/service/services/product-variant.service.ts

@@ -650,7 +650,7 @@ export class ProductVariantService {
             taxCategory = await this.connection.getEntityOrThrow(ctx, TaxCategory, taxCategoryId);
         } else {
             const taxCategories = await this.taxCategoryService.findAll(ctx);
-            taxCategory = taxCategories[0];
+            taxCategory = taxCategories.find(t => t.isDefault === true) ?? taxCategories[0];
         }
         if (!taxCategory) {
             // there is no TaxCategory set up, so create a default

+ 10 - 0
packages/core/src/service/services/tax-category.service.ts

@@ -29,6 +29,11 @@ export class TaxCategoryService {
 
     async create(ctx: RequestContext, input: CreateTaxCategoryInput): Promise<TaxCategory> {
         const taxCategory = new TaxCategory(input);
+        if (input.isDefault === true) {
+            await this.connection
+                .getRepository(ctx, TaxCategory)
+                .update({ isDefault: true }, { isDefault: false });
+        }
         const newTaxCategory = await this.connection.getRepository(ctx, TaxCategory).save(taxCategory);
         return assertFound(this.findOne(ctx, newTaxCategory.id));
     }
@@ -39,6 +44,11 @@ export class TaxCategoryService {
             throw new EntityNotFoundError('TaxCategory', input.id);
         }
         const updatedTaxCategory = patchEntity(taxCategory, input);
+        if (input.isDefault === true) {
+            await this.connection
+                .getRepository(ctx, TaxCategory)
+                .update({ isDefault: true }, { isDefault: false });
+        }
         await this.connection.getRepository(ctx, TaxCategory).save(updatedTaxCategory, { reload: false });
         return assertFound(this.findOne(ctx, taxCategory.id));
     }

+ 8 - 1
packages/dev-server/dev-config.ts

@@ -3,6 +3,7 @@ import { AdminUiPlugin } from '@vendure/admin-ui-plugin';
 import { AssetServerPlugin } from '@vendure/asset-server-plugin';
 import { ADMIN_API_PATH, API_PORT, SHOP_API_PATH } from '@vendure/common/lib/shared-constants';
 import {
+    Asset,
     DefaultJobQueuePlugin,
     DefaultLogger,
     DefaultSearchPlugin,
@@ -63,7 +64,13 @@ export const devConfig: VendureConfig = {
         paymentMethodEligibilityCheckers: [testPaymentChecker],
         paymentMethodHandlers: [dummyPaymentHandler],
     },
-    customFields: {},
+    customFields: {
+        /*Administrator: [
+            { name: 'profileLink', type: 'string' },
+            { name: 'avatar', type: 'relation', entity: Asset },
+        ],
+        Channel: [{ name: 'description', type: 'string' }],*/
+    },
     logger: new DefaultLogger({ level: LogLevel.Info }),
     importExportOptions: {
         importAssetsDir: path.join(__dirname, 'import-assets'),

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

@@ -2213,11 +2213,13 @@ export type UpdateTagInput = {
 
 export type CreateTaxCategoryInput = {
     name: Scalars['String'];
+    isDefault?: Maybe<Scalars['Boolean']>;
 };
 
 export type UpdateTaxCategoryInput = {
     id: Scalars['ID'];
     name?: Maybe<Scalars['String']>;
+    isDefault?: Maybe<Scalars['Boolean']>;
 };
 
 export type CreateTaxRateInput = {
@@ -3943,6 +3945,7 @@ export type TaxCategory = Node & {
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
     name: Scalars['String'];
+    isDefault: Scalars['Boolean'];
 };
 
 export type TaxRate = Node & {

File diff ditekan karena terlalu besar
+ 0 - 0
schema-admin.json


File diff ditekan karena terlalu besar
+ 0 - 0
schema-shop.json


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini