|
|
@@ -1,4 +1,5 @@
|
|
|
import { ConfigArg } from '@vendure/common/lib/generated-types';
|
|
|
+import { pick } from '@vendure/common/lib/pick';
|
|
|
|
|
|
import { RequestContext } from '../../api/common/request-context';
|
|
|
import {
|
|
|
@@ -7,11 +8,24 @@ import {
|
|
|
ConfigurableOperationDef,
|
|
|
ConfigurableOperationDefOptions,
|
|
|
} from '../../common/configurable-operation';
|
|
|
+import { PromotionState } from '../../entity';
|
|
|
import { OrderItem } from '../../entity/order-item/order-item.entity';
|
|
|
import { OrderLine } from '../../entity/order-line/order-line.entity';
|
|
|
import { Order } from '../../entity/order/order.entity';
|
|
|
import { ShippingLine } from '../../entity/shipping-line/shipping-line.entity';
|
|
|
|
|
|
+import { PromotionConditionState } from './promotion-condition';
|
|
|
+
|
|
|
+
|
|
|
+export type ConditionConfig = {
|
|
|
+ [name: string]: { required?: boolean };
|
|
|
+}
|
|
|
+export type ConditionRequiredKeys<U extends ConditionConfig, value extends true | false> =
|
|
|
+ NonNullable<{ [K in keyof U]: value extends U[K]['required'] ? K : never }[keyof U]>;
|
|
|
+export type ConditionalState<U extends ConditionConfig> = {
|
|
|
+ [K in keyof U]: U[K]['required'] extends true ? PromotionConditionState : PromotionConditionState | undefined;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* @description
|
|
|
* The function which is used by a PromotionItemAction to calculate the
|
|
|
@@ -20,11 +34,12 @@ import { ShippingLine } from '../../entity/shipping-line/shipping-line.entity';
|
|
|
* @docsCategory promotions
|
|
|
* @docsPage promotion-action
|
|
|
*/
|
|
|
-export type ExecutePromotionItemActionFn<T extends ConfigArgs> = (
|
|
|
+export type ExecutePromotionItemActionFn<T extends ConfigArgs, U extends ConditionConfig> = (
|
|
|
ctx: RequestContext,
|
|
|
orderItem: OrderItem,
|
|
|
orderLine: OrderLine,
|
|
|
args: ConfigArgValues<T>,
|
|
|
+ state: ConditionalState<U>,
|
|
|
) => number | Promise<number>;
|
|
|
|
|
|
/**
|
|
|
@@ -35,10 +50,11 @@ export type ExecutePromotionItemActionFn<T extends ConfigArgs> = (
|
|
|
* @docsCategory promotions
|
|
|
* @docsPage promotion-action
|
|
|
*/
|
|
|
-export type ExecutePromotionOrderActionFn<T extends ConfigArgs> = (
|
|
|
+export type ExecutePromotionOrderActionFn<T extends ConfigArgs, U extends ConditionConfig> = (
|
|
|
ctx: RequestContext,
|
|
|
order: Order,
|
|
|
args: ConfigArgValues<T>,
|
|
|
+ state: ConditionalState<U>,
|
|
|
) => number | Promise<number>;
|
|
|
|
|
|
/**
|
|
|
@@ -49,15 +65,19 @@ export type ExecutePromotionOrderActionFn<T extends ConfigArgs> = (
|
|
|
* @docsCategory promotions
|
|
|
* @docsPage promotion-action
|
|
|
*/
|
|
|
-export type ExecutePromotionShippingActionFn<T extends ConfigArgs> = (
|
|
|
+export type ExecutePromotionShippingActionFn<T extends ConfigArgs, U extends ConditionConfig> = (
|
|
|
ctx: RequestContext,
|
|
|
shippingLine: ShippingLine,
|
|
|
order: Order,
|
|
|
args: ConfigArgValues<T>,
|
|
|
+ state: ConditionalState<U>,
|
|
|
) => number | Promise<number>;
|
|
|
|
|
|
-export interface PromotionActionConfig<T extends ConfigArgs> extends ConfigurableOperationDefOptions<T> {
|
|
|
+
|
|
|
+export interface PromotionActionConfig<T extends ConfigArgs, U extends ConditionConfig>
|
|
|
+ extends ConfigurableOperationDefOptions<T> {
|
|
|
priorityValue?: number;
|
|
|
+ conditions?: U;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -67,12 +87,13 @@ export interface PromotionActionConfig<T extends ConfigArgs> extends Configurabl
|
|
|
* @docsCategory promotions
|
|
|
* @docsPage promotion-action
|
|
|
*/
|
|
|
-export interface PromotionItemActionConfig<T extends ConfigArgs> extends PromotionActionConfig<T> {
|
|
|
+export interface PromotionItemActionConfig<T extends ConfigArgs, U extends ConditionConfig>
|
|
|
+ extends PromotionActionConfig<T, U> {
|
|
|
/**
|
|
|
* @description
|
|
|
* The function which contains the promotion calculation logic.
|
|
|
*/
|
|
|
- execute: ExecutePromotionItemActionFn<T>;
|
|
|
+ execute: ExecutePromotionItemActionFn<T, U>;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -81,12 +102,13 @@ export interface PromotionItemActionConfig<T extends ConfigArgs> extends Promoti
|
|
|
* @docsCategory promotions
|
|
|
* @docsPage promotion-action
|
|
|
*/
|
|
|
-export interface PromotionOrderActionConfig<T extends ConfigArgs> extends PromotionActionConfig<T> {
|
|
|
+export interface PromotionOrderActionConfig<T extends ConfigArgs, U extends ConditionConfig>
|
|
|
+ extends PromotionActionConfig<T, U> {
|
|
|
/**
|
|
|
* @description
|
|
|
* The function which contains the promotion calculation logic.
|
|
|
*/
|
|
|
- execute: ExecutePromotionOrderActionFn<T>;
|
|
|
+ execute: ExecutePromotionOrderActionFn<T, U>;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -95,12 +117,13 @@ export interface PromotionOrderActionConfig<T extends ConfigArgs> extends Promot
|
|
|
* @docsCategory promotions
|
|
|
* @docsPage promotion-action
|
|
|
*/
|
|
|
-export interface PromotionShippingActionConfig<T extends ConfigArgs> extends PromotionActionConfig<T> {
|
|
|
+export interface PromotionShippingActionConfig<T extends ConfigArgs, U extends ConditionConfig>
|
|
|
+ extends PromotionActionConfig<T, U> {
|
|
|
/**
|
|
|
* @description
|
|
|
* The function which contains the promotion calculation logic.
|
|
|
*/
|
|
|
- execute: ExecutePromotionShippingActionFn<T>;
|
|
|
+ execute: ExecutePromotionShippingActionFn<T, U>;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -111,7 +134,7 @@ export interface PromotionShippingActionConfig<T extends ConfigArgs> extends Pro
|
|
|
* @docsPage promotion-action
|
|
|
* @docsWeight 0
|
|
|
*/
|
|
|
-export abstract class PromotionAction<T extends ConfigArgs = {}> extends ConfigurableOperationDef<T> {
|
|
|
+export abstract class PromotionAction<T extends ConfigArgs = {}, U extends ConditionConfig = {}> extends ConfigurableOperationDef<T> {
|
|
|
/**
|
|
|
* @description
|
|
|
* Used to determine the order of application of multiple Promotions
|
|
|
@@ -121,10 +144,12 @@ export abstract class PromotionAction<T extends ConfigArgs = {}> extends Configu
|
|
|
* @default 0
|
|
|
*/
|
|
|
readonly priorityValue: number;
|
|
|
+ readonly conditions?: U;
|
|
|
|
|
|
- protected constructor(config: PromotionActionConfig<T>) {
|
|
|
+ protected constructor(config: PromotionActionConfig<T, U>) {
|
|
|
super(config);
|
|
|
this.priorityValue = config.priorityValue || 0;
|
|
|
+ this.conditions = config.conditions;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -149,16 +174,18 @@ export abstract class PromotionAction<T extends ConfigArgs = {}> extends Configu
|
|
|
* @docsPage promotion-action
|
|
|
* @docsWeight 1
|
|
|
*/
|
|
|
-export class PromotionItemAction<T extends ConfigArgs = ConfigArgs> extends PromotionAction<T> {
|
|
|
- private readonly executeFn: ExecutePromotionItemActionFn<T>;
|
|
|
- constructor(config: PromotionItemActionConfig<T>) {
|
|
|
+export class PromotionItemAction<T extends ConfigArgs = ConfigArgs, U extends ConditionConfig = {}>
|
|
|
+ extends PromotionAction<T, U> {
|
|
|
+ private readonly executeFn: ExecutePromotionItemActionFn<T, U>;
|
|
|
+ constructor(config: PromotionItemActionConfig<T, U>) {
|
|
|
super(config);
|
|
|
this.executeFn = config.execute;
|
|
|
}
|
|
|
|
|
|
/** @internal */
|
|
|
- execute(ctx: RequestContext, orderItem: OrderItem, orderLine: OrderLine, args: ConfigArg[]) {
|
|
|
- return this.executeFn(ctx, orderItem, orderLine, this.argsArrayToHash(args));
|
|
|
+ execute(ctx: RequestContext, orderItem: OrderItem, orderLine: OrderLine, args: ConfigArg[], state: PromotionState) {
|
|
|
+ const actionState = this.conditions ? pick(state, Object.keys(this.conditions)) : {};
|
|
|
+ return this.executeFn(ctx, orderItem, orderLine, this.argsArrayToHash(args), actionState as ConditionalState<U>);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -183,16 +210,17 @@ export class PromotionItemAction<T extends ConfigArgs = ConfigArgs> extends Prom
|
|
|
* @docsPage promotion-action
|
|
|
* @docsWeight 2
|
|
|
*/
|
|
|
-export class PromotionOrderAction<T extends ConfigArgs = ConfigArgs> extends PromotionAction<T> {
|
|
|
- private readonly executeFn: ExecutePromotionOrderActionFn<T>;
|
|
|
- constructor(config: PromotionOrderActionConfig<T>) {
|
|
|
+export class PromotionOrderAction<T extends ConfigArgs = ConfigArgs, U extends ConditionConfig = {}> extends PromotionAction<T, U> {
|
|
|
+ private readonly executeFn: ExecutePromotionOrderActionFn<T, U>;
|
|
|
+ constructor(config: PromotionOrderActionConfig<T, U>) {
|
|
|
super(config);
|
|
|
this.executeFn = config.execute;
|
|
|
}
|
|
|
|
|
|
/** @internal */
|
|
|
- execute(ctx: RequestContext, order: Order, args: ConfigArg[]) {
|
|
|
- return this.executeFn(ctx, order, this.argsArrayToHash(args));
|
|
|
+ execute(ctx: RequestContext, order: Order, args: ConfigArg[], state: PromotionState) {
|
|
|
+ const actionState = this.conditions ? pick(state, Object.keys(this.conditions)) : {};
|
|
|
+ return this.executeFn(ctx, order, this.argsArrayToHash(args), actionState as ConditionalState<U>);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -204,15 +232,16 @@ export class PromotionOrderAction<T extends ConfigArgs = ConfigArgs> extends Pro
|
|
|
* @docsPage promotion-action
|
|
|
* @docsWeight 3
|
|
|
*/
|
|
|
-export class PromotionShippingAction<T extends ConfigArgs = ConfigArgs> extends PromotionAction<T> {
|
|
|
- private readonly executeFn: ExecutePromotionShippingActionFn<T>;
|
|
|
- constructor(config: PromotionShippingActionConfig<T>) {
|
|
|
+export class PromotionShippingAction<T extends ConfigArgs = ConfigArgs, U extends ConditionConfig = {}> extends PromotionAction<T, U> {
|
|
|
+ private readonly executeFn: ExecutePromotionShippingActionFn<T, U>;
|
|
|
+ constructor(config: PromotionShippingActionConfig<T, U>) {
|
|
|
super(config);
|
|
|
this.executeFn = config.execute;
|
|
|
}
|
|
|
|
|
|
/** @internal */
|
|
|
- execute(ctx: RequestContext, shippingLine: ShippingLine, order: Order, args: ConfigArg[]) {
|
|
|
- return this.executeFn(ctx, shippingLine, order, this.argsArrayToHash(args));
|
|
|
+ execute(ctx: RequestContext, shippingLine: ShippingLine, order: Order, args: ConfigArg[], state: PromotionState) {
|
|
|
+ const actionState = this.conditions ? pick(state, Object.keys(this.conditions)) : {};
|
|
|
+ return this.executeFn(ctx, shippingLine, order, this.argsArrayToHash(args), actionState as ConditionalState<U>);
|
|
|
}
|
|
|
}
|