fix pbg payments
This commit is contained in:
@@ -22,3 +22,20 @@ BigdataResume::generateResumeData(253,2025,"simbg");
|
|||||||
exit
|
exit
|
||||||
BigdataResume::generateResumeData(253,2025,"simbg");
|
BigdataResume::generateResumeData(253,2025,"simbg");
|
||||||
exit
|
exit
|
||||||
|
$importDatasource = \App\Models\ImportDatasource::create([
|
||||||
|
'message' => 'Testing BigdataResume Generation',
|
||||||
|
'status' => 'success',
|
||||||
|
'start_time' => now(),
|
||||||
|
'finish_time' => now()
|
||||||
|
]);
|
||||||
|
$bigdataresume = BigdataResume::generateResumeData($importDatasource->id, 2025, 'simbg');
|
||||||
|
$bigdataresume = BigdataResume::generateResumeData($importDatasource->id, 2025, 'simbg');
|
||||||
|
exit
|
||||||
|
$importDatasource = \App\Models\ImportDatasource::create([
|
||||||
|
'message' => 'Testing BigdataResume Generation',
|
||||||
|
'status' => 'success',
|
||||||
|
'start_time' => now(),
|
||||||
|
'finish_time' => now()
|
||||||
|
]);
|
||||||
|
$bigdataresume = BigdataResume::generateResumeData($importDatasource->id, 2025, 'simbg');
|
||||||
|
exit
|
||||||
|
|||||||
88
app/Console/Commands/SyncPbgTaskPayments.php
Normal file
88
app/Console/Commands/SyncPbgTaskPayments.php
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Services\ServiceGoogleSheet;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class SyncPbgTaskPayments extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'sync:pbg-payments';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Sync PBG task payments from Google Sheets REALISASI PAD';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$this->info('🚀 Starting PBG Task Payments sync...');
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$service = new ServiceGoogleSheet();
|
||||||
|
|
||||||
|
// Show progress bar
|
||||||
|
$this->info('📊 Fetching data from Google Sheets...');
|
||||||
|
$result = $service->sync_pbg_task_payments();
|
||||||
|
|
||||||
|
// Display results
|
||||||
|
$this->newLine();
|
||||||
|
$this->info('✅ Sync completed successfully!');
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
$this->table(
|
||||||
|
['Metric', 'Count'],
|
||||||
|
[
|
||||||
|
['Total rows processed', $result['total_rows']],
|
||||||
|
['Successful syncs', $result['successful_syncs']],
|
||||||
|
['Failed syncs', $result['failed_syncs']],
|
||||||
|
['Tasks not found', $result['not_found_tasks']],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Show success rate
|
||||||
|
$success_rate = $result['total_rows'] > 0
|
||||||
|
? round(($result['successful_syncs'] / $result['total_rows']) * 100, 2)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
$this->info("📈 Success rate: {$success_rate}%");
|
||||||
|
|
||||||
|
// Show errors if any
|
||||||
|
if (!empty($result['errors'])) {
|
||||||
|
$this->newLine();
|
||||||
|
$this->warn('⚠️ Errors encountered:');
|
||||||
|
foreach (array_slice($result['errors'], 0, 5) as $error) {
|
||||||
|
$this->line(" Row {$error['row']} ({$error['registration_number']}): {$error['error']}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($result['errors']) > 5) {
|
||||||
|
$remaining = count($result['errors']) - 5;
|
||||||
|
$this->line(" ... and {$remaining} more errors (check logs for details)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->newLine();
|
||||||
|
$this->info('📝 Check Laravel logs for detailed information.');
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->newLine();
|
||||||
|
$this->error('❌ Sync failed!');
|
||||||
|
$this->error('Error: ' . $e->getMessage());
|
||||||
|
|
||||||
|
return Command::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ use App\Http\Resources\BigdataResumeResource;
|
|||||||
use App\Models\BigdataResume;
|
use App\Models\BigdataResume;
|
||||||
use App\Models\DataSetting;
|
use App\Models\DataSetting;
|
||||||
use App\Models\SpatialPlanning;
|
use App\Models\SpatialPlanning;
|
||||||
|
use App\Models\PbgTaskPayment;
|
||||||
use Barryvdh\DomPDF\Facade\Pdf;
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -59,6 +60,11 @@ class BigDataResumeController extends Controller
|
|||||||
$tata_ruang = $spatialData['sum'];
|
$tata_ruang = $spatialData['sum'];
|
||||||
$tata_ruang_count = $spatialData['count'];
|
$tata_ruang_count = $spatialData['count'];
|
||||||
|
|
||||||
|
// Get real-time PBG Task Payments data
|
||||||
|
$pbgPaymentsData = $this->getPbgTaskPaymentsData();
|
||||||
|
$pbg_task_payments_sum = $pbgPaymentsData['sum'];
|
||||||
|
$pbg_task_payments_count = $pbgPaymentsData['count'];
|
||||||
|
|
||||||
$kekurangan_potensi = $target_pad - $big_data_resume->potention_sum;
|
$kekurangan_potensi = $target_pad - $big_data_resume->potention_sum;
|
||||||
|
|
||||||
// percentage kekurangan potensi
|
// percentage kekurangan potensi
|
||||||
@@ -107,6 +113,10 @@ class BigDataResumeController extends Controller
|
|||||||
$proses_dinas_teknis_percentage = $big_data_resume->verified_sum > 0 && $proses_dinas_teknis_sum >= 0
|
$proses_dinas_teknis_percentage = $big_data_resume->verified_sum > 0 && $proses_dinas_teknis_sum >= 0
|
||||||
? round(($proses_dinas_teknis_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
? round(($proses_dinas_teknis_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
|
// percentage pbg_task_payments (payments / verified)
|
||||||
|
$pbg_task_payments_percentage = $realisasi_terbit_pbg_sum > 0 && $pbg_task_payments_sum >= 0
|
||||||
|
? round(($pbg_task_payments_sum / $realisasi_terbit_pbg_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
$business_rab_count = $big_data_resume->business_rab_count;
|
$business_rab_count = $big_data_resume->business_rab_count;
|
||||||
$business_krk_count = $big_data_resume->business_krk_count;
|
$business_krk_count = $big_data_resume->business_krk_count;
|
||||||
$non_business_rab_count = $big_data_resume->non_business_rab_count;
|
$non_business_rab_count = $big_data_resume->non_business_rab_count;
|
||||||
@@ -171,7 +181,12 @@ class BigDataResumeController extends Controller
|
|||||||
'business_krk_count' => $business_krk_count,
|
'business_krk_count' => $business_krk_count,
|
||||||
'non_business_rab_count' => $non_business_rab_count,
|
'non_business_rab_count' => $non_business_rab_count,
|
||||||
'non_business_krk_count' => $non_business_krk_count,
|
'non_business_krk_count' => $non_business_krk_count,
|
||||||
'business_dlh_count' => $business_dlh_count
|
'business_dlh_count' => $business_dlh_count,
|
||||||
|
'pbg_task_payments' => [
|
||||||
|
'sum' => (float) $pbg_task_payments_sum,
|
||||||
|
'count' => $pbg_task_payments_count,
|
||||||
|
'percentage' => $pbg_task_payments_percentage
|
||||||
|
]
|
||||||
];
|
];
|
||||||
return response()->json($result);
|
return response()->json($result);
|
||||||
}catch(\Exception $e){
|
}catch(\Exception $e){
|
||||||
@@ -398,6 +413,11 @@ class BigDataResumeController extends Controller
|
|||||||
'sum' => 0,
|
'sum' => 0,
|
||||||
'count' => 0,
|
'count' => 0,
|
||||||
'percentage' => 0
|
'percentage' => 0
|
||||||
|
],
|
||||||
|
'pbg_task_payments' => [
|
||||||
|
'sum' => 0,
|
||||||
|
'count' => 0,
|
||||||
|
'percentage' => 0
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -457,4 +477,33 @@ class BigDataResumeController extends Controller
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get PBG Task Payments data from database
|
||||||
|
*/
|
||||||
|
private function getPbgTaskPaymentsData(): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Get sum and count from PbgTaskPayment model
|
||||||
|
$totalSum = PbgTaskPayment::whereYear('payment_date', date('Y'))->sum('pad_amount') ?? 0;
|
||||||
|
$totalCount = PbgTaskPayment::whereYear('payment_date', date('Y'))->count() ?? 0;
|
||||||
|
|
||||||
|
Log::info("Real-time PBG Task Payments Data", [
|
||||||
|
'total_records' => $totalCount,
|
||||||
|
'total_sum' => $totalSum,
|
||||||
|
'source' => 'pbg_task_payments table'
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'sum' => (float) $totalSum,
|
||||||
|
'count' => (int) $totalCount,
|
||||||
|
];
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error("Error getting PBG task payments data", ['error' => $e->getMessage()]);
|
||||||
|
return [
|
||||||
|
'sum' => 0.0,
|
||||||
|
'count' => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,20 +314,19 @@ class BigdataResume extends Model
|
|||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Get sum values using proper aggregation to handle multiple retributions
|
// Calculate totals using count-based formula
|
||||||
|
// Business: $business_count * 200 * 44300
|
||||||
|
// Non-Business: $non_business_count * 72 * 16000
|
||||||
|
$business_total = $business_count * 200 * 44300;
|
||||||
|
$non_business_total = $non_business_count * 72 * 16000;
|
||||||
|
$non_verified_total = $business_total + $non_business_total;
|
||||||
|
|
||||||
|
// Get other sum values using proper aggregation to handle multiple retributions
|
||||||
$stats = PbgTask::leftJoin('pbg_task_retributions as ptr', 'pbg_task.uuid', '=', 'ptr.pbg_task_uid')
|
$stats = PbgTask::leftJoin('pbg_task_retributions as ptr', 'pbg_task.uuid', '=', 'ptr.pbg_task_uid')
|
||||||
->where('pbg_task.is_valid', true)
|
->where('pbg_task.is_valid', true)
|
||||||
->whereYear('pbg_task.task_created_at', $year)
|
->whereYear('pbg_task.task_created_at', $year)
|
||||||
->selectRaw("
|
->selectRaw("
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getVerified()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS verified_total,
|
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getVerified()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS verified_total,
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS non_verified_total,
|
|
||||||
SUM(CASE WHEN (LOWER(TRIM(pbg_task.function_type)) LIKE '%fungsi usaha%'
|
|
||||||
OR LOWER(TRIM(pbg_task.function_type)) LIKE '%sebagai tempat usaha%')
|
|
||||||
AND pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS business_total,
|
|
||||||
SUM(CASE WHEN (LOWER(TRIM(pbg_task.function_type)) NOT LIKE '%fungsi usaha%'
|
|
||||||
AND LOWER(TRIM(pbg_task.function_type)) NOT LIKE '%sebagai tempat usaha%'
|
|
||||||
AND pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified())."))
|
|
||||||
OR (pbg_task.function_type IS NULL AND pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).")) THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS non_business_total,
|
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getWaitingClickDpmptsp()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS waiting_click_dpmptsp_total,
|
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getWaitingClickDpmptsp()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS waiting_click_dpmptsp_total,
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getIssuanceRealizationPbg()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS issuance_realization_pbg_total,
|
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getIssuanceRealizationPbg()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS issuance_realization_pbg_total,
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getProcessInTechnicalOffice()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS process_in_technical_office_total,
|
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getProcessInTechnicalOffice()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS process_in_technical_office_total,
|
||||||
@@ -338,7 +337,11 @@ class BigdataResume extends Model
|
|||||||
->first();
|
->first();
|
||||||
|
|
||||||
\Log::info('Stats calculation result', [
|
\Log::info('Stats calculation result', [
|
||||||
'non_verified_total' => $stats->non_verified_total ?? 'NULL',
|
'business_count' => $business_count,
|
||||||
|
'non_business_count' => $non_business_count,
|
||||||
|
'business_total' => $business_total,
|
||||||
|
'non_business_total' => $non_business_total,
|
||||||
|
'non_verified_total' => $non_verified_total,
|
||||||
'non_verified_tasks_count' => $stats->non_verified_tasks_count ?? 'NULL',
|
'non_verified_tasks_count' => $stats->non_verified_tasks_count ?? 'NULL',
|
||||||
'non_verified_with_retribution_count' => $stats->non_verified_with_retribution_count ?? 'NULL'
|
'non_verified_with_retribution_count' => $stats->non_verified_with_retribution_count ?? 'NULL'
|
||||||
]);
|
]);
|
||||||
@@ -352,13 +355,13 @@ class BigdataResume extends Model
|
|||||||
'potention_count' => $potention_count,
|
'potention_count' => $potention_count,
|
||||||
'potention_sum' => ($stats->potention_total ?? 0),
|
'potention_sum' => ($stats->potention_total ?? 0),
|
||||||
'non_verified_count' => $non_verified_count,
|
'non_verified_count' => $non_verified_count,
|
||||||
'non_verified_sum' => $stats->non_verified_total ?? 0.00,
|
'non_verified_sum' => $non_verified_total,
|
||||||
'verified_count' => $verified_count,
|
'verified_count' => $verified_count,
|
||||||
'verified_sum' => $stats->verified_total ?? 0.00,
|
'verified_sum' => $stats->verified_total ?? 0.00,
|
||||||
'business_count' => $business_count,
|
'business_count' => $business_count,
|
||||||
'business_sum' => $stats->business_total ?? 0.00,
|
'business_sum' => $business_total,
|
||||||
'non_business_count' => $non_business_count,
|
'non_business_count' => $non_business_count,
|
||||||
'non_business_sum' => $stats->non_business_total ?? 0.00,
|
'non_business_sum' => $non_business_total,
|
||||||
'year' => $year,
|
'year' => $year,
|
||||||
'waiting_click_dpmptsp_count' => $waiting_click_dpmptsp_count,
|
'waiting_click_dpmptsp_count' => $waiting_click_dpmptsp_count,
|
||||||
'waiting_click_dpmptsp_sum' => $stats->waiting_click_dpmptsp_total ?? 0.00,
|
'waiting_click_dpmptsp_sum' => $stats->waiting_click_dpmptsp_total ?? 0.00,
|
||||||
|
|||||||
72
app/Models/PbgTaskPayment.php
Normal file
72
app/Models/PbgTaskPayment.php
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
class PbgTaskPayment extends Model
|
||||||
|
{
|
||||||
|
protected $fillable = [
|
||||||
|
'pbg_task_id',
|
||||||
|
'pbg_task_uid',
|
||||||
|
'registration_number',
|
||||||
|
'sts_form_number',
|
||||||
|
'payment_date',
|
||||||
|
'pad_amount'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'payment_date' => 'date',
|
||||||
|
'pad_amount' => 'decimal:2'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the PBG task that owns this payment
|
||||||
|
*/
|
||||||
|
public function pbgTask(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(PbgTask::class, 'pbg_task_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean and convert registration number for matching
|
||||||
|
*/
|
||||||
|
public static function cleanRegistrationNumber(string $registrationNumber): string
|
||||||
|
{
|
||||||
|
return trim($registrationNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert pad amount string to decimal
|
||||||
|
*/
|
||||||
|
public static function convertPadAmount(?string $padAmount): float
|
||||||
|
{
|
||||||
|
if (empty($padAmount)) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove dots (thousands separator) and convert to float
|
||||||
|
$cleaned = str_replace('.', '', $padAmount);
|
||||||
|
$cleaned = str_replace(',', '.', $cleaned); // Handle comma as decimal separator if present
|
||||||
|
|
||||||
|
return is_numeric($cleaned) ? (float) $cleaned : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert date string to proper format
|
||||||
|
*/
|
||||||
|
public static function convertPaymentDate(?string $dateString): ?string
|
||||||
|
{
|
||||||
|
if (empty($dateString)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Carbon::parse($dateString)->format('Y-m-d');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -427,6 +427,203 @@ class ServiceGoogleSheet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function get_realisasi_pad_data(){
|
||||||
|
try {
|
||||||
|
// Get data from "REALISASI PAD" sheet
|
||||||
|
$sheet_data = $this->get_data_by_sheet_name("REALISASI PAD");
|
||||||
|
|
||||||
|
if (empty($sheet_data)) {
|
||||||
|
Log::warning("No data found in REALISASI PAD sheet");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Column indices: C=2, AK=36, AL=37, AW=48 (0-based)
|
||||||
|
$columns = [
|
||||||
|
'C' => 2,
|
||||||
|
'AK' => 36,
|
||||||
|
'AL' => 37,
|
||||||
|
'AW' => 48
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'headers' => [],
|
||||||
|
'data' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($sheet_data as $row_index => $row) {
|
||||||
|
if (!is_array($row)) continue;
|
||||||
|
|
||||||
|
if ($row_index === 0) {
|
||||||
|
// First row contains headers
|
||||||
|
foreach ($columns as $column_name => $column_index) {
|
||||||
|
$result['headers'][$column_name] = isset($row[$column_index]) ? trim($row[$column_index]) : '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Data rows
|
||||||
|
$row_data = [
|
||||||
|
'row' => $row_index + 1 // 1-based row number
|
||||||
|
];
|
||||||
|
|
||||||
|
$has_data = false;
|
||||||
|
foreach ($columns as $column_name => $column_index) {
|
||||||
|
$value = isset($row[$column_index]) ? trim($row[$column_index]) : '';
|
||||||
|
$row_data[$column_name] = $value;
|
||||||
|
if ($value !== '') {
|
||||||
|
$has_data = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only add row if it has at least one non-empty value
|
||||||
|
if ($has_data) {
|
||||||
|
$result['data'][] = $row_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info("REALISASI PAD Multiple Columns Data", [
|
||||||
|
'sheet_name' => 'REALISASI PAD',
|
||||||
|
'columns' => array_keys($columns),
|
||||||
|
'headers' => $result['headers'],
|
||||||
|
'total_data_rows' => count($result['data']),
|
||||||
|
'sample_data' => array_slice($result['data'], 0, 5), // Show first 5 rows as sample
|
||||||
|
'column_indices' => $columns
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error("Error getting REALISASI PAD data", ['error' => $e->getMessage()]);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sync_pbg_task_payments(){
|
||||||
|
try {
|
||||||
|
// Get payment data from REALISASI PAD sheet
|
||||||
|
$payment_data = $this->get_realisasi_pad_data();
|
||||||
|
|
||||||
|
if (empty($payment_data['data'])) {
|
||||||
|
Log::warning("No payment data found to sync");
|
||||||
|
return ['success' => false, 'message' => 'No payment data found'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$successful_syncs = 0;
|
||||||
|
$failed_syncs = 0;
|
||||||
|
$not_found_tasks = 0;
|
||||||
|
$not_found_tasks_registration_number = [];
|
||||||
|
$failed_sync_registration_numbers = [];
|
||||||
|
$errors = [];
|
||||||
|
|
||||||
|
foreach ($payment_data['data'] as $row) {
|
||||||
|
try {
|
||||||
|
// Clean registration number from column C
|
||||||
|
$registration_number = \App\Models\PbgTaskPayment::cleanRegistrationNumber($row['C']);
|
||||||
|
|
||||||
|
if (empty($registration_number)) {
|
||||||
|
$failed_syncs++;
|
||||||
|
$failed_sync_registration_numbers[] = [
|
||||||
|
'row' => $row['row'],
|
||||||
|
'registration_number' => $row['C'] ?? 'EMPTY',
|
||||||
|
'reason' => 'Empty registration number'
|
||||||
|
];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find PBG task by registration number
|
||||||
|
$pbg_task = \App\Models\PbgTask::where('registration_number', $registration_number)->first();
|
||||||
|
|
||||||
|
if (!$pbg_task) {
|
||||||
|
$not_found_tasks_registration_number[] = [
|
||||||
|
'row' => $row['row'],
|
||||||
|
'registration_number' => $registration_number
|
||||||
|
];
|
||||||
|
$not_found_tasks++;
|
||||||
|
Log::warning("PBG Task not found for registration number", [
|
||||||
|
'registration_number' => $registration_number,
|
||||||
|
'row' => $row['row']
|
||||||
|
]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert data types
|
||||||
|
$payment_date = \App\Models\PbgTaskPayment::convertPaymentDate($row['AK']);
|
||||||
|
$pad_amount = \App\Models\PbgTaskPayment::convertPadAmount($row['AW']);
|
||||||
|
$sts_form_number = !empty($row['AL']) ? trim($row['AL']) : null;
|
||||||
|
|
||||||
|
// Create or update payment record
|
||||||
|
\App\Models\PbgTaskPayment::updateOrCreate(
|
||||||
|
[
|
||||||
|
'pbg_task_id' => $pbg_task->id,
|
||||||
|
'registration_number' => $registration_number
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'pbg_task_uid' => $pbg_task->uuid,
|
||||||
|
'sts_form_number' => $sts_form_number,
|
||||||
|
'payment_date' => $payment_date,
|
||||||
|
'pad_amount' => $pad_amount
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$successful_syncs++;
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$failed_syncs++;
|
||||||
|
$registration_number = $row['C'] ?? 'N/A';
|
||||||
|
$failed_sync_registration_numbers[] = [
|
||||||
|
'row' => $row['row'],
|
||||||
|
'registration_number' => $registration_number,
|
||||||
|
'reason' => $e->getMessage()
|
||||||
|
];
|
||||||
|
$errors[] = [
|
||||||
|
'row' => $row['row'],
|
||||||
|
'registration_number' => $registration_number,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
];
|
||||||
|
|
||||||
|
Log::error("Error syncing payment data for row", [
|
||||||
|
'row' => $row['row'],
|
||||||
|
'registration_number' => $registration_number,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'success' => true,
|
||||||
|
'total_rows' => count($payment_data['data']),
|
||||||
|
'successful_syncs' => $successful_syncs,
|
||||||
|
'failed_syncs' => $failed_syncs,
|
||||||
|
'not_found_tasks' => $not_found_tasks,
|
||||||
|
'not_found_tasks_registration_number' => $not_found_tasks_registration_number,
|
||||||
|
'failed_sync_registration_numbers' => $failed_sync_registration_numbers,
|
||||||
|
'errors' => $errors
|
||||||
|
];
|
||||||
|
|
||||||
|
Log::info("PBG Task Payments sync completed", $result);
|
||||||
|
|
||||||
|
// Log detailed arrays for failed syncs and not found registration numbers
|
||||||
|
if (!empty($failed_sync_registration_numbers)) {
|
||||||
|
Log::warning("Failed Sync Registration Numbers", [
|
||||||
|
'count' => count($failed_sync_registration_numbers),
|
||||||
|
'details' => $failed_sync_registration_numbers
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($not_found_tasks_registration_number)) {
|
||||||
|
Log::warning("Not Found Registration Numbers", [
|
||||||
|
'count' => count($not_found_tasks_registration_number),
|
||||||
|
'details' => $not_found_tasks_registration_number
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error("Error syncing PBG task payments", ['error' => $e->getMessage()]);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function get_data_by_sheet($no_sheet = 8){
|
private function get_data_by_sheet($no_sheet = 8){
|
||||||
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
|
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
|
||||||
$sheets = $spreadsheet->getSheets();
|
$sheets = $spreadsheet->getSheets();
|
||||||
@@ -437,6 +634,45 @@ class ServiceGoogleSheet
|
|||||||
return!empty($values)? $values : [];
|
return!empty($values)? $values : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function get_data_by_sheet_name($sheet_name){
|
||||||
|
try {
|
||||||
|
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
|
||||||
|
$sheets = $spreadsheet->getSheets();
|
||||||
|
|
||||||
|
// Find sheet by name
|
||||||
|
$targetSheet = null;
|
||||||
|
foreach ($sheets as $sheet) {
|
||||||
|
if ($sheet->getProperties()->getTitle() === $sheet_name) {
|
||||||
|
$targetSheet = $sheet;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$targetSheet) {
|
||||||
|
Log::warning("Sheet not found", ['sheet_name' => $sheet_name]);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$range = "{$sheet_name}";
|
||||||
|
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
|
||||||
|
$values = $response->getValues();
|
||||||
|
|
||||||
|
Log::info("Sheet data retrieved", [
|
||||||
|
'sheet_name' => $sheet_name,
|
||||||
|
'total_rows' => count($values ?? [])
|
||||||
|
]);
|
||||||
|
|
||||||
|
return !empty($values) ? $values : [];
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error("Error getting data by sheet name", [
|
||||||
|
'sheet_name' => $sheet_name,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get specific values from a row that contains a specific text/section identifier
|
* Get specific values from a row that contains a specific text/section identifier
|
||||||
* @param string $section_identifier Text to search for in the row
|
* @param string $section_identifier Text to search for in the row
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('pbg_task_payments', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('pbg_task_id')->constrained('pbg_task', 'id')->onDelete('cascade');
|
||||||
|
$table->string('pbg_task_uid');
|
||||||
|
$table->string('registration_number');
|
||||||
|
$table->string('sts_form_number')->nullable();
|
||||||
|
$table->date('payment_date')->nullable();
|
||||||
|
$table->decimal('pad_amount', 12, 2)->default(0);
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
// Add index for better performance
|
||||||
|
$table->index('pbg_task_id');
|
||||||
|
$table->index('pbg_task_uid');
|
||||||
|
$table->index('registration_number');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('pbg_task_payments');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -535,9 +535,7 @@ class BigData {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartNonBusinessDLH() {
|
initChartNonBusinessDLH() {
|
||||||
document
|
document.querySelectorAll("#business-dlh-count").forEach((element) => {
|
||||||
.querySelectorAll("#non-business-dlh-count")
|
|
||||||
.forEach((element) => {
|
|
||||||
const count = this.safeGet(
|
const count = this.safeGet(
|
||||||
this.resumeBigData,
|
this.resumeBigData,
|
||||||
"business_dlh_count",
|
"business_dlh_count",
|
||||||
@@ -546,6 +544,41 @@ class BigData {
|
|||||||
element.innerText = `${count}`;
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initChartPotensiTataRuang() {
|
||||||
|
document
|
||||||
|
.querySelectorAll(".document-count.chart-payment-pbg-task")
|
||||||
|
.forEach((element) => {
|
||||||
|
const count = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"pbg_task_payments.count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
|
});
|
||||||
|
document
|
||||||
|
.querySelectorAll(".document-total.chart-payment-pbg-task")
|
||||||
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"pbg_task_payments.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
|
sum.toString()
|
||||||
|
)}`;
|
||||||
|
});
|
||||||
|
document
|
||||||
|
.querySelectorAll(".small-percentage.chart-payment-pbg-task")
|
||||||
|
.forEach((element) => {
|
||||||
|
const percentage = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"pbg_task_payments.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", async function (e) {
|
document.addEventListener("DOMContentLoaded", async function (e) {
|
||||||
|
|||||||
@@ -202,6 +202,17 @@
|
|||||||
])
|
])
|
||||||
@endcomponent
|
@endcomponent
|
||||||
|
|
||||||
|
@component('components.circle',[
|
||||||
|
'document_title' => 'Pembayaran Realisasi PBG',
|
||||||
|
'document_color' => '#8cc540',
|
||||||
|
'document_type' => 'Berkas',
|
||||||
|
'document_id' => 'chart-payment-pbg-task',
|
||||||
|
'visible_small_circle' => false,
|
||||||
|
'style' => 'top:550px;left:-150px;',
|
||||||
|
'document_url' => '#'
|
||||||
|
])
|
||||||
|
@endcomponent
|
||||||
|
|
||||||
<div class="square" style="top:650px;left:200px;width:250px;height:2px;background-color:black;">
|
<div class="square" style="top:650px;left:200px;width:250px;height:2px;background-color:black;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user