import { schema } from 'nexus' import * as Auth from '../../utils/auth' export const PromoCode = schema.objectType({ name: 'PromoCode', definition(t) { t.model.id() t.model.createdAt() t.model.updatedAt() t.model.title() t.model.description() t.model.value() t.model.isFromWalter() t.model.isPercentage() t.model.isOneTimeUsePerCustomer() t.model.isOneTimeUse() t.model.canBeUse() t.model.order() }, }) export const PromoCodeQueries = schema.extendType({ type: 'Query', definition(t) { t.crud.promoCode() t.crud.promoCodes({ filtering: true, ordering: true }) }, }) export const PromoCodeMutation = schema.extendType({ type: 'Mutation', definition: (t) => { t.crud.createOnePromoCode({ alias: 'createPromoCode' }) t.crud.deleteOnePromoCode({ alias: 'deletePromoCode' }) t.crud.updateOnePromoCode({ alias: 'updatePromoCode' }) t.field('getAndVerifyPromoCodeForCurrentUser', { type: 'PromoCode', args: { promoCodeTitle: schema.stringArg(), }, resolve: async (parent, { promoCodeTitle }, ctx: NexusContext) => { const currentUserId = Auth.getUserId(ctx) const promoCode = await ctx.prisma.promoCode.findOne({ where: { title: promoCodeTitle } }) if (!promoCode) { throw new Error('Invalid promo code') } if (promoCode.isOneTimeUse) { const ordersWithThisPromoCode = await ctx.prisma.order.findMany({ where: { promoCodes: { some: { title: promoCodeTitle, }, }, }, }) if (ordersWithThisPromoCode.length > 0) { throw new Error('This promo code has already been used') } } if (promoCode.isOneTimeUsePerCustomer) { const ordersWithThisPromoCodeByCurrentUser = await ctx.prisma.order.findMany({ where: { AND: [ { promoCodes: { some: { title: promoCodeTitle }, }, }, { customer: { id: currentUserId, }, }, ], }, }) if (ordersWithThisPromoCodeByCurrentUser.length > 0) { throw new Error("You've already used this promo code") } } return promoCode }, }) }, })