diff --git a/apps/OpenSign/src/routes/Form.js b/apps/OpenSign/src/routes/Form.js index 1069753e6..8191b84b4 100644 --- a/apps/OpenSign/src/routes/Form.js +++ b/apps/OpenSign/src/routes/Form.js @@ -34,7 +34,8 @@ const Forms = (props) => { Name: "", Description: "", Note: "Please review and sign this document", - TimeToCompleteDays: 15 + TimeToCompleteDays: 15, + SendinOrder: "false" }); const [fileupload, setFileUpload] = useState([]); const [fileload, setfileload] = useState(false); @@ -161,6 +162,8 @@ const Forms = (props) => { "TimeToCompleteDays", parseInt(formData?.TimeToCompleteDays) ); + const isChecked = formData.SendinOrder === "true" ? true : false; + object.set("SendinOrder", isChecked); } object.set("URL", fileupload); object.set("CreatedBy", Parse.User.createWithoutData(currentUser.id)); @@ -365,6 +368,32 @@ const Forms = (props) => { /> )} + {props.title !== "Sign Yourself" && ( +
+ +
+ +
Yes
+
+
+ +
No
+
+
+ )}
', + ' directly. If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ here.

', }; await axios.post(serverUrl + '/functions/sendmailv3', a, { headers: { @@ -80,9 +80,9 @@ async function sendCompletedMail(e) { html: "

Document sign successfully

All parties have successfully signed the document" + s + - '. Kindly download the document from the attachment.

This is an automated email from Open Sign. For any queries regarding this email, please contact the sender ' + + '. Kindly download the document from the attachment.

This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender ' + t.Mail + - ' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.

', + ' directly. If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ here.

