diff --git a/packages/lib/server-only/envelope/create-envelope.ts b/packages/lib/server-only/envelope/create-envelope.ts index 5f4198377..b92ba2d32 100644 --- a/packages/lib/server-only/envelope/create-envelope.ts +++ b/packages/lib/server-only/envelope/create-envelope.ts @@ -10,6 +10,7 @@ import { } from '@prisma/client'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; +import { insertFieldsFromPlaceholdersInPDF } from '@documenso/lib/server-only/pdf/auto-place-fields'; import { normalizePdf as makeNormalizedPdf } from '@documenso/lib/server-only/pdf/normalize-pdf'; import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; @@ -233,7 +234,7 @@ export const createEnvelope = async ({ ? await incrementDocumentId().then((v) => v.formattedDocumentId) : await incrementTemplateId().then((v) => v.formattedTemplateId); - return await prisma.$transaction(async (tx) => { + const createdEnvelope = await prisma.$transaction(async (tx) => { const envelope = await tx.envelope.create({ data: { id: prefixedId('envelope'), @@ -353,8 +354,12 @@ export const createEnvelope = async ({ recipients: true, fields: true, folder: true, - envelopeItems: true, envelopeAttachments: true, + envelopeItems: { + include: { + documentData: true, + }, + }, }, }); @@ -390,4 +395,51 @@ export const createEnvelope = async ({ return createdEnvelope; }); + + for (const envelopeItem of createdEnvelope.envelopeItems) { + const buffer = await getFileServerSide(envelopeItem.documentData); + + // Use normalized PDF if normalizePdf was true, otherwise use original + const pdfToProcess = normalizePdf + ? await makeNormalizedPdf(Buffer.from(buffer)) + : Buffer.from(buffer); + + await insertFieldsFromPlaceholdersInPDF( + pdfToProcess, + userId, + teamId, + { + type: 'envelopeId', + id: createdEnvelope.id, + }, + requestMetadata, + envelopeItem.id, + ); + } + + const finalEnvelope = await prisma.envelope.findFirst({ + where: { + id: createdEnvelope.id, + }, + include: { + documentMeta: true, + recipients: true, + fields: true, + folder: true, + envelopeAttachments: true, + envelopeItems: { + include: { + documentData: true, + }, + }, + }, + }); + + if (!finalEnvelope) { + throw new AppError(AppErrorCode.NOT_FOUND, { + message: 'Envelope not found', + }); + } + + return finalEnvelope; }; diff --git a/packages/lib/server-only/pdf/auto-place-fields.ts b/packages/lib/server-only/pdf/auto-place-fields.ts index ecd714e04..923c8138c 100644 --- a/packages/lib/server-only/pdf/auto-place-fields.ts +++ b/packages/lib/server-only/pdf/auto-place-fields.ts @@ -63,8 +63,8 @@ type RecipientPlaceholderInfo = { - Does it handle multiple recipients on the same page? ✅ YES! ✅ - Does it handle multiple recipients on multiple pages? ✅ YES! ✅ - What happens with incorrect placeholders? E.g. those containing non-accepted properties. - - The placeholder data is dynamic. How to handle this parsing? Perhaps we need to do it similar to the fieldMeta parsing. - - Need to handle envelopes with multiple items. + - The placeholder data is dynamic. How to handle this parsing? Perhaps we need to do it similar to the fieldMeta parsing. ✅ + - Need to handle envelopes with multiple items. ✅ */ /* @@ -202,9 +202,9 @@ export const extractPlaceholdersFromPDF = async (pdf: Buffer): Promise part.trim()); + for (const placeholderMatch of placeholderMatches) { + const placeholder = placeholderMatch[0]; + const placeholderData = placeholderMatch[1].split(',').map((part) => part.trim()); const [fieldTypeString, recipient, ...fieldMetaData] = placeholderData; @@ -223,7 +223,12 @@ export const extractPlaceholdersFromPDF = async (pdf: Buffer): Promise