Skip to content

Commit

Permalink
feat(core): Create OrderCodeStrategy for more control over order codes
Browse files Browse the repository at this point in the history
Closes #452

BREAKING CHANGE: The `orderOptions.generateOrderCode` config option has been replaced with `orderOptions.orderCodeStrategy`. This change allows order code generation to take advantage of the `InjectableStrategy` interface, i.e. to be able to inject Vendure services and other providers (e.g. the database connection). See the `OrderCodeStrategy` documentation for guidance on how to use the new API.
  • Loading branch information
michaelbromley committed Oct 2, 2020
1 parent 11caa23 commit 30dc639
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 5 deletions.
11 changes: 9 additions & 2 deletions packages/core/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,14 @@ export class AppModule implements NestModule, OnApplicationBootstrap, OnApplicat
const { adminAuthenticationStrategy, shopAuthenticationStrategy } = this.configService.authOptions;
const { taxCalculationStrategy, taxZoneStrategy } = this.configService.taxOptions;
const { jobQueueStrategy } = this.configService.jobQueueOptions;
const { mergeStrategy, priceCalculationStrategy } = this.configService.orderOptions;
const {
mergeStrategy,
checkoutMergeStrategy,
priceCalculationStrategy,
process,
orderCodeStrategy,
} = this.configService.orderOptions;
const { entityIdStrategy } = this.configService;
const { process } = this.configService.orderOptions;
return [
...adminAuthenticationStrategy,
...shopAuthenticationStrategy,
Expand All @@ -134,6 +139,8 @@ export class AppModule implements NestModule, OnApplicationBootstrap, OnApplicat
taxZoneStrategy,
jobQueueStrategy,
mergeStrategy,
checkoutMergeStrategy,
orderCodeStrategy,
entityIdStrategy,
priceCalculationStrategy,
...process,
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/config/default-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { DefaultLogger } from './logger/default-logger';
import { TypeOrmLogger } from './logger/typeorm-logger';
import { DefaultPriceCalculationStrategy } from './order/default-price-calculation-strategy';
import { MergeOrdersStrategy } from './order/merge-orders-strategy';
import { DefaultOrderCodeStrategy } from './order/order-code-strategy';
import { UseGuestStrategy } from './order/use-guest-strategy';
import { defaultPromotionActions, defaultPromotionConditions } from './promotion';
import { InMemorySessionCacheStrategy } from './session-cache/in-memory-session-cache-strategy';
Expand Down Expand Up @@ -105,7 +106,7 @@ export const defaultConfig: RuntimeVendureConfig = {
mergeStrategy: new MergeOrdersStrategy(),
checkoutMergeStrategy: new UseGuestStrategy(),
process: [],
generateOrderCode: () => generatePublicId(),
orderCodeStrategy: new DefaultOrderCodeStrategy(),
},
paymentOptions: {
paymentMethodHandlers: [],
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export * from './logger/noop-logger';
export * from './logger/vendure-logger';
export * from './merge-config';
export * from './order/custom-order-process';
export * from './order/order-code-strategy';
export * from './order/order-merge-strategy';
export * from './order/price-calculation-strategy';
export * from './payment-method/example-payment-method-handler';
Expand Down
52 changes: 52 additions & 0 deletions packages/core/src/config/order/order-code-strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { RequestContext } from '../../api/common/request-context';
import { generatePublicId } from '../../common/generate-public-id';
import { InjectableStrategy } from '../../common/types/injectable-strategy';

/**
* @description
* The OrderCodeStrategy determines how Order codes are generated.
* A custom strategy can be defined which e.g. integrates with an
* existing system to generate a code:
*
* @example
* ```TypeScript
* class MyOrderCodeStrategy implements OrderCodeStrategy {
* // Some imaginary service which calls out to an existing external
* // order management system.
* private mgmtService: ExternalOrderManagementService;
*
* init(injector: Injector) {
* this.mgmtService = injector.get(ExternalOrderManagementService);
* }
*
* async generate(ctx: RequestContext) {
* const result = await this.mgmtService.getAvailableOrderParams();
* return result.code;
* }
* }
* ```
*
* @docsCategory orders
* @docsPage OrderCodeStrategy
*/
export interface OrderCodeStrategy extends InjectableStrategy {
/**
* @description
* Generates the order code.
*/
generate(ctx: RequestContext): string | Promise<string>;
}

/**
* @description
* The default OrderCodeStrategy generates a random string consisting
* of 16 uppercase letters and numbers.
*
* @docsCategory orders
* @docsPage OrderCodeStrategy
*/
export class DefaultOrderCodeStrategy implements OrderCodeStrategy {
generate(ctx: RequestContext): string {
return generatePublicId();
}
}
5 changes: 4 additions & 1 deletion packages/core/src/config/vendure-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { CustomFulfillmentProcess } from './fulfillment/custom-fulfillment-proce
import { JobQueueStrategy } from './job-queue/job-queue-strategy';
import { VendureLogger } from './logger/vendure-logger';
import { CustomOrderProcess } from './order/custom-order-process';
import { OrderCodeStrategy } from './order/order-code-strategy';
import { OrderMergeStrategy } from './order/order-merge-strategy';
import { PriceCalculationStrategy } from './order/price-calculation-strategy';
import { PaymentMethodHandler } from './payment-method/payment-method-handler';
Expand Down Expand Up @@ -413,8 +414,10 @@ export interface OrderOptions {
* Note: when using a custom function for Order codes, bear in mind the database limit
* for string types (e.g. 255 chars for a varchar field in MySQL), and also the need
* for codes to be unique.
*
* @default DefaultOrderCodeStrategy
*/
generateOrderCode?: (ctx: RequestContext) => string | Promise<string>;
orderCodeStrategy?: OrderCodeStrategy;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/service/services/order.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ export class OrderService {

async create(ctx: RequestContext, userId?: ID): Promise<Order> {
const newOrder = new Order({
code: await this.configService.orderOptions.generateOrderCode(ctx),
code: await this.configService.orderOptions.orderCodeStrategy.generate(ctx),
state: this.orderStateMachine.getInitialState(),
lines: [],
couponCodes: [],
Expand Down

0 comments on commit 30dc639

Please sign in to comment.