fix handle null on scraping google sheet data and add detail data building

This commit is contained in:
arifal
2025-06-23 13:54:26 +07:00
parent ccff82bd22
commit 200b398868
6 changed files with 160 additions and 129 deletions

View File

@@ -1,40 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Jobs\SyncronizeSIMBG;
use App\Services\ServiceSIMBG;
use Illuminate\Console\Command;
use \Illuminate\Support\Facades\Log;
class ExecuteScraping extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:execute-scraping';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Execure scraping service daily every 12 pm';
/**
* Execute the console command.
*/
private $service_simbg;
public function __construct(){
parent::__construct();
}
public function handle()
{
SyncronizeSIMBG::dispatch()->onQueue('default');
Log::info("running scheduler daily scraping");
}
}

View File

@@ -56,7 +56,7 @@ class PbgTaskController extends Controller
*/
public function show(string $id)
{
$data = PbgTask::with(['pbg_task_retributions','pbg_task_index_integrations', 'pbg_task_retributions.pbg_task_prasarana'])->findOrFail($id);
$data = PbgTask::with(['pbg_task_retributions','pbg_task_index_integrations', 'pbg_task_retributions.pbg_task_prasarana', 'pbg_task_detail'])->findOrFail($id);
$statusOptions = PbgTaskStatus::getStatuses();
$applicationTypes = PbgTaskApplicationTypes::labels();
return view("pbg_task.show", compact("data", 'statusOptions', 'applicationTypes'));

View File

@@ -32,6 +32,7 @@ class ScrapingDataJob implements ShouldQueue
*/
public function handle()
{
$failed_uuid = null;
try {
$client = app(Client::class);
@@ -48,8 +49,6 @@ class ScrapingDataJob implements ShouldQueue
'failed_uuid' => null
]);
$failed_uuid = null;
// Run the scraping services
$service_google_sheet->run_service();
$service_pbg_task->run_service();
@@ -79,6 +78,7 @@ class ScrapingDataJob implements ShouldQueue
if (isset($import_datasource)) {
$import_datasource->update([
'status' => 'failed',
'message' => 'Terjadi kesalahan, Syncronize tidak selesai',
'response_body' => 'Terjadi kesalahan, Syncronize tidak selesai',
'finish_time' => now(),
'failed_uuid' => $failed_uuid,

View File

@@ -1,80 +0,0 @@
<?php
namespace App\Jobs;
use App\Models\ImportDatasource;
use App\Services\GoogleSheetService;
use App\Services\ServiceGoogleSheet;
use App\Services\ServicePbgTask;
use App\Services\ServiceTabPbgTask;
use GuzzleHttp\Client;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SyncronizeSIMBG implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 1;
public function __construct()
{
// Avoid injecting non-serializable dependencies here
}
public function handle(): void
{
$import_datasource = ImportDatasource::where('status', 'processing')->first();
if (!$import_datasource) {
$import_datasource = ImportDatasource::create([
'message' => 'Initiating scraping...',
'response_body' => null,
'status' => 'processing'
]);
}
try {
// Create an instance of GuzzleHttp\Client inside handle()
$client = new Client();
// Create instances of services inside handle()
$service_pbg_task = app(ServicePbgTask::class);
$service_tab_pbg_task = app(ServiceTabPbgTask::class);
// Create a record with "processing" status
// Run the service
$service_google_sheet = new ServiceGoogleSheet();
\Log::info('Starting Google Sheet service');
$service_google_sheet->run_service();
\Log::info('Google Sheet service completed');
\Log::info('Starting PBG Task service');
$service_pbg_task->run_service();
\Log::info('PBG Task service completed');
\Log::info('Starting Tab PBG Task service');
$service_tab_pbg_task->run_service();
\Log::info('Tab PBG Task service completed');
// Update the record status to "success" after completion
$import_datasource->update([
'status' => 'success',
'message' => 'Scraping completed successfully.'
]);
} catch (\Exception $e) {
\Log::error("SyncronizeSIMBG Job Failed: " . $e->getMessage(), [
'exception' => $e,
]);
$import_datasource->update([
'status' => 'failed',
'message' => 'Failed job'
]);
$this->fail($e); // Mark the job as failed
}
}
}

View File

@@ -36,7 +36,7 @@ class ServiceGoogleSheet
public function run_service(){
try{
$this->sync_big_data();
// $this->sync_big_data();
$this->sync_google_sheet_data();
}catch(Exception $e){
throw $e;
@@ -135,7 +135,11 @@ class ServiceGoogleSheet
}
// Count occurrences of each no_registrasi
$registrasiCounts = array_count_values(array_column($mapUpsert, 'no_registrasi'));
// Filter out null values before counting to avoid array_count_values error
$registrationNumbers = array_filter(array_column($mapUpsert, 'no_registrasi'), function($value) {
return $value !== null && $value !== '';
});
$registrasiCounts = array_count_values($registrationNumbers);
// Filter duplicates (those appearing more than once)
$duplicates = array_filter($registrasiCounts, function ($count) {
@@ -146,8 +150,14 @@ class ServiceGoogleSheet
Log::warning("Duplicate no_registrasi found", ['duplicates' => array_keys($duplicates)]);
}
// Remove duplicates before upsert
$mapUpsert = collect($mapUpsert)->unique('no_registrasi')->values()->all();
// Remove duplicates before upsert - filter out entries with null no_registrasi
$mapUpsert = collect($mapUpsert)
->filter(function($item) {
return !empty($item['no_registrasi']);
})
->unique('no_registrasi')
->values()
->all();
$batchSize = 1000;
$chunks = array_chunk($mapUpsert, $batchSize);
@@ -200,9 +210,19 @@ class ServiceGoogleSheet
}
foreach ($data_setting_result as $key => $value) {
// Ensure value is not null before saving to database
$processedValue = 0; // Default to 0 instead of null
if ($value !== null && $value !== '') {
if (strpos($key, '_COUNT') !== false) {
$processedValue = $this->convertToInteger($value) ?? 0;
} else {
$processedValue = $this->convertToDecimal($value) ?? 0;
}
}
DataSetting::updateOrInsert(
["key" => $key], // Find by key
["value" => $value] // Update or insert value
["value" => $processedValue] // Update or insert value
);
}
@@ -294,9 +314,22 @@ class ServiceGoogleSheet
];
foreach ($dataSettings as $key => $value) {
// Ensure value is not null before saving to database
$processedValue = null;
if ($value !== null && $value !== '') {
// Try to convert to appropriate type based on key name
if (strpos($key, '_COUNT') !== false) {
$processedValue = $this->convertToInteger($value) ?? 0;
} else {
$processedValue = $this->convertToDecimal($value) ?? 0;
}
} else {
$processedValue = 0; // Default to 0 instead of null
}
DataSetting::updateOrInsert(
['key' => $key],
['value' => $this->convertToInteger($value) ?? 0]
['value' => $processedValue]
);
}

View File

@@ -122,6 +122,11 @@
<span class="d-none d-sm-block">Penugasan</span>
</a>
</li>
<li class="nav-item">
<a href="#pbgTaskDetail" data-bs-toggle="tab" aria-expanded="false" class="nav-link">
<span class="d-none d-sm-block">Data Bangunan</span>
</a>
</li>
</ul>
</div>
<div class="card-body">
@@ -280,6 +285,119 @@
<input type="hidden" id="uuid" value="{{ $data->uuid }}" />
<div id="table-pbg-task-assignments"></div>
</div>
<div class="tab-pane" id="pbgTaskDetail">
@if ($data->pbg_task_detail)
<div class="row mb-3">
<div class="col-md-4">
<dt>Fungsi Bangunan</dt>
<dd>{{$data->pbg_task_detail->building_purpose}}</dd>
<dt>Jenis Prototipe</dt>
<dd>{{$data->pbg_task_detail->prototype ?? '-'}}</dd>
</div>
<div class="col-md-4">
<dt>Sub Fungsi Bangunan</dt>
<dd>{{$data->pbg_task_detail->building_use}}</dd>
</div>
<div class="col-md-4">
<dt>Nama Bangunan</dt>
<dd>{{$data->pbg_task_detail->name_building}}</dd>
</div>
</div>
<div class="row">
<div class="col-md-12">
<dt>Spesifikasi Bangunan</dt>
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-4">
<dt>Luas Bangunan</dt>
<dd>{{$data->pbg_task_detail->total_area ?? '-'}} m<sup>2</sup></dd>
<dt>Jumlah Lapis Basemen</dt>
<dd>{{$data->pbg_task_detail->basement ?? '-'}}</dd>
<dt>Estimasi Jumlah Penghuni</dt>
<dd>{{$data->pbg_task_detail->occupancy ?? '-'}}</dd>
</div>
<div class="col-md-4">
<dt>Ketinggian Bangunan</dt>
<dd>{{$data->pbg_task_detail->height ?? '-'}} m</dd>
<dt>Luas Basemen</dt>
<dd>{{$data->pbg_task_detail->basement_area ?? '-'}}</dd>
</div>
<div class="col-md-4">
<dt>Jumlah Lantai</dt>
<dd>{{$data->pbg_task_detail->floor ?? '-'}}</dd>
<dt>Jumlah Unit</dt>
<dd>{{$data->pbg_task_detail->unit ?? '-'}}</dd>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<dt>Intensitas Bangunan</dt>
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-4">
<dt>Nomor KKPR / KRK</dt>
<dd>{{$data->pbg_task_detail->kkr_number ?? '-'}}</dd>
<dt>Koefisien Lantai Bangunan (KLB)</dt>
<dd>{{$data->pbg_task_detail->koefisien_lantai_bangunan ?? '-'}}</dd>
</div>
<div class="col-md-4">
<dt>Garis Sempadan Bangunan (GSB)</dt>
<dd>{{$data->pbg_task_detail->gsb ?? '-'}}</dd>
<dt>Koefisien Dasar Hijau (KDH)</dt>
<dd>{{$data->pbg_task_detail->koefisien_dasar_hijau ?? '-'}}</dd>
</div>
<div class="col-md-4">
<dt>Koefisien Dasar Bangunan (KDB)</dt>
<dd>{{$data->pbg_task_detail->koefisien_dasar_bangunan ?? '-'}}</dd>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<dt>Lokasi Bangunan</dt>
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-4">
<dt>Provinsi</dt>
<dd>{{$data->pbg_task_detail->building_province_name ?? '-'}}</dd>
<dt>Desa / Kelurahan</dt>
<dd>{{$data->pbg_task_detail->building_ward_name ?? '-'}}</dd>
</div>
<div class="col-md-4">
<dt>Kabupaten / Kota</dt>
<dd>{{$data->pbg_task_detail->building_regency_name ?? '-'}}</dd>
<dt>Alamat Lengkap</dt>
<dd>{{$data->pbg_task_detail->building_address ?? '-'}}</dd>
</div>
<div class="col-md-4">
<dt>Kecamatan</dt>
<dd>{{$data->pbg_task_detail->building_district_name ?? '-'}}</dd>
<dt>Koordinat Latitude dan Longitude</dt>
<dd>{{$data->pbg_task_detail->latitude ?? '-'}}, {{$data->pbg_task_detail->longitude ?? '-'}}</dd>
</div>
</div>
</div>
</div>
</div>
</div>
@else
<div class="row">
<div class="col-md-12">
Data Not Available
</div>
</div>
@endif
</div>
</div>
</div>
</div>