Browse Source

refactor(core): Make ShippingConfigService more general

Michael Bromley 5 years ago
parent
commit
ea24ad212e

+ 1 - 1
packages/core/src/config/config.service.ts

@@ -71,7 +71,7 @@ export class ConfigService implements VendureConfig {
         return this.activeConfig.dbConnectionOptions;
     }
 
-    get promotionOptions(): PromotionOptions {
+    get promotionOptions(): Required<PromotionOptions> {
         return this.activeConfig.promotionOptions;
     }
 

+ 1 - 0
packages/core/src/i18n/messages/en.json

@@ -26,6 +26,7 @@
     "forbidden": "You are not currently authorized to perform this action",
     "invalid-sort-field": "The sort field '{ fieldName }' is invalid. Valid fields are: { validFields }",
     "no-active-tax-zone": "The active tax zone could not be determined. Ensure a default tax zone is set for the current channel.",
+    "no-configurable-operation-def-with-code-found": "No { type } with the code '{ code }' could be found",
     "no-search-plugin-configured": "No search plugin has been configured",
     "order-does-not-contain-line-with-id": "This order does not contain an OrderLine with the id { id }",
     "pending-identifier-missing": "Could not find the pending email address to update",

+ 76 - 0
packages/core/src/service/helpers/config-arg/config-arg.service.ts

@@ -0,0 +1,76 @@
+import { Injectable } from '@nestjs/common';
+import { ConfigurableOperationInput } from '@vendure/common/lib/generated-types';
+import { Type } from '@vendure/common/lib/shared-types';
+
+import { ConfigurableOperation } from '../../../../../common/lib/generated-types';
+import { ConfigurableOperationDef } from '../../../common/configurable-operation';
+import { UserInputError } from '../../../common/error/errors';
+import { CollectionFilter } from '../../../config/catalog/collection-filter';
+import { ConfigService } from '../../../config/config.service';
+import { FulfillmentHandler } from '../../../config/fulfillment/fulfillment-handler';
+import { PaymentMethodHandler } from '../../../config/payment-method/payment-method-handler';
+import { PromotionAction } from '../../../config/promotion/promotion-action';
+import { ShippingCalculator } from '../../../config/shipping-method/shipping-calculator';
+import { ShippingEligibilityChecker } from '../../../config/shipping-method/shipping-eligibility-checker';
+
+export type ConfigDefType =
+    | 'CollectionFilter'
+    | 'FulfillmentHandler'
+    | 'PaymentMethodHandler'
+    | 'PromotionAction'
+    | 'PromotionCondition'
+    | 'ShippingCalculator'
+    | 'ShippingEligibilityChecker';
+
+/**
+ * This helper class provides methods relating to ConfigurableOperationDef instances.
+ */
+@Injectable()
+export class ConfigArgService {
+    private readonly definitionsByType: { [K in ConfigDefType]: ConfigurableOperationDef[] };
+
+    constructor(private configService: ConfigService) {
+        this.definitionsByType = {
+            CollectionFilter: this.configService.catalogOptions.collectionFilters,
+            FulfillmentHandler: this.configService.shippingOptions.fulfillmentHandlers,
+            PaymentMethodHandler: this.configService.paymentOptions.paymentMethodHandlers,
+            PromotionAction: this.configService.promotionOptions.promotionActions,
+            PromotionCondition: this.configService.promotionOptions.promotionConditions,
+            ShippingCalculator: this.configService.shippingOptions.shippingCalculators,
+            ShippingEligibilityChecker: this.configService.shippingOptions.shippingEligibilityCheckers,
+        };
+    }
+
+    getDefinitions(defType: ConfigDefType): ConfigurableOperationDef[] {
+        return this.definitionsByType[defType];
+    }
+
+    parseInput(defType: ConfigDefType, input: ConfigurableOperationInput): ConfigurableOperation {
+        const defsOfType = this.definitionsByType[defType];
+        const match = defsOfType.find(def => def.code === input.code);
+        if (!match) {
+            throw new UserInputError(`error.no-configurable-operation-def-with-code-found`, {
+                code: input.code,
+                type: defType,
+            });
+        }
+        return {
+            code: input.code,
+            args: input.arguments,
+        };
+    }
+
+    /**
+     * Converts the input values of the "create" and "update" mutations into the format expected by the ShippingMethod entity.
+     */
+    private parseOperationArgs(
+        input: ConfigurableOperationInput,
+        checkerOrCalculator: ShippingEligibilityChecker | ShippingCalculator,
+    ): ConfigurableOperation {
+        const output: ConfigurableOperation = {
+            code: input.code,
+            args: input.arguments,
+        };
+        return output;
+    }
+}

+ 0 - 67
packages/core/src/service/helpers/shipping-configuration/shipping-configuration.ts

@@ -1,67 +0,0 @@
-import { Injectable } from '@nestjs/common';
-import { ConfigurableOperationInput } from '@vendure/common/lib/generated-types';
-
-import { ConfigurableOperation } from '../../../../../common/lib/generated-types';
-import { UserInputError } from '../../../common/error/errors';
-import { ConfigService } from '../../../config/config.service';
-import { FulfillmentHandler } from '../../../config/fulfillment/fulfillment-handler';
-import { ShippingCalculator } from '../../../config/shipping-method/shipping-calculator';
-import { ShippingEligibilityChecker } from '../../../config/shipping-method/shipping-eligibility-checker';
-
-/**
- * This helper class provides methods relating to ShippingMethod configurable operations (eligibility checkers, calculators
- * and fulfillment handlers).
- */
-@Injectable()
-export class ShippingConfiguration {
-    readonly shippingEligibilityCheckers: ShippingEligibilityChecker[];
-    readonly shippingCalculators: ShippingCalculator[];
-    readonly fulfillmentHandlers: FulfillmentHandler[];
-
-    constructor(private configService: ConfigService) {
-        this.shippingEligibilityCheckers =
-            this.configService.shippingOptions.shippingEligibilityCheckers || [];
-        this.shippingCalculators = this.configService.shippingOptions.shippingCalculators || [];
-        this.fulfillmentHandlers = this.configService.shippingOptions.fulfillmentHandlers || [];
-    }
-
-    parseCheckerInput(input: ConfigurableOperationInput): ConfigurableOperation {
-        const checker = this.getChecker(input.code);
-        return this.parseOperationArgs(input, checker);
-    }
-
-    parseCalculatorInput(input: ConfigurableOperationInput): ConfigurableOperation {
-        const calculator = this.getCalculator(input.code);
-        return this.parseOperationArgs(input, calculator);
-    }
-
-    /**
-     * Converts the input values of the "create" and "update" mutations into the format expected by the ShippingMethod entity.
-     */
-    private parseOperationArgs(
-        input: ConfigurableOperationInput,
-        checkerOrCalculator: ShippingEligibilityChecker | ShippingCalculator,
-    ): ConfigurableOperation {
-        const output: ConfigurableOperation = {
-            code: input.code,
-            args: input.arguments,
-        };
-        return output;
-    }
-
-    private getChecker(code: string): ShippingEligibilityChecker {
-        const match = this.shippingEligibilityCheckers.find(a => a.code === code);
-        if (!match) {
-            throw new UserInputError(`error.shipping-eligibility-checker-with-code-not-found`, { code });
-        }
-        return match;
-    }
-
-    private getCalculator(code: string): ShippingCalculator {
-        const match = this.shippingCalculators.find(a => a.code === code);
-        if (!match) {
-            throw new UserInputError(`error.shipping-calculator-with-code-not-found`, { code });
-        }
-        return match;
-    }
-}

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

@@ -11,6 +11,7 @@ import { WorkerServiceModule } from '../worker/worker-service.module';
 
 import { CollectionController } from './controllers/collection.controller';
 import { TaxRateController } from './controllers/tax-rate.controller';
+import { ConfigArgService } from './helpers/config-arg/config-arg.service';
 import { ExternalAuthenticationService } from './helpers/external-authentication/external-authentication.service';
 import { FulfillmentStateMachine } from './helpers/fulfillment-state-machine/fulfillment-state-machine';
 import { ListQueryBuilder } from './helpers/list-query-builder/list-query-builder';
@@ -22,7 +23,6 @@ import { PasswordCiper } from './helpers/password-cipher/password-ciper';
 import { PaymentStateMachine } from './helpers/payment-state-machine/payment-state-machine';
 import { RefundStateMachine } from './helpers/refund-state-machine/refund-state-machine';
 import { ShippingCalculator } from './helpers/shipping-calculator/shipping-calculator';
-import { ShippingConfiguration } from './helpers/shipping-configuration/shipping-configuration';
 import { SlugValidator } from './helpers/slug-validator/slug-validator';
 import { TranslatableSaver } from './helpers/translatable-saver/translatable-saver';
 import { VerificationTokenGenerator } from './helpers/verification-token-generator/verification-token-generator';
@@ -105,7 +105,7 @@ const helpers = [
     ShippingCalculator,
     VerificationTokenGenerator,
     RefundStateMachine,
-    ShippingConfiguration,
+    ConfigArgService,
     SlugValidator,
     ExternalAuthenticationService,
     TransactionalConnection,

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

@@ -18,9 +18,9 @@ import { Order } from '../../entity/order/order.entity';
 import { ProductVariant } from '../../entity/product-variant/product-variant.entity';
 import { ShippingLine } from '../../entity/shipping-line/shipping-line.entity';
 import { ShippingMethod } from '../../entity/shipping-method/shipping-method.entity';
+import { ConfigArgService } from '../helpers/config-arg/config-arg.service';
 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';
 
@@ -36,7 +36,7 @@ export class OrderTestingService {
         private connection: TransactionalConnection,
         private orderCalculator: OrderCalculator,
         private shippingCalculator: ShippingCalculator,
-        private shippingConfiguration: ShippingConfiguration,
+        private configArgService: ConfigArgService,
         private configService: ConfigService,
         private productVariantService: ProductVariantService,
     ) {}
@@ -50,8 +50,8 @@ export class OrderTestingService {
         input: TestShippingMethodInput,
     ): Promise<TestShippingMethodResult> {
         const shippingMethod = new ShippingMethod({
-            checker: this.shippingConfiguration.parseCheckerInput(input.checker),
-            calculator: this.shippingConfiguration.parseCalculatorInput(input.calculator),
+            checker: this.configArgService.parseInput('ShippingEligibilityChecker', input.checker),
+            calculator: this.configArgService.parseInput('ShippingCalculator', input.calculator),
         });
         const mockOrder = await this.buildMockOrder(ctx, input.shippingAddress, input.lines);
         const eligible = await shippingMethod.test(ctx, mockOrder);

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

@@ -847,12 +847,7 @@ export class OrderService {
         ctx: RequestContext,
         input: FulfillOrderInput,
     ): Promise<ErrorResultUnion<AddFulfillmentToOrderResult, Fulfillment>> {
-        if (
-            !input.lines ||
-            input.lines.length === 0 ||
-            input.lines.length === 0 ||
-            summate(input.lines, 'quantity') === 0
-        ) {
+        if (!input.lines || input.lines.length === 0 || summate(input.lines, 'quantity') === 0) {
             return new EmptyOrderLineSelectionError();
         }
         const ordersAndItems = await this.getOrdersAndItemsFromLines(

+ 18 - 9
packages/core/src/service/services/shipping-method.service.ts

@@ -18,8 +18,8 @@ import { Logger } from '../../config/logger/vendure-logger';
 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 { ConfigArgService } from '../helpers/config-arg/config-arg.service';
 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';
@@ -36,7 +36,7 @@ export class ShippingMethodService {
         private configService: ConfigService,
         private listQueryBuilder: ListQueryBuilder,
         private channelService: ChannelService,
-        private shippingConfiguration: ShippingConfiguration,
+        private configArgService: ConfigArgService,
         private translatableSaver: TranslatableSaver,
     ) {}
 
@@ -92,8 +92,11 @@ export class ShippingMethodService {
                     method.code,
                     input.fulfillmentHandler,
                 );
-                method.checker = this.shippingConfiguration.parseCheckerInput(input.checker);
-                method.calculator = this.shippingConfiguration.parseCalculatorInput(input.calculator);
+                method.checker = this.configArgService.parseInput(
+                    'ShippingEligibilityChecker',
+                    input.checker,
+                );
+                method.calculator = this.configArgService.parseInput('ShippingCalculator', input.calculator);
             },
         });
         this.channelService.assignToCurrentChannel(shippingMethod, ctx);
@@ -116,10 +119,14 @@ export class ShippingMethodService {
             translationType: ShippingMethodTranslation,
         });
         if (input.checker) {
-            updatedShippingMethod.checker = this.shippingConfiguration.parseCheckerInput(input.checker);
+            updatedShippingMethod.checker = this.configArgService.parseInput(
+                'ShippingEligibilityChecker',
+                input.checker,
+            );
         }
         if (input.calculator) {
-            updatedShippingMethod.calculator = this.shippingConfiguration.parseCalculatorInput(
+            updatedShippingMethod.calculator = this.configArgService.parseInput(
+                'ShippingCalculator',
                 input.calculator,
             );
         }
@@ -150,15 +157,17 @@ export class ShippingMethodService {
     }
 
     getShippingEligibilityCheckers(ctx: RequestContext): ConfigurableOperationDefinition[] {
-        return this.shippingConfiguration.shippingEligibilityCheckers.map(x => x.toGraphQlType(ctx));
+        return this.configArgService
+            .getDefinitions('ShippingEligibilityChecker')
+            .map(x => x.toGraphQlType(ctx));
     }
 
     getShippingCalculators(ctx: RequestContext): ConfigurableOperationDefinition[] {
-        return this.shippingConfiguration.shippingCalculators.map(x => x.toGraphQlType(ctx));
+        return this.configArgService.getDefinitions('ShippingCalculator').map(x => x.toGraphQlType(ctx));
     }
 
     getFulfillmentHandlers(ctx: RequestContext): ConfigurableOperationDefinition[] {
-        return this.shippingConfiguration.fulfillmentHandlers.map(x => x.toGraphQlType(ctx));
+        return this.configArgService.getDefinitions('FulfillmentHandler').map(x => x.toGraphQlType(ctx));
     }
 
     getActiveShippingMethods(channel: Channel): ShippingMethod[] {