172 lines
4.2 KiB
TypeScript
172 lines
4.2 KiB
TypeScript
import { ObjectType, Field, ID, ArgsType, InputType, registerEnumType } from 'type-graphql';
|
|
import { ApolloError } from 'apollo-server-lambda';
|
|
|
|
import { BaseGraphModel } from '@seed/graphql/BaseGraphModel';
|
|
import { Permission } from '@seed/interfaces/permission';
|
|
|
|
import { GetArgs } from '@seed/graphql/Request';
|
|
|
|
import AccountModel from '@src/accounts/account.model';
|
|
import { TranslatableComponent } from '@src/__components/components';
|
|
import { AccountTypeEnum } from '@src/accounts/account.components';
|
|
import { ApolloContext } from '@seed/interfaces/context';
|
|
import { PromoType } from './component';
|
|
|
|
const permissions: Permission = {
|
|
c: [AccountTypeEnum.admin],
|
|
r: [AccountTypeEnum.public, AccountTypeEnum.admin],
|
|
w: [AccountTypeEnum.admin],
|
|
d: [AccountTypeEnum.admin],
|
|
};
|
|
|
|
@ObjectType()
|
|
export default class PromoModel extends BaseGraphModel {
|
|
public constructor() {
|
|
super({
|
|
collectionName: 'shop.promos',
|
|
permissions: permissions,
|
|
});
|
|
}
|
|
@Field(() => ID)
|
|
readonly _id: string;
|
|
|
|
@Field()
|
|
code: string;
|
|
|
|
@Field(() => TranslatableComponent, { nullable: true })
|
|
description: TranslatableComponent;
|
|
|
|
@Field(() => PromoType)
|
|
type: PromoType;
|
|
|
|
@Field()
|
|
value: number;
|
|
|
|
@Field({ nullable: true })
|
|
validity?: Date;
|
|
|
|
@Field()
|
|
cummulable: boolean;
|
|
|
|
@Field({ nullable: true })
|
|
usageLimit?: number;
|
|
|
|
@Field()
|
|
usage: number;
|
|
|
|
searchOptions(): string[] {
|
|
return ['code'];
|
|
}
|
|
|
|
filterOptions(): string[] {
|
|
return ['code'];
|
|
}
|
|
|
|
// validatePromo = (): void => {
|
|
// try {
|
|
// if (this.usageLimit && this.usageLimit <= this.usage) {
|
|
// throw new ApolloError('promo.notValid', '404');
|
|
// }
|
|
// if (this.validity) {
|
|
// const today = new Date();
|
|
// if (this.validity < today) throw new ApolloError('promo.expired', '404');
|
|
// }
|
|
// } catch (error) {
|
|
// throw error;
|
|
// }
|
|
// };
|
|
}
|
|
|
|
@ArgsType()
|
|
export class PromoArgs {
|
|
@Field(() => GetArgs, { nullable: true })
|
|
pagination?: GetArgs;
|
|
@Field({ nullable: true })
|
|
search?: string;
|
|
}
|
|
|
|
@InputType()
|
|
export class NewPromoInput {
|
|
@Field()
|
|
code: string;
|
|
|
|
@Field(() => TranslatableComponent, { nullable: true })
|
|
description: TranslatableComponent;
|
|
|
|
@Field(() => PromoType)
|
|
type: PromoType;
|
|
|
|
@Field()
|
|
value: number;
|
|
|
|
@Field()
|
|
cummulable: boolean;
|
|
|
|
@Field({ nullable: true })
|
|
validity?: Date;
|
|
|
|
@Field({ nullable: true })
|
|
usageLimit?: number;
|
|
}
|
|
|
|
@InputType()
|
|
export class EditPromoInput {
|
|
@Field({ nullable: true })
|
|
code: string;
|
|
|
|
@Field(() => TranslatableComponent, { nullable: true })
|
|
description: TranslatableComponent;
|
|
|
|
@Field(() => PromoType, { nullable: true })
|
|
type: PromoType;
|
|
|
|
@Field({ nullable: true })
|
|
value: number;
|
|
|
|
@Field({ nullable: true })
|
|
cummulable: boolean;
|
|
|
|
@Field({ nullable: true })
|
|
validity?: Date;
|
|
|
|
@Field({ nullable: true })
|
|
usageLimit?: number;
|
|
}
|
|
|
|
export const onCreate = async (input: NewPromoInput, ctx: ApolloContext): Promise<void> => {
|
|
try {
|
|
const promo = await (await new PromoModel().db()).findOne({ code: input.code });
|
|
if (promo) {
|
|
throw new ApolloError('promo.nameTaken', '404');
|
|
}
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
export const onUpdate = async (input: EditPromoInput, ctx: ApolloContext): Promise<void> => {
|
|
try {
|
|
const promo = await (await new PromoModel().db()).findOne({ code: input.code });
|
|
if (promo) {
|
|
throw new ApolloError('promo.nameTaken', '404');
|
|
}
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
export const validatePromo = async (code: string, ctx: ApolloContext): Promise<void> => {
|
|
try {
|
|
const promo = await new PromoModel().getOne({ code }, ctx);
|
|
if (promo.usageLimit && promo.usageLimit <= promo.usage) {
|
|
throw new ApolloError('promo.notValid', '404');
|
|
}
|
|
if (promo.validity) {
|
|
const today = new Date();
|
|
if (promo.validity < today) throw new ApolloError('promo.expired', '404');
|
|
}
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
};
|