PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.1
ووسلام – همگام سازی ووکامرس و باسلام v1.10.1
1.10.21 1.10.19 1.10.20 1.10.18 1.10.17 1.10.15 1.10.14 1.10.13 1.10.12 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.2 1.9.1 1.9.0 1.8.8 1.8.5 All 54 releases
sync-basalam / assets / js / finance-balance-settlement.js

finance-balance-settlement.js in ووسلام – همگام سازی ووکامرس و باسلام 1.10.1, at assets/js/finance-balance-settlement.js

366 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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