PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.23
ووسلام – همگام سازی ووکامرس و باسلام v1.10.23
1.10.23 1.10.22 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 All 56 releases
sync-basalam / templates / FinancialManagement / main-page.php

main-page.php in ووسلام – همگام سازی ووکامرس و باسلام 1.10.23, at templates/FinancialManagement/main-page.php

420 lines 18.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use SyncBasalam\Admin\FinancialManagement\FinancialManagementHistory;
4 use SyncBasalam\Services\FinancialManagementService;
5 use SyncBasalam\Utilities\DateConverter;
6
7 defined('ABSPATH') || exit;
8
9 $service = new FinancialManagementService();
10 $perPage = $service->getDefaultPerPage();
11
12 $activePage = isset($_GET['sbp_active_page']) ? max(1, absint(wp_unslash($_GET['sbp_active_page']))) : 1;
13 $historyPage = isset($_GET['sbp_history_page']) ? max(1, absint(wp_unslash($_GET['sbp_history_page']))) : 1;
14
15 $balanceResult = $service->getBalance();
16 $activeSettlementsResult = $service->getActiveSettlements($activePage, $perPage);
17 $historyResult = $service->getSettlementHistory($historyPage, $perPage);
18 $accessDenied = (int) ($balanceResult['status_code'] ?? 0) === 403
19 || (int) ($activeSettlementsResult['status_code'] ?? 0) === 403
20 || (int) ($historyResult['status_code'] ?? 0) === 403;
21
22 $balanceData = (isset($balanceResult['data']) && is_array($balanceResult['data'])) ? $balanceResult['data'] : [];
23 $activeSettlementsData = (isset($activeSettlementsResult['data']) && is_array($activeSettlementsResult['data'])) ? $activeSettlementsResult['data'] : [];
24 $historyData = (isset($historyResult['data']) && is_array($historyResult['data'])) ? $historyResult['data'] : [];
25
26 $activeItems = (isset($activeSettlementsData['data']) && is_array($activeSettlementsData['data'])) ? $activeSettlementsData['data'] : [];
27 $historyItems = (isset($historyData['data']) && is_array($historyData['data'])) ? $historyData['data'] : [];
28
29 $activeTotalPages = max(1, (int) ($activeSettlementsData['last_page'] ?? 1));
30 $historyTotalPages = max(1, (int) ($historyData['last_page'] ?? 1));
31
32 // Convert from rials to Toman (divide by 10)
33 $formatAmount = static function ($amount): string {
34 if (!is_numeric($amount)) {
35 return '-';
36 }
37 $value = (float) $amount;
38 return number_format($value / 10, 0, '', ',');
39 };
40
41 $formatAmountWithUnit = static function ($amount) use ($formatAmount): string {
42 $formatted = $formatAmount($amount);
43 if ($formatted === '-') {
44 return $formatted;
45 }
46 return $formatted . ' تو�
47 ان';
48 };
49
50 $maskLastDigit = static function ($amount) use ($formatAmount): string {
51 if (!is_numeric($amount)) {
52 return '-';
53 }
54 $intAmount = (int) $amount;
55 $negativePrefix = $intAmount < 0 ? '-' : '';
56 $digits = ltrim((string) abs($intAmount), '0');
57
58 if ($digits === '') {
59 return '0';
60 }
61
62 $withoutLastDigit = strlen($digits) > 1 ? substr($digits, 0, -1) : '';
63 $formattedPart = $withoutLastDigit === '' ? '0' : $formatAmount((int) $withoutLastDigit * 10);
64
65 return $negativePrefix . $formattedPart;
66 };
67
68 // Format timestamp to Jalali (Shamsi) date using DateConverter
69 $formatJalaliTimestamp = static function ($timestamp): string {
70 if (!is_numeric($timestamp)) {
71 return '-';
72 }
73 $value = (int) $timestamp;
74 if ($value <= 0) {
75 return '-';
76 }
77
78 $dateTime = new DateTime('@' . $value);
79 $dateTime->setTimezone(wp_timezone());
80
81 $gy = (int) $dateTime->format('Y');
82 $gm = (int) $dateTime->format('m');
83 $gd = (int) $dateTime->format('d');
84 $time = $dateTime->format('H:i');
85
86 [$jy, $jm, $jd] = DateConverter::gregorianToJalaliArray($gy, $gm, $gd);
87
88 return sprintf('%04d/%02d/%02d - %s', $jy, $jm, $jd, $time);
89 };
90
91 // Format timestamp to Gregorian date
92 $formatGregorianTimestamp = static function ($timestamp): string {
93 if (!is_numeric($timestamp)) {
94 return '-';
95 }
96 $value = (int) $timestamp;
97 if ($value <= 0) {
98 return '-';
99 }
100 return wp_date('Y/m/d H:i', $value);
101 };
102
103 $getStatusLabel = static function (array $item): string {
104 if (!empty($item['status_label']) && is_string($item['status_label'])) {
105 return $item['status_label'];
106 }
107 if (!empty($item['status']['description']) && is_string($item['status']['description'])) {
108 return $item['status']['description'];
109 }
110 return '-';
111 };
112
113 $getStatusClass = static function (array $item): string {
114 $name = '';
115 if (!empty($item['status']['name']) && is_string($item['status']['name'])) {
116 $name = strtolower($item['status']['name']);
117 }
118 $map = [
119 'created' => 'created',
120 'prepared' => 'prepared',
121 'confirmed' => 'confirmed',
122 'system_payment_created' => 'prepared',
123 'system_succeeded' => 'paid',
124 'wallet_charged' => 'paid',
125 'paid' => 'paid',
126 'rejected' => 'rejected',
127 'cancelled' => 'rejected',
128 'system_failed' => 'rejected',
129 ];
130 return $map[$name] ?? 'default';
131 };
132
133 $getMethodLabel = static function (array $item): string {
134 if (!empty($item['method']['description']) && is_string($item['method']['description'])) {
135 return $item['method']['description'];
136 }
137 return '-';
138 };
139
140 $renderApiError = static function (array $result): void {
141 $statusCode = isset($result['status_code']) ? (int) $result['status_code'] : 0;
142 $message = isset($result['message']) && is_string($result['message']) ? $result['message'] : 'خطای نا�
143 شخص در دریافت اطلاعات.';
144 ?>
145 <div class="notice notice-error inline">
146 <p>
147 <?php echo esc_html($message); ?>
148 <?php if ($statusCode > 0): ?>
149 <span>(HTTP <?php echo esc_html((string) $statusCode); ?>)</span>
150 <?php endif; ?>
151 </p>
152 </div>
153 <?php
154 };
155
156 $buildPageUrl = static function (int $active, int $history): string {
157 return add_query_arg([
158 'page' => 'sync_basalam_financial_management',
159 'sbp_active_page' => max(1, $active),
160 'sbp_history_page' => max(1, $history),
161 ], admin_url('admin.php'));
162 };
163
164 $activeTitle = 'درخواست‌های تسویه فعال';
165 $historyTitle = 'ترازهای تسویه شده';
166 ?>
167
168 <div class="basalam-container basalam-finance-page<?php echo $accessDenied ? ' is-locked' : ''; ?>">
169 <div class="basalam-dashboard"<?php echo $accessDenied ? ' inert aria-hidden="true"' : ''; ?>>
170
171 <!-- Balance Section -->
172 <div class="basalam-status-card">
173 <div class="basalam-status-header">
174 <h2 class="basalam-h">
175 <span class="dashicons dashicons-chart-line"></span>
176 �
177 دیریت �
178 الی غرفه
179 </h2>
180 </div>
181
182 <?php if (empty($balanceResult['success'])): ?>
183 <?php $renderApiError($balanceResult); ?>
184 <?php else: ?>
185 <div class="basalam-balance-grid">
186 <div class="basalam-balance-card">
187 <div class="basalam-balance-card__icon">
188 <span class="dashicons dashicons-chart-area"></span>
189 </div>
190 <div class="basalam-balance-card__content">
191 <h3>تراز غرفه</h3>
192 <div class="basalam-balance-card__value"><?php echo esc_html($maskLastDigit($balanceData['balance'] ?? null)); ?> تو�
193 ان</div>
194 <p>تراز غرفه تا ساعت <?php echo esc_html($formatJalaliTimestamp($balanceData['calculated_at'] ?? null)); ?></p>
195 </div>
196 </div>
197
198 <div class="basalam-balance-card basalam-balance-card--highlight">
199 <div class="basalam-balance-card__icon">
200 <span class="dashicons dashicons-building"></span>
201 </div>
202 <div class="basalam-balance-card__content">
203 <h3>تسویه بانکی سال جاری</h3>
204 <div class="basalam-balance-card__value basalam-balance-card__value--small"><?php echo esc_html($formatAmountWithUnit($balanceData['settled']['cash'] ?? null)); ?></div>
205 </div>
206 </div>
207
208 <div class="basalam-balance-card">
209 <div class="basalam-balance-card__icon">
210 <span class="dashicons dashicons-money"></span>
211 </div>
212 <div class="basalam-balance-card__content">
213 <h3>تسویه کیف پول سال جاری</h3>
214 <div class="basalam-balance-card__value basalam-balance-card__value--small"><?php echo esc_html($formatAmountWithUnit($balanceData['settled']['credit'] ?? null)); ?></div>
215 </div>
216 </div>
217 </div>
218
219 <div class="basalam-balance-actions">
220 <button
221 type="button"
222 class="basalam-balance-action basalam-balance-action--wallet"
223 data-method="2">
224 انتقال به کیف پول
225 </button>
226 <button
227 type="button"
228 class="basalam-balance-action basalam-balance-action--bank"
229 data-method="1">
230 انتقال به حساب بانکی
231 </button>
232 </div>
233 <?php endif; ?>
234 </div>
235
236 <!-- Active Settlements -->
237 <div class="basalam-status-card">
238 <div class="basalam-status-header">
239 <h2 class="basalam-h">
240 <span class="dashicons dashicons-list-view"></span>
241 <?php echo esc_html($activeTitle); ?>
242 </h2>
243 <?php if (!empty($activeSettlementsResult['success']) && !empty($activeItems)): ?>
244 <span class="basalam-badge-success">
245 <?php echo esc_html(sprintf('تعداد %s �
246 ورد', number_format_i18n((int) ($activeSettlementsData['total'] ?? count($activeItems))))); ?>
247 </span>
248 <?php endif; ?>
249 </div>
250
251 <?php if (empty($activeSettlementsResult['success'])): ?>
252 <?php $renderApiError($activeSettlementsResult); ?>
253 <?php elseif (empty($activeItems)): ?>
254 <div class="basalam-empty-state">
255 <span class="dashicons dashicons-yes-alt"></span>
256 <p>در حال حاضر درخواست تسویه فعالی وجود ندارد.</p>
257 </div>
258 <?php else: ?>
259 <div class="basalam-settlement-list">
260 <?php foreach ($activeItems as $item): ?>
261 <?php if (!is_array($item)) {
262 continue;
263 } ?>
264 <?php $statusClass = $getStatusClass($item); ?>
265 <div class="basalam-settlement-card">
266 <div class="basalam-settlement-card__top">
267 <span class="basalam-settlement-card__id">#<?php echo esc_html((string) ($item['id'] ?? '-')); ?></span>
268 <span class="basalam-settlement-card__amount"><?php echo esc_html($formatAmountWithUnit($item['amount'] ?? null)); ?></span>
269 </div>
270
271 <div class="basalam-settlement-card__meta">
272 <span class="basalam-status-badge basalam-status-badge--<?php echo esc_attr($statusClass); ?>">
273 <?php echo esc_html($getStatusLabel($item)); ?>
274 </span>
275 <span>
276 <span class="dashicons dashicons-calendar-alt"></span>
277 ثبت: <?php echo esc_html($formatJalaliTimestamp($item['created_at'] ?? null)); ?>
278 </span>
279 <span>
280 <span class="dashicons dashicons-clock"></span>
281 قابل پرداخت: <?php echo esc_html($formatJalaliTimestamp($item['payable_at'] ?? null)); ?>
282 </span>
283 </div>
284
285 <p class="basalam-settlement-card__description">
286 <?php echo esc_html((string) ($item['status_description'] ?? 'توضیح وضعیت �
287 وجود نیست.')); ?>
288 </p>
289 </div>
290 <?php endforeach; ?>
291 </div>
292
293 <?php if ($activeTotalPages > 1): ?>
294 <div class="basalam-pagination" role="navigation" aria-label="صفحه‌بندی تسویه فعال">
295 <?php if ($activePage > 1): ?>
296 <a class="page-numbers" href="<?php echo esc_url($buildPageUrl($activePage - 1, $historyPage)); ?>">قبلی</a>
297 <?php endif; ?>
298
299 <?php $activeStart = max(1, $activePage - 2); ?>
300 <?php $activeEnd = min($activeTotalPages, $activePage + 2); ?>
301 <?php for ($i = $activeStart; $i <= $activeEnd; $i++): ?>
302 <a class="page-numbers <?php echo $i === $activePage ? 'current' : ''; ?>" href="<?php echo esc_url($buildPageUrl($i, $historyPage)); ?>">
303 <?php echo esc_html(number_format_i18n($i)); ?>
304 </a>
305 <?php endfor; ?>
306
307 <?php if ($activePage < $activeTotalPages): ?>
308 <a class="page-numbers prev-next" href="<?php echo esc_url($buildPageUrl($activePage + 1, $historyPage)); ?>">بعدی</a>
309 <?php endif; ?>
310 </div>
311 <?php endif; ?>
312 <?php endif; ?>
313 </div>
314
315 <!-- Settlement History -->
316 <?php
317 echo FinancialManagementHistory::render([
318 'activePage' => $activePage,
319 'historyPage' => $historyPage,
320 'historyTitle' => $historyTitle,
321 'historyResult' => $historyResult,
322 'historyData' => $historyData,
323 'historyItems' => $historyItems,
324 'historyTotalPages' => $historyTotalPages,
325 ]);
326 ?>
327
328 </div>
329
330 <div class="basalam-finance-lock" role="alert" aria-live="assertive">
331 <div class="basalam-finance-lock__card">
332 <span class="dashicons dashicons-lock" aria-hidden="true"></span>
333 <h2>دسترسی به اطلاعات �
334 الی نیاز به احراز هویت دارد</h2>
335 <p>برای دریافت صحیح اطلاعات، �
336 جدداً احراز هویت را انجا�
337 دهید.</p>
338 <form action="<?php echo esc_url(admin_url('admin-post.php')); ?>" method="post">
339 <input type="hidden" name="action" value="basalam_update_setting">
340 <input type="hidden" name="get_token" value="1">
341 <?php wp_nonce_field('basalam_update_setting_nonce', '_wpnonce'); ?>
342 <button type="submit" class="basalam-finance-lock__button">ورود به باسلا�
343 </button>
344 </form>
345 </div>
346 </div>
347
348 <!-- Settlement Modal -->
349 <div id="basalam-settlement-modal" class="basalam-plus-modal-overlay" role="dialog" aria-modal="true" aria-label="درخواست تسویه">
350 <div class="basalam-plus-modal">
351 <div class="basalam-plus-modal__header">
352 <h3 class="basalam-plus-modal__title">انتقال به کیف پول</h3>
353 <button type="button" id="basalam-settlement-close" class="basalam-plus-modal__close" aria-label="بستن">&times;</button>
354 </div>
355
356 <!-- Step 1: Amount -->
357 <div id="basalam-settlement-step-1">
358 <div class="basalam-plus-modal__body">
359 <div class="basalam-plus-modal__balance-info">
360 تراز غرفه: <strong><?php echo esc_html($formatAmount($balanceData['balance'] ?? 0)); ?> تو�
361 ان</strong>
362 </div>
363 <label for="basalam-settlement-amount" class="basalam-plus-modal__label">�
364 بلغ (تو�
365 ان)</label>
366 <input
367 type="text"
368 id="basalam-settlement-amount"
369 class="basalam-plus-modal__input basalam-input"
370 inputmode="numeric"
371 placeholder="�
372 ثال: 100,000"
373 autocomplete="off"
374 data-max-balance="<?php echo esc_attr((int) (($balanceData['balance'] ?? 0) / 10)); ?>" />
375 <div id="basalam-settlement-balance-error" class="basalam-plus-modal__error basalam-plus-modal__balance-error" style="display:none;">
376 �
377 بلغ نباید بیشتر از تراز غرفه باشد
378 </div>
379 <div id="basalam-settlement-error" class="basalam-plus-modal__error" style="display:none;"></div>
380 <input type="hidden" id="basalam-settlement-method" value="2" />
381 <input type="hidden" id="basalam-settlement-investment-option-id" value="1" />
382 <input type="hidden" id="basalam-settlement-bank-account-id" value="" />
383 </div>
384 <div class="basalam-plus-modal__footer">
385 <button type="button" id="basalam-settlement-cancel" class="basalam-plus-modal__btn basalam-plus-modal__btn--secondary">
386 انصراف
387 </button>
388 <button type="button" id="basalam-settlement-next" class="basalam-plus-modal__btn basalam-plus-modal__btn--primary" style="display:none;">
389 بعدی
390 </button>
391 <button type="button" id="basalam-settlement-submit" class="basalam-plus-modal__btn basalam-plus-modal__btn--primary">
392 ثبت درخواست
393 </button>
394 </div>
395 </div>
396
397 <!-- Step 2: Bank Accounts -->
398 <div id="basalam-settlement-step-2" style="display:none;">
399 <div class="basalam-plus-modal__body">
400 <p class="basalam-plus-modal__label">حساب بانکی �
401 قصد را انتخاب کنید</p>
402 <div id="basalam-bank-accounts-list" class="basalam-bank-accounts-list">
403 <div class="basalam-bank-accounts-loading">در حال بارگذاری...</div>
404 </div>
405 <div id="basalam-bank-accounts-error" class="basalam-plus-modal__error" style="display:none;"></div>
406 </div>
407 <div class="basalam-plus-modal__footer">
408 <button type="button" id="basalam-settlement-back" class="basalam-plus-modal__btn basalam-plus-modal__btn--secondary">
409 بازگشت
410 </button>
411 <button type="button" id="basalam-settlement-submit-bank" class="basalam-plus-modal__btn basalam-plus-modal__btn--primary" disabled>
412 ثبت درخواست
413 </button>
414 </div>
415 </div>
416
417 </div>
418 </div>
419 </div>
420