import { schema } from 'nexus' import { send as sendNotification } from '../../utils/notification' import { PackageWhereInput, PackageOrderByInput } from 'nexus-plugin-prisma/client' const PACKAGE_FRAGMENT = { id: true, title: true, description: true, isDraft: true, status: true, deliveredAt: true, client: { select: { id: true, }, }, project: { select: { id: true, name: true, managingCompany: { select: { id: true, shortName: true, longName: true, email: true, phone: { select: { number: true, }, }, address: { select: { address1: true, country: true, zip: true, city: true, apartmentNumber: true, state: true, }, }, logo: { select: { url: true, }, }, }, }, }, }, } export const Package = schema.objectType({ name: 'Package', definition(t) { t.model.id() t.model.createdAt() t.model.updatedAt() t.model.status() t.model.title() t.model.description() t.model.trackingNumber() t.model.isDraft() t.model.deliveredAt() t.model.client() t.model.project() t.model.picturesPackage() t.model.image() t.model.signatureImage() }, }) export const PackageMutation = schema.extendType({ type: 'Mutation', definition: (t) => { t.crud.deleteOnePackage({ alias: 'deletePackage' }) t.crud.updateOnePackage({ alias: 'updatePackage' }) t.crud.createOnePackage({ alias: 'createPackage' }) t.field('createPackage', { type: 'Package', args: { data: schema.arg({ type: 'PackageCreateInput' }), }, resolve: async (parent, { data }, ctx: NexusContext) => { if (data.status === 'DELIVERED') { data.deliveredAt = new Date() } const createdPackage = await ctx.prisma.package.create({ data }) if (!createdPackage.isDraft) { ctx.prisma.package .findOne({ where: { id: createdPackage.id }, select: { ...PACKAGE_FRAGMENT }, }) .then((thePackage) => thePackage.client ? ctx.prisma.user .findOne({ where: { id: thePackage.client.id }, select: { id: true, }, }) .then((user) => { sendNotification({ projectId: thePackage.project.id, users: [user], title: "You've received a package", titleFr: 'Vous avez reçu un colis', message: `You've received a new package at the reception${ thePackage.title || thePackage.description ? `: ${thePackage.title || thePackage.description}` : '' }`, messageFr: `Vous avez reçu un colis à la réception${ thePackage.title || thePackage.description ? `: ${thePackage.title || thePackage.description}` : '' }`, type: 'PACKAGE_AT_RECEPTION', data: { id: thePackage.id, }, }) }) : null ) } return createdPackage }, }) t.field('updatePackage', { type: 'Package', args: { data: schema.arg({ type: 'PackageUpdateInput' }), where: schema.arg({ type: 'PackageWhereUniqueInput' }), }, resolve: async (parent, { data, where }, ctx: NexusContext) => { const [updatedPackage, oldPackage] = await Promise.all([ ctx.prisma.package.update({ where, data }), ]) ctx.prisma.package.findOne({ where }) if (!updatedPackage.isDraft) { ctx.prisma.package .findOne({ where: { id: updatedPackage.id }, select: PACKAGE_FRAGMENT }) .then((thePackage) => { if (!thePackage.client) { return null } let notificationType let notificationTitle = 'One of your packages has been updated' let notificationTitleFr = 'Un de vos colis a été mis à jour' let notificationMessage = '' let notificationMessageFr = '' // Package is no longer in draft mode if (oldPackage && oldPackage.isDraft && updatedPackage && !updatedPackage.isDraft) { notificationType = 'PACKAGE_AT_RECEPTION' // prettier-ignore notificationTitle = 'You\'ve received a package' notificationTitleFr = 'Vous avez reçu un colis' // prettier-ignore notificationMessage = `You've received a new package at the reception: ${thePackage.title ||thePackage.description}` // prettier-ignore notificationMessageFr = `Vous avez reçu un colis à la réception: ${thePackage.title || thePackage.description}` } // Package has been delivered else if ( updatedPackage.status === 'DELIVERED' && (oldPackage === undefined || !oldPackage.status || oldPackage.status === 'AT_RECEPTION') ) { notificationType = 'PACKAGE_DELIVERED' // prettier-ignore notificationMessage = `"${thePackage.title || thePackage.description || 'Your package'}" is now "${thePackage.status}` // prettier-ignore notificationMessageFr = `"${thePackage.title || thePackage.description || 'Votre colis'}" est maintenant rendu "${thePackage.status}"` ctx.prisma.package .update({ where, data: { deliveredAt: new Date(), }, }) .catch(console.error) } // Simple package update else if ( oldPackage && (oldPackage.description !== thePackage.description || oldPackage.title !== thePackage.title) ) { notificationType = 'PACKAGE_UPDATE' // prettier-ignore notificationMessage = `"${thePackage.title || thePackage.description || 'Your package'}" informations has been updated` // prettier-ignore notificationMessageFr = `"${thePackage.title || thePackage.description || 'Votre colis'}" a été mis à jour` } else { // Don't send notification otherwise return } return ctx.prisma.user .findOne({ where: { id: thePackage.client.id }, select: { id: true, }, }) .then((user) => { sendNotification({ projectId: thePackage.project.id, users: [user], title: notificationTitle, titleFr: notificationTitleFr, message: notificationMessage, messageFr: notificationMessageFr, type: notificationType, data: { id: thePackage.id, }, }) }) }) } return updatedPackage }, }) }, }) export const PackageQuery = schema.extendType({ type: 'Query', definition(t) { t.crud.package() t.crud.packages({ filtering: true, ordering: true, pagination: true }) t.field('packages', { type: 'Package', list: true, args: { where: schema.arg({ type: 'PackageWhereInput' }), orderBy: schema.arg({ type: 'PackageOrderByInput', list: true }), first: schema.arg({ type: 'Int' }), skip: schema.arg({ type: 'Int' }), }, resolve: async ( parent, { where, orderBy, first, skip, }: { where?: PackageWhereInput orderBy?: PackageOrderByInput[] first?: number skip?: number }, ctx: NexusContext ) => { return ctx.prisma.package.findMany({ where: where, ...(orderBy?.length > 0 && { orderBy: orderBy[0] }), take: first, skip: skip, }) }, }) }, })