Merge branch 'main' into fix/refactor-use-template

This commit is contained in:
David Nguyen
2024-05-01 15:16:25 +07:00
committed by GitHub
11 changed files with 117 additions and 48 deletions

View File

@ -137,7 +137,7 @@ export const completeDocumentWithToken = async ({
await sendPendingEmail({ documentId, recipientId: recipient.id });
}
const documents = await prisma.document.updateMany({
const haveAllRecipientsSigned = await prisma.document.findFirst({
where: {
id: document.id,
Recipient: {
@ -146,13 +146,9 @@ export const completeDocumentWithToken = async ({
},
},
},
data: {
status: DocumentStatus.COMPLETED,
completedAt: new Date(),
},
});
if (documents.count > 0) {
if (haveAllRecipientsSigned) {
await sealDocument({ documentId: document.id, requestMetadata });
}

View File

@ -75,18 +75,20 @@ export const deleteDocument = async ({
}
// Continue to hide the document from the user if they are a recipient.
// Dirty way of doing this but it's faster than refetching the document.
if (userRecipient?.documentDeletedAt === null) {
await prisma.recipient.update({
where: {
documentId_email: {
documentId: document.id,
email: user.email,
await prisma.recipient
.update({
where: {
id: userRecipient.id,
},
},
data: {
documentDeletedAt: new Date().toISOString(),
},
});
data: {
documentDeletedAt: new Date().toISOString(),
},
})
.catch(() => {
// Do nothing.
});
}
// Return partial document for API v1 response.

View File

@ -40,6 +40,11 @@ export const sealDocument = async ({
const document = await prisma.document.findFirstOrThrow({
where: {
id: documentId,
Recipient: {
every: {
signingStatus: SigningStatus.SIGNED,
},
},
},
include: {
documentData: true,
@ -53,10 +58,6 @@ export const sealDocument = async ({
throw new Error(`Document ${document.id} has no document data`);
}
if (document.status !== DocumentStatus.COMPLETED) {
throw new Error(`Document ${document.id} has not been completed`);
}
const recipients = await prisma.recipient.findMany({
where: {
documentId: document.id,
@ -92,9 +93,9 @@ export const sealDocument = async ({
// !: Need to write the fields onto the document as a hard copy
const pdfData = await getFile(documentData);
const certificate = await getCertificatePdf({ documentId }).then(async (doc) =>
PDFDocument.load(doc),
);
const certificate = await getCertificatePdf({ documentId })
.then(async (doc) => PDFDocument.load(doc))
.catch(() => null);
const doc = await PDFDocument.load(pdfData);
@ -103,11 +104,13 @@ export const sealDocument = async ({
doc.getForm().flatten();
flattenAnnotations(doc);
const certificatePages = await doc.copyPages(certificate, certificate.getPageIndices());
if (certificate) {
const certificatePages = await doc.copyPages(certificate, certificate.getPageIndices());
certificatePages.forEach((page) => {
doc.addPage(page);
});
certificatePages.forEach((page) => {
doc.addPage(page);
});
}
for (const field of fields) {
await insertFieldInPDF(doc, field);
@ -138,6 +141,16 @@ export const sealDocument = async ({
}
await prisma.$transaction(async (tx) => {
await tx.document.update({
where: {
id: document.id,
},
data: {
status: DocumentStatus.COMPLETED,
completedAt: new Date(),
},
});
await tx.documentData.update({
where: {
id: documentData.id,

View File

@ -4,6 +4,8 @@ import { mailer } from '@documenso/email/mailer';
import { render } from '@documenso/email/render';
import { DocumentInviteEmailTemplate } from '@documenso/email/templates/document-invite';
import { FROM_ADDRESS, FROM_NAME } from '@documenso/lib/constants/email';
import { sealDocument } from '@documenso/lib/server-only/document/seal-document';
import { updateDocument } from '@documenso/lib/server-only/document/update-document';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
@ -211,6 +213,31 @@ export const sendDocument = async ({
}),
);
const allRecipientsHaveNoActionToTake = document.Recipient.every(
(recipient) => recipient.role === RecipientRole.CC,
);
if (allRecipientsHaveNoActionToTake) {
const updatedDocument = await updateDocument({
documentId,
userId,
teamId,
data: { status: DocumentStatus.COMPLETED },
});
await sealDocument({ documentId: updatedDocument.id, requestMetadata });
// Keep the return type the same for the `sendDocument` method
return await prisma.document.findFirstOrThrow({
where: {
id: documentId,
},
include: {
Recipient: true,
},
});
}
const updatedDocument = await prisma.$transaction(async (tx) => {
if (document.status === DocumentStatus.DRAFT) {
await tx.documentAuditLog.create({

View File

@ -35,6 +35,7 @@ export const getCertificatePdf = async ({ documentId }: GetCertificatePdfOptions
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/__htmltopdf/certificate?d=${encryptedId}`, {
waitUntil: 'networkidle',
timeout: 10_000,
});
const result = await page.pdf({

View File

@ -17,6 +17,7 @@ export const getFlag = async (
options?: GetFlagOptions,
): Promise<TFeatureFlagValue> => {
const requestHeaders = options?.requestHeaders ?? {};
delete requestHeaders['content-length'];
if (!isFeatureFlagEnabled()) {
return LOCAL_FEATURE_FLAGS[flag] ?? true;
@ -25,7 +26,7 @@ export const getFlag = async (
const url = new URL(`${APP_BASE_URL()}/api/feature-flag/get`);
url.searchParams.set('flag', flag);
const response = await fetch(url, {
return await fetch(url, {
headers: {
...requestHeaders,
},
@ -35,9 +36,10 @@ export const getFlag = async (
})
.then(async (res) => res.json())
.then((res) => ZFeatureFlagValueSchema.parse(res))
.catch(() => false);
return response;
.catch((err) => {
console.error(err);
return LOCAL_FEATURE_FLAGS[flag] ?? false;
});
};
/**
@ -50,6 +52,7 @@ export const getAllFlags = async (
options?: GetFlagOptions,
): Promise<Record<string, TFeatureFlagValue>> => {
const requestHeaders = options?.requestHeaders ?? {};
delete requestHeaders['content-length'];
if (!isFeatureFlagEnabled()) {
return LOCAL_FEATURE_FLAGS;
@ -67,7 +70,10 @@ export const getAllFlags = async (
})
.then(async (res) => res.json())
.then((res) => z.record(z.string(), ZFeatureFlagValueSchema).parse(res))
.catch(() => LOCAL_FEATURE_FLAGS);
.catch((err) => {
console.error(err);
return LOCAL_FEATURE_FLAGS;
});
};
/**
@ -89,7 +95,10 @@ export const getAllAnonymousFlags = async (): Promise<Record<string, TFeatureFla
})
.then(async (res) => res.json())
.then((res) => z.record(z.string(), ZFeatureFlagValueSchema).parse(res))
.catch(() => LOCAL_FEATURE_FLAGS);
.catch((err) => {
console.error(err);
return LOCAL_FEATURE_FLAGS;
});
};
interface GetFlagOptions {