refactor: add help test, remove uncessary code

This commit is contained in:
prafull-opensignlabs
2024-09-01 17:51:56 +05:30
parent 54a7628f75
commit 87cec67e60
26 changed files with 42651 additions and 2076 deletions
@@ -1,4 +1,6 @@
{
"headernews": "New feature: Public profiles are now live! Easily create and share public templates",
"headernewsbtn": "Setup Now",
"create-account": "Create Account",
"login": "Login",
"language": "Language",
@@ -38,7 +40,7 @@
"upgrade-now": "Upgrade now",
"upgrade-to": "Upgrade to",
"plan": "Plan",
"subscribe-card-plan": "Sign 100 docs using API. Only $0.15/doc after that.",
"subscribe-card-plan": "Unlock premium features starting at just {{premiumPrice}}/month. Enjoy enhanced performance and only {{addonPrice}} per additional credit after your included premium credits.",
"user-name-limit-char": "To have a username less than 8 character please subscribe",
"tour-content": "Don't show this again",
"pro": "PRO",
@@ -607,19 +609,17 @@
"user-name-exist": "user name already exist",
"format": "format",
"select-date-format": "Select a date format",
"buyapiaddon":"Buy APIs Credits",
"quantityofapis" :"Quantity of APIs",
"additionalapis":"Please purchase add-on APIs",
"remainingapis": "Remaining APIs Credits:",
"additional-quicksend": "Please purchase add-on quick send",
"quantityofquicksend": "Quantity of Quick send",
"quantityofcredits": "Quantity of premium credits",
"remainingcredits": "Premium credits available:",
"remainingcreditshelp":"Use premium credits for API document signing, bulk sending, or embedding OpenSign integration on your website. You have {{allowedcredits}} included credits and {{addoncredits}} additional purchased credits remaining.",
"additional-credits": "Please purchase premium credits",
"quotaerrquicksend": "Quota Reached, You don't have enough credits.",
"buycredits": "Buy credits",
"buycredits": "Buy Premium Credits",
"rotate-right":"Rotate right",
"rotate-left":"Rotate left",
"rotate-alert-mssg":"All widgets on this page will be lost. Are you sure you want to proceed?",
"templateid":"Template-Id",
"bulksendsubcriptionalert":"Please upgrade to Professional or Team plan to use quicksend.",
"bulksendsubcriptionalert":"Please upgrade to Professional or Team plan to use bulk send.",
"generate-test-token":"Generate Test Token",
"regenerate-test-token":"Regenerate Test Token",
"help-test-token":"This token can be used to test the APIs at the https://sandbox.opensignlabs.com/api/v1 endpoint, allowing you to conduct unlimited document signatures. Please note that the sandbox API will sign your documents with self-signed certificates, which may not be recognized as valid by Adobe. Once youve completed your testing, you can upgrade to one of our paid plans to generate a production token.",
@@ -1,5 +1,7 @@
{
"headernews": "Nouvelle fonctionnalité : les profils publics sont désormais en ligne ! Créez et partagez facilement des modèles publics",
"headernewsbtn": "Configurer maintenant",
"create-account": "Créer un compte",
"login": "Se Connecter",
"language": "Langue",
@@ -40,7 +42,7 @@
"upgrade-to": "Mettre à niveau vers",
"pro": "PRO",
"plan": "Offre",
"subscribe-card-plan": "Signez 100 documents à l'aide de l'API. Seulement 0,15 $/doc par la suite.",
"subscribe-card-plan": "Débloquez des fonctionnalités premium à partir de seulement {{premiumPrice}}/mois. Bénéficiez de performances améliorées et de seulement {{addonPrice}} par crédit supplémentaire après vos crédits premium inclus.",
"user-name-limit-char": "Pour avoir un nom d'utilisateur de moins de 8 caractères s'il vous plaît s'abonner",
"tour-content": "Ne plus afficher",
"team": "Équipe",
@@ -607,14 +609,13 @@
"Add-seats": "Ajouter des sièges",
"format": "format",
"select-date-format": "Sélectionnez un format de date",
"buyapiaddon":"Acheter des API Crédits",
"quantityofapis":"Quantité d'API",
"additionalapis":"Veuillez acheter des API complémentaires",
"remainingapis":"API restantes Crédits:",
"additional-quicksend":"Veuillez acheter le module complémentaire quick send",
"quantityofcredits":"Quantité de crédits de prime",
"remainingcredits":"Crédits premium disponibles :",
"additional-credits":"Veuillez acheter des crédits premium",
"remainingcreditshelp":"Utilisez des crédits premium pour la signature de documents API, l'envoi groupé ou l'intégration d'OpenSign sur votre site Web. Il vous reste {{allowedcredits}} crédits inclus et {{addoncredits}} crédits achetés supplémentaires.",
"quantityofquicksend": "Quantité de Quick send",
"quotaerrquicksend": "Quota atteint, vous n'avez pas assez de crédits.",
"buycredits": "Acheter des crédits",
"buycredits": "Acheter des crédits premium",
"rotate-right" :"Faire pivoter à droite",
"rotate-left" :"Faire pivoter à gauche",
"rotate-alert-mssg" :"Tous les widgets de cette page seront perdus. Êtes-vous sûr de vouloir continuer ?",
@@ -624,5 +625,4 @@
"regenerate-test-token":"Régénérer le jeton de test",
"help-test-token":"Ce jeton peut être utilisé pour tester les API au niveau du point de terminaison https://sandbox.opensignlabs.com/api/v1, vous permettant ainsi d'effectuer un nombre illimité de signatures de documents. Veuillez noter que l'API sandbox signera vos documents avec des certificats auto-signés, qui peuvent ne pas être reconnus comme valides par Adobe. Une fois vos tests terminés, vous pouvez passer à lun de nos forfaits payants pour générer un jeton de production.",
"help-api-token":"Ce jeton peut être utilisé pour accéder aux API de production au point de terminaison {{origin}}/api/v1. Il ne peut être généré que sur l'un de nos forfaits payants."
}
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -378,7 +378,7 @@ const BulkSendUi = (props) => {
</p>
<button
onClick={() => setIsBulkAvailable(false)}
className=" op-btn op-btn-primary w-28"
className=" op-btn op-btn-primary w-[200px]"
>
{t("buycredits")}
</button>
@@ -419,14 +419,14 @@ const BulkSendUi = (props) => {
) : (
<form onSubmit={handleAddOnQuickSubmit} className="p-3">
<p className="flex justify-center text-center mx-2 mb-3 text-base op-text-accent font-medium">
{t("additional-quicksend")}
{t("additional-credits")}
</p>
<div className="mb-3 flex justify-between">
<label
htmlFor="quantity"
className="block text-xs text-gray-700 font-semibold"
>
{t("quantityofquicksend")}
{t("quantityofcredits")}
<span className="text-[red] text-[13px]">*</span>
</label>
<select
+4 -11
View File
@@ -11,7 +11,7 @@ import {
saveLanguageInLocal
} from "../constant/Utils";
import { isEnableSubscription, isStaging } from "../constant/const";
import { paidUrl, validplan } from "../json/plansArr";
import { validplan } from "../json/plansArr";
import { useTranslation } from "react-i18next";
const Header = ({ showSidebar }) => {
@@ -101,25 +101,18 @@ const Header = ({ showSidebar }) => {
}
};
const handleNavigation = () => {
const route = paidUrl(isTeam.plan);
if (route === "/subscription") {
navigate(route);
} else {
openInNewTab(route, "_self");
}
navigate("/subscription");
};
return (
<div>
{isEnableSubscription && (
<div className="shadow py-1 text-center bg-[#CAE4FA] text-[14px] p-1">
New Feature: Public Profiles are now live! Create and share public
templates with ease
{t("headernews")}
<span
className="cursor-pointer font-medium underline text-blue-800"
onClick={() => navigate("/profile")}
>
{" "}
Setup Now.
{" " + t("headernewsbtn") + "."}
</span>
</div>
)}
+3 -9
View File
@@ -11,10 +11,9 @@ import ModalUi from "../primitives/ModalUi";
import { useNavigate, useLocation, Outlet } from "react-router-dom";
import { isEnableSubscription } from "../constant/const";
import { useCookies } from "react-cookie";
import { fetchSubscription, openInNewTab } from "../constant/Utils";
import { fetchSubscription } from "../constant/Utils";
import Loader from "../primitives/Loader";
import { showHeader } from "../redux/reducers/showHeader";
import { paidUrl } from "../json/plansArr";
import { useTranslation } from "react-i18next";
const HomeLayout = () => {
@@ -96,13 +95,8 @@ const HomeLayout = () => {
domain: updateDomain
});
};
const handleNavigation = (plan) => {
const route = paidUrl(plan);
if (route === "/subscription") {
navigate(route);
} else {
openInNewTab(route, "_self");
}
const handleNavigation = () => {
navigate("/subscription");
};
async function checkIsSubscribed() {
if (isEnableSubscription) {
+32 -18
View File
@@ -31,6 +31,7 @@ function GenerateToken() {
priceperapi: 0.15,
allowedcredits: 0,
addoncredits: 0,
totalcredits: 0,
price: (75.0).toFixed(2)
});
const [isFormLoader, setIsFormLoader] = useState(false);
@@ -61,10 +62,14 @@ function GenerateToken() {
const res = await axios.post(url, {}, { headers: headers });
if (res) {
const resCredits = await Parse.Cloud.run("allowedcredits");
const allowedcredits = resCredits?.allowedcredits || 0;
const addoncredits = resCredits?.addoncredits || 0;
const totalcredits = allowedcredits + addoncredits;
setAmount((obj) => ({
...obj,
allowedcredits: resCredits.allowedcredits,
addoncredits: resCredits.addoncredits
allowedcredits: allowedcredits,
addoncredits: addoncredits,
totalcredits: totalcredits
}));
SetApiToken(res?.data?.result?.result);
}
@@ -162,7 +167,8 @@ function GenerateToken() {
quantity: 500,
priceperapi: 0.15,
price: (75.0).toFixed(2),
addoncredits: _resAddon.addon
totalcredits: obj?.totalcredits + _resAddon.addon,
addoncredits: obj?.addoncredits + _resAddon.addon
}));
}
}
@@ -229,7 +235,7 @@ function GenerateToken() {
/>
</h1>
<ul className="w-full flex flex-col p-2 text-sm">
<li className="flex flex-col md:flex-row justify-between items-center border-y-[1px] border-gray-300 break-all py-2">
<li className="flex flex-col md:flex-row justify-between items-center border-t-[1px] border-gray-300 break-all py-2">
<div className="w-full md:w-[70%] flex-col md:flex-row text-xs md:text-[15px] flex items-center gap-x-5">
<span className="ml-1">
<span className="font-medium">API Test Token : </span>
@@ -254,7 +260,7 @@ function GenerateToken() {
</div>
<button
onClick={handleGenerateTestToken}
className="op-btn op-btn-primary w-[180px] md:w-auto"
className="op-btn op-btn-primary w-[200px] md:w-auto"
>
{apitestToken
? t("regenerate-test-token")
@@ -295,18 +301,26 @@ function GenerateToken() {
</div>
<button
onClick={apiToken ? handleModal : handleSubmit}
className="op-btn op-btn-primary w-[180px] md:w-auto"
className="op-btn op-btn-primary w-[200px] md:w-auto"
>
{apiToken ? t("regenerate-token") : t("generate-token")}
</button>
</li>
<div className="text-xs md:text-[15px] my-4">
<span className="font-medium">{t("remainingapis")}</span>{" "}
{amount.allowedcredits}
</div>
<div className="text-xs md:text-[15px] my-4">
<span className="font-medium">Addon credits: </span>{" "}
{amount.addoncredits}
<div className="text-xs md:text-[15px] my-3 w-full md:w-[70%] flex-col md:flex-row flex items-center gap-x-5">
<span className="font-medium">
{t("remainingcredits")}{" "}
<span className="text-xs">
<Tooltip
message={t("remainingcreditshelp", {
allowedcredits: amount?.allowedcredits || 0,
addoncredits: amount?.addoncredits || 0
})}
/>
</span>
</span>
<span className="md:text-end py-2 md:py-0">
{amount.totalcredits}
</span>
</div>
<hr />
</ul>
@@ -318,16 +332,16 @@ function GenerateToken() {
"https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1"
)
}
className="op-btn op-btn-secondary mt-2 md:mb-3 px-8 w-[180px] md:w-auto"
className="op-btn op-btn-secondary mt-2 md:mb-3 px-8 w-[200px] md:w-auto"
>
{t("view-docs")}
</button>
<button
type="button"
onClick={() => handleBuyAPIsModal()}
className="op-btn op-btn-secondary mt-2 mb-3 px-8 w-[180px] md:w-auto"
className="op-btn op-btn-secondary mt-2 mb-3 px-8 w-[200px] md:w-auto"
>
{t("buyapiaddon")}
{t("buycredits")}
</button>
</div>
<ModalUi
@@ -359,7 +373,7 @@ function GenerateToken() {
{/* buy APIs */}
<ModalUi
isOpen={isModal.buyapis}
title={"Buy Addon APIs"}
title={"Buy Credits"}
handleClose={handleBuyAPIsModal}
>
{isFormLoader && (
@@ -373,7 +387,7 @@ function GenerateToken() {
htmlFor="quantity"
className="block text-xs text-gray-700 font-semibold"
>
{t("quantityofapis")}
{t("quantityofcredits")}
<span className="text-[red] text-[13px]"> *</span>
</label>
<select
+2 -9
View File
@@ -31,7 +31,6 @@ import {
handleDownloadPdf,
handleToPrint,
handleDownloadCertificate,
openInNewTab,
getDefaultSignature,
onClickZoomIn,
onClickZoomOut,
@@ -51,7 +50,6 @@ import { useSelector } from "react-redux";
import SignerListComponent from "../components/pdf/SignerListComponent";
import VerifyEmail from "../components/pdf/VerifyEmail";
import PdfZoom from "../components/pdf/PdfZoom";
import { paidUrl } from "../json/plansArr";
import { useTranslation } from "react-i18next";
function PdfRequestFiles(props) {
@@ -239,13 +237,8 @@ function PdfRequestFiles(props) {
await handleSendOTP(currentUser?.email);
};
const handleNavigation = (plan) => {
const route = paidUrl(plan);
if (route === "/subscription") {
window.location.href = route;
} else {
openInNewTab(route, "_self");
}
const handleNavigation = () => {
window.location.href = "/subscription";
};
async function checkIsSubscribed(extUserId, contactId) {
const isGuestSign = isGuestSignFlow || false;
+2 -9
View File
@@ -35,7 +35,6 @@ import {
fetchSubscription,
convertPdfArrayBuffer,
getContainerScale,
openInNewTab,
convertBase64ToFile,
onClickZoomIn,
onClickZoomOut,
@@ -60,7 +59,6 @@ import Loader from "../primitives/Loader";
import { useSelector } from "react-redux";
import PdfZoom from "../components/pdf/PdfZoom";
import LottieWithLoader from "../primitives/DotLottieReact";
import { paidUrl } from "../json/plansArr";
import { useTranslation } from "react-i18next";
import RotateAlert from "../components/RotateAlert";
@@ -235,13 +233,8 @@ function PlaceHolderSign() {
return () => clearTimeout(timer);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [divRef.current, isHeader]);
const handleNavigation = (plan) => {
const route = paidUrl(plan);
if (route === "/subscription") {
navigate(route);
} else {
openInNewTab(route, "_self");
}
const handleNavigation = () => {
navigate("/subscription");
};
async function checkIsSubscribed() {
const res = await fetchSubscription();
+3 -9
View File
@@ -3,12 +3,11 @@ import { useLocation, useNavigate } from "react-router-dom";
import Parse from "parse";
import { appInfo } from "../constant/appinfo";
import { isEnableSubscription } from "../constant/const";
import { fetchSubscription, openInNewTab } from "../constant/Utils";
import { fetchSubscription } from "../constant/Utils";
import { useDispatch } from "react-redux";
import { showTenant } from "../redux/reducers/ShowTenant";
import ModalUi from "../primitives/ModalUi";
import Loader from "../primitives/Loader";
import { paidUrl } from "../json/plansArr";
import { useTranslation } from "react-i18next";
const SSOVerify = () => {
@@ -51,13 +50,8 @@ const SSOVerify = () => {
console.log("err", err.message);
}
};
const handlePaidRoute = (plan) => {
const route = paidUrl(plan);
if (route === "/subscription") {
navigate(route);
} else {
openInNewTab(route, "_self");
}
const handlePaidRoute = () => {
navigate("/subscription");
};
const checkExtUser = async (ssosign) => {
const params = { email: ssosign?.email };
@@ -26,7 +26,6 @@ import {
radioButtonWidget,
fetchSubscription,
getContainerScale,
openInNewTab,
convertBase64ToFile,
rotatePdfPage,
onClickZoomOut,
@@ -47,7 +46,6 @@ import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption";
import Parse from "parse";
import { useSelector } from "react-redux";
import PdfZoom from "../components/pdf/PdfZoom";
import { paidUrl } from "../json/plansArr";
import { useTranslation } from "react-i18next";
import RotateAlert from "../components/RotateAlert";
const TemplatePlaceholder = () => {
@@ -196,13 +194,8 @@ const TemplatePlaceholder = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [divRef.current, isHeader]);
const handleNavigation = (plan) => {
const route = paidUrl(plan);
if (route === "/subscription") {
navigate(route);
} else {
openInNewTab(route, "_self");
}
const handleNavigation = () => {
navigate("/subscription");
};
async function checkIsSubscribed() {
const res = await fetchSubscription();
+2 -7
View File
@@ -17,7 +17,7 @@ import {
import Upgrade from "../primitives/Upgrade";
import ModalUi from "../primitives/ModalUi";
import Loader from "../primitives/Loader";
import { paidUrl, validplan } from "../json/plansArr";
import { validplan } from "../json/plansArr";
import { useTranslation } from "react-i18next";
import SelectLanguage from "../components/pdf/SelectLanguage";
import { RWebShare } from "react-web-share";
@@ -315,12 +315,7 @@ function UserProfile() {
setIsDisableDocId(extendUser?.[0]?.HeaderDocId);
};
const handlePaidRoute = () => {
const route = paidUrl(isPlan.plan);
if (route === "/subscription") {
navigate(route);
} else {
openInNewTab(route, "_self");
}
navigate("/subscription");
};
const copytoclipboard = () => {
+6 -13
View File
@@ -1,29 +1,22 @@
import React from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { paidUrl } from "../json/plansArr";
import { openInNewTab } from "../constant/Utils";
const SubscribeCard = ({ plan, price, plan_code }) => {
const SubscribeCard = ({ plan, price }) => {
const { t } = useTranslation();
const navigate = useNavigate();
const handlePaidRoute = () => {
const route = paidUrl(plan_code);
if (route === "/subscription") {
navigate(route);
} else {
openInNewTab(route, "_self");
}
navigate("/subscription");
};
const premiumPrice = price ? "$" + price : "$9.99";
const addonPrice = "$0.15";
return (
<div className="op-card op-bg-primary text-primary-content w-full shadow-lg">
<div className="op-card-body">
<h2 className="op-card-title">
{t("upgrade-to")} {plan ? plan : "PRO"} {t("plan")}
{t("upgrade-to")} {plan ? plan : "Paid"} {t("plan")}
</h2>
<p>
${price ? price : "29.99"}/month: {t("subscribe-card-plan")}
</p>
<p>{t("subscribe-card-plan", { premiumPrice, addonPrice })}</p>
<div className="op-card-actions justify-end">
<button
onClick={() => handlePaidRoute()}
@@ -38,7 +38,7 @@
"upgrade-now": "Upgrade now",
"upgrade-to": "Upgrade to",
"plan": "Plan",
"subscribe-card-plan": "Sign 100 docs using API. Only $0.15/doc after that.",
"subscribe-card-plan": "Unlock premium features starting at just {{premiumPrice}}/month. Enjoy enhanced performance and only {{addonPrice}} per additional credit after your included premium credits.",
"user-name-limit-char": "To have a username less than 8 character please subscribe",
"tour-content": "Don't show this again",
"pro": "PRO",
@@ -39,7 +39,7 @@
"upgrade-to": "Mettre à niveau vers",
"pro": "PRO",
"plan": "Offre",
"subscribe-card-plan": "Signez 100 documents à l'aide de l'API. Seulement 0,15 $/doc par la suite.",
"subscribe-card-plan": "Débloquez des fonctionnalités premium à partir de seulement {{premiumPrice}}/mois. Bénéficiez de performances améliorées et de seulement {{addonPrice}} par crédit supplémentaire après vos crédits premium inclus.",
"user-name-limit-char": "Pour avoir un nom d'utilisateur de moins de 8 caractères s'il vous plaît s'abonner",
"tour-content": "Ne plus afficher",
"team": "Équipe",
+11
View File
@@ -210,3 +210,14 @@ export const useLocal = process.env.USE_LOCAL ? process.env.USE_LOCAL.toLowerCas
export const smtpsecure = process.env.SMTP_PORT && process.env.SMTP_PORT !== '465' ? false : true;
export const smtpenable =
process.env.SMTP_ENABLE && process.env.SMTP_ENABLE.toLowerCase() === 'true' ? true : false;
export const planCredits = {
'pro-weekly': 100,
'pro-yearly': 240,
'professional-monthly': 100,
'professional-yearly': 240,
'team-weekly': 100,
'team-yearly': 500,
'teams-monthly': 100,
'teams-yearly': 500,
};
@@ -1,3 +1,5 @@
import { planCredits } from '../../Utils.js';
export default async function saveSubscription(request, response) {
const SubscriptionId = request.body?.data?.subscription?.subscription_id;
const body = request.body;
@@ -5,6 +7,7 @@ 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 credits = planCredits?.[planCode] || 0;
let existAddon = 0;
if (addons?.length > 0) {
let allowedUsersMonthly = 0;
@@ -52,6 +55,9 @@ export default async function saveSubscription(request, response) {
if (existAddon > 0) {
updateSubscription.set('AllowedUsers', parseInt(existAddon));
}
if (credits > 0) {
updateSubscription.set('AllowedCredits', credits);
}
await updateSubscription.save(null, { useMasterKey: true });
return response.status(200).json({ status: 'update subscription!' });
} else {
@@ -82,6 +88,9 @@ export default async function saveSubscription(request, response) {
if (existAddon > 0) {
createSubscription.set('AllowedUsers', parseInt(existAddon));
}
if (credits > 0) {
createSubscription.set('AllowedCredits', credits);
}
await createSubscription.save(null, { useMasterKey: true });
return response.status(200).json({ status: 'create subscription!' });
}
-9
View File
@@ -6,7 +6,6 @@ import usersignup from './parsefunction/usersignup.js';
import FacebookSign from './parsefunction/FacebookSign.js';
import DocumentAftersave from './parsefunction/DocumentAftersave.js';
import ContactbookAftersave from './parsefunction/ContactBookAftersave.js';
// import ContractUsersAftersave from './parsefunction/ContractUsersAftersave.js';
import sendMailOTPv1 from './parsefunction/SendMailOTPv1.js';
import AuthLoginAsMail from './parsefunction/AuthLoginAsMail.js';
import getUserId from './parsefunction/getUserId.js';
@@ -62,10 +61,6 @@ import getOrgAdmins from './parsefunction/getOrgAdmins.js';
import getAllUserTeamByOrg from './parsefunction/getAllUserTeamByOrg.js';
import AllowedUsers from './parsefunction/AlllowedUsers.js';
import BuyAddonUsers from './parsefunction/BuyAddonUsers.js';
import AllowedApis from './parsefunction/AllowedApis.js';
import BuyApis from './parsefunction/BuyApis.js';
import AllowedQuicksend from './parsefunction/AllowedQuicksend.js';
import BuyQuickSend from './parsefunction/BuyQuicksend.js';
import ExtUserAftersave from './parsefunction/ExtUserAftersave.js';
import ExtUserAfterdelete from './parsefunction/ExtUserAfterdelete.js';
import AllowedCredits from './parsefunction/AllowedCredits.js';
@@ -145,9 +140,5 @@ Parse.Cloud.define('getorgadmins', getOrgAdmins);
Parse.Cloud.define('getalluserteambyorg', getAllUserTeamByOrg);
Parse.Cloud.define('allowedusers', AllowedUsers);
Parse.Cloud.define('buyaddonusers', BuyAddonUsers);
Parse.Cloud.define('allowedapis', AllowedApis);
Parse.Cloud.define('allowedquicksend', AllowedQuicksend);
Parse.Cloud.define('buyapis', BuyApis);
Parse.Cloud.define('buyquicksend', BuyQuickSend);
Parse.Cloud.define('allowedcredits', AllowedCredits);
Parse.Cloud.define('buycredits', BuyCredits);
@@ -189,34 +189,3 @@ export default async function AddAdmin(request) {
console.log('Err ', err);
}
}
// async function saveSubscription(extUserId, UserId, tenantId, subscription) {
// const SubscriptionId = subscription?.data?.subscription?.subscription_id || '';
// const Next_billing_date = subscription?.data?.subscription?.next_billing_at || '';
// const planCode = subscription?.data?.subscription?.plan?.plan_code || '';
// try {
// const createSubscription = new Parse.Object('contracts_Subscriptions');
// createSubscription.set('SubscriptionId', SubscriptionId);
// createSubscription.set('SubscriptionDetails', subscription);
// createSubscription.set('ExtUserPtr', {
// __type: 'Pointer',
// className: 'contracts_Users',
// objectId: extUserId,
// });
// createSubscription.set('CreatedBy', {
// __type: 'Pointer',
// className: '_User',
// objectId: UserId,
// });
// createSubscription.set('TenantId', {
// __type: 'Pointer',
// className: 'partners_Tenant',
// objectId: tenantId,
// });
// createSubscription.set('Next_billing_date', new Date(Next_billing_date));
// createSubscription.set('PlanCode', planCode);
// await createSubscription.save(null, { useMasterKey: true });
// } catch (err) {
// console.log('err in save subscription pgsignup', err);
// }
// }
@@ -1,37 +0,0 @@
export default async function AllowedApis(request) {
if (!request?.user) {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
}
try {
const extUser = new Parse.Query('contracts_Users');
extUser.equalTo('UserId', {
__type: 'Pointer',
className: '_User',
objectId: request.user.id,
});
const resExtUser = await extUser.first({ useMasterKey: true });
if (resExtUser) {
const _resExtUser = JSON.parse(JSON.stringify(resExtUser));
const subscription = new Parse.Query('contracts_Subscriptions');
subscription.equalTo('TenantId', {
__type: 'Pointer',
className: 'partners_Tenant',
objectId: _resExtUser.TenantId.objectId,
});
subscription.include('ExtUserPtr');
const resSub = await subscription.first({ useMasterKey: true });
if (resSub) {
const _resSub = JSON.parse(JSON.stringify(resSub));
const allowedapis = _resSub?.AllowedApis || 0;
return allowedapis;
}
} else {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
}
} catch (err) {
console.log('err in allowedapis', err);
const code = err?.code || 400;
const msg = err?.message || 'Something went wrong.';
throw new Parse.Error(code, msg);
}
}
@@ -1,37 +0,0 @@
export default async function AllowedQuicksend(request) {
if (!request?.user) {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
}
try {
const extUser = new Parse.Query('contracts_Users');
extUser.equalTo('UserId', {
__type: 'Pointer',
className: '_User',
objectId: request.user.id,
});
const resExtUser = await extUser.first({ useMasterKey: true });
if (resExtUser) {
const _resExtUser = JSON.parse(JSON.stringify(resExtUser));
const subscription = new Parse.Query('contracts_Subscriptions');
subscription.equalTo('TenantId', {
__type: 'Pointer',
className: 'partners_Tenant',
objectId: _resExtUser.TenantId.objectId,
});
subscription.include('ExtUserPtr');
const resSub = await subscription.first({ useMasterKey: true });
if (resSub) {
const _resSub = JSON.parse(JSON.stringify(resSub));
const allowedquicksend = _resSub?.AllowedQuicksend || 0;
return allowedquicksend;
}
} else {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
}
} catch (err) {
console.log('err in allowedapis', err);
const code = err?.code || 400;
const msg = err?.message || 'Something went wrong.';
throw new Parse.Error(code, msg);
}
}
@@ -1,91 +0,0 @@
import axios from 'axios';
export default async function BuyApis(request) {
const apis = request.params.apis;
if (!request?.user) {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
}
if (apis) {
try {
const extUser = new Parse.Query('contracts_Users');
extUser.equalTo('UserId', {
__type: 'Pointer',
className: '_User',
objectId: request.user.id,
});
const resExtUser = await extUser.first({ useMasterKey: true });
if (resExtUser) {
const _resExtUser = JSON.parse(JSON.stringify(resExtUser));
const subscription = new Parse.Query('contracts_Subscriptions');
subscription.equalTo('TenantId', {
__type: 'Pointer',
className: 'partners_Tenant',
objectId: _resExtUser.TenantId.objectId,
});
subscription.include('ExtUserPtr');
const resSub = await subscription.first({ useMasterKey: true });
if (resSub) {
const _resSub = JSON.parse(JSON.stringify(resSub));
// Define the URL
const url = 'https://accounts.zoho.in/oauth/v2/token';
// Convert the data to x-www-form-urlencoded format
const formData = new URLSearchParams();
formData.append('refresh_token', process.env.ZOHO_REFRESH_TOKEN);
formData.append('client_id', process.env.ZOHO_CLIENT_ID);
formData.append('client_secret', process.env.ZOHO_CLIENT_SECRET);
formData.append('redirect_uri', process.env.ZOHO_REDIRECT_URI);
formData.append('grant_type', 'refresh_token');
const headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
// Make the POST request using Axios
const res = await axios.post(url, formData, { headers });
if (res.data.access_token) {
const subscriptionId = _resSub.SubscriptionId;
const plan_code = _resSub?.SubscriptionDetails?.data?.subscription?.plan?.plan_code;
const quantity = parseInt(apis);
const addoncode = 'api-signatures';
const data = JSON.stringify({
plan: { plan_code: plan_code },
addons: [
{ addon_code: addoncode, addon_description: 'API Signatures', quantity: quantity },
],
});
const apiUrl = `https://www.zohoapis.in/billing/v1/subscriptions/${subscriptionId}/buyonetimeaddon`;
const resAPis = await axios.post(apiUrl, data, {
headers: {
Authorization: 'Zoho-oauthtoken ' + res.data.access_token,
'X-com-zoho-subscriptions-organizationid': process.env.ZOHO_BILLING_ORG_ID,
},
});
// console.log('resAPis ', resAPis.data);
if (resAPis.data) {
const existAllowedApis = _resSub?.AllowedApis ? _resSub.AllowedApis : 0;
const allowedapis = existAllowedApis + quantity;
const updateSub = new Parse.Object('contracts_Subscriptions');
updateSub.id = resSub.id;
updateSub.set('AllowedApis', allowedapis);
const resupdateSub = await updateSub.save(null, { useMasterKey: true });
// console.log('resupdateSub ', resupdateSub);
return { status: 'success', addon: allowedapis };
}
} else {
throw new Parse.Error('400', 'Invalid access token.');
}
}
} else {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
}
} catch (err) {
const code = err?.response?.data?.code || err?.response?.status || err?.code || 400;
const msg =
err?.response?.data?.error ||
err?.response?.data ||
err?.message ||
'Something went wrong.';
console.log('err in Buyaddonusers', code, msg);
throw new Parse.Error(code, msg);
}
} else {
throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Please provide parameters.');
}
}
@@ -1,89 +0,0 @@
import axios from 'axios';
export default async function BuyQuickSend(request) {
const apis = request.params.quicksend;
if (!request?.user) {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
}
if (apis) {
try {
const extUser = new Parse.Query('contracts_Users');
extUser.equalTo('UserId', {
__type: 'Pointer',
className: '_User',
objectId: request.user.id,
});
const resExtUser = await extUser.first({ useMasterKey: true });
if (resExtUser) {
const _resExtUser = JSON.parse(JSON.stringify(resExtUser));
const subscription = new Parse.Query('contracts_Subscriptions');
subscription.equalTo('TenantId', {
__type: 'Pointer',
className: 'partners_Tenant',
objectId: _resExtUser.TenantId.objectId,
});
subscription.include('ExtUserPtr');
const resSub = await subscription.first({ useMasterKey: true });
if (resSub) {
const _resSub = JSON.parse(JSON.stringify(resSub));
// Define the URL
const url = 'https://accounts.zoho.in/oauth/v2/token';
// Convert the data to x-www-form-urlencoded format
const formData = new URLSearchParams();
formData.append('refresh_token', process.env.ZOHO_REFRESH_TOKEN);
formData.append('client_id', process.env.ZOHO_CLIENT_ID);
formData.append('client_secret', process.env.ZOHO_CLIENT_SECRET);
formData.append('redirect_uri', process.env.ZOHO_REDIRECT_URI);
formData.append('grant_type', 'refresh_token');
const headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
// Make the POST request using Axios
const res = await axios.post(url, formData, { headers });
if (res.data.access_token) {
const subscriptionId = _resSub.SubscriptionId;
const plan_code = _resSub?.SubscriptionDetails?.data?.subscription?.plan?.plan_code;
const quantity = parseInt(apis);
const addoncode = 'bulk-signatures';
const data = JSON.stringify({
plan: { plan_code: plan_code },
addons: [
{ addon_code: addoncode, addon_description: 'Bulk Signatures', quantity: quantity },
],
});
const apiUrl = `https://www.zohoapis.in/billing/v1/subscriptions/${subscriptionId}/buyonetimeaddon`;
const resAPis = await axios.post(apiUrl, data, {
headers: {
Authorization: 'Zoho-oauthtoken ' + res.data.access_token,
'X-com-zoho-subscriptions-organizationid': process.env.ZOHO_BILLING_ORG_ID,
},
});
if (resAPis.data) {
const existQuickSend = _resSub?.AllowedQuicksend ? _resSub.AllowedQuicksend : 0;
const allowedQuicksend = existQuickSend + quantity;
const updateSub = new Parse.Object('contracts_Subscriptions');
updateSub.id = resSub.id;
updateSub.set('AllowedQuicksend', allowedQuicksend);
const resupdateSub = await updateSub.save(null, { useMasterKey: true });
return { status: 'success', addon: allowedQuicksend };
}
} else {
throw new Parse.Error('400', 'Invalid access token.');
}
}
} else {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
}
} catch (err) {
const code = err?.response?.data?.code || err?.response?.status || err?.code || 400;
const msg =
err?.response?.data?.error ||
err?.response?.data ||
err?.message ||
'Something went wrong.';
console.log('err in buyaddon', code, msg);
throw new Parse.Error(code, msg);
}
} else {
throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Please provide parameters.');
}
}
@@ -21,6 +21,7 @@ export default async function SubscribeFree(request) {
const updateSubscription = new Parse.Object('contracts_Subscriptions');
updateSubscription.id = subcripitions.id;
updateSubscription.set('PlanCode', 'freeplan');
updateSubscription.set('AllowedCredits', 0);
await updateSubscription.save(null, { useMasterKey: true });
return { status: 'success', result: 'subscribed!' };
} catch (err) {
@@ -34,6 +35,7 @@ export default async function SubscribeFree(request) {
const updateSubscription = new Parse.Object('contracts_Subscriptions');
updateSubscription.id = subcripitions.id;
updateSubscription.set('PlanCode', 'freeplan');
updateSubscription.set('AllowedCredits', 0);
await updateSubscription.save(null, { useMasterKey: true });
return { status: 'success', result: 'subscribed!' };
} catch (err) {
@@ -61,6 +63,7 @@ export default async function SubscribeFree(request) {
objectId: extUser.get('TenantId').id,
});
}
createSubscription.set('AllowedCredits', 0);
await createSubscription.save(null, { useMasterKey: true });
return { status: 'success', result: 'subscribed!' };
} catch (err) {
@@ -1,5 +1,5 @@
import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
import { cloudServerUrl, planCredits } from '../../Utils.js';
export default async function saveSubscription(request) {
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID;
@@ -8,6 +8,7 @@ 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 credits = planCredits?.[planCode] || 0;
let existAddon = 0;
try {
const userRes = await axios.get(serverUrl + '/users/me', {
@@ -69,6 +70,9 @@ export default async function saveSubscription(request) {
if (existAddon > 0) {
updateSubscription.set('AllowedUsers', parseInt(existAddon));
}
if (credits > 0) {
updateSubscription.set('AllowedCredits', credits);
}
await updateSubscription.save(null, { useMasterKey: true });
return { status: 'update subscription!' };
} else {
@@ -95,6 +99,9 @@ export default async function saveSubscription(request) {
if (existAddon > 0) {
createSubscription.set('AllowedUsers', parseInt(existAddon));
}
if (credits > 0) {
createSubscription.set('AllowedCredits', credits);
}
await createSubscription.save(null, { useMasterKey: true });
return { status: 'create subscription!' };
}
@@ -1,5 +1,5 @@
import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
import { cloudServerUrl, planCredits } from '../../Utils.js';
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const APPID = process.env.APP_ID;
const masterKEY = process.env.MASTER_KEY;
@@ -135,6 +135,8 @@ async function saveSubscription(extUserId, UserId, tenantId, subscription) {
const SubscriptionId = subscription?.data?.subscription?.subscription_id || '';
const Next_billing_date = subscription?.data?.subscription?.next_billing_at || '';
const planCode = subscription?.data?.subscription?.plan?.plan_code || '';
const credits = planCredits?.[planCode] || 0;
try {
const createSubscription = new Parse.Object('contracts_Subscriptions');
createSubscription.set('SubscriptionId', SubscriptionId);
@@ -156,6 +158,9 @@ async function saveSubscription(extUserId, UserId, tenantId, subscription) {
});
createSubscription.set('Next_billing_date', new Date(Next_billing_date));
createSubscription.set('PlanCode', planCode);
if (credits > 0) {
createSubscription.set('AllowedCredits', credits);
}
await createSubscription.save(null, { useMasterKey: true });
} catch (err) {
console.log('err in save subscription pgsignup', err);