Browse Source

feat(core): Add validation to Promotion conditions

Michael Bromley 6 years ago
parent
commit
74e7444500
1 changed files with 23 additions and 14 deletions
  1. 23 14
      packages/core/src/service/services/promotion.service.ts

+ 23 - 14
packages/core/src/service/services/promotion.service.ts

@@ -15,7 +15,7 @@ import { Connection } from 'typeorm';
 
 import { RequestContext } from '../../api/common/request-context';
 import { configurableDefToOperation } from '../../common/configurable-operation';
-import { UserInputError } from '../../common/error/errors';
+import { CouponCodeExpiredError, CouponCodeInvalidError, UserInputError } from '../../common/error/errors';
 import { ListQueryOptions } from '../../common/types/common-types';
 import { assertFound } from '../../common/utils';
 import { ConfigService } from '../../config/config.service';
@@ -82,7 +82,7 @@ export class PromotionService {
     }
 
     async createPromotion(ctx: RequestContext, input: CreatePromotionInput): Promise<Promotion> {
-        const adjustmentSource = new Promotion({
+        const promotion = new Promotion({
             name: input.name,
             enabled: input.enabled,
             couponCode: input.couponCode,
@@ -92,27 +92,27 @@ export class PromotionService {
             actions: input.actions.map(a => this.parseOperationArgs('action', a)),
             priorityScore: this.calculatePriorityScore(input),
         });
-        this.channelService.assignToChannels(adjustmentSource, ctx);
-        const newAdjustmentSource = await this.connection.manager.save(adjustmentSource);
+        this.validatePromotionConditions(promotion);
+        this.channelService.assignToChannels(promotion, ctx);
+        const newPromotion = await this.connection.manager.save(promotion);
         await this.updatePromotions();
-        return assertFound(this.findOne(newAdjustmentSource.id));
+        return assertFound(this.findOne(newPromotion.id));
     }
 
     async updatePromotion(ctx: RequestContext, input: UpdatePromotionInput): Promise<Promotion> {
-        const adjustmentSource = await getEntityOrThrow(this.connection, Promotion, input.id);
-        const updatedAdjustmentSource = patchEntity(adjustmentSource, omit(input, ['conditions', 'actions']));
+        const promotion = await getEntityOrThrow(this.connection, Promotion, input.id);
+        const updatedPromotion = patchEntity(promotion, omit(input, ['conditions', 'actions']));
         if (input.conditions) {
-            updatedAdjustmentSource.conditions = input.conditions.map(c =>
-                this.parseOperationArgs('condition', c),
-            );
+            updatedPromotion.conditions = input.conditions.map(c => this.parseOperationArgs('condition', c));
         }
         if (input.actions) {
-            updatedAdjustmentSource.actions = input.actions.map(a => this.parseOperationArgs('action', a));
+            updatedPromotion.actions = input.actions.map(a => this.parseOperationArgs('action', a));
         }
-        (adjustmentSource.priorityScore = this.calculatePriorityScore(input)),
-            await this.connection.manager.save(updatedAdjustmentSource);
+        this.validatePromotionConditions(updatedPromotion);
+        (promotion.priorityScore = this.calculatePriorityScore(input)),
+            await this.connection.manager.save(updatedPromotion);
         await this.updatePromotions();
-        return assertFound(this.findOne(updatedAdjustmentSource.id));
+        return assertFound(this.findOne(updatedPromotion.id));
     }
 
     async softDeletePromotion(promotionId: ID): Promise<DeletionResponse> {
@@ -169,4 +169,13 @@ export class PromotionService {
             where: { enabled: true },
         });
     }
+
+    /**
+     * Ensure the Promotion has at least one condition or a couponCode specified.
+     */
+    private validatePromotionConditions(promotion: Promotion) {
+        if (promotion.conditions.length === 0 && !promotion.couponCode) {
+            throw new UserInputError('error.promotion-must-have-conditions-or-coupon-code');
+        }
+    }
 }