diff --git a/app/Http/Controllers/Admin/PargarController.php b/app/Http/Controllers/Admin/PargarController.php index 0ee7c69..39834f0 100644 --- a/app/Http/Controllers/Admin/PargarController.php +++ b/app/Http/Controllers/Admin/PargarController.php @@ -274,6 +274,112 @@ class PargarController extends Controller $force = $request->boolean('force'); $result = app(PargarInboundWalletService::class)->syncWalletFromPargar($customer, $force); + $summary = $this->summarizeWalletSyncResult($result); + + return response()->json([ + 'ok' => $summary['ok'], + 'message' => $summary['message'], + 'result' => $result, + ]); + } + + /** + * همگام‌سازی ماندهٔ کیف برای همهٔ مشتریان دارای کد پرگار — تکه‌تکه (offset/limit). + */ + public function syncAllWallets(Request $request) + { + if (! app(ConfigService::class)->isPargarAccounting()) { + return response()->json([ + 'ok' => false, + 'message' => 'حسابداری پرگار فعال نیست', + ], 422); + } + + $limit = max(1, min(50, (int) $request->input('limit', 20))); + $offset = max(0, (int) $request->input('offset', 0)); + $force = $request->boolean('force'); + + $base = Customer::query() + ->whereNull('deleted_at') + ->whereNotNull('pargar_account_id') + ->where('pargar_account_id', '!=', ''); + + $total = (clone $base)->count(); + $customers = (clone $base) + ->orderBy('id') + ->offset($offset) + ->limit($limit) + ->get(['id', 'name', 'mobile', 'pargar_account_id', 'type']); + + $walletService = app(PargarInboundWalletService::class); + $success = 0; + $changed = 0; + $failed = 0; + $errors = []; + + foreach ($customers as $customer) { + try { + $result = $walletService->syncWalletFromPargar($customer, $force); + $summary = $this->summarizeWalletSyncResult($result); + $docErrors = $result['documents']['errors'] ?? []; + $hardFail = is_array($docErrors) && $docErrors !== [] + && ! ($result['mande']['applied'] ?? false); + + if ($hardFail) { + $failed++; + $errors[] = [ + 'id' => $customer->id, + 'name' => $customer->name, + 'mobile' => $customer->mobile, + 'error' => $summary['message'], + ]; + continue; + } + + $success++; + if ($summary['ok']) { + $changed++; + } + } catch (\Throwable $e) { + $failed++; + $errors[] = [ + 'id' => $customer->id, + 'name' => $customer->name, + 'mobile' => $customer->mobile, + 'error' => $e->getMessage() !== '' ? $e->getMessage() : 'خطای ناشناخته', + ]; + } + } + + $processed = $customers->count(); + $nextOffset = $offset + $processed; + + return response()->json([ + 'ok' => true, + 'message' => $total === 0 + ? 'مشتری دارای کد پرگار یافت نشد' + : "دستهٔ {$offset} تا {$nextOffset} از {$total}", + 'total' => $total, + 'offset' => $offset, + 'processed' => $processed, + 'next_offset' => $nextOffset, + 'done' => $nextOffset >= $total, + 'success' => $success, + 'changed' => $changed, + 'failed' => $failed, + 'errors' => $errors, + ]); + } + + /** + * @param array{ + * documents: array{applied: int, skipped: int, batches: int, acknowledged: int, errors: list}, + * mande: array{applied: bool, gold_delta?: float, rial_delta?: float, message: string} + * } $result + * @return array{ok: bool, message: string} + */ + private function summarizeWalletSyncResult(array $result): array + { $acknowledged = (int) ($result['documents']['acknowledged'] ?? 0); $skippedDocs = (int) ($result['documents']['skipped'] ?? 0); $batches = (int) ($result['documents']['batches'] ?? 0); @@ -304,11 +410,10 @@ class PargarController extends Controller $message .= ' — '.implode('؛ ', array_slice($docErrors, 0, 2)); } - return response()->json([ + return [ 'ok' => $ok, 'message' => $message, - 'result' => $result, - ]); + ]; } private function uniqueReferralId(): string diff --git a/routes/admin.php b/routes/admin.php index 6e1284d..ceb652a 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -191,6 +191,7 @@ Route::middleware('auth:user')->group(function (){ Route::post('pargar/customer-sync/panel-to-pargar', [PargarController::class, 'syncPanelToPargar']); Route::post('pargar/customer-sync/import-from-pargar', [PargarController::class, 'importFromPargar']); Route::post('pargar/customer-sync/rollback-import', [PargarController::class, 'rollbackImport']); + Route::post('pargar/wallet-sync/all', [PargarController::class, 'syncAllWallets']); Route::get('pargar/{id}', [PargarController::class, 'show']); Route::post('pargar/{id}/retry', [PargarController::class, 'retrySanad']); Route::post('customer/{id}/pargar/register', [PargarController::class, 'registerCustomer']);