Compare commits
88 Commits
feature/ch
...
fix/add-sy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
654d2efe19 | ||
|
|
0a080763cd | ||
|
|
f3ef21d1be | ||
|
|
d7bff86741 | ||
|
|
f36f250700 | ||
|
|
2c5da87856 | ||
|
|
a195559c4b | ||
|
|
088f173fec | ||
|
|
eadfddb3a4 | ||
|
|
47a9fb1dfb | ||
|
|
1713e32b67 | ||
|
|
cf998455e0 | ||
|
|
5e1c9f3a2e | ||
|
|
e940b8d6c7 | ||
|
|
5e139bc29c | ||
|
|
f9e1aa1604 | ||
|
|
2e385f80cd | ||
|
|
e2c26e0eff | ||
|
|
ca5b8ad403 | ||
|
|
e97b7eb70d | ||
|
|
0258ca9f04 | ||
|
|
0116147e06 | ||
|
|
7787db02a3 | ||
|
|
e47ab36d5e | ||
|
|
e5db2294b4 | ||
|
|
4db457d7bd | ||
|
|
7a82ad5302 | ||
|
|
b0d4d4c23b | ||
|
|
68ffc1c090 | ||
|
|
a1f4bd7f81 | ||
|
|
238aaba96c | ||
|
|
c7152d9dbe | ||
|
|
2a4b96d0b2 | ||
|
|
dd940ebdb6 | ||
|
|
dce5409248 | ||
|
|
b8f7d7f655 | ||
|
|
65600f1b4f | ||
|
|
b0f15a9221 | ||
|
|
bf55eb228e | ||
|
|
755720bac9 | ||
|
|
098b4c605b | ||
|
|
4632e102eb | ||
|
|
0431945a42 | ||
|
|
fbfa2a37bb | ||
|
|
c529a5d511 | ||
|
|
ff244039ff | ||
|
|
55902042f4 | ||
|
|
c67aa979c2 | ||
|
|
fbaa33ae13 | ||
|
|
9516b6f575 | ||
|
|
ffc08f26cc | ||
|
|
dceb46ab86 | ||
|
|
e0c35b8897 | ||
|
|
22ee7502ad | ||
|
|
2f3bc172eb | ||
|
|
bba932b2ba | ||
|
|
3f5d0eb1cd | ||
|
|
1f33d0de4e | ||
|
|
86d694bcac | ||
|
|
cb5a3243fc | ||
|
|
15210a56ee | ||
|
|
a08f2cb2b7 | ||
|
|
632433c496 | ||
|
|
5b4780495e | ||
|
|
0a7012a57c | ||
|
|
435a19346b | ||
|
|
8fcf8859d6 | ||
|
|
43a246d234 | ||
|
|
d6d0acf8fb | ||
|
|
b4ec7a9d25 | ||
|
|
5203babe11 | ||
|
|
c0faafdbd7 | ||
|
|
c5e3fdd915 | ||
|
|
572b86299c | ||
|
|
cdd84d02da | ||
|
|
ee1a395c75 | ||
|
|
3bfcaddba4 | ||
|
|
9ea7e96af1 | ||
|
|
e0d11af7d2 | ||
|
|
f5790cda94 | ||
|
|
f3db3783f9 | ||
|
|
101e76c0fa | ||
|
|
4cc698a623 | ||
|
|
544ad1db46 | ||
|
|
30ca819aa1 | ||
|
|
b0bab784d1 | ||
|
|
01fda22c89 | ||
|
|
de300c2c32 |
@@ -68,3 +68,4 @@ VITE_APP_NAME="${APP_NAME}"
|
|||||||
|
|
||||||
API_KEY_GOOGLE="xxxxx"
|
API_KEY_GOOGLE="xxxxx"
|
||||||
SPREAD_SHEET_ID="xxxxx"
|
SPREAD_SHEET_ID="xxxxx"
|
||||||
|
OPENAI_API_KEY="xxxxx"
|
||||||
136
README.md
136
README.md
@@ -1,66 +1,112 @@
|
|||||||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
|
# Usage icon
|
||||||
|
|
||||||
<p align="center">
|
search or pick icon in <a href="https://icon-sets.iconify.design/mingcute/?keyword=mingcute">here</a>
|
||||||
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
## About Laravel
|
# Set up queue for running automatically
|
||||||
|
|
||||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
|
- Install Supervisor
|
||||||
|
|
||||||
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
```
|
||||||
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
sudo apt update && sudo apt install supervisor -y
|
||||||
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
```
|
||||||
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
|
||||||
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
|
||||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
|
||||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
|
||||||
|
|
||||||
Laravel is accessible, powerful, and provides tools required for large, robust applications.
|
- Create Supervisor Config
|
||||||
|
|
||||||
## Learning Laravel
|
```
|
||||||
|
sudo nano /etc/supervisor/conf.d/laravel-worker.conf
|
||||||
|
|
||||||
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
|
[program:laravel-worker]
|
||||||
|
process_name=%(program_name)s_%(process_num)02d
|
||||||
|
command=php /home/arifal/development/sibedas-pbg-web/artisan queue:work --queue=default --timeout=40000 --tries=1
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
numprocs=1
|
||||||
|
redirect_stderr=true
|
||||||
|
stdout_logfile=/home/arifal/development/sibedas-pbg-web/storage/logs/worker.log
|
||||||
|
stopasgroup=true
|
||||||
|
killasgroup=true
|
||||||
|
```
|
||||||
|
|
||||||
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
|
- Reload Supervisor
|
||||||
|
|
||||||
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains thousands of video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
|
```
|
||||||
|
sudo supervisorctl reread
|
||||||
|
sudo supervisorctl update
|
||||||
|
sudo supervisorctl start laravel-worker
|
||||||
|
sudo supervisorctl restart laravel-worker
|
||||||
|
sudo supervisorctl status
|
||||||
|
```
|
||||||
|
|
||||||
## Laravel Sponsors
|
# How to running
|
||||||
|
|
||||||
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com).
|
- Install composer package
|
||||||
|
|
||||||
### Premium Partners
|
```
|
||||||
|
composer install
|
||||||
|
```
|
||||||
|
|
||||||
- **[Vehikl](https://vehikl.com/)**
|
- Install npm package
|
||||||
- **[Tighten Co.](https://tighten.co)**
|
|
||||||
- **[WebReinvent](https://webreinvent.com/)**
|
|
||||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
|
||||||
- **[64 Robots](https://64robots.com)**
|
|
||||||
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
|
|
||||||
- **[Cyber-Duck](https://cyber-duck.co.uk)**
|
|
||||||
- **[DevSquad](https://devsquad.com/hire-laravel-developers)**
|
|
||||||
- **[Jump24](https://jump24.co.uk)**
|
|
||||||
- **[Redberry](https://redberry.international/laravel/)**
|
|
||||||
- **[Active Logic](https://activelogic.com)**
|
|
||||||
- **[byte5](https://byte5.de)**
|
|
||||||
- **[OP.GG](https://op.gg)**
|
|
||||||
|
|
||||||
## Contributing
|
```
|
||||||
|
npm install && npm run build
|
||||||
|
```
|
||||||
|
|
||||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
- Create symlinks storage
|
||||||
|
|
||||||
## Code of Conduct
|
```
|
||||||
|
php artisan storage:link
|
||||||
|
```
|
||||||
|
|
||||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
- Running migration
|
||||||
|
|
||||||
## Security Vulnerabilities
|
```
|
||||||
|
php artisan migrate
|
||||||
|
```
|
||||||
|
|
||||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
- Running seeder
|
||||||
|
|
||||||
## License
|
```
|
||||||
|
php artisan db:seed
|
||||||
|
```
|
||||||
|
|
||||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
- Create view table
|
||||||
|
- excute all sql queries on folder database/view_query
|
||||||
|
|
||||||
|
# Add ENV variable
|
||||||
|
|
||||||
|
- API_KEY_GOOGLE
|
||||||
|
|
||||||
|
```
|
||||||
|
Get api key from google developer console for and turn on spreadsheet api or feaature for google sheet
|
||||||
|
```
|
||||||
|
|
||||||
|
- SPREAD_SHEET_ID
|
||||||
|
|
||||||
|
```
|
||||||
|
Get spreadsheet id from google sheet link
|
||||||
|
```
|
||||||
|
|
||||||
|
- OPENAI_API_KEY
|
||||||
|
|
||||||
|
```
|
||||||
|
Get OpenAI API key from chatgpt subscription
|
||||||
|
```
|
||||||
|
|
||||||
|
- ENV
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
API_KEY_GOOGLE="xxxxx"
|
||||||
|
SPREAD_SHEET_ID="xxxxx"
|
||||||
|
OPENAI_API_KEY="xxxxx"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
# Technology version
|
||||||
|
|
||||||
|
- php 8.3
|
||||||
|
- Laravel 11
|
||||||
|
- node v22.13.0
|
||||||
|
- npm 10.9.2
|
||||||
|
- mariadb Ver 15.1 Distrib 10.6.18-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper
|
||||||
|
- Ubuntu 24.04
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Jobs\SyncronizeSIMBG;
|
||||||
use App\Services\ServiceSIMBG;
|
use App\Services\ServiceSIMBG;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use \Illuminate\Support\Facades\Log;
|
use \Illuminate\Support\Facades\Log;
|
||||||
@@ -28,13 +29,12 @@ class ExecuteScraping extends Command
|
|||||||
|
|
||||||
private $service_simbg;
|
private $service_simbg;
|
||||||
|
|
||||||
public function __construct(ServiceSIMBG $service_simbg){
|
public function __construct(){
|
||||||
$this->service_simbg = $service_simbg;
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
SyncronizeSIMBG::dispatch()->onQueue('default');
|
||||||
Log::info("running scheduler daily scraping");
|
Log::info("running scheduler daily scraping");
|
||||||
$this->service_simbg->syncTaskList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
95
app/Console/Commands/ScrapingData.php
Normal file
95
app/Console/Commands/ScrapingData.php
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Jobs\ScrapingDataJob;
|
||||||
|
use App\Models\ImportDatasource;
|
||||||
|
use App\Services\ServiceGoogleSheet;
|
||||||
|
use App\Services\ServicePbgTask;
|
||||||
|
use App\Services\ServiceTabPbgTask;
|
||||||
|
use App\Services\ServiceTokenSIMBG;
|
||||||
|
use GuzzleHttp\Client; // Import Guzzle Client
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class ScrapingData extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'app:scraping-data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Command description';
|
||||||
|
/**
|
||||||
|
* Inject dependencies.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
) {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
dispatch(new ScrapingDataJob());
|
||||||
|
|
||||||
|
$this->info("Scraping job dispatched successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
// public function handle()
|
||||||
|
// {
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// // Create a record with "processing" status
|
||||||
|
// $import_datasource = ImportDatasource::create([
|
||||||
|
// 'message' => 'Initiating scraping...',
|
||||||
|
// 'response_body' => null,
|
||||||
|
// 'status' => 'processing',
|
||||||
|
// 'start_time' => now()
|
||||||
|
// ]);
|
||||||
|
|
||||||
|
// // Run the service
|
||||||
|
// $service_google_sheet = new ServiceGoogleSheet();
|
||||||
|
// $service_google_sheet->run_service();
|
||||||
|
|
||||||
|
// // Run the ServicePbgTask with injected Guzzle Client
|
||||||
|
// $this->service_pbg_task->run_service();
|
||||||
|
|
||||||
|
// // run the service pbg task assignments
|
||||||
|
// $this->service_tab_pbg_task->run_service();
|
||||||
|
|
||||||
|
// // Update the record status to "success" after completion
|
||||||
|
// $import_datasource->update([
|
||||||
|
// 'status' => 'success',
|
||||||
|
// 'message' => 'Scraping completed successfully.',
|
||||||
|
// 'finish_time' => now()
|
||||||
|
// ]);
|
||||||
|
|
||||||
|
// } catch (\Exception $e) {
|
||||||
|
|
||||||
|
// // Log the error for debugging
|
||||||
|
// Log::error('Scraping failed: ' . $e->getMessage(), ['trace' => $e->getTraceAsString()]);
|
||||||
|
|
||||||
|
// // Handle errors by updating the status to "failed"
|
||||||
|
// if (isset($import_datasource)) {
|
||||||
|
// $import_datasource->update([
|
||||||
|
// 'status' => 'failed',
|
||||||
|
// 'response_body' => 'Error: ' . $e->getMessage(),
|
||||||
|
// 'finish_time' => now()
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
31
app/Exports/DistrictPaymentRecapExport.php
Normal file
31
app/Exports/DistrictPaymentRecapExport.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
|
||||||
|
class DistrictPaymentRecapExport implements FromCollection, WithHeadings
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return PbgTaskGoogleSheet::select(
|
||||||
|
'kecamatan',
|
||||||
|
DB::raw('SUM(nilai_retribusi_keseluruhan_simbg) as total')
|
||||||
|
)
|
||||||
|
->groupBy('kecamatan')->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array{
|
||||||
|
return [
|
||||||
|
'Kecamatan',
|
||||||
|
'Total'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
90
app/Exports/ReportDirectorExport.php
Normal file
90
app/Exports/ReportDirectorExport.php
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\BigdataResume;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
|
||||||
|
class ReportDirectorExport implements FromCollection, WithHeadings, WithMapping
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return BigdataResume::select(
|
||||||
|
'potention_count',
|
||||||
|
'potention_sum',
|
||||||
|
'non_verified_count',
|
||||||
|
'non_verified_sum',
|
||||||
|
'verified_count',
|
||||||
|
'verified_sum',
|
||||||
|
'business_count',
|
||||||
|
'business_sum',
|
||||||
|
'non_business_count',
|
||||||
|
'non_business_sum',
|
||||||
|
'spatial_count',
|
||||||
|
'spatial_sum',
|
||||||
|
'waiting_click_dpmptsp_count',
|
||||||
|
'waiting_click_dpmptsp_sum',
|
||||||
|
'issuance_realization_pbg_count',
|
||||||
|
'issuance_realization_pbg_sum',
|
||||||
|
'process_in_technical_office_count',
|
||||||
|
'process_in_technical_office_sum',
|
||||||
|
'year',
|
||||||
|
'created_at'
|
||||||
|
)->orderBy('id', 'desc')->get();
|
||||||
|
}
|
||||||
|
public function headings(): array{
|
||||||
|
return [
|
||||||
|
"Jumlah Potensi" ,
|
||||||
|
"Total Potensi" ,
|
||||||
|
"Jumlah Berkas Belum Terverifikasi" ,
|
||||||
|
"Total Berkas Belum Terverifikasi" ,
|
||||||
|
"Jumlah Berkas Terverifikasi" ,
|
||||||
|
"Total Berkas Terverifikasi" ,
|
||||||
|
"Jumlah Usaha" ,
|
||||||
|
"Total Usaha" ,
|
||||||
|
"Jumlah Non Usaha" ,
|
||||||
|
"Total Non Usaha" ,
|
||||||
|
"Jumlah Tata Ruang" ,
|
||||||
|
"Total Tata Ruang" ,
|
||||||
|
"Jumlah Menunggu Klik DPMPTSP" ,
|
||||||
|
"Total Menunggu Klik DPMPTSP" ,
|
||||||
|
"Jumlah Realisasi Terbit PBG" ,
|
||||||
|
"Total Realisasi Terbit PBG" ,
|
||||||
|
"Jumlah Proses Dinas Teknis" ,
|
||||||
|
"Total Proses Dinas Teknis",
|
||||||
|
"Tahun",
|
||||||
|
"Created"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function map($row): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
$row->potention_count,
|
||||||
|
$row->potention_sum,
|
||||||
|
$row->non_verified_count,
|
||||||
|
$row->non_verified_sum,
|
||||||
|
$row->verified_count,
|
||||||
|
$row->verified_sum,
|
||||||
|
$row->business_count,
|
||||||
|
$row->business_sum,
|
||||||
|
$row->non_business_count,
|
||||||
|
$row->non_business_sum,
|
||||||
|
$row->spatial_count,
|
||||||
|
$row->spatial_sum,
|
||||||
|
$row->waiting_click_dpmptsp_count,
|
||||||
|
$row->waiting_click_dpmptsp_sum,
|
||||||
|
$row->issuance_realization_pbg_count,
|
||||||
|
$row->issuance_realization_pbg_sum,
|
||||||
|
$row->process_in_technical_office_count,
|
||||||
|
$row->process_in_technical_office_sum,
|
||||||
|
$row->year,
|
||||||
|
$row->created_at ? $row->created_at->format('Y-m-d H:i:s') : null, // Format created_at as Y-m-d
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
71
app/Exports/ReportPaymentRecapExport.php
Normal file
71
app/Exports/ReportPaymentRecapExport.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\BigdataResume;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
|
||||||
|
class ReportPaymentRecapExport implements FromCollection, WithHeadings
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
protected $startDate;
|
||||||
|
protected $endDate;
|
||||||
|
public function __construct($startDate, $endDate){
|
||||||
|
$this->startDate = $startDate;
|
||||||
|
$this->endDate = $endDate;
|
||||||
|
}
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
$query = BigdataResume::query()->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($this->startDate && $this->endDate) {
|
||||||
|
$query->whereBetween('created_at', [$this->startDate, $this->endDate]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = $query->get();
|
||||||
|
|
||||||
|
$categoryMap = [
|
||||||
|
'potention_sum' => 'Potensi',
|
||||||
|
'non_verified_sum' => 'Belum Terverifikasi',
|
||||||
|
'verified_sum' => 'Terverifikasi',
|
||||||
|
'business_sum' => 'Usaha',
|
||||||
|
'non_business_sum' => 'Non Usaha',
|
||||||
|
'spatial_sum' => 'Tata Ruang',
|
||||||
|
'waiting_click_dpmptsp_sum' => 'Menunggu Klik DPMPTSP',
|
||||||
|
'issuance_realization_pbg_sum' => 'Realisasi Terbit PBG',
|
||||||
|
'process_in_technical_office_sum' => 'Proses Di Dinas Teknis',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Restructure response
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$createdAt = $item->created_at;
|
||||||
|
$id = $item->id;
|
||||||
|
|
||||||
|
foreach ($item->toArray() as $key => $value) {
|
||||||
|
// Only include columns with "sum" in their names
|
||||||
|
if (strpos($key, 'sum') !== false) {
|
||||||
|
$data[] = [
|
||||||
|
'category' => $categoryMap[$key] ?? $key, // Map category
|
||||||
|
'nominal' => number_format($value, 0, ',', '.'), // Format number
|
||||||
|
'created_at' => $createdAt->format('Y-m-d H:i:s'), // Format date
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return collect($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array{
|
||||||
|
return [
|
||||||
|
'Kategori',
|
||||||
|
'Nominal',
|
||||||
|
'Created'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
32
app/Exports/ReportPbgPtspExport.php
Normal file
32
app/Exports/ReportPbgPtspExport.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\PbgTask;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
|
||||||
|
class ReportPbgPtspExport implements FromCollection, WithHeadings
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return PbgTask::select(
|
||||||
|
'status_name',
|
||||||
|
DB::raw('COUNT(*) as total')
|
||||||
|
)
|
||||||
|
->groupBy('status', 'status_name')
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Status Name',
|
||||||
|
'Total'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
25
app/Exports/ReportTourismExport.php
Normal file
25
app/Exports/ReportTourismExport.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\TourismBasedKBLI;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
|
||||||
|
class ReportTourismExport implements FromCollection, WithHeadings
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return TourismBasedKBLI::select('kbli_title', 'total_records')->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array{
|
||||||
|
return [
|
||||||
|
'Jenis Bisnis Pariwisata',
|
||||||
|
'Jumlah Total'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,17 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Exports\ReportDirectorExport;
|
||||||
|
use App\Exports\ReportPaymentRecapExport;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\BigdataResumeResource;
|
||||||
use App\Models\BigdataResume;
|
use App\Models\BigdataResume;
|
||||||
use App\Models\DataSetting;
|
use App\Models\DataSetting;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
|
||||||
class BigDataResumeController extends Controller
|
class BigDataResumeController extends Controller
|
||||||
{
|
{
|
||||||
@@ -18,11 +24,12 @@ class BigDataResumeController extends Controller
|
|||||||
try{
|
try{
|
||||||
$filterDate = $request->get("filterByDate");
|
$filterDate = $request->get("filterByDate");
|
||||||
|
|
||||||
// If filterByDate is "latest" or empty, get the most recent record
|
|
||||||
if (!$filterDate || $filterDate === "latest") {
|
if (!$filterDate || $filterDate === "latest") {
|
||||||
$big_data_resume = BigdataResume::latest()->first();
|
$big_data_resume = BigdataResume::where('year', now()->year)->latest()->first();
|
||||||
|
if (!$big_data_resume) {
|
||||||
|
return $this->response_empty_resume();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Filter by specific date
|
|
||||||
$big_data_resume = BigdataResume::whereDate('created_at', $filterDate)
|
$big_data_resume = BigdataResume::whereDate('created_at', $filterDate)
|
||||||
->orderBy('id', 'desc')
|
->orderBy('id', 'desc')
|
||||||
->first();
|
->first();
|
||||||
@@ -37,15 +44,19 @@ class BigDataResumeController extends Controller
|
|||||||
return response()->json(['message' => 'No data setting found']);
|
return response()->json(['message' => 'No data setting found']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$target_pad = floatval(optional($data_settings->where('key', 'TARGET_PAD')->first())->value);
|
function cleanNumber($value) {
|
||||||
$tata_ruang = floatval(optional($data_settings->where('key', 'TATA_RUANG')->first())->value);
|
return floatval(str_replace('.', '', $value));
|
||||||
$realisasi_terbit_pbg_sum = floatval(optional($data_settings->where('key', 'REALISASI_TERBIT_PBG_SUM')->first())->value);
|
}
|
||||||
$realisasi_terbit_pbg_count = floatval(optional($data_settings->where('key', 'REALISASI_TERBIT_PBG_COUNT')->first())->value);
|
|
||||||
$menuggu_klik_dpmptsp_sum = floatval(optional($data_settings->where('key', 'MENUNGGU_KLIK_DPMPTSP_SUM')->first())->value);
|
|
||||||
$menuggu_klik_dpmptsp_count = floatval(optional($data_settings->where('key', 'MENUNGGU_KLIK_DPMPTSP_COUNT')->first())->value);
|
|
||||||
$proses_dinas_teknis_sum = floatval(optional($data_settings->where('key', 'PROSES_DINAS_TEKNIS_SUM')->first())->value);
|
|
||||||
$proses_dinas_teknis_count = floatval(optional($data_settings->where('key', 'PROSES_DINAS_TEKNIS_COUNT')->first())->value);
|
|
||||||
|
|
||||||
|
$target_pad = floatval(optional($data_settings->where('key', 'TARGET_PAD')->first())->value);
|
||||||
|
$realisasi_terbit_pbg_sum = cleanNumber(optional($data_settings->where('key', 'REALISASI_TERBIT_PBG_SUM')->first())->value);
|
||||||
|
$realisasi_terbit_pbg_count = cleanNumber(optional($data_settings->where('key', 'REALISASI_TERBIT_PBG_COUNT')->first())->value);
|
||||||
|
$menunggu_klik_dpmptsp_sum = cleanNumber(optional($data_settings->where('key', 'MENUNGGU_KLIK_DPMPTSP_SUM')->first())->value);
|
||||||
|
$menunggu_klik_dpmptsp_count = cleanNumber(optional($data_settings->where('key', 'MENUNGGU_KLIK_DPMPTSP_COUNT')->first())->value);
|
||||||
|
$proses_dinas_teknis_sum = cleanNumber(optional($data_settings->where('key', 'PROSES_DINAS_TEKNIS_SUM')->first())->value);
|
||||||
|
$proses_dinas_teknis_count = cleanNumber(optional($data_settings->where('key', 'PROSES_DINAS_TEKNIS_COUNT')->first())->value);
|
||||||
|
|
||||||
|
$tata_ruang = $big_data_resume->spatial_sum;
|
||||||
$kekurangan_potensi = $target_pad - $big_data_resume->potention_sum;
|
$kekurangan_potensi = $target_pad - $big_data_resume->potention_sum;
|
||||||
|
|
||||||
// percentage kekurangan potensi
|
// percentage kekurangan potensi
|
||||||
@@ -81,8 +92,8 @@ class BigDataResumeController extends Controller
|
|||||||
? round(($realisasi_terbit_pbg_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
? round(($realisasi_terbit_pbg_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
// percentage menunggu klik dpmptsp
|
// percentage menunggu klik dpmptsp
|
||||||
$menunggu_klik_dpmptsp_percentage = $big_data_resume->verified_sum > 0 && $menuggu_klik_dpmptsp_sum > 0
|
$menunggu_klik_dpmptsp_percentage = $big_data_resume->verified_sum > 0 && $menunggu_klik_dpmptsp_sum > 0
|
||||||
? round(($menuggu_klik_dpmptsp_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
? round(($menunggu_klik_dpmptsp_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
// percentage proses_dinas_teknis
|
// percentage proses_dinas_teknis
|
||||||
$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
|
||||||
@@ -94,7 +105,8 @@ class BigDataResumeController extends Controller
|
|||||||
'percentage' => 100,
|
'percentage' => 100,
|
||||||
],
|
],
|
||||||
'tata_ruang' => [
|
'tata_ruang' => [
|
||||||
'sum' => $tata_ruang,
|
'sum' => $big_data_resume->spatial_sum,
|
||||||
|
'count' => $big_data_resume->spatial_count,
|
||||||
'percentage' => $tata_ruang_percentage,
|
'percentage' => $tata_ruang_percentage,
|
||||||
],
|
],
|
||||||
'kekurangan_potensi' => [
|
'kekurangan_potensi' => [
|
||||||
@@ -132,8 +144,8 @@ class BigDataResumeController extends Controller
|
|||||||
'percentage' => $realisasi_terbit_percentage
|
'percentage' => $realisasi_terbit_percentage
|
||||||
],
|
],
|
||||||
'menunggu_klik_dpmptsp' => [
|
'menunggu_klik_dpmptsp' => [
|
||||||
'sum' => $menuggu_klik_dpmptsp_sum,
|
'sum' => $menunggu_klik_dpmptsp_sum,
|
||||||
'count' => $menuggu_klik_dpmptsp_count,
|
'count' => $menunggu_klik_dpmptsp_count,
|
||||||
'percentage' => $menunggu_klik_dpmptsp_percentage
|
'percentage' => $menunggu_klik_dpmptsp_percentage
|
||||||
],
|
],
|
||||||
'proses_dinas_teknis' => [
|
'proses_dinas_teknis' => [
|
||||||
@@ -148,38 +160,166 @@ class BigDataResumeController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*/
|
public function bigdata_report(Request $request){
|
||||||
public function store(Request $request)
|
try{
|
||||||
{
|
$query = BigdataResume::query()->orderBy('id', 'desc');
|
||||||
//
|
|
||||||
|
if($request->filled('search')){
|
||||||
|
$query->where('year', 'LIKE', '%'.$request->input('search').'%');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
$query = $query->paginate(config('app.paginate_per_page', 50));
|
||||||
* Display the specified resource.
|
return BigdataResumeResource::collection($query)->response()->getData(true);
|
||||||
*/
|
}catch(\Exception $e){
|
||||||
public function show(string $id)
|
Log::error($e->getMessage());
|
||||||
{
|
return response()->json(['message' => 'Error when fetching data'], 500);
|
||||||
//
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function payment_recaps(Request $request)
|
||||||
* Update the specified resource in storage.
|
|
||||||
*/
|
|
||||||
public function update(Request $request, string $id)
|
|
||||||
{
|
{
|
||||||
//
|
try {
|
||||||
|
$query = BigdataResume::query()->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($request->filled('start_date') && $request->filled('end_date')) {
|
||||||
|
$startDate = Carbon::parse($request->input('start_date'))->startOfDay();
|
||||||
|
$endDate = Carbon::parse($request->input('end_date'))->endOfDay();
|
||||||
|
|
||||||
|
$query->whereBetween('created_at', [$startDate, $endDate]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
$data = $query->paginate(50);
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*/
|
// Restructure response
|
||||||
public function destroy(string $id)
|
$transformedData = [];
|
||||||
{
|
|
||||||
//
|
foreach ($data as $item) {
|
||||||
|
$createdAt = $item->created_at;
|
||||||
|
$id = $item->id;
|
||||||
|
|
||||||
|
foreach ($item->toArray() as $key => $value) {
|
||||||
|
// Only include columns with "sum" in their names
|
||||||
|
if (strpos($key, 'sum') !== false) {
|
||||||
|
$transformedData[] = [
|
||||||
|
'id' => $id,
|
||||||
|
'category' => $key,
|
||||||
|
'nominal' => $value,
|
||||||
|
'created_at' => $createdAt,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'data' => $transformedData, // Flat array
|
||||||
|
'pagination' => [
|
||||||
|
'total' => count($transformedData),
|
||||||
|
'per_page' => $data->perPage(),
|
||||||
|
'current_page' => $data->currentPage(),
|
||||||
|
'last_page' => $data->lastPage(),
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error($e->getMessage());
|
||||||
|
return response()->json(['message' => 'Error when fetching data'], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export_excel_payment_recaps(Request $request)
|
||||||
|
{
|
||||||
|
$startDate = null;
|
||||||
|
$endDate = null;
|
||||||
|
|
||||||
|
if ($request->filled('start_date') && $request->filled('end_date')) {
|
||||||
|
$startDate = Carbon::parse($request->input('start_date'))->startOfDay();
|
||||||
|
$endDate = Carbon::parse($request->input('end_date'))->endOfDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Excel::download(new ReportPaymentRecapExport($startDate, $endDate), 'laporan-rekap-pembayaran.xlsx');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export_pdf_payment_recaps(Request $request){
|
||||||
|
$query = BigdataResume::query()->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($request->filled('start_date') && $request->filled('end_date')) {
|
||||||
|
$startDate = Carbon::parse($request->input('start_date'))->startOfDay();
|
||||||
|
$endDate = Carbon::parse($request->input('end_date'))->endOfDay();
|
||||||
|
|
||||||
|
$query->whereBetween('created_at', [$startDate, $endDate]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = $query->get();
|
||||||
|
|
||||||
|
// Define category mapping
|
||||||
|
$categoryMap = [
|
||||||
|
'potention_sum' => 'Potensi',
|
||||||
|
'non_verified_sum' => 'Belum Terverifikasi',
|
||||||
|
'verified_sum' => 'Terverifikasi',
|
||||||
|
'business_sum' => 'Usaha',
|
||||||
|
'non_business_sum' => 'Non Usaha',
|
||||||
|
'spatial_sum' => 'Tata Ruang',
|
||||||
|
'waiting_click_dpmptsp_sum' => 'Menunggu Klik DPMPTSP',
|
||||||
|
'issuance_realization_pbg_sum' => 'Realisasi Terbit PBG',
|
||||||
|
'process_in_technical_office_sum' => 'Proses Di Dinas Teknis',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Restructure response
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$createdAt = $item->created_at;
|
||||||
|
$id = $item->id;
|
||||||
|
|
||||||
|
foreach ($item->toArray() as $key => $value) {
|
||||||
|
// Only include columns with "sum" in their names
|
||||||
|
if (strpos($key, 'sum') !== false) {
|
||||||
|
$data[] = [
|
||||||
|
'id' => $id,
|
||||||
|
'category' => $categoryMap[$key] ?? $key, // Map category
|
||||||
|
'nominal' => $value, // Format number
|
||||||
|
'created_at' => $createdAt->format('Y-m-d H:i:s'), // Format date
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf = Pdf::loadView('exports.payment_recaps_report', compact('data'));
|
||||||
|
return $pdf->download('laporan-rekap-pembayaran.pdf');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function export_excel_report_director(){
|
||||||
|
return Excel::download(new ReportDirectorExport, 'laporan-pimpinan.xlsx');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export_pdf_report_director(){
|
||||||
|
$data = BigdataResume::select(
|
||||||
|
'potention_count',
|
||||||
|
'potention_sum',
|
||||||
|
'non_verified_count',
|
||||||
|
'non_verified_sum',
|
||||||
|
'verified_count',
|
||||||
|
'verified_sum',
|
||||||
|
'business_count',
|
||||||
|
'business_sum',
|
||||||
|
'non_business_count',
|
||||||
|
'non_business_sum',
|
||||||
|
'spatial_count',
|
||||||
|
'spatial_sum',
|
||||||
|
'waiting_click_dpmptsp_count',
|
||||||
|
'waiting_click_dpmptsp_sum',
|
||||||
|
'issuance_realization_pbg_count',
|
||||||
|
'issuance_realization_pbg_sum',
|
||||||
|
'process_in_technical_office_count',
|
||||||
|
'process_in_technical_office_sum',
|
||||||
|
'year',
|
||||||
|
'created_at'
|
||||||
|
)->orderBy('id', 'desc')->get();
|
||||||
|
$pdf = Pdf::loadView('exports.director_report', compact('data'))->setPaper('a4', 'landscape');
|
||||||
|
return $pdf->download('laporan-pimpinan.pdf');
|
||||||
|
}
|
||||||
private function response_empty_resume(){
|
private function response_empty_resume(){
|
||||||
$result = [
|
$result = [
|
||||||
'target_pad' => [
|
'target_pad' => [
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use App\Models\BusinessOrIndustry;
|
|||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Maatwebsite\Excel\Facades\Excel;
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
use \Illuminate\Support\Facades\Validator;
|
use \Illuminate\Support\Facades\Validator;
|
||||||
|
use App\Http\Requests\ExcelUploadRequest;
|
||||||
class BusinessOrIndustriesController extends Controller
|
class BusinessOrIndustriesController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -30,7 +31,7 @@ class BusinessOrIndustriesController extends Controller
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($query->paginate());
|
return response()->json($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,29 +80,15 @@ class BusinessOrIndustriesController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function upload(Request $request){
|
public function upload(ExcelUploadRequest $request){
|
||||||
|
try {
|
||||||
if ($request->hasFile('file')) {
|
if(!$request->hasFile('file')){
|
||||||
$file = $request->file('file');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validasi file
|
|
||||||
$validator = Validator::make($request->all(), [
|
|
||||||
'file' => 'required|mimes:xlsx,xls|max:102400', // Max 100MB
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'File validation failed.',
|
'error' => 'No file provided'
|
||||||
'errors' => $validator->errors()
|
|
||||||
], 400);
|
], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
// Ambil file dari request
|
|
||||||
$file = $request->file('file');
|
$file = $request->file('file');
|
||||||
|
|
||||||
// Menggunakan Laravel Excel untuk mengimpor file
|
|
||||||
Excel::import(new BusinessIndustriesImport, $file);
|
Excel::import(new BusinessIndustriesImport, $file);
|
||||||
|
|
||||||
// Jika sukses, kembalikan respons sukses
|
// Jika sukses, kembalikan respons sukses
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use App\Services\OpenAIService;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class ChatbotController extends Controller
|
class ChatbotController extends Controller
|
||||||
{
|
{
|
||||||
@@ -19,7 +20,6 @@ class ChatbotController extends Controller
|
|||||||
|
|
||||||
public function generateText(Request $request)
|
public function generateText(Request $request)
|
||||||
{
|
{
|
||||||
info($request);
|
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'tab_active' => 'required|string',
|
'tab_active' => 'required|string',
|
||||||
'prompt' => 'required|string',
|
'prompt' => 'required|string',
|
||||||
@@ -33,52 +33,87 @@ class ChatbotController extends Controller
|
|||||||
default => "UNKNOWN",
|
default => "UNKNOWN",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$chatHistory = $request->input('chatHistory');
|
||||||
|
// Log::info('Chat history sebelum disimpan:', ['history' => $chatHistory]);
|
||||||
|
|
||||||
if ($main_content === "UNKNOWN") {
|
if ($main_content === "UNKNOWN") {
|
||||||
return response()->json(['response' => 'Invalid tab_active value.'], 400);
|
return response()->json(['response' => 'Invalid tab_active value.'], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
info($main_content);
|
// info($main_content);
|
||||||
|
|
||||||
// Klasifikasi apakah pertanyaan butuh database atau bisa dijawab langsung
|
$queryResponse = $this->openAIService->generateQueryBasedMainContent($request->input('prompt'), $main_content, $chatHistory);
|
||||||
$classifyResponse = $this->openAIService->generateClassifyMainContent($request->input('prompt'), $main_content);
|
|
||||||
|
|
||||||
if ($classifyResponse === "DATABASE") {
|
$firstValidation = $this->openAIService->validateSyntaxQuery($queryResponse);
|
||||||
$queryResponse = $this->openAIService->generateQueryBasedMainContent($request->input('prompt'), $main_content);
|
$secondValidation = $this->openAIService->validateSyntaxQuery($queryResponse);
|
||||||
if (is_array($queryResponse)) {
|
|
||||||
info('Query Response is an array: ', $queryResponse);
|
|
||||||
} else {
|
|
||||||
info('Query Response is a string: ' . $queryResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validasi query dua kali sebelum eksekusi
|
$formattedResultQuery = "[]";
|
||||||
if (
|
|
||||||
$this->openAIService->validateSyntaxQuery($queryResponse) === "VALID" &&
|
|
||||||
$this->openAIService->validateSyntaxQuery($queryResponse) === "VALID"
|
|
||||||
) {
|
|
||||||
info($queryResponse);
|
|
||||||
$queryResponse = str_replace(['```sql', '```'], '', $queryResponse);
|
$queryResponse = str_replace(['```sql', '```'], '', $queryResponse);
|
||||||
$resultQuery = DB::select($queryResponse);
|
$resultQuery = DB::select($queryResponse);
|
||||||
$formattedResultQuery = json_encode($resultQuery, JSON_PRETTY_PRINT);
|
$formattedResultQuery = json_encode($resultQuery, JSON_PRETTY_PRINT);
|
||||||
|
// info($formattedResultQuery);
|
||||||
|
|
||||||
$nlpResult = $this->openAIService->generateNLPFromQuery($request->input('prompt'), $formattedResultQuery);
|
$nlpResult = $this->openAIService->generateNLPFromQuery($request->input('prompt'), $formattedResultQuery);
|
||||||
$finalGeneratedText =$this->openAIService->generateFinalText($nlpResult);
|
$finalGeneratedText =$this->openAIService->generateFinalText($nlpResult);
|
||||||
return response()->json(['response' => $finalGeneratedText]);
|
return response()->json(['response' => $finalGeneratedText, 'nlpResponse' => $queryResponse]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(['response' => ''], 400);
|
public function mainGenerateText(Request $request)
|
||||||
|
{
|
||||||
|
// Log hanya data yang relevan
|
||||||
|
info("Received prompt: " . $request->input('prompt'));
|
||||||
|
|
||||||
|
// Validasi input
|
||||||
|
$request->validate([
|
||||||
|
'prompt' => 'required|string',
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Panggil service untuk generate text
|
||||||
|
$classifyResponse = $this->openAIService->classifyMainGenerateText($request->input('prompt'));
|
||||||
|
info($classifyResponse);
|
||||||
|
|
||||||
|
// Pastikan hasil klasifikasi valid sebelum melanjutkan
|
||||||
|
$validCategories = [
|
||||||
|
'reklame', 'business_or_industries', 'customers',
|
||||||
|
'pbg', 'retribusi', 'spatial_plannings',
|
||||||
|
'tourisms', 'umkms'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!in_array($classifyResponse, $validCategories)) {
|
||||||
|
return response()->json([
|
||||||
|
'error' => ''
|
||||||
|
], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($classifyResponse === "GENERAL") {
|
$chatHistory = $request->input('chatHistory');
|
||||||
$nlpResult = $this->openAIService->generateGeneralText($request->input('prompt'), $main_content);
|
Log::info('Chat history sebelum disimpan:', ['history' => $chatHistory]);
|
||||||
|
|
||||||
|
$queryResponse = $this->openAIService->createMainQuery($classifyResponse, $request->input('prompt'), $chatHistory);
|
||||||
|
info($queryResponse);
|
||||||
|
|
||||||
|
$firstValidation = $this->openAIService->validateSyntaxQuery($queryResponse);
|
||||||
|
$secondValidation = $this->openAIService->validateSyntaxQuery($queryResponse);
|
||||||
|
|
||||||
|
$formattedResultQuery = "[]";
|
||||||
|
|
||||||
|
$queryResponse = str_replace(['```sql', '```'], '', $queryResponse);
|
||||||
|
$queryResult = DB::select($queryResponse);
|
||||||
|
|
||||||
|
$formattedResultQuery = json_encode($queryResult, JSON_PRETTY_PRINT);
|
||||||
|
|
||||||
|
$nlpResult = $this->openAIService->generateNLPFromQuery($request->input('prompt'), $formattedResultQuery);
|
||||||
$finalGeneratedText =$this->openAIService->generateFinalText($nlpResult);
|
$finalGeneratedText =$this->openAIService->generateFinalText($nlpResult);
|
||||||
return response()->json(['response' => $finalGeneratedText]);
|
|
||||||
|
return response()->json(['response' => $finalGeneratedText, 'nlpResponse' => $queryResponse]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// Tangani error dan log exception
|
||||||
|
\Log::error("Error generating text: " . $e->getMessage());
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => ''
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(['response' => ''], 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function classifyContent(string $prompt) {
|
|
||||||
$classifyResponse = $this->openAIService->generateClassifyContent($prompt);
|
|
||||||
return $classifyResponse;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -22,9 +22,9 @@ class CustomersController extends Controller
|
|||||||
if ($request->has('search') &&!empty($request->get('search'))) {
|
if ($request->has('search') &&!empty($request->get('search'))) {
|
||||||
$query = $query->where('nomor_pelanggan', 'LIKE', '%'.$request->get('search').'%')
|
$query = $query->where('nomor_pelanggan', 'LIKE', '%'.$request->get('search').'%')
|
||||||
->orWhere('nama', 'LIKE', '%'.$request->get('search').'%')
|
->orWhere('nama', 'LIKE', '%'.$request->get('search').'%')
|
||||||
->orWhere('kota_palayanan', 'LIKE', '%'.$request->get('search').'%');
|
->orWhere('kota_pelayanan', 'LIKE', '%'.$request->get('search').'%');
|
||||||
}
|
}
|
||||||
return CustomersResource::collection($query->paginate());
|
return CustomersResource::collection($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class GlobalSettingsController extends Controller
|
|||||||
try {
|
try {
|
||||||
$data = GlobalSetting::create($request->validated());
|
$data = GlobalSetting::create($request->validated());
|
||||||
return new GlobalSettingResource($data);
|
return new GlobalSettingResource($data);
|
||||||
} catch (\Exception $e) {
|
} catch (Exception $e) {
|
||||||
return $this->resError($e->getMessage(), null, $e->getCode());
|
return $this->resError($e->getMessage(), null, $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,33 +3,15 @@
|
|||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Services\GoogleSheetService;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class GoogleSheetController extends Controller
|
class GoogleSheetController extends Controller
|
||||||
{
|
{
|
||||||
protected $googleSheetService;
|
public function index(Request $request)
|
||||||
public function __construct(GoogleSheetService $googleSheetService){
|
|
||||||
$this->googleSheetService = $googleSheetService;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Display a listing of the resource.
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
{
|
||||||
$dataCollection = $this->googleSheetService->getSheetDataCollection();
|
|
||||||
$result = [
|
|
||||||
"last_row" => $this->googleSheetService->getLastRowByColumn("C"),
|
|
||||||
"last_column" => $this->googleSheetService->getLastColumn(),
|
|
||||||
"header" => $this->googleSheetService->getHeader(),
|
|
||||||
"data_collection" => $dataCollection
|
|
||||||
];
|
|
||||||
return response()->json($result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*/
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class ImportDatasourceController extends Controller
|
|||||||
$search = $request->get("search");
|
$search = $request->get("search");
|
||||||
$query->where('status', 'like', "%".$search."%");
|
$query->where('status', 'like', "%".$search."%");
|
||||||
}
|
}
|
||||||
return ImportDatasourceResource::collection($query->paginate());
|
return ImportDatasourceResource::collection($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkImportDatasource(){
|
public function checkImportDatasource(){
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use App\Models\Advertisement;
|
|||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use App\Models\SpatialPlanning;
|
use App\Models\SpatialPlanning;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\TourismBasedKBLI;
|
||||||
|
|
||||||
class LackOfPotentialController extends Controller
|
class LackOfPotentialController extends Controller
|
||||||
{
|
{
|
||||||
@@ -16,11 +17,13 @@ class LackOfPotentialController extends Controller
|
|||||||
$total_reklame = Advertisement::count();
|
$total_reklame = Advertisement::count();
|
||||||
$total_pdam = Customer::count();
|
$total_pdam = Customer::count();
|
||||||
$total_tata_ruang = SpatialPlanning::count();
|
$total_tata_ruang = SpatialPlanning::count();
|
||||||
|
$data_report_tourism = TourismBasedKBLI::all();
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'total_reklame' => $total_reklame,
|
'total_reklame' => $total_reklame,
|
||||||
'total_pdam' => $total_pdam,
|
'total_pdam' => $total_pdam,
|
||||||
'total_tata_ruang' => $total_tata_ruang
|
'total_tata_ruang' => $total_tata_ruang,
|
||||||
|
'data_report' => $data_report_tourism,
|
||||||
], 200);
|
], 200);
|
||||||
}catch(\Exception $e){
|
}catch(\Exception $e){
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ class MenusController extends Controller
|
|||||||
$query = $query->where("name", "like", "%".$request->get("search")."%");
|
$query = $query->where("name", "like", "%".$request->get("search")."%");
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($query->paginate());
|
// return response()->json($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
|
return MenuResource::collection($query->paginate(config('app.paginate_per_page',50)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
61
app/Http/Controllers/Api/PbgTaskGoogleSheetsController.php
Normal file
61
app/Http/Controllers/Api/PbgTaskGoogleSheetsController.php
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\PbgTaskGoogleSheetResource;
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class PbgTaskGoogleSheetsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$query = PbgTaskGoogleSheet::query()->orderBy('id', 'desc');
|
||||||
|
if ($request->filled('search')) {
|
||||||
|
$query->where('no_registrasi', 'like', "%{$request->get('search')}%");
|
||||||
|
}
|
||||||
|
return PbgTaskGoogleSheetResource::collection($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$data = PbgTaskGoogleSheet::find($id);
|
||||||
|
$data->delete();
|
||||||
|
return response()->json(['message' => 'Data deleted successfully'], 200);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return response()->json(['message' => 'Failed to delete data'], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
app/Http/Controllers/Api/ReportPbgPtspController.php
Normal file
29
app/Http/Controllers/Api/ReportPbgPtspController.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Exports\ReportPbgPtspExport;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\PbgTask;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
|
||||||
|
class ReportPbgPtspController extends Controller
|
||||||
|
{
|
||||||
|
public function export_excel(){
|
||||||
|
return Excel::download(new ReportPbgPtspExport, 'laporan-ptsp.xlsx');
|
||||||
|
}
|
||||||
|
public function export_pdf(){
|
||||||
|
$data = PbgTask::select(
|
||||||
|
'status',
|
||||||
|
'status_name', // Keeping this column
|
||||||
|
DB::raw('COUNT(*) as total')
|
||||||
|
)
|
||||||
|
->groupBy('status', 'status_name')
|
||||||
|
->get();
|
||||||
|
$pdf = Pdf::loadView('exports.ptsp_report', compact('data'));
|
||||||
|
return $pdf->download('laporan-ptsp.pdf');
|
||||||
|
}
|
||||||
|
}
|
||||||
22
app/Http/Controllers/Api/ReportTourismsController.php
Normal file
22
app/Http/Controllers/Api/ReportTourismsController.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Exports\ReportTourismExport;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\TourismBasedKBLI;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
|
||||||
|
class ReportTourismsController extends Controller
|
||||||
|
{
|
||||||
|
public function export_excel(){
|
||||||
|
return Excel::download(new ReportTourismExport, 'laporan-pariwisata.xlsx');
|
||||||
|
}
|
||||||
|
public function export_pdf(){
|
||||||
|
$data = TourismBasedKBLI::all();
|
||||||
|
$pdf = Pdf::loadView('exports.tourisms_report', compact('data'));
|
||||||
|
return $pdf->download('laporan-pariwisata.pdf');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,10 +2,17 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Exports\DistrictPaymentRecapExport;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Resources\RequestAssignmentResouce;
|
use App\Http\Resources\RequestAssignmentResouce;
|
||||||
use App\Models\PbgTask;
|
use App\Models\PbgTask;
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use DB;
|
||||||
|
use Exception;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Log;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
|
||||||
class RequestAssignmentController extends Controller
|
class RequestAssignmentController extends Controller
|
||||||
{
|
{
|
||||||
@@ -17,11 +24,70 @@ class RequestAssignmentController extends Controller
|
|||||||
$query = PbgTask::query()->orderBy('id', 'desc');
|
$query = PbgTask::query()->orderBy('id', 'desc');
|
||||||
if($request->has('search') && !empty($request->get("search"))){
|
if($request->has('search') && !empty($request->get("search"))){
|
||||||
$query->where('name', 'LIKE', '%'.$request->get('search').'%')
|
$query->where('name', 'LIKE', '%'.$request->get('search').'%')
|
||||||
->orWhere('registration_number', 'LIKE', '%'.$request->get('search').'%');
|
->orWhere('registration_number', 'LIKE', '%'.$request->get('search').'%')
|
||||||
|
->orWhere('document_number', 'LIKE', '%'.$request->get('search').'%');
|
||||||
}
|
}
|
||||||
return RequestAssignmentResouce::collection($query->paginate());
|
return RequestAssignmentResouce::collection($query->paginate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function report_payment_recaps(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Query dengan group by kecamatan dan sum nilai_retribusi_keseluruhan_simbg
|
||||||
|
$query = PbgTaskGoogleSheet::select(
|
||||||
|
'kecamatan',
|
||||||
|
DB::raw('SUM(nilai_retribusi_keseluruhan_simbg) as total')
|
||||||
|
)
|
||||||
|
->groupBy('kecamatan')
|
||||||
|
->paginate(10);
|
||||||
|
|
||||||
|
// Return hasil dalam JSON format
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'data' => $query
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error($e->getMessage());
|
||||||
|
return response()->json(['message' => 'Terjadi kesalahan: ' . $e->getMessage()], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export_excel_district_payment_recaps(){
|
||||||
|
return Excel::download(new DistrictPaymentRecapExport, 'laporan-rekap-data-pembayaran.xlsx');
|
||||||
|
}
|
||||||
|
public function export_pdf_district_payment_recaps(){
|
||||||
|
$data = PbgTaskGoogleSheet::select(
|
||||||
|
'kecamatan',
|
||||||
|
DB::raw('SUM(nilai_retribusi_keseluruhan_simbg) as total')
|
||||||
|
)
|
||||||
|
->groupBy('kecamatan')->get();
|
||||||
|
$pdf = Pdf::loadView('exports.district_payment_report', compact('data'));
|
||||||
|
return $pdf->download('laporan-rekap-data-pembayaran.pdf');
|
||||||
|
}
|
||||||
|
public function report_pbg_ptsp()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Query dengan group by status dan count total per status
|
||||||
|
$query = PbgTask::select(
|
||||||
|
'status',
|
||||||
|
'status_name',
|
||||||
|
DB::raw('COUNT(*) as total')
|
||||||
|
)
|
||||||
|
->groupBy('status', 'status_name')
|
||||||
|
->paginate(10);
|
||||||
|
|
||||||
|
// Return hasil dalam JSON format
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'data' => $query
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error($e->getMessage());
|
||||||
|
return response()->json(['message' => 'Terjadi kesalahan: ' . $e->getMessage()], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Store a newly created resource in storage.
|
* Store a newly created resource in storage.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class RolesController extends Controller
|
|||||||
$query = $query->where('name', 'like', '%'. $request->get('search') . '%');
|
$query = $query->where('name', 'like', '%'. $request->get('search') . '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($query->paginate());
|
return response()->json($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,8 +4,15 @@ namespace App\Http\Controllers\Api;
|
|||||||
|
|
||||||
use App\Enums\ImportDatasourceStatus;
|
use App\Enums\ImportDatasourceStatus;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Jobs\ScrapingDataJob;
|
||||||
|
use App\Jobs\SyncronizeSIMBG;
|
||||||
use App\Models\ImportDatasource;
|
use App\Models\ImportDatasource;
|
||||||
use App\Traits\GlobalApiResponse;
|
use App\Traits\GlobalApiResponse;
|
||||||
|
use App\Services\ServiceTokenSIMBG;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use App\Services\ServiceGoogleSheet;
|
||||||
|
use App\Services\ServicePbgTask;
|
||||||
|
use App\Services\ServiceTabPbgTask;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -22,9 +29,12 @@ class ScrapingController extends Controller
|
|||||||
return $this->resError("Failed to execute while processing another scraping");
|
return $this->resError("Failed to execute while processing another scraping");
|
||||||
}
|
}
|
||||||
|
|
||||||
// run service artisan command
|
// use ole schema synchronization
|
||||||
Artisan::call("app:execute-scraping");
|
// dispatch(new SyncronizeSIMBG());
|
||||||
return $this->resSuccess("Success execute scraping service please wait");
|
|
||||||
|
// use new schema synchronization
|
||||||
|
dispatch(new ScrapingDataJob());
|
||||||
|
return $this->resSuccess(["message" => "Success execute scraping service on background, check status for more"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
64
app/Http/Controllers/Api/TaskAssignmentsController.php
Normal file
64
app/Http/Controllers/Api/TaskAssignmentsController.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\TaskAssignmentsResource;
|
||||||
|
use App\Models\TaskAssignment;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class TaskAssignmentsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request, $uuid)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$query = TaskAssignment::query()
|
||||||
|
->where('pbg_task_uid', $uuid)
|
||||||
|
->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($request->filled('search')) {
|
||||||
|
$query->where('name', 'like', "%{$request->get('search')}%")
|
||||||
|
->orWhere('email', 'like', "%{$request->get('search')}%");
|
||||||
|
}
|
||||||
|
|
||||||
|
return TaskAssignmentsResource::collection($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
|
}catch(\Exception $exception){
|
||||||
|
return response()->json(['message' => $exception->getMessage()], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,7 +39,7 @@ class TourismController extends Controller
|
|||||||
$tourisms->village_name = $village ? $village->village_name : null;
|
$tourisms->village_name = $village ? $village->village_name : null;
|
||||||
|
|
||||||
$district = DB::table('districts')->where('district_code', $tourisms->district_code)->first();
|
$district = DB::table('districts')->where('district_code', $tourisms->district_code)->first();
|
||||||
$tourisms->district_name = $village ? $village->village_name : null;
|
$tourisms->district_name = $district ? $district->district_name : null;
|
||||||
return $tourisms;
|
return $tourisms;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use App\Traits\GlobalApiResponse;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class UsersController extends Controller
|
class UsersController extends Controller
|
||||||
{
|
{
|
||||||
@@ -29,9 +30,10 @@ class UsersController extends Controller
|
|||||||
public function index(Request $request){
|
public function index(Request $request){
|
||||||
$query = User::query();
|
$query = User::query();
|
||||||
if($request->has('search') && !empty($request->get("search"))){
|
if($request->has('search') && !empty($request->get("search"))){
|
||||||
$query->where('name', 'LIKE', '%'.$request->get('search').'%');
|
$query->where('name', 'LIKE', '%'.$request->get('search').'%')
|
||||||
|
->orWhere('email', 'LIKE', '%'.$request->get('search').'%');
|
||||||
}
|
}
|
||||||
return UserResource::collection($query->paginate());
|
return UserResource::collection($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
}
|
}
|
||||||
public function logout(Request $request){
|
public function logout(Request $request){
|
||||||
$request->user()->tokens()->delete();
|
$request->user()->tokens()->delete();
|
||||||
@@ -83,4 +85,17 @@ class UsersController extends Controller
|
|||||||
return response()->json(['message' => $e->getMessage()],500);
|
return response()->json(['message' => $e->getMessage()],500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function destroy($id){
|
||||||
|
try{
|
||||||
|
$user = User::findOrFail($id);
|
||||||
|
DB::beginTransaction();
|
||||||
|
$user->delete();
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['message' => 'Successfully deleted'], 200);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
Log::error('Failed to delete user: '. $e->getMessage());
|
||||||
|
return response()->json(['message' => 'Failed to delete user'],500);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
65
app/Http/Controllers/Approval/ApprovalController.php
Normal file
65
app/Http/Controllers/Approval/ApprovalController.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Approval;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ApprovalController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('approval.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,8 +38,6 @@ class AuthenticatedSessionController extends Controller
|
|||||||
|
|
||||||
// Buat token untuk API
|
// Buat token untuk API
|
||||||
$token = $user->createToken(env('APP_KEY'))->plainTextToken;
|
$token = $user->createToken(env('APP_KEY'))->plainTextToken;
|
||||||
|
|
||||||
// Simpan token di session (bisa digunakan di JavaScript)
|
|
||||||
session(['api_token' => $token]);
|
session(['api_token' => $token]);
|
||||||
|
|
||||||
return redirect()->intended(RouteServiceProvider::HOME);
|
return redirect()->intended(RouteServiceProvider::HOME);
|
||||||
|
|||||||
48
app/Http/Controllers/BigdataResumesController.php
Normal file
48
app/Http/Controllers/BigdataResumesController.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class BigdataResumesController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('bigdata-resumes.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,63 +4,40 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use App\Models\BusinessOrIndustry;
|
use App\Models\BusinessOrIndustry;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class BusinessOrIndustriesController extends Controller
|
class BusinessOrIndustriesController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view('business-industries.index');
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
return view('business-industries.index', compact('creator', 'updater', 'destroyer','menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
return view("business-industries.create");
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
}
|
return view("business-industries.create", compact('menuId'));
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*/
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the specified resource.
|
|
||||||
*/
|
|
||||||
public function show(string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for editing the specified resource.
|
* Show the form for editing the specified resource.
|
||||||
*/
|
*/
|
||||||
public function edit(string $id)
|
public function edit(string $id, Request $request)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
$data = BusinessOrIndustry::findOrFail($id);
|
$data = BusinessOrIndustry::findOrFail($id);
|
||||||
return view('business-industries.edit', compact('data'));
|
return view('business-industries.edit', compact('data', 'menuId'));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the specified resource in storage.
|
|
||||||
*/
|
|
||||||
public function update(Request $request, string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*/
|
|
||||||
public function destroy(string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\ChatbotPimpinan;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ChatbotPimpinanController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('chatbot-pimpinan.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,54 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
abstract class Controller
|
abstract class Controller
|
||||||
{
|
{
|
||||||
//
|
protected array $permissions = [];
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
if (!Auth::check()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->setUserPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUserPermissions()
|
||||||
|
{
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$menus = $user->roles()
|
||||||
|
->with(['menus' => function ($query) {
|
||||||
|
$query->select('menus.id', 'menus.name')
|
||||||
|
->withPivot(['allow_show' ,'allow_create', 'allow_update', 'allow_destroy']);
|
||||||
|
}])
|
||||||
|
->get()
|
||||||
|
->pluck('menus')
|
||||||
|
->flatten()
|
||||||
|
->unique('id');
|
||||||
|
|
||||||
|
// Store permissions in an associative array
|
||||||
|
foreach ($menus as $menu) {
|
||||||
|
$this->permissions[$menu->id] = [
|
||||||
|
'allow_show' => $menu->pivot->allow_show ?? 0,
|
||||||
|
'allow_create' => $menu->pivot->allow_create ?? 0,
|
||||||
|
'allow_update' => $menu->pivot->allow_update ?? 0,
|
||||||
|
'allow_destroy' => $menu->pivot->allow_destroy ?? 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Share permissions globally in views
|
||||||
|
view()->share('permissions', $this->permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPermissions()
|
||||||
|
{
|
||||||
|
return $this->permissions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,23 +4,34 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class CustomersController extends Controller
|
class CustomersController extends Controller
|
||||||
{
|
{
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view('customers.index');
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view('customers.index', compact('creator', 'updater', 'destroyer', 'menuId'));
|
||||||
}
|
}
|
||||||
public function create()
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
return view('customers.create');
|
$menuId = $request->query('menu_id');
|
||||||
|
return view('customers.create', compact('menuId'));
|
||||||
}
|
}
|
||||||
public function edit(string $id)
|
public function edit(Request $request, string $id)
|
||||||
{
|
{
|
||||||
$data = Customer::findOrFail($id);
|
$data = Customer::findOrFail($id);
|
||||||
return view('customers.edit', compact('data'));
|
$menuId = $request->query('menu_id');
|
||||||
|
return view('customers.edit', compact('data', 'menuId'));
|
||||||
}
|
}
|
||||||
public function upload(){
|
public function upload(Request $request){
|
||||||
return view('customers.upload');
|
$menuId = $request->query('menu_id');
|
||||||
|
return view('customers.upload', compact('menuId'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
app/Http/Controllers/Dashboards/PotentialsController.php
Normal file
16
app/Http/Controllers/Dashboards/PotentialsController.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Dashboards;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class PotentialsController extends Controller
|
||||||
|
{
|
||||||
|
public function inside_system(){
|
||||||
|
return view('dashboards.potentials.inside_system');
|
||||||
|
}
|
||||||
|
public function outside_system(){
|
||||||
|
return view('dashboards.potentials.outside_system');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,15 +6,23 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\Models\Advertisement;
|
use App\Models\Advertisement;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class AdvertisementController extends Controller
|
class AdvertisementController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view('data.advertisements.index');
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$permissions = $this->permissions[$menuId] ?? []; // Avoid undefined index error
|
||||||
|
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view('data.advertisements.index', compact('creator', 'updater', 'destroyer','menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,8 +37,9 @@ class AdvertisementController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
$title = 'Advertisement';
|
$title = 'Advertisement';
|
||||||
$subtitle = 'Create Data';
|
$subtitle = 'Create Data';
|
||||||
|
|
||||||
@@ -47,14 +56,15 @@ class AdvertisementController extends Controller
|
|||||||
|
|
||||||
// $route = 'advertisements.create';
|
// $route = 'advertisements.create';
|
||||||
// info("AdvertisementController@edit diakses dengan ID: $title");
|
// info("AdvertisementController@edit diakses dengan ID: $title");
|
||||||
return view('data.advertisements.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
|
return view('data.advertisements.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions','menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for editing the specified resource.
|
* Show the form for editing the specified resource.
|
||||||
*/
|
*/
|
||||||
public function edit($id)
|
public function edit(Request $request, $id)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
info("AdvertisementController@edit diakses dengan ID: $id");
|
info("AdvertisementController@edit diakses dengan ID: $id");
|
||||||
$title = 'Advertisement';
|
$title = 'Advertisement';
|
||||||
$subtitle = 'Update Data';
|
$subtitle = 'Update Data';
|
||||||
@@ -62,7 +72,7 @@ class AdvertisementController extends Controller
|
|||||||
// Pastikan model ditemukan
|
// Pastikan model ditemukan
|
||||||
if (!$modelInstance) {
|
if (!$modelInstance) {
|
||||||
info("AdvertisementController@edit: Model tidak ditemukan.");
|
info("AdvertisementController@edit: Model tidak ditemukan.");
|
||||||
return redirect()->route('advertisements.index')->with('error', 'Advertisement not found');
|
return redirect()->route('web.advertisements.index')->with('error', 'Advertisement not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mengambil dan memetakan village_name dan district_name
|
// Mengambil dan memetakan village_name dan district_name
|
||||||
@@ -86,7 +96,7 @@ class AdvertisementController extends Controller
|
|||||||
|
|
||||||
// $route = 'advertisements.update'; // Menggunakan route update untuk form edit
|
// $route = 'advertisements.update'; // Menggunakan route update untuk form edit
|
||||||
// info("AdvertisementController@edit diakses dengan route: $route");
|
// info("AdvertisementController@edit diakses dengan route: $route");
|
||||||
return view('data.advertisements.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
|
return view('data.advertisements.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFields()
|
private function getFields()
|
||||||
|
|||||||
36
app/Http/Controllers/Data/GoogleSheetsController.php
Normal file
36
app/Http/Controllers/Data/GoogleSheetsController.php
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Data;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class GoogleSheetsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$menu_id = $request->query('menu_id');
|
||||||
|
$user_menu_permission = $this->permissions[$menu_id];
|
||||||
|
return view('data.google-sheet.index', compact('user_menu_permission'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('data.google-sheet.create');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
$data = PbgTaskGoogleSheet::find($id);
|
||||||
|
return view('data.google-sheet.show', compact('data'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
return view('data.google-sheet.edit');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,24 +11,33 @@ class SpatialPlanningController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view('data.spatialPlannings.index');
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$permissions = $this->permissions[$menuId] ?? []; // Avoid undefined index error
|
||||||
|
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view('data.spatialPlannings.index', compact('creator', 'updater', 'destroyer','menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show the form for creating a new resource.
|
* show the form for creating a new resource.
|
||||||
*/
|
*/
|
||||||
public function bulkCreate()
|
public function bulkCreate(Request $request)
|
||||||
{
|
{
|
||||||
return view('data.spatialPlannings.form-upload');
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
return view('data.spatialPlannings.form-upload', compact('menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
$title = 'Rencana Tata Ruang';
|
$title = 'Rencana Tata Ruang';
|
||||||
$subtitle = "Create Data";
|
$subtitle = "Create Data";
|
||||||
|
|
||||||
@@ -39,30 +48,15 @@ class SpatialPlanningController extends Controller
|
|||||||
$fieldTypes = $this->getFieldTypes();
|
$fieldTypes = $this->getFieldTypes();
|
||||||
|
|
||||||
$apiUrl = url('/api/spatial-plannings');
|
$apiUrl = url('/api/spatial-plannings');
|
||||||
return view('data.spatialPlannings.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
|
return view('data.spatialPlannings.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions','menuId'));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*/
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the specified resource.
|
|
||||||
*/
|
|
||||||
public function show(string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for editing the specified resource.
|
* Show the form for editing the specified resource.
|
||||||
*/
|
*/
|
||||||
public function edit(string $id)
|
public function edit(Request $request,string $id)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
$title = 'Rencana Tata Ruang';
|
$title = 'Rencana Tata Ruang';
|
||||||
$subtitle = 'Update Data';
|
$subtitle = 'Update Data';
|
||||||
|
|
||||||
@@ -78,23 +72,7 @@ class SpatialPlanningController extends Controller
|
|||||||
$fieldTypes = $this->getFieldTypes();
|
$fieldTypes = $this->getFieldTypes();
|
||||||
|
|
||||||
$apiUrl = url('/api/spatial-plannings');
|
$apiUrl = url('/api/spatial-plannings');
|
||||||
return view('data.spatialPlannings.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
|
return view('data.spatialPlannings.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions','menuId'));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the specified resource in storage.
|
|
||||||
*/
|
|
||||||
public function update(Request $request, string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*/
|
|
||||||
public function destroy(string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFields()
|
private function getFields()
|
||||||
|
|||||||
@@ -6,30 +6,39 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\Models\Tourism;
|
use App\Models\Tourism;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class TourismController extends Controller
|
class TourismController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource
|
* Display a listing of the resource
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view('data.tourisms.index');
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$permissions = $this->permissions[$menuId] ?? []; // Avoid undefined index error
|
||||||
|
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
return view('data.tourisms.index', compact('creator', 'updater', 'destroyer', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show the form for creating a new rsource.
|
* show the form for creating a new rsource.
|
||||||
*/
|
*/
|
||||||
public function bulkCreate()
|
public function bulkCreate(Request $request)
|
||||||
{
|
{
|
||||||
return view('data.tourisms.form-upload');
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
return view('data.tourisms.form-upload', compact('menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show th form for creating a new resource
|
* Show th form for creating a new resource
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
$title = 'Pariwisata';
|
$title = 'Pariwisata';
|
||||||
$subtitle = 'Create Data';
|
$subtitle = 'Create Data';
|
||||||
|
|
||||||
@@ -44,21 +53,22 @@ class TourismController extends Controller
|
|||||||
|
|
||||||
$apiUrl = url('/api/tourisms');
|
$apiUrl = url('/api/tourisms');
|
||||||
|
|
||||||
return view('data.tourisms.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
|
return view('data.tourisms.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show the form for editing the specified resource.
|
* show the form for editing the specified resource.
|
||||||
*/
|
*/
|
||||||
public function edit($id)
|
public function edit(Request $request, $id)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
$title = 'Pariwisata';
|
$title = 'Pariwisata';
|
||||||
$subtitle = 'Update Data';
|
$subtitle = 'Update Data';
|
||||||
|
|
||||||
$modelInstance = Tourism::find($id);
|
$modelInstance = Tourism::find($id);
|
||||||
// Pastikan model ditemukan
|
// Pastikan model ditemukan
|
||||||
if (!$modelInstance) {
|
if (!$modelInstance) {
|
||||||
return redirect()->route('tourisms.index') ->with('error', 'Pariwisata tidak ditemukan');
|
return redirect()->route('web-tourisms.index') ->with('error', 'Pariwisata tidak ditemukan');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mengambil dan memetakan village_name dan district_name
|
// Mengambil dan memetakan village_name dan district_name
|
||||||
@@ -78,7 +88,7 @@ class TourismController extends Controller
|
|||||||
|
|
||||||
$apiUrl = url('/api/tourisms');
|
$apiUrl = url('/api/tourisms');
|
||||||
|
|
||||||
return view('data.tourisms.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
|
return view('data.tourisms.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFields()
|
private function getFields()
|
||||||
|
|||||||
@@ -6,30 +6,39 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\Models\Umkm;
|
use App\Models\Umkm;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class UmkmController extends Controller
|
class UmkmController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view('data.umkm.index');
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$permissions = $this->permissions[$menuId] ?? []; // Avoid undefined index error
|
||||||
|
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
return view('data.umkm.index', compact('creator', 'updater', 'destroyer', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*/
|
*/
|
||||||
public function bulkCreate()
|
public function bulkCreate(Request $request)
|
||||||
{
|
{
|
||||||
return view('data.umkm.form-upload');
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
return view('data.umkm.form-upload', compact('menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
$title = 'UMKM';
|
$title = 'UMKM';
|
||||||
$subtitle = 'Create Data';
|
$subtitle = 'Create Data';
|
||||||
|
|
||||||
@@ -47,20 +56,21 @@ class UmkmController extends Controller
|
|||||||
|
|
||||||
$apiUrl = url('/api/umkm');
|
$apiUrl = url('/api/umkm');
|
||||||
|
|
||||||
return view('data.umkm.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
|
return view('data.umkm.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions','menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for editing the specified resource.
|
* Show the form for editing the specified resource.
|
||||||
*/
|
*/
|
||||||
public function edit($id)
|
public function edit(Request $request,$id)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
$title = 'UMKM';
|
$title = 'UMKM';
|
||||||
$subtitle = 'Update Data';
|
$subtitle = 'Update Data';
|
||||||
$modelInstance = Umkm::find($id);
|
$modelInstance = Umkm::find($id);
|
||||||
// Pastikan model ditemukan
|
// Pastikan model ditemukan
|
||||||
if (!$modelInstance) {
|
if (!$modelInstance) {
|
||||||
return redirect()->route('umkm.index')->with('error', 'Umkm not found');
|
return redirect()->route('web-umkm.index')->with('error', 'Umkm not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mengambil dan memetakan village_name dan district_name
|
// Mengambil dan memetakan village_name dan district_name
|
||||||
@@ -96,7 +106,7 @@ class UmkmController extends Controller
|
|||||||
$apiUrl = url('/api/umkm');
|
$apiUrl = url('/api/umkm');
|
||||||
|
|
||||||
// dd($modelInstance->business_form_id, $dropdownOptions['business_form']);
|
// dd($modelInstance->business_form_id, $dropdownOptions['business_form']);
|
||||||
return view('data.umkm.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
|
return view('data.umkm.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions','menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFields()
|
private function getFields()
|
||||||
|
|||||||
@@ -8,23 +8,31 @@ use Exception;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Request;
|
use Illuminate\Support\Facades\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Http\Request as IndexRequest;
|
||||||
|
|
||||||
class DataSettingController extends Controller
|
class DataSettingController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(IndexRequest $request)
|
||||||
{
|
{
|
||||||
return view("data-settings.index");
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
return view("data-settings.index", compact('creator', 'updater', 'destroyer','menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create(IndexRequest $request)
|
||||||
{
|
{
|
||||||
return view("data-settings.create");
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
return view("data-settings.create", compact('menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,14 +65,15 @@ class DataSettingController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Show the form for editing the specified resource.
|
* Show the form for editing the specified resource.
|
||||||
*/
|
*/
|
||||||
public function edit(string $id)
|
public function edit(IndexRequest $request,string $id)
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
$data = DataSetting::findOrFail($id);
|
$data = DataSetting::findOrFail($id);
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
if(empty($data)){
|
if(empty($data)){
|
||||||
return redirect()->route('data-settings.index')->with('error', 'Invalid id');
|
return redirect()->route('data-settings.index')->with('error', 'Invalid id');
|
||||||
}
|
}
|
||||||
return view("data-settings.edit", compact("data"));
|
return view("data-settings.edit", compact("data", 'menuId'));
|
||||||
}catch(Exception $ex){
|
}catch(Exception $ex){
|
||||||
return redirect()->route("data-settings.index")->with("error", "Invalid id");
|
return redirect()->route("data-settings.index")->with("error", "Invalid id");
|
||||||
}
|
}
|
||||||
|
|||||||
12
app/Http/Controllers/InvitationsController.php
Normal file
12
app/Http/Controllers/InvitationsController.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class InvitationsController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request){
|
||||||
|
return view('invitations.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ use Illuminate\Support\Facades\Hash;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Traits\GlobalApiResponse;
|
use App\Traits\GlobalApiResponse;
|
||||||
use Illuminate\Auth\Events\Registered;
|
use Illuminate\Auth\Events\Registered;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class UsersController extends Controller
|
class UsersController extends Controller
|
||||||
{
|
{
|
||||||
@@ -21,13 +22,20 @@ class UsersController extends Controller
|
|||||||
$users = User::all();
|
$users = User::all();
|
||||||
return $this->resSuccess($users);
|
return $this->resSuccess($users);
|
||||||
}
|
}
|
||||||
public function index(){
|
public function index(Request $request){
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
$users = User::paginate();
|
$users = User::paginate();
|
||||||
return view('master.users.index', compact('users'));
|
return view('master.users.index', compact('users', 'creator', 'updater', 'destroyer','menuId'));
|
||||||
}
|
}
|
||||||
public function create(){
|
public function create(Request $request){
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
$roles = Role::all();
|
$roles = Role::all();
|
||||||
return view('master.users.create', compact('roles'));
|
return view('master.users.create', compact('roles', 'menuId'));
|
||||||
}
|
}
|
||||||
public function store(UsersRequest $request){
|
public function store(UsersRequest $request){
|
||||||
$request->validate([
|
$request->validate([
|
||||||
@@ -65,10 +73,11 @@ class UsersController extends Controller
|
|||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
return view('master.users.show', compact('user'));
|
return view('master.users.show', compact('user'));
|
||||||
}
|
}
|
||||||
public function edit($id){
|
public function edit(Request $request, $id){
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
$roles = Role::all();
|
$roles = Role::all();
|
||||||
return view('master.users.edit', compact('user', 'roles'));
|
return view('master.users.edit', compact('user', 'roles', 'menuId'));
|
||||||
}
|
}
|
||||||
public function update(Request $request, $id){
|
public function update(Request $request, $id){
|
||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
|
|||||||
@@ -12,18 +12,35 @@ class MenusController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view('menus.index');
|
$menuId = (int) $request->query('menu_id', 0);
|
||||||
|
$permissions = $this->permissions[$menuId] ?? []; // Avoid undefined index error
|
||||||
|
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view('menus.index', compact('creator', 'updater', 'destroyer', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$parent_menus = Menu::whereNull('parent_id')->get();
|
$menuId = $request->query('menu_id'); // Get menu_id from request
|
||||||
return view("menus.create", compact('parent_menus'));
|
$menu = Menu::with('children')->find($menuId); // Find the menu
|
||||||
|
|
||||||
|
// Get IDs of all child menus to exclude
|
||||||
|
$excludedIds = $menu ? $this->getChildMenuIds($menu) : [$menuId];
|
||||||
|
|
||||||
|
// Fetch only menus that have children and are not in the excluded list
|
||||||
|
$parent_menus = Menu::whereHas('children')
|
||||||
|
->whereNotIn('id', $excludedIds)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return view("menus.create", compact('parent_menus', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,11 +73,16 @@ class MenusController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Show the form for editing the specified resource.
|
* Show the form for editing the specified resource.
|
||||||
*/
|
*/
|
||||||
public function edit(string $id)
|
public function edit(string $id, Request $request)
|
||||||
{
|
{
|
||||||
$menu = Menu::findOrFail($id);
|
$menuId = $request->query('menu_id');
|
||||||
$parent_menus = Menu::whereNull('parent_id')->where('id','!=',$id)->get();
|
$menu = Menu::with('children')->find($id);
|
||||||
return view("menus.edit", compact('menu','parent_menus'));
|
$excludedIds = $menu ? $this->getChildMenuIds($menu) : [$id];
|
||||||
|
|
||||||
|
$parent_menus = Menu::whereHas('children')
|
||||||
|
->whereNotIn('id', $excludedIds)
|
||||||
|
->get();
|
||||||
|
return view("menus.edit", compact('menu','parent_menus', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,4 +132,15 @@ class MenusController extends Controller
|
|||||||
$child->delete();
|
$child->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getChildMenuIds($menu)
|
||||||
|
{
|
||||||
|
$ids = [$menu->id]; // Start with current menu ID
|
||||||
|
|
||||||
|
foreach ($menu->children as $child) {
|
||||||
|
$ids = array_merge($ids, $this->getChildMenuIds($child)); // Recursively fetch children
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
64
app/Http/Controllers/PaymentRecapsController.php
Normal file
64
app/Http/Controllers/PaymentRecapsController.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class PaymentRecapsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('payment-recaps.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,6 @@ class ReportTourismController extends Controller
|
|||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$tourismBasedKBLI = TourismBasedKBLI::all();
|
$tourismBasedKBLI = TourismBasedKBLI::all();
|
||||||
info($tourismBasedKBLI);
|
|
||||||
return view('report.tourisms.index', compact('tourismBasedKBLI'));
|
return view('report.tourisms.index', compact('tourismBasedKBLI'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
12
app/Http/Controllers/ReportPaymentRecapsController.php
Normal file
12
app/Http/Controllers/ReportPaymentRecapsController.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ReportPaymentRecapsController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request){
|
||||||
|
return view('report-payment-recaps.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
12
app/Http/Controllers/ReportPbgPTSPController.php
Normal file
12
app/Http/Controllers/ReportPbgPTSPController.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ReportPbgPTSPController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request){
|
||||||
|
return view('report-pbg-ptsp.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,15 +5,37 @@ namespace App\Http\Controllers\RequestAssignment;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\PbgTask;
|
use App\Models\PbgTask;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class PbgTaskController extends Controller
|
class PbgTaskController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view('pbg_task.index');
|
$menuId = $request->query('menu_id');
|
||||||
|
$user = Auth::user();
|
||||||
|
$userId = $user->id;
|
||||||
|
|
||||||
|
// Ambil role_id yang dimiliki user
|
||||||
|
$roleIds = DB::table('user_role')
|
||||||
|
->where('user_id', $userId)
|
||||||
|
->pluck('role_id');
|
||||||
|
|
||||||
|
// Ambil data akses berdasarkan role_id dan menu_id
|
||||||
|
$roleAccess = DB::table('role_menu')
|
||||||
|
->whereIn('role_id', $roleIds)
|
||||||
|
->where('menu_id', $menuId)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// Pastikan roleAccess tidak null sebelum mengakses properti
|
||||||
|
$creator = $roleAccess->allow_create ?? 0;
|
||||||
|
$updater = $roleAccess->allow_update ?? 0;
|
||||||
|
$destroyer = $roleAccess->allow_destroy ?? 0;
|
||||||
|
|
||||||
|
return view('pbg_task.index', compact('creator', 'updater', 'destroyer'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,23 +10,31 @@ use Illuminate\Http\Request;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class RolesController extends Controller
|
class RolesController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view("roles.index");
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view("roles.index", compact('creator', 'updater', 'destroyer', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
return view("roles.create");
|
$menuId = $request->query('menu_id');
|
||||||
|
return view("roles.create", compact('menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,10 +67,11 @@ class RolesController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Show the form for editing the specified resource.
|
* Show the form for editing the specified resource.
|
||||||
*/
|
*/
|
||||||
public function edit(string $id)
|
public function edit(string $id, Request $request)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
$role = Role::findOrFail($id);
|
$role = Role::findOrFail($id);
|
||||||
return view("roles.edit", compact('role'));
|
return view("roles.edit", compact('role', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,12 +109,13 @@ class RolesController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function menu_permission(string $role_id){
|
public function menu_permission(string $role_id, Request $request){
|
||||||
try{
|
try{
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
$role = Role::findOrFail($role_id);
|
$role = Role::findOrFail($role_id);
|
||||||
$menus = Menu::all();
|
$menus = Menu::all();
|
||||||
$role_menus = RoleMenu::where('role_id', $role_id)->get() ?? collect();
|
$role_menus = RoleMenu::where('role_id', $role_id)->get() ?? collect();
|
||||||
return view('roles.role_menu', compact('role', 'menus', 'role_menus'));
|
return view('roles.role_menu', compact('role', 'menus', 'role_menus', 'menuId'));
|
||||||
}catch(\Exception $e){
|
}catch(\Exception $e){
|
||||||
return redirect()->back()->with("error", $e->getMessage());
|
return redirect()->back()->with("error", $e->getMessage());
|
||||||
}
|
}
|
||||||
@@ -113,8 +123,9 @@ class RolesController extends Controller
|
|||||||
|
|
||||||
public function update_menu_permission(Request $request, string $role_id){
|
public function update_menu_permission(Request $request, string $role_id){
|
||||||
try{
|
try{
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
$validateData = $request->validate([
|
$validateData = $request->validate([
|
||||||
"permissions" => "array",
|
"permissions" => "nullable|array",
|
||||||
"permissions.*.allow_show" => "nullable|boolean",
|
"permissions.*.allow_show" => "nullable|boolean",
|
||||||
"permissions.*.allow_create" => "nullable|boolean",
|
"permissions.*.allow_create" => "nullable|boolean",
|
||||||
"permissions.*.allow_update" => "nullable|boolean",
|
"permissions.*.allow_update" => "nullable|boolean",
|
||||||
@@ -123,6 +134,13 @@ class RolesController extends Controller
|
|||||||
|
|
||||||
$role = Role::find($role_id);
|
$role = Role::find($role_id);
|
||||||
|
|
||||||
|
// Jika `permissions` tidak ada atau kosong, hapus semua permissions terkait
|
||||||
|
if (!isset($validateData['permissions']) || empty($validateData['permissions'])) {
|
||||||
|
$role->menus()->detach();
|
||||||
|
return redirect()->route("roles.index", ['menu_id' => $menuId])
|
||||||
|
->with('success', 'All menu permissions have been removed.');
|
||||||
|
}
|
||||||
|
|
||||||
$permissionsArray = [];
|
$permissionsArray = [];
|
||||||
foreach ($validateData['permissions'] as $menu_id => $permission) {
|
foreach ($validateData['permissions'] as $menu_id => $permission) {
|
||||||
$permissionsArray[$menu_id] = [
|
$permissionsArray[$menu_id] = [
|
||||||
@@ -137,7 +155,7 @@ class RolesController extends Controller
|
|||||||
// Sync will update existing records and insert new ones
|
// Sync will update existing records and insert new ones
|
||||||
$role->menus()->sync($permissionsArray);
|
$role->menus()->sync($permissionsArray);
|
||||||
|
|
||||||
return redirect()->route("role-menu.permission", $role_id)->with('success','Menu Permission updated successfully');
|
return redirect()->route("roles.index", ['menu_id' => $menuId])->with('success','Menu Permission updated successfully');
|
||||||
}catch(\Exception $e){
|
}catch(\Exception $e){
|
||||||
Log::error("Error updating role_menu:", ["error" => $e->getMessage()]);
|
Log::error("Error updating role_menu:", ["error" => $e->getMessage()]);
|
||||||
return redirect()->route("role-menu.permission", $role_id)->with("error", $e->getMessage());
|
return redirect()->route("role-menu.permission", $role_id)->with("error", $e->getMessage());
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\Services\ServiceSIMBG;
|
use App\Services\ServiceSIMBG;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
class SyncronizeController extends Controller
|
class SyncronizeController extends Controller
|
||||||
{
|
{
|
||||||
protected $service_simbg;
|
protected $service_simbg;
|
||||||
@@ -13,16 +15,36 @@ class SyncronizeController extends Controller
|
|||||||
$this->service_simbg = $service_simbg;
|
$this->service_simbg = $service_simbg;
|
||||||
}
|
}
|
||||||
public function index(Request $request){
|
public function index(Request $request){
|
||||||
return view('settings.syncronize.index');
|
$menuId = $request->query('menu_id');
|
||||||
|
$user = Auth::user();
|
||||||
|
$userId = $user->id;
|
||||||
|
|
||||||
|
// Ambil role_id yang dimiliki user
|
||||||
|
$roleIds = DB::table('user_role')
|
||||||
|
->where('user_id', $userId)
|
||||||
|
->pluck('role_id');
|
||||||
|
|
||||||
|
// Ambil data akses berdasarkan role_id dan menu_id
|
||||||
|
$roleAccess = DB::table('role_menu')
|
||||||
|
->whereIn('role_id', $roleIds)
|
||||||
|
->where('menu_id', $menuId)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// Pastikan roleAccess tidak null sebelum mengakses properti
|
||||||
|
$creator = $roleAccess->allow_create ?? 0;
|
||||||
|
$updater = $roleAccess->allow_update ?? 0;
|
||||||
|
$destroyer = $roleAccess->allow_destroy ?? 0;
|
||||||
|
|
||||||
|
return view('settings.syncronize.index', compact('creator', 'updater', 'destroyer'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncPbgTask(){
|
public function syncPbgTask(){
|
||||||
$res = $this->service_simbg->syncTaskList();
|
$res = $this->service_simbg->syncTaskPBG();
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncronizeTask(Request $request){
|
public function syncronizeTask(Request $request){
|
||||||
$res = $this->service_simbg->syncTaskList();
|
$res = $this->service_simbg->syncTaskPBG();
|
||||||
return redirect()->back()->with('success', 'Processing completed successfully');
|
return redirect()->back()->with('success', 'Processing completed successfully');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +55,7 @@ class SyncronizeController extends Controller
|
|||||||
|
|
||||||
public function syncIndexIntegration(Request $request, $uuid){
|
public function syncIndexIntegration(Request $request, $uuid){
|
||||||
$token = $request->get('token');
|
$token = $request->get('token');
|
||||||
$res = $this->service_simbg->syncIndexIntegration($uuid, $token);
|
$res = $this->service_simbg->syncIndexIntegration($uuid);
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,4 +64,9 @@ class SyncronizeController extends Controller
|
|||||||
$res = $this->service_simbg->syncTaskDetailSubmit($uuid, $token);
|
$res = $this->service_simbg->syncTaskDetailSubmit($uuid, $token);
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function syncTaskAssignments($uuid){
|
||||||
|
$res = $this->service_simbg->syncTaskAssignments($uuid);
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
app/Http/Controllers/TpatptsController.php
Normal file
28
app/Http/Controllers/TpatptsController.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class TpatptsController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('tpa-tpt.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
51
app/Http/Resources/BigdataResumeResource.php
Normal file
51
app/Http/Resources/BigdataResumeResource.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class BigdataResumeResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'import_datasource_id' => $this->import_datasource_id,
|
||||||
|
'potention_count' => (int) $this->potention_count,
|
||||||
|
'potention_sum' => number_format((float) $this->potention_sum, 2, ',', '.'),
|
||||||
|
|
||||||
|
'non_verified_count' => (int) $this->non_verified_count,
|
||||||
|
'non_verified_sum' => number_format((float) $this->non_verified_sum, 2, ',', '.'),
|
||||||
|
|
||||||
|
'verified_count' => (int) $this->verified_count,
|
||||||
|
'verified_sum' => number_format((float) $this->verified_sum, 2, ',', '.'),
|
||||||
|
|
||||||
|
'business_count' => (int) $this->business_count,
|
||||||
|
'business_sum' => number_format((float) $this->business_sum, 2, ',', '.'),
|
||||||
|
|
||||||
|
'non_business_count' => (int) $this->non_business_count,
|
||||||
|
'non_business_sum' => number_format((float) $this->non_business_sum, 2, ',', '.'),
|
||||||
|
|
||||||
|
'spatial_count' => (int) $this->spatial_count,
|
||||||
|
'spatial_sum' => number_format((float) $this->spatial_sum, 2, ',', '.'),
|
||||||
|
|
||||||
|
'issuance_realization_pbg_count' => (int) $this->issuance_realization_pbg_count,
|
||||||
|
'issuance_realization_pbg_sum' => number_format((float) $this->issuance_realization_pbg_sum, 2, ',', '.'),
|
||||||
|
|
||||||
|
'waiting_click_dpmptsp_count' => (int) $this->waiting_click_dpmptsp_count,
|
||||||
|
'waiting_click_dpmptsp_sum' => number_format((float) $this->waiting_click_dpmptsp_sum, 2, ',', '.'),
|
||||||
|
|
||||||
|
'process_in_technical_office_count' => (int) $this->process_in_technical_office_count,
|
||||||
|
'process_in_technical_office_sum' => number_format((float) $this->process_in_technical_office_sum, 2, ',', '.'),
|
||||||
|
|
||||||
|
'year' => $this->year,
|
||||||
|
'created_at' => $this->created_at->toDateTimeString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Resources;
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
@@ -14,11 +15,18 @@ class ImportDatasourceResource extends JsonResource
|
|||||||
*/
|
*/
|
||||||
public function toArray(Request $request): array
|
public function toArray(Request $request): array
|
||||||
{
|
{
|
||||||
|
$startTime = $this->start_time ? Carbon::parse($this->start_time) : null;
|
||||||
|
$finishTime = $this->finish_time ? Carbon::parse($this->finish_time) : null;
|
||||||
return [
|
return [
|
||||||
"id"=> $this->id,
|
"id"=> $this->id,
|
||||||
"message" => $this->message,
|
"message" => $this->message,
|
||||||
"response_body" => $this->response_body,
|
"response_body" => $this->response_body,
|
||||||
"status" => $this->status,
|
"status" => $this->status,
|
||||||
|
"start_time" => $startTime ? $startTime->toDateTimeString() : null,
|
||||||
|
"duration" => ($startTime && $finishTime)
|
||||||
|
? $finishTime->diff($startTime)->format('%H:%I:%S')
|
||||||
|
: null,
|
||||||
|
"finish_time" => $finishTime ? $finishTime->toDateTimeString() : null,
|
||||||
"created_at" => $this->created_at->toDateTimeString(),
|
"created_at" => $this->created_at->toDateTimeString(),
|
||||||
"updated_at" => $this->updated_at->toDateTimeString(),
|
"updated_at" => $this->updated_at->toDateTimeString(),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -14,6 +14,16 @@ class MenuResource extends JsonResource
|
|||||||
*/
|
*/
|
||||||
public function toArray(Request $request): array
|
public function toArray(Request $request): array
|
||||||
{
|
{
|
||||||
return parent::toArray($request);
|
// return parent::toArray($request);
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'name' => $this->name,
|
||||||
|
'icon' => $this->icon,
|
||||||
|
'url' => $this->url,
|
||||||
|
'sort_order' => $this->sort_order,
|
||||||
|
'parent' => $this->parent ? new MenuResource($this->parent) : null,
|
||||||
|
'created_at' => $this->created_at,
|
||||||
|
'updated_at' => $this->updated_at
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
app/Http/Resources/PbgTaskGoogleSheetResource.php
Normal file
19
app/Http/Resources/PbgTaskGoogleSheetResource.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class PbgTaskGoogleSheetResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/TaskAssignmentsResource.php
Normal file
19
app/Http/Resources/TaskAssignmentsResource.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class TaskAssignmentsResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,37 +3,105 @@
|
|||||||
namespace App\Imports;
|
namespace App\Imports;
|
||||||
|
|
||||||
use App\Models\BusinessOrIndustry;
|
use App\Models\BusinessOrIndustry;
|
||||||
use Maatwebsite\Excel\Concerns\ToModel;
|
|
||||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithChunkReading;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithBatchInserts;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class BusinessIndustriesImport implements ToCollection
|
class BusinessIndustriesImport implements ToCollection, WithMultipleSheets, WithChunkReading, WithBatchInserts, ShouldQueue, WithHeadingRow
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param array $row
|
* @param Collection $collection
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Model|null
|
|
||||||
*/
|
*/
|
||||||
public function collection(Collection $rows)
|
public function collection(Collection $collection)
|
||||||
{
|
{
|
||||||
foreach ($rows->skip(1) as $row){
|
try{
|
||||||
$clean_nop = preg_replace('/[^A-Za-z0-9]/', '', $row[2]);
|
$batchData = [];
|
||||||
if (!BusinessOrIndustry::where('nop', $clean_nop)->exists()) {
|
$batchSize = 1000;
|
||||||
BusinessOrIndustry::create([
|
|
||||||
'nama_kecamatan' => $row[0],
|
foreach ($collection as $row){
|
||||||
'nama_kelurahan' => $row[1],
|
if(!isset($row['nop']) || empty($row['nop'])){
|
||||||
'nop' => $clean_nop, // Store cleaned 'nop'
|
continue;
|
||||||
'nama_wajib_pajak' => $row[3],
|
}
|
||||||
'alamat_wajib_pajak' => $row[4],
|
|
||||||
'alamat_objek_pajak' => $row[5],
|
|
||||||
'luas_bumi' => $row[6],
|
$clean_nop = preg_replace('/[^A-Za-z0-9]/', '', $row['nop']);
|
||||||
'luas_bangunan' => $row[7],
|
|
||||||
'njop_bumi' => $row[8],
|
$batchData[] = [
|
||||||
'njop_bangunan' => $row[9],
|
'nama_kecamatan' => $row['nama_kecamatan'],
|
||||||
'ketetapan' => $row[10],
|
'nama_kelurahan' => $row['nama_kelurahan'],
|
||||||
'tahun_pajak' => $row[11],
|
'nop' => $clean_nop,
|
||||||
|
'nama_wajib_pajak' => $row['nama_wajib_pajak'],
|
||||||
|
'alamat_wajib_pajak' => $row['alamat_wajib_pajak'],
|
||||||
|
'alamat_objek_pajak' => $row['alamat_objek_pajak'],
|
||||||
|
'luas_bumi' => $row['luas_bumi'],
|
||||||
|
'luas_bangunan' => $row['luas_bangunan'],
|
||||||
|
'njop_bumi' => $row['njop_bumi'],
|
||||||
|
'njop_bangunan' => $row['njop_bangunan'],
|
||||||
|
'ketetapan' => $row['ketetapan'],
|
||||||
|
'tahun_pajak' => $row['tahun_pajak'],
|
||||||
|
];
|
||||||
|
|
||||||
|
if(count($batchData) >= $batchSize){
|
||||||
|
BusinessOrIndustry::upsert($batchData, ['nop'], [
|
||||||
|
'nama_kecamatan',
|
||||||
|
'nama_kelurahan',
|
||||||
|
'nama_wajib_pajak',
|
||||||
|
'alamat_wajib_pajak',
|
||||||
|
'alamat_objek_pajak',
|
||||||
|
'luas_bumi',
|
||||||
|
'luas_bangunan',
|
||||||
|
'njop_bumi',
|
||||||
|
'njop_bangunan',
|
||||||
|
'ketetapan',
|
||||||
|
'tahun_pajak',
|
||||||
|
]);
|
||||||
|
$batchData = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!empty($batchData)){
|
||||||
|
BusinessOrIndustry::upsert($batchData, ['nop'], [
|
||||||
|
'nama_kecamatan',
|
||||||
|
'nama_kelurahan',
|
||||||
|
'nama_wajib_pajak',
|
||||||
|
'alamat_wajib_pajak',
|
||||||
|
'alamat_objek_pajak',
|
||||||
|
'luas_bumi',
|
||||||
|
'luas_bangunan',
|
||||||
|
'njop_bumi',
|
||||||
|
'njop_bangunan',
|
||||||
|
'ketetapan',
|
||||||
|
'tahun_pajak',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
}catch(\Exception $exception){
|
||||||
|
Log::error('Error while importing Business Industries data:', ['error' => $exception->getMessage()]);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function sheets(): array {
|
||||||
|
return [
|
||||||
|
0 => $this
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headingRow(): int
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function chunkSize(): int
|
||||||
|
{
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function batchSize(): int
|
||||||
|
{
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
|||||||
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Maatwebsite\Excel\Concerns\WithBatchInserts;
|
use Maatwebsite\Excel\Concerns\WithBatchInserts;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class CustomersImport implements ToCollection, WithMultipleSheets
|
class CustomersImport implements ToCollection, WithMultipleSheets, WithChunkReading, WithBatchInserts, ShouldQueue, WithHeadingRow
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param Collection $collection
|
* @param Collection $collection
|
||||||
@@ -20,23 +21,51 @@ class CustomersImport implements ToCollection, WithMultipleSheets
|
|||||||
public function collection(Collection $collection)
|
public function collection(Collection $collection)
|
||||||
{
|
{
|
||||||
$batchData = [];
|
$batchData = [];
|
||||||
|
$batchSize = 1000;
|
||||||
|
|
||||||
foreach ($collection->skip(1) as $row) {
|
foreach ($collection as $row) {
|
||||||
if (!isset($row[0]) || empty($row[0])) {
|
if (!isset($row['nomor_pelanggan']) || empty($row['nomor_pelanggan'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$latitude = filter_var($row[4], FILTER_VALIDATE_FLOAT) ? bcadd($row[4], '0', 18) : null;
|
$latitude = '0';
|
||||||
$longitude = filter_var($row[5], FILTER_VALIDATE_FLOAT) ? bcadd($row[5], '0', 18) : null;
|
$longitude = '0';
|
||||||
|
|
||||||
|
if (isset($row['latkor']) && !empty(trim($row['latkor']))) {
|
||||||
|
$latitude = str_replace(',', '.', trim($row['latkor']));
|
||||||
|
if (is_numeric($latitude)) {
|
||||||
|
$latitude = bcadd($latitude, '0', 18);
|
||||||
|
} else {
|
||||||
|
$latitude = '0';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$latitude = '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($row['lonkor']) && !empty(trim($row['lonkor']))) {
|
||||||
|
$longitude = str_replace(',', '.', trim($row['lonkor']));
|
||||||
|
if (is_numeric($longitude)) {
|
||||||
|
$longitude = bcadd($longitude, '0', 18);
|
||||||
|
} else {
|
||||||
|
$longitude = '0';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$longitude = '0';
|
||||||
|
}
|
||||||
|
|
||||||
$batchData[] = [
|
$batchData[] = [
|
||||||
'nomor_pelanggan' => $row[0],
|
'nomor_pelanggan' => $row['nomor_pelanggan'] ?? '',
|
||||||
'kota_pelayanan' => $row[1],
|
'kota_pelayanan' => $row['kota_pelayanan'] ?? '',
|
||||||
'nama' => $row[2],
|
'nama' => $row['nama'] ?? '',
|
||||||
'alamat' => $row[3],
|
'alamat' => $row['alamat'] ?? '',
|
||||||
'latitude' => $latitude,
|
'latitude' => $latitude,
|
||||||
'longitude' => $longitude,
|
'longitude' => $longitude,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (count($batchData) >= $batchSize) {
|
||||||
|
Customer::upsert($batchData, ['nomor_pelanggan'], ['kota_pelayanan', 'nama', 'alamat', 'latitude', 'longitude']);
|
||||||
|
$batchData = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($batchData)) {
|
if (!empty($batchData)) {
|
||||||
@@ -44,9 +73,20 @@ class CustomersImport implements ToCollection, WithMultipleSheets
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function sheets(): array {
|
public function sheets(): array {
|
||||||
return [
|
return [
|
||||||
0 => $this
|
0 => $this
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function chunkSize(): int
|
||||||
|
{
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function batchSize(): int
|
||||||
|
{
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
77
app/Jobs/ScrapingDataJob.php
Normal file
77
app/Jobs/ScrapingDataJob.php
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use App\Models\ImportDatasource;
|
||||||
|
use App\Services\ServiceGoogleSheet;
|
||||||
|
use App\Services\ServicePbgTask;
|
||||||
|
use App\Services\ServiceTabPbgTask;
|
||||||
|
use App\Services\ServiceTokenSIMBG;
|
||||||
|
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;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class ScrapingDataJob implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject dependencies instead of creating them inside.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
$client = app(Client::class);
|
||||||
|
$service_pbg_task = app(ServicePbgTask::class);
|
||||||
|
$service_tab_pbg_task = app(ServiceTabPbgTask::class);
|
||||||
|
$service_google_sheet = app(ServiceGoogleSheet::class);
|
||||||
|
$service_token = app(ServiceTokenSIMBG::class);
|
||||||
|
// Create a record with "processing" status
|
||||||
|
$import_datasource = ImportDatasource::create([
|
||||||
|
'message' => 'Initiating scraping...',
|
||||||
|
'response_body' => null,
|
||||||
|
'status' => 'processing',
|
||||||
|
'start_time' => now()
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Run the scraping services
|
||||||
|
$service_google_sheet->run_service();
|
||||||
|
$service_pbg_task->run_service();
|
||||||
|
$service_tab_pbg_task->run_service();
|
||||||
|
|
||||||
|
// Update status to success
|
||||||
|
$import_datasource->update([
|
||||||
|
'status' => 'success',
|
||||||
|
'message' => 'Scraping completed successfully.',
|
||||||
|
'finish_time' => now()
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Scraping failed: ' . $e->getMessage(), ['trace' => $e->getTraceAsString()]);
|
||||||
|
|
||||||
|
// Update status to failed
|
||||||
|
if (isset($import_datasource)) {
|
||||||
|
$import_datasource->update([
|
||||||
|
'status' => 'failed',
|
||||||
|
'response_body' => 'Error: ' . $e->getMessage(),
|
||||||
|
'finish_time' => now()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark the job as failed
|
||||||
|
$this->fail($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
80
app/Jobs/SyncronizeSIMBG.php
Normal file
80
app/Jobs/SyncronizeSIMBG.php
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<?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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,15 @@ class BigdataResume extends Model
|
|||||||
'business_sum',
|
'business_sum',
|
||||||
'non_business_count',
|
'non_business_count',
|
||||||
'non_business_sum',
|
'non_business_sum',
|
||||||
|
'spatial_count',
|
||||||
|
'spatial_sum',
|
||||||
|
'year',
|
||||||
|
'waiting_click_dpmptsp_count',
|
||||||
|
'waiting_click_dpmptsp_sum',
|
||||||
|
'issuance_realization_pbg_count',
|
||||||
|
'issuance_realization_pbg_sum',
|
||||||
|
'process_in_technical_office_count',
|
||||||
|
'process_in_technical_office_sum',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function importDatasource()
|
public function importDatasource()
|
||||||
@@ -28,88 +37,84 @@ class BigdataResume extends Model
|
|||||||
return $this->belongsTo(ImportDatasource::class, 'import_datasource_id');
|
return $this->belongsTo(ImportDatasource::class, 'import_datasource_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function generateResumeData($import_datasource_id){
|
public static function generateResumeData($import_datasource_id, $year, $data_setting){
|
||||||
$query_verified = once( function () {
|
$stats = PbgTask::with(['googleSheet', 'pbg_task_retributions'])
|
||||||
return DB::table('pbg_task AS pt')
|
->leftJoin('pbg_task_retributions as ptr', 'pbg_task.uuid', '=', 'ptr.pbg_task_uid')
|
||||||
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
->leftJoin('pbg_task_google_sheet as ptgs', 'pbg_task.registration_number', '=', 'ptgs.no_registrasi')
|
||||||
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
|
->when($year !== 'all', function ($query) use ($year) {
|
||||||
->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) = ?', [strtolower(trim('Selesai Verifikasi'))])
|
$query->whereYear('pbg_task.task_created_at', (int) $year);
|
||||||
->selectRaw('COUNT(pt.id) AS total_data,
|
})
|
||||||
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution')
|
->selectRaw("
|
||||||
|
COUNT(CASE WHEN LOWER(TRIM(ptgs.status_verifikasi)) = 'selesai verifikasi' THEN 1 END) AS verified_count,
|
||||||
|
SUM(CASE WHEN LOWER(TRIM(ptgs.status_verifikasi)) = 'selesai verifikasi' THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS verified_total,
|
||||||
|
|
||||||
|
COUNT(CASE WHEN LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL THEN 1 END) AS non_verified_count,
|
||||||
|
SUM(CASE WHEN LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS non_verified_total,
|
||||||
|
|
||||||
|
COUNT(CASE WHEN (LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL)
|
||||||
|
AND LOWER(TRIM(pbg_task.function_type)) = 'sebagai tempat usaha' THEN 1 END) AS business_count,
|
||||||
|
SUM(CASE WHEN (LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL)
|
||||||
|
AND LOWER(TRIM(pbg_task.function_type)) = 'sebagai tempat usaha' THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS business_total,
|
||||||
|
|
||||||
|
COUNT(CASE WHEN (LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL)
|
||||||
|
AND (LOWER(TRIM(pbg_task.function_type)) != 'sebagai tempat usaha' OR pbg_task.function_type IS NULL) THEN 1 END) AS non_business_count,
|
||||||
|
SUM(CASE WHEN (LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL)
|
||||||
|
AND (LOWER(TRIM(pbg_task.function_type)) != 'sebagai tempat usaha' OR pbg_task.function_type IS NULL) THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS non_business_total
|
||||||
|
")
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
|
// Assign Results
|
||||||
|
$verified_count = $stats->verified_count ?? 0;
|
||||||
|
$verified_total = $stats->verified_total ?? 0;
|
||||||
|
$non_verified_count = $stats->non_verified_count ?? 0;
|
||||||
|
$non_verified_total = $stats->non_verified_total ?? 0;
|
||||||
|
$business_count = $stats->business_count ?? 0;
|
||||||
|
$business_total = $stats->business_total ?? 0;
|
||||||
|
$non_business_count = $stats->non_business_count ?? 0;
|
||||||
|
$non_business_total = $stats->non_business_total ?? 0;
|
||||||
|
|
||||||
|
$query_potention = once(function () use ($year) {
|
||||||
|
$query = PbgTask::leftJoin('pbg_task_retributions as ptr', 'pbg_task.uuid', '=', 'ptr.pbg_task_uid')
|
||||||
|
->selectRaw('COUNT(DISTINCT pbg_task.id) as task_count, SUM(ptr.nilai_retribusi_bangunan) as total_retribution');
|
||||||
|
|
||||||
|
if ($year !== 'all') {
|
||||||
|
$query->whereYear('pbg_task.task_created_at', (int) $year);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->first();
|
||||||
});
|
});
|
||||||
|
|
||||||
$verified_count = $query_verified->total_data ?? 0;
|
|
||||||
$verified_total = $query_verified->total_retribution ?? 0;
|
|
||||||
|
|
||||||
$query_business = once(function () {
|
|
||||||
return DB::table('pbg_task AS pt')
|
|
||||||
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
|
||||||
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
|
|
||||||
->where(function ($query) {
|
|
||||||
$query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
|
|
||||||
->orWhereNull('ptgs.status_verifikasi');
|
|
||||||
})
|
|
||||||
->where(function ($query) {
|
|
||||||
$query->whereRaw('LOWER(TRIM(pt.function_type)) = ?', [strtolower(trim('Sebagai Tempat Usaha'))]);
|
|
||||||
})
|
|
||||||
->selectRaw('COUNT(pt.id) AS total_data,
|
|
||||||
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution')
|
|
||||||
->first();
|
|
||||||
});
|
|
||||||
|
|
||||||
$business_count = $query_business->total_data ?? 0;
|
|
||||||
$business_total = $query_business->total_retribution ?? 0;
|
|
||||||
|
|
||||||
$query_non_business = once( function () {
|
|
||||||
return DB::table('pbg_task AS pt')
|
|
||||||
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
|
||||||
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid') // Join ke pbg_task_retributions
|
|
||||||
->where(function ($query) {
|
|
||||||
$query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
|
|
||||||
->orWhereNull('ptgs.status_verifikasi'); // Include NULL values
|
|
||||||
})
|
|
||||||
->where(function ($query) {
|
|
||||||
$query->whereRaw('LOWER(TRIM(pt.function_type)) != ?', [strtolower(trim('Sebagai Tempat Usaha'))])
|
|
||||||
->orWhereNull('pt.function_type'); // Include NULL values
|
|
||||||
})
|
|
||||||
->selectRaw('COUNT(pt.id) AS total_data,
|
|
||||||
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions
|
|
||||||
->first();
|
|
||||||
});
|
|
||||||
$non_business_count = $query_non_business->total_data ?? 0;
|
|
||||||
$non_business_total = $query_non_business->total_retribution ?? 0;
|
|
||||||
|
|
||||||
$query_non_verified = once(function () {
|
|
||||||
return DB::table('pbg_task AS pt')
|
|
||||||
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
|
||||||
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid') // Join tabel pbg_task_retributions
|
|
||||||
->where(function ($query) {
|
|
||||||
$query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
|
|
||||||
->orWhereNull('ptgs.status_verifikasi'); // Include NULL values
|
|
||||||
})
|
|
||||||
->selectRaw('COUNT(pt.id) AS total_data,
|
|
||||||
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions
|
|
||||||
->first();
|
|
||||||
});
|
|
||||||
|
|
||||||
$non_verified_count = $query_non_verified->total_data ?? 0;
|
|
||||||
$non_verified_total = $query_non_verified->total_retribution ?? 0;
|
|
||||||
|
|
||||||
$query_potention = once( function () {
|
|
||||||
return DB::table('pbg_task as pt')
|
|
||||||
->leftJoin('pbg_task_retributions as ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
|
|
||||||
->select(
|
|
||||||
DB::raw('COUNT(DISTINCT pt.id) as task_count'),
|
|
||||||
DB::raw('SUM(ptr.nilai_retribusi_bangunan) as total_retribution')
|
|
||||||
)
|
|
||||||
->first();
|
|
||||||
});
|
|
||||||
$potention_count = $query_potention->task_count ?? 0;
|
$potention_count = $query_potention->task_count ?? 0;
|
||||||
$potention_total = $query_potention->total_retribution ?? 0;
|
$potention_total = $query_potention->total_retribution ?? 0;
|
||||||
|
|
||||||
|
$query_spatial_plannings = once(function () use ($year) {
|
||||||
|
$query = PbgTask::leftJoin('spatial_plannings as sp', 'pbg_task.document_number', '=', 'sp.number')
|
||||||
|
->leftJoin('pbg_task_retributions as ptr', 'ptr.pbg_task_uid', '=', 'pbg_task.uuid')
|
||||||
|
->selectRaw('
|
||||||
|
CASE
|
||||||
|
WHEN COUNT(DISTINCT sp.id) > 0 THEN COUNT(DISTINCT sp.id)
|
||||||
|
ELSE (SELECT COUNT(*) FROM spatial_plannings)
|
||||||
|
END as task_count,
|
||||||
|
SUM(CASE WHEN sp.id IS NOT NULL AND ptr.id IS NOT NULL THEN ptr.nilai_retribusi_bangunan ELSE 0 END) as total_retribution
|
||||||
|
');
|
||||||
|
|
||||||
|
if ($year !== 'all') {
|
||||||
|
$query->whereYear('pbg_task.task_created_at', (int) $year);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->first();
|
||||||
|
});
|
||||||
|
|
||||||
|
$spatial_planning_count = $query_spatial_plannings->task_count ?? 0;
|
||||||
|
$spatial_planning_total = $query_spatial_plannings->total_retribution;
|
||||||
|
|
||||||
|
$potention_count -= $spatial_planning_count;
|
||||||
|
$potention_total -= $spatial_planning_total;
|
||||||
|
|
||||||
return self::create([
|
return self::create([
|
||||||
'import_datasource_id' => $import_datasource_id,
|
'import_datasource_id' => $import_datasource_id,
|
||||||
|
'spatial_count' => $spatial_planning_count,
|
||||||
|
'spatial_sum' => $spatial_planning_total ?? 0.00,
|
||||||
'potention_count' => $potention_count ?? 0,
|
'potention_count' => $potention_count ?? 0,
|
||||||
'potention_sum' => $potention_total ?? 0.00,
|
'potention_sum' => $potention_total ?? 0.00,
|
||||||
'non_verified_count' => $non_verified_count ?? 0,
|
'non_verified_count' => $non_verified_count ?? 0,
|
||||||
@@ -120,6 +125,13 @@ class BigdataResume extends Model
|
|||||||
'business_sum' => $business_total ?? 0.00,
|
'business_sum' => $business_total ?? 0.00,
|
||||||
'non_business_count' => $non_business_count ?? 0,
|
'non_business_count' => $non_business_count ?? 0,
|
||||||
'non_business_sum' => $non_business_total ?? 0.00,
|
'non_business_sum' => $non_business_total ?? 0.00,
|
||||||
|
'year' => $year,
|
||||||
|
'waiting_click_dpmptsp_count' => $data_setting['MENUNGGU_KLIK_DPMPTSP_COUNT'] ?? 0,
|
||||||
|
'waiting_click_dpmptsp_sum' => $data_setting['MENUNGGU_KLIK_DPMPTSP_SUM'] ?? 0.00,
|
||||||
|
'issuance_realization_pbg_count' => $data_setting['REALISASI_TERBIT_PBG_COUNT'] ?? 0,
|
||||||
|
'issuance_realization_pbg_sum' => $data_setting['REALISASI_TERBIT_PBG_SUM'] ?? 0.00,
|
||||||
|
'process_in_technical_office_count' => $data_setting['PROSES_DINAS_TEKNIS_COUNT'] ?? 0,
|
||||||
|
'process_in_technical_office_sum' => $data_setting['PROSES_DINAS_TEKNIS_SUM'] ??0.00,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ class ImportDatasource extends Model
|
|||||||
'id',
|
'id',
|
||||||
'message',
|
'message',
|
||||||
'response_body',
|
'response_body',
|
||||||
'status'
|
'status',
|
||||||
|
'start_time',
|
||||||
|
'finish_time'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,4 +22,7 @@ class Menu extends Model
|
|||||||
public function children(){
|
public function children(){
|
||||||
return $this->hasMany(Menu::class,'parent_id');
|
return $this->hasMany(Menu::class,'parent_id');
|
||||||
}
|
}
|
||||||
|
public function parent(){
|
||||||
|
return $this->belongsTo(Menu::class,'parent_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,4 +37,13 @@ class PbgTask extends Model
|
|||||||
public function pbg_task_index_integrations(){
|
public function pbg_task_index_integrations(){
|
||||||
return $this->hasOne(PbgTaskIndexIntegrations::class, 'pbg_task_uid', 'uuid');
|
return $this->hasOne(PbgTaskIndexIntegrations::class, 'pbg_task_uid', 'uuid');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function googleSheet(){
|
||||||
|
return $this->hasOne(PbgTaskGoogleSheet::class, 'no_registrasi', 'registration_number');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function taskAssignments()
|
||||||
|
{
|
||||||
|
return $this->hasMany(TaskAssignment::class, 'pbg_task_uid', 'uuid');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,13 @@ class RoleMenu extends Model
|
|||||||
'allow_destroy',
|
'allow_destroy',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'allow_show' => 'boolean',
|
||||||
|
'allow_create' => 'boolean',
|
||||||
|
'allow_update' => 'boolean',
|
||||||
|
'allow_destroy' => 'boolean',
|
||||||
|
];
|
||||||
|
|
||||||
public $timestamps = true;
|
public $timestamps = true;
|
||||||
|
|
||||||
public function role(){
|
public function role(){
|
||||||
|
|||||||
28
app/Models/TaskAssignment.php
Normal file
28
app/Models/TaskAssignment.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
class TaskAssignment extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'user_id', 'name', 'username', 'email', 'phone_number', 'role',
|
||||||
|
'role_name', 'is_active', 'file', 'expertise', 'experience',
|
||||||
|
'is_verif', 'uid', 'status', 'status_name', 'note', 'pbg_task_uid', 'tas_id'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'is_active' => 'boolean',
|
||||||
|
'is_verif' => 'boolean',
|
||||||
|
'file' => 'array', // JSON field casting
|
||||||
|
];
|
||||||
|
|
||||||
|
public function pbgTask()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(PbgTask::class, 'pbg_task_uid', 'uuid');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ namespace App\Models;
|
|||||||
|
|
||||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Laravel\Sanctum\HasApiTokens;
|
use Laravel\Sanctum\HasApiTokens;
|
||||||
@@ -11,7 +12,7 @@ use Laravel\Sanctum\HasApiTokens;
|
|||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||||
use HasFactory, Notifiable, HasApiTokens;
|
use HasFactory, Notifiable, HasApiTokens, SoftDeletes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@@ -27,6 +28,8 @@ class User extends Authenticatable
|
|||||||
'position'
|
'position'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected $dates = ['deleted_at'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that should be hidden for serialization.
|
* The attributes that should be hidden for serialization.
|
||||||
*
|
*
|
||||||
@@ -50,7 +53,20 @@ class User extends Authenticatable
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete(){
|
||||||
|
$this->email = $this->email . '_deleted_'. now()->timestamp;
|
||||||
|
$this->save();
|
||||||
|
return parent::delete();
|
||||||
|
}
|
||||||
|
|
||||||
public function roles(){
|
public function roles(){
|
||||||
return $this->belongsToMany(Role::class, 'user_role')->withTimestamps();
|
return $this->belongsToMany(Role::class, 'user_role')->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function menus(){
|
||||||
|
return Menu::whereHas('roles', function ($query){
|
||||||
|
$query->whereIn('roles.id', $this->roles->pluck('id'))
|
||||||
|
->where('role_menu.allow_show', true);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,19 @@
|
|||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Models\Menu;
|
use App\Models\Menu;
|
||||||
|
use App\Services\ServiceGoogleSheet;
|
||||||
|
use App\Services\ServicePbgTask;
|
||||||
|
use App\Services\ServiceTabPbgTask;
|
||||||
|
use App\Services\ServiceTokenSIMBG;
|
||||||
use App\View\Components\Circle;
|
use App\View\Components\Circle;
|
||||||
use Auth;
|
use Auth;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
use Illuminate\Support\Facades\Blade;
|
use Illuminate\Support\Facades\Blade;
|
||||||
use Illuminate\Support\Facades\View;
|
use Illuminate\Support\Facades\View;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use App\Services\ServiceSIMBG;
|
||||||
|
use App\Services\GoogleSheetService;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
@@ -17,7 +24,25 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function register(): void
|
public function register(): void
|
||||||
{
|
{
|
||||||
//
|
$this->app->bind(Client::class, function () {
|
||||||
|
return new Client();
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->app->bind(ServiceTokenSIMBG::class, function ($app) {
|
||||||
|
return new ServiceTokenSIMBG();
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->app->bind(ServicePbgTask::class, function ($app) {
|
||||||
|
return new ServicePbgTask($app->make(Client::class), $app->make(ServiceTokenSIMBG::class));
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->app->bind(ServiceTabPbgTask::class, function ($app) {
|
||||||
|
return new ServiceTabPbgTask($app->make(Client::class), $app->make(ServiceTokenSIMBG::class));
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->app->bind(ServiceGoogleSheet::class, function ($app) {
|
||||||
|
return new ServiceGoogleSheet();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,13 +57,16 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
if ($user) {
|
if ($user) {
|
||||||
$menus = Menu::whereHas('roles', function ($query) use ($user) {
|
$menus = Menu::whereHas('roles', function ($query) use ($user) {
|
||||||
$query->where('roles.id', $user->roles->pluck('id'));
|
$query->whereIn('roles.id', $user->roles->pluck('id'))
|
||||||
|
->where('role_menu.allow_show', 1);
|
||||||
})
|
})
|
||||||
->with(['children' => function ($query) {
|
->with(['children' => function ($query) use ($user) {
|
||||||
$query->whereHas('roles', function ($subQuery) {
|
$query->whereHas('roles', function ($subQuery) use ($user) {
|
||||||
$subQuery->where('role_menu.allow_show', 1);
|
$subQuery->whereIn('roles.id', $user->roles->pluck('id'))
|
||||||
|
->where('role_menu.allow_show', 1);
|
||||||
});
|
});
|
||||||
}])
|
}])
|
||||||
|
->whereNull('parent_id') // Ambil hanya menu utama
|
||||||
->orderBy('sort_order', 'asc')
|
->orderBy('sort_order', 'asc')
|
||||||
->get();
|
->get();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class RouteServiceProvider extends ServiceProvider
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public const HOME = '/dashboards/bigdata';
|
public const HOME = '/home';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define your route model bindings, pattern filters, and other route configuration.
|
* Define your route model bindings, pattern filters, and other route configuration.
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class GoogleSheetService
|
|||||||
protected $client;
|
protected $client;
|
||||||
protected $service;
|
protected $service;
|
||||||
protected $spreadsheetID;
|
protected $spreadsheetID;
|
||||||
|
protected $service_sheets;
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->client = new Google_Client();
|
$this->client = new Google_Client();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Services;
|
|||||||
|
|
||||||
use OpenAI;
|
use OpenAI;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class OpenAIService
|
class OpenAIService
|
||||||
{
|
{
|
||||||
@@ -11,54 +12,11 @@ class OpenAIService
|
|||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
// $this->client = OpenAI::client(env('OPENAI_API_KEY'));
|
||||||
$this->client = OpenAI::client(env('OPENAI_API_KEY'));
|
$this->client = OpenAI::client(env('OPENAI_API_KEY'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateGeneralText($prompt, $mainContent)
|
public function generateQueryBasedMainContent($prompt, $mainContent, $chatHistory)
|
||||||
{
|
|
||||||
$response = $this->client->chat()->create([
|
|
||||||
'model' => 'gpt-4o-mini',
|
|
||||||
'messages' => [
|
|
||||||
[
|
|
||||||
'role' => 'system',
|
|
||||||
'content' => "You are an expert assistant. Your task is to generate a concise response based on the provided prompt and main content.
|
|
||||||
|
|
||||||
Guidelines:
|
|
||||||
- Summarize the key points in exactly 5 bullet points.
|
|
||||||
- Ensure the response is clear and relevant to the prompt.
|
|
||||||
- Use simple and professional language."
|
|
||||||
],
|
|
||||||
['role' => 'user', 'content' => "Prompt: $prompt \nMain Content: $mainContent"],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function generateClassifyMainContent($prompt, $mainContent)
|
|
||||||
{
|
|
||||||
$response = $this->client->chat()->create([
|
|
||||||
'model' => 'gpt-4o-mini',
|
|
||||||
'messages' => [
|
|
||||||
[
|
|
||||||
'role' => 'system',
|
|
||||||
'content' => "You are an expert assistant in classifying questions based on whether their answers must be retrieved from a database or can be explained generally.
|
|
||||||
Your task is to return one of the following two labels:
|
|
||||||
- \"DATABASE\" → If the question requires specific data that can only be obtained from a database.
|
|
||||||
- \"GENERAL\" → If the question can be answered without accessing a database.
|
|
||||||
|
|
||||||
Consider the following context: \"$mainContent\"
|
|
||||||
|
|
||||||
Respond with only one of the labels: \"DATABASE\" or \"GENERAL\"."
|
|
||||||
],
|
|
||||||
['role' => 'user', 'content' => $prompt],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function generateQueryBasedMainContent($prompt, $mainContent)
|
|
||||||
{
|
{
|
||||||
// Load file JSON
|
// Load file JSON
|
||||||
$jsonPath = public_path('templates/contentTemplatePrompt.json'); // Sesuaikan path
|
$jsonPath = public_path('templates/contentTemplatePrompt.json'); // Sesuaikan path
|
||||||
@@ -72,18 +30,60 @@ class OpenAIService
|
|||||||
// Ambil template berdasarkan kategori
|
// Ambil template berdasarkan kategori
|
||||||
$promptTemplate = $jsonData[$mainContent]['prompt'];
|
$promptTemplate = $jsonData[$mainContent]['prompt'];
|
||||||
|
|
||||||
|
// Menyusun pesan untuk OpenAI
|
||||||
|
$messages = [
|
||||||
|
['role' => 'system', 'content' => $promptTemplate],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Menambahkan chat history sebagai konteks
|
||||||
|
foreach ($chatHistory as $chat) {
|
||||||
|
if (isset($chat['user'])) {
|
||||||
|
$messages[] = ['role' => 'user', 'content' => $chat['user']];
|
||||||
|
}
|
||||||
|
if (isset($chat['rawBotResponse'])) {
|
||||||
|
$messages[] = ['role' => 'assistant', 'content' => $chat['rawBotResponse']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambahkan prompt terbaru user
|
||||||
|
$messages[] = ['role' => 'user', 'content' => $prompt];
|
||||||
|
|
||||||
|
// Kirim request ke OpenAI API
|
||||||
$response = $this->client->chat()->create([
|
$response = $this->client->chat()->create([
|
||||||
'model' => 'gpt-4o-mini',
|
'model' => 'gpt-4o-mini',
|
||||||
'messages' => [
|
'messages' => $messages,
|
||||||
['role' => 'system', 'content' => $promptTemplate],
|
|
||||||
['role' => 'user', 'content' => $prompt],
|
|
||||||
],
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// public function generateQueryBasedMainContent($prompt, $mainContent, $chatHistory)
|
||||||
|
// {
|
||||||
|
// // Load file JSON
|
||||||
|
// $jsonPath = public_path('templates/contentTemplatePrompt.json'); // Sesuaikan path
|
||||||
|
// $jsonData = json_decode(file_get_contents($jsonPath), true);
|
||||||
|
|
||||||
|
// // Periksa apakah kategori ada dalam JSON
|
||||||
|
// if (!isset($jsonData[$mainContent])) {
|
||||||
|
// return "Template prompt tidak ditemukan.";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Ambil template berdasarkan kategori
|
||||||
|
// $promptTemplate = $jsonData[$mainContent]['prompt'];
|
||||||
|
|
||||||
|
// $response = $this->client->chat()->create([
|
||||||
|
// 'model' => 'gpt-4o-mini',
|
||||||
|
// 'messages' => [
|
||||||
|
// ['role' => 'system', 'content' => $promptTemplate],
|
||||||
|
// ['role' => 'user', 'content' => $prompt],
|
||||||
|
// ],
|
||||||
|
// ]);
|
||||||
|
|
||||||
|
// return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
public function validateSyntaxQuery($queryResponse)
|
public function validateSyntaxQuery($queryResponse)
|
||||||
{
|
{
|
||||||
$response = $this->client->chat()->create([
|
$response = $this->client->chat()->create([
|
||||||
@@ -154,4 +154,123 @@ class OpenAIService
|
|||||||
return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function classifyMainGenerateText($prompt) {
|
||||||
|
$response = $this->client->chat()->create([
|
||||||
|
'model' => 'gpt-4o-mini',
|
||||||
|
'messages' => [
|
||||||
|
[
|
||||||
|
'role' => 'system',
|
||||||
|
'content' => "You are an assistant that classifies text into one of the following categories:
|
||||||
|
- reklame (ads or product/service promotions)
|
||||||
|
- business_or_industries (business or industries in general)
|
||||||
|
- customers (customers, consumers, or service users)
|
||||||
|
- pbg (tasks related to Building Approval)
|
||||||
|
- retribusi (retributions related to PBG)
|
||||||
|
- spatial_plannings (spatial planning)
|
||||||
|
- tourisms (tourism and tourist destinations)
|
||||||
|
- umkms (Micro, Small, and Medium Enterprises)
|
||||||
|
|
||||||
|
Respond with only one of the categories above without any additional explanation."
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'role' => 'user',
|
||||||
|
'content' => "Classify the following text:\n\n" . $prompt
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createMainQuery($classify, $prompt, $chatHistory)
|
||||||
|
{
|
||||||
|
// Load file JSON
|
||||||
|
$jsonPath = public_path('templates/table_config.json');
|
||||||
|
$jsonConfig = json_decode(file_get_contents($jsonPath), true);
|
||||||
|
|
||||||
|
// Pastikan kategori tersedia dalam konfigurasi
|
||||||
|
if (!isset($jsonConfig[$classify])) {
|
||||||
|
return "Error: Kategori tidak ditemukan dalam konfigurasi.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ambil nama tabel dan kolom
|
||||||
|
$tableName = $jsonConfig[$classify]['table_name'];
|
||||||
|
$columns = implode(', ', $jsonConfig[$classify]['list_column']);
|
||||||
|
|
||||||
|
// Konversi chatHistory ke dalam format messages
|
||||||
|
$messages = [
|
||||||
|
[
|
||||||
|
'role' => 'system',
|
||||||
|
'content' => "You are an AI assistant that generates only valid MariaDB queries based on user requests.
|
||||||
|
Use the following table information to construct the SQL query:
|
||||||
|
|
||||||
|
- Table Name: $tableName
|
||||||
|
- Available Columns: $columns
|
||||||
|
|
||||||
|
Generate only the SQL query without any explanation or additional text.
|
||||||
|
The query should include `LIMIT 10` to restrict the results."
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Menambahkan chat history sebagai konteks
|
||||||
|
foreach ($chatHistory as $chat) {
|
||||||
|
if (isset($chat['user'])) {
|
||||||
|
$messages[] = ['role' => 'user', 'content' => $chat['user']];
|
||||||
|
}
|
||||||
|
if (isset($chat['rawBotResponse'])) {
|
||||||
|
$messages[] = ['role' => 'assistant', 'content' => $chat['rawBotResponse']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambahkan prompt utama pengguna
|
||||||
|
$messages[] = ['role' => 'user', 'content' => $prompt];
|
||||||
|
|
||||||
|
// Kirim permintaan ke model AI
|
||||||
|
$response = $this->client->chat()->create([
|
||||||
|
'model' => 'gpt-4o-mini',
|
||||||
|
'messages' => $messages
|
||||||
|
]);
|
||||||
|
|
||||||
|
return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// public function createMainQuery($classify, $prompt)
|
||||||
|
// {
|
||||||
|
// // Load file JSON
|
||||||
|
// $jsonPath = public_path('templates/table_config.json');
|
||||||
|
// $jsonConfig = json_decode(file_get_contents($jsonPath), true);
|
||||||
|
|
||||||
|
// // Pastikan kategori tersedia dalam konfigurasi
|
||||||
|
// if (!isset($jsonConfig[$classify])) {
|
||||||
|
// return "Error: Kategori tidak ditemukan dalam konfigurasi.";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Ambil nama tabel dan kolom
|
||||||
|
// $tableName = $jsonConfig[$classify]['table_name'];
|
||||||
|
// $columns = implode(', ', $jsonConfig[$classify]['list_column']);
|
||||||
|
|
||||||
|
// $response = $this->client->chat()->create([
|
||||||
|
// 'model' => 'gpt-4o-mini',
|
||||||
|
// 'messages' => [
|
||||||
|
// [
|
||||||
|
// 'role' => 'system',
|
||||||
|
// 'content' => "You are an AI assistant that generates only valid MariaDB queries based on user requests.
|
||||||
|
// Use the following table information to construct the SQL query:
|
||||||
|
|
||||||
|
// - Table Name: $tableName
|
||||||
|
// - Available Columns: $columns
|
||||||
|
|
||||||
|
// Generate only the SQL query without any explanation or additional text
|
||||||
|
// The query should include `LIMIT 10` to restrict the results."
|
||||||
|
// ],
|
||||||
|
// [
|
||||||
|
// 'role' => 'user',
|
||||||
|
// 'content' => $prompt
|
||||||
|
// ],
|
||||||
|
// ],
|
||||||
|
// ]);
|
||||||
|
|
||||||
|
// return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,9 +51,25 @@ class ServiceClient
|
|||||||
|
|
||||||
$resultResponse = json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR);
|
$resultResponse = json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR);
|
||||||
return $this->resSuccess($resultResponse);
|
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) {
|
} catch (Exception $e) {
|
||||||
\Log::error('error from client service'. $e->getMessage());
|
// Handle unexpected errors
|
||||||
return $this->resError($e->getMessage());
|
return $this->resError('Unexpected error: ' . $e->getMessage(), null, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
280
app/Services/ServiceGoogleSheet.php
Normal file
280
app/Services/ServiceGoogleSheet.php
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
use App\Models\DataSetting;
|
||||||
|
use App\Models\ImportDatasource;
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Google_Client;
|
||||||
|
use Google_Service_Sheets;
|
||||||
|
use Log;
|
||||||
|
class ServiceGoogleSheet
|
||||||
|
{
|
||||||
|
protected $client;
|
||||||
|
protected $service;
|
||||||
|
protected $spreadsheetID;
|
||||||
|
protected $service_sheets;
|
||||||
|
protected $import_datasource;
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->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 run_service(){
|
||||||
|
try{
|
||||||
|
$this->sync_big_data();
|
||||||
|
$this->sync_google_sheet_data();
|
||||||
|
}catch(Exception $e){
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function sync_google_sheet_data() {
|
||||||
|
try {
|
||||||
|
$sheet_data = $this->get_data_by_sheet(0);
|
||||||
|
|
||||||
|
if (empty($sheet_data) || count($sheet_data) < 2) {
|
||||||
|
Log::warning("sync_google_sheet_data: No valid data found.");
|
||||||
|
throw new \Exception("sync_google_sheet_data: No valid data found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$cleanValue = function ($value) {
|
||||||
|
return (isset($value) && trim($value) !== '') ? trim($value) : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
$mapUpsert = [];
|
||||||
|
foreach(array_slice($sheet_data, 1) as $row){
|
||||||
|
if(!is_array($row)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$no_registrasi = $cleanValue($row[2] ?? null);
|
||||||
|
|
||||||
|
// Apply the same logic from your SQL UPDATE
|
||||||
|
if (strpos($no_registrasi, 'PBG-') === 0) {
|
||||||
|
$format_registrasi = $no_registrasi;
|
||||||
|
} else {
|
||||||
|
$format_registrasi = sprintf(
|
||||||
|
"PBG-%s-%s-%s",
|
||||||
|
substr($no_registrasi, 0, 6) ?: '',
|
||||||
|
substr($no_registrasi, 7, 8) ?: '',
|
||||||
|
substr($no_registrasi, -2) ?: ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$mapUpsert[] = [
|
||||||
|
'jenis_konsultasi' => $cleanValue($row[1] ?? null),
|
||||||
|
'no_registrasi' => $no_registrasi,
|
||||||
|
'formatted_registration_number' => $format_registrasi,
|
||||||
|
'nama_pemilik' => $cleanValue($row[3] ?? null),
|
||||||
|
'lokasi_bg' => $cleanValue($row[4] ?? null),
|
||||||
|
'fungsi_bg' => $cleanValue($row[5] ?? null),
|
||||||
|
'nama_bangunan' => $cleanValue($row[6] ?? null),
|
||||||
|
'tgl_permohonan' => $this->convertToDate($cleanValue($row[7] ?? null)),
|
||||||
|
'status_verifikasi' => $cleanValue($row[8] ?? null),
|
||||||
|
'status_permohonan' => $cleanValue($row[9] ?? null),
|
||||||
|
'alamat_pemilik' => $cleanValue($row[10] ?? null),
|
||||||
|
'no_hp' => $cleanValue($row[11] ?? null),
|
||||||
|
'email' => $cleanValue($row[12] ?? null),
|
||||||
|
'tanggal_catatan' => $this->convertToDate($cleanValue($row[13] ?? null)),
|
||||||
|
'catatan_kekurangan_dokumen' => $cleanValue($row[14] ?? null),
|
||||||
|
'gambar' => $cleanValue($row[15] ?? null),
|
||||||
|
'krk_kkpr' => $cleanValue($row[16] ?? null),
|
||||||
|
'no_krk' => $cleanValue($row[17] ?? null),
|
||||||
|
'lh' => $cleanValue($row[18] ?? null),
|
||||||
|
'ska' => $cleanValue($row[19] ?? null),
|
||||||
|
'keterangan' => $cleanValue($row[20] ?? null),
|
||||||
|
'helpdesk' => $cleanValue($row[21] ?? null),
|
||||||
|
'pj' => $cleanValue($row[22] ?? null),
|
||||||
|
'kepemilikan' => $cleanValue($row[24] ?? null),
|
||||||
|
'potensi_taru' => $cleanValue($row[25] ?? null),
|
||||||
|
'validasi_dinas' => $cleanValue($row[26] ?? null),
|
||||||
|
'kategori_retribusi' => $cleanValue($row[27] ?? null),
|
||||||
|
'no_urut_ba_tpt' => $cleanValue($row[28] ?? null),
|
||||||
|
'tanggal_ba_tpt' => $this->convertToDate($cleanValue($row[29] ?? null)),
|
||||||
|
'no_urut_ba_tpa' => $cleanValue($row[30] ?? null),
|
||||||
|
'tanggal_ba_tpa' => $this->convertToDate($cleanValue($row[31] ?? null)),
|
||||||
|
'no_urut_skrd' => $cleanValue($row[32] ?? null),
|
||||||
|
'tanggal_skrd' => $this->convertToDate($cleanValue($row[33] ?? null)),
|
||||||
|
'ptsp' => $cleanValue($row[34] ?? null),
|
||||||
|
'selesai_terbit' => $cleanValue($row[35] ?? null),
|
||||||
|
'tanggal_pembayaran' => $cleanValue($row[36] ?? null),
|
||||||
|
'format_sts' => $cleanValue($row[37] ?? null),
|
||||||
|
'tahun_terbit' => (int) $cleanValue($row[38] ?? null),
|
||||||
|
'tahun_berjalan' => (int) $cleanValue($row[39] ?? null),
|
||||||
|
'kelurahan' => $cleanValue($row[40] ?? null),
|
||||||
|
'kecamatan' => $cleanValue($row[41] ?? null),
|
||||||
|
'lb' => $this->convertToDecimal($cleanValue($row[42] ?? 0)),
|
||||||
|
'tb' => $this->convertToDecimal($cleanValue($row[43] ?? 0)),
|
||||||
|
'jlb' => (int) $cleanValue($row[44] ?? null),
|
||||||
|
'unit' => (int) $cleanValue($row[45] ?? null),
|
||||||
|
'usulan_retribusi' => (int) $cleanValue($row[46] ?? null),
|
||||||
|
'nilai_retribusi_keseluruhan_simbg' => $this->convertToDecimal($cleanValue($row[47] ?? 0)),
|
||||||
|
'nilai_retribusi_keseluruhan_pad' => $this->convertToDecimal($cleanValue($row[48] ?? 0)),
|
||||||
|
'denda' => $this->convertToDecimal($cleanValue($row[49] ?? 0)),
|
||||||
|
'latitude' => $cleanValue($row[50] ?? null),
|
||||||
|
'longitude' => $cleanValue($row[51] ?? null),
|
||||||
|
'nik_nib' => $cleanValue($row[52] ?? null),
|
||||||
|
'dok_tanah' => $cleanValue($row[53] ?? null),
|
||||||
|
'temuan' => $cleanValue($row[54] ?? null),
|
||||||
|
'updated_at' => now()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count occurrences of each no_registrasi
|
||||||
|
$registrasiCounts = array_count_values(array_column($mapUpsert, 'no_registrasi'));
|
||||||
|
|
||||||
|
// Filter duplicates (those appearing more than once)
|
||||||
|
$duplicates = array_filter($registrasiCounts, function ($count) {
|
||||||
|
return $count > 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!empty($duplicates)) {
|
||||||
|
Log::warning("Duplicate no_registrasi found", ['duplicates' => array_keys($duplicates)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove duplicates before upsert
|
||||||
|
$mapUpsert = collect($mapUpsert)->unique('no_registrasi')->values()->all();
|
||||||
|
|
||||||
|
$batchSize = 1000;
|
||||||
|
$chunks = array_chunk($mapUpsert, $batchSize);
|
||||||
|
foreach ($chunks as $chunk) {
|
||||||
|
PbgTaskGoogleSheet::upsert($chunk, ['no_registrasi']);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info("sync google sheet done");
|
||||||
|
return true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error("sync_google_sheet_data failed", ['error' => $e->getMessage()]);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function sync_big_data(){
|
||||||
|
try {
|
||||||
|
$sheet_big_data = $this->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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data_setting_result as $key => $value) {
|
||||||
|
DataSetting::updateOrInsert(
|
||||||
|
["key" => $key], // Find by key
|
||||||
|
["value" => $value] // Update or insert value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// **Log error**
|
||||||
|
Log::error("Error syncing Google Sheet data", ['error' => $e->getMessage()]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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 : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
173
app/Services/ServicePbgTask.php
Normal file
173
app/Services/ServicePbgTask.php
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Models\GlobalSetting;
|
||||||
|
use App\Models\PbgTask;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class ServicePbgTask
|
||||||
|
{
|
||||||
|
private $client;
|
||||||
|
private $simbg_host;
|
||||||
|
private $fetch_per_page;
|
||||||
|
private $pbg_task_url;
|
||||||
|
private $service_token;
|
||||||
|
private $user_token;
|
||||||
|
private $user_refresh_token;
|
||||||
|
|
||||||
|
public function __construct(Client $client, ServiceTokenSIMBG $service_token)
|
||||||
|
{
|
||||||
|
$settings = GlobalSetting::whereIn('key', ['SIMBG_HOST', 'FETCH_PER_PAGE'])
|
||||||
|
->pluck('value', 'key');
|
||||||
|
|
||||||
|
$this->simbg_host = trim((string) ($settings['SIMBG_HOST'] ?? ""));
|
||||||
|
$this->fetch_per_page = trim((string) ($settings['FETCH_PER_PAGE'] ?? "10"));
|
||||||
|
$this->client = $client;
|
||||||
|
$this->service_token = $service_token;
|
||||||
|
$this->pbg_task_url = "{$this->simbg_host}/api/pbg/v1/list/?page=1&size={$this->fetch_per_page}&sort=ASC";
|
||||||
|
$auth_data = $this->service_token->get_token();
|
||||||
|
$this->user_token = $auth_data['access'];
|
||||||
|
$this->user_refresh_token = $auth_data['refresh'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run_service()
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$this->fetch_pbg_task();
|
||||||
|
}catch(Exception $e){
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function fetch_pbg_task()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentPage = 1;
|
||||||
|
$totalPage = 1;
|
||||||
|
|
||||||
|
$options = [
|
||||||
|
'headers' => [
|
||||||
|
'Authorization' => "Bearer {$this->user_token}",
|
||||||
|
'Content-Type' => 'application/json'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$maxRetries = 3; // Maximum number of retries
|
||||||
|
$initialDelay = 1; // Initial delay in seconds
|
||||||
|
|
||||||
|
$fetchData = function ($url) use (&$options, $maxRetries, $initialDelay) {
|
||||||
|
$retryCount = 0;
|
||||||
|
|
||||||
|
while ($retryCount < $maxRetries) {
|
||||||
|
try {
|
||||||
|
return $this->client->get($url, $options);
|
||||||
|
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||||
|
if ($e->getCode() === 401) {
|
||||||
|
Log::warning("Unauthorized. Refreshing token...");
|
||||||
|
|
||||||
|
// Refresh token
|
||||||
|
$auth_data = $this->service_token->refresh_token($this->user_refresh_token);
|
||||||
|
if (!isset($auth_data['access'])) {
|
||||||
|
Log::error("Token refresh failed.");
|
||||||
|
throw new Exception("Token refresh failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update tokens
|
||||||
|
$this->user_token = $auth_data['access'];
|
||||||
|
$this->user_refresh_token = $auth_data['refresh'];
|
||||||
|
|
||||||
|
// Update headers
|
||||||
|
$options['headers']['Authorization'] = "Bearer {$this->user_token}";
|
||||||
|
|
||||||
|
// Retry request
|
||||||
|
return $this->client->get($url, $options);
|
||||||
|
}
|
||||||
|
throw $e;
|
||||||
|
} catch (\GuzzleHttp\Exception\ServerException | \GuzzleHttp\Exception\ConnectException $e) {
|
||||||
|
// Handle 502 or connection issues
|
||||||
|
if ($e->getCode() === 502) {
|
||||||
|
Log::warning("502 Bad Gateway - Retrying in {$initialDelay} seconds...");
|
||||||
|
} else {
|
||||||
|
Log::error("Network error - Retrying in {$initialDelay} seconds...");
|
||||||
|
}
|
||||||
|
|
||||||
|
$retryCount++;
|
||||||
|
sleep($initialDelay);
|
||||||
|
$initialDelay *= 2; // Exponential backoff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::error("Max retries reached. Failing request.");
|
||||||
|
throw new Exception("Max retries reached. Failing request.");
|
||||||
|
};
|
||||||
|
|
||||||
|
do {
|
||||||
|
$url = "{$this->simbg_host}/api/pbg/v1/list/?page={$currentPage}&size={$this->fetch_per_page}&sort=ASC";
|
||||||
|
|
||||||
|
$fetch_data = $fetchData($url);
|
||||||
|
if (!$fetch_data) {
|
||||||
|
Log::error("Failed to fetch data on page {$currentPage} after retries.");
|
||||||
|
throw new Exception("Failed to fetch data on page {$currentPage} after retries.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = json_decode($fetch_data->getBody()->getContents(), true);
|
||||||
|
if (!isset($response['data'])) {
|
||||||
|
Log::error("Invalid API response on page {$currentPage}");
|
||||||
|
throw new Exception("Invalid API response on page {$currentPage}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $response['data'];
|
||||||
|
$totalPage = isset($response['total_page']) ? (int) $response['total_page'] : 1;
|
||||||
|
|
||||||
|
$saved_data = [];
|
||||||
|
foreach ($data as $item) {
|
||||||
|
$saved_data[] = [
|
||||||
|
'uuid' => $item['uid'] ?? null,
|
||||||
|
'name' => $item['name'] ?? null,
|
||||||
|
'owner_name' => $item['owner_name'] ?? null,
|
||||||
|
'application_type' => $item['application_type'] ?? null,
|
||||||
|
'application_type_name' => $item['application_type_name'] ?? null,
|
||||||
|
'condition' => $item['condition'] ?? null,
|
||||||
|
'registration_number' => $item['registration_number'] ?? null,
|
||||||
|
'document_number' => $item['document_number'] ?? null,
|
||||||
|
'address' => $item['address'] ?? null,
|
||||||
|
'status' => $item['status'] ?? null,
|
||||||
|
'status_name' => $item['status_name'] ?? null,
|
||||||
|
'slf_status' => $item['slf_status'] ?? null,
|
||||||
|
'slf_status_name' => $item['slf_status_name'] ?? null,
|
||||||
|
'function_type' => $item['function_type'] ?? null,
|
||||||
|
'consultation_type' => $item['consultation_type'] ?? null,
|
||||||
|
'due_date' => $item['due_date'] ?? null,
|
||||||
|
'land_certificate_phase' => $item['land_certificate_phase'] ?? null,
|
||||||
|
'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(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($saved_data)) {
|
||||||
|
PbgTask::upsert($saved_data, ['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'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info("Page {$currentPage} fetched & saved", ['records' => count($saved_data)]);
|
||||||
|
|
||||||
|
$currentPage++;
|
||||||
|
} while ($currentPage <= $totalPage);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error("Error fetching PBG tasks", ['error' => $e->getMessage()]);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,12 +9,16 @@ use App\Models\ImportDatasource;
|
|||||||
use App\Models\PbgTaskIndexIntegrations;
|
use App\Models\PbgTaskIndexIntegrations;
|
||||||
use App\Models\PbgTaskPrasarana;
|
use App\Models\PbgTaskPrasarana;
|
||||||
use App\Models\PbgTaskRetributions;
|
use App\Models\PbgTaskRetributions;
|
||||||
|
use App\Models\TaskAssignment;
|
||||||
use Exception;
|
use Exception;
|
||||||
use App\Models\PbgTask;
|
use App\Models\PbgTask;
|
||||||
use App\Traits\GlobalApiResponse;
|
use App\Traits\GlobalApiResponse;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use App\Services\ServiceClient;
|
use App\Services\ServiceClient;
|
||||||
|
use App\Services\GoogleSheetService;
|
||||||
|
use App\Models\DataSetting;
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
|
||||||
class ServiceSIMBG
|
class ServiceSIMBG
|
||||||
{
|
{
|
||||||
@@ -24,10 +28,11 @@ class ServiceSIMBG
|
|||||||
private $simbg_host;
|
private $simbg_host;
|
||||||
private $fetch_per_page;
|
private $fetch_per_page;
|
||||||
private $service_client;
|
private $service_client;
|
||||||
|
private $googleSheetService;
|
||||||
/**
|
/**
|
||||||
* Create a new class instance.
|
* Create a new class instance.
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct(GoogleSheetService $googleSheetService)
|
||||||
{
|
{
|
||||||
$settings = GlobalSetting::whereIn('key', [
|
$settings = GlobalSetting::whereIn('key', [
|
||||||
'SIMBG_EMAIL', 'SIMBG_PASSWORD', 'SIMBG_HOST', 'FETCH_PER_PAGE'
|
'SIMBG_EMAIL', 'SIMBG_PASSWORD', 'SIMBG_HOST', 'FETCH_PER_PAGE'
|
||||||
@@ -39,6 +44,7 @@ class ServiceSIMBG
|
|||||||
$this->fetch_per_page = trim((string) ($settings['FETCH_PER_PAGE'] ?? ""));
|
$this->fetch_per_page = trim((string) ($settings['FETCH_PER_PAGE'] ?? ""));
|
||||||
|
|
||||||
$this->service_client = new ServiceClient($this->simbg_host);
|
$this->service_client = new ServiceClient($this->simbg_host);
|
||||||
|
$this->googleSheetService = $googleSheetService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getToken(){
|
public function getToken(){
|
||||||
@@ -61,13 +67,20 @@ class ServiceSIMBG
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncIndexIntegration($uuids, $token)
|
public function syncIndexIntegration($uuids)
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
if(empty($uuids)){
|
if(empty($uuids)){
|
||||||
return false;
|
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 = [];
|
$integrations = [];
|
||||||
foreach($uuids as $uuid){
|
foreach($uuids as $uuid){
|
||||||
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/indeks-terintegrasi/";
|
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/indeks-terintegrasi/";
|
||||||
@@ -81,13 +94,13 @@ class ServiceSIMBG
|
|||||||
if (empty($res->original['success']) || !$res->original['success']) {
|
if (empty($res->original['success']) || !$res->original['success']) {
|
||||||
// Log error
|
// Log error
|
||||||
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
|
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
|
||||||
return false;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $res->original['data']['data'] ?? null;
|
$data = $res->original['data']['data'] ?? null;
|
||||||
if (!$data) {
|
if (!$data) {
|
||||||
Log::error("No valid data returned from API", ['url' => $url, 'uuid' => $uuid]);
|
Log::error("No valid data returned from API", ['url' => $url, 'uuid' => $uuid]);
|
||||||
return false;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$integrations[] = [
|
$integrations[] = [
|
||||||
@@ -105,19 +118,6 @@ class ServiceSIMBG
|
|||||||
PbgTaskIndexIntegrations::upsert($integrations, ['pbg_task_uid'], ['indeks_fungsi_bangunan',
|
PbgTaskIndexIntegrations::upsert($integrations, ['pbg_task_uid'], ['indeks_fungsi_bangunan',
|
||||||
'indeks_parameter_kompleksitas', 'indeks_parameter_permanensi', 'indeks_parameter_ketinggian', 'faktor_kepemilikan', 'indeks_terintegrasi', 'total']);
|
'indeks_parameter_kompleksitas', 'indeks_parameter_permanensi', 'indeks_parameter_ketinggian', 'faktor_kepemilikan', 'indeks_terintegrasi', 'total']);
|
||||||
|
|
||||||
// $resultData = PbgTaskIndexIntegrations::updateOrCreate(
|
|
||||||
// ['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,
|
|
||||||
// ]
|
|
||||||
// );
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}catch (Exception $e){
|
}catch (Exception $e){
|
||||||
Log::error('error when sync index integration ', ['index integration'=> $e->getMessage()]);
|
Log::error('error when sync index integration ', ['index integration'=> $e->getMessage()]);
|
||||||
@@ -125,22 +125,183 @@ class ServiceSIMBG
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncTaskList()
|
public function syncTaskPBG()
|
||||||
{
|
{
|
||||||
$initResToken = $this->getToken();
|
try {
|
||||||
|
Log::info("Processing google sheet sync");
|
||||||
$importDatasource = ImportDatasource::create([
|
$importDatasource = ImportDatasource::create([
|
||||||
'status' => ImportDatasourceStatus::Processing->value,
|
'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'])) {
|
if (empty($initResToken->original['data']['token']['access'])) {
|
||||||
$importDatasource->update([
|
$importDatasource->update([
|
||||||
'status' => ImportDatasourceStatus::Failed->value,
|
'status' => ImportDatasourceStatus::Failed->value,
|
||||||
'message' => 'Failed to retrieve token'
|
'response_body' => 'Failed to retrieve token'
|
||||||
]);
|
]);
|
||||||
return $this->resError("Failed to retrieve token");
|
return $this->resError("Failed to retrieve token");
|
||||||
}
|
}
|
||||||
|
|
||||||
$apiToken = $initResToken->original['data']['token']['access'];
|
$apiToken = $initResToken->original['data']['token']['access'];
|
||||||
$headers = ['Authorization' => "Bearer " . $apiToken];
|
$headers = ['Authorization' => "Bearer " . $apiToken];
|
||||||
|
|
||||||
@@ -151,40 +312,56 @@ class ServiceSIMBG
|
|||||||
if ($totalPage == 0) {
|
if ($totalPage == 0) {
|
||||||
$importDatasource->update([
|
$importDatasource->update([
|
||||||
'status' => ImportDatasourceStatus::Failed->value,
|
'status' => ImportDatasourceStatus::Failed->value,
|
||||||
'message' => 'Invalid response: no total_page'
|
'response_body' => 'Invalid response: no total_page'
|
||||||
]);
|
]);
|
||||||
return $this->resError("Invalid response from API");
|
return $this->resError("Invalid response from API");
|
||||||
}
|
}
|
||||||
|
|
||||||
$savedCount = $failedCount = 0;
|
$savedCount = $failedCount = 0;
|
||||||
|
|
||||||
|
Log::info("Fetching tasks", ['total page' => $totalPage]);
|
||||||
|
|
||||||
for ($currentPage = 1; $currentPage <= $totalPage; $currentPage++) {
|
for ($currentPage = 1; $currentPage <= $totalPage; $currentPage++) {
|
||||||
|
try {
|
||||||
$pageUrl = "/api/pbg/v1/list/?page={$currentPage}&size={$this->fetch_per_page}&sort=ASC";
|
$pageUrl = "/api/pbg/v1/list/?page={$currentPage}&size={$this->fetch_per_page}&sort=ASC";
|
||||||
$getToken = $this->getToken();
|
|
||||||
Log::info("response index integration", ['currentPage' => $currentPage]);
|
Log::info("Fetching tasks", ['currentPage' => $currentPage]);
|
||||||
if (empty($getToken->original['data']['token']['access'])) {
|
$headers = [
|
||||||
$importDatasource->update([
|
'Authorization' => "Bearer " . $apiToken, // Update headers
|
||||||
'status' => ImportDatasourceStatus::Failed->value,
|
];
|
||||||
'message' => 'Failed to retrieve token'
|
|
||||||
]);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
$token = $getToken->original['data']['token']['access'];
|
|
||||||
$headers = ['Authorization' => "Bearer " . $token];
|
|
||||||
$response = $this->service_client->get($pageUrl, $headers);
|
|
||||||
$tasks = $response->original['data']['data'] ?? [];
|
$tasks = $response->original['data']['data'] ?? [];
|
||||||
|
|
||||||
if (empty($tasks)) {
|
if (empty($tasks)) {
|
||||||
$importDatasource->update([
|
|
||||||
'status' => ImportDatasourceStatus::Failed->value,
|
|
||||||
'message' => 'No data found on page'
|
|
||||||
]);
|
|
||||||
Log::warning("No data found on page", ['page' => $currentPage]);
|
Log::warning("No data found on page", ['page' => $currentPage]);
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::info("executed page", ['page' => $currentPage, 'total' => $totalPage]);
|
|
||||||
|
|
||||||
$tasksCollective = [];
|
$tasksCollective = [];
|
||||||
foreach ($tasks as $item) {
|
foreach ($tasks as $item) {
|
||||||
try {
|
try {
|
||||||
@@ -211,25 +388,20 @@ class ServiceSIMBG
|
|||||||
'created_at' => now(),
|
'created_at' => now(),
|
||||||
];
|
];
|
||||||
|
|
||||||
// $this->syncIndexIntegration($item['uid'], $token);
|
$this->syncTaskDetailSubmit($item['uid'], $apiToken);
|
||||||
|
$this->syncTaskAssignments($item['uid']);
|
||||||
$this->syncTaskDetailSubmit($item['uid'], $token);
|
|
||||||
|
|
||||||
$savedCount++;
|
$savedCount++;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$failedCount++;
|
$failedCount++;
|
||||||
$importDatasource->update([
|
|
||||||
'status' => ImportDatasourceStatus::Failed->value,
|
|
||||||
'message' => "Successfully processed: $savedCount, Failed: $failedCount"
|
|
||||||
]);
|
|
||||||
Log::error("Failed to process task", [
|
Log::error("Failed to process task", [
|
||||||
'error' => $e->getMessage(),
|
'error' => $e->getMessage(),
|
||||||
'task' => $item,
|
'task' => $item,
|
||||||
]);
|
]);
|
||||||
break;
|
continue; // Skip failed task, continue processing the rest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($tasksCollective)) {
|
||||||
PbgTask::upsert($tasksCollective, ['uuid'], [
|
PbgTask::upsert($tasksCollective, ['uuid'], [
|
||||||
'name', 'owner_name', 'application_type', 'application_type_name', 'condition',
|
'name', 'owner_name', 'application_type', 'application_type_name', 'condition',
|
||||||
'registration_number', 'document_number', 'address', 'status', 'status_name',
|
'registration_number', 'document_number', 'address', 'status', 'status_name',
|
||||||
@@ -238,41 +410,80 @@ class ServiceSIMBG
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$uuids = array_column($tasksCollective, 'uuid');
|
$uuids = array_column($tasksCollective, 'uuid');
|
||||||
$this->syncIndexIntegration($uuids, $token);
|
$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, "all", $data_setting_result);
|
||||||
|
BigdataResume::generateResumeData($importDatasource->id, now()->year, $data_setting_result);
|
||||||
|
|
||||||
|
// Final update after processing all pages
|
||||||
$importDatasource->update([
|
$importDatasource->update([
|
||||||
'status' => ImportDatasourceStatus::Success->value,
|
'status' => ImportDatasourceStatus::Success->value,
|
||||||
'message' => "Successfully processed: $savedCount, Failed: $failedCount"
|
'message' => "Successfully processed: $savedCount, Failed: $failedCount"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
BigdataResume::generateResumeData($importDatasource->id);
|
|
||||||
|
|
||||||
Log::info("syncTaskList completed", ['savedCount' => $savedCount, 'failedCount' => $failedCount]);
|
Log::info("syncTaskList completed", ['savedCount' => $savedCount, 'failedCount' => $failedCount]);
|
||||||
|
|
||||||
return $this->resSuccess(['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)
|
public function syncTaskDetailSubmit($uuid, $token)
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/submit/";
|
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/submit/";
|
||||||
|
|
||||||
$headers = [
|
$headers = [
|
||||||
'Authorization' => "Bearer " . $token,
|
'Authorization' => "Bearer " . $token,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
for ($attempt = 0; $attempt < 2; $attempt++) {
|
||||||
$res = $this->service_client->get($url, $headers);
|
$res = $this->service_client->get($url, $headers);
|
||||||
|
|
||||||
if (empty($res->original['success']) || !$res->original['success']) {
|
// Check if response is JsonResponse and decode it
|
||||||
// Log error
|
if ($res instanceof \Illuminate\Http\JsonResponse) {
|
||||||
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
|
$decodedResponse = json_decode($res->getContent(), true);
|
||||||
return false;
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $res->original['data']['data'] ?? [];
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure response is valid before accessing properties
|
||||||
|
$responseData = $res->original ?? [];
|
||||||
|
$data = $responseData['data']['data'] ?? [];
|
||||||
if (empty($data)) {
|
if (empty($data)) {
|
||||||
Log::error("No data returned from API", ['url' => $url, 'uuid' => $uuid]);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,4 +546,118 @@ class ServiceSIMBG
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
408
app/Services/ServiceTabPbgTask.php
Normal file
408
app/Services/ServiceTabPbgTask.php
Normal file
@@ -0,0 +1,408 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Models\GlobalSetting;
|
||||||
|
use App\Models\PbgTask;
|
||||||
|
use App\Models\PbgTaskIndexIntegrations;
|
||||||
|
use App\Models\PbgTaskPrasarana;
|
||||||
|
use App\Models\PbgTaskRetributions;
|
||||||
|
use App\Models\TaskAssignment;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
class ServiceTabPbgTask
|
||||||
|
{
|
||||||
|
private $client;
|
||||||
|
private $simbg_host;
|
||||||
|
private $fetch_per_page;
|
||||||
|
private $service_token;
|
||||||
|
private $user_token;
|
||||||
|
private $user_refresh_token;
|
||||||
|
|
||||||
|
public function __construct(Client $client, ServiceTokenSIMBG $service_token)
|
||||||
|
{
|
||||||
|
$settings = GlobalSetting::whereIn('key', ['SIMBG_HOST', 'FETCH_PER_PAGE'])
|
||||||
|
->pluck('value', 'key');
|
||||||
|
|
||||||
|
$this->simbg_host = trim((string) ($settings['SIMBG_HOST'] ?? ""));
|
||||||
|
$this->fetch_per_page = trim((string) ($settings['FETCH_PER_PAGE'] ?? "10"));
|
||||||
|
$this->client = $client;
|
||||||
|
$this->service_token = $service_token;
|
||||||
|
$auth_data = $this->service_token->get_token();
|
||||||
|
$this->user_token = $auth_data['access'];
|
||||||
|
$this->user_refresh_token = $auth_data['refresh'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run_service()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$pbg_tasks = PbgTask::all();
|
||||||
|
|
||||||
|
foreach ($pbg_tasks as $pbg_task) {
|
||||||
|
$this->scraping_task_assignments($pbg_task->uuid);
|
||||||
|
$this->scraping_task_retributions($pbg_task->uuid);
|
||||||
|
$this->scraping_task_integrations($pbg_task->uuid);
|
||||||
|
|
||||||
|
// Process task assignments here if needed
|
||||||
|
Log::info("Successfully fetched for UUID: {$pbg_task->uuid}");
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error("Failed to scrape task assignments: " . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function scraping_task_assignments($uuid)
|
||||||
|
{
|
||||||
|
$url = "{$this->simbg_host}/api/pbg/v1/list-tim-penilai/{$uuid}/?page=1&size=10";
|
||||||
|
$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);
|
||||||
|
|
||||||
|
if (empty($responseData['data']) || !is_array($responseData['data'])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$task_assignments = [];
|
||||||
|
|
||||||
|
foreach ($responseData['data'] as $data) {
|
||||||
|
$task_assignments[] = [
|
||||||
|
'pbg_task_uid' => $uuid,
|
||||||
|
'user_id' => $data['user_id'] ?? null,
|
||||||
|
'name' => $data['name'] ?? null,
|
||||||
|
'username' => $data['username'] ?? null,
|
||||||
|
'email' => $data['email'] ?? null,
|
||||||
|
'phone_number' => $data['phone_number'] ?? null,
|
||||||
|
'role' => $data['role'] ?? null,
|
||||||
|
'role_name' => $data['role_name'] ?? null,
|
||||||
|
'is_active' => $data['is_active'] ?? false,
|
||||||
|
'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'] ?? false,
|
||||||
|
'uid' => $data['uid'] ?? null,
|
||||||
|
'status' => $data['status'] ?? null,
|
||||||
|
'status_name' => $data['status_name'] ?? null,
|
||||||
|
'note' => $data['note'] ?? null,
|
||||||
|
'ta_id' => $data['id'] ?? null,
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($task_assignments)) {
|
||||||
|
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 $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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
} 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 (\Exception $e) {
|
||||||
|
Log::error("Unexpected error: " . $e->getMessage());
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::error("Failed to fetch task assignments for UUID {$uuid} after {$maxRetries} retries.");
|
||||||
|
throw new \Exception("Failed to fetch task assignments for UUID {$uuid} after retries.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function scraping_task_retributions($uuid)
|
||||||
|
{
|
||||||
|
$url = "{$this->simbg_host}/api/pbg/v1/detail/" . $uuid . "/retribution/submit/";
|
||||||
|
$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'];
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
PbgTaskPrasarana::upsert($insertData, ['prasarana_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 retributions for UUID {$uuid} after retries.");
|
||||||
|
throw new \Exception("Failed to fetch task retributions for UUID {$uuid} after retries.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function scraping_task_integrations($uuid){
|
||||||
|
$url = "{$this->simbg_host}/api/pbg/v1/detail/" . $uuid . "/retribution/indeks-terintegrasi/";
|
||||||
|
$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'];
|
||||||
|
|
||||||
|
$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,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!empty($integrations)) {
|
||||||
|
PbgTaskIndexIntegrations::upsert($integrations, ['pbg_task_uid'], ['indeks_fungsi_bangunan',
|
||||||
|
'indeks_parameter_kompleksitas', 'indeks_parameter_permanensi', 'indeks_parameter_ketinggian', 'faktor_kepemilikan', 'indeks_terintegrasi', 'total']);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 index integration for UUID {$uuid} after retries.");
|
||||||
|
throw new \Exception("Failed to fetch task index integration for UUID {$uuid} after retries.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function refreshToken()
|
||||||
|
{
|
||||||
|
$maxRetries = 3; // Maximum retry attempts
|
||||||
|
$attempt = 0;
|
||||||
|
|
||||||
|
while ($attempt < $maxRetries) {
|
||||||
|
try {
|
||||||
|
$attempt++;
|
||||||
|
Log::info("Attempt $attempt: Refreshing token...");
|
||||||
|
|
||||||
|
$newAuthToken = $this->service_token->refresh_token($this->user_refresh_token);
|
||||||
|
|
||||||
|
if (!isset($newAuthToken['access']) || !isset($newAuthToken['refresh'])) {
|
||||||
|
throw new \Exception("Invalid refresh token response.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->user_token = $newAuthToken['access'];
|
||||||
|
$this->user_refresh_token = $newAuthToken['refresh'];
|
||||||
|
|
||||||
|
Log::info("Token refreshed successfully on attempt $attempt.");
|
||||||
|
return; // Exit function on success
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error("Token refresh failed on attempt $attempt: " . $e->getMessage());
|
||||||
|
|
||||||
|
if ($attempt >= $maxRetries) {
|
||||||
|
Log::info("Max retries reached. Attempting to log in again...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(30); // Wait for 30 seconds before retrying
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If refresh fails after retries, attempt re-login
|
||||||
|
$attempt = 0;
|
||||||
|
while ($attempt < $maxRetries) {
|
||||||
|
try {
|
||||||
|
$attempt++;
|
||||||
|
Log::info("Attempt $attempt: Re-logging in...");
|
||||||
|
|
||||||
|
$loginAgain = $this->service_token->get_token(); // Login again
|
||||||
|
|
||||||
|
if (!isset($loginAgain['access']) || !isset($loginAgain['refresh'])) {
|
||||||
|
throw new \Exception("Invalid login response.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->user_token = $loginAgain['access'];
|
||||||
|
$this->user_refresh_token = $loginAgain['refresh'];
|
||||||
|
|
||||||
|
Log::info("Re-login successful on attempt $attempt.");
|
||||||
|
return; // Exit function on success
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error("Re-login failed on attempt $attempt: " . $e->getMessage());
|
||||||
|
|
||||||
|
if ($attempt >= $maxRetries) {
|
||||||
|
throw new \Exception("Both token refresh and login failed after $maxRetries attempts. " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(30); // Wait for 30 seconds before retrying
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
79
app/Services/ServiceTokenSIMBG.php
Normal file
79
app/Services/ServiceTokenSIMBG.php
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
use App\Models\GlobalSetting;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use GuzzleHttp\Exception\RequestException;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
class ServiceTokenSIMBG
|
||||||
|
{
|
||||||
|
private $client;
|
||||||
|
private $login_url;
|
||||||
|
private $email;
|
||||||
|
private $password;
|
||||||
|
private $simbg_host;
|
||||||
|
private $fetch_per_page;
|
||||||
|
private $refresh_url;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$settings = GlobalSetting::whereIn('key', [
|
||||||
|
'SIMBG_EMAIL', 'SIMBG_PASSWORD', 'SIMBG_HOST', 'FETCH_PER_PAGE'
|
||||||
|
])->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->client = new Client();
|
||||||
|
$this->login_url = $this->simbg_host . "/api/user/v1/auth/login/";
|
||||||
|
$this->refresh_url = $this->simbg_host. "/api/user/v1/auth/token/refresh/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_token(){
|
||||||
|
try {
|
||||||
|
$response = $this->client->request('POST', $this->login_url, [
|
||||||
|
'headers' => [
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'Accept' => 'application/json',
|
||||||
|
],
|
||||||
|
'json' => [
|
||||||
|
'email' => $this->email,
|
||||||
|
'password' => $this->password
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$data = json_decode($response->getBody()->getContents(), true);
|
||||||
|
|
||||||
|
return $data['token'];
|
||||||
|
} catch (RequestException $e) {
|
||||||
|
Log::error("Failed to get token", [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'response' => $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
|
||||||
|
]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refresh_token(string $refresh_token){
|
||||||
|
try {
|
||||||
|
$response = $this->client->request('POST', $this->refresh_url, [
|
||||||
|
'headers' => [
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'Accept' => 'application/json',
|
||||||
|
],
|
||||||
|
'json' => [
|
||||||
|
'refresh' => $refresh_token
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$data = json_decode($response->getBody()->getContents(), true);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Log::error("Failed to refresh token", [
|
||||||
|
'error' => $th->getMessage()
|
||||||
|
]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
|
"barryvdh/laravel-dompdf": "^3.1",
|
||||||
"google/apiclient": "^2.12",
|
"google/apiclient": "^2.12",
|
||||||
"guzzlehttp/guzzle": "^7.9",
|
"guzzlehttp/guzzle": "^7.9",
|
||||||
"laravel/framework": "^11.31",
|
"laravel/framework": "^11.31",
|
||||||
@@ -57,7 +58,7 @@
|
|||||||
],
|
],
|
||||||
"dev": [
|
"dev": [
|
||||||
"Composer\\Config::disableProcessTimeout",
|
"Composer\\Config::disableProcessTimeout",
|
||||||
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite"
|
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
|
|||||||
370
composer.lock
generated
370
composer.lock
generated
@@ -4,8 +4,85 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "41bb51871a746904ab745e4095db8b46",
|
"content-hash": "e657a4f0a463fa048a0110c08babba93",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "barryvdh/laravel-dompdf",
|
||||||
|
"version": "v3.1.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/barryvdh/laravel-dompdf.git",
|
||||||
|
"reference": "8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d",
|
||||||
|
"reference": "8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"dompdf/dompdf": "^3.0",
|
||||||
|
"illuminate/support": "^9|^10|^11|^12",
|
||||||
|
"php": "^8.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"larastan/larastan": "^2.7|^3.0",
|
||||||
|
"orchestra/testbench": "^7|^8|^9|^10",
|
||||||
|
"phpro/grumphp": "^2.5",
|
||||||
|
"squizlabs/php_codesniffer": "^3.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"aliases": {
|
||||||
|
"PDF": "Barryvdh\\DomPDF\\Facade\\Pdf",
|
||||||
|
"Pdf": "Barryvdh\\DomPDF\\Facade\\Pdf"
|
||||||
|
},
|
||||||
|
"providers": [
|
||||||
|
"Barryvdh\\DomPDF\\ServiceProvider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Barryvdh\\DomPDF\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Barry vd. Heuvel",
|
||||||
|
"email": "barryvdh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A DOMPDF Wrapper for Laravel",
|
||||||
|
"keywords": [
|
||||||
|
"dompdf",
|
||||||
|
"laravel",
|
||||||
|
"pdf"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/barryvdh/laravel-dompdf/issues",
|
||||||
|
"source": "https://github.com/barryvdh/laravel-dompdf/tree/v3.1.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://fruitcake.nl",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/barryvdh",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-02-13T15:07:54+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
"version": "0.12.1",
|
"version": "0.12.1",
|
||||||
@@ -538,6 +615,161 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-02-05T11:56:58+00:00"
|
"time": "2024-02-05T11:56:58+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "dompdf/dompdf",
|
||||||
|
"version": "v3.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/dompdf/dompdf.git",
|
||||||
|
"reference": "a51bd7a063a65499446919286fb18b518177155a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/a51bd7a063a65499446919286fb18b518177155a",
|
||||||
|
"reference": "a51bd7a063a65499446919286fb18b518177155a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"dompdf/php-font-lib": "^1.0.0",
|
||||||
|
"dompdf/php-svg-lib": "^1.0.0",
|
||||||
|
"ext-dom": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"masterminds/html5": "^2.0",
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-json": "*",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"mockery/mockery": "^1.3",
|
||||||
|
"phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11",
|
||||||
|
"squizlabs/php_codesniffer": "^3.5",
|
||||||
|
"symfony/process": "^4.4 || ^5.4 || ^6.2 || ^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-gd": "Needed to process images",
|
||||||
|
"ext-gmagick": "Improves image processing performance",
|
||||||
|
"ext-imagick": "Improves image processing performance",
|
||||||
|
"ext-zlib": "Needed for pdf stream compression"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Dompdf\\": "src/"
|
||||||
|
},
|
||||||
|
"classmap": [
|
||||||
|
"lib/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-2.1"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "The Dompdf Community",
|
||||||
|
"homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
|
||||||
|
"homepage": "https://github.com/dompdf/dompdf",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/dompdf/dompdf/issues",
|
||||||
|
"source": "https://github.com/dompdf/dompdf/tree/v3.1.0"
|
||||||
|
},
|
||||||
|
"time": "2025-01-15T14:09:04+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dompdf/php-font-lib",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/dompdf/php-font-lib.git",
|
||||||
|
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
|
||||||
|
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"FontLib\\": "src/FontLib"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-2.1-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "The FontLib Community",
|
||||||
|
"homepage": "https://github.com/dompdf/php-font-lib/blob/master/AUTHORS.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A library to read, parse, export and make subsets of different types of font files.",
|
||||||
|
"homepage": "https://github.com/dompdf/php-font-lib",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/dompdf/php-font-lib/issues",
|
||||||
|
"source": "https://github.com/dompdf/php-font-lib/tree/1.0.1"
|
||||||
|
},
|
||||||
|
"time": "2024-12-02T14:37:59+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dompdf/php-svg-lib",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/dompdf/php-svg-lib.git",
|
||||||
|
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
|
||||||
|
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": "^7.1 || ^8.0",
|
||||||
|
"sabberworm/php-css-parser": "^8.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Svg\\": "src/Svg"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-3.0-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "The SvgLib Community",
|
||||||
|
"homepage": "https://github.com/dompdf/php-svg-lib/blob/master/AUTHORS.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A library to read, parse and export to PDF SVG files.",
|
||||||
|
"homepage": "https://github.com/dompdf/php-svg-lib",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/dompdf/php-svg-lib/issues",
|
||||||
|
"source": "https://github.com/dompdf/php-svg-lib/tree/1.0.0"
|
||||||
|
},
|
||||||
|
"time": "2024-04-29T13:26:35+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dragonmantank/cron-expression",
|
"name": "dragonmantank/cron-expression",
|
||||||
"version": "v3.4.0",
|
"version": "v3.4.0",
|
||||||
@@ -2794,6 +3026,73 @@
|
|||||||
},
|
},
|
||||||
"time": "2022-12-02T22:17:43+00:00"
|
"time": "2022-12-02T22:17:43+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "masterminds/html5",
|
||||||
|
"version": "2.9.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Masterminds/html5-php.git",
|
||||||
|
"reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6",
|
||||||
|
"reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-dom": "*",
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.7-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Masterminds\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Matt Butcher",
|
||||||
|
"email": "technosophos@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Matt Farina",
|
||||||
|
"email": "matt@mattfarina.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Asmir Mustafic",
|
||||||
|
"email": "goetas@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "An HTML5 parser and serializer.",
|
||||||
|
"homepage": "http://masterminds.github.io/html5-php",
|
||||||
|
"keywords": [
|
||||||
|
"HTML5",
|
||||||
|
"dom",
|
||||||
|
"html",
|
||||||
|
"parser",
|
||||||
|
"querypath",
|
||||||
|
"serializer",
|
||||||
|
"xml"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Masterminds/html5-php/issues",
|
||||||
|
"source": "https://github.com/Masterminds/html5-php/tree/2.9.0"
|
||||||
|
},
|
||||||
|
"time": "2024-03-31T07:05:07+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "monolog/monolog",
|
"name": "monolog/monolog",
|
||||||
"version": "3.8.1",
|
"version": "3.8.1",
|
||||||
@@ -4695,6 +4994,71 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-04-27T21:32:50+00:00"
|
"time": "2024-04-27T21:32:50+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "sabberworm/php-css-parser",
|
||||||
|
"version": "v8.7.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
|
||||||
|
"reference": "f414ff953002a9b18e3a116f5e462c56f21237cf"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/f414ff953002a9b18e3a116f5e462c56f21237cf",
|
||||||
|
"reference": "f414ff953002a9b18e3a116f5e462c56f21237cf",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-iconv": "*",
|
||||||
|
"php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.40"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-mbstring": "for parsing UTF-8 CSS"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "9.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Sabberworm\\CSS\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Raphael Schweikert"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Oliver Klee",
|
||||||
|
"email": "github@oliverklee.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jake Hotson",
|
||||||
|
"email": "jake.github@qzdesign.co.uk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Parser for CSS Files written in PHP",
|
||||||
|
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
|
||||||
|
"keywords": [
|
||||||
|
"css",
|
||||||
|
"parser",
|
||||||
|
"stylesheet"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
|
||||||
|
"source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.7.0"
|
||||||
|
},
|
||||||
|
"time": "2024-10-27T17:38:32+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/clock",
|
"name": "symfony/clock",
|
||||||
"version": "v7.2.0",
|
"version": "v7.2.0",
|
||||||
@@ -9474,12 +9838,12 @@
|
|||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": {},
|
"stability-flags": [],
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "^8.2"
|
"php": "^8.2"
|
||||||
},
|
},
|
||||||
"platform-dev": {},
|
"platform-dev": [],
|
||||||
"plugin-api-version": "2.6.0"
|
"plugin-api-version": "2.6.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,5 +123,6 @@ return [
|
|||||||
'store' => env('APP_MAINTENANCE_STORE', 'database'),
|
'store' => env('APP_MAINTENANCE_STORE', 'database'),
|
||||||
],
|
],
|
||||||
|
|
||||||
'api_url' => env('API_URL', 'http://localhost:8000')
|
'api_url' => env('API_URL', 'http://localhost:8000'),
|
||||||
|
'paginate_per_page' => 50
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ return [
|
|||||||
'engine' => null,
|
'engine' => null,
|
||||||
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||||
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
||||||
|
PDO::ATTR_TIMEOUT => 40000,
|
||||||
|
PDO::MYSQL_ATTR_INIT_COMMAND => "SET SESSION wait_timeout=40000; SET SESSION interactive_timeout=40000;"
|
||||||
]) : [],
|
]) : [],
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
@@ -109,4 +109,10 @@ return [
|
|||||||
'table' => 'failed_jobs',
|
'table' => 'failed_jobs',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// set timeout queue
|
||||||
|
|
||||||
|
'worker' => [
|
||||||
|
'timeout' => 40000
|
||||||
|
]
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?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::table('bigdata_resumes', function (Blueprint $table) {
|
||||||
|
$table->integer('spatial_count')->default(0);
|
||||||
|
$table->decimal('spatial_sum', 20,2)->default(0);
|
||||||
|
$table->string('year');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('bigdata_resumes', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('spatial_count');
|
||||||
|
$table->dropColumn('spatial_sum');
|
||||||
|
$table->dropColumn('year');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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::table('bigdata_resumes', function (Blueprint $table) {
|
||||||
|
$table->integer('waiting_click_dpmptsp_count')->default(0);
|
||||||
|
$table->decimal('waiting_click_dpmptsp_sum', 20,2)->default(0);
|
||||||
|
$table->integer('issuance_realization_pbg_count')->default(0);
|
||||||
|
$table->decimal('issuance_realization_pbg_sum', 20,2)->default(0);
|
||||||
|
$table->integer('process_in_technical_office_count')->default(0);
|
||||||
|
$table->decimal('process_in_technical_office_sum', 20,2)->default(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('bigdata_resumes', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('waiting_click_dpmptsp_count');
|
||||||
|
$table->dropColumn('waiting_click_dpmptsp_sum');
|
||||||
|
$table->dropColumn('issuance_realization_pbg_count');
|
||||||
|
$table->dropColumn('issuance_realization_pbg_sum');
|
||||||
|
$table->dropColumn('process_in_technical_office_count');
|
||||||
|
$table->dropColumn('process_in_technical_office_sum');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<?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('task_assignments', function (Blueprint $table) {
|
||||||
|
$table->id(); // Auto-increment primary key
|
||||||
|
|
||||||
|
// Foreign key reference to pbg_tasks (uid column)
|
||||||
|
$table->string('pbg_task_uid');
|
||||||
|
$table->foreign('pbg_task_uid')->references('uuid')->on('pbg_task')->onDelete('cascade');
|
||||||
|
|
||||||
|
$table->unsignedBigInteger('user_id'); // Reference to users table
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('username')->unique();
|
||||||
|
$table->string('email')->unique();
|
||||||
|
$table->string('phone_number')->nullable();
|
||||||
|
$table->unsignedInteger('role'); // Assuming role is numeric
|
||||||
|
$table->string('role_name');
|
||||||
|
$table->boolean('is_active')->default(true);
|
||||||
|
$table->json('file')->nullable(); // Store as JSON if 'file' is an array
|
||||||
|
$table->string('expertise')->nullable();
|
||||||
|
$table->string('experience')->nullable();
|
||||||
|
$table->boolean('is_verif')->default(false);
|
||||||
|
$table->string('uid')->unique();
|
||||||
|
$table->unsignedTinyInteger('status')->default(0); // Assuming status is a small integer
|
||||||
|
$table->string('status_name')->nullable();
|
||||||
|
$table->text('note')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('task_assignments');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?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::table('task_assignments', function (Blueprint $table) {
|
||||||
|
$table->json('expertise')->nullable()->change();
|
||||||
|
$table->json('experience')->nullable()->change();
|
||||||
|
$table->bigInteger('ta_id')->nullable()->after('id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('task_assignments', function (Blueprint $table) {
|
||||||
|
$table->text('expertise')->nullable()->change();
|
||||||
|
$table->text('experience')->nullable()->change();
|
||||||
|
$table->dropColumn('ta_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?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::table('task_assignments', function (Blueprint $table) {
|
||||||
|
$indexes = DB::select("SHOW INDEXES FROM task_assignments WHERE Key_name = 'task_assignments_email_unique'");
|
||||||
|
|
||||||
|
if (!empty($indexes)) {
|
||||||
|
$table->dropUnique('task_assignments_email_unique');
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexes = DB::select("SHOW INDEXES FROM task_assignments WHERE Key_name = 'task_assignments_username_unique'");
|
||||||
|
|
||||||
|
if (!empty($indexes)) {
|
||||||
|
$table->dropUnique('task_assignments_username_unique');
|
||||||
|
}
|
||||||
|
$table->string('email')->nullable()->change();
|
||||||
|
$table->string('username')->nullable()->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('task_assignments', function (Blueprint $table) {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?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::table('users', function (Blueprint $table) {
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->dropSoftDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?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::table('import_datasources', function (Blueprint $table) {
|
||||||
|
$table->timestamp('start_time')->nullable();
|
||||||
|
$table->timestamp('finish_time')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('import_datasources', function (Blueprint $table) {
|
||||||
|
$table->dropColumn(['start_time', 'finish_time']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -15,17 +15,23 @@ class DatabaseSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
// User::factory(10)->create();
|
User::updateOrCreate(
|
||||||
|
['email' => 'user@demo.com'], // Kondisi pencarian
|
||||||
User::factory()->create([
|
[
|
||||||
'name' => 'Darkone',
|
'name' => 'Darkone',
|
||||||
'email' => 'user@demo.com',
|
|
||||||
'email_verified_at' => now(),
|
'email_verified_at' => now(),
|
||||||
'password' => Hash::make('password'),
|
'password' => Hash::make('password'),
|
||||||
'firstname' => 'John',
|
'firstname' => 'John',
|
||||||
'lastname' => 'Doe',
|
'lastname' => 'Doe',
|
||||||
'position' => 'crusial',
|
'position' => 'crusial',
|
||||||
'remember_token' => Str::random(10),
|
'remember_token' => Str::random(10),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->call([
|
||||||
|
RoleSeeder::class,
|
||||||
|
MenuSeeder::class,
|
||||||
|
UsersRoleMenuSeeder::class
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
287
database/seeders/MenuSeeder.php
Normal file
287
database/seeders/MenuSeeder.php
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use App\Models\Menu;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class MenuSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$menus = [
|
||||||
|
[
|
||||||
|
"name" => "Dashboard",
|
||||||
|
"url" => "/dashboard",
|
||||||
|
"icon" => "mingcute:home-3-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"name" => "Dashboard Pimpinan",
|
||||||
|
"url" => "dashboard.home",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Dashboard PBG",
|
||||||
|
"url" => "dashboard.pbg",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Dashboard Potensi",
|
||||||
|
"url" => '/potentials',
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 3,
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"name" => "Luar Sistem",
|
||||||
|
"url" => "dashboard.potentials.inside_system",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Dalam Sistem",
|
||||||
|
"url" => "dashboard.potentials.outside_system",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 2,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "PETA",
|
||||||
|
"url" => "dashboard.maps",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 4,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Master",
|
||||||
|
"url" => "/master",
|
||||||
|
"icon" => "mingcute:cylinder-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 2,
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"name" => "Users",
|
||||||
|
"url" => "users.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Settings",
|
||||||
|
"url" => "/settings",
|
||||||
|
"icon" => "mingcute:settings-6-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 3,
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"name" => "Syncronize",
|
||||||
|
"url" => "settings.syncronize",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Menu",
|
||||||
|
"url" => "menus.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Role",
|
||||||
|
"url" => "roles.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 3,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Data Settings",
|
||||||
|
"url" => "/data-settings",
|
||||||
|
"icon" => "mingcute:settings-1-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 4,
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"name" => "Setting Dashboard",
|
||||||
|
"url" => "data-settings.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Data",
|
||||||
|
"url" => "/data",
|
||||||
|
"icon" => "mingcute:task-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 5,
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"name" => "PBG",
|
||||||
|
"url" => "pbg-task.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Reklame",
|
||||||
|
"url" => "web-advertisements.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Usaha atau Industri",
|
||||||
|
"url" => "business-industries.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "UMKM",
|
||||||
|
"url" => "web-umkm.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 4,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Pariwisata",
|
||||||
|
"url" => "web-tourisms.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 5,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Tata Ruang",
|
||||||
|
"url" => "web-spatial-plannings.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 6,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "PDAM",
|
||||||
|
"url" => "customers",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 7,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Google Sheets",
|
||||||
|
"url" => "google-sheets",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 8,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "TPA TPT",
|
||||||
|
"url" => "tpa-tpt.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 9,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Laporan",
|
||||||
|
"url" => "/laporan",
|
||||||
|
"icon" => "mingcute:report-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 6,
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"name" => "Lap Pariwisata",
|
||||||
|
"url" => "tourisms-report.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Lap Pimpinan",
|
||||||
|
"url" => "bigdata-resumes",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Rekap Pembayaran",
|
||||||
|
"url" => "payment-recaps",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Lap Rekap Data Pembayaran",
|
||||||
|
"url" => "report-payment-recaps",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 4,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Lap PBG (PTSP)",
|
||||||
|
"url" => "report-pbg-ptsp",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 5,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Neng Bedas",
|
||||||
|
"url" => "/chat",
|
||||||
|
"icon" => "mingcute:wechat-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 7,
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"name" => "Chat",
|
||||||
|
"url" => "main-chatbot.index",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Approval",
|
||||||
|
"url" => "/approval",
|
||||||
|
"icon" => "mingcute:user-follow-2-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 8,
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"name" => "Approval Pejabat",
|
||||||
|
"url" => "approval-list",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Tools",
|
||||||
|
"url" => "/tools",
|
||||||
|
"icon" => "mingcute:tool-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 9,
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"name" => "Undangan",
|
||||||
|
"url" => "invitations",
|
||||||
|
"icon" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($menus as $menuData) {
|
||||||
|
$this->createOrUpdateMenu($menuData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createOrUpdateMenu($menuData, $parentId = null){
|
||||||
|
$menuData['parent_id'] = $parentId;
|
||||||
|
|
||||||
|
$menu = Menu::updateOrCreate(['name' => $menuData['name']], Arr::except($menuData, ['children']));
|
||||||
|
|
||||||
|
if(!empty($menuData['children'])){
|
||||||
|
foreach($menuData['children'] as $child){
|
||||||
|
$this->createOrUpdateMenu($child, $menu->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
database/seeders/RoleSeeder.php
Normal file
37
database/seeders/RoleSeeder.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\Role;
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class RoleSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$roles = [
|
||||||
|
[
|
||||||
|
"name" => "superadmin",
|
||||||
|
"description" => "show all menus for super admins",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "admin",
|
||||||
|
"description" => "show only necessary menus for admins",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "operator",
|
||||||
|
"description" => "show only necessary menus for operators",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "user",
|
||||||
|
"description" => "show only necessary menus for users",
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
Role::upsert($roles, ['name']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,271 +15,52 @@ class UsersRoleMenuSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$roles = [
|
// Fetch roles in a single query
|
||||||
[
|
$roles = Role::whereIn('name', ['superadmin', 'admin', 'operator'])->get()->keyBy('name');
|
||||||
"name" => "superadmin",
|
|
||||||
"description" => "show all menus for super admins",
|
// Fetch all menus in a single query and index by name
|
||||||
|
$menus = Menu::whereIn('name', [
|
||||||
|
'Dashboard', 'Master', 'Settings', 'Data Settings', 'Data', 'Laporan', 'Neng Bedas',
|
||||||
|
'Approval', 'Tools', 'Dashboard Pimpinan', 'Dashboard PBG', 'Users', 'Syncronize',
|
||||||
|
'Menu', 'Role', 'Setting Dashboard', 'PBG', 'Reklame', 'Usaha atau Industri', 'Pariwisata',
|
||||||
|
'Lap Pariwisata', 'UMKM', 'Dashboard Potensi', 'Tata Ruang', 'PDAM', 'PETA',
|
||||||
|
'Lap Pimpinan', 'Chat', 'Dalam Sistem', 'Luar Sistem', 'Google Sheets', 'TPA TPT',
|
||||||
|
'Approval Pejabat', 'Undangan', 'Rekap Pembayaran', 'Lap Rekap Data Pembayaran', 'Lap PBG (PTSP)'
|
||||||
|
])->get()->keyBy('name');
|
||||||
|
|
||||||
|
// Define access levels for each role
|
||||||
|
$permissions = [
|
||||||
|
'superadmin' => [
|
||||||
|
'Dashboard', 'Master', 'Settings', 'Data Settings', 'Data', 'Laporan', 'Neng Bedas',
|
||||||
|
'Approval', 'Tools', 'Dashboard Pimpinan', 'Dashboard PBG', 'Users', 'Syncronize',
|
||||||
|
'Menu', 'Role', 'Setting Dashboard', 'PBG', 'Reklame', 'Usaha atau Industri', 'Pariwisata',
|
||||||
|
'Lap Pariwisata', 'UMKM', 'Dashboard Potensi', 'Tata Ruang', 'PDAM', 'Dalam Sistem',
|
||||||
|
'Luar Sistem', 'Lap Pimpinan', 'Chat', 'Google Sheets', 'TPA TPT', 'Approval Pejabat',
|
||||||
|
'Undangan', 'Rekap Pembayaran', 'Lap Rekap Data Pembayaran', 'Lap PBG (PTSP)'
|
||||||
],
|
],
|
||||||
[
|
'admin' => ['Dashboard', 'Master', 'Settings'],
|
||||||
"name" => "admin",
|
'operator' => ['Dashboard', 'Data', 'Laporan']
|
||||||
"description" => "show only necessary menus for admins",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "operator",
|
|
||||||
"description" => "show only necessary menus for operators",
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
|
|
||||||
Role::upsert($roles, ['name']);
|
// Define permission levels
|
||||||
|
$superadminPermissions = ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true];
|
||||||
|
$adminPermissions = ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true];
|
||||||
|
$operatorPermissions = ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false];
|
||||||
|
|
||||||
$parent_menus = [
|
// Assign menus to roles
|
||||||
[
|
foreach ($permissions as $roleName => $menuNames) {
|
||||||
"name" => "Dashboard",
|
$role = $roles[$roleName] ?? null;
|
||||||
"url" => "/dashboard",
|
if ($role) {
|
||||||
"icon" => "mingcute:home-3-line",
|
$role->menus()->sync(
|
||||||
"parent_id" => null,
|
collect($menuNames)->mapWithKeys(fn($menuName) => [
|
||||||
"sort_order" => 1,
|
$menus[$menuName]->id => ($roleName === 'superadmin' ? $superadminPermissions :
|
||||||
],
|
($roleName === 'admin' ? $adminPermissions : $operatorPermissions))
|
||||||
[
|
])->toArray()
|
||||||
"name" => "Master",
|
);
|
||||||
"url" => "/master",
|
}
|
||||||
"icon" => "mingcute:cylinder-line",
|
|
||||||
"parent_id" => null,
|
|
||||||
"sort_order" => 2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Settings",
|
|
||||||
"url" => "/settings",
|
|
||||||
"icon" => "mingcute:settings-6-line",
|
|
||||||
"parent_id" => null,
|
|
||||||
"sort_order" => 3,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Data Settings",
|
|
||||||
"url" => "/data-settings",
|
|
||||||
"icon" => "mingcute:settings-1-line",
|
|
||||||
"parent_id" => null,
|
|
||||||
"sort_order" => 4,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Data",
|
|
||||||
"url" => "/data",
|
|
||||||
"icon" => "mingcute:task-line",
|
|
||||||
"parent_id" => null,
|
|
||||||
"sort_order" => 5,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Laporan",
|
|
||||||
"url" => "/laporan",
|
|
||||||
"icon" => "mingcute:task-line",
|
|
||||||
"parent_id" => null,
|
|
||||||
"sort_order" => 6,
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($parent_menus as $parent_menu) {
|
|
||||||
Menu::firstOrCreate(['name' => $parent_menu['name']], $parent_menu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach Menus to Roles
|
|
||||||
$superadmin = Role::where('name', 'superadmin')->first();
|
|
||||||
$admin = Role::where('name', 'admin')->first();
|
|
||||||
$operator = Role::where('name', 'operator')->first();
|
|
||||||
|
|
||||||
$dashboard = Menu::where('name', 'Dashboard')->first();
|
|
||||||
$master = Menu::where('name', 'Master')->first();
|
|
||||||
$settings = Menu::where('name', 'Settings')->first();
|
|
||||||
$dataSettings = Menu::where('name', 'Data Settings')->first();
|
|
||||||
$data = Menu::where('name', 'Data')->first();
|
|
||||||
$laporan = Menu::where('name', 'Laporan')->first();
|
|
||||||
|
|
||||||
// create children menu
|
|
||||||
$children_menus = [
|
|
||||||
[
|
|
||||||
"name" => "Dashboard Pimpinan",
|
|
||||||
"url" => "dashboard.home",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $dashboard->id,
|
|
||||||
"sort_order" => 1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Dashboard PBG",
|
|
||||||
"url" => "dashboard.pbg",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $dashboard->id,
|
|
||||||
"sort_order" => 2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Dashboard Potensi",
|
|
||||||
"url" => "dashboard.lack_of_potential",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $dashboard->id,
|
|
||||||
"sort_order" => 3,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "PETA",
|
|
||||||
"url" => "dashboard.maps",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $dashboard->id,
|
|
||||||
"sort_order" => 4,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Users",
|
|
||||||
"url" => "users.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $master->id,
|
|
||||||
"sort_order" => 1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Syncronize",
|
|
||||||
"url" => "settings.syncronize",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $settings->id,
|
|
||||||
"sort_order" => 1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Menu",
|
|
||||||
"url" => "menus.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $settings->id,
|
|
||||||
"sort_order" => 2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Role",
|
|
||||||
"url" => "roles.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $settings->id,
|
|
||||||
"sort_order" => 3,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Setting Dashboard",
|
|
||||||
"url" => "data-settings.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $dataSettings->id,
|
|
||||||
"sort_order" => 1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "PBG",
|
|
||||||
"url" => "pbg-task.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $data->id,
|
|
||||||
"sort_order" => 1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Reklame",
|
|
||||||
"url" => "advertisements.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $data->id,
|
|
||||||
"sort_order" => 2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Usaha atau Industri",
|
|
||||||
"url" => "business-industries.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $data->id,
|
|
||||||
"sort_order" => 3,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "UMKM",
|
|
||||||
"url" => "umkm.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $data->id,
|
|
||||||
"sort_order" => 4,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Pariwisata",
|
|
||||||
"url" => "tourisms.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $data->id,
|
|
||||||
"sort_order" => 5,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Tata Ruang",
|
|
||||||
"url" => "spatial-plannings.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $data->id,
|
|
||||||
"sort_order" => 6,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "PDAM",
|
|
||||||
"url" => "customers",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $data->id,
|
|
||||||
"sort_order" => 7,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"name" => "Lap Pariwisata",
|
|
||||||
"url" => "tourisms.index",
|
|
||||||
"icon" => null,
|
|
||||||
"parent_id" => $laporan->id,
|
|
||||||
"sort_order" => 1,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($children_menus as $child_menu) {
|
|
||||||
Menu::firstOrCreate(['name' => $child_menu['name']], $child_menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
$dashboard_pimpinan = Menu::where('name', 'Dashboard Pimpinan')->first();
|
|
||||||
$dashboard_pbg = Menu::where('name', 'Dashboard PBG')->first();
|
|
||||||
$users = Menu::where('name', 'Users')->first();
|
|
||||||
$syncronize = Menu::where('name', 'Syncronize')->first();
|
|
||||||
$setting_menu = Menu::where('name', 'Menu')->first();
|
|
||||||
$setting_role = Menu::where('name', 'Role')->first();
|
|
||||||
$setting_dashboard = Menu::where('name', 'Setting Dashboard')->first();
|
|
||||||
$setting_pbg = Menu::where('name', 'PBG')->first();
|
|
||||||
$reklame = Menu::where('name', 'Reklame')->first();
|
|
||||||
$businessIndustries = Menu::where('name', 'Usaha atau Industri')->first();
|
|
||||||
$pariwisata = Menu::where('name', 'Pariwisata')->first();
|
|
||||||
$laporan_pariwisata = Menu::where('name', 'Lap Pariwisata')->first();
|
|
||||||
$umkm = Menu::where('name', 'UMKM')->first();
|
|
||||||
$lack_of_potentials = Menu::where('name', 'Dashboard Potensi')->first();
|
|
||||||
$spatial_plannings = Menu::where('name', 'Tata Ruang')->first();
|
|
||||||
$pdam = Menu::where('name', 'PDAM')->first();
|
|
||||||
$peta = Menu::where('name', 'PETA')->first();
|
|
||||||
|
|
||||||
// Superadmin gets all menus
|
|
||||||
$superadmin->menus()->sync([
|
|
||||||
// parent
|
|
||||||
$dashboard->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
|
||||||
$master->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
|
||||||
$settings->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
|
||||||
$dataSettings->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
|
||||||
$data->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
|
||||||
$laporan->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
|
||||||
// children
|
|
||||||
$dashboard_pimpinan->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$dashboard_pbg->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$users->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$syncronize->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$setting_menu->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$setting_role->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$setting_dashboard->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$setting_pbg->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$reklame->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$businessIndustries->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$pariwisata->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$laporan_pariwisata->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$umkm->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$lack_of_potentials->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$spatial_plannings->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$pdam->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$peta->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Admin gets limited menus
|
|
||||||
$admin->menus()->sync([
|
|
||||||
$dashboard->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$master->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$settings->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Operator gets only basic menus with full permissions
|
|
||||||
$operator->menus()->sync([
|
|
||||||
$dashboard->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
$data->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
|
||||||
]);
|
|
||||||
// Attach User to role super admin
|
// Attach User to role super admin
|
||||||
User::findOrFail(1)->roles()->sync([$superadmin->id]);
|
User::findOrFail(1)->roles()->sync([$roles['superadmin']->id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
database/view_query/v_advertisements.sql
Normal file
21
database/view_query/v_advertisements.sql
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
CREATE VIEW v_advertisements AS
|
||||||
|
SELECT
|
||||||
|
a.no,
|
||||||
|
a.business_name,
|
||||||
|
a.npwpd,
|
||||||
|
a.advertisement_type,
|
||||||
|
a.advertisement_content,
|
||||||
|
a.business_address,
|
||||||
|
a.advertisement_location,
|
||||||
|
v.village_name AS village_name,
|
||||||
|
d.district_name AS district_name,
|
||||||
|
a.length,
|
||||||
|
a.width,
|
||||||
|
a.viewing_angle,
|
||||||
|
a.face,
|
||||||
|
a.area,
|
||||||
|
a.angle,
|
||||||
|
a.contact
|
||||||
|
FROM advertisements a
|
||||||
|
JOIN villages v ON a.village_code = v.village_code
|
||||||
|
JOIN districts d ON a.district_code = d.district_code;
|
||||||
8
database/view_query/v_tourism_base_kbli.sql
Normal file
8
database/view_query/v_tourism_base_kbli.sql
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
CREATE VIEW v_tourisms_based_kbli AS
|
||||||
|
SELECT kbli_title, total_records
|
||||||
|
FROM (
|
||||||
|
SELECT kbli, kbli_title, COUNT(*) AS total_records
|
||||||
|
FROM tourisms
|
||||||
|
GROUP BY kbli, kbli_title
|
||||||
|
) AS subquery
|
||||||
|
ORDER BY total_records DESC;
|
||||||
29
database/view_query/v_tourisms.sql
Normal file
29
database/view_query/v_tourisms.sql
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
CREATE VIEW v_tourisms AS
|
||||||
|
SELECT
|
||||||
|
t.project_id,
|
||||||
|
t.project_type_id,
|
||||||
|
t.nib,
|
||||||
|
t.business_name,
|
||||||
|
t.oss_publication_date,
|
||||||
|
t.investment_status_description,
|
||||||
|
t.business_form,
|
||||||
|
t.project_risk,
|
||||||
|
t.project_name,
|
||||||
|
t.business_scale,
|
||||||
|
t.business_address,
|
||||||
|
v.village_name as village_name,
|
||||||
|
d.district_name as district_name,
|
||||||
|
t.longitude,
|
||||||
|
t.latitude,
|
||||||
|
t.project_submission_date,
|
||||||
|
t.kbli_title,
|
||||||
|
t.supervisory_sector,
|
||||||
|
t.user_name,
|
||||||
|
t.email,
|
||||||
|
t.contact,
|
||||||
|
t.land_area_in_m2,
|
||||||
|
t.investment_amount,
|
||||||
|
t.tki
|
||||||
|
FROM tourisms t
|
||||||
|
JOIN villages v on t.village_code = v.village_code
|
||||||
|
JOIN districts d on t.district_code = d.district_code;
|
||||||
28
database/view_query/v_umkms.sql
Normal file
28
database/view_query/v_umkms.sql
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
CREATE VIEW v_umkms AS
|
||||||
|
SELECT
|
||||||
|
u.business_address,
|
||||||
|
u.business_contact,
|
||||||
|
u.business_desc,
|
||||||
|
bf.business_form,
|
||||||
|
u.business_id_number,
|
||||||
|
u.business_name,
|
||||||
|
bs.business_scale,
|
||||||
|
u.business_type,
|
||||||
|
u.created_at,
|
||||||
|
d.district_name,
|
||||||
|
u.land_area,
|
||||||
|
u.number_of_employee,
|
||||||
|
u.owner_address,
|
||||||
|
u.owner_contact,
|
||||||
|
u.owner_id,
|
||||||
|
u.owner_name,
|
||||||
|
ps.permit_status,
|
||||||
|
u.revenue,
|
||||||
|
u.updated_at,
|
||||||
|
v.village_name
|
||||||
|
FROM umkms u
|
||||||
|
JOIN business_form bf on u.business_form_id = bf.id
|
||||||
|
JOIN permit_status ps on u.permit_status_id = ps.id
|
||||||
|
JOIn business_scale bs on u.business_scale_id = bs.id
|
||||||
|
JOIN villages v on u.village_code = v.village_code
|
||||||
|
JOIN districts d on u.district_code = v.district_code;
|
||||||
39
deploy.sh
Executable file
39
deploy.sh
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
GIT_BRANCH="dev"
|
||||||
|
PHP_VERSION="php8.3"
|
||||||
|
|
||||||
|
echo "🚀 Starting deployment..."
|
||||||
|
php artisan down
|
||||||
|
|
||||||
|
echo "📥 Pulling latest changes from Git..."
|
||||||
|
git fetch origin $GIT_BRANCH
|
||||||
|
git reset --hard origin/$GIT_BRANCH
|
||||||
|
git pull origin $GIT_BRANCH
|
||||||
|
|
||||||
|
echo "⚡ Installing NPM dependencies and building assets..."
|
||||||
|
npm ci --no-audit --no-fund
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
echo "📦 Installing composer dependencies..."
|
||||||
|
COMPOSER_ALLOW_SUPERUSER=1 composer install --no-interaction --optimize-autoloader
|
||||||
|
|
||||||
|
echo "🗄️ Running migrations..."
|
||||||
|
php artisan migrate --force
|
||||||
|
|
||||||
|
echo "Running seeders..."
|
||||||
|
php artisan db:seed --force
|
||||||
|
|
||||||
|
echo "⚡ Optimizing application..."
|
||||||
|
php artisan optimize:clear
|
||||||
|
|
||||||
|
echo "🔄 Restarting PHP service..."
|
||||||
|
systemctl reload $PHP_VERSION-fpm
|
||||||
|
|
||||||
|
echo "🔁 Restarting Supervisor queue workers..."
|
||||||
|
php artisan queue:restart
|
||||||
|
|
||||||
|
supervisorctl reread
|
||||||
|
supervisorctl update
|
||||||
|
supervisorctl restart all
|
||||||
|
|
||||||
|
php artisan up
|
||||||
|
echo "🚀 Deployment completed successfully!"
|
||||||
9
package-lock.json
generated
9
package-lock.json
generated
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "sibedas-pbg",
|
"name": "sibedas-pbg-web",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
"gridjs": "^5.1.0",
|
"gridjs": "^5.1.0",
|
||||||
"iconify-icon": "^2.1.0",
|
"iconify-icon": "^2.1.0",
|
||||||
"jsvectormap": "^1.5.1",
|
"jsvectormap": "^1.5.1",
|
||||||
|
"leaflet": "^1.9.4",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"node-waves": "^0.7.6",
|
"node-waves": "^0.7.6",
|
||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
@@ -1467,6 +1468,12 @@
|
|||||||
"vite": "^5.0.0 || ^6.0.0"
|
"vite": "^5.0.0 || ^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/leaflet": {
|
||||||
|
"version": "1.9.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||||
|
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
|
||||||
|
"license": "BSD-2-Clause"
|
||||||
|
},
|
||||||
"node_modules/lilconfig": {
|
"node_modules/lilconfig": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user