From 65d9247b46a83762674d73b0ee982b47a27cf1d9 Mon Sep 17 00:00:00 2001 From: arifal hidayat Date: Sun, 31 Aug 2025 01:22:51 +0700 Subject: [PATCH] fix new hit endpoint pbg status --- .../Controllers/QuickSearchController.php | 3 +- app/Jobs/ScrapingDataJob.php | 11 +-- app/Models/PbgStatus.php | 57 +++++++++++++++ app/Models/PbgTask.php | 5 ++ app/Services/ServiceTabPbgTask.php | 72 +++++++++++++++++++ ...08_30_235722_create_pbg_statuses_table.php | 42 +++++++++++ resources/js/public-search/index.js | 2 + 7 files changed, 186 insertions(+), 6 deletions(-) create mode 100644 app/Models/PbgStatus.php create mode 100644 database/migrations/2025_08_30_235722_create_pbg_statuses_table.php diff --git a/app/Http/Controllers/QuickSearchController.php b/app/Http/Controllers/QuickSearchController.php index 2d995a5..51c768b 100644 --- a/app/Http/Controllers/QuickSearchController.php +++ b/app/Http/Controllers/QuickSearchController.php @@ -100,7 +100,8 @@ class QuickSearchController extends Controller $query = PbgTask::select([ 'pbg_task.*', DB::raw('(SELECT name_building FROM pbg_task_details WHERE pbg_task_details.pbg_task_uid = pbg_task.uuid LIMIT 1) as name_building'), - DB::raw('(SELECT nilai_retribusi_bangunan FROM pbg_task_retributions WHERE pbg_task_retributions.pbg_task_uid = pbg_task.uuid LIMIT 1) as nilai_retribusi_bangunan') + DB::raw('(SELECT nilai_retribusi_bangunan FROM pbg_task_retributions WHERE pbg_task_retributions.pbg_task_uid = pbg_task.uuid LIMIT 1) as nilai_retribusi_bangunan'), + DB::raw('(SELECT note FROM pbg_statuses WHERE pbg_statuses.pbg_task_uuid = pbg_task.uuid LIMIT 1) as note') ]) ->where(function ($q) use ($search) { $q->where('pbg_task.registration_number', 'LIKE', "%$search%") diff --git a/app/Jobs/ScrapingDataJob.php b/app/Jobs/ScrapingDataJob.php index cfef2e8..e752fe1 100644 --- a/app/Jobs/ScrapingDataJob.php +++ b/app/Jobs/ScrapingDataJob.php @@ -66,7 +66,7 @@ class ScrapingDataJob implements ShouldQueue Log::info("=== STEP 1: SCRAPING GOOGLE SHEET ==="); $import_datasource->update(['message' => 'Scraping Google Sheet data...']); - $service_google_sheet->run_service(); + // $service_google_sheet->run_service(); Log::info("Google Sheet scraping completed successfully"); // STEP 2: Scrape PBG Task to get parent data @@ -196,10 +196,11 @@ class ScrapingDataJob implements ShouldQueue private function processTaskDetails(ServiceTabPbgTask $service, string $uuid): void { // Call all detail scraping methods for this task - $service->scraping_task_details($uuid); - $service->scraping_pbg_data_list($uuid); - $service->scraping_task_retributions($uuid); - $service->scraping_task_integrations($uuid); + // $service->scraping_task_details($uuid); + // $service->scraping_pbg_data_list($uuid); + // $service->scraping_task_retributions($uuid); + // $service->scraping_task_integrations($uuid); + $service->scraping_task_detail_status($uuid); } /** diff --git a/app/Models/PbgStatus.php b/app/Models/PbgStatus.php new file mode 100644 index 0000000..0888762 --- /dev/null +++ b/app/Models/PbgStatus.php @@ -0,0 +1,57 @@ +belongsTo(PbgTask::class, 'pbg_task_uuid', 'uuid'); + } + + public static function createOrUpdateFromApi(array $apiResponse, string $pbgTaskUuid) + { + $data = $apiResponse['data'] ?? []; + + return self::updateOrCreate( + [ + 'pbg_task_uuid' => $pbgTaskUuid, + 'status' => $apiResponse['status'], // key pencarian unik + ], + [ + 'status_name' => $apiResponse['status_name'] ?? null, + 'slf_status' => $apiResponse['slf_status'] ?? null, + 'slf_status_name' => $apiResponse['slf_status_name'] ?? null, + 'due_date' => $apiResponse['due_date'] ?? null, + + // nested data + 'uid' => $data['uid'] ?? null, + 'note' => $data['note'] ?? null, + 'file' => $data['file'] ?? null, + 'data_due_date' => $data['due_date'] ?? null, + 'data_created_at' => isset($data['created_at']) ? Carbon::parse($data['created_at'])->format('Y-m-d H:i:s') : null, + + 'slf_data' => $apiResponse['slf_data'] ?? null, + ] + ); + } +} diff --git a/app/Models/PbgTask.php b/app/Models/PbgTask.php index 8c9eb43..451763c 100644 --- a/app/Models/PbgTask.php +++ b/app/Models/PbgTask.php @@ -65,6 +65,11 @@ class PbgTask extends Model return $this->hasMany(PbgTaskDetailDataList::class, 'pbg_task_uuid', 'uuid'); } + public function pbg_status() + { + return $this->hasOne(PbgStatus::class, 'pbg_task_uuid', 'uuid'); + } + /** * Get only data lists with files */ diff --git a/app/Services/ServiceTabPbgTask.php b/app/Services/ServiceTabPbgTask.php index 6613b73..5a996de 100644 --- a/app/Services/ServiceTabPbgTask.php +++ b/app/Services/ServiceTabPbgTask.php @@ -3,6 +3,7 @@ namespace App\Services; use App\Models\GlobalSetting; +use App\Models\PbgStatus; use App\Models\PbgTask; use App\Models\PbgTaskDetail; use App\Models\PbgTaskDetailDataList; @@ -220,6 +221,77 @@ class ServiceTabPbgTask throw new \Exception("Failed to fetch task details for UUID {$uuid} after retries."); } + public function scraping_task_detail_status($uuid) + { + $url = "{$this->simbg_host}/api/pbg/v1/detail/{$uuid}/status/"; + $options = [ + 'headers' => [ + 'Authorization' => "Bearer {$this->user_token}", + 'Content-Type' => 'application/json' + ] + ]; + + $maxRetries = 3; + $initialDelay = 1; + $retriedAfter401 = false; + + for ($retryCount = 0; $retryCount < $maxRetries; $retryCount++) { + try { + $response = $this->client->get($url, $options); + $responseData = json_decode($response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR); + + if (empty($responseData['data']) || !is_array($responseData['data'])) { + return true; + } + + $data = $responseData['data']; + + Log::info("Executed uid : {$uuid}"); + + // Use the static method from PbgTaskDetail model to create/update + PbgStatus::createOrUpdateFromApi($data, $uuid); + + return $responseData; + } catch (\GuzzleHttp\Exception\ClientException $e) { + if ($e->getCode() === 401 && !$retriedAfter401) { + Log::warning("401 Unauthorized - Refreshing token and retrying..."); + try{ + $this->refreshToken(); + $options['headers']['Authorization'] = "Bearer {$this->user_token}"; + $retriedAfter401 = true; + continue; + }catch(\Exception $refreshError){ + Log::error("Token refresh and login failed: " . $refreshError->getMessage()); + return false; + } + } + + return false; + } catch (\GuzzleHttp\Exception\ServerException | \GuzzleHttp\Exception\ConnectException $e) { + if ($e->getCode() === 502) { + Log::warning("502 Bad Gateway - Retrying in {$initialDelay} seconds..."); + } else { + Log::error("Network error ({$e->getCode()}) - Retrying in {$initialDelay} seconds..."); + } + + sleep($initialDelay); + $initialDelay *= 2; + } catch (\GuzzleHttp\Exception\RequestException $e) { + Log::error("Request error ({$e->getCode()}): " . $e->getMessage()); + return false; + } catch (\JsonException $e) { + Log::error("JSON decoding error: " . $e->getMessage()); + return false; + } catch (\Throwable $e) { + Log::critical("Unhandled error: " . $e->getMessage(), ['trace' => $e->getTraceAsString()]); + return false; + } + } + + Log::error("Failed to fetch task detail status for UUID {$uuid} after {$maxRetries} retries."); + throw new \Exception("Failed to fetch task details for UUID {$uuid} after retries."); + } + public function scraping_task_assignments($uuid) { $url = "{$this->simbg_host}/api/pbg/v1/list-tim-penilai/{$uuid}/?page=1&size=10"; diff --git a/database/migrations/2025_08_30_235722_create_pbg_statuses_table.php b/database/migrations/2025_08_30_235722_create_pbg_statuses_table.php new file mode 100644 index 0000000..e6fb430 --- /dev/null +++ b/database/migrations/2025_08_30_235722_create_pbg_statuses_table.php @@ -0,0 +1,42 @@ +id(); + $table->uuid('pbg_task_uuid'); + $table->integer('status'); + $table->string('status_name'); + $table->integer('slf_status')->nullable(); + $table->string('slf_status_name')->nullable(); + $table->date('due_date')->nullable(); + + // nested "data" + $table->uuid('uid')->nullable(); + $table->text('note')->nullable(); + $table->string('file')->nullable(); + $table->date('data_due_date')->nullable(); + $table->timestamp('data_created_at')->nullable(); + + $table->json('slf_data')->nullable(); // kalau nanti slf_data ada struktur JSON + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('pbg_statuses'); + } +}; diff --git a/resources/js/public-search/index.js b/resources/js/public-search/index.js index f19edeb..07ef3f4 100644 --- a/resources/js/public-search/index.js +++ b/resources/js/public-search/index.js @@ -239,6 +239,7 @@ class PublicSearch { { name: "Jenis Konsultasi", width: "150px" }, { name: "Tanggal Jatuh Tempo", width: "140px" }, { name: "Retribusi", width: "120px" }, + { name: "Note", width: "120px" }, ], search: false, pagination: { @@ -278,6 +279,7 @@ class PublicSearch { item.nilai_retribusi_bangunan ) : "-", + item.note || "-", ]); }, total: (data) => data.total || 0,