+ All roles in this document are currently linked to contacts. To
+ 'quick send' copies of this template to multiple
+ signers, please ensure that at least one role is not linked to
+ any contact.
- All roles in this document are currently linked to contacts. To
- 'quick send' copies of this template to multiple
- signers, please ensure that at least one role is not linked to any
- contact.
-
- )}
- >
+ )}
+ >
+ ) : (
+
+ Please ensure there's at least one signature widget added for
+ all recipients.
+
Please add at least one role to this template in order to 'quick
diff --git a/apps/OpenSign/src/components/pdf/RenderPdf.js b/apps/OpenSign/src/components/pdf/RenderPdf.js
index 44f15881c..2bac6b85e 100644
--- a/apps/OpenSign/src/components/pdf/RenderPdf.js
+++ b/apps/OpenSign/src/components/pdf/RenderPdf.js
@@ -206,13 +206,9 @@ function RenderPdf({
const checkSignedSignes = (data) => {
let checkSign = [];
//condition to handle quick send flow and using normal request sign flow
- if (signedSigners[0]?.Id) {
- checkSign = signedSigners.filter((sign) => sign.Id === data.Id);
- } else {
- checkSign = signedSigners.filter(
- (sign) => sign.objectId === data.signerObjId
- );
- }
+ checkSign = signedSigners.filter(
+ (sign) => sign?.Id === data?.Id || sign?.objectId === data?.signerObjId
+ );
if (data.signerObjId === signerObjectId) {
setCurrentSigner(true);
}
diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js
index 3a24c4398..25a91a20c 100644
--- a/apps/OpenSign/src/constant/Utils.js
+++ b/apps/OpenSign/src/constant/Utils.js
@@ -669,6 +669,7 @@ export const createDocument = async (template, placeholders, signerData) => {
Name: Doc.Name,
URL: Doc.URL,
SignedUrl: Doc.SignedUrl,
+ SentToOthers: Doc.SentToOthers,
Description: Doc.Description,
Note: Doc.Note,
Placeholders: placeholdersArr,
diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js
index 97f2c71be..426a3aadf 100644
--- a/apps/OpenSign/src/pages/PdfRequestFiles.js
+++ b/apps/OpenSign/src/pages/PdfRequestFiles.js
@@ -403,25 +403,34 @@ function PdfRequestFiles() {
let signers = [];
let unSignedSigner = [];
- //`emailExist` variable to handle condition for quick send flow and show unsigned signers list
- const emailExist = documentData[0].Placeholders[0]?.email;
+ const placeholdersOrSigners = [];
+ for (const placeholder of documentData[0].Placeholders) {
+ //`emailExist` variable to handle condition for quick send flow and show unsigned signers list
+ const emailExist = placeholder?.email;
+ if (emailExist) {
+ placeholdersOrSigners.push(placeholder);
+ } else {
+ const getSignerData = documentData[0].Signers.filter(
+ (data) => data.objectId === placeholder?.signerObjId
+ );
+ placeholdersOrSigners.push(getSignerData[0]);
+ }
+ }
//condition to check already signed document by someone
if (audittrailData && audittrailData.length > 0) {
setIsDocId(true);
- const placeholdersOrSigners = emailExist
- ? documentData[0].Placeholders
- : documentData[0].Signers;
for (const item of placeholdersOrSigners) {
+ const checkEmail = item?.email;
//if email exist then compare user signed by using email else signers objectId
- const emailOrId = emailExist ? item.email : item.objectId;
+ const emailOrId = checkEmail ? item.email : item.objectId;
//`isSignedSignature` variable to handle break loop whenever it get true
let isSignedSignature = false;
//checking the signer who signed the document by using audit trail details.
//and save signedSigners and unsignedSigners details
for (const doc of audittrailData) {
- const signedExist = emailExist
+ const signedExist = checkEmail
? doc?.UserPtr.Email
: doc?.UserPtr.objectId;
@@ -441,12 +450,7 @@ function PdfRequestFiles() {
} else {
//else condition is show there are no details in audit trail then direct push all signers details
//in unsignedsigners array
- let unsigned = [];
- const placeholdersOrSigners = emailExist
- ? documentData[0].Placeholders
- : documentData[0].Signers;
- unsigned.push(placeholdersOrSigners);
- setUnSignedSigners(unsigned[0]);
+ setUnSignedSigners(placeholdersOrSigners);
setSignerPos(documentData[0].Placeholders);
}
setPdfDetails(documentData);
@@ -1000,8 +1004,10 @@ function PdfRequestFiles() {
}
const getFirstLetter = (name) => {
- const firstLetter = name.charAt(0);
- return firstLetter;
+ if (name) {
+ const firstLetter = name.charAt(0);
+ return firstLetter;
+ }
};
//function for image upload or update
const onImageChange = (event) => {
@@ -1123,8 +1129,12 @@ function PdfRequestFiles() {
};
const checkUserNameColor = (obj) => {
const getBackColor = checkSignerBackColor(obj);
- const color = darkenColor(getBackColor, 0.4);
- return color;
+ if (getBackColor) {
+ const color = darkenColor(getBackColor, 0.4);
+ return color;
+ } else {
+ return "#abd1d0";
+ }
};
//function for set decline true on press decline button
diff --git a/apps/OpenSign/src/pages/PlaceHolderSign.js b/apps/OpenSign/src/pages/PlaceHolderSign.js
index 6e9fa46a9..3f25695f5 100644
--- a/apps/OpenSign/src/pages/PlaceHolderSign.js
+++ b/apps/OpenSign/src/pages/PlaceHolderSign.js
@@ -936,6 +936,7 @@ function PlaceHolderSign() {
Placeholders: filterPrefill,
SignedUrl: pdfUrl,
Signers: signers,
+ SentToOthers: true,
ExpiryDate: {
iso: updateExpiryDate,
__type: "Date"
@@ -945,7 +946,8 @@ function PlaceHolderSign() {
data = {
Placeholders: filterPrefill,
SignedUrl: pdfUrl,
- Signers: signers
+ Signers: signers,
+ SentToOthers: true
};
}
await axios
diff --git a/apps/OpenSign/src/primitives/GetReportDisplay.js b/apps/OpenSign/src/primitives/GetReportDisplay.js
index 0a04073bf..45011e213 100644
--- a/apps/OpenSign/src/primitives/GetReportDisplay.js
+++ b/apps/OpenSign/src/primitives/GetReportDisplay.js
@@ -143,6 +143,7 @@ const ReportTable = (props) => {
Name: Doc.Name,
URL: Doc.URL,
SignedUrl: Doc.SignedUrl,
+ SentToOthers: Doc?.SentToOthers || false,
Description: Doc.Description,
Note: Doc.Note,
Placeholders: placeholdersArr,
@@ -338,7 +339,7 @@ const ReportTable = (props) => {
const sendMail = item?.SendMail || false;
const getUrl = (x) => {
//encode this url value `${item.objectId}/${x.Email}/${x.objectId}` to base64 using `btoa` function
- if (x.objectId) {
+ if (x?.signerObjId) {
const encodeBase64 = btoa(
`${item.objectId}/${x.signerPtr.Email}/${x.signerPtr.objectId}/${sendMail}`
);
@@ -495,9 +496,9 @@ const ReportTable = (props) => {
// `handleSubjectChange` is used to add or change subject of resend mail
const handleSubjectChange = (subject, doc) => {
- const encodeBase64 = btoa(
- `${doc.objectId}/${userDetails.Email}/${userDetails.objectId}`
- );
+ const encodeBase64 = userDetails?.objectId
+ ? btoa(`${doc.objectId}/${userDetails.Email}/${userDetails.objectId}`)
+ : btoa(`${doc.objectId}/${userDetails.Email}`);
const expireDate = doc.ExpiryDate.iso;
const newDate = new Date(expireDate);
const localExpireDate = newDate.toLocaleDateString("en-US", {
@@ -511,8 +512,8 @@ const ReportTable = (props) => {
sender_name: doc.ExtUserPtr.Name,
sender_mail: doc.ExtUserPtr.Email,
sender_phone: doc.ExtUserPtr?.Phone || "",
- receiver_name: userDetails.Name,
- receiver_email: userDetails.Email,
+ receiver_name: userDetails?.Name,
+ receiver_email: userDetails?.Email,
receiver_phone: userDetails?.Phone || "",
expiry_date: localExpireDate,
company_name: doc.ExtUserPtr.Company,
@@ -524,9 +525,9 @@ const ReportTable = (props) => {
};
// `handlebodyChange` is used to add or change body of resend mail
const handlebodyChange = (body, doc) => {
- const encodeBase64 = btoa(
- `${doc.objectId}/${userDetails.Email}/${userDetails.objectId}`
- );
+ const encodeBase64 = userDetails?.objectId
+ ? btoa(`${doc.objectId}/${userDetails.Email}/${userDetails.objectId}`)
+ : btoa(`${doc.objectId}/${userDetails.Email}`);
const expireDate = doc.ExpiryDate.iso;
const newDate = new Date(expireDate);
const localExpireDate = newDate.toLocaleDateString("en-US", {
@@ -540,8 +541,8 @@ const ReportTable = (props) => {
sender_name: doc.ExtUserPtr.Name,
sender_mail: doc.ExtUserPtr.Email,
sender_phone: doc.ExtUserPtr?.Phone || "",
- receiver_name: userDetails.Name,
- receiver_email: userDetails.Email,
+ receiver_name: userDetails?.Name || "",
+ receiver_email: userDetails?.Email || "",
receiver_phone: userDetails?.Phone || "",
expiry_date: localExpireDate,
company_name: doc.ExtUserPtr.Company,
@@ -556,8 +557,18 @@ const ReportTable = (props) => {
// `handleNextBtn` is used to open edit mail template screen in resend mail modal
// as well as replace variable with original one
const handleNextBtn = (user, doc) => {
- setUserDetails(user);
- const encodeBase64 = btoa(`${doc.objectId}/${user.Email}/${user.objectId}`);
+ const userdata = {
+ Name: user?.signerPtr?.Name,
+ Email: user.email ? user?.email : user.signerPtr?.Email,
+ Phone: user?.signerPtr?.Phone,
+ objectId: user?.signerPtr?.objectId
+ };
+ setUserDetails(userdata);
+ const encodeBase64 = user.email
+ ? btoa(`${doc.objectId}/${user.email}`)
+ : btoa(
+ `${doc.objectId}/${user.signerPtr.Email}/${user.signerPtr.objectId}`
+ );
const expireDate = doc.ExpiryDate.iso;
const newDate = new Date(expireDate);
const localExpireDate = newDate.toLocaleDateString("en-US", {
@@ -571,9 +582,9 @@ const ReportTable = (props) => {
sender_name: doc.ExtUserPtr.Name,
sender_mail: doc.ExtUserPtr.Email,
sender_phone: doc.ExtUserPtr?.Phone || "",
- receiver_name: user.Name,
- receiver_email: user.Email,
- receiver_phone: user?.Phone || "",
+ receiver_name: user?.signerPtr?.Name || "",
+ receiver_email: user?.email ? user?.email : user?.signerPtr?.Email,
+ receiver_phone: user?.signerPtr?.Phone || "",
expiry_date: localExpireDate,
company_name: doc?.ExtUserPtr?.Company || "",
signing_url: `
Sign here`
@@ -584,14 +595,14 @@ const ReportTable = (props) => {
`{{sender_name}} has requested you to sign "{{document_title}}"`;
const body =
doc?.RequestBody ||
- `
Hi {{receiver_name}},
We hope this email finds you well. {{sender_name}} has requested you to review and sign "{{document_title}}".
Your signature is crucial to proceed with the next steps as it signifies your agreement and authorization.
{{signing_url}}
If you have any questions or need further clarification regarding the document or the signing process, please contact the sender.
Thanks
Team OpenSign™
`;
+ `
Hi {{receiver_name}},
We hope this email finds you well. {{sender_name}} has requested you to review and sign "{{document_title}}".
Your signature is crucial to proceed with the next steps as it signifies your agreement and authorization.
{{signing_url}}
If you have any questions or need further clarification regarding the document or the signing process, please contact the sender.
Thanks
Team OpenSign™
`;
const res = replaceMailVaribles(subject, body, variables);
setMail((prev) => ({ ...prev, subject: res.subject, body: res.body }));
- setIsNextStep({ [user.objectId]: true });
+ setIsNextStep({ [user.Id]: true });
};
const handleResendMail = async (e, doc, user) => {
e.preventDefault();
- setActLoader({ [user.objectId]: true });
+ setActLoader({ [user?.Id]: true });
const url = `${localStorage.getItem("baseUrl")}functions/sendmailv3`;
const headers = {
"Content-Type": "application/json",
@@ -601,7 +612,7 @@ const ReportTable = (props) => {
let params = {
mailProvider: doc?.ExtUserPtr?.active_mail_adapter,
extUserId: doc?.ExtUserPtr?.objectId,
- recipient: userDetails.Email,
+ recipient: userDetails?.Email,
subject: mail.subject,
from: doc?.ExtUserPtr?.Email,
html: mail.body
@@ -633,9 +644,9 @@ const ReportTable = (props) => {
}
};
const fetchUserStatus = (user, doc) => {
- const audit = doc?.AuditTrail?.find(
- (x) => x.UserPtr.objectId === user.objectId
- );
+ const email = user.email ? user.email : user.signerPtr.Email;
+ const audit = doc?.AuditTrail?.find((x) => x.UserPtr.Email === email);
+
return (
@@ -789,23 +800,38 @@ const ReportTable = (props) => {
const getPlaceholder = item?.Placeholders;
//condiiton to check role is exist or not
if (getPlaceholder && getPlaceholder.length > 0) {
- let extendUser = JSON.parse(localStorage.getItem("Extand_Class"));
- const userName = extendUser[0]?.UserName;
- setIsPublicUserName(extendUser[0]?.UserName);
- //condition to check user have public url or not
- if (userName) {
- setIsPublic((prevStates) => ({
- ...prevStates,
- [item.objectId]: e.target.checked
- }));
- const getPlaceholder = item?.Placeholders;
- if (getPlaceholder.length === 1) {
- setSelectedPublicRole(getPlaceholder[0]?.Role);
- }
+ const checkIsSignatureExistt = getPlaceholder?.every((placeholderObj) =>
+ placeholderObj?.placeHolder?.some((holder) =>
+ holder?.pos?.some((posItem) => posItem?.type === "signature")
+ )
+ );
+ if (checkIsSignatureExistt) {
+ let extendUser = JSON.parse(localStorage.getItem("Extand_Class"));
+ const userName = extendUser[0]?.UserName;
+ setIsPublicUserName(extendUser[0]?.UserName);
+ //condition to check user have public url or not
+ if (userName) {
+ setIsPublic((prevStates) => ({
+ ...prevStates,
+ [item.objectId]: e.target.checked
+ }));
+ const getPlaceholder = item?.Placeholders;
+ if (getPlaceholder.length === 1) {
+ setSelectedPublicRole(getPlaceholder[0]?.Role);
+ }
- setIsMakePublic({ [item.objectId]: true });
+ setIsMakePublic({ [item.objectId]: true });
+ } else {
+ setIsPublicProfile({ [item.objectId]: true });
+ }
} else {
- setIsPublicProfile({ [item.objectId]: true });
+ setIsAlert(true);
+ setAlertMsg({
+ type: "danger",
+ message:
+ " Please ensure there's at least one signature widget added for all recipients."
+ });
+ setTimeout(() => setIsAlert(false), 5000);
}
} else {
setIsAlert(true);
@@ -813,7 +839,7 @@ const ReportTable = (props) => {
type: "danger",
message: "Please assign at least one role to make this template public."
});
- setTimeout(() => setIsAlert(false), 3000);
+ setTimeout(() => setIsAlert(false), 5000);
}
};
@@ -1240,11 +1266,11 @@ const ReportTable = (props) => {
}}
>
- {item?.Signers.map((user) => (
-
- {isNextStep[user.objectId] && (
+ {item?.Placeholders?.map((user) => (
+
+ {isNextStep[user.Id] && (
- {actLoader[user.objectId] && (
+ {actLoader[user.Id] && (
{
>
{
{Object?.keys(isNextStep) <= 0 && (
- {user.Name} {`<${user.Email}>`}
+ {user?.signerPtr?.Name || "-"}{" "}
+ {`<${
+ user?.email
+ ? user.email
+ : user.signerPtr.Email
+ }>`}
<>{fetchUserStatus(user, item)}>
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js
index aa3d327ea..758ff7971 100644
--- a/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js
@@ -179,6 +179,7 @@ export default async function createDocumentWithTemplate(request, response) {
}
object.set('URL', template.URL);
object.set('SignedUrl', template.URL);
+ object.set('SentToOthers', true);
if (TimeToCompleteDays) {
object.set('TimeToCompleteDays', TimeToCompleteDays);
}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js
index 32df43ad0..f00161a2b 100644
--- a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js
@@ -141,6 +141,7 @@ export default async function createDocumentwithCoordinate(request, response) {
}
object.set('URL', fileUrl);
object.set('SignedUrl', fileUrl);
+ object.set('SentToOthers', true);
object.set('CreatedBy', userPtr);
object.set('ExtUserPtr', extUserPtr);
if (TimeToCompleteDays) {
diff --git a/apps/OpenSignServer/cloud/parsefunction/createBatchDocs.js b/apps/OpenSignServer/cloud/parsefunction/createBatchDocs.js
index 2f4aed714..602ddb9db 100644
--- a/apps/OpenSignServer/cloud/parsefunction/createBatchDocs.js
+++ b/apps/OpenSignServer/cloud/parsefunction/createBatchDocs.js
@@ -140,12 +140,14 @@ export default async function createBatchDocs(request) {
: { ...y, signerPtr: {}, signerObjId: '' }
),
SignedUrl: x.URL || x.SignedUrl,
+ SentToOthers: true,
Signers: allSigner?.map(y => ({
__type: 'Pointer',
className: 'contracts_Contactbook',
objectId: y.objectId,
})),
ACL: Acl,
+ SentToOthers: true,
RemindOnceInEvery: x.RemindOnceInEvery || 5,
AutomaticReminders: x.AutomaticReminders || false,
TimeToCompleteDays: x.TimeToCompleteDays || 15,