mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-03 16:28:56 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8145feebc | ||
|
|
df38d15611 | ||
|
|
fee53fb020 | ||
|
|
d086e60ae5 | ||
|
|
51150d4e47 | ||
|
|
1d3cd02f9d | ||
|
|
d03515efc4 | ||
|
|
30e6e4b3fd | ||
|
|
cbdd729e95 | ||
|
|
ac82209d52 | ||
|
|
d5cc6f6758 | ||
|
|
3aa211dc1a | ||
|
|
33d5eecbbf | ||
|
|
1d6c108ba4 | ||
|
|
79da0f285d | ||
|
|
e8eef32958 | ||
|
|
660eaeb714 | ||
|
|
79126700c4 | ||
|
|
6355c02485 | ||
|
|
bce028877b | ||
|
|
e47211a8c0 | ||
|
|
4a4c9eaa2d | ||
|
|
0a5653f53d | ||
|
|
5a90a0f484 | ||
|
|
a3a398bd92 | ||
|
|
7d70162137 | ||
|
|
e4c62c4eeb | ||
|
|
3eadca01fa | ||
|
|
659b7fe0f4 | ||
|
|
ade6694427 | ||
|
|
f8160665a4 | ||
|
|
5778bdecae | ||
|
|
9122c71c90 | ||
|
|
2c2065aca8 | ||
|
|
64fd3580ac | ||
|
|
01273777b7 | ||
|
|
23eaa1ae81 | ||
|
|
3fd0613407 | ||
|
|
d45566257f | ||
|
|
e9eb59aa7a | ||
|
|
9e3ba2cf5c | ||
|
|
81afc92c14 | ||
|
|
d3bf9e9e9b | ||
|
|
18e25f6cd9 |
@@ -205,6 +205,33 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ugoconsonni",
|
||||
"name": "ugoconsonni",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/13661702?v=4",
|
||||
"profile": "https://github.com/ugoconsonni",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "daniel-mutwiri",
|
||||
"name": "Daniel Mutwiri",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/8936960?v=4",
|
||||
"profile": "https://github.com/daniel-mutwiri",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Zathiel",
|
||||
"name": "Zathiel",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/26553418?v=4",
|
||||
"profile": "https://github.com/Zathiel",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -134,6 +134,9 @@ We would like to thank all our contributors and users for their support and feed
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/VikramNagwal"><img src="https://avatars.githubusercontent.com/u/123088024?v=4?s=100" width="100px;" alt="Vikram"/><br /><sub><b>Vikram</b></sub></a><br /><a href="#code-VikramNagwal" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ugoconsonni"><img src="https://avatars.githubusercontent.com/u/13661702?v=4?s=100" width="100px;" alt="ugoconsonni"/><br /><sub><b>ugoconsonni</b></sub></a><br /><a href="#code-ugoconsonni" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/daniel-mutwiri"><img src="https://avatars.githubusercontent.com/u/8936960?v=4?s=100" width="100px;" alt="Daniel Mutwiri"/><br /><sub><b>Daniel Mutwiri</b></sub></a><br /><a href="#code-daniel-mutwiri" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Zathiel"><img src="https://avatars.githubusercontent.com/u/26553418?v=4?s=100" width="100px;" alt="Zathiel"/><br /><sub><b>Zathiel</b></sub></a><br /><a href="#code-Zathiel" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -22,7 +22,8 @@ const RenderDebugPdf = (props) => {
|
||||
flex: 1,
|
||||
position: "relative",
|
||||
border: "1px solid grey",
|
||||
overflow: "auto"
|
||||
overflow: "auto",
|
||||
cursor: "crosshair"
|
||||
}}
|
||||
onMouseMove={props.handleMouseMoveDiv}
|
||||
>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useNavigate } from "react-router-dom";
|
||||
import { themeColor } from "../../constant/const";
|
||||
import axios from "axios";
|
||||
import ModalUi from "../../primitives/ModalUi";
|
||||
import Parse from "parse";
|
||||
import { appInfo } from "../../constant/appinfo";
|
||||
|
||||
function Header({
|
||||
isPdfRequestFiles,
|
||||
@@ -64,7 +64,19 @@ function Header({
|
||||
event.preventDefault();
|
||||
|
||||
try {
|
||||
const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
||||
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
||||
const axiosRes = await axios.post(
|
||||
`${appInfo.baseUrl}/functions/getsignedurl`,
|
||||
{ url: pdfUrl },
|
||||
{
|
||||
headers: {
|
||||
"content-type": "Application/json",
|
||||
"X-Parse-Application-Id": appInfo.appId,
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
}
|
||||
);
|
||||
const url = axiosRes.data.result;
|
||||
const pdf = await getBase64FromUrl(url);
|
||||
const isAndroidDevice = navigator.userAgent.match(/Android/i);
|
||||
const isAppleDevice =
|
||||
@@ -94,7 +106,19 @@ function Header({
|
||||
const handleDownloadPdf = async () => {
|
||||
const pdfName = pdfDetails[0] && pdfDetails[0].Name;
|
||||
try {
|
||||
const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
||||
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
||||
const axiosRes = await axios.post(
|
||||
`${appInfo.baseUrl}/functions/getsignedurl`,
|
||||
{ url: pdfUrl },
|
||||
{
|
||||
headers: {
|
||||
"content-type": "Application/json",
|
||||
"X-Parse-Application-Id": appInfo.appId,
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
}
|
||||
);
|
||||
const url = axiosRes.data.result;
|
||||
saveAs(url, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||
} catch (err) {
|
||||
console.log("err in getsignedurl", err);
|
||||
@@ -577,8 +601,13 @@ function Header({
|
||||
handleClose={() => setIsCertificate(false)}
|
||||
>
|
||||
<div className="p-3 md:p-5 text-[13px] md:text-base text-center">
|
||||
<p>Completion certificate is generating,</p>
|
||||
<p>please wait for some time if not download try again later</p>
|
||||
<p>
|
||||
Your completion certificate is being generated. Please wait
|
||||
momentarily.
|
||||
</p>
|
||||
<p>
|
||||
If the download doesn't start shortly, click the button again.
|
||||
</p>
|
||||
</div>
|
||||
</ModalUi>
|
||||
</div>
|
||||
|
||||
@@ -566,13 +566,13 @@ export const signPdfFun = async (
|
||||
// for adding it in completion certificate
|
||||
let getSignature;
|
||||
for (let item of xyPosition) {
|
||||
const typeExist = item.pos.some((data) => data?.type);
|
||||
if (typeExist) {
|
||||
getSignature = item.pos.find((data) => data?.type === "signature");
|
||||
break;
|
||||
} else {
|
||||
getSignature = item.pos.find((data) => !data.isStamp);
|
||||
break;
|
||||
if (!getSignature) {
|
||||
const typeExist = item.pos.some((data) => data?.type);
|
||||
if (typeExist) {
|
||||
getSignature = item.pos.find((data) => data?.type === "signature");
|
||||
} else {
|
||||
getSignature = item.pos.find((data) => !data.isStamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,6 @@ function PdfRequestFiles() {
|
||||
const [currWidgetsDetails, setCurrWidgetsDetails] = useState({});
|
||||
const [isSubscriptionExpired, setIsSubscriptionExpired] = useState(false);
|
||||
const [extUserId, setExtUserId] = useState("");
|
||||
const [pdfArrayBuffer, setPdfArrayBuffer] = useState("");
|
||||
const [isEmailVerified, setIsEmailVerified] = useState(true);
|
||||
const [isVerifyModal, setIsVerifyModal] = useState(false);
|
||||
const [otp, setOtp] = useState("");
|
||||
@@ -225,16 +224,6 @@ function PdfRequestFiles() {
|
||||
//getting document details
|
||||
const documentData = await contractDocument(documentId);
|
||||
if (documentData && documentData.length > 0) {
|
||||
const url =
|
||||
documentData[0] && (documentData[0]?.SignedUrl || documentData[0]?.URL);
|
||||
//convert document url in array buffer format to use embed widgets in pdf using pdf-lib
|
||||
const arrayBuffer = await convertPdfArrayBuffer(url);
|
||||
if (arrayBuffer === "Error") {
|
||||
setHandleError("Error: Something went wrong!");
|
||||
} else {
|
||||
setPdfArrayBuffer(arrayBuffer);
|
||||
}
|
||||
|
||||
setExtUserId(documentData[0]?.ExtUserPtr?.objectId);
|
||||
const isCompleted =
|
||||
documentData[0].IsCompleted && documentData[0].IsCompleted;
|
||||
@@ -642,9 +631,32 @@ function PdfRequestFiles() {
|
||||
setWidgetsTour(true);
|
||||
} else {
|
||||
setIsUiLoading(true);
|
||||
|
||||
const pngUrl = checkUser[0].placeHolder;
|
||||
let pdfArrBuffer;
|
||||
//`contractDocument` function used to get updated SignedUrl
|
||||
//resolved issue of sign document by multiple signers simultaneously
|
||||
const documentData = await contractDocument(documentId);
|
||||
if (documentData && documentData.length > 0) {
|
||||
const url = documentData[0]?.SignedUrl || documentData[0]?.URL;
|
||||
//convert document url in array buffer format to use embed widgets in pdf using pdf-lib
|
||||
const arrayBuffer = await convertPdfArrayBuffer(url);
|
||||
if (arrayBuffer === "Error") {
|
||||
setHandleError("Error: invalid document!");
|
||||
} else {
|
||||
pdfArrBuffer = arrayBuffer;
|
||||
}
|
||||
} else if (
|
||||
documentData === "Error: Something went wrong!" ||
|
||||
(documentData.result && documentData.result.error)
|
||||
) {
|
||||
setHandleError("Error: Something went wrong!");
|
||||
} else {
|
||||
setHandleError("Document not Found!");
|
||||
}
|
||||
|
||||
// Load a PDFDocument from the existing PDF bytes
|
||||
const existingPdfBytes = pdfArrayBuffer;
|
||||
const existingPdfBytes = pdfArrBuffer;
|
||||
try {
|
||||
const pdfDoc = await PDFDocument.load(existingPdfBytes);
|
||||
const isSignYourSelfFlow = false;
|
||||
|
||||
@@ -830,11 +830,11 @@ function PlaceHolderSign() {
|
||||
return pdfDetails[0].URL;
|
||||
}
|
||||
};
|
||||
|
||||
const alertSendEmail = async () => {
|
||||
const filterPrefill = signerPos?.filter((data) => data.Role !== "prefill");
|
||||
const getPrefill = signerPos?.filter((data) => data.Role === "prefill");
|
||||
let isLabel = false;
|
||||
//condition is used to check text widget data is empty or have response
|
||||
if (getPrefill && getPrefill.length > 0) {
|
||||
const prefillPlaceholder = getPrefill[0].placeHolder;
|
||||
if (prefillPlaceholder) {
|
||||
@@ -845,6 +845,29 @@ function PlaceHolderSign() {
|
||||
});
|
||||
}
|
||||
}
|
||||
let isSignatureExist = true; // variable is used to check a signature widget exit or not then execute other code
|
||||
//for loop is used to check signature widget exist or not
|
||||
for (let item of filterPrefill) {
|
||||
let signatureExist = false; // Reset for each iteration
|
||||
for (let x of item.placeHolder) {
|
||||
if (!signatureExist) {
|
||||
const typeExist = x.pos.some((data) => data?.type);
|
||||
if (typeExist) {
|
||||
signatureExist = x.pos.some((data) => data?.type === "signature");
|
||||
} else {
|
||||
signatureExist = x.pos.some((data) => !data.isStamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!signatureExist) {
|
||||
isSignatureExist = false;
|
||||
const alert = {
|
||||
mssg: "sure",
|
||||
alert: true
|
||||
};
|
||||
setIsSendAlert(alert);
|
||||
}
|
||||
}
|
||||
|
||||
if (getPrefill && isLabel) {
|
||||
const alert = {
|
||||
@@ -852,23 +875,26 @@ function PlaceHolderSign() {
|
||||
alert: true
|
||||
};
|
||||
setIsSendAlert(alert);
|
||||
} else if (filterPrefill.length === signersdata.length) {
|
||||
const IsSignerNotExist = filterPrefill?.filter((x) => !x.signerObjId);
|
||||
if (IsSignerNotExist && IsSignerNotExist?.length > 0) {
|
||||
setSignerExistModal(true);
|
||||
setSelectWidgetId(IsSignerNotExist[0]?.placeHolder?.[0]?.pos?.[0]?.key);
|
||||
} else if (isSignatureExist) {
|
||||
if (filterPrefill.length === signersdata.length) {
|
||||
const IsSignerNotExist = filterPrefill?.filter((x) => !x.signerObjId);
|
||||
if (IsSignerNotExist && IsSignerNotExist?.length > 0) {
|
||||
setSignerExistModal(true);
|
||||
setSelectWidgetId(
|
||||
IsSignerNotExist[0]?.placeHolder?.[0]?.pos?.[0]?.key
|
||||
);
|
||||
} else {
|
||||
saveDocumentDetails();
|
||||
}
|
||||
} else {
|
||||
saveDocumentDetails();
|
||||
const alert = {
|
||||
mssg: "sure",
|
||||
alert: true
|
||||
};
|
||||
setIsSendAlert(alert);
|
||||
}
|
||||
} else {
|
||||
const alert = {
|
||||
mssg: "sure",
|
||||
alert: true
|
||||
};
|
||||
setIsSendAlert(alert);
|
||||
}
|
||||
};
|
||||
|
||||
//function to use save placeholder details in contracts_document
|
||||
const saveDocumentDetails = async () => {
|
||||
setIsUiLoading(true);
|
||||
@@ -1687,8 +1713,8 @@ function PlaceHolderSign() {
|
||||
>
|
||||
{isSendAlert.mssg === "sure" ? (
|
||||
<span>
|
||||
Please add at least one signature field for all
|
||||
recipients.
|
||||
Please ensure there's at least one signature widget
|
||||
added for all recipients.
|
||||
</span>
|
||||
) : isSendAlert.mssg === textWidget ? (
|
||||
<p>Please confirm that you have filled the text field.</p>
|
||||
|
||||
@@ -480,13 +480,13 @@ function SignYourSelf() {
|
||||
Width: widgetTypeExist
|
||||
? calculateInitialWidthHeight(dragTypeValue, widgetValue).getWidth
|
||||
: dragTypeValue === "initials"
|
||||
? defaultWidthHeight(dragTypeValue).width
|
||||
: "",
|
||||
? defaultWidthHeight(dragTypeValue).width
|
||||
: "",
|
||||
Height: widgetTypeExist
|
||||
? calculateInitialWidthHeight(dragTypeValue, widgetValue).getHeight
|
||||
: dragTypeValue === "initials"
|
||||
? defaultWidthHeight(dragTypeValue).height
|
||||
: "",
|
||||
? defaultWidthHeight(dragTypeValue).height
|
||||
: "",
|
||||
options: addWidgetOptions(dragTypeValue)
|
||||
};
|
||||
|
||||
@@ -603,7 +603,8 @@ function SignYourSelf() {
|
||||
};
|
||||
//function for send placeholder's co-ordinate(x,y) position embed signature url or stamp url
|
||||
async function embedWidgetsData() {
|
||||
let showAlert = false;
|
||||
let showAlert = false,
|
||||
isSignatureExist = false;
|
||||
try {
|
||||
for (let i = 0; i < xyPostion?.length; i++) {
|
||||
const requiredWidgets = xyPostion[i].pos.filter(
|
||||
@@ -627,17 +628,26 @@ function SignYourSelf() {
|
||||
}
|
||||
}
|
||||
}
|
||||
//condition to check exist signature widget or not
|
||||
if (!isSignatureExist) {
|
||||
isSignatureExist = xyPostion[i].pos.some(
|
||||
(data) => data?.type === "signature"
|
||||
);
|
||||
}
|
||||
}
|
||||
if (xyPostion.length === 0) {
|
||||
if (xyPostion.length === 0 || !isSignatureExist) {
|
||||
setIsAlert({
|
||||
header: "Fields required",
|
||||
isShow: true,
|
||||
alertMessage: "Please complete your signature!"
|
||||
alertMessage:
|
||||
"Please ensure there's at least one signature widget added"
|
||||
});
|
||||
return;
|
||||
} else if (showAlert) {
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: "Please complete your signature!"
|
||||
alertMessage:
|
||||
"Please ensure all field is accurately filled and meets all requirements."
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
@@ -713,13 +723,13 @@ function SignYourSelf() {
|
||||
// for adding it in completion certificate
|
||||
let getSignature;
|
||||
for (let item of xyPostion) {
|
||||
const typeExist = item.pos.some((data) => data?.type);
|
||||
if (typeExist) {
|
||||
getSignature = item.pos.find((data) => data?.type === "signature");
|
||||
break;
|
||||
} else {
|
||||
getSignature = item.pos.find((data) => !data.isStamp);
|
||||
break;
|
||||
if (!getSignature) {
|
||||
const typeExist = item.pos.some((data) => data?.type);
|
||||
if (typeExist) {
|
||||
getSignature = item.pos.find((data) => data?.type === "signature");
|
||||
} else {
|
||||
getSignature = item.pos.find((data) => !data.isStamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
let base64Sign = getSignature.SignUrl;
|
||||
@@ -1161,7 +1171,7 @@ function SignYourSelf() {
|
||||
<ModalUi
|
||||
headerColor={"#dc3545"}
|
||||
isOpen={isAlert.isShow}
|
||||
title={"Alert"}
|
||||
title={isAlert?.header || "Alert"}
|
||||
handleClose={() => {
|
||||
setIsAlert({
|
||||
isShow: false,
|
||||
@@ -1171,28 +1181,6 @@ function SignYourSelf() {
|
||||
>
|
||||
<div style={{ height: "100%", padding: 20 }}>
|
||||
<p>{isAlert.alertMessage}</p>
|
||||
|
||||
<div
|
||||
style={{
|
||||
height: "1px",
|
||||
backgroundColor: "#9f9f9f",
|
||||
width: "100%",
|
||||
marginTop: "15px",
|
||||
marginBottom: "15px"
|
||||
}}
|
||||
></div>
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsAlert({
|
||||
isShow: false,
|
||||
alertMessage: ""
|
||||
});
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn cancelBtn"
|
||||
>
|
||||
Ok
|
||||
</button>
|
||||
</div>
|
||||
</ModalUi>
|
||||
|
||||
|
||||
@@ -88,12 +88,20 @@ export default async function createDocumentWithTemplate(request, response) {
|
||||
const updateSigners = placeholder.every(y => signers?.some(x => x.role === y.Role));
|
||||
// console.log('isValid ', isValid);
|
||||
if (isValid && updateSigners) {
|
||||
//Check if every item's placeholders contain at least one placeholder with type 'signature'.
|
||||
let isSignature = template?.Placeholders?.every(item =>
|
||||
item?.placeHolder.some(x => x?.pos.some(data => data?.type === 'signature'))
|
||||
);
|
||||
if (!isSignature) {
|
||||
return response
|
||||
.status(400)
|
||||
.json({ error: 'Please add at least one signature widget for all signers' });
|
||||
}
|
||||
const folderPtr = {
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Document',
|
||||
objectId: folderId,
|
||||
};
|
||||
const template = JSON.parse(JSON.stringify(templateRes));
|
||||
const object = new Parse.Object('contracts_Document');
|
||||
object.set('Name', template.Name);
|
||||
if (template?.Note) {
|
||||
@@ -169,6 +177,7 @@ export default async function createDocumentWithTemplate(request, response) {
|
||||
object.set('Signers', templateSigner);
|
||||
}
|
||||
object.set('URL', template.URL);
|
||||
object.set('SignedUrl', template.URL);
|
||||
object.set('CreatedBy', template.CreatedBy);
|
||||
object.set('ExtUserPtr', {
|
||||
__type: 'Pointer',
|
||||
|
||||
@@ -88,6 +88,15 @@ export default async function createDocumentwithCoordinate(request, response) {
|
||||
objectId: parseUser.userId.objectId,
|
||||
};
|
||||
if (signers && signers.length > 0) {
|
||||
// Check if at least one signature exists among all items in the signers array
|
||||
let isSignExist = signers.every(item =>
|
||||
item.widgets.some(data => data?.type === 'signature')
|
||||
);
|
||||
if (!isSignExist) {
|
||||
return response
|
||||
.status(400)
|
||||
.json({ error: 'Please add at least one signature widget for all signers' });
|
||||
}
|
||||
let fileUrl;
|
||||
if (request.files?.[0]) {
|
||||
const base64 = fileData?.toString('base64');
|
||||
@@ -130,6 +139,7 @@ export default async function createDocumentwithCoordinate(request, response) {
|
||||
object.set('SendinOrder', sendInOrder);
|
||||
}
|
||||
object.set('URL', fileUrl);
|
||||
object.set('SignedUrl', fileUrl);
|
||||
object.set('CreatedBy', userPtr);
|
||||
object.set('ExtUserPtr', extUserPtr);
|
||||
object.set('IsSendMail', send_email);
|
||||
@@ -279,7 +289,7 @@ export default async function createDocumentwithCoordinate(request, response) {
|
||||
const objectId = contactMail[i].contactPtr.objectId;
|
||||
const hostUrl = baseUrl.origin;
|
||||
//encode this url value `${response.id}/${contactMail[i].email}/${objectId}` to base64 using `btoa` function
|
||||
const encodeBase64 = btoa(`${response.id}/${contactMail[i].email}/${objectId}`);
|
||||
const encodeBase64 = btoa(`${res.id}/${contactMail[i].email}/${objectId}`);
|
||||
let signPdf = `${hostUrl}/login/${encodeBase64}`;
|
||||
const openSignUrl = 'https://www.opensignlabs.com/contact-us';
|
||||
const orgName = parseExtUser.Company ? parseExtUser.Company : '';
|
||||
@@ -332,7 +342,7 @@ export default async function createDocumentwithCoordinate(request, response) {
|
||||
);
|
||||
} else {
|
||||
replaceVar = {
|
||||
subject: `${parseExtUser.Name} has requested you to sign "${parseExtUser.Name}"`,
|
||||
subject: `${parseExtUser.Name} has requested you to sign "${name}"`,
|
||||
body: email_html,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export default async function GenerateCertificate(docDetails) {
|
||||
const company = docDetails?.ExtUserPtr?.Company || '';
|
||||
const createdAt = docDetails?.DocSentAt?.iso || docDetails.createdAt;
|
||||
const auditTrail =
|
||||
docDetails.AuditTrail?.length > 1
|
||||
docDetails?.Signers?.length > 0
|
||||
? docDetails.AuditTrail.map(x => {
|
||||
const data = docDetails.Signers.find(y => y.objectId === x.UserPtr.objectId);
|
||||
return {
|
||||
@@ -281,7 +281,7 @@ export default async function GenerateCertificate(docDetails) {
|
||||
});
|
||||
|
||||
page.drawText('Viewed on :', {
|
||||
x: half +55,
|
||||
x: half + 55,
|
||||
y: yPosition2,
|
||||
size: timeText,
|
||||
font: timesRomanFont,
|
||||
|
||||
Reference in New Issue
Block a user