Jelajahi Sumber

refactor(core): Update cached tax rates in worker on changes in main

Michael Bromley 6 tahun lalu
induk
melakukan
200cdc9f71

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

@@ -3442,22 +3442,6 @@ export type GetChannelsQuery = { __typename?: 'Query' } & {
     channels: Array<{ __typename?: 'Channel' } & Pick<Channel, 'id' | 'code' | 'token'>>;
 };
 
-export type AssignProductsToChannelMutationVariables = {
-    input: AssignProductsToChannelInput;
-};
-
-export type AssignProductsToChannelMutation = { __typename?: 'Mutation' } & {
-    assignProductsToChannel: Array<{ __typename?: 'Product' } & ProductWithVariantsFragment>;
-};
-
-export type RemoveProductsFromChannelMutationVariables = {
-    input: RemoveProductsFromChannelInput;
-};
-
-export type RemoveProductsFromChannelMutation = { __typename?: 'Mutation' } & {
-    removeProductsFromChannel: Array<{ __typename?: 'Product' } & ProductWithVariantsFragment>;
-};
-
 export type DeleteChannelMutationVariables = {
     id: Scalars['ID'];
 };
@@ -4442,6 +4426,30 @@ export type CreateChannelMutation = { __typename?: 'Mutation' } & {
         };
 };
 
+export type DeleteProductVariantMutationVariables = {
+    id: Scalars['ID'];
+};
+
+export type DeleteProductVariantMutation = { __typename?: 'Mutation' } & {
+    deleteProductVariant: { __typename?: 'DeletionResponse' } & Pick<DeletionResponse, 'result' | 'message'>;
+};
+
+export type AssignProductsToChannelMutationVariables = {
+    input: AssignProductsToChannelInput;
+};
+
+export type AssignProductsToChannelMutation = { __typename?: 'Mutation' } & {
+    assignProductsToChannel: Array<{ __typename?: 'Product' } & ProductWithVariantsFragment>;
+};
+
+export type RemoveProductsFromChannelMutationVariables = {
+    input: RemoveProductsFromChannelInput;
+};
+
+export type RemoveProductsFromChannelMutation = { __typename?: 'Mutation' } & {
+    removeProductsFromChannel: Array<{ __typename?: 'Product' } & ProductWithVariantsFragment>;
+};
+
 export type UpdateOptionGroupMutationVariables = {
     input: UpdateProductOptionGroupInput;
 };
@@ -4724,14 +4732,6 @@ export type GetOptionGroupQuery = { __typename?: 'Query' } & {
     >;
 };
 
-export type DeleteProductVariantMutationVariables = {
-    id: Scalars['ID'];
-};
-
-export type DeleteProductVariantMutation = { __typename?: 'Mutation' } & {
-    deleteProductVariant: { __typename?: 'DeletionResponse' } & Pick<DeletionResponse, 'result' | 'message'>;
-};
-
 export type DeletePromotionMutationVariables = {
     id: Scalars['ID'];
 };
@@ -5133,18 +5133,6 @@ export namespace GetChannels {
     export type Channels = NonNullable<GetChannelsQuery['channels'][0]>;
 }
 