', }; await axios.post(serverUrl + '/functions/sendmailv3', a, { headers: { @@ -238,13 +238,13 @@ async function PDF(i, n) { v && 0 < v.length ? plainAddPlaceholder({ pdfBuffer: e, - reason: 'Digitally signed by Open sign for ' + v?.join(', '), + reason: 'Digitally signed by OpenSign for ' + v?.join(', '), location: 'location', signatureLength: 1e4, }) : plainAddPlaceholder({ pdfBuffer: e, - reason: 'Digitally signed by Open sign for ' + m + ' <' + g + '>', + reason: 'Digitally signed by OpenSign for ' + m + ' <' + g + '>', location: 'location', signatureLength: 1e4, })), diff --git a/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js b/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js index b935f9bea..992305225 100644 --- a/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js +++ b/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js @@ -79,6 +79,7 @@ function PdfRequestFiles() { const [isExpired, setIsExpired] = useState(false); const [alreadySign, setAlreadySign] = useState(false); const [containerWH, setContainerWH] = useState({}); + const [sendInOrder, setSendInOrder] = useState(false); const divRef = useRef(null); const isMobile = window.innerWidth < 767; const rowLevel = @@ -184,6 +185,7 @@ function PdfRequestFiles() { setAlreadySign(true); } else { const obj = documentData?.[0]; + setSendInOrder(obj?.SendinOrder || false); if ( obj && obj.Signers && @@ -328,175 +330,292 @@ function PdfRequestFiles() { }); }; + const checkSendInOrder = () => { + if (sendInOrder) { + const index = pdfDetails?.[0].Signers.findIndex( + (x) => x.Email === jsonSender.email + ); + const newIndex = index - 1; + if (newIndex !== -1) { + const user = pdfDetails?.[0].Signers[newIndex]; + const isPrevUserSigned = + pdfDetails?.[0].AuditTrail && + pdfDetails?.[0].AuditTrail.some( + (x) => + x.UserPtr.objectId === user.objectId && x.Activity === "Signed" + ); + if (isPrevUserSigned) { + return true; + } else { + return false; + } + } else { + return true; + } + } else { + return true; + } + }; //function for embed signature or image url in pdf async function embedImages() { - const checkUser = signerPos.filter( - (data) => data.signerObjId === signerObjectId - ); - if (checkUser && checkUser.length > 0) { - let checkSignUrl = []; - const checkSign = checkUser[0].placeHolder.filter( - (data, ind) => data.pos + const validateSigning = checkSendInOrder(); + if (validateSigning) { + const checkUser = signerPos.filter( + (data) => data.signerObjId === signerObjectId ); - for (let i = 0; i < checkSign.length; i++) { - const posData = checkSign[i].pos.filter((pos) => !pos.SignUrl); - if (posData && posData.length > 0) { - checkSignUrl.push(posData); - } - } - - if (checkSignUrl && checkSignUrl.length > 0) { - setIsAlert({ - isShow: true, - alertMessage: "Please complete your signature!" - }); - } else { - setIsUiLoading(true); - const pngUrl = checkUser[0].placeHolder; - // Load a PDFDocument from the existing PDF bytes - const existingPdfBytes = await fetch(pdfUrl).then((res) => - res.arrayBuffer() + if (checkUser && checkUser.length > 0) { + let checkSignUrl = []; + const checkSign = checkUser[0].placeHolder.filter( + (data, ind) => data.pos ); - const pdfDoc = await PDFDocument.load(existingPdfBytes, { - ignoreEncryption: true - }); - // let pdfBase64; - - //checking if signature is only one then send image url in jpeg formate to server - // if (pngUrl.length === 1 && pngUrl[0].pos.length === 1) { - // if (isDocId) { - // try { - // pdfBase64 = await getBase64FromUrl(pdfUrl); - // } catch (err) { - // console.log(err); - // } - // } else { - // //embed document's object id to all pages in pdf document - // try { - // await embedDocId(pdfDoc, documentId, allPages); - // } catch (err) { - // console.log(err); - // } - // try { - // pdfBase64 = await pdfDoc.saveAsBase64({ - // useObjectStreams: false - // }); - // } catch (err) { - // console.log(err); - // } - // } - // for (let pngData of pngUrl) { - // const imgUrlList = pngData.pos; - // const pageNo = pngData.pageNumber; - // imgUrlList.map(async (data) => { - // //cheking signUrl is defau;t signature url of custom url - // let ImgUrl = data.SignUrl; - // const checkUrl = urlValidator(ImgUrl); - // //if default signature url then convert it in base 64 - // if (checkUrl) { - // ImgUrl = await getBase64FromIMG(ImgUrl + "?get"); - // } - // //function for called convert png signatre to jpeg in base 64 - // convertPNGtoJPEG(ImgUrl) - // .then((jpegBase64Data) => { - // const removeBase64Fromjpeg = "data:image/jpeg;base64,"; - // const newImgUrl = jpegBase64Data.replace( - // removeBase64Fromjpeg, - // "" - // ); - - // //function for call to embed signature in pdf and get digital signature pdf - // signPdfFun( - // newImgUrl, - // documentId, - // signerObjectId, - // pdfOriginalWidth, - // pngUrl, - // containerWH, - // setIsAlert, - // data, - // pdfBase64, - // pageNo - // ) - // .then((res) => { - // if (res && res.status === "success") { - // setPdfUrl(res.data); - // setIsSigned(true); - // setSignedSigners([]); - // setUnSignedSigners([]); - // getDocumentDetails(); - // } else { - // setIsAlert({ - // isShow: true, - // alertMessage: "something went wrong" - // }); - // } - // }) - // .catch((err) => { - // setIsAlert({ - // isShow: true, - // alertMessage: "something went wrong" - // }); - // }); - // }) - // .catch((error) => { - // console.error("Error:", error); - // }); - // }); - // } - // } - // //else if signature is more than one then embed all sign with the use of pdf-lib - // else if (pngUrl.length > 0 && pngUrl[0].pos.length > 0) { - const flag = false; - //embed document's object id to all pages in pdf document - if (!isDocId) { - await embedDocId(pdfDoc, documentId, allPages); + for (let i = 0; i < checkSign.length; i++) { + const posData = checkSign[i].pos.filter((pos) => !pos.SignUrl); + if (posData && posData.length > 0) { + checkSignUrl.push(posData); + } } - //embed multi signature in pdf - const pdfBytes = await multiSignEmbed( - pngUrl, - pdfDoc, - pdfOriginalWidth, - flag, - containerWH - ); - //function for call to embed signature in pdf and get digital signature pdf - try { - const res = await signPdfFun( - pdfBytes, - documentId, - signerObjectId, - pdfOriginalWidth, - pngUrl, - containerWH, - setIsAlert + + if (checkSignUrl && checkSignUrl.length > 0) { + setIsAlert({ + isShow: true, + alertMessage: "Please complete your signature!" + }); + } else { + setIsUiLoading(true); + const pngUrl = checkUser[0].placeHolder; + // Load a PDFDocument from the existing PDF bytes + const existingPdfBytes = await fetch(pdfUrl).then((res) => + res.arrayBuffer() ); - if (res && res.status === "success") { - setPdfUrl(res.data); - setIsSigned(true); - setSignedSigners([]); - setUnSignedSigners([]); - getDocumentDetails(); - } else { + const pdfDoc = await PDFDocument.load(existingPdfBytes, { + ignoreEncryption: true + }); + // let pdfBase64; + + //checking if signature is only one then send image url in jpeg formate to server + // if (pngUrl.length === 1 && pngUrl[0].pos.length === 1) { + // if (isDocId) { + // try { + // pdfBase64 = await getBase64FromUrl(pdfUrl); + // } catch (err) { + // console.log(err); + // } + // } else { + // //embed document's object id to all pages in pdf document + // try { + // await embedDocId(pdfDoc, documentId, allPages); + // } catch (err) { + // console.log(err); + // } + // try { + // pdfBase64 = await pdfDoc.saveAsBase64({ + // useObjectStreams: false + // }); + // } catch (err) { + // console.log(err); + // } + // } + // for (let pngData of pngUrl) { + // const imgUrlList = pngData.pos; + // const pageNo = pngData.pageNumber; + // imgUrlList.map(async (data) => { + // //cheking signUrl is defau;t signature url of custom url + // let ImgUrl = data.SignUrl; + // const checkUrl = urlValidator(ImgUrl); + // //if default signature url then convert it in base 64 + // if (checkUrl) { + // ImgUrl = await getBase64FromIMG(ImgUrl + "?get"); + // } + // //function for called convert png signatre to jpeg in base 64 + // convertPNGtoJPEG(ImgUrl) + // .then((jpegBase64Data) => { + // const removeBase64Fromjpeg = "data:image/jpeg;base64,"; + // const newImgUrl = jpegBase64Data.replace( + // removeBase64Fromjpeg, + // "" + // ); + + // //function for call to embed signature in pdf and get digital signature pdf + // signPdfFun( + // newImgUrl, + // documentId, + // signerObjectId, + // pdfOriginalWidth, + // pngUrl, + // containerWH, + // setIsAlert, + // data, + // pdfBase64, + // pageNo + // ) + // .then((res) => { + // if (res && res.status === "success") { + // setPdfUrl(res.data); + // setIsSigned(true); + // setSignedSigners([]); + // setUnSignedSigners([]); + // getDocumentDetails(); + // } else { + // setIsAlert({ + // isShow: true, + // alertMessage: "something went wrong" + // }); + // } + // }) + // .catch((err) => { + // setIsAlert({ + // isShow: true, + // alertMessage: "something went wrong" + // }); + // }); + // }) + // .catch((error) => { + // console.error("Error:", error); + // }); + // }); + // } + // } + // //else if signature is more than one then embed all sign with the use of pdf-lib + // else if (pngUrl.length > 0 && pngUrl[0].pos.length > 0) { + const flag = false; + //embed document's object id to all pages in pdf document + if (!isDocId) { + await embedDocId(pdfDoc, documentId, allPages); + } + //embed multi signature in pdf + const pdfBytes = await multiSignEmbed( + pngUrl, + pdfDoc, + pdfOriginalWidth, + flag, + containerWH + ); + //function for call to embed signature in pdf and get digital signature pdf + try { + const res = await signPdfFun( + pdfBytes, + documentId, + signerObjectId, + pdfOriginalWidth, + pngUrl, + containerWH, + setIsAlert + ); + if (res && res.status === "success") { + setPdfUrl(res.data); + setIsSigned(true); + setSignedSigners([]); + setUnSignedSigners([]); + getDocumentDetails(); + if (sendInOrder) { + const index = pdfDetails?.[0].Signers.findIndex( + (x) => x.Email === jsonSender.email + ); + const newIndex = index + 1; + const user = pdfDetails?.[0].Signers[newIndex]; + if (user) { + let sendMail; + // console.log("pdfDetails", pdfDetails); + const expireDate = pdfDetails?.[0].ExpiryDate.iso; + const newDate = new Date(expireDate); + const localExpireDate = newDate.toLocaleDateString("en-US", { + day: "numeric", + month: "long", + year: "numeric" + }); + let sender = pdfDetails?.[0].ExtUserPtr.Email; + + try { + const imgPng = + "https://qikinnovation.ams3.digitaloceanspaces.com/logo.png"; + let url = `${localStorage.getItem( + "baseUrl" + )}functions/sendmailv3/`; + const headers = { + "Content-Type": "application/json", + "X-Parse-Application-Id": + localStorage.getItem("parseAppId"), + sessionToken: localStorage.getItem("accesstoken") + }; + const serverUrl = localStorage.getItem("baseUrl"); + const newServer = serverUrl.replaceAll("/", "%2F"); + const objectId = user.objectId; + const serverParams = `${newServer}&${localStorage.getItem( + "parseAppId" + )}&${localStorage.getItem("_appName")}`; + + const hostUrl = + window.location.origin + "/loadmf/signmicroapp"; + let signPdf = `${hostUrl}/login/${pdfDetails?.[0].objectId}/${user.Email}/${objectId}/${serverParams}`; + const openSignUrl = + "https://www.opensignlabs.com/contact-us"; + const orgName = pdfDetails[0]?.ExtUserPtr.Company + ? pdfDetails[0].ExtUserPtr.Company + : ""; + const themeBGcolor = themeColor(); + let params = { + recipient: user.Email, + subject: `${pdfDetails?.[0].ExtUserPtr.Name} has requested you to sign ${pdfDetails?.[0].Name}`, + from: sender, + + html: + "

