Skip to content

Commit

Permalink
feat(core): Add validation to Promotion conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbromley committed Oct 9, 2019
1 parent e615d2f commit 74e7444
Showing 1 changed file with 23 additions and 14 deletions.
37 changes: 23 additions & 14 deletions packages/core/src/service/services/promotion.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand All @@ -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> {
Expand Down Expand Up @@ -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');
}
}
}

0 comments on commit 74e7444

Please sign in to comment.