-export namespace AssignProductsToChannel {
-    export type Variables = AssignProductsToChannelMutationVariables;
-    export type Mutation = AssignProductsToChannelMutation;
-    export type AssignProductsToChannel = ProductWithVariantsFragment;
-}
-
-export namespace RemoveProductsFromChannel {
-    export type Variables = RemoveProductsFromChannelMutationVariables;
-    export type Mutation = RemoveProductsFromChannelMutation;
-    export type RemoveProductsFromChannel = ProductWithVariantsFragment;
-}
-
 export namespace DeleteChannel {
     export type Variables = DeleteChannelMutationVariables;
     export type Mutation = DeleteChannelMutation;
@@ -5800,6 +5788,24 @@ export namespace CreateChannel {
     export type DefaultTaxZone = NonNullable<CreateChannelMutation['createChannel']['defaultTaxZone']>;
 }
 
+export namespace DeleteProductVariant {
+    export type Variables = DeleteProductVariantMutationVariables;
+    export type Mutation = DeleteProductVariantMutation;
+    export type DeleteProductVariant = DeleteProductVariantMutation['deleteProductVariant'];
+}
+
+export namespace AssignProductsToChannel {
+    export type Variables = AssignProductsToChannelMutationVariables;
+    export type Mutation = AssignProductsToChannelMutation;
+    export type AssignProductsToChannel = ProductWithVariantsFragment;
+}
+
+export namespace RemoveProductsFromChannel {
+    export type Variables = RemoveProductsFromChannelMutationVariables;
+    export type Mutation = RemoveProductsFromChannelMutation;
+    export type RemoveProductsFromChannel = ProductWithVariantsFragment;
+}
+
 export namespace UpdateOptionGroup {
     export type Variables = UpdateOptionGroupMutationVariables;
     export type Mutation = UpdateOptionGroupMutation;
@@ -5993,12 +5999,6 @@ export namespace GetOptionGroup {
     export type Options = NonNullable<(NonNullable<GetOptionGroupQuery['productOptionGroup']>)['options'][0]>;
 }
 
-export namespace DeleteProductVariant {
-    export type Variables = DeleteProductVariantMutationVariables;
-    export type Mutation = DeleteProductVariantMutation;
-    export type DeleteProductVariant = DeleteProductVariantMutation['deleteProductVariant'];
-}
-
 export namespace DeletePromotion {
     export type Variables = DeletePromotionMutationVariables;
     export type Mutation = DeletePromotionMutation;

+ 0 - 5
packages/core/src/plugin/default-search-plugin/indexer/indexer.controller.ts

@@ -15,7 +15,6 @@ import { ProductVariant } from '../../../entity/product-variant/product-variant.
 import { Product } from '../../../entity/product/product.entity';
 import { translateDeep } from '../../../service/helpers/utils/translate-entity';
 import { ProductVariantService } from '../../../service/services/product-variant.service';
-import { TaxRateService } from '../../../service/services/tax-rate.service';
 import { AsyncQueue } from '../async-queue';
 import { SearchIndexItem } from '../search-index-item.entity';
 import {
@@ -52,7 +51,6 @@ export class IndexerController {
     constructor(
         @InjectConnection() private connection: Connection,
         private productVariantService: ProductVariantService,
-        private taxRateService: TaxRateService,
     ) {}
 
     @MessagePattern(ReindexMessage.pattern)
@@ -69,9 +67,6 @@ export class IndexerController {
                 );
                 const batches = Math.ceil(count / BATCH_SIZE);
 
-                // Ensure tax rates are up-to-date.
-                await this.taxRateService.updateActiveTaxRates();
-
                 await this.connection
                     .getRepository(SearchIndexItem)
                     .delete({ languageCode: ctx.languageCode, channelId: ctx.channelId });

+ 22 - 0
packages/core/src/service/controllers/tax-rate.controller.ts

@@ -0,0 +1,22 @@
+import { Controller } from '@nestjs/common';
+import { MessagePattern } from '@nestjs/microservices';
+import { InjectConnection } from '@nestjs/typeorm';
+import { from, Observable } from 'rxjs';
+import { Connection } from 'typeorm';
+
+import { TaxRateService } from '../services/tax-rate.service';
+import { TaxRateUpdatedMessage } from '../types/tax-rate-messages';
+
+@Controller()
+export class TaxRateController {
+    constructor(@InjectConnection() private connection: Connection, private taxRateService: TaxRateService) {}
+
+    /**
+     * When a TaxRate is updated on the main process, this will update the activeTaxRates
+     * cache on the worker.
+     */
+    @MessagePattern(TaxRateUpdatedMessage.pattern)
+    taxRateUpdated(): Observable<TaxRateUpdatedMessage['response']> {
+        return from(this.taxRateService.updateActiveTaxRates().then(() => true));
+    }
+}

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

@@ -15,6 +15,7 @@ import { OrderLine } from '../../../entity/order-line/order-line.entity';
 import { Order } from '../../../entity/order/order.entity';
 import { TaxCategory } from '../../../entity/tax-category/tax-category.entity';
 import { EventBus } from '../../../event-bus/event-bus';
+import { WorkerService } from '../../../worker/worker.service';
 import { TaxRateService } from '../../services/tax-rate.service';
 import { ZoneService } from '../../services/zone.service';
 import { ListQueryBuilder } from '../list-query-builder/list-query-builder';
@@ -42,6 +43,7 @@ describe('OrderCalculator', () => {
                 { provide: ListQueryBuilder, useValue: {} },
                 { provide: ConfigService, useClass: MockConfigService },
                 { provide: EventBus, useValue: { publish: () => ({}) } },
+                { provide: WorkerService, useValue: { send: () => ({}) } },
                 { provide: ZoneService, useValue: { findAll: () => [] } },
             ],
         }).compile();

+ 2 - 0
packages/core/src/service/helpers/tax-calculator/tax-calculator.spec.ts

@@ -5,6 +5,7 @@ import { ConfigService } from '../../../config/config.service';
 import { MockConfigService } from '../../../config/config.service.mock';
 import { DefaultTaxCalculationStrategy } from '../../../config/tax/default-tax-calculation-strategy';
 import { EventBus } from '../../../event-bus/event-bus';
+import { WorkerService } from '../../../worker/worker.service';
 import { TaxRateService } from '../../services/tax-rate.service';
 import { ListQueryBuilder } from '../list-query-builder/list-query-builder';
 
@@ -36,6 +37,7 @@ describe('TaxCalculator', () => {
                 { provide: Connection, useClass: MockConnection },
                 { provide: ListQueryBuilder, useValue: {} },
                 { provide: EventBus, useValue: { publish: () => ({}) } },
+                { provide: WorkerService, useValue: { send: () => ({}) } },
             ],
         }).compile();
 

+ 2 - 1
packages/core/src/service/service.module.ts

@@ -7,6 +7,7 @@ import { EventBusModule } from '../event-bus/event-bus.module';
 import { WorkerServiceModule } from '../worker/worker-service.module';
 
 import { CollectionController } from './controllers/collection.controller';
+import { TaxRateController } from './controllers/tax-rate.controller';
 import { ListQueryBuilder } from './helpers/list-query-builder/list-query-builder';
 import { OrderCalculator } from './helpers/order-calculator/order-calculator';
 import { OrderMerger } from './helpers/order-merger/order-merger';
@@ -96,7 +97,7 @@ const helpers = [
     ShippingConfiguration,
 ];
 
-const workerControllers = [CollectionController];
+const workerControllers = [CollectionController, TaxRateController];
 
 let defaultTypeOrmModule: DynamicModule;
 let workerTypeOrmModule: DynamicModule;

+ 5 - 0
packages/core/src/service/services/tax-rate.service.ts

@@ -13,9 +13,11 @@ import { TaxRate } from '../../entity/tax-rate/tax-rate.entity';
 import { Zone } from '../../entity/zone/zone.entity';
 import { EventBus } from '../../event-bus/event-bus';
 import { TaxRateModificationEvent } from '../../event-bus/events/tax-rate-modification-event';
+import { WorkerService } from '../../worker/worker.service';
 import { ListQueryBuilder } from '../helpers/list-query-builder/list-query-builder';
 import { getEntityOrThrow } from '../helpers/utils/get-entity-or-throw';
 import { patchEntity } from '../helpers/utils/patch-entity';
+import { TaxRateUpdatedMessage } from '../types/tax-rate-messages';
 
 export class TaxRateService {
     /**
@@ -34,6 +36,7 @@ export class TaxRateService {
         @InjectConnection() private connection: Connection,
         private eventBus: EventBus,
         private listQueryBuilder: ListQueryBuilder,
+        private workerService: WorkerService,
     ) {}
 
     async initTaxRates() {
@@ -69,6 +72,7 @@ export class TaxRateService {
         }
         const newTaxRate = await this.connection.getRepository(TaxRate).save(taxRate);
         await this.updateActiveTaxRates();
+        await this.workerService.send(new TaxRateUpdatedMessage(newTaxRate.id)).toPromise();
         this.eventBus.publish(new TaxRateModificationEvent(ctx, newTaxRate));
         return assertFound(this.findOne(newTaxRate.id));
     }
@@ -94,6 +98,7 @@ export class TaxRateService {
         }
         await this.connection.getRepository(TaxRate).save(updatedTaxRate);
         await this.updateActiveTaxRates();
+        await this.workerService.send(new TaxRateUpdatedMessage(updatedTaxRate.id)).toPromise();
         this.eventBus.publish(new TaxRateModificationEvent(ctx, updatedTaxRate));
         return assertFound(this.findOne(taxRate.id));
     }

+ 10 - 0
packages/core/src/service/types/tax-rate-messages.ts

@@ -0,0 +1,10 @@
+import { ID } from '@vendure/common/lib/shared-types';
+
+import { WorkerMessage } from '../../worker/types';
+
+/**
+ * A message sent to the Worker whenever a TaxRate is updated.
+ */
+export class TaxRateUpdatedMessage extends WorkerMessage<ID, boolean> {
+    static readonly pattern = 'TaxRateUpdated';
+}