Compare commits
73 Commits
feature/da
...
feat/view-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
fefef609ac | ||
|
|
f5790cda94 | ||
|
|
f3db3783f9 | ||
|
|
101e76c0fa | ||
|
|
4cc698a623 | ||
|
|
544ad1db46 | ||
|
|
30ca819aa1 | ||
|
|
b0bab784d1 | ||
|
|
01fda22c89 | ||
|
|
de300c2c32 | ||
|
|
7f8a2e4936 | ||
|
|
aa9943ba45 | ||
|
|
9e55ea0dbb | ||
|
|
93f0ac5ef7 | ||
|
|
bb4ab5c769 | ||
|
|
e743b82087 | ||
|
|
c3c7b8e3ec | ||
|
|
d49035ce8d | ||
|
|
ffd9d3514c | ||
|
|
675477c734 | ||
|
|
4350c466e3 | ||
|
|
5ab407d672 | ||
|
|
2aaa487746 | ||
|
|
080582f7ab | ||
|
|
91475aeead | ||
|
|
5d50d6d6cc | ||
|
|
39717d184c |
@@ -67,4 +67,5 @@ AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
VITE_APP_NAME="${APP_NAME}"
|
||||
|
||||
API_KEY_GOOGLE="xxxxx"
|
||||
SPREAD_SHEET_ID="xxxxx"
|
||||
SPREAD_SHEET_ID="xxxxx"
|
||||
OPENAI_API_KEY="xxxxx"
|
||||
130
README.md
130
README.md
@@ -1,66 +1,106 @@
|
||||
<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">
|
||||
<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>
|
||||
search or pick icon in <a href="https://icon-sets.iconify.design/mingcute/?keyword=mingcute">here</a>
|
||||
|
||||
## 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).
|
||||
- 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).
|
||||
```
|
||||
sudo apt update && sudo apt install supervisor -y
|
||||
```
|
||||
|
||||
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 --sleep=3
|
||||
autostart=true
|
||||
autorestart=true
|
||||
numprocs=4
|
||||
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/)**
|
||||
- **[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)**
|
||||
- Install npm package
|
||||
|
||||
## 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.
|
||||
- Create view table
|
||||
- excute all sql queries on folder database/view_query
|
||||
|
||||
## License
|
||||
# Add ENV variable
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
- 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;
|
||||
|
||||
use App\Jobs\SyncronizeSIMBG;
|
||||
use App\Services\ServiceSIMBG;
|
||||
use Illuminate\Console\Command;
|
||||
use \Illuminate\Support\Facades\Log;
|
||||
@@ -28,13 +29,12 @@ class ExecuteScraping extends Command
|
||||
|
||||
private $service_simbg;
|
||||
|
||||
public function __construct(ServiceSIMBG $service_simbg){
|
||||
$this->service_simbg = $service_simbg;
|
||||
public function __construct(){
|
||||
parent::__construct();
|
||||
}
|
||||
public function handle()
|
||||
{
|
||||
SyncronizeSIMBG::dispatch()->onQueue('default');
|
||||
Log::info("running scheduler daily scraping");
|
||||
$this->service_simbg->syncTaskList();
|
||||
}
|
||||
}
|
||||
|
||||
281
app/Http/Controllers/Api/BigDataResumeController.php
Normal file
281
app/Http/Controllers/Api/BigDataResumeController.php
Normal file
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Resources\BigdataResumeResource;
|
||||
use App\Models\BigdataResume;
|
||||
use App\Models\DataSetting;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class BigDataResumeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
try{
|
||||
$filterDate = $request->get("filterByDate");
|
||||
|
||||
if (!$filterDate || $filterDate === "latest") {
|
||||
$big_data_resume = BigdataResume::where('year', now()->year)->latest()->first();
|
||||
if (!$big_data_resume) {
|
||||
return $this->response_empty_resume();
|
||||
}
|
||||
} else {
|
||||
$big_data_resume = BigdataResume::whereDate('created_at', $filterDate)
|
||||
->orderBy('id', 'desc')
|
||||
->first();
|
||||
|
||||
if (!$big_data_resume) {
|
||||
return $this->response_empty_resume();
|
||||
}
|
||||
}
|
||||
|
||||
$data_settings = DataSetting::all();
|
||||
if($data_settings->isEmpty()){
|
||||
return response()->json(['message' => 'No data setting found']);
|
||||
}
|
||||
|
||||
function cleanNumber($value) {
|
||||
return floatval(str_replace('.', '', $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;
|
||||
|
||||
// percentage kekurangan potensi
|
||||
$kekurangan_potensi_percentage = $target_pad > 0 && $target_pad > 0
|
||||
? round(($kekurangan_potensi / $target_pad) * 100, 2) : 0;
|
||||
|
||||
// percentage total potensi
|
||||
$total_potensi_percentage = $big_data_resume->potention_sum > 0 && $target_pad > 0
|
||||
? round(($big_data_resume->potention_sum / $target_pad) * 100, 2) : 0;
|
||||
|
||||
// percentage verified document
|
||||
$verified_percentage = $big_data_resume->verified_sum > 0 && $big_data_resume->potention_sum > 0
|
||||
? round(($big_data_resume->verified_sum / $big_data_resume->potention_sum) * 100, 2) : 0;
|
||||
|
||||
// percentage non-verified document
|
||||
$non_verified_percentage = $big_data_resume->non_verified_sum > 0 && $big_data_resume->potention_sum > 0
|
||||
? round(($big_data_resume->non_verified_sum / $big_data_resume->potention_sum) * 100, 2) : 0;
|
||||
|
||||
// percentage business document
|
||||
$business_percentage = $big_data_resume->business_sum > 0 && $big_data_resume->non_verified_sum > 0
|
||||
? round(($big_data_resume->business_sum / $big_data_resume->non_verified_sum) * 100, 2) : 0;
|
||||
|
||||
// percentage non-business document
|
||||
$non_business_percentage = $big_data_resume->non_business_sum > 0 && $big_data_resume->potention_sum > 0
|
||||
? round(($big_data_resume->non_business_sum / $big_data_resume->potention_sum) * 100, 2) : 0;
|
||||
|
||||
// percentage tata ruang
|
||||
$tata_ruang_percentage = $tata_ruang > 0 && $big_data_resume->potention_sum > 0
|
||||
? round(($tata_ruang / $big_data_resume->potention_sum) * 100, 2) : 0;
|
||||
|
||||
// percentage realisasi terbit pbg
|
||||
$realisasi_terbit_percentage = $big_data_resume->verified_sum > 0 && $realisasi_terbit_pbg_sum > 0
|
||||
? round(($realisasi_terbit_pbg_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
||||
|
||||
// percentage menunggu klik dpmptsp
|
||||
$menunggu_klik_dpmptsp_percentage = $big_data_resume->verified_sum > 0 && $menunggu_klik_dpmptsp_sum > 0
|
||||
? round(($menunggu_klik_dpmptsp_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
||||
|
||||
// percentage proses_dinas_teknis
|
||||
$proses_dinas_teknis_percentage = $big_data_resume->verified_sum > 0 && $proses_dinas_teknis_sum > 0
|
||||
? round(($proses_dinas_teknis_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
||||
|
||||
$result = [
|
||||
'target_pad' => [
|
||||
'sum' => $target_pad,
|
||||
'percentage' => 100,
|
||||
],
|
||||
'tata_ruang' => [
|
||||
'sum' => $big_data_resume->spatial_sum,
|
||||
'count' => $big_data_resume->spatial_count,
|
||||
'percentage' => $tata_ruang_percentage,
|
||||
],
|
||||
'kekurangan_potensi' => [
|
||||
'sum' => $kekurangan_potensi,
|
||||
'percentage' => $kekurangan_potensi_percentage
|
||||
],
|
||||
'total_potensi' => [
|
||||
'sum' => (float) $big_data_resume->potention_sum,
|
||||
'count' => $big_data_resume->potention_count,
|
||||
'percentage' => $total_potensi_percentage
|
||||
],
|
||||
'verified_document' => [
|
||||
'sum' => (float) $big_data_resume->verified_sum,
|
||||
'count' => $big_data_resume->verified_count,
|
||||
'percentage' => $verified_percentage
|
||||
],
|
||||
'non_verified_document' => [
|
||||
'sum' => (float) $big_data_resume->non_verified_sum,
|
||||
'count' => $big_data_resume->non_verified_count,
|
||||
'percentage' => $non_verified_percentage
|
||||
],
|
||||
'business_document' => [
|
||||
'sum' => (float) $big_data_resume->business_sum,
|
||||
'count' => $big_data_resume->business_count,
|
||||
'percentage' => $business_percentage
|
||||
],
|
||||
'non_business_document' => [
|
||||
'sum' => (float) $big_data_resume->non_business_sum,
|
||||
'count' => $big_data_resume->non_business_count,
|
||||
'percentage' => $non_business_percentage
|
||||
],
|
||||
'realisasi_terbit' => [
|
||||
'sum' => $realisasi_terbit_pbg_sum,
|
||||
'count' => $realisasi_terbit_pbg_count,
|
||||
'percentage' => $realisasi_terbit_percentage
|
||||
],
|
||||
'menunggu_klik_dpmptsp' => [
|
||||
'sum' => $menunggu_klik_dpmptsp_sum,
|
||||
'count' => $menunggu_klik_dpmptsp_count,
|
||||
'percentage' => $menunggu_klik_dpmptsp_percentage
|
||||
],
|
||||
'proses_dinas_teknis' => [
|
||||
'sum' => $proses_dinas_teknis_sum,
|
||||
'count' => $proses_dinas_teknis_count,
|
||||
'percentage' => $proses_dinas_teknis_percentage
|
||||
]
|
||||
];
|
||||
return response()->json($result);
|
||||
}catch(\Exception $e){
|
||||
return response()->json(['message' => 'Error when fetching data'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function bigdata_report(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));
|
||||
return BigdataResumeResource::collection($query)->response()->getData(true);
|
||||
}catch(\Exception $e){
|
||||
Log::error($e->getMessage());
|
||||
return response()->json(['message' => 'Error when fetching data'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function payment_recaps(Request $request)
|
||||
{
|
||||
try {
|
||||
$query = BigdataResume::query()->orderBy('id', 'desc');
|
||||
|
||||
if ($request->filled('date')) {
|
||||
$query->where('year', 'LIKE', '%' . $request->input('search') . '%');
|
||||
}
|
||||
|
||||
$data = $query->paginate(10);
|
||||
|
||||
// Restructure response
|
||||
$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' => $data->total(),
|
||||
'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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function response_empty_resume(){
|
||||
$result = [
|
||||
'target_pad' => [
|
||||
'sum' => 0,
|
||||
'percentage' => 100,
|
||||
],
|
||||
'tata_ruang' => [
|
||||
'sum' => 0,
|
||||
'percentage' => 0,
|
||||
],
|
||||
'kekurangan_potensi' => [
|
||||
'sum' => 0,
|
||||
'percentage' => 0
|
||||
],
|
||||
'total_potensi' => [
|
||||
'sum' => 0,
|
||||
'count' => 0,
|
||||
'percentage' => 0
|
||||
],
|
||||
'verified_document' => [
|
||||
'sum' => 0,
|
||||
'count' => 0,
|
||||
'percentage' => 0
|
||||
],
|
||||
'non_verified_document' => [
|
||||
'sum' => 0,
|
||||
'count' => 0,
|
||||
'percentage' => 0
|
||||
],
|
||||
'business_document' => [
|
||||
'sum' => 0,
|
||||
'count' => 0,
|
||||
'percentage' => 0
|
||||
],
|
||||
'non_business_document' => [
|
||||
'sum' => 0,
|
||||
'count' => 0,
|
||||
'percentage' => 0
|
||||
],
|
||||
'realisasi_terbit' => [
|
||||
'sum' => 0,
|
||||
'count' => 0,
|
||||
'percentage' => 0
|
||||
],
|
||||
'menunggu_klik_dpmptsp' => [
|
||||
'sum' => 0,
|
||||
'count' => 0,
|
||||
'percentage' => 0
|
||||
],
|
||||
'proses_dinas_teknis' => [
|
||||
'sum' => 0,
|
||||
'count' => 0,
|
||||
'percentage' => 0
|
||||
]
|
||||
];
|
||||
|
||||
return response()->json($result);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ use App\Models\BusinessOrIndustry;
|
||||
use Illuminate\Http\Request;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use \Illuminate\Support\Facades\Validator;
|
||||
use App\Http\Requests\ExcelUploadRequest;
|
||||
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){
|
||||
|
||||
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([
|
||||
'message' => 'File validation failed.',
|
||||
'errors' => $validator->errors()
|
||||
], 400);
|
||||
}
|
||||
|
||||
public function upload(ExcelUploadRequest $request){
|
||||
try {
|
||||
// Ambil file dari request
|
||||
$file = $request->file('file');
|
||||
if(!$request->hasFile('file')){
|
||||
return response()->json([
|
||||
'error' => 'No file provided'
|
||||
], 400);
|
||||
}
|
||||
|
||||
// Menggunakan Laravel Excel untuk mengimpor file
|
||||
$file = $request->file('file');
|
||||
Excel::import(new BusinessIndustriesImport, $file);
|
||||
|
||||
// Jika sukses, kembalikan respons sukses
|
||||
|
||||
119
app/Http/Controllers/Api/ChatbotController.php
Normal file
119
app/Http/Controllers/Api/ChatbotController.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Services\OpenAIService;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ChatbotController extends Controller
|
||||
{
|
||||
protected $openAIService;
|
||||
|
||||
public function __construct(OpenAIService $openAIService)
|
||||
{
|
||||
$this->openAIService = $openAIService;
|
||||
}
|
||||
|
||||
public function generateText(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'tab_active' => 'required|string',
|
||||
'prompt' => 'required|string',
|
||||
]);
|
||||
|
||||
$tab_active = $request->input('tab_active');
|
||||
$main_content = match ($tab_active) {
|
||||
"count-retribusi" => "RETRIBUTION",
|
||||
"document-validation" => "DOCUMENT VALIDATION",
|
||||
"data-information" => "DATA SUMMARY",
|
||||
default => "UNKNOWN",
|
||||
};
|
||||
|
||||
$chatHistory = $request->input('chatHistory');
|
||||
// Log::info('Chat history sebelum disimpan:', ['history' => $chatHistory]);
|
||||
|
||||
if ($main_content === "UNKNOWN") {
|
||||
return response()->json(['response' => 'Invalid tab_active value.'], 400);
|
||||
}
|
||||
|
||||
// info($main_content);
|
||||
|
||||
$queryResponse = $this->openAIService->generateQueryBasedMainContent($request->input('prompt'), $main_content, $chatHistory);
|
||||
|
||||
$firstValidation = $this->openAIService->validateSyntaxQuery($queryResponse);
|
||||
$secondValidation = $this->openAIService->validateSyntaxQuery($queryResponse);
|
||||
|
||||
$formattedResultQuery = "[]";
|
||||
$queryResponse = str_replace(['```sql', '```'], '', $queryResponse);
|
||||
$resultQuery = DB::select($queryResponse);
|
||||
$formattedResultQuery = json_encode($resultQuery, JSON_PRETTY_PRINT);
|
||||
// info($formattedResultQuery);
|
||||
|
||||
$nlpResult = $this->openAIService->generateNLPFromQuery($request->input('prompt'), $formattedResultQuery);
|
||||
$finalGeneratedText =$this->openAIService->generateFinalText($nlpResult);
|
||||
return response()->json(['response' => $finalGeneratedText, 'nlpResponse' => $queryResponse]);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$chatHistory = $request->input('chatHistory');
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,9 +22,9 @@ class CustomersController extends Controller
|
||||
if ($request->has('search') &&!empty($request->get('search'))) {
|
||||
$query = $query->where('nomor_pelanggan', '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 {
|
||||
$data = GlobalSetting::create($request->validated());
|
||||
return new GlobalSettingResource($data);
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
return $this->resError($e->getMessage(), null, $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,33 +3,15 @@
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\GoogleSheetService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class GoogleSheetController extends Controller
|
||||
{
|
||||
protected $googleSheetService;
|
||||
public function __construct(GoogleSheetService $googleSheetService){
|
||||
$this->googleSheetService = $googleSheetService;
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
$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)
|
||||
{
|
||||
//
|
||||
|
||||
@@ -24,7 +24,7 @@ class ImportDatasourceController extends Controller
|
||||
$search = $request->get("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(){
|
||||
|
||||
34
app/Http/Controllers/Api/LackOfPotentialController.php
Normal file
34
app/Http/Controllers/Api/LackOfPotentialController.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Advertisement;
|
||||
use App\Models\Customer;
|
||||
use App\Models\SpatialPlanning;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\TourismBasedKBLI;
|
||||
|
||||
class LackOfPotentialController extends Controller
|
||||
{
|
||||
|
||||
public function count_lack_of_potential(){
|
||||
try{
|
||||
$total_reklame = Advertisement::count();
|
||||
$total_pdam = Customer::count();
|
||||
$total_tata_ruang = SpatialPlanning::count();
|
||||
$data_report_tourism = TourismBasedKBLI::all();
|
||||
|
||||
return response()->json([
|
||||
'total_reklame' => $total_reklame,
|
||||
'total_pdam' => $total_pdam,
|
||||
'total_tata_ruang' => $total_tata_ruang,
|
||||
'data_report' => $data_report_tourism,
|
||||
], 200);
|
||||
}catch(\Exception $e){
|
||||
return response()->json([
|
||||
'message' => 'Error: '.$e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,11 @@
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\MenuRequest;
|
||||
use App\Http\Resources\MenuResource;
|
||||
use App\Models\Menu;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class MenusController extends Controller
|
||||
{
|
||||
@@ -13,21 +16,27 @@ class MenusController extends Controller
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = Menu::query();
|
||||
$query = Menu::query()->orderBy('id', 'desc');
|
||||
|
||||
if($request->has("search") && !empty($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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(MenuRequest $request)
|
||||
{
|
||||
//
|
||||
try{
|
||||
$menu = Menu::create($request->validated());
|
||||
return response()->json(['message' => 'Menu created successfully', 'data' => new MenuResource($menu)]);
|
||||
}catch(\Exception $e){
|
||||
Log::error($e);
|
||||
return response()->json(['message' => 'Error when creating menu'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,15 +44,37 @@ class MenusController extends Controller
|
||||
*/
|
||||
public function show(string $id)
|
||||
{
|
||||
//
|
||||
try{
|
||||
$menu = Menu::find($id);
|
||||
if($menu){
|
||||
return response()->json(['message' => 'Menu found', 'data' => new MenuResource($menu)]);
|
||||
} else {
|
||||
return response()->json(['message' => 'Menu not found'], 404);
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
Log::error($e);
|
||||
Log::error($e->getMessage());
|
||||
return response()->json(['message' => 'Error when finding menu'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
public function update(MenuRequest $request, string $id)
|
||||
{
|
||||
//
|
||||
try{
|
||||
$menu = Menu::findOrFail($id);
|
||||
if($menu){
|
||||
$menu->update($request->validated());
|
||||
return response()->json(['message' => 'Menu updated successfully', 'data' => new MenuResource($menu)]);
|
||||
} else {
|
||||
return response()->json(['message' => 'Menu not found'], 404);
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
Log::error($e);
|
||||
return response()->json(['message' => 'Error when updating menu'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,6 +82,28 @@ class MenusController extends Controller
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
{
|
||||
//
|
||||
try{
|
||||
$menu = Menu::findOrFail($id);
|
||||
if($menu){
|
||||
$this->deleteChildren($menu);
|
||||
$menu->roles()->detach();
|
||||
$menu->delete();
|
||||
return response()->json(['message' => 'Menu deleted successfully']);
|
||||
} else {
|
||||
return response()->json(['message' => 'Menu not found'], 404);
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
Log::error($e);
|
||||
return response()->json(['message' => 'Error when deleting menu'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
private function deleteChildren($menu)
|
||||
{
|
||||
foreach ($menu->children as $child) {
|
||||
$this->deleteChildren($child); // Recursively delete its children
|
||||
$child->roles()->detach(); // Detach roles before deleting
|
||||
$child->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,11 @@ namespace App\Http\Controllers\Api;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Resources\RequestAssignmentResouce;
|
||||
use App\Models\PbgTask;
|
||||
use App\Models\PbgTaskGoogleSheet;
|
||||
use DB;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
|
||||
class RequestAssignmentController extends Controller
|
||||
{
|
||||
@@ -17,11 +21,57 @@ class RequestAssignmentController extends Controller
|
||||
$query = PbgTask::query()->orderBy('id', 'desc');
|
||||
if($request->has('search') && !empty($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());
|
||||
}
|
||||
|
||||
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 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.
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\RoleRequest;
|
||||
use App\Models\Role;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -13,21 +14,26 @@ class RolesController extends Controller
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = Role::query();
|
||||
$query = Role::query()->orderBy('id', 'desc');
|
||||
|
||||
if($request->has('search') && !empty($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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(RoleRequest $request)
|
||||
{
|
||||
//
|
||||
try{
|
||||
$role = Role::create($request->validated());
|
||||
return response()->json(['message' => 'Successfully created', 'data' => $role]);
|
||||
}catch(\Exception $e){
|
||||
return response()->json(['message' => 'Error when creating role', 'error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,15 +41,34 @@ class RolesController extends Controller
|
||||
*/
|
||||
public function show(string $id)
|
||||
{
|
||||
//
|
||||
try{
|
||||
$role = Role::find($id);
|
||||
if($role){
|
||||
return response()->json(['data' => $role]);
|
||||
} else {
|
||||
return response()->json(['message' => 'Role not found'], 404);
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
return response()->json(['message' => 'Error when getting role', 'error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
public function update(RoleRequest $request, string $id)
|
||||
{
|
||||
//
|
||||
try{
|
||||
$role = Role::find($id);
|
||||
if($role){
|
||||
$role->update($request->validated());
|
||||
return response()->json(['message' => 'Successfully updated', 'data' => $role]);
|
||||
} else {
|
||||
return response()->json(['message' => 'Role not found'], 404);
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
return response()->json(['message' => 'Error when updating role', 'error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,6 +76,16 @@ class RolesController extends Controller
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
{
|
||||
//
|
||||
try{
|
||||
$role = Role::find($id);
|
||||
if($role){
|
||||
$role->delete();
|
||||
return response()->json(['message' => 'Successfully deleted']);
|
||||
} else {
|
||||
return response()->json(['message' => 'Role not found'], 404);
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
return response()->json(['message' => 'Error when deleting role', 'error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Enums\ImportDatasourceStatus;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Jobs\SyncronizeSIMBG;
|
||||
use App\Models\ImportDatasource;
|
||||
use App\Traits\GlobalApiResponse;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
@@ -23,8 +24,8 @@ class ScrapingController extends Controller
|
||||
}
|
||||
|
||||
// run service artisan command
|
||||
Artisan::call("app:execute-scraping");
|
||||
return $this->resSuccess("Success execute scraping service please wait");
|
||||
SyncronizeSIMBG::dispatch();
|
||||
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;
|
||||
|
||||
$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;
|
||||
});
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ use App\Traits\GlobalApiResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
@@ -29,9 +30,10 @@ class UsersController extends Controller
|
||||
public function index(Request $request){
|
||||
$query = User::query();
|
||||
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){
|
||||
$request->user()->tokens()->delete();
|
||||
|
||||
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
|
||||
$token = $user->createToken(env('APP_KEY'))->plainTextToken;
|
||||
|
||||
// Simpan token di session (bisa digunakan di JavaScript)
|
||||
session(['api_token' => $token]);
|
||||
|
||||
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,15 +4,36 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\BusinessOrIndustry;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class BusinessOrIndustriesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('business-industries.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('business-industries.index', compact('creator', 'updater', 'destroyer'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
17
app/Http/Controllers/Chatbot/ChatbotController.php
Normal file
17
app/Http/Controllers/Chatbot/ChatbotController.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Chatbot;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ChatbotController extends Controller
|
||||
{
|
||||
/**
|
||||
* Displya a listing of the resource
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('chatbot.index');
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
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,12 +4,34 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CustomersController extends Controller
|
||||
{
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('customers.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('customers.index', compact('creator', 'updater', 'destroyer'));
|
||||
}
|
||||
public function create()
|
||||
{
|
||||
|
||||
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,36 @@ use App\Http\Controllers\Controller;
|
||||
use App\Models\Advertisement;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AdvertisementController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('data.advertisements.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('data.advertisements.index', compact('creator', 'updater', 'destroyer'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +83,7 @@ class AdvertisementController extends Controller
|
||||
// Pastikan model ditemukan
|
||||
if (!$modelInstance) {
|
||||
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
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
@@ -5,15 +5,37 @@ namespace App\Http\Controllers\Data;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\SpatialPlanning;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class SpatialPlanningController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('data.spatialPlannings.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('data.spatialPlannings.index', compact('creator', 'updater', 'destroyer'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,15 +6,35 @@ use App\Http\Controllers\Controller;
|
||||
use App\Models\Tourism;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class TourismController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource
|
||||
*/
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('data.tourisms.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('data.tourisms.index', compact('creator', 'updater', 'destroyer'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +78,7 @@ class TourismController extends Controller
|
||||
$modelInstance = Tourism::find($id);
|
||||
// Pastikan model ditemukan
|
||||
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
|
||||
|
||||
@@ -6,15 +6,35 @@ use App\Http\Controllers\Controller;
|
||||
use App\Models\Umkm;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UmkmController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('data.umkm.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('data.umkm.index', compact('creator', 'updater', 'destroyer'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +80,7 @@ class UmkmController extends Controller
|
||||
$modelInstance = Umkm::find($id);
|
||||
// Pastikan model ditemukan
|
||||
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
|
||||
|
||||
@@ -8,15 +8,36 @@ use Exception;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Http\Request as IndexRequest;
|
||||
|
||||
class DataSettingController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
public function index(IndexRequest $request)
|
||||
{
|
||||
return view("data-settings.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("data-settings.index", compact('creator', 'updater', 'destroyer'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
12
app/Http/Controllers/GoogleApisController.php
Normal file
12
app/Http/Controllers/GoogleApisController.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class GoogleApisController extends Controller
|
||||
{
|
||||
public function index(){
|
||||
return view('maps.google-api');
|
||||
}
|
||||
}
|
||||
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\Traits\GlobalApiResponse;
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
@@ -21,9 +22,29 @@ class UsersController extends Controller
|
||||
$users = User::all();
|
||||
return $this->resSuccess($users);
|
||||
}
|
||||
public function index(){
|
||||
public function index(Request $request){
|
||||
$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;
|
||||
|
||||
$users = User::paginate();
|
||||
return view('master.users.index', compact('users'));
|
||||
return view('master.users.index', compact('users', 'creator', 'updater', 'destroyer'));
|
||||
}
|
||||
public function create(){
|
||||
$roles = Role::all();
|
||||
|
||||
@@ -6,15 +6,36 @@ use App\Http\Requests\MenuRequest;
|
||||
use App\Models\Menu;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class MenusController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('menus.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('menus.index', compact('creator', 'updater', 'destroyer'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
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)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
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\Models\PbgTask;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class PbgTaskController extends Controller
|
||||
{
|
||||
/**
|
||||
* 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,15 +10,36 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RolesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view("roles.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("roles.index", compact('creator', 'updater', 'destroyer'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,8 @@ use App\Http\Controllers\Controller;
|
||||
use App\Services\ServiceSIMBG;
|
||||
use Illuminate\Http\Request;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
class SyncronizeController extends Controller
|
||||
{
|
||||
protected $service_simbg;
|
||||
@@ -13,16 +15,36 @@ class SyncronizeController extends Controller
|
||||
$this->service_simbg = $service_simbg;
|
||||
}
|
||||
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(){
|
||||
$res = $this->service_simbg->syncTaskList();
|
||||
$res = $this->service_simbg->syncTaskPBG();
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function syncronizeTask(Request $request){
|
||||
$res = $this->service_simbg->syncTaskList();
|
||||
$res = $this->service_simbg->syncTaskPBG();
|
||||
return redirect()->back()->with('success', 'Processing completed successfully');
|
||||
}
|
||||
|
||||
@@ -33,7 +55,7 @@ class SyncronizeController extends Controller
|
||||
|
||||
public function syncIndexIntegration(Request $request, $uuid){
|
||||
$token = $request->get('token');
|
||||
$res = $this->service_simbg->syncIndexIntegration($uuid, $token);
|
||||
$res = $this->service_simbg->syncIndexIntegration($uuid);
|
||||
return $res;
|
||||
}
|
||||
|
||||
@@ -42,4 +64,9 @@ class SyncronizeController extends Controller
|
||||
$res = $this->service_simbg->syncTaskDetailSubmit($uuid, $token);
|
||||
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)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class DataSettingRequest extends FormRequest
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$id = $this->route('data_setting');
|
||||
$id = $this->route('data_setting_id');
|
||||
return [
|
||||
"key" => "required|unique:data_settings,key," . $id,
|
||||
"value" => "required",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class MenuRequest extends FormRequest
|
||||
{
|
||||
@@ -21,12 +22,14 @@ class MenuRequest extends FormRequest
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$menuId = $this->route('menu_id'); // Get the menu ID if updating
|
||||
|
||||
return [
|
||||
'name' => ['required','string','max:255'],
|
||||
'url' => ['nullable','string','max:255'],
|
||||
'icon' => ['nullable','string','max:255'],
|
||||
'parent_id' => ['nullable','exists:menus,id'],
|
||||
'sort_order' => ['required','integer'],
|
||||
'name' => ['required', 'string', 'max:255', Rule::unique('menus', 'name')->ignore($menuId)],
|
||||
'url' => ['nullable', 'string', 'max:255'],
|
||||
'icon' => ['nullable', 'string', 'max:255'],
|
||||
'parent_id' => ['nullable', 'exists:menus,id'],
|
||||
'sort_order' => ['required', 'integer'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class RoleRequest extends FormRequest
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$roleId = $this->route('role');
|
||||
$roleId = $this->route('role_id');
|
||||
return [
|
||||
'name' => 'required|string|max:255|unique:roles,name,' . ($roleId ?? 'NULL') . ',id',
|
||||
'description' => 'nullable|string',
|
||||
|
||||
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(),
|
||||
];
|
||||
}
|
||||
}
|
||||
19
app/Http/Resources/MenuResource.php
Normal file
19
app/Http/Resources/MenuResource.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class MenuResource 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/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;
|
||||
|
||||
use App\Models\BusinessOrIndustry;
|
||||
use Maatwebsite\Excel\Concerns\ToModel;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
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
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Model|null
|
||||
*/
|
||||
public function collection(Collection $rows)
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
foreach ($rows->skip(1) as $row){
|
||||
$clean_nop = preg_replace('/[^A-Za-z0-9]/', '', $row[2]);
|
||||
if (!BusinessOrIndustry::where('nop', $clean_nop)->exists()) {
|
||||
BusinessOrIndustry::create([
|
||||
'nama_kecamatan' => $row[0],
|
||||
'nama_kelurahan' => $row[1],
|
||||
'nop' => $clean_nop, // Store cleaned 'nop'
|
||||
'nama_wajib_pajak' => $row[3],
|
||||
'alamat_wajib_pajak' => $row[4],
|
||||
'alamat_objek_pajak' => $row[5],
|
||||
'luas_bumi' => $row[6],
|
||||
'luas_bangunan' => $row[7],
|
||||
'njop_bumi' => $row[8],
|
||||
'njop_bangunan' => $row[9],
|
||||
'ketetapan' => $row[10],
|
||||
'tahun_pajak' => $row[11],
|
||||
try{
|
||||
$batchData = [];
|
||||
$batchSize = 1000;
|
||||
|
||||
foreach ($collection as $row){
|
||||
if(!isset($row['nop']) || empty($row['nop'])){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$clean_nop = preg_replace('/[^A-Za-z0-9]/', '', $row['nop']);
|
||||
|
||||
$batchData[] = [
|
||||
'nama_kecamatan' => $row['nama_kecamatan'],
|
||||
'nama_kelurahan' => $row['nama_kelurahan'],
|
||||
'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,32 +11,61 @@ 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 CustomersImport implements ToCollection, WithMultipleSheets
|
||||
class CustomersImport implements ToCollection, WithMultipleSheets, WithChunkReading, WithBatchInserts, ShouldQueue, WithHeadingRow
|
||||
{
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchData = [];
|
||||
$batchSize = 1000;
|
||||
|
||||
foreach ($collection->skip(1) as $row) {
|
||||
if (!isset($row[0]) || empty($row[0])) {
|
||||
foreach ($collection as $row) {
|
||||
if (!isset($row['nomor_pelanggan']) || empty($row['nomor_pelanggan'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$latitude = filter_var($row[4], FILTER_VALIDATE_FLOAT) ? bcadd($row[4], '0', 18) : null;
|
||||
$longitude = filter_var($row[5], FILTER_VALIDATE_FLOAT) ? bcadd($row[5], '0', 18) : null;
|
||||
$latitude = '0';
|
||||
$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[] = [
|
||||
'nomor_pelanggan' => $row[0],
|
||||
'kota_pelayanan' => $row[1],
|
||||
'nama' => $row[2],
|
||||
'alamat' => $row[3],
|
||||
'nomor_pelanggan' => $row['nomor_pelanggan'] ?? '',
|
||||
'kota_pelayanan' => $row['kota_pelayanan'] ?? '',
|
||||
'nama' => $row['nama'] ?? '',
|
||||
'alamat' => $row['alamat'] ?? '',
|
||||
'latitude' => $latitude,
|
||||
'longitude' => $longitude,
|
||||
];
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
Customer::upsert($batchData, ['nomor_pelanggan'], ['kota_pelayanan', 'nama', 'alamat', 'latitude', 'longitude']);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
@@ -44,9 +73,20 @@ class CustomersImport implements ToCollection, WithMultipleSheets
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function sheets(): array {
|
||||
return [
|
||||
0 => $this
|
||||
];
|
||||
}
|
||||
|
||||
public function chunkSize(): int
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
public function batchSize(): int
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
|
||||
35
app/Jobs/SyncronizeSIMBG.php
Normal file
35
app/Jobs/SyncronizeSIMBG.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Services\GoogleSheetService;
|
||||
use App\Services\ServiceSIMBG;
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
try {
|
||||
$serviceSIMBG = app(ServiceSIMBG::class);
|
||||
$serviceSIMBG->syncTaskPBG();
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("SyncronizeSIMBG Job Failed: " . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
]);
|
||||
$this->fail($e); // Mark the job as failed
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,15 @@ class BigdataResume extends Model
|
||||
'business_sum',
|
||||
'non_business_count',
|
||||
'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()
|
||||
@@ -28,88 +37,84 @@ class BigdataResume extends Model
|
||||
return $this->belongsTo(ImportDatasource::class, 'import_datasource_id');
|
||||
}
|
||||
|
||||
public static function generateResumeData($import_datasource_id){
|
||||
$query_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')
|
||||
->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) = ?', [strtolower(trim('Selesai Verifikasi'))])
|
||||
->selectRaw('COUNT(pt.id) AS total_data,
|
||||
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution')
|
||||
->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
|
||||
public static function generateResumeData($import_datasource_id, $year, $data_setting){
|
||||
$stats = PbgTask::with(['googleSheet', 'pbg_task_retributions'])
|
||||
->leftJoin('pbg_task_retributions as ptr', 'pbg_task.uuid', '=', 'ptr.pbg_task_uid')
|
||||
->leftJoin('pbg_task_google_sheet as ptgs', 'pbg_task.registration_number', '=', 'ptgs.no_registrasi')
|
||||
->when($year !== 'all', function ($query) use ($year) {
|
||||
$query->whereYear('pbg_task.task_created_at', (int) $year);
|
||||
})
|
||||
->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;
|
||||
->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,
|
||||
|
||||
$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
|
||||
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();
|
||||
|
||||
// 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();
|
||||
});
|
||||
|
||||
$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_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([
|
||||
'import_datasource_id' => $import_datasource_id,
|
||||
'spatial_count' => $spatial_planning_count,
|
||||
'spatial_sum' => $spatial_planning_total ?? 0.00,
|
||||
'potention_count' => $potention_count ?? 0,
|
||||
'potention_sum' => $potention_total ?? 0.00,
|
||||
'non_verified_count' => $non_verified_count ?? 0,
|
||||
@@ -120,6 +125,13 @@ class BigdataResume extends Model
|
||||
'business_sum' => $business_total ?? 0.00,
|
||||
'non_business_count' => $non_business_count ?? 0,
|
||||
'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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,4 +37,13 @@ class PbgTask extends Model
|
||||
public function pbg_task_index_integrations(){
|
||||
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',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'allow_show' => 'boolean',
|
||||
'allow_create' => 'boolean',
|
||||
'allow_update' => 'boolean',
|
||||
'allow_destroy' => 'boolean',
|
||||
];
|
||||
|
||||
public $timestamps = true;
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
@@ -53,4 +53,11 @@ class User extends Authenticatable
|
||||
public function roles(){
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Carbon\Carbon;
|
||||
use App\Services\ServiceSIMBG;
|
||||
use App\Services\GoogleSheetService;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -17,7 +19,12 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
$this->app->singleton(GoogleSheetService::class, function () {
|
||||
return new GoogleSheetService();
|
||||
});
|
||||
$this->app->singleton(ServiceSIMBG::class, function ($app) {
|
||||
return new ServiceSIMBG($app->make(GoogleSheetService::class));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,21 +34,24 @@ class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
Blade::component('circle', Circle::class);
|
||||
|
||||
View::composer('layouts.partials.sidebar', function ($view){
|
||||
View::composer('layouts.partials.sidebar', function ($view) {
|
||||
$user = Auth::user();
|
||||
|
||||
if($user){
|
||||
$menus = Menu::whereHas('roles', function ($query) use ($user){
|
||||
$query->where('roles.id', $user->roles->pluck('id'));
|
||||
})
|
||||
->with(['children' => function ($query) {
|
||||
$query->whereHas('roles', function ($subQuery) {
|
||||
$subQuery->where('role_menu.allow_show', 1);
|
||||
});
|
||||
}])
|
||||
->orderBy('sort_order', 'asc')
|
||||
->get();
|
||||
}else{
|
||||
if ($user) {
|
||||
$menus = Menu::whereHas('roles', function ($query) use ($user) {
|
||||
$query->whereIn('roles.id', $user->roles->pluck('id'))
|
||||
->where('role_menu.allow_show', 1);
|
||||
})
|
||||
->with(['children' => function ($query) use ($user) {
|
||||
$query->whereHas('roles', function ($subQuery) use ($user) {
|
||||
$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')
|
||||
->get();
|
||||
} else {
|
||||
$menus = collect();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/dashboards/bigdata';
|
||||
public const HOME = '/home';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, and other route configuration.
|
||||
|
||||
@@ -13,6 +13,7 @@ class GoogleSheetService
|
||||
protected $client;
|
||||
protected $service;
|
||||
protected $spreadsheetID;
|
||||
protected $service_sheets;
|
||||
public function __construct()
|
||||
{
|
||||
$this->client = new Google_Client();
|
||||
|
||||
276
app/Services/OpenAIService.php
Normal file
276
app/Services/OpenAIService.php
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use OpenAI;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class OpenAIService
|
||||
{
|
||||
protected $client;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// $this->client = OpenAI::client(env('OPENAI_API_KEY'));
|
||||
$this->client = OpenAI::client(env('OPENAI_API_KEY'));
|
||||
}
|
||||
|
||||
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'];
|
||||
|
||||
// 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([
|
||||
'model' => 'gpt-4o-mini',
|
||||
'messages' => $messages,
|
||||
]);
|
||||
|
||||
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)
|
||||
{
|
||||
$response = $this->client->chat()->create([
|
||||
'model' => 'gpt-4o-mini',
|
||||
'messages' => [
|
||||
[
|
||||
'role' => 'system',
|
||||
'content' => "You are a MariaDB SQL expert. Your task is to validate the syntax of an SQL query to ensure it follows proper MariaDB syntax rules.
|
||||
|
||||
Guidelines:
|
||||
- Check for any syntax errors, missing keywords, or incorrect clause usage.
|
||||
- Ensure the query is well-structured and adheres to best practices.
|
||||
- Verify that all SQL keywords are used correctly and in the right order.
|
||||
- If the query is valid, respond with: \"VALID\".
|
||||
- If the query has issues, respond with: \"INVALID\".
|
||||
|
||||
Always respond with either \"VALID\" or \"INVALID\"."
|
||||
],
|
||||
['role' => 'user', 'content' => $queryResponse],
|
||||
],
|
||||
]);
|
||||
|
||||
return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
||||
}
|
||||
|
||||
public function generateNLPFromQuery($inputUser, $resultQuery) {
|
||||
$response = $this->client->chat()->create([
|
||||
'model' => 'gpt-4o-mini',
|
||||
'messages' => [
|
||||
[
|
||||
'role' => 'system',
|
||||
'content' => "You are an expert assistant. Your task is to analyze the database query results and transform them into a human-readable answer based on the user's question.
|
||||
|
||||
Guidelines:
|
||||
- Understand the user's question and extract the key intent.
|
||||
- Summarize or format the query results to directly answer the user's question.
|
||||
- Ensure the response is clear, concise, and relevant.
|
||||
- If the query result is empty or does not match the question, provide a polite response indicating that no data is available.
|
||||
|
||||
Always provide a well-structured response that makes sense based on the input question."
|
||||
],
|
||||
['role' => 'user', 'content' => "User's question: $inputUser \nDatabase result: $resultQuery"],
|
||||
],
|
||||
]);
|
||||
|
||||
return trim($response['choices'][0]['message']['content'] ?? 'No response');
|
||||
}
|
||||
|
||||
public function generateFinalText($nlpResult) {
|
||||
$response = $this->client->chat()->create([
|
||||
'model' => 'gpt-4o-mini',
|
||||
'messages' => [
|
||||
[
|
||||
'role' => 'system',
|
||||
'content' => "You are an expert text formatter. Your task is to take the given NLP result and format it into a structured, human-readable text suitable for rendering inside an HTML <div>.
|
||||
|
||||
Guidelines:
|
||||
- Preserve the meaning and clarity of the content.
|
||||
- Use proper line breaks for readability.
|
||||
- If the text contains lists, convert them into bullet points.
|
||||
- Emphasize important keywords using <strong> tags if necessary.
|
||||
- Ensure the response remains clean and concise without extra explanations."
|
||||
],
|
||||
['role' => 'user', 'content' => "Here is the NLP result that needs formatting:\n\n$nlpResult"],
|
||||
],
|
||||
]);
|
||||
|
||||
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,10 +51,26 @@ class ServiceClient
|
||||
|
||||
$resultResponse = json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR);
|
||||
return $this->resSuccess($resultResponse);
|
||||
} catch (Exception $e) {
|
||||
\Log::error('error from client service'. $e->getMessage());
|
||||
return $this->resError($e->getMessage());
|
||||
}
|
||||
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||
// Handle 4xx errors (e.g., 401 Unauthorized)
|
||||
$responseBody = (string) $e->getResponse()->getBody();
|
||||
$errorResponse = json_decode($responseBody, true);
|
||||
|
||||
if (isset($errorResponse['code']) && $errorResponse['code'] === 'token_not_valid') {
|
||||
return $this->resError('Invalid token, please refresh your token.', $errorResponse, 401);
|
||||
}
|
||||
|
||||
return $this->resError('Client error from API', $errorResponse, $e->getResponse()->getStatusCode());
|
||||
} catch (\GuzzleHttp\Exception\ServerException $e) {
|
||||
// Handle 5xx errors (e.g., Internal Server Error)
|
||||
return $this->resError('Server error from API', (string) $e->getResponse()->getBody(), 500);
|
||||
} catch (\GuzzleHttp\Exception\RequestException $e) {
|
||||
// Handle network errors (e.g., timeout, connection issues)
|
||||
return $this->resError('Network error: ' . $e->getMessage(), null, 503);
|
||||
} catch (Exception $e) {
|
||||
// Handle unexpected errors
|
||||
return $this->resError('Unexpected error: ' . $e->getMessage(), null, 500);
|
||||
}
|
||||
}
|
||||
|
||||
// Fungsi untuk melakukan permintaan GET
|
||||
|
||||
@@ -9,12 +9,16 @@ use App\Models\ImportDatasource;
|
||||
use App\Models\PbgTaskIndexIntegrations;
|
||||
use App\Models\PbgTaskPrasarana;
|
||||
use App\Models\PbgTaskRetributions;
|
||||
use App\Models\TaskAssignment;
|
||||
use Exception;
|
||||
use App\Models\PbgTask;
|
||||
use App\Traits\GlobalApiResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Carbon\Carbon;
|
||||
use App\Services\ServiceClient;
|
||||
use App\Services\GoogleSheetService;
|
||||
use App\Models\DataSetting;
|
||||
use App\Models\PbgTaskGoogleSheet;
|
||||
|
||||
class ServiceSIMBG
|
||||
{
|
||||
@@ -24,10 +28,11 @@ class ServiceSIMBG
|
||||
private $simbg_host;
|
||||
private $fetch_per_page;
|
||||
private $service_client;
|
||||
private $googleSheetService;
|
||||
/**
|
||||
* Create a new class instance.
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct(GoogleSheetService $googleSheetService)
|
||||
{
|
||||
$settings = GlobalSetting::whereIn('key', [
|
||||
'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->service_client = new ServiceClient($this->simbg_host);
|
||||
$this->googleSheetService = $googleSheetService;
|
||||
}
|
||||
|
||||
public function getToken(){
|
||||
@@ -61,32 +67,44 @@ class ServiceSIMBG
|
||||
}
|
||||
}
|
||||
|
||||
public function syncIndexIntegration($uuid, $token)
|
||||
public function syncIndexIntegration($uuids)
|
||||
{
|
||||
try{
|
||||
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/indeks-terintegrasi/";
|
||||
|
||||
$headers = [
|
||||
'Authorization' => "Bearer " . $token,
|
||||
];
|
||||
|
||||
$res = $this->service_client->get($url, $headers);
|
||||
|
||||
if (empty($res->original['success']) || !$res->original['success']) {
|
||||
// Log error
|
||||
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
|
||||
if(empty($uuids)){
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = $res->original['data']['data'] ?? null;
|
||||
if (!$data) {
|
||||
Log::error("No valid data returned from API", ['url' => $url, 'uuid' => $uuid]);
|
||||
|
||||
$initResToken = $this->getToken();
|
||||
if (empty($initResToken->original['data']['token']['access'])) {
|
||||
Log::error("API response indicates failure", ['token' => 'Failed to retrieve token']);
|
||||
return false;
|
||||
}
|
||||
$token = $initResToken->original['data']['token']['access'];
|
||||
|
||||
$integrations = [];
|
||||
foreach($uuids as $uuid){
|
||||
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/indeks-terintegrasi/";
|
||||
|
||||
$resultData = PbgTaskIndexIntegrations::updateOrCreate(
|
||||
['pbg_task_uid' => $uuid],
|
||||
[
|
||||
$headers = [
|
||||
'Authorization' => "Bearer " . $token,
|
||||
];
|
||||
|
||||
$res = $this->service_client->get($url, $headers);
|
||||
|
||||
if (empty($res->original['success']) || !$res->original['success']) {
|
||||
// Log error
|
||||
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$data = $res->original['data']['data'] ?? null;
|
||||
if (!$data) {
|
||||
Log::error("No valid data returned from API", ['url' => $url, 'uuid' => $uuid]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$integrations[] = [
|
||||
'pbg_task_uid' => $uuid,
|
||||
'indeks_fungsi_bangunan' => $data['indeks_fungsi_bangunan'] ?? null,
|
||||
'indeks_parameter_kompleksitas' => $data['indeks_parameter_kompleksitas'] ?? null,
|
||||
'indeks_parameter_permanensi' => $data['indeks_parameter_permanensi'] ?? null,
|
||||
@@ -94,8 +112,11 @@ class ServiceSIMBG
|
||||
'faktor_kepemilikan' => $data['faktor_kepemilikan'] ?? null,
|
||||
'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null,
|
||||
'total' => $data['total'] ?? null,
|
||||
]
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
PbgTaskIndexIntegrations::upsert($integrations, ['pbg_task_uid'], ['indeks_fungsi_bangunan',
|
||||
'indeks_parameter_kompleksitas', 'indeks_parameter_permanensi', 'indeks_parameter_ketinggian', 'faktor_kepemilikan', 'indeks_terintegrasi', 'total']);
|
||||
|
||||
return true;
|
||||
}catch (Exception $e){
|
||||
@@ -104,151 +125,366 @@ class ServiceSIMBG
|
||||
}
|
||||
}
|
||||
|
||||
public function syncTaskList()
|
||||
public function syncTaskPBG()
|
||||
{
|
||||
$initResToken = $this->getToken();
|
||||
|
||||
$importDatasource = ImportDatasource::create([
|
||||
'status' => ImportDatasourceStatus::Processing->value,
|
||||
]);
|
||||
|
||||
if (empty($initResToken->original['data']['token']['access'])) {
|
||||
$importDatasource->update([
|
||||
'status' => ImportDatasourceStatus::Failed->value,
|
||||
'message' => 'Failed to retrieve token'
|
||||
try {
|
||||
Log::info("Processing google sheet sync");
|
||||
$importDatasource = ImportDatasource::create([
|
||||
'status' => ImportDatasourceStatus::Processing->value,
|
||||
]);
|
||||
return $this->resError("Failed to retrieve token");
|
||||
}
|
||||
|
||||
$apiToken = $initResToken->original['data']['token']['access'];
|
||||
$headers = ['Authorization' => "Bearer " . $apiToken];
|
||||
|
||||
$url = "/api/pbg/v1/list/?page=1&size={$this->fetch_per_page}&sort=ASC";
|
||||
$initialResponse = $this->service_client->get($url, $headers);
|
||||
|
||||
$totalPage = $initialResponse->original['data']['total_page'] ?? 0;
|
||||
if ($totalPage == 0) {
|
||||
$importDatasource->update([
|
||||
'status' => ImportDatasourceStatus::Failed->value,
|
||||
'message' => 'Invalid response: no total_page'
|
||||
]);
|
||||
return $this->resError("Invalid response from API");
|
||||
}
|
||||
|
||||
$savedCount = $failedCount = 0;
|
||||
|
||||
for ($currentPage = 1; $currentPage <= $totalPage; $currentPage++) {
|
||||
$pageUrl = "/api/pbg/v1/list/?page={$currentPage}&size={$this->fetch_per_page}&sort=ASC";
|
||||
$getToken = $this->getToken();
|
||||
Log::info("response index integration", ['currentPage' => $currentPage]);
|
||||
if (empty($getToken->original['data']['token']['access'])) {
|
||||
$importDatasource->update([
|
||||
'status' => ImportDatasourceStatus::Failed->value,
|
||||
'message' => 'Failed to retrieve token'
|
||||
]);
|
||||
break;
|
||||
}
|
||||
$token = $getToken->original['data']['token']['access'];
|
||||
$headers = ['Authorization' => "Bearer " . $token];
|
||||
$response = $this->service_client->get($pageUrl, $headers);
|
||||
$tasks = $response->original['data']['data'] ?? [];
|
||||
|
||||
if (empty($tasks)) {
|
||||
$importDatasource->update([
|
||||
'status' => ImportDatasourceStatus::Failed->value,
|
||||
'message' => 'No data found on page'
|
||||
]);
|
||||
Log::warning("No data found on page", ['page' => $currentPage]);
|
||||
break;
|
||||
}
|
||||
|
||||
Log::info("executed page", ['page' => $currentPage, 'total' => $totalPage]);
|
||||
|
||||
$tasksCollective = [];
|
||||
foreach ($tasks as $item) {
|
||||
try {
|
||||
$tasksCollective[] = [
|
||||
'uuid' => $item['uid'],
|
||||
'name' => $item['name'],
|
||||
'owner_name' => $item['owner_name'],
|
||||
'application_type' => $item['application_type'],
|
||||
'application_type_name' => $item['application_type_name'],
|
||||
'condition' => $item['condition'],
|
||||
'registration_number' => $item['registration_number'],
|
||||
'document_number' => $item['document_number'],
|
||||
'address' => $item['address'],
|
||||
'status' => $item['status'],
|
||||
'status_name' => $item['status_name'],
|
||||
'slf_status' => $item['slf_status'] ?? null,
|
||||
'slf_status_name' => $item['slf_status_name'] ?? null,
|
||||
'function_type' => $item['function_type'],
|
||||
'consultation_type' => $item['consultation_type'],
|
||||
'due_date' => $item['due_date'],
|
||||
'land_certificate_phase' => $item['land_certificate_phase'],
|
||||
'task_created_at' => isset($item['created_at']) ? Carbon::parse($item['created_at'])->format('Y-m-d H:i:s') : null,
|
||||
'updated_at' => now(),
|
||||
'created_at' => now(),
|
||||
];
|
||||
|
||||
$this->syncIndexIntegration($item['uid'], $token);
|
||||
|
||||
$this->syncTaskDetailSubmit($item['uid'], $token);
|
||||
|
||||
$savedCount++;
|
||||
} catch (Exception $e) {
|
||||
$failedCount++;
|
||||
$importDatasource->update([
|
||||
'status' => ImportDatasourceStatus::Failed->value,
|
||||
'message' => "Successfully processed: $savedCount, Failed: $failedCount"
|
||||
]);
|
||||
Log::error("Failed to process task", [
|
||||
'error' => $e->getMessage(),
|
||||
'task' => $item,
|
||||
]);
|
||||
break;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
PbgTask::upsert($tasksCollective, ['uuid'], [
|
||||
'name', 'owner_name', 'application_type', 'application_type_name', 'condition',
|
||||
'registration_number', 'document_number', 'address', 'status', 'status_name',
|
||||
'slf_status', 'slf_status_name', 'function_type', 'consultation_type', 'due_date',
|
||||
'land_certificate_phase', 'task_created_at', 'updated_at'
|
||||
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' => $data['no__registrasi'] ?? null,
|
||||
'jenis_konsultasi' => $data['jenis_konsultasi'] ?? null,
|
||||
'fungsi_bg' => $data['fungsi_bg'] ?? null,
|
||||
'tgl_permohonan' => $this->convertToDate($data['tgl_permohonan']),
|
||||
'status_verifikasi' => $data['status_verifikasi'] ?? null,
|
||||
'status_permohonan' => $this->convertToDate($data['status_permohonan']),
|
||||
'alamat_pemilik' => $data['alamat_pemilik'] ?? null,
|
||||
'no_hp' => $data['no__hp'] ?? null,
|
||||
'email' => $data['e_mail'] ?? null,
|
||||
'tanggal_catatan' => $this->convertToDate($data['tanggal_catatan']),
|
||||
'catatan_kekurangan_dokumen' => $data['catatan_kekurangan_dokumen'] ?? null,
|
||||
'gambar' => $data['gambar'] ?? null,
|
||||
'krk_kkpr' => $data['krk_kkpr'] ?? null,
|
||||
'no_krk' => $data['no__krk'] ?? null,
|
||||
'lh' => $data['lh'] ?? null,
|
||||
'ska' => $data['ska'] ?? null,
|
||||
'keterangan' => $data['keterangan'] ?? null,
|
||||
'helpdesk' => $data['helpdesk'] ?? null,
|
||||
'pj' => $data['pj'] ?? null,
|
||||
'kepemilikan' => $data['kepemilikan'] ?? null,
|
||||
'potensi_taru' => $data['potensi_taru'] ?? null,
|
||||
'validasi_dinas' => $data['validasi_dinas'] ?? null,
|
||||
'kategori_retribusi' => $data['kategori_retribusi'] ?? null,
|
||||
'no_urut_ba_tpt' => $data['no__urut_ba_tpt__2024_0001_'] ?? null,
|
||||
'tanggal_ba_tpt' => $this->convertToDate($data['tanggal_ba_tpt']),
|
||||
'no_urut_ba_tpa' => $data['no__urut_ba_tpa'] ?? null,
|
||||
'tanggal_ba_tpa' => $this->convertToDate($data['tanggal_ba_tpa']),
|
||||
'no_urut_skrd' => $data['no__urut_skrd__2024_0001_'] ?? null,
|
||||
'tanggal_skrd' => $this->convertToDate($data['tanggal_skrd']),
|
||||
'ptsp' => $data['ptsp'] ?? null,
|
||||
'selesai_terbit' => $data['selesai_terbit'] ?? null,
|
||||
'tanggal_pembayaran' => $this->convertToDate($data['tanggal_pembayaran__yyyy_mm_dd_']),
|
||||
'format_sts' => $data['format_sts'] ?? null,
|
||||
'tahun_terbit' => (int) $data['tahun_terbit'] ?? null,
|
||||
'tahun_berjalan' => (int) $data['tahun_berjalan'] ?? null,
|
||||
'kelurahan' => $data['kelurahan'] ?? null,
|
||||
'kecamatan' => $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' => $data['latitude'] ?? null,
|
||||
'longitude' => $data['longitude'] ?? null,
|
||||
'nik_nib' => $data['nik_nib'] ?? null,
|
||||
'dok_tanah' => $data['dok__tanah'] ?? null,
|
||||
'temuan' => $data['temuan'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
$batchSize = 1000;
|
||||
$chunks = array_chunk($mapToUpsert, $batchSize);
|
||||
|
||||
foreach($chunks as $chunk){
|
||||
PbgTaskGoogleSheet::upsert($chunk, ["no_registrasi"],[
|
||||
'jenis_konsultasi',
|
||||
'nama_pemilik',
|
||||
'lokasi_bg',
|
||||
'fungsi_bg',
|
||||
'nama_bangunan',
|
||||
'tgl_permohonan',
|
||||
'status_verifikasi',
|
||||
'status_permohonan',
|
||||
'alamat_pemilik',
|
||||
'no_hp',
|
||||
'email',
|
||||
'tanggal_catatan',
|
||||
'catatan_kekurangan_dokumen',
|
||||
'gambar',
|
||||
'krk_kkpr',
|
||||
'no_krk',
|
||||
'lh',
|
||||
'ska',
|
||||
'keterangan',
|
||||
'helpdesk',
|
||||
'pj',
|
||||
'kepemilikan',
|
||||
'potensi_taru',
|
||||
'validasi_dinas',
|
||||
'kategori_retribusi',
|
||||
'no_urut_ba_tpt',
|
||||
'tanggal_ba_tpt',
|
||||
'no_urut_ba_tpa',
|
||||
'tanggal_ba_tpa',
|
||||
'no_urut_skrd',
|
||||
'tanggal_skrd',
|
||||
'ptsp',
|
||||
'selesai_terbit',
|
||||
'tanggal_pembayaran',
|
||||
'format_sts',
|
||||
'tahun_terbit',
|
||||
'tahun_berjalan',
|
||||
'kelurahan',
|
||||
'kecamatan',
|
||||
'lb',
|
||||
'tb',
|
||||
'jlb',
|
||||
'unit',
|
||||
'usulan_retribusi',
|
||||
'nilai_retribusi_keseluruhan_simbg',
|
||||
'nilai_retribusi_keseluruhan_pad',
|
||||
'denda',
|
||||
'latitude',
|
||||
'longitude',
|
||||
'nik_nib',
|
||||
'dok_tanah',
|
||||
'temuan',
|
||||
]);
|
||||
}
|
||||
|
||||
$initResToken = $this->getToken();
|
||||
if (empty($initResToken->original['data']['token']['access'])) {
|
||||
$importDatasource->update([
|
||||
'status' => ImportDatasourceStatus::Failed->value,
|
||||
'response_body' => 'Failed to retrieve token'
|
||||
]);
|
||||
return $this->resError("Failed to retrieve token");
|
||||
}
|
||||
$apiToken = $initResToken->original['data']['token']['access'];
|
||||
$headers = ['Authorization' => "Bearer " . $apiToken];
|
||||
|
||||
$url = "/api/pbg/v1/list/?page=1&size={$this->fetch_per_page}&sort=ASC";
|
||||
$initialResponse = $this->service_client->get($url, $headers);
|
||||
|
||||
$totalPage = $initialResponse->original['data']['total_page'] ?? 0;
|
||||
if ($totalPage == 0) {
|
||||
$importDatasource->update([
|
||||
'status' => ImportDatasourceStatus::Failed->value,
|
||||
'response_body' => 'Invalid response: no total_page'
|
||||
]);
|
||||
return $this->resError("Invalid response from API");
|
||||
}
|
||||
|
||||
$savedCount = $failedCount = 0;
|
||||
|
||||
Log::info("Fetching tasks", ['total page' => $totalPage]);
|
||||
|
||||
for ($currentPage = 1; $currentPage <= $totalPage; $currentPage++) {
|
||||
try {
|
||||
$pageUrl = "/api/pbg/v1/list/?page={$currentPage}&size={$this->fetch_per_page}&sort=ASC";
|
||||
|
||||
Log::info("Fetching tasks", ['currentPage' => $currentPage]);
|
||||
$headers = [
|
||||
'Authorization' => "Bearer " . $apiToken, // Update headers
|
||||
];
|
||||
|
||||
for ($attempt = 0; $attempt < 2; $attempt++) { // Try twice (original + retry)
|
||||
|
||||
$response = $this->service_client->get($pageUrl, $headers);
|
||||
|
||||
if ($response instanceof \Illuminate\Http\JsonResponse) {
|
||||
$decodedResponse = json_decode($response->getContent(), true);
|
||||
|
||||
if (isset($decodedResponse['errors']['code']) && $decodedResponse['errors']['code'] === 'token_not_valid') {
|
||||
$initResToken = $this->getToken();
|
||||
|
||||
if (!empty($initResToken->original['data']['token']['access'])) {
|
||||
$new_token = $initResToken->original['data']['token']['access'];
|
||||
$headers['Authorization'] = "Bearer " . $new_token;
|
||||
continue;
|
||||
} else {
|
||||
Log::error("Failed to refresh token");
|
||||
return $this->resError("Failed to refresh token");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Success case, break loop
|
||||
break;
|
||||
}
|
||||
|
||||
$tasks = $response->original['data']['data'] ?? [];
|
||||
|
||||
if (empty($tasks)) {
|
||||
Log::warning("No data found on page", ['page' => $currentPage]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$tasksCollective = [];
|
||||
foreach ($tasks as $item) {
|
||||
try {
|
||||
$tasksCollective[] = [
|
||||
'uuid' => $item['uid'],
|
||||
'name' => $item['name'],
|
||||
'owner_name' => $item['owner_name'],
|
||||
'application_type' => $item['application_type'],
|
||||
'application_type_name' => $item['application_type_name'],
|
||||
'condition' => $item['condition'],
|
||||
'registration_number' => $item['registration_number'],
|
||||
'document_number' => $item['document_number'],
|
||||
'address' => $item['address'],
|
||||
'status' => $item['status'],
|
||||
'status_name' => $item['status_name'],
|
||||
'slf_status' => $item['slf_status'] ?? null,
|
||||
'slf_status_name' => $item['slf_status_name'] ?? null,
|
||||
'function_type' => $item['function_type'],
|
||||
'consultation_type' => $item['consultation_type'],
|
||||
'due_date' => $item['due_date'],
|
||||
'land_certificate_phase' => $item['land_certificate_phase'],
|
||||
'task_created_at' => isset($item['created_at']) ? Carbon::parse($item['created_at'])->format('Y-m-d H:i:s') : null,
|
||||
'updated_at' => now(),
|
||||
'created_at' => now(),
|
||||
];
|
||||
|
||||
$this->syncTaskDetailSubmit($item['uid'], $apiToken);
|
||||
$this->syncTaskAssignments($item['uid']);
|
||||
$savedCount++;
|
||||
} catch (Exception $e) {
|
||||
$failedCount++;
|
||||
Log::error("Failed to process task", [
|
||||
'error' => $e->getMessage(),
|
||||
'task' => $item,
|
||||
]);
|
||||
continue; // Skip failed task, continue processing the rest
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($tasksCollective)) {
|
||||
PbgTask::upsert($tasksCollective, ['uuid'], [
|
||||
'name', 'owner_name', 'application_type', 'application_type_name', 'condition',
|
||||
'registration_number', 'document_number', 'address', 'status', 'status_name',
|
||||
'slf_status', 'slf_status_name', 'function_type', 'consultation_type', 'due_date',
|
||||
'land_certificate_phase', 'task_created_at', 'updated_at'
|
||||
]);
|
||||
|
||||
$uuids = array_column($tasksCollective, 'uuid');
|
||||
$this->syncIndexIntegration($uuids);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::error("Failed to process page", [
|
||||
'error' => $e->getMessage(),
|
||||
'page' => $currentPage,
|
||||
]);
|
||||
continue; // Skip the failed page and move to the next
|
||||
}
|
||||
}
|
||||
|
||||
BigdataResume::generateResumeData($importDatasource->id, "all", $data_setting_result);
|
||||
BigdataResume::generateResumeData($importDatasource->id, now()->year, $data_setting_result);
|
||||
|
||||
// Final update after processing all pages
|
||||
$importDatasource->update([
|
||||
'status' => ImportDatasourceStatus::Success->value,
|
||||
'message' => "Successfully processed: $savedCount, Failed: $failedCount"
|
||||
]);
|
||||
|
||||
Log::info("syncTaskList completed", ['savedCount' => $savedCount, 'failedCount' => $failedCount]);
|
||||
|
||||
return $this->resSuccess(['savedCount' => $savedCount, 'failedCount' => $failedCount]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
Log::error("syncTaskList failed", ['error' => $e->getMessage()]);
|
||||
if (isset($importDatasource)) {
|
||||
$importDatasource->update([
|
||||
'status' => ImportDatasourceStatus::Failed->value,
|
||||
'response_body' => 'Critical failure: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
return $this->resError("Critical failure occurred: " . $e->getMessage());
|
||||
}
|
||||
|
||||
$importDatasource->update([
|
||||
'status' => ImportDatasourceStatus::Success->value,
|
||||
'message' => "Successfully processed: $savedCount, Failed: $failedCount"
|
||||
]);
|
||||
|
||||
BigdataResume::generateResumeData($importDatasource->id);
|
||||
|
||||
Log::info("syncTaskList completed", ['savedCount' => $savedCount, 'failedCount' => $failedCount]);
|
||||
|
||||
return $this->resSuccess(['savedCount' => $savedCount, 'failedCount' => $failedCount]);
|
||||
}
|
||||
|
||||
|
||||
public function syncTaskDetailSubmit($uuid, $token)
|
||||
{
|
||||
try{
|
||||
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/submit/";
|
||||
|
||||
$headers = [
|
||||
'Authorization' => "Bearer " . $token,
|
||||
];
|
||||
|
||||
$res = $this->service_client->get($url, $headers);
|
||||
|
||||
if (empty($res->original['success']) || !$res->original['success']) {
|
||||
// Log error
|
||||
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
|
||||
return false;
|
||||
|
||||
for ($attempt = 0; $attempt < 2; $attempt++) {
|
||||
$res = $this->service_client->get($url, $headers);
|
||||
|
||||
// Check if response is JsonResponse and decode it
|
||||
if ($res instanceof \Illuminate\Http\JsonResponse) {
|
||||
$decodedResponse = json_decode($res->getContent(), true);
|
||||
|
||||
if (isset($decodedResponse['errors']['code']) && $decodedResponse['errors']['code'] === 'token_not_valid') {
|
||||
$initResToken = $this->getToken();
|
||||
|
||||
if (!empty($initResToken->original['data']['token']['access'])) {
|
||||
$new_token = $initResToken->original['data']['token']['access'];
|
||||
|
||||
$headers['Authorization'] = "Bearer " . $new_token;
|
||||
continue;
|
||||
} else {
|
||||
Log::error("Failed to refresh token");
|
||||
return $this->resError("Failed to refresh token");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$data = $res->original['data']['data'] ?? [];
|
||||
|
||||
// Ensure response is valid before accessing properties
|
||||
$responseData = $res->original ?? [];
|
||||
$data = $responseData['data']['data'] ?? [];
|
||||
if (empty($data)) {
|
||||
Log::error("No data returned from API", ['url' => $url, 'uuid' => $uuid]);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -311,5 +547,113 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,8 @@
|
||||
"laravel/framework": "^11.31",
|
||||
"laravel/sanctum": "^4.0",
|
||||
"laravel/tinker": "^2.9",
|
||||
"maatwebsite/excel": "^3.1"
|
||||
"maatwebsite/excel": "^3.1",
|
||||
"openai-php/client": "^0.10.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
@@ -56,7 +57,7 @@
|
||||
],
|
||||
"dev": [
|
||||
"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": {
|
||||
|
||||
300
composer.lock
generated
300
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "52617d098d62b15c6ce8538cc8aea775",
|
||||
"content-hash": "41bb51871a746904ab745e4095db8b46",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
@@ -3296,6 +3296,97 @@
|
||||
],
|
||||
"time": "2024-11-21T10:39:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "openai-php/client",
|
||||
"version": "v0.10.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/openai-php/client.git",
|
||||
"reference": "4a565d145e0fb3ea1baba8fffe39d86c56b6dc2c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/openai-php/client/zipball/4a565d145e0fb3ea1baba8fffe39d86c56b6dc2c",
|
||||
"reference": "4a565d145e0fb3ea1baba8fffe39d86c56b6dc2c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.1.0",
|
||||
"php-http/discovery": "^1.20.0",
|
||||
"php-http/multipart-stream-builder": "^1.4.2",
|
||||
"psr/http-client": "^1.0.3",
|
||||
"psr/http-client-implementation": "^1.0.1",
|
||||
"psr/http-factory-implementation": "*",
|
||||
"psr/http-message": "^1.1.0|^2.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/guzzle": "^7.9.2",
|
||||
"guzzlehttp/psr7": "^2.7.0",
|
||||
"laravel/pint": "^1.18.1",
|
||||
"mockery/mockery": "^1.6.12",
|
||||
"nunomaduro/collision": "^7.11.0|^8.5.0",
|
||||
"pestphp/pest": "^2.36.0|^3.5.0",
|
||||
"pestphp/pest-plugin-arch": "^2.7|^3.0",
|
||||
"pestphp/pest-plugin-type-coverage": "^2.8.7|^3.1.0",
|
||||
"phpstan/phpstan": "^1.12.7",
|
||||
"symfony/var-dumper": "^6.4.11|^7.1.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/OpenAI.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"OpenAI\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nuno Maduro",
|
||||
"email": "enunomaduro@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Sandro Gehri"
|
||||
}
|
||||
],
|
||||
"description": "OpenAI PHP is a supercharged PHP API client that allows you to interact with the Open AI API",
|
||||
"keywords": [
|
||||
"GPT-3",
|
||||
"api",
|
||||
"client",
|
||||
"codex",
|
||||
"dall-e",
|
||||
"language",
|
||||
"natural",
|
||||
"openai",
|
||||
"php",
|
||||
"processing",
|
||||
"sdk"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/openai-php/client/issues",
|
||||
"source": "https://github.com/openai-php/client/tree/v0.10.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/paypalme/enunomaduro",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/gehrisandro",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nunomaduro",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-12T20:51:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v3.0.0",
|
||||
@@ -3413,6 +3504,141 @@
|
||||
},
|
||||
"time": "2020-10-15T08:29:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-http/discovery",
|
||||
"version": "1.20.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-http/discovery.git",
|
||||
"reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d",
|
||||
"reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-plugin-api": "^1.0|^2.0",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"nyholm/psr7": "<1.0",
|
||||
"zendframework/zend-diactoros": "*"
|
||||
},
|
||||
"provide": {
|
||||
"php-http/async-client-implementation": "*",
|
||||
"php-http/client-implementation": "*",
|
||||
"psr/http-client-implementation": "*",
|
||||
"psr/http-factory-implementation": "*",
|
||||
"psr/http-message-implementation": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "^1.0.2|^2.0",
|
||||
"graham-campbell/phpspec-skip-example-extension": "^5.0",
|
||||
"php-http/httplug": "^1.0 || ^2.0",
|
||||
"php-http/message-factory": "^1.0",
|
||||
"phpspec/phpspec": "^5.1 || ^6.1 || ^7.3",
|
||||
"sebastian/comparator": "^3.0.5 || ^4.0.8",
|
||||
"symfony/phpunit-bridge": "^6.4.4 || ^7.0.1"
|
||||
},
|
||||
"type": "composer-plugin",
|
||||
"extra": {
|
||||
"class": "Http\\Discovery\\Composer\\Plugin",
|
||||
"plugin-optional": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Http\\Discovery\\": "src/"
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"src/Composer/Plugin.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Márk Sági-Kazár",
|
||||
"email": "mark.sagikazar@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations",
|
||||
"homepage": "http://php-http.org",
|
||||
"keywords": [
|
||||
"adapter",
|
||||
"client",
|
||||
"discovery",
|
||||
"factory",
|
||||
"http",
|
||||
"message",
|
||||
"psr17",
|
||||
"psr7"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-http/discovery/issues",
|
||||
"source": "https://github.com/php-http/discovery/tree/1.20.0"
|
||||
},
|
||||
"time": "2024-10-02T11:20:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-http/multipart-stream-builder",
|
||||
"version": "1.4.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-http/multipart-stream-builder.git",
|
||||
"reference": "10086e6de6f53489cca5ecc45b6f468604d3460e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/10086e6de6f53489cca5ecc45b6f468604d3460e",
|
||||
"reference": "10086e6de6f53489cca5ecc45b6f468604d3460e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0",
|
||||
"php-http/discovery": "^1.15",
|
||||
"psr/http-factory-implementation": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"nyholm/psr7": "^1.0",
|
||||
"php-http/message": "^1.5",
|
||||
"php-http/message-factory": "^1.0.2",
|
||||
"phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Http\\Message\\MultipartStream\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A builder class that help you create a multipart stream",
|
||||
"homepage": "http://php-http.org",
|
||||
"keywords": [
|
||||
"factory",
|
||||
"http",
|
||||
"message",
|
||||
"multipart stream",
|
||||
"stream"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-http/multipart-stream-builder/issues",
|
||||
"source": "https://github.com/php-http/multipart-stream-builder/tree/1.4.2"
|
||||
},
|
||||
"time": "2024-09-04T13:22:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/phpspreadsheet",
|
||||
"version": "1.29.10",
|
||||
@@ -7155,74 +7381,6 @@
|
||||
},
|
||||
"time": "2020-07-09T08:09:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ibex/crud-generator",
|
||||
"version": "v2.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/awais-vteams/laravel-crud-generator.git",
|
||||
"reference": "3906f4a702c91bbe3a84d940c3021d1511834320"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/awais-vteams/laravel-crud-generator/zipball/3906f4a702c91bbe3a84d940c3021d1511834320",
|
||||
"reference": "3906f4a702c91bbe3a84d940c3021d1511834320",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"laravel/framework": "^10.30|^11.0",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Ibex\\CrudGenerator\\CrudServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Ibex\\CrudGenerator\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "M Awais",
|
||||
"email": "asargodha@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel CRUD Generator",
|
||||
"keywords": [
|
||||
"alpine js",
|
||||
"bootstrap css",
|
||||
"crud",
|
||||
"crud generator",
|
||||
"laravel",
|
||||
"laravel crud generator",
|
||||
"laravel package",
|
||||
"tailwind css"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/awais-vteams/laravel-crud-generator/issues",
|
||||
"source": "https://github.com/awais-vteams/laravel-crud-generator/tree/v2.1.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/awais-vteams",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://ko-fi.com/mawais",
|
||||
"type": "ko_fi"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-09T06:01:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/pail",
|
||||
"version": "v1.2.2",
|
||||
@@ -9316,12 +9474,12 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {},
|
||||
"prefer-stable": true,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": "^8.2"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
|
||||
@@ -123,5 +123,6 @@ return [
|
||||
'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,
|
||||
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||
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',
|
||||
],
|
||||
|
||||
// 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,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('pbg_task_google_sheet', function (Blueprint $table) {
|
||||
$table->string('formatted_registration_number')->nullable()->after('no_registrasi');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('pbg_task_google_sheet', function (Blueprint $table) {
|
||||
$table->dropColumn('formatted_registration_number');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -71,10 +71,31 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
[
|
||||
"name" => "Laporan",
|
||||
"url" => "/laporan",
|
||||
"icon" => "mingcute:task-line",
|
||||
"icon" => "mingcute:report-line",
|
||||
"parent_id" => null,
|
||||
"sort_order" => 6,
|
||||
]
|
||||
],
|
||||
[
|
||||
"name" => "Neng Bedas",
|
||||
"url" => "/chat",
|
||||
"icon" => "mingcute:wechat-line",
|
||||
"parent_id" => null,
|
||||
"sort_order" => 7,
|
||||
],
|
||||
[
|
||||
"name" => "Approval",
|
||||
"url" => "/approval",
|
||||
"icon" => "mingcute:user-follow-2-line",
|
||||
"parent_id" => null,
|
||||
"sort_order" => 8,
|
||||
],
|
||||
[
|
||||
"name" => "Tools",
|
||||
"url" => "/tools",
|
||||
"icon" => "mingcute:tool-line",
|
||||
"parent_id" => null,
|
||||
"sort_order" => 9,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($parent_menus as $parent_menu) {
|
||||
@@ -92,6 +113,9 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
$dataSettings = Menu::where('name', 'Data Settings')->first();
|
||||
$data = Menu::where('name', 'Data')->first();
|
||||
$laporan = Menu::where('name', 'Laporan')->first();
|
||||
$chat_bedas = Menu::where('name', 'Neng Bedas')->first();
|
||||
$approval = Menu::where('name', 'Approval')->first();
|
||||
$tools = Menu::where('name', 'Tools')->first();
|
||||
|
||||
// create children menu
|
||||
$children_menus = [
|
||||
@@ -111,11 +135,18 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
],
|
||||
[
|
||||
"name" => "Dashboard Potensi",
|
||||
"url" => "dashboard.lack_of_potential",
|
||||
"url" => null,
|
||||
"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",
|
||||
@@ -123,6 +154,13 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
"parent_id" => $master->id,
|
||||
"sort_order" => 1,
|
||||
],
|
||||
[
|
||||
"name" => "Approval Pejabat",
|
||||
"url" => "approval-list",
|
||||
"icon" => null,
|
||||
"parent_id" => $approval->id,
|
||||
"sort_order" => 1,
|
||||
],
|
||||
[
|
||||
"name" => "Syncronize",
|
||||
"url" => "settings.syncronize",
|
||||
@@ -160,7 +198,7 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
],
|
||||
[
|
||||
"name" => "Reklame",
|
||||
"url" => "advertisements.index",
|
||||
"url" => "web.advertisements.index",
|
||||
"icon" => null,
|
||||
"parent_id" => $data->id,
|
||||
"sort_order" => 2,
|
||||
@@ -174,21 +212,21 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
],
|
||||
[
|
||||
"name" => "UMKM",
|
||||
"url" => "umkm.index",
|
||||
"url" => "web-umkm.index",
|
||||
"icon" => null,
|
||||
"parent_id" => $data->id,
|
||||
"sort_order" => 4,
|
||||
],
|
||||
[
|
||||
"name" => "Pariwisata",
|
||||
"url" => "tourisms.index",
|
||||
"url" => "web-tourisms.index",
|
||||
"icon" => null,
|
||||
"parent_id" => $data->id,
|
||||
"sort_order" => 5,
|
||||
],
|
||||
[
|
||||
"name" => "Tata Ruang",
|
||||
"url" => "spatial-plannings.index",
|
||||
"url" => "web-spatial-plannings.index",
|
||||
"icon" => null,
|
||||
"parent_id" => $data->id,
|
||||
"sort_order" => 6,
|
||||
@@ -200,13 +238,83 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
"parent_id" => $data->id,
|
||||
"sort_order" => 7,
|
||||
],
|
||||
[
|
||||
"name" => "Google Sheets",
|
||||
"url" => "google-sheets",
|
||||
"icon" => null,
|
||||
"parent_id" => $data->id,
|
||||
"sort_order" => 8,
|
||||
],
|
||||
[
|
||||
"name" => "TPA TPT",
|
||||
"url" => "tpa-tpt",
|
||||
"icon" => null,
|
||||
"parent_id" => $data->id,
|
||||
"sort_order" => 9,
|
||||
],
|
||||
[
|
||||
"name" => "Lap Pariwisata",
|
||||
"url" => "tourisms.index",
|
||||
"url" => "tourisms-report.index",
|
||||
"icon" => null,
|
||||
"parent_id" => $laporan->id,
|
||||
"sort_order" => 1,
|
||||
],
|
||||
[
|
||||
"name" => "Lap Pimpinan",
|
||||
"url" => "bigdata-resumes",
|
||||
"icon" => null,
|
||||
"parent_id" => $laporan->id,
|
||||
"sort_order" => 2,
|
||||
],
|
||||
[
|
||||
"name" => "Rekap Pembayaran",
|
||||
"url" => "payment-recaps",
|
||||
"icon" => null,
|
||||
"parent_id" => $laporan->id,
|
||||
"sort_order" => 3,
|
||||
],
|
||||
[
|
||||
"name" => "Lap Rekap Data Pembayaran",
|
||||
"url" => "report-payment-recap",
|
||||
"icon" => null,
|
||||
"parent_id" => $laporan->id,
|
||||
"sort_order" => 4,
|
||||
],
|
||||
[
|
||||
"name" => "Lap PBG (PTSP)",
|
||||
"url" => "report-pbg-ptsp",
|
||||
"icon" => null,
|
||||
"parent_id" => $laporan->id,
|
||||
"sort_order" => 5,
|
||||
],
|
||||
[
|
||||
"name" => "Chat",
|
||||
"url" => "main-chatbot.index",
|
||||
"icon" => null,
|
||||
"parent_id" => $chat_bedas->id,
|
||||
"sort_order" => 1,
|
||||
],
|
||||
[
|
||||
"name" => "Luar Sistem",
|
||||
"url" => "dashboard.potentials.inside_system",
|
||||
"icon" => null,
|
||||
"parent_id" => Menu::where('name', 'Dashboard Potensi')->first()->id,
|
||||
"sort_order" => 1,
|
||||
],
|
||||
[
|
||||
"name" => "Dalam Sistem",
|
||||
"url" => "dashboard.potentials.outside_system",
|
||||
"icon" => null,
|
||||
"parent_id" => Menu::where('name', 'Dashboard Potensi')->first()->id,
|
||||
"sort_order" => 2,
|
||||
],
|
||||
[
|
||||
"name" => "Undangan",
|
||||
"url" => "invitations",
|
||||
"icon" => null,
|
||||
"parent_id" => $tools->id,
|
||||
"sort_order" => 1,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($children_menus as $child_menu) {
|
||||
@@ -229,6 +337,18 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
$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();
|
||||
$bigdata_resume = Menu::where('name', 'Lap Pimpinan')->first();
|
||||
$chatbot = Menu::where('name', 'Chat')->first();
|
||||
$dalam_sistem = Menu::where('name', 'Dalam Sistem')->first();
|
||||
$luar_sistem = Menu::where('name', 'Luar Sistem')->first();
|
||||
$google_sheets = Menu::where('name', 'Google Sheets')->first();
|
||||
$tpa_tpt = Menu::where('name', 'TPA TPT')->first();
|
||||
$approval_pejabat = Menu::where('name', 'Approval Pejabat')->first();
|
||||
$intivations = Menu::where('name', 'Undangan')->first();
|
||||
$payment_recap = Menu::where('name', 'Rekap Pembayaran')->first();
|
||||
$report_payment_recap = Menu::where('name', 'Lap Rekap Data Pembayaran')->first();
|
||||
$report_pbg_ptsp = Menu::where('name', 'Lap PBG (PTSP)')->first();
|
||||
|
||||
// Superadmin gets all menus
|
||||
$superadmin->menus()->sync([
|
||||
@@ -239,6 +359,9 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
$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],
|
||||
$chat_bedas->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
||||
$approval->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
||||
$tools->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],
|
||||
@@ -256,6 +379,18 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
$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],
|
||||
$dalam_sistem->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
$luar_sistem->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
$bigdata_resume->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
$chatbot->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
$google_sheets->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
$tpa_tpt->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
$approval_pejabat->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
$intivations->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
$payment_recap->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
$report_payment_recap->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
$report_pbg_ptsp->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||
]);
|
||||
|
||||
// Admin gets limited menus
|
||||
@@ -270,6 +405,7 @@ class UsersRoleMenuSeeder extends Seeder
|
||||
$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
|
||||
User::findOrFail(1)->roles()->sync([$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;
|
||||
34
deploy.sh
Executable file
34
deploy.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
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 "⚡ Optimizing application..."
|
||||
php artisan optimize:clear
|
||||
|
||||
echo "🔄 Restarting PHP service..."
|
||||
systemctl restart $PHP_VERSION-fpm
|
||||
|
||||
echo "🔁 Restarting Supervisor queue workers..."
|
||||
supervisorctl stop all
|
||||
supervisorctl reload
|
||||
supervisorctl start all
|
||||
|
||||
php artisan up
|
||||
echo "🚀 Deployment completed successfully!"
|
||||
5851
package-lock.json
generated
5851
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
69
package.json
69
package.json
@@ -1,36 +1,37 @@
|
||||
{
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"dev": "vite"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.20",
|
||||
"axios": "^1.7.4",
|
||||
"concurrently": "^9.0.1",
|
||||
"laravel-vite-plugin": "^1.0",
|
||||
"postcss": "^8.4.47",
|
||||
"sass": "^1.81.1",
|
||||
"tailwindcss": "^3.4.13",
|
||||
"vite": "^5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"apexcharts": "^3.44.2",
|
||||
"big.js": "^6.2.2",
|
||||
"bootstrap": "^5.3.3",
|
||||
"countup.js": "^2.3.2",
|
||||
"dropzone": "^5.9.0",
|
||||
"flatpickr": "^4.6.13",
|
||||
"gmaps": "^0.4.25",
|
||||
"gridjs": "^5.1.0",
|
||||
"iconify-icon": "^2.1.0",
|
||||
"jsvectormap": "^1.5.1",
|
||||
"moment": "^2.29.4",
|
||||
"node-waves": "^0.7.6",
|
||||
"quill": "^1.3.7",
|
||||
"simplebar": "^5.3.9",
|
||||
"sweetalert2": "^11.16.0",
|
||||
"wnumb": "^1.2.0"
|
||||
}
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"dev": "vite"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.20",
|
||||
"axios": "^1.7.4",
|
||||
"concurrently": "^9.0.1",
|
||||
"laravel-vite-plugin": "^1.0",
|
||||
"postcss": "^8.4.47",
|
||||
"sass": "^1.81.1",
|
||||
"tailwindcss": "^3.4.13",
|
||||
"vite": "^5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"apexcharts": "^3.44.2",
|
||||
"big.js": "^6.2.2",
|
||||
"bootstrap": "^5.3.3",
|
||||
"countup.js": "^2.3.2",
|
||||
"dropzone": "^5.9.0",
|
||||
"flatpickr": "^4.6.13",
|
||||
"gmaps": "^0.4.25",
|
||||
"gridjs": "^5.1.0",
|
||||
"iconify-icon": "^2.1.0",
|
||||
"jsvectormap": "^1.5.1",
|
||||
"leaflet": "^1.9.4",
|
||||
"moment": "^2.29.4",
|
||||
"node-waves": "^0.7.6",
|
||||
"quill": "^1.3.7",
|
||||
"simplebar": "^5.3.9",
|
||||
"sweetalert2": "^11.16.0",
|
||||
"wnumb": "^1.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
public/images/iconchatbot.jpeg
Normal file
BIN
public/images/iconchatbot.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 177 KiB |
@@ -5,6 +5,7 @@ use Illuminate\Http\Request;
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
ini_set('max_execution_time',14400);
|
||||
ini_set('memory_limit', '2G');
|
||||
|
||||
// Determine if the application is in maintenance mode...
|
||||
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
|
||||
|
||||
BIN
public/leaflet/layers-2x.png
Normal file
BIN
public/leaflet/layers-2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
public/leaflet/layers.png
Normal file
BIN
public/leaflet/layers.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 696 B |
BIN
public/leaflet/marker-icon-2x.png
Normal file
BIN
public/leaflet/marker-icon-2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
public/leaflet/marker-icon.png
Normal file
BIN
public/leaflet/marker-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
public/leaflet/marker-shadow.png
Normal file
BIN
public/leaflet/marker-shadow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 618 B |
11
public/templates/contentTemplatePrompt.json
Normal file
11
public/templates/contentTemplatePrompt.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"RETRIBUTION": {
|
||||
"prompt": "You are a MariaDB SQL expert. Your task is to generate an efficient and optimized SQL query based on user input.\n\n The query should retrieve data from the view table `v_pbg_task_with_retributions`, specifically selecting the following columns:\n\n - nilai_retribusi_bangunan\n - land_certificate_phase\n - due_date\n - consultation_type\n - function_type\n - slf_status_name\n - slf_status\n - status_name\n - status\n - address\n - document_number\n - registration_number\n - application_type_name\n - application_type\n - owner_name\n - name\n\n Ensure the query is well-structured, uses best indexing practices, and avoids performance bottlenecks.\n\n Consider the following context: \"$mainContent\".\n\n Always return only the SQL query without any additional explanation.\n\n The query should include `LIMIT 5` to restrict the results."
|
||||
},
|
||||
"DOCUMENT VALIDATION": {
|
||||
"prompt": "You are a MariaDB SQL expert. Your task is to generate an efficient and optimized SQL query based on user input.\n\n The query should retrieve data from the view table `pbg_task`, specifically selecting the following columns:\n\n - name\n - owner_name\n - application_type\n - application_type_name\n - registration_number\n - document_number\n - address\n - status_name\n - slf_status\n - slf_status_name\n - function_type\n - consultation_type\n - function_type\n - consultation_type\n - due_date\n - land_certificate_phase\n\n Ensure the query is well-structured, uses best indexing practices, and avoids performance bottlenecks.\n\n Consider the following context: \"$mainContent\".\n\n Always return only the SQL query without any additional explanation.\n\n The query should include `LIMIT 5` to restrict the results."
|
||||
},
|
||||
"DATA SUMMARY": {
|
||||
"prompt": "You are a MariaDB SQL expert. Your task is to generate an efficient and optimized SQL query based on user input.\n\n The query should retrieve data from the view table `bigdata_resumes`, specifically selecting the following columns:\n\n - potention_count\n - potention_sum\n - non_verified_count\n - non_verified_sum\n - verified_sum\n - verified_count\n - business_count\n - business_sum\n - non_business_count\n - non_business_sum\n - spatial_count\n - spatial_sum\n - updated_at\n\n Ensure the query is well-structured, uses best indexing practices, and avoids performance bottlenecks.\n\n Consider the following context: \"$mainContent\".\n\n Always return only the SQL query without any additional explanation.\n\n The query should include `LIMIT 5` to restrict the results."
|
||||
}
|
||||
}
|
||||
169
public/templates/table_config.json
Normal file
169
public/templates/table_config.json
Normal file
@@ -0,0 +1,169 @@
|
||||
{
|
||||
"reklame": {
|
||||
"table_name": "v_advertisements",
|
||||
"list_column": [
|
||||
"no",
|
||||
"business_name",
|
||||
"npwpd",
|
||||
"advertisement_type",
|
||||
"advertisement_content",
|
||||
"business_address",
|
||||
"advertisement_location",
|
||||
"village_name",
|
||||
"district_name",
|
||||
"length",
|
||||
"width",
|
||||
"viewing_angle",
|
||||
"face",
|
||||
"area",
|
||||
"angle",
|
||||
"contact"
|
||||
]
|
||||
},
|
||||
"business_or_industries": {
|
||||
"table_name": "business_or_industries",
|
||||
"list_column": [
|
||||
"nama_kecamatan",
|
||||
"nama_kelurahan",
|
||||
"nop",
|
||||
"nama_wajib_pajak",
|
||||
"alamat_wajib_pajak",
|
||||
"alamat_objek_pajak",
|
||||
"luas_bumi",
|
||||
"luas_bangunan",
|
||||
"njop_bumi",
|
||||
"njop_bangunan",
|
||||
"ketetapan",
|
||||
"tahun_pajak",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
]
|
||||
},
|
||||
"customers": {
|
||||
"table_name": "customers",
|
||||
"list_column": [
|
||||
"nomor_pelanggan",
|
||||
"kota_pelayanan",
|
||||
"nama",
|
||||
"alamat",
|
||||
"latitude",
|
||||
"longitude",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
]
|
||||
},
|
||||
"pbg": {
|
||||
"table_name": "pbg_task",
|
||||
"list_column": [
|
||||
"uuid",
|
||||
"name",
|
||||
"owner_name",
|
||||
"application_type",
|
||||
"application_type_name",
|
||||
"condition",
|
||||
"registration_number",
|
||||
"document_number",
|
||||
"address",
|
||||
"status_name",
|
||||
"slf_status_name",
|
||||
"function_type",
|
||||
"consultation_type",
|
||||
"due_date",
|
||||
"land_certificate_phase",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"task_created_at"
|
||||
]
|
||||
},
|
||||
"retribusi": {
|
||||
"table_name": "v_pbg_task_with_retributions",
|
||||
"list_column": [
|
||||
"uuid",
|
||||
"name",
|
||||
"owner_name",
|
||||
"application_type",
|
||||
"application_type_name",
|
||||
"condition",
|
||||
"registration_number",
|
||||
"document_number",
|
||||
"address",
|
||||
"status_name",
|
||||
"slf_status_name",
|
||||
"consultation_type",
|
||||
"due_date",
|
||||
"land_certificate_phase",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"task_created_at",
|
||||
"nilai_retribusi_bangunan"
|
||||
]
|
||||
},
|
||||
"spatial_plannings": {
|
||||
"table_name": "spatial_plannings",
|
||||
"list_column": [
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"name",
|
||||
"kbli",
|
||||
"activities",
|
||||
"area",
|
||||
"location",
|
||||
"number",
|
||||
"date"
|
||||
]
|
||||
},
|
||||
"tourisms": {
|
||||
"table_name": "v_tourisms",
|
||||
"list_column": [
|
||||
"project_id",
|
||||
"project_type_id",
|
||||
"nib",
|
||||
"business_name",
|
||||
"oss_publication_date",
|
||||
"investment_status_description",
|
||||
"business_form",
|
||||
"project_risk",
|
||||
"project_name",
|
||||
"business_scale",
|
||||
"business_address",
|
||||
"village_name",
|
||||
"district_name",
|
||||
"longitude",
|
||||
"latitude",
|
||||
"project_submission_date",
|
||||
"kbli_title",
|
||||
"supervisory_sector",
|
||||
"user_name",
|
||||
"email",
|
||||
"contact",
|
||||
"land_area_in_m2",
|
||||
"investment_amount",
|
||||
"tki"
|
||||
]
|
||||
},
|
||||
"umkms": {
|
||||
"table_name": "v_umkms",
|
||||
"list_column": [
|
||||
"business_address",
|
||||
"business_contact",
|
||||
"business_desc",
|
||||
"business_form",
|
||||
"business_id_number",
|
||||
"business_name",
|
||||
"business_scale",
|
||||
"business_type",
|
||||
"created_at",
|
||||
"district_name",
|
||||
"land_area",
|
||||
"number_of_employee",
|
||||
"owner_address",
|
||||
"owner_contact",
|
||||
"owner_id",
|
||||
"owner_name",
|
||||
"permit_status",
|
||||
"revenue",
|
||||
"updated_at",
|
||||
"village_name"
|
||||
]
|
||||
}
|
||||
}
|
||||
90
resources/js/approval/index.js
Normal file
90
resources/js/approval/index.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import { Grid } from "gridjs/dist/gridjs.umd.js";
|
||||
import "gridjs/dist/gridjs.umd.js";
|
||||
import gridjs from "gridjs/dist/gridjs.umd.js";
|
||||
import GlobalConfig from "../global-config";
|
||||
|
||||
class Approval {
|
||||
constructor() {
|
||||
this.toastMessage = document.getElementById("toast-message");
|
||||
this.toastElement = document.getElementById("toastNotification");
|
||||
this.toast = new bootstrap.Toast(this.toastElement);
|
||||
this.table = null;
|
||||
this.initTableApproval();
|
||||
}
|
||||
initTableApproval() {
|
||||
let tableContainer = document.getElementById("table-approvals");
|
||||
this.table = new Grid({
|
||||
columns: [
|
||||
"ID",
|
||||
{ name: "Name", width: "15%" },
|
||||
{ name: "Condition", width: "7%" },
|
||||
"Registration Number",
|
||||
"Document Number",
|
||||
{ name: "Address", width: "30%" },
|
||||
"Status",
|
||||
"Function Type",
|
||||
"Consultation Type",
|
||||
{ name: "Due Date", width: "10%" },
|
||||
{
|
||||
name: "Action",
|
||||
formatter: (cell) => {
|
||||
return gridjs.html(`
|
||||
<div class="d-flex justify-content-center align-items-center gap-2">
|
||||
<button class="btn btn-sm btn-success approve-btn" data-id="${cell}">
|
||||
Approve
|
||||
</button>
|
||||
<button class="btn btn-sm btn-danger reject-btn" data-id="${cell}">
|
||||
Reject
|
||||
</button>
|
||||
</div>
|
||||
`);
|
||||
},
|
||||
},
|
||||
],
|
||||
search: {
|
||||
server: {
|
||||
url: (prev, keyword) => `${prev}?search=${keyword}`,
|
||||
},
|
||||
debounceTimeout: 1000,
|
||||
},
|
||||
pagination: {
|
||||
limit: 15,
|
||||
server: {
|
||||
url: (prev, page) =>
|
||||
`${prev}${prev.includes("?") ? "&" : "?"}page=${
|
||||
page + 1
|
||||
}`,
|
||||
},
|
||||
},
|
||||
sort: true,
|
||||
server: {
|
||||
url: `${GlobalConfig.apiHost}/api/request-assignments`,
|
||||
credentials: "include",
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
then: (data) =>
|
||||
data.data.map((item) => [
|
||||
item.id,
|
||||
item.name,
|
||||
item.condition,
|
||||
item.registration_number,
|
||||
item.document_number,
|
||||
item.address,
|
||||
item.status_name,
|
||||
item.function_type,
|
||||
item.consultation_type,
|
||||
item.due_date,
|
||||
item.id,
|
||||
]),
|
||||
total: (data) => data.meta.total,
|
||||
},
|
||||
}).render(tableContainer);
|
||||
}
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function (e) {
|
||||
new Approval();
|
||||
});
|
||||
178
resources/js/bigdata-resumes/index.js
Normal file
178
resources/js/bigdata-resumes/index.js
Normal file
@@ -0,0 +1,178 @@
|
||||
import { Grid } from "gridjs/dist/gridjs.umd.js";
|
||||
import gridjs from "gridjs/dist/gridjs.umd.js";
|
||||
import "gridjs/dist/gridjs.umd.js";
|
||||
import GlobalConfig, { addThousandSeparators } from "../global-config.js";
|
||||
import moment from "moment";
|
||||
|
||||
class BigdataResume {
|
||||
constructor() {
|
||||
this.toastMessage = document.getElementById("toast-message");
|
||||
this.toastElement = document.getElementById("toastNotification");
|
||||
this.toast = new bootstrap.Toast(this.toastElement);
|
||||
this.table = null;
|
||||
|
||||
// Initialize functions
|
||||
this.initEvents();
|
||||
}
|
||||
async initEvents() {
|
||||
await this.initBigdataResumeTable();
|
||||
// this.handleSearch();
|
||||
}
|
||||
|
||||
async initBigdataResumeTable() {
|
||||
let tableContainer = document.getElementById("table-bigdata-resumes");
|
||||
|
||||
this.table = new Grid({
|
||||
columns: [
|
||||
{ name: "ID" },
|
||||
{ name: "Jumlah Potensi" },
|
||||
{ name: "Total Potensi" },
|
||||
{ name: "Jumlah Berkas Belum Terverifikasi" },
|
||||
{ name: "Total Berkas Belum Terverifikasi" },
|
||||
{ name: "Jumlah Berkas Terverifikasi" },
|
||||
{ name: "Total Berkas Terverifikasi" },
|
||||
{ name: "Jumlah Usaha" },
|
||||
{ name: "Total Usaha" },
|
||||
{ name: "Jumlah Non Usaha" },
|
||||
{ name: "Total Non Usaha" },
|
||||
{ name: "Jumlah Tata Ruang" },
|
||||
{ name: "Total Tata Ruang" },
|
||||
{ name: "Jumlah Menunggu Klik DPMPTSP" },
|
||||
{ name: "Total Menunggu Klik DPMPTSP" },
|
||||
{ name: "Jumlah Realisasi Terbit PBG" },
|
||||
{ name: "Total Realisasi Terbit PBG" },
|
||||
{ name: "Jumlah Proses Dinas Teknis" },
|
||||
{ name: "Total Proses Dinas Teknis" },
|
||||
{
|
||||
name: "Created",
|
||||
attributes: {
|
||||
style: "width: 200px; white-space: nowrap;",
|
||||
},
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
limit: 50,
|
||||
server: {
|
||||
url: (prev, page) =>
|
||||
`${prev}${prev.includes("?") ? "&" : "?"}page=${
|
||||
page + 1
|
||||
}`,
|
||||
},
|
||||
},
|
||||
sort: true,
|
||||
search: {
|
||||
server: {
|
||||
url: (prev, keyword) => `${prev}?search=${keyword}`,
|
||||
},
|
||||
debounceTimeout: 1000,
|
||||
},
|
||||
server: {
|
||||
url: `${GlobalConfig.apiHost}/api/bigdata-report`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
then: (data) => {
|
||||
return data.data.map((item) => [
|
||||
item.id,
|
||||
item.potention_count,
|
||||
addThousandSeparators(item.potention_sum),
|
||||
item.non_verified_count,
|
||||
addThousandSeparators(item.non_verified_sum),
|
||||
item.verified_count,
|
||||
addThousandSeparators(item.verified_sum),
|
||||
item.business_count,
|
||||
addThousandSeparators(item.business_sum),
|
||||
item.non_business_count,
|
||||
addThousandSeparators(item.non_business_sum),
|
||||
item.spatial_count,
|
||||
addThousandSeparators(item.spatial_sum),
|
||||
item.waiting_click_dpmptsp_count,
|
||||
addThousandSeparators(item.waiting_click_dpmptsp_sum),
|
||||
item.issuance_realization_pbg_count,
|
||||
addThousandSeparators(
|
||||
item.issuance_realization_pbg_sum
|
||||
),
|
||||
item.process_in_technical_office_count,
|
||||
addThousandSeparators(
|
||||
item.process_in_technical_office_sum
|
||||
),
|
||||
moment(item.created_at).format("YYYY-MM-DD H:mm:ss"),
|
||||
]);
|
||||
},
|
||||
total: (data) => data.total,
|
||||
},
|
||||
width: "auto",
|
||||
fixedHeader: true,
|
||||
});
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.table.render(tableContainer);
|
||||
this.table.on("ready", resolve); // Tunggu event "ready"
|
||||
});
|
||||
}
|
||||
|
||||
handleSearch() {
|
||||
document.getElementById("search-btn").addEventListener("click", () => {
|
||||
let searchValue = document.getElementById("search-box").value;
|
||||
|
||||
if (!this.table) {
|
||||
// Ensure table is initialized
|
||||
console.error("Table element not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
this.table
|
||||
.updateConfig({
|
||||
server: {
|
||||
url: `${GlobalConfig.apiHost}/api/bigdata-report?search=${searchValue}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
then: (data) => {
|
||||
return data.data.map((item) => [
|
||||
item.id,
|
||||
item.potention_count,
|
||||
addThousandSeparators(item.potention_sum),
|
||||
item.non_verified_count,
|
||||
addThousandSeparators(item.non_verified_sum),
|
||||
item.verified_count,
|
||||
addThousandSeparators(item.verified_sum),
|
||||
item.business_count,
|
||||
addThousandSeparators(item.business_sum),
|
||||
item.non_business_count,
|
||||
addThousandSeparators(item.non_business_sum),
|
||||
item.spatial_count,
|
||||
addThousandSeparators(item.spatial_sum),
|
||||
item.waiting_click_dpmptsp_count,
|
||||
addThousandSeparators(
|
||||
item.waiting_click_dpmptsp_sum
|
||||
),
|
||||
item.issuance_realization_pbg_count,
|
||||
addThousandSeparators(
|
||||
item.issuance_realization_pbg_sum
|
||||
),
|
||||
item.process_in_technical_office_count,
|
||||
addThousandSeparators(
|
||||
item.process_in_technical_office_sum
|
||||
),
|
||||
moment(item.created_at).format(
|
||||
"YYYY-MM-DD H:mm:ss"
|
||||
),
|
||||
]);
|
||||
},
|
||||
total: (data) => data.total,
|
||||
},
|
||||
})
|
||||
.forceRender();
|
||||
});
|
||||
}
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function (e) {
|
||||
new BigdataResume();
|
||||
});
|
||||
@@ -5,9 +5,9 @@ Dropzone.autoDiscover = false;
|
||||
var previewTemplate,
|
||||
dropzone,
|
||||
dropzonePreviewNode = document.querySelector("#dropzone-preview-list");
|
||||
console.log(previewTemplate);
|
||||
console.log(dropzone);
|
||||
console.log(dropzonePreviewNode);
|
||||
|
||||
const uploadButton = document.getElementById("btnUploadBusinessIndustry");
|
||||
const spinner = document.getElementById("spinner");
|
||||
|
||||
const toastNotification = document.getElementById("toastNotification");
|
||||
const toast = new bootstrap.Toast(toastNotification);
|
||||
@@ -29,97 +29,50 @@ const toast = new bootstrap.Toast(toastNotification);
|
||||
.getAttribute("content")}`,
|
||||
},
|
||||
init: function () {
|
||||
// Listen for the success event
|
||||
this.on("success", function (file, response) {
|
||||
console.log("File successfully uploaded:", file);
|
||||
console.log("API Response:", response);
|
||||
|
||||
// Show success toast
|
||||
document.getElementById("toast-message").innerText =
|
||||
response.message;
|
||||
toast.show();
|
||||
document.getElementById("submit-upload").innerHTML =
|
||||
"Upload Files";
|
||||
// Tunggu sebentar lalu reload halaman
|
||||
setTimeout(() => {
|
||||
window.location.href = "/data/business-industries";
|
||||
}, 2000);
|
||||
});
|
||||
// Listen for the error event
|
||||
this.on("error", function (file, errorMessage) {
|
||||
console.error("Error uploading file:", file);
|
||||
console.error("Error message:", errorMessage);
|
||||
// Handle the error response
|
||||
|
||||
// Show error toast
|
||||
document.getElementById("toast-message").innerText =
|
||||
errorMessage.message;
|
||||
toast.show();
|
||||
document.getElementById("submit-upload").innerHTML =
|
||||
"Upload Files";
|
||||
uploadButton.disabled = false;
|
||||
spinner.classList.add("d-none");
|
||||
});
|
||||
},
|
||||
})));
|
||||
|
||||
// Add event listener to control the submission manually
|
||||
document.querySelector("#submit-upload").addEventListener("click", function () {
|
||||
console.log("Ini adalah value dropzone", dropzone.files[0]);
|
||||
const formData = new FormData();
|
||||
console.log("Dropzonefiles", dropzone.files);
|
||||
document
|
||||
.querySelector("#btnUploadBusinessIndustry")
|
||||
.addEventListener("click", function () {
|
||||
console.log("Ini adalah value dropzone", dropzone.files[0]);
|
||||
const formData = new FormData();
|
||||
|
||||
this.innerHTML =
|
||||
'<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>Loading...';
|
||||
if (dropzone.files.length > 0) {
|
||||
formData.append("file", dropzone.files[0]);
|
||||
dropzone.processQueue(); // Ini akan manual memicu upload
|
||||
uploadButton.disabled = true;
|
||||
spinner.classList.remove("d-none");
|
||||
} else {
|
||||
document.getElementById("toast-message").innerText =
|
||||
"Please add a file first.";
|
||||
toast.show();
|
||||
uploadButton.disabled = false;
|
||||
spinner.classList.add("d-none");
|
||||
}
|
||||
});
|
||||
|
||||
// Pastikan ada file dalam queue sebelum memprosesnya
|
||||
if (dropzone.files.length > 0) {
|
||||
formData.append("file", dropzone.files[0]);
|
||||
console.log("ini adalah form data on submit", ...formData);
|
||||
dropzone.processQueue(); // Ini akan manual memicu upload
|
||||
} else {
|
||||
// Show error toast when no file is selected
|
||||
document.getElementById("toast-message").innerText =
|
||||
"Please add a file first.";
|
||||
toast.show();
|
||||
|
||||
document.getElementById("submit-upload").innerHTML = "Upload Files";
|
||||
}
|
||||
});
|
||||
|
||||
// Optional: Listen for the 'addedfile' event to log or control file add behavior
|
||||
dropzone.on("addedfile", function (file) {
|
||||
console.log("File ditambahkan:", file);
|
||||
console.log("Nama File:", file.name);
|
||||
console.log("Tipe File:", file.type);
|
||||
console.log("Ukuran File:", (file.size / 1024).toFixed(2) + " KB");
|
||||
});
|
||||
dropzone.on("addedfile", function (file) {});
|
||||
|
||||
dropzone.on("complete", function (file) {
|
||||
dropzone.removeFile(file);
|
||||
});
|
||||
|
||||
// Function to show toast
|
||||
// function showToast(iconClass, iconColor, message) {
|
||||
// const toastElement = document.getElementById("toastUploadAdvertisement");
|
||||
// const toastBody = toastElement.querySelector(".toast-body");
|
||||
// const toastHeader = toastElement.querySelector(".toast-header");
|
||||
|
||||
// // Remove existing icon (if any) before adding the new one
|
||||
// const existingIcon = toastHeader.querySelector(".bx");
|
||||
// if (existingIcon) {
|
||||
// toastHeader.querySelector(".auth-logo").removeChild(existingIcon); // Remove the existing icon
|
||||
// }
|
||||
|
||||
// // Add the new icon to the toast header
|
||||
// const icon = document.createElement("i");
|
||||
// icon.classList.add("bx", iconClass);
|
||||
// icon.style.fontSize = "25px";
|
||||
// icon.style.color = iconColor;
|
||||
// toastHeader.querySelector(".auth-logo").appendChild(icon);
|
||||
|
||||
// // Set the toast message
|
||||
// toastBody.textContent = message;
|
||||
|
||||
// // Show the toast
|
||||
// const toast = new bootstrap.Toast(toastElement); // Inisialisasi Bootstrap Toast
|
||||
// toast.show();
|
||||
// }
|
||||
|
||||
@@ -2,58 +2,41 @@ import { Grid } from "gridjs/dist/gridjs.umd.js";
|
||||
import gridjs from "gridjs/dist/gridjs.umd.js";
|
||||
import "gridjs/dist/gridjs.umd.js";
|
||||
import GlobalConfig from "../global-config.js";
|
||||
import Swal from "sweetalert2";
|
||||
|
||||
class BusinessIndustries {
|
||||
constructor() {
|
||||
this.table = null; // Store Grid.js instance
|
||||
this.toastMessage = document.getElementById("toast-message");
|
||||
this.toastElement = document.getElementById("toastNotification");
|
||||
this.toast = new bootstrap.Toast(this.toastElement);
|
||||
this.table = null;
|
||||
|
||||
// Initialize functions
|
||||
this.initTableBusinessIndustries();
|
||||
this.initEvents();
|
||||
}
|
||||
init() {
|
||||
this.getFetchApiData();
|
||||
initEvents() {
|
||||
document.body.addEventListener("click", async (event) => {
|
||||
const deleteButton = event.target.closest(
|
||||
".btn-delete-business-industry"
|
||||
);
|
||||
if (deleteButton) {
|
||||
event.preventDefault();
|
||||
await this.handleDelete(deleteButton);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getFetchApiData() {
|
||||
initTableBusinessIndustries() {
|
||||
let tableContainer = document.getElementById(
|
||||
"table-business-industries"
|
||||
);
|
||||
|
||||
if (this.table) {
|
||||
// If table exists, update its data instead of recreating
|
||||
this.table
|
||||
.updateConfig({
|
||||
server: {
|
||||
url: `${GlobalConfig.apiHost}/api/api-business-industries`,
|
||||
credentials: "include",
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
then: (data) =>
|
||||
data.data.map((item) => [
|
||||
item.id,
|
||||
item.nama_kecamatan,
|
||||
item.nama_kelurahan,
|
||||
item.nop,
|
||||
item.nama_wajib_pajak,
|
||||
item.alamat_wajib_pajak,
|
||||
item.alamat_objek_pajak,
|
||||
item.luas_bumi,
|
||||
item.luas_bangunan,
|
||||
item.njop_bumi,
|
||||
item.njop_bangunan,
|
||||
item.ketetapan,
|
||||
item.tahun_pajak,
|
||||
item.created_at,
|
||||
item.id,
|
||||
]),
|
||||
total: (data) => data.total,
|
||||
},
|
||||
})
|
||||
.forceRender();
|
||||
return;
|
||||
}
|
||||
|
||||
tableContainer.innerHTML = "";
|
||||
let canUpdate = tableContainer.getAttribute("data-updater") === "1";
|
||||
let canDelete = tableContainer.getAttribute("data-destroyer") === "1";
|
||||
|
||||
// Create a new Grid.js instance only if it doesn't exist
|
||||
this.table = new Grid({
|
||||
columns: [
|
||||
{ name: "ID", width: "80px", hidden: false },
|
||||
@@ -71,29 +54,35 @@ class BusinessIndustries {
|
||||
{ name: "Tahun Pajak", width: "120px" },
|
||||
{ name: "Created", width: "180px" },
|
||||
{
|
||||
name: "Actions",
|
||||
width: "120px",
|
||||
formatter: function (cell) {
|
||||
return gridjs.html(`
|
||||
<div class="d-flex justify-content-center gap-2">
|
||||
<a href="/data/business-industries/${cell}/edit" class="btn btn-yellow btn-sm d-inline-flex align-items-center justify-content-center">
|
||||
<i class='bx bx-edit'></i>
|
||||
</a>
|
||||
<button class="btn btn-sm btn-red d-inline-flex align-items-center justify-content-center btn-delete-business-industries" data-id="${cell}">
|
||||
<i class='bx bxs-trash'></i>
|
||||
</button>
|
||||
</div>
|
||||
`);
|
||||
name: "Action",
|
||||
formatter: (cell) => {
|
||||
|
||||
let buttons = `<div class="d-flex justify-content-center gap-2">`;
|
||||
|
||||
if (canUpdate) {
|
||||
buttons += `
|
||||
<a href="/data/business-industries/${cell}/edit" class="btn btn-yellow btn-sm d-inline-flex align-items-center justify-content-center">
|
||||
<i class='bx bx-edit'></i>
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
|
||||
if (canDelete) {
|
||||
buttons += `
|
||||
<button data-id="${cell}" class="btn btn-sm btn-red btn-delete-business-industry d-inline-flex align-items-center justify-content-center">
|
||||
<i class='bx bxs-trash'></i>
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
|
||||
buttons += `</div>`;
|
||||
|
||||
return gridjs.html(buttons);
|
||||
},
|
||||
},
|
||||
],
|
||||
search: {
|
||||
server: {
|
||||
url: (prev, keyword) => `${prev}?search=${keyword}`,
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
limit: 15,
|
||||
limit: 50,
|
||||
server: {
|
||||
url: (prev, page) =>
|
||||
`${prev}${prev.includes("?") ? "&" : "?"}page=${
|
||||
@@ -102,6 +91,12 @@ class BusinessIndustries {
|
||||
},
|
||||
},
|
||||
sort: true,
|
||||
search: {
|
||||
server: {
|
||||
url: (prev, keyword) => `${prev}?search=${keyword}`,
|
||||
},
|
||||
debounceTimeout: 1000,
|
||||
},
|
||||
server: {
|
||||
url: `${GlobalConfig.apiHost}/api/api-business-industries`,
|
||||
headers: {
|
||||
@@ -131,98 +126,26 @@ class BusinessIndustries {
|
||||
total: (data) => data.total,
|
||||
},
|
||||
}).render(tableContainer);
|
||||
|
||||
document.addEventListener("click", this.handleDelete.bind(this));
|
||||
}
|
||||
handleDelete(event) {
|
||||
if (event.target.classList.contains("btn-delete-business-industries")) {
|
||||
event.preventDefault();
|
||||
const id = event.target.getAttribute("data-id");
|
||||
let modalElement = document.getElementById("modalConfirmation");
|
||||
let toastMessage = document.getElementById("toast-message");
|
||||
async handleDelete(deleteButton) {
|
||||
const id = deleteButton.getAttribute("data-id");
|
||||
|
||||
if (!modalElement) {
|
||||
console.error("Modal element not found!");
|
||||
return;
|
||||
}
|
||||
const result = await Swal.fire({
|
||||
title: "Are you sure?",
|
||||
text: "You won't be able to revert this!",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#3085d6",
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonText: "Yes, delete it!",
|
||||
});
|
||||
|
||||
let modal = new bootstrap.Modal(modalElement);
|
||||
let btnSaveConfirmation = document.getElementById(
|
||||
"btnSaveConfirmation"
|
||||
);
|
||||
let toastElement = document.getElementById("toastNotification");
|
||||
let toast = new bootstrap.Toast(toastElement);
|
||||
|
||||
// Remove previous event listeners to avoid multiple bindings
|
||||
btnSaveConfirmation.replaceWith(
|
||||
btnSaveConfirmation.cloneNode(true)
|
||||
);
|
||||
btnSaveConfirmation = document.getElementById(
|
||||
"btnSaveConfirmation"
|
||||
);
|
||||
|
||||
// Set the role ID on the confirm button inside the modal
|
||||
btnSaveConfirmation.setAttribute("data-business-industries-id", id);
|
||||
|
||||
// Show the modal
|
||||
modal.show();
|
||||
|
||||
btnSaveConfirmation.addEventListener("click", async () => {
|
||||
let deletedId = btnSaveConfirmation.getAttribute(
|
||||
"data-business-industries-id"
|
||||
);
|
||||
|
||||
try {
|
||||
let response = await fetch(
|
||||
`${GlobalConfig.apiHost}/api/api-business-industries/${deletedId}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": document
|
||||
.querySelector('meta[name="csrf-token"]')
|
||||
.getAttribute("content"),
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (response.ok) {
|
||||
let result = await response.json();
|
||||
toastMessage.innerText =
|
||||
result.message || "Deleted successfully!";
|
||||
toast.show();
|
||||
|
||||
// Hide modal
|
||||
modal.hide();
|
||||
|
||||
// Refresh Grid.js table
|
||||
this.refreshDataSettings();
|
||||
} else {
|
||||
let error = await response.json();
|
||||
console.error("Delete failed:", error);
|
||||
toastMessage.innerText =
|
||||
error.message || "Delete failed!";
|
||||
toast.show();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error deleting item:", error);
|
||||
toastMessage.innerText = "An error occurred!";
|
||||
toast.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
refreshDataSettings() {
|
||||
if (this.table) {
|
||||
this.table
|
||||
.updateConfig({
|
||||
server: {
|
||||
url: `${GlobalConfig.apiHost}/api/api-business-industries`,
|
||||
if (result.isConfirmed) {
|
||||
try {
|
||||
let response = await fetch(
|
||||
`${GlobalConfig.apiHost}/api/api-business-industries/${id}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
@@ -230,31 +153,34 @@ class BusinessIndustries {
|
||||
.getAttribute("content")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
then: (data) =>
|
||||
data.data.map((item) => [
|
||||
item.id,
|
||||
item.nama_kecamatan,
|
||||
item.nama_kelurahan,
|
||||
item.nop,
|
||||
item.nama_wajib_pajak,
|
||||
item.alamat_wajib_pajak,
|
||||
item.alamat_objek_pajak,
|
||||
item.luas_bumi,
|
||||
item.luas_bangunan,
|
||||
item.njop_bumi,
|
||||
item.njop_bangunan,
|
||||
item.ketetapan,
|
||||
item.tahun_pajak,
|
||||
item.created_at,
|
||||
item.id, // ID for Actions column
|
||||
]),
|
||||
total: (data) => data.total,
|
||||
},
|
||||
})
|
||||
.forceRender();
|
||||
}
|
||||
);
|
||||
|
||||
if (response.ok) {
|
||||
let result = await response.json();
|
||||
this.toastMessage.innerText =
|
||||
result.message || "Deleted successfully!";
|
||||
this.toast.show();
|
||||
|
||||
// Refresh Grid.js table
|
||||
if (typeof this.table !== "undefined") {
|
||||
this.table.updateConfig({}).forceRender();
|
||||
}
|
||||
} else {
|
||||
let error = await response.json();
|
||||
console.error("Delete failed:", error);
|
||||
this.toastMessage.innerText =
|
||||
error.message || "Delete failed!";
|
||||
this.toast.show();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error deleting item:", error);
|
||||
this.toastMessage.innerText = "An error occurred!";
|
||||
this.toast.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function (e) {
|
||||
new BusinessIndustries().init();
|
||||
new BusinessIndustries();
|
||||
});
|
||||
|
||||
155
resources/js/chatbot-pimpinan/index.js
Normal file
155
resources/js/chatbot-pimpinan/index.js
Normal file
@@ -0,0 +1,155 @@
|
||||
import GlobalConfig from "../global-config.js";
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const timeElements = document.querySelectorAll(".sending-message-time p");
|
||||
|
||||
timeElements.forEach((element) => {
|
||||
element.textContent = getCurrentTime();
|
||||
});
|
||||
|
||||
const textarea = document.getElementById("user-message");
|
||||
const sendButton = document.getElementById("send");
|
||||
const conversationArea = document.querySelector(".row.flex-grow");
|
||||
const chatHistory = [];
|
||||
|
||||
// Fungsi untuk mengirim pesan
|
||||
async function sendMessage() {
|
||||
const userText = textarea.value.trim();
|
||||
if (userText !== "") {
|
||||
// Kosongkan textarea setelah mengirim
|
||||
textarea.value = "";
|
||||
|
||||
// Tambahkan pesan user ke UI
|
||||
addMessage(userText, "user");
|
||||
|
||||
// Tambahkan pesan bot sementara dengan "Loading..."
|
||||
const botMessageElement = addMessage('<div class="bot-message-text">...</div>', "bot");
|
||||
|
||||
const messageTextContainer = botMessageElement.querySelector(".bot-message-text");
|
||||
if (messageTextContainer) {
|
||||
messageTextContainer.innerHTML = '<div class="loader ms-3"></div>';
|
||||
}
|
||||
|
||||
// Panggil API untuk mendapatkan respons dari bot
|
||||
const botResponse = await getBotResponse(userText, chatHistory);
|
||||
|
||||
// Perbarui pesan bot dengan respons yang sebenarnya
|
||||
if (messageTextContainer) {
|
||||
messageTextContainer.innerHTML = botResponse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Event listener untuk klik tombol
|
||||
sendButton.addEventListener("click", sendMessage);
|
||||
|
||||
// Event listener untuk menekan Enter di textarea
|
||||
textarea.addEventListener("keydown", function (event) {
|
||||
if (event.key === "Enter" && !event.shiftKey) {
|
||||
event.preventDefault(); // Mencegah newline di textarea
|
||||
sendMessage(); // Panggil fungsi kirim pesan
|
||||
}
|
||||
});
|
||||
|
||||
function getCurrentTime() {
|
||||
const now = new Date();
|
||||
return now.getHours().toString().padStart(2, "0") + ":" + now.getMinutes().toString().padStart(2, "0");
|
||||
}
|
||||
|
||||
function addMessage(text, sender) {
|
||||
const messageRow = document.createElement("div");
|
||||
// Atur posisi berdasarkan sender (user -> end, bot -> start)
|
||||
messageRow.classList.add("row", "flex-grow", "overflow-auto", sender === "user" ? "justify-content-end" : "justify-content-start");
|
||||
|
||||
const messageCol = document.createElement("div");
|
||||
messageCol.classList.add("col-9", "w-auto");
|
||||
|
||||
// Atur lebar maksimum berdasarkan sender
|
||||
messageCol.style.maxWidth = sender === "user" ? "50%" : "75%";
|
||||
|
||||
// Container untuk menyimpan nama dan bubble chat
|
||||
const messageWrapper = document.createElement("div");
|
||||
messageWrapper.classList.add("d-flex", "flex-column");
|
||||
|
||||
// Tambahkan Nama di luar bubble chat
|
||||
const messageName = document.createElement("p");
|
||||
messageName.classList.add("fw-bolder", sender === "user" ? "text-end" : "text-start", "mb-1");
|
||||
messageName.textContent = sender === "user" ? "You" : "Neng Bedas";
|
||||
|
||||
// Bubble Chat
|
||||
const messageContainer = document.createElement("div");
|
||||
messageContainer.classList.add("p-2", "rounded", "mb-2", "d-inline-block");
|
||||
if (sender === "user") {
|
||||
messageContainer.classList.add("user-response", "bg-primary", "text-white");
|
||||
} else {
|
||||
messageContainer.classList.add("bot-response", "bg-light");
|
||||
}
|
||||
|
||||
const messageContent = document.createElement("div");
|
||||
messageContent.classList.add("bot-message-text", "mb-0", "text-start");
|
||||
messageContent.textContent = text;
|
||||
|
||||
// Waktu di dalam bubble chat
|
||||
const messageTime = document.createElement("div");
|
||||
messageTime.classList.add("sending-message-time", "text-end", "mt-1");
|
||||
messageTime.innerHTML = `<p class="small mb-0 ${sender === "user" ? "text-white text-start" : "text-muted"}">${getCurrentTime()}</p>`;
|
||||
|
||||
messageContainer.appendChild(messageContent);
|
||||
messageContainer.appendChild(messageTime);
|
||||
|
||||
// Jika pengirim adalah bot, tambahkan avatar
|
||||
if (sender !== "user") {
|
||||
const avatarContainer = document.createElement("div");
|
||||
avatarContainer.classList.add("col-auto", "pe-0");
|
||||
|
||||
const avatarImg = document.createElement("img");
|
||||
avatarImg.classList.add("rounded-circle");
|
||||
avatarImg.width = 45;
|
||||
avatarImg.src = "/images/iconchatbot.jpeg";
|
||||
avatarImg.alt = "bot-avatar";
|
||||
|
||||
avatarContainer.appendChild(avatarImg);
|
||||
messageRow.appendChild(avatarContainer);
|
||||
}
|
||||
|
||||
// Masukkan nama dan bubble ke dalam wrapper
|
||||
messageWrapper.appendChild(messageName);
|
||||
messageWrapper.appendChild(messageContainer);
|
||||
messageCol.appendChild(messageWrapper);
|
||||
messageRow.appendChild(messageCol);
|
||||
|
||||
conversationArea.appendChild(messageRow);
|
||||
conversationArea.scrollTop = conversationArea.scrollHeight;
|
||||
|
||||
return messageContainer;
|
||||
}
|
||||
|
||||
// Fungsi untuk memanggil API
|
||||
async function getBotResponse(userText, historyChat) {
|
||||
try {
|
||||
const url = `${GlobalConfig.apiHost}/api/main-generate-text`;
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({prompt: userText, chatHistory: historyChat}),
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
const rawBotResponse = data.nlpResponse;
|
||||
// Tambahkan ke chatHistory
|
||||
chatHistory.push({
|
||||
user: userText,
|
||||
rawBotResponse: rawBotResponse,
|
||||
});
|
||||
return data.response || "Maaf, saya tidak mengerti.";
|
||||
} catch (error) {
|
||||
console.error("Error fetching bot response:", error);
|
||||
return "Terjadi kesalahan, coba lagi nanti.";
|
||||
}
|
||||
}
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user