|
|
|
@ -10,7 +10,7 @@ frappe.provide("jey_wizard");
|
|
|
|
// Bump this string in every commit that changes wizard code. Displayed in the badge so
|
|
|
|
// Bump this string in every commit that changes wizard code. Displayed in the badge so
|
|
|
|
// we can tell at a glance which version is actually running on a given machine. Kept in
|
|
|
|
// we can tell at a glance which version is actually running on a given machine. Kept in
|
|
|
|
// sync with __version__ in jey_wizard/__init__.py.
|
|
|
|
// sync with __version__ in jey_wizard/__init__.py.
|
|
|
|
const JEY_WIZARD_VERSION = "0.0.8";
|
|
|
|
const JEY_WIZARD_VERSION = "0.0.9";
|
|
|
|
|
|
|
|
|
|
|
|
// Wipe Frappe + ERPNext default slides so their `before_load`/`after_load` listeners
|
|
|
|
// Wipe Frappe + ERPNext default slides so their `before_load`/`after_load` listeners
|
|
|
|
// don't try to mutate a wizard that isn't slide-based anymore.
|
|
|
|
// don't try to mutate a wizard that isn't slide-based anymore.
|
|
|
|
@ -41,6 +41,8 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
const year = new Date().getFullYear();
|
|
|
|
const year = new Date().getFullYear();
|
|
|
|
this.data = {
|
|
|
|
this.data = {
|
|
|
|
language: "az",
|
|
|
|
language: "az",
|
|
|
|
|
|
|
|
asan_prefix: "",
|
|
|
|
|
|
|
|
asan_local_number: "",
|
|
|
|
asan_phone: "",
|
|
|
|
asan_phone: "",
|
|
|
|
asan_user_id: "",
|
|
|
|
asan_user_id: "",
|
|
|
|
asan_login_name: "",
|
|
|
|
asan_login_name: "",
|
|
|
|
@ -143,11 +145,23 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
|
|
|
|
|
|
|
|
render_asan($body) {
|
|
|
|
render_asan($body) {
|
|
|
|
if (this.asan_state === "input") {
|
|
|
|
if (this.asan_state === "input") {
|
|
|
|
|
|
|
|
// +994 is hardcoded (every Azerbaijani mobile uses it); the visible
|
|
|
|
|
|
|
|
// parts are the carrier prefix (dropdown) and the 7-digit local number.
|
|
|
|
|
|
|
|
const prefixOptions = ["50", "51", "10", "55", "60", "70", "77", "99"]
|
|
|
|
|
|
|
|
.map((p) => `<option value="${p}">0${p}</option>`)
|
|
|
|
|
|
|
|
.join("");
|
|
|
|
$body.html(`
|
|
|
|
$body.html(`
|
|
|
|
<h3 style="margin-bottom:16px">${__("Asan Imza authentication")}</h3>
|
|
|
|
<h3 style="margin-bottom:16px">${__("Asan Imza authentication")}</h3>
|
|
|
|
<div style="margin-bottom:12px">
|
|
|
|
<div style="margin-bottom:12px">
|
|
|
|
<label style="display:block;margin-bottom:4px">${__("Phone number")}</label>
|
|
|
|
<label style="display:block;margin-bottom:4px">${__("Phone number")}</label>
|
|
|
|
<input type="text" class="jey-asan-phone form-control" style="max-width:280px" placeholder="${__("e.g. 0501234567")}" />
|
|
|
|
<div style="display:flex;align-items:center;gap:6px;max-width:320px">
|
|
|
|
|
|
|
|
<span style="padding:6px 10px;background:#f0f0f0;border:1px solid #d1d1d1;border-radius:4px;color:#555">+994</span>
|
|
|
|
|
|
|
|
<select class="jey-asan-prefix form-control" style="width:80px">
|
|
|
|
|
|
|
|
<option value="">${__("Prefix")}</option>
|
|
|
|
|
|
|
|
${prefixOptions}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
<input type="text" inputmode="numeric" maxlength="7" class="jey-asan-phone form-control" style="flex:1" placeholder="${__("7 digits")}" />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div style="margin-bottom:12px">
|
|
|
|
<div style="margin-bottom:12px">
|
|
|
|
<label style="display:block;margin-bottom:4px">${__("User ID")}</label>
|
|
|
|
<label style="display:block;margin-bottom:4px">${__("User ID")}</label>
|
|
|
|
@ -155,8 +169,14 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<button class="btn btn-primary jey-asan-auth" style="margin-top:8px">${__("Send request to Asan Imza")}</button>
|
|
|
|
<button class="btn btn-primary jey-asan-auth" style="margin-top:8px">${__("Send request to Asan Imza")}</button>
|
|
|
|
`);
|
|
|
|
`);
|
|
|
|
$body.find(".jey-asan-phone").val(this.data.asan_phone);
|
|
|
|
$body.find(".jey-asan-prefix").val(this.data.asan_prefix || "");
|
|
|
|
|
|
|
|
$body.find(".jey-asan-phone").val(this.data.asan_local_number || "");
|
|
|
|
$body.find(".jey-asan-userid").val(this.data.asan_user_id);
|
|
|
|
$body.find(".jey-asan-userid").val(this.data.asan_user_id);
|
|
|
|
|
|
|
|
$body.find(".jey-asan-phone").on("input", (e) => {
|
|
|
|
|
|
|
|
// Strip anything that isn't a digit as the user types.
|
|
|
|
|
|
|
|
const cleaned = String($(e.currentTarget).val() || "").replace(/\D/g, "").slice(0, 7);
|
|
|
|
|
|
|
|
$(e.currentTarget).val(cleaned);
|
|
|
|
|
|
|
|
});
|
|
|
|
$body.find(".jey-asan-auth").on("click", () => this.start_asan_auth());
|
|
|
|
$body.find(".jey-asan-auth").on("click", () => this.start_asan_auth());
|
|
|
|
} else if (this.asan_state === "polling") {
|
|
|
|
} else if (this.asan_state === "polling") {
|
|
|
|
const code = this.asan_verification_code || "";
|
|
|
|
const code = this.asan_verification_code || "";
|
|
|
|
@ -206,7 +226,7 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
`);
|
|
|
|
`);
|
|
|
|
$body.find(".jey-cert-pick").on("click", (e) => {
|
|
|
|
$body.find(".jey-cert-pick").on("click", (e) => {
|
|
|
|
const idx = parseInt($(e.currentTarget).attr("data-idx"), 10);
|
|
|
|
const idx = parseInt($(e.currentTarget).attr("data-idx"), 10);
|
|
|
|
this.pick_certificate(idx);
|
|
|
|
this.confirm_and_pick_certificate(idx);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} else if (this.asan_state === "fetching") {
|
|
|
|
} else if (this.asan_state === "fetching") {
|
|
|
|
$body.html(`
|
|
|
|
$body.html(`
|
|
|
|
@ -251,7 +271,11 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
<div style="font-weight:600;margin-bottom:6px">${__("Cached datasets")}</div>
|
|
|
|
<div style="font-weight:600;margin-bottom:6px">${__("Cached datasets")}</div>
|
|
|
|
<ul style="line-height:1.6;margin:0;padding-left:20px">${rows}</ul>
|
|
|
|
<ul style="line-height:1.6;margin:0;padding-left:20px">${rows}</ul>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style="margin-top:16px;text-align:right">
|
|
|
|
|
|
|
|
<button class="btn btn-default btn-sm jey-change-company">${__("Wrong company? Change")}</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
`);
|
|
|
|
`);
|
|
|
|
|
|
|
|
$body.find(".jey-change-company").on("click", () => this.reset_company_selection());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -264,19 +288,17 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
<div style="margin-top:12px;padding:12px;background:#fff8e1;border-left:3px solid #e0a800;border-radius:4px">
|
|
|
|
<div style="margin-top:12px;padding:12px;background:#fff8e1;border-left:3px solid #e0a800;border-radius:4px">
|
|
|
|
<b>${__("Heads up:")}</b> ${__("You will receive a second confirmation request on your phone from ASAN Sign / MyGovID. This is separate from the one you just approved for the tax portal.")}
|
|
|
|
<b>${__("Heads up:")}</b> ${__("You will receive a second confirmation request on your phone from ASAN Sign / MyGovID. This is separate from the one you just approved for the tax portal.")}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<p style="color:#888;margin-top:12px">${__("This step is optional. Skip it if your company has no employees or is not registered with ƏMAS.")}</p>
|
|
|
|
<p style="color:#888;margin-top:12px">${__("This step is optional. Use Next to skip if your company has no employees or is not registered with ƏMAS.")}</p>
|
|
|
|
${alreadyLoaded
|
|
|
|
${alreadyLoaded
|
|
|
|
? `<div style="margin-top:12px;padding:10px;background:#e8f5e9;border-radius:4px">
|
|
|
|
? `<div style="margin-top:12px;padding:10px;background:#e8f5e9;border-radius:4px">
|
|
|
|
${__("Already selected:")} <b>${alreadyLoaded}</b> ${__("employee(s)")}.
|
|
|
|
${__("Already loaded:")} <b>${alreadyLoaded}</b> ${__("employee(s)")}.
|
|
|
|
</div>`
|
|
|
|
</div>`
|
|
|
|
: ""}
|
|
|
|
: ""}
|
|
|
|
<div style="margin-top:20px;display:flex;gap:12px">
|
|
|
|
<div style="margin-top:20px">
|
|
|
|
<button class="btn btn-primary jey-amas-load">${alreadyLoaded ? __("Change selection") : __("Load employees")}</button>
|
|
|
|
<button class="btn btn-primary jey-amas-load">${__("Load employees")}</button>
|
|
|
|
<button class="btn btn-default jey-amas-skip">${__("Skip")}</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
`);
|
|
|
|
`);
|
|
|
|
$body.find(".jey-amas-load").on("click", () => this.amas_start_auth());
|
|
|
|
$body.find(".jey-amas-load").on("click", () => this.amas_start_auth());
|
|
|
|
$body.find(".jey-amas-skip").on("click", () => this.amas_skip());
|
|
|
|
|
|
|
|
} else if (this.amas_state === "auth") {
|
|
|
|
} else if (this.amas_state === "auth") {
|
|
|
|
const code = this.amas_verification_code || "";
|
|
|
|
const code = this.amas_verification_code || "";
|
|
|
|
$body.html(`
|
|
|
|
$body.html(`
|
|
|
|
@ -355,14 +377,8 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
(${__("new")}: <b>${newCount < 0 ? n : newCount}</b>, ${__("already in system")}: <b>${existingCount}</b>)
|
|
|
|
(${__("new")}: <b>${newCount < 0 ? n : newCount}</b>, ${__("already in system")}: <b>${existingCount}</b>)
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<p style="color:#666">${__("All employees will be imported into ƏMAS Employees and the standard Employee doctype after the wizard finishes.")}</p>
|
|
|
|
<p style="color:#666">${__("All employees will be imported into ƏMAS Employees and the standard Employee doctype after the wizard finishes.")}</p>
|
|
|
|
<div style="margin-top:16px">
|
|
|
|
|
|
|
|
<button class="btn btn-default jey-amas-back-intro">${__("Reload from ƏMAS")}</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
`);
|
|
|
|
`);
|
|
|
|
$body.find(".jey-amas-back-intro").on("click", () => {
|
|
|
|
// No extra buttons here — Back/Next in nav cover everything.
|
|
|
|
this.amas_state = "intro";
|
|
|
|
|
|
|
|
this.show_current_step();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -437,9 +453,10 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
// surfaces a standard Next.
|
|
|
|
// surfaces a standard Next.
|
|
|
|
showStdNext = this.asan_state === "done";
|
|
|
|
showStdNext = this.asan_state === "done";
|
|
|
|
} else if (step === "employees") {
|
|
|
|
} else if (step === "employees") {
|
|
|
|
// On intro the user uses explicit Skip / Load buttons, not Next.
|
|
|
|
// Next is visible on intro (acts as "skip this step") and on done
|
|
|
|
// Only the "done" sub-state surfaces a standard Next to move on.
|
|
|
|
// (move on with the loaded selection). During auth/loading/etc it
|
|
|
|
showStdNext = this.amas_state === "done";
|
|
|
|
// stays hidden so the flow can't be short-circuited mid-request.
|
|
|
|
|
|
|
|
showStdNext = this.amas_state === "intro" || this.amas_state === "done";
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
showStdNext = true;
|
|
|
|
showStdNext = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -488,6 +505,24 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
|
|
|
|
|
|
|
|
next() {
|
|
|
|
next() {
|
|
|
|
if (!this.capture_current()) return;
|
|
|
|
if (!this.capture_current()) return;
|
|
|
|
|
|
|
|
const step = this.steps[this.current_step];
|
|
|
|
|
|
|
|
// Skip-by-Next on employees/intro with no prior selection: clear any stale
|
|
|
|
|
|
|
|
// cache so materialize_after_setup doesn't re-import a previous run's data.
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
|
|
|
step === "employees" &&
|
|
|
|
|
|
|
|
this.amas_state === "intro" &&
|
|
|
|
|
|
|
|
(this.data.amas_selected_employees || []).length === 0
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
this.data.amas_skipped = true;
|
|
|
|
|
|
|
|
frappe.call({
|
|
|
|
|
|
|
|
method: "jey_wizard.amas.clear_amas_cache",
|
|
|
|
|
|
|
|
callback: () => {
|
|
|
|
|
|
|
|
this.current_step++;
|
|
|
|
|
|
|
|
this.show_current_step();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
this.current_step++;
|
|
|
|
this.current_step++;
|
|
|
|
this.show_current_step();
|
|
|
|
this.show_current_step();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -536,14 +571,26 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
// ---------- asan flow ----------
|
|
|
|
// ---------- asan flow ----------
|
|
|
|
|
|
|
|
|
|
|
|
start_asan_auth() {
|
|
|
|
start_asan_auth() {
|
|
|
|
const phone = (this.$wrap.find(".jey-asan-phone").val() || "").trim();
|
|
|
|
const prefix = (this.$wrap.find(".jey-asan-prefix").val() || "").trim();
|
|
|
|
|
|
|
|
const local = (this.$wrap.find(".jey-asan-phone").val() || "").replace(/\D/g, "");
|
|
|
|
const userId = (this.$wrap.find(".jey-asan-userid").val() || "").trim();
|
|
|
|
const userId = (this.$wrap.find(".jey-asan-userid").val() || "").trim();
|
|
|
|
if (!phone || !userId) {
|
|
|
|
if (!prefix) {
|
|
|
|
this.$wrap.find(".jey-status").text(__("Phone and User ID are required"));
|
|
|
|
this.$wrap.find(".jey-status").text(__("Select a phone prefix"));
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.data.asan_phone = phone;
|
|
|
|
if (local.length !== 7) {
|
|
|
|
|
|
|
|
this.$wrap.find(".jey-status").text(__("Phone number must be 7 digits"));
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!userId) {
|
|
|
|
|
|
|
|
this.$wrap.find(".jey-status").text(__("User ID is required"));
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.data.asan_prefix = prefix;
|
|
|
|
|
|
|
|
this.data.asan_local_number = local;
|
|
|
|
|
|
|
|
this.data.asan_phone = `+994${prefix}${local}`;
|
|
|
|
this.data.asan_user_id = userId;
|
|
|
|
this.data.asan_user_id = userId;
|
|
|
|
|
|
|
|
const phone = this.data.asan_phone;
|
|
|
|
this.$wrap.find(".jey-status").empty();
|
|
|
|
this.$wrap.find(".jey-status").empty();
|
|
|
|
|
|
|
|
|
|
|
|
frappe.call({
|
|
|
|
frappe.call({
|
|
|
|
@ -656,6 +703,21 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
confirm_and_pick_certificate(idx) {
|
|
|
|
|
|
|
|
const cert = this.asan_certificates[idx];
|
|
|
|
|
|
|
|
if (!cert) return;
|
|
|
|
|
|
|
|
const legal = cert.legalInfo || {};
|
|
|
|
|
|
|
|
const certName = `${legal.name || ""} (${legal.voen || legal.tin || ""})`;
|
|
|
|
|
|
|
|
// Cert selection triggers a cascade (select_taxpayer → fetch_etaxes_data) that
|
|
|
|
|
|
|
|
// writes a lot of cached data. Picking the wrong cert is reversible but costs
|
|
|
|
|
|
|
|
// another phone tap, so confirm explicitly first.
|
|
|
|
|
|
|
|
frappe.confirm(
|
|
|
|
|
|
|
|
__("You selected {0}. Is this the right company? Switching later will require clearing loaded data and re-authenticating.", [frappe.utils.escape_html(certName)]),
|
|
|
|
|
|
|
|
() => this.pick_certificate(idx),
|
|
|
|
|
|
|
|
() => {}
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pick_certificate(idx) {
|
|
|
|
pick_certificate(idx) {
|
|
|
|
const cert = this.asan_certificates[idx];
|
|
|
|
const cert = this.asan_certificates[idx];
|
|
|
|
if (!cert) return;
|
|
|
|
if (!cert) return;
|
|
|
|
@ -714,6 +776,44 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reset_company_selection() {
|
|
|
|
|
|
|
|
// Reached from asan/done when the user realizes they picked the wrong cert.
|
|
|
|
|
|
|
|
// Warn explicitly — we wipe both the e-taxes cache and the AMAS selection,
|
|
|
|
|
|
|
|
// and clear the certificate/main_token on Asan Login. Cert list stays in
|
|
|
|
|
|
|
|
// this.asan_certificates so the user can pick again without re-polling.
|
|
|
|
|
|
|
|
frappe.confirm(
|
|
|
|
|
|
|
|
__("This will delete all loaded tax portal data and any ƏMAS employee selection. You will need to pick a certificate again. Continue?"),
|
|
|
|
|
|
|
|
() => {
|
|
|
|
|
|
|
|
frappe.call({
|
|
|
|
|
|
|
|
method: "jey_wizard.api.reset_company_selection",
|
|
|
|
|
|
|
|
args: { asan_login_name: this.data.asan_login_name },
|
|
|
|
|
|
|
|
freeze: true,
|
|
|
|
|
|
|
|
freeze_message: __("Clearing..."),
|
|
|
|
|
|
|
|
callback: (r) => {
|
|
|
|
|
|
|
|
const m = r.message || {};
|
|
|
|
|
|
|
|
if (!m.ok) {
|
|
|
|
|
|
|
|
this.$wrap.find(".jey-status").text(__("Failed to clear data."));
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.data.company_name = "";
|
|
|
|
|
|
|
|
this.data.asan_voen = "";
|
|
|
|
|
|
|
|
this.data.amas_selected_employees = [];
|
|
|
|
|
|
|
|
this.data.amas_skipped = false;
|
|
|
|
|
|
|
|
this.data.amas_organization_name = "";
|
|
|
|
|
|
|
|
this.amas_employees = [];
|
|
|
|
|
|
|
|
this.amas_existing_map = {};
|
|
|
|
|
|
|
|
this.amas_state = "intro";
|
|
|
|
|
|
|
|
this.asan_fetch_summary = {};
|
|
|
|
|
|
|
|
this.asan_fetch_errors = {};
|
|
|
|
|
|
|
|
this.asan_state = "certs";
|
|
|
|
|
|
|
|
this.show_current_step();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
() => {}
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fetch_etaxes_data() {
|
|
|
|
fetch_etaxes_data() {
|
|
|
|
frappe.call({
|
|
|
|
frappe.call({
|
|
|
|
method: "jey_wizard.etaxes.fetch_all_etaxes",
|
|
|
|
method: "jey_wizard.etaxes.fetch_all_etaxes",
|
|
|
|
@ -735,20 +835,6 @@ frappe.setup.SetupWizard = class JeySetupWizard {
|
|
|
|
|
|
|
|
|
|
|
|
// ---------- AMAS flow ----------
|
|
|
|
// ---------- AMAS flow ----------
|
|
|
|
|
|
|
|
|
|
|
|
amas_skip() {
|
|
|
|
|
|
|
|
this.data.amas_skipped = true;
|
|
|
|
|
|
|
|
this.data.amas_selected_employees = [];
|
|
|
|
|
|
|
|
frappe.call({
|
|
|
|
|
|
|
|
method: "jey_wizard.amas.clear_amas_cache",
|
|
|
|
|
|
|
|
freeze: true,
|
|
|
|
|
|
|
|
freeze_message: __("Skipping..."),
|
|
|
|
|
|
|
|
callback: () => {
|
|
|
|
|
|
|
|
this.current_step++;
|
|
|
|
|
|
|
|
this.show_current_step();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
amas_start_auth() {
|
|
|
|
amas_start_auth() {
|
|
|
|
if (!this.data.asan_login_name) {
|
|
|
|
if (!this.data.asan_login_name) {
|
|
|
|
this.$wrap.find(".jey-status").text(__("Finish Asan Imza authentication first."));
|
|
|
|
this.$wrap.find(".jey-status").text(__("Finish Asan Imza authentication first."));
|
|
|
|
|