import { prisma } from '@documenso/prisma'; import { SendStatus, SigningStatus } from '@documenso/prisma/client'; export interface SetFieldsForDocumentOptions { userId: number; documentId: number; fields: { id?: number | null; signerEmail: string; pageNumber: number; pageX: number; pageY: number; pageWidth: number; pageHeight: number; }[]; } export const setFieldsForDocument = async ({ userId, documentId, fields, }: SetFieldsForDocumentOptions) => { const document = await prisma.document.findFirst({ where: { id: documentId, userId, }, }); if (!document) { throw new Error('Document not found'); } const existingFields = await prisma.field.findMany({ where: { documentId, }, include: { Recipient: true, }, }); const removedFields = existingFields.filter( (existingField) => !fields.find( (field) => field.id === existingField.id || field.signerEmail === existingField.Recipient?.email, ), ); const linkedFields = fields.map((field) => { const existing = existingFields.find((existingField) => existingField.id === field.id); return { ...field, ...existing, }; }); for (const field of linkedFields) { if ( field.Recipient?.sendStatus === SendStatus.SENT || field.Recipient?.signingStatus === SigningStatus.SIGNED ) { throw new Error('Cannot modify fields after sending'); } } const persistedFields = await prisma.$transaction( linkedFields.map((field) => field.id ? prisma.field.update({ where: { id: field.id, recipientId: field.recipientId, documentId, }, data: { type: field.type, page: field.pageNumber, positionX: field.pageX, positionY: field.pageY, width: field.pageWidth, height: field.pageHeight, }, }) : prisma.field.create({ data: { type: field.type!, page: field.pageNumber, positionX: field.pageX, positionY: field.pageY, width: field.pageWidth, height: field.pageHeight, customText: '', inserted: false, Document: { connect: { id: document.id, }, }, Recipient: { connect: { documentId_email: { documentId: document.id, email: field.signerEmail, }, }, }, }, }), ), ); if (removedFields.length > 0) { await prisma.field.deleteMany({ where: { id: { in: removedFields.map((field) => field.id), }, }, }); } return persistedFields; };