sync = $sync; $this->client = $client; } public function healthCheck() { $result = $this->client->healthCheck(); $status = ! empty($result['ok']) ? 200 : 422; return response()->json(array_merge([ 'ok' => ! empty($result['ok']), 'message' => $result['message'] ?? null, 'http_status' => $result['http_status'] ?? null, 'timeout' => ! empty($result['timeout']), 'body' => $this->sanitizeBodyForAdmin($result['body'] ?? null), ], $this->client->debugExchange($result)), $status); } /** * @param array $data */ public function storeTrade(array $data) { return $this->sync->recordTrade($data); } /** * @param array $data */ public function wallet(array $data) { return $this->sync->recordWalletCash($data); } /** * @param array $data */ public function walletGold(array $data) { return $this->sync->recordWalletGold($data); } public function registerCustomer($customerId) { if (! app(\App\Services\ConfigService::class)->isShayeganAccounting()) { return response()->json(['ok' => false, 'message' => 'حسابداری شایگان فعال نیست'], 422); } $customer = \App\Models\Customer::findOrFail($customerId); $result = $this->sync->registerCustomer($customer); return response()->json($result, ($result['ok'] ?? false) ? 200 : 422); } public function table(Request $request) { if (! Schema::hasTable('shayegan')) { return response()->json([ 'rows' => [], 'query' => [ 'limit' => (int) $request->input('limit', 20), 'page' => 1, 'total' => 0, 'filters' => $request->input('filters', []), 'search' => $request->input('search'), ], ]); } $query = Shayegan::query()->orderByDesc('id'); \App\DB\Te\TableEngine::create($query, $request) ->initSearch(['desc', 'type', 'shayegan_number', 'sync_status']) ->select(['*']) ->export($query); return response()->json($query); } public function show($id) { $row = Shayegan::findOrFail($id); return response()->json($row); } /** * Manual retry — refuses timeout rows unless force=1 after operator verified remote. */ public function retrySanad(Request $request, $id) { $row = Shayegan::findOrFail($id); if ($row->sync_status === ShayeganSyncService::STATUS_SUCCESS) { return response()->json(['ok' => true, 'message' => 'already synced', 'row' => $row]); } if ($row->sync_status === ShayeganSyncService::STATUS_TIMEOUT && ! $request->boolean('force')) { return response()->json([ 'ok' => false, 'message' => 'این سند timeout شده؛ بدون بررسی نتیجه در حسابگر دوباره ارسال نکنید. در صورت تایید force=1 بفرستید.', ], 422); } $payload = json_decode((string) $row->data, true); $put = is_array($payload) ? ($payload['PutObject'] ?? null) : null; $endpoint = (string) ($row->endpoint ?: 'Document/Put'); if (! is_array($put) || $put === []) { return response()->json(['ok' => false, 'message' => 'payload خالی است'], 422); } // Clear timeout lock only when force retry requested if ($row->sync_status === ShayeganSyncService::STATUS_TIMEOUT) { $row->sync_status = ShayeganSyncService::STATUS_PENDING; $row->save(); } $result = $this->client->put($endpoint, $put); $exchange = $this->client->debugExchange($result); if (! empty($result['timeout'])) { $row->sync_status = ShayeganSyncService::STATUS_TIMEOUT; $row->sync_log = (string) ($result['message'] ?? 'timeout'); $row->res = json_encode(['timeout' => true], JSON_UNESCAPED_UNICODE); $row->save(); return response()->json(array_merge(['ok' => false, 'message' => 'timeout', 'row' => $row], $exchange), 422); } if (! empty($result['ok'])) { $row->sync_status = ShayeganSyncService::STATUS_SUCCESS; $row->sync_log = null; $row->shayegan_number = $result['number'] ?? null; $row->shayegan_guid = $result['guid'] ?? null; $row->res = json_encode($result['body'] ?? [], JSON_UNESCAPED_UNICODE); $row->save(); return response()->json(array_merge(['ok' => true, 'row' => $row], $exchange)); } $row->sync_status = ShayeganSyncService::STATUS_FAILED; $row->sync_log = (string) ($result['message'] ?? 'failed'); $row->res = json_encode($result['body'] ?? [], JSON_UNESCAPED_UNICODE); $row->save(); return response()->json(array_merge(['ok' => false, 'message' => $row->sync_log, 'row' => $row], $exchange), 422); } /** * @param mixed $body * @return mixed */ private function sanitizeBodyForAdmin($body) { if (! is_array($body)) { return $body; } // Drop huge Result lists from health if present if (isset($body['Result']) && is_array($body['Result'])) { $body['Result'] = array_slice($body['Result'], 0, 3); } return $body; } }