diff --git a/app/Http/Controllers/Admin/TahesabController.php b/app/Http/Controllers/Admin/TahesabController.php index 5d43761..ed39249 100644 --- a/app/Http/Controllers/Admin/TahesabController.php +++ b/app/Http/Controllers/Admin/TahesabController.php @@ -56,29 +56,96 @@ class TahesabController extends Controller return response()->json($tahesab); } + /** همه مشتریان ته‌حساب را از API می‌گیرد و برمی‌گرداند (Code => [Code,Name,Tel]) */ + private function fetchAllTahesabCustomers(): array + { + try { + $response = Http::withoutVerifying()->timeout(30)->withHeaders([ + 'DBName' => $this->Config('tahesab_db'), + 'Content-Type' => 'application/json', + 'Authorization' => 'Bearer ' . $this->Config('tahesab_token'), + ])->post($this->tahesabApiUrl(), [ + 'DoListMoshtari' => [1, 999999], + ])->json(); + + if (! is_array($response)) return []; + return $response; + } catch (\Exception $e) { + return []; + } + } + public function customerSyncStatus(Request $request): \Illuminate\Http\JsonResponse { - $total = Customer::whereNull('deleted_at')->count(); - $registered = Customer::whereNull('deleted_at')->whereNotNull('moshtari_code')->count(); - $unregistered = $total - $registered; + // مشتریان پنل + $panelTotal = Customer::whereNull('deleted_at')->count(); + $panelRegistered = Customer::whereNull('deleted_at')->whereNotNull('moshtari_code')->count(); + $panelOnly = $panelTotal - $panelRegistered; // در پنل هستند ولی در ته‌حساب نیستند - $query = Customer::whereNull('deleted_at')->whereNull('moshtari_code') + // مشتریان ته‌حساب + $tahesabCustomers = $this->fetchAllTahesabCustomers(); + $tahesabTotal = count($tahesabCustomers); + + // موبایل‌های پنل (بدون صفر ابتدایی چون ته‌حساب بدون صفر ذخیره می‌کند) + $panelMobiles = Customer::whereNull('deleted_at') + ->whereNotNull('mobile') + ->pluck('mobile') + ->map(fn ($m) => ltrim((string) $m, '0')) + ->flip() + ->toArray(); + + // مشتریان ته‌حساب که در پنل نیستند + $tahesabOnlyList = []; + foreach ($tahesabCustomers as $item) { + if (! is_array($item)) continue; + $tel = ltrim((string) ($item['Tel'] ?? ''), '0'); + if ($tel && isset($panelMobiles[$tel])) continue; // موجود در پنل + $tahesabOnlyList[] = [ + 'code' => $item['Code'] ?? null, + 'name' => $item['Name'] ?? '', + 'tel' => $item['Tel'] ?? '', + 'gid' => $item['GID'] ?? null, + 'group'=> $item['GoroupName'] ?? '', + ]; + } + $tahesabOnlyCount = count($tahesabOnlyList); + + // مشتریان پنل که در ته‌حساب نیستند + $tahesabCodes = Customer::whereNull('deleted_at') + ->whereNotNull('moshtari_code') + ->pluck('moshtari_code') + ->flip() + ->toArray(); + + $panelOnlyQuery = Customer::whereNull('deleted_at')->whereNull('moshtari_code') ->select('id', 'name', 'mobile', 'created_at'); if ($search = $request->input('search')) { - $query->where(function ($q) use ($search) { + $panelOnlyQuery->where(function ($q) use ($search) { $q->where('name', 'like', "%{$search}%") ->orWhere('mobile', 'like', "%{$search}%"); }); } + $panelOnlyList = $panelOnlyQuery->orderBy('id')->paginate(20); - $list = $query->orderBy('id')->paginate(20); + // پیجینیشن برای تب ته‌حساب → پنل + $tahesabOnlyPage = (int) $request->input('tahesab_page', 1); + $perPage = 20; + $tahesabOnlyPaged = array_slice($tahesabOnlyList, ($tahesabOnlyPage - 1) * $perPage, $perPage); return response()->json([ - 'total' => $total, - 'registered' => $registered, - 'unregistered'=> $unregistered, - 'list' => $list, + 'panel_total' => $panelTotal, + 'panel_registered' => $panelRegistered, + 'panel_only' => $panelOnly, + 'tahesab_total' => $tahesabTotal, + 'tahesab_only_count'=> $tahesabOnlyCount, + 'panel_only_list' => $panelOnlyList, + 'tahesab_only_list' => [ + 'data' => $tahesabOnlyPaged, + 'total' => $tahesabOnlyCount, + 'current_page' => $tahesabOnlyPage, + 'last_page' => max(1, (int) ceil($tahesabOnlyCount / $perPage)), + ], ]); } @@ -111,6 +178,56 @@ class TahesabController extends Controller ]); } + public function importFromTahesab(Request $request): \Illuminate\Http\JsonResponse + { + $validated = $request->validate([ + 'customers' => 'required|array', + 'customers.*.code' => 'required|integer', + 'customers.*.name' => 'required|string', + 'customers.*.tel' => 'nullable|string', + ]); + + $success = 0; + $failed = 0; + $errors = []; + + foreach ($validated['customers'] as $item) { + $mobile = '0' . ltrim((string) ($item['tel'] ?? ''), '0'); + + // کد معرف یکتا + $characters = '0123456789abcdefghijklmnopqrstuvwxyz'; + do { + $referralId = ''; + for ($i = 0; $i < 4; $i++) { + $referralId .= $characters[random_int(0, strlen($characters) - 1)]; + } + } while (Customer::where('referral_id', $referralId)->exists()); + + try { + $customer = Customer::create([ + 'name' => trim($item['name']), + 'fname' => trim($item['name']), + 'mobile' => $mobile ?: null, + 'active' => true, + 'moshtari_code' => $item['code'], + 'referral_id' => $referralId, + 'type' => 2, + ]); + $success++; + } catch (\Exception $e) { + $failed++; + $errors[] = ['name' => $item['name'], 'code' => $item['code'], 'error' => $e->getMessage()]; + } + } + + return response()->json([ + 'ok' => true, + 'success' => $success, + 'failed' => $failed, + 'errors' => $errors, + ]); + } + public function retrySanad($id) { $tahesab = Tahesab::with('customer')->findOrFail($id); diff --git a/routes/admin.php b/routes/admin.php index a65f525..0c8b962 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -155,6 +155,7 @@ Route::middleware('auth:user')->group(function (){ Route::post('tahesab/table', [TahesabController::class, 'table']); Route::get('tahesab/customer-sync/status', [TahesabController::class, 'customerSyncStatus']); Route::post('tahesab/customer-sync/panel-to-tahesab', [TahesabController::class, 'syncPanelToTahesab']); + Route::post('tahesab/customer-sync/import-from-tahesab', [TahesabController::class, 'importFromTahesab']); Route::get('tahesab/{id}', [TahesabController::class, 'show']); Route::post('tahesab/{id}/retry', [TahesabController::class, 'retrySanad']); Route::post('customer/{id}/tahesab/register', [TahesabController::class, 'registerCustomer']);