| 1 |
(function () { |
| 2 |
var config = window.syncBasalamBalanceSettlement; |
| 3 |
|
| 4 |
if (!config || typeof window.fetch !== "function") { |
| 5 |
return; |
| 6 |
} |
| 7 |
|
| 8 |
var overlay = document.getElementById("basalam-settlement-modal"); |
| 9 |
var amountInput = document.getElementById("basalam-settlement-amount"); |
| 10 |
var submitBtn = document.getElementById("basalam-settlement-submit"); |
| 11 |
var nextBtn = document.getElementById("basalam-settlement-next"); |
| 12 |
var cancelBtn = document.getElementById("basalam-settlement-cancel"); |
| 13 |
var closeBtn = document.getElementById("basalam-settlement-close"); |
| 14 |
var errorMessage = document.getElementById("basalam-settlement-error"); |
| 15 |
var methodInput = document.getElementById("basalam-settlement-method"); |
| 16 |
var investmentInput = document.getElementById("basalam-settlement-investment-option-id"); |
| 17 |
var bankAccountInput = document.getElementById("basalam-settlement-bank-account-id"); |
| 18 |
|
| 19 |
var step1 = document.getElementById("basalam-settlement-step-1"); |
| 20 |
var step2 = document.getElementById("basalam-settlement-step-2"); |
| 21 |
var backBtn = document.getElementById("basalam-settlement-back"); |
| 22 |
var submitBankBtn = document.getElementById("basalam-settlement-submit-bank"); |
| 23 |
var bankAccountsList = document.getElementById("basalam-bank-accounts-list"); |
| 24 |
var bankAccountsError = document.getElementById("basalam-bank-accounts-error"); |
| 25 |
|
| 26 |
var selectedBankAccountId = null; |
| 27 |
|
| 28 |
function formatWithCommas(value) { |
| 29 |
var num = value.replace(/\D/g, ""); |
| 30 |
return num.replace(/\B(?=(\d{3})+(?!\d))/g, ","); |
| 31 |
} |
| 32 |
|
| 33 |
function getRawNumber(value) { |
| 34 |
return parseInt(value.replace(/,/g, ""), 10) || 0; |
| 35 |
} |
| 36 |
|
| 37 |
function openModal(method) { |
| 38 |
methodInput.value = method; |
| 39 |
amountInput.value = ""; |
| 40 |
amountInput.classList.remove("basalam-plus-modal__input--error"); |
| 41 |
errorMessage.style.display = "none"; |
| 42 |
errorMessage.textContent = ""; |
| 43 |
selectedBankAccountId = null; |
| 44 |
|
| 45 |
var balanceError = document.getElementById("basalam-settlement-balance-error"); |
| 46 |
if (balanceError) { |
| 47 |
balanceError.style.display = "none"; |
| 48 |
} |
| 49 |
|
| 50 |
// Show step 1, hide step 2 |
| 51 |
step1.style.display = ""; |
| 52 |
step2.style.display = "none"; |
| 53 |
|
| 54 |
// For bank transfer (method=1): show "بعدی", hide "ثبت درخواست" |
| 55 |
// For wallet transfer (method=2): hide "بعدی", show "ثبت درخواست" |
| 56 |
var isBank = parseInt(method, 10) === 1; |
| 57 |
nextBtn.style.display = isBank ? "" : "none"; |
| 58 |
submitBtn.style.display = isBank ? "none" : ""; |
| 59 |
|
| 60 |
submitBtn.disabled = false; |
| 61 |
submitBtn.textContent = config.submitText; |
| 62 |
|
| 63 |
overlay.classList.add("is-open"); |
| 64 |
amountInput.focus(); |
| 65 |
} |
| 66 |
|
| 67 |
function closeModal() { |
| 68 |
overlay.classList.remove("is-open"); |
| 69 |
} |
| 70 |
|
| 71 |
function showError(msg) { |
| 72 |
errorMessage.textContent = msg; |
| 73 |
errorMessage.style.display = "block"; |
| 74 |
} |
| 75 |
|
| 76 |
function setLoading(loading) { |
| 77 |
submitBtn.disabled = loading; |
| 78 |
submitBtn.textContent = loading ? config.loadingText : config.submitText; |
| 79 |
} |
| 80 |
|
| 81 |
function setBankLoading(loading) { |
| 82 |
submitBankBtn.disabled = loading; |
| 83 |
submitBankBtn.textContent = loading ? config.loadingText : config.submitText; |
| 84 |
} |
| 85 |
|
| 86 |
function goToStep2() { |
| 87 |
step1.style.display = "none"; |
| 88 |
step2.style.display = ""; |
| 89 |
fetchBankAccounts(); |
| 90 |
} |
| 91 |
|
| 92 |
function goToStep1() { |
| 93 |
step2.style.display = "none"; |
| 94 |
step1.style.display = ""; |
| 95 |
} |
| 96 |
|
| 97 |
function fetchBankAccounts() { |
| 98 |
bankAccountsList.innerHTML = '<div class="basalam-bank-accounts-loading">در حال بارگذاری...</div>'; |
| 99 |
bankAccountsError.style.display = "none"; |
| 100 |
selectedBankAccountId = null; |
| 101 |
submitBankBtn.disabled = true; |
| 102 |
|
| 103 |
var body = new URLSearchParams(); |
| 104 |
body.set("action", config.bankAccountsAction); |
| 105 |
body.set("nonce", config.nonce); |
| 106 |
|
| 107 |
window |
| 108 |
.fetch(config.ajaxUrl, { |
| 109 |
method: "POST", |
| 110 |
credentials: "same-origin", |
| 111 |
headers: { |
| 112 |
Accept: "application/json", |
| 113 |
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", |
| 114 |
}, |
| 115 |
body: body.toString(), |
| 116 |
}) |
| 117 |
.then(function (response) { |
| 118 |
return response.json(); |
| 119 |
}) |
| 120 |
.then(function (payload) { |
| 121 |
if (!payload || !payload.success) { |
| 122 |
var msg = payload && payload.data && payload.data.message ? payload.data.message : config.bankAccountsError; |
| 123 |
throw new Error(msg); |
| 124 |
} |
| 125 |
|
| 126 |
var accounts = payload.data && payload.data.accounts ? payload.data.accounts : []; |
| 127 |
renderBankAccounts(accounts); |
| 128 |
}) |
| 129 |
.catch(function (error) { |
| 130 |
bankAccountsList.innerHTML = ""; |
| 131 |
bankAccountsError.textContent = error.message || config.bankAccountsError; |
| 132 |
bankAccountsError.style.display = "block"; |
| 133 |
}); |
| 134 |
} |
| 135 |
|
| 136 |
function renderBankAccounts(accounts) { |
| 137 |
if (!accounts || accounts.length === 0) { |
| 138 |
bankAccountsList.innerHTML = '<div class="basalam-bank-accounts-empty">حساب بانکی یافت نشد.</div>'; |
| 139 |
return; |
| 140 |
} |
| 141 |
|
| 142 |
var html = ""; |
| 143 |
for (var i = 0; i < accounts.length; i++) { |
| 144 |
var acc = accounts[i]; |
| 145 |
var id = acc.id || ""; |
| 146 |
var owner = acc.account_owner || "-"; |
| 147 |
var bankName = acc.bank_name || "-"; |
| 148 |
var sheba = acc.sheba_number || "-"; |
| 149 |
|
| 150 |
html += |
| 151 |
'<label class="basalam-bank-account-item" data-id="' + id + '">' + |
| 152 |
'<input type="radio" name="bank_account" value="' + id + '" class="basalam-bank-account-item__radio" />' + |
| 153 |
'<div class="basalam-bank-account-item__content">' + |
| 154 |
'<div class="basalam-bank-account-item__row">' + |
| 155 |
'<span class="basalam-bank-account-item__label">صاحب حساب:</span>' + |
| 156 |
'<span class="basalam-bank-account-item__value">' + owner + '</span>' + |
| 157 |
'</div>' + |
| 158 |
'<div class="basalam-bank-account-item__row">' + |
| 159 |
'<span class="basalam-bank-account-item__label">بانک:</span>' + |
| 160 |
'<span class="basalam-bank-account-item__value">' + bankName + '</span>' + |
| 161 |
'</div>' + |
| 162 |
'<div class="basalam-bank-account-item__row">' + |
| 163 |
'<span class="basalam-bank-account-item__label">ش� |
| 164 |
اره شبا:</span>' + |
| 165 |
'<span class="basalam-bank-account-item__value basalam-bank-account-item__sheba">' + sheba + '</span>' + |
| 166 |
'</div>' + |
| 167 |
'</div>' + |
| 168 |
'</label>'; |
| 169 |
} |
| 170 |
|
| 171 |
bankAccountsList.innerHTML = html; |
| 172 |
} |
| 173 |
|
| 174 |
// Bank account selection |
| 175 |
bankAccountsList.addEventListener("change", function (e) { |
| 176 |
if (e.target.name !== "bank_account") { |
| 177 |
return; |
| 178 |
} |
| 179 |
|
| 180 |
var id = e.target.value; |
| 181 |
selectedBankAccountId = id; |
| 182 |
bankAccountInput.value = id; |
| 183 |
submitBankBtn.disabled = false; |
| 184 |
|
| 185 |
// Highlight selected |
| 186 |
var items = bankAccountsList.querySelectorAll(".basalam-bank-account-item"); |
| 187 |
for (var i = 0; i < items.length; i++) { |
| 188 |
items[i].classList.toggle("is-selected", items[i].getAttribute("data-id") === id); |
| 189 |
} |
| 190 |
}); |
| 191 |
|
| 192 |
// Open modal on button click |
| 193 |
document.addEventListener("click", function (e) { |
| 194 |
var btn = e.target.closest(".basalam-balance-action"); |
| 195 |
if (!btn || btn.disabled) { |
| 196 |
return; |
| 197 |
} |
| 198 |
|
| 199 |
var method = btn.getAttribute("data-method"); |
| 200 |
if (!method) { |
| 201 |
return; |
| 202 |
} |
| 203 |
|
| 204 |
e.preventDefault(); |
| 205 |
openModal(parseInt(method, 10)); |
| 206 |
|
| 207 |
var title = btn.classList.contains("basalam-balance-action--wallet") ? config.walletTitle : config.bankTitle; |
| 208 |
var modalTitle = overlay.querySelector(".basalam-plus-modal__title"); |
| 209 |
if (modalTitle) { |
| 210 |
modalTitle.textContent = title; |
| 211 |
} |
| 212 |
}); |
| 213 |
|
| 214 |
// Format input with commas and validate against balance |
| 215 |
amountInput.addEventListener("input", function () { |
| 216 |
var cursorPos = this.selectionStart; |
| 217 |
var before = this.value; |
| 218 |
var formatted = formatWithCommas(this.value); |
| 219 |
this.value = formatted; |
| 220 |
|
| 221 |
var diff = formatted.length - before.length; |
| 222 |
this.setSelectionRange(cursorPos + diff, cursorPos + diff); |
| 223 |
|
| 224 |
// Reset error state on new input |
| 225 |
this.classList.remove("basalam-plus-modal__input--error"); |
| 226 |
var balanceError = document.getElementById("basalam-settlement-balance-error"); |
| 227 |
if (balanceError) { |
| 228 |
balanceError.style.display = "none"; |
| 229 |
} |
| 230 |
|
| 231 |
// Validate against max balance |
| 232 |
var maxBalance = parseInt(this.getAttribute("data-max-balance"), 10) || 0; |
| 233 |
var rawAmount = getRawNumber(formatted); |
| 234 |
if (maxBalance > 0 && rawAmount > maxBalance) { |
| 235 |
this.classList.add("basalam-plus-modal__input--error"); |
| 236 |
if (balanceError) { |
| 237 |
balanceError.style.display = "block"; |
| 238 |
} |
| 239 |
} |
| 240 |
}); |
| 241 |
|
| 242 |
// Close modal |
| 243 |
cancelBtn.addEventListener("click", closeModal); |
| 244 |
closeBtn.addEventListener("click", closeModal); |
| 245 |
|
| 246 |
overlay.addEventListener("click", function (e) { |
| 247 |
if (e.target === overlay) { |
| 248 |
closeModal(); |
| 249 |
} |
| 250 |
}); |
| 251 |
|
| 252 |
document.addEventListener("keydown", function (e) { |
| 253 |
if (e.key === "Escape" && overlay.classList.contains("is-open")) { |
| 254 |
closeModal(); |
| 255 |
} |
| 256 |
}); |
| 257 |
|
| 258 |
// Validate amount helper |
| 259 |
function validateAmount() { |
| 260 |
var rawAmount = getRawNumber(amountInput.value); |
| 261 |
|
| 262 |
if (rawAmount <= 0) { |
| 263 |
showError(config.amountError); |
| 264 |
return false; |
| 265 |
} |
| 266 |
|
| 267 |
if (amountInput.classList.contains("basalam-plus-modal__input--error")) { |
| 268 |
return false; |
| 269 |
} |
| 270 |
|
| 271 |
return true; |
| 272 |
} |
| 273 |
|
| 274 |
// Next button (step 1 → step 2) for bank transfer |
| 275 |
nextBtn.addEventListener("click", function () { |
| 276 |
errorMessage.style.display = "none"; |
| 277 |
if (!validateAmount()) { |
| 278 |
return; |
| 279 |
} |
| 280 |
goToStep2(); |
| 281 |
}); |
| 282 |
|
| 283 |
// Back button (step 2 → step 1) |
| 284 |
backBtn.addEventListener("click", function () { |
| 285 |
goToStep1(); |
| 286 |
}); |
| 287 |
|
| 288 |
// Submit settlement request (used by both wallet and bank) |
| 289 |
function submitSettlement() { |
| 290 |
var rawAmount = getRawNumber(amountInput.value); |
| 291 |
|
| 292 |
if (!validateAmount()) { |
| 293 |
return; |
| 294 |
} |
| 295 |
|
| 296 |
var rialAmount = rawAmount * 10; |
| 297 |
|
| 298 |
errorMessage.style.display = "none"; |
| 299 |
|
| 300 |
var body = new URLSearchParams(); |
| 301 |
body.set("action", config.action); |
| 302 |
body.set("nonce", config.nonce); |
| 303 |
body.set("amount", String(rialAmount)); |
| 304 |
body.set("method", methodInput.value); |
| 305 |
|
| 306 |
var investmentId = investmentInput ? investmentInput.value : ""; |
| 307 |
var bankAccountIdVal = bankAccountInput ? bankAccountInput.value : ""; |
| 308 |
|
| 309 |
if (investmentId !== "") { |
| 310 |
body.set("investment_option_id", investmentId); |
| 311 |
} |
| 312 |
if (bankAccountIdVal !== "") { |
| 313 |
body.set("bank_account_id", bankAccountIdVal); |
| 314 |
} |
| 315 |
|
| 316 |
return window.fetch(config.ajaxUrl, { |
| 317 |
method: "POST", |
| 318 |
credentials: "same-origin", |
| 319 |
headers: { |
| 320 |
Accept: "application/json", |
| 321 |
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", |
| 322 |
}, |
| 323 |
body: body.toString(), |
| 324 |
}) |
| 325 |
.then(function (response) { |
| 326 |
return response.json(); |
| 327 |
}) |
| 328 |
.then(function (payload) { |
| 329 |
if (!payload || !payload.success) { |
| 330 |
var msg = payload && payload.data && payload.data.message ? payload.data.message : config.errorMessage; |
| 331 |
throw new Error(msg); |
| 332 |
} |
| 333 |
|
| 334 |
closeModal(); |
| 335 |
if (payload.data && payload.data.message) { |
| 336 |
window.alert(payload.data.message); |
| 337 |
} else { |
| 338 |
window.alert(config.successMessage); |
| 339 |
} |
| 340 |
window.location.reload(); |
| 341 |
}); |
| 342 |
} |
| 343 |
|
| 344 |
// Wallet submit (step 1 direct) |
| 345 |
submitBtn.addEventListener("click", function () { |
| 346 |
setLoading(true); |
| 347 |
submitSettlement().catch(function (error) { |
| 348 |
setLoading(false); |
| 349 |
showError(error.message || config.errorMessage); |
| 350 |
}); |
| 351 |
}); |
| 352 |
|
| 353 |
// Bank submit (step 2) |
| 354 |
submitBankBtn.addEventListener("click", function () { |
| 355 |
if (!selectedBankAccountId) { |
| 356 |
return; |
| 357 |
} |
| 358 |
setBankLoading(true); |
| 359 |
submitSettlement().catch(function (error) { |
| 360 |
setBankLoading(false); |
| 361 |
bankAccountsError.textContent = error.message || config.errorMessage; |
| 362 |
bankAccountsError.style.display = "block"; |
| 363 |
}); |
| 364 |
}); |
| 365 |
})(); |
| 366 |
|