Browse Source

refactor(server): Extract shared code from promotions actions

Michael Bromley 7 years ago
parent
commit
127d03ee3a

+ 22 - 0
server/src/common/types/common-types.graphql

@@ -18,6 +18,28 @@ type Adjustment {
     amount: Int!
 }
 
+type AdjustmentArg {
+    name: String!
+    type: String!
+    value: String
+}
+
+type AdjustmentOperation {
+    code: String!
+    args: [AdjustmentArg!]!
+    description: String!
+}
+
+input AdjustmentOperationInputArg {
+    name: String!
+    value: String!
+}
+
+input AdjustmentOperationInput {
+    code: String!
+    arguments: [AdjustmentOperationInputArg!]!
+}
+
 interface PaginatedList {
     items: [Node!]!
     totalItems: Int!

+ 37 - 0
server/src/config/common/adjustments.ts

@@ -0,0 +1,37 @@
+import { AdjustmentArg } from 'shared/generated-types';
+
+export type ValidArgTypes = 'percentage' | 'money' | 'int' | 'string' | 'datetime' | 'boolean';
+
+export type AdjustmentArgs<T extends ValidArgTypes> = {
+    [name: string]: T;
+};
+
+export type ArgumentValues<T extends AdjustmentArgs<any>> = {
+    [K in keyof T]: T[K] extends 'int' | 'money' | 'percentage'
+        ? number
+        : T[K] extends 'datetime' ? Date : T[K] extends 'boolean' ? boolean : string
+};
+
+export function argsArrayToHash<T>(args: AdjustmentArg[]): ArgumentValues<T> {
+    const output: ArgumentValues<T> = {} as any;
+    for (const arg of args) {
+        if (arg.value != null) {
+            output[arg.name] = coerceValueToType<T>(arg);
+        }
+    }
+    return output;
+}
+
+function coerceValueToType<T>(arg: AdjustmentArg): ArgumentValues<T>[keyof T] {
+    switch (arg.type as ValidArgTypes) {
+        case 'int':
+        case 'money':
+            return Number.parseInt(arg.value || '', 10) as any;
+        case 'datetime':
+            return Date.parse(arg.value || '') as any;
+        case 'boolean':
+            return !!arg.value as any;
+        default:
+            return (arg.value as string) as any;
+    }
+}

+ 6 - 17
server/src/config/promotion/promotion-action.ts

@@ -1,14 +1,13 @@
-import { Adjustment, AdjustmentArg } from 'shared/generated-types';
+import { AdjustmentArg } from 'shared/generated-types';
 
 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 { AdjustmentArgs, argsArrayToHash, ArgumentValues } from '../common/adjustments';
 
 export type PromotionActionArgType = 'percentage' | 'money';
-export type PromotionActionArgs = {
-    [name: string]: PromotionActionArgType;
-};
-export type ArgumentValues<T extends PromotionActionArgs> = { [K in keyof T]: number };
+export type PromotionActionArgs = AdjustmentArgs<PromotionActionArgType>;
+
 export type ExecutePromotionItemActionFn<T extends PromotionActionArgs> = (
     orderItem: OrderItem,
     orderLine: OrderLine,
@@ -44,16 +43,6 @@ export abstract class PromotionAction<T extends PromotionActionArgs = {}> {
         this.args = config.args;
         this.priorityValue = config.priorityValue || 0;
     }
-
-    protected argsArrayToHash(args: AdjustmentArg[]): ArgumentValues<T> {
-        const output: ArgumentValues<T> = {} as any;
-        for (const arg of args) {
-            if (arg.value != null) {
-                output[arg.name] = Number.parseInt(arg.value || '', 10);
-            }
-        }
-        return output;
-    }
 }
 
 /**
@@ -67,7 +56,7 @@ export class PromotionItemAction<T extends PromotionActionArgs = {}> extends Pro
     }
 
     execute(orderItem: OrderItem, orderLine: OrderLine, args: AdjustmentArg[]) {
-        return this.executeFn(orderItem, orderLine, this.argsArrayToHash(args));
+        return this.executeFn(orderItem, orderLine, argsArrayToHash(args));
     }
 }
 
@@ -82,6 +71,6 @@ export class PromotionOrderAction<T extends PromotionActionArgs = {}> extends Pr
     }
 
     execute(order: Order, args: AdjustmentArg[]) {
-        return this.executeFn(order, this.argsArrayToHash(args));
+        return this.executeFn(order, argsArrayToHash(args));
     }
 }

+ 4 - 36
server/src/config/promotion/promotion-condition.ts

@@ -1,17 +1,10 @@
-import { AdjustmentArg, AdjustmentOperation } from 'shared/generated-types';
+import { AdjustmentArg } from 'shared/generated-types';
 
 import { Order } from '../../entity/order/order.entity';
+import { AdjustmentArgs, argsArrayToHash, ArgumentValues } from '../common/adjustments';
 
 export type PromotionConditionArgType = 'int' | 'money' | 'string' | 'datetime' | 'boolean';
-export type PromotionConditionArgs = {
-    [name: string]: PromotionConditionArgType;
-};
-export type ArgumentValues<T extends PromotionConditionArgs> = {
-    [K in keyof T]: T[K] extends 'int' | 'money'
-        ? number
-        : T[K] extends 'datetime' ? Date : T[K] extends 'boolean' ? boolean : string
-};
-
+export type PromotionConditionArgs = AdjustmentArgs<PromotionConditionArgType>;
 export type CheckPromotionConditionFn<T extends PromotionConditionArgs> = (
     order: Order,
     args: ArgumentValues<T>,
@@ -39,31 +32,6 @@ export class PromotionCondition<T extends PromotionConditionArgs = {}> {
     }
 
     check(order: Order, args: AdjustmentArg[]) {
-        return this.checkFn(order, this.argsArrayToHash(args));
-    }
-
-    private argsArrayToHash(args: AdjustmentArg[]): ArgumentValues<T> {
-        const output: ArgumentValues<T> = {} as any;
-
-        for (const arg of args) {
-            if (arg.value != null) {
-                output[arg.name] = this.coerceValueToType(arg);
-            }
-        }
-        return output;
-    }
-
-    private coerceValueToType(arg: AdjustmentArg): ArgumentValues<T>[keyof T] {
-        switch (arg.type as PromotionConditionArgType) {
-            case 'int':
-            case 'money':
-                return Number.parseInt(arg.value || '', 10) as any;
-            case 'datetime':
-                return Date.parse(arg.value || '') as any;
-            case 'boolean':
-                return !!arg.value as any;
-            default:
-                return (arg.value as string) as any;
-        }
+        return this.checkFn(order, argsArrayToHash<T>(args));
     }
 }

+ 0 - 23
server/src/entity/promotion/promotion.graphql

@@ -8,29 +8,6 @@ type Promotion implements Node {
     actions: [AdjustmentOperation!]!
 }
 
-
-type AdjustmentArg {
-    name: String!
-    type: String!
-    value: String
-}
-
-type AdjustmentOperation {
-    code: String!
-    args: [AdjustmentArg!]!
-    description: String!
-}
-
-input AdjustmentOperationInputArg {
-    name: String!
-    value: String!
-}
-
-input AdjustmentOperationInput {
-    code: String!
-    arguments: [AdjustmentOperationInputArg!]!
-}
-
 input CreatePromotionInput {
     name: String!
     enabled: Boolean!