diff --git a/app/Console/Commands/ScrapingLeaderData.php b/app/Console/Commands/ScrapingLeaderData.php deleted file mode 100644 index 04f8bc9..0000000 --- a/app/Console/Commands/ScrapingLeaderData.php +++ /dev/null @@ -1,33 +0,0 @@ -sync_leader_data(); - $this->info('Leader data synced successfully'); - } -} diff --git a/app/Http/Controllers/Api/PbgTaskController.php b/app/Http/Controllers/Api/PbgTaskController.php index 7b0a9ce..fdc653c 100644 --- a/app/Http/Controllers/Api/PbgTaskController.php +++ b/app/Http/Controllers/Api/PbgTaskController.php @@ -12,7 +12,6 @@ use App\Models\DataSetting; use App\Models\ImportDatasource; use App\Models\PbgTask; use App\Models\PbgTaskGoogleSheet; -use App\Services\GoogleSheetService; use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; @@ -20,10 +19,6 @@ use Illuminate\Validation\Rules\Enum; class PbgTaskController extends Controller { - protected $googleSheetService; - public function __construct(GoogleSheetService $googleSheetService){ - $this->googleSheetService = $googleSheetService; - } public function index(Request $request) { info($request); diff --git a/app/Http/Controllers/Settings/SyncronizeController.php b/app/Http/Controllers/Settings/SyncronizeController.php index 68f9641..3d9b960 100644 --- a/app/Http/Controllers/Settings/SyncronizeController.php +++ b/app/Http/Controllers/Settings/SyncronizeController.php @@ -3,17 +3,12 @@ namespace App\Http\Controllers\Settings; use App\Http\Controllers\Controller; -use App\Services\ServiceSIMBG; use Illuminate\Http\Request; use Exception; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; class SyncronizeController extends Controller { - protected $service_simbg; - public function __construct(ServiceSIMBG $service_simbg){ - $this->service_simbg = $service_simbg; - } public function index(Request $request){ $menuId = $request->query('menu_id'); $user = Auth::user(); @@ -37,36 +32,4 @@ class SyncronizeController extends Controller return view('settings.syncronize.index', compact('creator', 'updater', 'destroyer')); } - - public function syncPbgTask(){ - $res = $this->service_simbg->syncTaskPBG(); - return $res; - } - - public function syncronizeTask(Request $request){ - $res = $this->service_simbg->syncTaskPBG(); - return redirect()->back()->with('success', 'Processing completed successfully'); - } - - public function getUserToken(){ - $res = $this->service_simbg->getToken(); - return $res; - } - - public function syncIndexIntegration(Request $request, $uuid){ - $token = $request->get('token'); - $res = $this->service_simbg->syncIndexIntegration($uuid); - return $res; - } - - public function syncTaskDetailSubmit(Request $request, $uuid){ - $token = $request->get('token'); - $res = $this->service_simbg->syncTaskDetailSubmit($uuid, $token); - return $res; - } - - public function syncTaskAssignments($uuid){ - $res = $this->service_simbg->syncTaskAssignments($uuid); - return $res; - } } diff --git a/app/Jobs/ScrapingDataJob.php b/app/Jobs/ScrapingDataJob.php index a96da3c..da98be3 100644 --- a/app/Jobs/ScrapingDataJob.php +++ b/app/Jobs/ScrapingDataJob.php @@ -59,28 +59,12 @@ class ScrapingDataJob implements ShouldQueue 'start_time' => now(), 'failed_uuid' => null ]); - - Log::info("ImportDatasource created", ['id' => $import_datasource->id]); - - // STEP 1: Scrape Google Sheet data first - Log::info("=== STEP 1: SCRAPING GOOGLE SHEET ==="); - $import_datasource->update(['message' => 'Scraping Google Sheet data...']); - - $service_google_sheet->run_service(); - Log::info("Google Sheet scraping completed successfully"); - - // STEP 2: Scrape PBG Task to get parent data - Log::info("=== STEP 2: SCRAPING PBG TASK PARENT DATA ==="); $import_datasource->update(['message' => 'Scraping PBG Task parent data...']); $service_pbg_task->run_service(); - Log::info("PBG Task parent data scraping completed"); // STEP 3: Get all PBG tasks for detail scraping $totalTasks = PbgTask::count(); - Log::info("=== STEP 3: SCRAPING PBG TASK DETAILS ===", [ - 'total_tasks' => $totalTasks - ]); $import_datasource->update([ 'message' => "Scraping details for {$totalTasks} PBG tasks..." @@ -135,13 +119,10 @@ class ScrapingDataJob implements ShouldQueue } }); - Log::info("Task details scraping completed", [ - 'processed_tasks' => $processedTasks, - 'total_tasks' => $totalTasks - ]); + $import_datasource->update(['message' => 'Scraping Google Sheet data...']); + + $service_google_sheet->run_service(); - // STEP 4: Generate BigData Resume - Log::info("=== STEP 4: GENERATING BIGDATA RESUME ==="); $import_datasource->update(['message' => 'Generating BigData resume...']); BigdataResume::generateResumeData($import_datasource->id, date('Y'), "simbg"); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index cb4925e..5cf29b6 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -14,8 +14,6 @@ use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; use Carbon\Carbon; -use App\Services\ServiceSIMBG; -use App\Services\GoogleSheetService; class AppServiceProvider extends ServiceProvider { diff --git a/app/Services/GoogleSheetService.php b/app/Services/GoogleSheetService.php deleted file mode 100644 index f8483ff..0000000 --- a/app/Services/GoogleSheetService.php +++ /dev/null @@ -1,153 +0,0 @@ -client = new Google_Client(); - $this->client->setApplicationName("Sibedas Google Sheets API"); - $this->client->setScopes([Google_Service_Sheets::SPREADSHEETS_READONLY]); - $this->client->setAuthConfig(storage_path("app/teak-banner-450003-s8-ea05661d9db0.json")); - $this->client->setAccessType("offline"); - - $this->service = new Google_Service_Sheets($this->client); - $this->spreadsheetID = env("SPREAD_SHEET_ID"); - - $this->service_sheets = new Google_Service_Sheets($this->client); - } - - public function getSheetData($range){ - $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); - return $response->getValues(); - } - - public function getLastRowByColumn($column = "A") - { - try{ - // Ambil spreadsheet - $spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID); - $sheets = $spreadsheet->getSheets(); - - if (!empty($sheets)) { - // Ambil nama sheet pertama dengan benar - $firstSheetTitle = $sheets[0]->getProperties()->getTitle(); - - // ✅ Format range harus benar! - $range = "{$firstSheetTitle}!{$column}:{$column}"; - - // Ambil data dari kolom yang diminta - $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); - $values = $response->getValues(); - - // Cek nilai terakhir yang tidak kosong - $lastRow = 0; - if (!empty($values)) { - foreach ($values as $index => $row) { - if (!empty($row[0])) { // Jika ada data, update lastRow - $lastRow = $index + 1; - } - } - } - - return $lastRow; - } - - return 0; - }catch(\Exception $e){ - throw $e; - } - } - public function getHeader() - { - try{ - $spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID); - $sheets = $spreadsheet->getSheets(); - - // Ambil nama sheet pertama - $firstSheetTitle = $sheets[0]->getProperties()->getTitle(); - - // Ambil data dari baris pertama (header) - $range = "{$firstSheetTitle}!1:1"; - $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); - $values = $response->getValues(); - - // Kembalikan header (baris pertama) - return !empty($values) ? $values[0] : []; - }catch(\Exception $e){ - throw $e; - } - } - - public function getLastColumn() - { - $spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID); - $sheets = $spreadsheet->getSheets(); - - // Ambil nama sheet pertama - $firstSheetTitle = $sheets[0]->getProperties()->getTitle(); - - // Ambil baris pertama untuk mendapatkan jumlah kolom yang terisi - $range = "{$firstSheetTitle}!1:1"; - $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); - $values = $response->getValues(); - - // Hitung jumlah kolom yang memiliki nilai - return !empty($values) ? count(array_filter($values[0], fn($value) => $value !== "")) : 0; - } - - public function getSheetDataCollection($totalRow = 10){ - try{ - $spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID); - $sheets = $spreadsheet->getSheets(); - $firstSheetTitle = $sheets[0]->getProperties()->getTitle(); - - $header = $this->getHeader(); - $header = array_map(function($columnHeader) { - // Trim spaces first, then replace non-alphanumeric characters with underscores - $columnHeader = trim($columnHeader); - return strtolower(preg_replace('/[^A-Za-z0-9_]/', '_', $columnHeader)); - }, $header); - $range = "{$firstSheetTitle}!2:{$totalRow}"; - - $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); - $values = $response->getValues(); - - $mappedData = []; - if (!empty($values)) { - foreach ($values as $row) { - $rowData = []; - foreach ($header as $index => $columnHeader) { - // Map header to the corresponding value from the row - $rowData[$columnHeader] = isset($row[$index]) ? $row[$index] : null; - } - $mappedData[] = $rowData; - } - } - - return $mappedData; - }catch(\Exception $e){ - throw $e; - } - } - public function get_data_by_sheet($no_sheet = 1){ - $spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID); - $sheets = $spreadsheet->getSheets(); - $sheetTitle = $sheets[$no_sheet]->getProperties()->getTitle(); - $range = "{$sheetTitle}"; - $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); - $values = $response->getValues(); - return!empty($values)? $values : []; - } -} diff --git a/app/Services/ServiceClient.php b/app/Services/ServiceClient.php deleted file mode 100644 index 88de0b3..0000000 --- a/app/Services/ServiceClient.php +++ /dev/null @@ -1,99 +0,0 @@ -client = new Client(); - $this->baseUrl = $baseUrl; - $this->headers = array_merge( - [ - 'Accept' => 'application/json', - 'Content-Type' => 'application/json' - ], - $headers - ); - } - - public function makeRequest($url, $method = 'GET', $body = null, $headers = [], $timeout = 14400){ - try { - - $headers = array_merge($this->headers, $headers); - - $options = [ - 'headers' => $headers, - 'timeout' => $timeout, - 'connect_timeout' => 60 - ]; - - if ($body) { - $options['json'] = $body; // Guzzle akan mengonversi array ke JSON - } - - $response = $this->client->request($method, $this->baseUrl . $url, $options); - $responseBody = (string) $response->getBody(); - - if (!str_contains($response->getHeaderLine('Content-Type'), 'application/json')) { - \Log::error('Unexpected response format: ' . $responseBody); - return $this->resError('API response is not JSON'); - } - - $resultResponse = json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR); - return $this->resSuccess($resultResponse); - } catch (\GuzzleHttp\Exception\ClientException $e) { - // Handle 4xx errors (e.g., 401 Unauthorized) - $responseBody = (string) $e->getResponse()->getBody(); - $errorResponse = json_decode($responseBody, true); - - if (isset($errorResponse['code']) && $errorResponse['code'] === 'token_not_valid') { - return $this->resError('Invalid token, please refresh your token.', $errorResponse, 401); - } - - return $this->resError('Client error from API', $errorResponse, $e->getResponse()->getStatusCode()); - } catch (\GuzzleHttp\Exception\ServerException $e) { - // Handle 5xx errors (e.g., Internal Server Error) - return $this->resError('Server error from API', (string) $e->getResponse()->getBody(), 500); - } catch (\GuzzleHttp\Exception\RequestException $e) { - // Handle network errors (e.g., timeout, connection issues) - return $this->resError('Network error: ' . $e->getMessage(), null, 503); - } catch (Exception $e) { - // Handle unexpected errors - return $this->resError('Unexpected error: ' . $e->getMessage(), null, 500); - } - } - - // Fungsi untuk melakukan permintaan GET - public function get($url, $headers = []) - { - return $this->makeRequest($url, 'GET', null, $headers); - } - - // Fungsi untuk melakukan permintaan POST - public function post($url, $body, $headers = []) - { - return $this->makeRequest($url, 'POST', $body, $headers); - } - - // Fungsi untuk melakukan permintaan PUT - public function put($url, $body, $headers = []) - { - return $this->makeRequest($url, 'PUT', $body, $headers); - } - - // Fungsi untuk melakukan permintaan DELETE - public function delete($url, $headers = []) - { - return $this->makeRequest($url, 'DELETE', null, $headers); - } -} diff --git a/app/Services/ServiceSIMBG.php b/app/Services/ServiceSIMBG.php deleted file mode 100644 index e3451aa..0000000 --- a/app/Services/ServiceSIMBG.php +++ /dev/null @@ -1,662 +0,0 @@ -pluck('value', 'key'); - - $this->email = trim((string) ($settings['SIMBG_EMAIL'] ?? "")); - $this->password = trim((string) ($settings['SIMBG_PASSWORD'] ?? "")); - $this->simbg_host = trim((string) ($settings['SIMBG_HOST'] ?? "")); - $this->fetch_per_page = trim((string) ($settings['FETCH_PER_PAGE'] ?? "")); - - $this->service_client = new ServiceClient($this->simbg_host); - $this->googleSheetService = $googleSheetService; - } - - public function getToken(){ - try{ - $url = "/api/user/v1/auth/login/"; - $body = [ - 'email' => $this->email, - 'password' => $this->password, - ]; - - $res = $this->service_client->post($url, $body); - if(!$res->original['success']){ - Log::error("Token not retrieved ", ['response' => $res]); - throw new Exception("Token not retrieved."); - } - return $res; - }catch(Exception $e){ - Log::error("Error on method get token ", ['response' => $e->getMessage()]); - throw $e; - } - } - - public function syncIndexIntegration($uuids) - { - try{ - if(empty($uuids)){ - return false; - } - - $initResToken = $this->getToken(); - if (empty($initResToken->original['data']['token']['access'])) { - Log::error("API response indicates failure", ['token' => 'Failed to retrieve token']); - return false; - } - $token = $initResToken->original['data']['token']['access']; - - $integrations = []; - foreach($uuids as $uuid){ - $url = "/api/pbg/v1/detail/" . $uuid . "/retribution/indeks-terintegrasi/"; - - $headers = [ - 'Authorization' => "Bearer " . $token, - ]; - - $res = $this->service_client->get($url, $headers); - - if (empty($res->original['success']) || !$res->original['success']) { - // Log error - Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]); - continue; - } - - $data = $res->original['data']['data'] ?? null; - if (!$data) { - Log::error("No valid data returned from API", ['url' => $url, 'uuid' => $uuid]); - continue; - } - - $integrations[] = [ - 'pbg_task_uid' => $uuid, - 'indeks_fungsi_bangunan' => $data['indeks_fungsi_bangunan'] ?? null, - 'indeks_parameter_kompleksitas' => $data['indeks_parameter_kompleksitas'] ?? null, - 'indeks_parameter_permanensi' => $data['indeks_parameter_permanensi'] ?? null, - 'indeks_parameter_ketinggian' => $data['indeks_parameter_ketinggian'] ?? null, - 'faktor_kepemilikan' => $data['faktor_kepemilikan'] ?? null, - 'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null, - 'total' => $data['total'] ?? null, - ]; - } - - PbgTaskIndexIntegrations::upsert($integrations, ['pbg_task_uid'], ['indeks_fungsi_bangunan', - 'indeks_parameter_kompleksitas', 'indeks_parameter_permanensi', 'indeks_parameter_ketinggian', 'faktor_kepemilikan', 'indeks_terintegrasi', 'total']); - - return true; - }catch (Exception $e){ - Log::error('error when sync index integration ', ['index integration'=> $e->getMessage()]); - throw $e; - } - } - - public function syncTaskPBG() - { - try { - Log::info("Processing google sheet sync"); - $importDatasource = ImportDatasource::create([ - 'status' => ImportDatasourceStatus::Processing->value, - ]); - - // sync google sheet first - $totalRowCount = $this->googleSheetService->getLastRowByColumn("C"); - $sheetData = $this->googleSheetService->getSheetDataCollection($totalRowCount); - $sheet_big_data = $this->googleSheetService->get_data_by_sheet(); - $data_setting_result = []; // Initialize result storage - - $found_section = null; // Track which section is found - - foreach ($sheet_big_data as $row) { - // Check for section headers - if (in_array("•PROSES PENERBITAN:", $row)) { - $found_section = "MENUNGGU_KLIK_DPMPTSP"; - } elseif (in_array("•BERKAS AKTUAL TERVERIFIKASI DINAS TEKNIS 2024:", $row)) { - $found_section = "REALISASI_TERBIT_PBG"; - } elseif (in_array("•TERPROSES DI DPUTR: belum selesai rekomtek'", $row)) { - $found_section = "PROSES_DINAS_TEKNIS"; - } - - // If a section is found and we reach "Grand Total", save the corresponding values - if ($found_section && isset($row[0]) && trim($row[0]) === "Grand Total") { - if ($found_section === "MENUNGGU_KLIK_DPMPTSP") { - $data_setting_result["MENUNGGU_KLIK_DPMPTSP_COUNT"] = $this->convertToInteger($row[2]) ?? null; - $data_setting_result["MENUNGGU_KLIK_DPMPTSP_SUM"] = $this->convertToDecimal($row[3]) ?? null; - } elseif ($found_section === "REALISASI_TERBIT_PBG") { - $data_setting_result["REALISASI_TERBIT_PBG_COUNT"] = $this->convertToInteger($row[2]) ?? null; - $data_setting_result["REALISASI_TERBIT_PBG_SUM"] = $this->convertToDecimal($row[4]) ?? null; - } elseif ($found_section === "PROSES_DINAS_TEKNIS") { - $data_setting_result["PROSES_DINAS_TEKNIS_COUNT"] = $this->convertToInteger($row[2]) ?? null; - $data_setting_result["PROSES_DINAS_TEKNIS_SUM"] = $this->convertToDecimal($row[3]) ?? null; - } - - // Reset section tracking after capturing "Grand Total" - $found_section = null; - } - } - - Log::info("data setting result", ['result' => $data_setting_result]); - - foreach ($data_setting_result as $key => $value) { - DataSetting::updateOrInsert( - ["key" => $key], // Find by key - ["value" => $value] // Update or insert value - ); - } - $mapToUpsert = []; - - foreach ($sheetData as $data) { - $mapToUpsert[] = [ - 'no_registrasi' => $this->cleanString($data['no__registrasi'] ?? null), - 'jenis_konsultasi' => $this->cleanString($data['jenis_konsultasi'] ?? null), - 'fungsi_bg' => $this->cleanString($data['fungsi_bg'] ?? null), - 'tgl_permohonan' => $this->convertToDate($this->cleanString($data['tgl_permohonan'] ?? null)), - 'status_verifikasi' => $this->cleanString($data['status_verifikasi'] ?? null), - 'status_permohonan' => $this->convertToDate($this->cleanString($data['status_permohonan'] ?? null)), - 'alamat_pemilik' => $this->cleanString($data['alamat_pemilik'] ?? null), - 'no_hp' => $this->cleanString($data['no__hp'] ?? null), - 'email' => $this->cleanString($data['e_mail'] ?? null), - 'tanggal_catatan' => $this->convertToDate($this->cleanString($data['tanggal_catatan'] ?? null)), - 'catatan_kekurangan_dokumen' => $this->cleanString($data['catatan_kekurangan_dokumen'] ?? null), - 'gambar' => $this->cleanString($data['gambar'] ?? null), - 'krk_kkpr' => $this->cleanString($data['krk_kkpr'] ?? null), - 'no_krk' => $this->cleanString($data['no__krk'] ?? null), - 'lh' => $this->cleanString($data['lh'] ?? null), - 'ska' => $this->cleanString($data['ska'] ?? null), - 'keterangan' => $this->cleanString($data['keterangan'] ?? null), - 'helpdesk' => $this->cleanString($data['helpdesk'] ?? null), - 'pj' => $this->cleanString($data['pj'] ?? null), - 'kepemilikan' => $this->cleanString($data['kepemilikan'] ?? null), - 'potensi_taru' => $this->cleanString($data['potensi_taru'] ?? null), - 'validasi_dinas' => $this->cleanString($data['validasi_dinas'] ?? null), - 'kategori_retribusi' => $this->cleanString($data['kategori_retribusi'] ?? null), - 'no_urut_ba_tpt' => $this->cleanString($data['no__urut_ba_tpt__2024_0001_'] ?? null), - 'tanggal_ba_tpt' => $this->convertToDate($this->cleanString($data['tanggal_ba_tpt'] ?? null)), - 'no_urut_ba_tpa' => $this->cleanString($data['no__urut_ba_tpa'] ?? null), - 'tanggal_ba_tpa' => $this->convertToDate($this->cleanString($data['tanggal_ba_tpa'] ?? null)), - 'no_urut_skrd' => $this->cleanString($data['no__urut_skrd__2024_0001_'] ?? null), - 'tanggal_skrd' => $this->convertToDate($this->cleanString($data['tanggal_skrd'] ?? null)), - 'ptsp' => $this->cleanString($data['ptsp'] ?? null), - 'selesai_terbit' => $this->cleanString($data['selesai_terbit'] ?? null), - 'tanggal_pembayaran' => $this->convertToDate($this->cleanString($data['tanggal_pembayaran__yyyy_mm_dd_'] ?? null)), - 'format_sts' => $this->cleanString($data['format_sts'] ?? null), - 'tahun_terbit' => (int) ($data['tahun_terbit'] ?? null), - 'tahun_berjalan' => (int) ($data['tahun_berjalan'] ?? null), - 'kelurahan' => $this->cleanString($data['kelurahan'] ?? null), - 'kecamatan' => $this->cleanString($data['kecamatan'] ?? null), - 'lb' => $this->convertToDecimal($data['lb'] ?? null), - 'tb' => $this->convertToDecimal($data['tb'] ?? null), - 'jlb' => (int) ($data['jlb'] ?? null), - 'unit' => (int) ($data['unit'] ?? null), - 'usulan_retribusi' => (int) ($data['usulan_retribusi'] ?? null), - 'nilai_retribusi_keseluruhan_simbg' => $this->convertToDecimal($data['nilai_retribusi_keseluruhan__simbg_'] ?? null), - 'nilai_retribusi_keseluruhan_pad' => $this->convertToDecimal($data['nilai_retribusi_keseluruhan__pad_'] ?? null), - 'denda' => $this->convertToDecimal($data['denda'] ?? null), - 'latitude' => $this->cleanString($data['latitude'] ?? null), - 'longitude' => $this->cleanString($data['longitude'] ?? null), - 'nik_nib' => $this->cleanString($data['nik_nib'] ?? null), - 'dok_tanah' => $this->cleanString($data['dok__tanah'] ?? null), - 'temuan' => $this->cleanString($data['temuan'] ?? null), - ]; - } - - $batchSize = 1000; - $chunks = array_chunk($mapToUpsert, $batchSize); - - foreach($chunks as $chunk){ - PbgTaskGoogleSheet::upsert($chunk, ["no_registrasi"],[ - 'jenis_konsultasi', - 'nama_pemilik', - 'lokasi_bg', - 'fungsi_bg', - 'nama_bangunan', - 'tgl_permohonan', - 'status_verifikasi', - 'status_permohonan', - 'alamat_pemilik', - 'no_hp', - 'email', - 'tanggal_catatan', - 'catatan_kekurangan_dokumen', - 'gambar', - 'krk_kkpr', - 'no_krk', - 'lh', - 'ska', - 'keterangan', - 'helpdesk', - 'pj', - 'kepemilikan', - 'potensi_taru', - 'validasi_dinas', - 'kategori_retribusi', - 'no_urut_ba_tpt', - 'tanggal_ba_tpt', - 'no_urut_ba_tpa', - 'tanggal_ba_tpa', - 'no_urut_skrd', - 'tanggal_skrd', - 'ptsp', - 'selesai_terbit', - 'tanggal_pembayaran', - 'format_sts', - 'tahun_terbit', - 'tahun_berjalan', - 'kelurahan', - 'kecamatan', - 'lb', - 'tb', - 'jlb', - 'unit', - 'usulan_retribusi', - 'nilai_retribusi_keseluruhan_simbg', - 'nilai_retribusi_keseluruhan_pad', - 'denda', - 'latitude', - 'longitude', - 'nik_nib', - 'dok_tanah', - 'temuan', - ]); - } - - $initResToken = $this->getToken(); - if (empty($initResToken->original['data']['token']['access'])) { - $importDatasource->update([ - 'status' => ImportDatasourceStatus::Failed->value, - 'response_body' => 'Failed to retrieve token' - ]); - return $this->resError("Failed to retrieve token"); - } - $apiToken = $initResToken->original['data']['token']['access']; - $headers = ['Authorization' => "Bearer " . $apiToken]; - - $url = "/api/pbg/v1/list/?page=1&size={$this->fetch_per_page}&sort=ASC"; - $initialResponse = $this->service_client->get($url, $headers); - - $totalPage = $initialResponse->original['data']['total_page'] ?? 0; - if ($totalPage == 0) { - $importDatasource->update([ - 'status' => ImportDatasourceStatus::Failed->value, - 'response_body' => 'Invalid response: no total_page' - ]); - return $this->resError("Invalid response from API"); - } - - $savedCount = $failedCount = 0; - - Log::info("Fetching tasks", ['total page' => $totalPage]); - - for ($currentPage = 1; $currentPage <= $totalPage; $currentPage++) { - try { - $pageUrl = "/api/pbg/v1/list/?page={$currentPage}&size={$this->fetch_per_page}&sort=ASC"; - - Log::info("Fetching tasks", ['currentPage' => $currentPage]); - $headers = [ - 'Authorization' => "Bearer " . $apiToken, // Update headers - ]; - - for ($attempt = 0; $attempt < 2; $attempt++) { // Try twice (original + retry) - - $response = $this->service_client->get($pageUrl, $headers); - - if ($response instanceof \Illuminate\Http\JsonResponse) { - $decodedResponse = json_decode($response->getContent(), true); - - if (isset($decodedResponse['errors']['code']) && $decodedResponse['errors']['code'] === 'token_not_valid') { - $initResToken = $this->getToken(); - - if (!empty($initResToken->original['data']['token']['access'])) { - $new_token = $initResToken->original['data']['token']['access']; - $headers['Authorization'] = "Bearer " . $new_token; - continue; - } else { - Log::error("Failed to refresh token"); - return $this->resError("Failed to refresh token"); - } - } - } - - // Success case, break loop - break; - } - - $tasks = $response->original['data']['data'] ?? []; - - if (empty($tasks)) { - Log::warning("No data found on page", ['page' => $currentPage]); - continue; - } - - $tasksCollective = []; - foreach ($tasks as $item) { - try { - $tasksCollective[] = [ - 'uuid' => $item['uid'], - 'name' => $item['name'], - 'owner_name' => $item['owner_name'], - 'application_type' => $item['application_type'], - 'application_type_name' => $item['application_type_name'], - 'condition' => $item['condition'], - 'registration_number' => $item['registration_number'], - 'document_number' => $item['document_number'], - 'address' => $item['address'], - 'status' => $item['status'], - 'status_name' => $item['status_name'], - 'slf_status' => $item['slf_status'] ?? null, - 'slf_status_name' => $item['slf_status_name'] ?? null, - 'function_type' => $item['function_type'], - 'consultation_type' => $item['consultation_type'], - 'due_date' => $item['due_date'], - 'land_certificate_phase' => $item['land_certificate_phase'], - 'task_created_at' => isset($item['created_at']) ? Carbon::parse($item['created_at'])->format('Y-m-d H:i:s') : null, - 'updated_at' => now(), - 'created_at' => now(), - ]; - - $this->syncTaskDetailSubmit($item['uid'], $apiToken); - $this->syncTaskAssignments($item['uid']); - $savedCount++; - } catch (Exception $e) { - $failedCount++; - Log::error("Failed to process task", [ - 'error' => $e->getMessage(), - 'task' => $item, - ]); - continue; // Skip failed task, continue processing the rest - } - } - - if (!empty($tasksCollective)) { - PbgTask::upsert($tasksCollective, ['uuid'], [ - 'name', 'owner_name', 'application_type', 'application_type_name', 'condition', - 'registration_number', 'document_number', 'address', 'status', 'status_name', - 'slf_status', 'slf_status_name', 'function_type', 'consultation_type', 'due_date', - 'land_certificate_phase', 'task_created_at', 'updated_at' - ]); - - $uuids = array_column($tasksCollective, 'uuid'); - $this->syncIndexIntegration($uuids); - } - } catch (Exception $e) { - Log::error("Failed to process page", [ - 'error' => $e->getMessage(), - 'page' => $currentPage, - ]); - continue; // Skip the failed page and move to the next - } - } - - BigdataResume::generateResumeData($importDatasource->id, date('Y'), "simbg"); - - // Final update after processing all pages - $importDatasource->update([ - 'status' => ImportDatasourceStatus::Success->value, - 'message' => "Successfully processed: $savedCount, Failed: $failedCount" - ]); - - Log::info("syncTaskList completed", ['savedCount' => $savedCount, 'failedCount' => $failedCount]); - - return $this->resSuccess(['savedCount' => $savedCount, 'failedCount' => $failedCount]); - - } catch (Exception $e) { - Log::error("syncTaskList failed", ['error' => $e->getMessage()]); - if (isset($importDatasource)) { - $importDatasource->update([ - 'status' => ImportDatasourceStatus::Failed->value, - 'response_body' => 'Critical failure: ' . $e->getMessage() - ]); - } - return $this->resError("Critical failure occurred: " . $e->getMessage()); - } - } - - public function syncTaskDetailSubmit($uuid, $token) - { - try{ - $url = "/api/pbg/v1/detail/" . $uuid . "/retribution/submit/"; - - $headers = [ - 'Authorization' => "Bearer " . $token, - ]; - - for ($attempt = 0; $attempt < 2; $attempt++) { - $res = $this->service_client->get($url, $headers); - - // Check if response is JsonResponse and decode it - if ($res instanceof \Illuminate\Http\JsonResponse) { - $decodedResponse = json_decode($res->getContent(), true); - - if (isset($decodedResponse['errors']['code']) && $decodedResponse['errors']['code'] === 'token_not_valid') { - $initResToken = $this->getToken(); - - if (!empty($initResToken->original['data']['token']['access'])) { - $new_token = $initResToken->original['data']['token']['access']; - - $headers['Authorization'] = "Bearer " . $new_token; - continue; - } else { - Log::error("Failed to refresh token"); - return $this->resError("Failed to refresh token"); - } - } - } - - break; - } - - // Ensure response is valid before accessing properties - $responseData = $res->original ?? []; - $data = $responseData['data']['data'] ?? []; - if (empty($data)) { - return false; - } - - $detailCreatedAt = isset($data['created_at']) - ? Carbon::parse($data['created_at'])->format('Y-m-d H:i:s') - : null; - - $detailUpdatedAt = isset($data['updated_at']) - ? Carbon::parse($data['updated_at'])->format('Y-m-d H:i:s') - : null; - - $pbg_task_retributions = PbgTaskRetributions::updateOrCreate( - ['detail_id' => $data['id']], - [ - 'detail_uid' => $data['uid'] ?? null, - 'detail_created_at' => $detailCreatedAt ?? null, - 'detail_updated_at' => $detailUpdatedAt ?? null, - 'luas_bangunan' => $data['luas_bangunan'] ?? null, - 'indeks_lokalitas' => $data['indeks_lokalitas'] ?? null, - 'wilayah_shst' => $data['wilayah_shst'] ?? null, - 'kegiatan_id' => $data['kegiatan']['id'] ?? null, - 'kegiatan_name' => $data['kegiatan']['name'] ?? null, - 'nilai_shst' => $data['nilai_shst'] ?? null, - 'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null, - 'indeks_bg_terbangun' => $data['indeks_bg_terbangun'] ?? null, - 'nilai_retribusi_bangunan' => $data['nilai_retribusi_bangunan'] ?? null, - 'nilai_prasarana' => $data['nilai_prasarana'] ?? null, - 'created_by' => $data['created_by'] ?? null, - 'pbg_document' => $data['pbg_document'] ?? null, - 'underpayment' => $data['underpayment'] ?? null, - 'skrd_amount' => $data['skrd_amount'] ?? null, - 'pbg_task_uid' => $uuid, - ] - ); - - $pbg_task_retribution_id = $pbg_task_retributions->id; - - $prasaranaData = $data['prasarana'] ?? []; - if (!empty($prasaranaData)) { - $insertData = array_map(fn($item) => [ - 'pbg_task_uid' => $uuid, - 'pbg_task_retribution_id' => $pbg_task_retribution_id, - 'prasarana_id' => $item['id'] ?? null, - 'prasarana_type' => $item['prasarana_type'] ?? null, - 'building_type' => $item['building_type'] ?? null, - 'total' => $item['total'] ?? null, - 'quantity' => $item['quantity'] ?? null, - 'unit' => $item['unit'] ?? null, - 'index_prasarana' => $item['index_prasarana'] ?? null, - ], $prasaranaData); - - // Use bulk insert or upsert for faster database operation - PbgTaskPrasarana::upsert($insertData, ['prasarana_id']); - } - return true; - - }catch(Exception $e){ - Log::error("Failed to sync task detail submit", ['error' => $e->getMessage(), 'uuid' => $uuid]); - throw $e; - } - } - - public function syncTaskAssignments($uuid){ - try{ - $init_token = $this->getToken(); - $token = $init_token->original['data']['token']['access']; - $url = "/api/pbg/v1/list-tim-penilai/". $uuid . "/?page=1&size=10"; - $headers = [ - 'Authorization' => "Bearer " . $token, - ]; - - $response = $this->service_client->get($url, $headers); - $datas = $response->original['data']['data'] ?? []; - if(empty($datas)){ - return false; - } - $task_assignments = []; - - foreach ($datas as $data) { - $task_assignments[] = [ - 'pbg_task_uid' => $uuid, - 'user_id' => $data['user_id'], - 'name' => $data['name'], - 'username' => $data['username'], - 'email' => $data['email'], - 'phone_number' => $data['phone_number'], - 'role' => $data['role'], - 'role_name' => $data['role_name'], - 'is_active' => $data['is_active'], - 'file' => !empty($data['file']) ? json_encode($data['file']) : null, - 'expertise' => !empty($data['expertise']) ? json_encode($data['expertise']) : null, - 'experience' => !empty($data['experience']) ? json_encode($data['experience']) : null, - 'is_verif' => $data['is_verif'], - 'uid' => $data['uid'], - 'status' => $data['status'], - 'status_name' => $data['status_name'], - 'note' => $data['note'], - 'ta_id' => $data['id'], - 'created_at' => now(), - 'updated_at' => now(), - ]; - } - TaskAssignment::upsert( - $task_assignments, - ['uid'], - ['ta_id','name', 'username', 'email', 'phone_number', 'role', 'role_name', 'is_active', 'file', 'expertise', 'experience', 'is_verif', 'status', 'status_name', 'note', 'updated_at'] - ); - return true; - }catch(Exception $e){ - Log::error("Failed to sync task assignments", ['error' => $e->getMessage()]); - throw $e; - } - } - - protected function convertToDecimal(?string $value): ?float - { - if (empty($value)) { - return null; // Return null if the input is empty - } - - // Remove all non-numeric characters except comma and dot - $value = preg_replace('/[^0-9,\.]/', '', $value); - - // If the number contains both dot (.) and comma (,) - if (strpos($value, '.') !== false && strpos($value, ',') !== false) { - $value = str_replace('.', '', $value); // Remove thousands separator - $value = str_replace(',', '.', $value); // Convert decimal separator to dot - } - // If only a dot is present (assumed as thousands separator) - elseif (strpos($value, '.') !== false) { - $value = str_replace('.', '', $value); // Remove all dots (treat as thousands separators) - } - // If only a comma is present (assumed as decimal separator) - elseif (strpos($value, ',') !== false) { - $value = str_replace(',', '.', $value); // Convert comma to dot (decimal separator) - } - - // Ensure the value is numeric before returning - return is_numeric($value) ? (float) number_format((float) $value, 2, '.', '') : null; - } - - protected function convertToInteger($value) { - // Check if the value is an empty string, and return null if true - if (trim($value) === "") { - return null; - } - - $cleaned = str_replace('.','', $value); - - // Otherwise, cast to integer - return (int) $cleaned; - } - - protected function convertToDate($dateString) - { - try { - // Check if the string is empty - if (empty($dateString)) { - return null; - } - - // Try to parse the date string - $date = Carbon::parse($dateString); - - // Return the Carbon instance - return $date->format('Y-m-d'); - } catch (Exception $e) { - // Return null if an error occurs during parsing - return null; - } - } - - private function cleanString($value) - { - return isset($value) ? trim(strip_tags($value)) : null; - } -} \ No newline at end of file diff --git a/app/Services/ServiceTabPbgTask.php b/app/Services/ServiceTabPbgTask.php index 5a996de..5930066 100644 --- a/app/Services/ServiceTabPbgTask.php +++ b/app/Services/ServiceTabPbgTask.php @@ -246,8 +246,6 @@ class ServiceTabPbgTask $data = $responseData['data']; - Log::info("Executed uid : {$uuid}"); - // Use the static method from PbgTaskDetail model to create/update PbgStatus::createOrUpdateFromApi($data, $uuid); diff --git a/resources/js/settings/syncronize/syncronize.js b/resources/js/settings/syncronize/syncronize.js index 46db360..02f3ea5 100644 --- a/resources/js/settings/syncronize/syncronize.js +++ b/resources/js/settings/syncronize/syncronize.js @@ -216,7 +216,9 @@ class SyncronizeTask { }) .then((data) => { this.toastMessage.innerText = - data.data.message || "Synchronize successfully!"; + data?.data?.message || + data?.message || + "Synchronize successfully!"; this.toast.show(); // Update the table if it exists diff --git a/routes/api.php b/routes/api.php index 243a644..3b31e75 100644 --- a/routes/api.php +++ b/routes/api.php @@ -79,7 +79,6 @@ Route::group(['middleware' => 'auth:sanctum'], function (){ Route::get('/scraping','index')->name('scraping'); Route::get('/retry-scraping/{id}','retry_syncjob')->name('retry-scraping'); }); - // Route::apiResource('/scraping', ScrapingController::class); // reklame Route::apiResource('advertisements', AdvertisementController::class); @@ -118,11 +117,6 @@ Route::group(['middleware' => 'auth:sanctum'], function (){ // sync pbg google sheet Route::apiResource('/api-google-sheet', GoogleSheetController::class); - Route::get('/sync-task', [SyncronizeController::class, 'syncPbgTask'])->name('api.task'); - Route::get('/get-user-token', [SyncronizeController::class, 'getUserToken'])->name('api.task.token'); - Route::get('/get-index-integration-retribution/{uuid}', [SyncronizeController::class, 'syncIndexIntegration'])->name('api.task.inntegration'); - Route::get('/sync-task-submit/{uuid}', [SyncronizeController::class, 'syncTaskDetailSubmit'])->name('api.task.submit'); - Route::get('/sync-task-assignments/{uuid}', [SyncronizeController::class, 'syncTaskAssignments'])->name('api.task.assignments'); // menus api Route::controller(MenusController::class)->group(function (){ diff --git a/routes/console.php b/routes/console.php index 64ea3bc..b07e33e 100644 --- a/routes/console.php +++ b/routes/console.php @@ -8,6 +8,5 @@ Artisan::command('inspire', function () { $this->comment(Inspiring::quote()); })->purpose('Display an inspiring quote')->hourly(); -// Schedule::command("app:scraping-leader-data")->dailyAt("00:00"); Schedule::command("app:start-scraping-data --confirm")->dailyAt("00:00");