diff --git a/packages/lib/server-only/document/duplicate-document-by-id.ts b/packages/lib/server-only/document/duplicate-document-by-id.ts index 6f1af4e12..18d0b4ec6 100644 --- a/packages/lib/server-only/document/duplicate-document-by-id.ts +++ b/packages/lib/server-only/document/duplicate-document-by-id.ts @@ -1,4 +1,6 @@ -import { DocumentSource, type Prisma, WebhookTriggerEvents } from '@prisma/client'; +import type { Prisma, Recipient } from '@prisma/client'; +import { DocumentSource, WebhookTriggerEvents } from '@prisma/client'; +import { omit } from 'remeda'; import { prisma } from '@documenso/prisma'; @@ -7,7 +9,7 @@ import { ZWebhookDocumentSchema, mapDocumentToWebhookDocumentPayload, } from '../../types/webhook-payload'; -import { prefixedId } from '../../universal/id'; +import { nanoid, prefixedId } from '../../universal/id'; import { triggerWebhook } from '../webhooks/trigger/trigger-webhook'; import { getDocumentWhereInput } from './get-document-by-id'; @@ -40,14 +42,16 @@ export const duplicateDocument = async ({ type: true, }, }, - documentMeta: { + authOptions: true, + visibility: true, + documentMeta: true, + recipients: { select: { - message: true, - subject: true, - dateFormat: true, - password: true, - timezone: true, - redirectUrl: true, + email: true, + name: true, + role: true, + signingOrder: true, + fields: true, }, }, }, @@ -59,56 +63,83 @@ export const duplicateDocument = async ({ }); } - const createDocumentArguments: Prisma.DocumentCreateArgs = { + const documentData = await prisma.documentData.create({ data: { - title: document.title, - qrToken: prefixedId('qr'), - user: { - connect: { - id: document.userId, - }, - }, - team: { - connect: { - id: teamId, - }, - }, - documentData: { - create: { - ...document.documentData, - data: document.documentData.initialData, - }, - }, - documentMeta: { - create: { - ...document.documentMeta, - }, - }, - source: DocumentSource.DOCUMENT, + type: document.documentData.type, + data: document.documentData.initialData, + initialData: document.documentData.initialData, }, - }; + }); - if (teamId !== undefined) { - createDocumentArguments.data.team = { - connect: { - id: teamId, + let documentMeta: Prisma.DocumentCreateArgs['data']['documentMeta'] | undefined = undefined; + + if (document.documentMeta) { + documentMeta = { + create: { + ...omit(document.documentMeta, ['id', 'documentId']), + emailSettings: document.documentMeta.emailSettings || undefined, }, }; } const createdDocument = await prisma.document.create({ - ...createDocumentArguments, + data: { + userId: document.userId, + teamId: teamId, + title: document.title, + documentDataId: documentData.id, + authOptions: document.authOptions || undefined, + visibility: document.visibility, + qrToken: prefixedId('qr'), + documentMeta, + source: DocumentSource.DOCUMENT, + }, include: { recipients: true, documentMeta: true, }, }); + const recipientsToCreate = document.recipients.map((recipient) => ({ + documentId: createdDocument.id, + email: recipient.email, + name: recipient.name, + role: recipient.role, + signingOrder: recipient.signingOrder, + token: nanoid(), + fields: { + createMany: { + data: recipient.fields.map((field) => ({ + documentId: createdDocument.id, + type: field.type, + page: field.page, + positionX: field.positionX, + positionY: field.positionY, + width: field.width, + height: field.height, + customText: '', + inserted: false, + fieldMeta: field.fieldMeta as PrismaJson.FieldMeta, + })), + }, + }, + })); + + const recipients: Recipient[] = []; + + for (const recipientData of recipientsToCreate) { + const newRecipient = await prisma.recipient.create({ + data: recipientData, + }); + + recipients.push(newRecipient); + } + await triggerWebhook({ event: WebhookTriggerEvents.DOCUMENT_CREATED, data: ZWebhookDocumentSchema.parse({ ...mapDocumentToWebhookDocumentPayload(createdDocument), - recipients: createdDocument.recipients, + recipients, documentMeta: createdDocument.documentMeta, }), userId: userId, diff --git a/packages/lib/server-only/template/duplicate-template.ts b/packages/lib/server-only/template/duplicate-template.ts index f0be0d4e8..c82a9f70a 100644 --- a/packages/lib/server-only/template/duplicate-template.ts +++ b/packages/lib/server-only/template/duplicate-template.ts @@ -23,8 +23,15 @@ export const duplicateTemplate = async ({ team: buildTeamWhereQuery({ teamId, userId }), }, include: { - recipients: true, - fields: true, + recipients: { + select: { + email: true, + name: true, + role: true, + signingOrder: true, + fields: true, + }, + }, templateDocumentData: true, templateMeta: true, }, @@ -59,13 +66,8 @@ export const duplicateTemplate = async ({ teamId, title: template.title + ' (copy)', templateDocumentDataId: documentData.id, - recipients: { - create: template.recipients.map((recipient) => ({ - email: recipient.email, - name: recipient.name, - token: nanoid(), - })), - }, + authOptions: template.authOptions || undefined, + visibility: template.visibility, templateMeta, }, include: { @@ -73,32 +75,36 @@ export const duplicateTemplate = async ({ }, }); - await prisma.field.createMany({ - data: template.fields.map((field) => { - const recipient = template.recipients.find((recipient) => recipient.id === field.recipientId); + const recipientsToCreate = template.recipients.map((recipient) => ({ + templateId: duplicatedTemplate.id, + email: recipient.email, + name: recipient.name, + role: recipient.role, + signingOrder: recipient.signingOrder, + token: nanoid(), + fields: { + createMany: { + data: recipient.fields.map((field) => ({ + templateId: duplicatedTemplate.id, + type: field.type, + page: field.page, + positionX: field.positionX, + positionY: field.positionY, + width: field.width, + height: field.height, + customText: '', + inserted: false, + fieldMeta: field.fieldMeta as PrismaJson.FieldMeta, + })), + }, + }, + })); - const duplicatedTemplateRecipient = duplicatedTemplate.recipients.find( - (doc) => doc.email === recipient?.email, - ); - - if (!duplicatedTemplateRecipient) { - throw new Error('Recipient not found.'); - } - - return { - type: field.type, - page: field.page, - positionX: field.positionX, - positionY: field.positionY, - width: field.width, - height: field.height, - customText: field.customText, - inserted: field.inserted, - templateId: duplicatedTemplate.id, - recipientId: duplicatedTemplateRecipient.id, - }; - }), - }); + for (const recipientData of recipientsToCreate) { + await prisma.recipient.create({ + data: recipientData, + }); + } return duplicatedTemplate; };