From 806894b24b34dd1d06a8509ae079b7c2673caa88 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Wed, 4 Sep 2024 14:48:49 +0530 Subject: [PATCH 1/7] fix : issue while rename the document/folder in opensign-drive --- .../src/components/opensigndrive/DriveBody.js | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/apps/OpenSign/src/components/opensigndrive/DriveBody.js b/apps/OpenSign/src/components/opensigndrive/DriveBody.js index 37f11c55c..4a7fde6b0 100644 --- a/apps/OpenSign/src/components/opensigndrive/DriveBody.js +++ b/apps/OpenSign/src/components/opensigndrive/DriveBody.js @@ -357,7 +357,7 @@ function DriveBody(props) { e.stopPropagation(); handleMenuItemClick("Download", data); }} - className="fa-light fa-download mr-[8px] op-text-primary" + className="fa-light fa-download mr-[8px] op-text-primary cursor-pointer" aria-hidden="true" > @@ -370,7 +370,16 @@ function DriveBody(props) { {/* folder */}
handleOnclikFolder(data)} + onClick={() => { + if (rename) { + inputRef.current.setSelectionRange( + inputRef.current.value.length, + inputRef.current.value.length + ); + } else { + handleOnclikFolder(data); + } + }} className="cursor-pointer" > {rename === data.objectId ? ( {data.Name} @@ -423,7 +425,11 @@ function DriveBody(props) {
) : ( - +
@@ -432,7 +438,16 @@ function DriveBody(props) { {/* pdf */}
checkPdfStatus(data)} + onClick={() => { + if (rename) { + inputRef.current.setSelectionRange( + inputRef.current.value.length, + inputRef.current.value.length + ); + } else { + checkPdfStatus(data); + } + }} className="cursor-pointer" > { - inputRef.current.setSelectionRange(0, 0); - const input = inputRef.current; - if (input) { - input.select(); - } - }} + onFocus={() => inputRef.current.select()} onBlur={() => handledRenameDoc(data)} onKeyDown={(e) => handleEnterPress(e, data)} ref={inputRef} defaultValue={renameValue} - // value={renameValue} onChange={(e) => setRenameValue(e.target.value)} - className="w-[100px] border-[1.5px] border-black rounded-sm text-[10px]" + className="op-input op-input-bordered op-input-xs w-[100px] focus:outline-none hover:border-base-content text-[10px]" /> ) : ( {data.Name} From 4f2b0313dec77c96ccf70bf408b511fcd59f4246 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Wed, 4 Sep 2024 15:09:38 +0530 Subject: [PATCH 2/7] refactor code --- .../src/components/opensigndrive/DriveBody.js | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/apps/OpenSign/src/components/opensigndrive/DriveBody.js b/apps/OpenSign/src/components/opensigndrive/DriveBody.js index 4a7fde6b0..b0df1a745 100644 --- a/apps/OpenSign/src/components/opensigndrive/DriveBody.js +++ b/apps/OpenSign/src/components/opensigndrive/DriveBody.js @@ -371,12 +371,7 @@ function DriveBody(props) {
{ - if (rename) { - inputRef.current.setSelectionRange( - inputRef.current.value.length, - inputRef.current.value.length - ); - } else { + if (!rename) { handleOnclikFolder(data); } }} @@ -439,12 +434,7 @@ function DriveBody(props) {
{ - if (rename) { - inputRef.current.setSelectionRange( - inputRef.current.value.length, - inputRef.current.value.length - ); - } else { + if (!rename) { checkPdfStatus(data); } }} From 9cc9a93c3d29b45187baca249acd3fa61e30cc96 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Wed, 4 Sep 2024 15:13:10 +0530 Subject: [PATCH 3/7] fix: handle error --- .../src/components/opensigndrive/DriveBody.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/OpenSign/src/components/opensigndrive/DriveBody.js b/apps/OpenSign/src/components/opensigndrive/DriveBody.js index b0df1a745..1b4e69a2e 100644 --- a/apps/OpenSign/src/components/opensigndrive/DriveBody.js +++ b/apps/OpenSign/src/components/opensigndrive/DriveBody.js @@ -386,7 +386,12 @@ function DriveBody(props) { {rename === data.objectId ? ( inputRef.current.select()} + onFocus={() => { + const input = inputRef.current; + if (input) { + input.select(); + } + }} autoFocus={true} type="text" onBlur={() => handledRenameDoc(data)} @@ -451,7 +456,12 @@ function DriveBody(props) { inputRef.current.select()} + onFocus={() => { + const input = inputRef.current; + if (input) { + input.select(); + } + }} onBlur={() => handledRenameDoc(data)} onKeyDown={(e) => handleEnterPress(e, data)} ref={inputRef} From e2eddb6362fd404c9db6e0ce120ac8f39014d45c Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Thu, 5 Sep 2024 16:59:47 +0530 Subject: [PATCH 4/7] refactor: validation --- .../public/locales/en/translation.json | 9 +- .../public/locales/fr/translation.json | 7 +- apps/OpenSign/src/components/BulkSendUi.js | 117 ++++++++++++------ apps/OpenSign/src/constant/Utils.js | 19 +-- apps/OpenSign/src/pages/GenerateToken.js | 43 ++++++- .../src/script/locales/en/translation.json | 7 +- .../src/script/locales/fr/translation.json | 7 +- .../cloud/customRoute/saveSubscription.js | 92 +++++++++++--- .../cloud/parsefunction/BuyAddonUsers.js | 6 + .../cloud/parsefunction/saveSubscription.js | 91 +++++++++++--- 10 files changed, 302 insertions(+), 96 deletions(-) diff --git a/apps/OpenSign/public/locales/en/translation.json b/apps/OpenSign/public/locales/en/translation.json index f6df36dd7..017fdef3b 100644 --- a/apps/OpenSign/public/locales/en/translation.json +++ b/apps/OpenSign/public/locales/en/translation.json @@ -475,7 +475,7 @@ "role-not-found": "Role not found.", "do-not-access": "You don't have access, please contact the admin.", "add-admin": "Add admin", - "opensign-setup": "Opensign Setup", + "opensign-setup": "OpenSign Setup", "join-discord": "Join our discord server", "admin-already-exist": "Admin already exist.", "password-update-alert-1": "Password updated successfully.", @@ -531,7 +531,7 @@ "filed-required-correctly": "Please fill required details correctly.", "admin-created": "Admin created", "invalid-masterkey": "Invalid masterkey", - "opensign-Setup": "Opensign Setup", + "opensign-Setup": "OpenSign Setup", "master-key": " Master key", "profile-update-alert": "Profile updated successfully.", "date": "Date", @@ -593,7 +593,7 @@ "Recently sent for signatures": "This is a list of documents you've sent to other parties for signature.", "Drafts": "This are documents you have started but have not finalized for sending.", "public-template": "This video demonstrates how to set up your personalized public profile, such as ‘https://opensign.me/your-username’. You’ll also learn how to customize your tagline and make your templates available for public signing." - }, + }, "enter-email-plaholder": "Add an email address and hit enter", "success-email-alert": "Email sent successfully!", "expired-doc-title": "Expired Document", @@ -634,6 +634,7 @@ "quotamailselfsign": "You've reached your limit of 20 emails for this month. Upgrade now to continue sending emails directly.", "quotamail": "You've reached your limit of 20 signature request emails for this month. Upgrade now to continue sending emails directly.", "quotamailTip":"Tip: You can still sign unlimited documents by manually sharing the signing request links below.", - "quotamailhead":"Quota Reached" + "quotamailhead":"Quota Reached", + "unauthorized-modal":"You don't have permission to perform this action, please contact {{adminName}}<{{adminEmail}}>." } diff --git a/apps/OpenSign/public/locales/fr/translation.json b/apps/OpenSign/public/locales/fr/translation.json index e52882f39..e90ffc42c 100644 --- a/apps/OpenSign/public/locales/fr/translation.json +++ b/apps/OpenSign/public/locales/fr/translation.json @@ -474,7 +474,7 @@ "role-not-found": "Rôle introuvable.", "do-not-access": "Vous n'y avez pas accès, veuillez contacter l'administrateur.", "add-admin": "Ajouter un administrateur", - "opensign-setup": "Configuration d'Opensign", + "opensign-setup": "Configuration d'OpenSign", "join-discord": "Rejoignez notre serveur Discord", "admin-already-exist": "L'administrateur existe déjà.", "password-update-alert-1": "Mot de passe mis à jour avec succès.", @@ -530,7 +530,7 @@ "filed-required-correctly": "Veuillez remplir correctement les informations requises.", "admin-created": "Administrateur créé", "invalid-masterkey": "Clé principale invalide", - "opensign-Setup": "Configuration d'Opensign", + "opensign-Setup": "Configuration d'OpenSign", "master-key": "La clef maitresse", "profile-update-alert": "Mise à jour du profil réussie.", "date": "Date", @@ -634,6 +634,7 @@ "quotamailselfsign": "Vous avez atteint votre limite de 20 e-mails pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.", "quotamail": "Vous avez atteint votre limite de 20 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.", "quotamailTip":"Astuce : Vous pouvez toujours signer un nombre illimité de documents en partageant manuellement les liens de demande de signature ci-dessous.", - "quotamailhead":"Quota atteint" + "quotamailhead":"Quota atteint", + "unauthorized-modal":"Vous n'êtes pas autorisé à effectuer cette action, veuillez contacter {{adminName}}<{{adminEmail}}>." } diff --git a/apps/OpenSign/src/components/BulkSendUi.js b/apps/OpenSign/src/components/BulkSendUi.js index 4491a08d3..6e42344a5 100644 --- a/apps/OpenSign/src/components/BulkSendUi.js +++ b/apps/OpenSign/src/components/BulkSendUi.js @@ -29,6 +29,12 @@ const BulkSendUi = (props) => { const [isQuotaReached, setIsQuotaReached] = useState(false); const [isLoader, setIsLoader] = useState(false); const [isFreePlan, setIsFreePlan] = useState(false); + const [admin, setAdmin] = useState({ + objectId: "", + name: "", + email: "", + isAdmin: true + }); const allowedSigners = 50; useEffect(() => { signatureExist(); @@ -41,6 +47,27 @@ const BulkSendUi = (props) => { setIsLoader(true); try { const subscription = await fetchSubscription(); + const extUser = + localStorage.getItem("Extand_Class") && + JSON.parse(localStorage.getItem("Extand_Class"))?.[0]; + if ( + subscription?.adminId && + extUser?.objectId === subscription?.adminId + ) { + setAdmin((obj) => ({ + ...obj, + objectId: subscription?.adminId, + isAdmin: true + })); + } else { + setAdmin((obj) => ({ + ...obj, + isAdmin: false, + name: extUser?.CreatedBy?.name, + email: extUser?.CreatedBy?.email + })); + } + setAdmin((obj) => ({ ...obj, objectId: subscription?.adminId })); if (subscription?.plan === "freeplan") { setIsFreePlan(true); } @@ -69,6 +96,7 @@ const BulkSendUi = (props) => { } } else { setIsBulkAvailable(true); + setAdmin((obj) => ({ ...obj, isAdmin: true })); const getPlaceholder = props.item?.Placeholders; const checkIsSignatureExistt = getPlaceholder?.every((placeholderObj) => placeholderObj?.placeHolder?.some((holder) => @@ -417,46 +445,57 @@ const BulkSendUi = (props) => {
) : ( -
-

- {t("additional-credits")} -

-
- - -
-
- -
- USD {amount.price} + <> + {admin?.isAdmin ? ( + +

+ {t("additional-credits")} +

+
+ + +
+
+ +
+ USD {amount.price} +
+
+
+ + + ) : ( +
+ {t("unauthorized-modal", { + adminName: admin?.name, + adminEmail: admin?.email + })}
-
-
- - + )} + )} )} diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index 71f7aa69d..4ec3c35d0 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -56,7 +56,7 @@ export async function fetchSubscription( ? { contactId: contactObjId } : { extUserId: extUser }; const tenatRes = await axios.post(url, params, { headers: headers }); - let plan, status, billingDate; + let plan, status, billingDate, adminId; if (isGuestSign) { plan = tenatRes.data?.result?.result?.plan; status = tenatRes.data?.result?.result?.isSubscribed; @@ -64,12 +64,13 @@ export async function fetchSubscription( plan = tenatRes.data?.result?.result?.PlanCode; billingDate = tenatRes.data?.result?.result?.Next_billing_date?.iso; const allowedUsers = tenatRes.data?.result?.result?.AllowedUsers || 0; + adminId = tenatRes?.data?.result?.result?.ExtUserPtr?.objectId; localStorage.setItem("allowedUsers", allowedUsers); } - return { plan, billingDate, status }; + return { plan, billingDate, status, adminId }; } catch (err) { console.log("Err in fetch subscription", err); - return { plan: "", billingDate: "" }; + return { plan: "", billingDate: "", status: "", adminId: "" }; } } @@ -122,22 +123,22 @@ export async function checkIsSubscribed() { try { const res = await fetchSubscription(); if (res.plan === "freeplan") { - return { plan: res.plan, isValid: false }; + return { plan: res.plan, isValid: false, adminId: res?.adminId }; } else if (res.billingDate) { const plan = validplan[res.plan] || false; if (plan && new Date(res.billingDate) > new Date()) { - return { plan: res.plan, isValid: true }; + return { plan: res.plan, isValid: true, adminId: res?.adminId }; } else if (new Date(res.billingDate) > new Date()) { - return { plan: res.plan, isValid: true }; + return { plan: res.plan, isValid: true, adminId: res?.adminId }; } else { - return { plan: res.plan, isValid: false }; + return { plan: res.plan, isValid: false, adminId: res?.adminId }; } } else { - return { plan: res.plan, isValid: false }; + return { plan: res.plan, isValid: false, adminId: res?.adminId }; } } catch (err) { console.log("Err in fetch subscription", err); - return { plan: "no-plan", isValid: false }; + return { plan: "no-plan", isValid: false, adminId: "" }; } } diff --git a/apps/OpenSign/src/pages/GenerateToken.js b/apps/OpenSign/src/pages/GenerateToken.js index d5fa82ac6..757a0f1f8 100644 --- a/apps/OpenSign/src/pages/GenerateToken.js +++ b/apps/OpenSign/src/pages/GenerateToken.js @@ -21,9 +21,16 @@ function GenerateToken() { const [isLoader, setIsLoader] = useState(true); const [isModal, setIsModal] = useState({ generateapi: false, - buyapis: false + buyapis: false, + unauthorized: false + }); + const [isSubscribe, setIsSubscribe] = useState({ + plan: "", + isValid: false, + adminId: "", + adminName: "", + adminEmail: "" }); - const [isSubscribe, setIsSubscribe] = useState({ plan: "", isValid: false }); const [isAlert, setIsAlert] = useState({ type: "success", msg: "" }); const [isTour, setIsTour] = useState(false); const [amount, setAmount] = useState({ @@ -139,10 +146,24 @@ function GenerateToken() { if (isSubscribe?.plan === "freeplan" && isEnableSubscription) { setIsTour(true); } else { - setIsModal((obj) => ({ ...obj, buyapis: !obj.buyapis })); + const extUser = + localStorage.getItem("Extand_Class") && + JSON.parse(localStorage.getItem("Extand_Class"))?.[0]; + if (isSubscribe?.adminId && extUser?.objectId === isSubscribe?.adminId) { + setIsModal((obj) => ({ ...obj, buyapis: !obj.buyapis })); + } else { + setIsSubscribe((obj) => ({ + ...obj, + adminName: extUser?.CreatedBy?.name, + adminEmail: extUser?.CreatedBy?.email + })); + setIsModal((obj) => ({ ...obj, unauthorized: !obj.unauthorized })); + } } }; - + const handleCloseModal = () => { + setIsModal({ generateapi: false, buyapis: false, unauthorized: false }); + }; const handlePricePerAPIs = (e) => { const quantity = e.target?.value; const price = @@ -374,7 +395,7 @@ function GenerateToken() { {isFormLoader && (
@@ -419,6 +440,18 @@ function GenerateToken() { + +
+ {t("unauthorized-modal", { + adminName: isSubscribe?.adminName, + adminEmail: isSubscribe?.adminEmail + })} +
+
{isEnableSubscription && isSubscribe?.plan === "freeplan" && (
diff --git a/apps/OpenSign/src/script/locales/en/translation.json b/apps/OpenSign/src/script/locales/en/translation.json index af6e2fbed..6564f0233 100644 --- a/apps/OpenSign/src/script/locales/en/translation.json +++ b/apps/OpenSign/src/script/locales/en/translation.json @@ -475,7 +475,7 @@ "role-not-found": "Role not found.", "do-not-access": "You don't have access, please contact the admin.", "add-admin": "Add admin", - "opensign-setup": "Opensign Setup", + "opensign-setup": "OpenSign Setup", "join-discord": "Join our discord server", "admin-already-exist": "Admin already exist.", "password-update-alert-1": "Password updated successfully.", @@ -531,7 +531,7 @@ "filed-required-correctly": "Please fill required details correctly.", "admin-created": "Admin created", "invalid-masterkey": "Invalid masterkey", - "opensign-Setup": "Opensign Setup", + "opensign-Setup": "OpenSign Setup", "master-key": " Master key", "profile-update-alert": "Profile updated successfully.", "date": "Date", @@ -631,6 +631,7 @@ "quotamailselfsign": "You've reached your limit of 20 emails for this month. Upgrade now to continue sending emails directly.", "quotamail": "You've reached your limit of 20 signature request emails for this month. Upgrade now to continue sending emails directly.", "quotamailTip":"Tip: You can still sign unlimited documents by manually sharing the signing request links below.", - "quotamailhead":"Quota Reached" + "quotamailhead":"Quota Reached", + "unauthorized-modal":"You don't have permission to perform this action, please contact {{adminName}}<{{adminEmail}}>." } diff --git a/apps/OpenSign/src/script/locales/fr/translation.json b/apps/OpenSign/src/script/locales/fr/translation.json index 6956bcff1..34d93d349 100644 --- a/apps/OpenSign/src/script/locales/fr/translation.json +++ b/apps/OpenSign/src/script/locales/fr/translation.json @@ -474,7 +474,7 @@ "role-not-found": "Rôle introuvable.", "do-not-access": "Vous n'y avez pas accès, veuillez contacter l'administrateur.", "add-admin": "Ajouter un administrateur", - "opensign-setup": "Configuration d'Opensign", + "opensign-setup": "Configuration d'OpenSign", "join-discord": "Rejoignez notre serveur Discord", "admin-already-exist": "L'administrateur existe déjà.", "password-update-alert-1": "Mot de passe mis à jour avec succès.", @@ -530,7 +530,7 @@ "filed-required-correctly": "Veuillez remplir correctement les informations requises.", "admin-created": "Administrateur créé", "invalid-masterkey": "Clé principale invalide", - "opensign-Setup": "Configuration d'Opensign", + "opensign-Setup": "Configuration d'OpenSign", "master-key": "La clef maitresse", "profile-update-alert": "Mise à jour du profil réussie.", "date": "Date", @@ -631,6 +631,7 @@ "quotamailselfsign": "Vous avez atteint votre limite de 20 e-mails pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.", "quotamail": "Vous avez atteint votre limite de 20 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.", "quotamailTip":"Astuce : Vous pouvez toujours signer un nombre illimité de documents en partageant manuellement les liens de demande de signature ci-dessous.", - "quotamailhead":"Quota atteint" + "quotamailhead":"Quota atteint", + "unauthorized-modal":"Vous n'êtes pas autorisé à effectuer cette action, veuillez contacter {{adminName}}<{{adminEmail}}>." } diff --git a/apps/OpenSignServer/cloud/customRoute/saveSubscription.js b/apps/OpenSignServer/cloud/customRoute/saveSubscription.js index 31b14503e..d6db217fd 100644 --- a/apps/OpenSignServer/cloud/customRoute/saveSubscription.js +++ b/apps/OpenSignServer/cloud/customRoute/saveSubscription.js @@ -7,8 +7,10 @@ export default async function saveSubscription(request, response) { const Next_billing_date = request.body?.data?.subscription?.next_billing_at; const planCode = request.body?.data?.subscription?.plan?.plan_code; const addons = request.body?.data?.subscription?.addons || []; + const event = request.body?.data?.event_type || ''; const credits = planCredits?.[planCode] || 0; - let existAddon = 0; + const isTeamPlan = planCode?.includes('team'); + let newAddons = 0; if (addons?.length > 0) { let allowedUsersMonthly = 0; let allowedUsersYearly = 0; @@ -22,11 +24,11 @@ export default async function saveSubscription(request, response) { } }); if (allowedUsersMonthly > 0 || allowedUsersYearly > 0) { - existAddon = allowedUsersMonthly + allowedUsersYearly + 1; + newAddons = allowedUsersMonthly + allowedUsersYearly + 1; } } else { if (planCode === 'teams-yearly' || planCode === 'teams-monthly' || planCode === 'team-weekly') { - existAddon = 1; + newAddons = 1; } } try { @@ -42,6 +44,7 @@ export default async function saveSubscription(request, response) { }); const subscription = await subcriptionCls.first({ useMasterKey: true }); if (subscription) { + const _resSub = JSON.parse(JSON.stringify(subscription)); const updateSubscription = new Parse.Object('contracts_Subscriptions'); updateSubscription.id = subscription.id; updateSubscription.set('SubscriptionId', SubscriptionId); @@ -52,27 +55,81 @@ export default async function saveSubscription(request, response) { updateSubscription.unset('Next_billing_date'); } updateSubscription.set('PlanCode', planCode); - if (existAddon > 0) { - updateSubscription.set('AllowedUsers', parseInt(existAddon)); + if (newAddons > 0) { + updateSubscription.set('AllowedUsers', parseInt(newAddons)); + } + let existAddon = 0; + let allowedUsersMonthly = 0; + let allowedUsersYearly = 0; + _resSub.SubscriptionDetails?.data?.subscription?.addons?.forEach(item => { + if (item.addon_code === 'extra-teams-users-monthly') { + allowedUsersMonthly += item.quantity; + } else if (item.addon_code === 'extra-teams-users-yearly') { + allowedUsersYearly += item.quantity; + } else if (item.addon_code === 'extra-users') { + allowedUsersMonthly += item.quantity; + } + }); + if (allowedUsersMonthly > 0 || allowedUsersYearly > 0) { + existAddon = allowedUsersMonthly + allowedUsersYearly + 1; // + 1 is Admin user + } else { + if ( + planCode === 'teams-yearly' || + planCode === 'teams-monthly' || + planCode === 'team-weekly' + ) { + existAddon = 1; // 1 is Admin user + } } const isSameAsPrevPlan = subscription?.get('PlanCode') === planCode; if (isSameAsPrevPlan) { const planCredits = subscription?.get('PlanCredits'); + const existAllowedCredits = subscription?.get('AllowedCredits') || 0; if (planCredits) { - updateSubscription.set('AllowedCredits', planCredits); + const oldAddons = existAddon; + const substractedAddon = newAddons - oldAddons; + if (isTeamPlan && substractedAddon > 0) { + const newCredits = existAllowedCredits + substractedAddon * planCredits; + updateSubscription.set('AllowedCredits', newCredits); + if (event === 'subscription_created') { + updateSubscription.set('PlanCredits', credits); + } + } else if (isTeamPlan) { + const existCredits = existAddon * planCredits; + updateSubscription.set('AllowedCredits', existCredits); + if (event === 'subscription_created') { + updateSubscription.set('PlanCredits', credits); + } + } else { + updateSubscription.set('AllowedCredits', planCredits); + if (event === 'subscription_created') { + updateSubscription.set('PlanCredits', credits); + } + } } else { if (credits > 0) { - updateSubscription.set('AllowedCredits', credits); - updateSubscription.set('PlanCredits', credits); + if (isTeamPlan) { + const newCredits = newAddons * credits; + updateSubscription.set('AllowedCredits', newCredits); + updateSubscription.set('PlanCredits', credits); + } else { + updateSubscription.set('AllowedCredits', credits); + updateSubscription.set('PlanCredits', credits); + } } } } else { if (credits > 0) { - updateSubscription.set('AllowedCredits', credits); - updateSubscription.set('PlanCredits', credits); + if (isTeamPlan) { + const newCredits = newAddons * credits; + updateSubscription.set('AllowedCredits', newCredits); + updateSubscription.set('PlanCredits', credits); + } else { + updateSubscription.set('AllowedCredits', credits); + updateSubscription.set('PlanCredits', credits); + } } } - await updateSubscription.save(null, { useMasterKey: true }); return response.status(200).json({ status: 'update subscription!' }); } else { @@ -100,11 +157,18 @@ export default async function saveSubscription(request, response) { createSubscription.unset('Next_billing_date'); } createSubscription.set('PlanCode', planCode); - if (existAddon > 0) { - createSubscription.set('AllowedUsers', parseInt(existAddon)); + if (newAddons > 0) { + createSubscription.set('AllowedUsers', parseInt(newAddons)); } if (credits > 0) { - createSubscription.set('AllowedCredits', credits); + if (isTeamPlan) { + const totalCredits = parseInt(newAddons) * credits; + createSubscription.set('AllowedCredits', totalCredits); + createSubscription.set('PlanCredits', credits); + } else { + createSubscription.set('AllowedCredits', credits); + createSubscription.set('PlanCredits', credits); + } } await createSubscription.save(null, { useMasterKey: true }); return response.status(200).json({ status: 'create subscription!' }); diff --git a/apps/OpenSignServer/cloud/parsefunction/BuyAddonUsers.js b/apps/OpenSignServer/cloud/parsefunction/BuyAddonUsers.js index 3ca147f4a..4281ab9d4 100644 --- a/apps/OpenSignServer/cloud/parsefunction/BuyAddonUsers.js +++ b/apps/OpenSignServer/cloud/parsefunction/BuyAddonUsers.js @@ -1,4 +1,5 @@ import axios from 'axios'; +import { planCredits } from '../../Utils.js'; export default async function BuyAddonUsers(request) { const users = request.params.users; if (!request?.user) { @@ -88,10 +89,15 @@ export default async function BuyAddonUsers(request) { ); const subscriptionInfo = { data: updatedSubscription.data }; const allowedUsers = quantity + 1; + const existAllowedCredits = _resSub?.AllowedCredits || 0; + const credits = resSub?.PlanCredits || planCredits[plan_code]; + const newAllowedCredits = users * credits; + const totalCredits = existAllowedCredits + newAllowedCredits; const updateSub = new Parse.Object('contracts_Subscriptions'); updateSub.id = resSub.id; updateSub.set('SubscriptionDetails', subscriptionInfo); updateSub.set('AllowedUsers', allowedUsers); + updateSub.set('AllowedCredits', totalCredits); const resupdateSub = await updateSub.save(null, { useMasterKey: true }); return { status: 'success', addon: allowedUsers }; } else { diff --git a/apps/OpenSignServer/cloud/parsefunction/saveSubscription.js b/apps/OpenSignServer/cloud/parsefunction/saveSubscription.js index 2c2a0a373..b7e8fcb3a 100644 --- a/apps/OpenSignServer/cloud/parsefunction/saveSubscription.js +++ b/apps/OpenSignServer/cloud/parsefunction/saveSubscription.js @@ -8,8 +8,10 @@ export default async function saveSubscription(request) { const body = subscription; const Next_billing_date = subscription.data.subscription.next_billing_at; const planCode = subscription.data.subscription.plan.plan_code; + const event = subscription?.data?.event_type || ''; const credits = planCredits?.[planCode] || 0; - let existAddon = 0; + const isTeamPlan = planCode?.includes('team'); + let newAddons = 0; try { const userRes = await axios.get(serverUrl + '/users/me', { headers: { @@ -47,7 +49,7 @@ export default async function saveSubscription(request) { } }); if (allowedUsersMonthly > 0 || allowedUsersYearly > 0) { - existAddon = allowedUsersMonthly + allowedUsersYearly + 1; + newAddons = allowedUsersMonthly + allowedUsersYearly + 1; // + 1 is Admin user } } else { if ( @@ -55,39 +57,90 @@ export default async function saveSubscription(request) { planCode === 'teams-monthly' || planCode === 'team-weekly' ) { - existAddon = 1; + newAddons = 1; // 1 is Admin user } } - - // const existAddon = addons.reduce((acc, curr) => acc + curr.quantity, 1); if (resSubscription) { + const _resSub = JSON.parse(JSON.stringify(resSubscription)); const updateSubscription = new Parse.Object('contracts_Subscriptions'); updateSubscription.id = resSubscription.id; updateSubscription.set('SubscriptionId', SubscriptionId); updateSubscription.set('SubscriptionDetails', body); updateSubscription.set('Next_billing_date', new Date(Next_billing_date)); updateSubscription.set('PlanCode', planCode); - if (existAddon > 0) { - updateSubscription.set('AllowedUsers', parseInt(existAddon)); + if (newAddons > 0) { + updateSubscription.set('AllowedUsers', parseInt(newAddons)); + } + let existAddon = 0; + let allowedUsersMonthly = 0; + let allowedUsersYearly = 0; + _resSub.SubscriptionDetails?.data?.subscription?.addons?.forEach(item => { + if (item.addon_code === 'extra-teams-users-monthly') { + allowedUsersMonthly += item.quantity; + } else if (item.addon_code === 'extra-teams-users-yearly') { + allowedUsersYearly += item.quantity; + } else if (item.addon_code === 'extra-users') { + allowedUsersMonthly += item.quantity; + } + }); + if (allowedUsersMonthly > 0 || allowedUsersYearly > 0) { + existAddon = allowedUsersMonthly + allowedUsersYearly + 1; // + 1 is Admin user + } else { + if ( + planCode === 'teams-yearly' || + planCode === 'teams-monthly' || + planCode === 'team-weekly' + ) { + existAddon = 1; // 1 is Admin user + } } const isSameAsPrevPlan = resSubscription?.get('PlanCode') === planCode; if (isSameAsPrevPlan) { const planCredits = resSubscription?.get('PlanCredits'); + const existAllowedCredits = resSubscription?.get('AllowedCredits') || 0; if (planCredits) { - updateSubscription.set('AllowedCredits', planCredits); + const oldAddons = existAddon; + const substractedAddon = newAddons - oldAddons; + if (isTeamPlan && substractedAddon > 0) { + const newCredits = existAllowedCredits + substractedAddon * planCredits; + updateSubscription.set('AllowedCredits', newCredits); + if (event === 'subscription_created') { + updateSubscription.set('PlanCredits', credits); + } + } else if (isTeamPlan) { + const existCredits = existAddon * planCredits; + updateSubscription.set('AllowedCredits', existCredits); + if (event === 'subscription_created') { + updateSubscription.set('PlanCredits', credits); + } + } else { + updateSubscription.set('AllowedCredits', planCredits); + if (event === 'subscription_created') { + updateSubscription.set('PlanCredits', credits); + } + } } else { - if (credits > 0) { + if (isTeamPlan) { + const newCredits = newAddons * credits; + updateSubscription.set('AllowedCredits', newCredits); + updateSubscription.set('PlanCredits', credits); + } else { updateSubscription.set('AllowedCredits', credits); updateSubscription.set('PlanCredits', credits); } } } else { if (credits > 0) { - updateSubscription.set('AllowedCredits', credits); - updateSubscription.set('PlanCredits', credits); + if (isTeamPlan) { + const newCredits = newAddons * credits; + updateSubscription.set('AllowedCredits', newCredits); + updateSubscription.set('PlanCredits', credits); + } else { + updateSubscription.set('AllowedCredits', credits); + updateSubscription.set('PlanCredits', credits); + } } } - await updateSubscription.save(null, { useMasterKey: true }); return { status: 'update subscription!' }; } else { @@ -111,12 +164,18 @@ export default async function saveSubscription(request) { }); createSubscription.set('Next_billing_date', new Date(Next_billing_date)); createSubscription.set('PlanCode', planCode); - if (existAddon > 0) { - createSubscription.set('AllowedUsers', parseInt(existAddon)); + if (newAddons > 0) { + createSubscription.set('AllowedUsers', parseInt(newAddons)); } if (credits > 0) { - createSubscription.set('AllowedCredits', credits); - createSubscription.set('PlanCredits', credits); + if (isTeamPlan) { + const totalCredits = parseInt(newAddons) * credits; + createSubscription.set('AllowedCredits', totalCredits); + createSubscription.set('PlanCredits', credits); + } else { + createSubscription.set('AllowedCredits', credits); + createSubscription.set('PlanCredits', credits); + } } await createSubscription.save(null, { useMasterKey: true }); return { status: 'create subscription!' }; From 3b79da527d328984893c5d7a0b5ad0e8e752318c Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Thu, 5 Sep 2024 18:32:42 +0530 Subject: [PATCH 5/7] fix: display incorrect count of document on dashboard --- apps/OpenSign/src/json/dashboardJson.js | 2 +- apps/OpenSignServer/cloud/parsefunction/reportsJson.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/OpenSign/src/json/dashboardJson.js b/apps/OpenSign/src/json/dashboardJson.js index dd1245954..591602b1a 100644 --- a/apps/OpenSign/src/json/dashboardJson.js +++ b/apps/OpenSign/src/json/dashboardJson.js @@ -36,7 +36,7 @@ const dashboardJson = [ queryType: "", class: "contracts_Document", query: - 'where={"Type":{"#*ne":"Folder"},"Signers":{"#*exists":true,"#*ne":[]},"Placeholders":{"#*ne":null},"IsCompleted":{"#*ne":true},"IsDeclined":{"#*ne":true},"IsArchive":{"#*ne":true},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"#UserId.objectId#"},"ExpiryDate":{"#*gt":{"__type":"#Date#","iso":"#today#"}}}&count=1', + 'where={"Type":{"#*ne":"Folder"},"Signers":{"#*exists":true,"#*ne":[]},"Placeholders":{"#*ne":null},"SignedUrl":{"#*ne":null},"IsCompleted":{"#*ne":true},"IsDeclined":{"#*ne":true},"IsArchive":{"#*ne":true},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"#UserId.objectId#"},"ExpiryDate":{"#*gt":{"__type":"#Date#","iso":"#today#"}}}&count=1', key: "count", Redirect_type: "Report", Redirect_id: "1MwEuxLEkF", diff --git a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js index a3613094e..49f5b42e4 100644 --- a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js +++ b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js @@ -243,6 +243,7 @@ export default function reportJson(id, userId) { reportName: 'Recent signature requests', params: { Type: { $ne: 'Folder' }, + SignedUrl: { $ne: null }, IsCompleted: { $ne: true }, IsDeclined: { $ne: true }, IsArchive: { $ne: true }, From af2666c83d62750ec973bbf6a9d7a7468629c0f9 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Thu, 5 Sep 2024 18:36:30 +0530 Subject: [PATCH 6/7] feat: show email used count --- apps/OpenSign/src/components/Header.js | 16 +++++++++++++++- apps/OpenSign/src/redux/reducers/index.js | 12 ------------ apps/OpenSignServer/Utils.js | 8 ++++---- .../cloud/parsefunction/sendMailv3.js | 4 ++-- 4 files changed, 21 insertions(+), 19 deletions(-) delete mode 100644 apps/OpenSign/src/redux/reducers/index.js diff --git a/apps/OpenSign/src/components/Header.js b/apps/OpenSign/src/components/Header.js index 9a03aeddc..9f3c9bb27 100644 --- a/apps/OpenSign/src/components/Header.js +++ b/apps/OpenSign/src/components/Header.js @@ -18,7 +18,7 @@ const Header = ({ showSidebar }) => { const { t, i18n } = useTranslation(); const navigate = useNavigate(); const { width } = useWindowSize(); - let username = localStorage.getItem("username"); + const username = localStorage.getItem("username") || ""; const image = localStorage.getItem("profileImg") || dp; const [isOpen, setIsOpen] = useState(false); const [isSubscribe, setIsSubscribe] = useState(true); @@ -26,6 +26,7 @@ const Header = ({ showSidebar }) => { const [applogo, setAppLogo] = useState( localStorage.getItem("appLogo") || " " ); + const [emailUsed, setEmailUsed] = useState(0); const toggleDropdown = () => { setIsOpen(!isOpen); @@ -47,6 +48,11 @@ const Header = ({ showSidebar }) => { } setIsTeam(subscribe); setIsSubscribe(subscribe.isValid); + const extUser = + localStorage.getItem("Extand_Class") && + JSON.parse(localStorage.getItem("Extand_Class"))?.[0]; + const MonthlyFreeEmails = extUser?.MonthlyFreeEmails || 0; + setEmailUsed(MonthlyFreeEmails); } } @@ -195,6 +201,14 @@ const Header = ({ showSidebar }) => { tabIndex={0} className="mt-3 z-[1] p-2 shadow op-menu op-menu-sm op-dropdown-content text-base-content bg-base-100 rounded-box w-52" > + {isEnableSubscription && isTeam?.plan === "freeplan" && ( +
  • + + Email used:{" "} + {emailUsed}/20 + +
  • + )}
  • openInNewTab("https://docs.opensignlabs.com")}> {t("docs")} diff --git a/apps/OpenSign/src/redux/reducers/index.js b/apps/OpenSign/src/redux/reducers/index.js deleted file mode 100644 index 277fce1af..000000000 --- a/apps/OpenSign/src/redux/reducers/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import { combineReducers } from "redux"; -import infoReducer from "./infoReducer"; -import ShowTenant from "./ShowTenant"; -import TourStepsReducer from "./TourStepsReducer"; -import showHeader from "./showHeader"; - -export default combineReducers({ - appInfo: infoReducer, - TourSteps: TourStepsReducer, - ShowTenant, - showHeader -}); diff --git a/apps/OpenSignServer/Utils.js b/apps/OpenSignServer/Utils.js index 2ff086bdd..5d38b996a 100644 --- a/apps/OpenSignServer/Utils.js +++ b/apps/OpenSignServer/Utils.js @@ -103,15 +103,15 @@ export const updateMailCount = async (extUserId, plan, monthchange) => { if (plan === 'freeplan') { if (monthchange) { contractUser.set('LastEmailCountReset', new Date()); - contractUser.set('MontlyfreeEmails', 1); + contractUser.set('MonthlyFreeEmails', 1); } else { - if (contractUser?.get('MontlyfreeEmails')) { - contractUser.increment('MontlyfreeEmails', 1); + if (contractUser?.get('MonthlyFreeEmails')) { + contractUser.increment('MonthlyFreeEmails', 1); if (contractUser?.get('LastEmailCountReset')) { contractUser.set('LastEmailCountReset', new Date()); } } else { - contractUser.set('MontlyfreeEmails', 1); + contractUser.set('MonthlyFreeEmails', 1); contractUser.set('LastEmailCountReset', new Date()); } } diff --git a/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js b/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js index 4cef012d6..b0c68b402 100644 --- a/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js +++ b/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js @@ -216,7 +216,7 @@ async function sendmailv3(req) { } } else { if (Plan && Plan === 'freeplan') { - let MontlyfreeEmails = _extRes?.MontlyfreeEmails || 0; + let MonthlyFreeEmails = _extRes?.MonthlyFreeEmails || 0; if (_extRes?.LastEmailCountReset?.iso) { const lastDate = new Date(_extRes?.LastEmailCountReset?.iso); const newDate = new Date(); @@ -225,7 +225,7 @@ async function sendmailv3(req) { const nonCustomMail = await sendMailProvider(req, Plan, true); return nonCustomMail; } else { - if (MontlyfreeEmails >= 20) { + if (MonthlyFreeEmails >= 20) { return { status: 'quota-reached' }; } else { const nonCustomMail = await sendMailProvider(req, Plan); From 181d6bf1e4d31994a3d28bbf7bd508365fccf0a9 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Thu, 5 Sep 2024 19:19:15 +0530 Subject: [PATCH 7/7] fix: email count not update until re-login --- apps/OpenSign/src/components/Header.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/OpenSign/src/components/Header.js b/apps/OpenSign/src/components/Header.js index 9f3c9bb27..22340a834 100644 --- a/apps/OpenSign/src/components/Header.js +++ b/apps/OpenSign/src/components/Header.js @@ -48,11 +48,13 @@ const Header = ({ showSidebar }) => { } setIsTeam(subscribe); setIsSubscribe(subscribe.isValid); - const extUser = - localStorage.getItem("Extand_Class") && - JSON.parse(localStorage.getItem("Extand_Class"))?.[0]; - const MonthlyFreeEmails = extUser?.MonthlyFreeEmails || 0; - setEmailUsed(MonthlyFreeEmails); + try { + const extUser = await Parse.Cloud.run("getUserDetails"); + const MonthlyFreeEmails = extUser?.get("MonthlyFreeEmails") || 0; + setEmailUsed(MonthlyFreeEmails); + } catch (err) { + console.log("err in while fetching monthlyfreeEmails", err); + } } }