Digital Signature Request

" + + pdfDetails?.[0].ExtUserPtr.Name + + " has requested you to review and sign " + + pdfDetails?.[0].Name + + ".

Sender " + + sender + + "
Organization " + + orgName + + "
Expires on " + + localExpireDate + + "

This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender " + + sender + + " directly.If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ here.

" + }; + sendMail = await axios.post(url, params, { + headers: headers + }); + } catch (error) { + console.log("error", error); + } + } + } + } else { + setIsAlert({ + isShow: true, + alertMessage: "something went wrong" + }); + } + } catch (err) { setIsAlert({ isShow: true, alertMessage: "something went wrong" }); } - } catch (err) { - setIsAlert({ - isShow: true, - alertMessage: "something went wrong" - }); } - } - setIsSignPad(false); - // } + setIsSignPad(false); + // } + } else { + setIsAlert({ + isShow: true, + alertMessage: "something went wrong" + }); + } } else { setIsAlert({ isShow: true, - alertMessage: "something went wrong" + alertMessage: + "Please wait for your turn to sign this document, as it has been set up by the creator to be signed in a specific order; you'll be notified when it's your turn." }); } } diff --git a/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js b/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js index a8c34524d..ed8c54812 100644 --- a/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js +++ b/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js @@ -668,7 +668,8 @@ const TemplatePlaceholder = () => { Signers: signers, Name: pdfDetails[0]?.Name || "", Note: pdfDetails[0]?.Note || "", - Description: pdfDetails[0]?.Description || "" + Description: pdfDetails[0]?.Description || "", + SendinOrder: pdfDetails[0]?.SendinOrder || false }; await axios diff --git a/microfrontends/SignDocuments/src/Component/component/EditTemplate.js b/microfrontends/SignDocuments/src/Component/component/EditTemplate.js index f60091c6d..9290069ad 100644 --- a/microfrontends/SignDocuments/src/Component/component/EditTemplate.js +++ b/microfrontends/SignDocuments/src/Component/component/EditTemplate.js @@ -7,7 +7,8 @@ const EditTemplate = ({ template, onSuccess }) => { const [formData, setFormData] = useState({ Name: template?.Name || "", Note: template?.Note || "", - Description: template?.Description || "" + Description: template?.Description || "", + SendinOrder: template?.SendinOrder ? `${template?.SendinOrder}` : "false" }); const handleStrInput = (e) => { @@ -22,7 +23,8 @@ const EditTemplate = ({ template, onSuccess }) => { const handleSubmit = async (e) => { e.preventDefault(); e.stopPropagation(); - const data = {...formData } + const isChecked = formData.SendinOrder === "true" ? true : false; + const data = { ...formData, SendinOrder: isChecked }; onSuccess(data); }; @@ -86,6 +88,45 @@ const EditTemplate = ({ template, onSuccess }) => { className="addUserInput" /> +
+ +
+ +
Yes
+
+
+ +
No
+
+
{/* */}